package oracle import "testing" func TestStabilityMonitorTriggersOnOscillation(t *testing.T) { sm := NewStabilityMonitor(5, 3) // Feed rising bond rate — no trigger yet. for i := range 5 { if sm.Observe(100, int64(20+i*10), uint32(i)) { t.Fatalf("unexpected trigger at observation %d (rising phase)", i) } } // Now oscillate: feed alternating high/low to trigger reversals. gen := uint32(5) triggered := false for round := range 20 { var bonded int64 if round%2 == 0 { bonded = 20 // low } else { bonded = 80 // high } if sm.Observe(100, bonded, gen) { triggered = true break } gen++ } if !triggered { t.Fatal("stability monitor did not trigger after oscillation") } if sm.LastSignalGen == 0 { t.Error("LastSignalGen not updated") } } func TestStabilityMonitorResetsAfterTrigger(t *testing.T) { sm := NewStabilityMonitor(3, 3) // Force oscillation. gen := uint32(0) for range 30 { bonded := int64(80) if gen%2 == 0 { bonded = 20 } if sm.Observe(100, bonded, gen) { break } gen++ } // After trigger, detector should be reset — reversals back to 0. if sm.Detector.Reversals != 0 { t.Errorf("reversals not reset after trigger: %d", sm.Detector.Reversals) } // Should not immediately re-trigger on next observation. if sm.Observe(100, 50, gen+1) { t.Error("re-triggered immediately after reset") } } func TestStabilityMonitorSteadyStateNoTrigger(t *testing.T) { sm := NewStabilityMonitor(5, 3) // Feed steady rising bond rate — should never trigger. for i := range 50 { if sm.Observe(100, int64(10+i), uint32(i)) { t.Fatalf("triggered on steadily rising input at observation %d", i) } } }