diff --git a/forgetest/forgetest/suite/cloud.py b/forgetest/forgetest/suite/cloud.py index 37381b7..662534a 100644 --- a/forgetest/forgetest/suite/cloud.py +++ b/forgetest/forgetest/suite/cloud.py @@ -1209,18 +1209,23 @@ def lid_interlock_abort_body(ctx, ev, off, job, offset): @test("cloud.lid-during-button-wait", title="Lid open at the cloud button prompt cancels the print", - subsystem="cloud", kind="operator", est_min=6, + subsystem="cloud", kind="operator", est_min=8, covers=_MACHINE_RUN, requires=[], actions=["lid"], steps=[OFFLINE_STEP, LID_STEP, - "When the button lights white, do NOT press it - open the lid, and close it when told. " - "Nothing moves and nothing fires."], + "The job is longer than the ring holds, so the ring is filled before the button " + "lights; that takes a minute. When the button lights white, do NOT press it - open " + "the lid, and close it when told. Nothing moves and nothing fires."], description="A cloud print waiting for the button is cancelled by the lid: the wait ends " "with the lid named as the reason, the laser latch relocks, the armed window " - "closes, no run starts, and the job ends ':cancelled'.") + "closes, no run starts, and the job ends ':cancelled'. The job is longer than " + "the ring, so its feeder is alive through the wait with the rest of the print " + "in hand: the cancel has to stop that feeder before the park clears the ring, " + "and the ring has to stay empty afterward. A feeder left alive would refill " + "it and the park, which ignores the lid, would play the print's path.") def lid_during_button_wait(ctx): ev = ctx.evidence offset = enter_offline(ctx) - job = offline_job(ctx, "wait.puls", seconds=20) + job = offline_job(ctx, "wait.puls", seconds=3500) off = Offline().__enter__() try: lid_during_button_wait_body(ctx, ev, off, job, offset) @@ -1231,7 +1236,9 @@ def lid_during_button_wait(ctx): def lid_during_button_wait_body(ctx, ev, off, job, offset): off.print_ready(9003, job) - got = wait_log(ctx, offset, ["waiting for button"], 120) + got = wait_log(ctx, offset, ["job is longer than the ring", "waiting for button"], 180) + ctx.check(got["job is longer than the ring"], + "the job fit the ring: this test needs a job the ring cannot hold") ctx.check(got["waiting for button"], "the print never reached the button wait") ctx.act("lid", "open", text="The button is lit: do NOT press it.", timeout=120) relock = "button wait lid opened - relocking the laser" @@ -1261,11 +1268,25 @@ def lid_during_button_wait_body(ctx, ev, off, job, offset): ctx.check(ev["latch_locked"], "kernel latch not locked after the cancel") ev["button_dark"] = hw.button_lit() ctx.check(ev["button_dark"] is False, "the button is still lit after the cancel (%s)", ev["button_dark"]) + # The park cleared the ring and nothing refilled it: the feeder is gone, + # the device is out of live-feed mode, and the program total stands at + # zero and stays there. A feeder left alive shows here as a total that + # comes back within its retry period. + total = read_program_total() + ctx.sleep(2) + later = read_program_total() + streaming = hw.sysfs_int("cnc/streaming", 0) + ev["program_total_after"] = {"first": total, "later": later} + ev["streaming_after"] = streaming + ctx.check(total == 0 and later == 0, + "the ring is not empty after the cancel (program total %s, then %s): the feeder " + "outlived the job", total, later) + ctx.check(streaming == 0, "cnc/streaming is %s after the cancel", streaming) ctx.act("lid", "close") settle_cloud(ctx, offset) ev["events"] = offline_events(off) ctx.log("PASS: lid open at the button prompt cancelled the print; latch locked, armed=false, " - "button dark") + "button dark, ring empty with the feed stopped") @test("cloud.pause-resume", title="Button pauses and resumes a cloud print (factory backtrack + lead)", diff --git a/forgetest/tests/test_cloud_suite.py b/forgetest/tests/test_cloud_suite.py index 14e4461..1c4228c 100644 --- a/forgetest/tests/test_cloud_suite.py +++ b/forgetest/tests/test_cloud_suite.py @@ -893,7 +893,11 @@ class CloudSuiteTests(unittest.TestCase): self.in_offline() lines = fixture("buttonwait") pre, rest = cut(lines, "waiting for button") - pre, rest = pre + [rest[0]], rest[1:] + # The bench excerpt is a print that fit the ring; the test now wants + # one that did not, so the feeder is alive through the wait. + long_job = ("2026-08-17T09:44:14.100000+00:00 gfcloud[1927] INFO machine:_feed_and_run " + "job is longer than the ring: 33554432 bytes enqueued, feeding the rest as it plays") + pre, rest = pre + [long_job, rest[0]], rest[1:] self.offline_print_hooks(pre) hooks = {"do NOT press it": lambda: (self.lid(False), self.append(rest, delay=0.05)), "Close the lid.": lambda: self.lid(True)} @@ -903,6 +907,8 @@ class CloudSuiteTests(unittest.TestCase): self.assertEqual(ev["runs_started_after_wait"], 0) self.assertIn(":cancelled", ev["log"]["print finished"]) self.assertTrue(ev["latch_locked"]) + self.assertEqual(ev["program_total_after"], {"first": 0, "later": 0}) + self.assertEqual(ev["streaming_after"], 0) self.assertEqual(self.fc.posts, []) self.assertTrue(any("PASS: lid open at the button prompt" in l for l in run.lines))