Files
cnc_wams/wasm-port/docs/compatibility-validation.md
wangdequan 7e42efc48e 按规划继续工作
结论:将 INI 派生非法参数文件和刀具表文件名的拒绝验证扩展到真实 Chromium OPFS 与 LinuxCNC INI WASM 路径,并通过 host/WASM/browser 聚合验证。
2026-06-08 09:07:23 +08:00

21 KiB

Compatibility Validation

Purpose

This document records how the standalone LinuxCNC WASM port currently proves that migrated behavior remains tied to LinuxCNC source code and fixture semantics.

The primary native validation command is:

wasm-port/tests/native/verify_native_probes.sh

The current WASM smoke validation command is:

wasm-port/tests/wasm/node/verify_ini_wasm.sh

The current WASM interpreter-core smoke validation command is:

wasm-port/tests/wasm/node/verify_interp_wasm.sh

The current OPFS host-boundary validation command is:

wasm-port/tests/opfs/node/verify_file_service.sh

The current browser smoke validation command is:

wasm-port/tests/browser/verify_ini_panel_browser.sh

The current browser interpreter smoke validation command is:

wasm-port/tests/browser/verify_interp_browser.sh

The current aggregate host/WASM/browser smoke command is:

wasm-port/tests/host/verify_host_smokes.sh

Validation Chain

The native validation script runs these checks in order:

  1. tools/verify_upstream_baseline.sh Confirms ../linuxcnc is at the recorded upstream commit in tools/upstream-baseline.txt.
  2. tools/verify_vendor_sync.sh Confirms every manifest file is present in vendor/linuxcnc/, no extra vendored file exists, and every vendored file is byte-identical to upstream.
  3. tools/verify_no_standalone_cnc_semantics.sh Confirms standalone code has not introduced project-owned Interp::... member definitions outside the documented Python/remap runtime-edge stubs.
  4. tools/verify_native_linuxcnc_fixture_baseline.sh Runs a side-by-side fixture baseline through upstream ../linuxcnc/bin/rs274 and compares normalized canonical events for fixtures that do not require standalone-only runtime adapters.
  5. tools/build_native_probes.sh Builds native source probes and standalone harnesses from vendored LinuxCNC source plus narrow runtime wrappers.
  6. tests/native/verify_native_probes.sh Checks probe exit codes, source-probe coverage, harness stdout, canonical fixture events, and expected error behavior.

The WASM INI smoke script builds runtime/ui/ini-panel/linuxcnc_ini.js and linuxcnc_ini.wasm from vendored LinuxCNC inifile.cc, then loads that module through runtime/sdk/src/index.js in Node and verifies INI string and boolean queries against a file written to the Emscripten filesystem. Boolean conversion is validated through vendored LinuxCNC iniFindBool().

The WASM interpreter-core smoke script builds build/wasm/core/linuxcnc_interp.js and linuxcnc_interp.wasm from the same vendored LinuxCNC interpreter source set used by the native minimal interpreter harness. It loads the module in Node through runtime/sdk/src/index.js, runs the first WASM interpreter fixture group through Interp::execute(), and compares emitted canonical events plus required LinuxCNC _setup state readback with the matching files in tests/fixtures/canon/. It also writes selected G-code fixtures into the Emscripten filesystem through the SDK and runs them through LinuxCNC Interp::open(), Interp::read(), and Interp::execute() to validate the file execution path. The same Node smoke writes LinuxCNC-format parameter files into the Emscripten filesystem and validates vendored Interp::restore_parameters() and Interp::save_parameters(), including the saved parameter values and .bak backup file boundary.

The OPFS host-boundary script validates the JavaScript file-service adapter with a Node mock of the browser File System Access handles. It covers nested directory creation, text save/load, missing file behavior, invalid relative paths, unavailable OPFS storage, and the host-side OPFS path model for INI, tool table, parameter, G-code, preview-cache, and session-snapshot storage targets. It also validates the host-side session snapshot JSON envelope and round-trip store plus pure-text machine file and G-code stores without defining CNC machine-state or file-format semantics. It now also validates the OPFS-to-WASM parameter-file bridge with a mock interpreter SDK to ensure the host boundary copies text into and out of the WASM filesystem without defining parameter semantics, and that INI-derived machine file names are still rejected by the OPFS path model when they contain traversal or nested path segments.

The browser INI/OPFS smoke script serves wasm-port/ over localhost and runs Chromium headless against a test page that imports the JS SDK, loads the INI WASM module, queries vendored LinuxCNC INI parsing through the SDK, and performs an OPFS text-file, generic session snapshot, machine file, and G-code text round trip.

The browser interpreter smoke script serves wasm-port/ over localhost and runs Chromium headless against a test page that loads the interpreter-core WASM module through runtime/sdk/src/index.js, writes no CNC behavior in JavaScript, and verifies existing canonical fixtures through the exported C ABI backed by vendored LinuxCNC Interp::execute() and Interp::open()/read()/execute() paths, including the INI-aware named-parameter file path and negative interpreter fixtures with expected error text plus absent canonical motion output. It also uses real browser OPFS storage plus the interpreter SDK to restore and save a LinuxCNC parameter file through vendored Interp::restore_parameters() and Interp::save_parameters(), to load/save LinuxCNC tool tables through vendored tooldata_common.cc, and to reject invalid INI-derived parameter/tool-table file names through the OPFS path model after the names are parsed by the LinuxCNC-backed INI WASM SDK.

The aggregate host smoke script builds the INI and interpreter-core WASM artifacts once, then runs the Node WASM smokes, the Node OPFS mock smoke, and the Chromium browser smokes.

Source Coverage

Every .c and .cc entry in tools/source-manifest.txt must have a corresponding *_source_probe entry in build/native/source-probes.tsv. The validation fails if:

  • a manifest source file lacks a source probe;
  • a source probe references a file not listed in the manifest;
  • a manifest file is duplicated;
  • vendored files drift byte-for-byte from upstream LinuxCNC.

Current Native Harnesses

Harness Purpose
linuxcnc_ini_probe Validates vendored LinuxCNC INI parsing can be used standalone.
linuxcnc_interp_state_probe Validates interpreter state constants and structs compile under the standalone boundary.
linuxcnc_emc_status_probe Validates the standalone emcStatus machine-units status boundary used by vendored interpreter conversion and initialization code.
linuxcnc_namedparam_harness Validates LinuxCNC named parameter behavior, _ini[...], and _hal[...] adapter resolution.
linuxcnc_interp_minimal_harness Runs G-code fixtures through vendored LinuxCNC parser/execution/conversion code, captures canonical events, and validates feed-rate state readback across length-unit changes.
linuxcnc_parameter_file_harness Validates LinuxCNC parameter file restore/save behavior and required/read-only parameter handling.
linuxcnc_interp_init_harness Validates vendored LinuxCNC Interp::init() emits canonical initialization boundaries, reads metric/inch machine units, and synchronizes current/selected tool slots through standalone status adapters.
linuxcnc_indexer_harness Validates vendored LinuxCNC single-axis rotary indexer dispatch emits lock/unlock and motion boundaries through the standalone event sink.
linuxcnc_tp_api_probe Validates vendored LinuxCNC trajectory planner calls for linear, arc, and queued motion paths.
linuxcnc_kinematics_probe Validates vendored LinuxCNC trivkins.c plus kins_util.c initialize and perform identity forward/inverse mapping through the standalone HAL/RTAPI boundary.
linuxcnc_5axis_kinematics_probe Validates vendored LinuxCNC 5axiskins.c through switchkins.c, including 5-axis forward/inverse round-trip behavior and switching to identity kinematics.
linuxcnc_xyzac_trt_kinematics_probe Validates vendored LinuxCNC XYZAC TRT kinematics through switchkins.c, including forward/inverse round-trip behavior and switching to identity kinematics.
linuxcnc_xyzbc_trt_kinematics_probe Validates vendored LinuxCNC XYZBC TRT kinematics through switchkins.c, including forward/inverse round-trip behavior and switching to identity kinematics.
linuxcnc_corexy_kinematics_probe Validates vendored LinuxCNC CoreXY forward/inverse behavior through the standalone HAL/RTAPI boundary.
linuxcnc_rotate_kinematics_probe Validates vendored LinuxCNC rotated-axis forward/inverse behavior.
linuxcnc_rose_kinematics_probe Validates vendored LinuxCNC rose kinematics forward/inverse behavior.
linuxcnc_max_kinematics_probe Validates vendored LinuxCNC max kinematics forward/inverse behavior.
linuxcnc_lineardelta_kinematics_probe Validates vendored LinuxCNC linear-delta inverse/forward pose round-trip behavior.
linuxcnc_rotarydelta_kinematics_probe Validates vendored LinuxCNC rotary-delta inverse/forward pose round-trip behavior.
linuxcnc_scorbot_kinematics_probe Validates vendored LinuxCNC Scorbot forward/inverse behavior and pose round-trip behavior.
linuxcnc_tripod_kinematics_probe Validates vendored LinuxCNC tripod inverse/forward behavior, including below-platform flag behavior.
linuxcnc_scara_kinematics_probe Validates vendored LinuxCNC SCARA forward/inverse behavior and switching to identity kinematics.
linuxcnc_puma_kinematics_probe Validates vendored LinuxCNC PUMA forward/inverse behavior, pose round-trip behavior, and switching to identity kinematics.
linuxcnc_genser_kinematics_probe Validates vendored LinuxCNC generic serial kinematics forward/inverse behavior and switching to identity kinematics.
linuxcnc_genhex_kinematics_probe Validates vendored LinuxCNC generic hexapod inverse/forward behavior, including the switchkins iterative-forward warmup path.
linuxcnc_pentakins_kinematics_probe Validates vendored LinuxCNC pentapod inverse/forward pose round-trip behavior.

Current WASM Harnesses

Harness Purpose
tests/wasm/node/verify_ini_wasm.sh Validates the browser-facing INI WASM module can be built from vendored LinuxCNC inifile.cc, loaded through the JS SDK in Node, and queried through the exported C ABI.
tests/wasm/node/verify_interp_wasm.sh Validates the initial interpreter-core WASM module can be built from vendored LinuxCNC interpreter source, loaded through the interpreter JS SDK, run the first fixture group through Interp::execute() and selected file fixtures through Interp::open()/read()/execute(), match the native canonical event plus required state readback fixtures, and run parameter-file restore/save through vendored LinuxCNC Interp::restore_parameters() and Interp::save_parameters().
tests/opfs/node/verify_file_service.sh Validates the host-owned OPFS text-file adapter, path model, session snapshot store, machine file store, G-code text store, OPFS-to-WASM parameter/tool-table bridges, and grouped machine-session loading without moving file persistence, parameter semantics, or tool-table semantics into the WASM core.
tests/browser/verify_ini_panel_browser.sh Validates the INI SDK, INI/interpreter WASM module loading, OPFS text-file round trip, generic session snapshot round trip, machine file text round trip, G-code text round trip, and the INI panel UI's machine-session load, G-code run, and canonical-event display paths in a real browser runtime.
tests/browser/verify_interp_browser.sh Validates the interpreter-core WASM module loads through the interpreter JS SDK in a real browser runtime and runs selected positive and negative canonical fixtures through vendored LinuxCNC Interp::execute() plus Interp::open()/read()/execute() via the exported C ABI, including OPFS-backed parameter-file restore/save and tool-table load/save through vendored LinuxCNC source.
tests/host/verify_host_smokes.sh Runs the current host-side Node, WASM interpreter-core, OPFS, and browser smoke validation with shared WASM builds.

Fixture Coverage

Positive G-code fixtures currently cover:

  • linear traverse/feed
  • arc semantics
  • modal absolute/incremental motion
  • position parameters
  • canned cycles
  • coordinate offsets
  • G53 machine-coordinate motion
  • feed and motion control modes
  • probing
  • threading and rigid tap
  • NURBS G5/G6
  • spindle orient
  • tool semantics
  • tool table setup
  • tool-data reload boundary
  • interpreter state-tag boundary
  • percent-delimited file FINISH boundary
  • file-open ON_RESET boundary
  • comment logging canonical calls
  • named and numbered parameters
  • O-word subroutines
  • program-end modal reset
  • canonical runtime edge calls

Negative fixtures currently cover:

  • zero-feed G1
  • arc radius mismatch
  • zero-radius arc
  • G53 incremental-mode rejection
  • read-only named parameter writes
  • read-only numbered parameter writes
  • missing tool
  • missing tool length offset

Validation Boundaries

Current full-core validation is native-only. WASM/SDK validation covers the INI parser smoke harness and an initial interpreter-core canonical event smoke for minimal_linear, arc_semantics, length_units, modal_incremental, plane_selection, coordinate_offsets, g53_machine_coordinates, feed_control_modes, position_params, probe_semantics, spindle_orient, comment_logging, numbered_params, tool_semantics, tool_table_setup, tool_reload, canned_cycles, cutter_comp_motion, threading_sync, nurbs_g5_semantics, nurbs_g6_semantics, state_tag_motion, canon_runtime_edges, program_end_modal_reset, and namedparam_semantics, plus the g1_zero_feed, arc_radius_mismatch, arc_zero_radius, cutter_comp_plane_change, g53_incremental, namedparam_readonly, numbered_param_readonly, tool_not_found, and tool_length_offset_not_found negative fixtures. The WASM interpreter file path additionally covers the same canonical-event fixture group, plus namedparam_semantics through the INI-aware file execution ABI, file_open_reset, percent_file_finish, and oword_subroutine. position_params uses a dedicated file-path expectation under tests/fixtures/canon_file/ because LinuxCNC file execution advances the post-execute position parameters differently than the line-by-line MDI smoke. The Node WASM interpreter smoke also covers LinuxCNC parameter-file restore/save behavior through the exported C ABI, including out-of-order file rejection, missing-file success, required numeric parameter writeback, removal of named-parameter-only lines from saved output, and the .bak backup produced by vendored save_parameters(). It also covers LinuxCNC tool-table load/save behavior through vendored tooldata_common.cc, including the non-random and random-toolchanger tooldata_init() branches, with the SDK only copying text into the Emscripten filesystem and calling the exported C ABI. OPFS validation covers the JavaScript host-boundary adapter, the INI browser smoke harness, the INI panel UI's machine-session load and G-code run buttons, the raw canonical-event display fed directly by LinuxCNC interpreter WASM output, the Node parameter/tool-table bridges that copy OPFS text through the SDK into vendored LinuxCNC file APIs, the Node machine-session bridge that groups INI, parameter, and tool-table loading, the random-toolchanger flag derived from vendored LinuxCNC INI boolean parsing, INI-derived [RS274NGC]PARAMETER_FILE and [EMCIO]TOOL_TABLE file names mapped to OPFS machine files, OPFS path-model rejection of invalid INI-derived file names, and a browser interpreter smoke that uses the same session bridge with real LinuxCNC INI WASM parsing before saving OPFS-backed parameter and tool-table text through vendored LinuxCNC file APIs. Full browser coverage, full SDK coverage, and richer machine-state validation remain future work.

WASM/Browser Fixture Matrix

The executable fixture lists for Node WASM and browser interpreter smoke tests are centralized in tests/fixtures/interp-fixture-matrix.mjs. Additions to the matrix must continue to route execution through the SDK and exported C ABI backed by vendored LinuxCNC interpreter code; the matrix is only a test coverage list, not a CNC behavior implementation.

Node WASM Interp::execute() coverage currently includes:

  • minimal_linear
  • arc_semantics
  • length_units
  • modal_incremental
  • plane_selection
  • coordinate_offsets
  • g53_machine_coordinates
  • feed_control_modes
  • position_params
  • probe_semantics
  • spindle_orient
  • comment_logging
  • numbered_params
  • tool_semantics
  • tool_table_setup
  • tool_reload
  • canned_cycles
  • cutter_comp_motion
  • threading_sync
  • nurbs_g5_semantics
  • nurbs_g6_semantics
  • state_tag_motion
  • canon_runtime_edges
  • program_end_modal_reset
  • namedparam_semantics through the INI-aware program ABI

Node WASM file-path coverage currently includes:

  • minimal_linear
  • arc_semantics
  • length_units
  • modal_incremental
  • plane_selection
  • coordinate_offsets
  • g53_machine_coordinates
  • feed_control_modes
  • probe_semantics
  • spindle_orient
  • comment_logging
  • numbered_params
  • tool_semantics
  • tool_table_setup
  • tool_reload
  • canned_cycles
  • cutter_comp_motion
  • threading_sync
  • nurbs_g5_semantics
  • nurbs_g6_semantics
  • state_tag_motion
  • canon_runtime_edges
  • program_end_modal_reset
  • file_open_reset
  • percent_file_finish
  • oword_subroutine
  • position_params through the dedicated canon_file/ expectation
  • namedparam_semantics through the INI-aware file ABI

Browser interpreter Interp::execute() coverage currently includes:

  • minimal_linear
  • arc_semantics
  • length_units
  • modal_incremental
  • plane_selection
  • coordinate_offsets
  • g53_machine_coordinates
  • feed_control_modes
  • canned_cycles
  • numbered_params
  • comment_logging
  • tool_semantics
  • tool_table_setup
  • probe_semantics
  • spindle_orient
  • cutter_comp_motion
  • threading_sync
  • nurbs_g5_semantics
  • nurbs_g6_semantics
  • state_tag_motion
  • canon_runtime_edges
  • tool_reload
  • program_end_modal_reset

Browser interpreter negative coverage currently includes every fixture under tests/fixtures/gcode_errors/:

  • g1_zero_feed
  • arc_radius_mismatch
  • arc_zero_radius
  • g53_incremental
  • cutter_comp_plane_change
  • namedparam_readonly
  • numbered_param_readonly
  • tool_length_offset_not_found
  • tool_not_found

Browser interpreter file-path coverage currently includes the same INTERP_FILE_FIXTURES list as the Node WASM smoke:

  • minimal_linear
  • arc_semantics
  • length_units
  • modal_incremental
  • plane_selection
  • coordinate_offsets
  • g53_machine_coordinates
  • feed_control_modes
  • probe_semantics
  • spindle_orient
  • comment_logging
  • numbered_params
  • tool_semantics
  • tool_table_setup
  • tool_reload
  • canned_cycles
  • cutter_comp_motion
  • threading_sync
  • nurbs_g5_semantics
  • nurbs_g6_semantics
  • state_tag_motion
  • canon_runtime_edges
  • program_end_modal_reset
  • file_open_reset
  • percent_file_finish
  • oword_subroutine
  • position_params through the dedicated canon_file/ expectation
  • namedparam_semantics through the INI-aware file ABI

All current positive G-code fixtures have browser interpreter smoke coverage through either Interp::execute(), the file-path ABI, or the INI-aware file-path ABI.

The current fixture expectations validate standalone behavior against both the vendored LinuxCNC source path and an upstream rs274 side-by-side baseline for parser/conversion, arc geometry, offsets, feed-control and feed-state readback, comment/logging, numbered-parameter, probing, spindle-orient, file-open reset, file-finish, tool-reload, tool select/change/length-offset, canned-cycle, state-tag motion, tool-table setup, and O-word subroutine fixtures, plus threading/rigid tap, NURBS dispatch boundaries, and the comparable canonical runtime edge and program-end cleanup calls. Fixtures that depend on standalone-only runtime adapters, HAL/INI/tool-change state, upstream rs274 output gaps such as WAIT or hidden NURBS control-point detail, or richer machine session state still need dedicated native LinuxCNC baselines.

Remaining positive fixtures that are not in the upstream rs274 side-by-side baseline are intentionally held out until they get a dedicated native LinuxCNC baseline: namedparam_semantics depends on standalone INI/HAL adapter resolution. state_tag_motion now compares its motion events with upstream rs274, while UPDATE_TAG events remain a standalone state-tag capture boundary. tool_semantics now compares T/M6/G43/G49 canonical events with upstream rs274; M61 current-pocket host-state behavior remains covered by the standalone fixture expectation, and Interp::synch() current/selected tool slot reads are covered by the native init harness.

The kinematics probes currently cover LinuxCNC identity/trivial kinematics, the switchable 5axiskins XYZBCW bridge-mill model, TRT xyzac/xyzbc table-rotary models, CoreXY, rotated-axis, rose, max, linear-delta, rotary-delta, Scorbot, tripod, SCARA, PUMA, generic serial, generic hexapod, and pentapod models.