@Test
  public void testBasic() throws Exception {
    CuratorFramework client =
        CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
    try {
      client.start();

      final DistributedBarrier barrier = new DistributedBarrier(client, "/barrier");
      barrier.setBarrier();

      ExecutorService service = Executors.newSingleThreadExecutor();
      service.submit(
          new Callable<Object>() {
            @Override
            public Object call() throws Exception {
              Thread.sleep(1000);
              barrier.removeBarrier();
              return null;
            }
          });

      Assert.assertTrue(barrier.waitOnBarrier(10, TimeUnit.SECONDS));
    } finally {
      client.close();
    }
  }
  @Test
  public void testNoBarrier() throws Exception {
    CuratorFramework client =
        CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
    try {
      client.start();

      final DistributedBarrier barrier = new DistributedBarrier(client, "/barrier");
      Assert.assertTrue(barrier.waitOnBarrier(10, TimeUnit.SECONDS));

      // just for grins, test the infinite wait
      ExecutorService service = Executors.newSingleThreadExecutor();
      Future<Object> future =
          service.submit(
              new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                  barrier.waitOnBarrier();
                  return "";
                }
              });
      Assert.assertTrue(future.get(10, TimeUnit.SECONDS) != null);
    } finally {
      client.close();
    }
  }
  @Test
  public void testServerCrash() throws Exception {
    final int TIMEOUT = 1000;

    final CuratorFramework client =
        CuratorFrameworkFactory.builder()
            .connectString(server.getConnectString())
            .connectionTimeoutMs(TIMEOUT)
            .retryPolicy(new RetryOneTime(1))
            .build();
    try {
      client.start();

      final DistributedBarrier barrier = new DistributedBarrier(client, "/barrier");
      barrier.setBarrier();

      final ExecutorService service = Executors.newSingleThreadExecutor();
      Future<Object> future =
          service.submit(
              new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                  Thread.sleep(TIMEOUT / 2);
                  server.stop();
                  return null;
                }
              });

      barrier.waitOnBarrier(TIMEOUT * 2, TimeUnit.SECONDS);
      future.get();
      Assert.fail();
    } catch (KeeperException.ConnectionLossException expected) {
      // expected
    } finally {
      client.close();
    }
  }