Beispiel #1
0
def test_replace_injections_container_already_started(container_factory,
                                                      rabbit_config):
    class Service(object):
        proxy = rpc_proxy("foo_service")

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

    with pytest.raises(RuntimeError):
        replace_injections(container, "proxy")
Beispiel #2
0
def test_replace_injections_container_already_started(container_factory,
                                                      rabbit_config):

    class Service(object):
        proxy = rpc_proxy("foo_service")

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

    with pytest.raises(RuntimeError):
        replace_injections(container, "proxy")
Beispiel #3
0
def test_replace_non_injection(container_factory, rabbit_config):
    class Service(object):
        proxy = rpc_proxy("foo_service")

        @rpc
        def method(self):
            pass

    container = container_factory(Service, rabbit_config)

    # error if dependency doesn't exit
    with pytest.raises(DependencyNotFound):
        replace_injections(container, "nonexist")

    # error if dependency is not an injection
    with pytest.raises(DependencyNotFound):
        replace_injections(container, "method")
Beispiel #4
0
def test_shop_checkout_integration(runner_factory, rpc_proxy_factory):
    """ Simulate a checkout flow as an integration test.

    Requires instances of AcmeShopService, StockService and InvoiceService
    to be running. Explicitly replaces the rpc proxy to PaymentService so
    that service doesn't need to be hosted.

    Also replaces the event dispatcher injection on AcmeShopService and
    disables the timer entrypoint on StockService. Limiting the interactions
    of services in this way reduces the scope of the integration test and
    eliminates undesirable side-effects (e.g. processing events unnecessarily).
    """
    context_data = {'user_id': 'wile_e_coyote'}
    shop = rpc_proxy_factory('acmeshopservice', context_data=context_data)

    runner = runner_factory(AcmeShopService, StockService, InvoiceService)

    # replace ``event_dispatcher`` and ``payment_service``  injections on
    # AcmeShopService with Mock injections
    shop_container = get_container(runner, AcmeShopService)
    fire_event, payment_service = replace_injections(
        shop_container, "fire_event", "payment_service")

    # restrict entrypoints on StockService
    stock_container = get_container(runner, StockService)
    restrict_entrypoints(stock_container, "check_price", "check_stock")

    runner.start()

    # add some items to the basket
    assert shop.add_to_basket("anvil") == "anvil"
    assert shop.add_to_basket("invisible_paint") == "invisible_paint"

    # try to buy something that's out of stock
    with pytest.raises(RemoteError) as exc_info:
        shop.add_to_basket("toothpicks")
    assert exc_info.value.exc_type == "ItemOutOfStock"

    # provide a mock response from the payment service
    payment_service.take_payment.return_value = "Payment complete."

    # checkout
    res = shop.checkout()

    total_amount = 100 + 10
    assert res == total_amount

    # verify integration with mocked out payment service
    payment_service.take_payment.assert_called_once_with({
        'customer': "wile_e_coyote",
        'address': "12 Long Road, High Cliffs, Utah",
        'amount': total_amount,
        'message': "Dear Wile E Coyote. Please pay $110 to ACME Corp."
    })

    # verify events fired as expected
    assert fire_event.call_count == 3
Beispiel #5
0
def test_replace_non_injection(container_factory, rabbit_config):

    class Service(object):
        proxy = rpc_proxy("foo_service")

        @rpc
        def method(self):
            pass

    container = container_factory(Service, rabbit_config)

    # error if dependency doesn't exit
    with pytest.raises(DependencyNotFound):
        replace_injections(container, "nonexist")

    # error if dependency is not an injection
    with pytest.raises(DependencyNotFound):
        replace_injections(container, "method")
Beispiel #6
0
def test_replace_injections(container_factory, rabbit_config):
    class Service(object):
        foo_proxy = rpc_proxy("foo_service")
        bar_proxy = rpc_proxy("bar_service")
        baz_proxy = rpc_proxy("baz_service")

        @rpc
        def method(self, arg):
            self.foo_proxy.remote_method(arg)

        @rpc
        def foo(self):
            return "bar"

    container = container_factory(Service, rabbit_config)

    # replace a single injection
    foo_proxy = replace_injections(container, "foo_proxy")

    # replace multiple injections
    replacements = replace_injections(container, "bar_proxy", "baz_proxy")
    assert len([x for x in replacements]) == 2

    # verify that container.dependencies doesn't include an rpc_proxy anymore
    assert all([
        not isinstance(dependency, rpc_proxy.provider_cls)
        for dependency in container.dependencies
    ])

    container.start()

    # verify that the mock injection collects calls
    msg = "msg"
    with RpcProxy("service", rabbit_config) as service_proxy:
        service_proxy.method(msg)

    foo_proxy.remote_method.assert_called_once_with(msg)
Beispiel #7
0
def test_replace_injections(container_factory, rabbit_config):

    class Service(object):
        foo_proxy = rpc_proxy("foo_service")
        bar_proxy = rpc_proxy("bar_service")
        baz_proxy = rpc_proxy("baz_service")

        @rpc
        def method(self, arg):
            self.foo_proxy.remote_method(arg)

        @rpc
        def foo(self):
            return "bar"

    container = container_factory(Service, rabbit_config)

    # replace a single injection
    foo_proxy = replace_injections(container, "foo_proxy")

    # replace multiple injections
    replacements = replace_injections(container, "bar_proxy", "baz_proxy")
    assert len([x for x in replacements]) == 2

    # verify that container.dependencies doesn't include an rpc_proxy anymore
    assert all([not isinstance(dependency, rpc_proxy.provider_cls)
                for dependency in container.dependencies])

    container.start()

    # verify that the mock injection collects calls
    msg = "msg"
    with RpcProxy("service", rabbit_config) as service_proxy:
        service_proxy.method(msg)

    foo_proxy.remote_method.assert_called_once_with(msg)
def test_shop_checkout_integration(runner_factory, rpc_proxy_factory):
    """ Simulate a checkout flow as an integration test.

    Requires instances of AcmeShopService, StockService and InvoiceService
    to be running. Explicitly replaces the rpc proxy to PaymentService so
    that service doesn't need to be hosted.

    Also replaces the event dispatcher injection on AcmeShopService and
    disables the timer entrypoint on StockService. Limiting the interactions
    of services in this way reduces the scope of the integration test and
    eliminates undesirable side-effects (e.g. processing events unnecessarily).
    """
    context_data = {'user_id': 'wile_e_coyote'}
    shop = rpc_proxy_factory('acmeshopservice', context_data=context_data)

    runner = runner_factory(AcmeShopService, StockService, InvoiceService)

    # replace ``event_dispatcher`` and ``payment_service``  injections on
    # AcmeShopService with Mock injections
    shop_container = get_container(runner, AcmeShopService)
    fire_event, payment_service = replace_injections(shop_container,
                                                     "fire_event",
                                                     "payment_service")

    # restrict entrypoints on StockService
    stock_container = get_container(runner, StockService)
    restrict_entrypoints(stock_container, "check_price", "check_stock")

    runner.start()

    # add some items to the basket
    assert shop.add_to_basket("anvil") == "anvil"
    assert shop.add_to_basket("invisible_paint") == "invisible_paint"

    # try to buy something that's out of stock
    with pytest.raises(RemoteError) as exc_info:
        shop.add_to_basket("toothpicks")
    assert exc_info.value.exc_type == "ItemOutOfStock"

    # provide a mock response from the payment service
    payment_service.take_payment.return_value = "Payment complete."

    # checkout
    res = shop.checkout()

    total_amount = 100 + 10
    assert res == total_amount

    # verify integration with mocked out payment service
    payment_service.take_payment.assert_called_once_with({
        'customer':
        "wile_e_coyote",
        'address':
        "12 Long Road, High Cliffs, Utah",
        'amount':
        total_amount,
        'message':
        "Dear Wile E Coyote. Please pay $110 to ACME Corp."
    })

    # verify events fired as expected
    assert fire_event.call_count == 3