stability_test.go raw

   1  package oracle
   2  
   3  import "testing"
   4  
   5  func TestStabilityMonitorTriggersOnOscillation(t *testing.T) {
   6  	sm := NewStabilityMonitor(5, 3)
   7  
   8  	// Feed rising bond rate — no trigger yet.
   9  	for i := range 5 {
  10  		if sm.Observe(100, int64(20+i*10), uint32(i)) {
  11  			t.Fatalf("unexpected trigger at observation %d (rising phase)", i)
  12  		}
  13  	}
  14  
  15  	// Now oscillate: feed alternating high/low to trigger reversals.
  16  	gen := uint32(5)
  17  	triggered := false
  18  	for round := range 20 {
  19  		var bonded int64
  20  		if round%2 == 0 {
  21  			bonded = 20 // low
  22  		} else {
  23  			bonded = 80 // high
  24  		}
  25  		if sm.Observe(100, bonded, gen) {
  26  			triggered = true
  27  			break
  28  		}
  29  		gen++
  30  	}
  31  
  32  	if !triggered {
  33  		t.Fatal("stability monitor did not trigger after oscillation")
  34  	}
  35  
  36  	if sm.LastSignalGen == 0 {
  37  		t.Error("LastSignalGen not updated")
  38  	}
  39  }
  40  
  41  func TestStabilityMonitorResetsAfterTrigger(t *testing.T) {
  42  	sm := NewStabilityMonitor(3, 3)
  43  
  44  	// Force oscillation.
  45  	gen := uint32(0)
  46  	for range 30 {
  47  		bonded := int64(80)
  48  		if gen%2 == 0 {
  49  			bonded = 20
  50  		}
  51  		if sm.Observe(100, bonded, gen) {
  52  			break
  53  		}
  54  		gen++
  55  	}
  56  
  57  	// After trigger, detector should be reset — reversals back to 0.
  58  	if sm.Detector.Reversals != 0 {
  59  		t.Errorf("reversals not reset after trigger: %d", sm.Detector.Reversals)
  60  	}
  61  
  62  	// Should not immediately re-trigger on next observation.
  63  	if sm.Observe(100, 50, gen+1) {
  64  		t.Error("re-triggered immediately after reset")
  65  	}
  66  }
  67  
  68  func TestStabilityMonitorSteadyStateNoTrigger(t *testing.T) {
  69  	sm := NewStabilityMonitor(5, 3)
  70  
  71  	// Feed steady rising bond rate — should never trigger.
  72  	for i := range 50 {
  73  		if sm.Observe(100, int64(10+i), uint32(i)) {
  74  			t.Fatalf("triggered on steadily rising input at observation %d", i)
  75  		}
  76  	}
  77  }
  78