|
@@ -21,6 +21,8 @@ import java.util.function.Supplier;
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
|
import com.google.common.collect.Lists;
|
|
|
+import org.apache.hadoop.hdfs.LogVerificationAppender;
|
|
|
+import org.apache.log4j.spi.LoggingEvent;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
@@ -287,6 +289,49 @@ public class TestStandbyCheckpoints {
|
|
|
cluster.transitionToStandby(2);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Tests that a null FSImage is handled gracefully by the ImageServlet.
|
|
|
+ * If putImage is called while a NameNode is still starting up, the FSImage
|
|
|
+ * may not have been initialized yet. See HDFS-15290.
|
|
|
+ */
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testCheckpointBeforeNameNodeInitializationIsComplete()
|
|
|
+ throws Exception {
|
|
|
+ final LogVerificationAppender appender = new LogVerificationAppender();
|
|
|
+ final org.apache.log4j.Logger logger = org.apache.log4j.Logger
|
|
|
+ .getRootLogger();
|
|
|
+ logger.addAppender(appender);
|
|
|
+
|
|
|
+ // Transition 2 to observer
|
|
|
+ cluster.transitionToObserver(2);
|
|
|
+ doEdits(0, 10);
|
|
|
+ // After a rollEditLog, Standby(nn1)'s next checkpoint would be
|
|
|
+ // ahead of observer(nn2).
|
|
|
+ nns[0].getRpcServer().rollEditLog();
|
|
|
+
|
|
|
+ NameNode nn2 = nns[2];
|
|
|
+ FSImage nnFSImage = NameNodeAdapter.getAndSetFSImageInHttpServer(nn2, null);
|
|
|
+
|
|
|
+ // After standby creating a checkpoint, it will try to push the image to
|
|
|
+ // active and all observer, updating it's own txid to the most recent.
|
|
|
+ HATestUtil.waitForCheckpoint(cluster, 1, ImmutableList.of(12));
|
|
|
+ HATestUtil.waitForCheckpoint(cluster, 0, ImmutableList.of(12));
|
|
|
+
|
|
|
+ NameNodeAdapter.getAndSetFSImageInHttpServer(nn2, nnFSImage);
|
|
|
+ cluster.transitionToStandby(2);
|
|
|
+ logger.removeAppender(appender);
|
|
|
+
|
|
|
+ for (LoggingEvent event : appender.getLog()) {
|
|
|
+ String message = event.getRenderedMessage();
|
|
|
+ if (message.contains("PutImage failed") &&
|
|
|
+ message.contains("FSImage has not been set in the NameNode.")) {
|
|
|
+ //Logs have the expected exception.
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fail("Expected exception not present in logs.");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Test for the case when the SBN is configured to checkpoint based
|
|
|
* on a time period, but no transactions are happening on the
|