mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -07:00
setup suite: the port wait, and the first run's accounts on a failure
Two harness faults found on the bench reference in the campaign on image
20260923084705.
setup.gate-blocks-controllers probed the Grbl port once, at the moment
GET /mode first read the controller running. The supervisor reports
running from the fork and the controller binds TCP 23 a few tens of
milliseconds later, so the probe failed whenever the 0.25 s poll landed
inside that window ("the Grbl port is closed with the controller
running"). Timed on the board with the controller restarted through
forgectrl: /mode read running at 0.066 s, the port accepted at 0.087 s.
The test now waits up to 10 s for the port (50 ms polls) and records
how long it took (port_open_after_s). PASS on the bench (0.001 s).
first_run() replayed the system accounts (forgefirm-users reload) and
removed the temporary home only after its block succeeded. When the
block failed, the records came back but /etc/passwd kept the temporary
account in place of the operator's, and image.health failed after it
(the record's account missing from /etc/passwd). The replay and
the home removal now run in a finally. Proof on the bench: the failing
case run on purpose (setup.first-run-flow against the image's own
forgectrl, which refuses a home by hand at the cloud step) leaves the
operator's account the one account from uid 1000 up and no temporary
home; the same failure before the fix left the temporary account in
/etc/passwd and its home in /data/forgefirm/home.
forgetest's unit tests: 452 OK. setup.first-run-flow and
setup.gate-blocks-controllers PASS on the bench with this file mounted.
This commit is contained in:
@@ -427,8 +427,12 @@ def gate_blocks_controllers(ctx):
|
|||||||
ev["override_mode"] = m
|
ev["override_mode"] = m
|
||||||
ctx.check(took is not None and isinstance(m, dict) and m.get("controller") == "running",
|
ctx.check(took is not None and isinstance(m, dict) and m.get("controller") == "running",
|
||||||
"the controller did not come back under the override: %s", m)
|
"the controller did not come back under the override: %s", m)
|
||||||
ctx.check(hw.grbl_port_open(timeout=5), "the Grbl port is closed with the controller running")
|
# /mode reads running from the fork; the controller binds its port
|
||||||
ctx.log("override: the controller is back (%s)", m)
|
# a few tens of milliseconds later
|
||||||
|
opened = ctx.wait_for(lambda: hw.grbl_port_open(timeout=1), 10, poll=0.05)
|
||||||
|
ev["port_open_after_s"] = opened
|
||||||
|
ctx.check(opened is not None, "the Grbl port is closed with the controller running")
|
||||||
|
ctx.log("override: the controller is back (%s), the Grbl port accepts after %.3f s", m, opened)
|
||||||
|
|
||||||
# the real record is back under a restart; the override reads as found
|
# the real record is back under a restart; the override reads as found
|
||||||
after = wiz(fc)
|
after = wiz(fc)
|
||||||
@@ -1419,6 +1423,7 @@ def first_run(ctx):
|
|||||||
except OSError:
|
except OSError:
|
||||||
homes_before = set()
|
homes_before = set()
|
||||||
state = {"temp_account": None}
|
state = {"temp_account": None}
|
||||||
|
try:
|
||||||
with Restore(ctx, FIRST_RUN_SETTINGS):
|
with Restore(ctx, FIRST_RUN_SETTINGS):
|
||||||
with installed(ctx, {record_path(): seed, users_path(): None, override_path(): b""}):
|
with installed(ctx, {record_path(): seed, users_path(): None, override_path(): b""}):
|
||||||
w = wiz(fc)
|
w = wiz(fc)
|
||||||
@@ -1427,9 +1432,13 @@ def first_run(ctx):
|
|||||||
and w.get("advisories_complete") is False and w.get("acceptance_done") is False,
|
and w.get("advisories_complete") is False and w.get("acceptance_done") is False,
|
||||||
"the machine does not read as a first run: %s", wiz_summary(w))
|
"the machine does not read as a first run: %s", wiz_summary(w))
|
||||||
m = mode(fc)
|
m = mode(fc)
|
||||||
ctx.check(m.get("controller") == "gated", "the controller is %s on a first run", m.get("controller"))
|
ctx.check(m.get("controller") == "gated", "the controller is %s on a first run",
|
||||||
|
m.get("controller"))
|
||||||
yield state
|
yield state
|
||||||
# the real records are back; the system accounts follow the record
|
finally:
|
||||||
|
# the real records are back, whether or not the block passed; the
|
||||||
|
# system accounts follow the record, and a temporary account the
|
||||||
|
# block created goes with its home
|
||||||
rc, out = hw.initd("forgefirm-users", "reload")
|
rc, out = hw.initd("forgefirm-users", "reload")
|
||||||
ev["users_reload_rc"] = rc
|
ev["users_reload_rc"] = rc
|
||||||
ctx.log("forgefirm-users reload -> rc %s %s", rc, out.strip()[:200])
|
ctx.log("forgefirm-users reload -> rc %s %s", rc, out.strip()[:200])
|
||||||
|
|||||||
Reference in New Issue
Block a user