def test_responder_worker_exc(mock_producer): message = Mock() message.properties = {'reply_to': ''} exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) # serialisable exception worker_exc = Exception('error') result, exc_info = responder.send_response(None, (Exception, worker_exc, "tb")) assert result is None assert exc_info == (Exception, worker_exc, "tb") expected_msg = { 'result': None, 'error': { 'exc_path': '{}.Exception'.format(EXCEPTION_MODULE), 'value': 'error', 'exc_type': 'Exception', 'exc_args': ['error'] } } (msg, ), _ = mock_producer.publish.call_args assert msg == expected_msg
def test_responder_unserializable_result( mock_publish, unserializable, serializer, exception_info_string): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: '', SERIALIZER_CONFIG_KEY: serializer} responder = Responder(config, message) # unserialisable result worker_result = unserializable result, exc_info = responder.send_response(worker_result, None) # responder will return the error from the serializer assert result is None # Different kombu versions return different exceptions, so # testing for the concrete exception is not feasible assert exc_info == (ANY, ANY, ANY) assert exception_info_string in str(exc_info[1]) # and publish a dictionary-serialized UnserializableValueError # on worker_result expected_msg = { 'result': None, 'error': { 'exc_path': 'nameko.exceptions.UnserializableValueError', 'value': 'Unserializable value: `{}`'.format(worker_result), 'exc_type': 'UnserializableValueError', 'exc_args': [], } } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_unserializable_result( message, mock_producer, unserializable, serializer, content_type, exception_info_string): message.properties['content_type'] = content_type exchange = Mock() responder = Responder('amqp://localhost', exchange, serializer, message) # unserialisable result worker_result = unserializable result, exc_info = responder.send_response(worker_result, None) # responder will return the error from the serializer assert result is None # Different kombu versions return different exceptions, so # testing for the concrete exception is not feasible assert exc_info == (ANY, ANY, ANY) assert exception_info_string in str(exc_info[1]) # and publish a dictionary-serialized UnserializableValueError # on worker_result expected_msg = { 'result': None, 'error': { 'exc_path': 'nameko.exceptions.UnserializableValueError', 'value': 'Unserializable value: `{}`'.format(worker_result), 'exc_type': 'UnserializableValueError', 'exc_args': [], } } (msg,), _ = mock_producer.publish.call_args assert msg == expected_msg
def test_responder_unserializable_exc(mock_publish): message = Mock() message.properties = {"reply_to": ""} container = Mock() container.config = {AMQP_URI_CONFIG_KEY: ""} responder = Responder(message) # unserialisable exception worker_exc = Exception(object()) result, exc_info = responder.send_response(container, True, (Exception, worker_exc, "tb")) # responder will return the TypeError from json.dumps assert result is None assert exc_info == (TypeError, ANY, ANY) assert exc_info[1].message == ("{} is not JSON " "serializable".format(worker_exc.args[0])) # and publish a dictionary-serialized UnserializableValueError # (where the unserialisable value is a dictionary-serialized worker_exc) serialized_exc = serialize(worker_exc) expected_msg = { "result": None, "error": { "exc_path": "nameko.exceptions.UnserializableValueError", "value": "Unserializable value: `{}`".format(serialized_exc), "exc_type": "UnserializableValueError", "exc_args": (), }, } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_worker_exc(mock_publish): message = Mock() message.properties = {"reply_to": ""} container = Mock() container.config = {AMQP_URI_CONFIG_KEY: ""} responder = Responder(message) # serialisable exception worker_exc = Exception("error") result, exc_info = responder.send_response(container, None, (Exception, worker_exc, "tb")) assert result is None assert exc_info == (Exception, worker_exc, "tb") expected_msg = { "result": None, "error": { "exc_path": "exceptions.Exception", "value": "error", "exc_type": "Exception", "exc_args": ("error",), }, } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_worker_exc(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # serialisable exception worker_exc = Exception('error') result, exc_info = responder.send_response( None, (Exception, worker_exc, "tb")) assert result is None assert exc_info == (Exception, worker_exc, "tb") expected_msg = { 'result': None, 'error': { 'exc_path': '{}.Exception'.format(EXCEPTION_MODULE), 'value': 'error', 'exc_type': 'Exception', 'exc_args': ['error'] } } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_unserializable_result(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # unserialisable result worker_result = object() result, exc_info = responder.send_response(worker_result, None) # responder will return the TypeError from json.dumps assert result is None assert exc_info == (TypeError, ANY, ANY) assert str(exc_info[1]) == "{} is not JSON serializable".format( worker_result) # and publish a dictionary-serialized UnserializableValueError # on worker_result expected_msg = { 'result': None, 'error': { 'exc_path': 'nameko.exceptions.UnserializableValueError', 'value': 'Unserializable value: `{}`'.format(worker_result), 'exc_type': 'UnserializableValueError', 'exc_args': [], } } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_unserializable_result(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # unserialisable result worker_result = object() result, exc_info = responder.send_response(worker_result, None) # responder will return the TypeError from json.dumps assert result is None assert exc_info == (TypeError, ANY, ANY) assert str( exc_info[1]) == "{} is not JSON serializable".format(worker_result) # and publish a dictionary-serialized UnserializableValueError # on worker_result expected_msg = { 'result': None, 'error': { 'exc_path': 'nameko.exceptions.UnserializableValueError', 'value': 'Unserializable value: `{}`'.format(worker_result), 'exc_type': 'UnserializableValueError', 'exc_args': [], } } (msg, ), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_worker_exc(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # serialisable exception worker_exc = Exception('error') result, exc_info = responder.send_response(None, (Exception, worker_exc, "tb")) assert result is None assert exc_info == (Exception, worker_exc, "tb") expected_msg = { 'result': None, 'error': { 'exc_path': '{}.Exception'.format(EXCEPTION_MODULE), 'value': 'error', 'exc_type': 'Exception', 'exc_args': ['error'] } } (msg, ), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_unserializable_exc(mock_publish): message = Mock() message.properties = {'reply_to': ''} container = Mock() container.config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(message) # unserialisable exception worker_exc = Exception(object()) result, exc_info = responder.send_response(container, True, (Exception, worker_exc, "tb")) # responder will return the TypeError from json.dumps assert result is None assert exc_info == (TypeError, ANY, ANY) assert exc_info[1].message == ("{} is not JSON " "serializable".format(worker_exc.args[0])) # and publish a dictionary-serialized UnserializableValueError # (where the unserialisable value is a dictionary-serialized worker_exc) serialized_exc = serialize(worker_exc) expected_msg = { 'result': None, 'error': { 'exc_path': 'nameko.exceptions.UnserializableValueError', 'value': 'Unserializable value: `{}`'.format(serialized_exc), 'exc_type': 'UnserializableValueError', 'exc_args': () } } (msg, ), _ = mock_publish.call_args assert msg == expected_msg
def test_responder(message, mock_producer): exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) # serialisable result result, exc_info = responder.send_response(True, None) assert result is True assert exc_info is None expected_msg = {'result': True, 'error': None} (msg, ), _ = mock_producer.publish.call_args assert msg == expected_msg
def test_unexpected_correlation_id(container_factory, rabbit_config): container = container_factory(FooService, rabbit_config) container.start() with ServiceRpcProxy("foobar", rabbit_config) as proxy: message = Message(channel=None, properties={ 'reply_to': proxy.reply_listener.routing_key, 'correlation_id': 'invalid', }) responder = Responder(container.config, message) with patch('nameko.standalone.rpc._logger', autospec=True) as logger: responder.send_response(None, None) assert proxy.spam(ham='eggs') == 'eggs' assert logger.debug.call_count == 1
def test_responder_cannot_repr_exc(message, mock_producer): exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) class CannotRepr(object): def __repr__(self): raise Exception('error') # un-repr-able exception worker_exc = Exception(CannotRepr()) # send_response should not throw responder.send_response(True, (Exception, worker_exc, "tb"))
def test_responder(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # serialisable result result, exc_info = responder.send_response(True, None) assert result is True assert exc_info is None expected_msg = {'result': True, 'error': None} (msg, ), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_cannot_unicode_exc(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) class CannotUnicode(object): def __str__(self): raise Exception('error') # un-unicode-able exception worker_exc = Exception(CannotUnicode()) # send_response should not throw responder.send_response(True, (Exception, worker_exc, "tb"))
def test_responder_cannot_repr_exc(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) class CannotRepr(object): def __repr__(self): raise Exception('error') # un-repr-able exception worker_exc = Exception(CannotRepr()) # send_response should not throw responder.send_response(True, (Exception, worker_exc, "tb"))
def test_responder(message, mock_producer): exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) # serialisable result result, exc_info = responder.send_response(True, None) assert result is True assert exc_info is None expected_msg = { 'result': True, 'error': None } (msg,), _ = mock_producer.publish.call_args assert msg == expected_msg
def test_responder(mock_publish): message = Mock() message.properties = {"reply_to": ""} container = Mock() container.config = {AMQP_URI_CONFIG_KEY: ""} responder = Responder(message) # serialisable result result, exc_info = responder.send_response(container, True, None) assert result is True assert exc_info is None expected_msg = {"result": True, "error": None} (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_cannot_unicode_exc(mock_producer): message = Mock() message.properties = {'reply_to': ''} exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) class CannotUnicode(object): def __str__(self): raise Exception('error') # un-unicode-able exception worker_exc = Exception(CannotUnicode()) # send_response should not throw responder.send_response(True, (Exception, worker_exc, "tb"))
def test_responder(mock_publish): message = Mock() message.properties = {'reply_to': ''} config = {AMQP_URI_CONFIG_KEY: ''} responder = Responder(config, message) # serialisable result result, exc_info = responder.send_response(True, None) assert result is True assert exc_info is None expected_msg = { 'result': True, 'error': None } (msg,), _ = mock_publish.call_args assert msg == expected_msg
def test_responder_cannot_unicode_exc(mock_publish): message = Mock() message.properties = {"reply_to": ""} container = Mock() container.config = {AMQP_URI_CONFIG_KEY: ""} responder = Responder(message) class CannotUnicode(object): def __str__(self): raise Exception("error") # un-unicode-able exception worker_exc = Exception(CannotUnicode()) # send_response should not throw responder.send_response(container, True, (Exception, worker_exc, "tb"))
def rpc_consumer_handle_result(self, message, result, exc_info): from sv_base.extensions.service.rpc import RpcResult if isinstance(result, RpcResult): rpc_result = result amqp_uri = self.container.config[AMQP_URI_CONFIG_KEY] serializer = self.container.config.get(SERIALIZER_CONFIG_KEY, DEFAULT_SERIALIZER) exchange = get_rpc_exchange(self.container.config) ssl = self.container.config.get(AMQP_SSL_CONFIG_KEY) responder = Responder(amqp_uri, exchange, serializer, message, ssl=ssl) result, exc_info = responder.send_response(rpc_result.result, exc_info) self.queue_consumer.ack_message(message) if rpc_result.rely_callback: rpc_result.rely_callback() return result, exc_info else: return _rpc_consumer_handle_result_default(self, message, result, exc_info)
def test_responder_worker_exc(message, mock_producer): exchange = Mock() responder = Responder('amqp://localhost', exchange, 'json', message) # serialisable exception worker_exc = Exception('error') result, exc_info = responder.send_response( None, (Exception, worker_exc, "tb")) assert result is None assert exc_info == (Exception, worker_exc, "tb") expected_msg = { 'result': None, 'error': { 'exc_path': '{}.Exception'.format(EXCEPTION_MODULE), 'value': 'error', 'exc_type': 'Exception', 'exc_args': ['error'] } } (msg,), _ = mock_producer.publish.call_args assert msg == expected_msg
def replacement_constructor(amqp_uri, *args): return Responder(toxiproxy.uri, *args)