package org.apache.hadoop.hdfs.server.datanode; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.MiniAvatarCluster; import org.apache.hadoop.hdfs.protocol.FSConstants.DatanodeReportType; import org.apache.hadoop.hdfs.server.namenode.FSNamesystem; import org.apache.hadoop.hdfs.util.InjectionEvent; import org.apache.hadoop.util.InjectionEventI; import org.apache.hadoop.util.InjectionHandler; import static org.junit.Assert.*; import org.junit.Test; public class TestAvatarDatanodeRetryRegister { private static int registrations = 0; private static class TestAvatarDatanodeRetryRegisterHandler extends InjectionHandler { @Override public void _processEventIO(InjectionEventI event, Object... args) throws IOException { if (event == InjectionEvent.OFFERSERVICE_BEFORE_REGISTRATION) { registrations++; throw new IOException("EXCEPTION!!!"); } } } /** * This tests whether when the datanode is having trouble with registration * to the namenode, the offerservice threads for the datanode are restarted * and the datanode then is correctly able to register to the namenode. */ @Test(timeout=60000) public void testAvatarDatanodeRetryRegister() throws Exception { Configuration conf = new Configuration(); conf.setLong("dfs.heartbeat.interval", 1); InjectionHandler.set(new TestAvatarDatanodeRetryRegisterHandler()); MiniAvatarCluster.createAndStartZooKeeper(); MiniAvatarCluster cluster = new MiniAvatarCluster(conf, 1, true, null, null); try { FSNamesystem ns = cluster.getPrimaryAvatar(0).avatar.namesystem; // These two lines make sure the datanode is marked as dead and is no longer registered. ns.setDatanodeDead(ns.getDatanode(cluster.getDataNodes().get(0) .getDNRegistrationForNS(cluster.getNamespaceId(0)))); ns.removeDatanode(cluster.getDataNodes().get(0) .getDNRegistrationForNS(cluster.getNamespaceId(0))); assertEquals(0, ns.getNameNode().getDatanodeReport(DatanodeReportType.LIVE).length); int livenodes = ns.getNameNode().getDatanodeReport(DatanodeReportType.LIVE).length; // Wait for the datanode to register successfully. while (registrations != 1 || livenodes != 1) { System.out.println("Waiting for registrations : " + registrations); Thread.sleep(1000); livenodes = ns.getNameNode().getDatanodeReport(DatanodeReportType.LIVE).length; } assertEquals(1, ns.getNameNode().getDatanodeReport(DatanodeReportType.LIVE).length); assertEquals(1, registrations); } finally { cluster.shutDown(); MiniAvatarCluster.shutDownZooKeeper(); } } }