From 1e28eb92cd83e74feaa56ee8d7f1e6c13784bc5a Mon Sep 17 00:00:00 2001 From: ScottW514 Date: Wed, 14 Oct 2026 10:48:52 -0400 Subject: [PATCH] Catalog: setup.factory-return leaves setup.factory-return leaves for forgectrl's tests/host_guard.sh (d21e200): POST /restore/factory-return with the token and no confirm is 400 and names confirm, confirm=0 is 400, GET /update/status shows no job running, GET /slots lists the archives (run only where /usr/sbin/ffboot is not on the host), and GET /setup carries the confirmed call; confirm=1 is never sent. The catalog goes from 98 to 97. It was the only test in the "the operator" section of suite/setup.py, and called no helper of its own. tests/test_setup_suite.py drops its id and test_the_factory_return_never_runs_the_return. src/update.* stays covered by the update tests, src/ui/wizard.js by the wizard and mirror tests, and src/main.c by the tests that already name it. test_setup_suite.py passes (31 tests). The coverage lint on the tree manifest finds no uncovered path and no host-tested row problem across the 97 tests; its one finding is setup.check-lens's empty src/lensfind.* entry. pyflakes is clean on both files. The full forgetest suite was not run. No HOST_TESTED row: the pinned workflow does not run host_guard.sh. Fingerprints: the deletion changes suite/setup.py's shared text, so the 34 tests that read it move again: the 9 left in setup.py, setup_dark 9, setup_burns 2, bedsize 1, exthost 9, extcall, extcat, extsender and extwizard 1 each. The pending pin bump from c274f19 already owes 32 of them; setup.machine-name and exthost.platform are the two it adds, as before. releases/ is unchanged. --- forgetest/forgetest/suite/setup.py | 39 ----------------------------- forgetest/tests/test_setup_suite.py | 11 +------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/forgetest/forgetest/suite/setup.py b/forgetest/forgetest/suite/setup.py index cac7b06..13e36c1 100644 --- a/forgetest/forgetest/suite/setup.py +++ b/forgetest/forgetest/suite/setup.py @@ -723,45 +723,6 @@ def ssh_until_reboot(ctx): "the SSH state is not as found: %s (was %s)", final, before) -# ---------------------------------------------------------- the operator - -@test("setup.factory-return", title="The return to the factory firmware is guarded", - subsystem="setup", kind="auto", est_min=1, - covers=[("forgectrl", "src/update.*"), ("forgectrl", "src/main.c"), ("forgectrl", "src/ui/wizard.js")], - requires=["update.slots-and-signature"], - description="The return itself reboots the machine as a Glowforge, so it never runs from the " - "catalog; it is a bench drill, run once per release. The " - "test probes the guards: POST /restore/factory-return without confirm=1 is " - "refused (400) and with confirm=0 too, no update job starts, /slots lists the " - "archived factory images, and the setup page carries the footer link's call " - "with confirm=1 behind its confirmation.") -def factory_return(ctx): - fc = ctx.forgectrl - ev = ctx.evidence - st, body = fc.post("/restore/factory-return") - ev["no_confirm"] = {"status": st, "body": body if isinstance(body, (str, dict)) else None} - ctx.log("POST /restore/factory-return (no confirm) -> %s %s", st, body) - ctx.check(st == 400 and "confirm" in str(body), "the return without confirm=1 -> %s %s, expected 400", st, body) - st, body = fc.post("/restore/factory-return", params={"confirm": "0"}) - ctx.check(st == 400, "the return with confirm=0 -> %s, expected 400", st) - st, us = fc.get("/update/status") - ctx.check(st == 200 and isinstance(us, dict) and not us.get("running"), - "an update job runs after the refused returns: %s", us) - st, slots = fc.get("/slots") - archives = (slots or {}).get("archives") if isinstance(slots, dict) else None - ev["archives"] = archives - ctx.log("GET /slots archives: %s", archives) - ctx.check(st == 200 and isinstance(archives, list), "GET /slots -> %s without an archive list", st) - if not archives: - ctx.log("no archived factory image on this machine: the return would be refused (409) and " - "the factory recovery mode is the way back") - st, page = fc.get("/setup", raw=True) - ev["setup_page"] = {"status": st, "bytes": len(page or b"")} - ctx.check(st == 200 and b"/restore/factory-return?confirm=1" in (page or b""), - "the setup page does not carry the footer link's confirmed call (%s)", st) - ctx.log("PASS: the return is refused without confirm=1; the page confirms before it calls") - - # --------------------------------------------------- the machine's name def mac_suffix(): diff --git a/forgetest/tests/test_setup_suite.py b/forgetest/tests/test_setup_suite.py index eb31510..72c8f36 100644 --- a/forgetest/tests/test_setup_suite.py +++ b/forgetest/tests/test_setup_suite.py @@ -18,7 +18,7 @@ from forgetest import baseline, catalog from forgetest.suite import setup IDS = ("setup.account-login", "setup.https-only-writes", - "setup.ssh-until-reboot", "setup.factory-return", "setup.machine-name", "setup.first-run-flow", + "setup.ssh-until-reboot", "setup.machine-name", "setup.first-run-flow", "setup.first-run-page", "setup.record-export", "setup.mirror") OPERATOR = ("setup.first-run-flow", "setup.first-run-page") @@ -104,15 +104,6 @@ class RegistrationTests(unittest.TestCase): self.assertEqual(attended, ["setup.cloud-header-capture", "setup.first-run-page", "setup.floor", "setup.focus"]) - def test_the_factory_return_never_runs_the_return(self): - import inspect - t = self.reg["setup.factory-return"] - src = inspect.getsource(t.fn) - self.assertNotIn('"confirm": "1"', src) # the only argument that starts the return - self.assertIn('"confirm": "0"', src) - self.assertEqual(t.kind, "auto") # the return itself is a bench drill, not a test - self.assertFalse(t.hands) - def test_the_machine_name_covers_nothing_by_design(self): self.assertEqual(self.reg["setup.machine-name"].covers, ())