### Question:
SafeMode extends ZooKeeperLockManager { public void registerNode(String node, byte[] data) throws KeeperException, InterruptedException { lock(SETUP); register(node, data); if (isLeader(node)) { lock(STARTUP); unlock(SETUP); waitForClusterToSettle(); unlock(STARTUP); } else { unlock(SETUP); lock(STARTUP); unlock(STARTUP); } } SafeMode(ZooKeeper zooKeeper, String lockPath, String nodePath, TimeUnit waitTimeUnit, long waitTime,
      TimeUnit duplicateNodeTimeoutTimeUnit, long duplicateNodeTimeout, int minimumNumberOfNodes); void registerNode(String node, byte[] data); static final String STARTUP; static final String SETUP; }### Answer:
@Test public void testExtraNodeStartup() throws IOException, InterruptedException, KeeperException { ZooKeeper zk = new ZooKeeper(miniCluster.getZkConnectionString(), 20000, new Watcher() { @Override public void process(WatchedEvent event) { } }); SafeMode setupSafeMode = new SafeMode(zk, "/testing/safemode", "/testing/nodepath", TimeUnit.SECONDS, 5, TimeUnit.SECONDS, 60, 0); setupSafeMode.registerNode("node1", null); SafeMode safeMode = new SafeMode(zk, "/testing/safemode", "/testing/nodepath", TimeUnit.SECONDS, 5, TimeUnit.SECONDS, 60, 0); long s = System.nanoTime(); safeMode.registerNode("node101", null); long e = System.nanoTime(); assertTrue((e - s) < TimeUnit.SECONDS.toNanos(1)); zk.close(); }
@Test public void testSecondNodeStartup() throws IOException, InterruptedException, KeeperException { ZooKeeper zk = new ZooKeeper(miniCluster.getZkConnectionString(), 20000, new Watcher() { @Override public void process(WatchedEvent event) { } }); SafeMode setupSafeMode = new SafeMode(zk, "/testing/safemode", "/testing/nodepath", TimeUnit.SECONDS, 5, TimeUnit.SECONDS, 60, 0); setupSafeMode.registerNode("node10", null); SafeMode safeMode = new SafeMode(zk, "/testing/safemode", "/testing/nodepath", TimeUnit.SECONDS, 5, TimeUnit.SECONDS, 15, 0); try { safeMode.registerNode("node10", null); fail("should throw exception."); } catch (Exception e) { } zk.close(); }