mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-16 01:29:55 -07:00
b447ae77f17eb94fc1649262e9d6f896f4f13253
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
520d62ac05 |
forgetest tests: the confirmed trims of the tool's own unit tests
The cases that tested a mock, a timer, a wording or a table, or that
replayed a judgment a host test already holds, leave forgetest/tests.
What catches a false PASS, keeps the bench safe, or guards the gate
stays.
- test_baseline: the fake sysfs tree is a mixin with no test_ methods,
so ExtensionFreeTests and BaselineModeTests no longer re-run
BaselineTests' 25 cases (133 runs, now 45). CoolPublishTests, the
lamp-fade cases and TransientNotLeftoverTests go; PositionDeadbandTests
keeps a reading past the band and an unreadable reading, both never
excused. Both latch-relock cases stay.
- test_fixture: MdnsTests, the three timing cases, the probe's log
wording, and nine prompt-routing variants go. A live test never runs
unattended, the arm-press opt-in, the short-press edge, the presence
press handing over the arm press, and the arm notice dropping at the
press stay (35 cases, now 21).
- test_cloud_suite: three false-PASS guards stay: the latch open at a
dark print's button, a lid stop that is not edge-driven, the kernel
refusing the resume. The guards for the latch unlocking in the hold
and a paused print resuming left with their catalog tests in
|
||
|
|
dc9bede034 |
forgetest: the first /state parses each suite module once
The first GET /state after forgetest starts hashes every test's implementation, and it took from 81 s to more than 12 minutes on the bench reference. Two causes: - sibling_imports() read and parsed a test's module and every sibling it imports, transitively, once per test: 280 ast.parse calls for 26 suite modules. module_parts() kept its own parse, sibling_imports() kept none. - The page gives up on a poll after 20 s and polls again; the server thread goes on computing. Each new poll started the same cold work beside the first, all of it on the one CPU, so the longer the first took the more copies ran. That is the spread between 81 s and 12 minutes. Each module's text and tree are now read and parsed once and kept, as are its direct sibling imports, and the implementation hash is filled by one thread at a time: a poll that arrives while it is computed waits for it instead of repeating it. catalog.forget(path) drops what is kept about a file, for the unit tests that edit their modules. The hashes do not move: every test's implementation hash and domain fingerprint on the image manifest of 20260923220034 is byte-identical before and after, so no result is invalidated. On the host the cold computation went from 7.00 s to 0.29 s (280 parses to 25). On the bench reference (the file bind-mounted on image 20260923220034, the page open) the first /state answered in 8 to 12 s after a restart, where the same restart earlier in the evening had not answered after 7 minutes. tests/test_responsiveness.py pins both: each suite module parsed at most once while every test's implementation hash is computed, and three threads reading one test's hash compute it once. With the old behavior put back by a patch both fail (280 parses for 26 modules; the hash computed 3 times). forgetest's unit tests 454 OK. forgetest is the dev-only harness, outside the catalog's coverage; its catalog consequence is none, since no fingerprint moves. |
||
|
|
0eb764bf75 | Added SPDX | ||
|
|
e99888753f |
forgetest's page moves onto Bootstrap with forgectrl's theme; forgectrl pinned at the panel overhaul
The acceptance page is assembled by page.py from forgetest/forgetest/ui/ (index.html, page.css, help.js, app.js) plus theme.css and the vendored Bootstrap files, which are byte for byte the ones forgectrl's panel carries, so the two pages look like one product and share the light and dark themes (same localStorage key). A plain file is read in a checkout; on the dev image the recipe installs ui/ gzipped and page.py reads the .gz sibling, inflating once at first request: the rootfs is raw ext4, so bytes in the package are bytes on the image. The explanatory prose (campaign rules, the queues, the campaign actions, the prerequisites switch, the bench intro) is a "?" popover with a link into the documentation site; operator steps, prompts, notices and the live-laser acknowledgment stay in the page, and confirmLive() stays a blocking dialog. The page's own rules hold: rows, prompt buttons and tool entries are built once and updated in place, and the popovers sit on static markup only, so no rebuild orphans one. On a phone the Run pane goes to the top for the duration of a run. scripts/check-ui-vendor.py compares the shared files against forgectrl at its pinned revision (or a local checkout with --forgectrl); it runs in forgetest-ci.yml, so the copies cannot drift. Tests: test_page.py (the gzipped install assembles to the same bytes as a checkout, one self-contained response, the token placeholder once, a missing marker refused); test_server asserts the served page's invariants; test_responsiveness keeps its rules with needles pointed at the new files, its ASCII rule applied to our own sources (Bootstrap's CSS carries an em dash of its own), and its self-contained rule testing asset tags rather than the presence of https:// (the documentation links are meant to be there). forgectrl.panel-serves gains two needles for the panel's theme attribute and save bar. Proof: the unit suite, and the page in Chrome against a fake catalog (both themes, popovers, the bench tab, a full operator run with its prompt, abort). forgectrl pinned at 9d1f6f2 (the panel on Bootstrap, one save bar, help popovers, themes, the gzipped page); PV unchanged. The pin moves only forgectrl's fingerprint. The forgetest changes are the harness's own and have no catalog consequence. |
||
|
|
e810d52c9d |
Put every test group on the same column grid
The subsystems are separate tables, so each sized its own columns from its own content and no two lined up. Reading down the page meant reading down six different layouts, which is what made it look busy. They now share one colgroup and a fixed table layout: Kind, Status, Last result and the Start button are the same width in every group, and the Test column takes the remainder. Two things had to come out of the columns first, because both are long enough to stretch a cell and drag one group's grid out of step with the rest. The details block moves to a full-width row of its own, where the prose and the operator steps have room and opening one no longer widens the Test column. The requires note moves from under the Start button to under Status, which is sized for it: the catalog's longest names three prerequisites in 73 characters, and beneath a button it wrapped into a ragged stack. It reads better there anyway, next to the reason the test is required rather than beneath the control it disables. Also gives a test's description its own block in the details. Without operator steps to separate them it ran straight into the Requires line. |
||
|
|
0258268aae |
Let the page run a campaign's remaining tests as a queue
A campaign is mostly waiting for the next Start. The page now offers two queues, and each takes every test of its kinds the campaign does not already count as satisfied: Unattended for the auto tests, which need nobody in the room, and Operator and live for the ones that need somebody at the machine, since they prompt and they fire the laser. The buttons say how many they would run and ask before starting; the live queue names the tests that fire and takes the acknowledgment once, for all of them. A queue runs one test at a time through the runner's single slot, in prerequisite order. Registration order otherwise, so a run reads down the page, but a prerequisite inside the queue always goes first. It stops on the first result that is not a PASS: a FAIL closes the campaign, and carrying on would only open a second one behind the operator's back. A test the runner refuses to start is skipped with the reason on the page and the rest carry on, which is what happens to an auto test waiting on an operator one: run the attended queue, then the unattended one again. The queue lives in the runner, not in the tab, so reloading the page or closing it leaves the run alone. While one is up it holds the machine between its tests as well as during them, so a single Start and the bench tools are refused rather than cutting in. Stop the queue cancels what is still waiting and lets the run in progress finish; Abort ends that one too, and lands as the non-PASS that stops the queue. Every run a queue starts records which one put it there. Also moves the /state ETag test to the end of its class. It invalidates, timestamps are whole seconds, and a PASS stamped in the same second as an invalidate is deliberately not inheritable, so on a fast run it decided the inheritance an earlier test was checking. forgetest is a dev-only component and can never appear in a coverage map, so this has no acceptance catalog consequence. |
||
|
|
474e14e0e8 |
Make the acceptance page answer the operator, not the timer
Presses on Start and Continue were being swallowed. Every poll rebuilt the whole test table and the prompt buttons with innerHTML, and a button destroyed between mousedown and mouseup raises no click event at all: the press simply vanished. Measured on the page as it stood, a Start button node was replaced 13 times in 40 seconds, and with a poll landing mid-press 8 presses out of 8 were lost. Rows, prompt buttons and tool entries are now built once and afterwards only updated in place through setters that skip the write when the value has not changed; under the same test 8 presses out of 8 land. The page also felt slow because each poll re-read and re-parsed the whole result log and recomputed all 42 domain fingerprints. A result record carries its run log, so the file reaches megabytes over a campaign and the poll cost grew with it. The log now parses each line once and reads only the bytes appended since, and a fingerprint is memoized against the manifest's content hash. On the same manifest, catalog and log, one /state goes from 8.89 ms to 0.10 ms at 0.89 MB and from 41.79 ms to 0.23 ms at 10.62 MB, and no longer grows with the log. Actions now report on the press instead of on the next poll: Start greys every Start and marks the row, Continue and Abort grey themselves, and each pulls the next poll forward. /state carries an ETag so an idle page polls for a 304, the poll ticks faster during a run, and the connection is kept alive rather than handshaking per request. Keeping the connection alive exposed a hazard worth naming: a POST refused before its body was read left that body in the socket, where the next read took it for a request line. A refusal now ends the connection. forgetest is a dev-only component and can never appear in a coverage map, so this has no acceptance catalog consequence; the host tests carry the proof, including one that fails if a per-poll innerHTML rebuild ever comes back. |