github.com/yandex/pandora@v0.5.32/core/schedule/composite_test.go (about) 1 package schedule 2 3 import ( 4 "sync" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/yandex/pandora/core" 10 "github.com/yandex/pandora/core/coretest" 11 "go.uber.org/atomic" 12 ) 13 14 func Test_composite(t *testing.T) { 15 t.Run("empty", func(t *testing.T) { 16 testee := NewComposite() 17 coretest.ExpectScheduleNexts(t, testee, 0) 18 }) 19 20 t.Run("only", func(t *testing.T) { 21 testee := NewComposite(NewConst(1, time.Second)) 22 coretest.ExpectScheduleNexts(t, testee, 0, time.Second) 23 }) 24 25 t.Run("composite", func(t *testing.T) { 26 testee := NewComposite( 27 NewConst(1, 2*time.Second), 28 NewOnce(2), 29 NewConst(0, 5*time.Second), 30 NewOnce(0), 31 NewOnce(1), 32 ) 33 coretest.ExpectScheduleNexts(t, testee, 34 0, 35 time.Second, 36 37 2*time.Second, 38 2*time.Second, 39 40 7*time.Second, 41 7*time.Second, // Finish. 42 ) 43 }) 44 45 // Load concurrently, and let race detector do it's work. 46 t.Run("race", func(t *testing.T) { 47 var ( 48 nexts []core.Schedule 49 tokensGot atomic.Int64 50 tokensExpected int64 51 ) 52 addOnce := func(v int64) { 53 nexts = append(nexts, NewOnce(v)) 54 tokensExpected += v 55 } 56 addOnce(100000) // Delay to start concurrent readers. 57 for i := 0; i < 100000; i++ { 58 // Some work for catching races. 59 addOnce(0) 60 addOnce(1) 61 } 62 testee := NewCompositeConf(CompositeConf{nexts}) 63 var wg sync.WaitGroup 64 for i := 0; i < 8; i++ { 65 wg.Add(1) 66 go func() { 67 defer wg.Done() 68 for { 69 _, ok := testee.Next() 70 if !ok { 71 return 72 } 73 tokensGot.Inc() 74 } 75 }() 76 } 77 wg.Wait() 78 assert.Equal(t, tokensExpected, tokensGot.Load()) 79 }) 80 81 t.Run("left with unknown", func(t *testing.T) { 82 unlimitedDuration := time.Second 83 testee := NewComposite( 84 NewUnlimited(unlimitedDuration), 85 NewOnce(0), 86 NewConst(1, 2*time.Second), 87 NewOnce(1), 88 ) 89 assert.Equal(t, -1, testee.Left()) 90 startAt := time.Now().Add(-unlimitedDuration) 91 testee.Start(startAt) 92 93 unlimitedFinish := startAt.Add(unlimitedDuration) 94 sched := testee.(*compositeSchedule).scheds[0] 95 assert.Equal(t, unlimitedFinish, sched.(*unlimitedSchedule).finish.Load()) 96 97 assert.Equal(t, 3, testee.Left()) 98 99 actualNexts := coretest.DrainScheduleDuration(t, testee, unlimitedFinish) 100 expectedNests := []time.Duration{ 101 0, 102 time.Second, 103 2 * time.Second, 104 2 * time.Second, // Finish. 105 } 106 assert.Equal(t, expectedNests, actualNexts) 107 }) 108 }