@Test(timeout = 300000)
public void testTransactionSinceLastCheckpointMetrics() throws Exception {

  Random random = new Random();
  int retryCount = 0;
  while (retryCount < 5) {
    try {
      int basePort = 10060 + random.nextInt(100) * 2;
      MiniDFSNNTopology topology = new MiniDFSNNTopology()
          .addNameservice(new MiniDFSNNTopology.NSConf("ns1")
          .addNN(new MiniDFSNNTopology.NNConf("nn1").setHttpPort(basePort))
          .addNN(new MiniDFSNNTopology.NNConf("nn2").setHttpPort(basePort + 1)));
      HdfsConfiguration conf2 = new HdfsConfiguration();
      // Lower the checkpoint condition for purpose of testing.
      conf2.setInt(
          DFSConfigKeys.DFS_NAMENODE_CHECKPOINT_TXNS_KEY,
          100);
      // Check for checkpoint condition very often, for purpose of testing.
      conf2.setInt(
          DFSConfigKeys.DFS_NAMENODE_CHECKPOINT_CHECK_PERIOD_KEY,
          1);
      // Poll and follow ANN txns very often, for purpose of testing.
      conf2.setInt(DFSConfigKeys.DFS_HA_TAILEDITS_PERIOD_KEY, 1);
      MiniDFSCluster cluster2 = new MiniDFSCluster.Builder(conf2)
          .nnTopology(topology).numDataNodes(1).build();
      cluster2.waitActive();
      DistributedFileSystem fs2 = cluster2.getFileSystem(0);
      NameNode nn0 = cluster2.getNameNode(0);
      NameNode nn1 = cluster2.getNameNode(1);
      cluster2.transitionToActive(0);
      fs2.mkdirs(new Path("/tmp-t1"));
      fs2.mkdirs(new Path("/tmp-t2"));
      HATestUtil.waitForStandbyToCatchUp(nn0, nn1);
      // Test to ensure tracking works before the first-ever
      // checkpoint.
      assertEquals("SBN failed to track 2 transactions pre-checkpoint.",
          4L, // 2 txns added further when catch-up is called.
          cluster2.getNameNode(1).getNamesystem()
            .getTransactionsSinceLastCheckpoint());
      // Complete up to the boundary required for
      // an auto-checkpoint. Using 94 to expect fsimage
      // rounded at 100, as 4 + 94 + 2 (catch-up call) = 100.
      for (int i = 1; i <= 94; i++) {
        fs2.mkdirs(new Path("/tmp-" + i));
      }
      HATestUtil.waitForStandbyToCatchUp(nn0, nn1);
      // Assert 100 transactions in checkpoint.
      HATestUtil.waitForCheckpoint(cluster2, 1, ImmutableList.of(100));
      // Test to ensure number tracks the right state of
      // uncheckpointed edits, and does not go negative
      // (as fixed in HDFS-7501).
      assertEquals("Should be zero right after the checkpoint.",
          0L,
          cluster2.getNameNode(1).getNamesystem()
            .getTransactionsSinceLastCheckpoint());
      fs2.mkdirs(new Path("/tmp-t3"));
      fs2.mkdirs(new Path("/tmp-t4"));
      HATestUtil.waitForStandbyToCatchUp(nn0, nn1);
      // Test to ensure we track the right numbers after
      // the checkpoint resets it to zero again.
      assertEquals("SBN failed to track 2 added txns after the ckpt.",
          4L,
          cluster2.getNameNode(1).getNamesystem()
            .getTransactionsSinceLastCheckpoint());
      cluster2.shutdown();
      break;
    } catch (Exception e) {
      LOG.warn("Unable to set up HA cluster, exception thrown: " + e);
      retryCount++;
    }
  }
}