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