@Test
  public void testActiveMasterManagerFromZK() throws Exception {
    try (ZKWatcher zk =
      new ZKWatcher(TEST_UTIL.getConfiguration(), "testActiveMasterManagerFromZK", null, true)) {
      try {
        ZKUtil.deleteNode(zk, zk.getZNodePaths().masterAddressZNode);
        ZKUtil.deleteNode(zk, zk.getZNodePaths().clusterStateZNode);
      } catch (KeeperException.NoNodeException nne) {
      }

      // Create the master node with a dummy address
      ServerName firstMasterAddress =
        ServerName.valueOf("localhost", 1, EnvironmentEdgeManager.currentTime());
      ServerName secondMasterAddress =
        ServerName.valueOf("localhost", 2, EnvironmentEdgeManager.currentTime());

      // Should not have a master yet
      DummyMaster ms1 = new DummyMaster(zk, firstMasterAddress);
      ActiveMasterManager activeMasterManager = ms1.getActiveMasterManager();
      assertFalse(activeMasterManager.clusterHasActiveMaster.get());
      assertFalse(activeMasterManager.getActiveMasterServerName().isPresent());

      // First test becoming the active master uninterrupted
      ClusterStatusTracker clusterStatusTracker = ms1.getClusterStatusTracker();
      clusterStatusTracker.setClusterUp();

      activeMasterManager.blockUntilBecomingActiveMaster(100, mockTaskGroup());
      assertTrue(activeMasterManager.clusterHasActiveMaster.get());
      assertMaster(zk, firstMasterAddress);
      assertMaster(zk, activeMasterManager.getActiveMasterServerName().get());

      // New manager will now try to become the active master in another thread
      WaitToBeMasterThread t = new WaitToBeMasterThread(zk, secondMasterAddress);
      t.start();
      // Wait for this guy to figure out there is another active master
      // Wait for 1 second at most
      int sleeps = 0;
      while (!t.manager.clusterHasActiveMaster.get() && sleeps < 100) {
        Thread.sleep(10);
        sleeps++;
      }

      // Both should see that there is an active master
      assertTrue(activeMasterManager.clusterHasActiveMaster.get());
      assertTrue(t.manager.clusterHasActiveMaster.get());
      // But secondary one should not be the active master
      assertFalse(t.isActiveMaster);
      // Verify the active master ServerName is populated in standby master.
      assertEquals(firstMasterAddress, t.manager.getActiveMasterServerName().get());

      // Close the first server and delete it's master node
      ms1.stop("stopping first server");

      // Use a listener to capture when the node is actually deleted
      NodeDeletionListener listener =
        new NodeDeletionListener(zk, zk.getZNodePaths().masterAddressZNode);
      zk.registerListener(listener);

      LOG.info("Deleting master node");
      ZKUtil.deleteNode(zk, zk.getZNodePaths().masterAddressZNode);

      // Wait for the node to be deleted
      LOG.info("Waiting for active master manager to be notified");
      listener.waitForDeletion();
      LOG.info("Master node deleted");

      // Now we expect the secondary manager to have and be the active master
      // Wait for 1 second at most
      sleeps = 0;
      while (!t.isActiveMaster && sleeps < 100) {
        Thread.sleep(10);
        sleeps++;
      }
      LOG.debug("Slept " + sleeps + " times");

      assertTrue(t.manager.clusterHasActiveMaster.get());
      assertTrue(t.isActiveMaster);
      assertEquals(secondMasterAddress, t.manager.getActiveMasterServerName().get());

      LOG.info("Deleting master node");

      ZKUtil.deleteNode(zk, zk.getZNodePaths().masterAddressZNode);
    }
  }
Unit tests that uses ZooKeeper but does not use the master-side methods but rather acts
directly on ZK.
hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestActiveMasterManager.java