k8s.io/client-go@v0.22.2/util/workqueue/delaying_queue_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package workqueue 18 19 import ( 20 "fmt" 21 "math/rand" 22 "reflect" 23 "testing" 24 "time" 25 26 "k8s.io/apimachinery/pkg/util/clock" 27 "k8s.io/apimachinery/pkg/util/wait" 28 ) 29 30 func TestSimpleQueue(t *testing.T) { 31 fakeClock := clock.NewFakeClock(time.Now()) 32 q := NewDelayingQueueWithCustomClock(fakeClock, "") 33 34 first := "foo" 35 36 q.AddAfter(first, 50*time.Millisecond) 37 if err := waitForWaitingQueueToFill(q); err != nil { 38 t.Fatalf("unexpected err: %v", err) 39 } 40 41 if q.Len() != 0 { 42 t.Errorf("should not have added") 43 } 44 45 fakeClock.Step(60 * time.Millisecond) 46 47 if err := waitForAdded(q, 1); err != nil { 48 t.Errorf("should have added") 49 } 50 item, _ := q.Get() 51 q.Done(item) 52 53 // step past the next heartbeat 54 fakeClock.Step(10 * time.Second) 55 56 err := wait.Poll(1*time.Millisecond, 30*time.Millisecond, func() (done bool, err error) { 57 if q.Len() > 0 { 58 return false, fmt.Errorf("added to queue") 59 } 60 61 return false, nil 62 }) 63 if err != wait.ErrWaitTimeout { 64 t.Errorf("expected timeout, got: %v", err) 65 } 66 67 if q.Len() != 0 { 68 t.Errorf("should not have added") 69 } 70 } 71 72 func TestDeduping(t *testing.T) { 73 fakeClock := clock.NewFakeClock(time.Now()) 74 q := NewDelayingQueueWithCustomClock(fakeClock, "") 75 76 first := "foo" 77 78 q.AddAfter(first, 50*time.Millisecond) 79 if err := waitForWaitingQueueToFill(q); err != nil { 80 t.Fatalf("unexpected err: %v", err) 81 } 82 q.AddAfter(first, 70*time.Millisecond) 83 if err := waitForWaitingQueueToFill(q); err != nil { 84 t.Fatalf("unexpected err: %v", err) 85 } 86 if q.Len() != 0 { 87 t.Errorf("should not have added") 88 } 89 90 // step past the first block, we should receive now 91 fakeClock.Step(60 * time.Millisecond) 92 if err := waitForAdded(q, 1); err != nil { 93 t.Errorf("should have added") 94 } 95 item, _ := q.Get() 96 q.Done(item) 97 98 // step past the second add 99 fakeClock.Step(20 * time.Millisecond) 100 if q.Len() != 0 { 101 t.Errorf("should not have added") 102 } 103 104 // test again, but this time the earlier should override 105 q.AddAfter(first, 50*time.Millisecond) 106 q.AddAfter(first, 30*time.Millisecond) 107 if err := waitForWaitingQueueToFill(q); err != nil { 108 t.Fatalf("unexpected err: %v", err) 109 } 110 if q.Len() != 0 { 111 t.Errorf("should not have added") 112 } 113 114 fakeClock.Step(40 * time.Millisecond) 115 if err := waitForAdded(q, 1); err != nil { 116 t.Errorf("should have added") 117 } 118 item, _ = q.Get() 119 q.Done(item) 120 121 // step past the second add 122 fakeClock.Step(20 * time.Millisecond) 123 if q.Len() != 0 { 124 t.Errorf("should not have added") 125 } 126 if q.Len() != 0 { 127 t.Errorf("should not have added") 128 } 129 } 130 131 func TestAddTwoFireEarly(t *testing.T) { 132 fakeClock := clock.NewFakeClock(time.Now()) 133 q := NewDelayingQueueWithCustomClock(fakeClock, "") 134 135 first := "foo" 136 second := "bar" 137 third := "baz" 138 139 q.AddAfter(first, 1*time.Second) 140 q.AddAfter(second, 50*time.Millisecond) 141 if err := waitForWaitingQueueToFill(q); err != nil { 142 t.Fatalf("unexpected err: %v", err) 143 } 144 145 if q.Len() != 0 { 146 t.Errorf("should not have added") 147 } 148 149 fakeClock.Step(60 * time.Millisecond) 150 151 if err := waitForAdded(q, 1); err != nil { 152 t.Fatalf("unexpected err: %v", err) 153 } 154 item, _ := q.Get() 155 if !reflect.DeepEqual(item, second) { 156 t.Errorf("expected %v, got %v", second, item) 157 } 158 159 q.AddAfter(third, 2*time.Second) 160 161 fakeClock.Step(1 * time.Second) 162 if err := waitForAdded(q, 1); err != nil { 163 t.Fatalf("unexpected err: %v", err) 164 } 165 item, _ = q.Get() 166 if !reflect.DeepEqual(item, first) { 167 t.Errorf("expected %v, got %v", first, item) 168 } 169 170 fakeClock.Step(2 * time.Second) 171 if err := waitForAdded(q, 1); err != nil { 172 t.Fatalf("unexpected err: %v", err) 173 } 174 item, _ = q.Get() 175 if !reflect.DeepEqual(item, third) { 176 t.Errorf("expected %v, got %v", third, item) 177 } 178 } 179 180 func TestCopyShifting(t *testing.T) { 181 fakeClock := clock.NewFakeClock(time.Now()) 182 q := NewDelayingQueueWithCustomClock(fakeClock, "") 183 184 first := "foo" 185 second := "bar" 186 third := "baz" 187 188 q.AddAfter(first, 1*time.Second) 189 q.AddAfter(second, 500*time.Millisecond) 190 q.AddAfter(third, 250*time.Millisecond) 191 if err := waitForWaitingQueueToFill(q); err != nil { 192 t.Fatalf("unexpected err: %v", err) 193 } 194 195 if q.Len() != 0 { 196 t.Errorf("should not have added") 197 } 198 199 fakeClock.Step(2 * time.Second) 200 201 if err := waitForAdded(q, 3); err != nil { 202 t.Fatalf("unexpected err: %v", err) 203 } 204 actualFirst, _ := q.Get() 205 if !reflect.DeepEqual(actualFirst, third) { 206 t.Errorf("expected %v, got %v", third, actualFirst) 207 } 208 actualSecond, _ := q.Get() 209 if !reflect.DeepEqual(actualSecond, second) { 210 t.Errorf("expected %v, got %v", second, actualSecond) 211 } 212 actualThird, _ := q.Get() 213 if !reflect.DeepEqual(actualThird, first) { 214 t.Errorf("expected %v, got %v", first, actualThird) 215 } 216 } 217 218 func BenchmarkDelayingQueue_AddAfter(b *testing.B) { 219 fakeClock := clock.NewFakeClock(time.Now()) 220 q := NewDelayingQueueWithCustomClock(fakeClock, "") 221 222 // Add items 223 for n := 0; n < b.N; n++ { 224 data := fmt.Sprintf("%d", n) 225 q.AddAfter(data, time.Duration(rand.Int63n(int64(10*time.Minute)))) 226 } 227 228 // Exercise item removal as well 229 fakeClock.Step(11 * time.Minute) 230 for n := 0; n < b.N; n++ { 231 _, _ = q.Get() 232 } 233 } 234 235 func waitForAdded(q DelayingInterface, depth int) error { 236 return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) { 237 if q.Len() == depth { 238 return true, nil 239 } 240 241 return false, nil 242 }) 243 } 244 245 func waitForWaitingQueueToFill(q DelayingInterface) error { 246 return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) { 247 if len(q.(*delayingType).waitingForAddCh) == 0 { 248 return true, nil 249 } 250 251 return false, nil 252 }) 253 }