def test_should_configure_two_services_without_subscribers():
    spy = SpyEvents()

    def assert_store(event: Event) -> BoolResult:
        spy.append(event)
        return isSuccess

    configurer_service_1 = RabbitMqEventConfigurerMother.with_service(
        "service1")
    configurer_service_1.configure()

    configurer_service_2 = RabbitMqEventConfigurerMother.with_service(
        "service2")
    configurer_service_2.configure()

    event = EventUserCreatedMother.random()
    bus = RabbitMqEventBusMother.with_service("service1")
    bus.publish(event)

    consumer = RabbitMqEventConsumerMother.default()
    consumer.add_handler_on_store(assert_store)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer_service_1.clear()
    configurer_service_2.clear()

    spy.assert_number_unique_events(1)
    spy.assert_first_event(event)
    spy.assert_last_event(event)
    spy.assert_count_by_event_id(event.event_id, 1)
Example #2
0
def test_should_consumer_react_to_chaos_inputs(
    max_retries_allowed, expected_number_event_consumed, chaos
):
    spy = SpyEvents()

    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)

    consumer = RabbitMqEventConsumerMother.with_chaos(chaos, max_retries_allowed)
    consumer.add_subscribers(subscribers)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()
    spy.assert_count_by_event_id(event.event_id, expected_number_event_consumed)
def test_should_publish_two_event_and_consume_from_store_queue_from_rabbitmq(
    max_retries_allowed, simulated_results
):

    spy = SpyEvents()

    def assert_consumer_event_store(event: Event) -> Result[bool, Error]:
        spy.append(event)
        result = simulated_results.pop(0)
        return result

    event_1 = EventUserCreatedMother.random()
    event_2 = EventUserCreatedMother.random()

    configurer = RabbitMqEventConfigurerMother.with_retry_ttl_10ms()
    configurer.configure_event(event_1)
    configurer.configure_event(event_2)

    bus = RabbitMqEventBusMother.default()
    bus.publish(event_1)
    bus.publish(event_2)

    consumer = RabbitMqEventConsumerMother.with_max_retries(max_retries_allowed)

    consumer.add_handler_on_store(assert_consumer_event_store)
    consumer.start()

    sleep(1.0)
    consumer.stop()
    configurer.clear()

    spy.assert_number_unique_events(2)
def test_should_publish_consume_from_store_queue_from_rabbitmq():

    spy = SpyEvents()

    def assert_consumer_event_store(event: Event) -> BoolResult:
        spy.append(event)
        return isSuccess

    event = EventUserCreatedMother.random()

    configurer = RabbitMqEventConfigurerMother.default()
    configurer.configure_event(event)

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

    consumer = RabbitMqEventConsumerMother.default()

    consumer.add_handler_on_store(assert_consumer_event_store)
    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)
Example #5
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_unsubscribe_and_resume_handler_on_dead_letter_store_queue():

    spy_dead_letter = SpyEvents()

    def assert_consumer_event_store(event: Event) -> BoolResult:
        return isFailure

    def assert_consumer_event_dead_letter(event: Event) -> BoolResult:
        spy_dead_letter.append(event)
        return isSuccess

    bus = RabbitMqEventBusMother.default()

    first_event = EventUserCreatedMother.random()
    configurer = RabbitMqEventConfigurerMother.with_retry_ttl_10ms()
    configurer.configure_event(first_event)

    # Consumer configuration
    consumer = RabbitMqEventConsumerMother.default()
    consumer.add_handler_on_store(assert_consumer_event_store)
    consumer.add_handler_on_queue(
        "dead_letter.store", assert_consumer_event_dead_letter
    )
    consumer.start()

    for i in range(10):
        bus.publish(EventUserCreatedMother.random())
    sleep(5.0)

    consumer.unsubscribe_handler_on_queue("dead_letter.store")

    for i in range(10):
        bus.publish(EventUserCreatedMother.random())
    sleep(5.0)

    consumer.resume_handler_on_queue("dead_letter.store")

    for i in range(10):
        bus.publish(EventUserCreatedMother.random())
    sleep(5.0)

    consumer.stop()
    configurer.clear()

    spy_dead_letter.assert_number_unique_events(30)
Example #7
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
Example #8
0
def test_should_publish_consume_and_retry_event_from_rabbitmq_when_fail_consumer(
        max_retries_allowed, expected_number_event_consumed,
        simulated_results):
    spy = SpyEvents()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        result = simulated_results.pop(0)
        return result

    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)

    consumer = RabbitMqEventConsumerMother.with_max_retries(
        max_retries_allowed)
    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_last_event(event)
    spy.assert_count_by_event_id(event.event_id,
                                 expected_number_event_consumed)
Example #9
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)
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)
Example #11
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 #12
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"] == {}
Example #13
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"
    )
def test_should_publish_and_then_consumer_retry_publish_only_on_store_queue_not_affecting_default_event_queue(
):

    spy_consumer_default_queue = SpyEvents()
    spy_consumer_store = SpyEvents()

    def assert_consumer_default_queue(event: Event) -> BoolResult:
        spy_consumer_default_queue.append(event)
        bus = RabbitMqEventBusMother.default()
        bus.retry_publish_only_on_store_queue(event)
        return isSuccess

    def assert_consumer_store(event: Event) -> BoolResult:
        spy_consumer_store.append(event)
        return isSuccess

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

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

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

    consumer = RabbitMqEventConsumerMother.default()
    consumer.add_subscribers(subscribers)
    consumer.add_handler_on_store(assert_consumer_store)

    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy_consumer_default_queue.assert_count_by_event_id(event.event_id, 1)
    spy_consumer_store.assert_count_by_event_id(event.event_id, 2)
Example #15
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)
Example #16
0
def test_should_publish_consume_with_event_handler_with_default_parameters_when_success_consumer(
    given_any_petisco
):
    spy = SpyEvents()

    @event_handler()
    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.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)
def test_should_publish_consume_from_store_queue_from_rabbitmq_with_stop_and_start():

    spy = SpyEvents()

    def assert_consumer_event_store(event: Event) -> BoolResult:
        spy.append(event)
        return isSuccess

    bus = RabbitMqEventBusMother.default()

    first_event = EventUserCreatedMother.random()
    configurer = RabbitMqEventConfigurerMother.default()
    configurer.configure_event(first_event)

    # First Start & Stop
    bus.publish(first_event)
    first_consumer = RabbitMqEventConsumerMother.default()
    first_consumer.add_handler_on_store(assert_consumer_event_store)
    first_consumer.start()
    sleep(1.0)
    first_consumer.stop()

    # Second Start & Stop
    second_event = EventUserCreatedMother.random()
    second_consumer = RabbitMqEventConsumerMother.default()
    second_consumer.add_handler_on_store(assert_consumer_event_store)
    second_consumer.start()
    bus.publish(second_event)
    sleep(1.0)
    second_consumer.stop()

    configurer.clear()

    spy.assert_number_unique_events(2)
    spy.assert_count_by_event_id(first_event.event_id, 1)
    spy.assert_count_by_event_id(second_event.event_id, 1)
def test_should_configure_two_services_without_subscribers_and_consuming_event_from_store_queues(
    publish_events_service_1,
    publish_events_service_2,
    expected_unique_events,
    expected_total_received_events,
    simulated_results_store,
):
    spy = SpyEvents()

    def assert_store(event: Event) -> BoolResult:
        spy.append(event)
        result = simulated_results_store.pop(0)
        return result

    configurer_service_1 = RabbitMqEventConfigurerMother.with_service(
        "service1")
    configurer_service_1.configure()

    configurer_service_2 = RabbitMqEventConfigurerMother.with_service(
        "service2")
    configurer_service_2.configure()

    bus_service_1 = RabbitMqEventBusMother.with_service("service1")
    bus_service_2 = RabbitMqEventBusMother.with_service("service2")

    def publish_event(bus: IEventBus, times: int):
        for _ in range(times):
            event = EventUserCreatedMother.random()
            bus.publish(event)

    publish_event(bus_service_1, publish_events_service_1)
    publish_event(bus_service_2, publish_events_service_2)

    consumer = RabbitMqEventConsumerMother.with_service("service1")
    consumer.add_handler_on_store(assert_store)
    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer_service_1.clear()
    configurer_service_2.clear()

    spy.assert_number_unique_events(expected_unique_events)
    spy.assert_number_total_events(expected_total_received_events)
Example #19
0
def test_should_publish_consume_and_retry_event_with_two_handlers_from_rabbitmq_when_fail_consumer(
        max_retries_allowed, expected_number_event_consumed,
        simulated_results):

    spy_consumer_1 = SpyEvents()
    spy_consumer_2 = SpyEvents()

    simulated_results_1 = copy.deepcopy(simulated_results)
    simulated_results_2 = copy.deepcopy(simulated_results)

    def assert_consumer_1(event: Event) -> Result[bool, Error]:
        spy_consumer_1.append(event)
        result = simulated_results_1.pop(0)
        return result

    def assert_consumer_2(event: Event) -> Result[bool, Error]:
        spy_consumer_2.append(event)
        result = simulated_results_2.pop(0)
        return result

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

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

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

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

    sleep(1.5)

    consumer.stop()
    configurer.clear()

    print(f"num events: {len(spy_consumer_1.events)} - {spy_consumer_1}")
    print(f"num events: {len(spy_consumer_2.events)} - {spy_consumer_2}")

    spy_consumer_1.assert_number_unique_events(1)
    spy_consumer_1.assert_first_event(event)
    spy_consumer_1.assert_count_by_event_id(event.event_id,
                                            expected_number_event_consumed)

    spy_consumer_2.assert_number_unique_events(1)
    spy_consumer_2.assert_first_event(event)
    spy_consumer_2.assert_count_by_event_id(event.event_id,
                                            expected_number_event_consumed)
def test_should_configure_one_services_with_modern_event_management_an_other_with_legacy(
):
    spy_legacy = SpyEvents()
    spy_modern = SpyEvents()
    event = EventUserCreatedMother.random()

    def step_1_execute_legacy():
        # Define legacy Subscriber
        @subscriber_handler(logger=NotImplementedLogger())
        def main_handler(event: Event):
            spy_legacy.append(event)
            return isFailure

        subscriber = RabbitMqEventSubscriberMother.default(main_handler)
        subscriber.start()

        # Define legacy Publisher
        legacy_publisher = RabbitMqEventPublisherMother.default()
        legacy_publisher.publish(event)

        sleep(1.0)

        subscriber.stop()

    def step_2_execute_modern():
        # Define modern Consumer
        def modern_handler(event: Event) -> BoolResult:
            spy_modern.append(event)
            return isSuccess

        legacy_queue = RabbitMqQueueNamingMother.legacy_dead_letter_queue()
        consumer = RabbitMqEventConsumerMother.default()
        consumer.add_handler_on_queue(legacy_queue, modern_handler)
        consumer.start()

        sleep(1.0)

        consumer.stop()

    rabbitmq = RabbitMqDeclarerMother.default()
    rabbitmq.delete_queue(RabbitMqQueueNamingMother.legacy_dead_letter_queue())

    step_1_execute_legacy()
    step_2_execute_modern()

    spy_legacy.assert_number_unique_events(1)
    spy_legacy.assert_first_event(event)

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

    rabbitmq.delete_queue(RabbitMqQueueNamingMother.legacy_main_queue())
    rabbitmq.delete_queue(RabbitMqQueueNamingMother.legacy_dead_letter_queue())
Example #21
0
def test_should_publish_consume_retry_and_send_to_dead_letter_event_from_rabbitmq_when_fail_consumer(
):
    max_retries_allowed = 2
    expected_number_event_consumed = 3

    spy = SpyEvents()
    spy_dead_letter = SpyEvents()

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

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

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

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

    consumer = RabbitMqEventConsumerMother.with_max_retries(
        max_retries_allowed)
    consumer.add_subscribers(subscribers)

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

    consumer.add_subscriber_on_dead_letter(subscriber, dead_letter_consumer)

    consumer.start()

    sleep(1.5)

    consumer.stop()
    configurer.clear()

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

    spy_dead_letter.assert_number_unique_events(1)
    spy_dead_letter.assert_first_event(event)
    spy_dead_letter.assert_count_by_event_id(event.event_id, 1)
Example #22
0
def test_should_publish_consume_and_retry_event_not_affecting_other_queue_including_store_queue_from_rabbitmq(
    max_retries_allowed,
    expected_number_event_consumed_by_store,
    expected_number_event_consumed_by_handler_1,
    expected_number_event_consumed_by_handler_2,
    simulated_results_store,
    simulated_results_handler_1,
    simulated_results_handler_2,
):

    spy_consumer_event_store = SpyEvents()
    spy_consumer_handler_1 = SpyEvents()
    spy_consumer_handler_2 = SpyEvents()

    def assert_consumer_event_store(event: Event) -> Result[bool, Error]:
        spy_consumer_event_store.append(event)
        result = simulated_results_store.pop(0)
        return result

    def assert_consumer_handler_1(event: Event) -> Result[bool, Error]:
        spy_consumer_handler_1.append(event)
        result = simulated_results_handler_1.pop(0)
        return result

    def assert_consumer_handler_2(event: Event) -> Result[bool, Error]:
        spy_consumer_handler_2.append(event)
        result = simulated_results_handler_2.pop(0)
        return result

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

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

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

    consumer = RabbitMqEventConsumerMother.with_max_retries(
        max_retries_allowed)
    consumer.add_subscribers(subscribers)
    consumer.add_handler_on_store(assert_consumer_event_store)

    consumer.start()

    sleep(1.0)

    consumer.stop()
    configurer.clear()

    spy_consumer_event_store.assert_number_unique_events(1)
    spy_consumer_event_store.assert_first_event(event)
    spy_consumer_event_store.assert_count_by_event_id(
        event.event_id, expected_number_event_consumed_by_store)

    spy_consumer_handler_1.assert_number_unique_events(1)
    spy_consumer_handler_1.assert_first_event(event)
    spy_consumer_handler_1.assert_count_by_event_id(
        event.event_id, expected_number_event_consumed_by_handler_1)

    spy_consumer_handler_2.assert_number_unique_events(1)
    spy_consumer_handler_2.assert_first_event(event)
    spy_consumer_handler_2.assert_count_by_event_id(
        event.event_id, expected_number_event_consumed_by_handler_2)
Example #23
0
def test_should_publish_consume_and_retry_event_with_two_handlers_from_rabbitmq(
):

    spy_consumer_1 = SpyEvents()
    spy_consumer_2 = SpyEvents()

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

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

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

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

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

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

    sleep(1.0)

    consumer.stop()
    configurer.clear()

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

    spy_consumer_2.assert_number_unique_events(1)
    spy_consumer_2.assert_first_event(event)
    spy_consumer_2.assert_count_by_event_id(event.event_id, 1)
Example #24
0
def test_should_publish_consume_and_retry_event_from_rabbitmq_when_a_queue_is_configured_with_specific_parameters(
    max_retries_allowed, expected_number_event_consumed, simulated_results
):
    spy = SpyEvents()
    spy_specific = SpyEvents()

    def assert_consumer(event: Event) -> Result[bool, Error]:
        spy.append(event)
        result = simulated_results.pop(0)
        return result

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

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

    specific_queue_config = SpecificQueueConfig(
        wildcard="*assert_specific_consumer",
        specific_retry_ttl=50,
        specific_main_ttl=75,
    )
    queue_config = QueueConfigMother.with_specific_queue_config(
        specific_queue_config, default_retry_ttl=100, default_main_ttl=100
    )

    configurer = RabbitMqEventConfigurerMother.with_queue_config(queue_config)
    configurer.configure_subscribers(subscribers)

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

    consumer = RabbitMqEventConsumerMother.with_max_retries(max_retries_allowed)
    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_last_event(event)
    spy.assert_count_by_event_id(event.event_id, expected_number_event_consumed)
    spy_specific.assert_number_unique_events(1)