Skip to content

Commit e4df13d

Browse files
committed
test: simplify runner recovery diagnostics assertion
1 parent 5807622 commit e4df13d

1 file changed

Lines changed: 89 additions & 71 deletions

File tree

src/platforms/ios/__tests__/runner-command-retry.test.ts

Lines changed: 89 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -57,31 +57,11 @@ beforeEach(() => {
5757
});
5858

5959
test('prepareIosRunner marks a bad restored artifact and rebuilds once after health failure', async () => {
60-
const restoredArtifact = makeRunnerArtifact({
61-
xctestrunPath: '/tmp/restored.xctestrun',
62-
cache: 'exact',
63-
artifact: 'valid',
64-
});
65-
const rebuiltArtifact = makeRunnerArtifact({
66-
xctestrunPath: '/tmp/rebuilt.xctestrun',
67-
cache: 'miss',
68-
artifact: 'rebuilt',
69-
buildMs: 123,
70-
});
71-
const restoredSession = makeRunnerSession({
72-
port: 8100,
73-
xctestrunPath: restoredArtifact.xctestrunPath,
74-
xctestrunArtifact: restoredArtifact,
75-
});
76-
const rebuiltSession = makeRunnerSession({
77-
port: 8101,
78-
xctestrunPath: rebuiltArtifact.xctestrunPath,
79-
xctestrunArtifact: rebuiltArtifact,
80-
});
60+
const fixtures = makeBadCacheRecoveryFixtures();
8161

8262
mockEnsureRunnerSession
83-
.mockResolvedValueOnce(restoredSession)
84-
.mockResolvedValueOnce(rebuiltSession);
63+
.mockResolvedValueOnce(fixtures.restoredSession)
64+
.mockResolvedValueOnce(fixtures.rebuiltSession);
8565
mockExecuteRunnerCommandWithSession
8666
.mockRejectedValueOnce(new AppError('COMMAND_FAILED', 'Runner did not accept connection'))
8767
.mockResolvedValueOnce({ uptimeMs: 42 });
@@ -91,54 +71,9 @@ test('prepareIosRunner marks a bad restored artifact and rebuilds once after hea
9171
buildTimeoutMs: 300_000,
9272
});
9373

94-
assert.deepEqual(result, {
95-
runner: { uptimeMs: 42 },
96-
cache: 'miss',
97-
artifact: 'rebuilt',
98-
buildMs: 123,
99-
connectMs: result.connectMs,
100-
healthCheckMs: result.healthCheckMs,
101-
xctestrunPath: '/tmp/rebuilt.xctestrun',
102-
recoveryReason: 'Runner did not accept connection',
103-
});
104-
assert.equal(result.failureReason, undefined);
105-
assert.equal(result.connectMs >= 0, true);
106-
assert.equal(result.healthCheckMs >= 0, true);
107-
assert.deepEqual(mockInvalidateRunnerSession.mock.calls[0], [
108-
restoredSession,
109-
'prepare_cached_runner_health_failed',
110-
]);
111-
assert.deepEqual(mockMarkRunnerXctestrunArtifactBadForRun.mock.calls[0], [
112-
restoredArtifact,
113-
'Runner did not accept connection',
114-
]);
115-
assert.deepEqual(mockEnsureRunnerSession.mock.calls[1]?.[1], {
116-
healthTimeoutMs: 90_000,
117-
buildTimeoutMs: 300_000,
118-
cleanStaleBundles: true,
119-
forceRunnerXctestrunRebuild: true,
120-
});
121-
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls.length, 2);
122-
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[0]?.[2].command, 'uptime');
123-
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[0]?.[4], 90_000);
124-
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[1]?.[1], rebuiltSession);
125-
assert.ok(
126-
mockEmitDiagnostic.mock.calls.some(
127-
([event]) => event.phase === 'ios_runner_prepare_bad_cache_recovered',
128-
),
129-
);
130-
assert.ok(
131-
mockEmitDiagnostic.mock.calls.some(
132-
([event]) =>
133-
event.phase === 'apple_runner_prepare' &&
134-
event.data?.cache === 'miss' &&
135-
event.data?.artifact === 'rebuilt' &&
136-
event.data?.xctestrunPath === '/tmp/rebuilt.xctestrun' &&
137-
event.data?.recoveryReason === 'Runner did not accept connection' &&
138-
event.data?.failureReason === undefined &&
139-
event.level === 'info',
140-
),
141-
);
74+
assertRecoveredPrepareResult(result);
75+
assertBadCacheRecoverySideEffects(fixtures);
76+
assertRecoveredPrepareDiagnostics();
14277
});
14378

14479
test('prepareIosRunner invalidates rebuilt sessions when bad-cache recovery health fails', async () => {
@@ -715,6 +650,89 @@ test('mutating commands invalidate the retry session without replaying again', a
715650
});
716651
});
717652

653+
function makeBadCacheRecoveryFixtures() {
654+
const restoredArtifact = makeRunnerArtifact({
655+
xctestrunPath: '/tmp/restored.xctestrun',
656+
cache: 'exact',
657+
artifact: 'valid',
658+
});
659+
const rebuiltArtifact = makeRunnerArtifact({
660+
xctestrunPath: '/tmp/rebuilt.xctestrun',
661+
cache: 'miss',
662+
artifact: 'rebuilt',
663+
buildMs: 123,
664+
});
665+
const restoredSession = makeRunnerSession({
666+
port: 8100,
667+
xctestrunPath: restoredArtifact.xctestrunPath,
668+
xctestrunArtifact: restoredArtifact,
669+
});
670+
const rebuiltSession = makeRunnerSession({
671+
port: 8101,
672+
xctestrunPath: rebuiltArtifact.xctestrunPath,
673+
xctestrunArtifact: rebuiltArtifact,
674+
});
675+
676+
return { restoredArtifact, restoredSession, rebuiltSession };
677+
}
678+
679+
function assertRecoveredPrepareResult(result: Awaited<ReturnType<typeof prepareIosRunner>>): void {
680+
assert.deepEqual(result, {
681+
runner: { uptimeMs: 42 },
682+
cache: 'miss',
683+
artifact: 'rebuilt',
684+
buildMs: 123,
685+
connectMs: result.connectMs,
686+
healthCheckMs: result.healthCheckMs,
687+
xctestrunPath: '/tmp/rebuilt.xctestrun',
688+
recoveryReason: 'Runner did not accept connection',
689+
});
690+
assert.equal(result.failureReason, undefined);
691+
assert.equal(result.connectMs >= 0, true);
692+
assert.equal(result.healthCheckMs >= 0, true);
693+
}
694+
695+
function assertBadCacheRecoverySideEffects(
696+
fixtures: ReturnType<typeof makeBadCacheRecoveryFixtures>,
697+
): void {
698+
assert.deepEqual(mockInvalidateRunnerSession.mock.calls[0], [
699+
fixtures.restoredSession,
700+
'prepare_cached_runner_health_failed',
701+
]);
702+
assert.deepEqual(mockMarkRunnerXctestrunArtifactBadForRun.mock.calls[0], [
703+
fixtures.restoredArtifact,
704+
'Runner did not accept connection',
705+
]);
706+
assert.deepEqual(mockEnsureRunnerSession.mock.calls[1]?.[1], {
707+
healthTimeoutMs: 90_000,
708+
buildTimeoutMs: 300_000,
709+
cleanStaleBundles: true,
710+
forceRunnerXctestrunRebuild: true,
711+
});
712+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls.length, 2);
713+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[0]?.[2].command, 'uptime');
714+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[0]?.[4], 90_000);
715+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[1]?.[1], fixtures.rebuiltSession);
716+
}
717+
718+
function assertRecoveredPrepareDiagnostics(): void {
719+
assert.ok(
720+
mockEmitDiagnostic.mock.calls.some(
721+
([event]) => event.phase === 'ios_runner_prepare_bad_cache_recovered',
722+
),
723+
);
724+
const prepareDiagnostic = mockEmitDiagnostic.mock.calls.find(
725+
([event]) => event.phase === 'apple_runner_prepare',
726+
)?.[0];
727+
assert.ok(prepareDiagnostic);
728+
assert.equal(prepareDiagnostic.level, 'info');
729+
assert.equal(prepareDiagnostic.data?.cache, 'miss');
730+
assert.equal(prepareDiagnostic.data?.artifact, 'rebuilt');
731+
assert.equal(prepareDiagnostic.data?.xctestrunPath, '/tmp/rebuilt.xctestrun');
732+
assert.equal(prepareDiagnostic.data?.recoveryReason, 'Runner did not accept connection');
733+
assert.equal(prepareDiagnostic.data?.failureReason, undefined);
734+
}
735+
718736
function assertDiagnosticDecision(expected: {
719737
decision: 'skipped' | 'retained';
720738
reason: string;

0 commit comments

Comments
 (0)