Files
FreeCADWasmDev/tools/run_p6_import_persistence.mjs
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

87 lines
3.9 KiB
JavaScript

import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { execFileSync } from "node:child_process";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
const sourceRoot = path.join(root, "freecad-source");
const bin = path.join(sourceRoot, "build-web/configure/bin");
const smoke = path.join(sourceRoot, "src/WebAssembly/FreeCADCoreProbe/import-runtime-smoke.js");
const dist = path.join(root, "web/dist");
const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
function replay() {
const output = execFileSync(process.execPath, [smoke, bin], { encoding: "utf8" }).trim();
const result = JSON.parse(output.split("\n").at(-1));
return {
handle: result.importHandle,
summary: result.firstImport,
release: result.release,
activeAfterRelease: result.activeAfterRelease,
stateSha256: result.validSnapshotHash,
error: result.missingFileError,
stateAfterError: result.afterMissingSnapshot,
};
}
const first = replay();
const reopened = replay();
const html = fs.readFileSync(path.join(dist, "import.html"), "utf8");
const entryMatch = html.match(/src="(\/assets\/import-[^"]+\.js)"/);
const worker = fs.readdirSync(path.join(dist, "assets")).find((file) => /^import\.worker-[^.]+\.js$/.test(file));
if (!entryMatch || !worker) throw new Error("Import dist entry or worker asset is missing");
const artifacts = {
html: { path: "web/dist/import.html", sha256: sha256(path.join(dist, "import.html")) },
entry: { path: `web/dist${entryMatch[1]}`, sha256: sha256(path.join(dist, entryMatch[1])) },
worker: { path: `web/dist/assets/${worker}`, sha256: sha256(path.join(dist, "assets", worker)) },
js: { path: "web/dist/kernel/FreeCADWebImportRuntimeProbe.js", sha256: sha256(path.join(dist, "kernel/FreeCADWebImportRuntimeProbe.js")) },
wasm: { path: "web/dist/kernel/FreeCADWebImportRuntimeProbe.wasm", sha256: sha256(path.join(dist, "kernel/FreeCADWebImportRuntimeProbe.wasm")) },
};
assert.deepEqual(reopened.summary, first.summary);
assert.equal(first.handle, 1);
assert.equal(reopened.handle, 1);
assert.equal(first.release, 1);
assert.equal(reopened.release, 1);
assert.equal(first.activeAfterRelease, 0);
assert.equal(reopened.activeAfterRelease, 0);
assert.equal(first.stateSha256, reopened.stateSha256);
assert.deepEqual(first.stateAfterError, first.summary);
assert.equal(artifacts.js.sha256, sha256(path.join(bin, "FreeCADWebImportRuntimeProbe.js")));
assert.equal(artifacts.wasm.sha256, sha256(path.join(bin, "FreeCADWebImportRuntimeProbe.wasm")));
const report = {
schema: "freecad-web-p6-import-persistence/v1",
module: "Import",
action: "import/step",
result: "pass_boundary",
persistence: {
applicability: "not_applicable_current_action",
reason: "FCStd save/reopen is a separate declared Import action and is not claimed by the import/step first slice",
verification: "resource-manifest-and-fresh-runtime-replay",
},
fixture: {
path: "web/public/samples/freecad-sample.step",
sha256: sha256(path.join(root, "web/public/samples/freecad-sample.step")),
},
first,
reopened,
replayDeterministic: JSON.stringify(first.summary) === JSON.stringify(reopened.summary),
oldStatePreservedAfterError: JSON.stringify(first.summary) === JSON.stringify(first.stateAfterError),
artifacts,
sourceBacked: true,
};
fs.writeFileSync(path.join(root, "docs/p6/import-persistence.json"), `${JSON.stringify(report, null, 2)}\n`);
fs.writeFileSync(path.join(root, "docs/freecad-p6-import-g-persistence.log"), [
`result=${report.result}`,
`applicability=${report.persistence.applicability}`,
`fixtureSha256=${report.fixture.sha256}`,
`stateSha256=${first.stateSha256}`,
`replayDeterministic=${report.replayDeterministic}`,
`oldStatePreservedAfterError=${report.oldStatePreservedAfterError}`,
`wasmSha256=${artifacts.wasm.sha256}`,
"",
].join("\n"));
console.log(JSON.stringify(report));