Commit Graph
8 Commits
Author SHA1 Message Date
ScottW514 d4e2f85538 forgetest: motion tests end on the machine's idle; the Grbl client survives a soft reset
wait_idle returned on a stale Idle before a just-commanded move began,
and the tests declared PASS on grblHAL's Idle while the kernel still
played the stream depth and the decel tail (the baseline caught
state=running after motion.pacing). Every motion test now ends on
forgectrl's idle (machine_idle), and wait_idle ignores an Idle inside a
short grace unless a non-Idle state was seen.

status_report re-sends '?' every 0.5 s until a report arrives: a soft
reset (^X) flushes the controller's read buffer and eats a '?' that lands
in it - the bench saw motion.cancel-abort error with no report for 5 s
after the abort while the controller answered the next '?' at once.

motion.deadman: the SIGSTOP drill waited for a running controller and
got the killed pid back before the supervisor reaped it (drill 1 already
waited for a different pid); and the forgectrl-restart drill expected the
busy controller's pid to survive the retake, but a retake under the
broker is stop-at-idle, re-probe, start a supervised controller (the old
inherited fd cannot be adopted) - the check is now: the move finished
unmanaged, supervision came back running and verified. Bench-proven
2026-08-16: kill respawn 1.3 s, hang -> underrun 0.21 s, retake at idle.
2026-08-16 14:21:53 -04:00
ScottW514 13beb51e26 forgetest: kernel.k1-k2 leaves the position counters where it found them
K2 streamed 1000 masked +X steps; the counters advanced although nothing
moved, and forgectrl's position display carried the offset. The stream
now runs 1000 out and 1000 back, and the counters returning to start is
a check. Bench-proven 2026-08-16: (0,0,0) before and after.
2026-08-16 13:35:20 -04:00
ScottW514 4aaedc8080 forgetest: every run starts from, and leaves, the fresh-boot idle state
A baseline pass brackets every test and bench tool: before the run the
machine is verified against the fresh-boot idle state and anything off it
is restored; after the run - pass, fail, or abort - it is restored again.
Fixed items are the resting values the boot establishes (module defaults,
forgectrl's start-up writes, the GRBL controller's init writes) and
forgectrl's idle picture (controller running with motion verified, no
diagnostic, camera and cooling engines idle); preserved items (lid lamp
level, position counters, settings map, controller mode) are captured
before and handed back after. Deviations are leftovers: in the run pane,
in the result's evidence, and on the page - attributed to the previous run
when found before, to the run itself when found after.

forgetest takes a fresh-boot reference once per boot (within ten minutes
of boot, after the supervisor settles) as the session's resting lid-lamp
level and the check on the fixed values; the values were confirmed
against a fresh boot of the dev image on the bench (step_freq rests at
28160, the controller's default tick, not the probe's 10000).

Takeover runs capture the controller-owned kernel attributes on entry and
write them back before forgectrl restarts: the bench found the kernel
tests leaving motor_lock=15 behind, which masked the supervisor's
liveness probe - no motion by construction, a false driver-wedge verdict,
the rail-off ladder, and finally motion-fault. The takeover wrapper also
waits for the supervisor to settle on both sides (moved into baseline).

Catalog consequence: none beyond the runner; the tests' own drills are
unchanged.
2026-08-16 13:35:19 -04:00
ScottW514 799e0e829c forgetest: a takeover waits for forgectrl to settle on both sides
forgectrl's supervisor probes motion liveness on every start - a small
head move verified by the accelerometer, with a rail-off ladder of up to
about 70 s on a dead verdict. The takeover wrapper returned as soon as
forgectrl start succeeded, so a test that followed found the machine
busy (bench: cooling.flow-verify refused with 409 machine is not idle
13 s after kernel.fire-abu), and back-to-back takeover tests stopped
forgectrl mid-probe. The wrapper now waits for /mode to settle - motion
verified, motion-fault (logged as a warning), or standby - before it
stops forgectrl and again after it starts it, giving up after 10 s when
forgectrl does not answer at all (the host, or a daemon that is down).
No catalog consequence: the takeover tests' own drills are unchanged.
2026-08-16 13:09:56 -04:00
ScottW514 a4b757add5 forgetest: a diag start is 202 Accepted with started:true
forgectrl answers a started diagnostic with 202 (an async job); the
cooling.flow-verify test asserted 200 and failed on the bench before the
diagnostic ran. No catalog consequence beyond the test's own source
hash.
2026-08-16 13:08:48 -04:00
ScottW514 d17655c3c0 forgetest: logs.routing and logs.level-settings; export gets its own timeout
The routing test proves the path every logger takes and stands for the
emitters and relays in every component (fflog in forgectrl and grblHAL,
the SysLogHandler in the Python apps, the supervisor's per-controller
relay, the daemon's fifo relay, the render step): one logger daemon,
rendered rules and the effective record consistent with /logs, the tree,
the daemon's own emitter line, `logger` probes routed by program name in
the ff_line format, a stray program only in system/, kernel lines, relay
processes, nothing written outside the tree. The level-settings test
covers the validators and the configured-vs-effective / pending_reboot
contract. Both PASS on the bench with the existing logs.tree-tail-export
through the real Runner. That test's export call now uses a 300 s client:
the sanitized export took 13.9 s on the target and tripped the 10 s
default. Pin: forgectrl 4d19e9d (the sanitizer skips passes a line
cannot match; 4x faster). Coverage lint enforced: 0 uncovered.
2026-08-15 17:44:44 -04:00
ScottW514 16deb4896f forgetest: /fuse-identity is two-factor; the auth test asserts both refusals
forgectrl reveals the fuse identity only to the token AND the physical
button held, so the token alone must answer 403 with the button message.
The test now asserts the no-token refusal and the token-without-button
refusal and never fetches the identity itself (a 200 would have carried
the fuse password into the result log). BRINGUP: the bench campaign on
the flashed dev image, 7 of 24 passed so far.
2026-08-15 16:07:12 -04:00
ScottW514 c0f53a865f forgetest: the release acceptance tool and the bench diagnostics page
A stdlib-only daemon on the dev image (HTTP :8090) that runs the acceptance
catalog against the machine from a self-contained page, keeps the append-only
result log under /data/forgetest, and exports the release artifact the gate
reads. Tests declare kind (auto / operator / live), hardware (api / takeover),
coverage globs, prerequisites, and core membership; a test's domain
fingerprint is the hash of the manifest files its globs select plus the
platform and its own implementation, so a PASS stays valid exactly while
nothing it covers changed. Campaign rules: a FAIL ends the campaign, the core
(image health, kernel latch and drills, one live emission witness) is never
inherited, invalidate-all forces a full campaign, no SKIP. Live tests need the
operator acknowledgment and the physical arm press through the controller;
takeover tests stop forgectrl for the duration with a crash-recoverable
marker; the tool never touches the laser latch.

Catalog v1: 24 tests ported from the proven bench drills with their recorded
pass criteria (image, kernel K1-K3 and fire A/B/U, forgectrl API and logs,
motion incl. dead-man, cooling, live laser, camera, update, cloud). The bench
tab lists every scripts/bench tool and runs the board-side ones as
subprocesses (takeover tools wrapped). 44 host unit tests, including the gate
verification fixtures. Installed only by forgefirm-image-dev, with the bench
scripts under /usr/share/forgetest/bench.
2026-08-15 15:57:11 -04:00