Commit Graph
3 Commits
Author SHA1 Message Date
ScottW514 54e1689889 Let a test declare the controller mode it needs; the runner switches to it
The cloud job tests enter cloud mode and stay there, by design, so a
queue (or an operator) that goes on to a motion test reaches it with
gfcloud as the controller and no grblHAL process to find:
motion.step-timing-under-load failed on exactly that, before it touched
the machine. Nothing in the runner put the machine into the mode a test
needed; the baseline only preserved the mode it found.

A test now declares `mode="grbl"` (or "cloud") in @test. The runner's pre
pass, after the leftovers are handled and before the preserved state is
captured, switches through POST /mode, waits for the supervisor to settle
(controller running, motion verified) and for the Grbl port to answer,
and fails the test with the reason when the mode cannot be established.
Capturing after the switch means the post pass keeps the mode the test
asked for, so the machine changes mode only where the next test asks for
it and never between tests of the same mode. The cloud job tests keep
managing their own entry (enter_cloud also waits for the service
session) and declare nothing.

Tagged: every motion.* test but the mode-agnostic liveness probe, the six
laser.* tests, cooling.fans-quiet-after-motion, cloud.mode-switch and
cloud.gfhome-homing (both start in GRBL mode). controller_pid() now says
what mode forgectrl reports when the process is missing. The page shows
the declared mode as a badge; the Grbl port probe moved to hw.

Proof: tests/test_mode.py (switch_mode against the fake forgectrl,
including a refused switch, a controller that never comes up and a port
that never opens; the runner end to end from cloud mode, from grbl mode,
an undeclared test, and a failed switch). 151 unit tests pass; the
coverage lint is clean. No catalog consequence beyond the suite modules'
own source hashes: the change is to how a test is started, not to what
it proves.
2026-08-21 12:34:03 -04:00
ScottW514 86ce0419e5 forgetest: cloud tests stay in cloud mode; the page can ignore prerequisites
The cloud job tests (lid-abort, lid-during-button-wait, hunt-lid-open,
pause-resume) run in cloud mode and leave the machine there: enter_cloud
reuses a live session (pid-scoped from the client's own websocket state
lines) and switches once from GRBL mode, declaring the change to the
baseline; nothing switches back. Each test judges the log from its own
window, the print by its own "print [id]: finished" line, and waits the
service's follow-up moves out (wait_quiet) before it ends. hunt-lid-open
restarts the cloud client through the supervisor's stop/start lever for
a fresh connect. The former switch-back is what failed the last bench run
of hunt-lid-open (409 machine is not idle: the service was still
re-finding the head after the lid closed).

The baseline is mode-aware: in cloud mode the client owns the GRBL
controller's init values, the lid lamp, and the position counters; the
mode itself is preserved unless the run declared the change
(Context.mode_changed); controller_mode is never handed back as a bare
setting (a bare write left the persisted mode out of step with the live
one). The undeclared-change restore now uses the captured state, which
the post pass never saw before.

The acceptance page gets an "Ignore prerequisites" switch (remembered by
the browser): POST /start {ignore_requires} starts a test whose requires
are unmet, and the run records the unmet prerequisites in its evidence
and log; they stay required for the release. The cloud tests' requires
no longer chain through cloud.mode-switch.

Proof: tests/test_cloud_suite.py replays the four tests on the bench's
own gfcloud excerpts (fixtures/) and the run loop's emitted pause/resume
lines under the real runner Context against a fake forgectrl; baseline
mode tests and the server override test; the whole suite (98) and the
coverage lint pass. Catalog consequence: cloud.* fingerprints move with
the module; the catalog hash moves with the requires.
2026-08-17 06:42:48 -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