diff --git a/package.json b/package.json index c43a3759..1f88aa82 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,15 @@ "lint:colors": "npm run check:raw-hex", "test": "npm run test:unit", "test:fast": "npm run test:unit", - "test:unit": "TEST_BUDGET_SUITE=unit TEST_BUDGET_MS=55000 LOG_LEVEL=warn vitest run --project=unit-client --project=unit-node --reporter=default --reporter=./scripts/test-budget-reporter.mjs", - "test:related": "TEST_BUDGET_SUITE=related TEST_BUDGET_MS=15000 LOG_LEVEL=warn vitest related --run --project=unit-client --project=unit-node --reporter=default --reporter=./scripts/test-budget-reporter.mjs", + "test:unit": "TEST_BUDGET_SUITE=unit TEST_BUDGET_MS=55000 LOG_LEVEL=warn vitest run --project=unit-client --project=unit-node --project=unit-node-http --reporter=default --reporter=./scripts/test-budget-reporter.mjs", + "test:related": "TEST_BUDGET_SUITE=related TEST_BUDGET_MS=15000 LOG_LEVEL=warn vitest related --run --project=unit-client --project=unit-node --project=unit-node-http --reporter=default --reporter=./scripts/test-budget-reporter.mjs", "test:integration": "TEST_BUDGET_SUITE=integration-toolchain TEST_BUDGET_MS=120000 LOG_LEVEL=warn vitest run --project=integration-toolchain --reporter=default --reporter=./scripts/test-budget-reporter.mjs", "test:docker": "TEST_BUDGET_SUITE=integration-docker TEST_BUDGET_MS=180000 FORCE_DOCKER=1 DOCKER_SANDBOX_IMAGE=unosim-sandbox:latest SKIP_HEAVY_TESTS=false LOG_LEVEL=warn vitest run --project=integration-docker --reporter=default --reporter=./scripts/test-budget-reporter.mjs", - "test:security:inputs": "TEST_BUDGET_SUITE=security-inputs TEST_BUDGET_MS=15000 LOG_LEVEL=warn vitest run --project=unit-node tests/shared/input-limits.test.ts tests/shared/websocket-direction-schemas.test.ts tests/server/security/safe-paths.test.ts tests/server/routes/compiler.routes.test.ts tests/integration/simulation-state-sequence.test.ts --reporter=default --reporter=./scripts/test-budget-reporter.mjs", + "test:security:inputs": "TEST_BUDGET_SUITE=security-inputs TEST_BUDGET_MS=15000 LOG_LEVEL=warn vitest run --project=unit-node --project=unit-node-http tests/shared/input-limits.test.ts tests/shared/websocket-direction-schemas.test.ts tests/server/security/safe-paths.test.ts tests/server/routes/compiler.routes.test.ts tests/integration/simulation-state-sequence.test.ts --reporter=default --reporter=./scripts/test-budget-reporter.mjs", "test:all": "npm run test:unit && npm run test:integration && npm run test:docker", - "test:watch": "LOG_LEVEL=info vitest --project=unit-client --project=unit-node", - "test:coverage": "node scripts/coverage-guard.mjs prepare && TEST_BUDGET_SUITE=unit-coverage TEST_BUDGET_WARN_MS=60000 TEST_BUDGET_FAIL_MS=70000 LOG_LEVEL=warn vitest run --coverage --project=unit-client --project=unit-node --reporter=default --reporter=./scripts/test-budget-reporter.mjs && node scripts/coverage-guard.mjs validate", - "test:debug": "LOG_LEVEL=debug vitest run --project=unit-client --project=unit-node", + "test:watch": "LOG_LEVEL=info vitest --project=unit-client --project=unit-node --project=unit-node-http", + "test:coverage": "node scripts/coverage-guard.mjs prepare && TEST_BUDGET_SUITE=unit-coverage TEST_BUDGET_WARN_MS=60000 TEST_BUDGET_FAIL_MS=70000 LOG_LEVEL=warn vitest run --coverage --project=unit-client --project=unit-node --project=unit-node-http --reporter=default --reporter=./scripts/test-budget-reporter.mjs && node scripts/coverage-guard.mjs validate", + "test:debug": "LOG_LEVEL=debug vitest run --project=unit-client --project=unit-node --project=unit-node-http", "test:ci": "npm run test:unit", "test:e2e": "ARDUINO_CACHE_DIR=./server/arduino-cache playwright test", "test:e2e:ci": "ARDUINO_CACHE_DIR=./server/arduino-cache playwright test && ./check-leaks.sh --cleanup", diff --git a/vitest.config.ts b/vitest.config.ts index 8089350f..54c285c5 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,6 +11,27 @@ process.env.NODE_ENV = "test"; const __dirname = path.resolve(); +// These tests open real local HTTP listeners; parallel file execution has +// caused sporadic ECONNRESET and 30-second HTTP timeouts despite stable +// isolated runs, so keep only this group serial. +const serializedHttpUnitTests = [ + "tests/server/cache-optimization.test.ts", + "tests/server/cli-label-isolation.test.ts", + "tests/server/routes/compiler.routes.test.ts", + "tests/server/routes/examples.routes.test.ts", + "tests/server/routes/routes-core.test.ts", + "tests/server/routes/server-status-observability.test.ts", + "tests/server/routes/server-status.test.ts", + "tests/server/routes/simulation-admission.test.ts", + "tests/server/routes/simulation-start-readiness.test.ts", + "tests/server/routes/test-reset.routes.test.ts", + "tests/server/routes/tutor.routes.test.ts", + "tests/server/routes/websocket-lifecycle-handlers.test.ts", + "tests/server/security/access-control.test.ts", + "tests/server/services/protocol-version.test.ts", + "tests/integration/simulation-state-sequence.test.ts", +] as const; + export default defineConfig({ plugins: [tsconfigPaths()], resolve: { @@ -87,11 +108,23 @@ export default defineConfig({ "tests/integration/docker-security-contract.test.ts", "tests/server/telemetry-heartbeat-integration.test.ts", "tests/core/sandbox-stress.test.ts", + ...serializedHttpUnitTests, ], environment: "node", setupFiles: ["./tests/setup.node.ts"], }, }, + { + extends: true, + test: { + name: "unit-node-http", + include: [...serializedHttpUnitTests], + environment: "node", + setupFiles: ["./tests/setup.node.ts"], + fileParallelism: false, + maxWorkers: 1, + }, + }, { extends: true, test: {