import path from "node:path"; import { loadWasmProbe } from "./wasm-probe-runtime.mjs"; const dir = path.resolve("freecad-source/build-web/cloud-configure-r2/bin"); let stage = "load"; const capabilityId = "Cloud:cloud.configureRecompute"; const persistenceCapabilityId = "Cloud:cloud.saveReopen"; let kernel; const cases = []; const persistenceCases = []; let activeCapabilityId = capabilityId; function recordAssertion(assertions, name, passed) { assertions.push({ name, passed }); if (!passed) throw new Error(name); } function finish(report, code) { kernel?.PThread?.terminateAllThreads(); process.stdout.write(`${JSON.stringify(report)}\n`, () => process.exit(code)); } try { stage = "select"; const selected = JSON.parse(process.env.FREECAD_BUSINESS_IDS ?? JSON.stringify([capabilityId])); if (!Array.isArray(selected) || !selected.every((id) => typeof id === "string")) { throw new Error("FREECAD_BUSINESS_IDS must be a JSON array of capability IDs"); } if (!selected.includes(capabilityId) && !selected.includes(persistenceCapabilityId)) { finish({ schema: "freecad-web-business-cases/v1", module: "Cloud", results: [] }, 0); } else { stage = "load"; const { kernel: k } = await loadWasmProbe(dir, "FreeCADWebCloudKernelProbe"); kernel = k; const s = (n) => String(k.ccall(n, "string")); const n = (n) => Number(k.ccall(n, "number")); const inputs = [ { url: "https://cloud.freecad.example", tokenAuth: "bearer", tokenSecret: "secret", tcpPort: "443", protocolVersion: "v1", region: "test" }, { url: "https://second.freecad.example", tokenAuth: "access", tokenSecret: "different-secret", tcpPort: "8443", protocolVersion: "4", region: "eu-west-1" }, ]; let documentName; for (const [index, input] of inputs.entries()) { if (!selected.includes(capabilityId)) break; stage = "configure"; const out = String(k.ccall("fc_web_cloud_configure", "string", ["string","string","string","string","string","string"], Object.values(input))); if (!out) throw new Error(`${s("fc_web_cloud_kernel_error_code")}: ${s("fc_web_cloud_kernel_error_message")}`); const configuration = Object.fromEntries(Object.entries({ url: "url", tokenAuth: "token_auth", tokenSecret: "token_secret", tcpPort: "tcp_port", protocolVersion: "protocol_version", region: "region" }).map(([field, suffix]) => [field, s(`fc_web_cloud_kernel_${suffix}`)])); const assertions = []; const businessCase = { name: `configure-and-recompute-${index + 1}`, input, assertions }; cases.push(businessCase); for (const [field, value] of Object.entries(input)) { recordAssertion(assertions, `Cloud configuration matches ${field}`, configuration[field] === value); } const result = { schema: "freecad-web-cloud/configure-recompute/v1", module: "Cloud", action: "configure/recompute", configuration: { ...configuration, setterCount: n("fc_web_cloud_kernel_setter_count") }, recompute: { count: n("fc_web_cloud_kernel_recompute_count"), hasError: n("fc_web_cloud_kernel_recompute_has_error"), summary: s("fc_web_cloud_kernel_recompute_summary") } }; businessCase.result = result; recordAssertion(assertions, "All six native setters completed", result.configuration.setterCount === 6); recordAssertion(assertions, "Native document recomputed", result.recompute.count >= 1); recordAssertion(assertions, "Native recompute has no error", result.recompute.hasError === 0); recordAssertion(assertions, "Active document is present and retained", Boolean(result.recompute.summary) && (documentName === undefined || result.recompute.summary === documentName)); documentName = result.recompute.summary; if (index === 0) { stage = "reject-null-url"; const rejected = k.ccall("fc_web_cloud_configure", "string", ["string","string","string","string","string","string"], [null, input.tokenAuth, input.tokenSecret, input.tcpPort, input.protocolVersion, input.region]); const code = s("fc_web_cloud_kernel_error_code"); const setters = n("fc_web_cloud_kernel_setter_count"); const recomputes = n("fc_web_cloud_kernel_recompute_count"); const rejectionAssertions = []; cases.push({ name: "reject-null-url", input: { ...input, url: null }, result: { rejected, code, setters, recomputes }, assertions: rejectionAssertions }); recordAssertion(rejectionAssertions, "Null URL returns no configuration", !rejected); recordAssertion(rejectionAssertions, "Null URL reports invalid_argument", code === "invalid_argument"); recordAssertion(rejectionAssertions, "Null URL invokes no setters", setters === 0); recordAssertion(rejectionAssertions, "Null URL invokes no recompute", recomputes === 0); } } const results = []; if (selected.includes(capabilityId)) results.push({ capabilityId, status: "passed", cases }); if (selected.includes(persistenceCapabilityId)) { activeCapabilityId = persistenceCapabilityId; for (const [index, input] of inputs.entries()) { stage = "save-reopen"; const assertions = []; const businessCase = { name: `save-reopen-current-configuration-${index + 1}`, input, assertions }; persistenceCases.push(businessCase); const configured = k.ccall("fc_web_cloud_configure", "string", ["string", "string", "string", "string", "string", "string"], Object.values(input)); recordAssertion(assertions, "User configuration initialized in WASM", Boolean(configured)); const activeDocument = s("fc_web_cloud_kernel_recompute_summary"); recordAssertion(assertions, "Current native document exists", Boolean(activeDocument)); const completed = n("fc_web_cloud_kernel_persistence_boundary"); const errorCode = s("fc_web_cloud_kernel_error_code"); const errorMessage = s("fc_web_cloud_kernel_error_message"); const before = s("fc_web_cloud_persistence_state_before"); const reason = s("fc_web_cloud_persistence_reason"); const saveAvailable = n("fc_web_cloud_persistence_save_available"); const restoreAvailable = n("fc_web_cloud_persistence_restore_available"); const documentCountBefore = n("fc_web_cloud_persistence_document_count_before"); const documentCountAfter = n("fc_web_cloud_persistence_document_count_after"); const replayEqual = n("fc_web_cloud_persistence_replay_equal"); const applicable = n("fc_web_cloud_persistence_applicable"); const configurationAfter = Object.fromEntries(Object.entries({ url: "url", tokenAuth: "token_auth", tokenSecret: "token_secret", tcpPort: "tcp_port", protocolVersion: "protocol_version", region: "region" }).map(([field, suffix]) => [field, s(`fc_web_cloud_kernel_${suffix}`)])); const persistenceAssert = (name, passed) => assertions.push({ name, passed }); persistenceAssert("Native persistence boundary completed without error", completed === 1 && !errorCode); persistenceAssert("Remote persistence requirement is reported", Boolean(reason)); persistenceAssert("Native configuration state was captured", before.length > 0); persistenceAssert("Cloud exposes callable Save and Restore", saveAvailable === 1 && restoreAvailable === 1); persistenceAssert("Persistence document counts remain unchanged", documentCountBefore === documentCountAfter); persistenceAssert("Rejected configuration change preserves native state", replayEqual === 1); persistenceAssert("Cloud persistence boundary is explicitly remote-only", applicable === 0 && reason.includes("remote S3")); persistenceAssert("Configuration remains unchanged when FCStd persistence is not applicable", configurationAfter.url === "https://cloud.example.invalid" && configurationAfter.tokenAuth === "web-fixture-access"); businessCase.result = { activeDocument, completed, applicable, errorCode, errorMessage, reason, saveAvailable, restoreAvailable, documentCountBefore, documentCountAfter, replayEqual, state: before, configurationAfter }; } results.push({ capabilityId: persistenceCapabilityId, status: "passed", cases: persistenceCases }); } finish({ schema: "freecad-web-business-cases/v1", module: "Cloud", results }, results.some((result) => result.status === "failed") ? 1 : 0); } } catch (error) { const report = { schema: "freecad-web-business-cases/v1", module: "Cloud", results: [{ capabilityId: activeCapabilityId, status: "failed", cases: activeCapabilityId === persistenceCapabilityId ? persistenceCases : cases, stage, error: error instanceof Error ? error.message : String(error) }] }; finish(report, 1); }