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 * http://www.apache.org/licenses/LICENSE-2.0 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.apache.hadoop.hbase.quotas; 017 018import java.util.List; 019import java.util.Map; 020import java.util.concurrent.atomic.AtomicLong; 021 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.hbase.HBaseClassTestRule; 024import org.apache.hadoop.hbase.HBaseTestingUtility; 025import org.apache.hadoop.hbase.MetaTableAccessor; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.Waiter; 028import org.apache.hadoop.hbase.client.Put; 029import org.apache.hadoop.hbase.client.RegionInfo; 030import org.apache.hadoop.hbase.master.HMaster; 031import org.apache.hadoop.hbase.testclassification.LargeTests; 032import org.apache.hadoop.hbase.util.Bytes; 033import org.junit.AfterClass; 034import org.junit.Assert; 035import org.junit.Before; 036import org.junit.BeforeClass; 037import org.junit.ClassRule; 038import org.junit.Rule; 039import org.junit.Test; 040import org.junit.experimental.categories.Category; 041import org.junit.rules.TestName; 042import org.slf4j.Logger; 043import org.slf4j.LoggerFactory; 044 045@Category(LargeTests.class) 046public class TestSpaceQuotaDropTable { 047 048 @ClassRule 049 public static final HBaseClassTestRule CLASS_RULE = 050 HBaseClassTestRule.forClass(TestSpaceQuotaDropTable.class); 051 052 private static final Logger LOG = LoggerFactory.getLogger(TestSpaceQuotaDropTable.class); 053 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 054 055 @Rule 056 public TestName testName = new TestName(); 057 private SpaceQuotaHelperForTests helper; 058 059 @BeforeClass 060 public static void setUp() throws Exception { 061 Configuration conf = TEST_UTIL.getConfiguration(); 062 SpaceQuotaHelperForTests.updateConfigForQuotas(conf); 063 TEST_UTIL.startMiniCluster(1); 064 } 065 066 @AfterClass 067 public static void tearDown() throws Exception { 068 TEST_UTIL.shutdownMiniCluster(); 069 } 070 071 @Before 072 public void removeAllQuotas() throws Exception { 073 helper = new SpaceQuotaHelperForTests(TEST_UTIL, testName, new AtomicLong(0)); 074 helper.removeAllQuotas(); 075 } 076 077 @Test 078 public void testSetQuotaAndThenDropTableWithNoInserts() throws Exception { 079 setQuotaAndThenDropTable(SpaceViolationPolicy.NO_INSERTS); 080 } 081 082 @Test 083 public void testSetQuotaAndThenDropTableWithNoWrite() throws Exception { 084 setQuotaAndThenDropTable(SpaceViolationPolicy.NO_WRITES); 085 } 086 087 @Test 088 public void testSetQuotaAndThenDropTableWithNoWritesCompactions() throws Exception { 089 setQuotaAndThenDropTable(SpaceViolationPolicy.NO_WRITES_COMPACTIONS); 090 } 091 092 @Test 093 public void testSetQuotaAndThenDropTableWithDisable() throws Exception { 094 setQuotaAndThenDropTable(SpaceViolationPolicy.DISABLE); 095 } 096 097 @Test 098 public void testSetQuotaAndThenDropTableWithRegionReport() throws Exception { 099 final TableName tn = helper.createTable(); 100 helper.setQuotaLimit(tn, SpaceViolationPolicy.NO_INSERTS, 1L); 101 helper.writeData(tn, 2L); 102 103 final HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster(); 104 final MasterQuotaManager quotaManager = master.getMasterQuotaManager(); 105 106 // Make sure the master has report for the table. 107 Waiter.waitFor(TEST_UTIL.getConfiguration(), 30 * 1000, new Waiter.Predicate<Exception>() { 108 @Override 109 public boolean evaluate() throws Exception { 110 Map<RegionInfo, Long> regionSizes = quotaManager.snapshotRegionSizes(); 111 List<RegionInfo> tableRegions = 112 MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn); 113 return regionSizes.containsKey(tableRegions.get(0)); 114 } 115 }); 116 117 boolean hasRegionSize = false; 118 119 // region report should be present before dropping the table. 120 for (Map.Entry<RegionInfo, Long> entry : quotaManager.snapshotRegionSizes().entrySet()) { 121 if (entry.getKey().getTable().equals(tn)) { 122 hasRegionSize = true; 123 break; 124 } 125 } 126 127 // regionSize report for the given table should be present before dropping the table. 128 Assert.assertTrue(hasRegionSize); 129 130 // drop the table 131 TEST_UTIL.getAdmin().disableTable(tn); 132 TEST_UTIL.getAdmin().deleteTable(tn); 133 134 // check if deleted table region report still present in the map. 135 for (Map.Entry<RegionInfo, Long> entry : quotaManager.snapshotRegionSizes().entrySet()) { 136 if (entry.getKey().getTable().equals(tn)) { 137 Assert.fail("Dropped table regionSizes were not deleted during the drop command"); 138 } 139 } 140 } 141 142 private void setQuotaAndThenDropTable(SpaceViolationPolicy policy) throws Exception { 143 Put put = new Put(Bytes.toBytes("to_reject")); 144 put.addColumn(Bytes.toBytes(SpaceQuotaHelperForTests.F1), Bytes.toBytes("to"), 145 Bytes.toBytes("reject")); 146 147 // Do puts until we violate space policy 148 final TableName tn = helper.writeUntilViolationAndVerifyViolation(policy, put); 149 150 // Now, drop the table 151 TEST_UTIL.deleteTable(tn); 152 LOG.debug("Successfully deleted table ", tn); 153 154 // Now re-create the table 155 TEST_UTIL.createTable(tn, Bytes.toBytes(SpaceQuotaHelperForTests.F1)); 156 LOG.debug("Successfully re-created table ", tn); 157 158 // Put some rows now: should not violate as table/quota was dropped 159 helper.verifyNoViolation(tn, put); 160 } 161}