Files
forgefirm/forgetest
ScottW514 8570c0141e forgetest: motion.soft-limits runs its own camera home and hands the head back
motion.soft-limits homed only when the machine was not homed already,
and then with whatever homing_mode the machine had: it counted on the
home cloud.mode-switch used to leave behind. cloud.mode-switch now drops
its camera home when it hands the head back, so the test started
unhomed, and under the operator's homing_mode = manual its $H was a
manual home, declared at once where the head stood (2.2 s, no web-service
session), and the test failed on gfhome's missing completion line. When
it did home, it left the head at the corner and the machine homed.

The test now sets homing_mode = gfcloud and unsets the camera-home
offsets for its run, so the envelope is the bed from the home corner,
and always runs its own camera home, every motion of it judged whole
(homeoff.judge_whole_motions). A setting is written when the controller
takes it (it refuses one for a moment after a Grbl client closes). At
the end the settings are put back as found and homeoff.camera_home_return
drops the home and jogs the head back to where the test found it. The
helpers are imported inside the function: homeoff imports this module.

Proof: on the bench reference, image 20260925183749 with this file
mounted, motion.soft-limits PASS: the camera home in 52.6 s, every
motion completed; X max, Y max and X min refused with ALARM:2 and no
motion, the jog past the bed refused with error 15, the move inside the
bed ran and came back; the settings put back; the head jogged back
28.95/13.03 mm to where the test found it; the baseline clean. forgetest
499 OK.

Acceptance: the test is the change; its fingerprint moves and no other
test's does.
2026-09-25 15:21:45 -04:00
..
2026-09-18 12:14:22 -04:00
2026-09-18 12:14:22 -04:00

forgetest - the ForgeFIRM release acceptance tool

The daemon behind http://<machine>:8090/ on the dev image: runs the acceptance catalog against the machine, keeps the append-only result log, decides which results still apply to the image that is running, exports the release artifact scripts/release.sh gates on, and serves the bench diagnostics page. The contract - catalog, campaigns, fingerprints, inheritance, the gate, the coverage rule - is the Acceptance page of the documentation site.

Run the host tests

cd forgetest
python3 -m unittest discover -s tests -v

Run the daemon on a workstation (against a mock or a manifest file)

FORGETEST_DATA=/tmp/ft FORGETEST_MANIFEST=../tree-manifest.json \
FORGECTRL_URL=http://<machine> python3 -m forgetest --port 8090

scripts/manifest-from-tree.py produces tree-manifest.json from the recipe pins; the coverage lint is python3 -m forgetest.coverage --manifest ....

Environment

Variable Default Purpose
FORGETEST_DATA /data/forgetest results.jsonl, bench.jsonl, token, export/
FORGETEST_MANIFEST /etc/forgefirm-manifest.json the image manifest
FORGETEST_PORT, FORGETEST_HOST 8090, 0.0.0.0 listener
FORGETEST_BENCH_DIR /usr/share/forgetest/bench the installed bench scripts
FORGETEST_BENCH_DATA <FORGETEST_DATA>/bench passed to bench tools: where they keep their data files (with GF_HOST=127.0.0.1 and the panel token in GF_TOKEN)
FORGETEST_MARKER /run/forgetest.active takeover marker
FORGECTRL_URL, FORGECTRL_TOKEN_FILE http://127.0.0.1, /data/forgefirm/panel.token forgectrl client (HTTP; the token authorizes writes from the board)
FORGECTRL_TLS_URL https://127.0.0.1 forgectrl over HTTPS (self-signed, unverified), for the login test
GF_SYSFS_ROOT /sys/glowforge/ kernel module sysfs
GRBL_HOST, GRBL_PORT 127.0.0.1, 23 Grbl TCP

Adding a test

Register it in the subsystem module under forgetest/suite/ with @test(...): id subsystem.name, kind, hardware, mode (the controller mode the test needs; the runner switches to it first), covers, requires, always, steps. The body gets a Context (log, check, fail, prompt, confirm, instruct, sleep, evidence, forgectrl, sysfs, grbl, takeover). Return normally for PASS, raise runner.Failed for FAIL. Then run the unit tests and the coverage lint.