104 lines
3.8 KiB
JavaScript
104 lines
3.8 KiB
JavaScript
import fs from "node:fs";
|
|
import { spawnSync } from "node:child_process";
|
|
import {
|
|
evidencePath,
|
|
expectedEvidenceIdentity,
|
|
root,
|
|
sha256,
|
|
} from "./v1-acceptance-lib.mjs";
|
|
|
|
const { ledgerSha256, packageSha256, plan, toolSourceSha256 } = expectedEvidenceIdentity();
|
|
const basePort = Number.parseInt(process.env.WEB_ACCEPTANCE_PORT ?? "5400", 10);
|
|
if (!Number.isInteger(basePort) || basePort < 1024 || basePort > 65000 - plan.entries.length) {
|
|
throw new Error(`WEB_ACCEPTANCE_PORT must leave ${plan.entries.length} sequential ports available`);
|
|
}
|
|
|
|
function capture(command, args) {
|
|
const result = spawnSync(command, args, {
|
|
cwd: root,
|
|
encoding: "utf8",
|
|
env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
maxBuffer: 16 * 1024 * 1024,
|
|
});
|
|
return `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
|
|
}
|
|
|
|
const blenderBin = process.env.BLENDER_BIN ?? "build_blender_5.2.0/bin/blender";
|
|
const blenderArchiveSha256 = process.env.BLENDER_ARCHIVE_SHA256 ?? "";
|
|
if (blenderArchiveSha256 && !/^[a-f0-9]{64}$/.test(blenderArchiveSha256)) {
|
|
throw new Error("BLENDER_ARCHIVE_SHA256 must be a lowercase SHA-256");
|
|
}
|
|
const environment = {
|
|
node: process.version,
|
|
npm: capture("npm", ["--version"]).split(/\r?\n/)[0],
|
|
chromium: capture(process.env.CHROME_PATH ?? "google-chrome", ["--version"]).split(/\r?\n/)[0],
|
|
blenderBin: process.env.BLENDER_BIN ? "BLENDER_BIN" : blenderBin,
|
|
blenderExecutableSha256: fs.existsSync(blenderBin) ? sha256(fs.readFileSync(blenderBin)) : "unavailable",
|
|
blenderArchiveSha256: blenderArchiveSha256 || "unavailable",
|
|
blender: capture(blenderBin, [
|
|
"--background",
|
|
"--factory-startup",
|
|
"--python-expr",
|
|
"import bpy; print('ACCEPTANCE_BLENDER=' + bpy.app.version_string + ';USD=' + str(bpy.app.build_options.usd))",
|
|
]).split(/\r?\n/).filter((line) => line.includes("ACCEPTANCE_BLENDER=")).at(-1) ?? "unavailable",
|
|
};
|
|
|
|
const results = [];
|
|
for (const [index, entry] of plan.entries.entries()) {
|
|
const started = Date.now();
|
|
process.stdout.write(`[${index + 1}/${plan.entries.length}] ${entry.token}\n`);
|
|
const result = spawnSync("npm", ["--prefix", "web", "run", entry.script, ...entry.args], {
|
|
cwd: root,
|
|
encoding: "utf8",
|
|
env: {
|
|
...process.env,
|
|
FORCE_COLOR: "0",
|
|
NO_COLOR: "1",
|
|
WEB_TEST_PORT: String(basePort + index),
|
|
},
|
|
maxBuffer: 32 * 1024 * 1024,
|
|
});
|
|
const output = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
|
|
const storedOutput = output.slice(-4096) || `${entry.token} produced no output`;
|
|
const exitCode = result.status ?? 1;
|
|
results.push({
|
|
token: entry.token,
|
|
familyIds: entry.familyIds,
|
|
command: entry.command,
|
|
exitCode,
|
|
durationMs: Date.now() - started,
|
|
outputSha256: sha256(storedOutput),
|
|
output: storedOutput,
|
|
});
|
|
process.stdout.write(` exit=${exitCode} durationMs=${results.at(-1).durationMs}\n`);
|
|
}
|
|
|
|
const manifest = {
|
|
schemaVersion: 1,
|
|
source: "docs/status/parity-ledger.json",
|
|
sourceSha256: ledgerSha256,
|
|
package: "web/package.json",
|
|
packageSha256,
|
|
toolSourceSha256,
|
|
generatedAt: new Date().toISOString(),
|
|
environment,
|
|
summary: {
|
|
families: plan.familyCount,
|
|
declarations: plan.declarationCount,
|
|
unique: plan.uniqueCount,
|
|
passed: results.filter((result) => result.exitCode === 0).length,
|
|
failed: results.filter((result) => result.exitCode !== 0).length,
|
|
},
|
|
results,
|
|
};
|
|
fs.writeFileSync(evidencePath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
|
|
const failed = results.filter((result) => result.exitCode !== 0);
|
|
process.stdout.write(
|
|
`v1-acceptance-run-complete passed=${manifest.summary.passed} failed=${manifest.summary.failed} evidence=${evidencePath}\n`,
|
|
);
|
|
if (failed.length > 0) {
|
|
process.stderr.write(`failed acceptance: ${failed.map((result) => result.token).join(", ")}\n`);
|
|
process.exitCode = 1;
|
|
}
|