github.com/yandex/pandora@v0.5.32/core/schedule/schedule_test.go (about) 1 package schedule 2 3 import ( 4 "sort" 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 ) 12 13 func Test_unlimited(t *testing.T) { 14 conf := UnlimitedConfig{50 * time.Millisecond} 15 testee := NewUnlimitedConf(conf) 16 start := time.Now() 17 finish := start.Add(conf.Duration) 18 assert.Equal(t, -1, testee.Left()) 19 testee.Start(start) 20 var i int 21 for prev := time.Now(); ; i++ { 22 left := testee.Left() 23 x, ok := testee.Next() 24 if !ok { 25 break 26 } 27 assert.Equal(t, -1, left) 28 assert.True(t, x.After(prev)) 29 assert.True(t, x.Before(finish)) 30 } 31 assert.Equal(t, 0, testee.Left()) 32 assert.Greater(t, i, 50) 33 } 34 35 func TestOnce(t *testing.T) { 36 t.Run("started", func(t *testing.T) { 37 testee := NewOnce(1) 38 coretest.ExpectScheduleNexts(t, testee, 0, 0) 39 }) 40 41 t.Run("unstarted", func(t *testing.T) { 42 testee := NewOnce(1) 43 start := time.Now() 44 x1, ok := testee.Next() 45 threshold := time.Since(start) 46 47 assert.True(t, ok) 48 assert.WithinDuration(t, start, x1, threshold) 49 50 x2, ok := testee.Next() 51 assert.False(t, ok) 52 assert.Equal(t, x1, x2) 53 }) 54 55 } 56 57 func TestConst(t *testing.T) { 58 tests := []struct { 59 name string 60 conf ConstConfig 61 wantN int64 62 wantAssertNext []time.Duration 63 }{ 64 { 65 name: "non-zero ops", 66 conf: ConstConfig{ 67 Ops: 1, 68 Duration: 2 * time.Second, 69 }, 70 wantN: 2, 71 wantAssertNext: []time.Duration{ 72 0, time.Second, 2 * time.Second, 73 }, 74 }, 75 { 76 name: "zero ops", 77 conf: ConstConfig{ 78 Ops: 0, 79 Duration: 2 * time.Second, 80 }, 81 wantN: 0, 82 wantAssertNext: []time.Duration{ 83 2 * time.Second, 84 }, 85 }, 86 } 87 for _, tt := range tests { 88 t.Run(tt.name, func(t *testing.T) { 89 90 testee := NewConstConf(tt.conf) 91 underlying := testee.(*doAtSchedule) 92 93 assert.Equal(t, tt.wantN, underlying.n) 94 coretest.ExpectScheduleNexts(t, testee, tt.wantAssertNext...) 95 }) 96 } 97 } 98 99 func TestLine(t *testing.T) { 100 tests := []struct { 101 name string 102 conf LineConfig 103 wantN int64 104 wantAssertNext []time.Duration 105 assert func(t *testing.T, testee core.Schedule, underlying *doAtSchedule) 106 }{ 107 { 108 name: "too small ops", 109 conf: LineConfig{ 110 From: 0, 111 To: 1.999, 112 Duration: time.Second, 113 }, 114 wantN: 0, 115 wantAssertNext: []time.Duration{time.Second}, 116 }, 117 { 118 name: "const ops", 119 conf: LineConfig{ 120 From: 1, 121 To: 1, 122 Duration: 2 * time.Second, 123 }, 124 wantN: 2, 125 wantAssertNext: []time.Duration{0, time.Second, 2 * time.Second}, 126 }, 127 { 128 name: "zero start", 129 conf: LineConfig{ 130 From: 0, 131 To: 1, 132 Duration: 2 * time.Second, 133 }, 134 wantN: 1, 135 wantAssertNext: []time.Duration{0, 2 * time.Second}, 136 }, 137 } 138 for _, tt := range tests { 139 t.Run(tt.name, func(t *testing.T) { 140 testee := NewLineConf(tt.conf) 141 underlying := testee.(*doAtSchedule) 142 143 assert.Equal(t, tt.wantN, underlying.n) 144 coretest.ExpectScheduleNexts(t, testee, tt.wantAssertNext...) 145 }) 146 } 147 } 148 149 func TestLineNonZeroStart(t *testing.T) { 150 testee := NewLineConf(LineConfig{ 151 From: 2, 152 To: 8, 153 Duration: 2 * time.Second, 154 }) 155 underlying := testee.(*doAtSchedule) 156 157 assert.Equal(t, int64(10), underlying.n) 158 159 start := time.Now() 160 testee.Start(start) 161 162 var ( 163 i int 164 xs []time.Time 165 x time.Time 166 ) 167 for ok := true; ok; i++ { 168 x, ok = testee.Next() 169 xs = append(xs, x) 170 } 171 assert.Equal(t, 11, i) 172 assert.True(t, sort.SliceIsSorted(xs, func(i, j int) bool { 173 return xs[i].Before(xs[j]) 174 })) 175 assert.Equal(t, xs[len(xs)-1], start.Add(2*time.Second)) 176 } 177 178 func TestStep(t *testing.T) { 179 conf := StepConfig{ 180 From: 1, 181 To: 2, 182 Step: 1, 183 Duration: 2 * time.Second, 184 } 185 testee := NewStepConf(conf) 186 assert.Equal(t, 6, testee.Left()) 187 } 188 189 func TestInstanceStep(t *testing.T) { 190 conf := InstanceStepConfig{ 191 From: 1, 192 To: 3, 193 Step: 1, 194 StepDuration: 2 * time.Second, 195 } 196 testee := NewInstanceStepConf(conf) 197 assert.Equal(t, 3, testee.Left()) 198 } 199 200 func BenchmarkLineSchedule(b *testing.B) { 201 schedule := NewLine(0, float64(b.N), 2*time.Second) 202 benchmarkScheduleNext(b, schedule) 203 } 204 205 func BenchmarkLineScheduleParallel(b *testing.B) { 206 schedule := NewLine(0, float64(b.N), 2*time.Second) 207 benchmarkScheduleNextParallel(b, schedule) 208 } 209 210 func BenchmarkUnlimitedSchedule(b *testing.B) { 211 schedule := NewUnlimited(time.Minute) 212 benchmarkScheduleNext(b, schedule) 213 } 214 215 func BenchmarkUnlimitedScheduleParallel(b *testing.B) { 216 schedule := NewUnlimited(time.Minute) 217 benchmarkScheduleNextParallel(b, schedule) 218 } 219 220 func benchmarkScheduleNextParallel(b *testing.B, schedule core.Schedule) { 221 run := func(pb *testing.PB) { 222 for pb.Next() { 223 schedule.Next() 224 } 225 } 226 schedule.Start(time.Now()) 227 b.ReportAllocs() 228 b.ResetTimer() 229 b.RunParallel(run) 230 } 231 232 func benchmarkScheduleNext(b *testing.B, schedule core.Schedule) { 233 schedule.Start(time.Now()) 234 b.ReportAllocs() 235 b.ResetTimer() 236 for i := 0; i < b.N; i++ { 237 schedule.Next() 238 } 239 }