Add anomaly and performance monitoring
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from time import perf_counter
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.actuators.lifecycle import ActuatorReconciliationService
|
||||
from app.actuators.models import ModelSnapshot
|
||||
from app.actuators.models import JobStatus, ModelSnapshot
|
||||
from app.actuators.store import ActuatorStore
|
||||
from app.behavior.engine import BehaviorEngine
|
||||
from app.config import Settings
|
||||
@@ -407,7 +407,7 @@ def test_reconciliation_run_records_visible_job_queue(tmp_path: Path) -> None:
|
||||
assert payload["jobs"][-1]["status"] == "completed"
|
||||
|
||||
|
||||
def test_dashboard_start_path_stays_within_five_second_budget(tmp_path: Path) -> None:
|
||||
def test_dashboard_start_path_stays_within_three_second_budget(tmp_path: Path) -> None:
|
||||
with TestClient(app) as client:
|
||||
_install_service(tmp_path)
|
||||
client.get("/v1/actuators/discovery")
|
||||
@@ -423,8 +423,38 @@ def test_dashboard_start_path_stays_within_five_second_budget(tmp_path: Path) ->
|
||||
|
||||
assert root_response.status_code == 200
|
||||
assert dashboard_response.status_code == 200
|
||||
assert root_elapsed < 5.0
|
||||
assert dashboard_elapsed < 5.0
|
||||
assert root_elapsed < 3.0
|
||||
assert dashboard_elapsed < 3.0
|
||||
|
||||
|
||||
def test_dashboard_reports_performance_budget_and_anomalies(tmp_path: Path) -> None:
|
||||
with TestClient(app) as client:
|
||||
_install_service(tmp_path)
|
||||
client.get("/v1/actuators/discovery")
|
||||
client.post("/v1/actuators", json={"actuator_entity_id": "light.abstellkammer"})
|
||||
store = app.state.actuator_store
|
||||
job = store.start_job(kind="training", trigger="test", summary="Langsamer Testjob")
|
||||
queue = store.load_job_queue()
|
||||
queue.jobs = [
|
||||
item.model_copy(update={"started_at": datetime.now(timezone.utc) - timedelta(seconds=4)})
|
||||
if item.job_id == job.job_id
|
||||
else item
|
||||
for item in queue.jobs
|
||||
]
|
||||
store._persist_job_queue(queue)
|
||||
store.finish_job(job.job_id, status=JobStatus.COMPLETED, summary="Fertig")
|
||||
|
||||
dashboard_response = client.get("/v1/actuators/dashboard")
|
||||
anomalies_response = client.get("/v1/actuators/anomalies")
|
||||
|
||||
assert dashboard_response.status_code == 200
|
||||
system = dashboard_response.json()["system"]
|
||||
assert system["performance_budget_ms"] == 3000
|
||||
assert system["slow_job_count"] == 1
|
||||
assert system["performance_status"] == "slow"
|
||||
assert system["anomaly_count"] >= 1
|
||||
assert anomalies_response.status_code == 200
|
||||
assert anomalies_response.json()
|
||||
|
||||
|
||||
def test_discovery_reads_entities_once_and_reuses_them(tmp_path: Path) -> None:
|
||||
|
||||
Reference in New Issue
Block a user