forked from Rockachopa/Timmy-time-dashboard
This commit is contained in:
@@ -336,7 +336,12 @@ async def test_check_agent_health_no_token():
|
|||||||
"""Returns idle status gracefully when Gitea token is absent."""
|
"""Returns idle status gracefully when Gitea token is absent."""
|
||||||
from timmy.vassal.agent_health import check_agent_health
|
from timmy.vassal.agent_health import check_agent_health
|
||||||
|
|
||||||
status = await check_agent_health("claude")
|
mock_settings = MagicMock()
|
||||||
|
mock_settings.gitea_enabled = True
|
||||||
|
mock_settings.gitea_token = "" # explicitly no token → early return
|
||||||
|
|
||||||
|
with patch("config.settings", mock_settings):
|
||||||
|
status = await check_agent_health("claude")
|
||||||
# Should not raise; returns idle (no active issues discovered)
|
# Should not raise; returns idle (no active issues discovered)
|
||||||
assert isinstance(status, AgentStatus)
|
assert isinstance(status, AgentStatus)
|
||||||
assert status.agent == "claude"
|
assert status.agent == "claude"
|
||||||
@@ -478,7 +483,12 @@ async def test_check_agent_health_fetch_exception(monkeypatch):
|
|||||||
async def test_get_full_health_report_returns_both_agents():
|
async def test_get_full_health_report_returns_both_agents():
|
||||||
from timmy.vassal.agent_health import get_full_health_report
|
from timmy.vassal.agent_health import get_full_health_report
|
||||||
|
|
||||||
report = await get_full_health_report()
|
mock_settings = MagicMock()
|
||||||
|
mock_settings.gitea_enabled = False # disabled → no network calls
|
||||||
|
mock_settings.gitea_token = ""
|
||||||
|
|
||||||
|
with patch("config.settings", mock_settings):
|
||||||
|
report = await get_full_health_report()
|
||||||
agent_names = {a.agent for a in report.agents}
|
agent_names = {a.agent for a in report.agents}
|
||||||
assert "claude" in agent_names
|
assert "claude" in agent_names
|
||||||
assert "kimi" in agent_names
|
assert "kimi" in agent_names
|
||||||
@@ -488,7 +498,12 @@ async def test_get_full_health_report_returns_both_agents():
|
|||||||
async def test_get_full_health_report_structure():
|
async def test_get_full_health_report_structure():
|
||||||
from timmy.vassal.agent_health import get_full_health_report
|
from timmy.vassal.agent_health import get_full_health_report
|
||||||
|
|
||||||
report = await get_full_health_report()
|
mock_settings = MagicMock()
|
||||||
|
mock_settings.gitea_enabled = False # disabled → no network calls
|
||||||
|
mock_settings.gitea_token = ""
|
||||||
|
|
||||||
|
with patch("config.settings", mock_settings):
|
||||||
|
report = await get_full_health_report()
|
||||||
assert isinstance(report, AgentHealthReport)
|
assert isinstance(report, AgentHealthReport)
|
||||||
assert len(report.agents) == 2
|
assert len(report.agents) == 2
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,29 @@ from timmy.vassal.orchestration_loop import VassalCycleRecord, VassalOrchestrato
|
|||||||
|
|
||||||
pytestmark = pytest.mark.unit
|
pytestmark = pytest.mark.unit
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Helpers — prevent real network calls under xdist parallel execution
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def _disabled_settings() -> MagicMock:
|
||||||
|
"""Settings mock with Gitea disabled — backlog + agent health skip HTTP."""
|
||||||
|
s = MagicMock()
|
||||||
|
s.gitea_enabled = False
|
||||||
|
s.gitea_token = ""
|
||||||
|
s.vassal_stuck_threshold_minutes = 120
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def _fast_snapshot() -> MagicMock:
|
||||||
|
"""Minimal SystemSnapshot mock — no disk warnings, Ollama not probed."""
|
||||||
|
snap = MagicMock()
|
||||||
|
snap.warnings = []
|
||||||
|
snap.disk.percent_used = 0.0
|
||||||
|
return snap
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# VassalCycleRecord
|
# VassalCycleRecord
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -74,7 +97,15 @@ async def test_run_cycle_completes_without_services():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator(cycle_interval=300)
|
orch = VassalOrchestrator(cycle_interval=300)
|
||||||
|
|
||||||
record = await orch.run_cycle()
|
with (
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
record = await orch.run_cycle()
|
||||||
|
|
||||||
assert isinstance(record, VassalCycleRecord)
|
assert isinstance(record, VassalCycleRecord)
|
||||||
assert record.cycle_id == 1
|
assert record.cycle_id == 1
|
||||||
@@ -95,8 +126,16 @@ async def test_run_cycle_increments_cycle_count():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator()
|
orch = VassalOrchestrator()
|
||||||
|
|
||||||
await orch.run_cycle()
|
with (
|
||||||
await orch.run_cycle()
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
await orch.run_cycle()
|
||||||
|
await orch.run_cycle()
|
||||||
|
|
||||||
assert orch.cycle_count == 2
|
assert orch.cycle_count == 2
|
||||||
assert len(orch.history) == 2
|
assert len(orch.history) == 2
|
||||||
@@ -109,7 +148,15 @@ async def test_get_status_after_cycle():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator()
|
orch = VassalOrchestrator()
|
||||||
|
|
||||||
await orch.run_cycle()
|
with (
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
await orch.run_cycle()
|
||||||
status = orch.get_status()
|
status = orch.get_status()
|
||||||
|
|
||||||
assert status["cycle_count"] == 1
|
assert status["cycle_count"] == 1
|
||||||
@@ -183,10 +230,18 @@ async def test_run_cycle_records_backlog_error():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator()
|
orch = VassalOrchestrator()
|
||||||
|
|
||||||
with patch(
|
with (
|
||||||
"timmy.vassal.backlog.fetch_open_issues",
|
patch(
|
||||||
new_callable=AsyncMock,
|
"timmy.vassal.backlog.fetch_open_issues",
|
||||||
side_effect=ConnectionError("gitea unreachable"),
|
new_callable=AsyncMock,
|
||||||
|
side_effect=ConnectionError("gitea unreachable"),
|
||||||
|
),
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
):
|
):
|
||||||
record = await orch.run_cycle()
|
record = await orch.run_cycle()
|
||||||
|
|
||||||
@@ -202,10 +257,18 @@ async def test_run_cycle_records_agent_health_error():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator()
|
orch = VassalOrchestrator()
|
||||||
|
|
||||||
with patch(
|
with (
|
||||||
"timmy.vassal.agent_health.get_full_health_report",
|
patch(
|
||||||
new_callable=AsyncMock,
|
"timmy.vassal.agent_health.get_full_health_report",
|
||||||
side_effect=RuntimeError("health check failed"),
|
new_callable=AsyncMock,
|
||||||
|
side_effect=RuntimeError("health check failed"),
|
||||||
|
),
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
):
|
):
|
||||||
record = await orch.run_cycle()
|
record = await orch.run_cycle()
|
||||||
|
|
||||||
@@ -221,10 +284,13 @@ async def test_run_cycle_records_house_health_error():
|
|||||||
clear_dispatch_registry()
|
clear_dispatch_registry()
|
||||||
orch = VassalOrchestrator()
|
orch = VassalOrchestrator()
|
||||||
|
|
||||||
with patch(
|
with (
|
||||||
"timmy.vassal.house_health.get_system_snapshot",
|
patch(
|
||||||
new_callable=AsyncMock,
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
side_effect=OSError("disk check failed"),
|
new_callable=AsyncMock,
|
||||||
|
side_effect=OSError("disk check failed"),
|
||||||
|
),
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
):
|
):
|
||||||
record = await orch.run_cycle()
|
record = await orch.run_cycle()
|
||||||
|
|
||||||
@@ -301,6 +367,12 @@ async def test_run_cycle_respects_max_dispatch_cap():
|
|||||||
"timmy.vassal.dispatch.dispatch_issue",
|
"timmy.vassal.dispatch.dispatch_issue",
|
||||||
new_callable=AsyncMock,
|
new_callable=AsyncMock,
|
||||||
),
|
),
|
||||||
|
patch("config.settings", _disabled_settings()),
|
||||||
|
patch(
|
||||||
|
"timmy.vassal.house_health.get_system_snapshot",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
return_value=_fast_snapshot(),
|
||||||
|
),
|
||||||
):
|
):
|
||||||
record = await orch.run_cycle()
|
record = await orch.run_cycle()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user