svcforge: reference implementation
ci / lint (push) Successful in 1m19s
ci / unit (push) Failing after 1m2s
ci / integration (push) Has been skipped
ci / types (push) Successful in 1m37s
ci / security (push) Failing after 38s
ci / dockerfile (push) Successful in 14s
ci / image (api) (push) Has been skipped
ci / image (reconciler) (push) Has been skipped
ci / image (worker) (push) Has been skipped
ci / bump (push) Has been skipped

Complete working build of the system learn-python/ teaches.
164 tests, mypy --strict clean, domain coverage 99%.
This commit is contained in:
Nguyen Minh Phuc
2026-07-17 10:44:54 +00:00
commit 50c2fe2a1e
102 changed files with 12018 additions and 0 deletions
+144
View File
@@ -0,0 +1,144 @@
"""Unit tests for maintenance windows. Pure domain: no DB, no clock, no mocks.
`now` is a parameter everywhere in `windows.py`, which is why none of these tests
monkeypatch `datetime.now` — there is nothing to patch. That is the point of the design.
"""
from datetime import UTC, datetime, timedelta
from zoneinfo import ZoneInfo
import pytest
from svcforge_core.domain.windows import (
BadWindow,
MaintenanceWindow,
next_window_open,
parse_window,
schedule_upgrade_at,
)
HCM = MaintenanceWindow("0 3 * * 0", "Asia/Ho_Chi_Minh") # 03:00 every Sunday, Vietnam time
def test_next_window_open_with_naive_now_raises_value_error() -> None:
"""The one bug this module exists to prevent, caught at the boundary.
A naive datetime does not raise when you build it; it raises when you compare it,
which is inside a worker at 03:00. mypy sees `datetime` either way.
"""
with pytest.raises(ValueError, match="aware"):
next_window_open(HCM, datetime(2026, 7, 18, 20, 0)) # naive on purpose
def test_next_window_open_returns_the_hcm_sunday_expressed_in_utc() -> None:
"""Sunday 03:00 in Ho Chi Minh (UTC+7, no DST) is Saturday 20:00 UTC.
`now` here IS that instant, and the answer is that instant: the window is open right
now, so the upgrade runs now. Strictly-greater semantics would push it a full week.
"""
now = datetime(2026, 7, 18, 20, 0, tzinfo=UTC)
assert now.weekday() == 5 # a Saturday
opens = next_window_open(HCM, now)
assert opens.tzinfo is UTC
assert opens == datetime(2026, 7, 18, 20, 0, tzinfo=UTC)
assert opens.astimezone(ZoneInfo("Asia/Ho_Chi_Minh")) == datetime(
2026, 7, 19, 3, 0, tzinfo=ZoneInfo("Asia/Ho_Chi_Minh")
)
def test_next_window_open_rolls_to_next_week_once_the_window_has_passed() -> None:
"""A second past the open and you wait for the next one. Guards the -1s inclusivity trick."""
opens = next_window_open(HCM, datetime(2026, 7, 18, 20, 0, 1, tzinfo=UTC))
assert opens == datetime(2026, 7, 25, 20, 0, tzinfo=UTC)
assert opens.tzinfo is UTC
def test_schedule_upgrade_at_with_security_returns_now_exactly() -> None:
"""A CVE with a public exploit does not wait until Sunday."""
now = datetime(2026, 7, 18, 20, 0, tzinfo=UTC)
assert schedule_upgrade_at(HCM, security=True, now=now) == now
def test_schedule_upgrade_at_without_window_returns_now() -> None:
"""maintenance_window is null -> upgrade any time."""
now = datetime(2026, 7, 15, 9, 30, tzinfo=UTC)
assert schedule_upgrade_at(None, security=False, now=now) == now
assert next_window_open(None, now).tzinfo is UTC
def test_window_across_spring_forward_returns_one_aware_instant() -> None:
"""DST spring-forward, asserting croniter's REAL behaviour rather than trusting docs.
On 2026-03-08 America/New_York jumps 02:00 EST -> 03:00 EDT, so a `30 2 * * *` window
has no 02:30 that day. Observed: croniter does not skip the day and does not raise —
it CLAMPS to the transition instant, yielding 03:00:00-04:00 (not 03:30). The window
opens half an hour "late" in local terms, exactly once, and the following days resume
at 02:30 EDT. One instant, aware, and the caller never sees a nonexistent local time.
"""
window = MaintenanceWindow("30 2 * * *", "America/New_York")
now = datetime(2026, 3, 7, 17, 0, tzinfo=UTC) # Sat midday in New York, before the jump
opens = next_window_open(window, now)
assert opens.tzinfo is UTC
assert opens == datetime(2026, 3, 8, 7, 0, tzinfo=UTC) # == 03:00 EDT, the clamp
local = opens.astimezone(ZoneInfo("America/New_York"))
assert (local.hour, local.minute) == (3, 0)
assert local.utcoffset() == timedelta(hours=-4) # EDT: the jump has happened
# The day after, the window is back where the tenant expects it.
after = next_window_open(window, opens + timedelta(seconds=1))
assert after == datetime(2026, 3, 9, 6, 30, tzinfo=UTC) # 02:30 EDT
def test_window_across_fall_back_returns_the_first_of_the_two_local_times() -> None:
"""Fall-back makes 01:30 happen twice. Observed: croniter yields BOTH, EDT then EST.
next_window_open returns the earlier one (fold=0, -04:00). Not a bug to fix here: a
window that opens twice on one night is what the tenant's cron literally asked for.
"""
window = MaintenanceWindow("30 1 * * *", "America/New_York")
now = datetime(2026, 10, 31, 16, 0, tzinfo=UTC)
first = next_window_open(window, now)
second = next_window_open(window, first + timedelta(seconds=1))
assert first == datetime(2026, 11, 1, 5, 30, tzinfo=UTC) # 01:30 EDT
assert second == datetime(2026, 11, 1, 6, 30, tzinfo=UTC) # 01:30 EST, one hour later
assert first.tzinfo is UTC and second.tzinfo is UTC
def test_parse_window_bad_cron_raises_bad_window() -> None:
with pytest.raises(BadWindow, match="cron"):
parse_window("not a cron|Asia/Ho_Chi_Minh")
def test_parse_window_roundtrips_a_valid_spec() -> None:
assert parse_window("0 3 * * 0|Asia/Ho_Chi_Minh") == HCM
def test_parse_window_none_and_blank_mean_any_time() -> None:
assert parse_window(None) is None
assert parse_window(" ") is None
def test_parse_window_unknown_zone_raises_bad_window() -> None:
with pytest.raises(BadWindow, match="IANA"):
parse_window("0 3 * * 0|Mars/Olympus_Mons")
def test_parse_window_without_separator_raises_bad_window() -> None:
with pytest.raises(BadWindow, match="CRON"):
parse_window("0 3 * * 0")
def test_parse_window_six_field_cron_raises_bad_window() -> None:
"""croniter's is_valid() accepts a 6-field (seconds) form; the column is 5-field."""
with pytest.raises(BadWindow, match="exactly 5 fields"):
parse_window("0 0 3 * * 0|Asia/Ho_Chi_Minh")