def test_build_handler(): def call(treq, tres, tchan): assert treq.transport.headers == { 'as': 'thrift', 'cn': 'test_caller' } tres.write_header('foo', 'baar') return "world" response_header = InMemStream() response_body = InMemStream() req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], scheme=ThriftArgScheme(FakeResult), headers={'cn': 'test_caller', 'as': 'thrift'}, ) req.close_argstreams() res = Response( argstreams=[ InMemStream(), response_header, response_body, ], scheme=ThriftArgScheme(FakeResult), ) tchannel = mock.Mock() handler = build_handler(FakeResult, call) yield handler(req, res, tchannel) serialized_headers = yield response_header.read() assert serialized_headers == bytearray( [ 0x00, 0x01, # num headers = 1 0x00, 0x03, # strlen('foo') = 3 ] + list('foo') + [ 0x00, 0x04, # strlen('baar') = 4 ] + list('baar') ) serialized_body = yield response_body.read() assert serialized_body == bytearray([ 0x0b, # field type = TType.STRING 0x00, 0x00, # field ID = 0 0x00, 0x00, 0x00, 0x05, # string length = 5 ] + list("world") + [ 0x00, # end struct ]) assert 0 == res.status_code
def test_deprecated_build_handler(): def call(treq, tres): assert treq.transport.headers == { 'as': 'thrift', 'cn': 'test_caller' } tres.write_header('foo', 'baar') return "world" response_header = InMemStream() response_body = InMemStream() req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], serializer=ThriftSerializer(FakeResult), headers={'cn': 'test_caller', 'as': 'thrift'}, ) req.close_argstreams() res = Response( argstreams=[ InMemStream(), response_header, response_body, ], serializer=ThriftSerializer(FakeResult), ) handler = deprecated_build_handler(FakeResult, call) yield handler(req, res) serialized_headers = yield response_header.read() assert serialized_headers == bytearray( [ 0x00, 0x01, # num headers = 1 0x00, 0x03, # strlen('foo') = 3 ] + list('foo') + [ 0x00, 0x04, # strlen('baar') = 4 ] + list('baar') ) serialized_body = yield response_body.read() assert serialized_body == bytearray([ 0x0b, # field type = TType.STRING 0x00, 0x00, # field ID = 0 0x00, 0x00, 0x00, 0x05, # string length = 5 ] + list("world") + [ 0x00, # end struct ]) assert 0 == res.status_code
def test_deprecated_build_handler_exception(): def call(treq, tres): raise FakeException('fail') response_body = mock.Mock(spec=InMemStream) req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], serializer=ThriftSerializer(FakeResult), ) req.close_argstreams() res = Response( argstreams=[ InMemStream(), InMemStream(), response_body, ], serializer=ThriftSerializer(FakeResult), ) handler = deprecated_build_handler(FakeResult, call) yield handler(req, res) response_body.write.assert_called_once_with( bytearray([ 0x0c, # field type = TType.STRUCT 0x00, 0x01, # field ID = 1 0x0b, # field type = TType.STRING 0x00, 0x01, # field ID = 1 0x00, 0x00, 0x00, 0x04, # string length = 5 ] + list(b"fail") + [ 0x00, # end exception struct 0x00, # end response struct ])) assert 1 == res.status_code
def test_build_handler_application_exception(): def call(req): raise FakeException('fail') req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], serializer=ThriftSerializer(FakeResult), ) req.close_argstreams() handler = build_handler(FakeResult, call) res = yield handler(req) assert res.status == 1
def test_build_handler_exception(): def call(treq, tres, tchan): raise FakeException('fail') response_body = mock.Mock(spec=InMemStream) req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], scheme=ThriftArgScheme(FakeResult), ) req.close_argstreams() res = Response( argstreams=[ InMemStream(), InMemStream(), response_body, ], scheme=ThriftArgScheme(FakeResult), ) tchannel = mock.Mock() handler = build_handler(FakeResult, call) yield handler(req, res, tchannel) response_body.write.assert_called_once_with( bytearray([ 0x0c, # field type = TType.STRUCT 0x00, 0x01, # field ID = 1 0x0b, # field type = TType.STRING 0x00, 0x01, # field ID = 1 0x00, 0x00, 0x00, 0x04, # string length = 5 ] + list("fail") + [ 0x00, # end exception struct 0x00, # end response struct ]) ) assert 1 == res.status_code
def test_loop_failure(tornado_pair): server, client = tornado_pair headers = dummy_headers() # ... yeah server.tchannel = mock.MagicMock() server.tchannel.event_emitter.fire.return_value = gen.maybe_future(None) client.tchannel = mock.MagicMock() client.tchannel.event_emitter.fire.return_value = gen.maybe_future(None) handshake_future = client.initiate_handshake(headers=headers) yield server.expect_handshake(headers=headers) yield handshake_future assert client._handshake_performed assert server._handshake_performed # We'll put an invalid message into the reader queue. This should cause one # iteration of the loop to fail but the system should continue working # afterwards. yield server.reader.queue.put(gen.maybe_future(42)) # not a message id = client.writer.next_message_id() response_future = client.send_request( Request( id=id, service='server', endpoint='bar', headers={'cn': 'client'}, )) call_req = yield server. await () assert call_req.message_type == messages.Types.CALL_REQ response = Response(id=id) response.close_argstreams(force=True) yield server.post_response(response) yield response_future assert client._handshake_performed assert server._handshake_performed client.close() # The system needs a little time to recognize that the connections were # closed. yield gen.sleep(0.15) assert client.closed assert server.closed
def test_build_handler(): def call(treq, tres, tchan): return "world" response_body = mock.Mock(spec=InMemStream) req = Request( argstreams=[ InMemStream('hello'), InMemStream('\00\00'), # no headers InMemStream('\00'), # empty struct ], scheme=ThriftArgScheme(FakeResult), ) req.close_argstreams() res = Response( argstreams=[ InMemStream(), InMemStream(), response_body, ], scheme=ThriftArgScheme(FakeResult), ) tchannel = mock.Mock() handler = build_handler(FakeResult, call) yield handler(req, res, tchannel) response_body.write.assert_called_once_with( bytearray([ 0x0b, # field type = TType.STRING 0x00, 0x00, # field ID = 0 0x00, 0x00, 0x00, 0x05, # string length = 5 ] + list("world") + [ 0x00, # end struct ]) ) assert 0 == res.status_code
def test_transport_metadata_creation(): request = Request( id=42, flags=FlagsType.fragment, ttl=100, service='some_service', headers={'cn': 'another_service', 'as': 'thrift'} ) meta = TransportMetadata.from_request(request) assert 42 == meta.id assert FlagsType.fragment == meta.flags assert 100 == meta.ttl assert 'some_service' == meta.service assert {'cn': 'another_service', 'as': 'thrift'} == meta.headers
def test_writer_serialization_error(): server = TChannel('server') server.listen() conn = yield connection.StreamConnection.outgoing( server.hostport, tchannel=mock.MagicMock()) with pytest.raises(AttributeError) as exc_info: yield conn.send_request( Request( id=conn.writer.next_message_id(), service='foo', endpoint='bar', headers={'cn': None}, )) assert "'NoneType' object has no attribute 'encode'" in str(exc_info)
def test_timeout_not_pending(tornado_pair): server, client = tornado_pair headers = dummy_headers() server.tchannel = mock.MagicMock() client.tchannel = mock.MagicMock() handshake_future = client.initiate_handshake(headers=headers) yield server.expect_handshake(headers=headers) yield handshake_future # Make a request that times out and ensure that a late response is # discarded correctly. id = client.writer.next_message_id() response_future = client.send_request( Request( id=id, service='server', endpoint='bar', headers={'cn': 'client'}, ttl=0.05, )) assert id in client._outbound_pending_call call_req = yield server. await () assert call_req.message_type == messages.Types.CALL_REQ yield gen.sleep(0.1) # make the request time out assert id in client._request_tombstones assert id not in client._outbound_pending_call # late response yield server.write( messages.ErrorMessage( id=id, code=messages.ErrorCode.unexpected, description='great sadness', )) with pytest.raises(TimeoutError): yield response_future