/* * Copyright (C) 2015 hops.io. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.hops.leaderElection; import io.hops.exception.StorageException; import io.hops.exception.StorageInitializtionException; import io.hops.leaderElection.experiments.LightWeightNameNode; import io.hops.leader_election.node.ActiveNode; import io.hops.metadata.LEStorageFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class TestLEDeadNodes { private static final Log LOG = LogFactory.getLog(TestLEDeadNodes.class); List<LightWeightNameNode> nnList; private final int DFS_LEADER_CHECK_INTERVAL_IN_MS = 3 * 1000; private final int DFS_LEADER_MISSED_HB_THRESHOLD = 2; private final String HTTP_ADDRESS = "dummy.address.com:9999"; private final String RPC_ADDRESS = "repc.server.ip:0000"; private final String DRIVER_JAR = ""; private final String DRIVER_CLASS = "io.hops.metadata.ndb.NdbStorageFactory"; private final String DFS_STORAGE_DRIVER_CONFIG_FILE = "ndb-config.properties"; private final long TIME_PERIOD_INCREMENT = 200; @Before public void init() throws StorageInitializtionException, StorageException, IOException { LogManager.getRootLogger().setLevel(Level.ALL); nnList = new ArrayList<LightWeightNameNode>(); LEStorageFactory.setConfiguration(DRIVER_JAR, DRIVER_CLASS, DFS_STORAGE_DRIVER_CONFIG_FILE); LEStorageFactory.formatStorage(); VarsRegister.registerHdfsDefaultValues(); } @After public void tearDown() { //stop all NN LOG.debug("tearDown"); for (LightWeightNameNode nn : nnList) { nn.stop(); } } /** * Test if the NN are correctly removed from the Active NN list */ @Test public void testDeadNodesRemoval() throws IOException, InterruptedException, CloneNotSupportedException { LOG.debug("start testDeadNodesRemoval"); List<InetSocketAddress> isaList = new ArrayList<InetSocketAddress>(); //create 10 NN for (int i = 0; i < 10; i++) { LightWeightNameNode nn = new LightWeightNameNode(new HdfsLeDescriptorFactory(), DFS_LEADER_CHECK_INTERVAL_IN_MS, DFS_LEADER_MISSED_HB_THRESHOLD, TIME_PERIOD_INCREMENT, HTTP_ADDRESS, "127.0.0.1:" + (50000 + i)); nnList.add(nn); isaList.add(nn.getNameNodeAddress()); } // wait for one HB and the first node should have complete list of nodes Thread.sleep( DFS_LEADER_CHECK_INTERVAL_IN_MS * DFS_LEADER_MISSED_HB_THRESHOLD); //verify that the number of active nn is equal to the number of started NN List<ActiveNode> activesNNs = nnList.get(0).getActiveNameNodes().getActiveNodes(); assertTrue("wrong number of active NN " + activesNNs.size(), activesNNs.size() == nnList.size()); //verify that there is one and only one leader. int leaderId = 0; int nbLeaders = 0; for (int i = 0; i < nnList.size(); i++) { if (nnList.get(i).isLeader()) { nbLeaders++; leaderId = i; } } assertTrue("there is no leader", nbLeaders > 0); assertTrue("there is more than one leader", nbLeaders == 1); //stop the leader nnList.get(leaderId).stop(); Thread.sleep( DFS_LEADER_CHECK_INTERVAL_IN_MS * (DFS_LEADER_MISSED_HB_THRESHOLD + 2)); //verify that there is one and only one leader. int newLeaderId = 0; nbLeaders = 0; for (int i = 0; i < nnList.size(); i++) { if (i != leaderId) { if (nnList.get(i).isLeader()) { nbLeaders++; newLeaderId = i; } } } assertTrue("there is no leader", nbLeaders > 0); assertTrue("there is more than one leader", nbLeaders == 1); //verify that the stoped leader is not in the active list anymore activesNNs = nnList.get(newLeaderId).getActiveNameNodes().getActiveNodes(); for (ActiveNode ann : activesNNs) { assertFalse("previous is stil in active nn", ann.getInetSocketAddress().equals(isaList.get(leaderId))); } //stop NN last alive NN int tokill = nnList.size() - 1; while (leaderId == tokill || newLeaderId == tokill) { tokill--; } LOG.debug("stopping node: " + nnList.get(tokill).getLeCurrentId()); nnList.get(tokill).stop(); Thread.sleep( DFS_LEADER_CHECK_INTERVAL_IN_MS * (DFS_LEADER_MISSED_HB_THRESHOLD + 2)); //verify that the killed NN is not in the active NN list anymore activesNNs = nnList.get(newLeaderId).getActiveNameNodes().getActiveNodes(); assertTrue("wrong nb of active nn " + activesNNs.size(), activesNNs.size() == 8); for (ActiveNode ann : activesNNs) { assertFalse("killed nn is stil in active nn", ann.getInetSocketAddress().equals(isaList.get(tokill))); } } }