private void testZookeeperCanaryWithArgs(String[] args) throws Exception {
    String hostPort = testingUtility.getZkCluster().getAddress().toString();
    testingUtility.getConfiguration().set(HConstants.ZOOKEEPER_QUORUM, hostPort);
    ExecutorService executor = new ScheduledThreadPoolExecutor(2);
    CanaryTool.ZookeeperStdOutSink sink = spy(new CanaryTool.ZookeeperStdOutSink());
    CanaryTool canary = new CanaryTool(executor, sink);
    assertEquals(0, ToolRunner.run(testingUtility.getConfiguration(), canary, args));

    String baseZnode = testingUtility.getConfiguration().get(HConstants.ZOOKEEPER_ZNODE_PARENT,
      HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT);
    verify(sink, atLeastOnce()).publishReadTiming(eq(baseZnode), eq(hostPort), anyLong());
  }
When CanaryTool times out, it should stop scanning and shutdown quickly and gracefully. This
test helps to confirm that threadpools do not continue executing work after the canary
finishes. It also verifies sink behavior and measures correct failure counts in the sink.
@throws Exception if it can't create a table, communicate with minicluster, or run the canary.
hbase-server/src/test/java/org/apache/hadoop/hbase/tool/TestCanaryTool.java