- webapp.py lifespan now initializes json_logging, recovery, cost_guard, task_history - Dispatcher receives cost_guard and task_history dependencies - ContainerCleaner starts if Docker is available - Added /health/costs endpoint for API cost monitoring - Added tests/test_smoke.py with 2 tests for basic health and costs endpoint - All existing health tests still pass (8 tests)
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
import pytest
|
|
from contextlib import asynccontextmanager
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import httpx
|
|
|
|
|
|
@asynccontextmanager
|
|
async def mock_lifespan(app):
|
|
yield
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_smoke_health():
|
|
from agent.webapp import app
|
|
app.router.lifespan_context = mock_lifespan
|
|
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url="http://test") as client:
|
|
resp = await client.get("/health")
|
|
assert resp.status_code == 200
|
|
assert resp.json()["status"] == "ok"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_smoke_health_costs():
|
|
from agent.webapp import app
|
|
app.router.lifespan_context = mock_lifespan
|
|
|
|
mock_guard = MagicMock()
|
|
mock_guard.get_daily_summary = AsyncMock(return_value={
|
|
"total_cost_usd": 1.5,
|
|
"daily_limit_usd": 10.0,
|
|
"remaining_usd": 8.5,
|
|
"record_count": 3,
|
|
"total_tokens_input": 50000,
|
|
"total_tokens_output": 20000,
|
|
})
|
|
|
|
with patch("agent.cost_guard.get_cost_guard", new_callable=AsyncMock, return_value=mock_guard):
|
|
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url="http://test") as client:
|
|
resp = await client.get("/health/costs")
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["total_cost_usd"] == 1.5
|
|
assert data["daily_limit_usd"] == 10.0
|