fix(windows-seed): record slow Windows files in full instead of at the 6-minute deadline

The first Windows recording on eca247e99 (run 39008249142) killed
test/gstack-doctor.test.ts at the 360 s per-file deadline and would have
seeded it at 360 s, although it takes about 484 s on Windows. --record-durations
now honors an explicit --wall-timeout as its per-file deadline, and the
windows-record-durations job passes --wall-timeout 1200 (inside its 30-minute
job limit). The shard job's 15-minute timeout and the shard count are unchanged.

The recording job also uploads its full per-file logs, so a file that fails
while recording (browse/test/cookie-import-native-job.test.ts did in that run)
can be diagnosed.

Intentional pin change: test/windows-native-workflows.test.ts now expects
the --wall-timeout 1200 recording command and the log upload step.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-17 06:13:26 +00:00
1 parent eca247e99a
commit 3115004917
4 files changed
+33 -5

No files matched your search

+11 -3
View File
@@ -1707,13 +1707,21 @@ export function exitCodeFor(status: FreeShardStatus): number {
return status === 'timed-out' ? 124 : 1;
}
/** Per-file deadline for `--record-durations`: an explicit --wall-timeout, else the one-file default. */
export function recordingWallTimeoutMs(options: Pick<CliOptions, 'wallTimeoutExplicit' | 'wallTimeoutMs'>): number {
return options.wallTimeoutExplicit ? options.wallTimeoutMs : wallTimeoutForShard(1);
}
/**
* `--record-durations`: time every file in its own child (exact per-file wall,
* immune to bun's stream buffering) and write the committed seed atomically.
* Uses the same isolated, strictly classified children as a normal run.
* Run against an immutable checkout; never time while editing its inputs.
* An explicit --wall-timeout sets the per-file deadline, so a file slower than
* the default deadline is timed in full instead of being killed and recorded
* at the deadline.
*/
async function recordFreeTestDurations(files: string[], jobs: number): Promise<number> {
async function recordFreeTestDurations(files: string[], jobs: number, wallTimeoutMs: number): Promise<number> {
const durations: Record<string, number> = {};
const failed: string[] = [];
const expectedCount = files.length;
@@ -1722,7 +1730,7 @@ async function recordFreeTestDurations(files: string[], jobs: number): Promise<n
// As in full-suite mode, finish parallel work before exclusive host-state fixtures.
await forEachFileAlone(files.filter(file => !(file in TREE_MUTATING)), files.filter(file => file in TREE_MUTATING), jobs, async (file, index) => {
const outcome = await runFreeShard([file], index + 1, files.length, {
wallTimeoutMs: wallTimeoutForShard(1), quiet: true, homeGuard: sharedFreeHome,
wallTimeoutMs, quiet: true, homeGuard: sharedFreeHome,
});
durations[normalizeRelativePath(file)] = outcome.elapsedMs;
if (outcome.status !== 'passed') failed.push(file);
@@ -1907,7 +1915,7 @@ async function main(): Promise<number> {
}
if (options.recordDurations) {
return recordFreeTestDurations(files, fullSuiteJobs());
return recordFreeTestDurations(files, fullSuiteJobs(), recordingWallTimeoutMs(options));
}
if (options.attributeHome) return attributeFreeHomeWriters(files.filter(file => !(file in TREE_MUTATING)), files.filter(file => file in TREE_MUTATING),
fullSuiteJobs(), (file, index, homeGuard) => runFreeShard([file], index + 1, files.length, { wallTimeoutMs: wallTimeoutForShard(1), quiet: true, log: () => {}, homeGuard }));