@@ -2,11 +2,22 @@ open Thread
22open Rate_limit
33open QCheck
44
5+ let test_bad_fill_rate () =
6+ let tb_zero = Token_bucket. create ~burst_size: 1.0 ~fill_rate: 0.0 in
7+ Alcotest. (check bool )
8+ " Creating a token bucket with 0 fill rate should fail" true (tb_zero = None ) ;
9+ let tb_negative = Token_bucket. create ~burst_size: 1.0 ~fill_rate: ~-. 1.0 in
10+ Alcotest. (check bool )
11+ " Creating a token bucket with negative fill rate should fail" true
12+ (tb_negative = None )
13+
514let test_consume_removes_correct_amount () =
615 let initial_time = Mtime.Span. of_uint64_ns 0L in
716 let tb =
8- Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
9- ~fill_rate: 2.0
17+ Option. get
18+ (Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
19+ ~fill_rate: 2.0
20+ )
1021 in
1122
1223 Alcotest. (check (float 0.0 ))
@@ -25,8 +36,10 @@ let test_consume_removes_correct_amount () =
2536let test_consume_more_than_available () =
2637 let initial_time = Mtime.Span. of_uint64_ns 0L in
2738 let tb =
28- Token_bucket. create_with_timestamp initial_time ~burst_size: 5.0
29- ~fill_rate: 1.0
39+ Option. get
40+ (Token_bucket. create_with_timestamp initial_time ~burst_size: 5.0
41+ ~fill_rate: 1.0
42+ )
3043 in
3144
3245 let _ = Token_bucket. consume_with_timestamp (fun () -> initial_time) tb 4.0 in
@@ -43,8 +56,10 @@ let test_consume_more_than_available () =
4356let test_consume_refills_before_removing () =
4457 let initial_time = Mtime.Span. of_uint64_ns 0L in
4558 let tb =
46- Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
47- ~fill_rate: 2.0
59+ Option. get
60+ (Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
61+ ~fill_rate: 2.0
62+ )
4863 in
4964
5065 let first_consume =
@@ -67,8 +82,10 @@ let test_consume_refills_before_removing () =
6782let test_peek_respects_burst_size () =
6883 let initial_time = Mtime.Span. of_uint64_ns 0L in
6984 let tb =
70- Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
71- ~fill_rate: 5.0
85+ Option. get
86+ (Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
87+ ~fill_rate: 5.0
88+ )
7289 in
7390
7491 let _ = Token_bucket. consume_with_timestamp (fun () -> initial_time) tb 8.0 in
@@ -80,8 +97,10 @@ let test_peek_respects_burst_size () =
8097
8198let test_concurrent_access () =
8299 let tb =
83- Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 15.0
84- ~fill_rate: 0.0
100+ Option. get
101+ (Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 15.0
102+ ~fill_rate: 0.01
103+ )
85104 in
86105 let threads =
87106 Array. init 10 (fun _ ->
@@ -101,14 +120,14 @@ let test_concurrent_access () =
101120 5.0
102121
103122let test_sleep () =
104- let tb = Token_bucket. create ~burst_size: 20.0 ~fill_rate: 5.0 in
123+ let tb = Option. get ( Token_bucket. create ~burst_size: 20.0 ~fill_rate: 5.0 ) in
105124 let _ = Token_bucket. consume tb 10.0 in
106125 Thread. delay 1.0 ;
107126 Alcotest. (check (float 0.2 ))
108127 " Sleep 1 should refill token bucket by fill_rate" 15.0 (Token_bucket. peek tb)
109128
110129let test_system_time_versions () =
111- let tb = Token_bucket. create ~burst_size: 10.0 ~fill_rate: 2.0 in
130+ let tb = Option. get ( Token_bucket. create ~burst_size: 10.0 ~fill_rate: 2.0 ) in
112131
113132 let initial_peek = Token_bucket. peek tb in
114133 Alcotest. (check (float 0.01 ))
@@ -122,7 +141,7 @@ let test_system_time_versions () =
122141 " After consume, should have 7 tokens" 7.0 after_consume_peek
123142
124143let test_concurrent_system_time () =
125- let tb = Token_bucket. create ~burst_size: 100.0 ~fill_rate: 10.0 in
144+ let tb = Option. get ( Token_bucket. create ~burst_size: 100.0 ~fill_rate: 10.0 ) in
126145 let num_threads = 20 in
127146 let consume_per_thread = 3 in
128147
@@ -149,8 +168,10 @@ let test_concurrent_system_time () =
149168
150169let test_consume_more_than_available_concurrent () =
151170 let tb =
152- Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 5.0
153- ~fill_rate: 0.0
171+ Option. get
172+ (Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 5.0
173+ ~fill_rate: 0.1
174+ )
154175 in
155176 let num_threads = 10 in
156177 let consume_per_thread = 1 in
@@ -180,15 +201,17 @@ let test_consume_more_than_available_concurrent () =
180201
181202 Alcotest. (check int )
182203 " Only 5 consumptions should succeed" 5 ! successful_consumes ;
183- Alcotest. (check (float 0.0 ))
204+ Alcotest. (check (float 0.1 ))
184205 " Bucket should be empty after consumptions" 0.0
185206 (Token_bucket. peek_with_timestamp Mtime.Span. zero tb)
186207
187208let test_delay_until_available () =
188209 let initial_time = Mtime.Span. of_uint64_ns 0L in
189210 let tb =
190- Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
191- ~fill_rate: 2.0
211+ Option. get
212+ (Token_bucket. create_with_timestamp initial_time ~burst_size: 10.0
213+ ~fill_rate: 2.0
214+ )
192215 in
193216
194217 let _ =
@@ -201,57 +224,40 @@ let test_delay_until_available () =
201224 Alcotest. (check (float 0.01 ))
202225 " Delay for 4 tokens at 2 tokens/sec should be 2 seconds" 2.0 delay ;
203226
204- let tb_fresh = Token_bucket. create ~burst_size: 10.0 ~fill_rate: 2.0 in
227+ let tb_fresh =
228+ Option. get (Token_bucket. create ~burst_size: 10.0 ~fill_rate: 2.0 )
229+ in
205230 let _ = Token_bucket. consume tb_fresh 10.0 in
206231 let delay_system = Token_bucket. delay_until_available tb_fresh 4.0 in
207232
208233 Alcotest. (check (float 0.1 ))
209234 " System time delay should be approximately 2 seconds" 2.0 delay_system
210235
211236let test_edge_cases () =
212- let tb_zero_rate =
213- Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 5.0
214- ~fill_rate: 0.0
215- in
216- let _ =
217- Token_bucket. consume_with_timestamp
218- (fun () -> Mtime.Span. zero)
219- tb_zero_rate 2.0
220- in
221- let later_time = Mtime.Span. of_uint64_ns 1_000_000_000_000L in
222- let available = Token_bucket. peek_with_timestamp later_time tb_zero_rate in
223- Alcotest. (check (float 0.0 ))
224- " Zero fill rate should not add tokens" 3.0 available ;
225-
226- let tb_zero_amount =
227- Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 5.0
228- ~fill_rate: 1.0
237+ let tb =
238+ Option. get
239+ (Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 5.0
240+ ~fill_rate: 1.0
241+ )
229242 in
230243 let success =
231- Token_bucket. consume_with_timestamp
232- (fun () -> Mtime.Span. zero)
233- tb_zero_amount 0.0
244+ Token_bucket. consume_with_timestamp (fun () -> Mtime.Span. zero) tb 0.0
234245 in
235246 Alcotest. (check bool ) " Consuming zero tokens should succeed" true success ;
236247
237248 let tb_small =
238- Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 1.0
239- ~fill_rate: 0.1
249+ Option. get
250+ (Token_bucket. create_with_timestamp Mtime.Span. zero ~burst_size: 1.0
251+ ~fill_rate: 0.1
252+ )
240253 in
241254 let success_small =
242255 Token_bucket. consume_with_timestamp
243256 (fun () -> Mtime.Span. zero)
244257 tb_small 0.001
245258 in
246259 Alcotest. (check bool )
247- " Consuming very small amount should succeed" true success_small ;
248-
249- let tb_zero = Token_bucket. create ~burst_size: 0.0 ~fill_rate: 0.0 in
250- let success_zero = Token_bucket. consume tb_zero 0.0 in
251- let success_small = Token_bucket. consume tb_zero 0.001 in
252- Alcotest. (check bool ) " Consuming zero tokens should succeed" true success_zero ;
253- Alcotest. (check bool )
254- " Consuming very small amount should fail" false success_small
260+ " Consuming very small amount should succeed" true success_small
255261
256262let test_consume_quickcheck =
257263 let open QCheck.Gen in
@@ -289,7 +295,8 @@ let test_consume_quickcheck =
289295 let property (burst_size , fill_rate , operations ) =
290296 let initial_time = Mtime.Span. of_uint64_ns 0L in
291297 let tb =
292- Token_bucket. create_with_timestamp initial_time ~burst_size ~fill_rate
298+ Option. get
299+ (Token_bucket. create_with_timestamp initial_time ~burst_size ~fill_rate )
293300 in
294301
295302 let rec check_operations op_num time_ns last_refill_ns current_tokens ops =
@@ -345,7 +352,9 @@ let test_consume_quickcheck =
345352 in
346353
347354 let gen_all =
348- map3 (fun burst fill ops -> (burst, fill, ops)) pfloat pfloat gen_operations
355+ map3
356+ (fun burst fill ops -> (burst, fill, ops))
357+ pfloat (float_range 1e-9 1e9 ) gen_operations
349358 in
350359
351360 let arb_all =
@@ -371,7 +380,11 @@ let test_consume_quickcheck =
371380
372381let test =
373382 [
374- ( " Consume removes correct amount"
383+ ( " A bucket with zero or negative fill rate cannot be created"
384+ , `Quick
385+ , test_bad_fill_rate
386+ )
387+ ; ( " Consume removes correct amount"
375388 , `Quick
376389 , test_consume_removes_correct_amount
377390 )
0 commit comments