From d0c06cef9aea70b308a45a2c6f51ee330e7aef74 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Tue, 1 Jul 2025 13:04:29 +0200 Subject: [PATCH 01/15] Test mixed version with 3.13.7/OTP26 --- .github/workflows/test-make-target.yaml | 2 +- .github/workflows/test-make.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-make-target.yaml b/.github/workflows/test-make-target.yaml index 184fb927a02..dcb7980d5bb 100644 --- a/.github/workflows/test-make-target.yaml +++ b/.github/workflows/test-make-target.yaml @@ -62,7 +62,7 @@ jobs: uses: dsaltares/fetch-gh-release-asset@master if: inputs.mixed_clusters with: - version: 'tags/v4.0.9' + version: 'tags/v3.13.7' regex: true file: "rabbitmq-server-generic-unix-\\d.+\\.tar\\.xz" target: ./ diff --git a/.github/workflows/test-make.yaml b/.github/workflows/test-make.yaml index 7b274228d8a..dd28079d6d8 100644 --- a/.github/workflows/test-make.yaml +++ b/.github/workflows/test-make.yaml @@ -82,12 +82,12 @@ jobs: fail-fast: false matrix: erlang_version: - - '28' + - '26' elixir_version: - '1.18' metadata_store: - mnesia - - khepri + #- khepri uses: ./.github/workflows/test-make-tests.yaml with: erlang_version: ${{ matrix.erlang_version }} From 9baa8b2bb718556e66a894e0d4155858baa5df87 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Tue, 1 Jul 2025 15:51:53 +0200 Subject: [PATCH 02/15] temporarily disable all except mixed-version tests --- .github/workflows/test-make.yaml | 150 ++++++++++++++++--------------- 1 file changed, 76 insertions(+), 74 deletions(-) diff --git a/.github/workflows/test-make.yaml b/.github/workflows/test-make.yaml index dd28079d6d8..acc2d1ba0c7 100644 --- a/.github/workflows/test-make.yaml +++ b/.github/workflows/test-make.yaml @@ -1,5 +1,6 @@ name: Test (make) on: + workflow_dispatch: push: branches: - main @@ -15,66 +16,67 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: - build-and-xref: - name: Build and Xref - strategy: - fail-fast: false - matrix: - erlang_version: - - '26' - - '27' - - '28' - elixir_version: - - '1.18' - # @todo Add macOS and Windows. - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - name: CHECKOUT REPOSITORY - uses: actions/checkout@v4 - - - name: FETCH TAGS - run: git fetch --tags - - - name: SETUP OTP & ELIXIR - uses: erlef/setup-beam@v1.19 - with: - otp-version: ${{ matrix.erlang_version }} - elixir-version: ${{ matrix.elixir_version }} - hexpm-mirrors: | - https://builds.hex.pm - https://cdn.jsdelivr.net/hex - - - name: SANITY CHECK (rabbit) - run: make -C deps/rabbit parallel-ct-sanity-check - - - name: SANITY CHECK (rabbitmq_mqtt) - run: make -C deps/rabbitmq_mqtt parallel-ct-sanity-check - - - name: BUILD - run: make - - - name: XREF - run: make xref - - test: - name: Test - strategy: - fail-fast: false - matrix: - erlang_version: - - '28' - elixir_version: - - '1.18' - metadata_store: - - mnesia - - khepri - uses: ./.github/workflows/test-make-tests.yaml - with: - erlang_version: ${{ matrix.erlang_version }} - elixir_version: ${{ matrix.elixir_version }} - metadata_store: ${{ matrix.metadata_store }} - mixed_clusters: false + # DISABLED SINCE WE ARE TESTING MIXED-VERSION ONLY CHANGES FOR NOW + # build-and-xref: + # name: Build and Xref + # strategy: + # fail-fast: false + # matrix: + # erlang_version: + # - '26' + # - '27' + # - '28' + # elixir_version: + # - '1.18' + # # @todo Add macOS and Windows. + # runs-on: ubuntu-latest + # timeout-minutes: 60 + # steps: + # - name: CHECKOUT REPOSITORY + # uses: actions/checkout@v4 + # + # - name: FETCH TAGS + # run: git fetch --tags + # + # - name: SETUP OTP & ELIXIR + # uses: erlef/setup-beam@v1.19 + # with: + # otp-version: ${{ matrix.erlang_version }} + # elixir-version: ${{ matrix.elixir_version }} + # hexpm-mirrors: | + # https://builds.hex.pm + # https://cdn.jsdelivr.net/hex + # + # - name: SANITY CHECK (rabbit) + # run: make -C deps/rabbit parallel-ct-sanity-check + # + # - name: SANITY CHECK (rabbitmq_mqtt) + # run: make -C deps/rabbitmq_mqtt parallel-ct-sanity-check + # + # - name: BUILD + # run: make + # + # - name: XREF + # run: make xref + # + # test: + # name: Test + # strategy: + # fail-fast: false + # matrix: + # erlang_version: + # - '28' + # elixir_version: + # - '1.18' + # metadata_store: + # - mnesia + # - khepri + # uses: ./.github/workflows/test-make-tests.yaml + # with: + # erlang_version: ${{ matrix.erlang_version }} + # elixir_version: ${{ matrix.elixir_version }} + # metadata_store: ${{ matrix.metadata_store }} + # mixed_clusters: false test-mixed-clusters: name: Test mixed clusters @@ -87,7 +89,7 @@ jobs: - '1.18' metadata_store: - mnesia - #- khepri + #- khepri # not supported by 3.13 uses: ./.github/workflows/test-make-tests.yaml with: erlang_version: ${{ matrix.erlang_version }} @@ -95,16 +97,16 @@ jobs: metadata_store: ${{ matrix.metadata_store }} mixed_clusters: true - type-check: - name: Type check - strategy: - fail-fast: false - matrix: - erlang_version: # Latest OTP - - '28' - elixir_version: # Latest Elixir - - '1.18' - uses: ./.github/workflows/test-make-type-check.yaml - with: - erlang_version: ${{ matrix.erlang_version }} - elixir_version: ${{ matrix.elixir_version }} + # type-check: + # name: Type check + # strategy: + # fail-fast: false + # matrix: + # erlang_version: # Latest OTP + # - '28' + # elixir_version: # Latest Elixir + # - '1.18' + # uses: ./.github/workflows/test-make-type-check.yaml + # with: + # erlang_version: ${{ matrix.erlang_version }} + # elixir_version: ${{ matrix.elixir_version }} From e781c69c9aa7826990578934834a2375378e00b4 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Tue, 1 Jul 2025 16:21:07 +0200 Subject: [PATCH 03/15] rabbit_fifo_prop_SUITE: skip rather than fail mixed versions tests being run between different RabbitMQ versions with different OTP versions maybe sometimes intentionally test upgrades with the same OTP version (eg. 3.13->4.2 with OTP26) so let's just skip this test in such cases --- deps/rabbit/test/rabbit_fifo_prop_SUITE.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/rabbit/test/rabbit_fifo_prop_SUITE.erl b/deps/rabbit/test/rabbit_fifo_prop_SUITE.erl index f7010a69558..e269a599ce2 100644 --- a/deps/rabbit/test/rabbit_fifo_prop_SUITE.erl +++ b/deps/rabbit/test/rabbit_fifo_prop_SUITE.erl @@ -1123,8 +1123,8 @@ two_nodes_different_otp_version(_Config) -> pong -> case is_same_otp_version(Node) of true -> - ct:fail("expected CT node and 'rabbit_fifo_prop@localhost' " - "to have different OTP versions"); + {skip, "expected CT node and 'rabbit_fifo_prop@localhost' " + "to have different OTP versions"}; false -> Prefixes = ["rabbit_fifo", "rabbit_misc", "mc", "lqueue", "priority_queue", "ra_"], From c9e23d37997003fbefaefc18e3a347f213416f7b Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Tue, 1 Jul 2025 16:40:57 +0200 Subject: [PATCH 04/15] Skip async_notify_unsettled_classic_queue on 3.13 --- deps/rabbit/test/amqp_client_SUITE.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deps/rabbit/test/amqp_client_SUITE.erl b/deps/rabbit/test/amqp_client_SUITE.erl index 8d062dd80e1..2d0bee164bd 100644 --- a/deps/rabbit/test/amqp_client_SUITE.erl +++ b/deps/rabbit/test/amqp_client_SUITE.erl @@ -326,7 +326,8 @@ init_per_testcase(T, Config) end; init_per_testcase(T, Config) when T =:= leader_transfer_quorum_queue_credit_single orelse - T =:= leader_transfer_quorum_queue_credit_batches -> + T =:= leader_transfer_quorum_queue_credit_batches orelse + T =:= async_notify_unsettled_classic_queue -> %% These test cases flake with feature flag 'rabbitmq_4.0.0' disabled. case rabbit_ct_broker_helpers:enable_feature_flag(Config, 'rabbitmq_4.0.0') of ok -> From aff20990f1eb00db6f22e83197e803dac3c49661 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Wed, 2 Jul 2025 09:05:24 +0200 Subject: [PATCH 05/15] CLI: ignore the exact error message There error is slightly different for different Elixir versions --- .../test/ctl/set_permissions_command_test.exs | 4 ++-- .../test/ctl/set_permissions_globally_command_test.exs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs index 746d43fc085..2961b0049a4 100644 --- a/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs @@ -96,10 +96,10 @@ defmodule SetPermissionsCommandTest do @tag user: @user, vhost: @root test "run: invalid regex patterns returns an error", context do - assert @command.run( + assert match?({:error, {:invalid_regexp, ~c"*", _}}, @command.run( [context[:user], "^#{context[:user]}-.*", ".*", "*"], context[:opts] - ) == {:error, {:invalid_regexp, ~c"*", {~c"quantifier does not follow a repeatable item", 0}}} + )) # asserts that the failed command didn't change anything u = Enum.find(list_permissions(context[:vhost]), fn x -> x[:user] == context[:user] end) diff --git a/deps/rabbitmq_cli/test/ctl/set_permissions_globally_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_permissions_globally_command_test.exs index 28003ab9116..f9336509d14 100644 --- a/deps/rabbitmq_cli/test/ctl/set_permissions_globally_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_permissions_globally_command_test.exs @@ -97,10 +97,10 @@ defmodule SetPermissionsGloballyCommandTest do p2 = Enum.find(list_permissions(@vhost2), fn x -> x[:user] == context[:user] end) p3 = Enum.find(list_permissions(@vhost3), fn x -> x[:user] == context[:user] end) - assert @command.run( - [context[:user], "^#{context[:user]}-.*", ".*", "*"], - context[:opts] - ) == {:error, {:invalid_regexp, ~c"*", {~c"quantifier does not follow a repeatable item", 0}}} + assert match?({:error, {:invalid_regexp, ~c"*", _}}, @command.run( + [context[:user], "^#{context[:user]}-.*", ".*", "*"], + context[:opts] + )) # asserts that the failed command didn't change anything p4 = Enum.find(list_permissions(@vhost1), fn x -> x[:user] == context[:user] end) From 9a5d0ed81ae48ad28d2b536db59737f368642e2a Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Wed, 2 Jul 2025 11:32:07 +0200 Subject: [PATCH 06/15] QQ: disable some tests in 3.13/mixed version situations --- deps/rabbit/test/quorum_queue_SUITE.erl | 257 +++++++++++++----------- 1 file changed, 141 insertions(+), 116 deletions(-) diff --git a/deps/rabbit/test/quorum_queue_SUITE.erl b/deps/rabbit/test/quorum_queue_SUITE.erl index c1c0e948208..88ab05f8a98 100644 --- a/deps/rabbit/test/quorum_queue_SUITE.erl +++ b/deps/rabbit/test/quorum_queue_SUITE.erl @@ -1286,155 +1286,167 @@ single_active_consumer_priority(Config) -> force_shrink_member_to_current_member(Config) -> case rabbit_ct_helpers:is_mixed_versions() of - true -> - {skip, "Should not run in mixed version environments"}; - _ -> - [Server0, Server1, Server2] = + true -> + {skip, "Should not run in mixed version environments"}; + _ -> + [Server0, Server1, Server2] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), - QQ = ?config(queue_name, Config), - ?assertEqual({'queue.declare_ok', QQ, 0, 0}, - declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), + QQ = ?config(queue_name, Config), + ?assertEqual({'queue.declare_ok', QQ, 0, 0}, + declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - RaName = ra_name(QQ), - rabbit_ct_client_helpers:publish(Ch, QQ, 3), - wait_for_messages_ready([Server0], RaName, 3), + RaName = ra_name(QQ), + rabbit_ct_client_helpers:publish(Ch, QQ, 3), + wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(3, length(Nodes0)), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(3, length(Nodes0)), - rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, - force_shrink_member_to_current_member, [<<"/">>, QQ]), + rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, + force_shrink_member_to_current_member, [<<"/">>, QQ]), - wait_for_messages_ready([Server0], RaName, 3), + wait_for_messages_ready([Server0], RaName, 3), - {ok, Q1} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), - #{nodes := Nodes1} = amqqueue:get_type_state(Q1), - ?assertEqual(1, length(Nodes1)), + {ok, Q1} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), + #{nodes := Nodes1} = amqqueue:get_type_state(Q1), + ?assertEqual(1, length(Nodes1)), - %% grow queues back to all nodes - [rpc:call(Server0, rabbit_quorum_queue, grow, [S, <<"/">>, <<".*">>, all]) || S <- [Server1, Server2]], + %% grow queues back to all nodes + [rpc:call(Server0, rabbit_quorum_queue, grow, [S, <<"/">>, <<".*">>, all]) || S <- [Server1, Server2]], - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q2} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), - #{nodes := Nodes2} = amqqueue:get_type_state(Q2), - ?assertEqual(3, length(Nodes2)) + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q2} = rpc:call(Server0, rabbit_amqqueue, lookup, [QQ, <<"/">>]), + #{nodes := Nodes2} = amqqueue:get_type_state(Q2), + ?assertEqual(3, length(Nodes2)) end. force_all_queues_shrink_member_to_current_member(Config) -> - [Server0, Server1, Server2] = - rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + case rabbit_ct_helpers:is_mixed_versions() of + true -> + {skip, "Should not run in mixed version environments"}; + _ -> + [Server0, Server1, Server2] = + rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), - QQ = ?config(queue_name, Config), - AQ = ?config(alt_queue_name, Config), - ?assertEqual({'queue.declare_ok', QQ, 0, 0}, - declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - ?assertEqual({'queue.declare_ok', AQ, 0, 0}, - declare(Ch, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), + QQ = ?config(queue_name, Config), + AQ = ?config(alt_queue_name, Config), + ?assertEqual({'queue.declare_ok', QQ, 0, 0}, + declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + ?assertEqual({'queue.declare_ok', AQ, 0, 0}, + declare(Ch, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - QQs = [QQ, AQ], + QQs = [QQ, AQ], - [begin - RaName = ra_name(Q), - rabbit_ct_client_helpers:publish(Ch, Q, 3), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(3, length(Nodes0)) - end || Q <- QQs], + [begin + RaName = ra_name(Q), + rabbit_ct_client_helpers:publish(Ch, Q, 3), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(3, length(Nodes0)) + end || Q <- QQs], - rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, - force_all_queues_shrink_member_to_current_member, []), + rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, + force_all_queues_shrink_member_to_current_member, []), - [begin - RaName = ra_name(Q), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(1, length(Nodes0)) - end || Q <- QQs], + [begin + RaName = ra_name(Q), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(1, length(Nodes0)) + end || Q <- QQs], - %% grow queues back to all nodes - [rpc:call(Server0, rabbit_quorum_queue, grow, [S, <<"/">>, <<".*">>, all]) || S <- [Server1, Server2]], + %% grow queues back to all nodes + [rpc:call(Server0, rabbit_quorum_queue, grow, [S, <<"/">>, <<".*">>, all]) || S <- [Server1, Server2]], - [begin - RaName = ra_name(Q), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(3, length(Nodes0)) - end || Q <- QQs]. + [begin + RaName = ra_name(Q), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, <<"/">>]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(3, length(Nodes0)) + end || Q <- QQs] + end. force_vhost_queues_shrink_member_to_current_member(Config) -> - [Server0, Server1, Server2] = - rabbit_ct_broker_helpers:get_node_configs(Config, nodename), + case rabbit_ct_helpers:is_mixed_versions() of + true -> + {skip, "Should not run in mixed version environments"}; + _ -> + [Server0, Server1, Server2] = + rabbit_ct_broker_helpers:get_node_configs(Config, nodename), - Ch0 = rabbit_ct_client_helpers:open_channel(Config, Server0), - QQ = ?config(queue_name, Config), - AQ = ?config(alt_queue_name, Config), - ?assertEqual({'queue.declare_ok', QQ, 0, 0}, - declare(Ch0, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - ?assertEqual({'queue.declare_ok', AQ, 0, 0}, - declare(Ch0, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + Ch0 = rabbit_ct_client_helpers:open_channel(Config, Server0), + QQ = ?config(queue_name, Config), + AQ = ?config(alt_queue_name, Config), + ?assertEqual({'queue.declare_ok', QQ, 0, 0}, + declare(Ch0, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + ?assertEqual({'queue.declare_ok', AQ, 0, 0}, + declare(Ch0, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - QQs = [QQ, AQ], + QQs = [QQ, AQ], - VHost1 = <<"/">>, - VHost2 = <<"another-vhost">>, - VHosts = [VHost1, VHost2], + VHost1 = <<"/">>, + VHost2 = <<"another-vhost">>, + VHosts = [VHost1, VHost2], - User = ?config(rmq_username, Config), - ok = rabbit_ct_broker_helpers:add_vhost(Config, Server0, VHost2, User), - ok = rabbit_ct_broker_helpers:set_full_permissions(Config, User, VHost2), - Conn1 = rabbit_ct_client_helpers:open_unmanaged_connection(Config, Server0, VHost2), - {ok, Ch1} = amqp_connection:open_channel(Conn1), - ?assertEqual({'queue.declare_ok', QQ, 0, 0}, - declare(Ch1, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - ?assertEqual({'queue.declare_ok', AQ, 0, 0}, - declare(Ch1, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + User = ?config(rmq_username, Config), + ok = rabbit_ct_broker_helpers:add_vhost(Config, Server0, VHost2, User), + ok = rabbit_ct_broker_helpers:set_full_permissions(Config, User, VHost2), + Conn1 = rabbit_ct_client_helpers:open_unmanaged_connection(Config, Server0, VHost2), + {ok, Ch1} = amqp_connection:open_channel(Conn1), + ?assertEqual({'queue.declare_ok', QQ, 0, 0}, + declare(Ch1, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), + ?assertEqual({'queue.declare_ok', AQ, 0, 0}, + declare(Ch1, AQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}])), - [rabbit_ct_client_helpers:publish(Ch, Q, 3) || Q <- QQs, Ch <- [Ch0, Ch1]], + [rabbit_ct_client_helpers:publish(Ch, Q, 3) || Q <- QQs, Ch <- [Ch0, Ch1]], - [begin - QQRes = rabbit_misc:r(VHost, queue, Q), - {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(3, length(Nodes0)) - end || Q <- QQs, VHost <- VHosts], + [begin + QQRes = rabbit_misc:r(VHost, queue, Q), + {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(3, length(Nodes0)) + end || Q <- QQs, VHost <- VHosts], - rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, - force_vhost_queues_shrink_member_to_current_member, [VHost2]), + rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, + force_vhost_queues_shrink_member_to_current_member, [VHost2]), - [begin - QQRes = rabbit_misc:r(VHost, queue, Q), - {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - case VHost of - VHost1 -> ?assertEqual(3, length(Nodes0)); - VHost2 -> ?assertEqual(1, length(Nodes0)) - end - end || Q <- QQs, VHost <- VHosts], + [begin + QQRes = rabbit_misc:r(VHost, queue, Q), + {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + case VHost of + VHost1 -> ?assertEqual(3, length(Nodes0)); + VHost2 -> ?assertEqual(1, length(Nodes0)) + end + end || Q <- QQs, VHost <- VHosts], - %% grow queues back to all nodes in VHost2 only - [rpc:call(Server0, rabbit_quorum_queue, grow, [S, VHost2, <<".*">>, all]) || S <- [Server1, Server2]], + %% grow queues back to all nodes in VHost2 only + [rpc:call(Server0, rabbit_quorum_queue, grow, [S, VHost2, <<".*">>, all]) || S <- [Server1, Server2]], - [begin - QQRes = rabbit_misc:r(VHost, queue, Q), - {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), - wait_for_messages_ready([Server0], RaName, 3), - {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), - #{nodes := Nodes0} = amqqueue:get_type_state(Q0), - ?assertEqual(3, length(Nodes0)) - end || Q <- QQs, VHost <- VHosts]. + [begin + QQRes = rabbit_misc:r(VHost, queue, Q), + {ok, RaName} = rpc:call(Server0, rabbit_queue_type_util, qname_to_internal_name, [QQRes]), + wait_for_messages_ready([Server0], RaName, 3), + {ok, Q0} = rpc:call(Server0, rabbit_amqqueue, lookup, [Q, VHost]), + #{nodes := Nodes0} = amqqueue:get_type_state(Q0), + ?assertEqual(3, length(Nodes0)) + end || Q <- QQs, VHost <- VHosts] + end. force_checkpoint_on_queue(Config) -> + check_quorum_queues_v4_compat(Config), + [Server0, Server1, Server2] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), @@ -1501,6 +1513,8 @@ force_checkpoint_on_queue(Config) -> end). force_checkpoint(Config) -> + check_quorum_queues_v4_compat(Config), + [Server0, _Server1, _Server2] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), @@ -1722,6 +1736,7 @@ subscribe_from_each(Config) -> ok. dont_leak_file_handles(Config) -> + check_quorum_queues_v4_compat(Config), [Server0 | _] = Servers = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), @@ -1770,6 +1785,8 @@ dont_leak_file_handles(Config) -> ok. gh_12635(Config) -> + check_quorum_queues_v4_compat(Config), + % https://github.com/rabbitmq/rabbitmq-server/issues/12635 [Server0, _Server1, Server2] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), @@ -3268,6 +3285,8 @@ subscribe_redelivery_limit(Config) -> end. subscribe_redelivery_limit_disable(Config) -> + check_quorum_queues_v4_compat(Config), + [Server | _] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server), @@ -3664,6 +3683,8 @@ queue_length_limit_reject_publish(Config) -> ok. queue_length_limit_policy_cleared(Config) -> + check_quorum_queues_v4_compat(Config), + [Server | _] = Servers = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server), @@ -4723,6 +4744,8 @@ select_nodes_with_least_replicas_node_down(Config) -> || Q <- Qs]. requeue_multiple_true(Config) -> + check_quorum_queues_v4_compat(Config), + Ch = rabbit_ct_client_helpers:open_channel(Config), QQ = ?config(queue_name, Config), ?assertEqual({'queue.declare_ok', QQ, 0, 0}, @@ -4761,6 +4784,8 @@ requeue_multiple_true(Config) -> amqp_channel:call(Ch, #'queue.delete'{queue = QQ})). requeue_multiple_false(Config) -> + check_quorum_queues_v4_compat(Config), + Ch = rabbit_ct_client_helpers:open_channel(Config), QQ = ?config(queue_name, Config), ?assertEqual({'queue.declare_ok', QQ, 0, 0}, From 7dda401cf8fe730564813f40b4885139c3945d09 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Wed, 2 Jul 2025 11:52:51 +0200 Subject: [PATCH 07/15] Disable OCI workflow for now --- .github/workflows/oci-make.yaml | 190 ++++++++++++++++---------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/.github/workflows/oci-make.yaml b/.github/workflows/oci-make.yaml index e00c080179b..35be566e21b 100644 --- a/.github/workflows/oci-make.yaml +++ b/.github/workflows/oci-make.yaml @@ -32,98 +32,98 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: - build-package-generic-unix: - strategy: - matrix: - otp_version: - - ${{ github.event.inputs.otp_version || '28' }} - runs-on: ubuntu-latest - outputs: - # When dependabot, or a user from a fork, creates PRs, secrets are not injected, and the OCI workflow can't push the image - # This check acts as a gate keeper - authorized: ${{ steps.authorized.outputs.authorized }} - steps: - - name: CHECK IF IMAGE WILL PUSH - id: authorized - run: | - if [ -n "${{ secrets.DOCKERHUB_PASSWORD }}" ]; then - echo "authorized=true" | tee -a $GITHUB_OUTPUT - else - echo "authorized=false" | tee -a $GITHUB_OUTPUT - fi - - name: Checkout - if: steps.authorized.outputs.authorized == 'true' - uses: actions/checkout@v4 - - name: Configure Erlang - if: steps.authorized.outputs.authorized == 'true' - uses: erlef/setup-beam@v1 - with: - otp-version: ${{ matrix.otp_version }} - elixir-version: latest - - name: make package-generic-unix - if: steps.authorized.outputs.authorized == 'true' - run: | - make package-generic-unix PROJECT_VERSION=${{ env.VERSION }} - - name: Upload package-generic-unix - if: steps.authorized.outputs.authorized == 'true' - uses: actions/upload-artifact@v4 - with: - name: package-generic-unix-otp${{ matrix.otp_version }} - path: PACKAGES/rabbitmq-server-*.tar.xz - - build-and-push: - strategy: - fail-fast: false - matrix: - otp_version: - - ${{ github.event.inputs.otp_version || '28' }} - needs: build-package-generic-unix - runs-on: ubuntu-latest - if: ${{ needs.build-package-generic-unix.outputs.authorized }} == 'true' - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Download package-generic-unix - uses: actions/download-artifact@v4 - with: - name: package-generic-unix-otp${{ matrix.otp_version }} - path: PACKAGES - - name: Rename package-generic-unix - run: | - cp \ - PACKAGES/rabbitmq-server-generic-unix-*.tar.xz \ - packaging/docker-image/package-generic-unix.tar.xz - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY_IMAGE }} - flavor: | - suffix=-otp${{ matrix.otp_version }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=sha,format=long - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Build and push by digest - id: build - uses: docker/build-push-action@v6 - with: - push: true - context: packaging/docker-image - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ github.event.inputs.build_arm && 'linux/amd64, linux/arm64' || 'linux/amd64' }} - tags: ${{ steps.meta.outputs.tags }} - cache-to: type=gha,mode=max,scope=${{ matrix.otp_version }} - cache-from: type=gha,scope=${{ matrix.otp_version }} - build-args: | - OTP_VERSION=${{ matrix.otp_version }} - RABBITMQ_VERSION=${{ env.VERSION }} + # build-package-generic-unix: + # strategy: + # matrix: + # otp_version: + # - ${{ github.event.inputs.otp_version || '28' }} + # runs-on: ubuntu-latest + # outputs: + # # When dependabot, or a user from a fork, creates PRs, secrets are not injected, and the OCI workflow can't push the image + # # This check acts as a gate keeper + # authorized: ${{ steps.authorized.outputs.authorized }} + # steps: + # - name: CHECK IF IMAGE WILL PUSH + # id: authorized + # run: | + # if [ -n "${{ secrets.DOCKERHUB_PASSWORD }}" ]; then + # echo "authorized=true" | tee -a $GITHUB_OUTPUT + # else + # echo "authorized=false" | tee -a $GITHUB_OUTPUT + # fi + # - name: Checkout + # if: steps.authorized.outputs.authorized == 'true' + # uses: actions/checkout@v4 + # - name: Configure Erlang + # if: steps.authorized.outputs.authorized == 'true' + # uses: erlef/setup-beam@v1 + # with: + # otp-version: ${{ matrix.otp_version }} + # elixir-version: latest + # - name: make package-generic-unix + # if: steps.authorized.outputs.authorized == 'true' + # run: | + # make package-generic-unix PROJECT_VERSION=${{ env.VERSION }} + # - name: Upload package-generic-unix + # if: steps.authorized.outputs.authorized == 'true' + # uses: actions/upload-artifact@v4 + # with: + # name: package-generic-unix-otp${{ matrix.otp_version }} + # path: PACKAGES/rabbitmq-server-*.tar.xz + # + # build-and-push: + # strategy: + # fail-fast: false + # matrix: + # otp_version: + # - ${{ github.event.inputs.otp_version || '28' }} + # needs: build-package-generic-unix + # runs-on: ubuntu-latest + # if: ${{ needs.build-package-generic-unix.outputs.authorized }} == 'true' + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # - name: Download package-generic-unix + # uses: actions/download-artifact@v4 + # with: + # name: package-generic-unix-otp${{ matrix.otp_version }} + # path: PACKAGES + # - name: Rename package-generic-unix + # run: | + # cp \ + # PACKAGES/rabbitmq-server-generic-unix-*.tar.xz \ + # packaging/docker-image/package-generic-unix.tar.xz + # - name: Docker meta + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: ${{ env.REGISTRY_IMAGE }} + # flavor: | + # suffix=-otp${{ matrix.otp_version }} + # tags: | + # type=ref,event=branch + # type=ref,event=pr + # type=sha,format=long + # - name: Set up QEMU + # uses: docker/setup-qemu-action@v3 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v3 + # - name: Login to Docker Hub + # uses: docker/login-action@v3 + # with: + # username: ${{ secrets.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_PASSWORD }} + # - name: Build and push by digest + # id: build + # uses: docker/build-push-action@v6 + # with: + # push: true + # context: packaging/docker-image + # labels: ${{ steps.meta.outputs.labels }} + # platforms: ${{ github.event.inputs.build_arm && 'linux/amd64, linux/arm64' || 'linux/amd64' }} + # tags: ${{ steps.meta.outputs.tags }} + # cache-to: type=gha,mode=max,scope=${{ matrix.otp_version }} + # cache-from: type=gha,scope=${{ matrix.otp_version }} + # build-args: | + # OTP_VERSION=${{ matrix.otp_version }} + # RABBITMQ_VERSION=${{ env.VERSION }} From 059207180f52e00fd1a65319d21bf03d9fa9aa01 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Wed, 2 Jul 2025 15:58:49 +0200 Subject: [PATCH 08/15] feature flags: skip tests for recently fixed bugs These tests fail in a mixed-version cluster with 3.13 --- deps/rabbit/test/feature_flags_SUITE.erl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/deps/rabbit/test/feature_flags_SUITE.erl b/deps/rabbit/test/feature_flags_SUITE.erl index bf5abaa8f6d..a62850dabad 100644 --- a/deps/rabbit/test/feature_flags_SUITE.erl +++ b/deps/rabbit/test/feature_flags_SUITE.erl @@ -1277,6 +1277,13 @@ activating_plugin_with_new_ff_enabled(Config) -> ok. enable_plugin_feature_flag_after_deactivating_plugin(Config) -> + case rabbit_ct_broker_helpers:is_feature_flag_enabled(Config, 'rabbitmq_4.0.0') of + true -> + ok; + false -> + throw({skip, "this test triggers a bug present in 3.13"}) + end, + FFSubsysOk = is_feature_flag_subsystem_available(Config), log_feature_flags_of_all_nodes(Config), @@ -1307,6 +1314,13 @@ enable_plugin_feature_flag_after_deactivating_plugin(Config) -> ok. restart_node_with_unknown_enabled_feature_flag(Config) -> + case rabbit_ct_broker_helpers:is_feature_flag_enabled(Config, 'rabbitmq_4.0.0') of + true -> + ok; + false -> + throw({skip, "this test triggers a bug present in 3.13"}) + end, + FFSubsysOk = is_feature_flag_subsystem_available(Config), log_feature_flags_of_all_nodes(Config), From ec0cf8a71f14673ea9c7b0ac38ba3d6e52d429db Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Wed, 2 Jul 2025 11:35:41 +0200 Subject: [PATCH 09/15] Enable FFs required by 4.0 --- .../test/clustering_management_SUITE.erl | 18 ++++++++++++++++-- deps/rabbit/test/feature_flags_SUITE.erl | 9 ++++++++- deps/rabbit/test/rabbit_stream_queue_SUITE.erl | 9 ++++++++- deps/rabbitmq_mqtt/test/mqtt_shared_SUITE.erl | 12 +++++++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/deps/rabbit/test/clustering_management_SUITE.erl b/deps/rabbit/test/clustering_management_SUITE.erl index 33ff6693e8e..2b585f1df8f 100644 --- a/deps/rabbit/test/clustering_management_SUITE.erl +++ b/deps/rabbit/test/clustering_management_SUITE.erl @@ -146,12 +146,26 @@ init_per_group(unclustered_2_nodes, Config) -> Config1 = rabbit_ct_helpers:set_config( Config, [{rmq_nodes_clustered, false}]), rabbit_ct_helpers:merge_app_env( - Config1, {rabbit, [{forced_feature_flags_on_init, []}]}); + Config1, {rabbit, [{forced_feature_flags_on_init, [ + restart_streams, + stream_sac_coordinator_unblock_group, + stream_update_config_command, + stream_filtering, + message_containers, + quorum_queue_non_voters + ]}]}); init_per_group(unclustered_3_nodes, Config) -> Config1 = rabbit_ct_helpers:set_config( Config, [{rmq_nodes_clustered, false}]), rabbit_ct_helpers:merge_app_env( - Config1, {rabbit, [{forced_feature_flags_on_init, []}]}); + Config1, {rabbit, [{forced_feature_flags_on_init, [ + restart_streams, + stream_sac_coordinator_unblock_group, + stream_update_config_command, + stream_filtering, + message_containers, + quorum_queue_non_voters + ]}]}); init_per_group(clustered_2_nodes, Config) -> rabbit_ct_helpers:set_config(Config, [{rmq_nodes_clustered, true}]); init_per_group(clustered_3_nodes, Config) -> diff --git a/deps/rabbit/test/feature_flags_SUITE.erl b/deps/rabbit/test/feature_flags_SUITE.erl index a62850dabad..5bbc840a495 100644 --- a/deps/rabbit/test/feature_flags_SUITE.erl +++ b/deps/rabbit/test/feature_flags_SUITE.erl @@ -197,7 +197,14 @@ init_per_group(clustering, Config) -> {rmq_nodes_clustered, false}, {start_rmq_with_plugins_disabled, true}]), Config2 = rabbit_ct_helpers:merge_app_env( - Config1, {rabbit, [{forced_feature_flags_on_init, []}]}), + Config1, {rabbit, [{forced_feature_flags_on_init, [ + restart_streams, + stream_sac_coordinator_unblock_group, + stream_update_config_command, + stream_filtering, + message_containers, + quorum_queue_non_voters + ]}]}), rabbit_ct_helpers:run_setup_steps(Config2, [fun prepare_my_plugin/1]); init_per_group(activating_plugin, Config) -> Config1 = rabbit_ct_helpers:set_config( diff --git a/deps/rabbit/test/rabbit_stream_queue_SUITE.erl b/deps/rabbit/test/rabbit_stream_queue_SUITE.erl index 9e45d0d04ff..66d3b8c0405 100644 --- a/deps/rabbit/test/rabbit_stream_queue_SUITE.erl +++ b/deps/rabbit/test/rabbit_stream_queue_SUITE.erl @@ -238,7 +238,14 @@ init_per_group1(Group, Config) -> Config1 end, Config1c = rabbit_ct_helpers:merge_app_env( - Config1b, {rabbit, [{forced_feature_flags_on_init, []}]}), + Config1b, {rabbit, [{forced_feature_flags_on_init, [ + restart_streams, + stream_sac_coordinator_unblock_group, + stream_update_config_command, + stream_filtering, + message_containers, + quorum_queue_non_voters + ]}]}), Ret = rabbit_ct_helpers:run_steps(Config1c, [fun merge_app_env/1 ] ++ rabbit_ct_broker_helpers:setup_steps()), diff --git a/deps/rabbitmq_mqtt/test/mqtt_shared_SUITE.erl b/deps/rabbitmq_mqtt/test/mqtt_shared_SUITE.erl index 41519b49eb9..f50b19b42c6 100644 --- a/deps/rabbitmq_mqtt/test/mqtt_shared_SUITE.erl +++ b/deps/rabbitmq_mqtt/test/mqtt_shared_SUITE.erl @@ -164,7 +164,17 @@ init_per_suite(Config) -> Config, {rabbit, [ {quorum_tick_interval, 1000}, {stream_tick_interval, 1000}, - {forced_feature_flags_on_init, []}, + {forced_feature_flags_on_init, [ + delete_ra_cluster_mqtt_node, + mqtt_v5, + rabbit_mqtt_qos0_queue, + restart_streams, + stream_sac_coordinator_unblock_group, + stream_update_config_command, + stream_filtering, + message_containers, + quorum_queue_non_voters + ]}, {start_rmq_with_plugins_disabled, true} ]}), rabbit_ct_helpers:run_setup_steps(Config1). From 23bd773e26f308e51702493c0ed211f6d9f2a9da Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Thu, 3 Jul 2025 11:01:46 +0200 Subject: [PATCH 10/15] Use ra:member_overview instead of rabbit_fifo:overview member_overview works better with different machine versions --- deps/rabbit/test/quorum_queue_SUITE.erl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/deps/rabbit/test/quorum_queue_SUITE.erl b/deps/rabbit/test/quorum_queue_SUITE.erl index 88ab05f8a98..b8d0d275002 100644 --- a/deps/rabbit/test/quorum_queue_SUITE.erl +++ b/deps/rabbit/test/quorum_queue_SUITE.erl @@ -3986,7 +3986,7 @@ receive_and_ack(Ch) -> end. message_ttl_policy(Config) -> - %% Using ttl is very difficul to guarantee 100% test rate success, unless + %% Using ttl is very difficult to guarantee 100% test rate success, unless %% using really high ttl values. Previously, this test used 1s and 3s ttl, %% but expected to see first the messages in the queue and then the messages %% gone. A slow CI run, would fail the first assertion as the messages would @@ -4006,9 +4006,8 @@ message_ttl_policy(Config) -> VHost = <<"%2F">>, RaName = binary_to_atom(<>, utf8), - QueryFun = fun rabbit_fifo:overview/1, - ?awaitMatch({ok, {_, #{config := #{msg_ttl := 1000}}}, _}, - rpc:call(Server, ra, local_query, [RaName, QueryFun]), + ?awaitMatch({ok, #{machine := #{config := #{msg_ttl := 1000}}}, _}, + rpc:call(Server, ra, member_overview, [RaName]), ?DEFAULT_AWAIT), Msg1 = <<"msg1">>, Msg2 = <<"msg11">>, @@ -4020,8 +4019,8 @@ message_ttl_policy(Config) -> ok = rabbit_ct_broker_helpers:set_policy(Config, 0, <<"msg-ttl">>, QQ, <<"queues">>, [{<<"message-ttl">>, 1000}]), - {ok, {_, Overview2}, _} = rpc:call(Server, ra, local_query, [RaName, QueryFun]), - ?assertMatch(#{config := #{msg_ttl := 1000}}, Overview2), + {ok, Overview2, _} = rpc:call(Server, ra, member_overview, [RaName]), + ?assertMatch(#{machine := #{config := #{msg_ttl := 1000}}}, Overview2), publish(Ch, QQ, Msg1), wait_for_messages(Config, [[QQ, <<"1">>, <<"1">>, <<"0">>]]), wait_for_messages(Config, [[QQ, <<"0">>, <<"0">>, <<"0">>]]), From e8da7b2dc869671562d5ff3f3bd2e57bdac7abfe Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Thu, 3 Jul 2025 11:26:31 +0200 Subject: [PATCH 11/15] Disable forget_cluster_node test (not supported by 3.13) --- deps/rabbit/test/dynamic_qq_SUITE.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deps/rabbit/test/dynamic_qq_SUITE.erl b/deps/rabbit/test/dynamic_qq_SUITE.erl index dbe55c2aec0..e23f0223b44 100644 --- a/deps/rabbit/test/dynamic_qq_SUITE.erl +++ b/deps/rabbit/test/dynamic_qq_SUITE.erl @@ -222,6 +222,8 @@ quorum_unaffected_after_vhost_failure(Config) -> forget_cluster_node(Config) -> %% Tests that quorum queues shrink when forget_cluster_node %% operations are issues. + quorum_queue_SUITE:check_quorum_queues_v4_compat(Config), + [Server | _] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server), From f672627cfd3b7caf3d95f8e30a4b2c094c5e55c5 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Thu, 3 Jul 2025 13:43:25 +0200 Subject: [PATCH 12/15] Skip Khepri-specific tests when 3.13 is in the mix --- deps/rabbit/test/queue_length_limits_SUITE.erl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/deps/rabbit/test/queue_length_limits_SUITE.erl b/deps/rabbit/test/queue_length_limits_SUITE.erl index f171651f6a5..2186a7f33e6 100644 --- a/deps/rabbit/test/queue_length_limits_SUITE.erl +++ b/deps/rabbit/test/queue_length_limits_SUITE.erl @@ -82,8 +82,17 @@ init_per_group(mnesia_parallel_tests = Group, Config0) -> Config = rabbit_ct_helpers:set_config(Config0, [{metadata_store, mnesia}]), init_per_group0(Group, Config); init_per_group(khepri_parallel_tests = Group, Config0) -> - Config = rabbit_ct_helpers:set_config(Config0, [{metadata_store, khepri}]), - init_per_group0(Group, Config). + %% this is very hacky way of skipping the tests, but the khepri_db + %% flag exists in 3,13, but it's not compatible with 4.x. We can remove + %% this after 4.2 + SecondaryDist = os:getenv("SECONDARY_DIST", ""), + case string:str(SecondaryDist, "3.13.") == 0 of + true -> + Config = rabbit_ct_helpers:set_config(Config0, [{metadata_store, khepri}]), + init_per_group0(Group, Config); + _ -> + {skip, "Khepri was not supported in 3.13"} + end. init_per_group0(Group, Config) -> case lists:member({group, Group}, all()) of From 5df10f51740b1affeb098a0760d2da5285947edf Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Fri, 4 Jul 2025 13:52:58 +0200 Subject: [PATCH 13/15] amqp_client_SUITE: skip some tests in mixed-version with 3.13 --- TODO | 3 +++ deps/rabbit/test/amqp_client_SUITE.erl | 17 ++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 00000000000..3999b61fbed --- /dev/null +++ b/TODO @@ -0,0 +1,3 @@ +- skip AMQP-1.0 tests when using 3.13 - check if works now +- dead-lettering https://github.com/rabbitmq/rabbitmq-server/actions/runs/16000107488/job/45132635443?pr=14171 +- QQs https://github.com/rabbitmq/rabbitmq-server/actions/runs/16000107488/job/45132635471?pr=14171 diff --git a/deps/rabbit/test/amqp_client_SUITE.erl b/deps/rabbit/test/amqp_client_SUITE.erl index 2d0bee164bd..d6f36adc4ed 100644 --- a/deps/rabbit/test/amqp_client_SUITE.erl +++ b/deps/rabbit/test/amqp_client_SUITE.erl @@ -327,7 +327,14 @@ init_per_testcase(T, Config) init_per_testcase(T, Config) when T =:= leader_transfer_quorum_queue_credit_single orelse T =:= leader_transfer_quorum_queue_credit_batches orelse - T =:= async_notify_unsettled_classic_queue -> + T =:= async_notify_unsettled_classic_queue orelse + T =:= leader_transfer_stream_credit_single orelse + T =:= dead_letter_into_stream orelse + T =:= classic_queue_on_new_node orelse + T =:= leader_transfer_quorum_queue_send orelse + T =:= last_queue_confirms orelse + T =:= leader_transfer_stream_credit_batches orelse + T =:= leader_transfer_stream_send -> %% These test cases flake with feature flag 'rabbitmq_4.0.0' disabled. case rabbit_ct_broker_helpers:enable_feature_flag(Config, 'rabbitmq_4.0.0') of ok -> @@ -343,14 +350,6 @@ init_per_testcase(T = immutable_bare_message, Config) -> {skip, "RabbitMQ is known to wrongfully modify the bare message with feature " "flag rabbitmq_4.0.0 disabled"} end; -init_per_testcase(T = dead_letter_into_stream, Config) -> - case rabbit_ct_broker_helpers:enable_feature_flag(Config, message_containers_deaths_v2) of - ok -> - rabbit_ct_helpers:testcase_started(Config, T); - _ -> - {skip, "This test is known to fail with feature flag message_containers_deaths_v2 disabled " - "due to missing feature https://github.com/rabbitmq/rabbitmq-server/issues/11173"} - end; init_per_testcase(T = dead_letter_reject, Config) -> case rabbit_ct_broker_helpers:enable_feature_flag(Config, message_containers_deaths_v2) of ok -> From 58c000226555a1eb3ddb39591d0edbdcabb02bca Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Fri, 4 Jul 2025 14:03:11 +0200 Subject: [PATCH 14/15] skip dead_letter_headers_should_not_be_appended_for_republish with 3.13 --- deps/rabbit/test/dead_lettering_SUITE.erl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deps/rabbit/test/dead_lettering_SUITE.erl b/deps/rabbit/test/dead_lettering_SUITE.erl index 3b70bd14693..489f4e154e4 100644 --- a/deps/rabbit/test/dead_lettering_SUITE.erl +++ b/deps/rabbit/test/dead_lettering_SUITE.erl @@ -184,6 +184,14 @@ init_per_testcase(T, Config) %% * stream is known to fail due to https://github.com/rabbitmq/rabbitmq-server/issues/11173 ok = rabbit_ct_broker_helpers:enable_feature_flag(Config, message_containers_deaths_v2), init_per_testcase0(T, Config); +init_per_testcase(T, Config) + when T =:= dead_letter_headers_should_not_be_appended_for_republish -> + case rabbit_ct_broker_helpers:enable_feature_flag(Config, 'rabbitmq_4.0.0') of + ok -> + init_per_testcase0(T, Config); + _ -> + {skip, "The expectations of this test don't match 3.13 behaviour"} + end; init_per_testcase(Testcase, Config) -> init_per_testcase0(Testcase, Config). From bf33919e5f6877870f116df2ff5b43341788e280 Mon Sep 17 00:00:00 2001 From: Michal Kuratczyk Date: Fri, 4 Jul 2025 15:19:52 +0200 Subject: [PATCH 15/15] quorum_queue_SUITE: fixes for 3.13 compatibility --- deps/rabbit/test/quorum_queue_SUITE.erl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/deps/rabbit/test/quorum_queue_SUITE.erl b/deps/rabbit/test/quorum_queue_SUITE.erl index b8d0d275002..2ae9f23d406 100644 --- a/deps/rabbit/test/quorum_queue_SUITE.erl +++ b/deps/rabbit/test/quorum_queue_SUITE.erl @@ -322,6 +322,10 @@ init_per_testcase(T, Config) init_per_testcase(Testcase, Config) -> ClusterSize = ?config(rmq_nodes_count, Config), IsMixed = rabbit_ct_helpers:is_mixed_versions(), + RabbitMQ3 = case rabbit_ct_broker_helpers:enable_feature_flag(Config, 'rabbitmq_4.0.0') of + ok -> false; + _ -> true + end, SameKhepriMacVers = ( rabbit_ct_broker_helpers:do_nodes_run_same_ra_machine_version( Config, khepri_machine)), @@ -359,6 +363,8 @@ init_per_testcase(Testcase, Config) -> {skip, "reclaim_memory_with_wrong_queue_type isn't mixed versions compatible"}; peek_with_wrong_queue_type when IsMixed -> {skip, "peek_with_wrong_queue_type isn't mixed versions compatible"}; + cancel_consumer_gh_3729 when IsMixed andalso RabbitMQ3 -> + {skip, "this test is not compatible with RabbitMQ 3.13.x"}; _ -> Config1 = rabbit_ct_helpers:testcase_started(Config, Testcase), rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, delete_queues, []), @@ -1535,7 +1541,7 @@ force_checkpoint(Config) -> ForceCheckpointRes = rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_quorum_queue, force_checkpoint, [<<".*">>, <<".*">>]), ExpectedRes = [{QQName, {ok}}], - + % Result should only have quorum queue ?assertEqual(ExpectedRes, ForceCheckpointRes). @@ -2494,8 +2500,6 @@ metrics_cleanup_on_leader_crash(Config) -> publish(Ch, QQ), publish(Ch, QQ), - wait_for_messages_ready([Server], RaName, 3), - wait_for_messages_pending_ack([Server], RaName, 0), {ok, _, {Name, Leader}} = ra:members({RaName, Server}), QRes = rabbit_misc:r(<<"/">>, queue, QQ), rabbit_ct_helpers:await_condition(