setup.focus: the test's own sysfs reads go on record however the burn ends, and their tube-current check has a case

emission_seen, the two peaks the test reads from sysfs at every poll
and the count of polls that read both, was written inside emission_ok
after the three checks of the burn's result. A burn the daemon reports
dark fails at the first of them (Context.check raises), and a burn that
ends in a wizard error, a timeout or an abort never reaches emission_ok.
On each of those paths the record kept the daemon's word alone, where
the test's own reading is the one worth comparing with it. burn() now
records emission_seen, and logs it, in the finally of its run_check, so
it is on record however the burn ends. emission_ok keeps its checks, in
their order.

The check that the tube current read over HV_ON from here had no case
that could fail it: the one negative case reads both attributes at 0
and stops at the LASER_ON check, which comes first. A new case reads
the LASER_ON count nonzero and the tube current at 0, and fails on the
tube current.

Proof: tests/test_setup_burns.py, the Unit tests step of
forgetest-ci.yml (python -B -m unittest discover -s tests), 23 tests OK
on Windows with python 3.14 and on Ubuntu 24.04 with python 3.12, with
tests/test_setup_dark.py (20 OK):
test_a_burn_whose_tube_current_the_test_never_saw_rise_fails
(cnc/laser_on_sampled 118, pic/hv_current 0: Failed "the tube current
never read over 30 from here", the settings as found);
test_a_dark_burn_fails_and_still_restores finds emission_seen at 118
and 431 beside the dark result; the aborted burn's record carries
emission_seen too. run_test keeps the Run of a test that fails.
Negative controls on scratch copies: the tube-current check made
vacuous (True or ...) fails the new case (Failed not raised);
setup_burns.py as it was fails the dark case (no emission_seen) and the
aborted case. pyflakes reports no undefined name.

Acceptance: setup.focus's fingerprint moves (setup_burns.py's shared
text); no other test moves (source_sha compared before and after).
Against the campaign this series already needs, that adds no run:
850498f moved all 43 once.
This commit is contained in:
ScottW514
2026-10-16 14:44:40 -04:00
parent bed46e961e
commit 9451587728
2 changed files with 20 additions and 4 deletions
+6 -3
View File
@@ -176,9 +176,6 @@ def emission_ok(ctx, last, seen):
"the result does not record the beam sensor: %s", e) "the result does not record the beam sensor: %s", e)
ctx.log("the beam sensor rose %s (seen: %s)", e.get("thermopile_delta"), e.get("beam_sensor_seen")) ctx.log("the beam sensor rose %s (seen: %s)", e.get("thermopile_delta"), e.get("beam_sensor_seen"))
w = seen.record() w = seen.record()
ctx.evidence["emission_seen"] = w
ctx.log("seen from here: LASER_ON count peak %s, tube current peak %s over %d polls",
w["laser_on_max"], w["hv_max"], w["reads"])
ctx.check(w["reads"] > 0, "the test could not read the witnesses from sysfs during the burn") ctx.check(w["reads"] > 0, "the test could not read the witnesses from sysfs during the burn")
ctx.check((w["laser_on_max"] or 0) > 0, ctx.check((w["laser_on_max"] or 0) > 0,
"the kernel's LASER_ON count never read nonzero from here during the burn (%d reads); the " "the kernel's LASER_ON count never read nonzero from here during the burn (%d reads); the "
@@ -231,6 +228,12 @@ def burn(ctx, wid, arm, pick, want):
last = run_check(ctx, wid, on_prompt, 900, on_poll=seen) last = run_check(ctx, wid, on_prompt, 900, on_poll=seen)
finally: finally:
ctx.clear_notice() ctx.clear_notice()
# What the test read itself goes on record however the burn ends:
# reported dark, failed, timed out, or aborted.
w = seen.record()
ctx.evidence["emission_seen"] = w
ctx.log("seen from here: LASER_ON count peak %s, tube current peak %s over %d polls",
w["laser_on_max"], w["hv_max"], w["reads"])
emission_ok(ctx, last, seen) emission_ok(ctx, last, seen)
r = last.get("result") or {} r = last.get("result") or {}
missing = [k for k in want if k not in r] missing = [k for k in want if k not in r]
+14 -1
View File
@@ -314,7 +314,7 @@ class BurnRunTests(unittest.TestCase):
def run_test(self, tid): def run_test(self, tid):
t = catalog.load_suite()[tid] t = catalog.load_suite()[tid]
run = Run("test", t.id, t.title) run = self.run = Run("test", t.id, t.title) # kept for a run that fails
run.unattended = True # the ready gate passes; the arm cue is a notice run.unattended = True # the ready gate passes; the arm cue is a notice
t.fn(Context(run, None, t)) t.fn(Context(run, None, t))
return run return run
@@ -434,6 +434,9 @@ class BurnRunTests(unittest.TestCase):
with self.assertRaises(Failed) as cm: with self.assertRaises(Failed) as cm:
self.run_test("setup.focus") self.run_test("setup.focus")
self.assertIn("the tube current never rose", str(cm.exception)) self.assertIn("the tube current never rose", str(cm.exception))
# what the test read itself is on record beside the daemon's word
seen = self.run.evidence["emission_seen"]
self.assertEqual((seen["laser_on_max"], seen["hv_max"]), (118, 431))
self.assert_found() self.assert_found()
def test_a_head_off_its_home_fails_before_any_start(self): def test_a_head_off_its_home_fails_before_any_start(self):
@@ -469,6 +472,15 @@ class BurnRunTests(unittest.TestCase):
self.assert_found() self.assert_found()
self.assert_restarted_on_found() self.assert_restarted_on_found()
def test_a_burn_whose_tube_current_the_test_never_saw_rise_fails(self):
# The LASER_ON count read nonzero from here, and the tube current
# never left zero: the second witness is judged on its own reads.
self.plant("pic/hv_current", "0")
with self.assertRaises(Failed) as cm:
self.run_test("setup.focus")
self.assertIn("tube current never read over %d from here" % setup_burns.HV_ON, str(cm.exception))
self.assert_found()
def test_a_burn_with_a_silent_beam_sensor_passes(self): def test_a_burn_with_a_silent_beam_sensor_passes(self):
# A head whose beam sensor gives no output: the tube current and # A head whose beam sensor gives no output: the tube current and
# LASER_ON saw the beam, so the burn counts. # LASER_ON saw the beam, so the burn counts.
@@ -511,6 +523,7 @@ class BurnRunTests(unittest.TestCase):
with self.assertRaises(Aborted): with self.assertRaises(Aborted):
t.fn(Context(run, None, t)) t.fn(Context(run, None, t))
self.assertEqual(self.daemon.aborted, ["laser.focus"]) self.assertEqual(self.daemon.aborted, ["laser.focus"])
self.assertIn("emission_seen", run.evidence) # the test's own reads, on record all the same
self.assert_found() self.assert_found()
self.assert_restarted_on_found() self.assert_restarted_on_found()