@@ -432,3 +432,111 @@ def test_traffic_controller_provider_configs(provider, expected_capacity):
432432 controller .check_outbound_request (provider ) # Create policy
433433 metrics = controller .get_metrics (provider )
434434 assert metrics ["rate_limit" ]["capacity" ] == expected_capacity
435+
436+
437+ class TestAntiLoopProtection :
438+ """Testy dla anti-loop protection helper methods."""
439+
440+ def test_is_under_global_request_cap_below_threshold (self ):
441+ """Test że requests poniżej globalnego limitu zwracają True."""
442+ config = TrafficControlConfig ()
443+ config .max_requests_per_minute_global = 1000
444+
445+ assert config .is_under_global_request_cap (500 ) is True
446+ assert config .is_under_global_request_cap (999 ) is True
447+
448+ def test_is_under_global_request_cap_at_threshold (self ):
449+ """Test że requests równe limitowi zwracają False."""
450+ config = TrafficControlConfig ()
451+ config .max_requests_per_minute_global = 1000
452+
453+ assert config .is_under_global_request_cap (1000 ) is False
454+
455+ def test_is_under_global_request_cap_above_threshold (self ):
456+ """Test że requests powyżej limitu zwracają False."""
457+ config = TrafficControlConfig ()
458+ config .max_requests_per_minute_global = 1000
459+
460+ assert config .is_under_global_request_cap (1001 ) is False
461+ assert config .is_under_global_request_cap (2000 ) is False
462+
463+ def test_can_retry_operation_below_max (self ):
464+ """Test że retry_count poniżej max_retries zwraca True."""
465+ config = TrafficControlConfig ()
466+ config .max_retries_per_operation = 5
467+
468+ assert config .can_retry_operation (0 ) is True
469+ assert config .can_retry_operation (4 ) is True
470+
471+ def test_can_retry_operation_at_max (self ):
472+ """Test że retry_count równy max_retries zwraca False."""
473+ config = TrafficControlConfig ()
474+ config .max_retries_per_operation = 5
475+
476+ assert config .can_retry_operation (5 ) is False
477+
478+ def test_can_retry_operation_above_max (self ):
479+ """Test że retry_count powyżej max_retries zwraca False."""
480+ config = TrafficControlConfig ()
481+ config .max_retries_per_operation = 5
482+
483+ assert config .can_retry_operation (6 ) is False
484+ assert config .can_retry_operation (10 ) is False
485+
486+ def test_should_enter_degraded_state_disabled (self ):
487+ """Test że degraded mode wyłączony zawsze zwraca False."""
488+ config = TrafficControlConfig ()
489+ config .degraded_mode_enabled = False
490+ config .max_requests_per_minute_global = 1000
491+ config .degraded_mode_failure_threshold = 10
492+
493+ # Nawet przy przekroczeniu limitów
494+ assert config .should_enter_degraded_state (2000 , 20 ) is False
495+
496+ def test_should_enter_degraded_state_request_cap_exceeded (self ):
497+ """Test przejścia w degraded gdy przekroczony globalny limit requestów."""
498+ config = TrafficControlConfig ()
499+ config .degraded_mode_enabled = True
500+ config .max_requests_per_minute_global = 1000
501+ config .degraded_mode_failure_threshold = 10
502+
503+ # Przekroczenie requestów
504+ assert config .should_enter_degraded_state (1000 , 0 ) is True
505+ assert config .should_enter_degraded_state (1500 , 5 ) is True
506+
507+ def test_should_enter_degraded_state_failure_threshold_exceeded (self ):
508+ """Test przejścia w degraded gdy przekroczony próg błędów."""
509+ config = TrafficControlConfig ()
510+ config .degraded_mode_enabled = True
511+ config .max_requests_per_minute_global = 1000
512+ config .degraded_mode_failure_threshold = 10
513+
514+ # Przekroczenie błędów
515+ assert config .should_enter_degraded_state (500 , 10 ) is True
516+ assert config .should_enter_degraded_state (100 , 15 ) is True
517+
518+ def test_should_enter_degraded_state_below_all_thresholds (self ):
519+ """Test że degraded mode nie włącza się gdy wszystko w normie."""
520+ config = TrafficControlConfig ()
521+ config .degraded_mode_enabled = True
522+ config .max_requests_per_minute_global = 1000
523+ config .degraded_mode_failure_threshold = 10
524+
525+ assert config .should_enter_degraded_state (500 , 5 ) is False
526+ assert config .should_enter_degraded_state (999 , 9 ) is False
527+
528+ def test_should_enter_degraded_state_boundary_conditions (self ):
529+ """Test warunków brzegowych dla degraded mode."""
530+ config = TrafficControlConfig ()
531+ config .degraded_mode_enabled = True
532+ config .max_requests_per_minute_global = 1000
533+ config .degraded_mode_failure_threshold = 10
534+
535+ # Dokładnie na granicy requestów (should trigger)
536+ assert config .should_enter_degraded_state (1000 , 0 ) is True
537+
538+ # Dokładnie na granicy błędów (should trigger)
539+ assert config .should_enter_degraded_state (0 , 10 ) is True
540+
541+ # Jeden poniżej granic (should not trigger)
542+ assert config .should_enter_degraded_state (999 , 9 ) is False
0 commit comments