|
@@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs.server.blockmanagement;
|
|
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.junit.Assert.assertFalse;
|
|
import static org.junit.Assert.assertFalse;
|
|
|
|
+import static org.junit.Assert.assertNotNull;
|
|
import static org.junit.Assert.assertTrue;
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
|
|
import java.io.File;
|
|
import java.io.File;
|
|
@@ -44,6 +45,10 @@ import org.apache.hadoop.hdfs.server.namenode.NameNode;
|
|
import org.apache.hadoop.net.NetworkTopology;
|
|
import org.apache.hadoop.net.NetworkTopology;
|
|
import org.apache.hadoop.net.Node;
|
|
import org.apache.hadoop.net.Node;
|
|
import org.apache.hadoop.util.Time;
|
|
import org.apache.hadoop.util.Time;
|
|
|
|
+import org.apache.log4j.AppenderSkeleton;
|
|
|
|
+import org.apache.log4j.Level;
|
|
|
|
+import org.apache.log4j.Logger;
|
|
|
|
+import org.apache.log4j.spi.LoggingEvent;
|
|
import org.junit.BeforeClass;
|
|
import org.junit.BeforeClass;
|
|
import org.junit.Rule;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
import org.junit.Test;
|
|
@@ -375,7 +380,71 @@ public class TestReplicationPolicy {
|
|
new ArrayList<DatanodeDescriptor>(), BLOCK_SIZE);
|
|
new ArrayList<DatanodeDescriptor>(), BLOCK_SIZE);
|
|
assertEquals(targets.length, 3);
|
|
assertEquals(targets.length, 3);
|
|
assertTrue(cluster.isOnSameRack(targets[1], targets[2]));
|
|
assertTrue(cluster.isOnSameRack(targets[1], targets[2]));
|
|
- assertFalse(cluster.isOnSameRack(targets[0], targets[1]));
|
|
|
|
|
|
+ assertFalse(cluster.isOnSameRack(targets[0], targets[1]));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * In this testcase, it tries to choose more targets than available nodes and
|
|
|
|
+ * check the result.
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ @Test
|
|
|
|
+ public void testChooseTargetWithMoreThanAvaiableNodes() throws Exception {
|
|
|
|
+ // make data node 0 & 1 to be not qualified to choose: not enough disk space
|
|
|
|
+ for(int i=0; i<2; i++) {
|
|
|
|
+ dataNodes[i].updateHeartbeat(
|
|
|
|
+ 2*HdfsConstants.MIN_BLOCKS_FOR_WRITE*BLOCK_SIZE, 0L,
|
|
|
|
+ (HdfsConstants.MIN_BLOCKS_FOR_WRITE-1)*BLOCK_SIZE, 0L, 0, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ final TestAppender appender = new TestAppender();
|
|
|
|
+ final Logger logger = Logger.getRootLogger();
|
|
|
|
+ logger.addAppender(appender);
|
|
|
|
+
|
|
|
|
+ // try to choose NUM_OF_DATANODES which is more than actually available
|
|
|
|
+ // nodes.
|
|
|
|
+ DatanodeDescriptor[] targets = replicator.chooseTarget(filename,
|
|
|
|
+ NUM_OF_DATANODES, dataNodes[0], new ArrayList<DatanodeDescriptor>(),
|
|
|
|
+ BLOCK_SIZE);
|
|
|
|
+ assertEquals(targets.length, NUM_OF_DATANODES - 2);
|
|
|
|
+
|
|
|
|
+ final List<LoggingEvent> log = appender.getLog();
|
|
|
|
+ assertNotNull(log);
|
|
|
|
+ assertFalse(log.size() == 0);
|
|
|
|
+ final LoggingEvent lastLogEntry = log.get(log.size() - 1);
|
|
|
|
+
|
|
|
|
+ assertEquals(lastLogEntry.getLevel(), Level.WARN);
|
|
|
|
+ // Suppose to place replicas on each node but two data nodes are not
|
|
|
|
+ // available for placing replica, so here we expect a short of 2
|
|
|
|
+ assertTrue(((String)lastLogEntry.getMessage()).contains("in need of 2"));
|
|
|
|
+
|
|
|
|
+ for(int i=0; i<2; i++) {
|
|
|
|
+ dataNodes[i].updateHeartbeat(
|
|
|
|
+ 2*HdfsConstants.MIN_BLOCKS_FOR_WRITE*BLOCK_SIZE, 0L,
|
|
|
|
+ HdfsConstants.MIN_BLOCKS_FOR_WRITE*BLOCK_SIZE, 0L, 0, 0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class TestAppender extends AppenderSkeleton {
|
|
|
|
+ private final List<LoggingEvent> log = new ArrayList<LoggingEvent>();
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean requiresLayout() {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected void append(final LoggingEvent loggingEvent) {
|
|
|
|
+ log.add(loggingEvent);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void close() {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<LoggingEvent> getLog() {
|
|
|
|
+ return new ArrayList<LoggingEvent>(log);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private boolean containsWithinRange(DatanodeDescriptor target,
|
|
private boolean containsWithinRange(DatanodeDescriptor target,
|