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
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
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 == ""
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()
def server(endpoint): tchannel_server = TChannel(name='testserver', hostport='localhost:0') tchannel_server.register(endpoint, 'raw', handler_error) tchannel_server.listen() return tchannel_server
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()
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()