mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
"""The respawn_tracker table — durable backing for the PM-respawn counter.
|
|||
|
|
|
||
|
|
Mirrors WaitingRecordTable: a composite-PK row per (agent_slug, task_id) the
|
||
|
|
orchestrator's loop-breaker counter is keyed on, so it survives a restart
|
||
|
|
instead of resetting to count=1 and re-burning the strike threshold.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import TYPE_CHECKING, cast
|
||
|
|
|
||
|
|
from roboco.db.tables import RespawnTrackerTable
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from sqlalchemy import Table
|
||
|
|
|
||
|
|
_TABLE = cast("Table", RespawnTrackerTable.__table__)
|
||
|
|
|
||
|
|
|
||
|
|
def test_table_name() -> None:
|
||
|
|
assert RespawnTrackerTable.__tablename__ == "respawn_tracker"
|
||
|
|
|
||
|
|
|
||
|
|
def test_composite_primary_key_is_agent_slug_and_task_id() -> None:
|
||
|
|
pk_cols = {col.name for col in _TABLE.primary_key.columns}
|
||
|
|
assert pk_cols == {"agent_slug", "task_id"}
|
||
|
|
|
||
|
|
|
||
|
|
def test_payload_columns_present() -> None:
|
||
|
|
cols = set(_TABLE.columns.keys())
|
||
|
|
assert {
|
||
|
|
"agent_slug",
|
||
|
|
"task_id",
|
||
|
|
"count",
|
||
|
|
"last_status",
|
||
|
|
"last_check",
|
||
|
|
"tracing_resets",
|
||
|
|
"notified",
|
||
|
|
"updated_at",
|
||
|
|
} <= cols
|
||
|
|
|
||
|
|
|
||
|
|
def test_task_id_has_no_foreign_key() -> None:
|
||
|
|
# Deliberately NOT a FK to tasks: the startup loader validates against live
|
||
|
|
# tasks instead, so a cascade can never silently resurrect/erase a counter.
|
||
|
|
task_id = _TABLE.columns["task_id"]
|
||
|
|
assert task_id.foreign_keys == set()
|
||
|
|
|
||
|
|
|
||
|
|
def test_last_check_index_present() -> None:
|
||
|
|
index_names = {idx.name for idx in _TABLE.indexes}
|
||
|
|
assert "ix_respawn_tracker_last_check" in index_names
|