@Test
  public void testAsyncResolutionSuccess() throws Exception {

    final Bootstrap bootstrapA = new Bootstrap();
    bootstrapA.group(groupA);
    bootstrapA.channel(LocalChannel.class);
    bootstrapA.resolver(new TestAddressResolverGroup(true));
    bootstrapA.handler(dummyHandler);

    final ServerBootstrap bootstrapB = new ServerBootstrap();
    bootstrapB.group(groupB);
    bootstrapB.channel(LocalServerChannel.class);
    bootstrapB.childHandler(dummyHandler);
    SocketAddress localAddress = bootstrapB.bind(LocalAddress.ANY).sync().channel().localAddress();

    // Connect to the server using the asynchronous resolver.
    bootstrapA.connect(localAddress).sync();
  }
 @Test
 public void testLateRegisterSuccess() throws Exception {
   TestEventLoopGroup group = new TestEventLoopGroup();
   try {
     ServerBootstrap bootstrap = new ServerBootstrap();
     bootstrap.group(group);
     bootstrap.channel(LocalServerChannel.class);
     bootstrap.childHandler(new DummyHandler());
     bootstrap.localAddress(new LocalAddress("1"));
     ChannelFuture future = bootstrap.bind();
     assertFalse(future.isDone());
     group.promise.setSuccess();
     final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<Boolean>();
     future.addListener(
         new ChannelFutureListener() {
           @Override
           public void operationComplete(ChannelFuture future) throws Exception {
             queue.add(future.channel().eventLoop().inEventLoop(Thread.currentThread()));
             queue.add(future.isSuccess());
           }
         });
     assertTrue(queue.take());
     assertTrue(queue.take());
   } finally {
     group.shutdownGracefully();
     group.terminationFuture().sync();
   }
 }
  @Test
  public void testAsyncResolutionFailure() throws Exception {

    final Bootstrap bootstrapA = new Bootstrap();
    bootstrapA.group(groupA);
    bootstrapA.channel(LocalChannel.class);
    bootstrapA.resolver(new TestAddressResolverGroup(false));
    bootstrapA.handler(dummyHandler);

    final ServerBootstrap bootstrapB = new ServerBootstrap();
    bootstrapB.group(groupB);
    bootstrapB.channel(LocalServerChannel.class);
    bootstrapB.childHandler(dummyHandler);
    SocketAddress localAddress = bootstrapB.bind(LocalAddress.ANY).sync().channel().localAddress();

    // Connect to the server using the asynchronous resolver.
    ChannelFuture connectFuture = bootstrapA.connect(localAddress);

    // Should fail with the UnknownHostException.
    assertThat(connectFuture.await(10000), is(true));
    assertThat(connectFuture.cause(), is(instanceOf(UnknownHostException.class)));
    assertThat(connectFuture.channel().isOpen(), is(false));
  }
  @Test
  public void testLateRegisterSuccessBindFailed() throws Exception {
    TestEventLoopGroup group = new TestEventLoopGroup();
    try {
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap.group(group);
      bootstrap.channelFactory(
          new ChannelFactory<ServerChannel>() {
            @Override
            public ServerChannel newChannel() {
              return new LocalServerChannel() {
                @Override
                public ChannelFuture bind(SocketAddress localAddress) {
                  // Close the Channel to emulate what NIO and others impl do on bind failure
                  // See https://github.com/netty/netty/issues/2586
                  close();
                  return newFailedFuture(new SocketException());
                }

                @Override
                public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
                  // Close the Channel to emulate what NIO and others impl do on bind failure
                  // See https://github.com/netty/netty/issues/2586
                  close();
                  return promise.setFailure(new SocketException());
                }
              };
            }
          });
      bootstrap.childHandler(new DummyHandler());
      bootstrap.localAddress(new LocalAddress("1"));
      ChannelFuture future = bootstrap.bind();
      assertFalse(future.isDone());
      group.promise.setSuccess();
      final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<Boolean>();
      future.addListener(
          new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
              queue.add(future.channel().eventLoop().inEventLoop(Thread.currentThread()));
              queue.add(future.isSuccess());
            }
          });
      assertTrue(queue.take());
      assertFalse(queue.take());
    } finally {
      group.shutdownGracefully();
      group.terminationFuture().sync();
    }
  }