Skip to content

Commit 70b9066

Browse files
authored
fix: stabilize legacy workspace session_count test (#325)
## Summary Hardens `agent-gateway` `sums session_count across legacy split buckets of one root`. External session seeds are not watched into the minidb read model. `PYTHINKER_CODE_WATCH` only reloads `workspaces.json` (150ms debounce). Session counters update on boot project, API/mirror dirty marks, or the 60s reconcile tick. The old test wrote buckets under a live server and polled with the default 1s `waitFor`, so CI could observe a folded workspace with a stale count of 1. ## Change - Fresh home for the case - Seed both legacy buckets on disk - Restart the same home so boot projection indexes both dirs - 10s `waitFor` (same budget as the sibling sessions read-model test) Test-only. No product change. No changeset. ## Test plan - [x] `pnpm --filter @pymodel/agent-gateway exec vitest run test/workspaces.test.ts` - [ ] CI green on this PR <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Improved workspace consolidation test reliability by resetting server state between test phases. * Added coverage for restarting with either a fresh or existing home environment. * Added explicit timeout handling while waiting for workspace consolidation and session counts. * Improved cleanup behavior and retry handling for temporary test environments. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 96d1a0c commit 70b9066

1 file changed

Lines changed: 51 additions & 8 deletions

File tree

‎packages/agent-gateway/test/workspaces.test.ts‎

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,44 @@ describe('server-v2 /api/v1/workspaces', () => {
6868
delete process.env['PYTHINKER_CODE_WATCH'];
6969
});
7070

71+
async function restartWithFreshHome(): Promise<void> {
72+
if (server !== undefined) {
73+
await server.close();
74+
server = undefined;
75+
}
76+
if (home !== undefined) {
77+
await new Promise((resolve) => setTimeout(resolve, 25));
78+
await rm(home, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 });
79+
}
80+
home = await mkdtemp(join(tmpdir(), 'pythinker-server-v2-workspaces-'));
81+
process.env['PYTHINKER_CODE_WATCH'] = '1';
82+
server = await startServer({
83+
hostIdentity: TEST_HOST_IDENTITY,
84+
host: '127.0.0.1',
85+
port: 0,
86+
homeDir: home,
87+
logLevel: 'silent',
88+
});
89+
base = `http://127.0.0.1:${server.port}`;
90+
}
91+
92+
async function restartSameHome(): Promise<void> {
93+
if (server !== undefined) {
94+
await server.close();
95+
server = undefined;
96+
}
97+
process.env['PYTHINKER_CODE_WATCH'] = '1';
98+
server = await startServer({
99+
hostIdentity: TEST_HOST_IDENTITY,
100+
host: '127.0.0.1',
101+
port: 0,
102+
homeDir: home as string,
103+
logLevel: 'silent',
104+
});
105+
base = `http://127.0.0.1:${server.port}`;
106+
}
107+
108+
71109
async function postJson<T>(
72110
path: string,
73111
body?: unknown,
@@ -206,6 +244,7 @@ describe('server-v2 /api/v1/workspaces', () => {
206244
});
207245

208246
it('sums session_count across legacy split buckets of one root', async () => {
247+
await restartWithFreshHome();
209248
const typedRoot = 'C:\\Users\\Foo\\Proj';
210249
const lowerRoot = 'c:\\users\\foo\\proj';
211250
const typedId = encodeWorkDirKey(typedRoot);
@@ -246,14 +285,18 @@ describe('server-v2 /api/v1/workspaces', () => {
246285
};
247286
await seedBucket(typedId, 's-typed', {});
248287
await seedBucket(lowerId, 's-lower', { archived: true, updatedAt: 2 });
249-
250-
await vi.waitFor(async () => {
251-
const { body } = await getJson<ListWire>('/api/v1/workspaces');
252-
expect(body.code).toBe(0);
253-
const unions = body.data.items.filter((w) => [typedId, lowerId].includes(w.id));
254-
expect(unions).toHaveLength(1);
255-
expect(unions[0]?.session_count).toBe(2);
256-
});
288+
await restartSameHome();
289+
290+
await vi.waitFor(
291+
async () => {
292+
const { body } = await getJson<ListWire>('/api/v1/workspaces');
293+
expect(body.code).toBe(0);
294+
const unions = body.data.items.filter((w) => [typedId, lowerId].includes(w.id));
295+
expect(unions).toHaveLength(1);
296+
expect(unions[0]?.session_count).toBe(2);
297+
},
298+
{ timeout: 10_000 },
299+
);
257300
});
258301

259302
it('adds an additional directory and persists it by default', async () => {

0 commit comments

Comments
 (0)