Skip to content

Commit 12b013f

Browse files
committed
fix(tests): stabilize CI across default branch and timing
1 parent 1626083 commit 12b013f

3 files changed

Lines changed: 47 additions & 28 deletions

File tree

tests/integration/orchestration.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ describe('orchestration integration', () => {
417417
await commitInJobWorktree('job-c', 'src/feature.ts', 'export const featureEnabled = true;\n');
418418
await simulateJobCompletion('job-c', monitor, orchestrator);
419419

420-
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 10000);
420+
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 20000);
421421

422422
const finalPlan = await loadPlan();
423423
expect(finalPlan?.status).toBe('completed');
@@ -597,7 +597,7 @@ describe('orchestration integration', () => {
597597
await simulateJobCompletion('job-b', monitor2, orchestrator2);
598598
await simulateJobCompletion('job-c', monitor2, orchestrator2);
599599

600-
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 10000);
600+
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 20000);
601601
expect((await loadPlan())?.status).toBe('completed');
602602
}, 30000);
603603

@@ -663,7 +663,7 @@ describe('orchestration integration', () => {
663663
await simulateJobCompletion('job-c', monitor, orchestrator);
664664
await kickReconciler(orchestrator);
665665

666-
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 10000);
666+
await waitForCondition(async () => (await loadPlan())?.status === 'completed', 20000);
667667
expect((await loadPlan())?.status).toBe('completed');
668668
}, 30000);
669669
});

tests/lib/integration.test.ts

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,30 @@ const TEST_REPO_DIR = join(tmpdir(), '.tmp-integration-test-repo');
1414
async function exec(
1515
args: string[],
1616
cwdOrOpts?: string | { cwd?: string },
17-
): Promise<{ stdout: string; exitCode: number }> {
17+
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
1818
const cwd = typeof cwdOrOpts === 'string' ? cwdOrOpts : cwdOrOpts?.cwd;
1919
const proc = Bun.spawn(args, {
2020
cwd,
2121
stdout: 'pipe',
2222
stderr: 'pipe',
2323
});
24-
const stdout = await new Response(proc.stdout).text();
24+
const [stdout, stderr] = await Promise.all([
25+
new Response(proc.stdout).text(),
26+
new Response(proc.stderr).text(),
27+
]);
2528
const exitCode = await proc.exited;
26-
return { stdout: stdout.trim(), exitCode };
29+
return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode };
30+
}
31+
32+
async function mustExec(
33+
args: string[],
34+
cwdOrOpts?: string | { cwd?: string },
35+
): Promise<string> {
36+
const result = await exec(args, cwdOrOpts);
37+
if (result.exitCode !== 0) {
38+
throw new Error(`Command failed: ${args.join(' ')}\n${result.stderr}`);
39+
}
40+
return result.stdout;
2741
}
2842

2943
async function setupTestRepo(): Promise<void> {
@@ -35,19 +49,20 @@ async function setupTestRepo(): Promise<void> {
3549

3650
const bareRepoDir = join(TEST_REPO_DIR, 'bare.git');
3751
fs.mkdirSync(bareRepoDir, { recursive: true });
38-
await exec(['git', 'init', '--bare'], bareRepoDir);
52+
await mustExec(['git', 'init', '--bare'], bareRepoDir);
3953

4054
const mainRepoDir = join(TEST_REPO_DIR, 'main');
4155
fs.mkdirSync(mainRepoDir, { recursive: true });
42-
await exec(['git', 'init'], mainRepoDir);
43-
await exec(['git', 'config', 'user.email', '[email protected]'], mainRepoDir);
44-
await exec(['git', 'config', 'user.name', 'Test'], mainRepoDir);
45-
await exec(['git', 'remote', 'add', 'origin', bareRepoDir], mainRepoDir);
56+
await mustExec(['git', 'init'], mainRepoDir);
57+
await mustExec(['git', 'branch', '-M', 'main'], mainRepoDir);
58+
await mustExec(['git', 'config', 'user.email', '[email protected]'], mainRepoDir);
59+
await mustExec(['git', 'config', 'user.name', 'Test'], mainRepoDir);
60+
await mustExec(['git', 'remote', 'add', 'origin', bareRepoDir], mainRepoDir);
4661

4762
fs.writeFileSync(join(mainRepoDir, 'test.txt'), 'initial content');
48-
await exec(['git', 'add', '.'], mainRepoDir);
49-
await exec(['git', 'commit', '-m', 'initial'], mainRepoDir);
50-
await exec(['git', 'push', '-u', 'origin', 'main'], mainRepoDir);
63+
await mustExec(['git', 'add', '.'], mainRepoDir);
64+
await mustExec(['git', 'commit', '-m', 'initial'], mainRepoDir);
65+
await mustExec(['git', 'push', '-u', 'origin', 'main'], mainRepoDir);
5166

5267
process.chdir(mainRepoDir);
5368
}
@@ -191,14 +206,14 @@ describe('integration', () => {
191206
describe('refreshIntegrationFromMain', () => {
192207
it('should refresh without conflicts', async () => {
193208
const planId = 'test-plan-7';
194-
const createResult = await createIntegrationBranch(planId);
209+
await createIntegrationBranch(planId);
195210

196211
const filePath = join(mainRepoDir, 'test.txt');
197212
const fs = await import('fs');
198213
fs.writeFileSync(filePath, 'updated content');
199-
await exec(['git', 'add', 'test.txt'], mainRepoDir);
200-
await exec(['git', 'commit', '-m', 'update on main'], mainRepoDir);
201-
await exec(['git', 'push', 'origin', 'main'], mainRepoDir);
214+
await mustExec(['git', 'add', 'test.txt'], mainRepoDir);
215+
await mustExec(['git', 'commit', '-m', 'update on main'], mainRepoDir);
216+
await mustExec(['git', 'push', 'origin', 'main'], mainRepoDir);
202217

203218
const result = await refreshIntegrationFromMain(planId);
204219

@@ -213,16 +228,16 @@ describe('integration', () => {
213228
const filePath = join(mainRepoDir, 'test.txt');
214229
const fs = await import('fs');
215230
fs.writeFileSync(filePath, 'main version');
216-
await exec(['git', 'add', 'test.txt'], mainRepoDir);
217-
await exec(['git', 'commit', '-m', 'main change'], mainRepoDir);
218-
await exec(['git', 'push', 'origin', 'main'], mainRepoDir);
231+
await mustExec(['git', 'add', 'test.txt'], mainRepoDir);
232+
await mustExec(['git', 'commit', '-m', 'main change'], mainRepoDir);
233+
await mustExec(['git', 'push', 'origin', 'main'], mainRepoDir);
219234

220235
const integrationFilePath = join(createResult.worktreePath, 'test.txt');
221236
fs.writeFileSync(integrationFilePath, 'integration version');
222-
await exec(['git', 'add', 'test.txt'], {
237+
await mustExec(['git', 'add', 'test.txt'], {
223238
cwd: createResult.worktreePath,
224239
});
225-
await exec(['git', 'commit', '-m', 'integration change'], {
240+
await mustExec(['git', 'commit', '-m', 'integration change'], {
226241
cwd: createResult.worktreePath,
227242
});
228243

tests/tools/kill.test.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
1+
import { describe, it, expect, beforeEach, afterEach, vi, type MockInstance } from 'vitest';
22
import type { Job } from '../../src/lib/job-state';
33
import * as jobState from '../../src/lib/job-state';
44
import * as tmux from '../../src/lib/tmux';
55

66
const { mc_kill } = await import('../../src/tools/kill');
77

8-
let mockGetJobByName: Mock;
9-
let mockUpdateJob: Mock;
10-
let mockKillSession: Mock;
11-
let mockKillWindow: Mock;
8+
let mockGetJobByName: MockInstance;
9+
let mockUpdateJob: MockInstance;
10+
let mockKillSession: MockInstance;
11+
let mockKillWindow: MockInstance;
1212

1313
const mockContext = {
1414
sessionID: 'test-session',
@@ -37,6 +37,10 @@ describe('mc_kill', () => {
3737
setupDefaultMocks();
3838
});
3939

40+
afterEach(() => {
41+
vi.restoreAllMocks();
42+
});
43+
4044
describe('tool definition', () => {
4145
it('should have correct description', () => {
4246
expect(mc_kill.description).toBe('Stop a running job');

0 commit comments

Comments
 (0)