Skip to content

tests: declare durable queues so the suite runs on RabbitMQ 4.3+ - #1242

Open
syedusmanali wants to merge 1 commit into
php-amqplib:masterfrom
syedusmanali:migrate_tests_off_transient_nonexcl_queues
Open

syedusmanali wants to merge 1 commit into
php-amqplib:masterfrom
syedusmanali:migrate_tests_off_transient_nonexcl_queues

Conversation

@syedusmanali

Copy link
Copy Markdown

Fixes #1241

RabbitMQ 4.3 flipped the transient_nonexcl_queues deprecated feature from permitted_by_default to denied_by_default, so the broker refuses non-durable, non-exclusive classic queues. .ci/ubuntu/gha-setup.sh pulls the unpinned rabbitmq:management tag, which now resolves to 4.3.x, and every functional test that declares a queue was taking queue_declare()'s defaults - durable=false, exclusive=false, exactly the combination that's refused. That's 32 errors on every PHP version in the matrix.

This turns durable on at the 14 call sites that needed it. Nothing else changes: the queues stay non-exclusive and keep auto_delete, so visibility and cleanup behave as before and only persistence differs.

Why durable and not exclusive

Declaring the queues exclusive also satisfies the broker, and I tried that first. It breaks the tests that deliberately destroy connections. An exclusive queue dies with its connection, which unbinds it, which auto-deletes the shared test_exchange_broken (exchange_declare defaults to auto_delete=true), and the next test then races that deletion and fails with NOT_FOUND - no exchange 'test_exchange_broken'. It's intermittent, which makes it worse. durable is also the smaller semantic change - exclusive alters both visibility and lifetime, durable only alters persistence.

Verification

Broker Deprecated features Result
4.3.5 nothing permitted OK - 864 tests, 1288 assertions, 0 failures
3.13.7 (as pinned by docker-compose.yaml) OK - 864 tests, 1288 assertions, 0 failures

Run three times in a row on 4.3.5 against a reused broker, so the second and third runs re-declared queues that already existed as durable. No inequivalent arg problems. vendor/bin/phpcs is clean.

Worth knowing for anyone testing this locally: if you already have a broker holding a transient reconnect_queue from before this change, your first run will hit PRECONDITION_FAILED - inequivalent arg 'durable'. ReconnectConnectionTest::tearDownCompat deletes the queue, so it sorts itself out after one run. CI never sees it because the broker is fresh every time.

On the tests requirement

CONTRIBUTING asks for tests with every patch and I can't really add one here, since the change is to the tests. The existing suite going from 32 errors to 0 against a strict broker is the only evidence this kind of change can offer.

Deliberately not in this PR

  • Pinning the CI image, or adding a job against the newest broker with all deprecated features denied.
  • queue_declare()'s own defaults, which is the user-facing half of this and needs a maintainer decision - discussed in the issue.
  • tests/rabbitmq.conf and docker-compose.yaml's rabbitmq:3-management pin.
  • The pre-existing duplicate listeners.tcp.default / listeners.ssl.default block in .ci/ubuntu/rabbitmq.conf. Unrelated, and tidying it here would just muddy the diff.

If you'd rather have CI green in one line while you review this, deprecated_features.permit.transient_nonexcl_queues = true in .ci/ubuntu/rabbitmq.conf does it, and I can send that separately. It's a stopgap though, since RabbitMQ intends to remove the feature regardless of config.

RabbitMQ 4.3 moved the transient_nonexcl_queues deprecated feature from
permitted_by_default to denied_by_default, so the broker now refuses
non-durable, non-exclusive classic queues.

Every functional test that declared a queue relied on queue_declare()'s
defaults, which are durable=false and exclusive=false - exactly the
combination that is refused. That is 32 errors, on every PHP version,
because the refusal comes from the broker rather than from PHP.

Turning durable on is the smallest change that fixes it: the queues stay
non-exclusive and keep auto_delete, so visibility and cleanup are unchanged
and only persistence differs. Declaring them exclusive would also satisfy
the broker, but exclusive queues die with their connection, which breaks
the tests that deliberately destroy connections - an exclusive queue there
takes the shared auto-delete exchange down with it and the next test races
the deletion.

Verified against RabbitMQ 4.3.5 with nothing permitted, and against 3.13.7
for compatibility.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Functional tests fail on RabbitMQ 4.3+ (transient_nonexcl_queues now denied by default)

1 participant