From 5df8412508bd9d1b15aea3e7567041f53cad910c Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 04:34:08 +0100 Subject: [PATCH] fix(test): extend no-output watchdog to sharded vitest runs --- scripts/run-vitest.mjs | 2 +- scripts/test-projects.mjs | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/scripts/run-vitest.mjs b/scripts/run-vitest.mjs index d0c30341556..23254e47928 100644 --- a/scripts/run-vitest.mjs +++ b/scripts/run-vitest.mjs @@ -134,7 +134,7 @@ export function installVitestNoOutputWatchdog(params) { }; } -function forwardVitestOutput(stream, target, shouldSuppressLine = () => false) { +export function forwardVitestOutput(stream, target, shouldSuppressLine = () => false) { if (!stream) { return; } diff --git a/scripts/test-projects.mjs b/scripts/test-projects.mjs index 24d9c5c2a48..ee14f1cfd2b 100644 --- a/scripts/test-projects.mjs +++ b/scripts/test-projects.mjs @@ -1,7 +1,14 @@ import fs from "node:fs"; import { acquireLocalHeavyCheckLockSync } from "./lib/local-heavy-check-runtime.mjs"; import { spawnPnpmRunner } from "./pnpm-runner.mjs"; -import { resolveVitestCliEntry, resolveVitestNodeArgs } from "./run-vitest.mjs"; +import { + forwardVitestOutput, + installVitestNoOutputWatchdog, + resolveVitestCliEntry, + resolveVitestNodeArgs, + resolveVitestNoOutputTimeoutMs, + shouldSuppressVitestStderrLine, +} from "./run-vitest.mjs"; import { applyParallelVitestCachePaths, buildFullSuiteVitestRunPlans, @@ -12,6 +19,7 @@ import { writeVitestIncludeFile, } from "./test-projects.test-support.mjs"; import { + forwardSignalToVitestProcessGroup, installVitestProcessGroupCleanup, shouldUseDetachedVitestProcessGroup, } from "./vitest-process-group.mjs"; @@ -106,17 +114,36 @@ function runVitestSpec(spec) { detached: shouldUseDetachedVitestProcessGroup(), pnpmArgs: spec.pnpmArgs, env: spec.env, + stdio: ["inherit", "pipe", "pipe"], }); const teardownChildCleanup = installVitestProcessGroupCleanup({ child }); + const teardownNoOutputWatchdog = installVitestNoOutputWatchdog({ + streams: [child.stdout, child.stderr], + timeoutMs: resolveVitestNoOutputTimeoutMs(spec.env), + log: (message) => { + console.error(message); + }, + onTimeout: () => { + forwardSignalToVitestProcessGroup({ child, signal: "SIGTERM" }); + }, + onForceKill: () => { + forwardSignalToVitestProcessGroup({ child, signal: "SIGKILL" }); + }, + }); + + forwardVitestOutput(child.stdout, process.stdout); + forwardVitestOutput(child.stderr, process.stderr, shouldSuppressVitestStderrLine); child.on("exit", (code, signal) => { teardownChildCleanup(); + teardownNoOutputWatchdog(); cleanupVitestRunSpec(spec); resolve({ code: code ?? 1, signal }); }); child.on("error", (error) => { teardownChildCleanup(); + teardownNoOutputWatchdog(); cleanupVitestRunSpec(spec); reject(error); });