Repository: celery/celery
File: t/unit/worker/test_native_delayed_delivery.py (Python)

Code before:
            'queue1': queue1,
            'queue2': queue2,
            'queue3': queue3,
        }

        # Make queue1 and queue3 fail with different errors
        def bind_side_effect(connection, queue):
            if queue.name == 'queue1':
                raise ValueError("Queue1 binding failed")
            elif queue.name == 'queue3':
                raise RuntimeError("Queue3 binding failed")

        mock_bind.side_effect = bind_side_effect

        delayed_delivery = DelayedDelivery(consumer_mock)

        # Should raise RuntimeError containing both exceptions messages
        with pytest.raises(ExceptionGroup) as exc_info:
            delayed_delivery._setup_delayed_delivery(consumer_mock, 'amqp://')

        # Verify the RuntimeError message contains both exceptions
        exception_group = exc_info.value
        assert str(exception_group) == (
            "One or more failures occurred while binding queues to delayed "
            "delivery exchanges\n"
            " (2 sub-exceptions)"
        )

        # Verify the ExceptionGroup contains both exceptions
        exceptions = exception_group.exceptions
        assert len(exceptions) == 2
        assert any(
            isinstance(ex, ValueError) and str(ex) == "Queue1 binding failed"
            for ex in exceptions
        )
        assert any(
            isinstance(ex, RuntimeError) and str(ex) == "Queue3 binding failed"
            for ex in exceptions
        )

        # Verify bind was called for all three queues
        assert mock_bind.call_count == 3

    @patch('celery.worker.consumer.delayed_delivery.bind_queue_to_native_delayed_delivery_exchange')
    def test_bind_retries_on_retried_exception(self, mock_bind, caplog):
        """
        Test that retried exceptions from
        bind_queue_to_native_delayed_delivery_exchange trigger the retry
        mechanism.
        """
        consumer_mock = MagicMock()

Review comment (suggestion):
```suggestion
            "delivery exchanges (2 sub-exceptions)"
```

Code after:
            'queue1': queue1,
            'queue2': queue2,
            'queue3': queue3,
        }

        # Make queue1 and queue3 fail with different errors
        def bind_side_effect(connection, queue):
            if queue.name == 'queue1':
                raise ValueError("Queue1 binding failed")
            elif queue.name == 'queue3':
                raise RuntimeError("Queue3 binding failed")

        mock_bind.side_effect = bind_side_effect

        delayed_delivery = DelayedDelivery(consumer_mock)

        # Should raise RuntimeError containing both exceptions messages
        with pytest.raises(ExceptionGroup) as exc_info:
            delayed_delivery._setup_delayed_delivery(consumer_mock, 'amqp://')

        # Verify the RuntimeError message contains both exceptions
        exception_group = exc_info.value
        assert str(exception_group) == (
            "One or more failures occurred while binding queues to delayed "
            "delivery exchanges (2 sub-exceptions)"
        )

        # Verify the ExceptionGroup contains both exceptions
        exceptions = exception_group.exceptions
        assert len(exceptions) == 2
        assert any(
            isinstance(ex, ValueError) and str(ex) == "Queue1 binding failed"
            for ex in exceptions
        )
        assert any(
            isinstance(ex, RuntimeError) and str(ex) == "Queue3 binding failed"
            for ex in exceptions
        )

        # Verify bind was called for all three queues
        assert mock_bind.call_count == 3

    @patch('celery.worker.consumer.delayed_delivery.bind_queue_to_native_delayed_delivery_exchange')
    def test_bind_retries_on_retried_exception(self, mock_bind, caplog):
        """
        Test that retried exceptions from
        bind_queue_to_native_delayed_delivery_exchange trigger the retry
        mechanism.
        """
        consumer_mock = MagicMock()
        consumer_mock.app.conf.broker_native_delayed_delivery_queue_type = \