2020-07-10 21:31:17 +08:00
|
|
|
%% This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
2019-02-19 17:29:38 +08:00
|
|
|
%%
|
2024-02-06 00:53:36 +08:00
|
|
|
%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
|
2019-02-19 17:29:38 +08:00
|
|
|
%%
|
2019-02-20 18:30:59 +08:00
|
|
|
-module(rabbitmq_queues_cli_integration_SUITE).
|
2019-02-19 17:29:38 +08:00
|
|
|
|
|
|
|
-include_lib("common_test/include/ct.hrl").
|
|
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
|
-include_lib("amqp_client/include/amqp_client.hrl").
|
|
|
|
|
|
|
|
-compile(export_all).
|
|
|
|
|
|
|
|
all() ->
|
|
|
|
[
|
|
|
|
{group, tests}
|
|
|
|
].
|
|
|
|
|
|
|
|
groups() ->
|
|
|
|
[
|
|
|
|
{tests, [], [
|
2019-02-20 20:23:12 +08:00
|
|
|
shrink,
|
2019-02-21 01:29:29 +08:00
|
|
|
grow,
|
|
|
|
grow_invalid_node_filtered
|
2019-02-19 17:29:38 +08:00
|
|
|
]}
|
|
|
|
].
|
|
|
|
|
|
|
|
init_per_suite(Config) ->
|
2021-06-25 17:10:04 +08:00
|
|
|
case rabbit_ct_helpers:is_mixed_versions() of
|
2020-07-15 19:14:31 +08:00
|
|
|
false ->
|
|
|
|
rabbit_ct_helpers:log_environment(),
|
|
|
|
rabbit_ct_helpers:run_setup_steps(Config);
|
|
|
|
_ ->
|
|
|
|
{skip, "growing and shrinking cannot be done in mixed mode"}
|
|
|
|
end.
|
2019-02-19 17:29:38 +08:00
|
|
|
|
|
|
|
end_per_suite(Config) ->
|
|
|
|
rabbit_ct_helpers:run_teardown_steps(Config).
|
|
|
|
|
|
|
|
init_per_group(tests, Config0) ->
|
|
|
|
NumNodes = 3,
|
|
|
|
Config1 = rabbit_ct_helpers:set_config(
|
|
|
|
Config0, [{rmq_nodes_count, NumNodes},
|
|
|
|
{rmq_nodes_clustered, true}]),
|
2022-07-29 17:48:48 +08:00
|
|
|
rabbit_ct_helpers:run_steps(Config1,
|
|
|
|
rabbit_ct_broker_helpers:setup_steps() ++
|
|
|
|
rabbit_ct_client_helpers:setup_steps()).
|
2019-02-19 17:29:38 +08:00
|
|
|
|
|
|
|
end_per_group(tests, Config) ->
|
|
|
|
rabbit_ct_helpers:run_steps(Config,
|
|
|
|
rabbit_ct_client_helpers:teardown_steps() ++
|
|
|
|
rabbit_ct_broker_helpers:teardown_steps()).
|
|
|
|
|
|
|
|
init_per_testcase(Testcase, Config0) ->
|
2019-02-20 20:23:12 +08:00
|
|
|
rabbit_ct_helpers:ensure_rabbitmq_queues_cmd(
|
2019-02-19 17:29:38 +08:00
|
|
|
rabbit_ct_helpers:testcase_started(Config0, Testcase)).
|
|
|
|
|
|
|
|
end_per_testcase(Testcase, Config0) ->
|
|
|
|
rabbit_ct_helpers:testcase_finished(Config0, Testcase).
|
|
|
|
|
|
|
|
shrink(Config) ->
|
|
|
|
NodeConfig = rabbit_ct_broker_helpers:get_node_config(Config, 2),
|
|
|
|
Nodename2 = ?config(nodename, NodeConfig),
|
|
|
|
Ch = rabbit_ct_client_helpers:open_channel(Config, Nodename2),
|
2021-03-27 00:04:10 +08:00
|
|
|
#'confirm.select_ok'{} = amqp_channel:call(Ch, #'confirm.select'{}),
|
2019-02-19 17:29:38 +08:00
|
|
|
%% declare a quorum queue
|
|
|
|
QName = "shrink1",
|
|
|
|
#'queue.declare_ok'{} = declare_qq(Ch, QName),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-19 17:29:38 +08:00
|
|
|
{ok, Out1} = rabbitmq_queues(Config, 0, ["shrink", Nodename2]),
|
|
|
|
?assertMatch(#{{"/", "shrink1"} := {2, ok}}, parse_result(Out1)),
|
2021-06-21 14:43:29 +08:00
|
|
|
%% removing a node can trigger a leader election, give this QQ some time
|
|
|
|
%% to do it
|
2021-06-21 14:39:05 +08:00
|
|
|
timer:sleep(1500),
|
2019-02-19 17:29:38 +08:00
|
|
|
Nodename1 = rabbit_ct_broker_helpers:get_node_config(Config, 1, nodename),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-19 17:29:38 +08:00
|
|
|
{ok, Out2} = rabbitmq_queues(Config, 0, ["shrink", Nodename1]),
|
|
|
|
?assertMatch(#{{"/", "shrink1"} := {1, ok}}, parse_result(Out2)),
|
2021-06-21 14:43:29 +08:00
|
|
|
%% removing a node can trigger a leader election, give this QQ some time
|
|
|
|
%% to do it
|
2021-06-21 14:39:05 +08:00
|
|
|
timer:sleep(1500),
|
2019-02-19 17:29:38 +08:00
|
|
|
Nodename0 = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-19 17:29:38 +08:00
|
|
|
{ok, Out3} = rabbitmq_queues(Config, 0, ["shrink", Nodename0]),
|
|
|
|
?assertMatch(#{{"/", "shrink1"} := {1, error}}, parse_result(Out3)),
|
|
|
|
ok.
|
|
|
|
|
2019-02-20 20:23:12 +08:00
|
|
|
grow(Config) ->
|
|
|
|
NodeConfig = rabbit_ct_broker_helpers:get_node_config(Config, 2),
|
|
|
|
Nodename2 = ?config(nodename, NodeConfig),
|
|
|
|
Ch = rabbit_ct_client_helpers:open_channel(Config, Nodename2),
|
2021-03-27 00:04:10 +08:00
|
|
|
#'confirm.select_ok'{} = amqp_channel:call(Ch, #'confirm.select'{}),
|
2019-02-20 20:23:12 +08:00
|
|
|
%% declare a quorum queue
|
|
|
|
QName = "grow1",
|
|
|
|
Args = [{<<"x-quorum-initial-group-size">>, long, 1}],
|
|
|
|
#'queue.declare_ok'{} = declare_qq(Ch, QName, Args),
|
|
|
|
Nodename0 = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-20 20:23:12 +08:00
|
|
|
{ok, Out1} = rabbitmq_queues(Config, 0, ["grow", Nodename0, "all"]),
|
|
|
|
?assertMatch(#{{"/", "grow1"} := {2, ok}}, parse_result(Out1)),
|
2021-06-21 14:39:05 +08:00
|
|
|
timer:sleep(500),
|
2019-02-20 20:23:12 +08:00
|
|
|
Nodename1 = rabbit_ct_broker_helpers:get_node_config(Config, 1, nodename),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-20 20:23:12 +08:00
|
|
|
{ok, Out2} = rabbitmq_queues(Config, 0, ["grow", Nodename1, "all"]),
|
|
|
|
?assertMatch(#{{"/", "grow1"} := {3, ok}}, parse_result(Out2)),
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2019-02-20 20:23:12 +08:00
|
|
|
{ok, Out3} = rabbitmq_queues(Config, 0, ["grow", Nodename0, "all"]),
|
|
|
|
?assertNotMatch(#{{"/", "grow1"} := _}, parse_result(Out3)),
|
|
|
|
ok.
|
|
|
|
|
2019-02-21 01:29:29 +08:00
|
|
|
grow_invalid_node_filtered(Config) ->
|
|
|
|
NodeConfig = rabbit_ct_broker_helpers:get_node_config(Config, 2),
|
|
|
|
Nodename2 = ?config(nodename, NodeConfig),
|
|
|
|
Ch = rabbit_ct_client_helpers:open_channel(Config, Nodename2),
|
2021-03-27 00:04:10 +08:00
|
|
|
#'confirm.select_ok'{} = amqp_channel:call(Ch, #'confirm.select'{}),
|
2019-02-21 01:29:29 +08:00
|
|
|
%% declare a quorum queue
|
|
|
|
QName = "grow-err",
|
|
|
|
Args = [{<<"x-quorum-initial-group-size">>, long, 1}],
|
|
|
|
#'queue.declare_ok'{} = declare_qq(Ch, QName, Args),
|
|
|
|
DummyNode = not_really_a_node@nothing,
|
2021-03-27 00:04:10 +08:00
|
|
|
publish_confirm(Ch, QName),
|
2023-05-02 16:59:17 +08:00
|
|
|
%% validated as of rabbitmq-server#8007
|
|
|
|
{error, _ExitCode, _} = rabbitmq_queues(Config, 0, ["grow", DummyNode, "all"]),
|
2019-02-21 01:29:29 +08:00
|
|
|
ok.
|
|
|
|
|
2019-02-19 17:29:38 +08:00
|
|
|
parse_result(S) ->
|
2019-02-20 20:23:12 +08:00
|
|
|
Lines = string:split(S, "\n", all),
|
2019-02-19 17:29:38 +08:00
|
|
|
maps:from_list(
|
|
|
|
[{{Vhost, QName},
|
|
|
|
{erlang:list_to_integer(Size), case Result of
|
|
|
|
"ok" -> ok;
|
|
|
|
_ -> error
|
|
|
|
end}}
|
|
|
|
|| [Vhost, QName, Size, Result] <-
|
|
|
|
[string:split(L, "\t", all) || L <- Lines]]).
|
|
|
|
|
2019-02-20 20:23:12 +08:00
|
|
|
declare_qq(Ch, Q, Args0) ->
|
|
|
|
Args = [{<<"x-queue-type">>, longstr, <<"quorum">>}] ++ Args0,
|
2019-02-19 17:29:38 +08:00
|
|
|
amqp_channel:call(Ch, #'queue.declare'{queue = list_to_binary(Q),
|
|
|
|
durable = true,
|
|
|
|
auto_delete = false,
|
|
|
|
arguments = Args}).
|
2019-02-20 20:23:12 +08:00
|
|
|
declare_qq(Ch, Q) ->
|
|
|
|
declare_qq(Ch, Q, []).
|
|
|
|
|
|
|
|
rabbitmq_queues(Config, N, Args) ->
|
|
|
|
rabbit_ct_broker_helpers:rabbitmq_queues(Config, N, ["--silent" | Args]).
|
2021-03-27 00:04:10 +08:00
|
|
|
|
|
|
|
publish_confirm(Ch, QName) ->
|
|
|
|
ok = amqp_channel:cast(Ch,
|
|
|
|
#'basic.publish'{routing_key = list_to_binary(QName)},
|
|
|
|
#amqp_msg{props = #'P_basic'{delivery_mode = 2},
|
|
|
|
payload = <<"msg">>}),
|
|
|
|
amqp_channel:register_confirm_handler(Ch, self()),
|
2022-10-08 06:59:05 +08:00
|
|
|
ct:pal("waiting for confirms from ~ts", [QName]),
|
2021-03-27 00:04:10 +08:00
|
|
|
receive
|
|
|
|
#'basic.ack'{} ->
|
2022-10-08 06:59:05 +08:00
|
|
|
ct:pal("CONFIRMED! ~ts", [QName]),
|
2021-03-27 00:04:10 +08:00
|
|
|
ok;
|
|
|
|
#'basic.nack'{} ->
|
2022-10-08 06:59:05 +08:00
|
|
|
ct:pal("NOT CONFIRMED! ~ts", [QName]),
|
2021-03-27 00:04:10 +08:00
|
|
|
fail
|
2024-12-12 22:51:59 +08:00
|
|
|
after 30000 ->
|
2021-03-27 00:04:10 +08:00
|
|
|
exit(confirm_timeout)
|
|
|
|
end.
|