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
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.concurrent.TimeUnit;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.hbase.HBaseTestingUtility;
26 import org.apache.hadoop.hbase.HConstants;
27 import org.apache.hadoop.hbase.TableName;
28 import org.apache.hadoop.hbase.client.Connection;
29 import org.apache.hadoop.hbase.client.ConnectionFactory;
30 import org.apache.hadoop.hbase.client.Put;
31 import org.apache.hadoop.hbase.client.Result;
32 import org.apache.hadoop.hbase.client.ResultScanner;
33 import org.apache.hadoop.hbase.client.Table;
34 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
35 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
36 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Throttle;
37 import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot.SpaceQuotaStatus;
38 import org.apache.hadoop.hbase.testclassification.MediumTests;
39 import org.junit.After;
40 import org.junit.AfterClass;
41 import org.junit.Before;
42 import org.junit.BeforeClass;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.experimental.categories.Category;
46 import org.junit.rules.TestName;
47
48
49
50
51 @Category({ MediumTests.class })
52 public class TestQuotaTableUtil {
53 final Log LOG = LogFactory.getLog(getClass());
54
55 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
56 private Connection connection;
57 private int tableNameCounter;
58
59 @Rule
60 public TestName testName = new TestName();
61
62 @BeforeClass
63 public static void setUpBeforeClass() throws Exception {
64 TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
65 TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, 2000);
66 TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
67 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
68 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
69 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
70 TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
71 TEST_UTIL.startMiniCluster(1);
72 TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
73 }
74
75 @AfterClass
76 public static void tearDownAfterClass() throws Exception {
77 TEST_UTIL.shutdownMiniCluster();
78 }
79
80 @Before
81 public void before() throws IOException {
82 this.connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
83 this.tableNameCounter = 0;
84 }
85
86 @After
87 public void after() throws IOException {
88 this.connection.close();
89 }
90
91 @Test
92 public void testTableQuotaUtil() throws Exception {
93 final TableName table = TableName.valueOf("testTableQuotaUtilTable");
94
95 Quotas quota =
96 Quotas
97 .newBuilder()
98 .setThrottle(
99 Throttle
100 .newBuilder()
101 .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
102 .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
103 .setReadSize(
104 ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
105 .build();
106
107
108 QuotaUtil.addTableQuota(this.connection, table, quota);
109 Quotas resQuota = QuotaUtil.getTableQuota(this.connection, table);
110 assertEquals(quota, resQuota);
111
112
113 QuotaUtil.deleteTableQuota(this.connection, table);
114 resQuota = QuotaUtil.getTableQuota(this.connection, table);
115 assertEquals(null, resQuota);
116 }
117
118 @Test
119 public void testNamespaceQuotaUtil() throws Exception {
120 final String namespace = "testNamespaceQuotaUtilNS";
121
122 Quotas quota =
123 Quotas
124 .newBuilder()
125 .setThrottle(
126 Throttle
127 .newBuilder()
128 .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
129 .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
130 .setReadSize(
131 ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
132 .build();
133
134
135 QuotaUtil.addNamespaceQuota(this.connection, namespace, quota);
136 Quotas resQuota = QuotaUtil.getNamespaceQuota(this.connection, namespace);
137 assertEquals(quota, resQuota);
138
139
140 QuotaUtil.deleteNamespaceQuota(this.connection, namespace);
141 resQuota = QuotaUtil.getNamespaceQuota(this.connection, namespace);
142 assertEquals(null, resQuota);
143 }
144
145 @Test
146 public void testUserQuotaUtil() throws Exception {
147 final TableName table = TableName.valueOf("testUserQuotaUtilTable");
148 final String namespace = "testNS";
149 final String user = "testUser";
150
151 Quotas quotaNamespace =
152 Quotas
153 .newBuilder()
154 .setThrottle(
155 Throttle
156 .newBuilder()
157 .setReqNum(ProtobufUtil.toTimedQuota(50000, TimeUnit.SECONDS, QuotaScope.MACHINE))
158 .build()).build();
159 Quotas quotaTable =
160 Quotas
161 .newBuilder()
162 .setThrottle(
163 Throttle
164 .newBuilder()
165 .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
166 .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
167 .setReadSize(
168 ProtobufUtil.toTimedQuota(10000, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
169 .build();
170 Quotas quota =
171 Quotas
172 .newBuilder()
173 .setThrottle(
174 Throttle
175 .newBuilder()
176 .setReqSize(ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE))
177 .setWriteSize(
178 ProtobufUtil.toTimedQuota(4096, TimeUnit.SECONDS, QuotaScope.MACHINE))
179 .setReadNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
180 .build()).build();
181
182
183 QuotaUtil.addUserQuota(this.connection, user, quota);
184 Quotas resQuota = QuotaUtil.getUserQuota(this.connection, user);
185 assertEquals(quota, resQuota);
186
187
188 QuotaUtil.addUserQuota(this.connection, user, table, quotaTable);
189 Quotas resQuotaTable = QuotaUtil.getUserQuota(this.connection, user, table);
190 assertEquals(quotaTable, resQuotaTable);
191
192
193 QuotaUtil.addUserQuota(this.connection, user, namespace, quotaNamespace);
194 Quotas resQuotaNS = QuotaUtil.getUserQuota(this.connection, user, namespace);
195 assertEquals(quotaNamespace, resQuotaNS);
196
197
198 QuotaUtil.deleteUserQuota(this.connection, user);
199 resQuota = QuotaUtil.getUserQuota(this.connection, user);
200 assertEquals(null, resQuota);
201
202
203 QuotaUtil.deleteUserQuota(this.connection, user, table);
204 resQuotaTable = QuotaUtil.getUserQuota(this.connection, user, table);
205 assertEquals(null, resQuotaTable);
206
207
208 QuotaUtil.deleteUserQuota(this.connection, user, namespace);
209 resQuotaNS = QuotaUtil.getUserQuota(this.connection, user, namespace);
210 assertEquals(null, resQuotaNS);
211 }
212
213 @Test
214 public void testSerDeViolationPolicies() throws Exception {
215 final TableName tn1 = getUniqueTableName();
216 final SpaceQuotaSnapshot violation1 = new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.DISABLE), 512L, 1024L);
217 final TableName tn2 = getUniqueTableName();
218 final SpaceQuotaSnapshot violation2 = new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.NO_INSERTS), 512L, 1024L);
219 final TableName tn3 = getUniqueTableName();
220 final SpaceQuotaSnapshot violation3 = new SpaceQuotaSnapshot(new SpaceQuotaStatus(SpaceViolationPolicy.NO_WRITES), 512L, 1024L);
221 List<Put> puts = new ArrayList<>();
222 puts.add(QuotaTableUtil.putSpaceSnapshot(tn1, violation1));
223 puts.add(QuotaTableUtil.putSpaceSnapshot(tn2, violation2));
224 puts.add(QuotaTableUtil.putSpaceSnapshot(tn3, violation3));
225 final Map<TableName,SpaceQuotaSnapshot> expectedPolicies = new HashMap<>();
226 expectedPolicies.put(tn1, violation1);
227 expectedPolicies.put(tn2, violation2);
228 expectedPolicies.put(tn3, violation3);
229
230 final Map<TableName,SpaceQuotaSnapshot> actualPolicies = new HashMap<>();
231 try (Table quotaTable = connection.getTable(QuotaUtil.QUOTA_TABLE_NAME)) {
232 quotaTable.put(puts);
233 ResultScanner scanner = quotaTable.getScanner(QuotaTableUtil.makeQuotaSnapshotScan());
234 for (Result r : scanner) {
235 QuotaTableUtil.extractQuotaSnapshot(r, actualPolicies);
236 }
237 scanner.close();
238 }
239
240 assertEquals(expectedPolicies, actualPolicies);
241 }
242
243 private TableName getUniqueTableName() {
244 return TableName.valueOf(testName.getMethodName() + "_" + tableNameCounter++);
245 }
246 }