@@ -215,19 +215,19 @@ setup_steps() ->
215215 fun rabbit_ct_helpers :ensure_rabbitmqctl_app /1 ,
216216 fun rabbit_ct_helpers :ensure_rabbitmq_plugins_cmd /1 ,
217217 fun set_lager_flood_limit /1 ,
218+ fun configure_metadata_store /1 ,
218219 fun start_rabbitmq_nodes /1 ,
219- fun share_dist_and_proxy_ports_map /1 ,
220- fun configure_metadata_store /1
220+ fun share_dist_and_proxy_ports_map /1
221221 ];
222222 _ ->
223223 [
224224 fun rabbit_ct_helpers :ensure_rabbitmqctl_cmd /1 ,
225225 fun rabbit_ct_helpers :load_rabbitmqctl_app /1 ,
226226 fun rabbit_ct_helpers :ensure_rabbitmq_plugins_cmd /1 ,
227227 fun set_lager_flood_limit /1 ,
228+ fun configure_metadata_store /1 ,
228229 fun start_rabbitmq_nodes /1 ,
229- fun share_dist_and_proxy_ports_map /1 ,
230- fun configure_metadata_store /1
230+ fun share_dist_and_proxy_ports_map /1
231231 ]
232232 end .
233233
@@ -441,8 +441,24 @@ start_rabbitmq_node(Master, Config, NodeConfig, I) ->
441441 {failed_boot_attempts , Attempts + 1 }),
442442 start_rabbitmq_node (Master , Config , NodeConfig5 , I );
443443 NodeConfig4 ->
444- Master ! {self (), I , NodeConfig4 },
445- unlink (Master )
444+ case uses_expected_metadata_store (Config , NodeConfig4 ) of
445+ {MetadataStore , MetadataStore } ->
446+ Master ! {self (), I , NodeConfig4 },
447+ unlink (Master );
448+ {ExpectedMetadataStore , UsedMetadataStore } ->
449+ % % If the active metadata store is not the one expected, we
450+ % % stop the node and skip the test.
451+ _ = stop_rabbitmq_node (Config , NodeConfig4 ),
452+ Nodename = ? config (nodename , NodeConfig4 ),
453+ Error = {skip ,
454+ rabbit_misc :format (
455+ " Node ~s is using the ~s metadata store, "
456+ " ~s was expected" ,
457+ [Nodename , UsedMetadataStore ,
458+ ExpectedMetadataStore ])},
459+ Master ! {self (), Error },
460+ unlink (Master )
461+ end
446462 end .
447463
448464run_node_steps (Config , NodeConfig , I , [Step | Rest ]) ->
@@ -630,29 +646,29 @@ write_config_file(Config, NodeConfig, _I) ->
630646
631647-define (REQUIRED_FEATURE_FLAGS , [
632648 % % Required in 3.11:
633- " virtual_host_metadata,"
634- " quorum_queue,"
635- " implicit_default_bindings,"
636- " maintenance_mode_status,"
637- " user_limits,"
649+ virtual_host_metadata ,
650+ quorum_queue ,
651+ implicit_default_bindings ,
652+ maintenance_mode_status ,
653+ user_limits ,
638654 % % Required in 3.12:
639- " stream_queue,"
640- " classic_queue_type_delivery_support,"
641- " tracking_records_in_ets,"
642- " stream_single_active_consumer,"
643- " listener_records_in_ets,"
644- " feature_flags_v2,"
645- " direct_exchange_routing_v2,"
646- " classic_mirrored_queue_version," % % @todo Missing in FF docs!!
655+ stream_queue ,
656+ classic_queue_type_delivery_support ,
657+ tracking_records_in_ets ,
658+ stream_single_active_consumer ,
659+ listener_records_in_ets ,
660+ feature_flags_v2 ,
661+ direct_exchange_routing_v2 ,
662+ classic_mirrored_queue_version , % % @todo Missing in FF docs!!
647663 % % Required in 3.12 in rabbitmq_management_agent:
648- % " drop_unroutable_metric,"
649- % " empty_basic_get_metric,"
664+ % drop_unroutable_metric,
665+ % empty_basic_get_metric,
650666 % % Required in 4.0:
651- " stream_sac_coordinator_unblock_group,"
652- " restart_streams,"
653- " stream_update_config_command,"
654- " stream_filtering,"
655- " message_containers" % % @todo Update FF docs!! It *is* required.
667+ stream_sac_coordinator_unblock_group ,
668+ restart_streams ,
669+ stream_update_config_command ,
670+ stream_filtering ,
671+ message_containers % % @todo Update FF docs!! It *is* required.
656672]).
657673
658674do_start_rabbitmq_node (Config , NodeConfig , I ) ->
@@ -734,6 +750,17 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
734750 false -> ExtraArgs3 ;
735751 _ -> [" NOBUILD=1" | ExtraArgs3 ]
736752 end ,
753+ % % TODO: When we start to do mixed-version testing against 4.1.x as the
754+ % % secondary umbrella, we will need to stop setting
755+ % % `$RABBITMQ_FEATURE_FLAGS'.
756+ MetadataStore = rabbit_ct_helpers :get_config (Config , metadata_store ),
757+ SecFeatureFlags0 = case MetadataStore of
758+ mnesia -> ? REQUIRED_FEATURE_FLAGS ;
759+ khepri -> [khepri_db | ? REQUIRED_FEATURE_FLAGS ]
760+ end ,
761+ SecFeatureFlags = string :join (
762+ [atom_to_list (F ) || F <- SecFeatureFlags0 ],
763+ " ," ),
737764 ExtraArgs = case UseSecondaryUmbrella of
738765 true ->
739766 DepsDir = ? config (erlang_mk_depsdir , Config ),
@@ -763,7 +790,8 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
763790 {" RABBITMQ_SCRIPTS_DIR=~ts " , [SecScriptsDir ]},
764791 {" RABBITMQ_SERVER=~ts /rabbitmq-server" , [SecScriptsDir ]},
765792 {" RABBITMQCTL=~ts /rabbitmqctl" , [SecScriptsDir ]},
766- {" RABBITMQ_PLUGINS=~ts /rabbitmq-plugins" , [SecScriptsDir ]}
793+ {" RABBITMQ_PLUGINS=~ts /rabbitmq-plugins" , [SecScriptsDir ]},
794+ {" RABBITMQ_FEATURE_FLAGS=~ts " , [SecFeatureFlags ]}
767795 | ExtraArgs4 ];
768796 false ->
769797 case UseSecondaryDist of
@@ -785,7 +813,7 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
785813 {" RABBITMQ_SCRIPTS_DIR=~ts /sbin" , [SecondaryDist ]},
786814 {" RABBITMQ_SERVER=~ts /sbin/rabbitmq-server" , [SecondaryDist ]},
787815 {" RABBITMQ_ENABLED_PLUGINS=~ts " , [SecondaryEnabledPlugins ]},
788- {" RABBITMQ_FEATURE_FLAGS=~ts " , [? REQUIRED_FEATURE_FLAGS ]}
816+ {" RABBITMQ_FEATURE_FLAGS=~ts " , [SecFeatureFlags ]}
789817 | ExtraArgs4 ];
790818 false ->
791819 ExtraArgs4
@@ -883,6 +911,21 @@ query_node(Config, NodeConfig) ->
883911 cover_add_node (Nodename ),
884912 rabbit_ct_helpers :set_config (NodeConfig , Vars ).
885913
914+ uses_expected_metadata_store (Config , NodeConfig ) ->
915+ % % We want to verify if the active metadata store matches the expected one.
916+ Nodename = ? config (nodename , NodeConfig ),
917+ ExpectedMetadataStore = rabbit_ct_helpers :get_config (
918+ Config , metadata_store ),
919+ IsKhepriEnabled = rpc (Config , Nodename , rabbit_khepri , is_enabled , []),
920+ UsedMetadataStore = case IsKhepriEnabled of
921+ true -> khepri ;
922+ false -> mnesia
923+ end ,
924+ ct :pal (
925+ " Metadata store on ~s : expected=~s , used=~s " ,
926+ [Nodename , UsedMetadataStore , ExpectedMetadataStore ]),
927+ {ExpectedMetadataStore , UsedMetadataStore }.
928+
886929maybe_cluster_nodes (Config ) ->
887930 Clustered0 = rabbit_ct_helpers :get_config (Config , rmq_nodes_clustered ),
888931 Clustered = case Clustered0 of
@@ -999,57 +1042,79 @@ share_dist_and_proxy_ports_map(Config) ->
9991042configured_metadata_store (Config ) ->
10001043 case rabbit_ct_helpers :get_config (Config , metadata_store ) of
10011044 khepri ->
1002- {khepri , []};
1003- {khepri , _FFs0 } = Khepri ->
1004- Khepri ;
1045+ khepri ;
10051046 mnesia ->
10061047 mnesia ;
10071048 _ ->
10081049 case os :getenv (" RABBITMQ_METADATA_STORE" ) of
1009- " khepri" ->
1010- {khepri , []};
1011- _ ->
1012- mnesia
1050+ " khepri" -> khepri ;
1051+ _ -> mnesia
10131052 end
10141053 end .
10151054
10161055configure_metadata_store (Config ) ->
10171056 ct :log (" Configuring metadata store..." ),
1018- case configured_metadata_store (Config ) of
1019- {khepri , FFs0 } ->
1020- case enable_khepri_metadata_store (Config , FFs0 ) of
1021- {skip , _ } = Skip ->
1022- _ = stop_rabbitmq_nodes (Config ),
1023- Skip ;
1024- Config1 ->
1025- Config1
1057+ Value = rabbit_ct_helpers :get_app_env (
1058+ Config , rabbit , forced_feature_flags_on_init , undefined ),
1059+ MetadataStore = configured_metadata_store (Config ),
1060+ Config1 = rabbit_ct_helpers :set_config (
1061+ Config , {metadata_store , MetadataStore }),
1062+ % % To enabled or disable `khepri_db', we use the relative forced feature
1063+ % % flags mechanism. This allows us to select the state of Khepri without
1064+ % % having to worry about other feature flags.
1065+ % %
1066+ % % However, RabbitMQ 4.0.x and older don't support it. See the
1067+ % % `uses_expected_metadata_store/2' check to see how Khepri is enabled in
1068+ % % this case.
1069+ % %
1070+ % % Note that this setting will be ignored by the secondary umbrella because
1071+ % % we set `$RABBITMQ_FEATURE_FLAGS' explisitly. In this case, we handle the
1072+ % % `khepri_db' feature flag when we compute the value of that variable.
1073+ % %
1074+ % % TODO: When we start to do mixed-version testing against 4.1.x as the
1075+ % % secondary umbrella, we will need to stop setting
1076+ % % `$RABBITMQ_FEATURE_FLAGS'.
1077+ case MetadataStore of
1078+ khepri ->
1079+ ct :log (" Enabling Khepri metadata store" ),
1080+ case Value of
1081+ undefined ->
1082+ rabbit_ct_helpers :merge_app_env (
1083+ Config1 ,
1084+ {rabbit ,
1085+ [{forced_feature_flags_on_init ,
1086+ {rel , [khepri_db ], []}}]});
1087+ _ ->
1088+ rabbit_ct_helpers :merge_app_env (
1089+ Config1 ,
1090+ {rabbit ,
1091+ [{forced_feature_flags_on_init ,
1092+ [khepri_db | Value ]}]})
10261093 end ;
10271094 mnesia ->
10281095 ct :log (" Enabling Mnesia metadata store" ),
1029- Config
1096+ case Value of
1097+ undefined ->
1098+ rabbit_ct_helpers :merge_app_env (
1099+ Config1 ,
1100+ {rabbit ,
1101+ [{forced_feature_flags_on_init ,
1102+ {rel , [], [khepri_db ]}}]});
1103+ _ ->
1104+ rabbit_ct_helpers :merge_app_env (
1105+ Config1 ,
1106+ {rabbit ,
1107+ [{forced_feature_flags_on_init ,
1108+ Value -- [khepri_db ]}]})
1109+ end
10301110 end .
10311111
1032- enable_khepri_metadata_store (Config , FFs0 ) ->
1033- ct :log (" Enabling Khepri metadata store" ),
1034- FFs = [khepri_db | FFs0 ],
1035- lists :foldl (fun (_FF , {skip , _Reason } = Skip ) ->
1036- Skip ;
1037- (FF , C ) ->
1038- case enable_feature_flag (C , FF ) of
1039- ok ->
1040- C ;
1041- {skip , _ } = Skip ->
1042- ct :pal (" Enabling metadata store failed: ~p " , [Skip ]),
1043- Skip
1044- end
1045- end , Config , FFs ).
1046-
10471112% % Waits until the metadata store replica on Node is up to date with the leader.
10481113await_metadata_store_consistent (Config , Node ) ->
10491114 case configured_metadata_store (Config ) of
10501115 mnesia ->
10511116 ok ;
1052- { khepri , _ } ->
1117+ khepri ->
10531118 RaClusterName = rabbit_khepri :get_ra_cluster_name (),
10541119 Leader = rpc (Config , Node , ra_leaderboard , lookup_leader , [RaClusterName ]),
10551120 LastAppliedLeader = ra_last_applied (Leader ),
0 commit comments