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.Assert.assertEquals; 021 022import java.io.IOException; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.fs.Path; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HBaseTestingUtil; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 029import org.apache.hadoop.hbase.client.RegionInfo; 030import org.apache.hadoop.hbase.client.RegionInfoBuilder; 031import org.apache.hadoop.hbase.client.TableDescriptor; 032import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 033import org.apache.hadoop.hbase.master.HMaster; 034import org.apache.hadoop.hbase.procedure2.Procedure; 035import org.apache.hadoop.hbase.procedure2.ProcedureEvent; 036import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 037import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; 038import org.apache.hadoop.hbase.procedure2.store.wal.WALProcedureStore; 039import org.apache.hadoop.hbase.testclassification.MasterTests; 040import org.apache.hadoop.hbase.testclassification.MediumTests; 041import org.apache.hadoop.hbase.util.CommonFSUtils; 042import org.junit.After; 043import org.junit.AfterClass; 044import org.junit.BeforeClass; 045import org.junit.ClassRule; 046import org.junit.Rule; 047import org.junit.Test; 048import org.junit.experimental.categories.Category; 049import org.junit.rules.TestName; 050import org.slf4j.Logger; 051import org.slf4j.LoggerFactory; 052 053@Category({ MasterTests.class, MediumTests.class }) 054public class TestMasterProcedureEvents { 055 056 @ClassRule 057 public static final HBaseClassTestRule CLASS_RULE = 058 HBaseClassTestRule.forClass(TestMasterProcedureEvents.class); 059 060 private static final Logger LOG = LoggerFactory.getLogger(TestCreateTableProcedure.class); 061 062 protected static final HBaseTestingUtil UTIL = new HBaseTestingUtil(); 063 064 @Rule 065 public TestName name = new TestName(); 066 067 private static void setupConf(Configuration conf) throws IOException { 068 conf.setInt(MasterProcedureConstants.MASTER_PROCEDURE_THREADS, 1); 069 conf.setBoolean(WALProcedureStore.USE_HSYNC_CONF_KEY, false); 070 } 071 072 @BeforeClass 073 public static void setupCluster() throws Exception { 074 Configuration conf = UTIL.getConfiguration(); 075 setupConf(UTIL.getConfiguration()); 076 UTIL.startMiniDFSCluster(3); 077 CommonFSUtils.setWALRootDir(conf, new Path(conf.get("fs.defaultFS"), "/tmp/wal")); 078 UTIL.startMiniCluster(2); 079 UTIL.waitUntilNoRegionsInTransition(); 080 } 081 082 @AfterClass 083 public static void cleanupTest() throws Exception { 084 try { 085 UTIL.shutdownMiniCluster(); 086 } catch (Exception e) { 087 LOG.warn("failure shutting down cluster", e); 088 } 089 } 090 091 @After 092 public void tearDown() throws Exception { 093 for (TableDescriptor htd : UTIL.getAdmin().listTableDescriptors()) { 094 LOG.info("Tear down, remove table=" + htd.getTableName()); 095 UTIL.deleteTable(htd.getTableName()); 096 } 097 } 098 099 @Test 100 public void testMasterInitializedEvent() throws Exception { 101 final TableName tableName = TableName.valueOf(name.getMethodName()); 102 HMaster master = UTIL.getMiniHBaseCluster().getMaster(); 103 ProcedureExecutor<MasterProcedureEnv> procExec = master.getMasterProcedureExecutor(); 104 105 RegionInfo hri = RegionInfoBuilder.newBuilder(tableName).build(); 106 TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName) 107 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build(); 108 109 while (!master.isInitialized()) { 110 Thread.sleep(250); 111 } 112 master.setInitialized(false); // fake it, set back later 113 114 // check event wait/wake 115 testProcedureEventWaitWake(master, master.getInitializedEvent(), 116 new CreateTableProcedure(procExec.getEnvironment(), htd, new RegionInfo[] { hri })); 117 } 118 119 private void testProcedureEventWaitWake(final HMaster master, final ProcedureEvent<?> event, 120 final Procedure<MasterProcedureEnv> proc) throws Exception { 121 final ProcedureExecutor<MasterProcedureEnv> procExec = master.getMasterProcedureExecutor(); 122 final MasterProcedureScheduler procSched = procExec.getEnvironment().getProcedureScheduler(); 123 124 final long startPollCalls = procSched.getPollCalls(); 125 final long startNullPollCalls = procSched.getNullPollCalls(); 126 127 // check that nothing is in the event queue 128 LOG.debug("checking " + event); 129 assertEquals(false, event.isReady()); 130 assertEquals(0, event.getSuspendedProcedures().size()); 131 132 // submit the procedure 133 LOG.debug("submit " + proc); 134 long procId = procExec.submitProcedure(proc); 135 136 // wait until the event is in the queue (proc executed and got into suspended state) 137 LOG.debug("wait procedure suspended on " + event); 138 while (event.getSuspendedProcedures().size() < 1) 139 Thread.sleep(25); 140 141 // check that the proc is in the event queue 142 LOG.debug("checking " + event + " size=" + event.getSuspendedProcedures().size()); 143 assertEquals(false, event.isReady()); 144 assertEquals(1, event.getSuspendedProcedures().size()); 145 146 // wake the event 147 LOG.debug("wake " + event); 148 event.wake(procSched); 149 assertEquals(true, event.isReady()); 150 151 // wait until proc completes 152 LOG.debug("waiting " + proc); 153 ProcedureTestingUtility.waitProcedure(procExec, procId); 154 155 // check that nothing is in the event queue and the event is not suspended 156 assertEquals(true, event.isReady()); 157 assertEquals(0, event.getSuspendedProcedures().size()); 158 LOG.debug( 159 "completed execution of " + proc + " pollCalls=" + (procSched.getPollCalls() - startPollCalls) 160 + " nullPollCalls=" + (procSched.getNullPollCalls() - startNullPollCalls)); 161 } 162}