66 lines
4.5 KiB
JavaScript
66 lines
4.5 KiB
JavaScript
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, "FreeCADWebReverseEngineeringRuntimeProbe.js")));
|
|
const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm")), print: () => {}, printErr: () => {} });
|
|
const c = (name, type = "number", argTypes = [], args = []) => kernel.ccall(name, type, argTypes, args);
|
|
const entry = "src/Mod/ReverseEngineering/App/AppReverseEngineering.cpp";
|
|
const inspect = () => ({
|
|
returnCode: c("fc_web_reverseengineering_source_inventory_validate", "number", ["string"], [entry]),
|
|
sourceEntry: c("fc_web_reverseengineering_source_entry", "string"),
|
|
summary: c("fc_web_reverseengineering_source_summary", "string"),
|
|
registeredTypeCount: c("fc_web_reverseengineering_registered_type_count"),
|
|
pythonBindingCount: c("fc_web_reverseengineering_python_binding_count"),
|
|
pythonApiNames: c("fc_web_reverseengineering_api_names", "string"),
|
|
resourcesReleased: c("fc_web_reverseengineering_inventory_resources_released"),
|
|
error: c("fc_web_reverseengineering_error", "string")
|
|
});
|
|
const first = inspect();
|
|
const second = inspect();
|
|
const invalidEntry = "src/Mod/ReverseEngineering/App/Missing.cpp";
|
|
const rejected = {
|
|
returnCode: c("fc_web_reverseengineering_source_inventory_validate", "number", ["string"], [invalidEntry]),
|
|
error: c("fc_web_reverseengineering_error", "string")
|
|
};
|
|
const recovered = inspect();
|
|
const fixture = { module: "ReverseEngineering", action: "inspect/source-inventory", sourceEntry: entry, pythonBindingCount: 2 };
|
|
const hash = value => crypto.createHash("sha256").update(value).digest("hex");
|
|
const baselineHash = hash(JSON.stringify(first));
|
|
const recoveredHash = hash(JSON.stringify(recovered));
|
|
const result = {
|
|
first,
|
|
second,
|
|
rejected,
|
|
recovered,
|
|
deterministic: JSON.stringify(first) === JSON.stringify(second),
|
|
recoveryStable: baselineHash === recoveredHash,
|
|
pass: first.returnCode === 1 && second.returnCode === 1 && rejected.returnCode === 0 &&
|
|
rejected.error === "revision_mismatch" && recovered.returnCode === 1 &&
|
|
first.sourceEntry === entry && first.pythonBindingCount === 2 && first.resourcesReleased === 1
|
|
};
|
|
const wasmPath = path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm");
|
|
const report = {
|
|
schema: "freecad-web-p6-reverseengineering-action-02-kernel/v1",
|
|
taskId: "FW-P6-REV-ACT-02-C",
|
|
module: "ReverseEngineering",
|
|
action: "inspect/source-inventory",
|
|
fixture: { ...fixture, inputSha256: hash(JSON.stringify(fixture)) },
|
|
result: result.pass && result.deterministic && result.recoveryStable ? "pass" : "fail",
|
|
replay: { ...result, baselineSha256: baselineHash, recoveredSha256: recoveredHash, resultSha256: hash(JSON.stringify(result)) },
|
|
commands: ["ninja -C freecad-source/build-web/configure FreeCADWebReverseEngineeringRuntimeProbe -j8", "node tools/run_p6_reverseengineering_action02_kernel.mjs freecad-source/build-web/configure/bin"],
|
|
artifacts: { wasm: { path: "freecad-source/build-web/configure/bin/FreeCADWebReverseEngineeringRuntimeProbe.wasm", sha256: hash(fs.readFileSync(wasmPath)) }, workerLog: "docs/freecad-p6-reverseengineering-action-02-c-kernel.log" },
|
|
boundaries: ["ReverseEngineering App has no persistent DocumentObject registrations in this GUI-free slice; the inventory reports zero native object types and two Python bindings.", "PCL-only APIs and ReverseEngineeringGui remain outside this action."]
|
|
};
|
|
fs.writeFileSync(path.join(docs, "reverseengineering-action-02-kernel.json"), `${JSON.stringify(report, null, 2)}\n`);
|
|
fs.writeFileSync(path.join(root, "docs/freecad-p6-reverseengineering-action-02-c-kernel.log"), `${JSON.stringify({ result: report.result, deterministic: result.deterministic, recoveryStable: result.recoveryStable, pythonBindingCount: first.pythonBindingCount })}\n`);
|
|
console.log(JSON.stringify({ result: report.result, deterministic: result.deterministic, recoveryStable: result.recoveryStable, pythonBindingCount: first.pythonBindingCount }));
|
|
if (report.result !== "pass") process.exitCode = 1;
|