mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-19 02:51:42 -07:00
forgetest: a press the fixture made and reported failed leaves no notice standing
press_now and arm_press hand the arm press to the operator when the
bench actuator reports that the press failed. When the box makes its
200 ms press and its reply is lost, the client raises that failure at
its 3 s timeout or later (with ip set in the config it does not
retry), and by then the controller has taken the press and put the
button out. The fallback put the notice up all the same and started
the watch, which waits for the button to light before it waits for it
to go out. The button does not light again, so "Press it now" stood
through the job and asked for a second press, and a press during the
job pauses it.
Both fallbacks now record the fixture's error and then read the
button. Out: the press was taken, it is recorded as the fixture's, and
no notice goes up. Lit, or unreadable: the notice goes up with its
watch, as before. Nothing presses for the operator, and no judge or
energy path changes.
Proof: forgetest-ci "Unit tests" (`python -B -m unittest discover -s
tests -v` in forgetest), on Ubuntu 24.04 with python 3.12 and on
Windows with python 3.14: test_fixture.py's
test_the_arm_notice_comes_down_when_the_press_is_taken gains the leg
where the box puts the button out and then reports a failure: press_now
returns True with no notice and the press recorded as the fixture's,
and arm_press leaves no notice and the same record. The file's 21
tests OK on Ubuntu, and on Windows with
test_ready_reads_a_short_press_as_an_edge skipped (no os.mkfifo).
test_setup_burns.py (22), test_setup_dark.py (20), test_server.py
(10), test_operator.py (17), test_queue.py (15) and test_mode.py (9)
OK on Ubuntu. Negative controls on scratch copies: the leg
against the runner as it was fails at press_now (False, the notice
standing); with arm_press's fallback alone as it was, the leg fails at
its record ('operator', the notice up). pyflakes reports no undefined
name.
Acceptance: every catalog test's fingerprint moves: runner.py is a
shared judge, in every implementation hash (43 of 43 move). Against
the campaign this series already needs, that adds no run: 850498f moved
all 43 once. tests/ are in none.
This commit is contained in:
@@ -464,8 +464,9 @@ class Context:
|
|||||||
|
|
||||||
The fixture presses where the bench took this test's presses (or
|
The fixture presses where the bench took this test's presses (or
|
||||||
opted in standing); otherwise the notice goes up for a person,
|
opted in standing); otherwise the notice goes up for a person,
|
||||||
who is looking at the same prompt. Returns True when the fixture
|
who is looking at the same prompt. A press the fixture reports
|
||||||
pressed."""
|
failed while the button went out was taken all the same, and no
|
||||||
|
notice goes up for it. Returns True when the fixture pressed."""
|
||||||
fixture = getattr(self.runner, "fixture", None) if self.runner is not None else None
|
fixture = getattr(self.runner, "fixture", None) if self.runner is not None else None
|
||||||
rec = {"channel": "button", "state": "arm", "by": "operator", "ts": now_ts()}
|
rec = {"channel": "button", "state": "arm", "by": "operator", "ts": now_ts()}
|
||||||
self.evidence.setdefault("actions", []).append(rec)
|
self.evidence.setdefault("actions", []).append(rec)
|
||||||
@@ -483,6 +484,8 @@ class Context:
|
|||||||
fixture.act("button", "press")
|
fixture.act("button", "press")
|
||||||
except _fixture.FixtureError as e:
|
except _fixture.FixtureError as e:
|
||||||
rec["fixture_error"] = str(e)
|
rec["fixture_error"] = str(e)
|
||||||
|
if self._press_taken(rec, e):
|
||||||
|
return True
|
||||||
self.log("ARM press: fixture failed (%s) - asking the operator", e)
|
self.log("ARM press: fixture failed (%s) - asking the operator", e)
|
||||||
self.notice(text)
|
self.notice(text)
|
||||||
self._clear_when_taken()
|
self._clear_when_taken()
|
||||||
@@ -491,6 +494,20 @@ class Context:
|
|||||||
self.log("ARM press by the fixture, at the machine's own press prompt")
|
self.log("ARM press by the fixture, at the machine's own press prompt")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _press_taken(self, rec, err):
|
||||||
|
"""After the box reported a failed press of a lit button: True when
|
||||||
|
the button is out, so the controller took a press (the box pressed
|
||||||
|
and its reply was lost). The press is recorded as the box's, and
|
||||||
|
no notice goes up, because it would ask for a second press, and a
|
||||||
|
press during the job pauses it. A button still lit, or unreadable,
|
||||||
|
is False: the operator is asked."""
|
||||||
|
if hw.button_lit() is not False:
|
||||||
|
return False
|
||||||
|
rec["by"] = "fixture"
|
||||||
|
self.log("ARM press: the fixture reported a failure (%s), and the button is out: the press "
|
||||||
|
"was taken; no notice", err)
|
||||||
|
return True
|
||||||
|
|
||||||
def _clear_when_taken(self, lit_timeout=ARM_LIT_WAIT_S):
|
def _clear_when_taken(self, lit_timeout=ARM_LIT_WAIT_S):
|
||||||
"""Take the arm notice down the moment the press is taken: the
|
"""Take the arm notice down the moment the press is taken: the
|
||||||
controller lights the button white for its arm wait and puts it out
|
controller lights the button white for its arm wait and puts it out
|
||||||
@@ -541,8 +558,9 @@ class Context:
|
|||||||
seconds for the button to light (the job may still be on its way
|
seconds for the button to light (the job may still be on its way
|
||||||
to the arm wait; a card that settles the coolant first takes
|
to the arm wait; a card that settles the coolant first takes
|
||||||
minutes) and presses once, recorded as the fixture's; if the
|
minutes) and presses once, recorded as the fixture's; if the
|
||||||
button never lights or the press fails, the notice goes up for a
|
button never lights, or the press fails with the button still lit,
|
||||||
person. Returns True when the fixture has been asked."""
|
the notice goes up for a person. Returns True when the fixture has
|
||||||
|
been asked."""
|
||||||
fixture = getattr(self.runner, "fixture", None) if self.runner is not None else None
|
fixture = getattr(self.runner, "fixture", None) if self.runner is not None else None
|
||||||
rec = {"channel": "button", "state": "arm", "by": "operator", "ts": now_ts()}
|
rec = {"channel": "button", "state": "arm", "by": "operator", "ts": now_ts()}
|
||||||
self.evidence.setdefault("actions", []).append(rec)
|
self.evidence.setdefault("actions", []).append(rec)
|
||||||
@@ -572,8 +590,11 @@ class Context:
|
|||||||
try:
|
try:
|
||||||
fixture.act("button", "press")
|
fixture.act("button", "press")
|
||||||
except _fixture.FixtureError as e:
|
except _fixture.FixtureError as e:
|
||||||
self.log("ARM press: fixture failed (%s) - asking the operator", e)
|
|
||||||
rec["fixture_error"] = str(e)
|
rec["fixture_error"] = str(e)
|
||||||
|
if self._press_taken(rec, e):
|
||||||
|
rec["took_s"] = round(lit, 2)
|
||||||
|
return
|
||||||
|
self.log("ARM press: fixture failed (%s) - asking the operator", e)
|
||||||
self.notice(text)
|
self.notice(text)
|
||||||
self._clear_when_taken()
|
self._clear_when_taken()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -626,6 +626,25 @@ class RoutingTests(unittest.TestCase):
|
|||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
lit["v"] = False
|
lit["v"] = False
|
||||||
self.assertTrue(settles(False))
|
self.assertTrue(settles(False))
|
||||||
|
# A press the box made and reported failed (its reply lost after
|
||||||
|
# the press): the button is out when the error arrives, so the
|
||||||
|
# press was taken, and no notice asks for a second one.
|
||||||
|
def pressed_then_failed(channel, state, ms=None):
|
||||||
|
lit["v"] = False # the controller takes the press
|
||||||
|
raise fx.FixtureError("timed out")
|
||||||
|
self.stub.act = pressed_then_failed
|
||||||
|
lit["v"] = True
|
||||||
|
self.assertTrue(ctx.press_now())
|
||||||
|
self.assertIsNone(run.notice)
|
||||||
|
self.assertEqual(ctx.evidence["actions"][-1]["by"], "fixture")
|
||||||
|
lit["v"] = True
|
||||||
|
self.assertTrue(ctx.arm_press())
|
||||||
|
deadline = time.time() + 2
|
||||||
|
while ctx.evidence["actions"][-1]["by"] != "fixture" and time.time() < deadline:
|
||||||
|
time.sleep(0.02)
|
||||||
|
time.sleep(0.1)
|
||||||
|
self.assertEqual(ctx.evidence["actions"][-1]["by"], "fixture")
|
||||||
|
self.assertIsNone(run.notice)
|
||||||
finally:
|
finally:
|
||||||
runner_mod.hw.button_lit = saved
|
runner_mod.hw.button_lit = saved
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user