A Python port of the Invisible Internet Project (I2P)
at main 112 lines 3.4 kB view raw
1"""Tests for Frequency — rolling average event frequency tracker.""" 2 3import time 4from unittest.mock import patch 5 6import pytest 7 8from i2p_stat.frequency import Frequency 9 10 11class TestFrequencyInit: 12 def test_valid_period(self): 13 f = Frequency(1000) 14 assert f.period == 1000 15 16 def test_zero_period_raises(self): 17 with pytest.raises(ValueError, match="positive"): 18 Frequency(0) 19 20 def test_negative_period_raises(self): 21 with pytest.raises(ValueError, match="positive"): 22 Frequency(-1) 23 24 25class TestFrequencyBasics: 26 def test_initial_avg_interval(self): 27 f = Frequency(1000) 28 # Initially period + 1 (no events) 29 assert f.get_average_interval() == 1001.0 30 31 def test_initial_event_count(self): 32 f = Frequency(1000) 33 assert f.get_event_count() == 0 34 35 def test_initial_events_per_period(self): 36 f = Frequency(1000) 37 # period / avg_interval = 1000 / 1001 < 1 38 assert f.get_average_events_per_period() < 1.0 39 40 def test_initial_strict_avg(self): 41 f = Frequency(1000) 42 # No events → period + 1 43 assert f.get_strict_average_interval() == 1001.0 44 45 46class TestFrequencyEvents: 47 def test_event_increments_count(self): 48 f = Frequency(10000) 49 f.event_occurred() 50 assert f.get_event_count() == 1 51 f.event_occurred() 52 assert f.get_event_count() == 2 53 54 def test_rapid_events_decrease_interval(self): 55 f = Frequency(10000) 56 initial = f.get_average_interval() 57 # Fire events with small delay so interval < period 58 for _ in range(5): 59 time.sleep(0.002) 60 f.event_occurred() 61 after = f.get_average_interval() 62 # Rapid events should decrease the average interval 63 assert after < initial 64 65 def test_min_avg_interval_tracks_minimum(self): 66 f = Frequency(10000) 67 # Fire events with small delay 68 for _ in range(10): 69 time.sleep(0.002) 70 f.event_occurred() 71 min_after_rapid = f.get_min_average_interval() 72 # min should be less than initial (period + 1) 73 assert min_after_rapid < 10001.0 74 75 def test_max_events_per_period(self): 76 f = Frequency(10000) 77 for _ in range(5): 78 time.sleep(0.002) 79 f.event_occurred() 80 max_epp = f.get_max_average_events_per_period() 81 assert max_epp > 0 82 83 def test_strict_average(self): 84 f = Frequency(10000) 85 time.sleep(0.002) 86 f.event_occurred() 87 f.event_occurred() 88 f.event_occurred() 89 strict = f.get_strict_average_interval() 90 # Should be (now - start) / 3, a small positive value 91 assert strict > 0 92 93 def test_recalculate_no_events(self): 94 f = Frequency(1) # 1ms period 95 # Sleep >1ms so interval exceeds period 96 time.sleep(0.01) 97 f.recalculate() 98 # Should reset to period + 1 99 assert f.get_average_interval() == 2.0 100 101 102class TestFrequencyEdgeCases: 103 def test_events_per_period_zero_avg(self): 104 """If avg_interval is somehow 0, return 0.""" 105 f = Frequency(1000) 106 f._avg_interval = 0.0 107 assert f.get_average_events_per_period() == 0.0 108 109 def test_max_events_zero_min(self): 110 f = Frequency(1000) 111 f._min_avg_interval = 0.0 112 assert f.get_max_average_events_per_period() == 0.0