81 lines
3.4 KiB
Python
81 lines
3.4 KiB
Python
"""Static-review follow-up regressions. Execution is deferred by user request."""
|
|
import contextlib
|
|
import io
|
|
import json
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from unittest.mock import Mock, patch
|
|
|
|
from app.common.validation import PayloadError, parse_payload, validate_structure
|
|
from app.worker.consumer import ProcessingWorker
|
|
from scripts import generate_traffic
|
|
from tests.test_api_delivery import payload
|
|
|
|
|
|
class TestVerifierContract(unittest.TestCase):
|
|
def test_missing_kafka_evidence_fails_before_sending_traffic(self):
|
|
unavailable = SimpleNamespace(KafkaEvidence=Mock(side_effect=ConnectionError("offline")))
|
|
with patch.dict(sys.modules, {"verification_kafka": unavailable}), \
|
|
patch.object(generate_traffic, "send_http_request") as request, \
|
|
contextlib.redirect_stdout(io.StringIO()):
|
|
result = generate_traffic.run_verification("http://unused", "http://unused", "http://unused", 1, 1)
|
|
self.assertEqual(result, 1)
|
|
request.assert_not_called()
|
|
|
|
def test_worker_unavailable_is_not_a_zero_stats_snapshot(self):
|
|
with patch.object(generate_traffic, "fetch_json", return_value={"pipeline": {"worker_status": "unreachable"}}):
|
|
self.assertIsNone(generate_traffic.stats_snapshot("http://unused"))
|
|
|
|
def test_stats_snapshot_keeps_received_and_acknowledged_counts_separate(self):
|
|
response = {
|
|
"pipeline": {
|
|
"total_received": 1570,
|
|
"total_acknowledged": 1540,
|
|
"total_processed": 1520,
|
|
"total_dlq": 50,
|
|
"in_flight_buffer": 0,
|
|
},
|
|
"breakdown": {"dlq_by_reason": {}},
|
|
}
|
|
with patch.object(generate_traffic, "fetch_json", return_value=response):
|
|
snapshot = generate_traffic.stats_snapshot("http://unused")
|
|
self.assertEqual(snapshot["total_received"], 1570)
|
|
self.assertEqual(snapshot["total_acknowledged"], 1540)
|
|
|
|
def test_assessment_metric_deltas_match_received_and_acknowledged_contract(self):
|
|
before = {
|
|
"total_received": 10,
|
|
"total_acknowledged": 8,
|
|
"total_processed": 7,
|
|
"total_dlq": 2,
|
|
}
|
|
after = {
|
|
"total_received": 1580,
|
|
"total_acknowledged": 1548,
|
|
"total_processed": 1527,
|
|
"total_dlq": 52,
|
|
}
|
|
self.assertTrue(generate_traffic.assessment_metrics_match(before, after))
|
|
after["total_acknowledged"] += 1
|
|
self.assertFalse(generate_traffic.assessment_metrics_match(before, after))
|
|
|
|
def test_k6_latency_guardrail_is_opt_in(self):
|
|
script = (Path(__file__).parents[1] / "scripts" / "load_test.js").read_text()
|
|
self.assertIn("__ENV.P95_MS ?", script)
|
|
self.assertNotIn("__ENV.P95_MS || 50", script)
|
|
|
|
def test_overflowing_json_float_is_rejected_even_in_extra_fields(self):
|
|
with self.assertRaises(PayloadError):
|
|
parse_payload(b'{"extra":1e400}')
|
|
|
|
def test_unpaired_surrogate_is_not_an_encodable_record_identity(self):
|
|
data = payload() | {"raw_id": "\ud800"}
|
|
with self.assertRaises(PayloadError):
|
|
validate_structure(parse_payload(json.dumps(data).encode()))
|
|
|
|
def test_deeply_nested_bad_json_can_be_preserved_for_dlq(self):
|
|
body = b"[" * 2000 + b"0" + b"]" * 2000
|
|
self.assertEqual(ProcessingWorker._original(SimpleNamespace(value=lambda: body)), body.decode())
|