github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/repeater/repeater_test.go (about) 1 package repeater 2 3 import ( 4 "context" 5 "fmt" 6 "runtime" 7 "testing" 8 "time" 9 10 "github.com/jonboulle/clockwork" 11 ) 12 13 func TestRepeaterNoWakeUpsAfterStop(t *testing.T) { 14 var ( 15 interval = time.Millisecond 16 wakeUpStart = make(chan struct{}) 17 wakeUpDone = make(chan struct{}) 18 ) 19 fakeClock := clockwork.NewFakeClock() 20 r := New(context.Background(), interval, func(ctx context.Context) (err error) { 21 wakeUpStart <- struct{}{} 22 <-wakeUpDone 23 24 return nil 25 }, WithClock(fakeClock)) 26 27 fakeClock.Advance(interval) 28 <-wakeUpStart // wait first wake up 29 wakeUpDone <- struct{}{} // unlock exit from first wake up 30 31 fakeClock.Advance(interval) 32 <-wakeUpStart // wait second wake up 33 r.stop(func() { // call stop 34 wakeUpDone <- struct{}{} // unlock exit from second wake up 35 }) 36 37 noWakeup := make(chan struct{}) 38 go func() { 39 <-fakeClock.After(interval * 2) 40 noWakeup <- struct{}{} 41 }() 42 43 waitNoWakeup: 44 for { 45 fakeClock.Advance(interval) 46 select { 47 case <-wakeUpStart: 48 t.Fatalf("unexpected wake up after stop") 49 case <-noWakeup: 50 break waitNoWakeup 51 default: 52 runtime.Gosched() 53 } 54 } 55 } 56 57 func TestRepeaterForceLogBackoff(t *testing.T) { 58 delays := []time.Duration{ 59 0 * time.Second, 60 1 * time.Second, // 1 sec 61 2 * time.Second, // 3 sec 62 4 * time.Second, // 7 sec 63 8 * time.Second, // 15 sec 64 16 * time.Second, // 31 sec 65 32 * time.Second, // 63 sec 66 } 67 68 fakeClock := clockwork.NewFakeClock() 69 var ( 70 wakeUps = 0 71 lastWakeUp = fakeClock.Now() 72 ) 73 74 repeaterDone := make(chan struct{}) 75 r := New(context.Background(), 10*time.Minute, func(ctx context.Context) (err error) { 76 defer func() { 77 repeaterDone <- struct{}{} 78 }() 79 80 sinceLastWakeUp := fakeClock.Since(lastWakeUp) 81 d := delays[wakeUps] 82 if sinceLastWakeUp != d { 83 t.Fatalf("unexpected wake up delay: %v, exp: %v", sinceLastWakeUp, d) 84 } 85 lastWakeUp = fakeClock.Now() 86 wakeUps++ 87 88 return fmt.Errorf("special error for force with log backoff") 89 }, WithClock(fakeClock)) 90 defer r.Stop() 91 92 r.Force() 93 <-repeaterDone 94 95 for _, delay := range delays[1:] { 96 // ensure right listeners attached 97 fakeClock.BlockUntil(2) 98 99 // release trash timer listeners 100 fakeClock.Advance(delay - 1) 101 102 // fire estimated time 103 fakeClock.Advance(1) 104 <-repeaterDone 105 } 106 }