def test_consume_from_rabbit(container_factory, rabbit_manager, rabbit_config): vhost = rabbit_config["vhost"] container = Mock(spec=ServiceContainer) container.shared_extensions = {} container.worker_ctx_cls = CustomWorkerContext container.service_name = "service" container.config = rabbit_config container.max_workers = 10 def spawn_thread(method, protected): return eventlet.spawn(method) container.spawn_managed_thread = spawn_thread worker_ctx = CustomWorkerContext(container, None, DummyProvider()) consumer = Consumer(queue=foobar_queue, requeue_on_error=False).bind(container, "publish") # prepare and start extensions consumer.setup() consumer.queue_consumer.setup() consumer.start() consumer.queue_consumer.start() # test queue, exchange and binding created in rabbit exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name) assert "foobar_ex" in [exchange["name"] for exchange in exchanges] assert "foobar_queue" in [queue["name"] for queue in queues] assert "foobar_ex" in [binding["source"] for binding in bindings] # test message consumed from queue container.spawn_worker.return_value = worker_ctx headers = {"nameko.language": "en", "nameko.customheader": "customvalue"} rabbit_manager.publish(vhost, foobar_ex.name, "", "msg", properties=dict(headers=headers)) ctx_data = {"language": "en", "customheader": "customvalue"} with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method: method.assert_called_once_with(consumer, ("msg",), {}, context_data=ctx_data, handle_result=ANY_PARTIAL) handle_result = method.call_args[1]["handle_result"] # ack message handle_result(worker_ctx, "result") # stop will hang if the consumer hasn't acked or requeued messages with eventlet.timeout.Timeout(CONSUME_TIMEOUT): consumer.stop() consumer.queue_consumer.kill()
def test_consume_provider(mock_container): container = mock_container container.shared_extensions = {} container.service_name = "service" worker_ctx = WorkerContext(container, None, DummyProvider()) spawn_worker = container.spawn_worker spawn_worker.return_value = worker_ctx queue_consumer = Mock() consume_provider = Consumer( queue=foobar_queue, requeue_on_error=False).bind(container, "consume") consume_provider.queue_consumer = queue_consumer message = Mock(headers={}) # test lifecycle consume_provider.setup() queue_consumer.register_provider.assert_called_once_with( consume_provider) consume_provider.stop() queue_consumer.unregister_provider.assert_called_once_with( consume_provider) # test handling successful call queue_consumer.reset_mock() consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, 'result') queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call without requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = False consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, (Exception, Exception('Error'), "tb")) queue_consumer.ack_message.assert_called_once_with(message) # test handling failed call with requeue queue_consumer.reset_mock() consume_provider.requeue_on_error = True consume_provider.handle_message("body", message) handle_result = spawn_worker.call_args[1]['handle_result'] handle_result(worker_ctx, None, (Exception, Exception('Error'), "tb")) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message) # test requeueing on ContainerBeingKilled (even without requeue_on_error) queue_consumer.reset_mock() consume_provider.requeue_on_error = False spawn_worker.side_effect = ContainerBeingKilled() consume_provider.handle_message("body", message) assert not queue_consumer.ack_message.called queue_consumer.requeue_message.assert_called_once_with(message)
def test_consume_from_rabbit(rabbit_manager, rabbit_config, mock_container): vhost = rabbit_config['vhost'] container = mock_container container.shared_extensions = {} container.worker_ctx_cls = WorkerContext container.service_name = "service" container.config = rabbit_config container.max_workers = 10 content_type = 'application/data' container.accept = [content_type] def spawn_managed_thread(method, identifier=None): return eventlet.spawn(method) container.spawn_managed_thread = spawn_managed_thread worker_ctx = WorkerContext(container, None, DummyProvider()) consumer = Consumer( queue=foobar_queue, requeue_on_error=False).bind(container, "publish") # prepare and start extensions consumer.setup() consumer.queue_consumer.setup() consumer.start() consumer.queue_consumer.start() # test queue, exchange and binding created in rabbit exchanges = rabbit_manager.get_exchanges(vhost) queues = rabbit_manager.get_queues(vhost) bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name) assert "foobar_ex" in [exchange['name'] for exchange in exchanges] assert "foobar_queue" in [queue['name'] for queue in queues] assert "foobar_ex" in [binding['source'] for binding in bindings] # test message consumed from queue container.spawn_worker.return_value = worker_ctx headers = {'nameko.language': 'en', 'nameko.customheader': 'customvalue'} rabbit_manager.publish( vhost, foobar_ex.name, '', 'msg', properties=dict(headers=headers, content_type=content_type)) ctx_data = { 'language': 'en', 'customheader': 'customvalue', } with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method: method.assert_called_once_with(consumer, ('msg',), {}, context_data=ctx_data, handle_result=ANY_PARTIAL) handle_result = method.call_args[1]['handle_result'] # ack message handle_result(worker_ctx, 'result') # stop will hang if the consumer hasn't acked or requeued messages with eventlet.timeout.Timeout(CONSUME_TIMEOUT): consumer.stop() consumer.queue_consumer.kill()