Skip to content

Commit 5091226

Browse files
committed
Run Quorum Queue property test on different OTP versions
## What? PR #13971 added a property test that applies the same quorum queue Raft command on different quorum queue members on different Erlang nodes ensuring that the state machine ends up in exaclty the same state. The different Erlang nodes run the **same** Erlang/OTP version however. This commit adds another property test where the different Erlang nodes run **different** Erlang/OTP versions. ## Why? This test allows spotting any non-determinism that could occur when running quorum queue members in a mixed version cluster, where mixed version means in our context different Erlang/OTP versions. ## How? CI runs currently tests with Erlang 27. This commit starts an Erlang 26 node in docker, specifically for the `rabbit_fifo_prop_SUITE`. Test case `two_nodes_different_otp_version` running Erlang 27 then transfers a few Erlang modules (e.g. module `rabbit_fifo`) to the Erlang 26 node. The test case then runs the Ra commands on its own node in Erlang 27 and on the Erlang 26 node in Docker. By default, this test case is skipped locally. However, to run this test case locally, simply start an Erlang node as follows: ``` erl -sname rabbit_fifo_prop@localhost ``` (cherry picked from commit eccf9fe)
1 parent f074a41 commit 5091226

File tree

5 files changed

+92
-23
lines changed

5 files changed

+92
-23
lines changed

.github/workflows/test-make-target.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ jobs:
8787
sudo systemctl is-active --quiet apparmor.service && sudo systemctl stop apparmor.service
8888
sudo systemctl disable apparmor.service
8989
90+
- name: RUN LOW VERSION ERLANG NODE IN DOCKER
91+
if: inputs.make_target == 'ct-rabbit_fifo_prop'
92+
run: |
93+
# This version must be at least 1 major version lower than inputs.erlang_version
94+
LOW_ERLANG_VERSION="26.2"
95+
96+
# Create ~/.erlang.cookie by starting a distributed node
97+
erl -sname temp_node -eval 'halt().' -noshell
98+
99+
docker run -d --network host --name erlang_low_version erlang:${LOW_ERLANG_VERSION} \
100+
erl -sname rabbit_fifo_prop@localhost -setcookie $(cat ~/.erlang.cookie) -noinput
101+
90102
- name: RUN TESTS
91103
if: inputs.plugin != 'rabbitmq_cli'
92104
run: |

.github/workflows/test-make-tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
- ct-metadata_store_clustering
3333
- ct-quorum_queue
3434
- ct-rabbit_stream_queue
35+
- ct-rabbit_fifo_prop
3536
uses: ./.github/workflows/test-make-target.yaml
3637
with:
3738
erlang_version: ${{ inputs.erlang_version }}

deps/rabbit/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ PARALLEL_CT_SET_2_B = clustering_recovery crashing_queues deprecated_features di
268268
PARALLEL_CT_SET_2_C = disk_monitor dynamic_qq unit_disk_monitor unit_file_handle_cache unit_log_management unit_operator_policy
269269
PARALLEL_CT_SET_2_D = queue_length_limits queue_parallel quorum_queue_member_reconciliation rabbit_fifo rabbit_fifo_dlx rabbit_stream_coordinator
270270

271-
PARALLEL_CT_SET_3_A = definition_import per_user_connection_channel_limit_partitions per_vhost_connection_limit_partitions policy priority_queue_recovery rabbit_fifo_prop rabbit_fifo_v0 rabbit_stream_sac_coordinator unit_credit_flow unit_queue_consumers unit_queue_location unit_quorum_queue
271+
PARALLEL_CT_SET_3_A = definition_import per_user_connection_channel_limit_partitions per_vhost_connection_limit_partitions policy priority_queue_recovery rabbit_fifo_v0 rabbit_stream_sac_coordinator unit_credit_flow unit_queue_consumers unit_queue_location unit_quorum_queue
272272
PARALLEL_CT_SET_3_B = cluster_upgrade list_consumers_sanity_check list_queues_online_and_offline logging lqueue maintenance_mode rabbit_fifo_q
273273
PARALLEL_CT_SET_3_C = cli_forget_cluster_node feature_flags_v2 mc_unit message_containers_deaths_v2 message_size_limit metadata_store_migration
274274
PARALLEL_CT_SET_3_D = metadata_store_phase1 metrics mirrored_supervisor peer_discovery_classic_config proxy_protocol runtime_parameters unit_stats_and_metrics unit_supervisor2 unit_vm_memory_monitor
@@ -283,7 +283,7 @@ PARALLEL_CT_SET_2 = $(sort $(PARALLEL_CT_SET_2_A) $(PARALLEL_CT_SET_2_B) $(PARAL
283283
PARALLEL_CT_SET_3 = $(sort $(PARALLEL_CT_SET_3_A) $(PARALLEL_CT_SET_3_B) $(PARALLEL_CT_SET_3_C) $(PARALLEL_CT_SET_3_D))
284284
PARALLEL_CT_SET_4 = $(sort $(PARALLEL_CT_SET_4_A) $(PARALLEL_CT_SET_4_B) $(PARALLEL_CT_SET_4_C) $(PARALLEL_CT_SET_4_D))
285285

286-
SEQUENTIAL_CT_SUITES = amqp_client clustering_management dead_lettering feature_flags metadata_store_clustering quorum_queue rabbit_stream_queue
286+
SEQUENTIAL_CT_SUITES = amqp_client clustering_management dead_lettering feature_flags metadata_store_clustering quorum_queue rabbit_stream_queue rabbit_fifo_prop
287287
PARALLEL_CT_SUITES = $(PARALLEL_CT_SET_1) $(PARALLEL_CT_SET_2) $(PARALLEL_CT_SET_3) $(PARALLEL_CT_SET_4)
288288

289289
ifeq ($(filter-out $(SEQUENTIAL_CT_SUITES) $(PARALLEL_CT_SUITES),$(CT_SUITES)),)

deps/rabbit/test/rabbit_fifo_prop_SUITE.erl

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ all_tests() ->
8585
dlx_08,
8686
dlx_09,
8787
single_active_ordering_02,
88-
different_nodes
88+
two_nodes_same_otp_version,
89+
two_nodes_different_otp_version
8990
].
9091

9192
groups() ->
@@ -1093,14 +1094,65 @@ single_active_ordering_03(_Config) ->
10931094
false
10941095
end.
10951096

1096-
%% Test that running the state machine commands on different Erlang nodes
1097-
%% end up in exactly the same state.
1098-
different_nodes(Config) ->
1099-
Config1 = rabbit_ct_helpers:run_setup_steps(
1100-
Config,
1101-
rabbit_ct_broker_helpers:setup_steps()),
1097+
%% Run the log on two Erlang nodes with the same OTP version.
1098+
two_nodes_same_otp_version(Config0) ->
1099+
Config = rabbit_ct_helpers:run_setup_steps(Config0,
1100+
rabbit_ct_broker_helpers:setup_steps()),
1101+
Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
1102+
case is_same_otp_version(Config) of
1103+
true ->
1104+
ok = rabbit_ct_broker_helpers:add_code_path_to_node(Node, ?MODULE),
1105+
two_nodes(Node);
1106+
false ->
1107+
ct:fail("expected CT node and RabbitMQ node to have the same OTP version")
1108+
end,
1109+
rabbit_ct_helpers:run_teardown_steps(Config,
1110+
rabbit_ct_broker_helpers:teardown_steps()).
1111+
1112+
%% Run the log on two Erlang nodes with different OTP versions.
1113+
two_nodes_different_otp_version(_Config) ->
1114+
Node = 'rabbit_fifo_prop@localhost',
1115+
case net_adm:ping(Node) of
1116+
pong ->
1117+
case is_same_otp_version(Node) of
1118+
true ->
1119+
ct:fail("expected CT node and 'rabbit_fifo_prop@localhost' "
1120+
"to have different OTP versions");
1121+
false ->
1122+
Prefixes = ["rabbit_fifo", "rabbit_misc", "mc",
1123+
"lqueue", "priority_queue", "ra_"],
1124+
[begin
1125+
Mod = list_to_atom(ModStr),
1126+
{Mod, Bin, _File} = code:get_object_code(Mod),
1127+
{module, Mod} = erpc:call(Node, code, load_binary, [Mod, ModStr, Bin])
1128+
end
1129+
|| {ModStr, _FileName, _Loaded} <- code:all_available(),
1130+
lists:any(fun(Prefix) -> lists:prefix(Prefix, ModStr) end, Prefixes)],
1131+
two_nodes(Node)
1132+
end;
1133+
pang ->
1134+
Reason = {node_down, Node},
1135+
case rabbit_ct_helpers:is_ci() of
1136+
true ->
1137+
ct:fail(Reason);
1138+
false ->
1139+
{skip, Reason}
1140+
end
1141+
end.
11021142

1103-
Size = 400,
1143+
is_same_otp_version(ConfigOrNode) ->
1144+
OurOTP = erlang:system_info(otp_release),
1145+
OtherOTP = case ConfigOrNode of
1146+
Cfg when is_list(Cfg) ->
1147+
rabbit_ct_broker_helpers:rpc(Cfg, erlang, system_info, [otp_release]);
1148+
Node when is_atom(Node) ->
1149+
erpc:call(Node, erlang, system_info, [otp_release])
1150+
end,
1151+
ct:pal("Our CT node runs OTP ~s, other node runs OTP ~s", [OurOTP, OtherOTP]),
1152+
OurOTP =:= OtherOTP.
1153+
1154+
two_nodes(Node) ->
1155+
Size = 500,
11041156
run_proper(
11051157
fun () ->
11061158
?FORALL({Length, Bytes, DeliveryLimit, SingleActive},
@@ -1118,13 +1170,9 @@ different_nodes(Config) ->
11181170
DeliveryLimit),
11191171
?FORALL(O, ?LET(Ops, log_gen_different_nodes(Size), expand(Ops, Conf)),
11201172
collect({log_size, length(O)},
1121-
different_nodes_prop(Config1, Conf, O)))
1173+
different_nodes_prop(Node, Conf, O)))
11221174
end)
1123-
end, [], Size),
1124-
1125-
rabbit_ct_helpers:run_teardown_steps(
1126-
Config1,
1127-
rabbit_ct_broker_helpers:teardown_steps()).
1175+
end, [], Size).
11281176

11291177
max_length(_Config) ->
11301178
%% tests that max length is never transgressed
@@ -1485,18 +1533,18 @@ single_active_prop(Conf0, Commands, ValidateOrder) ->
14851533
false
14861534
end.
14871535

1488-
different_nodes_prop(Config, Conf0, Commands) ->
1536+
different_nodes_prop(Node, Conf0, Commands) ->
14891537
Conf = Conf0#{release_cursor_interval => 100},
14901538
Indexes = lists:seq(1, length(Commands)),
14911539
Entries = lists:zip(Indexes, Commands),
14921540
InitState = test_init(Conf),
14931541
Fun = fun(_) -> true end,
1494-
Vsn = 6,
1542+
MachineVersion = 6,
14951543

1496-
{State0, _Effs0} = run_log(InitState, Entries, Fun, Vsn),
1497-
{State1, _Effs1} = rabbit_ct_broker_helpers:rpc(Config, ?MODULE, run_log,
1498-
[InitState, Entries, Fun, Vsn]),
1499-
State0 =:= State1.
1544+
{State1, _Effs1} = run_log(InitState, Entries, Fun, MachineVersion),
1545+
{State2, _Effs2} = erpc:call(Node, ?MODULE, run_log,
1546+
[InitState, Entries, Fun, MachineVersion]),
1547+
State1 =:= State2.
15001548

15011549
messages_total_prop(Conf0, Commands) ->
15021550
Conf = Conf0#{release_cursor_interval => 100},

deps/rabbitmq_ct_helpers/src/rabbit_ct_helpers.erl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@
5656
await_condition_with_retries/2,
5757

5858
eventually/1, eventually/3,
59-
consistently/1, consistently/3
59+
consistently/1, consistently/3,
60+
61+
is_ci/0
6062
]).
6163

6264
-define(SSL_CERT_PASSWORD, "test").
@@ -1175,6 +1177,12 @@ consistently({Line, Assertion} = TestObj, PollInterval, PollCount)
11751177
timer:sleep(PollInterval),
11761178
consistently(TestObj, PollInterval, PollCount - 1).
11771179

1180+
is_ci() ->
1181+
case os:getenv("CI") of
1182+
"true" -> true;
1183+
_ -> false
1184+
end.
1185+
11781186
%% -------------------------------------------------------------------
11791187
%% Cover-related functions.
11801188
%% -------------------------------------------------------------------

0 commit comments

Comments
 (0)