Example #1
0
def test_should_log_successfully_an_error_raised_by_a_meiga_handler(given_any_petisco):

    logger = FakeLogger()

    class UserNotFoundError(Error):
        pass

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self):
            Failure(UserNotFoundError()).unwrap_or_return()
            return isSuccess

    result = MyUseCase().execute()

    assert_failure(result, value_is_instance_of=UserNotFoundError)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        ERROR,
        LogMessageMother.get_use_case(
            operation="MyUseCase",
            message="Result[status: failure | value: UserNotFoundError] ",
        ).to_dict(),
    )
Example #2
0
def test_should_log_successfully_an_error_returned_on_a_use_case(given_any_petisco):

    logger = FakeLogger()

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self):
            return isFailure

    result = MyUseCase().execute()

    assert_failure(result, value_is_instance_of=Error)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        ERROR,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Result[status: failure | value: Error] "
        ).to_dict(),
    )
Example #3
0
def test_should_use_case_handler_return_a_failure_with_unknown_error_when_raise_an_uncontrolled_exception(
    given_any_petisco
):

    logger = FakeLogger()
    expected_raised_exception = RuntimeError("uncontrolled exception")

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self):
            raise expected_raised_exception

    result = MyUseCase().execute()

    assert_failure(
        result,
        value_is_instance_of=UnknownError,
        value_is_equal_to=UnknownError(expected_raised_exception),
    )

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert (
        "value: UnknownError (MyUseCase (Use Case)): RuntimeError: uncontrolled exception.\nTraceback (most recent call last):\n  File"
        in second_logging_message[1]["data"]["message"]
    )
Example #4
0
def test_should_subscriber_handler_always_simulate_a_nack(
    given_any_petisco, make_user_created_event, given_any_publisher_and_subscriber
):
    logger = FakeLogger()
    event = make_user_created_event()
    tracked_events_spy = TrackedEventsSpy()

    @subscriber_handler(logger=logger, percentage_simulate_nack=1.0)
    def main_handler(event: Event):
        tracked_events_spy.append(event)
        return isSuccess

    publisher, subscriber = given_any_publisher_and_subscriber(main_handler)

    subscriber.start()

    await_for_subscriber()

    publisher.publish(event)

    await_for_events()

    tracked_events_spy.assert_number_events(0)

    second_logging_message = logger.get_logging_messages()[1]

    assert second_logging_message == (
        WARNING,
        LogMessageMother.get_subscriber(
            operation="main_handler",
            message="Message rejected (Simulation rejecting 100.0% of the messages)",
        ).to_dict(),
    )

    subscriber.stop()
Example #5
0
def test_should_log_successfully_a_non_error_use_case_without_input_parameters_and_returning_a_string_result(
    given_any_petisco
):

    logger = FakeLogger()

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self):
            return Success("Hello Petisco")

    MyUseCase().execute()

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Hello Petisco"
        ).to_dict(),
    )
Example #6
0
def test_should_log_successfully_a_non_error_use_case_with_input_parameters_but_not_in_the_whitelist(
    given_any_petisco
):

    logger = FakeLogger()

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self, client_id: str, user_id: str):
            return Success("Hello Petisco")

    MyUseCase().execute(client_id="client_id", user_id="user_id")

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Hello Petisco"
        ).to_dict(),
    )
Example #7
0
def test_should_subscriber_handler_return_a_failure_with_unknown_error_when_raise_an_uncontrolled_exception(
    given_any_petisco, make_user_created_event, given_any_publisher_and_subscriber
):
    event = make_user_created_event()
    expected_organization = "acmeorganization"

    logger = FakeLogger()

    @subscriber_handler(logger=logger)
    def main_handler(event: Event, routing_key: RoutingKey):
        raise RuntimeError("uncontrolled exception")

    publisher, subscriber = given_any_publisher_and_subscriber(
        main_handler, organization=expected_organization
    )

    subscriber.start()

    await_for_subscriber()

    publisher.publish(event)

    await_for_events()

    subscriber.stop()

    second_logging_message = logger.get_logging_messages()[1]
    assert second_logging_message[0] == ERROR
    assert (
        "Result[status: failure | value: UnknownError (main_handler (Subscriber)): RuntimeError: uncontrolled exception."
        in second_logging_message[1]["data"]["message"]
    )
    assert "Input Parameters:" in second_logging_message[1]["data"]["message"]
Example #8
0
def test_should_log_successfully_a_filtered_object_by_blacklist_with_a_tuple(
    given_any_petisco
):

    logger = FakeLogger()

    @use_case_handler(logger=logger, logging_types_blacklist=[tuple])
    class MyUseCase(UseCase):
        def execute(self):
            binary_info = ("my_data", b"This are bytes")
            return Success(binary_info)

    result = MyUseCase().execute()

    assert_success(result)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Success result of type: tuple"
        ).to_dict(),
    )
Example #9
0
def test_should_subscriber_handler_always_returns_nack_filtering_by_invalid_routing_key(
    given_any_petisco, make_user_created_event, given_any_publisher_and_subscriber
):
    logger = FakeLogger()
    event = make_user_created_event()
    tracked_events_spy = TrackedEventsSpy()
    invalid_routing_key = "invalid.routing.key"

    @subscriber_handler(logger=logger, filter_routing_key=invalid_routing_key)
    def main_handler(event: Event):
        tracked_events_spy.append(event)
        return isSuccess

    publisher, subscriber = given_any_publisher_and_subscriber(main_handler)

    subscriber.start()

    await_for_subscriber()

    publisher.publish(event)

    await_for_events()

    tracked_events_spy.assert_number_events(0)

    second_logging_message = logger.get_logging_messages()[1]

    assert second_logging_message == (
        WARNING,
        LogMessageMother.get_subscriber(
            operation="main_handler",
            message=f"Message rejected (filtering by routing_key {invalid_routing_key})",
        ).to_dict(),
    )
    subscriber.stop()
def test_should_execute_successfully_a_empty_controller_with_jwt_requirement_with_user(
    given_any_petisco,
    given_any_token_type_with_user,
    given_headers_provider,
    given_auth_token_headers_creator,
    given_any_client_id,
    given_any_user_id,
    given_any_correlation_id,
    given_info_id_only_correlation_id,
):

    logger = FakeLogger()
    expected_info_id = InfoId(
        client_id=given_any_client_id,
        user_id=given_any_user_id,
        correlation_id=given_any_correlation_id,
    )

    @controller_handler(
        logger=logger,
        token_manager=TokenManager(accepted_tokens=[
            AcceptedToken(token_type=given_any_token_type_with_user,
                          require_user=True)
        ]),
        headers_provider=given_headers_provider({
            **given_auth_token_headers_creator(
                given_any_token_type_with_user,
                given_any_client_id,
                given_any_user_id,
            ),
            **given_info_id_only_correlation_id.get_http_headers(),
        }),
    )
    def my_controller(info_id: InfoId):
        assert info_id == expected_info_id
        return Success("Hello Petisco")

    http_response = my_controller()

    assert http_response == ({"message": "OK"}, 200)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=expected_info_id,
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Result[status: success | value: Hello Petisco]",
            info_id=expected_info_id,
        ).to_dict(),
    )
def test_should_execute_successfully_a_empty_controller_without_input_parameters(
        given_any_petisco, given_any_info_id, given_headers_provider):

    logger = FakeLogger()
    mock_event_bus = Mock(IEventBus)

    @controller_handler(
        app_name="petisco",
        app_version=__version__,
        logger=logger,
        send_request_responded_event=True,
        event_bus=mock_event_bus,
        headers_provider=given_headers_provider(
            given_any_info_id.get_http_headers()),
    )
    def my_controller():
        return Success("Hello Petisco")

    http_response = my_controller()

    assert http_response == ({"message": "OK"}, 200)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=given_any_info_id,
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Result[status: success | value: Hello Petisco]",
            info_id=given_any_info_id,
        ).to_dict(),
    )

    request_responded = mock_event_bus.publish.call_args[0][0]
    assert isinstance(request_responded, RequestResponded)
    assert request_responded.app_name == "petisco"
    assert request_responded.app_version == __version__
    assert request_responded.controller == "my_controller"
    assert request_responded.is_success is True
    assert request_responded.http_response["content"] == {
        "message": '{"message": "OK"}',
        "message_size": 17,
    }
    assert request_responded.http_response["status_code"] == 200
Example #12
0
def test_should_publish_consume_with_event_handler_notify_when_fail_consumer_with_critical_error(
    given_any_petisco
):
    spy = SpyEvents()
    logger = FakeLogger()
    notifier = FakeNotifier()

    class MyCriticalError(CriticalError):
        pass

    @event_handler(logger=logger, notifier=notifier)
    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return Failure(MyCriticalError(Exception()))

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]

    configurer = RabbitMqEventConfigurerMother.default()
    configurer.configure_subscribers(subscribers)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    consumer = RabbitMqEventConsumerMother.without_retry()
    consumer.add_subscribers(subscribers)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy.assert_number_unique_events(1)
    spy.assert_first_event(event)
    spy.assert_count_by_event_id(event.event_id, 1)

    first_logging_message = logger.get_logging_messages()[0]
    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_event_handler(
            operation="assert_consumer",
            message={"event": event.event_name, "body": event.to_json()},
        ).to_dict(),
    )
    assert notifier.publish_called
    assert notifier.publish_times_called == 1
def test_should_returns_an_error_when_a_empty_controller_get_a_required_jwt_token_but_missing_user(
    given_any_petisco,
    given_any_token_type,
    given_headers_provider,
    given_auth_token_headers_creator,
    given_any_token_type_with_user,
    given_any_client_id,
    given_info_id_only_correlation_id,
):
    logger = FakeLogger()

    @controller_handler(
        logger=logger,
        token_manager=TokenManager(accepted_tokens=[
            AcceptedToken(token_type=given_any_token_type, require_user=True)
        ]),
        headers_provider=given_headers_provider(
            {
                **given_auth_token_headers_creator(
                    given_any_token_type_with_user, given_any_client_id, None),
                **given_info_id_only_correlation_id.get_http_headers(),
            }),
    )
    def my_controller():
        return Success("Hello Petisco")

    http_response = my_controller()

    assert http_response == (
        {
            "error": {
                "message":
                "Access token is missing or invalid. This entry point expects a valid TOKEN Token with require_user=True",
                "type": "InvalidTokenHttpError",
            }
        },
        401,
    )

    first_logging_message = logger.get_logging_messages()[0]

    assert first_logging_message == (
        ERROR,
        LogMessageMother.get_controller(
            operation="my_controller",
            message=
            "Result[status: failure | value: InvalidTokenError: This entry point expects a valid TOKEN Token with require_user=True]",
        ).to_dict(),
    )
def test_should_execute_successfully_a_empty_controller_with_several_jwt_requirement(
    accepted_tokens,
    token_type,
    user_id,
    expected_status_code,
    given_any_petisco,
    given_headers_provider,
    given_auth_token_headers_creator,
    given_any_client_id,
    given_any_correlation_id,
    given_info_id_only_correlation_id,
):

    logger = FakeLogger()
    expected_info_id = InfoId(
        client_id=given_any_client_id,
        user_id=user_id,
        correlation_id=given_any_correlation_id,
    )

    @controller_handler(
        logger=logger,
        token_manager=TokenManager(accepted_tokens=accepted_tokens),
        headers_provider=given_headers_provider({
            **given_auth_token_headers_creator(token_type, given_any_client_id, user_id),
            **given_info_id_only_correlation_id.get_http_headers(),
        }),
    )
    def my_controller(info_id: InfoId):
        assert info_id == expected_info_id
        return Success("Hello Petisco")

    http_response = my_controller()

    assert http_response[1] == expected_status_code
Example #15
0
def test_should_consumer_react_to_chaos_with_nck_simulation_and_check_logger():
    spy = SpyEvents()
    logger = FakeLogger()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isSuccess

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]

    configurer = RabbitMqEventConfigurerMother.with_retry_ttl_10ms()
    configurer.configure_subscribers(subscribers)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    max_retries_allowed = 5
    chaos = RabbitMqEventChaos(percentage_simulate_nack=1.0)
    consumer = RabbitMqEventConsumerMother.with_chaos(
        chaos, max_retries_allowed, logger
    )
    consumer.add_subscribers(subscribers)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    assert len(logger.get_logging_messages()) >= 200
    first_logging_message = logger.get_logging_messages()[0]

    assert first_logging_message[0] == DEBUG
    assert first_logging_message[1]["meta"] == {
        "layer": "rabbitmq_event_consumer",
        "operation": "assert_consumer",
    }
    assert (
        first_logging_message[1]["data"]["message"]["chaos_action"] == "nack simulated"
    )
Example #16
0
def test_should_publish_consume_with_event_handler_when_fail_consumer():
    spy = SpyEvents()
    logger = FakeLogger()

    @event_handler(logger=logger)
    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isFailure

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]

    configurer = RabbitMqEventConfigurerMother.default()
    configurer.configure_subscribers(subscribers)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    consumer = RabbitMqEventConsumerMother.with_max_retries(1)
    consumer.add_subscribers(subscribers)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy.assert_number_unique_events(1)
    spy.assert_first_event(event)
    spy.assert_count_by_event_id(event.event_id, 1)

    first_logging_message = logger.get_logging_messages()[0]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_event_handler(
            operation="assert_consumer",
            message={"event": event.event_name, "body": event.to_json()},
        ).to_dict(),
    )
Example #17
0
def test_should_consumer_react_to_chaos_with_zero_probability():
    spy = SpyEvents()
    logger = FakeLogger()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isSuccess

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]

    configurer = RabbitMqEventConfigurerMother.with_retry_ttl_10ms()
    configurer.configure_subscribers(subscribers)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    max_retries_allowed = 5
    chaos = RabbitMqEventChaos(
        percentage_simulate_nack=0.0, percentage_simulate_failures=0.0
    )
    consumer = RabbitMqEventConsumerMother.with_chaos(
        chaos, max_retries_allowed, logger
    )
    consumer.add_subscribers(subscribers)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy.assert_number_unique_events(1)
    spy.assert_first_event(event)
    spy.assert_count_by_event_id(event.event_id, 1)

    assert len(logger.get_logging_messages()) == 2
    logging_message = logger.get_logging_messages()[1]
    assert logging_message[0] == DEBUG
    assert logging_message[1]["data"]["message"]["derived_action"] == {}
def test_should_execute_with_a_failure_a_empty_controller_without_input_parameters(
        given_any_petisco, given_any_info_id, given_headers_provider):

    logger = FakeLogger()

    @controller_handler(
        logger=logger,
        headers_provider=given_headers_provider(
            given_any_info_id.get_http_headers()),
    )
    def my_controller(headers=None):
        return isFailure

    http_response = my_controller()

    assert http_response == (
        {
            "error": {
                "message": "Unknown Error",
                "type": "HttpError"
            }
        },
        500,
    )

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=given_any_info_id,
        ).to_dict(),
    )

    assert second_logging_message == (
        ERROR,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Result[status: failure | value: Error]",
            info_id=given_any_info_id,
        ).to_dict(),
    )
Example #19
0
def test_should_consumer_react_to_chaos_with_failure_simulation_and_check_logger_with_subscribers():
    spy = SpyEvents()
    spy_dead_letter = SpyEvents()

    logger = FakeLogger()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isSuccess

    def assert_dead_letter_consumer(event: Event) -> Result[bool, Error]:
        spy_dead_letter.append(event)
        return isSuccess

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]

    configurer = RabbitMqEventConfigurerMother.with_main_and_retry_ttl_100ms()
    configurer.configure_subscribers(subscribers)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    max_retries_allowed = 5
    chaos = RabbitMqEventChaos(
        percentage_simulate_failures=1.0,
        protected_routing_keys=[
            "dead_letter.alice.petisco.1.event.user_created.assert_consumer"
        ],
    )
    consumer = RabbitMqEventConsumerMother.with_chaos(
        chaos, max_retries_allowed, logger
    )
    consumer.add_subscribers(subscribers)
    consumer.add_handler_on_queue(
        "dead_letter.alice.petisco.1.event.user_created.assert_consumer",
        assert_dead_letter_consumer,
    )

    consumer.start()

    sleep(1.5)

    consumer.stop()
    configurer.clear()

    spy.assert_count_by_event_id(event.event_id, 0)
    spy_dead_letter.assert_count_by_event_id(event.event_id, 1)

    assert_logger_represents_simulated_failure_scenario(logger, max_retries_allowed)
def test_should_log_an_exception_occurred_on_the_controller(
        given_any_petisco, given_any_info_id, given_headers_provider):

    logger = FakeLogger()

    @controller_handler(
        logger=logger,
        headers_provider=given_headers_provider(
            given_any_info_id.get_http_headers()),
    )
    def my_controller(headers=None):
        raise RuntimeError("my_controller exception")

    http_response = my_controller()

    assert http_response == (
        {
            "error": {
                "message": "Internal Error.",
                "type": "InternalHttpError"
            }
        },
        500,
    )

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=given_any_info_id,
        ).to_dict(),
    )

    assert second_logging_message[0] == ERROR
    assert "line" in second_logging_message[1]["data"]["message"]
    assert "RuntimeError" in second_logging_message[1]["data"]["message"]
    assert "my_controller exception" in second_logging_message[1]["data"][
        "message"]
Example #21
0
def test_should_use_case_handler_return_a_failure_with_unknown_error_when_raise_an_uncontrolled_exception_with_non_defined_input_parameters(
    given_any_petisco
):

    logger = FakeLogger()
    expected_raised_exception = RuntimeError("uncontrolled exception")
    input_text = "my-text"
    input_verbose = True

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self, text: str, verbose: bool):
            raise expected_raised_exception

    result = MyUseCase().execute(input_text, input_verbose)

    assert_failure(
        result,
        value_is_instance_of=UnknownError,
        value_is_equal_to=UnknownError(expected_raised_exception),
    )

    assert {"param_1": "my-text", "param_2": True} == result.value.input_parameters

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert (
        "value: UnknownError (MyUseCase (Use Case)): RuntimeError: uncontrolled exception.\nTraceback (most recent call last):\n  File"
        in second_logging_message[1]["data"]["message"]
    )
def test_should_execute_successfully_a_filtered_object_by_blacklist(
        given_any_petisco, given_any_info_id, given_headers_provider):

    logger = FakeLogger()

    @controller_handler(
        logger=logger,
        headers_provider=given_headers_provider(
            given_any_info_id.get_http_headers()),
    )
    def my_controller(headers=None):
        return Success(b"This are bytes")

    http_response = my_controller()

    assert http_response == ({"message": "OK"}, 200)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=given_any_info_id,
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Success result of type: bytes",
            info_id=given_any_info_id,
        ).to_dict(),
    )
def test_should_execute_successfully_a_empty_controller_with_correlation_id_as_only_input_parameter(
        given_any_petisco, given_any_info_id, given_headers_provider):

    logger = FakeLogger()

    @controller_handler(
        logger=logger,
        headers_provider=given_headers_provider(
            given_any_info_id.get_http_headers()),
    )
    def my_controller(headers=None):
        return Success("Hello Petisco")

    http_response = my_controller()

    assert http_response == ({"message": "OK"}, 200)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Processing Request",
            info_id=given_any_info_id,
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_controller(
            operation="my_controller",
            message="Result[status: success | value: Hello Petisco]",
            info_id=given_any_info_id,
        ).to_dict(),
    )
Example #24
0
def test_should_log_successfully_a_large_type_with_its_repr(given_any_petisco):

    logger = FakeLogger()

    class BinaryInfo(NamedTuple):
        name: str
        data: bytes

        def __repr__(self) -> str:
            return f"<BinaryInfo {self.name}, len(data)={len(self.data)}>"

    @use_case_handler(logger=logger)
    class MyUseCase(UseCase):
        def execute(self):
            binary_info = BinaryInfo(name="my_data", data=b"This are bytes")
            return Success(binary_info)

    result = MyUseCase().execute()

    assert_success(result)

    first_logging_message = logger.get_logging_messages()[0]
    second_logging_message = logger.get_logging_messages()[1]

    assert first_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="Running Use Case"
        ).to_dict(),
    )
    assert second_logging_message == (
        DEBUG,
        LogMessageMother.get_use_case(
            operation="MyUseCase", message="<BinaryInfo my_data, len(data)=14>"
        ).to_dict(),
    )
Example #25
0
def test_should_store_consumer_react_to_chaos_with_nck_simulation_and_send_several_event_to_dead_letter():
    spy = SpyEvents()
    spy_dead_letter_store = SpyEvents()
    logger = FakeLogger()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isSuccess

    def assert_dead_letter_store_consumer(event: Event) -> Result[bool, Error]:
        spy_dead_letter_store.append(event)
        return isSuccess

    configurer = RabbitMqEventConfigurerMother.with_main_and_retry_ttl_10ms()
    configurer.configure()

    bus = RabbitMqEventBusMother.default()

    event_ids = []
    for _ in range(5):
        event = EventUserCreatedMother.random()
        event_ids.append(event.event_id)
        bus.publish(event)

    max_retries_allowed = 5
    chaos = RabbitMqEventChaos(percentage_simulate_nack=1.0)
    consumer_with_chaos = RabbitMqEventConsumerMother.with_chaos(
        chaos, max_retries_allowed, logger
    )
    consumer_with_chaos.add_handler_on_store(assert_consumer)
    consumer_with_chaos.start()
    sleep(1.0)
    consumer_with_chaos.stop()

    consumer_without_chaos = RabbitMqEventConsumerMother.default()
    consumer_without_chaos.add_handler_on_queue(
        "dead_letter.store", assert_dead_letter_store_consumer
    )

    consumer_without_chaos.start()
    sleep(1.0)
    consumer_without_chaos.stop()

    configurer.clear()

    for event_id in event_ids:
        spy.assert_count_by_event_id(event_id, 0)  # Rejected before by Event Chaos
        spy_dead_letter_store.assert_count_by_event_id(event_id, 1)
Example #26
0
def test_should_consumer_react_to_chaos_with_failure_simulation_and_check_logger_without_subscribers():
    spy = SpyEvents()
    spy_dead_letter = SpyEvents()

    logger = FakeLogger()

    def assert_store_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        return isSuccess

    def assert_dead_letter_store_consumer(event: Event) -> Result[bool, Error]:
        spy_dead_letter.append(event)
        return isSuccess

    event = EventUserCreatedMother.random()

    configurer = RabbitMqEventConfigurerMother.with_main_and_retry_ttl_100ms()
    configurer.configure()

    bus = RabbitMqEventBusMother.default()
    bus.publish(event)

    max_retries_allowed = 5
    chaos = RabbitMqEventChaos(
        percentage_simulate_failures=1.0, protected_routing_keys=["dead_letter.store"]
    )
    consumer = RabbitMqEventConsumerMother.with_chaos(
        chaos, max_retries_allowed, logger
    )
    consumer.add_handler_on_store(assert_store_consumer)
    consumer.add_handler_on_queue(
        "dead_letter.store", assert_dead_letter_store_consumer
    )
    consumer.start()

    sleep(1.5)

    consumer.stop()
    configurer.clear()

    spy.assert_count_by_event_id(event.event_id, 0)
    spy_dead_letter.assert_count_by_event_id(event.event_id, 1)
def test_should_publish_event_on_consumer_with_event_handler():
    spy = SpyEvents()

    @event_handler(logger=FakeLogger())
    def assert_consumer(event: Event, event_bus: IEventBus) -> BoolResult:
        spy.append(event)
        event = EventUserUpdatedMother.random()
        event_bus.publish(event)
        return isSuccess

    event = EventUserCreatedMother.random()
    subscribers = [
        EventSubscriber(
            event_name=event.event_name,
            event_version=event.event_version,
            handlers=[assert_consumer],
        )
    ]
    configurer = RabbitMqEventConfigurerMother.with_retry_ttl_10ms()
    configurer.configure_subscribers(subscribers)

    consumer = RabbitMqEventConsumerMother.with_max_retries(1)
    consumer.add_subscribers(subscribers)
    consumer.start()

    bus = RabbitMqEventBusMother.default()
    for _ in range(1):
        event = EventUserCreatedMother.random()
        bus.publish(event)

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy.assert_number_unique_events(1)