US02-02: Persist and Coordinate Durable Jobs (#55)

This commit was merged in pull request #55.
This commit is contained in:
2026-07-15 22:47:13 +02:00
parent 22558a4efa
commit 0ebacfa544
7 changed files with 721 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
"""Job/item state-machine rules: only declared transitions are legal, and terminal
states are truly terminal (no duplicate terminal transition)."""
import pytest
from photo_pipeline.services.jobs import (
ALLOWED_TRANSITIONS,
ITEM_TRANSITIONS,
TERMINAL_STATES,
ItemState,
JobState,
can_transition,
)
def test_happy_path_transitions_are_allowed():
assert can_transition(JobState.QUEUED, JobState.RUNNING)
assert can_transition(JobState.RUNNING, JobState.SUCCEEDED)
assert can_transition(JobState.RUNNING, JobState.FAILED)
assert can_transition(JobState.FAILED, JobState.RETRY_QUEUED)
assert can_transition(JobState.RETRY_QUEUED, JobState.RUNNING)
assert can_transition(JobState.RUNNING, JobState.CANCELLING)
assert can_transition(JobState.CANCELLING, JobState.CANCELLED)
@pytest.mark.parametrize(
"current,target",
[
(JobState.QUEUED, JobState.SUCCEEDED), # can't skip running
(JobState.SUCCEEDED, JobState.RUNNING), # terminal, no revive
(JobState.CANCELLED, JobState.RUNNING), # terminal
(JobState.RUNNING, JobState.QUEUED), # no backward
],
)
def test_invalid_transitions_are_rejected(current, target):
assert not can_transition(current, target)
def test_terminal_states_have_no_outgoing_transition():
for state in TERMINAL_STATES:
assert ALLOWED_TRANSITIONS[state] == set()
def test_duplicate_terminal_transition_is_rejected():
assert not can_transition(JobState.SUCCEEDED, JobState.SUCCEEDED)
assert not can_transition(JobState.CANCELLED, JobState.CANCELLED)
def test_item_states_are_consistent():
assert ItemState.SUCCEEDED in ITEM_TRANSITIONS[ItemState.RUNNING]
assert ITEM_TRANSITIONS[ItemState.SUCCEEDED] == set() # terminal item