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.junit.Assert.assertEquals; 021 022import java.util.concurrent.TimeUnit; 023import org.apache.hadoop.hbase.HBaseClassTestRule; 024import org.apache.hadoop.hbase.HBaseTestingUtil; 025import org.apache.hadoop.hbase.TableName; 026import org.apache.hadoop.hbase.client.Admin; 027import org.apache.hadoop.hbase.testclassification.MediumTests; 028import org.apache.hadoop.hbase.testclassification.RegionServerTests; 029import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 030import org.apache.hadoop.security.UserGroupInformation; 031import org.junit.After; 032import org.junit.Before; 033import org.junit.ClassRule; 034import org.junit.Test; 035import org.junit.experimental.categories.Category; 036 037@Category({ RegionServerTests.class, MediumTests.class }) 038public class TestQuotaCache { 039 040 @ClassRule 041 public static final HBaseClassTestRule CLASS_RULE = 042 HBaseClassTestRule.forClass(TestQuotaCache.class); 043 044 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 045 private static final int REFRESH_TIME_MS = 1000; 046 047 @After 048 public void tearDown() throws Exception { 049 ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL); 050 EnvironmentEdgeManager.reset(); 051 TEST_UTIL.shutdownMiniCluster(); 052 } 053 054 @Before 055 public void setUp() throws Exception { 056 TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true); 057 TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, REFRESH_TIME_MS); 058 TEST_UTIL.getConfiguration().setInt(QuotaUtil.QUOTA_DEFAULT_USER_MACHINE_READ_NUM, 1000); 059 060 TEST_UTIL.startMiniCluster(1); 061 TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME); 062 } 063 064 @Test 065 public void testUserQuotaLookup() throws Exception { 066 QuotaCache quotaCache = 067 ThrottleQuotaTestUtil.getQuotaCaches(TEST_UTIL).stream().findAny().get(); 068 final Admin admin = TEST_UTIL.getAdmin(); 069 admin.setQuota(QuotaSettingsFactory.throttleUser("my_user", ThrottleType.READ_NUMBER, 3737, 070 TimeUnit.MINUTES)); 071 072 // Setting a quota and then looking it up from the cache should work, even if the cache has not 073 // refreshed 074 UserGroupInformation ugi = UserGroupInformation.createRemoteUser("my_user"); 075 QuotaLimiter quotaLimiter = quotaCache.getUserLimiter(ugi, TableName.valueOf("my_table")); 076 assertEquals(3737, quotaLimiter.getReadNumLimit()); 077 078 // if no specific user quota, fall back to default 079 ugi = UserGroupInformation.createRemoteUser("my_user2"); 080 quotaLimiter = quotaCache.getUserLimiter(ugi, TableName.valueOf("my_table")); 081 assertEquals(1000, quotaLimiter.getReadNumLimit()); 082 083 // still works after refresh 084 quotaCache.forceSynchronousCacheRefresh(); 085 ugi = UserGroupInformation.createRemoteUser("my_user"); 086 quotaLimiter = quotaCache.getUserLimiter(ugi, TableName.valueOf("my_table")); 087 assertEquals(3737, quotaLimiter.getReadNumLimit()); 088 089 ugi = UserGroupInformation.createRemoteUser("my_user2"); 090 quotaLimiter = quotaCache.getUserLimiter(ugi, TableName.valueOf("my_table")); 091 assertEquals(1000, quotaLimiter.getReadNumLimit()); 092 } 093 094 @Test 095 public void testTableQuotaLookup() throws Exception { 096 QuotaCache quotaCache = 097 ThrottleQuotaTestUtil.getQuotaCaches(TEST_UTIL).stream().findAny().get(); 098 final Admin admin = TEST_UTIL.getAdmin(); 099 admin.setQuota(QuotaSettingsFactory.throttleTable(TableName.valueOf("my_table"), 100 ThrottleType.READ_NUMBER, 3737, TimeUnit.MINUTES)); 101 102 // Setting a quota and then looking it up from the cache should work, even if the cache has not 103 // refreshed 104 QuotaLimiter quotaLimiter = quotaCache.getTableLimiter(TableName.valueOf("my_table")); 105 assertEquals(3737, quotaLimiter.getReadNumLimit()); 106 107 // if no specific table quota, fall back to default 108 quotaLimiter = quotaCache.getTableLimiter(TableName.valueOf("my_table2")); 109 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 110 111 // still works after refresh 112 quotaCache.forceSynchronousCacheRefresh(); 113 quotaLimiter = quotaCache.getTableLimiter(TableName.valueOf("my_table")); 114 assertEquals(3737, quotaLimiter.getReadNumLimit()); 115 116 quotaLimiter = quotaCache.getTableLimiter(TableName.valueOf("my_table2")); 117 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 118 } 119 120 @Test 121 public void testNamespaceQuotaLookup() throws Exception { 122 QuotaCache quotaCache = 123 ThrottleQuotaTestUtil.getQuotaCaches(TEST_UTIL).stream().findAny().get(); 124 final Admin admin = TEST_UTIL.getAdmin(); 125 admin.setQuota(QuotaSettingsFactory.throttleNamespace("my_namespace", ThrottleType.READ_NUMBER, 126 3737, TimeUnit.MINUTES)); 127 128 // Setting a quota and then looking it up from the cache should work, even if the cache has not 129 // refreshed 130 QuotaLimiter quotaLimiter = quotaCache.getNamespaceLimiter("my_namespace"); 131 assertEquals(3737, quotaLimiter.getReadNumLimit()); 132 133 // if no specific namespace quota, fall back to default 134 quotaLimiter = quotaCache.getNamespaceLimiter("my_namespace2"); 135 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 136 137 // still works after refresh 138 quotaCache.forceSynchronousCacheRefresh(); 139 quotaLimiter = quotaCache.getNamespaceLimiter("my_namespace"); 140 assertEquals(3737, quotaLimiter.getReadNumLimit()); 141 142 quotaLimiter = quotaCache.getNamespaceLimiter("my_namespace2"); 143 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 144 } 145 146 @Test 147 public void testRegionServerQuotaLookup() throws Exception { 148 QuotaCache quotaCache = 149 ThrottleQuotaTestUtil.getQuotaCaches(TEST_UTIL).stream().findAny().get(); 150 final Admin admin = TEST_UTIL.getAdmin(); 151 admin.setQuota(QuotaSettingsFactory.throttleRegionServer("my_region_server", 152 ThrottleType.READ_NUMBER, 3737, TimeUnit.MINUTES)); 153 154 // Setting a quota and then looking it up from the cache should work, even if the cache has not 155 // refreshed 156 QuotaLimiter quotaLimiter = quotaCache.getRegionServerQuotaLimiter("my_region_server"); 157 assertEquals(3737, quotaLimiter.getReadNumLimit()); 158 159 // if no specific server quota, fall back to default 160 quotaLimiter = quotaCache.getRegionServerQuotaLimiter("my_region_server2"); 161 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 162 163 // still works after refresh 164 quotaCache.forceSynchronousCacheRefresh(); 165 quotaLimiter = quotaCache.getRegionServerQuotaLimiter("my_region_server"); 166 assertEquals(3737, quotaLimiter.getReadNumLimit()); 167 168 quotaLimiter = quotaCache.getRegionServerQuotaLimiter("my_region_server2"); 169 assertEquals(Long.MAX_VALUE, quotaLimiter.getReadNumLimit()); 170 } 171}