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