Beispiel #1
0
def test_worker_context_gets_stack(container_factory):
    context_cls = worker_context_factory()

    class FooService(object):
        name = 'baz'

    container = container_factory(FooService, {})
    service = FooService()

    context = context_cls(container, service, DummyProvider("bar"))
    assert context.call_id == 'baz.bar.0'
    assert context.call_id_stack == ['baz.bar.0']
    assert context.parent_call_stack == []

    # Build stack
    context = context_cls(container,
                          service,
                          DummyProvider("foo"),
                          data={'call_id_stack': context.call_id_stack})
    assert context.call_id == 'baz.foo.1'
    assert context.call_id_stack == ['baz.bar.0', 'baz.foo.1']

    # Long stack
    many_ids = [str(i) for i in xrange(10)]
    context = context_cls(container,
                          service,
                          DummyProvider("long"),
                          data={'call_id_stack': many_ids})
    expected = many_ids + ['baz.long.2']
    assert context.call_id_stack == expected
Beispiel #2
0
def test_event_dispatcher(mock_container):

    container = mock_container
    container.service_name = "srcservice"

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("dispatch"))

    event_dispatcher = EventDispatcher(retry_policy={
        'max_retries': 5
    }).bind(container, attr_name="dispatch")
    event_dispatcher.setup()

    service.dispatch = event_dispatcher.get_dependency(worker_ctx)

    from mock import ANY
    with patch('nameko.standalone.events.producers') as mock_producers:
        with mock_producers[ANY].acquire() as mock_producer:

            service.dispatch('eventtype', 'msg')
            headers = event_dispatcher.get_message_headers(worker_ctx)
    mock_producer.publish.assert_called_once_with(
        'msg',
        exchange=ANY,
        headers=headers,
        serializer=container.serializer,
        routing_key='eventtype',
        retry=True,
        retry_policy={'max_retries': 5})
    _, call_kwargs = mock_producer.publish.call_args
    exchange = call_kwargs['exchange']
    assert exchange.name == 'srcservice.events'
Beispiel #3
0
def test_consume_provider(empty_config):

    container = Mock(spec=ServiceContainer)
    container.worker_ctx_cls = WorkerContext
    container.service_name = "service"
    container.config = empty_config

    worker_ctx = WorkerContext(container, None, DummyProvider())

    spawn_worker = container.spawn_worker
    spawn_worker.return_value = worker_ctx

    queue_consumer = Mock()

    consume_provider = ConsumeProvider(queue=foobar_queue,
                                       requeue_on_error=False)
    consume_provider.queue_consumer = queue_consumer
    consume_provider.bind("name", container)

    message = Mock(headers={})

    # test lifecycle
    consume_provider.prepare()
    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)
Beispiel #4
0
def test_unserialisable_headers(rabbit_manager, rabbit_config, mock_container):

    vhost = rabbit_config['vhost']

    container = mock_container
    container.service_name = "service"
    container.config = rabbit_config
    container.spawn_managed_thread = eventlet.spawn

    ctx_data = {'language': 'en', 'customheader': None}
    service = Mock()
    worker_ctx = WorkerContext(
        container, service, DummyProvider('method'), data=ctx_data
    )

    publisher = Publisher(
        exchange=foobar_ex, queue=foobar_queue).bind(container, "publish")

    publisher.setup()
    publisher.start()

    service.publish = publisher.get_dependency(worker_ctx)
    service.publish("msg")
    messages = rabbit_manager.get_messages(vhost, foobar_queue.name)

    assert messages[0]['properties']['headers'] == {
        'nameko.language': 'en',
        'nameko.call_id_stack': ['service.method.0'],
        # no `customheader`
    }
Beispiel #5
0
def test_publish_to_exchange(maybe_declare, patch_publisher, mock_container):
    container = mock_container
    container.service_name = "srcservice"

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("publish"))

    publisher = Publisher(exchange=foobar_ex).bind(container, "publish")

    producer = Mock()
    connection = Mock()

    get_connection, get_producer = patch_publisher(publisher)

    get_connection.return_value = as_context_manager(connection)
    get_producer.return_value = as_context_manager(producer)

    # test declarations
    publisher.setup()
    maybe_declare.assert_called_once_with(foobar_ex, connection)

    # test publish
    msg = "msg"
    service.publish = publisher.get_dependency(worker_ctx)
    service.publish(msg, publish_kwarg="value")
    headers = {
        'nameko.call_id_stack': ['srcservice.publish.0']
    }
    producer.publish.assert_called_once_with(
        msg, headers=headers, exchange=foobar_ex, retry=True,
        serializer=container.serializer,
        retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value")
Beispiel #6
0
def test_config_adapters(default_info, custom_info, mock_container):

    mock_container.service_name = 'dummy'
    mock_container.config = {
        constants.CONFIG_KEY: {
            constants.ADAPTERS_CONFIG_KEY: {
                'nameko.web.handlers.HttpRequestHandler':
                'test_dependency.CustomAdapter',
            }
        }
    }
    tracer = Tracer().bind(mock_container, 'logger')
    tracer.setup()

    default_worker_ctx = WorkerContext(mock_container, None, DummyProvider())
    http_worker_ctx = WorkerContext(mock_container, None,
                                    HttpRequestHandler('GET', 'http://yo'))

    calls = [
        tracer.worker_setup, tracer.worker_result, tracer.worker_setup,
        tracer.worker_result
    ]

    for call_ in calls:
        call_(default_worker_ctx)
        call_(http_worker_ctx)

    assert default_info.call_count == 4
    assert custom_info.call_count == 4
Beispiel #7
0
def test_dispatch_to_rabbit(rabbit_manager, rabbit_config, mock_container):

    vhost = rabbit_config['vhost']

    container = mock_container
    container.shared_extensions = {}
    container.service_name = "srcservice"
    container.config = rabbit_config

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider())

    dispatcher = EventDispatcher().bind(container, 'dispatch')
    dispatcher.setup()
    dispatcher.start()

    # we should have an exchange but no queues
    exchanges = rabbit_manager.get_exchanges(vhost)
    queues = rabbit_manager.get_queues(vhost)
    assert "srcservice.events" in [exchange['name'] for exchange in exchanges]
    assert queues == []

    # manually add a queue to capture the events
    rabbit_manager.create_queue(vhost, "event-sink", auto_delete=True)
    rabbit_manager.create_queue_binding(vhost,
                                        "srcservice.events",
                                        "event-sink",
                                        routing_key="eventtype")

    service.dispatch = dispatcher.get_dependency(worker_ctx)
    service.dispatch("eventtype", "msg")

    # test event receieved on manually added queue
    messages = rabbit_manager.get_messages(vhost, "event-sink")
    assert ['"msg"'] == [msg['payload'] for msg in messages]
Beispiel #8
0
def test_publish_to_exchange(empty_config, maybe_declare, patch_publisher):
    container = Mock(spec=ServiceContainer)
    container.service_name = "srcservice"
    container.config = empty_config

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("publish"))

    publisher = PublishProvider(exchange=foobar_ex)
    publisher.bind("publish", container)

    producer = Mock()
    connection = Mock()

    get_connection, get_producer = patch_publisher(publisher)

    get_connection.return_value = as_context_manager(connection)
    get_producer.return_value = as_context_manager(producer)

    # test declarations
    publisher.prepare()
    maybe_declare.assert_called_once_with(foobar_ex, connection)

    # test publish
    msg = "msg"
    publisher.inject(worker_ctx)
    service.publish(msg, publish_kwarg="value")
    headers = {'nameko.call_id_stack': ['srcservice.publish.0']}
    producer.publish.assert_called_once_with(msg,
                                             headers=headers,
                                             exchange=foobar_ex,
                                             retry=True,
                                             retry_policy=DEFAULT_RETRY_POLICY,
                                             publish_kwarg="value")
Beispiel #9
0
def test_publish_custom_headers(
    mock_container, maybe_declare, mock_producer, mock_connection,
    rabbit_config
):

    container = mock_container
    container.config = rabbit_config
    container.service_name = "srcservice"

    ctx_data = {'language': 'en', 'customheader': 'customvalue'}
    service = Mock()
    worker_ctx = WorkerContext(
        container, service, DummyProvider('method'), data=ctx_data
    )

    publisher = Publisher(queue=foobar_queue).bind(container, "publish")

    # test declarations
    publisher.setup()
    maybe_declare.assert_called_once_with(foobar_queue, mock_connection)

    # test publish
    msg = "msg"
    headers = {'nameko.language': 'en',
               'nameko.customheader': 'customvalue',
               'nameko.call_id_stack': ['srcservice.method.0']}
    service.publish = publisher.get_dependency(worker_ctx)
    service.publish(msg, publish_kwarg="value")
    mock_producer.publish.assert_called_once_with(
        msg, headers=headers, exchange=foobar_ex, retry=True,
        serializer=container.serializer, mandatory=False,
        retry_policy=DEFAULT_RETRY_POLICY, publish_kwarg="value")
Beispiel #10
0
def test_event_dispatcher(mock_container, mock_producer, rabbit_config):

    container = mock_container
    container.config = rabbit_config
    container.service_name = "srcservice"

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("dispatch"))

    event_dispatcher = EventDispatcher(retry_policy={
        'max_retries': 5
    }).bind(container, attr_name="dispatch")
    event_dispatcher.setup()

    service.dispatch = event_dispatcher.get_dependency(worker_ctx)
    service.dispatch('eventtype', 'msg')

    headers = event_dispatcher.get_message_headers(worker_ctx)

    mock_producer.publish.assert_called_once_with(
        'msg',
        exchange=ANY,
        headers=headers,
        serializer=container.serializer,
        routing_key='eventtype',
        retry=True,
        mandatory=False,
        retry_policy={'max_retries': 5})

    _, call_kwargs = mock_producer.publish.call_args
    exchange = call_kwargs['exchange']
    assert exchange.name == 'srcservice.events'
Beispiel #11
0
def test_dispatch_to_rabbit(rabbit_manager, rabbit_config):

    vhost = rabbit_config['vhost']

    container = Mock(spec=ServiceContainer)
    container.service_name = "srcservice"
    container.config = rabbit_config

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider())

    dispatcher = EventDispatcher()
    dispatcher.bind("dispatch", container)
    dispatcher.prepare()
    dispatcher.start()

    # we should have an exchange but no queues
    exchanges = rabbit_manager.get_exchanges(vhost)
    queues = rabbit_manager.get_queues(vhost)
    assert "srcservice.events" in [exchange['name'] for exchange in exchanges]
    assert queues == []

    # manually add a queue to capture the events
    rabbit_manager.create_queue(vhost, "event-sink", auto_delete=True)
    rabbit_manager.create_binding(vhost,
                                  "srcservice.events",
                                  "event-sink",
                                  rt_key=ExampleEvent.type)

    dispatcher.inject(worker_ctx)
    service.dispatch(ExampleEvent("msg"))

    # test event receieved on manually added queue
    messages = rabbit_manager.get_messages(vhost, "event-sink")
    assert ['msg'] == [msg['payload'] for msg in messages]
Beispiel #12
0
    def test_without_origin(self, mock_container):

        mock_container.service_name = "foo"

        service = Mock()
        entrypoint = DummyProvider("bar")
        context_data = {}

        worker_ctx = WorkerContext(mock_container,
                                   service,
                                   entrypoint,
                                   data=context_data)

        assert worker_ctx.origin_call_id is None
Beispiel #13
0
    def test_with_parent(self, mock_container):

        mock_container.service_name = "foo"

        service = Mock()
        entrypoint = DummyProvider("bar")
        context_data = {'call_id_stack': ['parent.method.1']}

        worker_ctx = WorkerContext(mock_container,
                                   service,
                                   entrypoint,
                                   data=context_data)

        assert worker_ctx.immediate_parent_call_id == "parent.method.1"
Beispiel #14
0
def test_short_call_stack(container_factory):
    class FooService(object):
        name = 'baz'

    container = container_factory(FooService, {PARENT_CALLS_CONFIG_KEY: 1})
    service = FooService()

    # Trim stack
    many_ids = [str(i) for i in range(100)]
    context = WorkerContext(container,
                            service,
                            DummyProvider("long"),
                            data={'call_id_stack': many_ids})
    assert context.call_id_stack == ['99', 'baz.long.0']
Beispiel #15
0
def test_publish_to_queue(patch_maybe_declare, mock_producer, mock_connection,
                          mock_container):
    container = mock_container
    container.config = {'AMQP_URI': 'memory://'}
    container.shared_extensions = {}
    container.service_name = "srcservice"

    ctx_data = {'language': 'en'}
    service = Mock()
    worker_ctx = WorkerContext(container,
                               service,
                               DummyProvider("publish"),
                               data=ctx_data)

    publisher = Publisher(queue=foobar_queue).bind(container, "publish")

    # test declarations
    publisher.setup()
    assert patch_maybe_declare.call_args_list == [
        call(foobar_queue, mock_connection)
    ]

    # test publish
    msg = "msg"
    headers = {
        'nameko.language': 'en',
        'nameko.call_id_stack': ['srcservice.publish.0'],
    }
    service.publish = publisher.get_dependency(worker_ctx)
    service.publish(msg, publish_kwarg="value")

    expected_args = ('msg', )
    expected_kwargs = {
        'publish_kwarg': "value",
        'exchange': foobar_ex,
        'headers': headers,
        'declare': publisher.declare,
        'retry': publisher.publisher_cls.retry,
        'retry_policy': publisher.publisher_cls.retry_policy,
        'compression': publisher.publisher_cls.compression,
        'mandatory': publisher.publisher_cls.mandatory,
        'expiration': publisher.publisher_cls.expiration,
        'delivery_mode': publisher.publisher_cls.delivery_mode,
        'priority': publisher.publisher_cls.priority,
        'serializer': publisher.serializer
    }

    assert mock_producer.publish.call_args_list == [
        call(*expected_args, **expected_kwargs)
    ]
Beispiel #16
0
def test_publish_custom_headers(mock_container, mock_producer, mock_connection,
                                rabbit_config):
    container = mock_container
    container.config = rabbit_config
    container.service_name = "srcservice"

    ctx_data = {'language': 'en', 'customheader': 'customvalue'}
    service = Mock()
    worker_ctx = WorkerContext(container,
                               service,
                               DummyProvider('method'),
                               data=ctx_data)

    publisher = Publisher(queue=foobar_queue).bind(container, "publish")
    publisher.setup()

    # test publish
    msg = "msg"
    headers = {
        'nameko.language': 'en',
        'nameko.customheader': 'customvalue',
        'nameko.call_id_stack': ['srcservice.method.0']
    }
    service.publish = publisher.get_dependency(worker_ctx)
    service.publish(msg, publish_kwarg="value")

    expected_args = ('msg', )
    expected_kwargs = {
        'publish_kwarg': "value",
        'exchange': foobar_ex,
        'headers': headers,
        'declare': publisher.declare,
        'retry': publisher.publisher_cls.retry,
        'retry_policy': publisher.publisher_cls.retry_policy,
        'compression': publisher.publisher_cls.compression,
        'mandatory': publisher.publisher_cls.mandatory,
        'expiration': publisher.publisher_cls.expiration,
        'delivery_mode': publisher.publisher_cls.delivery_mode,
        'priority': publisher.publisher_cls.priority,
        'serializer': publisher.serializer
    }

    assert mock_producer.publish.call_args_list == [
        call(*expected_args, **expected_kwargs)
    ]
Beispiel #17
0
def test_publish_to_rabbit(rabbit_manager, rabbit_config):

    vhost = rabbit_config['vhost']

    container = Mock(spec=ServiceContainer)
    container.service_name = "service"
    container.config = rabbit_config
    container.spawn_managed_thread = eventlet.spawn

    ctx_data = {'language': 'en', 'customheader': 'customvalue'}
    service = Mock()
    worker_ctx = CustomWorkerContext(container,
                                     service,
                                     DummyProvider('method'),
                                     data=ctx_data)

    publisher = PublishProvider(exchange=foobar_ex, queue=foobar_queue)
    publisher.bind("publish", container)

    # test queue, exchange and binding created in rabbit
    publisher.prepare()
    publisher.start()

    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 published to queue
    publisher.inject(worker_ctx)
    service.publish("msg")
    messages = rabbit_manager.get_messages(vhost, foobar_queue.name)
    assert ['msg'] == [msg['payload'] for msg in messages]

    # test message headers
    assert messages[0]['properties']['headers'] == {
        'nameko.language': 'en',
        'nameko.customheader': 'customvalue',
        'nameko.call_id_stack': ['service.method.0'],
    }
Beispiel #18
0
def test_publish_custom_headers(empty_config, maybe_declare, patch_publisher):

    container = Mock(spec=ServiceContainer)
    container.service_name = "srcservice"
    container.config = empty_config

    ctx_data = {'language': 'en', 'customheader': 'customvalue'}
    service = Mock()
    worker_ctx = CustomWorkerContext(container,
                                     service,
                                     DummyProvider('method'),
                                     data=ctx_data)

    publisher = PublishProvider(queue=foobar_queue)
    publisher.bind("publish", container)

    producer = Mock()
    connection = Mock()

    get_connection, get_producer = patch_publisher(publisher)

    get_connection.return_value = as_context_manager(connection)
    get_producer.return_value = as_context_manager(producer)

    # test declarations
    publisher.prepare()
    maybe_declare.assert_called_once_with(foobar_queue, connection)

    # test publish
    msg = "msg"
    headers = {
        'nameko.language': 'en',
        'nameko.customheader': 'customvalue',
        'nameko.call_id_stack': ['srcservice.method.0']
    }
    publisher.inject(worker_ctx)
    service.publish(msg, publish_kwarg="value")
    producer.publish.assert_called_once_with(msg,
                                             headers=headers,
                                             exchange=foobar_ex,
                                             retry=True,
                                             retry_policy=DEFAULT_RETRY_POLICY,
                                             publish_kwarg="value")
Beispiel #19
0
def test_publish_to_rabbit(rabbit_manager, rabbit_config, mock_container):

    vhost = rabbit_config['vhost']

    container = mock_container
    container.service_name = "service"
    container.config = rabbit_config

    ctx_data = {'language': 'en', 'customheader': 'customvalue'}
    service = Mock()
    worker_ctx = WorkerContext(
        container, service, DummyProvider('method'), data=ctx_data
    )

    publisher = Publisher(
        exchange=foobar_ex, queue=foobar_queue
    ).bind(container, "publish")

    publisher.setup()
    publisher.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]

    service.publish = publisher.get_dependency(worker_ctx)
    service.publish("msg")

    # test message published to queue
    messages = rabbit_manager.get_messages(vhost, foobar_queue.name)
    assert ['"msg"'] == [msg['payload'] for msg in messages]

    # test message headers
    assert messages[0]['properties']['headers'] == {
        'nameko.language': 'en',
        'nameko.customheader': 'customvalue',
        'nameko.call_id_stack': ['service.method.0'],
    }
Beispiel #20
0
def test_event_dispatcher(mock_container, mock_producer, rabbit_config):

    container = mock_container
    container.config = rabbit_config
    container.service_name = "srcservice"

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("dispatch"))

    custom_retry_policy = {'max_retries': 5}

    event_dispatcher = EventDispatcher(retry_policy=custom_retry_policy).bind(
        container, attr_name="dispatch")
    event_dispatcher.setup()

    service.dispatch = event_dispatcher.get_dependency(worker_ctx)
    service.dispatch('eventtype', 'msg')

    headers = event_dispatcher.get_message_headers(worker_ctx)

    expected_args = ('msg',)
    expected_kwargs = {
        'exchange': ANY,
        'routing_key': 'eventtype',
        'headers': headers,
        'declare': event_dispatcher.declare,
        'retry': event_dispatcher.publisher_cls.retry,
        'retry_policy': custom_retry_policy,
        'compression': event_dispatcher.publisher_cls.compression,
        'mandatory': event_dispatcher.publisher_cls.mandatory,
        'expiration': event_dispatcher.publisher_cls.expiration,
        'delivery_mode': event_dispatcher.publisher_cls.delivery_mode,
        'priority': event_dispatcher.publisher_cls.priority,
        'serializer': event_dispatcher.serializer,
    }

    assert mock_producer.publish.call_count == 1
    args, kwargs = mock_producer.publish.call_args
    assert args == expected_args
    assert kwargs == expected_kwargs
    assert kwargs['exchange'].name == 'srcservice.events'
Beispiel #21
0
def test_publish_to_queue(empty_config, maybe_declare, patch_publisher):
    container = Mock(spec=ServiceContainer)
    container.shared_extensions = {}
    container.service_name = "srcservice"
    container.config = empty_config

    ctx_data = {'language': 'en'}
    service = Mock()
    worker_ctx = WorkerContext(container,
                               service,
                               DummyProvider("publish"),
                               data=ctx_data)

    publisher = Publisher(queue=foobar_queue).bind(container, "publish")

    producer = Mock()
    connection = Mock()

    get_connection, get_producer = patch_publisher(publisher)

    get_connection.return_value = as_context_manager(connection)
    get_producer.return_value = as_context_manager(producer)

    # test declarations
    publisher.setup()
    maybe_declare.assert_called_once_with(foobar_queue, connection)

    # test publish
    msg = "msg"
    headers = {
        'nameko.language': 'en',
        'nameko.call_id_stack': ['srcservice.publish.0'],
    }
    service.publish = publisher.get_dependency(worker_ctx)
    service.publish(msg, publish_kwarg="value")
    producer.publish.assert_called_once_with(msg,
                                             headers=headers,
                                             exchange=foobar_ex,
                                             retry=True,
                                             retry_policy=DEFAULT_RETRY_POLICY,
                                             publish_kwarg="value")
Beispiel #22
0
def test_default_adapters(default_info, http_info, mock_container):

    mock_container.service_name = 'dummy'
    mock_container.config = {}
    tracer = Tracer().bind(mock_container, 'logger')
    tracer.setup()

    default_worker_ctx = WorkerContext(mock_container, None, DummyProvider())
    http_worker_ctx = WorkerContext(mock_container, None,
                                    HttpRequestHandler('GET', 'http://yo'))

    calls = [
        tracer.worker_setup, tracer.worker_result, tracer.worker_setup,
        tracer.worker_result
    ]

    for call_ in calls:
        call_(default_worker_ctx)
        call_(http_worker_ctx)

    assert default_info.call_count == 4
    assert http_info.call_count == 4
Beispiel #23
0
def test_event_dispatcher(empty_config):

    container = Mock(spec=ServiceContainer)
    container.service_name = "srcservice"
    container.config = empty_config

    service = Mock()
    worker_ctx = WorkerContext(container, service, DummyProvider("dispatch"))

    event_dispatcher = EventDispatcher()
    event_dispatcher.bind("dispatch", container)

    path = 'nameko.messaging.PublishProvider.prepare'
    with patch(path, autospec=True) as prepare:

        # test start method
        event_dispatcher.prepare()
        assert event_dispatcher.exchange.name == "srcservice.events"
        assert prepare.called

    evt = Mock(type="eventtype", data="msg")
    event_dispatcher.inject(worker_ctx)

    producer = Mock()

    with patch.object(event_dispatcher, 'get_producer',
                      autospec=True) as get_producer:
        get_producer.return_value = as_context_manager(producer)

        # test dispatch
        service.dispatch(evt, retry_policy={'max_retries': 5})
        headers = event_dispatcher.get_message_headers(worker_ctx)
        producer.publish.assert_called_once_with(
            evt.data,
            exchange=event_dispatcher.exchange,
            headers=headers,
            routing_key=evt.type,
            retry=True,
            retry_policy={'max_retries': 5})
Beispiel #24
0
def test_db(container_factory):

    container = container_factory(FooService, config)
    provider = next(iter(container.dependencies.injections))

    # fake instance creation and provider injection
    service = FooService()
    worker_ctx = WorkerContext(container, service, DummyProvider())
    provider.inject(worker_ctx)

    assert isinstance(service.session, Session)

    session = service.session
    session.add(FooModel())
    assert session.new

    provider.worker_teardown(worker_ctx)
    provider.release(worker_ctx)
    # if we had not closed the session we would still have new objects
    assert not session.new

    # teardown removes the injection
    assert not isinstance(service.session, Session)
Beispiel #25
0
def test_concurrency():

    container = Mock()
    container.config = config
    container.service_name = "fooservice"

    entrypoint = DummyProvider()
    service_instance = Mock()

    def inject(worker_ctx):
        orm_session = OrmSession(DeclBase)
        orm_session.container = container
        return orm_session.acquire_injection(worker_ctx)

    # get injections concurrently
    pile = GreenPile()
    for _ in xrange(CONCURRENT_REQUESTS):
        worker_ctx = WorkerContext(container, service_instance, entrypoint)
        pile.spawn(inject, worker_ctx)
    results = set(pile)

    # injections should all be unique
    assert len(results) == CONCURRENT_REQUESTS
Beispiel #26
0
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()
Beispiel #27
0
def test_consume_from_rabbit(rabbit_manager, rabbit_config):

    vhost = rabbit_config['vhost']

    container = Mock(spec=ServiceContainer)
    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())

    factory = DependencyFactory(ConsumeProvider,
                                queue=foobar_queue,
                                requeue_on_error=False)
    consumer = factory.create_and_bind_instance("injection_name", container)

    # prepare and start dependencies
    consumer.prepare()
    consumer.queue_consumer.prepare()
    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()