Files
deepseek-harness/vitest.snapshot.config.ts
T
Turtle ecdcc218b6 perf(test): run replay snapshot files in parallel
The snapshot config serialized all 13 files for every mode, but the
fixture-writing rationale only holds for record (real API quota per
scenario) and refresh (write-back harvests volatile values from
fixtures on disk). Replay — the keyless default and the CI mode — is
read-only with a unique temp dir per scenario subprocess, and the
suite factory already runs replay scenarios concurrently in-file.

Narrow the serialization to non-replay modes: pnpm test:snapshot drops
from ~49s to ~33s wall; record/refresh stay fully serial.
2026-08-04 13:25:28 +08:00

71 lines
3.2 KiB
TypeScript

import { availableParallelism } from 'node:os'
import tsconfigPaths from 'vite-tsconfig-paths'
import { defineConfig } from 'vitest/config'
import { vitestExecArgv } from './vitest.shared.ts'
const DEFAULT_SNAPSHOT_MAX_CONCURRENCY = 5
function positiveIntFromEnv(name: string, fallback: number): number {
const raw = process.env[name]
if (raw === undefined || raw === '') return fallback
const value = Number(raw)
if (!Number.isInteger(value) || value < 1) {
throw new Error(`${name} must be a positive integer, got ${JSON.stringify(raw)}`)
}
return value
}
const snapshotMaxConcurrency = positiveIntFromEnv(
'DSH_SNAPSHOT_MAX_CONCURRENCY',
Math.min(DEFAULT_SNAPSHOT_MAX_CONCURRENCY, availableParallelism()),
)
// Replay is the keyless default: boot real subprocess paths from recorded model responses and diff
// assembled requests, normalized protocol or transcript output, and persisted-log expected outputs.
// `record` calls the real API and updates fixtures and expected outputs; `refresh` replays committed scripts
// and updates current expected outputs. Replay/refresh never load `.env`; only record reads a key from the
// environment or root `.env`.
if (process.env.DSH_SNAPSHOT === 'record') {
try {
process.loadEnvFile(new URL('.env', import.meta.url).pathname)
} catch (error) {
// ENOENT (no .env) is fine — the key may already be in the environment.
// Surface any other failure rather than silently recording with wrong env.
if ((error as NodeJS.ErrnoException | null)?.code !== 'ENOENT') throw error
}
}
export default defineConfig({
// Same resolution note as vitest.config.ts: bare workspace names resolve
// through the tsconfig.base.json paths facade; the native option cannot do
// this (the root tsconfig is a solution file with no paths).
plugins: [tsconfigPaths({ projects: ['./tsconfig.base.json'] })],
test: {
execArgv: vitestExecArgv,
setupFiles: ['./scripts/test-invariants.ts'],
include: [
'scripts/**/*.snapshot.ts',
// The assembled Web snapshot executes generated client bundles; source
// mode remains the zero-build path, while lib mode requires a prior build.
...(process.env.DSH_EXAMPLE_MODE === 'lib' ? ['apps/web/tests/**/*.snapshot.ts'] : []),
'examples/*/tests/**/*.snapshot.ts',
// The shipped TUI's terminal-journey scenarios moved here with its config.
'apps/cli/tests/**/*.snapshot.ts',
'packages/sdk/*/tests/**/*.snapshot.ts',
'packages/ui/tui/tests/**/*.snapshot.ts',
],
// Each test boots a subprocess; give it room. Replay scenarios are
// read-only (unique temp dir and fixture set per subprocess), so replay
// runs the snapshot files in parallel and bounds in-file concurrency with
// the environment knob (value 1 restores serial replay on constrained
// machines). Record and refresh stay fully serial: record spends real API
// quota per scenario, and refresh write-back harvests volatile values from
// fixtures already on disk, so concurrent writers would corrupt goldens.
testTimeout: 120_000,
hookTimeout: 30_000,
fileParallelism: (process.env.DSH_SNAPSHOT || 'replay') === 'replay',
maxConcurrency: snapshotMaxConcurrency,
},
})