@Test
 public void testConnectFailure() throws Exception {
   final CountDownLatch done = new CountDownLatch(1);
   final AtomicBoolean success = new AtomicBoolean();
   final AtomicReference<Throwable> failure = new AtomicReference<>();
   Promise<RedisClientBase> connect = RedisClientBase.connect("localhost", 6380);
   connect
       .onSuccess(
           new Block<RedisClientBase>() {
             @Override
             public void apply(RedisClientBase redisClientBase) {
               success.set(true);
               done.countDown();
             }
           })
       .onFailure(
           new Block<Throwable>() {
             @Override
             public void apply(Throwable throwable) {
               success.set(false);
               failure.set(throwable);
               done.countDown();
             }
           });
   done.await(5000, TimeUnit.MILLISECONDS);
   assertFalse(success.get());
   assertEquals("Connection refused", failure.get().getMessage());
 }
 @Test
 public void testConnect() throws Exception {
   final CountDownLatch done = new CountDownLatch(1);
   final AtomicBoolean success = new AtomicBoolean();
   final AtomicReference<RedisClientBase> client = new AtomicReference<>();
   Promise<RedisClientBase> connect = RedisClientBase.connect("localhost", 6379);
   connect
       .onSuccess(
           new Block<RedisClientBase>() {
             @Override
             public void apply(RedisClientBase redisClientBase) {
               success.set(true);
               client.set(redisClientBase);
               done.countDown();
             }
           })
       .onFailure(
           new Block<Throwable>() {
             @Override
             public void apply(Throwable throwable) {
               success.set(false);
               done.countDown();
             }
           });
   done.await(5000, TimeUnit.MILLISECONDS);
   final CountDownLatch done2 = new CountDownLatch(1);
   assertTrue(success.get());
   client
       .get()
       .close()
       .onSuccess(
           new Block<Void>() {
             @Override
             public void apply(Void aVoid) {
               success.set(true);
               done2.countDown();
             }
           })
       .onFailure(
           new Block<Throwable>() {
             @Override
             public void apply(Throwable throwable) {
               success.set(false);
               done2.countDown();
             }
           });
   done2.await(5000, TimeUnit.MILLISECONDS);
   assertTrue(success.get());
 }
  @Test
  public void testPubSubPerformance() throws InterruptedException {
    final CountDownLatch done = new CountDownLatch(1);
    final Semaphore semaphore = new Semaphore(100);
    final AtomicInteger total = new AtomicInteger();
    Promise<RedisClient> redisClient =
        RedisClient.connect("localhost", 6379)
            .onSuccess(
                new Block<RedisClient>() {
                  @Override
                  public void apply(RedisClient redisClient) {
                    redisClient.addListener(
                        new MessageListener() {
                          @Override
                          public void message(byte[] channel, byte[] message) {
                            semaphore.release();
                            total.incrementAndGet();
                          }

                          @Override
                          public void pmessage(byte[] pattern, byte[] channel, byte[] message) {}
                        });
                    redisClient
                        .subscribe("test")
                        .onSuccess(
                            new Block<Void>() {
                              @Override
                              public void apply(Void aVoid) {
                                RedisClient.connect("localhost", 6379)
                                    .onSuccess(
                                        new Block<RedisClient>() {
                                          @Override
                                          public void apply(final RedisClient redisClient) {
                                            new Thread(
                                                    new Runnable() {
                                                      @Override
                                                      public void run() {
                                                        long start = System.currentTimeMillis();
                                                        while (System.currentTimeMillis() - start
                                                            < 5000) {
                                                          semaphore.acquireUninterruptibly();
                                                          redisClient.publish("test", "hello");
                                                        }
                                                        redisClient.close();
                                                        done.countDown();
                                                      }
                                                    })
                                                .start();
                                          }
                                        });
                              }
                            });
                  }
                });
    done.await(6000, TimeUnit.MILLISECONDS);
    redisClient.onSuccess(
        new Block<RedisClient>() {
          @Override
          public void apply(RedisClient redisClient) {
            redisClient.close();
          }
        });
    System.out.println(total.get() / 5 + " per second");
  }