Files
forgefirm/forgetest
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
..

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 docs/ACCEPTANCE.md.

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>:8080 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_MARKER /run/forgetest.active takeover marker
FORGECTRL_URL, FORGECTRL_TOKEN_FILE http://127.0.0.1:8080, /data/forgefirm/panel.token forgectrl client
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, 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.