1
2
3
4
5
6
7
8
9
10
11
12 package org.apache.hadoop.hbase.quotas;
13
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertFalse;
16 import static org.junit.Assert.assertTrue;
17
18 import java.util.concurrent.TimeUnit;
19
20 import org.apache.hadoop.hbase.testclassification.SmallTests;
21 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
22 import org.junit.Test;
23 import org.junit.experimental.categories.Category;
24
25
26
27
28 @Category({ SmallTests.class })
29 public class TestRateLimiter {
30 @Test
31 public void testWaitIntervalTimeUnitSeconds() {
32 testWaitInterval(TimeUnit.SECONDS, 10, 100);
33 }
34
35 @Test
36 public void testWaitIntervalTimeUnitMinutes() {
37 testWaitInterval(TimeUnit.MINUTES, 10, 6000);
38 }
39
40 @Test
41 public void testWaitIntervalTimeUnitHours() {
42 testWaitInterval(TimeUnit.HOURS, 10, 360000);
43 }
44
45 @Test
46 public void testWaitIntervalTimeUnitDays() {
47 testWaitInterval(TimeUnit.DAYS, 10, 8640000);
48 }
49
50 private void testWaitInterval(final TimeUnit timeUnit, final long limit,
51 final long expectedWaitInterval) {
52 RateLimiter limiter = new AverageIntervalRateLimiter();
53 limiter.set(limit, timeUnit);
54
55 long nowTs = 0;
56
57
58 for (int i = 0; i < (limit - 1); ++i) {
59 assertTrue(limiter.canExecute());
60 limiter.consume();
61 long waitInterval = limiter.waitInterval();
62 assertEquals(0, waitInterval);
63 }
64
65 for (int i = 0; i < (limit * 4); ++i) {
66
67
68 limiter.setNextRefillTime(limiter.getNextRefillTime() - nowTs);
69 assertTrue(limiter.canExecute());
70 assertEquals(0, limiter.waitInterval());
71 limiter.consume();
72
73 long waitInterval = limiter.waitInterval();
74 assertEquals(expectedWaitInterval, waitInterval);
75
76
77 nowTs = waitInterval;
78
79
80 long temp = nowTs + 500;
81 limiter.setNextRefillTime(limiter.getNextRefillTime() + temp);
82 assertFalse(limiter.canExecute());
83
84 limiter.setNextRefillTime(limiter.getNextRefillTime() - temp);
85 }
86 }
87
88 @Test
89 public void testOverconsumptionAverageIntervalRefillStrategy() {
90 RateLimiter limiter = new AverageIntervalRateLimiter();
91 limiter.set(10, TimeUnit.SECONDS);
92
93
94
95 assertTrue(limiter.canExecute());
96 limiter.consume(20);
97
98 assertEquals(100, limiter.waitInterval(1));
99
100 assertEquals(1000, limiter.waitInterval(10));
101
102 limiter.setNextRefillTime(limiter.getNextRefillTime() - 900);
103
104 assertTrue(limiter.canExecute(1));
105 limiter.setNextRefillTime(limiter.getNextRefillTime() - 100);
106
107 assertTrue(limiter.canExecute());
108 assertEquals(0, limiter.waitInterval());
109 }
110
111 @Test
112 public void testOverconsumptionFixedIntervalRefillStrategy() throws InterruptedException {
113 RateLimiter limiter = new FixedIntervalRateLimiter();
114 limiter.set(10, TimeUnit.SECONDS);
115
116
117
118 assertTrue(limiter.canExecute());
119 limiter.consume(20);
120
121 assertEquals(1000, limiter.waitInterval(1));
122
123 assertEquals(1000, limiter.waitInterval(10));
124
125 limiter.setNextRefillTime(limiter.getNextRefillTime() - 900);
126
127 assertFalse(limiter.canExecute(1));
128 limiter.setNextRefillTime(limiter.getNextRefillTime() - 100);
129
130
131 assertTrue(limiter.canExecute());
132 assertEquals(0, limiter.waitInterval());
133 }
134
135 @Test
136 public void testFixedIntervalResourceAvailability() throws Exception {
137 RateLimiter limiter = new FixedIntervalRateLimiter();
138 limiter.set(10, TimeUnit.SECONDS);
139
140 assertTrue(limiter.canExecute(10));
141 limiter.consume(3);
142 assertEquals(7, limiter.getAvailable());
143 assertFalse(limiter.canExecute(10));
144 limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000);
145 assertTrue(limiter.canExecute(10));
146 assertEquals(10, limiter.getAvailable());
147 }
148
149 @Test
150 public void testLimiterBySmallerRate() throws InterruptedException {
151
152 RateLimiter limiter = new FixedIntervalRateLimiter();
153 limiter.set(10, TimeUnit.SECONDS);
154
155 int count = 0;
156 while ((count++) < 10) {
157
158 limiter.setNextRefillTime(limiter.getNextRefillTime() - 500);
159 for (int i = 0; i < 3; i++) {
160
161 assertEquals(true, limiter.canExecute());
162 limiter.consume();
163 }
164 }
165 }
166
167 @Test
168 public void testCanExecuteOfAverageIntervalRateLimiter() throws InterruptedException {
169 RateLimiter limiter = new AverageIntervalRateLimiter();
170
171 limiter.set(100, TimeUnit.SECONDS);
172 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
173 assertEquals(50, testCanExecuteByRate(limiter, 50));
174
175
176 limiter.set(100, TimeUnit.SECONDS);
177 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
178 assertEquals(100, testCanExecuteByRate(limiter, 100));
179
180
181 limiter.set(100, TimeUnit.SECONDS);
182 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
183 assertEquals(200, testCanExecuteByRate(limiter, 200));
184
185
186 limiter.set(100, TimeUnit.SECONDS);
187 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
188 assertEquals(200, testCanExecuteByRate(limiter, 500));
189 }
190
191 @Test
192 public void testCanExecuteOfFixedIntervalRateLimiter() throws InterruptedException {
193 RateLimiter limiter = new FixedIntervalRateLimiter();
194
195 limiter.set(100, TimeUnit.SECONDS);
196 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
197 assertEquals(50, testCanExecuteByRate(limiter, 50));
198
199
200 limiter.set(100, TimeUnit.SECONDS);
201 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
202 assertEquals(100, testCanExecuteByRate(limiter, 100));
203
204
205 limiter.set(100, TimeUnit.SECONDS);
206 limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime());
207 assertEquals(100, testCanExecuteByRate(limiter, 200));
208 }
209
210 public int testCanExecuteByRate(RateLimiter limiter, int rate) {
211 int request = 0;
212 int count = 0;
213 while ((request++) < rate) {
214 limiter.setNextRefillTime(limiter.getNextRefillTime() - limiter.getTimeUnitInMillis() / rate);
215 if (limiter.canExecute()) {
216 count++;
217 limiter.consume();
218 }
219 }
220 return count;
221 }
222
223 @Test
224 public void testRefillOfAverageIntervalRateLimiter() throws InterruptedException {
225 RateLimiter limiter = new AverageIntervalRateLimiter();
226 limiter.set(60, TimeUnit.SECONDS);
227 assertEquals(60, limiter.getAvailable());
228
229 assertEquals(60, limiter.refill(limiter.getLimit()));
230
231 limiter.consume(30);
232
233
234 limiter.setNextRefillTime(limiter.getNextRefillTime() - 200);
235 assertEquals(12, limiter.refill(limiter.getLimit()));
236
237
238 limiter.setNextRefillTime(limiter.getNextRefillTime() - 500);
239 assertEquals(30, limiter.refill(limiter.getLimit()));
240
241
242 limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000);
243 assertEquals(60, limiter.refill(limiter.getLimit()));
244
245
246 limiter.setNextRefillTime(limiter.getNextRefillTime() - 3000);
247 assertEquals(60, limiter.refill(limiter.getLimit()));
248 limiter.setNextRefillTime(limiter.getNextRefillTime() - 5000);
249 assertEquals(60, limiter.refill(limiter.getLimit()));
250 }
251
252 @Test
253 public void testRefillOfFixedIntervalRateLimiter() throws InterruptedException {
254 RateLimiter limiter = new FixedIntervalRateLimiter();
255 limiter.set(60, TimeUnit.SECONDS);
256 assertEquals(60, limiter.getAvailable());
257
258 assertEquals(60, limiter.refill(limiter.getLimit()));
259
260 limiter.consume(30);
261
262
263 limiter.setNextRefillTime(limiter.getNextRefillTime() - 200);
264 assertEquals(0, limiter.refill(limiter.getLimit()));
265
266
267 limiter.setNextRefillTime(limiter.getNextRefillTime() - 500);
268 assertEquals(0, limiter.refill(limiter.getLimit()));
269
270
271 limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000);
272 assertEquals(60, limiter.refill(limiter.getLimit()));
273
274
275 limiter.setNextRefillTime(limiter.getNextRefillTime() - 3000);
276 assertEquals(60, limiter.refill(limiter.getLimit()));
277 limiter.setNextRefillTime(limiter.getNextRefillTime() - 5000);
278 assertEquals(60, limiter.refill(limiter.getLimit()));
279 }
280 }