package org.apache.hadoop.hdfs;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.MiniAvatarCluster.NameNodeInfo;
import org.apache.hadoop.hdfs.protocol.AvatarConstants;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.AvatarConstants.StartupOption;
import org.apache.hadoop.hdfs.server.namenode.AvatarNode;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
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 org.junit.BeforeClass;
import static org.junit.Assert.*;
import org.junit.Test;
public class TestAvatarStartup extends FailoverLoadTestUtil {
private static MiniAvatarCluster cluster;
private static final List<AvatarNode> extraNodes = new ArrayList<AvatarNode>();
private static Configuration conf;
private static AvatarZooKeeperClient zkClient;
private static final Random r = new Random();
private static final Log LOG = LogFactory
.getLog(TestAvatarStartup.class);
@BeforeClass
public static void setUpBeforeClass() throws Exception {
MiniAvatarCluster.createAndStartZooKeeper();
}
public void setUp(boolean federation, String testName) throws Exception {
setUp(federation, testName, false);
}
public void setUp(boolean federation, String testName, boolean retrywrites)
throws Exception {
LOG.info("------------------- test: " + testName
+ " START ----------------");
conf = new Configuration();
conf.setBoolean("fs.ha.retrywrites", retrywrites);
if (federation) {
cluster = new MiniAvatarCluster.Builder(conf)
.numNameNodes(2 + r.nextInt(4)).federation(true).enableQJM(false).build();
} else {
cluster = new MiniAvatarCluster.Builder(conf).enableQJM(false).build();
}
zkClient = new AvatarZooKeeperClient(conf, null);
}
@After
public void tearDown() throws Exception {
if (zkClient != null)
zkClient.shutdown();
if (cluster != null)
cluster.shutDown();
for(AvatarNode an : extraNodes) {
an.shutdown(true);
}
extraNodes.clear();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
MiniAvatarCluster.shutDownZooKeeper();
}
private long getSessionId(int index) throws Exception {
AvatarNode primaryAvatar = cluster.getPrimaryAvatar(index).avatar;
String address = primaryAvatar.getStartupConf().get(
NameNode.DFS_NAMENODE_RPC_ADDRESS_KEY);
return zkClient.getPrimarySsId(address, false);
}
private void verifyStartup(boolean federation, int index,
boolean singleStartup, boolean standby) throws Exception {
verifyStartup(federation, index, singleStartup, standby, false);
}
private void verifyStartup(boolean federation, int index,
boolean singleStartup, boolean standby, boolean forceStartup)
throws Exception {
MiniAvatarCluster.instantiationRetries = 2;
NameNodeInfo nnInfo = cluster.getNameNode(index);
String instance = (!standby) ? AvatarConstants.StartupOption.NODEZERO
.getName() : AvatarConstants.StartupOption.NODEONE.getName();
String force = (forceStartup) ? AvatarConstants.StartupOption.FORCE
.getName() : instance;
String[] primaryArgs = { instance, force };
String[] standbyArgs = { instance, force,
AvatarConstants.StartupOption.STANDBY.getName() };
String[] normalArgs = (!standby) ? primaryArgs : standbyArgs;
String[] federationPrimaryArgs = { instance, force,
StartupOption.SERVICE.getName(), nnInfo.nameserviceId };
String[] federationStandbyArgs = { instance, force,
StartupOption.SERVICE.getName(), nnInfo.nameserviceId,
AvatarConstants.StartupOption.STANDBY.getName() };
String[] federationArgs = (!standby) ? federationPrimaryArgs
: federationStandbyArgs;
String[] args = (federation) ? federationArgs : normalArgs;
AvatarNode primary1 = MiniAvatarCluster.instantiateAvatarNode(
args,
MiniAvatarCluster.getServerConf(instance, nnInfo));
extraNodes.add(primary1);
if (singleStartup) {
if (!standby) {
assertEquals(primary1.getSessionId(), getSessionId(index));
}
return;
}
try {
AvatarNode second = MiniAvatarCluster.instantiateAvatarNode(args,
MiniAvatarCluster.getServerConf(instance, nnInfo));
extraNodes.add(second);
fail("Did not throw exception");
} catch (Exception e) {
LOG.info("Expected exception : ", e);
if (!standby) {
assertEquals(primary1.getSessionId(), getSessionId(index));
}
}
}
@Test
public void testStartup() throws Exception {
setUp(false, "testStartup");
cluster.shutDownAvatarNodes();
int nameNodes = cluster.getNumNameNodes();
for (int i = 0; i < nameNodes; i++) {
verifyStartup(false, i, false, false);
}
}
@Test
public void testStartupFederation() throws Exception {
setUp(true, "testStartupFederation");
cluster.shutDownAvatarNodes();
int nameNodes = cluster.getNumNameNodes();
for (int i = 0; i < nameNodes; i++) {
verifyStartup(true, i, false, false);
}
}
@Test(expected = IOException.class)
public void testNullZKStartupPrimary() throws Exception {
setUp(false, "testNullZKStartupPrimary");
cluster.shutDownAvatarNodes();
cluster.clearZooKeeperNode(0);
verifyStartup(false, 0, true, false);
}
@Test(expected = IOException.class)
public void testNullZKStartupStandby() throws Exception {
setUp(false, "testNullZKStartupStandby");
cluster.shutDownAvatarNodes();
cluster.clearZooKeeperNode(0);
verifyStartup(false, 0, true, true);
}
@Test()
public void testNullZKStartupForce() throws Exception {
setUp(false, "testNullZKStartupForce");
cluster.shutDownAvatarNodes();
cluster.clearZooKeeperNode(0);
verifyStartup(false, 0, true, false, true);
verifyStartup(false, 0, true, true, true);
}
@Test()
public void testNullZKStartupForceWithLoad() throws Exception {
setUp(false, "testNullZKStartupForceWithLoad", true);
LoadThread loadThread = new LoadThread(cluster.getFileSystem());
loadThread.start();
Thread.sleep(3000);
cluster.shutDownAvatarNodes();
cluster.clearZooKeeperNode(0);
verifyStartup(false, 0, true, false, true);
verifyStartup(false, 0, true, true, true);
cluster.registerZooKeeperNodes();
Thread.sleep(3000);
loadThread.cancel();
loadThread.join(30000);
assertTrue(pass);
}
}