diff --git a/wasm-port/docs/compatibility-validation.md b/wasm-port/docs/compatibility-validation.md index 5f31b51..640d756 100644 --- a/wasm-port/docs/compatibility-validation.md +++ b/wasm-port/docs/compatibility-validation.md @@ -266,6 +266,11 @@ Negative fixtures currently cover: - missing tool - missing tool length offset +The negative fixture expectations are also checked against upstream +`rs274 -g`: the baseline requires LinuxCNC to reject each program, to emit the +expected error text, and to omit the canonical event lines marked as absent in +`tests/fixtures/canon_errors/`. + ## Validation Boundaries Current full-core validation is native-only. WASM/SDK validation covers the @@ -520,7 +525,9 @@ numbered-parameter, local named-parameter plus `_ini[...]` lookup through 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 +program-end cleanup calls. The same upstream baseline also validates the +current negative fixture error text and absent canonical-event constraints. +Fixtures that depend on standalone-only runtime adapters, HAL/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. diff --git a/wasm-port/docs/drift-report.md b/wasm-port/docs/drift-report.md index aa66e99..76fb9fd 100644 --- a/wasm-port/docs/drift-report.md +++ b/wasm-port/docs/drift-report.md @@ -96,7 +96,9 @@ semantic rewrites: select/change/length-offset, canned-cycle, state-tag motion, tool-table setup, and O-word subroutine fixtures; it also covers threading/rigid tap, NURBS dispatch boundaries, and comparable canonical runtime edge and - program-end cleanup calls. + program-end cleanup calls. It now also checks the negative fixture set + against upstream `rs274 -g` for expected error text and absent canonical + event constraints. HAL-backed adapter-heavy fixtures, standalone modal-state assertions, and upstream `rs274` output gaps such as `WAIT` or hidden NURBS control-point detail still need dedicated native LinuxCNC baselines. diff --git a/wasm-port/docs/scope-and-baseline.md b/wasm-port/docs/scope-and-baseline.md index 43238a3..7c665cb 100644 --- a/wasm-port/docs/scope-and-baseline.md +++ b/wasm-port/docs/scope-and-baseline.md @@ -65,6 +65,9 @@ Negative fixture coverage includes: - missing tool - missing tool length offset +The native baseline compares those negative fixtures with upstream +`rs274 -g` for expected error text and absent canonical-event constraints. + Machine baseline is still limited to standalone interpreter, trajectory planner, LinuxCNC identity/trivial kinematics, LinuxCNC `5axiskins` XYZBCW bridge-mill probing, and LinuxCNC TRT `xyzac`/`xyzbc` probing. Additional diff --git a/wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh b/wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh index 2014dcd..2a7e9f2 100755 --- a/wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh +++ b/wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh @@ -5,6 +5,8 @@ ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" UPSTREAM_RS274="$ROOT_DIR/../linuxcnc/bin/rs274" GCODE_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode" CANON_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon" +GCODE_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode_errors" +CANON_ERROR_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon_errors" FIXTURES=( minimal_linear @@ -37,6 +39,18 @@ FIXTURES=( tool_reload ) +ERROR_FIXTURES=( + arc_radius_mismatch + arc_zero_radius + cutter_comp_plane_change + g1_zero_feed + g53_incremental + namedparam_readonly + numbered_param_readonly + tool_length_offset_not_found + tool_not_found +) + if [[ ! -x "$UPSTREAM_RS274" ]]; then echo "missing upstream rs274 executable: $UPSTREAM_RS274" >&2 exit 1 @@ -807,6 +821,13 @@ filter_to_expected_event_keys() { ' "$expected_norm" - } +normalize_absent_standalone_event() { + local absent_line="$1" + local event="${absent_line#absent=canon_event=}" + + printf 'canon_event=%s\n' "$event" | normalize_standalone_events +} + for name in "${FIXTURES[@]}"; do gcode_file="$GCODE_FIXTURE_DIR/$name.ngc" expected_file="$CANON_FIXTURE_DIR/$name.events" @@ -903,4 +924,53 @@ for name in "${FIXTURES[@]}"; do fi done +for name in "${ERROR_FIXTURES[@]}"; do + gcode_file="$GCODE_ERROR_FIXTURE_DIR/$name.ngc" + expected_file="$CANON_ERROR_FIXTURE_DIR/$name.expected" + native_raw="$TMP_DIR/$name.error.rs274.raw" + native_norm="$TMP_DIR/$name.error.rs274.normalized" + + if [[ ! -f "$gcode_file" ]]; then + echo "missing negative G-code fixture: $gcode_file" >&2 + exit 1 + fi + + if [[ ! -f "$expected_file" ]]; then + echo "missing negative expected fixture: $expected_file" >&2 + exit 1 + fi + + set +e + "$UPSTREAM_RS274" -g "$gcode_file" > "$native_raw" 2>&1 + rs274_rc=$? + set -e + + if [[ "$rs274_rc" == "0" ]]; then + echo "upstream rs274 unexpectedly succeeded for negative fixture: $name" >&2 + sed -n '1,160p' "$native_raw" >&2 + exit 1 + fi + + normalize_upstream_rs274_output < "$native_raw" > "$native_norm" + + while IFS= read -r expected_line; do + [[ -z "$expected_line" ]] && continue + if [[ "$expected_line" == error_text=* ]]; then + expected_error="${expected_line#error_text=}" + if ! grep -Fq "$expected_error" "$native_raw"; then + echo "missing upstream rs274 error text for fixture $name: $expected_error" >&2 + sed -n '1,160p' "$native_raw" >&2 + exit 1 + fi + elif [[ "$expected_line" == absent=canon_event=* ]]; then + absent_norm="$(normalize_absent_standalone_event "$expected_line")" + if grep -Fxq "$absent_norm" "$native_norm"; then + echo "unexpected upstream rs274 event for fixture $name: $absent_norm" >&2 + sed -n '1,160p' "$native_raw" >&2 + exit 1 + fi + fi + done < "$expected_file" +done + echo "native LinuxCNC fixture baseline validation complete"