test: harden scheduling review boundaries

This commit is contained in:
lda
2026-09-10 02:17:27 +07:00 Verified
parent ed70223c1b
commit f8ed8e2192
10 changed files with 231 additions and 25 deletions
+83 -3
View File
@@ -9,10 +9,12 @@ anew.
from __future__ import annotations
from datetime import UTC, datetime, timedelta
from datetime import UTC, datetime, timedelta, timezone
from pathlib import Path
from typing import Any, cast
import pytest
from tests.artifacts.test_run_store import artifact as _artifact
from tests.artifacts.test_run_store import deployment as _deployment
from tests.scheduling.controlled import (
@@ -30,7 +32,11 @@ from wf_artifacts.runs.models import ResumeAttempt
from wf_artifacts.runs.store import FileRunStore
from wf_core import RunState, RunStatus
from wf_scheduling import recovery as sched_recovery
from wf_scheduling.history import FileScheduleHistoryRecorder
from wf_scheduling.history import (
FileScheduleHistoryRecorder,
HistoryEntry,
entry_occurrence_id,
)
from wf_scheduling.models import Schedule
from wf_scheduling.ownership import SchedulerOwnership
from wf_scheduling.poll import Scheduler
@@ -136,6 +142,80 @@ def _recover(
ownership.release()
def test_interval_identity_normalizes_offsets_and_deduplicates(
tmp_path: Path,
) -> None:
store = FileScheduleStore(tmp_path / "sched")
recorder = FileScheduleHistoryRecorder(store)
utc_start = datetime(2026, 9, 8, 12, 0, tzinfo=UTC)
utc_end = datetime(2026, 9, 8, 13, 0, tzinfo=UTC)
offset = timezone(timedelta(hours=2))
recorder.record(
HistoryEntry(
schedule_id="a",
kind="interval-summary",
interval_start=utc_start,
interval_end=utc_end,
interval_count=2,
created_at=utc_start,
)
)
recorder.record(
HistoryEntry(
schedule_id="a",
kind="interval-summary",
interval_start=utc_start.astimezone(offset),
interval_end=utc_end.astimezone(offset),
interval_count=2,
created_at=utc_end,
)
)
rows = cast(
list[dict[str, Any]], store.list_occurrences("a", limit=10)["occurrences"]
)
assert len(rows) == 1
row = rows[0]
assert row["occurrence_id"] == (
"a|summary|2026-09-08T12:00:00+00:00|2026-09-08T13:00:00+00:00"
)
assert row["interval_start"] == "2026-09-08T12:00:00Z"
assert row["interval_end"] == "2026-09-08T13:00:00Z"
@pytest.mark.parametrize(
("interval_start", "interval_end"),
[
(datetime(2026, 9, 8, 12, 0), datetime(2026, 9, 8, 13, 0, tzinfo=UTC)),
(datetime(2026, 9, 8, 12, 0, tzinfo=UTC), datetime(2026, 9, 8, 13, 0)),
(None, datetime(2026, 9, 8, 13, 0, tzinfo=UTC)),
(datetime(2026, 9, 8, 12, 0, tzinfo=UTC), None),
],
)
def test_interval_identity_rejects_naive_or_half_specified_bounds(
interval_start: datetime | None,
interval_end: datetime | None,
) -> None:
with pytest.raises(ValueError):
entry_occurrence_id(
HistoryEntry(
schedule_id="a",
kind="interval-summary",
interval_start=interval_start,
interval_end=interval_end,
),
datetime(2026, 9, 8, 14, 0, tzinfo=UTC),
)
def test_history_identity_without_interval_still_uses_created_time() -> None:
created = datetime(2026, 9, 8, 14, 0, tzinfo=UTC)
assert entry_occurrence_id(
HistoryEntry(schedule_id="a", kind="interval-summary"), created
) == "a|summary|2026-09-08T14:00:00+00:00"
def test_failed_run_persists_reason_without_callback(tmp_path: Path) -> None:
sched_store = FileScheduleStore(tmp_path / "sched")
run_store = FileRunStore(tmp_path / "runs")
@@ -466,7 +546,7 @@ def test_consumed_write_failure_recovers_without_dup(tmp_path: Path) -> None:
sched_store, run_store, ownership, script={"*": "hang"}
)
sched.sources["a"] = OneShotSource(intended)
with __import__("pytest").raises(OSError, match="injected consumed"):
with pytest.raises(OSError, match="injected consumed"):
sched.poll(intended)
assert [a.id for a in run_store.list_admissions()] != []
first = run_store.list_admissions()[0].id