90 lines
4.5 KiB
JavaScript
90 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 build = path.resolve(process.argv[2] ?? path.join(root, "freecad-source/build-web/configure/bin"));
|
|
const docs = path.join(root, "docs/p6");
|
|
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 call = (name, returnType = "number", argTypes = [], args = []) => kernel.ccall(name, returnType, argTypes, args);
|
|
const run = () => ({
|
|
initialize: call("fc_web_reverseengineering_initialize"),
|
|
initializationCalls: call("fc_web_reverseengineering_initialization_calls"),
|
|
initializationRuns: call("fc_web_reverseengineering_initialization_runs"),
|
|
moduleAvailable: call("fc_web_reverseengineering_module_available"),
|
|
error: call("fc_web_reverseengineering_error", "string")
|
|
});
|
|
|
|
const first = run();
|
|
const repeated = run();
|
|
const sourceEntry = "src/Mod/ReverseEngineering/App/AppReverseEngineering.cpp";
|
|
const apiValidation = call("fc_web_reverseengineering_python_api_validate", "number", ["string"], [sourceEntry]);
|
|
const apiExecution = call("fc_web_reverseengineering_python_api");
|
|
const second = run();
|
|
const invalidSource = call(
|
|
"fc_web_reverseengineering_python_api_validate",
|
|
"number",
|
|
["string"],
|
|
["src/Mod/ReverseEngineering/App/AppReverseEngineering.hxx"]
|
|
);
|
|
const invalidError = call("fc_web_reverseengineering_error", "string");
|
|
const semantic = value => ({
|
|
initialize: value.initialize,
|
|
initializationRuns: value.initializationRuns,
|
|
moduleAvailable: value.moduleAvailable,
|
|
error: value.error
|
|
});
|
|
const result = {
|
|
first,
|
|
repeated,
|
|
second,
|
|
apiValidation,
|
|
apiExecution,
|
|
apiNames: call("fc_web_reverseengineering_api_names", "string"),
|
|
apiCount: call("fc_web_reverseengineering_api_count"),
|
|
curveValid: call("fc_web_reverseengineering_curve_valid"),
|
|
invalidSource,
|
|
invalidError,
|
|
deterministic: JSON.stringify(semantic(first)) === JSON.stringify(semantic(second)),
|
|
pass: first.initialize === 1 && repeated.initialize === 1 && second.initialize === 1 &&
|
|
first.initializationRuns === 1 && repeated.initializationRuns === 1 && second.initializationRuns === 1 &&
|
|
repeated.initializationCalls === 2 && first.moduleAvailable === 1 && apiValidation === 1 &&
|
|
apiExecution === 1 && resultApiCountPlaceholder() && invalidSource === 0 &&
|
|
invalidError === "revision_mismatch"
|
|
};
|
|
|
|
function resultApiCountPlaceholder() {
|
|
return call("fc_web_reverseengineering_api_count") === 2 && call("fc_web_reverseengineering_curve_valid") === 1;
|
|
}
|
|
|
|
const wasmPath = path.join(build, "FreeCADWebReverseEngineeringRuntimeProbe.wasm");
|
|
const fixture = { module: "ReverseEngineering", sourceEntry, api: ["approxCurve", "approxSurface"] };
|
|
const hash = value => crypto.createHash("sha256").update(value).digest("hex");
|
|
const report = {
|
|
schema: "freecad-web-p6-reverseengineering-runtime/v1",
|
|
task_id: "FW-P6-REV-B-R1",
|
|
module: "ReverseEngineering",
|
|
status: result.pass && result.deterministic ? "pass" : "fail",
|
|
source_revision: "working-tree",
|
|
fixture: { ...fixture, input_sha256: hash(JSON.stringify(fixture)) },
|
|
result,
|
|
result_sha256: hash(JSON.stringify(result)),
|
|
artifacts: { wasm: { path: "freecad-source/build-web/configure/bin/FreeCADWebReverseEngineeringRuntimeProbe.wasm", sha256: hash(fs.readFileSync(wasmPath)) } },
|
|
boundaries: ["The Web target enables ReverseEngineering App only; ReverseEngineeringGui and PCL-only APIs remain outside this slice.", "The native probe registers Part and Mesh dependencies before the official ReverseEngineering Python module."]
|
|
};
|
|
fs.mkdirSync(docs, { recursive: true });
|
|
fs.writeFileSync(path.join(docs, "reverseengineering-runtime.json"), `${JSON.stringify(report, null, 2)}\n`);
|
|
fs.writeFileSync(path.join(root, "docs/freecad-p6-reverseengineering-b-runtime.log"), `${JSON.stringify({ status: report.status, initializationRuns: second.initializationRuns, apiCount: result.apiCount, invalidError })}\n`);
|
|
console.log(JSON.stringify({ status: report.status, initializationRuns: second.initializationRuns, apiCount: result.apiCount, apiExecution: result.apiExecution, invalidError }));
|
|
if (report.status !== "pass") process.exitCode = 1;
|