Add Core Hub production stabilization scheduled checks
Introduce the core-hub context resolver stabilization_check query, State Hub progress summaries, activity-definition projections, and unit tests for the CORE-WP-0007 post-cutover window.
This commit is contained in:
parent
c253139ee3
commit
151512a8fa
5 changed files with 383 additions and 1 deletions
98
tests/test_core_hub_context_resolver.py
Normal file
98
tests/test_core_hub_context_resolver.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from activity_core.context_resolvers.core_hub import CoreHubContextResolver
|
||||
|
||||
|
||||
class DummyResponse:
|
||||
def __init__(self, payload: Any, status_code: int = 200) -> None:
|
||||
self._payload = payload
|
||||
self.status_code = status_code
|
||||
self.text = str(payload)
|
||||
|
||||
def json(self) -> Any:
|
||||
return self._payload
|
||||
|
||||
|
||||
class DummyClient:
|
||||
def __init__(self, responses: dict[str, tuple[Any, int]]) -> None:
|
||||
self._responses = responses
|
||||
|
||||
def __enter__(self) -> DummyClient:
|
||||
return self
|
||||
|
||||
def __exit__(self, *args: Any) -> None:
|
||||
return None
|
||||
|
||||
def get(self, path: str) -> DummyResponse:
|
||||
payload, status = self._responses.get(
|
||||
path,
|
||||
({}, 404),
|
||||
)
|
||||
return DummyResponse(payload, status)
|
||||
|
||||
|
||||
def test_core_hub_stabilization_check_passes(monkeypatch) -> None:
|
||||
widget_types = [{"slug": f"type-{index}"} for index in range(26)]
|
||||
responses = {
|
||||
"/healthz": ({}, 200),
|
||||
"/readyz": ({}, 200),
|
||||
"/api/v2/widget-types": (widget_types, 200),
|
||||
"/api/v2/hubs": ({}, 401),
|
||||
}
|
||||
fixed_now = datetime(2026, 7, 7, 10, 0, tzinfo=timezone.utc)
|
||||
monkeypatch.setattr(httpx, "Client", lambda **kwargs: DummyClient(responses))
|
||||
monkeypatch.setattr(
|
||||
"activity_core.context_resolvers.core_hub._utc_now",
|
||||
lambda: fixed_now,
|
||||
)
|
||||
|
||||
result = CoreHubContextResolver().resolve("stabilization_check", None, {})
|
||||
|
||||
assert result["overall_pass"] is True
|
||||
assert result["skipped"] is False
|
||||
assert result["checks"]["widget_types_count"]["pass"] is True
|
||||
assert result["checks"]["api_v2_hubs"]["pass"] is True
|
||||
|
||||
|
||||
def test_core_hub_stabilization_check_skips_outside_window(monkeypatch) -> None:
|
||||
fixed_now = datetime(2026, 7, 12, 10, 0, tzinfo=timezone.utc)
|
||||
monkeypatch.setattr(
|
||||
"activity_core.context_resolvers.core_hub._utc_now",
|
||||
lambda: fixed_now,
|
||||
)
|
||||
|
||||
result = CoreHubContextResolver().resolve("stabilization_check", None, {})
|
||||
|
||||
assert result["skipped"] is True
|
||||
assert result["reason"] == "outside_stabilization_window"
|
||||
|
||||
|
||||
def test_core_hub_stabilization_closeout_raises_on_failure(monkeypatch) -> None:
|
||||
responses = {
|
||||
"/healthz": ({}, 500),
|
||||
"/readyz": ({}, 200),
|
||||
"/api/v2/widget-types": ([], 200),
|
||||
"/api/v2/hubs": ({}, 401),
|
||||
}
|
||||
fixed_now = datetime(2026, 7, 7, 10, 0, tzinfo=timezone.utc)
|
||||
monkeypatch.setattr(httpx, "Client", lambda **kwargs: DummyClient(responses))
|
||||
monkeypatch.setattr(
|
||||
"activity_core.context_resolvers.core_hub._utc_now",
|
||||
lambda: fixed_now,
|
||||
)
|
||||
|
||||
try:
|
||||
CoreHubContextResolver().resolve(
|
||||
"stabilization_check",
|
||||
None,
|
||||
{"closeout": True},
|
||||
)
|
||||
except RuntimeError as exc:
|
||||
assert "closeout failed" in str(exc)
|
||||
else:
|
||||
raise AssertionError("expected closeout failure")
|
||||
Loading…
Add table
Add a link
Reference in a new issue