Repair production automation truth and schedule cleanup
This commit is contained in:
parent
8bcb416285
commit
944fd158de
19 changed files with 441 additions and 64 deletions
|
|
@ -89,7 +89,7 @@ async def test_evaluate_instructions_returns_report_payload(monkeypatch) -> None
|
|||
"trusted_fields": [],
|
||||
"model": "test-model",
|
||||
"prompt": "Run report.",
|
||||
"output_schema": "schemas/daily-triage-report.json",
|
||||
"output_schema": "activity-core://schemas/daily-triage-report.json",
|
||||
"review_required": False,
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -201,6 +201,15 @@ async def test_status_endpoint_wraps_report(
|
|||
}
|
||||
|
||||
monkeypatch.setattr(ops_api, "ops_status", fake_status)
|
||||
session = AsyncMock()
|
||||
session.__aenter__ = AsyncMock(return_value=session)
|
||||
session.__aexit__ = AsyncMock(return_value=None)
|
||||
count_result = MagicMock()
|
||||
count_result.all.return_value = []
|
||||
stuck_result = MagicMock()
|
||||
stuck_result.scalar_one.return_value = 0
|
||||
session.execute = AsyncMock(side_effect=[count_result, stuck_result])
|
||||
ops_app.state.session_factory.return_value = session
|
||||
transport = ASGITransport(app=ops_app)
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
res = await client.get("/ops/automations/status", params={"since": "sunday"})
|
||||
|
|
|
|||
|
|
@ -79,6 +79,25 @@ def test_external_configmap_projects_disabled_ops_probe_definition(tmp_path) ->
|
|||
]
|
||||
|
||||
|
||||
def test_daily_todo_pause_note_matches_safe_sink_default(tmp_path) -> None:
|
||||
runtime_config = _by_kind_name("ConfigMap", "actcore-runtime-config")
|
||||
definition_config = _by_kind_name(
|
||||
"ConfigMap", "actcore-external-activity-definitions"
|
||||
)
|
||||
raw_definition = definition_config["data"]["daily-todo-md-stale-review.md"]
|
||||
definition_path = tmp_path / "daily-todo-md-stale-review.md"
|
||||
definition_path.write_text(raw_definition, encoding="utf-8")
|
||||
|
||||
definition = parse_file(definition_path)
|
||||
|
||||
assert runtime_config["data"]["ISSUE_SINK_TYPE"] == "state-hub"
|
||||
assert definition.enabled is False
|
||||
assert "ACTIVITY-WP-0022" in raw_definition
|
||||
assert "`ISSUE_SINK_TYPE=state-hub`" in raw_definition
|
||||
assert "default `rest`" not in raw_definition
|
||||
assert "does **not** create a Forgejo issue" in raw_definition
|
||||
|
||||
|
||||
def test_external_configmap_projects_weekly_legacy_meter_review(tmp_path) -> None:
|
||||
config = _by_kind_name("ConfigMap", "actcore-external-activity-definitions")
|
||||
raw_definition = config["data"]["weekly-legacy-meter-review.md"]
|
||||
|
|
@ -146,7 +165,7 @@ def test_statehub_edge_relay_deployment_uses_state_hub_image_and_outbox_pvc() ->
|
|||
container = deployment["spec"]["template"]["spec"]["containers"][0]
|
||||
env = {item["name"]: item["value"] for item in container["env"]}
|
||||
|
||||
assert container["image"] == "forgejo.coulomb.social/coulomb/state-hub:main-d8808bf"
|
||||
assert container["image"] == "forgejo.coulomb.social/coulomb/state-hub:main-1cf949b"
|
||||
assert env["STATEHUB_UPSTREAM_URL"] == "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
assert env["STATEHUB_OUTBOX_PATH"] == "/var/statehub/edge-outbox.sqlite3"
|
||||
assert env["STATEHUB_READ_CACHE_PATH"] == "/var/statehub/edge-read-cache.sqlite3"
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ def test_post_missed_fire_alert_dual_writes_workplan_scope(monkeypatch) -> None:
|
|||
posts: list[dict] = []
|
||||
|
||||
class _Resp:
|
||||
status_code = 201
|
||||
|
||||
def raise_for_status(self) -> None: ...
|
||||
def json(self) -> dict[str, str]:
|
||||
return {"id": "progress-1"}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ async def test_sync_schedule_rows_reports_drift_counts_and_preserves_one_shots(
|
|||
orphan_id = uuid.uuid4()
|
||||
upserted: list[tuple[uuid.UUID, bool, str]] = []
|
||||
deleted: list[str] = []
|
||||
cancelled_one_shots: list[uuid.UUID] = []
|
||||
|
||||
async def fake_upsert_schedule(client: object, defn: object) -> None:
|
||||
upserted.append((
|
||||
|
|
@ -65,9 +66,13 @@ async def test_sync_schedule_rows_reports_drift_counts_and_preserves_one_shots(
|
|||
async def fake_delete_schedule(client: object, activity_id: str) -> None:
|
||||
deleted.append(activity_id)
|
||||
|
||||
async def fake_cancel_scheduled(client: object, activity_id: uuid.UUID) -> None:
|
||||
cancelled_one_shots.append(activity_id)
|
||||
|
||||
monkeypatch.setattr(sync_schedules, "upsert_schedule", fake_upsert_schedule)
|
||||
monkeypatch.setattr(sync_schedules, "list_schedules", fake_list_schedules)
|
||||
monkeypatch.setattr(sync_schedules, "delete_schedule", fake_delete_schedule)
|
||||
monkeypatch.setattr(sync_schedules, "cancel_scheduled", fake_cancel_scheduled)
|
||||
|
||||
result = await sync_schedules.sync_schedule_rows(
|
||||
object(),
|
||||
|
|
@ -125,6 +130,49 @@ async def test_sync_schedule_rows_reports_drift_counts_and_preserves_one_shots(
|
|||
(one_shot_id, True, "scheduled"),
|
||||
]
|
||||
assert deleted == [str(orphan_id)]
|
||||
assert cancelled_one_shots == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_sync_schedule_rows_removes_disabled_one_shot(monkeypatch) -> None:
|
||||
one_shot_id = uuid.uuid4()
|
||||
cancelled: list[uuid.UUID] = []
|
||||
|
||||
async def fake_upsert_schedule(client: object, defn: object) -> None:
|
||||
raise AssertionError("disabled one-shot must not be upserted")
|
||||
|
||||
async def fake_cancel_scheduled(client: object, activity_id: uuid.UUID) -> None:
|
||||
cancelled.append(activity_id)
|
||||
|
||||
async def fake_list_schedules(client: object) -> list[dict[str, str]]:
|
||||
return []
|
||||
|
||||
monkeypatch.setattr(sync_schedules, "upsert_schedule", fake_upsert_schedule)
|
||||
monkeypatch.setattr(sync_schedules, "cancel_scheduled", fake_cancel_scheduled)
|
||||
monkeypatch.setattr(sync_schedules, "list_schedules", fake_list_schedules)
|
||||
|
||||
result = await sync_schedules.sync_schedule_rows(
|
||||
object(),
|
||||
[
|
||||
_row(
|
||||
activity_id=one_shot_id,
|
||||
enabled=False,
|
||||
trigger_config={
|
||||
"trigger_type": "scheduled",
|
||||
"at": datetime(2026, 8, 17, 6, 0, tzinfo=timezone.utc),
|
||||
"timezone": "UTC",
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
assert cancelled == [one_shot_id]
|
||||
assert result.to_dict() == {
|
||||
"upserted": 0,
|
||||
"paused": 1,
|
||||
"deleted_orphans": 0,
|
||||
"errors": 0,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ async def test_run_sync_runs_requested_sections(monkeypatch) -> None:
|
|||
"upserted": 3,
|
||||
"paused": 1,
|
||||
"deleted_orphans": 2,
|
||||
"errors": 0,
|
||||
}
|
||||
assert result["errors"] == []
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue