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.procedure; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import org.apache.hadoop.hbase.HBaseTestingUtil; 024import org.apache.hadoop.hbase.ServerName; 025import org.apache.hadoop.hbase.TableName; 026import org.apache.hadoop.hbase.client.RegionInfo; 027import org.apache.hadoop.hbase.client.Table; 028import org.apache.hadoop.hbase.master.HMaster; 029import org.apache.hadoop.hbase.master.assignment.AssignmentTestingUtil; 030import org.apache.hadoop.hbase.procedure2.Procedure; 031import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 032import org.apache.hadoop.hbase.testclassification.LargeTests; 033import org.apache.hadoop.hbase.testclassification.MasterTests; 034import org.junit.jupiter.api.Tag; 035import org.junit.jupiter.api.Test; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039@Tag(MasterTests.TAG) 040@Tag(LargeTests.TAG) 041public class TestSCP extends TestSCPBase { 042 043 private static final Logger LOG = LoggerFactory.getLogger(TestSCP.class); 044 045 @Test 046 public void testCrashTargetRs() throws Exception { 047 testRecoveryAndDoubleExecution(false, false); 048 } 049 050 @Test 051 public void testConcurrentSCPForSameServer() throws Exception { 052 final TableName tableName = TableName.valueOf("testConcurrentSCPForSameServer"); 053 try (Table t = createTable(tableName)) { 054 // Load the table with a bit of data so some logs to split and some edits in each region. 055 this.util.loadTable(t, HBaseTestingUtil.COLUMNS[0]); 056 final int count = HBaseTestingUtil.countRows(t); 057 assertTrue(count > 0, "expected some rows"); 058 // find the first server that match the request and executes the test 059 ServerName rsToKill = null; 060 for (RegionInfo hri : util.getAdmin().getRegions(tableName)) { 061 final ServerName serverName = AssignmentTestingUtil.getServerHoldingRegion(util, hri); 062 if (AssignmentTestingUtil.isServerHoldingMeta(util, serverName) == true) { 063 rsToKill = serverName; 064 break; 065 } 066 } 067 HMaster master = util.getHBaseCluster().getMaster(); 068 final ProcedureExecutor<MasterProcedureEnv> pExecutor = master.getMasterProcedureExecutor(); 069 ServerCrashProcedure procB = 070 new ServerCrashProcedure(pExecutor.getEnvironment(), rsToKill, false, false); 071 AssignmentTestingUtil.killRs(util, rsToKill); 072 long procId = getSCPProcId(pExecutor); 073 Procedure<?> procA = pExecutor.getProcedure(procId); 074 LOG.info("submit SCP procedureA"); 075 util.waitFor(5000, () -> procA.hasLock()); 076 LOG.info("procedureA acquired the lock"); 077 assertEquals(Procedure.LockState.LOCK_EVENT_WAIT, 078 procB.acquireLock(pExecutor.getEnvironment())); 079 LOG.info("procedureB should not be able to get the lock"); 080 util.waitFor(60000, 081 () -> procB.acquireLock(pExecutor.getEnvironment()) == Procedure.LockState.LOCK_ACQUIRED); 082 LOG.info("when procedure B get the lock, procedure A should be finished"); 083 assertTrue(procA.isFinished()); 084 } 085 } 086}