Files
snake-python/tests/test_MetricsManager.py
T

166 lines
5.0 KiB
Python

import unittest
from typing import Any, cast
from server.metrics.MetricsManager import MetricsManager
class TestMetricsManager(unittest.IsolatedAsyncioTestCase):
async def test_memory_backend_returns_local_snapshot(self):
manager = MetricsManager(backend="memory")
local = {
"games_started": 2,
"games_ended": 1,
"wins": 1,
"losses": 0,
"total_moves": 10,
"total_turns": 42,
"max_turn": 42,
"active_games_peak": 2,
"games_autocreated": 0,
"http_requests_total": 13,
"move_response_time_ms_total": 30.0,
"move_response_time_ms_max": 6.0,
"last_game_start_unix": 1,
"last_game_end_unix": 2,
"last_move_unix": 3,
"games_stuck_removed": 0,
"game_state_local_cache_enabled": False,
"metrics_backend": "memory",
"active_games": 1,
"tracked_games": 1,
"avg_turns_per_game": 42.0,
"win_rate": 1.0,
"avg_move_response_ms": 3.0,
"oldest_active_game_age_sec": 0,
"stale_game_timeout_sec": 180,
"active_games_stale": 0,
"http_requests_by_endpoint": {"info": 1, "start": 1, "move": 10, "end": 1},
"move_direction_counts": {
"up": 4,
"down": 2,
"left": 2,
"right": 2,
"unknown": 0,
},
}
snapshot = await manager.snapshot(local)
self.assertEqual(snapshot["games_started"], 2)
self.assertEqual(snapshot["metrics_backend"], "memory")
await manager.close()
async def test_merge_snapshots_aggregates_totals(self):
manager = MetricsManager(backend="memory")
merged = manager._merge_snapshots(
[
{
"games_started": 2,
"games_ended": 1,
"wins": 1,
"losses": 0,
"total_moves": 10,
"total_turns": 40,
"max_turn": 40,
"active_games_peak": 2,
"games_autocreated": 1,
"http_requests_total": 20,
"move_response_time_ms_total": 50.0,
"move_response_time_ms_max": 8.0,
"last_game_start_unix": 10,
"last_game_end_unix": 15,
"last_move_unix": 16,
"games_stuck_removed": 0,
"active_games": 1,
"tracked_games": 1,
"oldest_active_game_age_sec": 5,
"stale_game_timeout_sec": 180,
"active_games_stale": 0,
"game_state_local_cache_enabled": True,
"http_requests_by_endpoint": {
"info": 1,
"start": 1,
"move": 17,
"end": 1,
},
"move_direction_counts": {
"up": 5,
"down": 2,
"left": 1,
"right": 2,
"unknown": 0,
},
},
{
"games_started": 1,
"games_ended": 1,
"wins": 0,
"losses": 1,
"total_moves": 6,
"total_turns": 20,
"max_turn": 20,
"active_games_peak": 1,
"games_autocreated": 0,
"http_requests_total": 12,
"move_response_time_ms_total": 20.0,
"move_response_time_ms_max": 7.0,
"last_game_start_unix": 12,
"last_game_end_unix": 18,
"last_move_unix": 19,
"games_stuck_removed": 1,
"active_games": 2,
"tracked_games": 2,
"oldest_active_game_age_sec": 7,
"stale_game_timeout_sec": 180,
"active_games_stale": 1,
"game_state_local_cache_enabled": False,
"http_requests_by_endpoint": {
"info": 1,
"start": 1,
"move": 9,
"end": 1,
},
"move_direction_counts": {
"up": 1,
"down": 1,
"left": 2,
"right": 2,
"unknown": 0,
},
},
]
)
self.assertEqual(merged["games_started"], 3)
self.assertEqual(merged["games_ended"], 2)
self.assertEqual(merged["wins"], 1)
self.assertEqual(merged["losses"], 1)
self.assertEqual(merged["total_moves"], 16)
self.assertEqual(merged["move_response_time_ms_total"], 70.0)
self.assertEqual(merged["http_requests_by_endpoint"]["move"], 26)
self.assertEqual(merged["move_direction_counts"]["left"], 3)
self.assertEqual(merged["metrics_backend"], "redis")
await manager.close()
async def test_acquire_startup_cleanup_lock_uses_store_for_redis_backend(self):
class FakeStore:
def __init__(self):
self.calls = []
async def acquire_startup_cleanup_lock(self, lock_key:str, ttl_seconds:int=300):
self.calls.append((lock_key, ttl_seconds))
return True
async def close(self):
return None
manager = MetricsManager(backend="redis", key_prefix="snake:metrics:worker")
fake_store = FakeStore()
manager.store = cast(Any, fake_store)
allowed = await manager.acquire_startup_cleanup_lock(180)
self.assertTrue(allowed)
self.assertEqual(fake_store.calls, [("snake:metrics:worker:startup_cleanup_lock", 180)])
await manager.close()
if __name__ == "__main__":
unittest.main()