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