def test_cached_response_on_timeout(container):

    cached_rpc = get_extension(container, CachedRpcProxy)

    def fake_some_method(*args, **kwargs):
        return 'hi'

    with patch('nameko.rpc.MethodProxy.__call__', fake_some_method):
        with entrypoint_hook(container, 'cached') as hook:
            assert hook() == 'hi'

    def slow_response(*args, **kwargs):
        eventlet.sleep(3)
        return 'hi'

    start = time.time()
    with patch('nameko.rpc.MethodProxy.__call__', slow_response):
        with entrypoint_hook(container, 'cached') as hook:
            assert hook() == 'hi'
    assert time.time() - start < 2

    cached_rpc.cache = {}

    start = time.time()
    with patch('nameko.rpc.MethodProxy.__call__', slow_response):
        with entrypoint_hook(container, 'cached') as hook:
            assert hook() == 'hi'
    assert time.time() - start >= 3
Beispiel #2
0
    def test_reuse_when_down(
        self, publisher_container, consumer_container, tracker, toxiproxy,
    ):
        """ Verify we detect stale connections.

        Publish confirms are required for this functionality. Without confirms
        the later messages are silently lost and the test hangs waiting for a
        response.
        """
        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        with toxiproxy.disabled():

            # call 2 fails
            payload2 = "payload2"
            with pytest.raises(IOError):
                with entrypoint_hook(publisher_container, 'send') as send:
                    send(payload2)

            assert tracker.call_args_list == [
                call("send", payload1),
                call("recv", payload1),
                call("send", payload2),
            ]
Beispiel #3
0
    def test_normal(self, publisher_container, consumer_container, tracker):

        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        # call 2 succeeds
        payload2 = "payload2"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload2)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
            call("send", payload2),
            call("recv", payload2),
        ]
Beispiel #4
0
    def test_reuse_when_recovered(self, client_container, toxiproxy):
        """ Verify we detect and recover from stale connections.

        Publish confirms are required for this functionality. Without confirms
        the later messages are silently lost and the test hangs waiting for a
        response.
        """
        with entrypoint_hook(client_container, 'echo') as echo:
            assert echo(1) == 1

        toxiproxy.disable()

        with pytest.raises(IOError) as exc_info:
            with entrypoint_hook(client_container, 'echo') as echo:
                echo(2)
        assert (
            # expect the write to raise a BrokenPipe or, if it succeeds,
            # the socket to be closed on the subsequent confirmation read
            "Broken pipe" in str(exc_info.value)
            or "Socket closed" in str(exc_info.value))

        toxiproxy.enable()

        with entrypoint_hook(client_container, 'echo') as echo:
            assert echo(3) == 3
def test_end_to_end(container_factory, tmpdir):

    # create a temporary database
    db_uri = 'sqlite:///{}'.format(tmpdir.join("db").strpath)
    engine = create_engine(db_uri)
    ExampleModel.metadata.create_all(engine)

    config = {
        DB_URIS_KEY: {
            'exampleservice:examplebase': db_uri
        }
    }

    container = container_factory(ExampleService, config)
    container.start()

    # write through the service
    with entrypoint_hook(container, "write") as write:
        pk = write("foobar")

    # verify changes written to disk
    entries = list(engine.execute('SELECT data FROM example LIMIT 1'))
    assert entries == [('foobar',)]

    # read through the service
    with entrypoint_hook(container, "read") as read:
        assert read(pk) == "foobar"
Beispiel #6
0
    def test_reuse_when_down(
        self, publisher_container, consumer_container, tracker, toxiproxy,
    ):
        """ Verify we detect stale connections.

        Publish confirms are required for this functionality. Without confirms
        the later messages are silently lost and the test hangs waiting for a
        response.
        """
        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        with toxiproxy.disabled():

            # call 2 fails
            payload2 = "payload2"
            with pytest.raises(IOError):
                with entrypoint_hook(publisher_container, 'send') as send:
                    send(payload2)

            assert tracker.call_args_list == [
                call("send", payload1),
                call("recv", payload1),
                call("send", payload2),
            ]
Beispiel #7
0
    def test_normal(self, publisher_container, consumer_container, tracker):

        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        # call 2 succeeds
        payload2 = "payload2"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload2)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
            call("send", payload2),
            call("recv", payload2),
        ]
Beispiel #8
0
def test_integration(runner_factory, config):

    runner = runner_factory(config, Command, Query)
    runner.start()

    container = get_container(runner, Command)
    
    with entrypoint_hook(container, 'add_news') as entrypoint:
        data = {
            "title": "title test",
            "author": "author test",
            "content": "content test",
            "tags": [
                "test tag1",
                "test tag2",
            ],
        }
        result = entrypoint(data)
        
        assert result == data
        
    container = get_container(runner, Query)
    with entrypoint_hook(container, 'get_news') as entrypoint:

        news = json.loads(entrypoint(result['id']))

        assert news["_id"] == result['id']

    with entrypoint_hook(container, 'get_all_news') as get_all_news:

        news = json.loads(get_all_news(1, 10))

        assert len(news) > 0
def test_cached_response(container):

    cached_rpc = get_extension(container, CachedRpcProxy)

    def fake_some_method(*args, **kwargs):
        return 'hi'

    with patch('nameko.rpc.MethodProxy.__call__', fake_some_method):
        with entrypoint_hook(container, 'cached') as hook:
            assert hook('test') == 'hi'

    def broken_some_method(*args, **kwargs):
        raise Exception('hmm')

    with patch('nameko.rpc.MethodProxy.__call__', broken_some_method):
        with entrypoint_hook(container, 'cached') as hook:
            assert hook('test') == 'hi'

    with patch('nameko.rpc.MethodProxy.__call__', broken_some_method):
        with entrypoint_hook(container, 'cached') as hook:
            with pytest.raises(Exception):
                hook('unknown')

    cached_rpc.cache = {}

    with patch('nameko.rpc.MethodProxy.__call__', broken_some_method):
        with entrypoint_hook(container, 'cached') as hook:
            with pytest.raises(Exception):
                hook('test')
Beispiel #10
0
    def test_reuse_when_recovered(
        self, publisher_container, consumer_container, tracker, toxiproxy
    ):
        """ Verify we detect and recover from stale connections.

        Publish confirms are required for this functionality. Without confirms
        the later messages are silently lost and the test hangs waiting for a
        response.
        """
        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        toxiproxy.disable()

        # call 2 fails
        payload2 = "payload2"
        with pytest.raises(IOError) as exc_info:
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload2)
        assert (
            # expect the write to raise a BrokenPipe or, if it succeeds,
            # the socket to be closed on the subsequent confirmation read
            "Broken pipe" in str(exc_info.value) or
            "Socket closed" in str(exc_info.value)
        )

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
            call("send", payload2),
        ]

        toxiproxy.enable()

        # call 3 succeeds
        payload3 = "payload3"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload3)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
            call("send", payload2),
            call("send", payload3),
            call("recv", payload3),
        ]
Beispiel #11
0
    def test_retries(self, toxiproxy, disconnect, container):
        if not toxiproxy:
            pytest.skip('Toxiproxy not installed')

        with entrypoint_hook(container, 'create_record') as create_record:
            create_record()

        disconnect(reconnect=True)

        with entrypoint_hook(container, 'get_record_count') as hook:
            assert hook() == 1
Beispiel #12
0
    def test_reuse_when_recovered(
        self, publisher_container, consumer_container, tracker, toxiproxy
    ):
        """ Verify we detect and recover from stale connections.

        Publish confirms are required for this functionality. Without confirms
        the later messages are silently lost and the test hangs waiting for a
        response.
        """
        # call 1 succeeds
        payload1 = "payload1"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload1)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
        ]

        with toxiproxy.disabled():

            # call 2 fails
            payload2 = "payload2"
            with pytest.raises(IOError) as exc_info:
                with entrypoint_hook(publisher_container, 'send') as send:
                    send(payload2)
            assert (
                # expect the write to raise a BrokenPipe or, if it succeeds,
                # the socket to be closed on the subsequent confirmation read
                "Broken pipe" in str(exc_info.value) or
                "Socket closed" in str(exc_info.value)
            )

            assert tracker.call_args_list == [
                call("send", payload1),
                call("recv", payload1),
                call("send", payload2),
            ]

        # call 3 succeeds
        payload3 = "payload3"
        with entrypoint_waiter(consumer_container, 'recv'):
            with entrypoint_hook(publisher_container, 'send') as send:
                send(payload3)

        assert tracker.call_args_list == [
            call("send", payload1),
            call("recv", payload1),
            call("send", payload2),
            call("send", payload3),
            call("recv", payload3),
        ]
Beispiel #13
0
def test_unsubscribe(container, websocket):
    ws = websocket()
    ws.rpc('subscribe')
    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)
    assert get_message(ws) == 42
    ws.rpc('unsubscribe')

    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)
    with eventlet.Timeout(.1, exception=False):
        assert get_message(ws) == 42
Beispiel #14
0
    def test_raises_without_retry(self, toxiproxy, disconnect, container):
        if not toxiproxy:
            pytest.skip('Toxiproxy not installed')

        with entrypoint_hook(container, 'create_record') as create_record:
            create_record()

        disconnect(reconnect=True)

        with entrypoint_hook(container, 'get_record_count_no_retry') as hook:
            with pytest.raises(OperationalError):
                hook()
Beispiel #15
0
def test_unsubscribe(container, websocket):
    ws = websocket()
    ws.rpc('subscribe')
    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)
    assert get_message(ws) == 42
    ws.rpc('unsubscribe')

    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)
    with eventlet.Timeout(.1, exception=False):
        assert get_message(ws) == 42
Beispiel #16
0
def test_close(container, websocket):
    ws = websocket()

    ws.rpc('subscribe')

    with entrypoint_hook(container, 'list_subscribers') as list_subscribers:
        subscribers1 = list_subscribers()
        assert subscribers1['test_channel']

    ws.app.close()

    with entrypoint_hook(container, 'list_subscribers') as list_subscribers:
        subscribers2 = list_subscribers()
        assert not subscribers2['test_channel']
Beispiel #17
0
    def it_should_allow_method_calls_to_beanstalkd(self, bs):
        container = ServiceContainer(ExampleService, {})
        container.start()

        with entrypoint_hook(container, "write") as write:
            write("foobar")

        assert bs.Connection.return_value.put.called
        assert bs.Connection.return_value.put.call_args[0][0] == 'foobar'

        bs.Connection.return_value.reserve.return_value = MockJob('foobar')

        with entrypoint_hook(container, "read") as read:
            assert read() == "foobar"
Beispiel #18
0
def test_entrypoint_hook_with_return(runner_factory, rabbit_config):

    service_classes = (Service, ServiceA, ServiceB, ServiceC)
    runner = runner_factory(rabbit_config, *service_classes)
    runner.start()

    service_container = get_container(runner, Service)

    with entrypoint_hook(service_container, 'working') as working:
        assert working("value") == "value-a-b-c"

    with entrypoint_hook(service_container, 'broken') as broken:
        with pytest.raises(ExampleError):
            broken("value")
Beispiel #19
0
def test_entrypoint_hook_with_return(runner_factory, rabbit_config):

    service_classes = (Service, ServiceA, ServiceB, ServiceC)
    runner = runner_factory(rabbit_config, *service_classes)
    runner.start()

    service_container = get_container(runner, Service)

    with entrypoint_hook(service_container, "working") as working:
        assert working("value") == "value-a-b-c"

    with entrypoint_hook(service_container, "broken") as broken:
        with pytest.raises(ExampleError):
            broken("value")
Beispiel #20
0
def test_rpc_context_data(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    context_data = {'language': 'en', 'auth_token': '123456789'}

    with entrypoint_hook(container, 'say_hello', context_data) as say_hello:
        assert say_hello() == "hello"

    context_data['language'] = 'fr'

    with entrypoint_hook(container, 'say_hello', context_data) as say_hello:
        assert say_hello() == "bonjour"
Beispiel #21
0
def test_close(container, websocket):
    ws = websocket()

    ws.rpc('subscribe')

    with entrypoint_hook(container, 'list_subscribers') as list_subscribers:
        subscribers1 = list_subscribers()
        assert subscribers1['test_channel']

    ws.app.close()

    with entrypoint_hook(container, 'list_subscribers') as list_subscribers:
        subscribers2 = list_subscribers()
        assert not subscribers2['test_channel']
Beispiel #22
0
    def test_expected_exceptions(self, container_factory):

        exceptions = defaultdict(list)

        class CustomException(Exception):
            pass

        class Logger(DependencyProvider):
            """ Example DependencyProvider that interprets
            ``expected_exceptions`` on an entrypoint
            """

            def worker_result(self, worker_ctx, result=None, exc_info=None):
                if exc_info is None:  # nothing to do
                    return  # pragma: no cover

                exc = exc_info[1]
                expected = worker_ctx.entrypoint.expected_exceptions

                if isinstance(exc, expected):
                    exceptions['expected'].append(exc)
                else:
                    exceptions['unexpected'].append(exc)

        class Service(object):
            name = "service"

            logger = Logger()

            @dummy(expected_exceptions=CustomException)
            def expected(self):
                raise CustomException()

            @dummy
            def unexpected(self):
                raise CustomException()

        container = container_factory(Service, {})
        container.start()

        with entrypoint_hook(container, 'expected') as hook:
            with pytest.raises(CustomException) as expected_exc:
                hook()
        assert expected_exc.value in exceptions['expected']

        with entrypoint_hook(container, 'unexpected') as hook:
            with pytest.raises(CustomException) as unexpected_exc:
                hook()
        assert unexpected_exc.value in exceptions['unexpected']
Beispiel #23
0
    def test_expected_exceptions(self, container_factory):

        exceptions = defaultdict(list)

        class CustomException(Exception):
            pass

        class Logger(DependencyProvider):
            """ Example DependencyProvider that interprets
            ``expected_exceptions`` on an entrypoint
            """
            def worker_result(self, worker_ctx, result=None, exc_info=None):
                if exc_info is None:  # nothing to do
                    return  # pragma: no cover

                exc = exc_info[1]
                expected = worker_ctx.entrypoint.expected_exceptions

                if isinstance(exc, expected):
                    exceptions['expected'].append(exc)
                else:
                    exceptions['unexpected'].append(exc)

        class Service(object):
            name = "service"

            logger = Logger()

            @dummy(expected_exceptions=CustomException)
            def expected(self):
                raise CustomException()

            @dummy
            def unexpected(self):
                raise CustomException()

        container = container_factory(Service, {})
        container.start()

        with entrypoint_hook(container, 'expected') as hook:
            with pytest.raises(CustomException) as expected_exc:
                hook()
        assert expected_exc.value in exceptions['expected']

        with entrypoint_hook(container, 'unexpected') as hook:
            with pytest.raises(CustomException) as unexpected_exc:
                hook()
        assert unexpected_exc.value in exceptions['unexpected']
Beispiel #24
0
def test_verify_token_multiple_tokens(db, service_container):
    token = "im a token"

    user = User(email="*****@*****.**",
                password="******",
                display_name="Test Account")

    user_token_1 = UserToken(
        user=user,
        token=token,
        created_datetime_utc=datetime.datetime.utcnow() -
        datetime.timedelta(days=1),
    )

    user_token_2 = UserToken(user=user,
                             token=token + "123",
                             created_datetime_utc=datetime.datetime.utcnow())

    db.session.add(user)
    db.session.add(user_token_1)
    db.session.add(user_token_2)

    db.session.commit()

    with entrypoint_hook(service_container, "verify_token") as verify_token:
        verify_token(user.id, token + "123")
Beispiel #25
0
def test_proxy_disconnect_with_active_worker(container_factory,
                                             rabbit_manager, rabbit_config):
    """ Break the connection to rabbit while a service's queue consumer and
    rabbit while the service has an in-flight rpc request (i.e. it is waiting
    on a reply).
    """
    # ExampleService is the target; ProxyService has the rpc_proxy;
    proxy_container = container_factory(ProxyService, rabbit_config)
    example_container = container_factory(ExampleService, rabbit_config)

    proxy_container.start()

    # get proxyservice's queue consumer connection while we know it's the
    # only active connection
    vhost = rabbit_config['vhost']
    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert len(connections) == 1
    proxy_consumer_conn = connections[0]['name']

    example_container.start()

    # there should now be two connections:
    # 1. the queue consumer from proxyservice
    # 2. the queue consumer from exampleservice
    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert len(connections) == 2

    # disconnect proxyservice's queue consumer while its request is in-flight
    eventlet.spawn(disconnect_on_event, rabbit_manager, proxy_consumer_conn)
    with entrypoint_hook(proxy_container, 'entrypoint') as entrypoint:
        # we should receive a response after reconnection
        assert entrypoint('hello') == 'hello'

    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert proxy_consumer_conn not in [conn['name'] for conn in connections]
Beispiel #26
0
def test_structlog_depedency(greeting_service, greeting_rpc):
    greeting_rpc.log = TestingStructlogProcessor().get_logger()

    with entrypoint_hook(greeting_service.container, "greet") as greet:
        assert greet() == "Hi"

        assert greeting_rpc.log.info("bar") == ((), {"event": "bar"})
def test_raises_error_if_message_does_not_exist(message_svc,
                                                fake_strict_redis):
    with entrypoint_hook(message_svc, 'get_message') as get_message:
        with pytest.raises(RedisError) as err:
            get_message('message-x')

    err.match(r'Message not found: message-x')
def test_gets_all_messages(message_svc, fake_strict_redis):
    fake_strict_redis().set('message-1', 'Hello')
    fake_strict_redis().set('abcdef123456', 'Howdy')
    fake_strict_redis().set('xyz789', 'I Love Python')
    fake_strict_redis().set('aaaabbbb', 'So do I!')

    with entrypoint_hook(message_svc, 'get_all_messages') as get_all_messages:
        messages = get_all_messages()

    assert messages == [
        {
            'id': 'message-1',
            'message': 'Hello',
            'expires_in': -1
        },
        {
            'id': 'abcdef123456',
            'message': 'Howdy',
            'expires_in': -1
        },
        {
            'id': 'xyz789',
            'message': 'I Love Python',
            'expires_in': -1
        },
        {
            'id': 'aaaabbbb',
            'message': 'So do I!',
            'expires_in': -1
        },
    ]
Beispiel #29
0
    def test_timeout(self, client_container, toxiproxy):
        toxiproxy.set_timeout()

        with pytest.raises(IOError) as exc_info:
            with entrypoint_hook(client_container, 'echo') as echo:
                echo(1)
        assert "Socket closed" in str(exc_info.value)
Beispiel #30
0
    def test_event_dispatcher_over_ssl(self, container_factory,
                                       rabbit_ssl_config, rabbit_config):
        class Dispatcher(object):
            name = "dispatch"

            dispatch = EventDispatcher()

            @dummy
            def method(self, payload):
                return self.dispatch("event-type", payload)

        class Handler(object):
            name = "handler"

            @event_handler("dispatch", "event-type")
            def echo(self, payload):
                return payload

        dispatcher = container_factory(Dispatcher, rabbit_ssl_config)
        dispatcher.start()

        handler = container_factory(Handler, rabbit_config)
        handler.start()

        with entrypoint_waiter(handler, 'echo') as result:
            with entrypoint_hook(dispatcher, 'method') as dispatch:
                dispatch("payload")
        assert result.get() == "payload"
Beispiel #31
0
def test_proxy_disconnect_with_active_worker(container_factory, rabbit_manager,
                                             rabbit_config):
    """ Break the connection to rabbit while a service's queue consumer and
    rabbit while the service has an in-flight rpc request (i.e. it is waiting
    on a reply).
    """
    # ExampleService is the target; ProxyService has the rpc_proxy;
    proxy_container = container_factory(ProxyService, rabbit_config)
    example_container = container_factory(ExampleService, rabbit_config)

    proxy_container.start()

    # get proxyservice's queue consumer connection while we know it's the
    # only active connection
    vhost = rabbit_config['vhost']
    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert len(connections) == 1
    proxy_consumer_conn = connections[0]['name']

    example_container.start()

    # there should now be two connections:
    # 1. the queue consumer from proxyservice
    # 2. the queue consumer from exampleservice
    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert len(connections) == 2

    # disconnect proxyservice's queue consumer while its request is in-flight
    eventlet.spawn(disconnect_on_event, rabbit_manager, proxy_consumer_conn)
    with entrypoint_hook(proxy_container, 'entrypoint') as entrypoint:
        # we should receive a response after reconnection
        assert entrypoint('hello') == 'hello'

    connections = get_rabbit_connections(vhost, rabbit_manager)
    assert proxy_consumer_conn not in [conn['name'] for conn in connections]
Beispiel #32
0
def test_pub_sub(container, websocket):
    ws = websocket()
    assert ws.rpc('subscribe') == 'subscribed!'
    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)

    assert get_message(ws) == 42
Beispiel #33
0
def test_unicast(container, websocket):
    ws = websocket()
    _, connected_data = ws.wait_for_event('connected')
    socket_id = connected_data['socket_id']
    with entrypoint_hook(container, 'unicast') as unicast:
        assert unicast(target_socket_id=socket_id, value=42)
    assert get_message(ws) == 42
Beispiel #34
0
    def test_client_disconnect(
        self, container_factory, config, web_session
    ):
        class Service(object):
            name = "service"

            sentry = SentryReporter()

            @http('POST', '/resource')
            def resource(self, request):
                raise CustomException()

        container = container_factory(Service, config)
        container.start()

        request = Mock(
            method="GET",
            url="http://example.com",
            mimetype='application/json',
            environ={}
        )
        type(request).data = PropertyMock(side_effect=ClientDisconnected)

        with entrypoint_hook(container, 'resource') as hook:
            with pytest.raises(CustomException):
                hook(request)

        sentry = get_extension(container, SentryReporter)

        assert sentry.client.send.call_count == 1
        _, kwargs = sentry.client.send.call_args

        assert kwargs['request']['data'] == {}
Beispiel #35
0
def test_expected_exceptions_integration(container_factory, rabbit_config):
    container = container_factory(ExampleService, rabbit_config)
    container.start()

    worker_logger = get_extension(container, WorkerErrorLogger)

    with entrypoint_hook(container, 'broken') as broken:
        with pytest.raises(ExampleError):
            broken()

    with entrypoint_hook(container, 'very_broken') as very_broken:
        with pytest.raises(AttributeError):
            very_broken()

    assert worker_logger.expected == {'broken': ExampleError}
    assert worker_logger.unexpected == {'very_broken': AttributeError}
def test_create_user_successful(config, db, runner_factory):
    runner = runner_factory(MonitoringService)
    container = get_container(runner, MonitoringService)
    storage = replace_dependencies(container, "storage")
    runner.start()

    storage.api_requests.append.return_value = None

    with entrypoint_hook(
            container,
            "consume_monitoring_stream") as consume_monitoring_stream:
        consume_monitoring_stream(
            "123",
            {
                "__MONITOR_NAME": "API_REQUEST",
                "url": "url",
                "method": "method",
                "duration": "duration",
                "status": "status",
                "status_code": 1,
                "remote_addr": "remote_addr",
            },
        )

    assert storage.api_requests.append.call_args == call(
        "123", "url", "method", "duration", "status", 1, "remote_addr")
Beispiel #37
0
def test_expected_exceptions_integration(container_factory, rabbit_config):
    container = container_factory(ExampleService, rabbit_config)
    container.start()

    worker_logger = get_extension(container, WorkerErrorLogger)

    with entrypoint_hook(container, 'broken') as broken:
        with pytest.raises(ExampleError):
            broken()

    with entrypoint_hook(container, 'very_broken') as very_broken:
        with pytest.raises(AttributeError):
            very_broken()

    assert worker_logger.expected == {'broken': ExampleError}
    assert worker_logger.unexpected == {'very_broken': AttributeError}
Beispiel #38
0
    def test_down(self, client_container, toxiproxy):
        toxiproxy.disable()

        with pytest.raises(IOError) as exc_info:
            with entrypoint_hook(client_container, 'echo') as echo:
                echo(1)
        assert "ECONNREFUSED" in str(exc_info.value)
Beispiel #39
0
    def test_publisher_over_ssl(self, container_factory, rabbit_ssl_config,
                                rabbit_config, queue):
        class PublisherService(object):
            name = "publisher"

            publish = Publisher()

            @dummy
            def method(self, payload):
                return self.publish(payload, routing_key=queue.name)

        class ConsumerService(object):
            name = "consumer"

            @consume(queue)
            def echo(self, payload):
                return payload

        publisher = container_factory(PublisherService, rabbit_ssl_config)
        publisher.start()

        consumer = container_factory(ConsumerService, rabbit_config)
        consumer.start()

        with entrypoint_waiter(consumer, 'echo') as result:
            with entrypoint_hook(publisher, 'method') as publish:
                publish("payload")
        assert result.get() == "payload"
Beispiel #40
0
    def test_event_dispatcher_over_ssl(
        self, container_factory, rabbit_ssl_config, rabbit_config
    ):
        class Dispatcher(object):
            name = "dispatch"

            dispatch = EventDispatcher()

            @dummy
            def method(self, payload):
                return self.dispatch("event-type", payload)

        class Handler(object):
            name = "handler"

            @event_handler("dispatch", "event-type")
            def echo(self, payload):
                return payload

        dispatcher = container_factory(Dispatcher, rabbit_ssl_config)
        dispatcher.start()

        handler = container_factory(Handler, rabbit_config)
        handler.start()

        with entrypoint_waiter(handler, 'echo') as result:
            with entrypoint_hook(dispatcher, 'method') as dispatch:
                dispatch("payload")
        assert result.get() == "payload"
Beispiel #41
0
def test_erroring_result_adapter(logger, info, container_factory, tracker):
    class SomeError(Exception):
        pass

    class Service(object):

        name = "some-service"

        tracer = Tracer()

        @dummy
        def some_method(self, spam):
            pass

    container = container_factory(Service, {})
    container.start()

    info.side_effect = [Mock(return_value=(Mock(), Mock())), SomeError('Yo!')]
    with entrypoint_hook(container, 'some_method') as some_method:
        some_method('ham')

    # nothing logged by entrypoint logger
    assert len(tracker.log_records) == 0

    # warning logged by module logger
    assert logger.warning.call_args == call('Failed to log entrypoint trace',
                                            exc_info=True)
def test_gets_message(message_svc, fake_strict_redis):
    fake_strict_redis().set('message-1', 'Test message here!')

    with entrypoint_hook(message_svc, 'get_message') as get_message:
        message = get_message('message-1')

    assert message == 'Test message here!'
Beispiel #43
0
def test_async_rpc(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    with entrypoint_hook(container, 'call_async') as call_async:
        assert call_async() == ["result_b", "result_a", [[], {}]]
Beispiel #44
0
def test_pub_sub(container, websocket):
    ws = websocket()
    assert ws.rpc('subscribe') == 'subscribed!'
    with entrypoint_hook(container, 'broadcast') as broadcast:
        broadcast(value=42)

    assert get_message(ws) == 42
Beispiel #45
0
def test_async_rpc(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    with entrypoint_hook(container, 'call_async') as call_async:
        assert call_async() == ["result_b", "result_a", [[], {}]]
Beispiel #46
0
    def test_publisher_over_ssl(
        self, container_factory, rabbit_ssl_config, rabbit_config, queue
    ):
        class PublisherService(object):
            name = "publisher"

            publish = Publisher()

            @dummy
            def method(self, payload):
                return self.publish(payload, routing_key=queue.name)

        class ConsumerService(object):
            name = "consumer"

            @consume(queue)
            def echo(self, payload):
                return payload

        publisher = container_factory(PublisherService, rabbit_ssl_config)
        publisher.start()

        consumer = container_factory(ConsumerService, rabbit_config)
        consumer.start()

        with entrypoint_waiter(consumer, 'echo') as result:
            with entrypoint_hook(publisher, 'method') as publish:
                publish("payload")
        assert result.get() == "payload"
Beispiel #47
0
    def it_should_return_a_client_instance(self, bs):
        container = ServiceContainer(ExampleService, {})
        container.start()

        with entrypoint_hook(container, "client") as client:
            client()

        assert bs.Connection.call_count == 1
def test_hello_languages(language, greeting, container_factory, rabbit_config):

    container = container_factory(HelloService, rabbit_config)
    container.start()

    context_data = {'language': language}
    with entrypoint_hook(container, 'hello', context_data) as hook:
        assert hook("Matt") == "{}, Matt!".format(greeting)
Beispiel #49
0
def test_rpc_context_data(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    context_data = {
        'language': 'en',
        'auth_token': '123456789'
    }

    with entrypoint_hook(container, 'say_hello', context_data) as say_hello:
        assert say_hello() == "hello"

    context_data['language'] = 'fr'

    with entrypoint_hook(container, 'say_hello', context_data) as say_hello:
        assert say_hello() == "bonjour"
Beispiel #50
0
def test_entrypoint_hook_context_data(container_factory, rabbit_config, context_data):

    container = container_factory(Service, rabbit_config)
    container.start()

    method = "get_language"
    with entrypoint_hook(container, method, context_data) as get_language:
        assert get_language() == context_data["language"]
Beispiel #51
0
def test_expected_exceptions_integration(container_factory, rabbit_config):
    container = container_factory(ExampleService, rabbit_config)
    container.start()

    worker_logger = get_dependency(container, WorkerErrorLogger)

    with entrypoint_hook(container, 'broken') as broken:
        with pytest.raises(ExampleError):
            broken()

    with entrypoint_hook(container, 'very_broken') as very_broken:
        with pytest.raises(AttributeError):
            very_broken()

    wait_for_worker_idle(container)  # wait for worker lifecycle to complete
    assert worker_logger.expected == {'broken': ExampleError}
    assert worker_logger.unexpected == {'very_broken': AttributeError}
Beispiel #52
0
def test_error_in_worker(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    with entrypoint_hook(container, "broken") as broken:
        with pytest.raises(ExampleError):
            broken()
    assert not container._died.ready()
Beispiel #53
0
def test_error_in_remote_worker(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    with entrypoint_hook(container, "proxy") as proxy:
        with pytest.raises(RemoteError) as exc_info:
            proxy("broken")
    assert exc_info.value.exc_type == "ExampleError"
    assert not container._died.ready()
def test_end_to_end(container_factory, tmpdir, setup_db):
    db = setup_db

    class ExampleService(object):
        name = "exampleservice"

        rdbc = RDB(db)

        @dummy
        def write(self, value):
            result = r.table('test').insert({'data': value}).run(self.rdbc)
            return result

        @dummy
        def read(self, id):
            return r.table('test').get(id).run(self.rdbc)

    rdbc = r.connect(host=RDB_HOST, port=RDB_PORT)

    config = {
        RDB_KEY: {
            'exampleservice': {
                'RDB_HOST': RDB_HOST,
                'RDB_PORT': RDB_PORT,
            }
        }
    }

    container = container_factory(ExampleService, config)
    container.start()

    # write through the service
    with entrypoint_hook(container, "write") as write:
        write("foobar")

    # verify changes written to disk
    entries = r.db(db).table('test').run(rdbc)
    data = list(entries)[0]
    assert data['data'] == u'foobar'
    pk = data['id']
    # read through the service
    with entrypoint_hook(container, "read") as read:
        assert read(pk)['data'] == "foobar"
Beispiel #55
0
def test_multiple_calls(container, websocket):
    ws = websocket()
    ws.rpc('subscribe')
    count = 2
    for value in range(count):
        with entrypoint_hook(container, 'broadcast') as broadcast:
            broadcast(value=value)

    for value in range(count):
        assert get_message(ws) == value
Beispiel #56
0
def test_rpc_args_kwargs(container_factory, rabbit_config):

    container = container_factory(ExampleService, rabbit_config)
    container.start()

    with entrypoint_hook(container, 'echo') as echo:
        assert echo() == ((), {})
        assert echo("a", "b") == (("a", "b"), {})
        assert echo(foo="bar") == ((), {'foo': 'bar'})
        assert echo("arg", kwarg="kwarg") == (("arg",), {'kwarg': 'kwarg'})
Beispiel #57
0
def test_entrypoint_hook_dependency_not_found(container_factory, rabbit_config):

    container = container_factory(Service, rabbit_config)
    container.start()

    method = "nonexistent_method"

    with pytest.raises(ExtensionNotFound):
        with entrypoint_hook(container, method):
            pass
Beispiel #58
0
def test_call_id_stack(rabbit_config, predictable_call_ids, runner_factory):
    child_do_called = Mock()

    stack_request = Mock()
    LoggingWorkerContext = get_logging_worker_context(stack_request)

    class Child(object):
        name = 'child'

        @rpc
        def child_do(self):
            child_do_called()
            return 1

    class Parent(object):
        name = "parent"

        child_service = RpcProxy('child')

        @rpc
        def parent_do(self):
            return self.child_service.child_do()

    class Grandparent(object):
        name = "grandparent"

        parent_service = RpcProxy('parent')

        @rpc
        def grandparent_do(self):
            return self.parent_service.parent_do()

    runner = runner_factory(rabbit_config)
    runner.add_service(Child, LoggingWorkerContext)
    runner.add_service(Parent, LoggingWorkerContext)
    runner.add_service(Grandparent, LoggingWorkerContext)
    runner.start()

    container = get_container(runner, Grandparent)
    with entrypoint_hook(container, "grandparent_do") as grandparent_do:
        assert grandparent_do() == 1

    # Check child is called
    child_do_called.assert_called_with()
    assert child_do_called.call_count == 1

    # Check IDs were requested
    assert predictable_call_ids.call_count == 3

    # Check call ID stack persisted over RPC
    stack_request.assert_has_calls([
        call(None),
        call(['grandparent.grandparent_do.0']),
        call(['grandparent.grandparent_do.0', 'parent.parent_do.1']),
    ])
def test_sensitive_event(container_factory):

    container = container_factory(Service, {})
    handler_entrypoint = get_extension(container, EventHandler)

    assert handler_entrypoint.sensitive_variables == "event_data.foo"

    with entrypoint_hook(container, "handle") as handler:
        handler({"foo": "FOO", "bar": "BAR"})

    assert redacted == {"event_data": {"foo": REDACTED, "bar": "BAR"}}
Beispiel #60
0
def test_service_x_y_integration(runner_factory, rabbit_config):

    # run services in the normal manner
    runner = runner_factory(rabbit_config, ServiceX, ServiceY)
    runner.start()

    # artificially fire the "remote_method" entrypoint on ServiceX
    # and verify response
    container = get_container(runner, ServiceX)
    with entrypoint_hook(container, "remote_method") as entrypoint:
        assert entrypoint("value") == "value-x-y"