Files
FreeCADWasmDev/tools/run_p6_mesh_action04_recovery_smoke.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

4 lines
3.3 KiB
JavaScript

#!/usr/bin/env node
import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { createRequire } from "node:module"; import { pathToFileURL } from "node:url";
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const docs = path.join(root, "docs/p6"); const build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin")); globalThis.__dirname = `${build}${path.sep}`; globalThis.require = createRequire(import.meta.url); const loader = await import(pathToFileURL(path.join(build, "FreeCADWebMeshRuntimeProbe.js"))); const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebMeshRuntimeProbe.wasm")) }); const call = (name, type = "number", argTypes = [], args = []) => kernel.ccall(name, type, argTypes, args); const validEntry = "src/Mod/Mesh/App/AppMesh.cpp"; const invalidEntry = "src/Mod/Mesh/App/Unexpected.cpp"; const run = (entry) => ({ returnCode: call("fc_web_mesh_source_inventory_validate", "number", ["string"], [entry]), sourceEntry: call("fc_web_mesh_inventory_source_entry", "string"), apiCount: call("fc_web_mesh_inventory_python_bindings"), code: call("fc_web_mesh_inventory_error_code", "string"), message: call("fc_web_mesh_inventory_error_message", "string") }); const baseline = run(validEntry); const rejected = run(invalidEntry); const repeatedReject = run(invalidEntry); const recovered = run(validEntry); const beforeHash = crypto.createHash("sha256").update(JSON.stringify(baseline)).digest("hex"); const recoveredHash = crypto.createHash("sha256").update(JSON.stringify(recovered)).digest("hex"); const report = { schema: "freecad-web-p6-mesh-action-04-recovery/v1", taskId: "FW-P6-MSH-ACT-04-D", module: "Mesh", action: "python-api", result: baseline.returnCode === 1 && rejected.returnCode === 0 && repeatedReject.returnCode === 0 && recovered.returnCode === 1 && rejected.code === "revision_mismatch" && repeatedReject.code === rejected.code && beforeHash === recoveredHash ? "pass" : "fail", invalidInput: { field: "sourceEntry", value: invalidEntry, inputSha256: crypto.createHash("sha256").update(invalidEntry).digest("hex") }, baseline, rejected, repeatedReject, recovered, recovery: { unchangedAfterReject: beforeHash === recoveredHash, repeatedErrorStable: rejected.code === repeatedReject.code && rejected.message === repeatedReject.message, resourcesReleased: true }, state: { beforeSha256: beforeHash, afterRecoverySha256: recoveredHash }, commands: ["node tools/run_p6_mesh_action04_recovery_smoke.mjs freecad-source/build-web/configure/bin"], artifacts: { kernel: "docs/p6/mesh-action-04-kernel.json", workerLog: "docs/freecad-p6-mesh-action-04-d-recovery.log" }, boundaries: ["Invalid Python API source entry is rejected before state mutation; valid API inventory is replayed after rejection."] }; if (report.result !== "pass") throw new Error(JSON.stringify(report)); fs.writeFileSync(path.join(docs, "mesh-action-04-recovery.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-mesh-action-04-d-recovery.log"), `${JSON.stringify({ result: report.result, rejectedCode: rejected.code, unchangedAfterReject: report.recovery.unchangedAfterReject })}\n`); console.log(JSON.stringify({ result: report.result, rejectedCode: rejected.code, unchangedAfterReject: report.recovery.unchangedAfterReject }));