HBASE-26416 Implement a new method for region replication instead of using replay...
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / quotas / TestQuotaState.java
blob4c359f0d1bc87bf2431544f48e569231e0bc4a7e
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.quotas;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
25 import java.util.concurrent.TimeUnit;
26 import org.apache.hadoop.hbase.HBaseClassTestRule;
27 import org.apache.hadoop.hbase.TableName;
28 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
29 import org.apache.hadoop.hbase.testclassification.SmallTests;
30 import org.junit.ClassRule;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.experimental.categories.Category;
34 import org.junit.rules.TestName;
36 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
37 import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
38 import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Throttle;
40 @Category({RegionServerTests.class, SmallTests.class})
41 public class TestQuotaState {
43 @ClassRule
44 public static final HBaseClassTestRule CLASS_RULE =
45 HBaseClassTestRule.forClass(TestQuotaState.class);
47 private static final TableName UNKNOWN_TABLE_NAME = TableName.valueOf("unknownTable");
49 @Rule
50 public TestName name = new TestName();
52 @Test
53 public void testQuotaStateBypass() {
54 QuotaState quotaInfo = new QuotaState();
55 assertTrue(quotaInfo.isBypass());
56 assertNoopLimiter(quotaInfo.getGlobalLimiter());
58 UserQuotaState userQuotaState = new UserQuotaState();
59 assertTrue(userQuotaState.isBypass());
60 assertNoopLimiter(userQuotaState.getTableLimiter(UNKNOWN_TABLE_NAME));
63 @Test
64 public void testSimpleQuotaStateOperation() {
65 final TableName tableName = TableName.valueOf(name.getMethodName());
66 final int NUM_GLOBAL_THROTTLE = 3;
67 final int NUM_TABLE_THROTTLE = 2;
69 UserQuotaState quotaInfo = new UserQuotaState();
70 assertTrue(quotaInfo.isBypass());
72 // Set global quota
73 quotaInfo.setQuotas(buildReqNumThrottle(NUM_GLOBAL_THROTTLE));
74 assertFalse(quotaInfo.isBypass());
76 // Set table quota
77 quotaInfo.setQuotas(tableName, buildReqNumThrottle(NUM_TABLE_THROTTLE));
78 assertFalse(quotaInfo.isBypass());
79 assertTrue(quotaInfo.getGlobalLimiter() == quotaInfo.getTableLimiter(UNKNOWN_TABLE_NAME));
80 assertThrottleException(quotaInfo.getTableLimiter(UNKNOWN_TABLE_NAME), NUM_GLOBAL_THROTTLE);
81 assertThrottleException(quotaInfo.getTableLimiter(tableName), NUM_TABLE_THROTTLE);
84 @Test
85 public void testQuotaStateUpdateBypassThrottle() {
86 final long LAST_UPDATE = 10;
88 UserQuotaState quotaInfo = new UserQuotaState();
89 assertEquals(0, quotaInfo.getLastUpdate());
90 assertTrue(quotaInfo.isBypass());
92 UserQuotaState otherQuotaState = new UserQuotaState(LAST_UPDATE);
93 assertEquals(LAST_UPDATE, otherQuotaState.getLastUpdate());
94 assertTrue(otherQuotaState.isBypass());
96 quotaInfo.update(otherQuotaState);
97 assertEquals(LAST_UPDATE, quotaInfo.getLastUpdate());
98 assertTrue(quotaInfo.isBypass());
99 assertTrue(quotaInfo.getGlobalLimiter() == quotaInfo.getTableLimiter(UNKNOWN_TABLE_NAME));
100 assertNoopLimiter(quotaInfo.getTableLimiter(UNKNOWN_TABLE_NAME));
103 @Test
104 public void testQuotaStateUpdateGlobalThrottle() {
105 final int NUM_GLOBAL_THROTTLE_1 = 3;
106 final int NUM_GLOBAL_THROTTLE_2 = 11;
107 final long LAST_UPDATE_1 = 10;
108 final long LAST_UPDATE_2 = 20;
109 final long LAST_UPDATE_3 = 30;
111 QuotaState quotaInfo = new QuotaState();
112 assertEquals(0, quotaInfo.getLastUpdate());
113 assertTrue(quotaInfo.isBypass());
115 // Add global throttle
116 QuotaState otherQuotaState = new QuotaState(LAST_UPDATE_1);
117 otherQuotaState.setQuotas(buildReqNumThrottle(NUM_GLOBAL_THROTTLE_1));
118 assertEquals(LAST_UPDATE_1, otherQuotaState.getLastUpdate());
119 assertFalse(otherQuotaState.isBypass());
121 quotaInfo.update(otherQuotaState);
122 assertEquals(LAST_UPDATE_1, quotaInfo.getLastUpdate());
123 assertFalse(quotaInfo.isBypass());
124 assertThrottleException(quotaInfo.getGlobalLimiter(), NUM_GLOBAL_THROTTLE_1);
126 // Update global Throttle
127 otherQuotaState = new QuotaState(LAST_UPDATE_2);
128 otherQuotaState.setQuotas(buildReqNumThrottle(NUM_GLOBAL_THROTTLE_2));
129 assertEquals(LAST_UPDATE_2, otherQuotaState.getLastUpdate());
130 assertFalse(otherQuotaState.isBypass());
132 quotaInfo.update(otherQuotaState);
133 assertEquals(LAST_UPDATE_2, quotaInfo.getLastUpdate());
134 assertFalse(quotaInfo.isBypass());
135 assertThrottleException(quotaInfo.getGlobalLimiter(),
136 NUM_GLOBAL_THROTTLE_2 - NUM_GLOBAL_THROTTLE_1);
138 // Remove global throttle
139 otherQuotaState = new QuotaState(LAST_UPDATE_3);
140 assertEquals(LAST_UPDATE_3, otherQuotaState.getLastUpdate());
141 assertTrue(otherQuotaState.isBypass());
143 quotaInfo.update(otherQuotaState);
144 assertEquals(LAST_UPDATE_3, quotaInfo.getLastUpdate());
145 assertTrue(quotaInfo.isBypass());
146 assertNoopLimiter(quotaInfo.getGlobalLimiter());
149 @Test
150 public void testQuotaStateUpdateTableThrottle() {
151 final TableName tableNameA = TableName.valueOf(name.getMethodName() + "A");
152 final TableName tableNameB = TableName.valueOf(name.getMethodName() + "B");
153 final TableName tableNameC = TableName.valueOf(name.getMethodName() + "C");
154 final int TABLE_A_THROTTLE_1 = 3;
155 final int TABLE_A_THROTTLE_2 = 11;
156 final int TABLE_B_THROTTLE = 4;
157 final int TABLE_C_THROTTLE = 5;
158 final long LAST_UPDATE_1 = 10;
159 final long LAST_UPDATE_2 = 20;
160 final long LAST_UPDATE_3 = 30;
162 UserQuotaState quotaInfo = new UserQuotaState();
163 assertEquals(0, quotaInfo.getLastUpdate());
164 assertTrue(quotaInfo.isBypass());
166 // Add A B table limiters
167 UserQuotaState otherQuotaState = new UserQuotaState(LAST_UPDATE_1);
168 otherQuotaState.setQuotas(tableNameA, buildReqNumThrottle(TABLE_A_THROTTLE_1));
169 otherQuotaState.setQuotas(tableNameB, buildReqNumThrottle(TABLE_B_THROTTLE));
170 assertEquals(LAST_UPDATE_1, otherQuotaState.getLastUpdate());
171 assertFalse(otherQuotaState.isBypass());
173 quotaInfo.update(otherQuotaState);
174 assertEquals(LAST_UPDATE_1, quotaInfo.getLastUpdate());
175 assertFalse(quotaInfo.isBypass());
176 assertThrottleException(quotaInfo.getTableLimiter(tableNameA), TABLE_A_THROTTLE_1);
177 assertThrottleException(quotaInfo.getTableLimiter(tableNameB), TABLE_B_THROTTLE);
178 assertNoopLimiter(quotaInfo.getTableLimiter(tableNameC));
180 // Add C, Remove B, Update A table limiters
181 otherQuotaState = new UserQuotaState(LAST_UPDATE_2);
182 otherQuotaState.setQuotas(tableNameA, buildReqNumThrottle(TABLE_A_THROTTLE_2));
183 otherQuotaState.setQuotas(tableNameC, buildReqNumThrottle(TABLE_C_THROTTLE));
184 assertEquals(LAST_UPDATE_2, otherQuotaState.getLastUpdate());
185 assertFalse(otherQuotaState.isBypass());
187 quotaInfo.update(otherQuotaState);
188 assertEquals(LAST_UPDATE_2, quotaInfo.getLastUpdate());
189 assertFalse(quotaInfo.isBypass());
190 assertThrottleException(quotaInfo.getTableLimiter(tableNameA),
191 TABLE_A_THROTTLE_2 - TABLE_A_THROTTLE_1);
192 assertThrottleException(quotaInfo.getTableLimiter(tableNameC), TABLE_C_THROTTLE);
193 assertNoopLimiter(quotaInfo.getTableLimiter(tableNameB));
195 // Remove table limiters
196 otherQuotaState = new UserQuotaState(LAST_UPDATE_3);
197 assertEquals(LAST_UPDATE_3, otherQuotaState.getLastUpdate());
198 assertTrue(otherQuotaState.isBypass());
200 quotaInfo.update(otherQuotaState);
201 assertEquals(LAST_UPDATE_3, quotaInfo.getLastUpdate());
202 assertTrue(quotaInfo.isBypass());
203 assertNoopLimiter(quotaInfo.getTableLimiter(UNKNOWN_TABLE_NAME));
206 @Test
207 public void testTableThrottleWithBatch() {
208 final TableName TABLE_A = TableName.valueOf("TableA");
209 final int TABLE_A_THROTTLE_1 = 3;
210 final long LAST_UPDATE_1 = 10;
212 UserQuotaState quotaInfo = new UserQuotaState();
213 assertEquals(0, quotaInfo.getLastUpdate());
214 assertTrue(quotaInfo.isBypass());
216 // Add A table limiters
217 UserQuotaState otherQuotaState = new UserQuotaState(LAST_UPDATE_1);
218 otherQuotaState.setQuotas(TABLE_A, buildReqNumThrottle(TABLE_A_THROTTLE_1));
219 assertEquals(LAST_UPDATE_1, otherQuotaState.getLastUpdate());
220 assertFalse(otherQuotaState.isBypass());
222 quotaInfo.update(otherQuotaState);
223 assertEquals(LAST_UPDATE_1, quotaInfo.getLastUpdate());
224 assertFalse(quotaInfo.isBypass());
225 QuotaLimiter limiter = quotaInfo.getTableLimiter(TABLE_A);
226 try {
227 limiter.checkQuota(TABLE_A_THROTTLE_1 + 1, TABLE_A_THROTTLE_1 + 1, 0, 0, 1, 0);
228 fail("Should have thrown RpcThrottlingException");
229 } catch (RpcThrottlingException e) {
230 // expected
234 private Quotas buildReqNumThrottle(final long limit) {
235 return Quotas.newBuilder()
236 .setThrottle(Throttle.newBuilder()
237 .setReqNum(ProtobufUtil.toTimedQuota(limit, TimeUnit.MINUTES, QuotaScope.MACHINE))
238 .build())
239 .build();
242 private void assertThrottleException(final QuotaLimiter limiter, final int availReqs) {
243 assertNoThrottleException(limiter, availReqs);
244 try {
245 limiter.checkQuota(1, 1, 0, 0, 1, 0);
246 fail("Should have thrown RpcThrottlingException");
247 } catch (RpcThrottlingException e) {
248 // expected
252 private void assertNoThrottleException(final QuotaLimiter limiter, final int availReqs) {
253 for (int i = 0; i < availReqs; ++i) {
254 try {
255 limiter.checkQuota(1, 1, 0, 0, 1, 0);
256 } catch (RpcThrottlingException e) {
257 fail("Unexpected RpcThrottlingException after " + i + " requests. limit=" + availReqs);
259 limiter.grabQuota(1, 1, 0, 0, 1, 0);
263 private void assertNoopLimiter(final QuotaLimiter limiter) {
264 assertTrue(limiter == NoopQuotaLimiter.get());
265 assertNoThrottleException(limiter, 100);