Skip to content

Commit 9b2d732

Browse files
committed
fix(machine)
- refactor step reset trigger to avoid nested transitions
1 parent a61990d commit 9b2d732

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

src/lsst/cmservice/machines/nodes/steps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,9 @@ async def do_finish(self, event: EventData) -> None:
495495
async def do_reset(self, event: EventData) -> None:
496496
"""Transition method between "failed" and "waiting"."""
497497
# trigger retry to transition to ready
498-
await self.trigger("retry")
498+
await self.do_retry(event)
499499
# trigger unprepare to transition to waiting
500-
await self.trigger("unprepare")
500+
await self.do_unprepare(event)
501501

502502
async def do_retry(self, event: EventData) -> None:
503503
"""Transition method between "failed" and "ready"."""

tests/v2/test_machines.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,3 +739,52 @@ async def test_group_force_accept(
739739
await session.refresh(group, ["status", "metadata_", "machine"])
740740
group_status = group.status
741741
assert group_status is expected_status
742+
743+
744+
async def test_step_fail_reset(
745+
*,
746+
test_campaign_groups: str,
747+
session: AsyncSession,
748+
aclient: AsyncClient,
749+
) -> None:
750+
"""Tests that a failed Step is recoverable with the reset trigger"""
751+
campaign_id = urlparse(url=test_campaign_groups).path.split("/")[-2:][0]
752+
753+
# Fetch and FAIL to prepare a step, as a broken manifest may cause
754+
step_id = uuid5(UUID(campaign_id), "lambert.1")
755+
step = await session.get_one(Node, step_id)
756+
step_machine = StepMachine(o=step)
757+
with patch(
758+
"lsst.cmservice.machines.node.StepMachine.do_prepare",
759+
side_effect=RuntimeError("Step failed to prepare"),
760+
):
761+
await step_machine.trigger("prepare")
762+
763+
await session.refresh(step, ["status"])
764+
await session.commit()
765+
step_status = step.status
766+
assert step_status is StatusEnum.failed
767+
768+
# trigger 'RESET' by setting the status to waiting
769+
x = await aclient.patch(
770+
f"/cm-service/v2/nodes/{step.id}",
771+
json={"status": "waiting", "force": "true"},
772+
headers={"Content-Type": "application/merge-patch+json"},
773+
)
774+
assert x.is_success
775+
776+
# wait for and assert background task is successful
777+
update_url = x.headers["StatusUpdate"]
778+
for _ in range(5):
779+
x = await aclient.get(update_url)
780+
result = x.json()
781+
if len(result):
782+
activity_log_message = result[0]["detail"]["message"]
783+
assert "rolled back" in activity_log_message
784+
break
785+
else:
786+
await sleep(1.0)
787+
788+
await session.refresh(step, ["status", "metadata_"])
789+
step_status = step.status
790+
assert step_status is StatusEnum.waiting

0 commit comments

Comments
 (0)