Skip to content

Commit fa724ad

Browse files
committed
rabbitmq_ct_helpers: Change how Mnesia/Khepri is selected
[Why] Once `khepr_db` is enabled by default, we need another way to disable it to select Mnesia instead. [How] We use the new relative forced feature flags mechanism to indicate if we want to explicitly enable or disable `khepri_db`. This way, we don't touch other stable feature flags and only mess with Khepri. However, this mechanism is not supported by RabbitMQ 4.0.x and older. They will ignore the setting. Therefore, to make this work in mixed-version testing, we set the `$RABBITMQ_FEATURE_FLAGS` variable for the secondary umbrella. This part will go away once we test against RabbitMQ 4.1.x as the secondary umbrella in the future. At the end, we compare the effective metadata store to the expected one. If they don't match, we skip the test. While here, change `rjms_topic_selector_SUITE` to only choose Khepri without specifying any feature flags.
1 parent ae4f37b commit fa724ad

File tree

6 files changed

+131
-66
lines changed

6 files changed

+131
-66
lines changed

deps/rabbit/test/bindings_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ end_per_suite(Config) ->
7272
% init_per_group_common(Group, Config, 1);
7373
init_per_group(khepri_migration = Group, Config) ->
7474
case rabbit_ct_broker_helpers:configured_metadata_store(Config) of
75-
{khepri, _} ->
75+
khepri ->
7676
{skip, "skip khepri migration test when khepri already configured"};
7777
mnesia ->
7878
init_per_group_common(Group, Config, 1)

deps/rabbit/test/clustering_management_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ init_per_group(khepri_store, Config) ->
138138
end;
139139
init_per_group(mnesia_store, Config) ->
140140
case rabbit_ct_broker_helpers:configured_metadata_store(Config) of
141-
{khepri, _} ->
141+
khepri ->
142142
{skip, "These tests target mnesia"};
143143
_ ->
144144
Config

deps/rabbit/test/clustering_recovery_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ init_per_group(khepri_store, Config) ->
8080
end;
8181
init_per_group(mnesia_store, Config) ->
8282
case rabbit_ct_broker_helpers:configured_metadata_store(Config) of
83-
{khepri, _} ->
83+
khepri ->
8484
{skip, "These tests target mnesia"};
8585
_ ->
8686
Config

deps/rabbitmq_ct_helpers/src/rabbit_ct_broker_helpers.erl

Lines changed: 125 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -216,19 +216,19 @@ setup_steps() ->
216216
fun rabbit_ct_helpers:ensure_rabbitmqctl_app/1,
217217
fun rabbit_ct_helpers:ensure_rabbitmq_plugins_cmd/1,
218218
fun set_lager_flood_limit/1,
219+
fun configure_metadata_store/1,
219220
fun start_rabbitmq_nodes/1,
220-
fun share_dist_and_proxy_ports_map/1,
221-
fun configure_metadata_store/1
221+
fun share_dist_and_proxy_ports_map/1
222222
];
223223
_ ->
224224
[
225225
fun rabbit_ct_helpers:ensure_rabbitmqctl_cmd/1,
226226
fun rabbit_ct_helpers:load_rabbitmqctl_app/1,
227227
fun rabbit_ct_helpers:ensure_rabbitmq_plugins_cmd/1,
228228
fun set_lager_flood_limit/1,
229+
fun configure_metadata_store/1,
229230
fun start_rabbitmq_nodes/1,
230-
fun share_dist_and_proxy_ports_map/1,
231-
fun configure_metadata_store/1
231+
fun share_dist_and_proxy_ports_map/1
232232
]
233233
end.
234234

@@ -442,8 +442,24 @@ start_rabbitmq_node(Master, Config, NodeConfig, I) ->
442442
{failed_boot_attempts, Attempts + 1}),
443443
start_rabbitmq_node(Master, Config, NodeConfig5, I);
444444
NodeConfig4 ->
445-
Master ! {self(), I, NodeConfig4},
446-
unlink(Master)
445+
case uses_expected_metadata_store(Config, NodeConfig4) of
446+
{MetadataStore, MetadataStore} ->
447+
Master ! {self(), I, NodeConfig4},
448+
unlink(Master);
449+
{ExpectedMetadataStore, UsedMetadataStore} ->
450+
%% If the active metadata store is not the one expected, we
451+
%% stop the node and skip the test.
452+
_ = stop_rabbitmq_node(Config, NodeConfig4),
453+
Nodename = ?config(nodename, NodeConfig4),
454+
Error = {skip,
455+
rabbit_misc:format(
456+
"Node ~s is using the ~s metadata store, "
457+
"~s was expected",
458+
[Nodename, UsedMetadataStore,
459+
ExpectedMetadataStore])},
460+
Master ! {self(), Error},
461+
unlink(Master)
462+
end
447463
end.
448464

449465
run_node_steps(Config, NodeConfig, I, [Step | Rest]) ->
@@ -631,29 +647,29 @@ write_config_file(Config, NodeConfig, _I) ->
631647

632648
-define(REQUIRED_FEATURE_FLAGS, [
633649
%% Required in 3.11:
634-
"virtual_host_metadata,"
635-
"quorum_queue,"
636-
"implicit_default_bindings,"
637-
"maintenance_mode_status,"
638-
"user_limits,"
650+
virtual_host_metadata,
651+
quorum_queue,
652+
implicit_default_bindings,
653+
maintenance_mode_status,
654+
user_limits,
639655
%% Required in 3.12:
640-
"stream_queue,"
641-
"classic_queue_type_delivery_support,"
642-
"tracking_records_in_ets,"
643-
"stream_single_active_consumer,"
644-
"listener_records_in_ets,"
645-
"feature_flags_v2,"
646-
"direct_exchange_routing_v2,"
647-
"classic_mirrored_queue_version," %% @todo Missing in FF docs!!
656+
stream_queue,
657+
classic_queue_type_delivery_support,
658+
tracking_records_in_ets,
659+
stream_single_active_consumer,
660+
listener_records_in_ets,
661+
feature_flags_v2,
662+
direct_exchange_routing_v2,
663+
classic_mirrored_queue_version, %% @todo Missing in FF docs!!
648664
%% Required in 3.12 in rabbitmq_management_agent:
649-
% "drop_unroutable_metric,"
650-
% "empty_basic_get_metric,"
665+
% drop_unroutable_metric,
666+
% empty_basic_get_metric,
651667
%% Required in 4.0:
652-
"stream_sac_coordinator_unblock_group,"
653-
"restart_streams,"
654-
"stream_update_config_command,"
655-
"stream_filtering,"
656-
"message_containers" %% @todo Update FF docs!! It *is* required.
668+
stream_sac_coordinator_unblock_group,
669+
restart_streams,
670+
stream_update_config_command,
671+
stream_filtering,
672+
message_containers %% @todo Update FF docs!! It *is* required.
657673
]).
658674

659675
do_start_rabbitmq_node(Config, NodeConfig, I) ->
@@ -735,6 +751,17 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
735751
false -> ExtraArgs3;
736752
_ -> ["NOBUILD=1" | ExtraArgs3]
737753
end,
754+
%% TODO: When we start to do mixed-version testing against 4.1.x as the
755+
%% secondary umbrella, we will need to stop setting
756+
%% `$RABBITMQ_FEATURE_FLAGS'.
757+
MetadataStore = rabbit_ct_helpers:get_config(Config, metadata_store),
758+
SecFeatureFlags0 = case MetadataStore of
759+
mnesia -> ?REQUIRED_FEATURE_FLAGS;
760+
khepri -> [khepri_db | ?REQUIRED_FEATURE_FLAGS]
761+
end,
762+
SecFeatureFlags = string:join(
763+
[atom_to_list(F) || F <- SecFeatureFlags0],
764+
","),
738765
ExtraArgs = case UseSecondaryUmbrella of
739766
true ->
740767
DepsDir = ?config(erlang_mk_depsdir, Config),
@@ -764,7 +791,8 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
764791
{"RABBITMQ_SCRIPTS_DIR=~ts", [SecScriptsDir]},
765792
{"RABBITMQ_SERVER=~ts/rabbitmq-server", [SecScriptsDir]},
766793
{"RABBITMQCTL=~ts/rabbitmqctl", [SecScriptsDir]},
767-
{"RABBITMQ_PLUGINS=~ts/rabbitmq-plugins", [SecScriptsDir]}
794+
{"RABBITMQ_PLUGINS=~ts/rabbitmq-plugins", [SecScriptsDir]},
795+
{"RABBITMQ_FEATURE_FLAGS=~ts", [SecFeatureFlags]}
768796
| ExtraArgs4];
769797
false ->
770798
case UseSecondaryDist of
@@ -786,7 +814,7 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
786814
{"RABBITMQ_SCRIPTS_DIR=~ts/sbin", [SecondaryDist]},
787815
{"RABBITMQ_SERVER=~ts/sbin/rabbitmq-server", [SecondaryDist]},
788816
{"RABBITMQ_ENABLED_PLUGINS=~ts", [SecondaryEnabledPlugins]},
789-
{"RABBITMQ_FEATURE_FLAGS=~ts", [?REQUIRED_FEATURE_FLAGS]}
817+
{"RABBITMQ_FEATURE_FLAGS=~ts", [SecFeatureFlags]}
790818
| ExtraArgs4];
791819
false ->
792820
ExtraArgs4
@@ -884,6 +912,21 @@ query_node(Config, NodeConfig) ->
884912
cover_add_node(Nodename),
885913
rabbit_ct_helpers:set_config(NodeConfig, Vars).
886914

915+
uses_expected_metadata_store(Config, NodeConfig) ->
916+
%% We want to verify if the active metadata store matches the expected one.
917+
Nodename = ?config(nodename, NodeConfig),
918+
ExpectedMetadataStore = rabbit_ct_helpers:get_config(
919+
Config, metadata_store),
920+
IsKhepriEnabled = rpc(Config, Nodename, rabbit_khepri, is_enabled, []),
921+
UsedMetadataStore = case IsKhepriEnabled of
922+
true -> khepri;
923+
false -> mnesia
924+
end,
925+
ct:pal(
926+
"Metadata store on ~s: expected=~s, used=~s",
927+
[Nodename, UsedMetadataStore, ExpectedMetadataStore]),
928+
{ExpectedMetadataStore, UsedMetadataStore}.
929+
887930
maybe_cluster_nodes(Config) ->
888931
Clustered0 = rabbit_ct_helpers:get_config(Config, rmq_nodes_clustered),
889932
Clustered = case Clustered0 of
@@ -1000,57 +1043,79 @@ share_dist_and_proxy_ports_map(Config) ->
10001043
configured_metadata_store(Config) ->
10011044
case rabbit_ct_helpers:get_config(Config, metadata_store) of
10021045
khepri ->
1003-
{khepri, []};
1004-
{khepri, _FFs0} = Khepri ->
1005-
Khepri;
1046+
khepri;
10061047
mnesia ->
10071048
mnesia;
10081049
_ ->
10091050
case os:getenv("RABBITMQ_METADATA_STORE") of
1010-
"khepri" ->
1011-
{khepri, []};
1012-
_ ->
1013-
mnesia
1051+
"khepri" -> khepri;
1052+
_ -> mnesia
10141053
end
10151054
end.
10161055

10171056
configure_metadata_store(Config) ->
10181057
ct:log("Configuring metadata store..."),
1019-
case configured_metadata_store(Config) of
1020-
{khepri, FFs0} ->
1021-
case enable_khepri_metadata_store(Config, FFs0) of
1022-
{skip, _} = Skip ->
1023-
_ = stop_rabbitmq_nodes(Config),
1024-
Skip;
1025-
Config1 ->
1026-
Config1
1058+
Value = rabbit_ct_helpers:get_app_env(
1059+
Config, rabbit, forced_feature_flags_on_init, undefined),
1060+
MetadataStore = configured_metadata_store(Config),
1061+
Config1 = rabbit_ct_helpers:set_config(
1062+
Config, {metadata_store, MetadataStore}),
1063+
%% To enabled or disable `khepri_db', we use the relative forced feature
1064+
%% flags mechanism. This allows us to select the state of Khepri without
1065+
%% having to worry about other feature flags.
1066+
%%
1067+
%% However, RabbitMQ 4.0.x and older don't support it. See the
1068+
%% `uses_expected_metadata_store/2' check to see how Khepri is enabled in
1069+
%% this case.
1070+
%%
1071+
%% Note that this setting will be ignored by the secondary umbrella because
1072+
%% we set `$RABBITMQ_FEATURE_FLAGS' explisitly. In this case, we handle the
1073+
%% `khepri_db' feature flag when we compute the value of that variable.
1074+
%%
1075+
%% TODO: When we start to do mixed-version testing against 4.1.x as the
1076+
%% secondary umbrella, we will need to stop setting
1077+
%% `$RABBITMQ_FEATURE_FLAGS'.
1078+
case MetadataStore of
1079+
khepri ->
1080+
ct:log("Enabling Khepri metadata store"),
1081+
case Value of
1082+
undefined ->
1083+
rabbit_ct_helpers:merge_app_env(
1084+
Config1,
1085+
{rabbit,
1086+
[{forced_feature_flags_on_init,
1087+
{rel, [khepri_db], []}}]});
1088+
_ ->
1089+
rabbit_ct_helpers:merge_app_env(
1090+
Config1,
1091+
{rabbit,
1092+
[{forced_feature_flags_on_init,
1093+
[khepri_db | Value]}]})
10271094
end;
10281095
mnesia ->
10291096
ct:log("Enabling Mnesia metadata store"),
1030-
Config
1097+
case Value of
1098+
undefined ->
1099+
rabbit_ct_helpers:merge_app_env(
1100+
Config1,
1101+
{rabbit,
1102+
[{forced_feature_flags_on_init,
1103+
{rel, [], [khepri_db]}}]});
1104+
_ ->
1105+
rabbit_ct_helpers:merge_app_env(
1106+
Config1,
1107+
{rabbit,
1108+
[{forced_feature_flags_on_init,
1109+
Value -- [khepri_db]}]})
1110+
end
10311111
end.
10321112

1033-
enable_khepri_metadata_store(Config, FFs0) ->
1034-
ct:log("Enabling Khepri metadata store"),
1035-
FFs = [khepri_db | FFs0],
1036-
lists:foldl(fun(_FF, {skip, _Reason} = Skip) ->
1037-
Skip;
1038-
(FF, C) ->
1039-
case enable_feature_flag(C, FF) of
1040-
ok ->
1041-
C;
1042-
{skip, _} = Skip ->
1043-
ct:pal("Enabling metadata store failed: ~p", [Skip]),
1044-
Skip
1045-
end
1046-
end, Config, FFs).
1047-
10481113
%% Waits until the metadata store replica on Node is up to date with the leader.
10491114
await_metadata_store_consistent(Config, Node) ->
10501115
case configured_metadata_store(Config) of
10511116
mnesia ->
10521117
ok;
1053-
{khepri, _} ->
1118+
khepri ->
10541119
RaClusterName = rabbit_khepri:get_ra_cluster_name(),
10551120
Leader = rpc(Config, Node, ra_leaderboard, lookup_leader, [RaClusterName]),
10561121
LastAppliedLeader = ra_last_applied(Leader),

deps/rabbitmq_jms_topic_exchange/test/rjms_topic_selector_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ init_per_group(mnesia_store = Group, Config0) ->
5656
init_per_group(khepri_store = Group, Config0) ->
5757
Config = rabbit_ct_helpers:set_config(
5858
Config0,
59-
[{metadata_store, {khepri, [khepri_db]}}]),
59+
[{metadata_store, khepri}]),
6060
init_per_group_common(Group, Config);
6161
init_per_group(khepri_migration = Group, Config0) ->
6262
Config = rabbit_ct_helpers:set_config(Config0, [{metadata_store, mnesia}]),

deps/rabbitmq_recent_history_exchange/test/system_SUITE.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ end_per_suite(Config) ->
5959

6060
init_per_group(mnesia_store, Config) ->
6161
case rabbit_ct_broker_helpers:configured_metadata_store(Config) of
62-
{khepri, _} -> {skip, "These tests target Mnesia"};
63-
_ -> Config
62+
khepri -> {skip, "These tests target Mnesia"};
63+
_ -> Config
6464
end;
6565
init_per_group(khepri_store, Config) ->
6666
case rabbit_ct_broker_helpers:configured_metadata_store(Config) of

0 commit comments

Comments
 (0)