Expand LinuxCNC interpreter regression coverage

This commit is contained in:
2026-06-09 14:54:54 +08:00
parent 50757e45ba
commit 5bd8f12872
143 changed files with 10895 additions and 219 deletions

View File

@@ -100,12 +100,40 @@ wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```
Layer 4 sim-config staging uses `planSimConfigStaging()` to collect
Layer 4 INI-context staging uses `planIniFileContextStaging()` to collect
INI-declared `[DISPLAY]OPEN_FILE`, `[EMCIO]TOOL_TABLE`,
`[RS274NGC]PARAMETER_FILE`, `[RS274NGC]SUBROUTINE_PATH`,
`[RS274NGC]USER_M_PATH`, and remap-NGC files from the vendored source
manifest. That planner is a host filesystem helper only; execution still goes
through vendored LinuxCNC interpreter/remap/tool/parameter code.
manifest without browser directory enumeration. `planSimConfigStaging()` is the
`configs/sim` wrapper around that generic planner. These planners are host
filesystem helpers only; execution still goes through vendored LinuxCNC
interpreter/remap/tool/parameter code.
Layer responsibilities are intentionally narrow:
| Layer | LinuxCNC-owned behavior | Host/WASM adapter allowance | Expected-failure policy |
| --- | --- | --- | --- |
| 1 | `nc_files` parsing and execution through upstream `rs274` | Generate only the native harness INI/tool-table context needed to classify upstream examples | Expected failures document missing machine/task context or known upstream example edges; they must not be made pass by changing G-code semantics. |
| 2 | `configs/sim` file execution through upstream `rs274` with sim INI context | Locate the corresponding INI/tool table and classify main programs, macros, and remap subroutines | Expected failures document upstream standalone `rs274` limits such as task/user-M process edges and the preserved `incremental_repetition_g533.ngc` demo edge. |
| 3 | Vendored LinuxCNC interpreter, remap, tool, parameter, kinematics, and planner code | Provide deterministic runtime shims for filesystem, HAL/user-M boundaries, machine status, and build/source-probe coverage | A standalone pass may cover a runtime edge that Layer 1/2 cannot provide, but it must still call vendored LinuxCNC source for CNC behavior. |
| 4 | Vendored LinuxCNC C ABI behavior from generated WASM modules | Stage files, apply executable bits, persist OPFS text, generate manifest-based staging plans, and forward paths/results between JS/browser and C ABI | A WASM/browser pass proves the host boundary can reproduce the staged LinuxCNC context; it does not replace native source validation or justify JS-owned CNC semantics. |
## Layer 2 Expected Failures
The current `wasm-port/tests/native/verify_sim_configs.sh` run reports
`total: 159`, `pass: 151`, `expected_fail: 8`, and `unexpected_fail: 0`.
The eight expected failures are:
| Program | Layer 2 classification | Current Layer 3/4 coverage or boundary |
| --- | --- | --- |
| `axis/foam/foam.ngc` | `ini-axis-mask-UV`; native upstream `bin/rs274` rejects `U`/`V` words before the standalone runtime applies the INI machine axis mask. | Covered by `wasm-port/tests/native/verify_native_probes.sh`, `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh`, and `wasm-port/tests/browser/verify_interp_browser.sh`, which run the vendored file with `axis_foam.ini` and verify `U/V` axis acceptance through LinuxCNC-backed file execution. |
| `axis/vismach/5axis/bridgemill/5axisgui.ngc` | `ini-axis-mask-W`; native upstream `bin/rs274` rejects the `W` word outside the bridge-mill runtime context. | Covered by `wasm-port/tests/native/verify_native_probes.sh`, `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh`, and `wasm-port/tests/browser/verify_interp_browser.sh`, which stage `5axis.ini`, the tool table, and remap subroutines, then execute through the vendored LinuxCNC remap/file path. |
| `axis/geometry/xyzc.ngc` | `user-m-code-M110`; native upstream `bin/rs274` does not register or execute the sim-config `USER_M_PATH` handler. | Covered by `wasm-port/tests/native/verify_native_probes.sh`, `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh`, and `wasm-port/tests/browser/verify_interp_browser.sh`; the smoke assertions require `canon_event=USER_M_COMMAND code=M110` and reject `Unknown m code used: M110`. |
| `axis/external_offsets/dyn_demo.ngc` | `user-m-code-M111`; native upstream `bin/rs274` does not register or execute the sim-config `USER_M_PATH` handler. | Covered by `wasm-port/tests/native/verify_native_probes.sh`, `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh`, and `wasm-port/tests/browser/verify_interp_browser.sh`; the smoke assertions require `canon_event=USER_M_COMMAND code=M111` and reject `Unknown m code used: M111`. |
| `axis/external_offsets/eoffsets.ngc` | `user-m-code-M111`; same standalone task/user-M boundary as `dyn_demo.ngc`. | Covered by `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh` and `wasm-port/tests/browser/verify_interp_browser.sh` with the vendored executable `M111` and `eoffset.tbl` staged from the manifest. |
| `axis/external_offsets/jwp_z.ngc` | `user-m-code-M111`; same standalone task/user-M boundary as `dyn_demo.ngc`. | Covered by `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh` and `wasm-port/tests/browser/verify_interp_browser.sh` with the vendored executable `M111` and `eoffset.tbl` staged from the manifest. |
| `axis/external_offsets/opa_demo.ngc` | `user-m-code-M111`; same standalone task/user-M boundary as `dyn_demo.ngc`, plus a subroutine dependency. | Covered by `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh` and `wasm-port/tests/browser/verify_interp_browser.sh`, which stage `M111`, `eoffset.tbl`, and the `SUBROUTINE_PATH` dependency `circles.ngc`. |
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc` | `upstream-demo-missing-motion-gcode`; upstream standalone `rs274` reports `Cannot use axis values without a g code that uses them`. | Preserved as an upstream demo expected failure. Do not make this pass by editing the G-code, changing JS interpreter behavior, or adding standalone semantics. |
## Validation Chain
@@ -205,10 +233,15 @@ It also calls vendored `Interp::init_named_parameters()` and
`Interp::find_named_param()` through the WASM C ABI to validate the native
named-parameter harness path for LinuxCNC built-in, INI-backed, HAL-backed,
and missing named-parameter lookup.
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. It also writes the vendored LinuxCNC `xyzac-trt` and
It also writes selected G-code fixtures and vendored `tests/interp/g10`
regressions 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, including G10 tool-table updates,
tool-length offset application timing, active G5X offset changes, G92
interaction, XY-rotation behavior, G52/G92 shared-offset transitions, and
G92 startup parameter-file persistence through vendored
`ini_load()`/`Interp::init()`/`restore_parameters()`, including
`DISABLE_G92_PERSISTENCE` clearing parameters 5210-5219. It also writes the vendored LinuxCNC `xyzac-trt` and
`xyzbc-trt` table-rotary-tilting sample machine INI, `remap_subs/*.ngc`, and
`xyzac_switchkins.ngc`/`xyzbc_switchkins.ngc`,
`xyzac_switchkins_test_1.ngc`, `xyzac_switchkins_test_2.ngc`,
@@ -252,7 +285,8 @@ same Node smoke writes the vendored LinuxCNC
`tests/interp/do-while-break`, `tests/interp/oword-bug315`,
`tests/interp/oword-bug315-p2`, `tests/interp/exists`,
`tests/interp/return-value`, `tests/interp/subs-follow-main`,
`tests/interp/fractional-linenumbers`, `tests/interp/namedparam-bug424`,
`tests/interp/fractional-linenumbers`, `tests/interp/cam-nisley` with its
upstream `test.tbl`, `tests/interp/namedparam-bug424`,
selected `tests/interp/rotation` pure interpreter cases, `tests/interp/iniparam`,
`tests/interp/iniparam-failassign`,
`tests/interp/sub-call-from-sub`, `tests/interp/sequence-number`, and
@@ -386,7 +420,9 @@ I/O semantics. It also writes vendored LinuxCNC `tests/interp/do-while-break`,
`tests/interp/oword-bug315`, `tests/interp/oword-bug315-p2`,
`tests/interp/exists`, `tests/interp/return-value`,
`tests/interp/subs-follow-main`, `tests/interp/fractional-linenumbers`,
`tests/interp/namedparam-bug424`, and selected `tests/interp/rotation`
`tests/interp/cam-nisley`, `tests/interp/namedparam-bug424`,
`tests/interp/inside-corners`,
`tests/interp/inverse-time-with-comp`, and selected `tests/interp/rotation`
`.ngc` files plus
`tests/interp/sub-call-from-sub` `test.ini`, `test.ngc`, and `subs/*.ngc`
files and `tests/interp/sequence-number` `test.ini`, `test.ngc`, and
@@ -396,9 +432,12 @@ files and `tests/interp/sequence-number` `test.ini`, `test.ngc`, and
`test.ini` and `test.ngc`, plus `tests/interp/m19` `test.ini` and `test.ngc`,
plus `tests/interp/magic_comments/param_format_printing` `test.ngc`,
plus selected pure-interpreter `tests/interp/m98m99` cases covering
Fanuc-style `M98/M99`, parameter scope, nested numbered subprograms,
subprograms after main program text, leading-zero O-word lookup, named and
numbered main programs, and expression-based O-sub/M98 calls,
Fanuc-style `M98/M99`, missing-P-word, missing-subprogram, mixed
Fanuc/RS274NGC sub-style, and `DISABLE_FANUC_STYLE_SUB` INI-gated errors,
main-program O-word termination rules, parameter scope, loop counts including
`L0`, nested numbered subprograms, subprograms after main program text,
leading-zero O-word lookup, named and numbered main programs, and
expression-based O-sub/M98 calls,
into the browser WASM filesystem and
validates those upstream
interpreter regressions through `runFile()` or `runFileWithIni()`, without
@@ -426,6 +465,7 @@ The validation fails if:
| --- | --- |
| `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_rs274_compile_probe` | Validates the upstream `tests/interp/compile` class remains a source/compile boundary rather than being misclassified as a runtime `.ngc` interpreter fixture. |
| `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. |
@@ -459,13 +499,13 @@ The validation fails if:
| 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, including LinuxCNC-backed boolean conversion and machine-session file-name string lookup. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the interpreter-core WASM module can be built from vendored LinuxCNC interpreter/remap source, loaded through the interpreter JS SDK, run the first fixture group through `Interp::execute()` and selected file fixtures plus vendored upstream `tests/interp` regression files through `Interp::open()`/`read()`/`execute()`, match the native canonical event plus required state readback fixtures, emit `run_step` execution-status records with LinuxCNC line number, encoded source statement, return code, and interpreter axis positions for file execution, cover vendored `tests/interp/flowsnake` recursive O-word file execution, selected `tests/interp/bad` file-error paths, and `tests/interp/g33.1` rigid-tap file execution, run vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo files through the WASM C ABI/SDK path, and run parameter-file restore/save through vendored LinuxCNC `Interp::restore_parameters()` and `Interp::save_parameters()`. |
| `tests/wasm/node/verify_sim_configs_wasm.sh` | Validates representative vendored LinuxCNC `configs/sim` programs in Node WASM through `planSimConfigStaging()` plus `runSimConfigProgram()`. The staging planner uses INI text and `tools/source-manifest.txt` to collect the program, INI, tool table, parameter file when vendored, `SUBROUTINE_PATH` files, `USER_M_PATH` files, and remap-NGC files before forwarding to `runFileWithIni()` or `runFiveAxisRemapFile()`. This covers INI-driven `U/V/W` axis mask handling, real `USER_M_PATH` registration for executable `M110`/`M111`, all four current external-offset M111 expected-failure programs, `SUBROUTINE_PATH` staging for `opa_demo.ngc -> circles.ngc`, bridge-mill remap-subroutine staging, and vendored LinuxCNC bridge-mill NGC remap execution without spawning host processes. The same smoke includes a synthetic staging-plan assertion for `TOOL_TABLE`, `PARAMETER_FILE`, `SUBROUTINE_PATH`, and `USER_M_PATH` collection. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the interpreter-core WASM module can be built from vendored LinuxCNC interpreter/remap source, loaded through the interpreter JS SDK, run the first fixture group through `Interp::execute()` and selected file fixtures plus vendored upstream `tests/interp` regression files through `Interp::open()`/`read()`/`execute()`, match the native canonical event plus required state readback fixtures, emit `run_step` execution-status records with LinuxCNC line number, encoded source statement, return code, and interpreter axis positions for file execution, cover vendored `tests/interp/flowsnake` recursive O-word file execution, `tests/interp/g6164` path-control and naive-cam tolerance execution, `tests/interp/oword-unwind` continue-on-error stack unwind behavior through planner-staged INI context, selected `tests/interp/bad` file-error paths, and `tests/interp/g33.1` rigid-tap file execution, run vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo files through the WASM C ABI/SDK path, and run parameter-file restore/save through vendored LinuxCNC `Interp::restore_parameters()` and `Interp::save_parameters()`. |
| `tests/wasm/node/verify_sim_configs_wasm.sh` | Validates representative vendored LinuxCNC `configs/sim` programs in Node WASM through `planSimConfigStaging()` plus `runSimConfigProgram()`. The generic `planIniFileContextStaging()` planner and its sim-config wrapper use INI text and `tools/source-manifest.txt` to collect the program, INI, tool table, parameter file when vendored, `SUBROUTINE_PATH` files, `USER_M_PATH` files, and remap-NGC files before forwarding to `runFileWithIni()` or `runFiveAxisRemapFile()`. This covers INI-driven `U/V/W` axis mask handling, real `USER_M_PATH` registration for executable `M110`/`M111`, all four current external-offset M111 expected-failure programs, `SUBROUTINE_PATH` staging for `opa_demo.ngc -> circles.ngc`, bridge-mill remap-subroutine staging, and vendored LinuxCNC bridge-mill NGC remap execution without spawning host processes. The same smoke includes synthetic staging-plan assertions for generic `TOOL_TABLE`, `PARAMETER_FILE`, multi-directory `SUBROUTINE_PATH`, `USER_M_PATH`, and `REMAP ... ngc=...` file collection. |
| `tests/wasm/node/verify_nc_files_wasm.sh` | Validates representative vendored LinuxCNC `nc_files` examples in Node WASM by copying `3D_Chips.ngc`, `arcspiral.ngc`, `hole-circle.ngc`, `factorial.ngc`, and `m6demo.ngc` into the Emscripten filesystem and forwarding to the LinuxCNC-backed `Interp::open()`/`read()`/`execute()` path. `3D_Chips.ngc` is staged with a minimal INI-declared `tool.tbl` because the upstream program contains `T1 M6`; JavaScript only stages files and checks LinuxCNC output, including `run_step` status records, and does not implement G-code, O-word, tool-change, or M-code behavior. |
| `tests/wasm/node/verify_tp_wasm.sh` | Validates a standalone trajectory-planner WASM module can be built from vendored LinuxCNC TP/TC/Ruckig support source, loaded in Node, and run the same linear, arc, and queued-line planner probe paths covered by the native TP harness. |
| `tests/opfs/node/verify_file_service.sh` | Validates the host-owned OPFS text-file adapter, path model, session snapshot store including custom filenames and envelope/path rejection paths, machine file store, G-code text store including filename rejection paths, 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, LinuxCNC-backed INI machine-session file-name string lookup, OPFS text-file round trip, generic session snapshot round trip plus custom filename and envelope/path rejection paths, machine file text round trip, G-code text round trip plus filename rejection paths, and the INI panel UI's machine-session load with default OPFS parameter/tool-table file mapping, G-code run, `run_step`-backed progress/line/statement/axis display, canonical-event display paths, and 5-axis remap demo action 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 plus vendored upstream `tests/interp` regression files through vendored LinuxCNC `Interp::execute()` and `Interp::open()`/`read()`/`execute()` via the exported C ABI, including direct browser SDK and OPFS-backed parameter-file restore/save, non-random/random tool-table load/save through vendored LinuxCNC source, vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo execution, representative vendored `configs/sim` `foam`, `geometry`, `external_offsets`, and bridge-mill programs through `runSimConfigProgram()`, and representative vendored `nc_files` examples through `runFile()` or `runFileWithIni()` when the upstream file requires INI/tool-table context. |
| `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 plus vendored upstream `tests/interp` regression files through vendored LinuxCNC `Interp::execute()` and `Interp::open()`/`read()`/`execute()` via the exported C ABI, including direct browser SDK and OPFS-backed parameter-file restore/save, non-random/random tool-table load/save through vendored LinuxCNC source, vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo execution, representative vendored `configs/sim` `foam`, `geometry`, `external_offsets`, and bridge-mill programs through `runSimConfigProgram()`, representative vendored `nc_files` examples through `runFile()` or `runFileWithIni()` when the upstream file requires INI/tool-table context, and a synthetic browser assertion that `planIniFileContextStaging()` can collect INI, program, tool-table, parameter, multi-directory subroutine, executable user-M, and remap-NGC files using only manifest text. |
| `tests/host/verify_host_smokes.sh` | Runs the current host-side Node, WASM interpreter-core, WASM trajectory-planner, OPFS, and browser smoke validation with shared WASM builds. |
## Fixture Coverage
@@ -493,6 +533,7 @@ Positive G-code fixtures currently cover:
- comment logging canonical calls
- local, INI-backed named parameters and numbered parameters
- O-word subroutines
- continue-on-error O-word unwind
- program-end modal reset
- canonical runtime edge calls
@@ -532,7 +573,8 @@ plus the `g1_zero_feed`, `arc_radius_mismatch`, `arc_zero_radius`,
path additionally covers the same canonical-event fixture group, plus
`namedparam_ini_semantics` and `namedparam_semantics` through the INI-aware
file execution ABI,
`file_open_reset`, `percent_file_finish`, and `oword_subroutine`.
`file_open_reset`, `percent_file_finish`, `oword_subroutine`,
`g6164`, and `oword_unwind`.
`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;
@@ -785,7 +827,20 @@ numbered-parameter, local named-parameter plus `_ini[...]` lookup through
tool-reload, tool select/change/length-offset, M61 current-tool-number update,
canned-cycle, state-tag motion, tool-table setup, and O-word subroutine
fixtures, plus vendored `tests/interp/flowsnake` recursive O-word toolpath,
selected upstream `tests/interp/bad` file-error paths, threading/rigid tap,
`tests/interp/cam-nisley` storm-door latch cam execution with upstream
tool-table context and a bare-run missing-tool negative check,
`tests/interp/inside-corners` cutter-compensation concave/convex/tangent
geometry across XY and ZX planes,
`tests/interp/inverse-time-with-comp` inverse-time feed and cutter-compensation
interaction,
selected upstream `tests/interp/bad` file-error paths including canned-cycle
A-axis rejection, center-format arc radius mismatch rejection, and
selected upstream `tests/interp/good` center-format arc tolerance acceptance,
selected `tests/interp/g72-*` lathe facing canned-cycle iteration regressions,
selected `tests/interp/g71-*` lathe roughing/finish canned-cycle regressions,
`tests/interp/g76` lathe threading with upstream tool-table context,
cutter-compensation rejection, selected standalone `tests/ccomp`
cutter-compensation file execution with upstream tool tables, threading/rigid tap,
vendored `tests/interp/g33.1` rigid-tap file execution, NURBS dispatch
boundaries, and the
comparable canonical runtime edge and program-end cleanup calls. The
@@ -873,9 +928,15 @@ numbered subroutine in the same external file, selected `tests/interp/rotation`
absolute-position `#<_abs_x>`, `#<_abs_y>`, and `#<_abs_z>` reporting under
G54, G92, XY rotation, and unit changes plus rotated-coordinate `G28` and
`G53` endpoint behavior, selected `tests/interp/m98m99`
Fanuc-style `M98/M99` subprogram calls, parameter-scope differences,
nested numbered subprograms, subprograms after main program text,
leading-zero O-word lookup, named/numbered main programs, and O-expression
calls, plus `(ABORT,...)` hot-comment numbered, named, and INI-parameter
Fanuc-style `M98/M99` subprogram calls, missing-P-word, missing-subprogram,
mixed Fanuc/RS274NGC sub-style, and `DISABLE_FANUC_STYLE_SUB` INI-gated
errors, main-program O-word termination rules, parameter-scope differences,
loop counts including `L0`, nested numbered subprograms, subprograms after main
program text, leading-zero O-word lookup, named/numbered main programs, and
O-expression calls, plus
`(ABORT,...)` hot-comment numbered, named, and INI-parameter
expansion, with skipped branch/subroutine messages and post-abort program end
asserted absent where applicable.
asserted absent where applicable. The same native, Node WASM, and browser
interpreter validation also stages an INI-declared variable file to verify
LinuxCNC G92 startup persistence and the `DISABLE_G92_PERSISTENCE` startup
clear path through vendored interpreter initialization.