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 java.util.concurrent.atomic.AtomicLong; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.hbase.HBaseClassTestRule; 023import org.apache.hadoop.hbase.HBaseTestingUtility; 024import org.apache.hadoop.hbase.NamespaceDescriptor; 025import org.apache.hadoop.hbase.TableName; 026import org.apache.hadoop.hbase.client.Put; 027import org.apache.hadoop.hbase.testclassification.LargeTests; 028import org.apache.hadoop.hbase.util.Bytes; 029import org.junit.AfterClass; 030import org.junit.Before; 031import org.junit.BeforeClass; 032import org.junit.ClassRule; 033import org.junit.Rule; 034import org.junit.Test; 035import org.junit.experimental.categories.Category; 036import org.junit.rules.TestName; 037 038@Category(LargeTests.class) 039public class TestSpaceQuotaRemoval { 040 041 @ClassRule 042 public static final HBaseClassTestRule CLASS_RULE = 043 HBaseClassTestRule.forClass(TestSpaceQuotaRemoval.class); 044 045 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 046 047 @Rule 048 public TestName testName = new TestName(); 049 private SpaceQuotaHelperForTests helper; 050 051 @BeforeClass 052 public static void setUp() throws Exception { 053 Configuration conf = TEST_UTIL.getConfiguration(); 054 SpaceQuotaHelperForTests.updateConfigForQuotas(conf); 055 TEST_UTIL.startMiniCluster(1); 056 } 057 058 @AfterClass 059 public static void tearDown() throws Exception { 060 TEST_UTIL.shutdownMiniCluster(); 061 } 062 063 @Before 064 public void removeAllQuotas() throws Exception { 065 helper = new SpaceQuotaHelperForTests(TEST_UTIL, testName, new AtomicLong(0)); 066 helper.removeAllQuotas(); 067 } 068 069 @Test 070 public void testSetQuotaAndThenRemoveInOneWithNoInserts() throws Exception { 071 setQuotaAndThenRemoveInOneAmongTwoTables(SpaceViolationPolicy.NO_INSERTS); 072 } 073 074 @Test 075 public void testSetQuotaAndThenRemoveInOneWithNoWrite() throws Exception { 076 setQuotaAndThenRemoveInOneAmongTwoTables(SpaceViolationPolicy.NO_WRITES); 077 } 078 079 @Test 080 public void testSetQuotaAndThenRemoveInOneWithNoWritesCompaction() throws Exception { 081 setQuotaAndThenRemoveInOneAmongTwoTables(SpaceViolationPolicy.NO_WRITES_COMPACTIONS); 082 } 083 084 @Test 085 public void testSetQuotaAndThenRemoveInOneWithDisable() throws Exception { 086 setQuotaAndThenRemoveInOneAmongTwoTables(SpaceViolationPolicy.DISABLE); 087 } 088 089 @Test 090 public void testSetQuotaAndThenRemoveWithNoInserts() throws Exception { 091 setQuotaAndThenRemove(SpaceViolationPolicy.NO_INSERTS); 092 } 093 094 @Test 095 public void testSetQuotaAndThenRemoveWithNoWrite() throws Exception { 096 setQuotaAndThenRemove(SpaceViolationPolicy.NO_WRITES); 097 } 098 099 @Test 100 public void testSetQuotaAndThenRemoveWithNoWritesCompactions() throws Exception { 101 setQuotaAndThenRemove(SpaceViolationPolicy.NO_WRITES_COMPACTIONS); 102 } 103 104 @Test 105 public void testSetQuotaAndThenRemoveWithDisable() throws Exception { 106 setQuotaAndThenRemove(SpaceViolationPolicy.DISABLE); 107 } 108 109 @Test 110 public void testSetQuotaAndThenDisableIncrEnableWithNoInserts() throws Exception { 111 setQuotaNextDisableThenIncreaseFinallyEnable(SpaceViolationPolicy.NO_INSERTS); 112 } 113 114 @Test 115 public void testSetQuotaAndThenDisableIncrEnableWithNoWrite() throws Exception { 116 setQuotaNextDisableThenIncreaseFinallyEnable(SpaceViolationPolicy.NO_WRITES); 117 } 118 119 @Test 120 public void testSetQuotaAndThenDisableIncrEnableWithNoWritesCompaction() throws Exception { 121 setQuotaNextDisableThenIncreaseFinallyEnable(SpaceViolationPolicy.NO_WRITES_COMPACTIONS); 122 } 123 124 @Test 125 public void testSetQuotaAndThenDisableIncrEnableWithDisable() throws Exception { 126 setQuotaNextDisableThenIncreaseFinallyEnable(SpaceViolationPolicy.DISABLE); 127 } 128 129 private void setQuotaAndThenRemove(SpaceViolationPolicy policy) throws Exception { 130 Put put = new Put(Bytes.toBytes("to_reject")); 131 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 132 Bytes.toBytes("reject")); 133 134 // Do puts until we violate space policy 135 final TableName tn = helper.writeUntilViolationAndVerifyViolation(policy, put); 136 137 // Now, remove the quota 138 helper.removeQuotaFromtable(tn); 139 140 // Put some rows now: should not violate as quota settings removed 141 helper.verifyNoViolation(tn, put); 142 } 143 144 @Test 145 public void testDeleteTableUsageSnapshotsForNamespace() throws Exception { 146 Put put = new Put(Bytes.toBytes("to_reject")); 147 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 148 Bytes.toBytes("reject")); 149 150 SpaceViolationPolicy policy = SpaceViolationPolicy.NO_INSERTS; 151 152 // Create a namespace 153 String ns1 = "nsnew"; 154 NamespaceDescriptor nsd = helper.createNamespace(ns1); 155 156 // Create 2nd namespace with name similar to ns1 157 String ns2 = ns1 + "test"; 158 NamespaceDescriptor nsd2 = helper.createNamespace(ns2); 159 160 // Do puts until we violate space policy on table tn1 in namesapce ns1 161 final TableName tn1 = helper.writeUntilViolationAndVerifyViolationInNamespace(ns1, policy, put); 162 163 // Do puts until we violate space policy on table tn2 in namespace ns2 164 final TableName tn2 = helper.writeUntilViolationAndVerifyViolationInNamespace(ns2, policy, put); 165 166 // Now, remove the quota from namespace ns1 which will remove table usage snapshots for ns1 167 helper.removeQuotaFromNamespace(ns1); 168 169 // Verify that table usage snapshot for table tn2 in namespace ns2 exist 170 helper.verifyTableUsageSnapshotForSpaceQuotaExist(tn2); 171 172 // Put a new row on tn2: should violate as space quota exists on namespace ns2 173 helper.verifyViolation(policy, tn2, put); 174 175 // Put a new row on tn1: should not violate as quota settings removed from namespace ns1 176 helper.verifyNoViolation(tn1, put); 177 } 178 179 @Test 180 public void testSetNamespaceSizeQuotaAndThenRemove() throws Exception { 181 Put put = new Put(Bytes.toBytes("to_reject")); 182 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 183 Bytes.toBytes("reject")); 184 185 SpaceViolationPolicy policy = SpaceViolationPolicy.NO_INSERTS; 186 187 // Create namespace 188 NamespaceDescriptor nsd = helper.createNamespace(); 189 String ns = nsd.getName(); 190 191 // Do puts until we violate space policy on table tn1 192 final TableName tn1 = helper.writeUntilViolationAndVerifyViolationInNamespace(ns, policy, put); 193 194 // Now, remove the quota from namespace 195 helper.removeQuotaFromNamespace(ns); 196 197 // Put a new row now on tn1: should not violate as quota settings removed from namespace 198 helper.verifyNoViolation(tn1, put); 199 } 200 201 private void setQuotaAndThenRemoveInOneAmongTwoTables(SpaceViolationPolicy policy) 202 throws Exception { 203 Put put = new Put(Bytes.toBytes("to_reject")); 204 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 205 Bytes.toBytes("reject")); 206 207 // Do puts until we violate space policy on table tn1 208 final TableName tn1 = helper.writeUntilViolationAndVerifyViolation(policy, put); 209 210 // Do puts until we violate space policy on table tn2 211 final TableName tn2 = helper.writeUntilViolationAndVerifyViolation(policy, put); 212 213 // Now, remove the quota from table tn1 214 helper.removeQuotaFromtable(tn1); 215 216 // Put a new row now on tn1: should not violate as quota settings removed 217 helper.verifyNoViolation(tn1, put); 218 // Put a new row now on tn2: should violate as quota settings exists 219 helper.verifyViolation(policy, tn2, put); 220 } 221 222 private void setQuotaNextDisableThenIncreaseFinallyEnable(SpaceViolationPolicy policy) 223 throws Exception { 224 Put put = new Put(Bytes.toBytes("to_reject")); 225 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 226 Bytes.toBytes("reject")); 227 228 // Do puts until we violate space policy 229 final TableName tn = helper.writeUntilViolationAndVerifyViolation(policy, put); 230 231 // Disable the table; in case of SpaceViolationPolicy.DISABLE already disabled 232 if (!policy.equals(SpaceViolationPolicy.DISABLE)) { 233 TEST_UTIL.getAdmin().disableTable(tn); 234 TEST_UTIL.waitTableDisabled(tn, 10000); 235 } 236 237 // Now, increase limit and perform put 238 helper.setQuotaLimit(tn, policy, 4L); 239 240 // in case of disable policy quota manager will enable it 241 if (!policy.equals(SpaceViolationPolicy.DISABLE)) { 242 TEST_UTIL.getAdmin().enableTable(tn); 243 } 244 TEST_UTIL.waitTableEnabled(tn, 10000); 245 246 // Put some row now: should not violate as quota limit increased 247 helper.verifyNoViolation(tn, put); 248 } 249}