| 94 | } |
| 95 | |
| 96 | func TestEngine_TimeoutExcluded(t *testing.T) { |
| 97 | slow := &stubDetector{name: "slow", result: okResult("slow", 0.9), delay: 50 * time.Millisecond} |
| 98 | fast := &stubDetector{name: "fast", result: okResult("fast", 0.2, CategoryObfuscation)} |
| 99 | eng := NewEngine(EngineConfig{Timeout: 10 * time.Millisecond, MinOK: 1}, slow, fast) |
| 100 | agg := eng.Evaluate(context.Background(), Request{}) |
| 101 | if agg.Degraded { |
| 102 | t.Fatalf("fast detector should satisfy MinOK") |
| 103 | } |
| 104 | // Only the fast detector counts → score ~0.2, slow excluded (not counted as 0.9 or as benign 0). |
| 105 | if agg.Score < 0.19 || agg.Score > 0.21 { |
| 106 | t.Errorf("timed-out detector should be excluded; score=%v want ~0.2", agg.Score) |
| 107 | } |
| 108 | // Confirm the slow one is recorded as timeout for audit. |
| 109 | var sawTimeout bool |
| 110 | for _, r := range agg.PerDetector { |
| 111 | if r.Provider.Name == "slow" && r.Status == StatusTimeout { |
| 112 | sawTimeout = true |
| 113 | } |
| 114 | } |
| 115 | if !sawTimeout { |
| 116 | t.Errorf("slow detector should be recorded StatusTimeout") |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | func TestEngine_PanicRecovered(t *testing.T) { |
| 121 | bad := &stubDetector{name: "bad", panicOn: true} |