This test tests for deadlock in rate limiter. It tried some fixed number of proposals in multiple goroutines. At the end it matches if sum of completed and aborted proposals is equal to tried proposals or not.
(t *testing.T)
| 56 | // multiple goroutines. At the end it matches if sum of completed and aborted proposals is |
| 57 | // equal to tried proposals or not. |
| 58 | func TestLimiterDeadlock(t *testing.T) { |
| 59 | toTry := int64(3000) // total proposals count to propose. |
| 60 | var currentCount, pending, completed, aborted int64 |
| 61 | |
| 62 | l := &rateLimiter{c: sync.NewCond(&sync.Mutex{}), max: 256} |
| 63 | go l.bleed() |
| 64 | |
| 65 | ticker := time.Tick(time.Second) |
| 66 | |
| 67 | go func() { |
| 68 | now := time.Now() |
| 69 | for range ticker { |
| 70 | l.c.L.Lock() |
| 71 | fmt.Println("Seconds elapsed :", int64(time.Since(now).Seconds()), |
| 72 | "Total proposals: ", atomic.LoadInt64(¤tCount), |
| 73 | "Pending proposal: ", atomic.LoadInt64(&pending), |
| 74 | "Completed Proposals: ", atomic.LoadInt64(&completed), |
| 75 | "Aborted Proposals: ", atomic.LoadInt64(&aborted), |
| 76 | "IOU: ", l.iou) |
| 77 | l.c.L.Unlock() |
| 78 | } |
| 79 | }() |
| 80 | |
| 81 | var wg sync.WaitGroup |
| 82 | for i := range 500 { |
| 83 | wg.Add(1) |
| 84 | go func(no int) { |
| 85 | defer wg.Done() |
| 86 | r := rand.New(rand.NewSource(time.Now().UnixNano())) |
| 87 | for { |
| 88 | if atomic.AddInt64(¤tCount, 1) > toTry { |
| 89 | break |
| 90 | } |
| 91 | atomic.AddInt64(&pending, 1) |
| 92 | if err := proposeAndWaitEmulator(l, r, 3, true); err != nil { |
| 93 | atomic.AddInt64(&aborted, 1) |
| 94 | } else { |
| 95 | atomic.AddInt64(&completed, 1) |
| 96 | } |
| 97 | atomic.AddInt64(&pending, -1) |
| 98 | } |
| 99 | }(i) |
| 100 | } |
| 101 | wg.Wait() |
| 102 | |
| 103 | // After trying all the proposals, (completed + aborted) should be equal to tried proposal. |
| 104 | require.True(t, toTry == completed+aborted, |
| 105 | fmt.Sprintf("Tried: %d, Compteted: %d, Aborted: %d", toTry, completed, aborted)) |
| 106 | } |
| 107 | |
| 108 | func BenchmarkRateLimiter(b *testing.B) { |
| 109 | ious := []int{256} |