/** * PR-D Production Check — Architecture Test * * Run: node --test test/architecture/production-check.test.mjs * * Tests: * 1. production-check.sh file exists * 2. production-check.sh is executable * 3. smoke-test.mjs file exists * 4. package.json contains production-check script * 5. Smoke test runs independently * 6. production-check runs end-to-end and exits 0 */ import { describe, it, before } from "node:test"; import assert from "node:assert"; import { existsSync, statSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { execSync, spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; const __dirname = join(fileURLToPath(import.meta.url), "..", "..", ".."); const ROOT = __dirname; const SCRIPTS = join(ROOT, "scripts"); // ─── Helpers ────────────────────────────────────────── function isExecutable(path) { try { const mode = statSync(path).mode; // Check owner execute bit return (mode & 0o100) !== 0; } catch { return false; } } // ─── Tests ──────────────────────────────────────────── describe("PR-D: Production Check Architecture", () => { // Test 1 it("production-check.sh file exists", () => { const path = join(SCRIPTS, "production-check.sh"); assert.ok(existsSync(path), `Missing: ${path}`); }); // Test 2 it("production-check.sh is executable", () => { const path = join(SCRIPTS, "production-check.sh"); assert.ok(existsSync(path), `Missing: ${path}`); assert.ok(isExecutable(path), `Not executable: ${path}. Run: chmod +x ${path}`); }); // Test 3 it("smoke-test.mjs file exists", () => { const path = join(SCRIPTS, "smoke-test.mjs"); assert.ok(existsSync(path), `Missing: ${path}`); }); // Test 4 it("package.json contains production-check, smoke, check:deprecations, test:baseline, guard scripts", () => { const pkg = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8")); const scripts = pkg.scripts || {}; assert.ok(typeof scripts["production-check"] === "string", "Missing scripts.production-check in package.json"); assert.ok(typeof scripts["smoke"] === "string", "Missing scripts.smoke in package.json"); assert.ok(typeof scripts["check:deprecations"] === "string", "Missing scripts.check:deprecations in package.json"); assert.ok(typeof scripts["test:baseline"] === "string", "Missing scripts.test:baseline in package.json"); assert.ok(typeof scripts["guard"] === "string", "Missing scripts.guard in package.json"); }); // Test 5 it("smoke test runs independently and exits 0", { timeout: 30000 }, () => { const script = join(SCRIPTS, "smoke-test.mjs"); const result = spawnSync("node", [script], { cwd: ROOT, encoding: "utf8", timeout: 25000, maxBuffer: 1024 * 1024, }); const output = result.stdout + result.stderr; console.log(output.slice(-800)); assert.equal(result.status, 0, `Smoke test failed (exit ${result.status}):\n${output.slice(-500)}`); assert.ok(output.includes("Smoke test PASSED") || output.includes("PASS"), `Expected "Smoke test PASSED" in output:\n${output.slice(-300)}`); }); // Test 6 it("production-check runs end-to-end and exits 0", { timeout: 120000 }, () => { const script = join(SCRIPTS, "production-check.sh"); const result = spawnSync("bash", [script], { cwd: ROOT, encoding: "utf8", timeout: 110000, maxBuffer: 2 * 1024 * 1024, }); const output = result.stdout + result.stderr; console.log(output.slice(-1200)); assert.equal(result.status, 0, `Production check failed (exit ${result.status}):\n${output.slice(-800)}`); // Verify all 6 steps ran const steps = [ "Step 1: Environment Check", "Step 2: Baseline Tests", "Step 3: Architecture Guards", "Step 4: Deprecation Check", "Step 5: Smoke Test", "Step 6: Summary Report", ]; for (const step of steps) { assert.ok(output.includes(step), `Missing step in output: "${step}"`); } assert.ok(output.includes("Overall:"), "Missing Overall summary"); assert.ok(output.includes("Duration:"), "Missing Duration in summary"); }); });