@Override
 public void tearDown() throws Exception {
   super.tearDown();
   if (null != mFactory) {
     mFactory.uninitialize();
     mFactory = null;
   }
   if (null != underReplicationManager) {
     underReplicationManager.close();
     underReplicationManager = null;
   }
 }
  /**
   * Tests that ReplicationWorker should not have identified for postponing the replication if
   * ledger is in open state and lastFragment is not in underReplication state. Note that RW should
   * not fence such ledgers.
   */
  @Test(timeout = 30000)
  public void testRWShouldReplicateTheLedgersAfterTimeoutIfLastFragmentIsNotUR() throws Exception {
    LedgerHandle lh = bkc.createLedger(3, 3, BookKeeper.DigestType.CRC32, TESTPASSWD);

    for (int i = 0; i < 10; i++) {
      lh.addEntry(data);
    }
    BookieSocketAddress replicaToKill =
        LedgerHandleAdapter.getLedgerMetadata(lh).getEnsembles().get(0L).get(0);

    LOG.info("Killing Bookie", replicaToKill);
    killBookie(replicaToKill);

    int startNewBookie = startNewBookie();

    // Reform ensemble...Making sure that last fragment is not in
    // under-replication
    for (int i = 0; i < 10; i++) {
      lh.addEntry(data);
    }

    BookieSocketAddress newBkAddr =
        new BookieSocketAddress(InetAddress.getLocalHost().getHostAddress(), startNewBookie);
    LOG.info("New Bookie addr :" + newBkAddr);

    ReplicationWorker rw = new ReplicationWorker(zkc, baseConf, newBkAddr);

    LedgerManagerFactory mFactory =
        LedgerManagerFactory.newLedgerManagerFactory(baseClientConf, zkc);
    LedgerUnderreplicationManager underReplicationManager =
        mFactory.newLedgerUnderreplicationManager();

    rw.start();
    try {

      underReplicationManager.markLedgerUnderreplicated(lh.getId(), replicaToKill.toString());
      while (isLedgerInUnderReplication(lh.getId(), basePath)) {
        Thread.sleep(100);
      }

      killAllBookies(lh, newBkAddr);

      // Should be able to read the entries from 0-9
      verifyRecoveredLedgers(lh, 0, 9);
      lh = bkc.openLedgerNoRecovery(lh.getId(), BookKeeper.DigestType.CRC32, TESTPASSWD);

      // Ledger should be still in open state
      assertTrue("Ledger must have been closed by RW", ClientUtil.isLedgerOpen(lh));
    } finally {
      rw.shutdown();
      underReplicationManager.close();
    }
  }