133 lines
4.4 KiB
JavaScript
133 lines
4.4 KiB
JavaScript
/**
|
|
* 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");
|
|
});
|
|
});
|