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.master; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021 022import java.util.concurrent.atomic.AtomicBoolean; 023import java.util.concurrent.atomic.AtomicInteger; 024import org.apache.hadoop.hbase.HBaseTestingUtil; 025import org.apache.hadoop.hbase.HConstants; 026import org.apache.hadoop.hbase.ServerName; 027import org.apache.hadoop.hbase.SingleProcessHBaseCluster; 028import org.apache.hadoop.hbase.StartTestingClusterOption; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 031import org.apache.hadoop.hbase.client.TableDescriptor; 032import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 033import org.apache.hadoop.hbase.master.hbck.HbckChore; 034import org.apache.hadoop.hbase.master.hbck.HbckReport; 035import org.apache.hadoop.hbase.regionserver.HRegion; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.junit.jupiter.api.BeforeEach; 038import org.junit.jupiter.api.Test; 039import org.junit.jupiter.api.TestInfo; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; 044 045public abstract class AbstractTestMasterRegionMutation { 046 047 private static final Logger LOG = LoggerFactory.getLogger(AbstractTestMasterRegionMutation.class); 048 049 protected static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 050 protected static ServerName rs0; 051 052 protected static final AtomicBoolean ERROR_OUT = new AtomicBoolean(false); 053 protected static final AtomicInteger ERROR_COUNTER = new AtomicInteger(0); 054 protected static final AtomicBoolean FIRST_TIME_ERROR = new AtomicBoolean(true); 055 056 protected static void setUpBeforeClass(int numMasters, Class<? extends HRegion> regionImplClass) 057 throws Exception { 058 TEST_UTIL.getConfiguration().setClass(HConstants.REGION_IMPL, regionImplClass, HRegion.class); 059 StartTestingClusterOption.Builder builder = StartTestingClusterOption.builder(); 060 builder.numMasters(numMasters).numRegionServers(3); 061 TEST_UTIL.startMiniCluster(builder.build()); 062 SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); 063 rs0 = cluster.getRegionServer(0).getServerName(); 064 TEST_UTIL.getAdmin().balancerSwitch(false, true); 065 } 066 067 protected static void tearDownAfterClass() throws Exception { 068 TEST_UTIL.shutdownMiniCluster(); 069 } 070 071 @BeforeEach 072 protected void setUp(TestInfo testInfo) throws Exception { 073 TableName tableName = TableName.valueOf(testInfo.getTestMethod().orElseThrow().getName()); 074 TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(tableName) 075 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build(); 076 int startKey = 0; 077 int endKey = 80000; 078 TEST_UTIL.getAdmin().createTable(tableDesc, Bytes.toBytes(startKey), Bytes.toBytes(endKey), 9); 079 } 080 081 @Test 082 protected void testMasterRegionMutations() throws Exception { 083 HbckChore hbckChore = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster()); 084 SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); 085 086 int numRegions0 = cluster.getRegionServer(0).getNumberOfOnlineRegions(); 087 int numRegions1 = cluster.getRegionServer(1).getNumberOfOnlineRegions(); 088 int numRegions2 = cluster.getRegionServer(2).getNumberOfOnlineRegions(); 089 090 hbckChore.choreForTesting(); 091 HbckReport hbckReport = hbckChore.getLastReport(); 092 assertEquals(0, hbckReport.getInconsistentRegions().size()); 093 assertEquals(0, hbckReport.getOrphanRegionsOnFS().size()); 094 assertEquals(0, hbckReport.getOrphanRegionsOnRS().size()); 095 096 ERROR_OUT.set(true); 097 TEST_UTIL.getAdmin().move( 098 cluster.getRegionServer(1).getRegions().get(0).getRegionInfo().getEncodedNameAsBytes(), rs0); 099 100 ERROR_OUT.set(true); 101 TEST_UTIL.getAdmin().move( 102 cluster.getRegionServer(2).getRegions().get(0).getRegionInfo().getEncodedNameAsBytes(), rs0); 103 104 HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); 105 106 TEST_UTIL.waitFor(5000, 1000, () -> { 107 LOG.info("numRegions0: {} , numRegions1: {} , numRegions2: {}", numRegions0, numRegions1, 108 numRegions2); 109 LOG.info("Online regions - server0 : {} , server1: {} , server2: {}", 110 cluster.getRegionServer(0).getNumberOfOnlineRegions(), 111 cluster.getRegionServer(1).getNumberOfOnlineRegions(), 112 cluster.getRegionServer(2).getNumberOfOnlineRegions()); 113 LOG.info("Num of successfully completed procedures: {} , num of all procedures: {}", 114 master.getMasterProcedureExecutor().getProcedures().stream() 115 .filter(masterProcedureEnvProcedure -> masterProcedureEnvProcedure.getState() 116 == ProcedureProtos.ProcedureState.SUCCESS) 117 .count(), 118 master.getMasterProcedureExecutor().getProcedures().size()); 119 return (numRegions0 + numRegions1 + numRegions2) 120 == (cluster.getRegionServer(0).getNumberOfOnlineRegions() 121 + cluster.getRegionServer(1).getNumberOfOnlineRegions() 122 + cluster.getRegionServer(2).getNumberOfOnlineRegions()) 123 && master.getMasterProcedureExecutor().getProcedures().stream() 124 .filter(masterProcedureEnvProcedure -> masterProcedureEnvProcedure.getState() 125 == ProcedureProtos.ProcedureState.SUCCESS) 126 .count() == master.getMasterProcedureExecutor().getProcedures().size(); 127 }); 128 129 TEST_UTIL.waitFor(5000, 1000, () -> { 130 HbckChore hbck = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster()); 131 hbck.choreForTesting(); 132 HbckReport report = hbck.getLastReport(); 133 return report.getInconsistentRegions().isEmpty() && report.getOrphanRegionsOnFS().isEmpty() 134 && report.getOrphanRegionsOnRS().isEmpty(); 135 }); 136 } 137}