Skip to content

Commit e3c44ea

Browse files
authored
test(vitest): retire the subprocess-stub kill-criterion experiment (#2255)
* test(vitest): record the subprocess-stub kill-criterion outcome #1823's kill criterion was met (~64 consecutive genuine Coverage-job completions since dbc4f2f with zero timeout-shaped failures), so the subprocess-stub project is gone for good rather than mid-experiment. Rewrite the vitest.config.ts comments to state that resolved outcome instead of framing it as an ongoing revert-on-first-failure trial. * test: remove retired subprocess project traces * test: model the active fuzz worker project
1 parent fbf914b commit e3c44ea

5 files changed

Lines changed: 31 additions & 37 deletions

File tree

scripts/gate/model.test.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const model = loadModel(repoRoot, tracked);
2222

2323
const scriptModel = (scripts: Record<string, string>) => ({
2424
scripts,
25-
vitestProjects: ['unit-core', 'subprocess-stub'],
25+
vitestProjects: ['unit-core', 'fuzz-worker'],
2626
opaque: {},
2727
});
2828

@@ -61,31 +61,29 @@ test('a filtered Vitest run does not credit the whole project', () => {
6161
test('a bare Vitest run spans every configured project', () => {
6262
assert.deepEqual(scriptUnits('all', scriptModel({ all: 'vitest run --coverage' })), [
6363
'vitest:unit-core',
64-
'vitest:subprocess-stub',
64+
'vitest:fuzz-worker',
6565
]);
6666
});
6767

6868
test('a negated --project subtracts from the configured set, so the skipped one is not credited', () => {
6969
assert.deepEqual(
70-
scriptUnits('cov', scriptModel({ cov: 'vitest run --coverage --project=!subprocess-stub' })),
70+
scriptUnits('cov', scriptModel({ cov: 'vitest run --coverage --project=!fuzz-worker' })),
7171
['vitest:unit-core'],
7272
);
7373
});
7474

75-
// The real `test:coverage:ci` shape: a negated `--project` leg, then a second leg that is a
76-
// nested script. Both indirections have to survive, or the lane stops owning the project it
77-
// hands to that leg.
78-
test('the two halves of test:coverage:ci together still own every project', () => {
75+
// A negated `--project` leg followed by a nested script must preserve both
76+
// indirections, or the lane stops owning the project handed to that leg.
77+
test('split coverage commands together still own every project', () => {
7978
assert.deepEqual(
8079
scriptUnits(
8180
'test:coverage:ci',
8281
scriptModel({
83-
'test:coverage:ci':
84-
'vitest run --coverage --project=!subprocess-stub && pnpm test:subprocess-stub',
85-
'test:subprocess-stub': 'vitest run --project subprocess-stub',
82+
'test:coverage:ci': 'vitest run --coverage --project=!fuzz-worker && pnpm test:fuzz-worker',
83+
'test:fuzz-worker': 'vitest run --project fuzz-worker',
8684
}),
8785
),
88-
['vitest:unit-core', 'vitest:subprocess-stub'],
86+
['vitest:unit-core', 'vitest:fuzz-worker'],
8987
);
9088
});
9189

scripts/mutation/test-scope.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// own static module graph.
1010
//
1111
// Two files are removed from whatever Vitest returns:
12-
// - the real-subprocess-spawn tests (SUBPROCESS_STUB_TESTS in vitest.config.ts —
12+
// - the real-subprocess-spawn tests (MUTATION_EXCLUDED_TESTS in vitest.config.ts —
1313
// spawns stubbed binaries and waits real subprocess/retry/poll time, out of scope
1414
// by the issue's constraint, and thousands of mutant runs would turn it into
1515
// timeout noise regardless of whether Vitest itself still serializes it, #1823);

src/__tests__/test-utils/fake-adb.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ export type FakeAdbProviderExtras = AndroidAdbProvider extends infer P
3737
* production {@link withAndroidAdbProvider} scope — the same seam the daemon
3838
* installs per request and the provider-scenario lane exercises. Prefer this
3939
* over PATH-stub subprocess helpers (`withMockedAdb`): no PATH
40-
* mutation, no spawns, no real subprocess waits, so converted files can leave
41-
* SUBPROCESS_STUB_TESTS in vitest.config.ts (#1823).
40+
* mutation, no spawns, no real subprocess waits, so converted files do not need a
41+
* mutation exclusion in vitest.config.ts.
4242
*
4343
* The fake `exec` receives device-scoped args without a leading
4444
* `-s <serial>`: scoped providers are per-device, and raw `runCmd('adb', …)`

vitest.config.ts

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,9 @@ import { defineConfig } from 'vitest/config';
22
import { resolveVitestMaxWorkers } from './scripts/lib/vitest-concurrency.ts';
33
import slowTestGateReporter from './scripts/vitest-slow-test-reporter.ts';
44

5-
// Files that spawn a real subprocess per case. They used to run one at a time in
6-
// their own serialized `subprocess-stub` project so broad file parallelism couldn't
7-
// starve a spawn past its internal budget and turn it into a generic timeout.
8-
// #1823 is now running that project's own kill criterion: un-serialized here in
9-
// `unit-core`'s default forks pool, watched for 20 consecutive CI runs with no
10-
// timeout-shaped failure. Revert (restore the project, restore this list to
11-
// unit-core's exclude) the moment one appears. Still excluded from the mutation
12-
// lane via SERIALIZED_TESTS below regardless of this experiment's outcome —
13-
// thousands of mutant reruns times a real spawn per case is timeout noise either way.
14-
const SUBPROCESS_STUB_TESTS: readonly string[] = [
5+
// A real per-case spawn is timeout noise under thousands of mutant reruns, so the
6+
// mutation lane excludes these tests even though the unit lane runs them normally.
7+
const MUTATION_EXCLUDED_SUBPROCESS_TESTS: readonly string[] = [
158
// Stubs npx plus the package managers and spawns a real Metro dev server per case.
169
'src/__tests__/client-metro.test.ts',
1710
// The SUT is the subprocess watchdog: a node subprocess per case, one hangs on purpose (#1414).
@@ -56,13 +49,14 @@ const FUZZ_WORKER_TESTS: readonly string[] = [
5649
'scripts/fuzz/corpus-replay.test.ts',
5750
];
5851
/**
59-
* Every test the mutation lane must not collect: a real per-case subprocess spawn is
60-
* timeout noise under thousands of mutant reruns, independent of whether Vitest also
61-
* serializes it — `fuzz-worker` still does; `subprocess-stub`'s former members no
62-
* longer do (#1823). The two lists above stay module-local: this union is the whole
63-
* cross-file surface, and the mutation lane wants exactly it.
52+
* Every test the mutation lane must not collect. The two lists above stay
53+
* module-local: this union is the whole cross-file surface, and the mutation lane
54+
* wants exactly it.
6455
*/
65-
export const SERIALIZED_TESTS: readonly string[] = [...SUBPROCESS_STUB_TESTS, ...FUZZ_WORKER_TESTS];
56+
export const MUTATION_EXCLUDED_TESTS: readonly string[] = [
57+
...MUTATION_EXCLUDED_SUBPROCESS_TESTS,
58+
...FUZZ_WORKER_TESTS,
59+
];
6660

6761
// Imported by vitest.mutation.config.ts so the two lanes cannot drift: a guard
6862
// added here must reach the Stryker sandbox too.
@@ -105,9 +99,8 @@ export default defineConfig({
10599
include: [
106100
'src/**/*.test.ts',
107101
'packages/*/src/**/*.test.ts',
108-
// The subprocess watchdog self-check (#1823): spawns a real node subprocess per
109-
// case, one hangs on purpose (#1414). Formerly a `subprocess-stub` member; see
110-
// SUBPROCESS_STUB_TESTS above for the kill-criterion experiment this rides.
102+
// The subprocess watchdog self-check: spawns a real node subprocess per case,
103+
// and one hangs on purpose (#1414).
111104
'scripts/fuzz/harness.test.ts',
112105
// The validation fuzz generators' expectation gates (#1781 B2): in-process, no
113106
// subprocess or worker, so they ride the fast lane unlike their serialized siblings.
@@ -198,8 +191,7 @@ export default defineConfig({
198191
},
199192
{
200193
test: {
201-
// Serialized for the same contention reason `subprocess-stub` used to be (#1823):
202-
// the per-case watchdog budget is real wall clock. The project exists so the
194+
// Serialized because the per-case watchdog budget is real wall clock. The project exists so the
203195
// coverage run can leave it out (see the comment above), not to run it differently.
204196
name: 'fuzz-worker',
205197
include: [...FUZZ_WORKER_TESTS],

vitest.mutation.config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url';
33
import { defineConfig } from 'vitest/config';
44
import { readTestScope, threadHostileTestFiles } from './scripts/mutation/test-scope.ts';
55
import { workspaceSourceAliases } from './scripts/mutation/workspace-aliases.ts';
6-
import { SERIALIZED_TESTS, SETUP_FILES } from './vitest.config.ts';
6+
import { MUTATION_EXCLUDED_TESTS, SETUP_FILES } from './vitest.config.ts';
77

88
const repoRoot = path.dirname(fileURLToPath(import.meta.url));
99

@@ -21,7 +21,11 @@ export default defineConfig({
2121
},
2222
test: {
2323
include: scope ?? ['src/**/*.test.ts', 'packages/*/src/**/*.test.ts'],
24-
exclude: [...SERIALIZED_TESTS, ...threadHostileTestFiles(repoRoot), '**/node_modules/**'],
24+
exclude: [
25+
...MUTATION_EXCLUDED_TESTS,
26+
...threadHostileTestFiles(repoRoot),
27+
'**/node_modules/**',
28+
],
2529
setupFiles: [...SETUP_FILES],
2630
},
2731
});

0 commit comments

Comments
 (0)