package org.apache.hadoop.hdfs.server.datanode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.MiniAvatarCluster; import org.apache.hadoop.hdfs.server.datanode.AvatarDataNode.ServicePair; import org.apache.hadoop.hdfs.util.InjectionEvent; import org.apache.hadoop.util.InjectionEventI; import org.apache.hadoop.util.InjectionHandler; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.*; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class TestAvatarDataNodeRestartService { protected static MiniAvatarCluster cluster; private static boolean pass = true; private static boolean injectionDone = false; private static Log LOG = LogFactory .getLog(TestAvatarDataNodeRestartService.class); private static Thread rThread = null; @BeforeClass public static void setUpBeforeClass() throws Exception { MiniAvatarCluster.createAndStartZooKeeper(); } @Before public void setUp() throws Exception { cluster = new MiniAvatarCluster(new Configuration(), 1, true, null, null); } @AfterClass public static void tearDownAfterClass() throws Exception { MiniAvatarCluster.shutDownZooKeeper(); } @After public void tearDown() throws Exception { InjectionHandler.clear(); injectionDone = false; cluster.shutDown(); } private static class RestartThread extends Thread { private final boolean serviceOne; public RestartThread(boolean serviceOne) { this.serviceOne = serviceOne; } public void run() { try { if (serviceOne) { cluster.killPrimary(); } else { cluster.killStandby(); } } catch (Exception e) { LOG.error("restart failed", e); pass = false; } if (serviceOne) { restartService1(); } else { restartService2(); } } } private static void waitInjection() { try { Thread.sleep(10000); } catch (InterruptedException ie) { } injectionDone = true; } private static class TestRestartServiceHandler extends InjectionHandler { private boolean enableOne = true; @Override public void _processEvent(InjectionEventI event, Object... args) { if (event == InjectionEvent.AVATARDATANODE_START_OFFERSERVICE1 && enableOne) { rThread = new RestartThread(true); rThread.start(); waitInjection(); } if (event == InjectionEvent.AVATARDATANODE_START_OFFERSERVICE2 && !enableOne) { rThread = new RestartThread(false); rThread.start(); waitInjection(); } } } private static ServicePair getPair() { AvatarDataNode dn = cluster.getDataNodes().get(0); return (ServicePair) dn.getAllNamespaceServices()[0]; } private static void restartService1() { try { getPair().restartService1(); } catch (Exception e) { LOG.error("restart failed", e); pass = false; } } private static void restartService2() { try { getPair().restartService2(); } catch (Exception e) { LOG.error("restart failed", e); pass = false; } } @Test public void testDatanodeRestartService1() throws Exception { InjectionHandler.set(new TestRestartServiceHandler()); restartService1(); while (!injectionDone) { Thread.sleep(100); } Thread.sleep(10000); assertTrue(pass); ServicePair pair = getPair(); assertFalse((pair.avatarnode1 == null && pair.offerService1.shouldRun())); assertFalse((pair.namenode1 == null && pair.offerService1.shouldRun())); } @Test public void testDatanodeRestartService2() throws Exception { ServicePair pair = getPair(); TestRestartServiceHandler handler = new TestRestartServiceHandler(); handler.enableOne = false; InjectionHandler.set(handler); restartService2(); while (!injectionDone) { Thread.sleep(100); } Thread.sleep(10000); assertTrue(pass); assertFalse((pair.avatarnode2 == null && pair.offerService2.shouldRun())); assertFalse((pair.namenode2 == null && pair.offerService2.shouldRun())); } }