001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.quotas;
019
020import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doGets;
021import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doPuts;
022import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerExceedThrottleQuotaCacheRefresh;
023import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerNamespaceCacheRefresh;
024import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerRegionServerCacheRefresh;
025import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerTableCacheRefresh;
026import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerUserCacheRefresh;
027import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.waitMinuteQuota;
028import static org.junit.Assert.assertEquals;
029
030import java.util.concurrent.TimeUnit;
031
032import org.apache.hadoop.hbase.HBaseClassTestRule;
033import org.apache.hadoop.hbase.HBaseTestingUtility;
034import org.apache.hadoop.hbase.HConstants;
035import org.apache.hadoop.hbase.TableName;
036import org.apache.hadoop.hbase.client.Admin;
037import org.apache.hadoop.hbase.client.Get;
038import org.apache.hadoop.hbase.client.Table;
039import org.apache.hadoop.hbase.security.User;
040import org.apache.hadoop.hbase.testclassification.MediumTests;
041import org.apache.hadoop.hbase.testclassification.RegionServerTests;
042import org.apache.hadoop.hbase.util.Bytes;
043import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
044import org.junit.After;
045import org.junit.AfterClass;
046import org.junit.BeforeClass;
047import org.junit.ClassRule;
048import org.junit.Ignore;
049import org.junit.Test;
050import org.junit.experimental.categories.Category;
051import org.slf4j.Logger;
052import org.slf4j.LoggerFactory;
053
054@Ignore // Disabled because flakey. Fails ~30% on a resource constrained GCE though not on Apache.
055@Category({RegionServerTests.class, MediumTests.class})
056public class TestQuotaThrottle {
057
058  @ClassRule
059  public static final HBaseClassTestRule CLASS_RULE =
060      HBaseClassTestRule.forClass(TestQuotaThrottle.class);
061
062  private final static Logger LOG = LoggerFactory.getLogger(TestQuotaThrottle.class);
063
064  private final static int REFRESH_TIME = 30 * 60000;
065
066  private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
067  private final static byte[] FAMILY = Bytes.toBytes("cf");
068  private final static byte[] QUALIFIER = Bytes.toBytes("q");
069
070  private final static TableName[] TABLE_NAMES = new TableName[] {
071    TableName.valueOf("TestQuotaAdmin0"),
072    TableName.valueOf("TestQuotaAdmin1"),
073    TableName.valueOf("TestQuotaAdmin2")
074  };
075
076  private static Table[] tables;
077
078  @BeforeClass
079  public static void setUpBeforeClass() throws Exception {
080    TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
081    TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, REFRESH_TIME);
082    TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
083    TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
084    TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
085    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
086    TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
087    TEST_UTIL.startMiniCluster(1);
088    TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
089    QuotaCache.TEST_FORCE_REFRESH = true;
090
091    tables = new Table[TABLE_NAMES.length];
092    for (int i = 0; i < TABLE_NAMES.length; ++i) {
093      tables[i] = TEST_UTIL.createTable(TABLE_NAMES[i], FAMILY);
094    }
095  }
096
097  @AfterClass
098  public static void tearDownAfterClass() throws Exception {
099    EnvironmentEdgeManager.reset();
100    for (int i = 0; i < tables.length; ++i) {
101      if (tables[i] != null) {
102        tables[i].close();
103        TEST_UTIL.deleteTable(TABLE_NAMES[i]);
104      }
105    }
106
107    TEST_UTIL.shutdownMiniCluster();
108  }
109
110  @After
111  public void tearDown() throws Exception {
112    ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL);
113  }
114
115  @Test
116  public void testUserGlobalThrottle() throws Exception {
117    final Admin admin = TEST_UTIL.getAdmin();
118    final String userName = User.getCurrent().getShortName();
119
120    // Add 6req/min limit
121    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6,
122      TimeUnit.MINUTES));
123    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
124
125    // should execute at max 6 requests
126    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
127
128    // wait a minute and you should get other 6 requests executed
129    waitMinuteQuota();
130    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
131
132    // Remove all the limits
133    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
134    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
135    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
136    assertEquals(60, doGets(60, tables));
137  }
138
139  @Test
140  public void testUserGlobalReadAndWriteThrottle() throws Exception {
141    final Admin admin = TEST_UTIL.getAdmin();
142    final String userName = User.getCurrent().getShortName();
143
144    // Add 6req/min limit for read request
145    admin.setQuota(
146      QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
147    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
148
149    // not limit for write request and should execute at max 6 read requests
150    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
151    assertEquals(6, doGets(100, tables));
152
153    waitMinuteQuota();
154
155    // Add 6req/min limit for write request
156    admin.setQuota(
157      QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
158    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
159
160    // should execute at max 6 read requests and at max 6 write write requests
161    assertEquals(6, doGets(100, tables));
162    assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables));
163
164    // Remove all the limits
165    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
166    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
167    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
168    assertEquals(60, doGets(60, tables));
169  }
170
171  @Test
172  public void testUserTableThrottle() throws Exception {
173    final Admin admin = TEST_UTIL.getAdmin();
174    final String userName = User.getCurrent().getShortName();
175
176    // Add 6req/min limit
177    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
178      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
179    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
180
181    // should execute at max 6 requests on tables[0] and have no limit on tables[1]
182    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
183    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
184
185    // wait a minute and you should get other 6 requests executed
186    waitMinuteQuota();
187    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
188
189    // Remove all the limits
190    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
191    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
192    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
193    assertEquals(60, doGets(60, tables));
194  }
195
196  @Test
197  public void testUserTableReadAndWriteThrottle() throws Exception {
198    final Admin admin = TEST_UTIL.getAdmin();
199    final String userName = User.getCurrent().getShortName();
200
201    // Add 6req/min limit for write request on tables[0]
202    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
203      ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
204    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
205
206    // should execute at max 6 write requests and have no limit for read request
207    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
208    assertEquals(60, doGets(60, tables[0]));
209
210    // no limit on tables[1]
211    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[1]));
212    assertEquals(60, doGets(60, tables[1]));
213
214    // wait a minute and you should get other 6 write requests executed
215    waitMinuteQuota();
216
217    // Add 6req/min limit for read request on tables[0]
218    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
219      ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
220    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
221
222    // should execute at max 6 read requests and at max 6 write requests
223    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
224    assertEquals(6, doGets(60, tables[0]));
225
226    // no limit on tables[1]
227    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
228    assertEquals(30, doGets(30, tables[1]));
229
230    // Remove all the limits
231    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
232    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
233    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
234    assertEquals(60, doGets(60, tables));
235  }
236
237  @Test
238  public void testUserNamespaceThrottle() throws Exception {
239    final Admin admin = TEST_UTIL.getAdmin();
240    final String userName = User.getCurrent().getShortName();
241    final String NAMESPACE = "default";
242
243    // Add 6req/min limit
244    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE,
245      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
246    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
247
248    // should execute at max 6 requests on tables[0] and have no limit on tables[1]
249    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
250
251    // wait a minute and you should get other 6 requests executed
252    waitMinuteQuota();
253    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
254
255    // Remove all the limits
256    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
257    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
258    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
259    assertEquals(60, doGets(60, tables));
260  }
261
262  @Test
263  public void testUserNamespaceReadAndWriteThrottle() throws Exception {
264    final Admin admin = TEST_UTIL.getAdmin();
265    final String userName = User.getCurrent().getShortName();
266    final String NAMESPACE = "default";
267
268    // Add 6req/min limit for read request
269    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.READ_NUMBER,
270      6, TimeUnit.MINUTES));
271    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
272
273    // should execute at max 6 read requests and have no limit for write request
274    assertEquals(6, doGets(60, tables[0]));
275    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[0]));
276
277    waitMinuteQuota();
278
279    // Add 6req/min limit for write request, too
280    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.WRITE_NUMBER,
281      6, TimeUnit.MINUTES));
282    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
283
284    // should execute at max 6 read requests and at max 6 write requests
285    assertEquals(6, doGets(60, tables[0]));
286    assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables[0]));
287
288    // Remove all the limits
289    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
290    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
291    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
292    assertEquals(60, doGets(60, tables));
293  }
294
295  @Test
296  public void testTableGlobalThrottle() throws Exception {
297    final Admin admin = TEST_UTIL.getAdmin();
298
299    // Add 6req/min limit
300    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
301      6, TimeUnit.MINUTES));
302    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
303
304    // should execute at max 6 requests
305    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
306    // should have no limits
307    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
308
309    // wait a minute and you should get other 6 requests executed
310    waitMinuteQuota();
311    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
312
313    // Remove all the limits
314    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
315    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
316    assertEquals(80, doGets(80, tables[0], tables[1]));
317  }
318
319  @Test
320  public void testTableGlobalReadAndWriteThrottle() throws Exception {
321    final Admin admin = TEST_UTIL.getAdmin();
322
323    // Add 6req/min limit for read request
324    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.READ_NUMBER, 6,
325      TimeUnit.MINUTES));
326    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
327
328    // should execute at max 6 read requests and have no limit for write request
329    assertEquals(6, doGets(100, tables[0]));
330    assertEquals(100, doPuts(100, FAMILY, QUALIFIER, tables[0]));
331    // should have no limits on tables[1]
332    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
333    assertEquals(30, doGets(30, tables[1]));
334
335    // wait a minute and you should get other 6 requests executed
336    waitMinuteQuota();
337
338    // Add 6req/min limit for write request, too
339    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 6,
340      TimeUnit.MINUTES));
341    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
342
343    // should execute at max 6 read requests and at max 6 write requests
344    assertEquals(6, doGets(100, tables[0]));
345    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
346    // should have no limits on tables[1]
347    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
348    assertEquals(30, doGets(30, tables[1]));
349
350    // Remove all the limits
351    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
352    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
353    assertEquals(80, doGets(80, tables[0], tables[1]));
354  }
355
356  @Test
357  public void testNamespaceGlobalThrottle() throws Exception {
358    final Admin admin = TEST_UTIL.getAdmin();
359    final String NAMESPACE = "default";
360
361    // Add 6req/min limit
362    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 6,
363      TimeUnit.MINUTES));
364    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
365
366    // should execute at max 6 requests
367    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
368
369    // wait a minute and you should get other 6 requests executed
370    waitMinuteQuota();
371    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
372
373    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
374    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
375    assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
376  }
377
378  @Test
379  public void testNamespaceGlobalReadAndWriteThrottle() throws Exception {
380    final Admin admin = TEST_UTIL.getAdmin();
381    final String NAMESPACE = "default";
382
383    // Add 6req/min limit for write request
384    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.WRITE_NUMBER, 6,
385      TimeUnit.MINUTES));
386    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
387
388    // should execute at max 6 write requests and no limit for read request
389    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
390    assertEquals(100, doGets(100, tables[0]));
391
392    // wait a minute and you should get other 6 requests executed
393    waitMinuteQuota();
394
395    // Add 6req/min limit for read request, too
396    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.READ_NUMBER, 6,
397      TimeUnit.MINUTES));
398    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
399
400    // should execute at max 6 write requests and at max 6 read requests
401    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
402    assertEquals(6, doGets(100, tables[0]));
403
404    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
405    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
406    assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
407  }
408
409  @Test
410  public void testUserAndTableThrottle() throws Exception {
411    final Admin admin = TEST_UTIL.getAdmin();
412    final String userName = User.getCurrent().getShortName();
413
414    // Add 6req/min limit for the user on tables[0]
415    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
416      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
417    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
418    // Add 12req/min limit for the user
419    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 12,
420      TimeUnit.MINUTES));
421    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1], TABLE_NAMES[2]);
422    // Add 8req/min limit for the tables[1]
423    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER,
424      8, TimeUnit.MINUTES));
425    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
426    // Add a lower table level throttle on tables[0]
427    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
428      3, TimeUnit.MINUTES));
429    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
430
431    // should execute at max 12 requests
432    assertEquals(12, doGets(100, tables[2]));
433
434    // should execute at max 8 requests
435    waitMinuteQuota();
436    assertEquals(8, doGets(100, tables[1]));
437
438    // should execute at max 3 requests
439    waitMinuteQuota();
440    assertEquals(3, doPuts(100, FAMILY, QUALIFIER, tables[0]));
441
442    // Remove all the throttling rules
443    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
444    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
445    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0], TABLE_NAMES[1]);
446
447    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1]));
448    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
449    waitMinuteQuota();
450    assertEquals(40, doGets(40, tables[1]));
451
452    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
453    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
454    waitMinuteQuota();
455    assertEquals(40, doGets(40, tables[0]));
456  }
457
458  @Test
459  public void testUserGlobalBypassThrottle() throws Exception {
460    final Admin admin = TEST_UTIL.getAdmin();
461    final String userName = User.getCurrent().getShortName();
462    final String NAMESPACE = "default";
463
464    // Add 6req/min limit for tables[0]
465    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
466      6, TimeUnit.MINUTES));
467    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
468    // Add 13req/min limit for the user
469    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER,
470      13, TimeUnit.MINUTES));
471    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
472
473    // should execute at max 6 requests on table[0] and (13 - 6) on table[1]
474    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
475    assertEquals(7, doGets(100, tables[1]));
476    waitMinuteQuota();
477
478    // Set the global bypass for the user
479    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true));
480    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[2],
481      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
482    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[2]);
483    assertEquals(30, doGets(30, tables[0]));
484    assertEquals(30, doGets(30, tables[1]));
485    waitMinuteQuota();
486
487    // Remove the global bypass
488    // should execute at max 6 requests on table[0] and (13 - 6) on table[1]
489    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false));
490    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[2]));
491    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[2]);
492    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
493    assertEquals(7, doGets(100, tables[1]));
494
495    // unset throttle
496    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
497    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
498    waitMinuteQuota();
499    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
500    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
501    assertEquals(30, doGets(30, tables[0]));
502    assertEquals(30, doGets(30, tables[1]));
503  }
504
505  @Test
506  public void testTableWriteCapacityUnitThrottle() throws Exception {
507    final Admin admin = TEST_UTIL.getAdmin();
508
509    // Add 6CU/min limit
510    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
511      ThrottleType.WRITE_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
512    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
513
514    // should execute at max 6 capacity units because each put size is 1 capacity unit
515    assertEquals(6, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
516
517    // wait a minute and you should execute at max 3 capacity units because each put size is 2
518    // capacity unit
519    waitMinuteQuota();
520    assertEquals(3, doPuts(20, 1025, FAMILY, QUALIFIER, tables[0]));
521
522    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
523    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
524  }
525
526  @Test
527  public void testTableReadCapacityUnitThrottle() throws Exception {
528    final Admin admin = TEST_UTIL.getAdmin();
529
530    // Add 6CU/min limit
531    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
532      ThrottleType.READ_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
533    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
534
535    assertEquals(20, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
536    // should execute at max 6 capacity units because each get size is 1 capacity unit
537    assertEquals(6, doGets(20, tables[0]));
538
539    assertEquals(20, doPuts(20, 2015, FAMILY, QUALIFIER, tables[0]));
540    // wait a minute and you should execute at max 3 capacity units because each get size is 2
541    // capacity unit on tables[0]
542    waitMinuteQuota();
543    assertEquals(3, doGets(20, tables[0]));
544
545    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
546    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
547  }
548
549  @Test
550  public void testTableExistsGetThrottle() throws Exception {
551    final Admin admin = TEST_UTIL.getAdmin();
552
553    // Add throttle quota
554    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
555      100, TimeUnit.MINUTES));
556    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
557
558    Table table = TEST_UTIL.getConnection().getTable(TABLE_NAMES[0]);
559    // An exists call when having throttle quota
560    table.exists(new Get(Bytes.toBytes("abc")));
561
562    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
563    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
564  }
565
566  @Test
567  public void testRegionServerThrottle() throws Exception {
568    final Admin admin = TEST_UTIL.getAdmin();
569    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
570      TimeUnit.MINUTES));
571
572    // requests are throttled by table quota
573    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
574      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 7, TimeUnit.MINUTES));
575    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
576    triggerRegionServerCacheRefresh(TEST_UTIL, false);
577    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
578    triggerRegionServerCacheRefresh(TEST_UTIL, false);
579    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
580
581    // requests are throttled by region server quota
582    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
583      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
584    triggerRegionServerCacheRefresh(TEST_UTIL, false);
585    assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
586    triggerRegionServerCacheRefresh(TEST_UTIL, false);
587    assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
588
589    // unthrottle
590    admin.setQuota(
591      QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
592    triggerRegionServerCacheRefresh(TEST_UTIL, true);
593    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
594    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
595    triggerRegionServerCacheRefresh(TEST_UTIL, true);
596  }
597
598  @Test
599  public void testExceedThrottleQuota() throws Exception {
600    final Admin admin = TEST_UTIL.getAdmin();
601    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
602      TimeUnit.MINUTES));
603    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
604    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
605      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
606    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
607      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.READ_NUMBER, 10, TimeUnit.SECONDS));
608    triggerRegionServerCacheRefresh(TEST_UTIL, false);
609
610    // enable exceed throttle quota
611    admin.exceedThrottleQuotaSwitch(true);
612    // exceed table limit and allowed by region server limit
613    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
614    waitMinuteQuota();
615    assertEquals(10, doPuts(10, FAMILY, QUALIFIER, tables[0]));
616    // exceed table limit and throttled by region server limit
617    waitMinuteQuota();
618    assertEquals(20, doPuts(25, FAMILY, QUALIFIER, tables[0]));
619
620    // set region server limiter is lower than table limiter
621    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
622      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 2, TimeUnit.SECONDS));
623    triggerRegionServerCacheRefresh(TEST_UTIL, false);
624    // throttled by region server limiter
625    waitMinuteQuota();
626    assertEquals(2, doPuts(10, FAMILY, QUALIFIER, tables[0]));
627    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
628      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
629    triggerRegionServerCacheRefresh(TEST_UTIL, false);
630
631    // disable exceed throttle quota
632    admin.exceedThrottleQuotaSwitch(false);
633    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
634    waitMinuteQuota();
635    // throttled by table limit
636    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
637
638    // enable exceed throttle quota and unthrottle region server
639    admin.exceedThrottleQuotaSwitch(true);
640    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
641    waitMinuteQuota();
642    admin.setQuota(
643      QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
644    triggerRegionServerCacheRefresh(TEST_UTIL, true);
645    waitMinuteQuota();
646    // throttled by table limit
647    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
648
649    // disable exceed throttle quota
650    admin.exceedThrottleQuotaSwitch(false);
651    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
652    // unthrottle table
653    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
654    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
655  }
656}