forgetest: the built-in extensions in setup.cloud-disabled-surface

forgectrl gains a table of built-in extensions, with cloud mode as entry
one, GET /extensions to serve it, and POST /settings asking it which
selections point at the cloud, how to refuse them, and what they fall back
to. It also gains an example client under examples/, and its test tokens
lose the names of clients nobody is building.

setup.cloud-disabled-surface is the gate for "nothing points at the cloud
while it is off", so it now holds the list to the settings three times: as
found (enabled as cloud_enabled says, the two roles with their providers
and fallbacks, each active exactly when its setting selects it), with the
cloud off (not enabled, no role active), and as restored. The two refusals
are held to the table's words. Its covers name src/builtin.*. The helper
lives inside the test's own function, so no other test of the module
changes its fingerprint.

The unit test's fake daemon serves the route the way builtin.c does, and
gains a case with two lists that lie (enabled after the cloud went off; a
role that stays active), each of which must fail the test.

forgectrl.tokens: the jog token is "forgetest jogger".

manifest: forgectrl's examples/** joins the non-behavioral paths. They are
clients that run on another computer: outside the image, outside every
fingerprint, and outside the coverage lint.

Proven. The unit suite passes (421) with no undefined name; the two lying
lists fail the test as they should. On the bench reference, forgectrl's
registry daemon hot-deployed over image 20260920152153, on a machine with
cloud mode on: setup.cloud-disabled-surface PASS through the whole path
(off, the sweep, the refusals, the restore), and forgectrl.tokens PASS with
the renamed token.

Acceptance. setup.cloud-disabled-surface is the gate for forgectrl's
built-in table through the settings route.
This commit is contained in:
ScottW514
2026-09-20 15:03:05 -04:00
parent ebc4222182
commit 19ce4d78d2
4 changed files with 77 additions and 12 deletions
+28 -1
View File
@@ -16,7 +16,7 @@ import unittest
import helpers
from forgetest import baseline, catalog
from forgetest.runner import Context, Run
from forgetest.runner import Context, Failed, Run
from forgetest.suite import setup
IDS = ("setup.gate-blocks-controllers", "setup.override-until-reboot",
@@ -375,6 +375,26 @@ class CloudDisabledSurfaceTests(unittest.TestCase):
return 409, "cloud mode is not enabled on this machine"
return None
self.fake.on_post = on_post
self.list_lies = None # a test sets this to break the list one way
def on_get(path, query):
if path != "/extensions":
return None
s = self.fake.state["settings"]
on = s.get("cloud_enabled") == "1"
roles = [{"role": role, "provider": prov, "kind": kind, "select_key": key, "fallback": back,
"active": on and s.get(key) == prov}
for role, prov, kind, key, back in (("homing", "gfcloud", "runner-fd", "homing_mode", "none"),
("controller", "cloud", "supervised", "controller_mode",
"grbl"))]
if self.list_lies == "stale-active":
roles[0]["active"] = True
if self.list_lies == "always-on":
on = True
return 200, {"extensions": [{"id": "cloud", "name": "Glowforge cloud mode", "builtin": True,
"enabled": on, "enable_key": "cloud_enabled", "setup_step": "cloud",
"tab": "gfcloud", "roles": roles}]}
self.fake.on_get = on_get
def tearDown(self):
self.fake.stop()
@@ -385,6 +405,13 @@ class CloudDisabledSurfaceTests(unittest.TestCase):
t.fn(Context(run, None, t))
return run
def test_a_list_that_disagrees_with_the_settings_fails(self):
for lie in ("always-on", "stale-active"):
self.list_lies = lie
self.fake.state["settings"].update({"cloud_enabled": "1", "homing_mode": "gfcloud"})
with self.assertRaises(Failed, msg=lie):
self.run_test()
def test_refusals_and_restore(self):
run = self.run_test()
s = self.fake.state["settings"]