Ejemplo n.º 1
0
def test_retry_on_error_success():
    mock_should_retry_on_error = mock.patch('tchannel.tornado.Request.should_retry_on_error')  # noqa
    mock_should_retry_on_error.return_value = True

    endpoint = 'tchannelretrytest'
    tchannel = yield chain(2, endpoint)
    hook = MyTestHook()
    tchannel.hooks.register(hook)

    tchannel_success = TChannel(name='test', hostport='localhost:0')
    tchannel_success.register(endpoint, 'raw', handler_success)
    tchannel_success.listen()
    tchannel.peers.get(tchannel_success.hostport)

    response = yield tchannel.request().send(
        endpoint,
        "test",
        "test",
        headers={
            're': retry.CONNECTION_ERROR_AND_TIMEOUT,
        },
        ttl=1,
        retry_limit=2,
    )

    header = yield response.get_header()
    body = yield response.get_body()
    assert body == b"success"
    assert header == b""

    assert hook.received_response == 1
    assert hook.received_error == 2
Ejemplo n.º 2
0
def test_retry_on_error_success():

    endpoint = b'tchannelretrytest'
    tchannel = chain(2, endpoint)

    tchannel_success = TChannel(name='test', hostport='localhost:0')
    tchannel_success.register(endpoint, 'raw', handler_success)
    tchannel_success.listen()
    tchannel.peers.get(tchannel_success.hostport)

    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        response = yield tchannel.request(
            score_threshold=0
        ).send(
            endpoint,
            "test",
            "test",
            headers={
                're': RetryType.CONNECTION_ERROR_AND_TIMEOUT,
            },
            ttl=0.01,
            attempt_times=3,
            retry_delay=0.01,
        )

        header = yield response.get_header()
        body = yield response.get_body()
        assert body == "success"
        assert header == ""
Ejemplo n.º 3
0
def test_retry_on_error_success(mock_should_retry_on_error):
    mock_should_retry_on_error.return_value = True

    endpoint = b'tchannelretrytest'
    tchannel = yield chain(2, endpoint)
    hook = MyTestHook()
    tchannel.hooks.register(hook)

    tchannel_success = TChannel(name='test', hostport='localhost:0')
    tchannel_success.register(endpoint, 'raw', handler_success)
    tchannel_success.listen()
    tchannel.peers.get(tchannel_success.hostport)

    response = yield tchannel.request().send(
        endpoint,
        "test",
        "test",
        headers={
            're': retry.CONNECTION_ERROR_AND_TIMEOUT,
        },
        ttl=1,
        retry_limit=2,
    )

    header = yield response.get_header()
    body = yield response.get_body()
    assert body == "success"
    assert header == ""

    assert hook.received_response == 1
    assert hook.received_error == 2
Ejemplo n.º 4
0
def main():  # pragma: no cover
    import sys

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--port",
        dest="port", default=8888, type=int,
    )
    parser.add_argument(
        "--host",
        dest="host", default="127.0.0.1"
    )
    args = parser.parse_args()

    client = TChannel('%s:%d' % (args.host, args.port))

    # TODO: service=test_as_raw
    handler = RequestDispatcher()
    client.host(handler)

    # TODO: do we need to implement these differently?
    handler.register("echo", echo)
    handler.register("streaming_echo", echo)

    client.listen()
    print 'listening on', client.hostport
    sys.stdout.flush()

    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 5
0
def main():  # pragma: no cover
    args = get_args()

    client = TChannel('localhost:%d' % args.port)
    register_example_endpoints(client)
    client.listen()

    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 6
0
def main():  # pragma: no cover
    args = get_args()

    client = TChannel(
        name='tchannel_server',
        hostport='%s:%d' % (args.host, args.port),
    )

    register_example_endpoints(client)
    client.listen()

    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 7
0
def main():
    args = get_args()

    app = TChannel(
        name='raw-server',
        hostport='%s:%d' % (args.host, args.port),
    )

    register_example_endpoints(app)

    app.listen()

    print("listening on %s" % app.hostport)
    sys.stdout.flush()

    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 8
0
def test_advertise():
    server = TChannel(name="test_server")

    @server.register('ad', 'json')
    @tornado.gen.coroutine
    def ad(request, response):
        body = yield request.get_body()
        response.write_body(body)

    server.listen()
    channel = TChannel(name='test')

    response = yield hyperbahn.advertise(channel, 'test', [server.hostport])
    result = yield response.get_body()
    assert (result == '{"services": [{"serviceName": "test", "cost": 0}]}'
            or result == '{"services": [{"cost": 0, "serviceName": "test"}]}')
Ejemplo n.º 9
0
def main():
    args = get_args()

    app = TChannel(
        name='json-server',
        hostport='%s:%d' % (args.host, args.port),
    )

    register_example_endpoints(app)

    def say_hi_json(request, response, proxy):
        response.write_body({'hi': 'Hello, world!'})

    app.register(endpoint="hi-json", scheme="json", handler=say_hi_json)

    app.listen()

    tornado.ioloop.IOLoop.instance().start()
Ejemplo n.º 10
0
def test_advertise():
    server = TChannel(name="test_server")

    @server.register("ad", "json")
    @tornado.gen.coroutine
    def ad(request, response):
        body = yield request.get_body()
        response.write_body(body)

    server.listen()
    channel = TChannel(name="test")

    response = yield hyperbahn.advertise(channel, "test", [server.hostport])
    result = yield response.get_body()
    assert (
        result == '{"services": [{"serviceName": "test", "cost": 0}]}'
        or result == '{"services": [{"cost": 0, "serviceName": "test"}]}'
    )
Ejemplo n.º 11
0
def test_false_result(thrift_service):
    # Verify that we aren't treating False as None.

    app = TChannel(name='app')

    @app.register(thrift_service)
    def healthy(request, response):
        return False

    app.listen()

    client = TChannel(name='client')
    response = yield client.request(hostport=app.hostport,
                                    arg_scheme='thrift').send(
                                        'Service::healthy', '\x00\x00', '\x00')

    body = yield response.get_body()
    assert body == '\x02\x00\x00\x00\x00'
def test_false_result(thrift_service):
    # Verify that we aren't treating False as None.

    app = TChannel(name='app')

    @app.register(thrift_service)
    def healthy(request, response):
        return False

    app.listen()

    client = TChannel(name='client')
    response = yield client.request(
        hostport=app.hostport, arg_scheme='thrift'
    ).send('Service::healthy', '\x00\x00', '\x00')

    body = yield response.get_body()
    assert body == '\x02\x00\x00\x00\x00'
Ejemplo n.º 13
0
def test_close_stops_listening():
    server = TChannel(name='server')
    server.listen()

    host = server.host
    port = server.port

    # Can connect
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))
    sock.close()

    server.close()

    # Can't connect
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    with pytest.raises(socket.error):
        sock.connect((host, port))
Ejemplo n.º 14
0
def test_close_stops_listening():
    server = TChannel(name='server')
    server.listen()

    host = server.host
    port = server.port

    # Can connect
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((host, port))
    sock.close()

    server.close()

    # Can't connect
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    with pytest.raises(socket.error):
        sock.connect((host, port))
Ejemplo n.º 15
0
class Fakebahn(object):
    def __init__(self, handle):
        self.tchannel = TChannel(name='hyperbahn')
        self.count = 0  # number of ad requests received

        @self.tchannel.register('ad', 'json')
        @gen.coroutine
        def ad(request, response):
            self.count += 1
            yield handle(request, response)

    @property
    def hostport(self):
        return self.tchannel.hostport

    def start(self):
        self.tchannel.listen()

    def stop(self):
        self.tchannel.close()
Ejemplo n.º 16
0
class Fakebahn(object):

    def __init__(self, handle):
        self.tchannel = TChannel(name='hyperbahn')
        self.count = 0  # number of ad requests received

        @self.tchannel.register('ad', 'json')
        @gen.coroutine
        def ad(request, response):
            self.count += 1
            yield handle(request, response)

    @property
    def hostport(self):
        return self.tchannel.hostport

    def start(self):
        self.tchannel.listen()

    def stop(self):
        self.tchannel.close()
Ejemplo n.º 17
0
def server(endpoint):
    tchannel_server = TChannel(name='testserver', hostport='localhost:0')
    tchannel_server.register(endpoint, 'raw', handler_error)
    tchannel_server.listen()
    return tchannel_server
Ejemplo n.º 18
0
class VCRProxyService(object):
    def __init__(self, cassette, unpatch):
        """
        :param unpatch:
            A function returning a context manager which temporarily unpatches
            any monkey patched code so that a real request can be made.
        :param cassette:
            Cassette being played.
        """
        self.unpatch = unpatch
        self.cassette = cassette

        self.tchannel = TChannel("proxy-server")
        self.tchannel.register(VCRProxy, handler=self.send)

    @wrap_uncaught(
        reraise=(VCRProxy.CannotRecordInteractionsError, VCRProxy.RemoteServiceError, VCRProxy.VCRServiceError)
    )
    @gen.coroutine
    def send(self, request, response):
        cassette = self.cassette
        request = request.args.request

        # TODO decode requests and responses based on arg scheme into more
        # readable formats.

        # Because Thrift doesn't handle UTF-8 correctly right now
        request.serviceName = request.serviceName.decode("utf-8")
        request.endpoint = request.endpoint.decode("utf-8")

        # TODO do we care about hostport being the same?
        if cassette.can_replay(request):
            vcr_response = cassette.replay(request)
            raise gen.Return(vcr_response)

        if cassette.write_protected:
            raise VCRProxy.CannotRecordInteractionsError(
                "Could not find a matching response for request %s and the "
                "record mode %s prevents new interactions from being "
                "recorded. Your test may be performing an uenxpected "
                "request." % (str(request), cassette.record_mode)
            )

        arg_scheme = VCRProxy.ArgScheme.to_name(request.argScheme).lower()

        with self.unpatch():
            # TODO propagate other request and response parameters
            # TODO might make sense to tag all VCR requests with a protocol
            # header of some kind
            response_future = self.tchannel.request(
                service=request.serviceName, arg_scheme=arg_scheme, hostport=request.hostPort
            ).send(
                request.endpoint,
                request.headers,
                request.body,
                headers={h.key: h.value for h in request.transportHeaders},
            )

        # Don't actually yield while everything is unpatched.
        try:
            response = yield response_future
        except TChannelError as e:
            raise VCRProxy.RemoteServiceError(code=e.code, message=e.message)
        response_headers = yield response.get_header()
        response_body = yield response.get_body()

        vcr_response = VCRProxy.Response(response.status_code, response_headers, response_body)
        cassette.record(request, vcr_response)
        raise gen.Return(vcr_response)

    @property
    def hostport(self):
        return self.tchannel.hostport

    def start(self):
        self.tchannel.listen()

    def stop(self):
        self.tchannel.close()

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, *args):
        self.stop()
Ejemplo n.º 19
0
def server(endpoint):
    tchannel_server = TChannel(name='testserver', hostport='localhost:0')
    tchannel_server.register(endpoint, 'raw', handler_error)
    tchannel_server.listen()
    return tchannel_server
Ejemplo n.º 20
0
class VCRProxyService(object):
    def __init__(self, cassette, unpatch):
        """
        :param unpatch:
            A function returning a context manager which temporarily unpatches
            any monkey patched code so that a real request can be made.
        :param cassette:
            Cassette being played.
        """
        self.unpatch = unpatch
        self.cassette = cassette

        self.io_loop = None
        self.thread = None
        self.tchannel = None

        self._running = threading.Event()

    @wrap_uncaught(reraise=(
        VCRProxy.CannotRecordInteractionsError,
        VCRProxy.RemoteServiceError,
        VCRProxy.VCRServiceError,
    ))
    @gen.coroutine
    def send(self, request, response):
        cassette = self.cassette
        request = request.args.request

        # TODO decode requests and responses based on arg scheme into more
        # readable formats.

        # Because Thrift doesn't handle UTF-8 correctly right now
        request.serviceName = request.serviceName.decode('utf-8')
        request.endpoint = request.endpoint.decode('utf-8')

        # TODO do we care about hostport being the same?
        if cassette.can_replay(request):
            vcr_response = cassette.replay(request)
            raise gen.Return(vcr_response)

        if cassette.write_protected:
            raise VCRProxy.CannotRecordInteractionsError(
                'Could not find a matching response for request %s and the '
                'record mode %s prevents new interactions from being '
                'recorded. Your test may be performing an uenxpected '
                'request.' % (str(request), cassette.record_mode))

        arg_scheme = VCRProxy.ArgScheme.to_name(request.argScheme).lower()

        with self.unpatch():
            # TODO propagate other request and response parameters
            # TODO might make sense to tag all VCR requests with a protocol
            # header of some kind
            response_future = self.tchannel.request(
                service=request.serviceName,
                arg_scheme=arg_scheme,
                hostport=request.hostPort,
            ).send(
                request.endpoint,
                request.headers,
                request.body,
                headers={h.key: h.value
                         for h in request.transportHeaders},
            )

        # Don't actually yield while everything is unpatched.
        try:
            response = yield response_future
        except TChannelError as e:
            raise VCRProxy.RemoteServiceError(
                code=e.code,
                message=e.message,
            )
        response_headers = yield response.get_header()
        response_body = yield response.get_body()

        vcr_response = VCRProxy.Response(
            response.status_code,
            response_headers,
            response_body,
        )
        cassette.record(request, vcr_response)
        raise gen.Return(vcr_response)

    @property
    def hostport(self):
        return self.tchannel.hostport

    def _run(self):
        self.io_loop = IOLoop()
        self.io_loop.make_current()

        self.tchannel = TChannel('proxy-server')
        self.tchannel.register(VCRProxy, handler=self.send)

        self.tchannel.listen()
        self._running.set()
        self.io_loop.start()

    def start(self):
        self.thread = threading.Thread(target=self._run)
        self.thread.start()

        self._running.wait(1)

    def stop(self):
        self.tchannel.close()
        self.tchannel = None

        self.io_loop.stop()
        self.io_loop = None

        self.thread.join(1)  # seconds
        self.thread = None

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, *args):
        self.stop()