import pytest from fastapi.testclient import TestClient from src.main import app # Inizializziamo il client di test di FastAPI client = TestClient(app) @pytest.fixture(autouse=True) def reset_metrics(): """Resetta i contatori prima di ogni test per garantire isolamento.""" client.post("/reset") def test_ingest_returns_200(): """Verifica che il webhook accetti il payload e risponda velocemente.""" payload = {"message": "Standard error log", "source": "nginx"} response = client.post("/ingest", json=payload) assert response.status_code == 200 def test_sqs_billing_block_calculation(): """ Simula l'invio di un payload > 64KB. AWS SQS fattura a blocchi di 64KB. 65KB = 2 blocchi. """ # 65 * 1024 bytes = 66560 caratteri (circa 65KB) large_payload = {"message": "A" * 66560} client.post("/ingest", json=large_payload) response = client.get("/metrics") metrics = response.json() # Ci aspettiamo 2 blocchi fatturabili assert metrics["sqs_billing_blocks"] == 2 def test_safety_first_leak_detection(): """ Verifica che se Logstash fallisce la sanitizzazione, il mock lo rilevi e incrementi il contatore delle violazioni (Safety First). """ leaky_payload = {"message": "User luca@example.com failed login"} client.post("/ingest", json=leaky_payload) response = client.get("/metrics") metrics = response.json() assert metrics["safety_violations_detected"] == 1 def test_double_check_token_count(): """ Verifica che il tokenizer calcoli esattamente il numero di token. La stringa 'Hello, world!' corrisponde a 4 token in cl100k_base. (Double Check) """ payload = {"message": "Hello, world!"} client.post("/ingest", json=payload) # Forziamo il processamento della coda client.post("/flush") response = client.get("/metrics") metrics = response.json() assert metrics["llm_estimated_input_tokens"] == 4 def test_little_often_batch_deduplication(): """ Simula l'invio di 10 log identici in rapida successione. Verifica che vengano deduplicati e che i token LLM siano contati per 1 solo log, simulando il batching (Little Often). """ payload = {"message": "Hello, world!"} # Inviamo 10 messaggi identici for _ in range(10): client.post("/ingest", json=payload) # Forziamo il processamento della coda client.post("/flush") response = client.get("/metrics") metrics = response.json() # 1. 10 richieste ricevute dal mock SQS assert metrics["total_requests"] == 10 # 2. Almeno 1 invocazione Lambda simulata assert metrics.get("lambda_simulated_invocations", 0) > 0 # 3. I token stimati devono essere solo 4 (quelli di 1 singolo messaggio), # NON 40 (che avremmo senza deduplicazione). assert metrics["llm_estimated_input_tokens"] == 4