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 org.apache.hadoop.fs.Path; 021import org.apache.hadoop.hbase.HBaseTestingUtility; 022import org.apache.hadoop.hbase.StartMiniClusterOption; 023import org.apache.hadoop.hbase.procedure2.Procedure; 024import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 025import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; 026import org.junit.AfterClass; 027import org.junit.BeforeClass; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031public abstract class MasterFailoverWithProceduresTestBase { 032 033 private static final Logger LOG = 034 LoggerFactory.getLogger(MasterFailoverWithProceduresTestBase.class); 035 036 protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 037 038 @BeforeClass 039 public static void setUp() throws Exception { 040 UTIL.getConfiguration().setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1); 041 StartMiniClusterOption option = StartMiniClusterOption.builder().numMasters(2).build(); 042 UTIL.startMiniCluster(option); 043 044 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor(); 045 ProcedureTestingUtility.setToggleKillBeforeStoreUpdate(procExec, false); 046 ProcedureTestingUtility.setKillBeforeStoreUpdate(procExec, false); 047 } 048 049 @AfterClass 050 public static void tearDown() throws Exception { 051 UTIL.shutdownMiniCluster(); 052 } 053 054 // ========================================================================== 055 // Helpers 056 // ========================================================================== 057 protected static ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() { 058 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor(); 059 } 060 061 protected static Path getRootDir() { 062 return UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getRootDir(); 063 } 064 065 protected static void testRecoveryAndDoubleExecution(final HBaseTestingUtility testUtil, 066 final long procId, final int lastStepBeforeFailover) throws Exception { 067 ProcedureExecutor<MasterProcedureEnv> procExec = 068 testUtil.getHBaseCluster().getMaster().getMasterProcedureExecutor(); 069 ProcedureTestingUtility.waitProcedure(procExec, procId); 070 071 final Procedure<?> proc = procExec.getProcedure(procId); 072 for (int i = 0; i < lastStepBeforeFailover; ++i) { 073 LOG.info("Restart " + i + " exec state: " + proc); 074 ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId); 075 MasterProcedureTestingUtility.restartMasterProcedureExecutor(procExec); 076 ProcedureTestingUtility.waitProcedure(procExec, procId); 077 } 078 ProcedureTestingUtility.assertProcNotYetCompleted(procExec, procId); 079 080 LOG.info("Trigger master failover"); 081 MasterProcedureTestingUtility.masterFailover(testUtil); 082 083 procExec = testUtil.getHBaseCluster().getMaster().getMasterProcedureExecutor(); 084 ProcedureTestingUtility.waitProcedure(procExec, procId); 085 ProcedureTestingUtility.assertProcNotFailed(procExec, procId); 086 } 087}