@Test
    public void testConnection() throws Throwable {
        final String PIPE_NAME;
        if (OS.startsWith("Windows")) {
            PIPE_NAME = "\\\\.\\pipe\\libuv-java-pipe-handle-test-pipe";
        } else {
            PIPE_NAME = "/tmp/libuv-java-pipe-handle-test-pipe";
            Files.deleteIfExists(FileSystems.getDefault().getPath(PIPE_NAME));
        }

        final AtomicInteger serverSendCount = new AtomicInteger(0);
        final AtomicInteger clientSendCount = new AtomicInteger(0);

        final AtomicInteger serverRecvCount = new AtomicInteger(0);
        final AtomicInteger clientRecvCount = new AtomicInteger(0);

        final AtomicBoolean serverDone = new AtomicBoolean(false);
        final AtomicBoolean clientDone = new AtomicBoolean(false);

        final Logger serverLoggingCallback = new Logger("S: ");
        final Logger clientLoggingCallback = new Logger("C: ");

        final LoopHandle loop = new LoopHandle();
        final PipeHandle server = new PipeHandle(loop, false);
        final PipeHandle peer = new PipeHandle(loop, false);
        final PipeHandle client = new PipeHandle(loop, false);

        peer.setReadCallback(new StreamReadCallback() {
            @Override
            public void onRead(final ByteBuffer data) throws Exception {
                serverRecvCount.incrementAndGet();
                if (data == null) {
                    peer.close();
                } else {
                    final Object[] args = {data};
                    serverLoggingCallback.log(args);
                    if (serverSendCount.get() < TIMES) {
                        peer.write("PING " + serverSendCount.incrementAndGet());
                    } else {
                        peer.close();
                    }
                }
            }
        });

        peer.setCloseCallback(new StreamCloseCallback() {
            @Override
            public void onClose() throws Exception {
                serverDone.set(true);
            }
        });

        server.setConnectionCallback(new StreamConnectionCallback() {
            @Override
            public void onConnection(int status, Exception error) throws Exception {
                serverLoggingCallback.log(status, error);
                server.accept(peer);
                peer.readStart();
                peer.write("INIT " + serverSendCount.incrementAndGet());
                server.close(); // not expecting any more connections
            }
        });

        client.setConnectCallback(new StreamConnectCallback() {
            @Override
            public void onConnect(int status, Exception error) throws Exception {
                clientLoggingCallback.log(status, error);
                client.readStart();
            }
        });

        client.setReadCallback(new StreamReadCallback() {
            @Override
            public void onRead(final ByteBuffer data) throws Exception {
                clientRecvCount.incrementAndGet();
                if (data == null) {
                    client.close();
                } else {
                    final Object[] args = {data};
                    clientLoggingCallback.log(args);
                    if (clientSendCount.incrementAndGet() < TIMES) {
                        client.write("PONG " + clientSendCount.get());
                    } else {
                        client.close();
                    }
                }
            }
        });

        client.setCloseCallback(new StreamCloseCallback() {
            @Override
            public void onClose() throws Exception {
                clientDone.set(true);
            }
        });

        server.bind(PIPE_NAME);
        server.listen(0);

        client.connect(PIPE_NAME);

        while (!serverDone.get() && !clientDone.get()) {
            loop.run();
        }

        client.close();
        server.close();

        Assert.assertEquals(serverSendCount.get(), TIMES);
        Assert.assertEquals(clientSendCount.get(), TIMES);
        Assert.assertEquals(serverRecvCount.get(), TIMES);
        Assert.assertEquals(clientRecvCount.get(), TIMES);
    }