建立ToolDbProcessPort合约层
结论:已新增ToolDbProcessPort合约、OPFS tool DB flat-file/transcript store和Node/WASM gates,baseline保持28/28/131/0且promotion继续锁定。
This commit is contained in:
@@ -61,6 +61,37 @@ export function toolTablePath(machineId, filename = "tool.tbl") {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toolDbRootPath(machineId) {
|
||||||
|
return opfsPath(
|
||||||
|
ROOT,
|
||||||
|
"machines",
|
||||||
|
assertSegment(machineId, "machine id"),
|
||||||
|
"tool-db",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toolDbFilePath(machineId, filename = "db_nonran_file") {
|
||||||
|
return opfsPath(
|
||||||
|
ROOT,
|
||||||
|
"machines",
|
||||||
|
assertSegment(machineId, "machine id"),
|
||||||
|
"tool-db",
|
||||||
|
assertSegment(filename, "tool DB filename"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toolDbTranscriptPath(machineId, runId, filename = "transcript.json") {
|
||||||
|
return opfsPath(
|
||||||
|
ROOT,
|
||||||
|
"machines",
|
||||||
|
assertSegment(machineId, "machine id"),
|
||||||
|
"tool-db",
|
||||||
|
"transcripts",
|
||||||
|
assertSegment(runId, "tool DB run id"),
|
||||||
|
assertSegment(filename, "tool DB transcript filename"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function parameterFilePath(machineId, filename = "linuxcnc.var") {
|
export function parameterFilePath(machineId, filename = "linuxcnc.var") {
|
||||||
return opfsPath(
|
return opfsPath(
|
||||||
ROOT,
|
ROOT,
|
||||||
|
|||||||
78
wasm-port/runtime/opfs/tool-db-store.js
Normal file
78
wasm-port/runtime/opfs/tool-db-store.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { loadTextFile, saveTextFile } from "./file-service.js";
|
||||||
|
import { toolDbFilePath, toolDbTranscriptPath } from "./path-model.js";
|
||||||
|
|
||||||
|
function stableTextHash(text) {
|
||||||
|
let hash = 0x811c9dc5;
|
||||||
|
for (let index = 0; index < text.length; index += 1) {
|
||||||
|
hash ^= text.charCodeAt(index);
|
||||||
|
hash = Math.imul(hash, 0x01000193) >>> 0;
|
||||||
|
}
|
||||||
|
return hash.toString(16).padStart(8, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayOpfsPath(path) {
|
||||||
|
return path.startsWith("linuxcnc/") ? path.slice("linuxcnc".length) : `/${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createToolDbStorePaths(machineId, {
|
||||||
|
dbFilename = "db_nonran_file",
|
||||||
|
runId = "run-1",
|
||||||
|
transcriptFilename = "transcript.json",
|
||||||
|
} = {}) {
|
||||||
|
return {
|
||||||
|
dbFile: toolDbFilePath(machineId, dbFilename),
|
||||||
|
transcript: toolDbTranscriptPath(machineId, runId, transcriptFilename),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveToolDbFile(machineId, text, options = {}) {
|
||||||
|
const path = options.path ?? toolDbFilePath(machineId, options.filename);
|
||||||
|
await saveTextFile(path, text, options.storage);
|
||||||
|
return {
|
||||||
|
opfsPath: path,
|
||||||
|
displayPath: displayOpfsPath(path),
|
||||||
|
dbFileHash: stableTextHash(text),
|
||||||
|
savedText: text,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadToolDbFile(machineId, options = {}) {
|
||||||
|
const path = options.path ?? toolDbFilePath(machineId, options.filename);
|
||||||
|
const text = await loadTextFile(path, options.storage);
|
||||||
|
return {
|
||||||
|
opfsPath: path,
|
||||||
|
displayPath: displayOpfsPath(path),
|
||||||
|
dbFileHash: stableTextHash(text),
|
||||||
|
text,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveToolDbTranscript(machineId, runId, transcript, options = {}) {
|
||||||
|
if (!Array.isArray(transcript)) {
|
||||||
|
throw new Error("transcript must be an array.");
|
||||||
|
}
|
||||||
|
const path = options.path ?? toolDbTranscriptPath(machineId, runId, options.filename);
|
||||||
|
const text = JSON.stringify({
|
||||||
|
schema: "linuxcnc.toolDbProcessTranscript.v1",
|
||||||
|
transcript,
|
||||||
|
}, null, 2);
|
||||||
|
await saveTextFile(path, text, options.storage);
|
||||||
|
return {
|
||||||
|
opfsPath: path,
|
||||||
|
displayPath: displayOpfsPath(path),
|
||||||
|
transcriptHash: stableTextHash(text),
|
||||||
|
text,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadToolDbTranscript(machineId, runId, options = {}) {
|
||||||
|
const path = options.path ?? toolDbTranscriptPath(machineId, runId, options.filename);
|
||||||
|
const text = await loadTextFile(path, options.storage);
|
||||||
|
const payload = JSON.parse(text);
|
||||||
|
return {
|
||||||
|
opfsPath: path,
|
||||||
|
displayPath: displayOpfsPath(path),
|
||||||
|
transcriptHash: stableTextHash(text),
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -126,6 +126,9 @@ import {
|
|||||||
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
createProjectReleaseReadinessReport,
|
createProjectReleaseReadinessReport,
|
||||||
createProjectReleaseReadinessSummaryViewModel,
|
createProjectReleaseReadinessSummaryViewModel,
|
||||||
|
createLinuxCncToolDbProcessPort,
|
||||||
|
createToolDbProcessDiagnostics,
|
||||||
|
createToolDbTransactionPlan,
|
||||||
createSessionSnapshot,
|
createSessionSnapshot,
|
||||||
defaultMachinePaths,
|
defaultMachinePaths,
|
||||||
gcodeFilenameFromProgramPath,
|
gcodeFilenameFromProgramPath,
|
||||||
@@ -143,6 +146,8 @@ import {
|
|||||||
loadMachineSessionSnapshot,
|
loadMachineSessionSnapshot,
|
||||||
loadMachineTextFiles,
|
loadMachineTextFiles,
|
||||||
loadMachineToolTableFromOpfs,
|
loadMachineToolTableFromOpfs,
|
||||||
|
loadToolDbFile,
|
||||||
|
loadToolDbTranscript,
|
||||||
loadTextFile,
|
loadTextFile,
|
||||||
machineFilePaths,
|
machineFilePaths,
|
||||||
machineIniPath,
|
machineIniPath,
|
||||||
@@ -183,9 +188,15 @@ import {
|
|||||||
saveMachineSessionSnapshot,
|
saveMachineSessionSnapshot,
|
||||||
saveMachineTextFiles,
|
saveMachineTextFiles,
|
||||||
saveSessionSnapshot,
|
saveSessionSnapshot,
|
||||||
|
saveToolDbFile,
|
||||||
|
saveToolDbTranscript,
|
||||||
saveTextFile,
|
saveTextFile,
|
||||||
sessionSnapshotPath,
|
sessionSnapshotPath,
|
||||||
|
toolDbFilePath,
|
||||||
|
toolDbRootPath,
|
||||||
|
toolDbTranscriptPath,
|
||||||
toolTablePath,
|
toolTablePath,
|
||||||
|
validateToolDbTranscript,
|
||||||
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
||||||
validateSessionSnapshot,
|
validateSessionSnapshot,
|
||||||
} from "./src/index.js";
|
} from "./src/index.js";
|
||||||
@@ -534,6 +545,7 @@ private module paths:
|
|||||||
- `getOpfsRoot()`, `saveTextFile()`, and `loadTextFile()` for browser OPFS text
|
- `getOpfsRoot()`, `saveTextFile()`, and `loadTextFile()` for browser OPFS text
|
||||||
persistence.
|
persistence.
|
||||||
- `machineIniPath()`, `toolTablePath()`, `parameterFilePath()`,
|
- `machineIniPath()`, `toolTablePath()`, `parameterFilePath()`,
|
||||||
|
`toolDbRootPath()`, `toolDbFilePath()`, `toolDbTranscriptPath()`,
|
||||||
`gcodeProgramPath()`, `sessionSnapshotPath()`, `defaultMachinePaths()`, and
|
`gcodeProgramPath()`, `sessionSnapshotPath()`, `defaultMachinePaths()`, and
|
||||||
`normalizeOpfsPath()` for stable OPFS path construction.
|
`normalizeOpfsPath()` for stable OPFS path construction.
|
||||||
- `createMachineSessionSnapshotPayload()`, `createSessionSnapshot()`,
|
- `createMachineSessionSnapshotPayload()`, `createSessionSnapshot()`,
|
||||||
@@ -552,6 +564,14 @@ private module paths:
|
|||||||
- `restoreMachineParametersFromOpfs()`, `loadMachineToolTableFromOpfs()`, and
|
- `restoreMachineParametersFromOpfs()`, `loadMachineToolTableFromOpfs()`, and
|
||||||
`loadMachineSessionFromOpfs()` for loading OPFS machine state into the
|
`loadMachineSessionFromOpfs()` for loading OPFS machine state into the
|
||||||
LinuxCNC-backed interpreter SDK.
|
LinuxCNC-backed interpreter SDK.
|
||||||
|
- `createLinuxCncToolDbProcessPort()`, `createToolDbTransactionPlan()`,
|
||||||
|
`validateToolDbTranscript()`, and `createToolDbProcessDiagnostics()` for the
|
||||||
|
LinuxCNC-owned tool DB process port contract. Contract-only mode does not run
|
||||||
|
`DB_PROGRAM`, does not parse `.tbl` as a fallback, and keeps execution and
|
||||||
|
promotion disabled.
|
||||||
|
- `saveToolDbFile()`, `loadToolDbFile()`, `saveToolDbTranscript()`, and
|
||||||
|
`loadToolDbTranscript()` for OPFS persistence of the DB flat file and protocol
|
||||||
|
transcript artifacts.
|
||||||
|
|
||||||
These helpers only move and validate host files. Parameter and tool-table
|
These helpers only move and validate host files. Parameter and tool-table
|
||||||
effects still come from the LinuxCNC-backed interpreter SDK methods they call.
|
effects still come from the LinuxCNC-backed interpreter SDK methods they call.
|
||||||
|
|||||||
@@ -91,6 +91,14 @@ export {
|
|||||||
planIniFileContextStaging,
|
planIniFileContextStaging,
|
||||||
planSimConfigStaging,
|
planSimConfigStaging,
|
||||||
} from "./sim-config-staging.js";
|
} from "./sim-config-staging.js";
|
||||||
|
export {
|
||||||
|
TOOL_DB_PROCESS_PORT_CONTRACT_VERSION,
|
||||||
|
TOOL_DB_TRANSACTION_PLAN,
|
||||||
|
createLinuxCncToolDbProcessPort,
|
||||||
|
createToolDbProcessDiagnostics,
|
||||||
|
createToolDbTransactionPlan,
|
||||||
|
validateToolDbTranscript,
|
||||||
|
} from "./tool-db-process-port.js";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
defaultMachinePaths,
|
defaultMachinePaths,
|
||||||
@@ -103,6 +111,9 @@ export {
|
|||||||
previewCachePath,
|
previewCachePath,
|
||||||
sessionSnapshotPath,
|
sessionSnapshotPath,
|
||||||
splitOpfsPath,
|
splitOpfsPath,
|
||||||
|
toolDbFilePath,
|
||||||
|
toolDbRootPath,
|
||||||
|
toolDbTranscriptPath,
|
||||||
toolTablePath,
|
toolTablePath,
|
||||||
} from "../../opfs/path-model.js";
|
} from "../../opfs/path-model.js";
|
||||||
export {
|
export {
|
||||||
@@ -138,6 +149,13 @@ export {
|
|||||||
loadMachineToolTableFromOpfs,
|
loadMachineToolTableFromOpfs,
|
||||||
saveMachineToolTableToOpfs,
|
saveMachineToolTableToOpfs,
|
||||||
} from "../../opfs/linuxcnc-tool-table-bridge.js";
|
} from "../../opfs/linuxcnc-tool-table-bridge.js";
|
||||||
|
export {
|
||||||
|
createToolDbStorePaths,
|
||||||
|
loadToolDbFile,
|
||||||
|
loadToolDbTranscript,
|
||||||
|
saveToolDbFile,
|
||||||
|
saveToolDbTranscript,
|
||||||
|
} from "../../opfs/tool-db-store.js";
|
||||||
export { loadMachineSessionFromOpfs } from "../../opfs/linuxcnc-machine-session-bridge.js";
|
export { loadMachineSessionFromOpfs } from "../../opfs/linuxcnc-machine-session-bridge.js";
|
||||||
export { readMachineSessionReadiness } from "../../opfs/machine-session-readiness.js";
|
export { readMachineSessionReadiness } from "../../opfs/machine-session-readiness.js";
|
||||||
|
|
||||||
|
|||||||
241
wasm-port/runtime/sdk/src/tool-db-process-port.js
Normal file
241
wasm-port/runtime/sdk/src/tool-db-process-port.js
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
const TOOL_DB_PROTOCOL_VERSION = "v2.1";
|
||||||
|
|
||||||
|
export const TOOL_DB_PROCESS_PORT_CONTRACT_VERSION = 1;
|
||||||
|
|
||||||
|
export const TOOL_DB_TRANSACTION_PLAN = [
|
||||||
|
{
|
||||||
|
phase: "startup_handshake",
|
||||||
|
direction: "read",
|
||||||
|
expect: TOOL_DB_PROTOCOL_VERSION,
|
||||||
|
requiresFini: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: "initial_get_all",
|
||||||
|
direction: "write",
|
||||||
|
line: "g",
|
||||||
|
expect: "T10..T19",
|
||||||
|
requiresFini: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: "tool_offset_notify",
|
||||||
|
direction: "write",
|
||||||
|
line: "p t11 p111 d0.33 z0.11",
|
||||||
|
expect: "FINI",
|
||||||
|
requiresFini: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: "spindle_load_notify",
|
||||||
|
direction: "write",
|
||||||
|
line: "l t14 p0",
|
||||||
|
expect: "T14 P0 after query",
|
||||||
|
requiresFini: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
phase: "spindle_unload_notify",
|
||||||
|
direction: "write",
|
||||||
|
line: "u t0 p0",
|
||||||
|
expect: "T14 P114 after query",
|
||||||
|
requiresFini: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function requireString(value, label) {
|
||||||
|
if (typeof value !== "string" || value.length === 0) {
|
||||||
|
throw new Error(`${label} must be a non-empty string.`);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeSourceFiles(sourceFiles = []) {
|
||||||
|
if (!Array.isArray(sourceFiles)) {
|
||||||
|
throw new Error("sourceFiles must be an array.");
|
||||||
|
}
|
||||||
|
return sourceFiles.map((sourceFile) => requireString(sourceFile, "source file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function stableTextHash(text) {
|
||||||
|
let hash = 0x811c9dc5;
|
||||||
|
for (let index = 0; index < text.length; index += 1) {
|
||||||
|
hash ^= text.charCodeAt(index);
|
||||||
|
hash = Math.imul(hash, 0x01000193) >>> 0;
|
||||||
|
}
|
||||||
|
return hash.toString(16).padStart(8, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
function transcriptText(transcript) {
|
||||||
|
return transcript
|
||||||
|
.map((entry) => `${entry.direction}:${entry.line}`)
|
||||||
|
.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createToolDbTransactionPlan() {
|
||||||
|
return TOOL_DB_TRANSACTION_PLAN.map((step) => ({ ...step }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createToolDbProcessDiagnostics({
|
||||||
|
dbProgramPath,
|
||||||
|
opfsDbPath = "-",
|
||||||
|
transcript = [],
|
||||||
|
dbFileText = "",
|
||||||
|
startupToolCount = 0,
|
||||||
|
mutationCount = 0,
|
||||||
|
runtimeMode = "contract-only",
|
||||||
|
runtimeExecutionReady = false,
|
||||||
|
} = {}) {
|
||||||
|
requireString(dbProgramPath, "dbProgramPath");
|
||||||
|
const transcriptHash = stableTextHash(transcriptText(transcript));
|
||||||
|
const dbFileHash = stableTextHash(dbFileText);
|
||||||
|
|
||||||
|
return {
|
||||||
|
contractVersion: TOOL_DB_PROCESS_PORT_CONTRACT_VERSION,
|
||||||
|
dbProgramPath,
|
||||||
|
opfsDbPath,
|
||||||
|
runtimeMode,
|
||||||
|
runtimeExecutionReady: runtimeExecutionReady === true,
|
||||||
|
protocolTranscriptReady: transcript.length > 0,
|
||||||
|
opfsPersistenceReady: dbFileText.length > 0,
|
||||||
|
transcriptHash,
|
||||||
|
dbFileHash,
|
||||||
|
startupToolCount,
|
||||||
|
mutationCount,
|
||||||
|
tblFallbackSufficient: false,
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateToolDbTranscript(transcript) {
|
||||||
|
if (!Array.isArray(transcript)) {
|
||||||
|
throw new Error("transcript must be an array.");
|
||||||
|
}
|
||||||
|
const lines = transcript.map((entry) => entry?.line ?? "");
|
||||||
|
const hasVersion = lines.includes(TOOL_DB_PROTOCOL_VERSION);
|
||||||
|
const hasGetAll = lines.includes("g");
|
||||||
|
const hasFini = lines.some((line) => line.startsWith("FINI"));
|
||||||
|
const hasPut = lines.includes("p t11 p111 d0.33 z0.11");
|
||||||
|
const hasLoad = lines.includes("l t14 p0");
|
||||||
|
const hasUnload = lines.includes("u t0 p0");
|
||||||
|
|
||||||
|
return {
|
||||||
|
protocolVersion: TOOL_DB_PROTOCOL_VERSION,
|
||||||
|
hasVersion,
|
||||||
|
hasGetAll,
|
||||||
|
hasFini,
|
||||||
|
hasPut,
|
||||||
|
hasLoad,
|
||||||
|
hasUnload,
|
||||||
|
ready: hasVersion && hasGetAll && hasFini && hasPut && hasLoad && hasUnload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createLinuxCncToolDbProcessPort({
|
||||||
|
dbProgramPath,
|
||||||
|
sourceFiles = [],
|
||||||
|
opfsRoot = null,
|
||||||
|
runtimeMode = "contract-only",
|
||||||
|
runtimeAdapter = null,
|
||||||
|
} = {}) {
|
||||||
|
requireString(dbProgramPath, "dbProgramPath");
|
||||||
|
const normalizedSourceFiles = normalizeSourceFiles(sourceFiles);
|
||||||
|
const transcript = [];
|
||||||
|
let started = false;
|
||||||
|
let closed = false;
|
||||||
|
|
||||||
|
function assertOpen() {
|
||||||
|
if (closed) {
|
||||||
|
throw new Error("ToolDbProcessPort is closed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
dbProgramPath,
|
||||||
|
sourceFiles: normalizedSourceFiles,
|
||||||
|
opfsRoot,
|
||||||
|
runtimeMode,
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
assertOpen();
|
||||||
|
started = true;
|
||||||
|
if (runtimeAdapter?.start) {
|
||||||
|
await runtimeAdapter.start();
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
runtimeMode,
|
||||||
|
runtimeExecutionReady: Boolean(runtimeAdapter),
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
async writeLine(line) {
|
||||||
|
assertOpen();
|
||||||
|
if (!started) {
|
||||||
|
throw new Error("ToolDbProcessPort must be started before writeLine().");
|
||||||
|
}
|
||||||
|
const normalizedLine = requireString(line, "line");
|
||||||
|
transcript.push({ direction: "write", line: normalizedLine });
|
||||||
|
if (runtimeAdapter?.writeLine) {
|
||||||
|
await runtimeAdapter.writeLine(normalizedLine);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async readLine() {
|
||||||
|
assertOpen();
|
||||||
|
if (!started) {
|
||||||
|
throw new Error("ToolDbProcessPort must be started before readLine().");
|
||||||
|
}
|
||||||
|
if (!runtimeAdapter?.readLine) {
|
||||||
|
throw new Error("ToolDbProcessPort has no runtime adapter; contract-only mode cannot read DB_PROGRAM output.");
|
||||||
|
}
|
||||||
|
const line = await runtimeAdapter.readLine();
|
||||||
|
transcript.push({ direction: "read", line });
|
||||||
|
return line;
|
||||||
|
},
|
||||||
|
|
||||||
|
async runTransactionPlan(plan = createToolDbTransactionPlan()) {
|
||||||
|
assertOpen();
|
||||||
|
if (!runtimeAdapter) {
|
||||||
|
return {
|
||||||
|
status: "blocked_runtime_adapter_required",
|
||||||
|
plan,
|
||||||
|
runtimeExecutionReady: false,
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
tblFallbackSufficient: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (const step of plan) {
|
||||||
|
if (step.direction === "write") {
|
||||||
|
await this.writeLine(step.line);
|
||||||
|
} else {
|
||||||
|
await this.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
status: "runtime_adapter_transaction_plan_executed",
|
||||||
|
plan,
|
||||||
|
transcript: this.exportTranscript(),
|
||||||
|
runtimeExecutionReady: true,
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
tblFallbackSufficient: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
exportTranscript() {
|
||||||
|
return transcript.map((entry) => ({ ...entry }));
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
if (runtimeAdapter?.close) {
|
||||||
|
runtimeAdapter.close();
|
||||||
|
}
|
||||||
|
closed = true;
|
||||||
|
return {
|
||||||
|
closed,
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -13,6 +13,9 @@ import {
|
|||||||
parameterFilePath,
|
parameterFilePath,
|
||||||
previewCachePath,
|
previewCachePath,
|
||||||
sessionSnapshotPath,
|
sessionSnapshotPath,
|
||||||
|
toolDbFilePath,
|
||||||
|
toolDbRootPath,
|
||||||
|
toolDbTranscriptPath,
|
||||||
toolTablePath,
|
toolTablePath,
|
||||||
} from "../../../runtime/opfs/path-model.js";
|
} from "../../../runtime/opfs/path-model.js";
|
||||||
import {
|
import {
|
||||||
@@ -205,6 +208,12 @@ assert.equal(await getOpfsRoot(storage), root);
|
|||||||
assert.equal(normalizeOpfsPath("linuxcnc/machines/xyzab.ini"), "linuxcnc/machines/xyzab.ini");
|
assert.equal(normalizeOpfsPath("linuxcnc/machines/xyzab.ini"), "linuxcnc/machines/xyzab.ini");
|
||||||
assert.equal(machineIniPath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/machine.ini");
|
assert.equal(machineIniPath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/machine.ini");
|
||||||
assert.equal(toolTablePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/tool.tbl");
|
assert.equal(toolTablePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/tool.tbl");
|
||||||
|
assert.equal(toolDbRootPath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/tool-db");
|
||||||
|
assert.equal(toolDbFilePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/tool-db/db_nonran_file");
|
||||||
|
assert.equal(
|
||||||
|
toolDbTranscriptPath("xyzab-tdr", "run-1"),
|
||||||
|
"linuxcnc/machines/xyzab-tdr/tool-db/transcripts/run-1/transcript.json",
|
||||||
|
);
|
||||||
assert.equal(parameterFilePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/linuxcnc.var");
|
assert.equal(parameterFilePath("xyzab-tdr"), "linuxcnc/machines/xyzab-tdr/linuxcnc.var");
|
||||||
assertGcodeProgramStoragePath("fixture.ngc", gcodeProgramPath("fixture.ngc"));
|
assertGcodeProgramStoragePath("fixture.ngc", gcodeProgramPath("fixture.ngc"));
|
||||||
assertGcodeProgramStoragePath(
|
assertGcodeProgramStoragePath(
|
||||||
|
|||||||
110
wasm-port/tests/opfs/node/verify_tool_db_store.mjs
Normal file
110
wasm-port/tests/opfs/node/verify_tool_db_store.mjs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createToolDbStorePaths,
|
||||||
|
loadToolDbFile,
|
||||||
|
loadToolDbTranscript,
|
||||||
|
saveToolDbFile,
|
||||||
|
saveToolDbTranscript,
|
||||||
|
} from "../../../runtime/opfs/tool-db-store.js";
|
||||||
|
import {
|
||||||
|
toolDbFilePath,
|
||||||
|
toolDbRootPath,
|
||||||
|
toolDbTranscriptPath,
|
||||||
|
} from "../../../runtime/opfs/path-model.js";
|
||||||
|
|
||||||
|
class MockFileHandle {
|
||||||
|
constructor(name) {
|
||||||
|
this.name = name;
|
||||||
|
this.textValue = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async createWritable() {
|
||||||
|
return {
|
||||||
|
write: async (text) => {
|
||||||
|
this.textValue = String(text);
|
||||||
|
},
|
||||||
|
close: async () => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFile() {
|
||||||
|
return {
|
||||||
|
text: async () => this.textValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockDirectoryHandle {
|
||||||
|
constructor(name = "") {
|
||||||
|
this.name = name;
|
||||||
|
this.dirs = new Map();
|
||||||
|
this.files = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDirectoryHandle(name, options = {}) {
|
||||||
|
if (!this.dirs.has(name)) {
|
||||||
|
if (!options.create) {
|
||||||
|
throw new Error(`missing directory: ${name}`);
|
||||||
|
}
|
||||||
|
this.dirs.set(name, new MockDirectoryHandle(name));
|
||||||
|
}
|
||||||
|
return this.dirs.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFileHandle(name, options = {}) {
|
||||||
|
if (!this.files.has(name)) {
|
||||||
|
if (!options.create) {
|
||||||
|
throw new Error(`missing file: ${name}`);
|
||||||
|
}
|
||||||
|
this.files.set(name, new MockFileHandle(name));
|
||||||
|
}
|
||||||
|
return this.files.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = new MockDirectoryHandle();
|
||||||
|
const storage = {
|
||||||
|
getDirectory: async () => root,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.equal(toolDbRootPath("db-demo"), "linuxcnc/machines/db-demo/tool-db");
|
||||||
|
assert.equal(toolDbFilePath("db-demo"), "linuxcnc/machines/db-demo/tool-db/db_nonran_file");
|
||||||
|
assert.equal(
|
||||||
|
toolDbTranscriptPath("db-demo", "run-42"),
|
||||||
|
"linuxcnc/machines/db-demo/tool-db/transcripts/run-42/transcript.json",
|
||||||
|
);
|
||||||
|
assert.deepEqual(createToolDbStorePaths("db-demo", { runId: "run-42" }), {
|
||||||
|
dbFile: "linuxcnc/machines/db-demo/tool-db/db_nonran_file",
|
||||||
|
transcript: "linuxcnc/machines/db-demo/tool-db/transcripts/run-42/transcript.json",
|
||||||
|
});
|
||||||
|
|
||||||
|
const dbText = "T11 P111 D0.33 Z0.11\nT14 P114 D0.14 Z0.14\n";
|
||||||
|
const savedDb = await saveToolDbFile("db-demo", dbText, { storage });
|
||||||
|
assert.equal(savedDb.opfsPath, "linuxcnc/machines/db-demo/tool-db/db_nonran_file");
|
||||||
|
assert.equal(savedDb.displayPath, "/machines/db-demo/tool-db/db_nonran_file");
|
||||||
|
assert.match(savedDb.dbFileHash, /^[0-9a-f]{8}$/);
|
||||||
|
|
||||||
|
const loadedDb = await loadToolDbFile("db-demo", { storage });
|
||||||
|
assert.equal(loadedDb.text, dbText);
|
||||||
|
assert.equal(loadedDb.dbFileHash, savedDb.dbFileHash);
|
||||||
|
|
||||||
|
const transcript = [
|
||||||
|
{ direction: "read", line: "v2.1" },
|
||||||
|
{ direction: "write", line: "g" },
|
||||||
|
{ direction: "read", line: "FINI (get_cmd)" },
|
||||||
|
];
|
||||||
|
const savedTranscript = await saveToolDbTranscript("db-demo", "run-42", transcript, { storage });
|
||||||
|
assert.equal(
|
||||||
|
savedTranscript.opfsPath,
|
||||||
|
"linuxcnc/machines/db-demo/tool-db/transcripts/run-42/transcript.json",
|
||||||
|
);
|
||||||
|
assert.equal(savedTranscript.displayPath, "/machines/db-demo/tool-db/transcripts/run-42/transcript.json");
|
||||||
|
assert.match(savedTranscript.transcriptHash, /^[0-9a-f]{8}$/);
|
||||||
|
|
||||||
|
const loadedTranscript = await loadToolDbTranscript("db-demo", "run-42", { storage });
|
||||||
|
assert.equal(loadedTranscript.payload.schema, "linuxcnc.toolDbProcessTranscript.v1");
|
||||||
|
assert.deepEqual(loadedTranscript.payload.transcript, transcript);
|
||||||
|
assert.equal(loadedTranscript.transcriptHash, savedTranscript.transcriptHash);
|
||||||
|
|
||||||
|
console.log("tool_db_store_opfs=ok");
|
||||||
6
wasm-port/tests/opfs/node/verify_tool_db_store.sh
Normal file
6
wasm-port/tests/opfs/node/verify_tool_db_store.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
|
||||||
|
node "$ROOT_DIR/tests/opfs/node/verify_tool_db_store.mjs"
|
||||||
@@ -90,6 +90,9 @@ import {
|
|||||||
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
createProjectReleaseReadinessReport,
|
createProjectReleaseReadinessReport,
|
||||||
createProjectReleaseReadinessSummaryViewModel,
|
createProjectReleaseReadinessSummaryViewModel,
|
||||||
|
createLinuxCncToolDbProcessPort,
|
||||||
|
createToolDbProcessDiagnostics,
|
||||||
|
createToolDbTransactionPlan,
|
||||||
createVirtualHalBridgeActionPlan,
|
createVirtualHalBridgeActionPlan,
|
||||||
createVirtualHalBridgeReadiness,
|
createVirtualHalBridgeReadiness,
|
||||||
createVirtualHalCommandScriptFixtureReport,
|
createVirtualHalCommandScriptFixtureReport,
|
||||||
@@ -153,6 +156,8 @@ import {
|
|||||||
loadMachineSessionSnapshot,
|
loadMachineSessionSnapshot,
|
||||||
loadMachineTextFiles,
|
loadMachineTextFiles,
|
||||||
loadMachineToolTableFromOpfs,
|
loadMachineToolTableFromOpfs,
|
||||||
|
loadToolDbFile,
|
||||||
|
loadToolDbTranscript,
|
||||||
loadTextFile,
|
loadTextFile,
|
||||||
machineFilePaths,
|
machineFilePaths,
|
||||||
machineIniPath,
|
machineIniPath,
|
||||||
@@ -172,7 +177,13 @@ import {
|
|||||||
saveSessionSnapshot,
|
saveSessionSnapshot,
|
||||||
saveTextFile,
|
saveTextFile,
|
||||||
sessionSnapshotPath,
|
sessionSnapshotPath,
|
||||||
|
saveToolDbFile,
|
||||||
|
saveToolDbTranscript,
|
||||||
|
toolDbFilePath,
|
||||||
|
toolDbRootPath,
|
||||||
|
toolDbTranscriptPath,
|
||||||
toolTablePath,
|
toolTablePath,
|
||||||
|
validateToolDbTranscript,
|
||||||
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
||||||
validateSessionSnapshot,
|
validateSessionSnapshot,
|
||||||
} from "../../../runtime/sdk/src/index.js";
|
} from "../../../runtime/sdk/src/index.js";
|
||||||
@@ -490,6 +501,9 @@ const requiredExports = [
|
|||||||
["loadTextFile", loadTextFile],
|
["loadTextFile", loadTextFile],
|
||||||
["machineIniPath", machineIniPath],
|
["machineIniPath", machineIniPath],
|
||||||
["toolTablePath", toolTablePath],
|
["toolTablePath", toolTablePath],
|
||||||
|
["toolDbRootPath", toolDbRootPath],
|
||||||
|
["toolDbFilePath", toolDbFilePath],
|
||||||
|
["toolDbTranscriptPath", toolDbTranscriptPath],
|
||||||
["parameterFilePath", parameterFilePath],
|
["parameterFilePath", parameterFilePath],
|
||||||
["gcodeProgramPath", gcodeProgramPath],
|
["gcodeProgramPath", gcodeProgramPath],
|
||||||
["sessionSnapshotPath", sessionSnapshotPath],
|
["sessionSnapshotPath", sessionSnapshotPath],
|
||||||
@@ -507,6 +521,14 @@ const requiredExports = [
|
|||||||
["saveMachineTextFiles", saveMachineTextFiles],
|
["saveMachineTextFiles", saveMachineTextFiles],
|
||||||
["loadMachineTextFiles", loadMachineTextFiles],
|
["loadMachineTextFiles", loadMachineTextFiles],
|
||||||
["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
|
["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
|
||||||
|
["createLinuxCncToolDbProcessPort", createLinuxCncToolDbProcessPort],
|
||||||
|
["createToolDbProcessDiagnostics", createToolDbProcessDiagnostics],
|
||||||
|
["createToolDbTransactionPlan", createToolDbTransactionPlan],
|
||||||
|
["validateToolDbTranscript", validateToolDbTranscript],
|
||||||
|
["saveToolDbFile", saveToolDbFile],
|
||||||
|
["loadToolDbFile", loadToolDbFile],
|
||||||
|
["saveToolDbTranscript", saveToolDbTranscript],
|
||||||
|
["loadToolDbTranscript", loadToolDbTranscript],
|
||||||
["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
|
["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
|
||||||
["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
|
["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
|
||||||
["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],
|
["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],
|
||||||
|
|||||||
95
wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs
Normal file
95
wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
|
||||||
|
import {
|
||||||
|
TOOL_DB_PROCESS_PORT_CONTRACT_VERSION,
|
||||||
|
TOOL_DB_TRANSACTION_PLAN,
|
||||||
|
createLinuxCncToolDbProcessPort,
|
||||||
|
createToolDbProcessDiagnostics,
|
||||||
|
createToolDbTransactionPlan,
|
||||||
|
validateToolDbTranscript,
|
||||||
|
} from "../../../runtime/sdk/src/tool-db-process-port.js";
|
||||||
|
|
||||||
|
assert.equal(TOOL_DB_PROCESS_PORT_CONTRACT_VERSION, 1);
|
||||||
|
assert.deepEqual(
|
||||||
|
createToolDbTransactionPlan().map((step) => step.phase),
|
||||||
|
[
|
||||||
|
"startup_handshake",
|
||||||
|
"initial_get_all",
|
||||||
|
"tool_offset_notify",
|
||||||
|
"spindle_load_notify",
|
||||||
|
"spindle_unload_notify",
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert.equal(TOOL_DB_TRANSACTION_PLAN[0].expect, "v2.1");
|
||||||
|
assert.equal(TOOL_DB_TRANSACTION_PLAN.every((step) => step.requiresFini || step.phase === "startup_handshake"), true);
|
||||||
|
|
||||||
|
const port = createLinuxCncToolDbProcessPort({
|
||||||
|
dbProgramPath: "./db_nonran.py",
|
||||||
|
sourceFiles: [
|
||||||
|
"configs/sim/axis/db_demo/db_nonran.py",
|
||||||
|
"configs/sim/axis/db_demo/db.py",
|
||||||
|
"lib/python/tooldb.py",
|
||||||
|
],
|
||||||
|
runtimeMode: "contract-only",
|
||||||
|
});
|
||||||
|
|
||||||
|
const startResult = await port.start();
|
||||||
|
assert.deepEqual(startResult, {
|
||||||
|
runtimeMode: "contract-only",
|
||||||
|
runtimeExecutionReady: false,
|
||||||
|
executionEnabled: false,
|
||||||
|
promotionAllowed: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const blockedPlan = await port.runTransactionPlan();
|
||||||
|
assert.equal(blockedPlan.status, "blocked_runtime_adapter_required");
|
||||||
|
assert.equal(blockedPlan.runtimeExecutionReady, false);
|
||||||
|
assert.equal(blockedPlan.executionEnabled, false);
|
||||||
|
assert.equal(blockedPlan.promotionAllowed, false);
|
||||||
|
assert.equal(blockedPlan.tblFallbackSufficient, false);
|
||||||
|
|
||||||
|
const transcript = [
|
||||||
|
{ direction: "read", line: "v2.1" },
|
||||||
|
{ direction: "write", line: "g" },
|
||||||
|
{ direction: "read", line: "T10 P110 D0.10 Z0.10" },
|
||||||
|
{ direction: "read", line: "FINI (get_cmd)" },
|
||||||
|
{ direction: "write", line: "p t11 p111 d0.33 z0.11" },
|
||||||
|
{ direction: "read", line: "FINI (update recvd) t11 p111 d0.33 z0.11" },
|
||||||
|
{ direction: "write", line: "l t14 p0" },
|
||||||
|
{ direction: "read", line: "FINI (update recvd) t14 p0" },
|
||||||
|
{ direction: "write", line: "u t0 p0" },
|
||||||
|
{ direction: "read", line: "FINI (update recvd) t0 p0" },
|
||||||
|
];
|
||||||
|
const validation = validateToolDbTranscript(transcript);
|
||||||
|
assert.equal(validation.ready, true);
|
||||||
|
assert.equal(validation.hasVersion, true);
|
||||||
|
assert.equal(validation.hasGetAll, true);
|
||||||
|
assert.equal(validation.hasFini, true);
|
||||||
|
assert.equal(validation.hasPut, true);
|
||||||
|
assert.equal(validation.hasLoad, true);
|
||||||
|
assert.equal(validation.hasUnload, true);
|
||||||
|
|
||||||
|
const diagnostics = createToolDbProcessDiagnostics({
|
||||||
|
dbProgramPath: "./db_nonran.py",
|
||||||
|
opfsDbPath: "/machines/db-demo/tool-db/db_nonran_file",
|
||||||
|
transcript,
|
||||||
|
dbFileText: "T11 P111 D0.33 Z0.11\nT14 P114 D0.14 Z0.14\n",
|
||||||
|
startupToolCount: 10,
|
||||||
|
mutationCount: 3,
|
||||||
|
runtimeMode: "wasm-tool-db-protocol-worker",
|
||||||
|
});
|
||||||
|
assert.equal(diagnostics.dbProgramPath, "./db_nonran.py");
|
||||||
|
assert.equal(diagnostics.protocolTranscriptReady, true);
|
||||||
|
assert.equal(diagnostics.opfsPersistenceReady, true);
|
||||||
|
assert.equal(diagnostics.startupToolCount, 10);
|
||||||
|
assert.equal(diagnostics.mutationCount, 3);
|
||||||
|
assert.equal(diagnostics.tblFallbackSufficient, false);
|
||||||
|
assert.equal(diagnostics.runtimeExecutionReady, false);
|
||||||
|
assert.equal(diagnostics.executionEnabled, false);
|
||||||
|
assert.equal(diagnostics.promotionAllowed, false);
|
||||||
|
assert.match(diagnostics.transcriptHash, /^[0-9a-f]{8}$/);
|
||||||
|
assert.match(diagnostics.dbFileHash, /^[0-9a-f]{8}$/);
|
||||||
|
|
||||||
|
assert.equal(port.close().promotionAllowed, false);
|
||||||
|
|
||||||
|
console.log("tool_db_process_port_sdk=ok");
|
||||||
6
wasm-port/tests/sdk/node/verify_tool_db_process_port.sh
Normal file
6
wasm-port/tests/sdk/node/verify_tool_db_process_port.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
|
||||||
|
node "$ROOT_DIR/tests/sdk/node/verify_tool_db_process_port.mjs"
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { resolve } from "node:path";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createLinuxCncToolDbProcessPort,
|
||||||
|
createToolDbProcessDiagnostics,
|
||||||
|
createToolDbTransactionPlan,
|
||||||
|
validateToolDbTranscript,
|
||||||
|
} from "../../../runtime/sdk/src/tool-db-process-port.js";
|
||||||
|
import {
|
||||||
|
createToolDbStorePaths,
|
||||||
|
} from "../../../runtime/opfs/tool-db-store.js";
|
||||||
|
|
||||||
|
const iniText = readFileSync(
|
||||||
|
resolve("linuxcnc/configs/sim/axis/db_demo/db_nonran.ini"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
assert.match(iniText, /DB_PROGRAM\s*=\s*\.\/db_nonran\.py/);
|
||||||
|
|
||||||
|
const plan = createToolDbTransactionPlan();
|
||||||
|
assert.equal(plan.length, 5);
|
||||||
|
assert.equal(plan[0].expect, "v2.1");
|
||||||
|
assert.equal(plan.some((step) => step.line === "g"), true);
|
||||||
|
assert.equal(plan.some((step) => step.line === "p t11 p111 d0.33 z0.11"), true);
|
||||||
|
assert.equal(plan.some((step) => step.line === "l t14 p0"), true);
|
||||||
|
assert.equal(plan.some((step) => step.line === "u t0 p0"), true);
|
||||||
|
|
||||||
|
const port = createLinuxCncToolDbProcessPort({
|
||||||
|
dbProgramPath: "./db_nonran.py",
|
||||||
|
sourceFiles: [
|
||||||
|
"configs/sim/axis/db_demo/db_nonran.py",
|
||||||
|
"configs/sim/axis/db_demo/db.py",
|
||||||
|
"lib/python/tooldb.py",
|
||||||
|
],
|
||||||
|
runtimeMode: "contract-only",
|
||||||
|
});
|
||||||
|
assert.equal((await port.start()).runtimeExecutionReady, false);
|
||||||
|
assert.equal((await port.runTransactionPlan()).status, "blocked_runtime_adapter_required");
|
||||||
|
|
||||||
|
const transcript = [
|
||||||
|
{ direction: "read", line: "v2.1" },
|
||||||
|
{ direction: "write", line: "g" },
|
||||||
|
{ direction: "read", line: "T10 P110 D0.10 Z0.10" },
|
||||||
|
{ direction: "read", line: "FINI (get_cmd)" },
|
||||||
|
{ direction: "write", line: "p t11 p111 d0.33 z0.11" },
|
||||||
|
{ direction: "write", line: "l t14 p0" },
|
||||||
|
{ direction: "write", line: "u t0 p0" },
|
||||||
|
];
|
||||||
|
assert.equal(validateToolDbTranscript(transcript).ready, true);
|
||||||
|
|
||||||
|
const paths = createToolDbStorePaths("db-demo", { runId: "run-1" });
|
||||||
|
assert.equal(paths.dbFile, "linuxcnc/machines/db-demo/tool-db/db_nonran_file");
|
||||||
|
assert.equal(paths.transcript, "linuxcnc/machines/db-demo/tool-db/transcripts/run-1/transcript.json");
|
||||||
|
|
||||||
|
const diagnostics = createToolDbProcessDiagnostics({
|
||||||
|
dbProgramPath: "./db_nonran.py",
|
||||||
|
opfsDbPath: "/machines/db-demo/tool-db/db_nonran_file",
|
||||||
|
transcript,
|
||||||
|
dbFileText: "T11 P111 D0.33 Z0.11\n",
|
||||||
|
startupToolCount: 10,
|
||||||
|
mutationCount: 3,
|
||||||
|
});
|
||||||
|
assert.equal(diagnostics.tblFallbackSufficient, false);
|
||||||
|
assert.equal(diagnostics.runtimeExecutionReady, false);
|
||||||
|
assert.equal(diagnostics.executionEnabled, false);
|
||||||
|
assert.equal(diagnostics.promotionAllowed, false);
|
||||||
|
|
||||||
|
console.log("tool_db_process_port_wasm=ok");
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
|
||||||
|
node "$ROOT_DIR/tests/wasm/node/verify_tool_db_process_port_wasm.mjs"
|
||||||
Reference in New Issue
Block a user