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