from itertools import count import fakeredis import pytest from pytest_mock import MockerFixture from resonance_engine.dsp.stats import InMemoryStatsBackend, RedisStatsBackend class TestInMemoryStatsBackend: @pytest.fixture def backend(self) -> InMemoryStatsBackend: return InMemoryStatsBackend() def test_initial_snapshot_is_zero(self, backend: InMemoryStatsBackend) -> None: stats = backend.snapshot() assert stats.requests == 0 assert stats.retries == 0 assert stats.rate_limited == 0 assert stats.rps is None def test_incr_requests(self, backend: InMemoryStatsBackend) -> None: backend.incr_requests() backend.incr_requests() assert backend.snapshot().requests == 2 def test_incr_retries(self, backend: InMemoryStatsBackend) -> None: backend.incr_retries() backend.incr_retries() backend.incr_retries() assert backend.snapshot().retries == 3 def test_incr_rate_limited(self, backend: InMemoryStatsBackend) -> None: backend.incr_rate_limited() assert backend.snapshot().rate_limited == 1 def test_rps_is_none_for_single_request( self, backend: InMemoryStatsBackend ) -> None: backend.incr_requests() assert backend.snapshot().rps is None def test_rps_is_set_after_multiple_requests( self, backend: InMemoryStatsBackend, mocker: MockerFixture ) -> None: tick = count(0) mocker.patch( "resonance_engine.dsp.stats.time.monotonic", side_effect=lambda: next(tick) * 0.1, ) for _ in range(5): backend.incr_requests() stats = backend.snapshot() assert stats.rps is not None assert stats.rps > 0 def test_last_rps_persists_after_window_expires( self, backend: InMemoryStatsBackend, mocker: MockerFixture ) -> None: tick = count(0) mocker.patch( "resonance_engine.dsp.stats.time.monotonic", side_effect=lambda: next(tick) * 0.1, ) for _ in range(5): backend.incr_requests() # First snapshot — rps is set, last_rps is saved. first = backend.snapshot() assert first.rps is not None assert first.last_rps == first.rps # Simulate window expiry: next snapshot at t >> 60s — rps goes None. mocker.patch( "resonance_engine.dsp.stats.time.monotonic", return_value=9999.0, ) second = backend.snapshot() assert second.rps is None assert second.last_rps == first.rps # still visible def test_last_rps_is_none_when_no_requests( self, backend: InMemoryStatsBackend ) -> None: assert backend.snapshot().last_rps is None class TestRedisStatsBackend: @pytest.fixture def backend(self) -> RedisStatsBackend: return RedisStatsBackend(fakeredis.FakeRedis(), key_prefix="test") def test_initial_snapshot_is_zero(self, backend: RedisStatsBackend) -> None: stats = backend.snapshot() assert stats.requests == 0 assert stats.retries == 0 assert stats.rate_limited == 0 assert stats.rps is None def test_incr_requests(self, backend: RedisStatsBackend) -> None: backend.incr_requests() backend.incr_requests() assert backend.snapshot().requests == 2 def test_incr_retries(self, backend: RedisStatsBackend) -> None: backend.incr_retries() backend.incr_retries() backend.incr_retries() assert backend.snapshot().retries == 3 def test_incr_rate_limited(self, backend: RedisStatsBackend) -> None: backend.incr_rate_limited() assert backend.snapshot().rate_limited == 1 def test_rps_is_none_for_single_request(self, backend: RedisStatsBackend) -> None: backend.incr_requests() assert backend.snapshot().rps is None def test_rps_is_set_after_multiple_requests( self, backend: RedisStatsBackend, mocker: MockerFixture ) -> None: tick = count(0) mocker.patch( "resonance_engine.dsp.stats.time.time", side_effect=lambda: next(tick) * 0.1, ) for _ in range(5): backend.incr_requests() stats = backend.snapshot() assert stats.rps is not None assert stats.rps > 0 def test_last_rps_persists_after_window_expires( self, backend: RedisStatsBackend, mocker: MockerFixture ) -> None: tick = count(0) mocker.patch( "resonance_engine.dsp.stats.time.time", side_effect=lambda: next(tick) * 0.1, ) for _ in range(5): backend.incr_requests() first = backend.snapshot() assert first.rps is not None assert first.last_rps == first.rps # Simulate window expiry: snapshot far in the future. mocker.patch( "resonance_engine.dsp.stats.time.time", return_value=9999.0, ) second = backend.snapshot() assert second.rps is None assert second.last_rps == first.rps def test_last_rps_is_none_when_no_requests( self, backend: RedisStatsBackend ) -> None: assert backend.snapshot().last_rps is None