@@ -36,50 +36,58 @@ func TestPermit_Simulation(t *testing.T) {
3636 tests := []struct {
3737 name string
3838 capacity []int // update every 50ms
39- goroutines int // each would block on acquiring 2-6 tokens for 100ms
40- goroutinesAcquireChan int // each would block using AcquireChan for 100ms
39+ goroutines int // each would block on acquiring 1-2 tokens for 100-150ms
40+ goroutinesAcquireChan int // each would block using AcquireChan for 100-150ms
4141 maxTestDuration time.Duration
42- expectFailures int
43- expectFailuresAtLeast int
42+ expectFailuresRange []int // range of failures, inclusive [min, max]
4443 }{
4544 {
4645 name : "enough permit, no blocking" ,
47- maxTestDuration : 100 * time .Millisecond ,
48- capacity : []int {1000 },
46+ maxTestDuration : 200 * time .Millisecond , // at most need 150 ms, add 50 ms buffer
47+ capacity : []int {10000 },
4948 goroutines : 100 ,
5049 goroutinesAcquireChan : 100 ,
51- expectFailures : 0 ,
50+ expectFailuresRange : [] int { 0 , 0 } ,
5251 },
5352 {
5453 name : "not enough permit, blocking but all acquire" ,
55- maxTestDuration : 1 * time .Second ,
54+ maxTestDuration : 1200 * time .Millisecond , // at most need 150ms * (1000 + 500) / 200 = 1125ms to acquire all permit
5655 capacity : []int {200 },
57- goroutines : 500 ,
58- goroutinesAcquireChan : 500 ,
59- expectFailures : 0 ,
56+ goroutines : 500 , // at most 1000 tokens
57+ goroutinesAcquireChan : 500 , // 500 tokens
58+ expectFailuresRange : [] int { 0 , 0 } ,
6059 },
6160 {
6261 name : "not enough permit for some to acquire, fail some" ,
63- maxTestDuration : 300 * time .Millisecond ,
64- capacity : []int {100 },
62+ maxTestDuration : 250 * time .Millisecond , // at least need 100ms * (500 + 500) / 200 = 250ms to acquire all permit
63+ capacity : []int {200 },
6564 goroutines : 500 ,
6665 goroutinesAcquireChan : 500 ,
67- expectFailuresAtLeast : 1 ,
66+ expectFailuresRange : [] int { 1 , 999 }, // should at least pass some acquires
6867 },
6968 {
7069 name : "not enough permit at beginning but due to capacity change, blocking but all acquire" ,
71- maxTestDuration : 300 * time .Millisecond ,
72- capacity : []int {100 , 300 , 500 },
70+ maxTestDuration : 250 * time .Millisecond ,
71+ capacity : []int {200 , 400 , 600 },
72+ goroutines : 500 ,
73+ goroutinesAcquireChan : 500 ,
74+ expectFailuresRange : []int {0 , 0 },
75+ },
76+ {
77+ name : "enough permit at beginning but due to capacity change, some would fail" ,
78+ maxTestDuration : 250 * time .Millisecond ,
79+ capacity : []int {600 , 400 , 200 },
7380 goroutines : 500 ,
7481 goroutinesAcquireChan : 500 ,
75- expectFailures : 0 ,
82+ expectFailuresRange : [] int { 1 , 999 } ,
7683 },
7784 {
78- name : "not enough permit for any acquire, fail all" ,
79- maxTestDuration : 300 * time .Millisecond ,
80- capacity : []int {0 },
81- goroutines : 1000 ,
82- expectFailures : 1000 ,
85+ name : "not enough permit for any acquire, fail all" ,
86+ maxTestDuration : 300 * time .Millisecond ,
87+ capacity : []int {0 },
88+ goroutines : 500 ,
89+ goroutinesAcquireChan : 500 ,
90+ expectFailuresRange : []int {1000 , 1000 },
8391 },
8492 }
8593
@@ -102,13 +110,12 @@ func TestPermit_Simulation(t *testing.T) {
102110 wg .Add (1 )
103111 go func () {
104112 defer wg .Done ()
105- num := rand .Intn (2 ) + 2
106- // num := 1
113+ num := rand .Intn (2 ) + 1
107114 if err := permit .Acquire (ctx , num ); err != nil {
108- failures .Add ( 1 )
115+ failures .Inc ( )
109116 return
110117 }
111- time .Sleep (time .Duration (rand .Intn (100 )) * time .Millisecond )
118+ time .Sleep (time .Duration (100 + rand .Intn (50 )) * time .Millisecond )
112119 permit .Release (num )
113120 }()
114121 }
@@ -118,22 +125,24 @@ func TestPermit_Simulation(t *testing.T) {
118125 defer wg .Done ()
119126 select {
120127 case <- permit .AcquireChan (ctx , wg ):
121- time .Sleep (time .Duration (rand .Intn (100 )) * time .Millisecond )
128+ time .Sleep (time .Duration (100 + rand .Intn (50 )) * time .Millisecond )
122129 permit .Release (1 )
123130 case <- ctx .Done ():
124- failures .Add ( 1 )
131+ failures .Inc ( )
125132 }
126133 }()
127134 }
128135
129136 wg .Wait ()
137+ // sanity check
130138 assert .Equal (t , 0 , permit .Count ())
131- if tt .expectFailuresAtLeast > 0 {
132- assert .LessOrEqual (t , tt .expectFailuresAtLeast , int (failures .Load ()))
133- } else {
134- assert .Equal (t , tt .expectFailures , int (failures .Load ()))
135- }
136139 assert .Equal (t , tt .capacity [len (tt .capacity )- 1 ], permit .Quota ())
140+
141+ // expect failures in range
142+ expectFailureMin := tt .expectFailuresRange [0 ]
143+ expectFailureMax := tt .expectFailuresRange [1 ]
144+ assert .GreaterOrEqual (t , int (failures .Load ()), expectFailureMin )
145+ assert .LessOrEqual (t , int (failures .Load ()), expectFailureMax )
137146 })
138147 }
139148}
0 commit comments