mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -07:00
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.
This commit is contained in:
+26
-3
@@ -30,7 +30,12 @@ Every test declares, in code (`forgetest/forgetest/suite/*.py`):
|
||||
- **covers** - the source paths whose content the test stands for, as
|
||||
`(component, glob)` pairs;
|
||||
- **requires** - tests that must be satisfied first (the emission tests
|
||||
require the motion and readback tests);
|
||||
require the motion and readback tests). This orders the runs; it is not
|
||||
a release condition of its own (the release needs every test satisfied
|
||||
anyway). The page's **Ignore prerequisites** switch lets any test start
|
||||
alone; a run started that way records the unmet prerequisites in its
|
||||
`evidence.prerequisites` and its log, and the prerequisites stay
|
||||
required;
|
||||
- **always** - membership in the **always-required core**, which is run
|
||||
in every campaign and is never inherited: image health, the kernel
|
||||
latch/safety readbacks, and one live emission witness with the
|
||||
@@ -103,7 +108,16 @@ forces a full campaign; nothing before it can be inherited.
|
||||
do not.
|
||||
3. Start the required tests. `operator` tests ask questions in the run
|
||||
pane; `live` tests need the acknowledgment and the physical arm press;
|
||||
`takeover` tests stop forgectrl for the duration.
|
||||
`takeover` tests stop forgectrl for the duration. A test whose
|
||||
prerequisites are not satisfied is locked until they are - or until
|
||||
the **Ignore prerequisites** switch in the Campaign card is on, which
|
||||
unlocks every Start (the switch is remembered by the browser; a run
|
||||
started under it says so in its record).
|
||||
The `cloud.*` job tests run **in cloud mode and stay there**: the first
|
||||
one switches from GRBL mode (once, its connect-time hunt waited out)
|
||||
and the following ones reuse the live session; nothing switches back -
|
||||
switch on the control panel when done. `cloud.mode-switch` is the one
|
||||
round trip and starts in GRBL mode.
|
||||
4. When *Release authorized: YES*, **Export release artifact**, download
|
||||
`acceptance.json` and `acceptance.md`, and commit them as
|
||||
`releases/v<version>/acceptance.json` and `.md`.
|
||||
@@ -126,7 +140,16 @@ at forgectrl's `lid_lamp_idle` setting; forgectrl: the controller running
|
||||
with motion verified, no diagnostic, the camera engine and cooling engine
|
||||
idle), and **preserved** state with no resting policy that a run must
|
||||
hand back as it found it (the position counters, the settings map, the
|
||||
controller mode). Deviations are
|
||||
controller mode). The mode in force decides what the baseline owns: in
|
||||
cloud mode the cloud client's own configuration (the GRBL controller's
|
||||
init values, which it rewrites from every pulse header; the lid lamp,
|
||||
its lid-image level; the position counters, re-zeroed at every service
|
||||
action) is left to it, and the safety readbacks, latch, ring, module
|
||||
defaults, and forgectrl's engines are checked as always. The mode itself
|
||||
is preserved unless the run declared the change (`ctx.mode_changed()`,
|
||||
the cloud tests entering cloud mode); the persisted `controller_mode`
|
||||
setting is never written back as a bare setting - only the switch keeps
|
||||
it in step with the live mode. Deviations are
|
||||
**leftovers**: logged in the run pane, kept in the result's `evidence`
|
||||
(`baseline.pre` / `baseline.post`), and surfaced in the page's message
|
||||
line - a leftover found before a run is attributed to the previous run; one
|
||||
|
||||
+25
-1
@@ -3082,7 +3082,31 @@ dev image (the confirmation campaign's image).**
|
||||
`cloud.lid-during-button-wait`, `cloud.hunt-lid-open`,
|
||||
`cloud.pause-resume` (live). Items 4 and 12 above are superseded by
|
||||
this policy (the mid-job Door hold is no longer the default path);
|
||||
close them with these tests. Still to observe once on the bench: the
|
||||
close them with these tests.
|
||||
Bench 2026-08-17 (dev image 20260817014132): `cloud.lid-abort` and
|
||||
`cloud.lid-during-button-wait` PASSED; `cloud.hunt-lid-open` reported
|
||||
FAIL for a harness defect - the hunt had completed with the lid open,
|
||||
but the test then insisted on switching back to GRBL while the
|
||||
service was still re-finding the head after the lid closed (`409
|
||||
machine is not idle`). Reworked: the cloud job tests now run **in
|
||||
cloud mode and stay there** (`enter_cloud` reuses a live session,
|
||||
pid-scoped from the client's own websocket lines; the switch is
|
||||
made once from GRBL and declared to the baseline; `wait_quiet`
|
||||
waits the service's follow-up moves out; the hunt test restarts the
|
||||
cloud client through the supervisor's stop/start lever for a fresh
|
||||
connect; every print is judged by its own `print [id]: finished`
|
||||
line), the baseline is mode-aware (cloud mode owns its kernel
|
||||
config, lamp, and counters; `controller_mode` is never restored as
|
||||
a bare setting - that had desynced the persisted mode from the live
|
||||
one), and the page has an **Ignore prerequisites** switch so any
|
||||
test can be started alone. Proof: `tests/test_cloud_suite.py` (15
|
||||
cases, the four tests replayed on the bench's own gfcloud excerpts
|
||||
+ the run loop's pause/resume lines), baseline/server tests, and a
|
||||
bench drill of `enter_cloud` (reuse) and of the fresh connect +
|
||||
hunt detection + quiet wait against the live machine (hunt
|
||||
`:completed`, 3 follow-up motions, quiet at 41 s). Left for the
|
||||
operator: `cloud.hunt-lid-open` with the lid actually open,
|
||||
`cloud.pause-resume` (live print + two presses). Still to observe once on the bench: the
|
||||
~90 ms HV_ENABLE re-arm gap on a GRBL resume (whether a dark dwell
|
||||
lead is wanted), the app's rendering of `print:paused`, and a lid open
|
||||
during the return-to-start motion (should be ignored).
|
||||
|
||||
Reference in New Issue
Block a user