@@ -216,19 +216,19 @@ setup_steps() ->
216
216
fun rabbit_ct_helpers :ensure_rabbitmqctl_app /1 ,
217
217
fun rabbit_ct_helpers :ensure_rabbitmq_plugins_cmd /1 ,
218
218
fun set_lager_flood_limit /1 ,
219
+ fun configure_metadata_store /1 ,
219
220
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
222
222
];
223
223
_ ->
224
224
[
225
225
fun rabbit_ct_helpers :ensure_rabbitmqctl_cmd /1 ,
226
226
fun rabbit_ct_helpers :load_rabbitmqctl_app /1 ,
227
227
fun rabbit_ct_helpers :ensure_rabbitmq_plugins_cmd /1 ,
228
228
fun set_lager_flood_limit /1 ,
229
+ fun configure_metadata_store /1 ,
229
230
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
232
232
]
233
233
end .
234
234
@@ -442,8 +442,24 @@ start_rabbitmq_node(Master, Config, NodeConfig, I) ->
442
442
{failed_boot_attempts , Attempts + 1 }),
443
443
start_rabbitmq_node (Master , Config , NodeConfig5 , I );
444
444
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
447
463
end .
448
464
449
465
run_node_steps (Config , NodeConfig , I , [Step | Rest ]) ->
@@ -631,29 +647,29 @@ write_config_file(Config, NodeConfig, _I) ->
631
647
632
648
-define (REQUIRED_FEATURE_FLAGS , [
633
649
% % 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 ,
639
655
% % 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!!
648
664
% % 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,
651
667
% % 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.
657
673
]).
658
674
659
675
do_start_rabbitmq_node (Config , NodeConfig , I ) ->
@@ -735,6 +751,17 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
735
751
false -> ExtraArgs3 ;
736
752
_ -> [" NOBUILD=1" | ExtraArgs3 ]
737
753
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
+ " ," ),
738
765
ExtraArgs = case UseSecondaryUmbrella of
739
766
true ->
740
767
DepsDir = ? config (erlang_mk_depsdir , Config ),
@@ -764,7 +791,8 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
764
791
{" RABBITMQ_SCRIPTS_DIR=~ts " , [SecScriptsDir ]},
765
792
{" RABBITMQ_SERVER=~ts /rabbitmq-server" , [SecScriptsDir ]},
766
793
{" RABBITMQCTL=~ts /rabbitmqctl" , [SecScriptsDir ]},
767
- {" RABBITMQ_PLUGINS=~ts /rabbitmq-plugins" , [SecScriptsDir ]}
794
+ {" RABBITMQ_PLUGINS=~ts /rabbitmq-plugins" , [SecScriptsDir ]},
795
+ {" RABBITMQ_FEATURE_FLAGS=~ts " , [SecFeatureFlags ]}
768
796
| ExtraArgs4 ];
769
797
false ->
770
798
case UseSecondaryDist of
@@ -786,7 +814,7 @@ do_start_rabbitmq_node(Config, NodeConfig, I) ->
786
814
{" RABBITMQ_SCRIPTS_DIR=~ts /sbin" , [SecondaryDist ]},
787
815
{" RABBITMQ_SERVER=~ts /sbin/rabbitmq-server" , [SecondaryDist ]},
788
816
{" RABBITMQ_ENABLED_PLUGINS=~ts " , [SecondaryEnabledPlugins ]},
789
- {" RABBITMQ_FEATURE_FLAGS=~ts " , [? REQUIRED_FEATURE_FLAGS ]}
817
+ {" RABBITMQ_FEATURE_FLAGS=~ts " , [SecFeatureFlags ]}
790
818
| ExtraArgs4 ];
791
819
false ->
792
820
ExtraArgs4
@@ -884,6 +912,21 @@ query_node(Config, NodeConfig) ->
884
912
cover_add_node (Nodename ),
885
913
rabbit_ct_helpers :set_config (NodeConfig , Vars ).
886
914
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
+
887
930
maybe_cluster_nodes (Config ) ->
888
931
Clustered0 = rabbit_ct_helpers :get_config (Config , rmq_nodes_clustered ),
889
932
Clustered = case Clustered0 of
@@ -1000,57 +1043,79 @@ share_dist_and_proxy_ports_map(Config) ->
1000
1043
configured_metadata_store (Config ) ->
1001
1044
case rabbit_ct_helpers :get_config (Config , metadata_store ) of
1002
1045
khepri ->
1003
- {khepri , []};
1004
- {khepri , _FFs0 } = Khepri ->
1005
- Khepri ;
1046
+ khepri ;
1006
1047
mnesia ->
1007
1048
mnesia ;
1008
1049
_ ->
1009
1050
case os :getenv (" RABBITMQ_METADATA_STORE" ) of
1010
- " khepri" ->
1011
- {khepri , []};
1012
- _ ->
1013
- mnesia
1051
+ " khepri" -> khepri ;
1052
+ _ -> mnesia
1014
1053
end
1015
1054
end .
1016
1055
1017
1056
configure_metadata_store (Config ) ->
1018
1057
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 ]}]})
1027
1094
end ;
1028
1095
mnesia ->
1029
1096
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
1031
1111
end .
1032
1112
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
-
1048
1113
% % Waits until the metadata store replica on Node is up to date with the leader.
1049
1114
await_metadata_store_consistent (Config , Node ) ->
1050
1115
case configured_metadata_store (Config ) of
1051
1116
mnesia ->
1052
1117
ok ;
1053
- { khepri , _ } ->
1118
+ khepri ->
1054
1119
RaClusterName = rabbit_khepri :get_ra_cluster_name (),
1055
1120
Leader = rpc (Config , Node , ra_leaderboard , lookup_leader , [RaClusterName ]),
1056
1121
LastAppliedLeader = ra_last_applied (Leader ),
0 commit comments