The grblHAL harnesses keep what only a running controller shows; the
cases a host unit test in grblHAL-glowforge proves, and the log and
reply wording, leave.
- laser_lifecycle_test: test_arm_waits_for_the_fans goes. laser_arm_test
case A4 (grblHAL-glowforge) proves the fan grace stretching the arm's
acknowledgment budget, on the same arm path. The docstring names it.
- xy_mode_test: case_x32, case_invalid and the log checks go; the
default, x16 and the low tick stay. xy_scale_test holds each mode's
tick and the not-a-mode parse.
- planner_blocks_test: one restart, at $398 1000; the 400 pass and the
fresh-store probe go.
- ctlport_test: test_poll_lf and test_crlf go (the CR LF poll stays); in
test_sender_out the network turn-away goes (serial_test holds it), and
the busy gating, the grant and the outlives-client part stay.
test_port_dark is whole.
- mcode_test: the timeout case runs on the host build's 5 s
GFMCODE_WAIT_S (grblHAL-glowforge's CI configures it; the image keeps
30 s) and still shows the hold, at 5.1 s; 5 s outlasts the 3 s
test_dark watches the wait; test_table refuses one form per
parser branch. test_timeout_holds and test_dark stay.
- envelope_test: test_unset and test_bounds go (lens_home_test holds the
clamp); test_armed and the open, apply and close cases stay.
- manual_home_test: the out-of-range offset block goes, a repeat of
gfhome_clamp_home_mm (lens_home_test); the modal-M3 FIRE check and
every release and energize case stay.
- cool_report_test: one non-hex secret and one CR LF injection stay;
runner-malformed and the exact header-set checks go. A bad secret is
never sent and a good one is.
- tray_test: test_offset keeps 20 mm; test_errors keeps a bad P and a
bad axis; the frame shift, envelope, barrier, persistence, port op,
unreferenced lens and camera home stay.
Proof: with grblHAL-glowforge's matching commit, the eleven harnesses
its CI runs pass under Linux against the null-sink build: nine on a
build with a 1 s M-code wait, and mcode_test and tray_test, the two
that wait at an M-code, on the 5 s build CI configures
(-DGFMCODE_WAIT_S=5.0). pyflakes reports nothing in the nine changed
files.
Push this before grblHAL-glowforge's commit.
Acceptance: none; host harnesses only.
scripts/bench/mcode_test.py drives the null-sink controller with the
scripted sender and port client of ctlport_test.py: the port's mcodes
table and its refusals, error:20 for a number nothing answers, an
answered M-code's wait (the head still, the port's state naming it with
its words, a port jog busy:mcode, stale and out-of-form answers refused,
the answer's words on the console), a refusal and a timeout each holding
the job, a soft reset ending the wait, and a wait under an open armed
window with M3 S500 shipping no FIRE tick. It is registered in the bench
registry as a CI harness, not a bench-page tool.
exthost.mcode (suite/extmcode.py, its own module): a package with the
reference id that asks for mcode:160 and job_time.run, the one granted,
and whose service answers POST /mcode on its call socket. The host's
status names it as the one that answers M160. A dark job (out 5 mm, M160
P1, back) through POST /job waits at the M-code with the port's state
naming it and the head still over 1 s (the kernel's counters and the
port's position), the service answering after 2 s; the job then ends
done, every line acknowledged, the head back, the service asked once with
the code and its words, no discharge. A job naming M161 fails at that
line with error:20 and nothing moved. A job at M160 P2, which the service
refuses, is held, and is aborted from there. A job left running by a
failed check is aborted before the put-back.
Proof: on the bench reference, with the controller, forgectrl, and
forgeext of this change bind-mounted, exthost.mcode first FAILED and
found the controller announcing the M-code before the kernel had played
the last move (the driver now waits for the kernel to go idle), then
PASS; exthost.service, motion.job, exthost.page-call, exthost.motion-jog,
motion.port-jog, and exthost.package-routes PASS on the same daemons.
mcode_test.py ALL PASS on the host build. forgetest's unit tests pass,
and the coverage lint passes with --enforce.