mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-15 17:19:55 -07:00
Harnesses: the null-sink cases other tests prove leave
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.
This commit is contained in:
@@ -24,12 +24,16 @@ sender and for the machine daemon:
|
||||
[MSG:] of its words, and a cycle start resumes it
|
||||
5. a soft reset ends the wait at once, and the controller answers the
|
||||
next line
|
||||
6. no answer in GFMCODE_WAIT_S holds the job
|
||||
6. no answer in GFMCODE_WAIT_S holds the job: 5 s in the host build
|
||||
(configured with -DGFMCODE_WAIT_S=5.0, as grblHAL-glowforge's CI
|
||||
does; the image keeps 30 s), longer than any case here waits at a
|
||||
barrier on purpose
|
||||
7. the barrier is dark: under an open armed window with M3 S500, a job
|
||||
waiting at an M-code ships no FIRE tick, the window stays open across
|
||||
the wait, and the next laser move fires again
|
||||
|
||||
Usage: mcode_test.py [path/to/grblHAL_glowforge]
|
||||
(a build configured with -DGFMCODE_WAIT_S=5.0)
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
@@ -39,7 +43,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import ctlport_test as ct # noqa: E402
|
||||
|
||||
fail = ct.fail
|
||||
WAIT_S = 30.0
|
||||
WAIT_S = 5.0 # the host build's GFMCODE_WAIT_S
|
||||
|
||||
|
||||
def send_nowait(s, line):
|
||||
@@ -66,7 +70,9 @@ def test_table(s):
|
||||
r = s.port.request("mcodes " + good)
|
||||
if r != "ok":
|
||||
fail("[table] mcodes %s -> %r" % (good, r))
|
||||
for bad in ("159", "180", "160,160", "160,", ",160", "16a", "0160", "160 161", "1600", "160,,161", ""):
|
||||
# one form per refusal: out of range, twice, a separator with nothing
|
||||
# after it, not a number, and nothing at all
|
||||
for bad in ("159", "160,160", "160,", ",160", ""):
|
||||
r = s.port.request("mcodes " + bad)
|
||||
if r != "error:invalid":
|
||||
fail("[table] mcodes %r -> %r, not error:invalid" % (bad, r))
|
||||
@@ -81,8 +87,8 @@ def test_table(s):
|
||||
time.sleep(0.02)
|
||||
if s.sender.responses[n:n + 1] != ["ok"]:
|
||||
fail("[table] M165 got %r" % s.sender.responses[n:])
|
||||
print("PASS [table]: the port takes '-' and numbers from M160 to M179, the whole range; 11 other forms "
|
||||
"refused, the table left as it was")
|
||||
print("PASS [table]: the port takes '-' and numbers from M160 to M179, the whole range; a form "
|
||||
"of each refusal is refused, the table left as it was")
|
||||
|
||||
|
||||
def test_unanswered(s):
|
||||
@@ -198,9 +204,9 @@ def test_timeout_holds(s):
|
||||
wait_pending(s)
|
||||
s.sender.wait_state("Hold", timeout=WAIT_S + 5)
|
||||
dt = time.time() - t0
|
||||
if dt < WAIT_S - 1:
|
||||
if dt < WAIT_S - 0.1:
|
||||
fail("[timeout] the job was held after %.1f s, not after the wait" % dt)
|
||||
if not s.sender.saw("M160 had no answer from its extension in 30 s: the job is held"):
|
||||
if not s.sender.saw("M160 had no answer from its extension"):
|
||||
fail("[timeout] the sender got no [MSG:] of the timeout")
|
||||
s.sender.realtime(b"~")
|
||||
s.sender.wait_state("Idle", timeout=5)
|
||||
|
||||
Reference in New Issue
Block a user