proposeAndWaitEmulator emulates proposeAndWait. It has one function(propose) inside it, which returns errInternalRetry 50% of the time. Rest of the time it just sleeps for 1 second to emulate successful response, if sleep is true. It also expects maxRetry as argument, which is max number of times pr
(l *rateLimiter, r *rand.Rand, maxRetry int, sleep bool)
| 22 | // to emulate successful response, if sleep is true. It also expects maxRetry as argument, which |
| 23 | // is max number of times propose should be called for each errInternalRetry. |
| 24 | func proposeAndWaitEmulator(l *rateLimiter, r *rand.Rand, maxRetry int, sleep bool) error { |
| 25 | // succeed/fail with equal probability. |
| 26 | propose := func(timeout time.Duration) error { |
| 27 | num := int(r.Int31n(10)) |
| 28 | if num%2 == 0 { |
| 29 | return errInternalRetry |
| 30 | } |
| 31 | |
| 32 | // Sleep for 1 second, to emulate successful behaviour. |
| 33 | if sleep { |
| 34 | time.Sleep(1 * time.Second) |
| 35 | } |
| 36 | return nil |
| 37 | } |
| 38 | |
| 39 | runPropose := func(i int) error { |
| 40 | if err := l.incr(context.Background(), i); err != nil { |
| 41 | return err |
| 42 | } |
| 43 | defer l.decr(i) |
| 44 | return propose(newTimeout(i)) |
| 45 | } |
| 46 | |
| 47 | for i := range maxRetry { |
| 48 | if err := runPropose(i); err != errInternalRetry { |
| 49 | return err |
| 50 | } |
| 51 | } |
| 52 | return errUnableToServe |
| 53 | } |
| 54 | |
| 55 | // This test tests for deadlock in rate limiter. It tried some fixed number of proposals in |
| 56 | // multiple goroutines. At the end it matches if sum of completed and aborted proposals is |
no test coverage detected