'--status={0}:{1}'.format(LOCALHOST, STATUS_PORT)
        ])

        # create connections with client
        pair1 = SocketPair(TlsClient('client', 'root', 13001),
                           TcpServer(13002))
        pair1.validate_can_send_from_client("toto", "pair1 works")
        pair1.validate_tunnel_ou("server", "pair1 -> ou=server")

        # Replace keystore and trigger reload
        os.rename('new_server.p12', 'server.p12')
        ghostunnel.send_signal(signal.SIGUSR1)

        TlsClient(None, 'root', STATUS_PORT).connect(20, 'new_server')
        print_ok("reload done")

        # create connections with client
        pair2 = SocketPair(TlsClient('client', 'root', 13001),
                           TcpServer(13002))
        pair2.validate_can_send_from_client("toto", "pair2 works")
        pair2.validate_tunnel_ou("new_server", "pair2 -> ou=new_server")
        pair2.cleanup()

        # ensure that pair1 is still alive
        pair1.validate_can_send_from_client("toto", "pair1 still works")
        pair1.cleanup()

        print_ok("OK")
    finally:
        terminate(ghostunnel)
            raise Exception('failed to reject other_server')
        except ssl.SSLError:
            print_ok("other_server correctly rejected")

        # connect to server2, confirm that the tunnel isn't up
        try:
            pair = SocketPair(TcpClient(13001), TlsServer(
                'server1', 'root', 13002))
            raise Exception('failed to reject server1')
        except ssl.SSLError:
            print_ok("server1 correctly rejected")

        # make sure also works after reload
        ghostunnel.send_signal(signal.SIGUSR1)
        TlsClient(None, 'root', STATUS_PORT).connect(20, 'client')
        print_ok("reload done")

        pair2 = SocketPair(TcpClient(13001), TlsServer(
            'server2', 'root', 13002))
        pair2.validate_can_send_from_client(
            "hello world", "1: client -> server")
        pair2.validate_can_send_from_server(
            "hello world", "1: server -> client")
        pair2.validate_closing_client_closes_server(
            "1: client closed -> server closed")
        pair2.cleanup()

        print_ok("OK")
    finally:
        terminate(ghostunnel)
                           TcpServer(13002))
        pair2.validate_can_send_from_client("hello world",
                                            "1: client -> server")
        pair2.validate_can_send_from_server("hello world",
                                            "1: server -> client")
        pair2.validate_closing_client_closes_server(
            "1: client closed -> server closed")

        # connect with client2, confirm that the tunnel isn't up
        try:
            pair = SocketPair(TlsClient('client2', 'root', 13001),
                              TcpServer(13002))
        except ssl.SSLError:
            raise Exception(
                'rejected unauthenticated client2, despite --disable-authentication'
            )

        # connect with other_client1, confirm that the tunnel isn't up
        try:
            pair = SocketPair(TlsClient('other_client1', 'root', 13001),
                              TcpServer(13002))
        except ssl.SSLError:
            raise Exception(
                'rejected authenticated other_client1, despite --disable-authentication'
            )

        pair.cleanup()
        print_ok("OK")
    finally:
        terminate(ghostunnel)
        def urlopen(path):
            return urllib.request.urlopen(path, cafile='root.crt')

        # block until ghostunnel is up
        TcpClient(STATUS_PORT).connect(20)

        # send some requests to status endpoints
        metrics = json.loads(str(urlopen(
            'https://{0}:{1}/_metrics'.format(LOCALHOST, STATUS_PORT)).read(), 'utf-8'))

        # send some data through proxy
        pair1 = SocketPair(
                TlsClient('client', 'root', 13001), TcpServer(13002))
        pair1.validate_can_send_from_client('toto', 'works')
        pair1.validate_can_send_from_server('toto', 'works')
        pair1.cleanup()

        terminate(ghostunnel)

        # make sure no logs printed
        out, err = ghostunnel.communicate()

        print('stdout (len={0}):'.format(len(out)))
        print(out)
        print('stderr (len={0}):'.format(len(err)))
        print(err)

        if len(err) > 0:
            raise Exception('ghostunnel logged to stderr with --quiet=all')

        print_ok('OK')
    try:
        # create certs
        root = RootCert('root')
        root.create_signed_cert('server')
        root.create_signed_cert('client')

        # start ghostunnel
        ghostunnel = run_ghostunnel(['server',
                                     '--listen={0}:13001'.format(LOCALHOST),
                                     '--target={0}:13002'.format(LOCALHOST),
                                     '--keystore=server.p12',
                                     '--status={0}:{1}'.format(LOCALHOST,
                                                               STATUS_PORT),
                                     '--cacert=root.crt',
                                     '--allow-ou=client'])

        # client should fail to connect since nothing is listening on 13003
        try:
            pair = SocketPair(
                TlsClient('client', 'root', 13001), TcpServer(13003))
            raise Exception('client should have failed to connect')
        except socket.timeout:
            print_ok("timeout when nothing is listening on 13003")

        # client should connect
        pair = SocketPair(TlsClient('client', 'root', 13001), TcpServer(13002))
        pair.cleanup()
        print_ok("OK")
    finally:
        terminate(ghostunnel)