From b6dad4c7ee8bd77f80fdc325b3293749ba1cf262 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 21 Sep 2022 13:13:16 +0200 Subject: [PATCH 01/49] WIP verify 1 connection listed (cherry picked from commit f72226525f04d070cf8b30a3bba75eb6182d15d2) (cherry picked from commit 0848b5a5cf577756d09a41db85cb23fbc0675201) --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 64 ++++++++++++++++---- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index eea21e338960..615b6e19b464 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -10,40 +10,49 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). --include_lib("amqp_client/include/amqp_client.hrl"). -include("rabbit_amqp1_0.hrl"). -define(COMMAND, 'Elixir.RabbitMQ.CLI.Ctl.Commands.ListAmqp10ConnectionsCommand'). all() -> [ - {group, non_parallel_tests} + {group, non_parallel_tests} ]. groups() -> [ {non_parallel_tests, [], [ merge_defaults, - validate + validate, + when_no_connections, + when_one_connection ]} ]. init_per_suite(Config) -> - Config1 = rabbit_ct_helpers:set_config(Config, - [{rmq_nodename_suffix, ?MODULE}]), + application:ensure_all_started(amqp10_client), rabbit_ct_helpers:log_environment(), - rabbit_ct_helpers:run_setup_steps(Config1, - rabbit_ct_broker_helpers:setup_steps()). + Config. end_per_suite(Config) -> - rabbit_ct_helpers:run_teardown_steps(Config, - rabbit_ct_broker_helpers:teardown_steps()). - -init_per_group(_, Config) -> Config. +init_per_group(Group, Config) -> + Suffix = rabbit_ct_helpers:testcase_absname(Config, "", "-"), + Config1 = rabbit_ct_helpers:set_config( + Config, [ + {rmq_nodename_suffix, Suffix}, + {amqp10_client_library, Group} + ]), + rabbit_ct_helpers:run_setup_steps( + Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + end_per_group(_, Config) -> - Config. + rabbit_ct_helpers:run_teardown_steps(Config, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()). init_per_testcase(Testcase, Config) -> rabbit_ct_helpers:testcase_started(Config, Testcase). @@ -67,3 +76,34 @@ validate(_Config) -> ok = ?COMMAND:validate([atom_to_binary(K, utf8) || K <- ?INFO_ITEMS], #{}), {validation_failure,{bad_info_key,[other]}} = ?COMMAND:validate([<<"other">>], #{}). + +println(What, Value) -> io:format("~p : ~p~n", [What, Value]). + +when_no_connections(_Config) -> + [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), + Opts = #{node => A, timeout => 2000, verbose => true}, + [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)). + +when_one_connection(_Config) -> + [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), + Opts = #{node => A, timeout => 2000, verbose => true}, + + Connection = open_client_connection(_Config), + List = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + println("connections", List), + close_client_connection(Connection). + +open_client_connection(_Config) -> + Host = ?config(rmq_hostname, _Config), + Port = rabbit_ct_broker_helpers:get_node_config(_Config, 0, tcp_port_amqp), + % create a configuration map + OpnConf = #{address => Host, + port => Port, + container_id => atom_to_binary(?FUNCTION_NAME, utf8), + sasl => {plain, <<"guest">>, <<"guest">>}}, + {ok, Connection} = amqp10_client:open_connection(OpnConf), + {ok, _} = amqp10_client:begin_session(Connection), + Connection. + +close_client_connection(Connection) -> + ok = amqp10_client:close_connection(Connection). From bf5f5a62624e9703bfc702bc96b7bf73654d44fb Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 21 Sep 2022 14:26:11 +0200 Subject: [PATCH 02/49] Add failing test that list a single connection (cherry picked from commit 1bb5f27ec272d77b1978d266005f4b0c1fb86397) (cherry picked from commit 22097471fec0dd5854fdebf455a63d14342b7322) --- deps/rabbitmq_amqp1_0/BUILD.bazel | 3 +++ deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/BUILD.bazel b/deps/rabbitmq_amqp1_0/BUILD.bazel index 5d0b2b2f5894..9744679c82c6 100644 --- a/deps/rabbitmq_amqp1_0/BUILD.bazel +++ b/deps/rabbitmq_amqp1_0/BUILD.bazel @@ -83,6 +83,9 @@ suites = [ deps = [ "//deps/amqp10_common:erlang_app", ], + runtime_deps = [ + "//deps/amqp10_client:erlang_app", + ], ), rabbitmq_integration_suite( PACKAGE, diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 615b6e19b464..815feec2bcbd 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -89,8 +89,8 @@ when_one_connection(_Config) -> Opts = #{node => A, timeout => 2000, verbose => true}, Connection = open_client_connection(_Config), - List = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - println("connections", List), + [ExpectedConnection|_] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + println("connection", ExpectedConnection), close_client_connection(Connection). open_client_connection(_Config) -> From 724b7a01d91696a49ea46ec38cb8e9d918a5c1cd Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 22 Sep 2022 09:56:12 +0200 Subject: [PATCH 03/49] Test listing 091 connections (cherry picked from commit 5510a656bf3076cfaf6474eac8444427b1c577fa) (cherry picked from commit c4dc7931702ea4bbd3a0aab0041c6a4cc02da3b1) --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 45 +++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 815feec2bcbd..81c88288a762 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -11,6 +11,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -include("rabbit_amqp1_0.hrl"). +-include_lib("amqp_client/include/amqp_client.hrl"). -define(COMMAND, 'Elixir.RabbitMQ.CLI.Ctl.Commands.ListAmqp10ConnectionsCommand'). @@ -25,7 +26,8 @@ groups() -> merge_defaults, validate, when_no_connections, - when_one_connection + when_one_connection, + when_one_amqp091_connection ]} ]. @@ -88,12 +90,43 @@ when_one_connection(_Config) -> [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), Opts = #{node => A, timeout => 2000, verbose => true}, - Connection = open_client_connection(_Config), - [ExpectedConnection|_] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + Connection = open_amqp10_connection(_Config), + [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), println("connection", ExpectedConnection), - close_client_connection(Connection). + close_amqp10_connection(Connection). -open_client_connection(_Config) -> +when_one_amqp091_connection(_Config) -> + [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), + Opts = #{node => A, timeout => 2000}, + + Connection = open_amqp091_client_connection(_Config), + println("amqp connection", Connection), + [ Listed ] = rabbitmqctl_list_connections(_Config, A), + println("listed connection:", Listed), + close_amqp091_client_connection(Connection). + +rabbitmqctl_list_connections(Config, Node) -> + {ok, StdOut} = rabbit_ct_broker_helpers:rabbitmqctl(Config, Node, + ["list_connections", "--no-table-headers"]), + [<<"Listing connections", _/binary>> | Rows] = re:split(StdOut, <<"\n">>, [trim]), + Rows. + +open_amqp091_client_connection(_Config) -> + ConnName = <<"Custom Name">>, + Host = ?config(rmq_hostname, _Config), + Port = rabbit_ct_broker_helpers:get_node_config(_Config, 0, tcp_port_amqp), + AmqpParams = #amqp_params_network{port = Port, + host = Host, + virtual_host = <<"/">> + }, + + {ok, Connection} = amqp_connection:start(AmqpParams, ConnName), + Connection. + +close_amqp091_client_connection(Connection) -> + ?assertEqual(ok, amqp_connection:close(Connection)). + +open_amqp10_connection(_Config) -> Host = ?config(rmq_hostname, _Config), Port = rabbit_ct_broker_helpers:get_node_config(_Config, 0, tcp_port_amqp), % create a configuration map @@ -105,5 +138,5 @@ open_client_connection(_Config) -> {ok, _} = amqp10_client:begin_session(Connection), Connection. -close_client_connection(Connection) -> +close_amqp10_connection(Connection) -> ok = amqp10_client:close_connection(Connection). From dc88d82d210776ce225e162711e11e7316dbca66 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 22 Sep 2022 10:01:21 +0200 Subject: [PATCH 04/49] Add failing test (cherry picked from commit 1638b1b407bc00ee388040a91d73327a210382d5) (cherry picked from commit f97b09a1a20f22d3c65f9dae60bec81254a08605) --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 81c88288a762..0691c8041403 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -91,8 +91,9 @@ when_one_connection(_Config) -> Opts = #{node => A, timeout => 2000, verbose => true}, Connection = open_amqp10_connection(_Config), - [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - println("connection", ExpectedConnection), + %%[ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + [ Listed ] = rabbitmqctl_list_connections(_Config, A), + println("connectionS", Listed), close_amqp10_connection(Connection). when_one_amqp091_connection(_Config) -> From 8e99efc935e4df9c5cfd4001d2ab2dc95fdedc4d Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 22 Sep 2022 13:41:43 +0200 Subject: [PATCH 05/49] Verified amqp 1.0 conn are tracked in ETS, but not returned by rabbitmqctl (cherry picked from commit e3f486e0403f2e3b49388035454d782d902f9b5f) (cherry picked from commit 4bfeec497a6a986a75c27c811982b00f8e71d28c) --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 0691c8041403..4beb63a4e430 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -91,9 +91,12 @@ when_one_connection(_Config) -> Opts = #{node => A, timeout => 2000, verbose => true}, Connection = open_amqp10_connection(_Config), - %%[ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - [ Listed ] = rabbitmqctl_list_connections(_Config, A), - println("connectionS", Listed), + + [{tracked_connection, _, _, _, _, _, {'AMQP',"1.0"}, _, _, _, _, _}] = + rabbit_ct_broker_helpers:rpc(_Config, A, + rabbit_connection_tracking, list, []), + + [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), close_amqp10_connection(Connection). when_one_amqp091_connection(_Config) -> From 4ee0240dfac7626d81d9e5aabfa5181d956df631 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Thu, 22 Sep 2022 18:23:39 +0200 Subject: [PATCH 06/49] WIP reader process was under different supervisor Maybe to fix this issue we can look up the process in ETC done by rabbit_connection_tracker module. At the moment, this is one reader process but when we query its info, the process crashes calling exactly the function which resolves user item info. crasher: initial call: rabbit_reader:init/3 pid: <0.769.0> exception error: no function clause matching rabbit_amqp1_0_reader:info_internal(user, (cherry picked from commit f48e013e66fc71e85a1d7b381ca1966c9f8453c9) (cherry picked from commit 1e168ccb0fdd72e28d6f446ad94a3e72324c2511) --- deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0.erl | 6 ++- .../src/rabbit_amqp1_0_reader.erl | 1 + deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 39 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0.erl index a7ea20d46661..f4140b9daf4d 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0.erl @@ -33,8 +33,10 @@ connection_info_local(Items) -> list() -> [ReaderPid || {_, TcpPid, _, [tcp_listener_sup]} <- supervisor:which_children(rabbit_sup), - {_, RanchLPid, _, [ranch_listener_sup]} <- supervisor:which_children(TcpPid), - {_, RanchCPid, _, [ranch_conns_sup]} <- supervisor:which_children(RanchLPid), + {_, RanchEPid, _, [ranch_embedded_sup]} <- supervisor:which_children(TcpPid), + {_, RanchLPid, _, [ranch_listener_sup]} <- supervisor:which_children(RanchEPid), + {_, RanchCSPid, _, [ranch_conns_sup_sup]} <- supervisor:which_children(RanchLPid), + {_, RanchCPid, _, [ranch_conns_sup]} <- supervisor:which_children(RanchCSPid), {rabbit_connection_sup, ConnPid, _, _} <- supervisor:which_children(RanchCPid), {reader, ReaderPid, _, _} <- supervisor:which_children(ConnPid) ]. diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl index a77e8e3ba7b7..a6be9d2954fd 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl @@ -187,6 +187,7 @@ handle_other({bump_credit, Msg}, State) -> handle_other(terminate_connection, State) -> State; handle_other({info, InfoItems, Pid}, State) -> + logger:info("Reader info: State: ~p pid ~p infoitems: ~p ", [State, Pid, InfoItems]), Infos = lists:map( fun(InfoItem) -> {InfoItem, info_internal(InfoItem, State)} diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 4beb63a4e430..974f24cbed97 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -96,6 +96,45 @@ when_one_connection(_Config) -> rabbit_ct_broker_helpers:rpc(_Config, A, rabbit_connection_tracking, list, []), + [P1, P2] = [P + || {_, P, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children, [rabbit_sup])], + println("Pid1", P1), + println("Pid2", P2), + + Children1 = rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[P1]), + println("tcp_listener_sup1", Children1), + Children2 = rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[P2]), + println("tcp_listener_sup2", Children2), + + [Res1, Res2] = [RanchSupPid + || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), + {_, RanchSupPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]) + ], + println("ranch_embedded_sup 1", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Res1])), + println("ranch_embedded_sup 2", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Res2])), + + [Rl1, Rl2] = [RanchLPid + || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), + {_, RanchEPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]), + {_, RanchLPid, _, [ranch_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchEPid]) + ], + println("ranch_listener_sup", [Rl1, Rl2]), + println("ranch_listener_sup 1", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Rl1])), + println("ranch_listener_sup 2", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Rl2])), + + ReaderPids = [ReaderPid + || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), + {_, RanchEPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]), + {_, RanchLPid, _, [ranch_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchEPid]), + {_, RanchSPid, _, [ranch_conns_sup_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchLPid]), + {_, RanchCPid, _, [ranch_conns_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchSPid]), + {rabbit_connection_sup, ConnPid, _, _} <- supervisor:which_children(RanchCPid), + {reader, ReaderPid, _, _} <- supervisor:which_children(ConnPid) + ], + println("ReaderPid", ReaderPids), + ReaderInfos = [rabbit_ct_broker_helpers:rpc(_Config, A, rabbit_amqp1_0_reader, info, [Pid, [node,user]]) || Pid <- ReaderPids], + println("ReaderPid info",ReaderInfos), + [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), close_amqp10_connection(Connection). From 562b3e0b50cde34ae6450232e62a4765f5b01a78 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Mon, 26 Sep 2022 14:38:14 +0200 Subject: [PATCH 07/49] Fix issue listing amqp 1.0 connections The issue was related to the supervisor hierarchy we used to search for the reader process (cherry picked from commit abdee763d59ac0690a7bccde0c1fe3deab329c69) (cherry picked from commit 14fc25a3861a5b31e7a54ecd540d42334412991a) --- .../src/rabbit_amqp1_0_reader.erl | 11 +- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 131 ++++++++++-------- .../test/system_SUITE_data/console/Program.cs | 44 ++++++ .../test/system_SUITE_data/console/README.md | 11 ++ .../console/standalone.csproj | 13 ++ 5 files changed, 149 insertions(+), 61 deletions(-) create mode 100644 deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/Program.cs create mode 100644 deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/README.md create mode 100644 deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/standalone.csproj diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl index a6be9d2954fd..9f85c64552ef 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl @@ -750,6 +750,9 @@ info(Pid, InfoItems) -> UnknownItems -> throw({bad_argument, UnknownItems}) end. +info_internal(pid, #v1{}) -> self(); +info_internal(connection, #v1{connection = Val}) -> + Val; info_internal(node, #v1{}) -> node(); info_internal(auth_mechanism, #v1{connection = #v1_connection{auth_mechanism = none}}) -> none; @@ -764,11 +767,11 @@ info_internal(frame_max, #v1{connection = #v1_connection{frame_max = Val}}) -> info_internal(timeout, #v1{connection = #v1_connection{timeout_sec = Val}}) -> Val; info_internal(user, - #v1{connection = #v1_connection{user = #user{username = none}}}) -> - ''; -info_internal(username, - #v1{connection = #v1_connection{user = #user{username = Val}}}) -> + #v1{connection = #v1_connection{user = {user, Val, _, _}}}) -> Val; +info_internal(user, + #v1{connection = #v1_connection{user = none}}) -> + ''; info_internal(state, #v1{connection_state = Val}) -> Val; info_internal(SockStat, S) when SockStat =:= recv_oct; diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 974f24cbed97..4ffac6ac14fa 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -90,53 +90,15 @@ when_one_connection(_Config) -> [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), Opts = #{node => A, timeout => 2000, verbose => true}, - Connection = open_amqp10_connection(_Config), + [Connection,Sender] = open_amqp10_connection(_Config), - [{tracked_connection, _, _, _, _, _, {'AMQP',"1.0"}, _, _, _, _, _}] = + TrackedConnections = rabbit_ct_broker_helpers:rpc(_Config, A, rabbit_connection_tracking, list, []), + println("tracked connections", TrackedConnections), - [P1, P2] = [P - || {_, P, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children, [rabbit_sup])], - println("Pid1", P1), - println("Pid2", P2), - - Children1 = rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[P1]), - println("tcp_listener_sup1", Children1), - Children2 = rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[P2]), - println("tcp_listener_sup2", Children2), - - [Res1, Res2] = [RanchSupPid - || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), - {_, RanchSupPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]) - ], - println("ranch_embedded_sup 1", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Res1])), - println("ranch_embedded_sup 2", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Res2])), - - [Rl1, Rl2] = [RanchLPid - || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), - {_, RanchEPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]), - {_, RanchLPid, _, [ranch_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchEPid]) - ], - println("ranch_listener_sup", [Rl1, Rl2]), - println("ranch_listener_sup 1", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Rl1])), - println("ranch_listener_sup 2", rabbit_ct_broker_helpers:rpc(_Config, A, supervisor,which_children,[Rl2])), - - ReaderPids = [ReaderPid - || {_, TcpPid, _, [tcp_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [rabbit_sup]), - {_, RanchEPid, _, [ranch_embedded_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [TcpPid]), - {_, RanchLPid, _, [ranch_listener_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchEPid]), - {_, RanchSPid, _, [ranch_conns_sup_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchLPid]), - {_, RanchCPid, _, [ranch_conns_sup]} <- rabbit_ct_broker_helpers:rpc(_Config, A, supervisor, which_children, [RanchSPid]), - {rabbit_connection_sup, ConnPid, _, _} <- supervisor:which_children(RanchCPid), - {reader, ReaderPid, _, _} <- supervisor:which_children(ConnPid) - ], - println("ReaderPid", ReaderPids), - ReaderInfos = [rabbit_ct_broker_helpers:rpc(_Config, A, rabbit_amqp1_0_reader, info, [Pid, [node,user]]) || Pid <- ReaderPids], - println("ReaderPid info",ReaderInfos), - - [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - close_amqp10_connection(Connection). + println("list_amqp10", 'Elixir.Enum':to_list(?COMMAND:run([], Opts))), + close_amqp10_connection(Connection, Sender). when_one_amqp091_connection(_Config) -> [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), @@ -169,17 +131,72 @@ open_amqp091_client_connection(_Config) -> close_amqp091_client_connection(Connection) -> ?assertEqual(ok, amqp_connection:close(Connection)). -open_amqp10_connection(_Config) -> - Host = ?config(rmq_hostname, _Config), - Port = rabbit_ct_broker_helpers:get_node_config(_Config, 0, tcp_port_amqp), - % create a configuration map - OpnConf = #{address => Host, - port => Port, - container_id => atom_to_binary(?FUNCTION_NAME, utf8), - sasl => {plain, <<"guest">>, <<"guest">>}}, - {ok, Connection} = amqp10_client:open_connection(OpnConf), - {ok, _} = amqp10_client:begin_session(Connection), - Connection. - -close_amqp10_connection(Connection) -> - ok = amqp10_client:close_connection(Connection). +open_amqp10_connection(Config) -> + Host = ?config(rmq_hostname, Config), + Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp), + QName = atom_to_binary(?FUNCTION_NAME, utf8), + Address = <<"/amq/queue/", QName/binary>>, + %% declare a quorum queue + Ch = rabbit_ct_client_helpers:open_channel(Config, 0), + amqp_channel:call(Ch, #'queue.declare'{queue = QName, + durable = true, + arguments = [{<<"x-queue-type">>, longstr, <<"quorum">>}]}), + + % create a configuration map + OpnConf = #{address => Host, + port => Port, + container_id => atom_to_binary(?FUNCTION_NAME, utf8), + sasl => {plain, <<"guest">>, <<"guest">>}}, + + % ct:pal("opening connectoin with ~p", [OpnConf]), + {ok, Connection} = amqp10_client:open_connection(OpnConf), + {ok, Session} = amqp10_client:begin_session(Connection), + SenderLinkName = <<"test-sender">>, + {ok, Sender} = amqp10_client:attach_sender_link(Session, + SenderLinkName, + Address), + + % wait for credit to be received + receive + {amqp10_event, {link, Sender, credited}} -> ok + after 2000 -> + exit(credited_timeout) + end, + + OutMsg = amqp10_msg:new(<<"my-tag">>, <<"my-body">>, true), + ok = amqp10_client:send_msg(Sender, OutMsg), + + flush("pre-receive"), + {ok, Receiver} = amqp10_client:attach_receiver_link(Session, + <<"test-receiver">>, + Address), + + % grant credit and drain + ok = amqp10_client:flow_link_credit(Receiver, 1, never, true), + + % wait for a delivery + receive + {amqp10_msg, Receiver, _InMsg} -> println("Received amqp 1.0 message",_InMsg ), ok + after 2000 -> + exit(delivery_timeout) + end, + + + + [Connection, Sender]. + +flush(Prefix) -> + receive + Msg -> + ct:pal("~s flushed: ~w~n", [Prefix, Msg]), + flush(Prefix) + after 1 -> + ok + end. + +close_amqp10_connection(Connection, Sender) -> + flush("final"), + println("Closing connection", Connection), + ok = amqp10_client:detach_link(Sender), + ok = amqp10_client:close_connection(Connection), + ok. diff --git a/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/Program.cs b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/Program.cs new file mode 100644 index 000000000000..a4c69b3d7c3a --- /dev/null +++ b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/Program.cs @@ -0,0 +1,44 @@ +using Amqp; +using Amqp.Framing; + +// See https://aka.ms/new-console-template for more information +Console.WriteLine("Sending 10 messages to amqp10-queue. Press a button to terminate"); + +// Create the AMQP connection string +var connectionString = $"amqp://guest:guest@localhost:5672/%2F"; + +// Create the AMQP connection +var connection = new Connection(new Address(connectionString)); + +// Create the AMQP session +var amqpSession = new Session(connection); + + // Give a name to the sender +var senderSubscriptionId = "rabbitmq.amqp.sender"; + +// Name of the topic you will be sending messages (Name of the Queue) +var topic = "amqp10-queue"; + +// Create the AMQP sender +var sender = new SenderLink(amqpSession, senderSubscriptionId, topic); + +for (var i = 0; i < 10; i++) +{ + // Create message + var message = new Message($"Received message {i}"); + + // Add a meesage id + message.Properties = new Properties() { MessageId = Guid.NewGuid().ToString() }; + + // Add some message properties + message.ApplicationProperties = new ApplicationProperties(); + message.ApplicationProperties["Message.Type.FullName"] = typeof(string).FullName; + + // Send message + sender.Send(message); + + Task.Delay(2000).Wait(); +} + + // Wait for a key to close the program +Console.Read(); diff --git a/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/README.md b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/README.md new file mode 100644 index 000000000000..ae3164c970c9 --- /dev/null +++ b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/README.md @@ -0,0 +1,11 @@ +# Console application to test AMQP 1.0 + +This is a basic .NetCore console application which uses *AMQP 1.0* .Net **AMQPNetLite** client library. + +Usage: +``` +dotnet run +``` + +It sends 10 messages and it waits for key-stroke to terminate which is very convenient +when we need to create AMQP 1.0 connections. diff --git a/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/standalone.csproj b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/standalone.csproj new file mode 100644 index 000000000000..2341b149952f --- /dev/null +++ b/deps/rabbitmq_amqp1_0/test/system_SUITE_data/console/standalone.csproj @@ -0,0 +1,13 @@ + + + + Exe + net6.0 + enable + enable + + + + + + From fad7e9fa3a9624bf9ad951973d323e41c6d073e7 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Mon, 26 Sep 2022 14:54:21 +0200 Subject: [PATCH 08/49] Refactor test that verifies one amqp 1.0 conn (cherry picked from commit 22ac4b873ba40520b9ed74f22a607913eb0196b4) (cherry picked from commit 342044d04d5e9140a8d3757ff60c5a463c6ce05a) --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 4ffac6ac14fa..2f99c390deaa 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -91,13 +91,8 @@ when_one_connection(_Config) -> Opts = #{node => A, timeout => 2000, verbose => true}, [Connection,Sender] = open_amqp10_connection(_Config), - - TrackedConnections = - rabbit_ct_broker_helpers:rpc(_Config, A, - rabbit_connection_tracking, list, []), - println("tracked connections", TrackedConnections), - - println("list_amqp10", 'Elixir.Enum':to_list(?COMMAND:run([], Opts))), + + [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), close_amqp10_connection(Connection, Sender). when_one_amqp091_connection(_Config) -> From dc851d8a59ed010000adecb880b340e36a9825c0 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Mon, 26 Sep 2022 16:37:03 +0200 Subject: [PATCH 09/49] Remove unnecessary test (cherry picked from commit e38b3dc0e60bf8765d172682921e2e0b18d0da6c) (cherry picked from commit c7a8837a67c2a90a03a2b068c51fe78ed8821ba8) --- .../src/rabbit_amqp1_0_reader.erl | 2 +- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 40 ++----------------- 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl index 9f85c64552ef..06c7db3e14bf 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl @@ -187,7 +187,7 @@ handle_other({bump_credit, Msg}, State) -> handle_other(terminate_connection, State) -> State; handle_other({info, InfoItems, Pid}, State) -> - logger:info("Reader info: State: ~p pid ~p infoitems: ~p ", [State, Pid, InfoItems]), + %logger:info("Reader info: State: ~p pid ~p infoitems: ~p ", [State, Pid, InfoItems]), Infos = lists:map( fun(InfoItem) -> {InfoItem, info_internal(InfoItem, State)} diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 2f99c390deaa..589baea7c510 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -26,9 +26,8 @@ groups() -> merge_defaults, validate, when_no_connections, - when_one_connection, - when_one_amqp091_connection - ]} + when_one_connection + ]} ]. init_per_suite(Config) -> @@ -91,40 +90,9 @@ when_one_connection(_Config) -> Opts = #{node => A, timeout => 2000, verbose => true}, [Connection,Sender] = open_amqp10_connection(_Config), - - [ExpectedConnection] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - close_amqp10_connection(Connection, Sender). -when_one_amqp091_connection(_Config) -> - [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), - Opts = #{node => A, timeout => 2000}, - - Connection = open_amqp091_client_connection(_Config), - println("amqp connection", Connection), - [ Listed ] = rabbitmqctl_list_connections(_Config, A), - println("listed connection:", Listed), - close_amqp091_client_connection(Connection). - -rabbitmqctl_list_connections(Config, Node) -> - {ok, StdOut} = rabbit_ct_broker_helpers:rabbitmqctl(Config, Node, - ["list_connections", "--no-table-headers"]), - [<<"Listing connections", _/binary>> | Rows] = re:split(StdOut, <<"\n">>, [trim]), - Rows. - -open_amqp091_client_connection(_Config) -> - ConnName = <<"Custom Name">>, - Host = ?config(rmq_hostname, _Config), - Port = rabbit_ct_broker_helpers:get_node_config(_Config, 0, tcp_port_amqp), - AmqpParams = #amqp_params_network{port = Port, - host = Host, - virtual_host = <<"/">> - }, - - {ok, Connection} = amqp_connection:start(AmqpParams, ConnName), - Connection. - -close_amqp091_client_connection(Connection) -> - ?assertEqual(ok, amqp_connection:close(Connection)). + [_] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + close_amqp10_connection(Connection, Sender). open_amqp10_connection(Config) -> Host = ?config(rmq_hostname, Config), From b1fe76ee8715214ab33cbbaa9a99b3b80bd35f24 Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Tue, 27 Sep 2022 14:54:07 +0200 Subject: [PATCH 10/49] Clean up code and use ct:pal over println (cherry picked from commit 78f4aaf205eb8e97994c54279f0e20322b3470a5) (cherry picked from commit 87d4f0fae88f88cb5e4d3c0fe50d75495281b1c0) --- deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl | 1 - deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl index 06c7db3e14bf..5a33e99b9f45 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl @@ -187,7 +187,6 @@ handle_other({bump_credit, Msg}, State) -> handle_other(terminate_connection, State) -> State; handle_other({info, InfoItems, Pid}, State) -> - %logger:info("Reader info: State: ~p pid ~p infoitems: ~p ", [State, Pid, InfoItems]), Infos = lists:map( fun(InfoItem) -> {InfoItem, info_internal(InfoItem, State)} diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 589baea7c510..6cccf427f90d 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -17,7 +17,7 @@ all() -> [ - {group, non_parallel_tests} + {group, non_parallel_tests} ]. groups() -> @@ -78,8 +78,6 @@ validate(_Config) -> {validation_failure,{bad_info_key,[other]}} = ?COMMAND:validate([<<"other">>], #{}). -println(What, Value) -> io:format("~p : ~p~n", [What, Value]). - when_no_connections(_Config) -> [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), Opts = #{node => A, timeout => 2000, verbose => true}, @@ -139,7 +137,7 @@ open_amqp10_connection(Config) -> % wait for a delivery receive - {amqp10_msg, Receiver, _InMsg} -> println("Received amqp 1.0 message",_InMsg ), ok + {amqp10_msg, Receiver, _InMsg} -> ct:pal("Received amqp 1.0 message : ~w~n", [_InMsg]), ok after 2000 -> exit(delivery_timeout) end, @@ -159,7 +157,7 @@ flush(Prefix) -> close_amqp10_connection(Connection, Sender) -> flush("final"), - println("Closing connection", Connection), + ct:pal("Closing connection ~w~n", [Connection]), ok = amqp10_client:detach_link(Sender), ok = amqp10_client:close_connection(Connection), ok. From a60ff45d9ffb057a9ed0823d392685b3bcea459f Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Wed, 28 Sep 2022 10:40:49 +0200 Subject: [PATCH 11/49] Use correct expr. to extract field from record (cherry picked from commit e23cb9e468282fb34f94a5a6313eaabd4f88bf47) (cherry picked from commit 58909873f06c312a6bbac867c318de9933d7e5df) --- deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl index 5a33e99b9f45..d1fdb1c60325 100644 --- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl +++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_reader.erl @@ -766,7 +766,7 @@ info_internal(frame_max, #v1{connection = #v1_connection{frame_max = Val}}) -> info_internal(timeout, #v1{connection = #v1_connection{timeout_sec = Val}}) -> Val; info_internal(user, - #v1{connection = #v1_connection{user = {user, Val, _, _}}}) -> + #v1{connection = #v1_connection{user = #user{username = Val}}}) -> Val; info_internal(user, #v1{connection = #v1_connection{user = none}}) -> From 19763feb908b562de44642daff9825050a3800cf Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 2 Oct 2022 13:58:53 +0400 Subject: [PATCH 12/49] Skip one AMQP 1.0/QQ test in mixed version mode --- deps/rabbitmq_amqp1_0/test/command_SUITE.erl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl index 6cccf427f90d..b740da664283 100644 --- a/deps/rabbitmq_amqp1_0/test/command_SUITE.erl +++ b/deps/rabbitmq_amqp1_0/test/command_SUITE.erl @@ -84,13 +84,18 @@ when_no_connections(_Config) -> [] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)). when_one_connection(_Config) -> - [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), - Opts = #{node => A, timeout => 2000, verbose => true}, + case rabbit_ct_helpers:is_mixed_versions() of + false -> + [A] = rabbit_ct_broker_helpers:get_node_configs(_Config, nodename), + Opts = #{node => A, timeout => 2000, verbose => true}, - [Connection,Sender] = open_amqp10_connection(_Config), + [Connection,Sender] = open_amqp10_connection(_Config), - [_] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), - close_amqp10_connection(Connection, Sender). + [_] = 'Elixir.Enum':to_list(?COMMAND:run([], Opts)), + close_amqp10_connection(Connection, Sender); + true -> + {skip, "stream tests are skipped in mixed mode"} + end. open_amqp10_connection(Config) -> Host = ?config(rmq_hostname, Config), From 1c3704ebf2f08c905c92da09e0ed5cca3b98d1a2 Mon Sep 17 00:00:00 2001 From: Sascha Bleidner Date: Thu, 29 Sep 2022 09:36:56 +0200 Subject: [PATCH 13/49] Add option for wildcard certificates to docs Matching wildcard certificates with the auth_backend_http plugin requires an additional option. See: https://erlang.org/pipermail/erlang-questions/2019-October/098529.html (cherry picked from commit cfa0d4d9aa87e7458e64bd9de4206a8f11424317) (cherry picked from commit 4911ab4a830509a6ebf6dbfb7bb9d07c38259e38) --- deps/rabbitmq_auth_backend_http/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deps/rabbitmq_auth_backend_http/README.md b/deps/rabbitmq_auth_backend_http/README.md index 651e32d7d6bb..53922fa2d59a 100644 --- a/deps/rabbitmq_auth_backend_http/README.md +++ b/deps/rabbitmq_auth_backend_http/README.md @@ -149,6 +149,11 @@ configure the plugin to use a CA and client certificate/key pair using the `rabb It is recommended to use TLS for authentication and enable peer verification. +### Wildcard Certificates + +If the certificate of your Web Server should be matched against a wildcard certificate in your `cacertfile`, the following option must be added to the `ssl_options`: + + {customize_hostname_check, [{match_fun,public_key:pkix_verify_hostname_match_fun(https)}]} ## Debugging From 7fb64ca84e953739d4c8e90f6f67d6cca00adb51 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Thu, 29 Sep 2022 08:22:43 -0700 Subject: [PATCH 14/49] Update branch names and links Fix publish of libs to hex.pm @lhoguin noticed that the hex packages for the amqp_client, amqp10_client and related project do not currently work with erlang.mk. This PR fixes this issue. Tested using this project: https://github.com/lukebakken/amqp-clients-test.git (cherry picked from commit 553aab51c95e22ed7e5611008a688c5de0eacecb) (cherry picked from commit 4f19b70a9b7b347c25059497bc841d595b07d532) --- deps/amqp10_client/Makefile | 7 ++++--- deps/amqp10_client/erlang.mk | 1 + deps/amqp10_client/rabbitmq-components.mk | 1 + deps/amqp10_common/Makefile | 7 ++++--- deps/amqp10_common/erlang.mk | 1 + deps/amqp10_common/rabbitmq-components.mk | 1 + deps/amqp_client/Makefile | 7 ++++--- deps/amqp_client/erlang.mk | 1 + deps/amqp_client/rabbitmq-components.mk | 1 + deps/rabbit_common/Makefile | 18 +++++++++++++----- deps/rabbit_common/erlang.mk | 1 + deps/rabbit_common/rabbitmq-components.mk | 1 + deps/rabbitmq_auth_backend_cache/README.md | 2 +- deps/rabbitmq_peer_discovery_k8s/README.md | 2 +- .../examples/gke/README.md | 4 +--- .../examples/kind/README.md | 8 ++++++-- .../examples/minikube/README.md | 8 ++++++-- 17 files changed, 48 insertions(+), 23 deletions(-) create mode 120000 deps/amqp10_client/erlang.mk create mode 120000 deps/amqp10_client/rabbitmq-components.mk create mode 120000 deps/amqp10_common/erlang.mk create mode 120000 deps/amqp10_common/rabbitmq-components.mk create mode 120000 deps/amqp_client/erlang.mk create mode 120000 deps/amqp_client/rabbitmq-components.mk create mode 120000 deps/rabbit_common/erlang.mk create mode 120000 deps/rabbit_common/rabbitmq-components.mk diff --git a/deps/amqp10_client/Makefile b/deps/amqp10_client/Makefile index a0d3d2dc2d43..560d96b415a3 100644 --- a/deps/amqp10_client/Makefile +++ b/deps/amqp10_client/Makefile @@ -45,10 +45,11 @@ DEP_PLUGINS = rabbit_common/mk/rabbitmq-macros.mk \ DEP_PLUGINS += elvis_mk dep_elvis_mk = git https://github.com/inaka/elvis.mk.git master -include ../../rabbitmq-components.mk -include ../../erlang.mk +include rabbitmq-components.mk +include erlang.mk -HEX_TARBALL_FILES += $(DEPS_DIR)/../rabbitmq-components.mk +HEX_TARBALL_FILES += rabbitmq-components.mk \ + git-revisions.txt # -------------------------------------------------------------------- # Compiler flags. diff --git a/deps/amqp10_client/erlang.mk b/deps/amqp10_client/erlang.mk new file mode 120000 index 000000000000..59af4a527a9d --- /dev/null +++ b/deps/amqp10_client/erlang.mk @@ -0,0 +1 @@ +../../erlang.mk \ No newline at end of file diff --git a/deps/amqp10_client/rabbitmq-components.mk b/deps/amqp10_client/rabbitmq-components.mk new file mode 120000 index 000000000000..43c0d3567154 --- /dev/null +++ b/deps/amqp10_client/rabbitmq-components.mk @@ -0,0 +1 @@ +../../rabbitmq-components.mk \ No newline at end of file diff --git a/deps/amqp10_common/Makefile b/deps/amqp10_common/Makefile index 9be169537223..ebf41ef29d23 100644 --- a/deps/amqp10_common/Makefile +++ b/deps/amqp10_common/Makefile @@ -44,9 +44,10 @@ DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk \ rabbit_common/mk/rabbitmq-test.mk \ rabbit_common/mk/rabbitmq-tools.mk -include ../../rabbitmq-components.mk -include ../../erlang.mk +include rabbitmq-components.mk +include erlang.mk -HEX_TARBALL_FILES += $(DEPS_DIR)/../rabbitmq-components.mk +HEX_TARBALL_FILES += rabbitmq-components.mk \ + git-revisions.txt -include development.post.mk diff --git a/deps/amqp10_common/erlang.mk b/deps/amqp10_common/erlang.mk new file mode 120000 index 000000000000..59af4a527a9d --- /dev/null +++ b/deps/amqp10_common/erlang.mk @@ -0,0 +1 @@ +../../erlang.mk \ No newline at end of file diff --git a/deps/amqp10_common/rabbitmq-components.mk b/deps/amqp10_common/rabbitmq-components.mk new file mode 120000 index 000000000000..43c0d3567154 --- /dev/null +++ b/deps/amqp10_common/rabbitmq-components.mk @@ -0,0 +1 @@ +../../rabbitmq-components.mk \ No newline at end of file diff --git a/deps/amqp_client/Makefile b/deps/amqp_client/Makefile index 7a5f11e4e2de..07f4c758a2fd 100644 --- a/deps/amqp_client/Makefile +++ b/deps/amqp_client/Makefile @@ -53,7 +53,8 @@ DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk \ PLT_APPS = ssl public_key -include ../../rabbitmq-components.mk -include ../../erlang.mk +include rabbitmq-components.mk +include erlang.mk -HEX_TARBALL_FILES += $(DEPS_DIR)/../rabbitmq-components.mk +HEX_TARBALL_FILES += rabbitmq-components.mk \ + git-revisions.txt diff --git a/deps/amqp_client/erlang.mk b/deps/amqp_client/erlang.mk new file mode 120000 index 000000000000..59af4a527a9d --- /dev/null +++ b/deps/amqp_client/erlang.mk @@ -0,0 +1 @@ +../../erlang.mk \ No newline at end of file diff --git a/deps/amqp_client/rabbitmq-components.mk b/deps/amqp_client/rabbitmq-components.mk new file mode 120000 index 000000000000..43c0d3567154 --- /dev/null +++ b/deps/amqp_client/rabbitmq-components.mk @@ -0,0 +1 @@ +../../rabbitmq-components.mk \ No newline at end of file diff --git a/deps/rabbit_common/Makefile b/deps/rabbit_common/Makefile index 389c737c4ae3..03bf6ebaa51d 100644 --- a/deps/rabbit_common/Makefile +++ b/deps/rabbit_common/Makefile @@ -6,7 +6,7 @@ define PROJECT_APP_EXTRA_KEYS {licenses, ["MPL-2.0"]}, {links, [ {"Website", "https://www.rabbitmq.com/"}, - {"GitHub", "https://github.com/rabbitmq/rabbitmq-server/tree/master/deps/rabbit_common"} + {"GitHub", "https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbit_common"} ]}, {build_tools, ["make", "rebar3"]}, {files, [ @@ -20,7 +20,7 @@ define HEX_TARBALL_EXTRA_METADATA licenses => [<<"MPL-2.0">>], links => #{ <<"Website">> => <<"https://www.rabbitmq.com">>, - <<"GitHub">> => <<"https://github.com/rabbitmq/rabbitmq-server/tree/master/deps/rabbit_common">> + <<"GitHub">> => <<"https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbit_common">> } } endef @@ -49,9 +49,17 @@ DEP_PLUGINS = $(PROJECT)/mk/rabbitmq-build.mk \ PLT_APPS += mnesia crypto ssl -include ../../rabbitmq-components.mk -include ../../erlang.mk +include rabbitmq-components.mk +include erlang.mk -HEX_TARBALL_FILES += $(DEPS_DIR)/../rabbitmq-components.mk +HEX_TARBALL_FILES += rabbitmq-components.mk \ + git-revisions.txt \ + mk/rabbitmq-build.mk \ + mk/rabbitmq-dist.mk \ + mk/rabbitmq-early-test.mk \ + mk/rabbitmq-hexpm.mk \ + mk/rabbitmq-macros.mk \ + mk/rabbitmq-test.mk \ + mk/rabbitmq-tools.mk -include development.post.mk diff --git a/deps/rabbit_common/erlang.mk b/deps/rabbit_common/erlang.mk new file mode 120000 index 000000000000..59af4a527a9d --- /dev/null +++ b/deps/rabbit_common/erlang.mk @@ -0,0 +1 @@ +../../erlang.mk \ No newline at end of file diff --git a/deps/rabbit_common/rabbitmq-components.mk b/deps/rabbit_common/rabbitmq-components.mk new file mode 120000 index 000000000000..43c0d3567154 --- /dev/null +++ b/deps/rabbit_common/rabbitmq-components.mk @@ -0,0 +1 @@ +../../rabbitmq-components.mk \ No newline at end of file diff --git a/deps/rabbitmq_auth_backend_cache/README.md b/deps/rabbitmq_auth_backend_cache/README.md index dc3ee7ce5d64..4043f3682974 100644 --- a/deps/rabbitmq_auth_backend_cache/README.md +++ b/deps/rabbitmq_auth_backend_cache/README.md @@ -95,7 +95,7 @@ In the classic config format: ]. ``` -The following example combines this backend with the [HTTP backend](https://github.com/rabbitmq/rabbitmq-auth-backend-http/tree/master) and its [example Spring Boot application](https://github.com/rabbitmq/rabbitmq-auth-backend-http/tree/master/examples): +The following example combines this backend with the [HTTP backend](https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbitmq_auth_backend_http) and its [example Spring Boot application](https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbitmq_auth_backend_http/examples): auth_backends.1 = cache diff --git a/deps/rabbitmq_peer_discovery_k8s/README.md b/deps/rabbitmq_peer_discovery_k8s/README.md index faaad4591dca..2a03b3a2ac58 100644 --- a/deps/rabbitmq_peer_discovery_k8s/README.md +++ b/deps/rabbitmq_peer_discovery_k8s/README.md @@ -15,7 +15,7 @@ are not in scope for this plugin. For a more comprehensive open source RabbitMQ on Kubernetes deployment solution, see the [RabbitMQ Cluster Operator for Kubernetes](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html). The Operator is developed [on GitHub](https://github.com/rabbitmq/cluster-operator/) and contains its -own [set of examples](https://github.com/rabbitmq/cluster-operator/tree/master/docs/examples). +own [set of examples](https://github.com/rabbitmq/cluster-operator/tree/main/docs/examples). ## Supported RabbitMQ Versions diff --git a/deps/rabbitmq_peer_discovery_k8s/examples/gke/README.md b/deps/rabbitmq_peer_discovery_k8s/examples/gke/README.md index 8523780755cf..ccd532929c02 100644 --- a/deps/rabbitmq_peer_discovery_k8s/examples/gke/README.md +++ b/deps/rabbitmq_peer_discovery_k8s/examples/gke/README.md @@ -1,3 +1 @@ -# Deploy RabbitMQ on Kubernetes with the Kubernetes Peer Discovery Plugin to GKE - -This example has graduated and moved to [a separate repository](https://github.com/rabbitmq/diy-kubernetes-examples/tree/master/gke). \ No newline at end of file +Please use the RabbitMQ Cluster Operator: [link](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html) diff --git a/deps/rabbitmq_peer_discovery_k8s/examples/kind/README.md b/deps/rabbitmq_peer_discovery_k8s/examples/kind/README.md index 1045547a9915..2de34b212980 100644 --- a/deps/rabbitmq_peer_discovery_k8s/examples/kind/README.md +++ b/deps/rabbitmq_peer_discovery_k8s/examples/kind/README.md @@ -1,3 +1,7 @@ -# Deploy RabbitMQ on Kubernetes with the Kubernetes Peer Discovery Plugin to Kind +# Recommended Deployment -This example has graduated and moved to [a separate repository](https://github.com/rabbitmq/diy-kubernetes-examples/tree/master/kind). +In Production, use the RabbitMQ Cluster Operator: [link](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html) + +## Deploy RabbitMQ on Kubernetes with the Kubernetes Peer Discovery Plugin to Kind + +This example has graduated and moved to [a separate repository](https://github.com/rabbitmq/diy-kubernetes-examples/tree/master/kind#production-non-suitability) diff --git a/deps/rabbitmq_peer_discovery_k8s/examples/minikube/README.md b/deps/rabbitmq_peer_discovery_k8s/examples/minikube/README.md index 57dbc6722747..ecf90a86a063 100644 --- a/deps/rabbitmq_peer_discovery_k8s/examples/minikube/README.md +++ b/deps/rabbitmq_peer_discovery_k8s/examples/minikube/README.md @@ -1,3 +1,7 @@ -# Deploy RabbitMQ on Kubernetes with the Kubernetes Peer Discovery Plugin to Minikube +# Recommended Deployment -This example has graduated and moved to [a separate repository](https://github.com/rabbitmq/diy-kubernetes-examples/tree/master/minikube). \ No newline at end of file +In Production, use the RabbitMQ Cluster Operator: [link](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html) + +## Deploy RabbitMQ on Kubernetes with the Kubernetes Peer Discovery Plugin to Minikube + +This example has graduated and moved to [a separate repository](https://github.com/rabbitmq/diy-kubernetes-examples/tree/master/minikube). From a8a0710cdf619db059846f72fb015fc1c40d708c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 18:51:14 +0000 Subject: [PATCH 15/49] Bump actions/cache from 3.0.8 to 3.0.9 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.8 to 3.0.9. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.8...v3.0.9) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/oci-base.yaml | 2 +- .github/workflows/oci.yaml | 6 +++--- .github/workflows/perform-bazel-execution-comparison.yaml | 2 +- .github/workflows/rabbitmq_peer_discovery_aws.yaml | 2 +- .github/workflows/secondary-umbrella.yaml | 2 +- .github/workflows/test-erlang-git.yaml | 2 +- .github/workflows/test-mixed-versions.yaml | 4 ++-- .github/workflows/test.yaml | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/oci-base.yaml b/.github/workflows/oci-base.yaml index f79017deaf18..26a4070493d6 100644 --- a/.github/workflows/oci-base.yaml +++ b/.github/workflows/oci-base.yaml @@ -15,7 +15,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-${{ matrix.image_tag_suffix }}-buildx-${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/oci.yaml b/.github/workflows/oci.yaml index f954b37b6f20..3dfe35ec582c 100644 --- a/.github/workflows/oci.yaml +++ b/.github/workflows/oci.yaml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v3 - name: Mount Bazel Cache - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -87,7 +87,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-${{ matrix.image_tag_suffix }}-buildx-${{ github.event.pull_request.head.sha || github.sha }} @@ -166,7 +166,7 @@ jobs: sed -i"_orig" -E '/APP_VERSION/ s/3\.[0-9]+\.[0-9]+/${{ github.event.pull_request.head.sha || github.sha }}/' rabbitmq.bzl - name: Mount Bazel Cache - uses: actions/cache@v3.0.7 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/perform-bazel-execution-comparison.yaml b/.github/workflows/perform-bazel-execution-comparison.yaml index c2be55b9e1aa..ead1e9246a2f 100644 --- a/.github/workflows/perform-bazel-execution-comparison.yaml +++ b/.github/workflows/perform-bazel-execution-comparison.yaml @@ -87,7 +87,7 @@ jobs: repository: bazelbuild/bazel path: bazel - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/.cache/bazel" key: bazel diff --git a/.github/workflows/rabbitmq_peer_discovery_aws.yaml b/.github/workflows/rabbitmq_peer_discovery_aws.yaml index a1c3fd1044b5..c3747b7e225a 100644 --- a/.github/workflows/rabbitmq_peer_discovery_aws.yaml +++ b/.github/workflows/rabbitmq_peer_discovery_aws.yaml @@ -22,7 +22,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} wait-interval: 30 # seconds - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/secondary-umbrella.yaml b/.github/workflows/secondary-umbrella.yaml index ac167d2eb32b..3aa754b0223c 100644 --- a/.github/workflows/secondary-umbrella.yaml +++ b/.github/workflows/secondary-umbrella.yaml @@ -35,7 +35,7 @@ jobs: git diff - name: Mount Bazel Cache - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache-secondary-umbrella diff --git a/.github/workflows/test-erlang-git.yaml b/.github/workflows/test-erlang-git.yaml index 167c0ad9e6ab..65a9028e7365 100644 --- a/.github/workflows/test-erlang-git.yaml +++ b/.github/workflows/test-erlang-git.yaml @@ -12,7 +12,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/test-mixed-versions.yaml b/.github/workflows/test-mixed-versions.yaml index dc91182ab614..27ef5177cc03 100644 --- a/.github/workflows/test-mixed-versions.yaml +++ b/.github/workflows/test-mixed-versions.yaml @@ -37,7 +37,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -86,7 +86,7 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 327e8148ab15..ef87b6e9c8db 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -37,7 +37,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -89,7 +89,7 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.8 + uses: actions/cache@v3.0.9 with: path: "/home/runner/repo-cache/" key: repo-cache From 763cc758e2da0e0962b0e39e0ed4bc1cc9b565f9 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Fri, 30 Sep 2022 12:32:52 +0200 Subject: [PATCH 16/49] Add //tools:erlang_ls_files that generates a tree for Erlang LS in the layout Erlang LS expects (cherry picked from commit 41a13e44e8ddf47cd69c740b96d0cb932d9da020) (cherry picked from commit 5c0f2d7a767486649392083f7d3bf59c9b34ac62) # Conflicts: # deps/rabbitmq_amqp1_0/BUILD.bazel --- deps/rabbitmq_amqp1_0/BUILD.bazel | 6 +++ tools/BUILD.bazel | 10 ++++- tools/erlang_ls.bzl | 62 ++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/BUILD.bazel b/deps/rabbitmq_amqp1_0/BUILD.bazel index 9744679c82c6..7e46485dd814 100644 --- a/deps/rabbitmq_amqp1_0/BUILD.bazel +++ b/deps/rabbitmq_amqp1_0/BUILD.bazel @@ -80,6 +80,12 @@ suites = [ PACKAGE, name = "command_SUITE", size = "medium", +<<<<<<< HEAD +======= + runtime_deps = [ + "//deps/amqp10_client:erlang_app", + ], +>>>>>>> 5c0f2d7a76 (Add //tools:erlang_ls_files that generates a tree for Erlang LS) deps = [ "//deps/amqp10_common:erlang_app", ], diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index e90ac62a9b3a..ad3f59297499 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -1,4 +1,12 @@ -load(":erlang_ls.bzl", "erlang_ls_config") +load("//:rabbitmq.bzl", "all_plugins") +load(":erlang_ls.bzl", "erlang_ls_config", "erlang_ls_tree") + +erlang_ls_tree( + name = "erlang_ls_files", + apps = all_plugins( + rabbitmq_workspace = "", + ), +) erlang_ls_config( name = "erlang_ls.config", diff --git a/tools/erlang_ls.bzl b/tools/erlang_ls.bzl index 2dbdea821bcf..6e532c8a7149 100644 --- a/tools/erlang_ls.bzl +++ b/tools/erlang_ls.bzl @@ -1,9 +1,21 @@ +load( + "@rules_erlang//:erlang_app_info.bzl", + "ErlangAppInfo", +) load( "@rules_erlang//tools:erlang_toolchain.bzl", "erlang_dirs", ) +load( + "@rules_erlang//:util.bzl", + "path_join", +) +load( + "@rules_erlang//private:util.bzl", + "additional_file_dest_relative_path", +) -def _impl(ctx): +def _erlang_ls_config(ctx): out = ctx.actions.declare_file(ctx.label.name) (erlang_home, _, _) = erlang_dirs(ctx) @@ -34,8 +46,54 @@ plt_path: bazel-bin/deps/rabbit/.base_plt.plt ] erlang_ls_config = rule( - implementation = _impl, + implementation = _erlang_ls_config, toolchains = [ "@rules_erlang//tools:toolchain_type", ], ) + +def _erlang_app_files(ctx, app, directory): + app_info = app[ErlangAppInfo] + app_path = path_join(directory, app_info.app_name) + files = [] + for hdr in app_info.srcs + app_info.beam: + rp = additional_file_dest_relative_path(app.label, hdr) + dest = ctx.actions.declare_file(path_join(app_path, rp)) + ctx.actions.symlink(output = dest, target_file = hdr) + files.append(dest) + return files + +def _erlang_ls_tree(ctx): + apps = ctx.attr.apps + deps = [] + + for app in apps: + app_info = app[ErlangAppInfo] + for dep in app_info.deps: + # this puts non rabbitmq plugins, like amqp10_client into deps, + # but maybe those should be in apps? Does it matter? + if dep not in deps and dep not in apps: + deps.append(dep) + + files = [] + for app in apps: + files.extend( + _erlang_app_files(ctx, app, path_join(ctx.label.name, "apps")), + ) + for dep in deps: + files.extend( + _erlang_app_files(ctx, dep, path_join(ctx.label.name, "deps")), + ) + + return [ + DefaultInfo(files = depset(files)), + ] + +erlang_ls_tree = rule( + implementation = _erlang_ls_tree, + attrs = { + "apps": attr.label_list( + providers = [ErlangAppInfo], + ), + }, +) From 6237e203526a2cb9112b55092ee6f3f349e8398d Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Fri, 30 Sep 2022 13:06:27 +0200 Subject: [PATCH 17/49] Change variable name (cherry picked from commit ec337d0866c9f4faace338673a823cf5bb734fcc) (cherry picked from commit 4bb6a5accd33c1ed493145ecc66ee218ce0a6662) --- tools/erlang_ls.bzl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/erlang_ls.bzl b/tools/erlang_ls.bzl index 6e532c8a7149..b1dc8bbd0292 100644 --- a/tools/erlang_ls.bzl +++ b/tools/erlang_ls.bzl @@ -56,10 +56,16 @@ def _erlang_app_files(ctx, app, directory): app_info = app[ErlangAppInfo] app_path = path_join(directory, app_info.app_name) files = [] - for hdr in app_info.srcs + app_info.beam: - rp = additional_file_dest_relative_path(app.label, hdr) - dest = ctx.actions.declare_file(path_join(app_path, rp)) - ctx.actions.symlink(output = dest, target_file = hdr) + for f in app_info.srcs + app_info.beam: + relative_path = additional_file_dest_relative_path(app.label, f) + dest = ctx.actions.declare_file(path_join(app_path, relative_path)) + + # ctx.actions.expand_template( + # template = f, + # output = dest, + # substitutions = {}, + # ) + ctx.actions.symlink(output = dest, target_file = f) files.append(dest) return files From df45ece2aa0b4cc95199d8bc5499119a2a3b2b05 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Fri, 30 Sep 2022 13:39:25 +0200 Subject: [PATCH 18/49] Turn the //tools:erlang_ls.config target into a generation script So that one can `bazel run tools:erlang_ls.config > erlang_ls.config` to generate a bazel friendly config (cherry picked from commit 25ed8595c34e2bd167de7b502d11ceef91f5f056) (cherry picked from commit 5bacec27d5eff87e7e47f940872677441718aae1) --- tools/erlang_ls.bzl | 51 +++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/tools/erlang_ls.bzl b/tools/erlang_ls.bzl index b1dc8bbd0292..670a338f5f3b 100644 --- a/tools/erlang_ls.bzl +++ b/tools/erlang_ls.bzl @@ -2,10 +2,6 @@ load( "@rules_erlang//:erlang_app_info.bzl", "ErlangAppInfo", ) -load( - "@rules_erlang//tools:erlang_toolchain.bzl", - "erlang_dirs", -) load( "@rules_erlang//:util.bzl", "path_join", @@ -16,40 +12,37 @@ load( ) def _erlang_ls_config(ctx): - out = ctx.actions.declare_file(ctx.label.name) - - (erlang_home, _, _) = erlang_dirs(ctx) + runtime_prefix = path_join( + ctx.label.package, + ctx.label.name + ".runfiles", + ctx.workspace_name, + ) ctx.actions.write( - output = out, - content = """otp_path: {erlang_home} + output = ctx.outputs.executable, + content = """#!/usr/bin/env bash + +set -euo pipefail + +BAZEL_BIN_ABSOLUTE_PATH="${{PWD%/{}}}" + +cat << EOF apps_dirs: - - deps/* - - deps/rabbit/apps/* +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps/* deps_dirs: - - bazel-bin/external/* +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps/* include_dirs: - - deps - - deps/* - - deps/*/include - - deps/*/src - - bazel-bin/external - - bazel-bin/external/*/include -plt_path: bazel-bin/deps/rabbit/.base_plt.plt -""".format( - erlang_home = erlang_home, - ), +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps/*/include +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps +- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps/*/include +EOF +""".format(runtime_prefix), ) - return [ - DefaultInfo(files = depset([out])), - ] - erlang_ls_config = rule( implementation = _erlang_ls_config, - toolchains = [ - "@rules_erlang//tools:toolchain_type", - ], + executable = True, ) def _erlang_app_files(ctx, app, directory): From b99f7644aa159289fa0b9aca7014cbd3a9729634 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Fri, 30 Sep 2022 13:53:56 +0200 Subject: [PATCH 19/49] Attempt to make generated erlang_ls.config more stable So that `-c dbg` does not require it to be regenerated (cherry picked from commit 638fb3f682409cbd7908e99a3af97cfd9c9f06db) (cherry picked from commit 6f49ad2de1f7378d47876118d7e6fa05f4757137) --- tools/erlang_ls.bzl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/erlang_ls.bzl b/tools/erlang_ls.bzl index 670a338f5f3b..1de95e985e87 100644 --- a/tools/erlang_ls.bzl +++ b/tools/erlang_ls.bzl @@ -13,6 +13,7 @@ load( def _erlang_ls_config(ctx): runtime_prefix = path_join( + ctx.bin_dir.path, ctx.label.package, ctx.label.name + ".runfiles", ctx.workspace_name, @@ -24,18 +25,18 @@ def _erlang_ls_config(ctx): set -euo pipefail -BAZEL_BIN_ABSOLUTE_PATH="${{PWD%/{}}}" +BAZEL_OUT_ABSOLUTE_PATH="${{PWD%/{}}}/bazel-out" cat << EOF apps_dirs: -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps/* +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/apps/* deps_dirs: -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps/* +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/deps/* include_dirs: -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/apps/*/include -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps -- ${{BAZEL_BIN_ABSOLUTE_PATH}}/tools/erlang_ls_files/deps/*/include +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/apps +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/apps/*/include +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/deps +- ${{BAZEL_OUT_ABSOLUTE_PATH}}/*/bin/tools/erlang_ls_files/deps/*/include EOF """.format(runtime_prefix), ) From 80d04bf28758389425d4e5a62595da6e5768d25a Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Fri, 30 Sep 2022 16:19:34 +0200 Subject: [PATCH 20/49] Remove commented code (cherry picked from commit 00881314aabea796a4c99341cc744758bb603c4e) (cherry picked from commit 04ae50cf3b741dd41145b5e113487e8560558252) --- tools/erlang_ls.bzl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/erlang_ls.bzl b/tools/erlang_ls.bzl index 1de95e985e87..1fc41468df7c 100644 --- a/tools/erlang_ls.bzl +++ b/tools/erlang_ls.bzl @@ -53,12 +53,6 @@ def _erlang_app_files(ctx, app, directory): for f in app_info.srcs + app_info.beam: relative_path = additional_file_dest_relative_path(app.label, f) dest = ctx.actions.declare_file(path_join(app_path, relative_path)) - - # ctx.actions.expand_template( - # template = f, - # output = dest, - # substitutions = {}, - # ) ctx.actions.symlink(output = dest, target_file = f) files.append(dest) return files From 5107d5057924d0fc53c5986e0e670b9103d1a2db Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 30 Sep 2022 21:59:32 +0400 Subject: [PATCH 21/49] Resolve a conflict --- deps/rabbitmq_amqp1_0/BUILD.bazel | 3 --- 1 file changed, 3 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/BUILD.bazel b/deps/rabbitmq_amqp1_0/BUILD.bazel index 7e46485dd814..8957f98a8d0a 100644 --- a/deps/rabbitmq_amqp1_0/BUILD.bazel +++ b/deps/rabbitmq_amqp1_0/BUILD.bazel @@ -80,12 +80,9 @@ suites = [ PACKAGE, name = "command_SUITE", size = "medium", -<<<<<<< HEAD -======= runtime_deps = [ "//deps/amqp10_client:erlang_app", ], ->>>>>>> 5c0f2d7a76 (Add //tools:erlang_ls_files that generates a tree for Erlang LS) deps = [ "//deps/amqp10_common:erlang_app", ], From cb8f429bbce22c3596144d21c216723766890d7d Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Mon, 3 Oct 2022 11:09:07 +0200 Subject: [PATCH 22/49] Use otp 25.1 for CI instead of 25.0 Also adjust MODULE.bazel/WORKSPACE for easier backporting of otp patch version update PRs --- .bazelrc | 2 +- MODULE.bazel | 11 ++++-- WORKSPACE | 16 +++++++-- bazel/platforms/BUILD.bazel | 14 ++++++-- packaging/docker-image/BUILD.bazel | 36 +++---------------- .../docker-image/test_configs/otp_ubuntu.yaml | 2 +- 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/.bazelrc b/.bazelrc index bb1c200a7eb6..54c40e5a5b06 100644 --- a/.bazelrc +++ b/.bazelrc @@ -42,7 +42,7 @@ build:rbe-24 --config=rbe build:rbe-24 --platforms=//bazel/platforms:erlang_linux_24_platform build:rbe-25 --config=rbe -build:rbe-25 --platforms=//bazel/platforms:erlang_linux_25_platform +build:rbe-25 --platforms=//bazel/platforms:erlang_linux_25_1_platform # no-op config so that --config=local does not error build:local --color=auto diff --git a/MODULE.bazel b/MODULE.bazel index 553ffb40330b..8ba422b12850 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -46,11 +46,17 @@ erlang_config.internal_erlang_from_github_release( ) erlang_config.internal_erlang_from_github_release( - name = "25", + name = "25_0", sha256 = "8fc707f92a124b2aeb0f65dcf9ac8e27b2a305e7bcc4cc1b2fdf770eec0165bf", version = "25.0.4", ) +erlang_config.internal_erlang_from_github_release( + name = "25_1", + sha256 = "a5ea27c1e07511a84bdd869c37f5e254f198c1cecf68ee9c8fedd23010750c31", + version = "25.1", +) + erlang_config.internal_erlang_from_http_archive( name = "git_master", strip_prefix = "otp-master", @@ -98,7 +104,8 @@ register_toolchains( "@erlang_config//external:toolchain", "@erlang_config//23:toolchain", "@erlang_config//24:toolchain", - "@erlang_config//25:toolchain", + "@erlang_config//25_0:toolchain", + "@erlang_config//25_1:toolchain", "@erlang_config//git_master:toolchain", "@elixir_config//external:toolchain", "@elixir_config//1_10:toolchain", diff --git a/WORKSPACE b/WORKSPACE index ab0dea705d1c..ea7012892149 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -77,12 +77,19 @@ http_file( ) http_file( - name = "otp_src_25", + name = "otp_src_25_0", downloaded_file_path = "OTP-25.0.4.tar.gz", sha256 = "05878cb51a64b33c86836b12a21903075c300409b609ad5e941ddb0feb8c2120", urls = ["https://github.com/erlang/otp/archive/OTP-25.0.4.tar.gz"], ) +http_file( + name = "otp_src_25_1", + downloaded_file_path = "OTP-25.1.tar.gz", + sha256 = "e00b2e02350688ee4ac83c41ec25c210774fe73b7f806860c46b185457ae135e", + urls = ["https://github.com/erlang/otp/archive/OTP-25.1.tar.gz"], +) + http_archive( name = "io_buildbuddy_buildbuddy_toolchain", sha256 = "a2a5cccec251211e2221b1587af2ce43c36d32a42f5d881737db3b546a536510", @@ -136,10 +143,15 @@ erlang_config( version = "24.3.4.5", ), internal_erlang_from_github_release( - name = "25", + name = "25_0", sha256 = "8fc707f92a124b2aeb0f65dcf9ac8e27b2a305e7bcc4cc1b2fdf770eec0165bf", version = "25.0.4", ), + internal_erlang_from_github_release( + name = "25_1", + sha256 = "a5ea27c1e07511a84bdd869c37f5e254f198c1cecf68ee9c8fedd23010750c31", + version = "25.1", + ), internal_erlang_from_http_archive( name = "git_master", strip_prefix = "otp-master", diff --git a/bazel/platforms/BUILD.bazel b/bazel/platforms/BUILD.bazel index 81dcdfd1df08..14ba96cb76aa 100644 --- a/bazel/platforms/BUILD.bazel +++ b/bazel/platforms/BUILD.bazel @@ -32,10 +32,18 @@ platform( ) platform( - name = "erlang_linux_25_platform", + name = "erlang_linux_25_0_platform", constraint_values = [ - "@erlang_config//:erlang_25", - "@erlang_config//:erlang_25_any_minor", + "@erlang_config//:erlang_25_0", + "@elixir_config//:elixir_1_14", + ], + parents = ["@rbe//config:platform"], +) + +platform( + name = "erlang_linux_25_1_platform", + constraint_values = [ + "@erlang_config//:erlang_25_1", "@elixir_config//:elixir_1_14", ], parents = ["@rbe//config:platform"], diff --git a/packaging/docker-image/BUILD.bazel b/packaging/docker-image/BUILD.bazel index 84c5d62b3abd..f7664b72359a 100644 --- a/packaging/docker-image/BUILD.bazel +++ b/packaging/docker-image/BUILD.bazel @@ -1,7 +1,3 @@ -load( - "@bazel_skylib//lib:selects.bzl", - "selects", -) load( "@io_bazel_rules_docker//container:container.bzl", "container_image", @@ -112,30 +108,6 @@ container_run_and_commit_layer( tags = ["manual"], ) -selects.config_setting_group( - name = "erlang_23_internal", - match_all = [ - "@erlang_config//:erlang_internal", - "@erlang_config//:erlang_23", - ], -) - -selects.config_setting_group( - name = "erlang_24_internal", - match_all = [ - "@erlang_config//:erlang_internal", - "@erlang_config//:erlang_24", - ], -) - -selects.config_setting_group( - name = "erlang_25_internal", - match_all = [ - "@erlang_config//:erlang_internal", - "@erlang_config//:erlang_25", - ], -) - container_image( name = "otp_source", base = ":otp_pkgs_image", @@ -148,10 +120,10 @@ container_image( ], tags = ["manual"], tars = select({ - ":erlang_23_internal": ["@otp_src_23//file"], - ":erlang_24_internal": ["@otp_src_24//file"], - ":erlang_25_internal": ["@otp_src_25//file"], - "//conditions:default": ["@otp_src_25//file"], + "@erlang_config//:erlang_23": ["@otp_src_23//file"], + "@erlang_config//:erlang_24": ["@otp_src_24//file"], + "@erlang_config//:erlang_25_0": ["@otp_src_25_0//file"], + "@erlang_config//:erlang_25_1": ["@otp_src_25_1//file"], }), ) diff --git a/packaging/docker-image/test_configs/otp_ubuntu.yaml b/packaging/docker-image/test_configs/otp_ubuntu.yaml index f02b5d142394..a96dbe90f26b 100644 --- a/packaging/docker-image/test_configs/otp_ubuntu.yaml +++ b/packaging/docker-image/test_configs/otp_ubuntu.yaml @@ -7,4 +7,4 @@ commandTests: - -noshell - -eval - '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' - expectedOutput: ["2\\d\\.\\d+\\.\\d+"] + expectedOutput: ["2\\d\\.\\d+"] From be5d092860901068f05f315e1c6172e671cef55e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 18:53:35 +0000 Subject: [PATCH 23/49] Bump actions/cache from 3.0.9 to 3.0.10 Bumps [actions/cache](https://github.com/actions/cache) from 3.0.9 to 3.0.10. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.0.9...v3.0.10) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/oci-base.yaml | 2 +- .github/workflows/oci.yaml | 6 +++--- .github/workflows/perform-bazel-execution-comparison.yaml | 2 +- .github/workflows/rabbitmq_peer_discovery_aws.yaml | 2 +- .github/workflows/secondary-umbrella.yaml | 2 +- .github/workflows/test-erlang-git.yaml | 2 +- .github/workflows/test-mixed-versions.yaml | 4 ++-- .github/workflows/test.yaml | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/oci-base.yaml b/.github/workflows/oci-base.yaml index 26a4070493d6..175a127620df 100644 --- a/.github/workflows/oci-base.yaml +++ b/.github/workflows/oci-base.yaml @@ -15,7 +15,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-${{ matrix.image_tag_suffix }}-buildx-${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/oci.yaml b/.github/workflows/oci.yaml index 3dfe35ec582c..4709d360a611 100644 --- a/.github/workflows/oci.yaml +++ b/.github/workflows/oci.yaml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v3 - name: Mount Bazel Cache - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -87,7 +87,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-${{ matrix.image_tag_suffix }}-buildx-${{ github.event.pull_request.head.sha || github.sha }} @@ -166,7 +166,7 @@ jobs: sed -i"_orig" -E '/APP_VERSION/ s/3\.[0-9]+\.[0-9]+/${{ github.event.pull_request.head.sha || github.sha }}/' rabbitmq.bzl - name: Mount Bazel Cache - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/perform-bazel-execution-comparison.yaml b/.github/workflows/perform-bazel-execution-comparison.yaml index ead1e9246a2f..de3ffd9eaaf2 100644 --- a/.github/workflows/perform-bazel-execution-comparison.yaml +++ b/.github/workflows/perform-bazel-execution-comparison.yaml @@ -87,7 +87,7 @@ jobs: repository: bazelbuild/bazel path: bazel - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/.cache/bazel" key: bazel diff --git a/.github/workflows/rabbitmq_peer_discovery_aws.yaml b/.github/workflows/rabbitmq_peer_discovery_aws.yaml index c3747b7e225a..0301703e455c 100644 --- a/.github/workflows/rabbitmq_peer_discovery_aws.yaml +++ b/.github/workflows/rabbitmq_peer_discovery_aws.yaml @@ -22,7 +22,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} wait-interval: 30 # seconds - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/secondary-umbrella.yaml b/.github/workflows/secondary-umbrella.yaml index 3aa754b0223c..b991f4f3776a 100644 --- a/.github/workflows/secondary-umbrella.yaml +++ b/.github/workflows/secondary-umbrella.yaml @@ -35,7 +35,7 @@ jobs: git diff - name: Mount Bazel Cache - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache-secondary-umbrella diff --git a/.github/workflows/test-erlang-git.yaml b/.github/workflows/test-erlang-git.yaml index 65a9028e7365..56f728f6bf57 100644 --- a/.github/workflows/test-erlang-git.yaml +++ b/.github/workflows/test-erlang-git.yaml @@ -12,7 +12,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/test-mixed-versions.yaml b/.github/workflows/test-mixed-versions.yaml index 27ef5177cc03..48ae70cbc8dc 100644 --- a/.github/workflows/test-mixed-versions.yaml +++ b/.github/workflows/test-mixed-versions.yaml @@ -37,7 +37,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -86,7 +86,7 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ef87b6e9c8db..c7051fd0e872 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -37,7 +37,7 @@ jobs: - name: CHECKOUT REPOSITORY uses: actions/checkout@v3 - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache @@ -89,7 +89,7 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - name: MOUNT BAZEL CACHE - uses: actions/cache@v3.0.9 + uses: actions/cache@v3.0.10 with: path: "/home/runner/repo-cache/" key: repo-cache From 471350c3b2c0bbfde24a23bcc12fb020d9a10261 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Mon, 3 Oct 2022 14:52:08 +0200 Subject: [PATCH 24/49] Use rules_erlang 3.7.2 (cherry picked from commit 702784ccd8937f4329ecad6082576eeec5cc1a8d) (cherry picked from commit b896797a60863693a5a632ed43f34fe93565ef20) --- MODULE.bazel | 2 +- WORKSPACE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 8ba422b12850..9cf3594659ae 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -25,7 +25,7 @@ bazel_dep( bazel_dep( name = "rules_erlang", - version = "3.7.1", + version = "3.7.2", ) erlang_config = use_extension( diff --git a/WORKSPACE b/WORKSPACE index ea7012892149..2d528fe5578a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -119,7 +119,7 @@ git_repository( git_repository( name = "rules_erlang", remote = "https://github.com/rabbitmq/rules_erlang.git", - tag = "3.7.1", + tag = "3.7.2", ) load( From 74cd9a4f7c21324409650dee84f16961bb491026 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Mon, 3 Oct 2022 17:22:51 +0200 Subject: [PATCH 25/49] Remove references to constraints no longer generated by rules_erlang --- bazel/platforms/BUILD.bazel | 2 -- 1 file changed, 2 deletions(-) diff --git a/bazel/platforms/BUILD.bazel b/bazel/platforms/BUILD.bazel index 14ba96cb76aa..43b03fc1a2dc 100644 --- a/bazel/platforms/BUILD.bazel +++ b/bazel/platforms/BUILD.bazel @@ -15,7 +15,6 @@ platform( name = "erlang_linux_23_platform", constraint_values = [ "@erlang_config//:erlang_23", - "@erlang_config//:erlang_23_any_minor", "@elixir_config//:elixir_1_10", ], parents = ["@rbe//config:platform"], @@ -25,7 +24,6 @@ platform( name = "erlang_linux_24_platform", constraint_values = [ "@erlang_config//:erlang_24", - "@erlang_config//:erlang_24_any_minor", "@elixir_config//:elixir_1_12", ], parents = ["@rbe//config:platform"], From 5214164d5c0cc4cdac757f5c9d069e83535603da Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Tue, 4 Oct 2022 11:42:29 +0200 Subject: [PATCH 26/49] Use Elixir 1.13.x with otp 24.x in bazel build (cherry picked from commit c494c7f1ece35d8313200a9091a0bc90dafea37e) (cherry picked from commit 929c59cffb8f18b6c4d9f60bc68254c063bf939e) --- bazel/platforms/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/platforms/BUILD.bazel b/bazel/platforms/BUILD.bazel index 43b03fc1a2dc..d2da9bfc9f9e 100644 --- a/bazel/platforms/BUILD.bazel +++ b/bazel/platforms/BUILD.bazel @@ -24,7 +24,7 @@ platform( name = "erlang_linux_24_platform", constraint_values = [ "@erlang_config//:erlang_24", - "@elixir_config//:elixir_1_12", + "@elixir_config//:elixir_1_13", ], parents = ["@rbe//config:platform"], ) From 202eec84091731fd5fcff46e1f4a5e6086779d32 Mon Sep 17 00:00:00 2001 From: GitHub Date: Tue, 4 Oct 2022 08:45:49 +0000 Subject: [PATCH 27/49] Adopt otp 25.1.1 (cherry picked from commit b5ebd52e681e685799c00459d41ed79a9dbf02e4) (cherry picked from commit f8edf35871bea427f789d8325ac7c655a91ac446) --- MODULE.bazel | 4 ++-- WORKSPACE | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 9cf3594659ae..a8f1c4f2f7e0 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -53,8 +53,8 @@ erlang_config.internal_erlang_from_github_release( erlang_config.internal_erlang_from_github_release( name = "25_1", - sha256 = "a5ea27c1e07511a84bdd869c37f5e254f198c1cecf68ee9c8fedd23010750c31", - version = "25.1", + sha256 = "42840c32e13a27bdb2c376d69aa22466513d441bfe5eb882de23baf8218308d3", + version = "25.1.1", ) erlang_config.internal_erlang_from_http_archive( diff --git a/WORKSPACE b/WORKSPACE index 2d528fe5578a..231cb4c5fa2f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -85,9 +85,9 @@ http_file( http_file( name = "otp_src_25_1", - downloaded_file_path = "OTP-25.1.tar.gz", - sha256 = "e00b2e02350688ee4ac83c41ec25c210774fe73b7f806860c46b185457ae135e", - urls = ["https://github.com/erlang/otp/archive/OTP-25.1.tar.gz"], + downloaded_file_path = "OTP-25.1.1.tar.gz", + sha256 = "3348616450868fa8b39bddf0b528030e4525afef5b30e3a4b54c375add7d3f4f", + urls = ["https://github.com/erlang/otp/archive/OTP-25.1.1.tar.gz"], ) http_archive( @@ -149,8 +149,8 @@ erlang_config( ), internal_erlang_from_github_release( name = "25_1", - sha256 = "a5ea27c1e07511a84bdd869c37f5e254f198c1cecf68ee9c8fedd23010750c31", - version = "25.1", + sha256 = "42840c32e13a27bdb2c376d69aa22466513d441bfe5eb882de23baf8218308d3", + version = "25.1.1", ), internal_erlang_from_http_archive( name = "git_master", From a47914092165d13ce23315d99ed51a0d3a3b67d1 Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 18:52:28 +0100 Subject: [PATCH 28/49] initial .formatter.exs configuration file (cherry picked from commit 56ca86a48e7314dc7d7d2574ff197ebfff2867d4) (cherry picked from commit 4bdbf7e6d6e1fca335763775c8609a791a1f09a1) --- deps/rabbitmq_cli/.formatter.exs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 deps/rabbitmq_cli/.formatter.exs diff --git a/deps/rabbitmq_cli/.formatter.exs b/deps/rabbitmq_cli/.formatter.exs new file mode 100644 index 000000000000..d304ff320a52 --- /dev/null +++ b/deps/rabbitmq_cli/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] From 0f89101de0fba1520a3841aac7b21263bbc958b6 Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 18:54:11 +0100 Subject: [PATCH 29/49] mix format rabbitmq_cli (cherry picked from commit 4cbbaad2df968450dd5b139c8cac0e21be89b6b3) (cherry picked from commit 059978e6fa3f7660e1b1d75417a4806cbcc2bd1d) # Conflicts: # deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex # deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex # deps/rabbitmq_cli/mix.exs # deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs # deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs # deps/rabbitmq_cli/test/upgrade/drain_command_test.exs # deps/rabbitmq_cli/test/upgrade/revive_command_test.exs --- deps/rabbitmq_cli/config/config.exs | 3 +- .../lib/rabbitmq/cli/auto_complete.ex | 2 + .../lib/rabbitmq/cli/command_behaviour.ex | 138 ++++--- .../lib/rabbitmq/cli/core/alarms.ex | 5 + .../lib/rabbitmq/cli/core/command_modules.ex | 1 + .../lib/rabbitmq/cli/core/feature_flags.ex | 25 ++ .../lib/rabbitmq/cli/core/helpers.ex | 21 +- .../lib/rabbitmq/cli/core/input.ex | 24 +- .../lib/rabbitmq/cli/core/listeners.ex | 120 ++++-- .../lib/rabbitmq/cli/core/log_files.ex | 44 ++- .../lib/rabbitmq/cli/core/memory.ex | 16 +- .../lib/rabbitmq/cli/core/networking.ex | 73 ++-- .../lib/rabbitmq/cli/core/parser.ex | 7 +- .../lib/rabbitmq/cli/core/platform.ex | 8 +- .../lib/rabbitmq/cli/core/validators.ex | 1 - .../lib/rabbitmq/cli/core/version.ex | 4 +- .../cli/ctl/commands/add_user_command.ex | 45 ++- .../cli/ctl/commands/add_vhost_command.ex | 67 +++- .../ctl/commands/authenticate_user_command.ex | 23 +- .../cli/ctl/commands/autocomplete_command.ex | 2 + .../commands/await_online_nodes_command.ex | 9 +- .../ctl/commands/change_password_command.ex | 24 +- .../ctl/commands/clear_permissions_command.ex | 14 +- .../clear_topic_permissions_command.ex | 14 +- .../ctl/commands/clear_user_limits_command.ex | 1 + .../commands/close_all_connections_command.ex | 19 +- .../ctl/commands/close_connection_command.ex | 3 +- .../ctl/commands/cluster_status_command.ex | 320 +++++++++------ .../cli/ctl/commands/decode_command.ex | 25 +- .../cli/ctl/commands/delete_user_command.ex | 9 +- .../commands/enable_feature_flag_command.ex | 38 +- .../cli/ctl/commands/encode_command.ex | 49 ++- .../cli/ctl/commands/environment_command.ex | 4 +- .../rabbitmq/cli/ctl/commands/eval_command.ex | 20 +- .../cli/ctl/commands/eval_file_command.ex | 12 +- .../commands/export_definitions_command.ex | 94 +++-- .../cli/ctl/commands/force_boot_command.ex | 4 +- .../cli/ctl/commands/force_gc_command.ex | 7 +- .../cli/ctl/commands/force_reset_command.ex | 2 +- .../commands/forget_cluster_node_command.ex | 32 +- .../rabbitmq/cli/ctl/commands/help_command.ex | 116 ++++-- .../cli/ctl/commands/hipe_compile_command.ex | 1 + .../commands/import_definitions_command.ex | 87 ++-- .../cli/ctl/commands/join_cluster_command.ex | 13 +- .../ctl/commands/list_consumers_command.ex | 23 +- .../commands/list_feature_flags_command.ex | 20 +- .../cli/ctl/commands/list_queues_command.ex | 11 +- .../list_unresponsive_queues_command.ex | 8 +- .../ctl/commands/list_user_limits_command.ex | 4 +- .../ctl/commands/node_health_check_command.ex | 3 +- .../rabbitmq/cli/ctl/commands/ping_command.ex | 9 +- .../cli/ctl/commands/report_command.ex | 9 +- .../cli/ctl/commands/reset_command.ex | 3 +- .../ctl/commands/resume_listeners_command.ex | 15 +- .../cli/ctl/commands/rotate_logs_command.ex | 1 + .../commands/set_global_parameter_command.ex | 2 + .../cli/ctl/commands/set_log_level_command.ex | 4 +- .../commands/set_operator_policy_command.ex | 17 +- .../cli/ctl/commands/set_parameter_command.ex | 4 +- .../ctl/commands/set_permissions_command.ex | 14 +- .../cli/ctl/commands/set_policy_command.ex | 17 +- .../commands/set_topic_permissions_command.ex | 16 +- .../cli/ctl/commands/set_user_tags_command.ex | 6 +- .../ctl/commands/set_vhost_tags_command.ex | 20 +- .../set_vm_memory_high_watermark_command.ex | 2 +- .../cli/ctl/commands/shutdown_command.ex | 37 +- .../cli/ctl/commands/start_app_command.ex | 3 +- .../cli/ctl/commands/status_command.ex | 196 +++++---- .../rabbitmq/cli/ctl/commands/stop_command.ex | 9 +- .../ctl/commands/suspend_listeners_command.ex | 15 +- .../cli/ctl/commands/sync_queue_command.ex | 4 +- .../commands/update_cluster_nodes_command.ex | 7 +- .../cli/ctl/commands/version_command.ex | 3 + .../rabbitmq/cli/ctl/commands/wait_command.ex | 7 +- .../lib/rabbitmq/cli/default_output.ex | 10 +- .../diagnostics/commands/alarms_command.ex | 3 +- .../commands/certificates_command.ex | 4 +- .../commands/check_alarms_command.ex | 4 +- .../check_certificate_expiration_command.ex | 27 +- .../commands/check_local_alarms_command.ex | 3 +- .../check_port_connectivity_command.ex | 4 +- .../commands/check_port_listener_command.ex | 6 +- .../check_protocol_listener_command.ex | 4 +- .../commands/check_running_command.ex | 4 +- .../commands/cipher_suites_command.ex | 33 +- .../command_line_arguments_command.ex | 5 +- .../commands/consume_event_stream_command.ex | 44 ++- ...le_auth_attempt_source_tracking_command.ex | 11 +- ...le_auth_attempt_source_tracking_command.ex | 10 +- .../commands/erlang_cookie_hash_command.ex | 7 +- .../commands/erlang_cookie_sources_command.ex | 46 ++- .../commands/erlang_version_command.ex | 18 +- .../commands/is_booting_command.ex | 6 +- .../commands/is_running_command.ex | 13 +- .../list_network_interfaces_command.ex | 27 +- .../list_node_auth_attempt_stats_command.ex | 29 +- .../commands/log_location_command.ex | 26 +- .../diagnostics/commands/log_tail_command.ex | 11 +- .../commands/log_tail_stream_command.ex | 40 +- .../commands/maybe_stuck_command.ex | 4 +- .../commands/memory_breakdown_command.ex | 5 +- .../diagnostics/commands/observer_command.ex | 7 +- .../diagnostics/commands/os_env_command.ex | 27 +- .../commands/remote_shell_command.ex | 5 +- .../commands/resolve_hostname_command.ex | 54 ++- .../commands/resolver_info_command.ex | 34 +- .../commands/runtime_thread_stats_command.ex | 3 +- .../commands/server_version_command.ex | 4 +- .../commands/tls_versions_command.ex | 3 +- .../cli/diagnostics/diagnostics_helpers.ex | 9 +- .../lib/rabbitmq/cli/formatter_behaviour.ex | 4 +- .../cli/formatters/formatter_helpers.ex | 1 - .../lib/rabbitmq/cli/formatters/json.ex | 18 +- .../rabbitmq/cli/formatters/json_stream.ex | 18 +- .../lib/rabbitmq/cli/formatters/plugins.ex | 2 + .../rabbitmq/cli/formatters/pretty_table.ex | 140 ++++--- .../cli/plugins/commands/disable_command.ex | 10 +- .../cli/plugins/commands/enable_command.ex | 10 +- .../cli/plugins/commands/is_enabled.ex | 9 +- .../cli/plugins/commands/list_command.ex | 5 +- .../cli/plugins/commands/set_command.ex | 10 +- .../lib/rabbitmq/cli/plugins/error_output.ex | 4 +- .../lib/rabbitmq/cli/printer_behaviour.ex | 3 +- .../cli/queues/commands/add_member_command.ex | 1 + ...if_node_is_mirror_sync_critical_command.ex | 50 ++- ...heck_if_node_is_quorum_critical_command.ex | 60 ++- .../cli/queues/commands/grow_command.ex | 97 +++-- .../cli/queues/commands/peek_command.ex | 34 +- .../cli/queues/commands/rebalance_command.ex | 24 +- .../commands/reclaim_quorum_memory_command.ex | 7 +- .../cli/queues/commands/shrink_command.ex | 39 +- .../commands/delete_replica_command.ex | 1 + .../set_stream_retention_policy_command.ex | 7 +- .../streams/commands/stream_status_command.ex | 5 +- .../lib/rabbitmq/cli/time_unit.ex | 1 - .../await_online_quorum_plus_one_command.ex | 62 ++- ...wait_online_synchronized_mirror_command.ex | 62 ++- .../cli/upgrade/commands/drain_command.ex | 16 +- .../upgrade/commands/post_upgrade_command.ex | 3 +- .../cli/upgrade/commands/revive_command.ex | 16 +- deps/rabbitmq_cli/lib/rabbitmqctl.ex | 92 +++-- deps/rabbitmq_cli/mix.exs | 164 ++++---- .../test/core/args_processing_test.exs | 43 +- .../test/core/auto_complete_test.exs | 37 +- .../test/core/command_modules_test.exs | 67 ++-- .../test/core/default_output_test.exs | 43 +- .../test/core/distribution_test.exs | 4 + deps/rabbitmq_cli/test/core/helpers_test.exs | 43 +- .../test/core/information_unit_test.exs | 31 +- .../test/core/json_stream_test.exs | 7 +- .../rabbitmq_cli/test/core/listeners_test.exs | 68 ++-- deps/rabbitmq_cli/test/core/os_pid_test.exs | 27 +- deps/rabbitmq_cli/test/core/parser_test.exs | 217 +++++----- .../test/core/rpc_stream_test.exs | 141 +++++-- .../test/core/table_formatter_test.exs | 77 +++- .../test/ctl/add_user_command_test.exs | 21 +- .../test/ctl/add_vhost_command_test.exs | 29 +- .../ctl/authenticate_user_command_test.exs | 35 +- .../test/ctl/autocomplete_command_test.exs | 10 +- .../ctl/await_online_nodes_command_test.exs | 8 +- .../test/ctl/await_startup_command_test.exs | 2 +- .../test/ctl/cancel_sync_command_test.exs | 15 +- .../change_cluster_node_type_command_test.exs | 50 +-- .../test/ctl/change_password_command_test.exs | 19 +- .../clear_global_parameter_command_test.exs | 38 +- .../clear_operator_policy_command_test.exs | 47 +-- .../test/ctl/clear_parameter_command_test.exs | 58 +-- .../test/ctl/clear_password_command_test.exs | 11 +- .../ctl/clear_permissions_command_test.exs | 15 +- .../test/ctl/clear_policy_command_test.exs | 49 +-- .../clear_topic_permissions_command_test.exs | 24 +- .../ctl/clear_user_limits_command_test.exs | 48 +-- .../ctl/clear_vhost_limits_command_test.exs | 28 +- .../close_all_connections_command_test.exs | 93 +++-- ...lose_all_user_connections_command_test.exs | 37 +- .../ctl/close_connection_command_test.exs | 61 +-- .../test/ctl/cluster_status_command_test.exs | 1 - .../test/ctl/decode_command_test.exs | 92 +++-- .../test/ctl/delete_queue_command_test.exs | 69 ++-- .../test/ctl/delete_user_command_test.exs | 3 +- .../test/ctl/delete_vhost_command_test.exs | 8 +- .../test/ctl/enable_feature_flag_test.exs | 40 +- .../test/ctl/encode_command_test.exs | 74 ++-- .../test/ctl/environment_command_test.exs | 5 +- .../test/ctl/eval_command_test.exs | 18 +- .../test/ctl/eval_file_command_test.exs | 1 - .../test/ctl/exec_command_test.exs | 2 - .../ctl/export_definitions_command_test.exs | 47 ++- .../test/ctl/force_gc_command_test.exs | 2 - .../test/ctl/force_reset_command_test.exs | 23 +- .../test/ctl/help_command_test.exs | 38 +- .../ctl/import_definitions_command_test.exs | 42 +- .../test/ctl/join_cluster_command_test.exs | 70 ++-- .../test/ctl/list_bindings_command_test.exs | 29 +- .../test/ctl/list_channels_command_test.exs | 75 ++-- .../test/ctl/list_ciphers_command_test.exs | 6 +- .../ctl/list_connections_command_test.exs | 40 +- .../test/ctl/list_consumers_command_test.exs | 224 +++++++---- .../test/ctl/list_exchanges_command_test.exs | 124 +++--- .../ctl/list_feature_flags_command_test.exs | 72 ++-- .../list_global_parameters_command_test.exs | 28 +- .../test/ctl/list_hashes_command_test.exs | 6 +- .../list_operator_policies_command_test.exs | 83 ++-- .../test/ctl/list_parameters_command_test.exs | 78 ++-- .../ctl/list_permissions_command_test.exs | 32 +- .../test/ctl/list_policies_command_test.exs | 82 ++-- .../test/ctl/list_queues_command_test.exs | 94 +++-- .../list_topic_permissions_command_test.exs | 22 +- .../ctl/list_user_limits_command_test.exs | 28 +- .../list_user_permissions_command_test.exs | 41 +- ...st_user_topic_permissions_command_test.exs | 15 +- .../test/ctl/list_users_command_test.exs | 31 +- .../ctl/list_vhost_limits_command_test.exs | 42 +- .../test/ctl/list_vhosts_command_test.exs | 69 ++-- .../ctl/node_health_check_command_test.exs | 1 - .../test/ctl/ping_command_test.exs | 3 +- .../test/ctl/purge_queue_command_test.exs | 22 +- .../test/ctl/report_command_test.exs | 9 +- .../test/ctl/reset_command_test.exs | 24 +- .../test/ctl/restart_vhost_command_test.exs | 51 +-- .../ctl/resume_listeners_command_test.exs | 3 +- .../ctl/set_cluster_name_command_test.exs | 2 - .../ctl/set_disk_free_limit_command_test.exs | 111 +++--- .../ctl/set_global_parameter_command_test.exs | 33 +- .../test/ctl/set_log_level_command_test.exs | 10 +- .../ctl/set_operator_policy_command_test.exs | 58 +-- .../test/ctl/set_parameter_command_test.exs | 62 +-- .../test/ctl/set_permissions_command_test.exs | 50 +-- .../test/ctl/set_policy_command_test.exs | 79 ++-- .../set_topic_permissions_command_test.exs | 51 +-- .../test/ctl/set_user_limits_command_test.exs | 63 ++- .../test/ctl/set_user_tags_command_test.exs | 99 ++--- .../ctl/set_vhost_limits_command_test.exs | 58 +-- .../test/ctl/set_vhost_tags_command_test.exs | 91 ++--- ..._vm_memory_high_watermark_command_test.exs | 80 ++-- .../test/ctl/shutdown_command_test.exs | 7 +- .../test/ctl/start_app_command_test.exs | 1 - .../test/ctl/status_command_test.exs | 1 - .../test/ctl/stop_app_command_test.exs | 4 +- .../test/ctl/stop_command_test.exs | 10 +- .../ctl/suspend_listeners_command_test.exs | 3 +- .../test/ctl/sync_queue_command_test.exs | 15 +- .../test/ctl/trace_off_command_test.exs | 5 +- .../test/ctl/trace_on_command_test.exs | 5 +- .../ctl/update_cluster_nodes_command_test.exs | 43 +- .../test/ctl/version_command_test.exs | 1 - .../test/ctl/wait_command_test.exs | 54 +-- .../test/diagnostics/alarms_command_test.exs | 18 +- .../diagnostics/check_alarms_command_test.exs | 38 +- .../check_local_alarms_command_test.exs | 29 +- .../check_port_connectivity_command_test.exs | 22 +- .../check_port_listener_command_test.exs | 14 +- .../check_protocol_listener_command_test.exs | 17 +- .../check_running_command_test.exs | 14 +- .../check_virtual_hosts_command_test.exs | 14 +- .../cipher_suites_command_test.exs | 37 +- .../command_line_arguments_command_test.exs | 12 +- .../consume_event_stream_command_test.exs | 45 ++- ...h_attempt_source_tracking_command_test.exs | 9 +- .../discover_peers_command_test.exs | 7 +- ...h_attempt_source_tracking_command_test.exs | 9 +- .../erlang_cookie_hash_command_test.exs | 11 +- .../erlang_version_command_test.exs | 19 +- .../diagnostics/is_booting_command_test.exs | 14 +- .../diagnostics/is_running_command_test.exs | 14 +- .../list_network_interfaces_command_test.exs | 9 +- ...t_node_auth_attempt_stats_command_test.exs | 9 +- .../diagnostics/listeners_command_test.exs | 22 +- .../diagnostics/log_location_command_test.exs | 35 +- .../diagnostics/log_tail_command_test.exs | 81 ++-- .../log_tail_stream_command_test.exs | 30 +- .../diagnostics/maybe_stuck_command_test.exs | 15 +- .../memory_breakdown_command_test.exs | 18 +- .../diagnostics/observer_command_test.exs | 12 +- .../test/diagnostics/os_env_command_test.exs | 24 +- .../diagnostics/remote_shell_command_test.exs | 10 +- .../resolve_hostname_command_test.exs | 37 +- .../resolver_info_command_test.exs | 18 +- .../runtime_thread_stats_command_test.exs | 20 +- .../diagnostics/schema_info_command_test.exs | 20 +- .../server_version_command_test.exs | 15 +- .../diagnostics/tls_versions_command_test.exs | 21 +- deps/rabbitmq_cli/test/json_formatting.exs | 19 +- .../test/plugins/directories_command_test.exs | 69 ++-- .../plugins/disable_plugins_command_test.exs | 279 ++++++++----- .../plugins/enable_plugins_command_test.exs | 272 ++++++++----- .../test/plugins/is_enabled_command_test.exs | 99 +++-- .../plugins/list_plugins_command_test.exs | 339 +++++++++++----- .../test/plugins/plugins_formatter_test.exs | 137 +++++-- .../test/plugins/set_plugins_command_test.exs | 187 +++++---- .../test/queues/add_member_command_test.exs | 28 +- ...e_is_mirror_sync_critical_command_test.exs | 17 +- ...f_node_is_quorum_critical_command_test.exs | 17 +- .../queues/delete_member_command_test.exs | 28 +- .../test/queues/grow_command_test.exs | 32 +- .../test/queues/peek_command_test.exs | 20 +- .../queues/quorum_status_command_test.exs | 26 +- .../reclaim_quorum_memory_command_test.exs | 26 +- .../test/queues/shrink_command_test.exs | 25 +- .../queues/stream_status_command_test.exs | 26 +- deps/rabbitmq_cli/test/rabbitmqctl_test.exs | 211 ++++++---- .../test/streams/add_replica_command_test.exs | 28 +- .../streams/delete_replica_command_test.exs | 34 +- ...t_stream_retention_policy_command_test.exs | 35 +- deps/rabbitmq_cli/test/test_helper.exs | 372 +++++++++++++----- ...it_online_quorum_plus_one_command_test.exs | 11 +- ...nline_synchronized_mirror_command_test.exs | 11 +- .../test/upgrade/drain_command_test.exs | 8 + .../upgrade/post_upgrade_command_test.exs | 11 +- .../test/upgrade/revive_command_test.exs | 8 + 310 files changed, 6985 insertions(+), 4057 deletions(-) diff --git a/deps/rabbitmq_cli/config/config.exs b/deps/rabbitmq_cli/config/config.exs index 0a88337ac6be..3cc55242115f 100644 --- a/deps/rabbitmq_cli/config/config.exs +++ b/deps/rabbitmq_cli/config/config.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - # This file is responsible for configuring your application # and its dependencies with the aid of the Mix.Config module. use Mix.Config @@ -25,7 +24,7 @@ use Mix.Config # # Or configure a 3rd-party app: # -config :logger, [level: :warn, console: [device: :standard_error]] +config :logger, level: :warn, console: [device: :standard_error] # # It is also possible to import configuration files, relative to this diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/auto_complete.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/auto_complete.ex index 557f4dbcf3e4..0f621d8da5b2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/auto_complete.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/auto_complete.ex @@ -28,6 +28,7 @@ defmodule RabbitMQ.CLI.AutoComplete do def suggest_command(_cmd_name, empty) when empty == %{} do nil end + def suggest_command(typed, module_map) do suggestion = module_map @@ -40,6 +41,7 @@ defmodule RabbitMQ.CLI.AutoComplete do case suggestion do {cmd, distance} when distance >= @jaro_distance_limit -> {:suggest, cmd} + _ -> nil end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/command_behaviour.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/command_behaviour.ex index 4b73a4694f98..c7adc88a058a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/command_behaviour.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/command_behaviour.ex @@ -48,7 +48,11 @@ defmodule RabbitMQ.CLI.CommandBehaviour do @callback scopes() :: [atom()] | nil @callback description() :: String.t() @callback help_section() :: String.t() - @callback usage_additional() :: String.t() | [String.t()] | nonempty_list(pair_of_strings()) | [{String.t(), String.t()}] + @callback usage_additional() :: + String.t() + | [String.t()] + | nonempty_list(pair_of_strings()) + | [{String.t(), String.t()}] @callback usage_doc_guides() :: String.t() | [String.t()] ## Erlang distribution control ## :cli - default rabbitmqctl generated node name @@ -57,46 +61,93 @@ defmodule RabbitMQ.CLI.CommandBehaviour do @callback distribution(map()) :: :cli | :none | {:fun, (map() -> :ok | {:error, any()})} defmacro defcmd(map) do - usage_q = case map[:usage] do - nil -> :ok - usage -> - quote do def usage(), do: unquote(usage) end - end - scopes_q = case map[:scopes] do - nil -> :ok - scopes -> - quote do def scopes(), do: unquote(scopes) end - end - description_q = case map[:description] do - nil -> :ok - description -> - quote do def description(), do: unquote(description) end - end - help_section_q = case map[:help_section] do - nil -> :ok - help_section -> - quote do def help_section(), do: unquote(help_section) end - end - usage_additional_q = case map[:usage_additional] do - nil -> :ok - usage_additional -> - quote do def usage_additional(), do: unquote(usage_additional) end - end - formatter_q = case map[:formatter] do - nil -> :ok - formatter -> - quote do def formatter(), do: unquote(formatter) end - end - switches_q = case map[:switches] do - nil -> :ok - switches -> - quote do def switches(), do: unquote(switches) end - end - aliases_q = case map[:aliases] do - nil -> :ok - aliases -> - quote do def aliases(), do: unquote(aliases) end - end + usage_q = + case map[:usage] do + nil -> + :ok + + usage -> + quote do + def usage(), do: unquote(usage) + end + end + + scopes_q = + case map[:scopes] do + nil -> + :ok + + scopes -> + quote do + def scopes(), do: unquote(scopes) + end + end + + description_q = + case map[:description] do + nil -> + :ok + + description -> + quote do + def description(), do: unquote(description) + end + end + + help_section_q = + case map[:help_section] do + nil -> + :ok + + help_section -> + quote do + def help_section(), do: unquote(help_section) + end + end + + usage_additional_q = + case map[:usage_additional] do + nil -> + :ok + + usage_additional -> + quote do + def usage_additional(), do: unquote(usage_additional) + end + end + + formatter_q = + case map[:formatter] do + nil -> + :ok + + formatter -> + quote do + def formatter(), do: unquote(formatter) + end + end + + switches_q = + case map[:switches] do + nil -> + :ok + + switches -> + quote do + def switches(), do: unquote(switches) + end + end + + aliases_q = + case map[:aliases] do + nil -> + :ok + + aliases -> + quote do + def aliases(), do: unquote(aliases) + end + end quote do unquote(usage_q) @@ -129,6 +180,7 @@ defmodule RabbitMQ.CLI.CommandBehaviour do :rabbitmqctl -> :other plugin -> {:plugin, plugin} end + section -> section end @@ -159,9 +211,7 @@ defmodule RabbitMQ.CLI.CommandBehaviour do end def validate_execution_environment(cmd, args, options) do - Helpers.apply_if_exported(cmd, - :validate_execution_environment, [args, options], - :ok) + Helpers.apply_if_exported(cmd, :validate_execution_environment, [args, options], :ok) end def distribution(cmd, options) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/alarms.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/alarms.ex index 9dd265093e4c..fe6710c9e4f6 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/alarms.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/alarms.ex @@ -54,9 +54,11 @@ defmodule RabbitMQ.CLI.Core.Alarms do def alarm_type(val) when is_atom(val) do val end + def alarm_type({:resource_limit, val, _node}) do val end + def alarm_type({{:resource_limit, val, _node}, []}) do val end @@ -64,6 +66,7 @@ defmodule RabbitMQ.CLI.Core.Alarms do def alarm_maps(xs) do Enum.map(xs, &alarm_map/1) end + def alarm_map(:file_descriptor_limit) do %{ type: :resource_limit, @@ -71,6 +74,7 @@ defmodule RabbitMQ.CLI.Core.Alarms do node: node() } end + def alarm_map({{:resource_limit, resource, node}, _}) do %{ type: :resource_limit, @@ -78,6 +82,7 @@ defmodule RabbitMQ.CLI.Core.Alarms do node: node } end + def alarm_map({:resource_limit, resource, node}) do %{ type: :resource_limit, diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/command_modules.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/command_modules.ex index 01935cf2da21..34f89cf9e57c 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/command_modules.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/command_modules.ex @@ -189,6 +189,7 @@ defmodule RabbitMQ.CLI.Core.CommandModules do |> to_snake_case |> String.to_atom() |> List.wrap() + scopes -> scopes end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex index fd573969e306..d4acfddd81e4 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex @@ -10,6 +10,31 @@ defmodule RabbitMQ.CLI.Core.FeatureFlags do # API # +<<<<<<< HEAD +======= + def is_enabled_remotely(node_name, feature_flag) do + case :rabbit_misc.rpc_call(node_name, :rabbit_feature_flags, :is_enabled, [feature_flag]) do + true -> true + false -> false + {:error, _} = error -> error + end + end + + def assert_feature_flag_enabled(node_name, feature_flag, success_fun) do + case is_enabled_remotely(node_name, feature_flag) do + true -> + success_fun.() + + false -> + {:error, ExitCodes.exit_dataerr(), + "The #{feature_flag} feature flag is not enabled on the target node"} + + {:error, _} = error -> + error + end + end + +>>>>>>> 059978e6fa (mix format rabbitmq_cli) def feature_flag_lines(feature_flags) do feature_flags |> Enum.map(fn %{name: name, state: state} -> diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/helpers.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/helpers.ex index 0d792238e0d2..d5af2ee3952a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/helpers.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/helpers.ex @@ -19,7 +19,7 @@ defmodule RabbitMQ.CLI.Core.Helpers do def normalise_node(name, node_name_type) do case NodeName.create(name, node_name_type) do {:ok, node_name} -> node_name - other -> other + other -> other end end @@ -27,9 +27,11 @@ defmodule RabbitMQ.CLI.Core.Helpers do def normalise_node_option(options) do node_opt = Config.get_option(:node, options) longnames_opt = Config.get_option(:longnames, options) + case NodeName.create(node_opt, longnames_opt) do {:error, _} = err -> err + {:ok, val} -> {:ok, Map.put(options, :node, val)} end @@ -38,10 +40,12 @@ defmodule RabbitMQ.CLI.Core.Helpers do def normalise_node_option(nil, _, _) do nil end + def normalise_node_option(node_opt, longnames_opt, options) do case NodeName.create(node_opt, longnames_opt) do {:error, _} = err -> err + {:ok, val} -> {:ok, Map.put(options, :node, val)} end @@ -50,6 +54,7 @@ defmodule RabbitMQ.CLI.Core.Helpers do def case_insensitive_format(%{format: format} = opts) do %{opts | format: String.downcase(format)} end + def case_insensitive_format(opts), do: opts def nodes_in_cluster(node, timeout \\ :infinity) do @@ -116,17 +121,17 @@ defmodule RabbitMQ.CLI.Core.Helpers do end def atomize_values(map, keys) do - Enum.reduce(map, %{}, - fn({k, v}, acc) -> - case Enum.member?(keys, k) do - false -> Map.put(acc, k, v) - true -> Map.put(acc, k, DataCoercion.to_atom(v)) - end - end) + Enum.reduce(map, %{}, fn {k, v}, acc -> + case Enum.member?(keys, k) do + false -> Map.put(acc, k, v) + true -> Map.put(acc, k, DataCoercion.to_atom(v)) + end + end) end def apply_if_exported(mod, fun, args, default) do Code.ensure_loaded(mod) + case function_exported?(mod, fun, length(args)) do true -> apply(mod, fun, args) false -> default diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/input.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/input.ex index 826a1ba0ad91..cab7ba89cfc2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/input.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/input.ex @@ -8,18 +8,20 @@ defmodule RabbitMQ.CLI.Core.Input do alias RabbitMQ.CLI.Core.Config def consume_single_line_string_with_prompt(prompt, opts) do - val = case Config.output_less?(opts) do - true -> - IO.read(:stdio, :line) - false -> - IO.puts(prompt) - IO.read(:stdio, :line) - end + val = + case Config.output_less?(opts) do + true -> + IO.read(:stdio, :line) + + false -> + IO.puts(prompt) + IO.read(:stdio, :line) + end case val do :eof -> :eof - "" -> :eof - s -> String.trim(s) + "" -> :eof + s -> String.trim(s) end end @@ -28,8 +30,8 @@ defmodule RabbitMQ.CLI.Core.Input do case val do :eof -> :eof - "" -> :eof - s -> String.trim(s) + "" -> :eof + s -> String.trim(s) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/listeners.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/listeners.ex index 4ff17607c69e..3fe2d0cd7273 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/listeners.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/listeners.ex @@ -13,9 +13,17 @@ defmodule RabbitMQ.CLI.Core.Listeners do # API # - defrecord :certificate, :Certificate, extract(:Certificate, from_lib: "public_key/include/public_key.hrl") - defrecord :tbscertificate, :TBSCertificate, extract(:TBSCertificate, from_lib: "public_key/include/public_key.hrl") - defrecord :validity, :Validity, extract(:Validity, from_lib: "public_key/include/public_key.hrl") + defrecord :certificate, + :Certificate, + extract(:Certificate, from_lib: "public_key/include/public_key.hrl") + + defrecord :tbscertificate, + :TBSCertificate, + extract(:TBSCertificate, from_lib: "public_key/include/public_key.hrl") + + defrecord :validity, + :Validity, + extract(:Validity, from_lib: "public_key/include/public_key.hrl") def listeners_on(listeners, target_node) do Enum.filter(listeners, fn listener(node: node) -> @@ -33,24 +41,22 @@ defmodule RabbitMQ.CLI.Core.Listeners do listeners |> listener_maps |> Enum.map(fn %{interface: interface, port: port, protocol: protocol} -> - "Interface: #{interface}, port: #{port}, protocol: #{protocol}, purpose: #{ - protocol_label(to_atom(protocol)) - }" + "Interface: #{interface}, port: #{port}, protocol: #{protocol}, purpose: #{protocol_label(to_atom(protocol))}" end) end + def listener_lines(listeners, node) do listeners |> listener_maps |> Enum.map(fn %{interface: interface, port: port, protocol: protocol} -> - "Node: #{node}, interface: #{interface}, port: #{port}, protocol: #{protocol}, purpose: #{ - protocol_label(to_atom(protocol)) - }" + "Node: #{node}, interface: #{interface}, port: #{port}, protocol: #{protocol}, purpose: #{protocol_label(to_atom(protocol))}" end) end def listener_map(listener) when is_map(listener) do listener end + def listener_map(listener) do # Listener options are left out intentionally: they can contain deeply nested values # that are impossible to serialise to JSON. @@ -74,7 +80,8 @@ defmodule RabbitMQ.CLI.Core.Listeners do end def listener_certs(listener) do - listener(node: node, protocol: protocol, ip_address: interface, port: port, opts: opts) = listener + listener(node: node, protocol: protocol, ip_address: interface, port: port, opts: opts) = + listener %{ node: node, @@ -90,29 +97,36 @@ defmodule RabbitMQ.CLI.Core.Listeners do def read_cert(nil) do nil end + def read_cert({:pem, pem}) do pem end + def read_cert(path) do case File.read(path) do {:ok, bin} -> bin + {:error, _} = err -> err end end def listener_expiring_within(listener, seconds) do - listener(node: node, protocol: protocol, ip_address: interface, port: port, opts: opts) = listener + listener(node: node, protocol: protocol, ip_address: interface, port: port, opts: opts) = + listener + certfile = Keyword.get(opts, :certfile) cacertfile = Keyword.get(opts, :cacertfile) now = :calendar.datetime_to_gregorian_seconds(:calendar.universal_time()) expiry_date = now + seconds certfile_expires_on = expired(cert_validity(read_cert(certfile)), expiry_date) cacertfile_expires_on = expired(cert_validity(read_cert(cacertfile)), expiry_date) + case {certfile_expires_on, cacertfile_expires_on} do {[], []} -> false + _ -> %{ node: node, @@ -123,11 +137,20 @@ defmodule RabbitMQ.CLI.Core.Listeners do cacertfile: cacertfile, certfile_expires_on: certfile_expires_on, cacertfile_expires_on: cacertfile_expires_on - } + } end end - def expired_listener_map(%{node: node, protocol: protocol, interface: interface, port: port, certfile_expires_on: certfile_expires_on, cacertfile_expires_on: cacertfile_expires_on, certfile: certfile, cacertfile: cacertfile}) do + def expired_listener_map(%{ + node: node, + protocol: protocol, + interface: interface, + port: port, + certfile_expires_on: certfile_expires_on, + cacertfile_expires_on: cacertfile_expires_on, + certfile: certfile, + cacertfile: cacertfile + }) do %{ node: node, protocol: protocol, @@ -144,6 +167,7 @@ defmodule RabbitMQ.CLI.Core.Listeners do def expires_on_list({:error, _} = error) do [error] end + def expires_on_list(expires) do Enum.map(expires, &expires_on/1) end @@ -151,6 +175,7 @@ defmodule RabbitMQ.CLI.Core.Listeners do def expires_on({:error, _} = error) do error end + def expires_on(seconds) do {:ok, naive} = NaiveDateTime.from_erl(:calendar.gregorian_seconds_to_datetime(seconds)) NaiveDateTime.to_string(naive) @@ -159,38 +184,52 @@ defmodule RabbitMQ.CLI.Core.Listeners do def expired(nil, _) do [] end + def expired({:error, _} = error, _) do error end + def expired(expires, expiry_date) do - Enum.filter(expires, fn ({:error, _}) -> true - (seconds) -> seconds < expiry_date end) + Enum.filter(expires, fn + {:error, _} -> true + seconds -> seconds < expiry_date + end) end def cert_validity(nil) do nil end + def cert_validity(cert) do dsa_entries = :public_key.pem_decode(cert) + case dsa_entries do [] -> {:error, "The certificate file provided does not contain any PEM entry."} + _ -> now = :calendar.datetime_to_gregorian_seconds(:calendar.universal_time()) - Enum.map(dsa_entries, fn ({:Certificate, _, _} = dsa_entry) -> - certificate(tbsCertificate: tbs_certificate) = :public_key.pem_entry_decode(dsa_entry) - tbscertificate(validity: validity) = tbs_certificate - validity(notAfter: not_after, notBefore: not_before) = validity - start = :pubkey_cert.time_str_2_gregorian_sec(not_before) - case start > now do - true -> - {:ok, naive} = NaiveDateTime.from_erl(:calendar.gregorian_seconds_to_datetime(start)) - startdate = NaiveDateTime.to_string(naive) - {:error, "Certificate is not yet valid. It starts on #{startdate}"} - false -> - :pubkey_cert.time_str_2_gregorian_sec(not_after) - end - ({type, _, _}) -> + + Enum.map(dsa_entries, fn + {:Certificate, _, _} = dsa_entry -> + certificate(tbsCertificate: tbs_certificate) = :public_key.pem_entry_decode(dsa_entry) + tbscertificate(validity: validity) = tbs_certificate + validity(notAfter: not_after, notBefore: not_before) = validity + start = :pubkey_cert.time_str_2_gregorian_sec(not_before) + + case start > now do + true -> + {:ok, naive} = + NaiveDateTime.from_erl(:calendar.gregorian_seconds_to_datetime(start)) + + startdate = NaiveDateTime.to_string(naive) + {:error, "Certificate is not yet valid. It starts on #{startdate}"} + + false -> + :pubkey_cert.time_str_2_gregorian_sec(not_after) + end + + {type, _, _} -> {:error, "The certificate file provided contains a #{type} entry."} end) end @@ -209,13 +248,13 @@ defmodule RabbitMQ.CLI.Core.Listeners do end end - def protocol_label(:amqp), do: "AMQP 0-9-1 and AMQP 1.0" - def protocol_label(:'amqp/ssl'), do: "AMQP 0-9-1 and AMQP 1.0 over TLS" - def protocol_label(:mqtt), do: "MQTT" - def protocol_label(:'mqtt/ssl'), do: "MQTT over TLS" - def protocol_label(:stomp), do: "STOMP" - def protocol_label(:'stomp/ssl'), do: "STOMP over TLS" - def protocol_label(:http), do: "HTTP API" + def protocol_label(:amqp), do: "AMQP 0-9-1 and AMQP 1.0" + def protocol_label(:"amqp/ssl"), do: "AMQP 0-9-1 and AMQP 1.0 over TLS" + def protocol_label(:mqtt), do: "MQTT" + def protocol_label(:"mqtt/ssl"), do: "MQTT over TLS" + def protocol_label(:stomp), do: "STOMP" + def protocol_label(:"stomp/ssl"), do: "STOMP over TLS" + def protocol_label(:http), do: "HTTP API" def protocol_label(:https), do: "HTTP API over TLS (HTTPS)" def protocol_label(:"http/web-mqtt"), do: "MQTT over WebSockets" def protocol_label(:"https/web-mqtt"), do: "MQTT over WebSockets and TLS (HTTPS)" @@ -245,9 +284,9 @@ defmodule RabbitMQ.CLI.Core.Listeners do "mqtt311" -> "mqtt" "mqtt3_1" -> "mqtt" "mqtt3_1_1" -> "mqtt" - "mqtts" -> "mqtt/ssl" - "mqtt+tls" -> "mqtt/ssl" - "mqtt+ssl" -> "mqtt/ssl" + "mqtts" -> "mqtt/ssl" + "mqtt+tls" -> "mqtt/ssl" + "mqtt+ssl" -> "mqtt/ssl" "stomp1.0" -> "stomp" "stomp1.1" -> "stomp" "stomp1.2" -> "stomp" @@ -257,7 +296,7 @@ defmodule RabbitMQ.CLI.Core.Listeners do "stomp1_0" -> "stomp" "stomp1_1" -> "stomp" "stomp1_2" -> "stomp" - "stomps" -> "stomp/ssl" + "stomps" -> "stomp/ssl" "stomp+tls" -> "stomp/ssl" "stomp+ssl" -> "stomp/ssl" "https" -> "https" @@ -304,6 +343,7 @@ defmodule RabbitMQ.CLI.Core.Listeners do # networks address ranges, etc actually works better # for the kind of values we can get here than :inet functions. MK. regex = Regex.recompile!(~r/:/) + case value =~ regex do true -> "[#{value}]" false -> value diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/log_files.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/log_files.ex index ef2874cd63ec..c54b1f3c6ca7 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/log_files.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/log_files.ex @@ -5,29 +5,35 @@ ## Copyright (c) 2019-2022 VMware, Inc. or its affiliates. All rights reserved. defmodule RabbitMQ.CLI.Core.LogFiles do - @spec get_log_locations(atom, integer | :infinity) :: [String.t] | {:badrpc, term} + @spec get_log_locations(atom, integer | :infinity) :: [String.t()] | {:badrpc, term} def get_log_locations(node_name, timeout) do - case :rabbit_misc.rpc_call(node_name, - :rabbit, :log_locations, [], - timeout) do - {:badrpc, _} = error -> error; + case :rabbit_misc.rpc_call(node_name, :rabbit, :log_locations, [], timeout) do + {:badrpc, _} = error -> error list -> Enum.map(list, &to_string/1) end end @spec get_default_log_location(atom, integer | :infinity) :: - {:ok, String.t} | {:badrpc, term} | {:error, term} + {:ok, String.t()} | {:badrpc, term} | {:error, term} def get_default_log_location(node_name, timeout) do case get_log_locations(node_name, timeout) do - {:badrpc, _} = error -> error; - [] -> {:error, "No log files configured on the node"}; + {:badrpc, _} = error -> + error + + [] -> + {:error, "No log files configured on the node"} + [first_log | _] = log_locations -> case get_log_config_file_location(node_name, timeout) do - {:badrpc, _} = error -> error; - nil -> {:ok, first_log}; + {:badrpc, _} = error -> + error + + nil -> + {:ok, first_log} + location -> case Enum.member?(log_locations, location) do - true -> {:ok, to_string(location)}; + true -> {:ok, to_string(location)} false -> {:ok, first_log} end end @@ -35,14 +41,18 @@ defmodule RabbitMQ.CLI.Core.LogFiles do end defp get_log_config_file_location(node_name, timeout) do - case :rabbit_misc.rpc_call(node_name, - :application, :get_env, [:rabbit, :log, :none], - timeout) do - {:badrpc, _} = error -> error; - :none -> nil; + case :rabbit_misc.rpc_call(node_name, :application, :get_env, [:rabbit, :log, :none], timeout) do + {:badrpc, _} = error -> + error + + :none -> + nil + log_config -> case log_config[:file] do - nil -> nil; + nil -> + nil + file_config -> file_config[:file] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/memory.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/memory.ex index 4f82884836ee..cf41f4cef67f 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/memory.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/memory.ex @@ -32,6 +32,7 @@ defmodule RabbitMQ.CLI.Core.Memory do def compute_relative_values(all_pairs) when is_map(all_pairs) do compute_relative_values(Enum.into(all_pairs, [])) end + def compute_relative_values(all_pairs) do num_pairs = Keyword.delete(all_pairs, :strategy) # Includes RSS, allocated and runtime-used ("erlang") values. @@ -56,21 +57,27 @@ defmodule RabbitMQ.CLI.Core.Memory do def formatted_watermark(val) when is_float(val) do %{relative: val} end + def formatted_watermark({:relative, val}) when is_float(val) do %{relative: val} end + def formatted_watermark(:infinity) do %{relative: 1.0} end + def formatted_watermark({:absolute, val}) do %{absolute: parse_watermark(val)} end + def formatted_watermark(val) when is_integer(val) do %{absolute: parse_watermark(val)} end + def formatted_watermark(val) when is_bitstring(val) do %{absolute: parse_watermark(val)} end + def formatted_watermark(val) when is_list(val) do %{absolute: parse_watermark(val)} end @@ -78,21 +85,24 @@ defmodule RabbitMQ.CLI.Core.Memory do def parse_watermark({:absolute, n}) do case IU.parse(n) do {:ok, parsed} -> parsed - err -> err + err -> err end end + def parse_watermark(n) when is_bitstring(n) do case IU.parse(n) do {:ok, parsed} -> parsed - err -> err + err -> err end end + def parse_watermark(n) when is_list(n) do case IU.parse(n) do {:ok, parsed} -> parsed - err -> err + err -> err end end + def parse_watermark(n) when is_float(n) or is_integer(n) do n end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/networking.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/networking.ex index 6dd37273672c..02fb744aa122 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/networking.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/networking.ex @@ -10,14 +10,15 @@ defmodule RabbitMQ.CLI.Core.Networking do @spec address_family(String.t() | atom() | charlist() | binary()) :: address_family() def address_family(value) do val = RabbitMQ.CLI.Core.DataCoercion.to_atom(value) + case val do - :inet -> :inet + :inet -> :inet :inet4 -> :inet :inet6 -> :inet6 - :ipv4 -> :inet - :ipv6 -> :inet6 - :IPv4 -> :inet - :IPv6 -> :inet6 + :ipv4 -> :inet + :ipv6 -> :inet6 + :IPv4 -> :inet + :IPv6 -> :inet6 end end @@ -25,14 +26,15 @@ defmodule RabbitMQ.CLI.Core.Networking do def valid_address_family?(value) when is_atom(value) do valid_address_family?(to_string(value)) end - def valid_address_family?("inet"), do: true + + def valid_address_family?("inet"), do: true def valid_address_family?("inet4"), do: true def valid_address_family?("inet6"), do: true - def valid_address_family?("ipv4"), do: true - def valid_address_family?("ipv6"), do: true - def valid_address_family?("IPv4"), do: true - def valid_address_family?("IPv6"), do: true - def valid_address_family?(_other), do: false + def valid_address_family?("ipv4"), do: true + def valid_address_family?("ipv6"), do: true + def valid_address_family?("IPv4"), do: true + def valid_address_family?("IPv6"), do: true + def valid_address_family?(_other), do: false @spec format_address(:inet.ip_address()) :: String.t() def format_address(addr) do @@ -46,28 +48,37 @@ defmodule RabbitMQ.CLI.Core.Networking do @spec inetrc_map(nonempty_list()) :: map() def inetrc_map(list) do - Enum.reduce(list, %{}, - fn hosts, acc when is_list(hosts) -> - Map.put(acc, "hosts", host_resolution_map(hosts)) - {k, v}, acc when k == :domain or k == :resolv_conf or k == :hosts_file -> - Map.put(acc, to_string(k), to_string(v)) - {k, v}, acc when is_list(v) when k == :search or k == :lookup -> - Map.put(acc, to_string(k), Enum.join(Enum.map(v, &to_string/1), ", ")) - {k, v}, acc when is_integer(v) -> - Map.put(acc, to_string(k), v) - {k, v, v2}, acc when is_tuple(v) when k == :nameserver or k == :nameservers or k == :alt_nameserver -> - Map.put(acc, to_string(k), "#{:inet.ntoa(v)}:#{v2}") - {k, v}, acc when is_tuple(v) when k == :nameserver or k == :nameservers or k == :alt_nameserver -> - Map.put(acc, to_string(k), to_string(:inet.ntoa(v))) - {k, v}, acc -> - Map.put(acc, to_string(k), to_string(v)) - end) + Enum.reduce(list, %{}, fn + hosts, acc when is_list(hosts) -> + Map.put(acc, "hosts", host_resolution_map(hosts)) + + {k, v}, acc when k == :domain or k == :resolv_conf or k == :hosts_file -> + Map.put(acc, to_string(k), to_string(v)) + + {k, v}, acc when is_list(v) when k == :search or k == :lookup -> + Map.put(acc, to_string(k), Enum.join(Enum.map(v, &to_string/1), ", ")) + + {k, v}, acc when is_integer(v) -> + Map.put(acc, to_string(k), v) + + {k, v, v2}, acc + when is_tuple(v) + when k == :nameserver or k == :nameservers or k == :alt_nameserver -> + Map.put(acc, to_string(k), "#{:inet.ntoa(v)}:#{v2}") + + {k, v}, acc + when is_tuple(v) + when k == :nameserver or k == :nameservers or k == :alt_nameserver -> + Map.put(acc, to_string(k), to_string(:inet.ntoa(v))) + + {k, v}, acc -> + Map.put(acc, to_string(k), to_string(v)) + end) end def host_resolution_map(hosts) do - Enum.reduce(hosts, %{}, - fn {:host, address, hosts}, acc -> - Map.put(acc, to_string(:inet.ntoa(address)), Enum.map(hosts, &to_string/1)) - end) + Enum.reduce(hosts, %{}, fn {:host, address, hosts}, acc -> + Map.put(acc, to_string(:inet.ntoa(address)), Enum.map(hosts, &to_string/1)) + end) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/parser.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/parser.ex index b930c307bc1a..b27c4f0d4b27 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/parser.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/parser.ex @@ -70,19 +70,22 @@ defmodule RabbitMQ.CLI.Core.Parser do {[_alias_command_name | cmd_arguments], cmd_options, cmd_invalid} = parse_alias(input, command_name, alias_module, alias_content, options) - {alias_module, command_name, cmd_arguments, Helpers.atomize_values(cmd_options, @atomized_options), cmd_invalid} + {alias_module, command_name, cmd_arguments, + Helpers.atomize_values(cmd_options, @atomized_options), cmd_invalid} command_module when is_atom(command_module) -> {[^command_name | cmd_arguments], cmd_options, cmd_invalid} = parse_command_specific(input, command_module, options) - {command_module, command_name, cmd_arguments, Helpers.atomize_values(cmd_options, @atomized_options), cmd_invalid} + {command_module, command_name, cmd_arguments, + Helpers.atomize_values(cmd_options, @atomized_options), cmd_invalid} end end def command_suggestion(_cmd_name, empty) when empty == %{} do nil end + def command_suggestion(typed, module_map) do RabbitMQ.CLI.AutoComplete.suggest_command(typed, module_map) end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/platform.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/platform.ex index 2a73ff6e8477..4be84f30f926 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/platform.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/platform.ex @@ -14,7 +14,7 @@ defmodule RabbitMQ.CLI.Core.Platform do def line_separator() do case :os.type() do - {:unix, _} -> "\n" + {:unix, _} -> "\n" {:win32, _} -> "\r\n" end end @@ -22,15 +22,19 @@ defmodule RabbitMQ.CLI.Core.Platform do def os_name({:unix, :linux}) do "Linux" end + def os_name({:unix, :darwin}) do "macOS" end + def os_name({:unix, :freebsd}) do "FreeBSD" end + def os_name({:unix, name}) do - name |> to_string |> String.capitalize + name |> to_string |> String.capitalize() end + def os_name({:win32, _}) do "Windows" end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/validators.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/validators.ex index 0973810a7b55..2037ae7fbcc0 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/validators.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/validators.ex @@ -9,7 +9,6 @@ defmodule RabbitMQ.CLI.Core.Validators do alias RabbitMQ.CLI.Core.Helpers import RabbitMQ.CLI.Core.{CodePath, Paths} - def chain([validator | rest], args) do case apply(validator, args) do :ok -> chain(rest, args) diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/version.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/version.ex index 25890955eae9..e27dd0585c21 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/version.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/version.ex @@ -11,14 +11,14 @@ defmodule RabbitMQ.CLI.Core.Version do to_string(:rabbit_misc.version()) end - def remote_version(node_name) do remote_version(node_name, @default_timeout) end + def remote_version(node_name, timeout) do case :rabbit_misc.rpc_call(node_name, :rabbit_misc, :version, [], timeout) do {:badrpc, _} = err -> err - val -> val + val -> val end end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_user_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_user_command.ex index 59423b649a83..30b55ed54ca1 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_user_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_user_command.ex @@ -15,9 +15,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do def validate(args, _) when length(args) < 1, do: {:validation_failure, :not_enough_args} def validate(args, _) when length(args) > 2, do: {:validation_failure, :too_many_args} def validate([_], _), do: :ok + def validate(["", _], _) do {:validation_failure, {:bad_argument, "user cannot be an empty string"}} end + def validate([_, _], _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -28,15 +30,19 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do # Credential validators can be used to require passwords of a certain length # or following a certain pattern. This is a core server responsibility. MK. case Input.infer_password("Password: ", opts) do - :eof -> {:error, :not_enough_args} - password -> :rabbit_misc.rpc_call( - node_name, - :rabbit_auth_backend_internal, - :add_user, - [username, password, Helpers.cli_acting_user()] - ) + :eof -> + {:error, :not_enough_args} + + password -> + :rabbit_misc.rpc_call( + node_name, + :rabbit_auth_backend_internal, + :add_user, + [username, password, Helpers.cli_acting_user()] + ) end end + def run([username, password], %{node: node_name}) do :rabbit_misc.rpc_call( node_name, @@ -49,28 +55,38 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do def output({:error, :not_enough_args}, _) do {:error, ExitCodes.exit_dataerr(), "Password is not provided via argument or stdin"} end + def output({:error, {:user_already_exists, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} already exists"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} already exists"}} end + def output({:error, {:user_already_exists, username}}, _) do {:error, ExitCodes.exit_software(), "User \"#{username}\" already exists"} end + def output(:ok, %{formatter: "json", node: node_name}) do m = %{ - "status" => "ok", - "node" => node_name, - "message" => "Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more." + "status" => "ok", + "node" => node_name, + "message" => + "Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more." } + {:ok, m} end + def output(:ok, opts) do case output_less?(opts) do true -> :ok + false -> - {:ok, "Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more."} + {:ok, + "Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more."} end end + use RabbitMQ.CLI.DefaultOutput def usage, do: "add_user " @@ -78,7 +94,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do def usage_additional() do [ ["", "Self-explanatory"], - ["", "Password this user will authenticate with. Use a blank string to disable password-based authentication."] + [ + "", + "Password this user will authenticate with. Use a blank string to disable password-based authentication." + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex index 589b7d3f10fe..9f1214dd4e3e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex @@ -9,40 +9,95 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do @behaviour RabbitMQ.CLI.CommandBehaviour - def switches(), do: [description: :string, - tags: :string, - default_queue_type: :string] + def switches(), do: [description: :string, tags: :string, default_queue_type: :string] def aliases(), do: [d: :description] def merge_defaults(args, opts) do {args, Map.merge(%{description: "", tags: ""}, opts)} end + use RabbitMQ.CLI.Core.AcceptsOnePositionalArgument use RabbitMQ.CLI.Core.RequiresRabbitAppRunning +<<<<<<< HEAD def run([vhost], %{node: node_name, description: desc, tags: tags, default_queue_type: default_qt}) do meta = %{description: desc, tags: parse_tags(tags), default_queue_type: default_qt} :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, meta, Helpers.cli_acting_user()]) +======= + def run([vhost], %{ + node: node_name, + description: desc, + tags: tags, + default_queue_type: default_qt + }) do + meta = %{description: desc, tags: parse_tags(tags), default_queue_type: default_qt} + # check if the respective feature flag is enabled + case default_qt do + "quorum" -> + FeatureFlags.assert_feature_flag_enabled(node_name, :quorum_queue, fn -> + :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ + vhost, + meta, + Helpers.cli_acting_user() + ]) + end) + + "stream" -> + FeatureFlags.assert_feature_flag_enabled(node_name, :stream_queue, fn -> + :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ + vhost, + meta, + Helpers.cli_acting_user() + ]) + end) + + _ -> + :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ + vhost, + meta, + Helpers.cli_acting_user() + ]) + end +>>>>>>> 059978e6fa (mix format rabbitmq_cli) end + def run([vhost], %{node: node_name, description: desc, tags: tags}) do - :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, desc, tags, Helpers.cli_acting_user()]) + :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ + vhost, + desc, + tags, + Helpers.cli_acting_user() + ]) end + def run([vhost], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, Helpers.cli_acting_user()]) end +<<<<<<< HEAD +======= + def output({:error, :invalid_queue_type}, _opts) do + {:error, ExitCodes.exit_usage(), "Unsupported default queue type"} + end + +>>>>>>> 059978e6fa (mix format rabbitmq_cli) use RabbitMQ.CLI.DefaultOutput - def usage, do: "add_vhost [--description --tags \",,<...>\" --default-queue-type ]" + def usage, + do: + "add_vhost [--description --tags \",,<...>\" --default-queue-type ]" def usage_additional() do [ ["", "Virtual host name"], ["--description ", "Virtual host description"], ["--tags ", "Command separated list of tags"], - ["--default-queue-type ", "Queue type to use if no type is explicitly provided by the client"] + [ + "--default-queue-type ", + "Queue type to use if no type is explicitly provided by the client" + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex index 715d1f0085f6..cf3cccb9634a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex @@ -24,15 +24,19 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AuthenticateUserCommand do # Credential validators can be used to require passwords of a certain length # or following a certain pattern. This is a core server responsibility. MK. case Input.infer_password("Password: ", opts) do - :eof -> {:error, :not_enough_args} - password -> :rabbit_misc.rpc_call( - node_name, - :rabbit_access_control, - :check_user_pass_login, - [user, password] - ) + :eof -> + {:error, :not_enough_args} + + password -> + :rabbit_misc.rpc_call( + node_name, + :rabbit_access_control, + :check_user_pass_login, + [user, password] + ) end end + def run([user, password], %{node: node_name}) do :rabbit_misc.rpc_call( node_name, @@ -59,18 +63,21 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AuthenticateUserCommand do def help_section(), do: :user_management - def description(), do: "Attempts to authenticate a user. Exits with a non-zero code if authentication fails." + def description(), + do: "Attempts to authenticate a user. Exits with a non-zero code if authentication fails." def banner([username | _], _), do: "Authenticating user \"#{username}\" ..." def output({:error, :not_enough_args}, _) do {:error, ExitCodes.exit_software(), "Password is not provided via argument or stdin"} end + def output({:refused, user, msg, args}, _) do {:error, RabbitMQ.CLI.Core.ExitCodes.exit_dataerr(), "Error: failed to authenticate user \"#{user}\"\n" <> to_string(:io_lib.format(msg, args))} end + def output({:ok, _user}, _) do {:ok, "Success"} end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/autocomplete_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/autocomplete_command.ex index 54751b8489cb..053603e2a17c 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/autocomplete_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/autocomplete_command.ex @@ -26,11 +26,13 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AutocompleteCommand do def run(args, %{script_name: script_name}) do {:stream, RabbitMQ.CLI.AutoComplete.complete(script_name, args)} end + def run(args, opts) do script_name = Config.get_system_option(:script_name, opts) {:stream, RabbitMQ.CLI.AutoComplete.complete(script_name, args)} end + use RabbitMQ.CLI.DefaultOutput def usage() do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/await_online_nodes_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/await_online_nodes_command.ex index 25f9e51a055c..3db7980f5bba 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/await_online_nodes_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/await_online_nodes_command.ex @@ -37,9 +37,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AwaitOnlineNodesCommand do use RabbitMQ.CLI.DefaultOutput def banner([count], %{node: node_name, timeout: timeout}) when is_number(timeout) do - "Will wait for at least #{count} nodes to join the cluster of #{node_name}. Timeout: #{ - trunc(timeout / 1000) - } seconds." + "Will wait for at least #{count} nodes to join the cluster of #{node_name}. Timeout: #{trunc(timeout / 1000)} seconds." end def banner([count], %{node: node_name, timeout: _timeout}) do @@ -52,7 +50,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AwaitOnlineNodesCommand do def usage_additional() do [ - ["", "how many cluster members must be up in order for this command to exit. When is 1, always exits immediately."] + [ + "", + "how many cluster members must be up in order for this command to exit. When is 1, always exits immediately." + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_password_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_password_command.ex index eac10be49ce6..58e434dc768f 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_password_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/change_password_command.ex @@ -24,15 +24,19 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ChangePasswordCommand do # Credential validators can be used to require passwords of a certain length # or following a certain pattern. This is a core server responsibility. MK. case Input.infer_password("Password: ", opts) do - :eof -> {:error, :not_enough_args} - password -> :rabbit_misc.rpc_call( - node_name, - :rabbit_auth_backend_internal, - :change_password, - [username, password, Helpers.cli_acting_user()] - ) + :eof -> + {:error, :not_enough_args} + + password -> + :rabbit_misc.rpc_call( + node_name, + :rabbit_auth_backend_internal, + :change_password, + [username, password, Helpers.cli_acting_user()] + ) end end + def run([username, password], %{node: node_name}) do :rabbit_misc.rpc_call( node_name, @@ -45,12 +49,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ChangePasswordCommand do def output({:error, :not_enough_args}, _) do {:error, ExitCodes.exit_software(), "Password is not provided via argument or stdin"} end + def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User \"#{username}\" does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "change_password " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex index d756a9618166..76aebb46d60d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex @@ -25,17 +25,27 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPermissionsCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} end + def output({:error, {:no_such_vhost, vhost}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "Virtual host #{vhost} does not exist"}} + {:error, + %{ + "result" => "error", + "node" => node_name, + "message" => "Virtual host #{vhost} does not exist" + }} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User #{username} does not exist"} end + def output({:error, {:no_such_vhost, vhost}}, _) do {:error, "Virtual host #{vhost} does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "clear_permissions [--vhost ] " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_topic_permissions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_topic_permissions_command.ex index 7d31a89d5692..6c9f5f7002af 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_topic_permissions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_topic_permissions_command.ex @@ -44,17 +44,27 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearTopicPermissionsCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} end + def output({:error, {:no_such_vhost, vhost}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "Virtual host #{vhost} does not exist"}} + {:error, + %{ + "result" => "error", + "node" => node_name, + "message" => "Virtual host #{vhost} does not exist" + }} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User #{username} does not exist"} end + def output({:error, {:no_such_vhost, vhost}}, _) do {:error, "Virtual host #{vhost} does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "clear_topic_permissions [--vhost ] []" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_user_limits_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_user_limits_command.ex index 0d9886b420dd..38f4ded1e50f 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_user_limits_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/clear_user_limits_command.ex @@ -45,6 +45,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearUserLimitsCommand do def banner([username, "all"], %{}) do "Clearing all limits for user \"#{username}\" ..." end + def banner([username, limit_type], %{}) do "Clearing \"#{limit_type}\" limit for user \"#{username}\" ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_connections_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_connections_command.ex index 2a831131fb6a..94f58bdc5965 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_connections_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_all_connections_command.ex @@ -62,18 +62,19 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseAllConnectionsCommand do per_connection_delay: delay, limit: limit }) do - run(args, %{ - node: node_name, - vhost: nil, - global: global_opt, - per_connection_delay: delay, - limit: limit - }) + run(args, %{ + node: node_name, + vhost: nil, + global: global_opt, + per_connection_delay: delay, + limit: limit + }) end def output({:stream, stream}, _opts) do {:stream, Stream.filter(stream, fn x -> x != :ok end)} end + use RabbitMQ.CLI.DefaultOutput def banner([explanation], %{node: node_name, global: true}) do @@ -108,7 +109,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseAllConnectionsCommand do def help_section(), do: :operations - def description(), do: "Instructs the broker to close all connections for the specified vhost or entire RabbitMQ node" + def description(), + do: + "Instructs the broker to close all connections for the specified vhost or entire RabbitMQ node" # # Implementation diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex index bcf1c06d0820..e9db621b6b0e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex @@ -40,7 +40,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseConnectionCommand do def help_section(), do: :operations - def description(), do: "Instructs the broker to close the connection associated with the Erlang process id" + def description(), + do: "Instructs the broker to close the connection associated with the Erlang process id" def banner([pid, explanation], _), do: "Closing connection #{pid}, reason: #{explanation}..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex index ff62c92d386d..d47e5be9e201 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex @@ -47,24 +47,35 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do nodes -> count = length(nodes) - alarms_by_node = Enum.map(nodes, fn n -> alarms_by_node(n, per_node_timeout(timeout, count)) end) - listeners_by_node = Enum.map(nodes, fn n -> listeners_of(n, per_node_timeout(timeout, count)) end) - versions_by_node = Enum.map(nodes, fn n -> versions_by_node(n, per_node_timeout(timeout, count)) end) - maintenance_status_by_node = Enum.map(nodes, - fn n -> maintenance_status_by_node(n, per_node_timeout(timeout, count)) end) - - feature_flags = case :rabbit_misc.rpc_call(node_name, :rabbit_ff_extra, :cli_info, [], timeout) do - {:badrpc, {:EXIT, {:undef, _}}} -> [] - {:badrpc, _} = err -> err - val -> val - end + + alarms_by_node = + Enum.map(nodes, fn n -> alarms_by_node(n, per_node_timeout(timeout, count)) end) + + listeners_by_node = + Enum.map(nodes, fn n -> listeners_of(n, per_node_timeout(timeout, count)) end) + + versions_by_node = + Enum.map(nodes, fn n -> versions_by_node(n, per_node_timeout(timeout, count)) end) + + maintenance_status_by_node = + Enum.map( + nodes, + fn n -> maintenance_status_by_node(n, per_node_timeout(timeout, count)) end + ) + + feature_flags = + case :rabbit_misc.rpc_call(node_name, :rabbit_ff_extra, :cli_info, [], timeout) do + {:badrpc, {:EXIT, {:undef, _}}} -> [] + {:badrpc, _} = err -> err + val -> val + end status ++ - [{:alarms, alarms_by_node}] ++ - [{:listeners, listeners_by_node}] ++ - [{:versions, versions_by_node}] ++ - [{:maintenance_status, maintenance_status_by_node}] ++ - [{:feature_flags, feature_flags}] + [{:alarms, alarms_by_node}] ++ + [{:listeners, listeners_by_node}] ++ + [{:versions, versions_by_node}] ++ + [{:maintenance_status, maintenance_status_by_node}] ++ + [{:feature_flags, feature_flags}] end end end @@ -80,11 +91,12 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do def output(result, %{formatter: "json"}) when is_list(result) do # format more data structures as map for sensible JSON output - m = result_map(result) - |> Map.update(:alarms, [], fn xs -> alarm_maps(xs) end) - |> Map.update(:listeners, %{}, fn m -> - Enum.map(m, fn {n, xs} -> {n, listener_maps(xs)} end) |> Enum.into(%{}) - end) + m = + result_map(result) + |> Map.update(:alarms, [], fn xs -> alarm_maps(xs) end) + |> Map.update(:listeners, %{}, fn m -> + Enum.map(m, fn {n, xs} -> {n, listener_maps(xs)} end) |> Enum.into(%{}) + end) {:ok, m} end @@ -97,62 +109,88 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do "Cluster name: #{m[:cluster_name]}" ] - disk_nodes_section = [ - "\n#{bright("Disk Nodes")}\n", - ] ++ node_lines(m[:disk_nodes]) + disk_nodes_section = + [ + "\n#{bright("Disk Nodes")}\n" + ] ++ node_lines(m[:disk_nodes]) - ram_nodes_section = case m[:ram_nodes] do - [] -> [] - xs -> [ - "\n#{bright("RAM Nodes")}\n", - ] ++ node_lines(xs) - end + ram_nodes_section = + case m[:ram_nodes] do + [] -> + [] + + xs -> + [ + "\n#{bright("RAM Nodes")}\n" + ] ++ node_lines(xs) + end + + running_nodes_section = + [ + "\n#{bright("Running Nodes")}\n" + ] ++ node_lines(m[:running_nodes]) + + versions_section = + [ + "\n#{bright("Versions")}\n" + ] ++ version_lines(m[:versions]) + + alarms_section = + [ + "\n#{bright("Alarms")}\n" + ] ++ + case m[:alarms] do + [] -> ["(none)"] + xs -> alarm_lines(xs, node_name) + end + + partitions_section = + [ + "\n#{bright("Network Partitions")}\n" + ] ++ + case map_size(m[:partitions]) do + 0 -> ["(none)"] + _ -> partition_lines(m[:partitions]) + end + + listeners_section = + [ + "\n#{bright("Listeners")}\n" + ] ++ + case map_size(m[:listeners]) do + 0 -> + ["(none)"] + + _ -> + Enum.reduce(m[:listeners], [], fn {node, listeners}, acc -> + acc ++ listener_lines(listeners, node) + end) + end + + maintenance_section = + [ + "\n#{bright("Maintenance status")}\n" + ] ++ maintenance_lines(m[:maintenance_status]) + + feature_flags_section = + [ + "\n#{bright("Feature flags")}\n" + ] ++ + case Enum.count(m[:feature_flags]) do + 0 -> ["(none)"] + _ -> feature_flag_lines(m[:feature_flags]) + end - running_nodes_section = [ - "\n#{bright("Running Nodes")}\n", - ] ++ node_lines(m[:running_nodes]) - - versions_section = [ - "\n#{bright("Versions")}\n", - ] ++ version_lines(m[:versions]) - - alarms_section = [ - "\n#{bright("Alarms")}\n", - ] ++ case m[:alarms] do - [] -> ["(none)"] - xs -> alarm_lines(xs, node_name) - end - - partitions_section = [ - "\n#{bright("Network Partitions")}\n" - ] ++ case map_size(m[:partitions]) do - 0 -> ["(none)"] - _ -> partition_lines(m[:partitions]) - end - - listeners_section = [ - "\n#{bright("Listeners")}\n" - ] ++ case map_size(m[:listeners]) do - 0 -> ["(none)"] - _ -> Enum.reduce(m[:listeners], [], fn {node, listeners}, acc -> - acc ++ listener_lines(listeners, node) - end) - end - - maintenance_section = [ - "\n#{bright("Maintenance status")}\n", - ] ++ maintenance_lines(m[:maintenance_status]) - - feature_flags_section = [ - "\n#{bright("Feature flags")}\n" - ] ++ case Enum.count(m[:feature_flags]) do - 0 -> ["(none)"] - _ -> feature_flag_lines(m[:feature_flags]) - end - - lines = cluster_name_section ++ disk_nodes_section ++ ram_nodes_section ++ running_nodes_section ++ - versions_section ++ maintenance_section ++ alarms_section ++ partitions_section ++ - listeners_section ++ feature_flags_section + lines = + cluster_name_section ++ + disk_nodes_section ++ + ram_nodes_section ++ + running_nodes_section ++ + versions_section ++ + maintenance_section ++ + alarms_section ++ + partitions_section ++ + listeners_section ++ feature_flags_section {:ok, Enum.join(lines, line_separator())} end @@ -173,7 +211,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do def help_section(), do: :cluster_management - def description(), do: "Displays all the nodes in the cluster grouped by node type, together with the currently running nodes" + def description(), + do: + "Displays all the nodes in the cluster grouped by node type, together with the currently running nodes" def banner(_, %{node: node_name}), do: "Cluster status of node #{node_name} ..." @@ -195,20 +235,22 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do disk_nodes: result |> Keyword.get(:nodes, []) |> Keyword.get(:disc, []), ram_nodes: result |> Keyword.get(:nodes, []) |> Keyword.get(:ram, []), running_nodes: result |> Keyword.get(:running_nodes, []) |> Enum.map(&to_string/1), - alarms: Keyword.get(result, :alarms) |> Keyword.values |> Enum.concat |> Enum.uniq, + alarms: Keyword.get(result, :alarms) |> Keyword.values() |> Enum.concat() |> Enum.uniq(), maintenance_status: Keyword.get(result, :maintenance_status, []) |> Enum.into(%{}), partitions: Keyword.get(result, :partitions, []) |> Enum.into(%{}), listeners: Keyword.get(result, :listeners, []) |> Enum.into(%{}), versions: Keyword.get(result, :versions, []) |> Enum.into(%{}), - feature_flags: Keyword.get(result, :feature_flags, []) |> Enum.map(fn ff -> Enum.into(ff, %{}) end) + feature_flags: + Keyword.get(result, :feature_flags, []) |> Enum.map(fn ff -> Enum.into(ff, %{}) end) } end defp alarms_by_node(node, timeout) do - alarms = case :rabbit_misc.rpc_call(to_atom(node), :rabbit, :alarms, [], timeout) do - {:badrpc, _} -> [] - xs -> xs - end + alarms = + case :rabbit_misc.rpc_call(to_atom(node), :rabbit, :alarms, [], timeout) do + {:badrpc, _} -> [] + xs -> xs + end {node, alarms} end @@ -218,65 +260,103 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do # in the cluster, so why do we run it on every node? See the badrpc clause, # some nodes may be inavailable or partitioned from other nodes. This way we # gather as complete a picture as possible. MK. - listeners = case :rabbit_misc.rpc_call(to_atom(node), :rabbit_networking, :active_listeners, [], timeout) do - {:badrpc, _} -> [] - xs -> xs - end + listeners = + case :rabbit_misc.rpc_call( + to_atom(node), + :rabbit_networking, + :active_listeners, + [], + timeout + ) do + {:badrpc, _} -> [] + xs -> xs + end {node, listeners_on(listeners, node)} end defp versions_by_node(node, timeout) do - {rmq_name, rmq_vsn, otp_vsn} = case :rabbit_misc.rpc_call( - to_atom(node), :rabbit, :product_info, [], timeout) do - {:badrpc, _} -> - {nil, nil, nil} - map -> - %{:otp_release => otp} = map - name = case map do - %{:product_name => v} -> v - %{:product_base_name => v} -> v - end - vsn = case map do - %{:product_version => v} -> v - %{:product_base_version => v} -> v - end - {name, vsn, otp} - end + {rmq_name, rmq_vsn, otp_vsn} = + case :rabbit_misc.rpc_call( + to_atom(node), + :rabbit, + :product_info, + [], + timeout + ) do + {:badrpc, _} -> + {nil, nil, nil} + + map -> + %{:otp_release => otp} = map + + name = + case map do + %{:product_name => v} -> v + %{:product_base_name => v} -> v + end + + vsn = + case map do + %{:product_version => v} -> v + %{:product_base_version => v} -> v + end + + {name, vsn, otp} + end - {node, %{rabbitmq_name: to_string(rmq_name), rabbitmq_version: to_string(rmq_vsn), erlang_version: to_string(otp_vsn)}} + {node, + %{ + rabbitmq_name: to_string(rmq_name), + rabbitmq_version: to_string(rmq_vsn), + erlang_version: to_string(otp_vsn) + }} end defp maintenance_status_by_node(node, timeout) do target = to_atom(node) - result = case :rabbit_misc.rpc_call(target, - :rabbit_maintenance, :status_local_read, [target], timeout) do - {:badrpc, _} -> "unknown" - :regular -> "not under maintenance" - :draining -> magenta("marked for maintenance") - # forward compatibility: should we figure out a way to know when - # draining completes (it involves inherently asynchronous cluster - # operations such as quorum queue leader re-election), we'd introduce - # a new state - :drained -> magenta("marked for maintenance") - value -> to_string(value) - end + + result = + case :rabbit_misc.rpc_call( + target, + :rabbit_maintenance, + :status_local_read, + [target], + timeout + ) do + {:badrpc, _} -> "unknown" + :regular -> "not under maintenance" + :draining -> magenta("marked for maintenance") + # forward compatibility: should we figure out a way to know when + # draining completes (it involves inherently asynchronous cluster + # operations such as quorum queue leader re-election), we'd introduce + # a new state + :drained -> magenta("marked for maintenance") + value -> to_string(value) + end {node, result} end defp node_lines(nodes) do - Enum.map(nodes, &to_string/1) |> Enum.sort + Enum.map(nodes, &to_string/1) |> Enum.sort() end defp version_lines(mapping) do - Enum.map(mapping, fn {node, %{rabbitmq_name: rmq_name, rabbitmq_version: rmq_vsn, erlang_version: otp_vsn}} -> - "#{node}: #{rmq_name} #{rmq_vsn} on Erlang #{otp_vsn}" - end) + Enum.map(mapping, fn {node, + %{ + rabbitmq_name: rmq_name, + rabbitmq_version: rmq_vsn, + erlang_version: otp_vsn + }} -> + "#{node}: #{rmq_name} #{rmq_vsn} on Erlang #{otp_vsn}" + end) end defp partition_lines(mapping) do - Enum.map(mapping, fn {node, unreachable_peers} -> "Node #{node} cannot communicate with #{Enum.join(unreachable_peers, ", ")}" end) + Enum.map(mapping, fn {node, unreachable_peers} -> + "Node #{node} cannot communicate with #{Enum.join(unreachable_peers, ", ")}" + end) end defp maintenance_lines(mapping) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/decode_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/decode_command.ex index f2e1adf2b830..2e4be0540b9f 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/decode_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/decode_command.ex @@ -19,16 +19,22 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DecodeCommand do iterations: :integer ] end + @atomized_keys [:cipher, :hash] def distribution(_), do: :none def merge_defaults(args, opts) do - with_defaults = Map.merge(%{ - cipher: :rabbit_pbe.default_cipher(), - hash: :rabbit_pbe.default_hash(), - iterations: :rabbit_pbe.default_iterations() - }, opts) + with_defaults = + Map.merge( + %{ + cipher: :rabbit_pbe.default_cipher(), + hash: :rabbit_pbe.default_hash(), + iterations: :rabbit_pbe.default_iterations() + }, + opts + ) + {args, Helpers.atomize_values(with_defaults, @atomized_keys)} end @@ -60,7 +66,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DecodeCommand do def run([value], %{cipher: cipher, hash: hash, iterations: iterations} = opts) do case Input.consume_single_line_string_with_prompt("Passphrase: ", opts) do - :eof -> {:error, :not_enough_args} + :eof -> + {:error, :not_enough_args} + passphrase -> try do term_value = Helpers.evaluate_input_as_term(value) @@ -69,6 +77,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DecodeCommand do case term_value do {:encrypted, _} = encrypted -> encrypted + _ -> {:encrypted, term_value} end @@ -91,6 +100,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DecodeCommand do case term_value do {:encrypted, _} = encrypted -> encrypted + _ -> {:encrypted, term_value} end @@ -110,7 +120,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DecodeCommand do "Decrypting value..." end - def usage, do: "decode value passphrase [--cipher ] [--hash ] [--iterations ]" + def usage, + do: "decode value passphrase [--cipher ] [--hash ] [--iterations ]" def usage_additional() do [ diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex index 7ab1e1304e43..9ee72042fdc0 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex @@ -23,11 +23,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteUserCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User \"#{username}\" does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "delete_user " @@ -46,7 +49,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteUserCommand do def help_section(), do: :user_management - def description(), do: "Removes a user from the internal database. Has no effect on users provided by external backends such as LDAP" + def description(), + do: + "Removes a user from the internal database. Has no effect on users provided by external backends such as LDAP" def banner([arg], _), do: "Deleting user \"#{arg}\" ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/enable_feature_flag_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/enable_feature_flag_command.ex index 8cc34aa095c1..be421d14a5df 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/enable_feature_flag_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/enable_feature_flag_command.ex @@ -4,15 +4,17 @@ ## ## Copyright (c) 2018-2022 VMware, Inc. or its affiliates. All rights reserved. - defmodule RabbitMQ.CLI.Ctl.Commands.EnableFeatureFlagCommand do @behaviour RabbitMQ.CLI.CommandBehaviour def merge_defaults(args, opts), do: {args, opts} def validate([], _), do: {:validation_failure, :not_enough_args} - def validate([_|_] = args, _) when length(args) > 1, do: {:validation_failure, :too_many_args} - def validate([""], _), do: {:validation_failure, {:bad_argument, "feature_flag cannot be an empty string."}} + def validate([_ | _] = args, _) when length(args) > 1, do: {:validation_failure, :too_many_args} + + def validate([""], _), + do: {:validation_failure, {:bad_argument, "feature_flag cannot be an empty string."}} + def validate([_], _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -22,37 +24,45 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EnableFeatureFlagCommand do # Server does not support feature flags, consider none are available. # See rabbitmq/rabbitmq-cli#344 for context. MK. {:badrpc, {:EXIT, {:undef, _}}} -> {:error, :unsupported} - {:badrpc, _} = err -> err - other -> other + {:badrpc, _} = err -> err + other -> other end end def run([feature_flag], %{node: node_name}) do - case :rabbit_misc.rpc_call(node_name, :rabbit_feature_flags, :enable, [String.to_atom(feature_flag)]) do + case :rabbit_misc.rpc_call(node_name, :rabbit_feature_flags, :enable, [ + String.to_atom(feature_flag) + ]) do # Server does not support feature flags, consider none are available. # See rabbitmq/rabbitmq-cli#344 for context. MK. {:badrpc, {:EXIT, {:undef, _}}} -> {:error, :unsupported} - {:badrpc, _} = err -> err - other -> other + {:badrpc, _} = err -> err + other -> other end end def output({:error, :unsupported}, %{node: node_name}) do - {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage, "This feature flag is not supported by node #{node_name}"} + {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage(), + "This feature flag is not supported by node #{node_name}"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "enable_feature_flag " def usage_additional() do - [ - ["", "name of the feature flag to enable, or \"all\" to enable all supported flags"] - ] -end + [ + [ + "", + "name of the feature flag to enable, or \"all\" to enable all supported flags" + ] + ] + end def help_section(), do: :feature_flags - def description(), do: "Enables a feature flag or all supported feature flags on the target node" + def description(), + do: "Enables a feature flag or all supported feature flags on the target node" def banner(["all"], _), do: "Enabling all feature flags ..." diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/encode_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/encode_command.ex index 976bbfe7755b..2d53978b8923 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/encode_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/encode_command.ex @@ -17,16 +17,22 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do iterations: :integer ] end + @atomized_keys [:cipher, :hash] def distribution(_), do: :none def merge_defaults(args, opts) do - with_defaults = Map.merge(%{ - cipher: :rabbit_pbe.default_cipher(), - hash: :rabbit_pbe.default_hash(), - iterations: :rabbit_pbe.default_iterations() - }, opts) + with_defaults = + Map.merge( + %{ + cipher: :rabbit_pbe.default_cipher(), + hash: :rabbit_pbe.default_hash(), + iterations: :rabbit_pbe.default_iterations() + }, + opts + ) + {args, Helpers.atomize_values(with_defaults, @atomized_keys)} end @@ -52,14 +58,22 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do def run([], %{cipher: cipher, hash: hash, iterations: iterations} = opts) do case Input.consume_single_line_string_with_prompt("Value to encode: ", opts) do - :eof -> {:error, :not_enough_args} + :eof -> + {:error, :not_enough_args} + value -> case Input.consume_single_line_string_with_prompt("Passphrase: ", opts) do - :eof -> {:error, :not_enough_args} + :eof -> + {:error, :not_enough_args} + passphrase -> try do term_value = Helpers.evaluate_input_as_term(value) - result = {:encrypted, _} = :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + + result = + {:encrypted, _} = + :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + {:ok, result} catch _, _ -> @@ -71,11 +85,17 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do def run([value], %{cipher: cipher, hash: hash, iterations: iterations} = opts) do case Input.consume_single_line_string_with_prompt("Passphrase: ", opts) do - :eof -> {:error, :not_enough_args} + :eof -> + {:error, :not_enough_args} + passphrase -> try do term_value = Helpers.evaluate_input_as_term(value) - result = {:encrypted, _} = :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + + result = + {:encrypted, _} = + :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + {:ok, result} catch _, _ -> @@ -87,7 +107,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do def run([value, passphrase], %{cipher: cipher, hash: hash, iterations: iterations}) do try do term_value = Helpers.evaluate_input_as_term(value) - result = {:encrypted, _} = :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + + result = + {:encrypted, _} = + :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, term_value) + {:ok, result} catch _, _ -> @@ -101,7 +125,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EncodeCommand do "Encrypting value ..." end - def usage, do: "encode value passphrase [--cipher ] [--hash ] [--iterations ]" + def usage, + do: "encode value passphrase [--cipher ] [--hash ] [--iterations ]" def usage_additional() do [ diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/environment_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/environment_command.ex index 67411e0819ba..649464fd2a24 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/environment_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/environment_command.ex @@ -32,7 +32,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EnvironmentCommand do def help_section(), do: :configuration - def description(), do: "Displays the name and value of each variable in the application environment for each running application" + def description(), + do: + "Displays the name and value of each variable in the application environment for each running application" def banner(_, %{node: node_name}), do: "Application environment of node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_command.ex index 9a8d8fa32916..1e46854d804d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_command.ex @@ -29,7 +29,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalCommand do def run([], %{node: node_name} = opts) do case Input.consume_multiline_string() do - :eof -> {:error, :not_enough_args} + :eof -> + {:error, :not_enough_args} + expr -> case ErlEval.parse_expr(expr) do {:ok, parsed} -> @@ -37,13 +39,15 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalCommand do case :rabbit_misc.rpc_call(node_name, :erl_eval, :exprs, [parsed, bindings]) do {:value, value, _} -> {:ok, value} - err -> err + err -> err end - {:error, msg} -> {:error, msg} + {:error, msg} -> + {:error, msg} end end end + def run([expr | arguments], %{node: node_name} = opts) do case ErlEval.parse_expr(expr) do {:ok, parsed} -> @@ -51,19 +55,23 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalCommand do case :rabbit_misc.rpc_call(node_name, :erl_eval, :exprs, [parsed, bindings]) do {:value, value, _} -> {:ok, value} - err -> err + err -> err end - {:error, msg} -> {:error, msg} + {:error, msg} -> + {:error, msg} end end def output({:error, :not_enough_args}, _) do - {:error, ExitCodes.exit_dataerr(), "Expression to evaluate is not provided via argument or stdin"} + {:error, ExitCodes.exit_dataerr(), + "Expression to evaluate is not provided via argument or stdin"} end + def output({:error, msg}, _) do {:error, ExitCodes.exit_dataerr(), "Evaluation failed: #{msg}"} end + use RabbitMQ.CLI.DefaultOutput def formatter(), do: RabbitMQ.CLI.Formatters.Erlang diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_file_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_file_command.ex index 0c1e8d8ad225..f6e3e06dd14d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_file_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/eval_file_command.ex @@ -24,13 +24,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalFileCommand do case File.read(file_path) do {:ok, expr} -> case ErlEval.parse_expr(expr) do - {:ok, _} -> :ok + {:ok, _} -> :ok {:error, err} -> {:validation_failure, err} end + {:error, :enoent} -> {:validation_failure, "File #{file_path} does not exist"} + {:error, :eacces} -> {:validation_failure, "Insufficient permissions to read file #{file_path}"} + {:error, err} -> {:validation_failure, err} end @@ -38,15 +41,15 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalFileCommand do def run([file_path], opts) do case File.read(file_path) do - {:ok, expr} -> EvalCommand.run([expr], opts) + {:ok, expr} -> EvalCommand.run([expr], opts) {:error, err} -> {:error, err} end - end def output({:error, msg}, _) do {:error, ExitCodes.exit_dataerr(), "Evaluation failed: #{msg}"} end + use RabbitMQ.CLI.DefaultOutput def formatter(), do: RabbitMQ.CLI.Formatters.Erlang @@ -69,7 +72,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalFileCommand do def help_section(), do: :operations - def description(), do: "Evaluates a file that contains a snippet of Erlang code on the target node" + def description(), + do: "Evaluates a file that contains a snippet of Erlang code on the target node" def banner(_, _), do: nil end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/export_definitions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/export_definitions_command.ex index 2aeb251c7907..dffde7cf247e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/export_definitions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/export_definitions_command.ex @@ -12,6 +12,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do def merge_defaults(["-"] = args, opts) do {args, Map.merge(%{format: "json", silent: true}, Helpers.case_insensitive_format(opts))} end + def merge_defaults(args, opts) do {args, Map.merge(%{format: "json"}, Helpers.case_insensitive_format(opts))} end @@ -23,23 +24,29 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do when format != "json" and format != "JSON" and format != "erlang" do {:validation_failure, {:bad_argument, "Format should be either json or erlang"}} end + def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 1 do {:validation_failure, :too_many_args} end + # output to stdout def validate(["-"], _) do :ok end + def validate([path], _) do dir = Path.dirname(path) - case File.exists?(dir, [raw: true]) do - true -> :ok + + case File.exists?(dir, raw: true) do + true -> :ok false -> {:validation_failure, {:bad_argument, "Directory #{dir} does not exist"}} end end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -51,46 +58,66 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do result -> {:ok, result} end end + def run([path], %{node: node_name, timeout: timeout, format: format}) do case :rabbit_misc.rpc_call(node_name, :rabbit_definitions, :all_definitions, [], timeout) do - {:badrpc, _} = err -> err - {:error, _} = err -> err - {:error, _, _} = err -> err + {:badrpc, _} = err -> + err + + {:error, _} = err -> + err + + {:error, _, _} = err -> + err + result -> - # write to the file in run/2 because output/2 is not meant to - # produce side effects - body = serialise(result, format) - abs_path = Path.absname(path) - - File.rm(abs_path) - case File.write(abs_path, body) do - # no output - :ok -> {:ok, nil} - {:error, :enoent} -> - {:error, ExitCodes.exit_dataerr(), "Parent directory or file #{path} does not exist"} - {:error, :enotdir} -> - {:error, ExitCodes.exit_dataerr(), "Parent directory of file #{path} is not a directory"} - {:error, :enospc} -> - {:error, ExitCodes.exit_dataerr(), "No space left on device hosting #{path}"} - {:error, :eacces} -> - {:error, ExitCodes.exit_dataerr(), "No permissions to write to file #{path} or its parent directory"} - {:error, :eisdir} -> - {:error, ExitCodes.exit_dataerr(), "Path #{path} is a directory"} - {:error, err} -> - {:error, ExitCodes.exit_dataerr(), "Could not write to file #{path}: #{err}"} - end + # write to the file in run/2 because output/2 is not meant to + # produce side effects + body = serialise(result, format) + abs_path = Path.absname(path) + + File.rm(abs_path) + + case File.write(abs_path, body) do + # no output + :ok -> + {:ok, nil} + + {:error, :enoent} -> + {:error, ExitCodes.exit_dataerr(), "Parent directory or file #{path} does not exist"} + + {:error, :enotdir} -> + {:error, ExitCodes.exit_dataerr(), + "Parent directory of file #{path} is not a directory"} + + {:error, :enospc} -> + {:error, ExitCodes.exit_dataerr(), "No space left on device hosting #{path}"} + + {:error, :eacces} -> + {:error, ExitCodes.exit_dataerr(), + "No permissions to write to file #{path} or its parent directory"} + + {:error, :eisdir} -> + {:error, ExitCodes.exit_dataerr(), "Path #{path} is a directory"} + + {:error, err} -> + {:error, ExitCodes.exit_dataerr(), "Could not write to file #{path}: #{err}"} + end end end def output({:ok, nil}, _) do {:ok, nil} end + def output({:ok, result}, %{format: "json"}) when is_map(result) do {:ok, serialise(result, "json")} end + def output({:ok, result}, %{format: "erlang"}) when is_map(result) do {:ok, serialise(result, "erlang")} end + use RabbitMQ.CLI.DefaultOutput def printer(), do: RabbitMQ.CLI.Printers.StdIORaw @@ -114,7 +141,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do def description(), do: "Exports definitions in JSON or compressed Erlang Term Format." - def banner([path], %{format: fmt}), do: "Exporting definitions in #{human_friendly_format(fmt)} to a file at \"#{path}\" ..." + def banner([path], %{format: fmt}), + do: "Exporting definitions in #{human_friendly_format(fmt)} to a file at \"#{path}\" ..." # # Implementation @@ -124,11 +152,13 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExportDefinitionsCommand do # make sure all runtime parameter values are maps, otherwise # they will end up being a list of pairs (a keyword list/proplist) # in the resulting JSON document - map = Map.update!(raw_map, :parameters, fn(params) -> - Enum.map(params, fn(param) -> - Map.update!(param, "value", &:rabbit_data_coercion.to_map/1) + map = + Map.update!(raw_map, :parameters, fn params -> + Enum.map(params, fn param -> + Map.update!(param, "value", &:rabbit_data_coercion.to_map/1) + end) end) - end) + {:ok, json} = JSON.encode(map) json end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_boot_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_boot_command.ex index 4b4d0340ecf8..01de7f208762 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_boot_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_boot_command.ex @@ -51,7 +51,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceBootCommand do def help_section(), do: :cluster_management - def description(), do: "Forces node to start even if it cannot contact or rejoin any of its previously known peers" + def description(), + do: + "Forces node to start even if it cannot contact or rejoin any of its previously known peers" def banner(_, _), do: nil end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_gc_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_gc_command.ex index f646e6b7fd9c..ca6285848cc2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_gc_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_gc_command.ex @@ -29,7 +29,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceGcCommand do def help_section(), do: :operations - def description, do: "Makes all Erlang processes on the target node perform/schedule a full sweep garbage collection" + def description, + do: + "Makes all Erlang processes on the target node perform/schedule a full sweep garbage collection" - def banner([], %{node: node_name}), do: "Will ask all processes on node #{node_name} to schedule a full sweep GC" + def banner([], %{node: node_name}), + do: "Will ask all processes on node #{node_name} to schedule a full sweep GC" end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex index a98cffe573c9..b4aabede1039 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex @@ -19,7 +19,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceResetCommand do def output({:error, :mnesia_unexpectedly_running}, %{node: node_name}) do {:error, ExitCodes.exit_software(), - RabbitMQ.CLI.DefaultOutput.mnesia_running_error(node_name)} + RabbitMQ.CLI.DefaultOutput.mnesia_running_error(node_name)} end use RabbitMQ.CLI.DefaultOutput diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/forget_cluster_node_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/forget_cluster_node_command.ex index deaff99d45dc..7c9e551d4ca2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/forget_cluster_node_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/forget_cluster_node_command.ex @@ -46,19 +46,31 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForgetClusterNodeCommand do def run([node_to_remove], %{node: node_name, offline: false}) do atom_name = to_atom(node_to_remove) - args = [atom_name, false] + args = [atom_name, false] + case :rabbit_misc.rpc_call(node_name, :rabbit_mnesia, :forget_cluster_node, args) do {:error, {:failed_to_remove_node, ^atom_name, {:active, _, _}}} -> - {:error, "RabbitMQ on node #{node_to_remove} must be stopped with 'rabbitmqctl -n #{node_to_remove} stop_app' before it can be removed"}; - {:error, _} = error -> error; - {:badrpc, _} = error -> error; + {:error, + "RabbitMQ on node #{node_to_remove} must be stopped with 'rabbitmqctl -n #{node_to_remove} stop_app' before it can be removed"} + + {:error, _} = error -> + error + + {:badrpc, _} = error -> + error + :ok -> case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :shrink_all, [atom_name]) do {:error, _} -> - {:error, "RabbitMQ failed to shrink some of the quorum queues on node #{node_to_remove}"}; - _ -> :ok + {:error, + "RabbitMQ failed to shrink some of the quorum queues on node #{node_to_remove}"} + + _ -> + :ok end - other -> other + + other -> + other end end @@ -70,7 +82,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForgetClusterNodeCommand do def usage_additional() do [ - ["--offline", "try to update cluster membership state directly. Use when target node is stopped. Only works for local nodes."] + [ + "--offline", + "try to update cluster membership state directly. Use when target node is stopped. Only works for local nodes." + ] ] end @@ -88,6 +103,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForgetClusterNodeCommand do def banner([node_to_remove], %{offline: true}) do "Removing node #{node_to_remove} from the cluster. Warning: quorum queues cannot be shrunk in offline mode" end + def banner([node_to_remove], _) do "Removing node #{node_to_remove} from the cluster" end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/help_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/help_command.ex index a3ebad67f7ce..ffa3a40e5973 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/help_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/help_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do def validate([], _), do: :ok def validate([_command], _), do: :ok + def validate(args, _) when length(args) > 1 do {:validation_failure, :too_many_args} end @@ -30,15 +31,19 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do CommandModules.load(opts) module_map = CommandModules.module_map() + case module_map[command_name] do nil -> # command not found # {:error, all_usage(opts)} case RabbitMQ.CLI.AutoComplete.suggest_command(command_name, module_map) do {:suggest, suggested} -> - suggest_message = "\nCommand '#{command_name}' not found. \n" <> - "Did you mean '#{suggested}'? \n" + suggest_message = + "\nCommand '#{command_name}' not found. \n" <> + "Did you mean '#{suggested}'? \n" + {:error, ExitCodes.exit_usage(), suggest_message} + nil -> {:error, ExitCodes.exit_usage(), "\nCommand '#{command_name}' not found."} end @@ -54,6 +59,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do case opts[:list_commands] do true -> {:ok, commands_description()} + _ -> {:ok, all_usage(opts)} end @@ -62,9 +68,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do def output({:ok, result}, _) do {:ok, result} end + def output({:error, result}, _) do {:error, ExitCodes.exit_usage(), result} end + use RabbitMQ.CLI.DefaultOutput def banner(_, _), do: nil @@ -81,25 +89,28 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do ] end - # # Implementation # def all_usage(opts) do tool_name = program_name(opts) + tool_usage(tool_name) ++ - ["\n\nAvailable commands:\n"] ++ commands_description() ++ - help_footer(tool_name) + ["\n\nAvailable commands:\n"] ++ + commands_description() ++ + help_footer(tool_name) end def command_usage(command, opts) do - Enum.join([base_usage(command, opts)] ++ - command_description(command) ++ - additional_usage(command) ++ - relevant_doc_guides(command) ++ - general_options_usage(), - "\n\n") <> "\n" + Enum.join( + [base_usage(command, opts)] ++ + command_description(command) ++ + additional_usage(command) ++ + relevant_doc_guides(command) ++ + general_options_usage(), + "\n\n" + ) <> "\n" end defp tool_usage(tool_name) do @@ -137,7 +148,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do defp general_options_usage() do [ - "#{bright("General Options")} + "#{bright("General Options")} The following options are accepted by most or all commands. @@ -154,12 +165,13 @@ short | long | description | | virtual host to use | --formatter | alternative result formatter to use | if supported: json, pretty_table, table, csv, erlang - not all commands support all (or any) alternative formatters."] + not all commands support all (or any) alternative formatters." + ] end defp command_description(command) do case CommandBehaviour.description(command) do - "" -> [] + "" -> [] other -> [other <> ".\n"] end end @@ -167,9 +179,11 @@ short | long | description defp list_item_formatter([option, description]) do "#{option}\n\t#{description}\n" end + defp list_item_formatter({option, description}) do "#{option}\n\t#{description}\n" end + defp list_item_formatter(line) do "#{line}\n" end @@ -180,8 +194,11 @@ short | long | description list when is_list(list) -> list |> Enum.map(&list_item_formatter/1) bin when is_binary(bin) -> ["#{bin}\n"] end + case command_usage do - [] -> [] + [] -> + [] + usage -> [flatten_string(["#{bright("Arguments and Options")}\n" | usage], "")] end @@ -193,8 +210,11 @@ short | long | description list when is_list(list) -> list |> Enum.map(fn ln -> " * #{ln}\n" end) bin when is_binary(bin) -> [" * #{bin}\n"] end + case guide_list do - [] -> [] + [] -> + [] + usage -> [flatten_string(["#{bright("Relevant Doc Guides")}\n" | usage], "")] end @@ -211,25 +231,25 @@ short | long | description defp commands_description() do module_map = CommandModules.module_map() - pad_commands_to = Enum.reduce(module_map, 0, - fn({name, _}, longest) -> + pad_commands_to = + Enum.reduce(module_map, 0, fn {name, _}, longest -> name_length = String.length(name) + case name_length > longest do - true -> name_length + true -> name_length false -> longest end end) - lines = module_map - |> Enum.map( - fn({name, cmd}) -> + lines = + module_map + |> Enum.map(fn {name, cmd} -> description = CommandBehaviour.description(cmd) help_section = CommandBehaviour.help_section(cmd) {name, {description, help_section}} end) - |> Enum.group_by(fn({_, {_, help_section}}) -> help_section end) - |> Enum.sort_by( - fn({help_section, _}) -> + |> Enum.group_by(fn {_, {_, help_section}} -> help_section end) + |> Enum.sort_by(fn {help_section, _} -> case help_section do :deprecated -> 999 :other -> 100 @@ -247,19 +267,16 @@ short | long | description _ -> 98 end end) - |> Enum.map( - fn({help_section, section_helps}) -> + |> Enum.map(fn {help_section, section_helps} -> [ - "\n" <> bright(section_head(help_section)) <> ":\n\n" | - Enum.sort(section_helps) - |> Enum.map( - fn({name, {description, _}}) -> + "\n" <> bright(section_head(help_section)) <> ":\n\n" + | Enum.sort(section_helps) + |> Enum.map(fn {name, {description, _}} -> " #{String.pad_trailing(name, pad_commands_to)} #{description}\n" end) ] - end) - |> Enum.concat() + |> Enum.concat() lines ++ ["\n"] end @@ -268,34 +285,49 @@ short | long | description case help_section do :help -> "Help" + :user_management -> "Users" + :cluster_management -> "Cluster" + :replication -> "Replication" + :node_management -> "Nodes" + :queues -> "Queues" + :observability_and_health_checks -> "Monitoring, observability and health checks" + :virtual_hosts -> - "Virtual hosts" + "Virtual hosts" + :access_control -> "Access Control" + :parameters -> "Parameters" + :policies -> "Policies" + :configuration -> "Configuration and Environment" + :feature_flags -> "Feature flags" + :other -> "Other" + {:plugin, plugin} -> plugin_section(plugin) <> " plugin" + custom -> snake_case_to_capitalized_string(custom) end @@ -307,16 +339,16 @@ short | long | description defp format_known_plugin_name_fragments(value) do case value do - ["amqp1.0"] -> "AMQP 1.0" + ["amqp1.0"] -> "AMQP 1.0" ["amqp1", "0"] -> "AMQP 1.0" - ["management"] -> "Management" - ["management", "agent"] -> "Management" - ["mqtt"] -> "MQTT" - ["stomp"] -> "STOMP" - ["web", "mqtt"] -> "Web MQTT" + ["management"] -> "Management" + ["management", "agent"] -> "Management" + ["mqtt"] -> "MQTT" + ["stomp"] -> "STOMP" + ["web", "mqtt"] -> "Web MQTT" ["web", "stomp"] -> "Web STOMP" - [other] -> snake_case_to_capitalized_string(other) - fragments -> snake_case_to_capitalized_string(Enum.join(fragments, "_")) + [other] -> snake_case_to_capitalized_string(other) + fragments -> snake_case_to_capitalized_string(Enum.join(fragments, "_")) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/hipe_compile_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/hipe_compile_command.ex index d7d6aa8985e8..11d7c00b81cc 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/hipe_compile_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/hipe_compile_command.ex @@ -60,6 +60,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HipeCompileCommand do def run([_target_dir], _opts) do :ok end + use RabbitMQ.CLI.DefaultOutput def usage, do: "hipe_compile " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/import_definitions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/import_definitions_command.ex index 04bae01cc767..958fcbe28b1f 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/import_definitions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/import_definitions_command.ex @@ -12,8 +12,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ImportDefinitionsCommand do def merge_defaults(["-"] = args, opts) do {args, Map.merge(%{format: "json", silent: true}, Helpers.case_insensitive_format(opts))} end + def merge_defaults(args, opts) do - {args, Map.merge(%{format: "json", skip_if_unchanged: false}, Helpers.case_insensitive_format(opts))} + {args, + Map.merge(%{format: "json", skip_if_unchanged: false}, Helpers.case_insensitive_format(opts))} end def switches(), do: [timeout: :integer, format: :string, skip_if_unchanged: :boolean] @@ -23,63 +25,86 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ImportDefinitionsCommand do when format != "json" and format != "JSON" and format != "erlang" do {:validation_failure, {:bad_argument, "Format should be either json or erlang"}} end + def validate(args, _) when length(args) > 1 do {:validation_failure, :too_many_args} end + def validate([path], _) do - case File.exists?(path, [raw: true]) do - true -> :ok + case File.exists?(path, raw: true) do + true -> :ok false -> {:validation_failure, {:bad_argument, "File #{path} does not exist"}} end end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([], %{node: node_name, format: format, timeout: timeout}) do case IO.read(:stdio, :all) do - :eof -> {:error, :not_enough_args} - bin -> + :eof -> + {:error, :not_enough_args} + + bin -> case deserialise(bin, format) do {:error, error} -> - {:error, ExitCodes.exit_dataerr(), "Failed to deserialise input (format: #{human_friendly_format(format)}) (error: #{inspect(error)})"} + {:error, ExitCodes.exit_dataerr(), + "Failed to deserialise input (format: #{human_friendly_format(format)}) (error: #{inspect(error)})"} + {:ok, map} -> skip? = Map.get(map, :skip_if_unchanged, false) - fun = case skip? do - true -> :import_parsed_with_hashing - false -> :import_parsed - end + + fun = + case skip? do + true -> :import_parsed_with_hashing + false -> :import_parsed + end + :rabbit_misc.rpc_call(node_name, :rabbit_definitions, fun, [map], timeout) end end end + def run([path], %{node: node_name, format: format, timeout: timeout}) do abs_path = Path.absname(path) case File.read(abs_path) do {:ok, ""} -> {:error, ExitCodes.exit_dataerr(), "File #{path} is zero-sized"} + {:ok, bin} -> case deserialise(bin, format) do {:error, error} -> - {:error, ExitCodes.exit_dataerr(), "Failed to deserialise input (format: #{human_friendly_format(format)}) (error: #{inspect(error)})"} + {:error, ExitCodes.exit_dataerr(), + "Failed to deserialise input (format: #{human_friendly_format(format)}) (error: #{inspect(error)})"} + {:ok, map} -> skip? = Map.get(map, :skip_if_unchanged, false) - fun = case skip? do - true -> :import_parsed_with_hashing - false -> :import_parsed - end + + fun = + case skip? do + true -> :import_parsed_with_hashing + false -> :import_parsed + end + :rabbit_misc.rpc_call(node_name, :rabbit_definitions, fun, [map], timeout) end - {:error, :enoent} -> + + {:error, :enoent} -> {:error, ExitCodes.exit_dataerr(), "Parent directory or file #{path} does not exist"} + {:error, :enotdir} -> {:error, ExitCodes.exit_dataerr(), "Parent directory of file #{path} is not a directory"} + {:error, :eacces} -> - {:error, ExitCodes.exit_dataerr(), "No permissions to read from file #{path} or its parent directory"} + {:error, ExitCodes.exit_dataerr(), + "No permissions to read from file #{path} or its parent directory"} + {:error, :eisdir} -> {:error, ExitCodes.exit_dataerr(), "Path #{path} is a directory"} - {:error, err} -> + + {:error, err} -> {:error, ExitCodes.exit_dataerr(), "Could not read from file #{path}: #{err}"} end end @@ -87,24 +112,34 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ImportDefinitionsCommand do def output(:ok, %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name}} end + def output(:ok, opts) do case Config.output_less?(opts) do - true -> :ok - false -> {:ok, "Successfully started definition import. " <> - "This process is asynchronous and can take some time.\n"} + true -> + :ok + + false -> + {:ok, + "Successfully started definition import. " <> + "This process is asynchronous and can take some time.\n"} end end + use RabbitMQ.CLI.DefaultOutput def printer(), do: RabbitMQ.CLI.Printers.StdIORaw - def usage, do: "import_definitions [--format ] [--skip-if-unchanged]" + def usage, + do: "import_definitions [--format ] [--skip-if-unchanged]" def usage_additional() do [ ["[file]", "Local file path to import from. If omitted will be read from standard input"], ["--format", "input format to use: json or erlang"], - ["--skip-if-unchanged", "Avoids repetitive definition imports when file contents are unchanged. Target node must be configured accordingly"] + [ + "--skip-if-unchanged", + "Avoids repetitive definition imports when file contents are unchanged. Target node must be configured accordingly" + ] ] end @@ -121,6 +156,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ImportDefinitionsCommand do def banner([], %{format: fmt}) do "Importing definitions in #{human_friendly_format(fmt)} from standard input ..." end + def banner([path], %{format: fmt}) do "Importing definitions in #{human_friendly_format(fmt)} from a file at \"#{path}\" ..." end @@ -136,8 +172,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ImportDefinitionsCommand do defp deserialise(bin, "erlang") do try do {:ok, :erlang.binary_to_term(bin)} - rescue e in ArgumentError -> - {:error, e.message} + rescue + e in ArgumentError -> + {:error, e.message} end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex index d23ceec3d8f6..5dcd1e67e950 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex @@ -77,8 +77,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do def usage_additional() do [ ["", "Existing cluster member (node) to join"], - ["--disc", "new node should be a disk one (stores its schema on disk). Highly recommended, used by default."], - ["--ram", "new node should be a RAM one (stores schema in RAM). Not recommended. Consult clustering doc guides first."] + [ + "--disc", + "new node should be a disk one (stores its schema on disk). Highly recommended, used by default." + ], + [ + "--ram", + "new node should be a RAM one (stores schema in RAM). Not recommended. Consult clustering doc guides first." + ] ] end @@ -91,5 +97,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do def help_section(), do: :cluster_management - def description(), do: "Instructs the node to become a member of the cluster that the specified node is in" + def description(), + do: "Instructs the node to become a member of the cluster that the specified node is in" end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex index 40b8da2e1a73..517936640c5b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex @@ -43,9 +43,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConsumersCommand do Helpers.with_nodes_in_cluster(node_name, fn nodes -> RpcStream.receive_list_items_with_fun( node_name, - [{:rabbit_amqqueue, - :emit_consumers_all, - [nodes, vhost]}], + [{:rabbit_amqqueue, :emit_consumers_all, [nodes, vhost]}], timeout, info_keys, Kernel.length(nodes), @@ -91,15 +89,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConsumersCommand do def fill_consumer_active_fields({items, {chunk, :continue}}) do {Enum.map(items, fn item -> - case Keyword.has_key?(item, :active) do - true -> - item - false -> - Keyword.drop(item, [:arguments]) - ++ [active: true, activity_status: :up] - ++ [arguments: Keyword.get(item, :arguments, [])] - end - end), {chunk, :continue}} + case Keyword.has_key?(item, :active) do + true -> + item + + false -> + Keyword.drop(item, [:arguments]) ++ + [active: true, activity_status: :up] ++ + [arguments: Keyword.get(item, :arguments, [])] + end + end), {chunk, :continue}} end def fill_consumer_active_fields(v) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_feature_flags_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_feature_flags_command.ex index 043260fbc4fc..2ab9da861e73 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_feature_flags_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_feature_flags_command.ex @@ -4,7 +4,6 @@ ## ## Copyright (c) 2018-2022 VMware, Inc. or its affiliates. All rights reserved. - defmodule RabbitMQ.CLI.Ctl.Commands.ListFeatureFlagsCommand do alias RabbitMQ.CLI.Core.{DocGuide, Validators} alias RabbitMQ.CLI.Ctl.InfoKeys @@ -41,15 +40,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListFeatureFlagsCommand do ) end - def run([_|_] = args, %{node: node_name, timeout: timeout}) do + def run([_ | _] = args, %{node: node_name, timeout: timeout}) do case :rabbit_misc.rpc_call(node_name, :rabbit_ff_extra, :cli_info, [], timeout) do # Server does not support feature flags, consider none are available. # See rabbitmq/rabbitmq-cli#344 for context. MK. {:badrpc, {:EXIT, {:undef, _}}} -> [] - {:badrpc, _} = err -> err - val -> filter_by_arg(val, args) + {:badrpc, _} = err -> err + val -> filter_by_arg(val, args) end - end def banner(_, _), do: "Listing feature flags ..." @@ -81,13 +79,15 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListFeatureFlagsCommand do ff_info end - defp filter_by_arg(ff_info, [_|_] = args) when is_list(ff_info) do + defp filter_by_arg(ff_info, [_ | _] = args) when is_list(ff_info) do symbol_args = InfoKeys.prepare_info_keys(args) - Enum.map(ff_info, - fn(ff) -> + + Enum.map( + ff_info, + fn ff -> symbol_args - |> Enum.filter(fn(arg) -> ff[arg] != nil end) - |> Enum.map(fn(arg) -> {arg, ff[arg]} end) + |> Enum.filter(fn arg -> ff[arg] != nil end) + |> Enum.map(fn arg -> {arg, ff[arg]} end) end ) end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex index 571935117687..2dc44d87d08d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex @@ -26,12 +26,13 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListQueuesCommand do leader members online)a def description(), do: "Lists queues and their properties" - def usage(), do: "list_queues [--vhost ] [--online] [--offline] [--local] [--no-table-headers] [, ...]" + + def usage(), + do: + "list_queues [--vhost ] [--online] [--offline] [--local] [--no-table-headers] [, ...]" + def scopes(), do: [:ctl, :diagnostics] - def switches(), do: [offline: :boolean, - online: :boolean, - local: :boolean, - timeout: :integer] + def switches(), do: [offline: :boolean, online: :boolean, local: :boolean, timeout: :integer] def aliases(), do: [t: :timeout] def info_keys(), do: @info_keys diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_unresponsive_queues_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_unresponsive_queues_command.ex index 9d57abfc9a71..9fa818f19551 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_unresponsive_queues_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_unresponsive_queues_command.ex @@ -85,11 +85,15 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUnresponsiveQueuesCommand do [ ["", "must be one of " <> Enum.join(Enum.sort(@info_keys), ", ")], ["--local", "only return queues hosted on the target node"], - ["--queue-timeout ", "per-queue timeout to use when checking for responsiveness"] + [ + "--queue-timeout ", + "per-queue timeout to use when checking for responsiveness" + ] ] end def help_section(), do: :observability_and_health_checks - def description(), do: "Tests queues to respond within timeout. Lists those which did not respond" + def description(), + do: "Tests queues to respond within timeout. Lists those which did not respond" end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_user_limits_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_user_limits_command.ex index 5e0de38b3fe5..1e01a13f644b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_user_limits_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_user_limits_command.ex @@ -43,7 +43,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUserLimitsCommand do end def run([], %{node: node_name, user: username}) do - case :rabbit_misc.rpc_call(node_name, :rabbit_auth_backend_internal, :get_user_limits, [username]) do + case :rabbit_misc.rpc_call(node_name, :rabbit_auth_backend_internal, :get_user_limits, [ + username + ]) do :undefined -> {:error, {:no_such_user, username}} diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex index c94eeb627002..9e898dd428de 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex @@ -70,9 +70,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.NodeHealthCheckCommand do end def help_section(), do: :deprecated + def description() do "DEPRECATED. Performs intrusive, opinionated health checks on a fully booted node. " <> - "See https://www.rabbitmq.com/monitoring.html#health-checks instead" + "See https://www.rabbitmq.com/monitoring.html#health-checks instead" end def banner(_, %{node: node_name, timeout: timeout}) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/ping_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/ping_command.ex index 3b7358b4c991..e949554a1b19 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/ping_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/ping_command.ex @@ -62,6 +62,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.PingCommand do {:error, RabbitMQ.CLI.Core.ExitCodes.exit_software(), "Error: timed out while waiting for a response from #{node_name}."} end + use RabbitMQ.CLI.DefaultOutput def usage() do @@ -76,12 +77,12 @@ defmodule RabbitMQ.CLI.Ctl.Commands.PingCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Checks that the node OS process is up, registered with EPMD and CLI tools can authenticate with it" + def description(), + do: + "Checks that the node OS process is up, registered with EPMD and CLI tools can authenticate with it" def banner([], %{node: node_name, timeout: timeout}) when is_number(timeout) do - "Will ping #{node_name}. This only checks if the OS process is running and registered with epmd. Timeout: #{ - timeout - } ms." + "Will ping #{node_name}. This only checks if the OS process is running and registered with epmd. Timeout: #{timeout} ms." end def banner([], %{node: node_name, timeout: _timeout}) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/report_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/report_command.ex index e86bf93c5c93..a2aada81116b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/report_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/report_command.ex @@ -6,6 +6,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do alias RabbitMQ.CLI.Core.DocGuide + alias RabbitMQ.CLI.Ctl.Commands.{ ClusterStatusCommand, EnvironmentCommand, @@ -20,6 +21,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do ListQueuesCommand, StatusCommand } + alias RabbitMQ.CLI.Diagnostics.Commands.{ CommandLineArgumentsCommand, OsEnvCommand @@ -73,8 +75,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do run_command(ListPermissionsCommand, [], opts), run_command(ListPoliciesCommand, [], opts), run_command(ListGlobalParametersCommand, [], opts), - run_command(ListParametersCommand, [], opts), - + run_command(ListParametersCommand, [], opts) ] end) @@ -96,7 +97,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Generate a server status report containing a concatenation of all server status information for support purposes" + def description(), + do: + "Generate a server status report containing a concatenation of all server status information for support purposes" def banner(_, %{node: node_name}), do: "Reporting server status of node #{node_name} ..." diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/reset_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/reset_command.ex index 61f4b66e95c2..4c6d8a9d26b2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/reset_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/reset_command.ex @@ -34,7 +34,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ResetCommand do def help_section(), do: :node_management - def description(), do: "Instructs a RabbitMQ node to leave the cluster and return to its virgin state" + def description(), + do: "Instructs a RabbitMQ node to leave the cluster and return to its virgin state" def banner(_, %{node: node_name}), do: "Resetting node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/resume_listeners_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/resume_listeners_command.ex index df14c2c8054a..afa500be6d3d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/resume_listeners_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/resume_listeners_command.ex @@ -21,7 +21,13 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ResumeListenersCommand do use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name, timeout: timeout}) do - :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :resume_all_client_listeners, [], timeout) + :rabbit_misc.rpc_call( + node_name, + :rabbit_maintenance, + :resume_all_client_listeners, + [], + timeout + ) end use RabbitMQ.CLI.DefaultOutput @@ -36,10 +42,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ResumeListenersCommand do def help_section(), do: :operations - def description(), do: "Resumes client connection listeners making them accept client connections again" + def description(), + do: "Resumes client connection listeners making them accept client connections again" def banner(_, %{node: node_name}) do - "Will resume client connection listeners on node #{node_name}. " - <> "The node will now accept client connections" + "Will resume client connection listeners on node #{node_name}. " <> + "The node will now accept client connections" end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex index a2fe30d2bb96..ddf295d14a24 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.RotateLogsCommand do "This command does not rotate logs anymore [deprecated]" } end + use RabbitMQ.CLI.DefaultOutput def usage, do: "rotate_logs" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_global_parameter_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_global_parameter_command.ex index 38f4cbb92e1c..a7edb7877ac2 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_global_parameter_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_global_parameter_command.ex @@ -14,9 +14,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetGlobalParameterCommand do def validate(args, _) when length(args) < 2 do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 2 do {:validation_failure, :too_many_args} end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_log_level_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_log_level_command.ex index 97dbf20be07d..972d0cd97991 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_log_level_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_log_level_command.ex @@ -26,6 +26,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetLogLevelCommand do def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 1 do {:validation_failure, :too_many_args} end @@ -36,7 +37,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetLogLevelCommand do :ok false -> - {:error, "level #{level} is not supported. Try one of debug, info, warning, error, critical, none"} + {:error, + "level #{level} is not supported. Try one of debug, info, warning, error, critical, none"} end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_operator_policy_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_operator_policy_command.ex index 055ab6dd1540..a612f8a7fb30 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_operator_policy_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_operator_policy_command.ex @@ -54,10 +54,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetOperatorPolicyCommand do def usage_additional() do [ ["", "policy name (identifier)"], - ["", "a regular expression pattern that will be used to match queue, exchanges, etc"], + [ + "", + "a regular expression pattern that will be used to match queue, exchanges, etc" + ], ["", "policy definition (arguments). Must be a valid JSON document"], ["--priority ", "policy priority"], - ["--apply-to ", "policy should only apply to queues, exchanges, or all entities (both of the above)"] + [ + "--apply-to ", + "policy should only apply to queues, exchanges, or all entities (both of the above)" + ] ] end @@ -69,11 +75,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetOperatorPolicyCommand do def help_section(), do: :policies - def description(), do: "Sets an operator policy that overrides a subset of arguments in user policies" + def description(), + do: "Sets an operator policy that overrides a subset of arguments in user policies" def banner([name, pattern, definition], %{vhost: vhost, priority: priority}) do - "Setting operator policy override \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{ - priority - }\" for vhost \"#{vhost}\" ..." + "Setting operator policy override \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{priority}\" for vhost \"#{vhost}\" ..." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex index ea36251afa18..11d0a2978e2a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex @@ -61,8 +61,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetParameterCommand do def description(), do: "Sets a runtime parameter." def banner([component_name, name, value], %{vhost: vhost}) do - "Setting runtime parameter \"#{name}\" for component \"#{component_name}\" to \"#{value}\" in vhost \"#{ - vhost - }\" ..." + "Setting runtime parameter \"#{name}\" for component \"#{component_name}\" to \"#{value}\" in vhost \"#{vhost}\" ..." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex index b57d1bb06bb2..c585aca45a39 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex @@ -39,17 +39,27 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPermissionsCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} end + def output({:error, {:no_such_vhost, vhost}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "Virtual host #{vhost} does not exist"}} + {:error, + %{ + "result" => "error", + "node" => node_name, + "message" => "Virtual host #{vhost} does not exist" + }} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User #{username} does not exist"} end + def output({:error, {:no_such_vhost, vhost}}, _) do {:error, "Virtual host #{vhost} does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "set_permissions [--vhost ] " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_policy_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_policy_command.ex index 7e6c7c1e3a20..539314134602 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_policy_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_policy_command.ex @@ -18,12 +18,15 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPolicyCommand do def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) < 3 do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 3 do {:validation_failure, :too_many_args} end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -51,10 +54,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPolicyCommand do def usage_additional() do [ ["", "policy name (identifier)"], - ["", "regular expression pattern that will be used to match queues, exchanges, etc"], + [ + "", + "regular expression pattern that will be used to match queues, exchanges, etc" + ], ["", "policy definition (arguments). Must be a valid JSON document"], ["--priority ", "policy priority"], - ["--apply-to ", "policy should only apply to queues, exchanges, or all entities (both of the above)"] + [ + "--apply-to ", + "policy should only apply to queues, exchanges, or all entities (both of the above)" + ] ] end @@ -69,8 +78,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPolicyCommand do def description(), do: "Sets or updates a policy" def banner([name, pattern, definition], %{vhost: vhost, priority: priority}) do - "Setting policy \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{ - priority - }\" for vhost \"#{vhost}\" ..." + "Setting policy \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{priority}\" for vhost \"#{vhost}\" ..." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_topic_permissions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_topic_permissions_command.ex index ff1fa629d6db..2e37a6fa12ba 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_topic_permissions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_topic_permissions_command.ex @@ -16,9 +16,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetTopicPermissionsCommand do def validate(args, _) when length(args) < 4 do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 4 do {:validation_failure, :too_many_args} end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -33,17 +35,27 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetTopicPermissionsCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exist"}} end + def output({:error, {:no_such_vhost, vhost}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "Virtual host #{vhost} does not exist"}} + {:error, + %{ + "result" => "error", + "node" => node_name, + "message" => "Virtual host #{vhost} does not exist" + }} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User #{username} does not exist"} end + def output({:error, {:no_such_vhost, vhost}}, _) do {:error, "Virtual host #{vhost} does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex index 9e9de36dc5b1..e166198d0b80 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex @@ -14,6 +14,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetUserTagsCommand do def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -28,11 +29,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetUserTagsCommand do end def output({:error, {:no_such_user, username}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} + {:error, + %{"result" => "error", "node" => node_name, "message" => "User #{username} does not exists"}} end + def output({:error, {:no_such_user, username}}, _) do {:error, ExitCodes.exit_nouser(), "User \"#{username}\" does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "set_user_tags [...]" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vhost_tags_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vhost_tags_command.ex index ed7181488938..752e329db1d1 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vhost_tags_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vhost_tags_command.ex @@ -14,25 +14,37 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetVhostTagsCommand do def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([vhost | tags], %{node: node_name}) do case :rabbit_misc.rpc_call( - node_name, :rabbit_vhost, :update_tags, [vhost, tags, Helpers.cli_acting_user()]) do - {:error, _} = err -> err + node_name, + :rabbit_vhost, + :update_tags, + [vhost, tags, Helpers.cli_acting_user()] + ) do + {:error, _} = err -> err {:badrpc, _} = err -> err - _ -> :ok + _ -> :ok end end def output({:error, {:no_such_vhost, vhost}}, %{node: node_name, formatter: "json"}) do - {:error, %{"result" => "error", "node" => node_name, "message" => "Virtual host \"#{vhost}\" does not exists"}} + {:error, + %{ + "result" => "error", + "node" => node_name, + "message" => "Virtual host \"#{vhost}\" does not exists" + }} end + def output({:error, {:no_such_vhost, vhost}}, _) do {:error, ExitCodes.exit_dataerr(), "Virtual host \"#{vhost}\" does not exist"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "set_vhost_tags [...]" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex index 27fa707d05a5..bfdbd195cb2a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex @@ -112,7 +112,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetVmMemoryHighWatermarkCommand do def usage_doc_guides() do [ DocGuide.alarms(), - DocGuide.memory_use(), + DocGuide.memory_use() ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/shutdown_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/shutdown_command.ex index 0d7c19b5cf6e..c21cf2eb569e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/shutdown_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/shutdown_command.ex @@ -9,8 +9,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ShutdownCommand do alias RabbitMQ.CLI.Core.{OsPid, NodeName} def switches() do - [timeout: :integer, - wait: :boolean] + [timeout: :integer, wait: :boolean] end def aliases(), do: [timeout: :t] @@ -26,16 +25,22 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ShutdownCommand do def validate([], %{node: node_name, wait: true}) do local_hostname = NodeName.hostname_from_node(Node.self()) remote_hostname = NodeName.hostname_from_node(node_name) + case addressing_local_node?(local_hostname, remote_hostname) do - true -> :ok; + true -> + :ok + false -> - msg = "\nThis command can only --wait for shutdown of local nodes " <> - "but node #{node_name} seems to be remote " <> - "(local hostname: #{local_hostname}, remote: #{remote_hostname}).\n" <> - "Pass --no-wait to shut node #{node_name} down without waiting.\n" + msg = + "\nThis command can only --wait for shutdown of local nodes " <> + "but node #{node_name} seems to be remote " <> + "(local hostname: #{local_hostname}, remote: #{remote_hostname}).\n" <> + "Pass --no-wait to shut node #{node_name} down without waiting.\n" + {:validation_failure, {:unsupported_target, msg}} end end + use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name, wait: false, timeout: timeout}) do @@ -46,6 +51,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ShutdownCommand do case :rabbit_misc.rpc_call(node_name, :os, :getpid, []) do pid when is_list(pid) -> shut_down_node_and_wait_pid_to_stop(node_name, pid, timeout) + other -> other end @@ -57,25 +63,30 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ShutdownCommand do def usage_additional() do [ - ["--wait", "if set, will wait for target node to terminate (by inferring and monitoring its PID file). Only works for local nodes."], + [ + "--wait", + "if set, will wait for target node to terminate (by inferring and monitoring its PID file). Only works for local nodes." + ], ["--no-wait", "if set, will not wait for target node to terminate"] ] end def help_section(), do: :node_management - def description(), do: "Stops RabbitMQ and its runtime (Erlang VM). Monitors progress for local nodes. Does not require a PID file path." + def description(), + do: + "Stops RabbitMQ and its runtime (Erlang VM). Monitors progress for local nodes. Does not require a PID file path." def banner(_, _), do: nil - # # Implementation # - def addressing_local_node?(_, remote_hostname) when remote_hostname == :localhost , do: :true - def addressing_local_node?(_, remote_hostname) when remote_hostname == 'localhost', do: :true - def addressing_local_node?(_, remote_hostname) when remote_hostname == "localhost", do: :true + def addressing_local_node?(_, remote_hostname) when remote_hostname == :localhost, do: true + def addressing_local_node?(_, remote_hostname) when remote_hostname == 'localhost', do: true + def addressing_local_node?(_, remote_hostname) when remote_hostname == "localhost", do: true + def addressing_local_node?(local_hostname, remote_hostname) do local_hostname == remote_hostname end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/start_app_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/start_app_command.ex index dc59e3442eb6..70d48841623e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/start_app_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/start_app_command.ex @@ -19,7 +19,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StartAppCommand do def help_section(), do: :node_management - def description(), do: "Starts the RabbitMQ application but leaves the runtime (Erlang VM) running" + def description(), + do: "Starts the RabbitMQ application but leaves the runtime (Erlang VM) running" def banner(_, %{node: node_name}), do: "Starting node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/status_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/status_command.ex index 671810fc6dcb..3c62a4a15208 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/status_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/status_command.ex @@ -32,6 +32,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do def validate(args, _) when length(args) > 0 do {:validation_failure, :too_many_args} end + def validate(_, %{unit: unit}) do case IU.known_unit?(unit) do true -> @@ -41,6 +42,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do {:validation_failure, "unit '#{unit}' is not supported. Please use one of: bytes, mb, gb"} end end + def validate(_, _), do: :ok use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -67,45 +69,52 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do def output(result, %{node: node_name, unit: unit}) when is_list(result) do m = result_map(result) - product_name_section = case m do - %{:product_name => product_name} when product_name != "" -> - ["Product name: #{product_name}"] - _ -> - [] - end - product_version_section = case m do - %{:product_version => product_version} when product_version != "" -> - ["Product version: #{product_version}"] - _ -> - [] - end + product_name_section = + case m do + %{:product_name => product_name} when product_name != "" -> + ["Product name: #{product_name}"] - runtime_section = [ - "#{bright("Runtime")}\n", - "OS PID: #{m[:pid]}", - "OS: #{m[:os]}", - # TODO: format - "Uptime (seconds): #{m[:uptime]}", - "Is under maintenance?: #{m[:is_under_maintenance]}" - ] ++ - product_name_section ++ - product_version_section ++ - [ - "RabbitMQ version: #{m[:rabbitmq_version]}", - "RabbitMQ release series support status: #{m[:release_series_support_status]}", - "Node name: #{node_name}", - "Erlang configuration: #{m[:erlang_version]}", - "Crypto library: #{m[:crypto_lib_version]}", - "Erlang processes: #{m[:processes][:used]} used, #{m[:processes][:limit]} limit", - "Scheduler run queue: #{m[:run_queue]}", - "Cluster heartbeat timeout (net_ticktime): #{m[:net_ticktime]}" - ] + _ -> + [] + end - plugin_section = [ - "\n#{bright("Plugins")}\n", - "Enabled plugin file: #{m[:enabled_plugin_file]}", - "Enabled plugins:\n" - ] ++ Enum.map(m[:active_plugins], fn pl -> " * #{pl}" end) + product_version_section = + case m do + %{:product_version => product_version} when product_version != "" -> + ["Product version: #{product_version}"] + + _ -> + [] + end + + runtime_section = + [ + "#{bright("Runtime")}\n", + "OS PID: #{m[:pid]}", + "OS: #{m[:os]}", + # TODO: format + "Uptime (seconds): #{m[:uptime]}", + "Is under maintenance?: #{m[:is_under_maintenance]}" + ] ++ + product_name_section ++ + product_version_section ++ + [ + "RabbitMQ version: #{m[:rabbitmq_version]}", + "RabbitMQ release series support status: #{m[:release_series_support_status]}", + "Node name: #{node_name}", + "Erlang configuration: #{m[:erlang_version]}", + "Crypto library: #{m[:crypto_lib_version]}", + "Erlang processes: #{m[:processes][:used]} used, #{m[:processes][:limit]} limit", + "Scheduler run queue: #{m[:run_queue]}", + "Cluster heartbeat timeout (net_ticktime): #{m[:net_ticktime]}" + ] + + plugin_section = + [ + "\n#{bright("Plugins")}\n", + "Enabled plugin file: #{m[:enabled_plugin_file]}", + "Enabled plugins:\n" + ] ++ Enum.map(m[:active_plugins], fn pl -> " * #{pl}" end) data_directory_section = [ "\n#{bright("Data directory")}\n", @@ -113,36 +122,46 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do "Raft data directory: #{m[:raft_data_directory]}" ] - config_section = [ - "\n#{bright("Config files")}\n" - ] ++ Enum.map(m[:config_files], fn path -> " * #{path}" end) - - log_section = [ - "\n#{bright("Log file(s)")}\n" - ] ++ Enum.map(m[:log_files], fn path -> " * #{path}" end) - - alarms_section = [ - "\n#{bright("Alarms")}\n", - ] ++ case m[:alarms] do - [] -> ["(none)"] - xs -> alarm_lines(xs, node_name) - end + config_section = + [ + "\n#{bright("Config files")}\n" + ] ++ Enum.map(m[:config_files], fn path -> " * #{path}" end) + + log_section = + [ + "\n#{bright("Log file(s)")}\n" + ] ++ Enum.map(m[:log_files], fn path -> " * #{path}" end) + + alarms_section = + [ + "\n#{bright("Alarms")}\n" + ] ++ + case m[:alarms] do + [] -> ["(none)"] + xs -> alarm_lines(xs, node_name) + end breakdown = compute_relative_values(m[:memory]) memory_calculation_strategy = to_atom(m[:vm_memory_calculation_strategy]) total_memory = get_in(m[:memory], [:total, memory_calculation_strategy]) - readable_watermark_setting = case m[:vm_memory_high_watermark_setting] do - %{:relative => val} -> "#{val} of available memory" - # absolute value - %{:absolute => val} -> "#{IU.convert(val, unit)} #{unit}" - end - memory_section = [ - "\n#{bright("Memory")}\n", - "Total memory used: #{IU.convert(total_memory, unit)} #{unit}", - "Calculation strategy: #{memory_calculation_strategy}", - "Memory high watermark setting: #{readable_watermark_setting}, computed to: #{IU.convert(m[:vm_memory_high_watermark_limit], unit)} #{unit}\n" - ] ++ Enum.map(breakdown, fn({category, val}) -> "#{category}: #{IU.convert(val[:bytes], unit)} #{unit} (#{val[:percentage]} %)" end) + readable_watermark_setting = + case m[:vm_memory_high_watermark_setting] do + %{:relative => val} -> "#{val} of available memory" + # absolute value + %{:absolute => val} -> "#{IU.convert(val, unit)} #{unit}" + end + + memory_section = + [ + "\n#{bright("Memory")}\n", + "Total memory used: #{IU.convert(total_memory, unit)} #{unit}", + "Calculation strategy: #{memory_calculation_strategy}", + "Memory high watermark setting: #{readable_watermark_setting}, computed to: #{IU.convert(m[:vm_memory_high_watermark_limit], unit)} #{unit}\n" + ] ++ + Enum.map(breakdown, fn {category, val} -> + "#{category}: #{IU.convert(val[:bytes], unit)} #{unit} (#{val[:percentage]} %)" + end) file_descriptors = [ "\n#{bright("File Descriptors")}\n", @@ -163,15 +182,24 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do "Virtual host count: #{m[:totals][:virtual_host_count]}" ] - listeners_section = [ - "\n#{bright("Listeners")}\n", - ] ++ case m[:listeners] do - [] -> ["(none)"] - xs -> listener_lines(xs) - end - lines = runtime_section ++ plugin_section ++ data_directory_section ++ - config_section ++ log_section ++ alarms_section ++ memory_section ++ - file_descriptors ++ disk_space_section ++ totals_section ++ listeners_section + listeners_section = + [ + "\n#{bright("Listeners")}\n" + ] ++ + case m[:listeners] do + [] -> ["(none)"] + xs -> listener_lines(xs) + end + + lines = + runtime_section ++ + plugin_section ++ + data_directory_section ++ + config_section ++ + log_section ++ + alarms_section ++ + memory_section ++ + file_descriptors ++ disk_space_section ++ totals_section ++ listeners_section {:ok, Enum.join(lines, line_separator())} end @@ -206,10 +234,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do # defp result_map(result) do - crypto_lib_version = case Keyword.get(result, :crypto_lib_info) do - {_, _, version} -> version - other -> other - end + crypto_lib_version = + case Keyword.get(result, :crypto_lib_info) do + {_, _, version} -> version + other -> other + end %{ os: os_name(Keyword.get(result, :os)), @@ -217,7 +246,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do product_name: Keyword.get(result, :product_name) |> to_string, product_version: Keyword.get(result, :product_version) |> to_string, rabbitmq_version: Keyword.get(result, :rabbitmq_version) |> to_string, - erlang_version: Keyword.get(result, :erlang_version) |> to_string |> String.trim_trailing, + erlang_version: Keyword.get(result, :erlang_version) |> to_string |> String.trim_trailing(), crypto_lib_version: crypto_lib_version, release_series_support_status: Keyword.get(result, :release_series_support_status, true), uptime: Keyword.get(result, :uptime), @@ -225,38 +254,31 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do processes: Enum.into(Keyword.get(result, :processes), %{}), run_queue: Keyword.get(result, :run_queue), net_ticktime: net_ticktime(result), - vm_memory_calculation_strategy: Keyword.get(result, :vm_memory_calculation_strategy), - vm_memory_high_watermark_setting: Keyword.get(result, :vm_memory_high_watermark) |> formatted_watermark, + vm_memory_high_watermark_setting: + Keyword.get(result, :vm_memory_high_watermark) |> formatted_watermark, vm_memory_high_watermark_limit: Keyword.get(result, :vm_memory_limit), - disk_free_limit: Keyword.get(result, :disk_free_limit), disk_free: Keyword.get(result, :disk_free), - file_descriptors: Enum.into(Keyword.get(result, :file_descriptors), %{}), - alarms: Keyword.get(result, :alarms), listeners: listener_maps(Keyword.get(result, :listeners, [])), memory: Keyword.get(result, :memory) |> Enum.into(%{}), - data_directory: Keyword.get(result, :data_directory) |> to_string, raft_data_directory: Keyword.get(result, :raft_data_directory) |> to_string, - config_files: Keyword.get(result, :config_files) |> Enum.map(&to_string/1), log_files: Keyword.get(result, :log_files) |> Enum.map(&to_string/1), - active_plugins: Keyword.get(result, :active_plugins) |> Enum.map(&to_string/1), enabled_plugin_file: Keyword.get(result, :enabled_plugin_file) |> to_string, - totals: Keyword.get(result, :totals) } end defp net_ticktime(result) do case Keyword.get(result, :kernel) do - {:net_ticktime, n} -> n + {:net_ticktime, n} -> n n when is_integer(n) -> n - _ -> :undefined + _ -> :undefined end end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/stop_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/stop_command.ex index c73341d7ae7b..b19426d760f4 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/stop_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/stop_command.ex @@ -55,12 +55,17 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StopCommand do def usage_additional() do [ - ["", "node PID file path to monitor. To avoid using a PID file, use 'rabbitmqctl shutdown'"], + [ + "", + "node PID file path to monitor. To avoid using a PID file, use 'rabbitmqctl shutdown'" + ], ["--idempotent", "return success if target node is not running (cannot be contacted)"] ] end - def description(), do: "Stops RabbitMQ and its runtime (Erlang VM). Requires a local node pid file path to monitor progress." + def description(), + do: + "Stops RabbitMQ and its runtime (Erlang VM). Requires a local node pid file path to monitor progress." def help_section(), do: :node_management diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/suspend_listeners_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/suspend_listeners_command.ex index 664847c3ffda..6fbb5b6725ed 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/suspend_listeners_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/suspend_listeners_command.ex @@ -22,7 +22,13 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SuspendListenersCommand do use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name, timeout: timeout}) do - :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :suspend_all_client_listeners, [], timeout) + :rabbit_misc.rpc_call( + node_name, + :rabbit_maintenance, + :suspend_all_client_listeners, + [], + timeout + ) end use RabbitMQ.CLI.DefaultOutput @@ -37,10 +43,11 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SuspendListenersCommand do def help_section(), do: :operations - def description(), do: "Suspends client connection listeners so that no new client connections are accepted" + def description(), + do: "Suspends client connection listeners so that no new client connections are accepted" def banner(_, %{node: node_name}) do - "Will suspend client connection listeners on node #{node_name}. " - <> "The node will no longer accept client connections!" + "Will suspend client connection listeners on node #{node_name}. " <> + "The node will no longer accept client connections!" end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex index c402f9e1f76a..43399973f32d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex @@ -46,7 +46,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SyncQueueCommand do def help_section(), do: :replication - def description(), do: "Instructs a mirrored queue with unsynchronised mirrors (follower replicas) to synchronise them" + def description(), + do: + "Instructs a mirrored queue with unsynchronised mirrors (follower replicas) to synchronise them" def banner([queue], %{vhost: vhost, node: _node}) do "Synchronising queue '#{queue}' in vhost '#{vhost}' ..." diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/update_cluster_nodes_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/update_cluster_nodes_command.ex index 9383424f0e2d..1823545dcd0d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/update_cluster_nodes_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/update_cluster_nodes_command.ex @@ -13,9 +13,10 @@ defmodule RabbitMQ.CLI.Ctl.Commands.UpdateClusterNodesCommand do use RabbitMQ.CLI.Core.AcceptsOnePositionalArgument use RabbitMQ.CLI.Core.RequiresRabbitAppStopped - def run([seed_node], options=%{node: node_name}) do + def run([seed_node], options = %{node: node_name}) do long_or_short_names = Config.get_option(:longnames, options) seed_node_normalised = Helpers.normalise_node(seed_node, long_or_short_names) + :rabbit_misc.rpc_call( node_name, :rabbit_mnesia, @@ -42,7 +43,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.UpdateClusterNodesCommand do def help_section(), do: :cluster_management - def description(), do: "Instructs a cluster member node to sync the list of known cluster members from " + def description(), + do: + "Instructs a cluster member node to sync the list of known cluster members from " def banner([seed_node], %{node: node_name}) do "Will seed #{node_name} from #{seed_node} on next start" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/version_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/version_command.ex index b43aa726b7c6..3d1a62704c0b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/version_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/version_command.ex @@ -21,13 +21,16 @@ defmodule RabbitMQ.CLI.Ctl.Commands.VersionCommand do def run([], %{formatter: "json"}) do {:ok, %{version: Version.local_version()}} end + def run([], %{formatter: "csv"}) do row = [version: Version.local_version()] {:ok, [row]} end + def run([], _opts) do {:ok, Version.local_version()} end + use RabbitMQ.CLI.DefaultOutput def help_section, do: :help diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/wait_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/wait_command.ex index b6ca408eaf70..99d69792d31e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/wait_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/wait_command.ex @@ -35,6 +35,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.WaitCommand do def validate_execution_environment([], %{pid: _} = opts) do Validators.rabbit_is_loaded([], opts) end + def validate_execution_environment([_pid_file], opts) do Validators.rabbit_is_loaded([], opts) end @@ -102,7 +103,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.WaitCommand do def help_section(), do: :node_management - def description(), do: "Waits for RabbitMQ node startup by monitoring a local PID file. See also 'rabbitmqctl await_online_nodes'" + def description(), + do: + "Waits for RabbitMQ node startup by monitoring a local PID file. See also 'rabbitmqctl await_online_nodes'" # # Implementation @@ -253,7 +256,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.WaitCommand do {pid, _} -> case check_distribution(pid, node_name) do :ok -> {:ok, pid} - _ -> {:error, :loop} + _ -> {:error, :loop} end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/default_output.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/default_output.ex index c01f96c2c8eb..ca4f28a67aba 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/default_output.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/default_output.ex @@ -28,10 +28,13 @@ defmodule RabbitMQ.CLI.DefaultOutput do defp normalize_output(:ok, %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name}} end + defp normalize_output(:ok, _opts), do: :ok + defp normalize_output({:ok, value}, %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name, "value" => value}} end + defp normalize_output({:ok, _} = input, _opts), do: input defp normalize_output({:stream, _} = input, _opts), do: input defp normalize_output({:badrpc_multi, _, _} = input, _opts), do: {:error, input} @@ -40,25 +43,30 @@ defmodule RabbitMQ.CLI.DefaultOutput do defp normalize_output({:badrpc, {:timeout, _n}} = input, _opts), do: {:error, input} defp normalize_output({:badrpc, {:timeout, _n, _msg}} = input, _opts), do: {:error, input} defp normalize_output({:badrpc, {:EXIT, reason}}, _opts), do: {:error, reason} + defp normalize_output({:error, exit_code, string}, _opts) when is_integer(exit_code) do {:error, exit_code, to_string(string)} end + defp normalize_output({:error, format, args}, _opts) when (is_list(format) or is_binary(format)) and is_list(args) do {:error, to_string(:rabbit_misc.format(format, args))} end + defp normalize_output({:error, _} = input, _opts), do: input + defp normalize_output({:error_string, string}, _opts) do {:error, to_string(string)} end + defp normalize_output(unknown, _opts) when is_atom(unknown), do: {:error, unknown} defp normalize_output({unknown, _} = input, _opts) when is_atom(unknown), do: {:error, input} defp normalize_output(result, _opts) when not is_atom(result), do: {:ok, result} - defp format_output({:error, _} = result) do result end + defp format_output({:error, _, _} = result) do result end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/alarms_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/alarms_command.ex index 5e51c0455777..37f25e68793d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/alarms_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/alarms_command.ex @@ -67,7 +67,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.AlarmsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Lists resource alarms (local or cluster-wide) in effect on the target node" + def description(), + do: "Lists resource alarms (local or cluster-wide) in effect on the target node" def usage, do: "alarms" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/certificates_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/certificates_command.ex index ac40ed65e8be..d2fc18cba9ef 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/certificates_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/certificates_command.ex @@ -49,7 +49,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CertificatesCommand do def help_section(), do: :configuration - def description(), do: "Displays certificates (public keys) for every listener on target node that is configured to use TLS" + def description(), + do: + "Displays certificates (public keys) for every listener on target node that is configured to use TLS" def banner(_, %{node: node_name}), do: "Certificates of node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_alarms_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_alarms_command.ex index 607fa5194885..2754a9a34879 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_alarms_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_alarms_command.ex @@ -76,7 +76,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckAlarmsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if the target node reports any alarms, local or cluster-wide." + def description(), + do: + "Health check that exits with a non-zero code if the target node reports any alarms, local or cluster-wide." def usage, do: "check_alarms" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_certificate_expiration_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_certificate_expiration_command.ex index 02710ec8fa88..2084bb33fab5 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_certificate_expiration_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_certificate_expiration_command.ex @@ -20,15 +20,18 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do def validate(args, _) when length(args) > 0 do {:validation_failure, :too_many_args} end + def validate(_, %{unit: unit}) do case TU.known_unit?(unit) do true -> :ok false -> - {:validation_failure, "unit '#{unit}' is not supported. Please use one of: days, weeks, months, years"} + {:validation_failure, + "unit '#{unit}' is not supported. Please use one of: days, weeks, months, years"} end end + def validate(_, _), do: :ok def run([], %{node: node_name, unit: unit, within: within, timeout: timeout}) do @@ -45,10 +48,12 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do xs when is_list(xs) -> listeners = listeners_on(xs, node_name) seconds = TU.convert(within, unit) - Enum.reduce(listeners, [], fn (listener, acc) -> case listener_expiring_within(listener, seconds) do - false -> acc - expiring -> [expiring | acc] - end + + Enum.reduce(listeners, [], fn listener, acc -> + case listener_expiring_within(listener, seconds) do + false -> acc + expiring -> [expiring | acc] + end end) end end @@ -63,7 +68,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do end def output(listeners, %{formatter: "json"}) do - {:error, :check_failed, %{"result" => "error", "expired" => Enum.map(listeners, &expired_listener_map/1)}} + {:error, :check_failed, + %{"result" => "error", "expired" => Enum.map(listeners, &expired_listener_map/1)}} end def output(listeners, %{}) do @@ -73,6 +79,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do def unit_label(1, unit) do unit |> String.slice(0..-2) end + def unit_label(_within, unit) do unit end @@ -82,7 +89,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do def usage_additional() do [ ["", "period of time to check. Default is four (weeks)."], - ["", "time unit for the period, can be days, weeks, months, years. Default is weeks."], + ["", "time unit for the period, can be days, weeks, months, years. Default is weeks."] ] end @@ -95,7 +102,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckCertificateExpirationCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Checks the expiration date on the certificates for every listener configured to use TLS" + def description(), + do: "Checks the expiration date on the certificates for every listener configured to use TLS" - def banner(_, %{node: node_name}), do: "Checking certificate expiration on node #{node_name} ..." + def banner(_, %{node: node_name}), + do: "Checking certificate expiration on node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_local_alarms_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_local_alarms_command.ex index 9517ad138259..054851d1e2dd 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_local_alarms_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_local_alarms_command.ex @@ -75,7 +75,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckLocalAlarmsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if the target node reports any local alarms" + def description(), + do: "Health check that exits with a non-zero code if the target node reports any local alarms" def usage, do: "check_local_alarms" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_connectivity_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_connectivity_command.ex index 010fff1ff8dc..a94b01a50b79 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_connectivity_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_connectivity_command.ex @@ -15,6 +15,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckPortConnectivityCommand do import RabbitMQ.CLI.Diagnostics.Helpers, only: [check_listener_connectivity: 3] + import RabbitMQ.CLI.Core.Platform, only: [line_separator: 0] import RabbitMQ.CLI.Core.Listeners @@ -87,7 +88,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckPortConnectivityCommand do {:error, Enum.join(lines, line_separator())} end - def description(), do: "Basic TCP connectivity health check for each listener's port on the target node" + def description(), + do: "Basic TCP connectivity health check for each listener's port on the target node" def help_section(), do: :observability_and_health_checks diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_listener_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_listener_command.ex index 89c767174855..740c0465341d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_listener_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_port_listener_command.ex @@ -65,14 +65,16 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckPortListenerCommand do def output({false, port, listeners}, %{node: node_name}) do ports = Enum.map(listeners, fn %{port: p} -> p end) |> Enum.sort() |> Enum.join(", ") - {:error, :check_failed, + {:error, :check_failed, "No listener for port #{port} is active on node #{node_name}. " <> "Found listeners that use the following ports: #{ports}"} end def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if target node does not have an active listener for given port" + def description(), + do: + "Health check that exits with a non-zero code if target node does not have an active listener for given port" def usage, do: "check_port_listener " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_protocol_listener_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_protocol_listener_command.ex index 08afa175e6d4..4ddab9d43b15 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_protocol_listener_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_protocol_listener_command.ex @@ -80,7 +80,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckProtocolListenerCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if target node does not have an active listener for given protocol" + def description(), + do: + "Health check that exits with a non-zero code if target node does not have an active listener for given protocol" def usage, do: "check_protocol_listener " diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_running_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_running_command.ex index 451ee96e548b..94d193cd64c1 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_running_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/check_running_command.ex @@ -36,7 +36,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CheckRunningCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if the RabbitMQ app on the target node is not running" + def description(), + do: + "Health check that exits with a non-zero code if the RabbitMQ app on the target node is not running" def usage, do: "check_running" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/cipher_suites_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/cipher_suites_command.ex index 3e49cef8926b..6f55c274d987 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/cipher_suites_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/cipher_suites_command.ex @@ -13,15 +13,14 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CipherSuitesCommand do {args, Map.merge(%{all: false, format: "openssl"}, Helpers.case_insensitive_format(opts))} end - def switches(), do: [timeout: :integer, - format: :string, - all: :boolean] + def switches(), do: [timeout: :integer, format: :string, all: :boolean] def aliases(), do: [t: :timeout] def validate(_, %{format: format}) when format != "openssl" and format != "erlang" and format != "map" do {:validation_failure, {:bad_argument, "Format should be either openssl, erlang or map"}} end + def validate(args, _) when length(args) > 0 do {:validation_failure, :too_many_args} end @@ -29,27 +28,33 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CipherSuitesCommand do def validate(_, _), do: :ok def run([], %{node: node_name, timeout: timeout, format: format} = opts) do - {mod, function} = case format do - "openssl" -> {:rabbit_ssl, :cipher_suites_openssl}; - "erlang" -> {:rabbit_ssl, :cipher_suites_erlang}; - "map" -> {:rabbit_ssl, :cipher_suites} - end - args = case opts do - %{all: true} -> [:all]; - %{} -> [:default] - end + {mod, function} = + case format do + "openssl" -> {:rabbit_ssl, :cipher_suites_openssl} + "erlang" -> {:rabbit_ssl, :cipher_suites_erlang} + "map" -> {:rabbit_ssl, :cipher_suites} + end + + args = + case opts do + %{all: true} -> [:all] + %{} -> [:default] + end + :rabbit_misc.rpc_call(node_name, mod, function, args, timeout) end use RabbitMQ.CLI.DefaultOutput - def banner([], %{format: "openssl"}), do: "Listing available cipher suites in OpenSSL format" + def banner([], %{format: "openssl"}), do: "Listing available cipher suites in OpenSSL format" def banner([], %{format: "erlang"}), do: "Listing available cipher suites in Erlang term format" def banner([], %{format: "map"}), do: "Listing available cipher suites in map format" def help_section(), do: :observability_and_health_checks - def description(), do: "Lists cipher suites enabled by default. To list all available cipher suites, add the --all argument." + def description(), + do: + "Lists cipher suites enabled by default. To list all available cipher suites, add the --all argument." def usage, do: "cipher_suites [--format ] [--all]" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/command_line_arguments_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/command_line_arguments_command.ex index cffbf5bd01a0..352789ce51eb 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/command_line_arguments_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/command_line_arguments_command.ex @@ -15,11 +15,13 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CommandLineArgumentsCommand do def validate(_, %{formatter: "json"}) do {:validation_failure, :unsupported_formatter} end + use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :init, :get_arguments, []) end + use RabbitMQ.CLI.DefaultOutput def formatter(), do: RabbitMQ.CLI.Formatters.Erlang @@ -35,7 +37,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.CommandLineArgumentsCommand do def help_section(), do: :configuration - def description(), do: "Displays target node's command-line arguments and flags as reported by the runtime" + def description(), + do: "Displays target node's command-line arguments and flags as reported by the runtime" def banner(_, %{node: node_name}), do: "Command line arguments of node #{node_name} ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/consume_event_stream_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/consume_event_stream_command.ex index 6d56c6858897..6a376256701a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/consume_event_stream_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/consume_event_stream_command.ex @@ -22,24 +22,37 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ConsumeEventStreamCommand do def run([], %{node: node_name, timeout: timeout, duration: duration, pattern: pattern}) do pid = self() ref = make_ref() - subscribed = :rabbit_misc.rpc_call( - node_name, - :rabbit_event_consumer, :register, - [pid, ref, duration, pattern], - timeout) + + subscribed = + :rabbit_misc.rpc_call( + node_name, + :rabbit_event_consumer, + :register, + [pid, ref, duration, pattern], + timeout + ) + case subscribed do {:ok, ^ref} -> - Stream.unfold(:confinue, - fn(:finished) -> nil - (:confinue) -> + Stream.unfold( + :confinue, + fn + :finished -> + nil + + :confinue -> receive do - {^ref, data, :finished} -> - {data, :finished}; - {^ref, data, :confinue} -> - {data, :confinue} - end - end) - error -> error + {^ref, data, :finished} -> + {data, :finished} + + {^ref, data, :confinue} -> + {data, :confinue} + end + end + ) + + error -> + error end end @@ -65,6 +78,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ConsumeEventStreamCommand do def banner([], %{node: node_name, duration: :infinity}) do "Streaming logs from node #{node_name} ..." end + def banner([], %{node: node_name, duration: duration}) do "Streaming logs from node #{node_name} for #{duration} seconds ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/disable_auth_attempt_source_tracking_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/disable_auth_attempt_source_tracking_command.ex index a1b29e373aa8..4b40a6ef095e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/disable_auth_attempt_source_tracking_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/disable_auth_attempt_source_tracking_command.ex @@ -13,9 +13,13 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.DisableAuthAttemptSourceTrackingComm use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([], %{node: node_name}) do - :rabbit_misc.rpc_call(node_name, :application, :set_env, - [:rabbit, :track_auth_attempt_source, :false]) + :rabbit_misc.rpc_call(node_name, :application, :set_env, [ + :rabbit, + :track_auth_attempt_source, + false + ]) end + use RabbitMQ.CLI.DefaultOutput def usage, do: "disable_track_auth_attempt_source" @@ -29,7 +33,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.DisableAuthAttemptSourceTrackingComm def help_section(), do: :configuration - def description(), do: "Disables the tracking of peer IP address and username of authentication attempts" + def description(), + do: "Disables the tracking of peer IP address and username of authentication attempts" def banner([], _), do: "Disabling authentication attempt source tracking ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/enable_auth_attempt_source_tracking_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/enable_auth_attempt_source_tracking_command.ex index 8e8b4ae0c301..531f6815b346 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/enable_auth_attempt_source_tracking_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/enable_auth_attempt_source_tracking_command.ex @@ -13,8 +13,11 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.EnableAuthAttemptSourceTrackingComma use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([], %{node: node_name}) do - :rabbit_misc.rpc_call(node_name, :application, :set_env, - [:rabbit, :track_auth_attempt_source, :true]) + :rabbit_misc.rpc_call(node_name, :application, :set_env, [ + :rabbit, + :track_auth_attempt_source, + true + ]) end use RabbitMQ.CLI.DefaultOutput @@ -30,7 +33,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.EnableAuthAttemptSourceTrackingComma def help_section(), do: :configuration - def description(), do: "Enables the tracking of peer IP address and username of authentication attempts" + def description(), + do: "Enables the tracking of peer IP address and username of authentication attempts" def banner([], _), do: "Enabling authentication attempt source tracking ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_hash_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_hash_command.ex index 88caf76c2296..1a3c35fbce59 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_hash_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_hash_command.ex @@ -13,19 +13,22 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieHashCommand do def run([], %{node: node_name, timeout: timeout}) do :rabbit_data_coercion.to_binary( - :rabbit_misc.rpc_call(node_name, :rabbit_nodes_common, :cookie_hash, [], timeout)) + :rabbit_misc.rpc_call(node_name, :rabbit_nodes_common, :cookie_hash, [], timeout) + ) end def output(result, %{formatter: "json"}) do {:ok, %{"result" => "ok", "value" => result}} end + def output(result, _options) when is_bitstring(result) do {:ok, result} end def help_section(), do: :configuration - def description(), do: "Displays a hash of the Erlang cookie (shared secret) used by the target node" + def description(), + do: "Displays a hash of the Erlang cookie (shared secret) used by the target node" def usage, do: "erlang_cookie_hash" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_sources_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_sources_command.ex index 1f2882b7973c..328dfee6e07b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_sources_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_cookie_sources_command.ex @@ -19,22 +19,30 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieSourcesCommand do switch_cookie = opts[:erlang_cookie] home_dir = get_home_dir() cookie_file_path = Path.join(home_dir, ".erlang.cookie") - cookie_file_stat = case File.stat(Path.join(home_dir, ".erlang.cookie")) do - {:error, :enoent} -> nil - {:ok, value} -> value - end - cookie_file_type = case cookie_file_stat do - nil -> nil - value -> value.type - end - cookie_file_access = case cookie_file_stat do - nil -> nil - value -> value.access - end - cookie_file_size = case cookie_file_stat do - nil -> nil - value -> value.size - end + + cookie_file_stat = + case File.stat(Path.join(home_dir, ".erlang.cookie")) do + {:error, :enoent} -> nil + {:ok, value} -> value + end + + cookie_file_type = + case cookie_file_stat do + nil -> nil + value -> value.type + end + + cookie_file_access = + case cookie_file_stat do + nil -> nil + value -> value.access + end + + cookie_file_size = + case cookie_file_stat do + nil -> nil + value -> value.size + end %{ os_env_cookie_set: System.get_env("RABBITMQ_ERLANG_COOKIE") != nil, @@ -66,7 +74,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieSourcesCommand do "Cookie file exists? #{result[:cookie_file_exists]}", "Cookie file type: #{result[:cookie_file_type] || "(n/a)"}", "Cookie file access: #{result[:cookie_file_access] || "(n/a)"}", - "Cookie file size: #{result[:cookie_file_size] || "(n/a)"}", + "Cookie file size: #{result[:cookie_file_size] || "(n/a)"}" ] switch_lines = [ @@ -106,11 +114,11 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieSourcesCommand do """ def get_home_dir() do homedrive = System.get_env("HOMEDRIVE") - homepath = System.get_env("HOMEPATH") + homepath = System.get_env("HOMEPATH") case {homedrive != nil, homepath != nil} do {true, true} -> "#{homedrive}#{homepath}" - _ -> System.get_env("HOME") + _ -> System.get_env("HOME") end end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_version_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_version_command.ex index 4bbd05ace63f..2b82fc980667 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_version_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/erlang_version_command.ex @@ -10,6 +10,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangVersionCommand do def switches() do [details: :boolean, offline: :boolean, timeout: :integer] end + def aliases(), do: [t: :timeout] def merge_defaults(args, opts) do @@ -21,29 +22,31 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangVersionCommand do def run([], %{details: details, offline: true}) do case details do true -> - :rabbit_data_coercion.to_binary( - :rabbit_misc.otp_system_version()) + :rabbit_data_coercion.to_binary(:rabbit_misc.otp_system_version()) false -> - :rabbit_data_coercion.to_binary( - :rabbit_misc.platform_and_version()) + :rabbit_data_coercion.to_binary(:rabbit_misc.platform_and_version()) end end + def run([], %{node: node_name, timeout: timeout, details: details}) do case details do true -> :rabbit_data_coercion.to_binary( - :rabbit_misc.rpc_call(node_name, :rabbit_misc, :otp_system_version, [], timeout)) + :rabbit_misc.rpc_call(node_name, :rabbit_misc, :otp_system_version, [], timeout) + ) false -> - :rabbit_data_coercion.to_binary( - :rabbit_misc.rpc_call(node_name, :rabbit_misc, :platform_and_version, [], timeout)) + :rabbit_data_coercion.to_binary( + :rabbit_misc.rpc_call(node_name, :rabbit_misc, :platform_and_version, [], timeout) + ) end end def output(result, %{formatter: "json"}) do {:ok, %{"result" => "ok", "value" => result}} end + def output(result, _opts) when is_bitstring(result) do {:ok, result} end @@ -66,6 +69,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ErlangVersionCommand do def banner([], %{offline: true}) do "CLI Erlang/OTP version ..." end + def banner([], %{node: node_name}) do "Asking node #{node_name} for its Erlang/OTP version..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_booting_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_booting_command.ex index 377b4efc87c8..53141b96b2a9 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_booting_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_booting_command.ex @@ -20,16 +20,20 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.IsBootingCommand do "result" => true, "message" => "RabbitMQ on node #{node_name} is booting" } + {:ok, m} end def output(false, %{node: node_name, formatter: "json"}) do m = %{ "result" => false, - "message" => "RabbitMQ on node #{node_name} is fully booted (check with is_running), stopped or has not started booting yet" + "message" => + "RabbitMQ on node #{node_name} is fully booted (check with is_running), stopped or has not started booting yet" } + {:ok, m} end + def output(true, %{node: node_name}) do {:ok, "RabbitMQ on node #{node_name} is booting"} end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_running_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_running_command.ex index f792435afbe5..7a6128ca3589 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_running_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/is_running_command.ex @@ -18,19 +18,28 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.IsRunningCommand do end def output(true, %{node: node_name, formatter: "json"}) do - {:ok, %{"result" => true, "message" => "RabbitMQ on node #{node_name} is fully booted and running"}} + {:ok, + %{"result" => true, "message" => "RabbitMQ on node #{node_name} is fully booted and running"}} end + def output(false, %{node: node_name, formatter: "json"}) do {:ok, - %{"result" => false, "message" => "RabbitMQ on node #{node_name} is not running or has not fully booted yet (check with is_booting)"}} + %{ + "result" => false, + "message" => + "RabbitMQ on node #{node_name} is not running or has not fully booted yet (check with is_booting)" + }} end + def output(true, %{node: node_name}) do {:ok, "RabbitMQ on node #{node_name} is fully booted and running"} end + def output(false, %{node: node_name}) do {:ok, "RabbitMQ on node #{node_name} is not running or has not fully booted yet (check with is_booting)"} end + use RabbitMQ.CLI.DefaultOutput def help_section(), do: :observability_and_health_checks diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_network_interfaces_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_network_interfaces_command.ex index 391b3163cb95..ec58a8ff6d1c 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_network_interfaces_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_network_interfaces_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNetworkInterfacesCommand do def run([], %{offline: true}) do :rabbit_net.getifaddrs() end + def run([], %{node: node_name, timeout: timeout}) do :rabbit_misc.rpc_call(node_name, :rabbit_net, :getifaddrs, [], timeout) end @@ -29,11 +30,14 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNetworkInterfacesCommand do def output(nic_map, %{node: node_name, formatter: "json"}) when map_size(nic_map) == 0 do {:ok, %{"result" => "ok", "node" => node_name, "interfaces" => %{}}} end + def output(nic_map, %{node: node_name}) when map_size(nic_map) == 0 do {:ok, "Node #{node_name} reported no network interfaces"} end + def output(nic_map0, %{node: node_name, formatter: "json"}) do - nic_map = Enum.map(nic_map0, fn ({k, v}) -> {to_string(k), v} end) + nic_map = Enum.map(nic_map0, fn {k, v} -> {to_string(k), v} end) + {:ok, %{ "result" => "ok", @@ -41,11 +45,13 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNetworkInterfacesCommand do "message" => "Node #{node_name} reported network interfaces" }} end + def output(nic_map, _) when is_map(nic_map) do lines = nic_lines(nic_map) {:ok, Enum.join(lines, line_separator())} end + use RabbitMQ.CLI.DefaultOutput def help_section(), do: :observability_and_health_checks @@ -63,15 +69,14 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNetworkInterfacesCommand do # defp nic_lines(nic_map) do - Enum.reduce(nic_map, [], - fn({iface, props}, acc) -> - iface_lines = Enum.reduce(props, [], - fn({prop, val}, inner_acc) -> - ["#{prop}: #{val}" | inner_acc] - end) - - header = "#{bright("Interface #{iface}")}\n" - acc ++ [header | iface_lines] ++ ["\n"] - end) + Enum.reduce(nic_map, [], fn {iface, props}, acc -> + iface_lines = + Enum.reduce(props, [], fn {prop, val}, inner_acc -> + ["#{prop}: #{val}" | inner_acc] + end) + + header = "#{bright("Interface #{iface}")}\n" + acc ++ [header | iface_lines] ++ ["\n"] + end) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_node_auth_attempt_stats_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_node_auth_attempt_stats_command.ex index 35b2207fe0af..3ef829ad67bc 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_node_auth_attempt_stats_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/list_node_auth_attempt_stats_command.ex @@ -26,30 +26,45 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNodeAuthAttemptStatsCommand do def run([], %{node: node_name, timeout: timeout, by_source: by_source}) do case by_source do - :true -> + true -> :rabbit_misc.rpc_call( - node_name, :rabbit_core_metrics, :get_auth_attempts_by_source, [], timeout) - :false -> + node_name, + :rabbit_core_metrics, + :get_auth_attempts_by_source, + [], + timeout + ) + + false -> :rabbit_misc.rpc_call( - node_name, :rabbit_core_metrics, :get_auth_attempts, [], timeout) + node_name, + :rabbit_core_metrics, + :get_auth_attempts, + [], + timeout + ) end end def output([], %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name, "attempts" => []}} end - def output([], %{node: node_name}) do + + def output([], %{node: node_name}) do {:ok, "Node #{node_name} reported no authentication attempt stats"} end + def output(rows, %{node: node_name, formatter: "json"}) do maps = Enum.map(rows, &Map.new/1) + {:ok, %{ - "result" => "ok", - "node" => node_name, + "result" => "ok", + "node" => node_name, "attempts" => maps }} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "list_node_auth_attempts [--by-source]" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_location_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_location_command.ex index 31fd18dafd2d..321567629e9d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_location_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_location_command.ex @@ -23,25 +23,29 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.LogLocationCommand do def run([], %{node: node_name, timeout: timeout, all: all}) do case all do - true -> LogFiles.get_log_locations(node_name, timeout); + true -> LogFiles.get_log_locations(node_name, timeout) false -> LogFiles.get_default_log_location(node_name, timeout) end end def output({:ok, location}, %{node: node_name, formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "node_name" => node_name, - "paths" => [location] - }} + {:ok, + %{ + "result" => "ok", + "node_name" => node_name, + "paths" => [location] + }} end + def output(locations, %{node: node_name, formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "node_name" => node_name, - "paths" => locations - }} + {:ok, + %{ + "result" => "ok", + "node_name" => node_name, + "paths" => locations + }} end + use RabbitMQ.CLI.DefaultOutput def help_section(), do: :configuration diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_command.ex index da43a3e4232f..b868d94cce41 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_command.ex @@ -13,20 +13,21 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.LogTailCommand do alias RabbitMQ.CLI.Core.LogFiles def switches, do: [number: :integer, timeout: :integer] - def aliases, do: ['N': :number, t: :timeout] + def aliases, do: [N: :number, t: :timeout] def merge_defaults(args, opts) do {args, Map.merge(%{number: 50}, opts)} end + use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name, timeout: timeout, number: n}) do case LogFiles.get_default_log_location(node_name, timeout) do {:ok, file} -> - :rabbit_misc.rpc_call(node_name, - :rabbit_log_tail, :tail_n_lines, [file, n], - timeout) - error -> error + :rabbit_misc.rpc_call(node_name, :rabbit_log_tail, :tail_n_lines, [file, n], timeout) + + error -> + error end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_stream_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_stream_command.ex index 153aad854e44..88c440111ba1 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_stream_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/log_tail_stream_command.ex @@ -12,7 +12,6 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.LogTailStreamCommand do alias RabbitMQ.CLI.Core.LogFiles - def switches(), do: [duration: :integer, timeout: :integer] def aliases(), do: [d: :duration, t: :timeout] @@ -29,24 +28,38 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.LogTailStreamCommand do {:ok, file} -> pid = self() ref = make_ref() - subscribed = :rabbit_misc.rpc_call( - node_name, - :rabbit_log_tail, :init_tail_stream, - [file, pid, ref, duration], - timeout) + + subscribed = + :rabbit_misc.rpc_call( + node_name, + :rabbit_log_tail, + :init_tail_stream, + [file, pid, ref, duration], + timeout + ) + case subscribed do {:ok, ^ref} -> - Stream.unfold(:confinue, - fn(:finished) -> nil - (:confinue) -> + Stream.unfold( + :confinue, + fn + :finished -> + nil + + :confinue -> receive do - {^ref, data, :finished} -> {data, :finished}; + {^ref, data, :finished} -> {data, :finished} {^ref, data, :confinue} -> {data, :confinue} end - end) - error -> error + end + ) + + error -> + error end - error -> error + + error -> + error end end @@ -67,6 +80,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.LogTailStreamCommand do def banner([], %{node: node_name, duration: :infinity}) do "Streaming logs from node #{node_name} ..." end + def banner([], %{node: node_name, duration: duration}) do "Streaming logs from node #{node_name} for #{duration} seconds ..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/maybe_stuck_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/maybe_stuck_command.ex index fd53c06017c8..84ac6820fea3 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/maybe_stuck_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/maybe_stuck_command.ex @@ -19,7 +19,9 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.MaybeStuckCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Detects Erlang processes (\"lightweight threads\") potentially not making progress on the target node" + def description(), + do: + "Detects Erlang processes (\"lightweight threads\") potentially not making progress on the target node" def usage, do: "maybe_stuck" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/memory_breakdown_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/memory_breakdown_command.ex index aeff315f4273..653989b418ca 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/memory_breakdown_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/memory_breakdown_command.ex @@ -68,7 +68,10 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.MemoryBreakdownCommand do def usage_additional() do [ ["--unit ", "byte multiple (bytes, megabytes, gigabytes) to use"], - ["--formatter ", "alternative formatter to use, JSON, CSV or Erlang terms"] + [ + "--formatter ", + "alternative formatter to use, JSON, CSV or Erlang terms" + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/observer_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/observer_command.ex index de39a10736b6..318864017cfe 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/observer_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/observer_command.ex @@ -15,16 +15,15 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ObserverCommand do {args, Map.merge(%{interval: 5}, opts)} end - use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments def run([], %{node: node_name, interval: interval}) do case :observer_cli.start(node_name, [{:interval, interval * 1000}]) do # See zhongwencool/observer_cli#54 - {:badrpc, _} = err -> err - {:error, _} = err -> err + {:badrpc, _} = err -> err + {:error, _} = err -> err {:error, _, _} = err -> err - :ok -> {:ok, "Disconnected from #{node_name}."} + :ok -> {:ok, "Disconnected from #{node_name}."} :quit -> {:ok, "Disconnected from #{node_name}."} other -> other end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/os_env_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/os_env_command.ex index 2ddba9b11c52..2d85f993d34e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/os_env_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/os_env_command.ex @@ -22,34 +22,47 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.OsEnvCommand do def run([], %{node: node_name, timeout: timeout}) do case :rabbit_misc.rpc_call(node_name, :rabbit_env, :get_used_env_vars, [], timeout) do - {:error, _} = err -> err - {:error, _, _} = err -> err + {:error, _} = err -> + err + + {:error, _, _} = err -> + err + xs when is_list(xs) -> # convert keys and values to binaries (Elixir strings) xs - |> Enum.map(fn {k, v} -> {:rabbit_data_coercion.to_binary(k), :rabbit_data_coercion.to_binary(v)} end) - |> :maps.from_list - other -> other + |> Enum.map(fn {k, v} -> + {:rabbit_data_coercion.to_binary(k), :rabbit_data_coercion.to_binary(v)} + end) + |> :maps.from_list() + + other -> + other end end def output([], %{formatter: fmt}) when fmt == "csv" or fmt == "erlang" do {:ok, []} end + def output([], %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name, "variables" => []}} end + def output([], %{node: node_name}) do {:ok, "Node #{node_name} reported no relevant environment variables."} end + def output(vars, %{node: node_name, formatter: "json"}) do {:ok, %{"result" => "ok", "node" => node_name, "variables" => vars}} end + def output(vars, %{formatter: "csv"}) do - {:stream, [Enum.map(vars, fn({k, v}) -> [variable: k, value: v] end)]} + {:stream, [Enum.map(vars, fn {k, v} -> [variable: k, value: v] end)]} end + def output(vars, _opts) do - lines = Enum.map(vars, fn({k, v}) -> "#{k}=#{v}" end) |> Enum.join(line_separator()) + lines = Enum.map(vars, fn {k, v} -> "#{k}=#{v}" end) |> Enum.join(line_separator()) {:ok, lines} end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/remote_shell_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/remote_shell_command.ex index 5c2cea8bb5eb..af3deb52cd6a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/remote_shell_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/remote_shell_command.ex @@ -15,9 +15,10 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.RemoteShellCommand do Process.flag(:trap_exit, true) user_drv = :user_drv.start(['tty_sl -c -e', {node_name, :shell, :start, []}]) Process.link(user_drv) + receive do - {'EXIT', _user_drv, _} -> - {:ok, "Disconnected from #{node_name}."} + {'EXIT', _user_drv, _} -> + {:ok, "Disconnected from #{node_name}."} end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolve_hostname_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolve_hostname_command.ex index 30f032ae1846..a01c2165f740 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolve_hostname_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolve_hostname_command.ex @@ -28,20 +28,32 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolveHostnameCommand do def validate(args, _) when length(args) < 1, do: {:validation_failure, :not_enough_args} def validate(args, _) when length(args) > 1, do: {:validation_failure, :too_many_args} + def validate([_], %{address_family: family}) do case Networking.valid_address_family?(family) do - true -> :ok - false -> {:validation_failure, {:bad_argument, "unsupported IP address family #{family}. Valid values are: ipv4, ipv6"}} + true -> + :ok + + false -> + {:validation_failure, + {:bad_argument, "unsupported IP address family #{family}. Valid values are: ipv4, ipv6"}} end end + def validate([_], _), do: :ok def run([hostname], %{address_family: family, offline: true}) do :inet.gethostbyname(to_charlist(hostname), Networking.address_family(family)) end + def run([hostname], %{node: node_name, address_family: family, offline: false, timeout: timeout}) do - case :rabbit_misc.rpc_call(node_name, :inet, :gethostbyname, - [to_charlist(hostname), Networking.address_family(family)], timeout) do + case :rabbit_misc.rpc_call( + node_name, + :inet, + :gethostbyname, + [to_charlist(hostname), Networking.address_family(family)], + timeout + ) do {:error, _} = err -> err {:error, _, _} = err -> err {:ok, result} -> {:ok, result} @@ -51,30 +63,38 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolveHostnameCommand do def output({:error, :nxdomain}, %{node: node_name, formatter: "json"}) do m = %{ - "result" => "error", - "node" => node_name, + "result" => "error", + "node" => node_name, "message" => "Hostname does not resolve (resolution failed with an nxdomain)" } + {:error, ExitCodes.exit_dataerr(), m} end + def output({:error, :nxdomain}, _opts) do - {:error, ExitCodes.exit_dataerr(), "Hostname does not resolve (resolution failed with an nxdomain)"} + {:error, ExitCodes.exit_dataerr(), + "Hostname does not resolve (resolution failed with an nxdomain)"} end + def output({:ok, result}, %{node: node_name, address_family: family, formatter: "json"}) do - hostname = hostent(result, :h_name) + hostname = hostent(result, :h_name) addresses = hostent(result, :h_addr_list) - {:ok, %{ - "result" => "ok", - "node" => node_name, - "hostname" => to_string(hostname), - "address_family" => family, - "addresses" => Networking.format_addresses(addresses) - }} + + {:ok, + %{ + "result" => "ok", + "node" => node_name, + "hostname" => to_string(hostname), + "address_family" => family, + "addresses" => Networking.format_addresses(addresses) + }} end + def output({:ok, result}, _opts) do addresses = hostent(result, :h_addr_list) {:ok, Enum.join(Networking.format_addresses(addresses), "\n")} end + use RabbitMQ.CLI.DefaultOutput def usage() do @@ -83,11 +103,13 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolveHostnameCommand do def help_section(), do: :configuration - def description(), do: "Resolves a hostname to a set of addresses. Takes Erlang's inetrc file into account." + def description(), + do: "Resolves a hostname to a set of addresses. Takes Erlang's inetrc file into account." def banner([hostname], %{offline: false, node: node_name, address_family: family}) do "Asking node #{node_name} to resolve hostname #{hostname} to #{family} addresses..." end + def banner([hostname], %{offline: true, address_family: family}) do "Resolving hostname #{hostname} to #{family} addresses..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolver_info_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolver_info_command.ex index b285aa9a99dc..ed6f13185a2e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolver_info_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/resolver_info_command.ex @@ -30,6 +30,7 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolverInfoCommand do def run([], %{offline: true}) do Networking.inetrc_map(:inet.get_rc()) end + def run([], %{node: node_name, timeout: timeout, offline: false}) do case :rabbit_misc.rpc_call(node_name, :inet, :get_rc, [], timeout) do {:error, _} = err -> err @@ -40,12 +41,14 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolverInfoCommand do end def output(info, %{node: node_name, formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "node" => node_name, - "resolver" => info - }} + {:ok, + %{ + "result" => "ok", + "node" => node_name, + "resolver" => info + }} end + def output(info, _opts) do main_section = [ "#{bright("Runtime Hostname Resolver (inetrc) Settings")}\n", @@ -54,13 +57,16 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolverInfoCommand do "Resolver conf file: #{info["resolv_conf"]}", "Cache size: #{info["cache_size"]}" ] - hosts_section = [ - "\n#{bright("inetrc File Host Entries")}\n" - ] ++ case info["hosts"] do - [] -> ["(none)"] - nil -> ["(none)"] - hs -> Enum.reduce(hs, [], fn {k, v}, acc -> ["#{k} #{Enum.join(v, ", ")}" | acc] end) - end + + hosts_section = + [ + "\n#{bright("inetrc File Host Entries")}\n" + ] ++ + case info["hosts"] do + [] -> ["(none)"] + nil -> ["(none)"] + hs -> Enum.reduce(hs, [], fn {k, v}, acc -> ["#{k} #{Enum.join(v, ", ")}" | acc] end) + end lines = main_section ++ hosts_section @@ -73,11 +79,13 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ResolverInfoCommand do def help_section(), do: :configuration - def description(), do: "Displays effective hostname resolver (inetrc) configuration on target node" + def description(), + do: "Displays effective hostname resolver (inetrc) configuration on target node" def banner(_, %{node: node_name, offline: false}) do "Asking node #{node_name} for its effective hostname resolver (inetrc) configuration..." end + def banner(_, %{offline: true}) do "Displaying effective hostname resolver (inetrc) configuration used by CLI tools..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/runtime_thread_stats_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/runtime_thread_stats_command.ex index b5c878729e55..79582129a446 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/runtime_thread_stats_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/runtime_thread_stats_command.ex @@ -46,7 +46,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.RuntimeThreadStatsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Provides a breakdown of runtime thread activity stats on the target node" + def description(), + do: "Provides a breakdown of runtime thread activity stats on the target node" def usage, do: "runtime_thread_stats [--sample-interval ]" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/server_version_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/server_version_command.ex index 15c8cfe69bf5..a8d73f9d3a45 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/server_version_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/server_version_command.ex @@ -13,12 +13,14 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.ServerVersionCommand do def run([], %{node: node_name, timeout: timeout}) do :rabbit_data_coercion.to_binary( - :rabbit_misc.rpc_call(node_name, :rabbit_misc, :version, [], timeout)) + :rabbit_misc.rpc_call(node_name, :rabbit_misc, :version, [], timeout) + ) end def output(result, %{formatter: "json"}) do {:ok, %{"result" => "ok", "value" => result}} end + def output(result, _options) when is_bitstring(result) do {:ok, result} end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/tls_versions_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/tls_versions_command.ex index 2e1111eecbc2..cda4bdc5f684 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/tls_versions_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/tls_versions_command.ex @@ -31,7 +31,8 @@ defmodule RabbitMQ.CLI.Diagnostics.Commands.TlsVersionsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Lists TLS versions supported (but not necessarily allowed) on the target node" + def description(), + do: "Lists TLS versions supported (but not necessarily allowed) on the target node" def usage, do: "tls_versions" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/diagnostics_helpers.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/diagnostics_helpers.ex index 73a7693bde15..908cd7266f29 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/diagnostics_helpers.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/diagnostics_helpers.ex @@ -6,15 +6,16 @@ defmodule RabbitMQ.CLI.Diagnostics.Helpers do def test_connection(hostname, port, timeout) do - case :gen_tcp.connect(hostname, port, [], timeout) do - {:error, _} -> :gen_tcp.connect(hostname, port, [:inet6], timeout) - r -> r - end + case :gen_tcp.connect(hostname, port, [], timeout) do + {:error, _} -> :gen_tcp.connect(hostname, port, [:inet6], timeout) + r -> r + end end def check_port_connectivity(port, node_name, timeout) do regex = Regex.recompile!(~r/^(.+)@/) hostname = Regex.replace(regex, to_string(node_name), "") |> to_charlist + try do case test_connection(hostname, port, timeout) do {:error, _} -> diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatter_behaviour.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatter_behaviour.ex index 0eedbd0f82b6..3b22a9a8217e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatter_behaviour.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatter_behaviour.ex @@ -28,14 +28,16 @@ defmodule RabbitMQ.CLI.FormatterBehaviour do def module_name(nil) do nil end + def module_name(formatter) do - mod = formatter |> String.downcase |> Macro.camelize + mod = formatter |> String.downcase() |> Macro.camelize() Module.safe_concat("RabbitMQ.CLI.Formatters", mod) end def machine_readable?(nil) do false end + def machine_readable?(formatter) do Helpers.apply_if_exported(module_name(formatter), :machine_readable?, [], false) end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/formatter_helpers.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/formatter_helpers.ex index d05a7df63174..cd931d6a824d 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/formatter_helpers.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/formatter_helpers.ex @@ -33,7 +33,6 @@ defmodule RabbitMQ.CLI.Formatters.FormatterHelpers do def proplist?([]), do: true def proplist?(_other), do: false - defmacro is_u8(x) do quote do unquote(x) >= 0 and unquote(x) <= 255 diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json.ex index 81d2b7cca5e2..5f048e72a443 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json.ex @@ -16,6 +16,7 @@ defmodule RabbitMQ.CLI.Formatters.Json do def format_output(output, opts) when is_bitstring(output) do format_output(%{"message" => output}, opts) end + def format_output(output, _opts) do {:ok, json} = JSON.encode(keys_to_atoms(output)) json @@ -29,7 +30,7 @@ defmodule RabbitMQ.CLI.Formatters.Json do fn [first | _] = element -> case FormatterHelpers.proplist?(first) or is_map(first) do - true -> element + true -> element false -> [element] end @@ -54,11 +55,16 @@ defmodule RabbitMQ.CLI.Formatters.Json do end def keys_to_atoms(enum) do - Enum.map(enum, - fn({k, v}) when is_binary(k) or is_list(k) -> - {String.to_atom(k), v} - (other) -> other - end) + Enum.map( + enum, + fn + {k, v} when is_binary(k) or is_list(k) -> + {String.to_atom(k), v} + + other -> + other + end + ) end def format_element(val, separator, options) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json_stream.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json_stream.ex index b95b8931577a..ff965a771f26 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json_stream.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/json_stream.ex @@ -29,6 +29,7 @@ defmodule RabbitMQ.CLI.Formatters.JsonStream do # we just emit the empty string as the last value for the stream in this case "" end + def format_output(output, _opts) do {:ok, json} = JSON.encode(keys_to_atoms(output)) json @@ -41,7 +42,7 @@ defmodule RabbitMQ.CLI.Formatters.JsonStream do fn [first | _] = element -> case FormatterHelpers.proplist?(first) or is_map(first) do - true -> element + true -> element false -> [element] end @@ -60,11 +61,16 @@ defmodule RabbitMQ.CLI.Formatters.JsonStream do end def keys_to_atoms(enum) do - Enum.map(enum, - fn({k, v}) when is_binary(k) or is_list(k) -> - {String.to_atom(k), v} - (other) -> other - end) + Enum.map( + enum, + fn + {k, v} when is_binary(k) or is_list(k) -> + {String.to_atom(k), v} + + other -> + other + end + ) end def format_element(val, options) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/plugins.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/plugins.ex index 7e6d24def240..4f9792b8db50 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/plugins.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/plugins.ex @@ -162,9 +162,11 @@ defmodule RabbitMQ.CLI.Formatters.Plugins do defp legend(_, :minimal, _) do [] end + defp legend(_, _, %{quiet: true}) do [] end + defp legend(_, _, %{silent: true}) do [] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/pretty_table.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/pretty_table.ex index b2e4871fe617..f0cf03617314 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/pretty_table.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/pretty_table.ex @@ -12,76 +12,120 @@ defmodule RabbitMQ.CLI.Formatters.PrettyTable do require Record import Record - defrecord :table , extract(:table, - from_lib: "stdout_formatter/include/stdout_formatter.hrl") - defrecord :cell, extract(:cell, - from_lib: "stdout_formatter/include/stdout_formatter.hrl") - defrecord :paragraph, extract(:paragraph, - from_lib: "stdout_formatter/include/stdout_formatter.hrl") + defrecord :table, + extract(:table, + from_lib: "stdout_formatter/include/stdout_formatter.hrl" + ) + + defrecord :cell, + extract(:cell, + from_lib: "stdout_formatter/include/stdout_formatter.hrl" + ) + + defrecord :paragraph, + extract(:paragraph, + from_lib: "stdout_formatter/include/stdout_formatter.hrl" + ) def format_stream(stream, _opts) do # Flatten for list_consumers - entries_with_keys = Stream.flat_map(stream, - fn([first | _] = element) -> - case FormatterHelpers.proplist?(first) or is_map(first) do - true -> element; - false -> [element] + entries_with_keys = + Stream.flat_map( + stream, + fn + [first | _] = element -> + case FormatterHelpers.proplist?(first) or is_map(first) do + true -> element + false -> [element] + end + + other -> + [other] end - (other) -> - [other] - end) + ) |> Enum.to_list() # Use stdout_formatter library to format the table. case entries_with_keys do [first_entry | _] -> - col_headers = Stream.map(first_entry, - fn({key, _}) -> - cell(content: key, props: %{:title => true}) - end) + col_headers = + Stream.map( + first_entry, + fn {key, _} -> + cell(content: key, props: %{:title => true}) + end + ) |> Enum.to_list() - rows = Stream.map(entries_with_keys, - fn(element) -> - Stream.map(element, - fn({_, value}) -> - cell(content: value, props: %{}) - end) + + rows = + Stream.map( + entries_with_keys, + fn element -> + Stream.map( + element, + fn {_, value} -> + cell(content: value, props: %{}) + end + ) |> Enum.to_list() - end) + end + ) |> Enum.to_list() - ret = :stdout_formatter.to_string( - table( - rows: [col_headers | rows], - props: %{:cell_padding => {0, 1}})) - [to_string ret] + + ret = + :stdout_formatter.to_string( + table( + rows: [col_headers | rows], + props: %{:cell_padding => {0, 1}} + ) + ) + + [to_string(ret)] + [] -> entries_with_keys end end def format_output(output, _opts) do - format = case is_binary(output) do - true -> "~s" - false -> "~p" - end - ret = :stdout_formatter.to_string( - table( - rows: [ - [cell(content: "Output", props: %{:title => true})], - [cell( - content: paragraph(content: output, - props: %{:format => format}))]], - props: %{:cell_padding => {0, 1}})) - to_string ret + format = + case is_binary(output) do + true -> "~s" + false -> "~p" + end + + ret = + :stdout_formatter.to_string( + table( + rows: [ + [cell(content: "Output", props: %{:title => true})], + [ + cell( + content: + paragraph( + content: output, + props: %{:format => format} + ) + ) + ] + ], + props: %{:cell_padding => {0, 1}} + ) + ) + + to_string(ret) end def format_value(value) do case is_binary(value) do - true -> value - false -> case is_atom(value) do - true -> to_string(value) - false -> inspect(value) - end + true -> + value + + false -> + case is_atom(value) do + true -> to_string(value) + false -> inspect(value) + end end end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/disable_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/disable_command.ex index 89622b82adf3..c529d125735b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/disable_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/disable_command.ex @@ -109,8 +109,14 @@ defmodule RabbitMQ.CLI.Plugins.Commands.DisableCommand do def usage_additional() do [ [" [ ]", "names of plugins to disable separated by a space"], - ["--online", "contact target node to disable the plugins. Changes are applied immediately."], - ["--offline", "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted."], + [ + "--online", + "contact target node to disable the plugins. Changes are applied immediately." + ], + [ + "--offline", + "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted." + ], ["--all", "disable all currently enabled plugins"] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/enable_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/enable_command.ex index cde9e14472fd..54c856acabe3 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/enable_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/enable_command.ex @@ -79,8 +79,14 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do [ [" [ ]", "names of plugins to enable separated by a space"], ["--online", "contact target node to enable the plugins. Changes are applied immediately."], - ["--offline", "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted."], - ["--all", "enable all available plugins. Not recommended as some plugins may conflict or otherwise be incompatible!"] + [ + "--offline", + "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted." + ], + [ + "--all", + "enable all available plugins. Not recommended as some plugins may conflict or otherwise be incompatible!" + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/is_enabled.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/is_enabled.ex index 2a719a2508f6..1133cf59ce6a 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/is_enabled.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/is_enabled.ex @@ -99,7 +99,10 @@ defmodule RabbitMQ.CLI.Plugins.Commands.IsEnabledCommand do def usage_additional() do [ [" [ ]", "names of plugins to check separated by a space"], - ["--online", "contact target node to perform the check. Requires the node to be running and reachable."], + [ + "--online", + "contact target node to perform the check. Requires the node to be running and reachable." + ], ["--offline", "check enabled plugins file directly without contacting target node."] ] end @@ -120,7 +123,9 @@ defmodule RabbitMQ.CLI.Plugins.Commands.IsEnabledCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Health check that exits with a non-zero code if provided plugins are not enabled on target node" + def description(), + do: + "Health check that exits with a non-zero code if provided plugins are not enabled on target node" # # Implementation diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/list_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/list_command.ex index be4e1684c6df..0930e307811e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/list_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/list_command.ex @@ -114,7 +114,10 @@ defmodule RabbitMQ.CLI.Plugins.Commands.ListCommand do [ ["", "only list plugins that match a regular expression pattern"], ["--verbose", "output more information"], - ["--minimal", "only print plugin names. Most useful in compbination with --silent and --enabled."], + [ + "--minimal", + "only print plugin names. Most useful in compbination with --silent and --enabled." + ], ["--enabled", "only list enabled plugins"], ["--implicitly-enabled", "include plugins enabled as dependencies of other plugins"] ] diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/set_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/set_command.ex index b67f809aaf40..aa295ad1beeb 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/set_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/set_command.ex @@ -66,9 +66,15 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do def usage_additional() do [ - [" [ ]", "names of plugins to enable separated by a space. All other plugins will be disabled."], + [ + " [ ]", + "names of plugins to enable separated by a space. All other plugins will be disabled." + ], ["--online", "contact target node to enable the plugins. Changes are applied immediately."], - ["--offline", "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted."] + [ + "--offline", + "update enabled plugins file directly without contacting target node. Changes will be delayed until the node is restarted." + ] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/error_output.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/error_output.ex index fcb2662a108d..770a8dc30afa 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/error_output.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/error_output.ex @@ -12,9 +12,7 @@ defmodule RabbitMQ.CLI.Plugins.ErrorOutput do quote do def output({:error, {:enabled_plugins_mismatch, cli_path, node_path}}, opts) do {:error, ExitCodes.exit_dataerr(), - "Could not update enabled plugins file at #{cli_path}: target node #{opts[:node]} uses a different path (#{ - node_path - })"} + "Could not update enabled plugins file at #{cli_path}: target node #{opts[:node]} uses a different path (#{node_path})"} end def output({:error, {:cannot_read_enabled_plugins_file, path, :eacces}}, _opts) do diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/printer_behaviour.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/printer_behaviour.ex index 37dcd8192046..af5140031085 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/printer_behaviour.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/printer_behaviour.ex @@ -14,8 +14,9 @@ defmodule RabbitMQ.CLI.PrinterBehaviour do def module_name(nil) do nil end + def module_name(printer) do - mod = printer |> String.downcase |> Macro.camelize + mod = printer |> String.downcase() |> Macro.camelize() String.to_atom("RabbitMQ.CLI.Printers." <> mod) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/add_member_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/add_member_command.ex index 03aa928e66ac..3026a3dec538 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/add_member_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/add_member_command.ex @@ -19,6 +19,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.AddMemberCommand do :infinity -> @default_timeout other -> other end + {args, Map.merge(%{vhost: "/", timeout: timeout}, opts)} end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_mirror_sync_critical_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_mirror_sync_critical_command.ex index f7cbb91d9128..ae599f467d61 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_mirror_sync_critical_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_mirror_sync_critical_command.ex @@ -25,66 +25,88 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsMirrorSyncCriticalCommand do use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([], %{node: node_name, timeout: timeout}) do - case :rabbit_misc.rpc_call(node_name, - :rabbit_nodes, :is_single_node_cluster, [], timeout) do + case :rabbit_misc.rpc_call(node_name, :rabbit_nodes, :is_single_node_cluster, [], timeout) do # if target node is the only one in the cluster, the check makes little sense # and false positives can be misleading - true -> {:ok, :single_node_cluster} + true -> + {:ok, :single_node_cluster} + false -> - case :rabbit_misc.rpc_call(node_name, - :rabbit_amqqueue, :list_local_mirrored_classic_without_synchronised_mirrors_for_cli, [], timeout) do + case :rabbit_misc.rpc_call( + node_name, + :rabbit_amqqueue, + :list_local_mirrored_classic_without_synchronised_mirrors_for_cli, + [], + timeout + ) do [] -> {:ok, []} qs when is_list(qs) -> {:ok, qs} other -> other end - other -> other + + other -> + other end end def output({:ok, :single_node_cluster}, %{formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "message" => "Target node seems to be the only one in a single node cluster, the check does not apply" - }} + {:ok, + %{ + "result" => "ok", + "message" => + "Target node seems to be the only one in a single node cluster, the check does not apply" + }} end + def output({:ok, []}, %{formatter: "json"}) do {:ok, %{"result" => "ok"}} end + def output({:ok, :single_node_cluster}, %{silent: true}) do {:ok, :check_passed} end + def output({:ok, []}, %{silent: true}) do {:ok, :check_passed} end + def output({:ok, :single_node_cluster}, %{node: node_name}) do - {:ok, "Node #{node_name} seems to be the only one in a single node cluster, the check does not apply"} + {:ok, + "Node #{node_name} seems to be the only one in a single node cluster, the check does not apply"} end + def output({:ok, []}, %{node: node_name}) do - {:ok, "Node #{node_name} reported no classic mirrored queues without online synchronised mirrors"} + {:ok, + "Node #{node_name} reported no classic mirrored queues without online synchronised mirrors"} end + def output({:ok, qs}, %{node: node_name, formatter: "json"}) when is_list(qs) do {:error, :check_failed, %{ "result" => "error", "queues" => qs, - "message" => "Node #{node_name} reported local classic mirrored queues without online synchronised mirrors" + "message" => + "Node #{node_name} reported local classic mirrored queues without online synchronised mirrors" }} end + def output({:ok, qs}, %{silent: true}) when is_list(qs) do {:error, :check_failed} end + def output({:ok, qs}, %{node: node_name}) when is_list(qs) do lines = queue_lines(qs, node_name) {:error, :check_failed, Enum.join(lines, line_separator())} end + use RabbitMQ.CLI.DefaultOutput def help_section(), do: :observability_and_health_checks def description() do "Health check that exits with a non-zero code if there are classic mirrored queues " <> - "without online synchronised mirrors (queues that would potentially lose data if the target node is shut down)" + "without online synchronised mirrors (queues that would potentially lose data if the target node is shut down)" end def usage, do: "check_if_node_is_mirror_sync_critical" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_quorum_critical_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_quorum_critical_command.ex index 0c9251655079..aef86bc2d65c 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_quorum_critical_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/check_if_node_is_quorum_critical_command.ex @@ -27,56 +27,83 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsQuorumCriticalCommand do case :rabbit_misc.rpc_call(node_name, :rabbit_nodes, :is_single_node_cluster, [], timeout) do # if target node is the only one in the cluster, the check makes little sense # and false positives can be misleading - true -> {:ok, :single_node_cluster} + true -> + {:ok, :single_node_cluster} + false -> - case :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :is_being_drained_local_read, [node_name]) do + case :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :is_being_drained_local_read, [ + node_name + ]) do # if target node is under maintenance, it has already transferred all of its quorum queue # replicas. Don't consider it to be quorum critical. See rabbitmq/rabbitmq-server#2469 - true -> {:ok, :under_maintenance} + true -> + {:ok, :under_maintenance} + false -> - case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :list_with_minimum_quorum_for_cli, [], timeout) do + case :rabbit_misc.rpc_call( + node_name, + :rabbit_quorum_queue, + :list_with_minimum_quorum_for_cli, + [], + timeout + ) do [] -> {:ok, []} qs when is_list(qs) -> {:ok, qs} other -> other end end - other -> other + + other -> + other end end def output({:ok, :single_node_cluster}, %{formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "message" => "Target node seems to be the only one in a single node cluster, the check does not apply" - }} + {:ok, + %{ + "result" => "ok", + "message" => + "Target node seems to be the only one in a single node cluster, the check does not apply" + }} end + def output({:ok, :under_maintenance}, %{formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "message" => "Target node seems to be in maintenance mode, the check does not apply" - }} + {:ok, + %{ + "result" => "ok", + "message" => "Target node seems to be in maintenance mode, the check does not apply" + }} end + def output({:ok, []}, %{formatter: "json"}) do {:ok, %{"result" => "ok"}} end + def output({:ok, :single_node_cluster}, %{silent: true}) do {:ok, :check_passed} end + def output({:ok, :under_maintenance}, %{silent: true}) do {:ok, :check_passed} end + def output({:ok, []}, %{silent: true}) do {:ok, :check_passed} end + def output({:ok, :single_node_cluster}, %{node: node_name}) do - {:ok, "Node #{node_name} seems to be the only one in a single node cluster, the check does not apply"} + {:ok, + "Node #{node_name} seems to be the only one in a single node cluster, the check does not apply"} end + def output({:ok, :under_maintenance}, %{node: node_name}) do {:ok, "Node #{node_name} seems to be in maintenance mode, the check does not apply"} end + def output({:ok, []}, %{node: node_name}) do {:ok, "Node #{node_name} reported no quorum queues with minimum quorum"} end + def output({:ok, qs}, %{node: node_name, formatter: "json"}) when is_list(qs) do {:error, :check_failed, %{ @@ -85,21 +112,24 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsQuorumCriticalCommand do "message" => "Node #{node_name} reported local queues with minimum online quorum" }} end + def output({:ok, qs}, %{silent: true}) when is_list(qs) do {:error, :check_failed} end + def output({:ok, qs}, %{node: node_name}) when is_list(qs) do lines = queue_lines(qs, node_name) {:error, :check_failed, Enum.join(lines, line_separator())} end + use RabbitMQ.CLI.DefaultOutput def help_section(), do: :observability_and_health_checks def description() do "Health check that exits with a non-zero code if there are queues " <> - "with minimum online quorum (queues that would lose their quorum if the target node is shut down)" + "with minimum online quorum (queues that would lose their quorum if the target node is shut down)" end def usage, do: "check_if_node_is_quorum_critical" diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/grow_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/grow_command.ex index 70374dad9316..6a8a9c281697 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/grow_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/grow_command.ex @@ -10,16 +10,14 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do @behaviour RabbitMQ.CLI.CommandBehaviour - defp default_opts, do: %{vhost_pattern: ".*", - queue_pattern: ".*", - errors_only: false} + defp default_opts, do: %{vhost_pattern: ".*", queue_pattern: ".*", errors_only: false} def switches(), do: [ - vhost_pattern: :string, - queue_pattern: :string, - errors_only: :boolean - ] + vhost_pattern: :string, + queue_pattern: :string, + errors_only: :boolean + ] def merge_defaults(args, opts) do {args, Map.merge(default_opts(), opts)} @@ -32,40 +30,57 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do def validate(args, _) when length(args) > 2 do {:validation_failure, :too_many_args} end + def validate([_, s], _) do - case s do - "all" -> :ok - "even" -> :ok - _ -> - {:validation_failure, "strategy '#{s}' is not recognised."} - end + case s do + "all" -> + :ok + + "even" -> + :ok + + _ -> + {:validation_failure, "strategy '#{s}' is not recognised."} + end end use RabbitMQ.CLI.Core.RequiresRabbitAppRunning - def run([node, strategy], %{node: node_name, - vhost_pattern: vhost_pat, - queue_pattern: queue_pat, - errors_only: errors_only}) do - case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :grow, [ - to_atom(node), - vhost_pat, - queue_pat, - to_atom(strategy)]) do - {:error, _} = error -> error; - {:badrpc, _} = error -> error; + def run([node, strategy], %{ + node: node_name, + vhost_pattern: vhost_pat, + queue_pattern: queue_pat, + errors_only: errors_only + }) do + case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :grow, [ + to_atom(node), + vhost_pat, + queue_pat, + to_atom(strategy) + ]) do + {:error, _} = error -> + error + + {:badrpc, _} = error -> + error + results when errors_only -> for {{:resource, vhost, _kind, name}, {:errors, _, _} = res} <- results, - do: [{:vhost, vhost}, - {:name, name}, - {:size, format_size res}, - {:result, format_result res}] + do: [ + {:vhost, vhost}, + {:name, name}, + {:size, format_size(res)}, + {:result, format_result(res)} + ] + results -> for {{:resource, vhost, _kind, name}, res} <- results, - do: [{:vhost, vhost}, - {:name, name}, - {:size, format_size res}, - {:result, format_result res}] + do: [ + {:vhost, vhost}, + {:name, name}, + {:size, format_size(res)}, + {:result, format_result(res)} + ] end end @@ -73,12 +88,16 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do def formatter(), do: RabbitMQ.CLI.Formatters.Table - def usage, do: "grow [--vhost-pattern ] [--queue-pattern ]" + def usage, + do: "grow [--vhost-pattern ] [--queue-pattern ]" def usage_additional do [ ["", "node name to place replicas on"], - ["", "add a member for all matching queues or just those whose membership count is an even number"], + [ + "", + "add a member for all matching queues or just those whose membership count is an even number" + ], ["--queue-pattern ", "regular expression to match queue names"], ["--vhost-pattern ", "regular expression to match virtual host names"], ["--errors-only", "only list queues which reported an error"] @@ -93,7 +112,9 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do def help_section, do: :cluster_management - def description, do: "Grows quorum queue clusters by adding a member (replica) on the specified node for all matching queues" + def description, + do: + "Grows quorum queue clusters by adding a member (replica) on the specified node for all matching queues" def banner([node, strategy], _) do "Growing #{strategy} quorum queues on #{node}..." @@ -106,10 +127,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do defp format_size({:ok, size}) do size end + defp format_size({:error, _size, :timeout}) do # the actual size is uncertain here "?" end + defp format_size({:error, size, _}) do size end @@ -117,10 +140,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommand do defp format_result({:ok, _size}) do "ok" end + defp format_result({:error, _size, :timeout}) do "error: the operation timed out and may not have been completed" end + defp format_result({:error, _size, err}) do - :io.format "error: ~W", [err, 10] + :io.format("error: ~W", [err, 10]) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/peek_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/peek_command.ex index daf5b051de48..b79b71f0faf7 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/peek_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/peek_command.ex @@ -17,32 +17,40 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommand do def validate(args, _) when length(args) < 2 do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 2 do {:validation_failure, :too_many_args} end + def validate([_, raw_pos], _) do - pos = case Integer.parse(raw_pos) do - {n, _} -> n - :error -> :error - _ -> :error - end + pos = + case Integer.parse(raw_pos) do + {n, _} -> n + :error -> :error + _ -> :error + end invalid_pos = {:validation_failure, "position value must be a positive integer"} + case pos do - :error -> invalid_pos - num when num < 1 -> invalid_pos + :error -> invalid_pos + num when num < 1 -> invalid_pos num when num >= 1 -> :ok end end + use RabbitMQ.CLI.Core.RequiresRabbitAppRunning def run([name, pos] = _args, %{node: node_name, vhost: vhost}) do {pos, _} = Integer.parse(pos) + case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :peek, [vhost, name, pos]) do {:error, :classic_queue_not_supported} -> {:error, "Cannot peek into a classic queue"} + {:ok, msg} -> {:ok, msg} + err -> err end @@ -55,6 +63,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommand do "message" => "Target queue was not found in virtual host '#{vhost}'" }} end + def output({:error, :no_message_at_pos}, %{formatter: "json"}) do {:error, %{ @@ -62,6 +71,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommand do "message" => "Target queue does not have a message at that position" }} end + def output({:error, error}, %{formatter: "json"}) do {:error, %{ @@ -69,19 +79,24 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommand do "message" => "Failed to perform the operation: #{error}" }} end + def output({:error, :not_found}, %{vhost: vhost}) do {:error, "Target queue was not found in virtual host '#{vhost}'"} end + def output({:error, :no_message_at_pos}, _) do {:error, "Target queue does not have a message at that position"} end + def output({:ok, msg}, %{formatter: "json"}) do {:ok, %{"result" => "ok", "message" => Enum.into(msg, %{})}} end + def output({:ok, msg}, _) do - res = Enum.map(msg, fn {k,v} -> [{"keys", k}, {"values", v}] end) + res = Enum.map(msg, fn {k, v} -> [{"keys", k}, {"values", v}] end) {:stream, res} end + use RabbitMQ.CLI.DefaultOutput def formatter(), do: RabbitMQ.CLI.Formatters.PrettyTable @@ -92,8 +107,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommand do def usage_additional do [ - ["", "Name of the queue", - "", "Position in the queue, starts at 1"] + ["", "Name of the queue", "", "Position in the queue, starts at 1"] ] end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/rebalance_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/rebalance_command.ex index 92fb71c973e4..0837db8857a7 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/rebalance_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/rebalance_command.ex @@ -16,14 +16,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.RebalanceCommand do "quorum" ] - defp default_opts, do: %{vhost_pattern: ".*", - queue_pattern: ".*"} + defp default_opts, do: %{vhost_pattern: ".*", queue_pattern: ".*"} def switches(), do: [ - vhost_pattern: :string, - queue_pattern: :string - ] + vhost_pattern: :string, + queue_pattern: :string + ] use RabbitMQ.CLI.Core.RequiresRabbitAppRunning @@ -34,6 +33,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.RebalanceCommand do def validate([], _) do {:validation_failure, :not_enough_args} end + def validate(args, _) when length(args) > 1 do {:validation_failure, :too_many_args} end @@ -48,16 +48,16 @@ defmodule RabbitMQ.CLI.Queues.Commands.RebalanceCommand do end end - def run([type], %{node: node_name, - vhost_pattern: vhost_pat, - queue_pattern: queue_pat}) do + def run([type], %{node: node_name, vhost_pattern: vhost_pat, queue_pattern: queue_pat}) do arg = String.to_atom(type) :rabbit_misc.rpc_call(node_name, :rabbit_amqqueue, :rebalance, [arg, vhost_pat, queue_pat]) end def formatter(), do: RabbitMQ.CLI.Formatters.PrettyTable - def usage, do: "rebalance < all | classic | quorum > [--vhost-pattern ] [--queue-pattern ]" + def usage, + do: + "rebalance < all | classic | quorum > [--vhost-pattern ] [--queue-pattern ]" def usage_additional do [ @@ -75,17 +75,21 @@ defmodule RabbitMQ.CLI.Queues.Commands.RebalanceCommand do def help_section, do: :cluster_management - def description, do: "Re-balances leaders of replicated queues across up-and-running cluster nodes" + def description, + do: "Re-balances leaders of replicated queues across up-and-running cluster nodes" def banner([:all], _) do "Re-balancing leaders of all replicated queues..." end + def banner([:classic], _) do "Re-balancing leaders of replicated (mirrored, non-exclusive) classic queues..." end + def banner([:quorum], _) do "Re-balancing leaders of quorum queues..." end + def banner([type], _) do "Re-balancing leaders of #{type} queues..." end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/reclaim_quorum_memory_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/reclaim_quorum_memory_command.ex index 4c1ca15ee14e..2e81dffe1bf5 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/reclaim_quorum_memory_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/reclaim_quorum_memory_command.ex @@ -31,6 +31,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.ReclaimQuorumMemoryCommand do "message" => "Target queue was not found in virtual host '#{vhost}'" }} end + def output({:error, error}, %{formatter: "json"}) do {:error, %{ @@ -38,9 +39,11 @@ defmodule RabbitMQ.CLI.Queues.Commands.ReclaimQuorumMemoryCommand do "message" => "Failed to perform the operation: #{error}" }} end + def output({:error, :not_found}, %{vhost: vhost}) do {:error, "Target queue was not found in virtual host '#{vhost}'"} end + use RabbitMQ.CLI.DefaultOutput def usage() do @@ -62,7 +65,9 @@ defmodule RabbitMQ.CLI.Queues.Commands.ReclaimQuorumMemoryCommand do def help_section(), do: :operations - def description(), do: "Flushes quorum queue processes WAL, performs a full sweep GC on all of its local Erlang processes" + def description(), + do: + "Flushes quorum queue processes WAL, performs a full sweep GC on all of its local Erlang processes" def banner([name], %{}), do: "Will flush Raft WAL of quorum queue #{name} ..." diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/shrink_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/shrink_command.ex index 140b45039694..7747aed3501b 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/shrink_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/queues/commands/shrink_command.ex @@ -23,20 +23,29 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommand do def run([node], %{node: node_name, errors_only: errs}) do case :rabbit_misc.rpc_call(node_name, :rabbit_quorum_queue, :shrink_all, [to_atom(node)]) do - {:error, _} = error -> error; - {:badrpc, _} = error -> error; + {:error, _} = error -> + error + + {:badrpc, _} = error -> + error + results when errs -> for {{:resource, vhost, _kind, name}, {:error, _, _} = res} <- results, - do: [{:vhost, vhost}, - {:name, name}, - {:size, format_size(res)}, - {:result, format_result(res)}] + do: [ + {:vhost, vhost}, + {:name, name}, + {:size, format_size(res)}, + {:result, format_result(res)} + ] + results -> for {{:resource, vhost, _kind, name}, res} <- results, - do: [{:vhost, vhost}, - {:name, name}, - {:size, format_size(res)}, - {:result, format_result(res)}] + do: [ + {:vhost, vhost}, + {:name, name}, + {:size, format_size(res)}, + {:result, format_result(res)} + ] end end @@ -65,7 +74,8 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommand do def help_section, do: :cluster_management - def description, do: "Shrinks quorum queue clusters by removing any members (replicas) on the given node." + def description, + do: "Shrinks quorum queue clusters by removing any members (replicas) on the given node." # # Implementation @@ -74,10 +84,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommand do defp format_size({:ok, size}) do size end + defp format_size({:error, _size, :timeout}) do # the actual size is uncertain here "?" end + defp format_size({:error, size, _}) do size end @@ -85,13 +97,16 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommand do defp format_result({:ok, _size}) do "ok" end + defp format_result({:error, _size, :last_node}) do "error: the last node cannot be removed" end + defp format_result({:error, _size, :timeout}) do "error: the operation timed out and may not have been completed" end + defp format_result({:error, _size, err}) do - :io.format "error: ~W", [err, 10] + :io.format("error: ~W", [err, 10]) end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/delete_replica_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/delete_replica_command.ex index 2c12a7c2f8be..9f0c2213a3fe 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/delete_replica_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/delete_replica_command.ex @@ -31,6 +31,7 @@ defmodule RabbitMQ.CLI.Streams.Commands.DeleteReplicaCommand do {:error, :last_stream_member} -> {:error, "Cannot delete the last member of a stream"} + other -> other end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/set_stream_retention_policy_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/set_stream_retention_policy_command.ex index 2f9bff516632..2878e29a9f81 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/set_stream_retention_policy_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/set_stream_retention_policy_command.ex @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. - defmodule RabbitMQ.CLI.Streams.Commands.SetStreamRetentionPolicyCommand do alias RabbitMQ.CLI.Core.DocGuide @@ -17,9 +16,9 @@ defmodule RabbitMQ.CLI.Streams.Commands.SetStreamRetentionPolicyCommand do def run([name, retention_policy], %{node: node_name, vhost: vhost}) do :rabbit_misc.rpc_call(node_name, :rabbit_stream_queue, :set_retention_policy, [ - name, - vhost, - retention_policy + name, + vhost, + retention_policy ]) end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/stream_status_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/stream_status_command.ex index 6c6673dda57c..e87c5295ce36 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/stream_status_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/streams/commands/stream_status_command.ex @@ -17,7 +17,7 @@ defmodule RabbitMQ.CLI.Streams.Commands.StreamStatusCommand do use RabbitMQ.CLI.Core.AcceptsOnePositionalArgument use RabbitMQ.CLI.Core.RequiresRabbitAppRunning - def run([name] = _args, %{node: node_name, vhost: vhost, tracking: :false}) do + def run([name] = _args, %{node: node_name, vhost: vhost, tracking: false}) do case :rabbit_misc.rpc_call(node_name, :rabbit_stream_queue, :status, [vhost, name]) do {:error, :classic_queue_not_supported} -> {:error, "Cannot get stream status of a classic queue"} @@ -29,7 +29,8 @@ defmodule RabbitMQ.CLI.Streams.Commands.StreamStatusCommand do other end end - def run([name] = _args, %{node: node_name, vhost: vhost, tracking: :true}) do + + def run([name] = _args, %{node: node_name, vhost: vhost, tracking: true}) do case :rabbit_misc.rpc_call(node_name, :rabbit_stream_queue, :tracking_status, [vhost, name]) do {:error, :classic_queue_not_supported} -> {:error, "Cannot get stream status of a classic queue"} diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/time_unit.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/time_unit.ex index 814fd5c42862..c26b7c17bba6 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/time_unit.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/time_unit.ex @@ -44,5 +44,4 @@ defmodule RabbitMQ.CLI.TimeUnit do defp do_convert(time, "years") do time * @years_seconds end - end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_quorum_plus_one_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_quorum_plus_one_command.ex index 26a5e6a1ee4b..fd541d6e02ff 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_quorum_plus_one_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_quorum_plus_one_command.ex @@ -26,41 +26,69 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.AwaitOnlineQuorumPlusOneCommand do {args, Map.put(opts, :timeout, timeout)} end - def run([], %{node: node_name, timeout: timeout}) do rpc_timeout = timeout + 500 + case :rabbit_misc.rpc_call(node_name, :rabbit_nodes, :is_single_node_cluster, [], rpc_timeout) do # if target node is the only one in the cluster, the command makes little sense # and false positives can be misleading - true -> {:ok, :single_node_cluster} + true -> + {:ok, :single_node_cluster} + false -> - case :rabbit_misc.rpc_call(node_name, :rabbit_upgrade_preparation, :await_online_quorum_plus_one, [timeout], rpc_timeout) do - {:error, _} = err -> err - {:error, _, _} = err -> err - {:badrpc, _} = err -> err + case :rabbit_misc.rpc_call( + node_name, + :rabbit_upgrade_preparation, + :await_online_quorum_plus_one, + [timeout], + rpc_timeout + ) do + {:error, _} = err -> + err + + {:error, _, _} = err -> + err + + {:badrpc, _} = err -> + err + + true -> + :ok - true -> :ok - false -> {:error, "time is up, no quorum + 1 online replicas came online for at least some quorum queues"} + false -> + {:error, + "time is up, no quorum + 1 online replicas came online for at least some quorum queues"} end - other -> other + + other -> + other end end def output({:ok, :single_node_cluster}, %{formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "message" => "Target node seems to be the only one in a single node cluster, the check does not apply" - }} + {:ok, + %{ + "result" => "ok", + "message" => + "Target node seems to be the only one in a single node cluster, the check does not apply" + }} end + def output({:error, msg}, %{node: node_name, formatter: "json"}) do {:error, %{"result" => "error", "node" => node_name, "message" => msg}} end + def output({:ok, :single_node_cluster}, opts) do case output_less?(opts) do - true -> :ok; - false -> {:ok, "Target node seems to be the only one in a single node cluster, the command does not apply"} + true -> + :ok + + false -> + {:ok, + "Target node seems to be the only one in a single node cluster, the command does not apply"} end end + use RabbitMQ.CLI.DefaultOutput def usage, do: "await_online_quorum_plus_one" @@ -76,10 +104,10 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.AwaitOnlineQuorumPlusOneCommand do def description() do "Waits for all quorum queues to have an above minimum online quorum. " <> - "This makes sure that no queues would lose their quorum if the target node is shut down" + "This makes sure that no queues would lose their quorum if the target node is shut down" end def banner([], %{timeout: timeout}) do - "Will wait for a quorum + 1 of nodes to be online for all quorum queues for #{round(timeout/1000)} seconds..." + "Will wait for a quorum + 1 of nodes to be online for all quorum queues for #{round(timeout / 1000)} seconds..." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_synchronized_mirror_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_synchronized_mirror_command.ex index 7cc73dc93f25..7396a31f00d3 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_synchronized_mirror_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/await_online_synchronized_mirror_command.ex @@ -26,41 +26,69 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.AwaitOnlineSynchronizedMirrorCommand do {args, Map.put(opts, :timeout, timeout)} end - def run([], %{node: node_name, timeout: timeout}) do rpc_timeout = timeout + 500 + case :rabbit_misc.rpc_call(node_name, :rabbit_nodes, :is_single_node_cluster, [], rpc_timeout) do # if target node is the only one in the cluster, the command makes little sense # and false positives can be misleading - true -> {:ok, :single_node_cluster} + true -> + {:ok, :single_node_cluster} + false -> - case :rabbit_misc.rpc_call(node_name, :rabbit_upgrade_preparation, :await_online_synchronised_mirrors, [timeout], rpc_timeout) do - {:error, _} = err -> err - {:error, _, _} = err -> err - {:badrpc, _} = err -> err + case :rabbit_misc.rpc_call( + node_name, + :rabbit_upgrade_preparation, + :await_online_synchronised_mirrors, + [timeout], + rpc_timeout + ) do + {:error, _} = err -> + err + + {:error, _, _} = err -> + err + + {:badrpc, _} = err -> + err + + true -> + :ok - true -> :ok - false -> {:error, "time is up, no synchronised mirror came online for at least some classic mirrored queues"} + false -> + {:error, + "time is up, no synchronised mirror came online for at least some classic mirrored queues"} end - other -> other + + other -> + other end end def output({:ok, :single_node_cluster}, %{formatter: "json"}) do - {:ok, %{ - "result" => "ok", - "message" => "Target node seems to be the only one in a single node cluster, the check does not apply" - }} + {:ok, + %{ + "result" => "ok", + "message" => + "Target node seems to be the only one in a single node cluster, the check does not apply" + }} end + def output({:error, msg}, %{node: node_name, formatter: "json"}) do {:error, %{"result" => "error", "node" => node_name, "message" => msg}} end + def output({:ok, :single_node_cluster}, opts) do case output_less?(opts) do - true -> :ok; - false -> {:ok, "Target node seems to be the only one in a single node cluster, the command does not apply"} + true -> + :ok + + false -> + {:ok, + "Target node seems to be the only one in a single node cluster, the command does not apply"} end end + use RabbitMQ.CLI.DefaultOutput def usage, do: "await_online_synchronized_mirror" @@ -76,10 +104,10 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.AwaitOnlineSynchronizedMirrorCommand do def description() do "Waits for all classic mirrored queues hosted on the target node to have at least one synchronized mirror online. " <> - "This makes sure that if target node is shut down, there will be an up-to-date mirror to promote." + "This makes sure that if target node is shut down, there will be an up-to-date mirror to promote." end def banner([], %{timeout: timeout}) do - "Will wait for a synchronised mirror be online for all classic mirrored queues for #{round(timeout/1000)} seconds..." + "Will wait for a synchronised mirror be online for all classic mirrored queues for #{round(timeout / 1000)} seconds..." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/drain_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/drain_command.ex index b8f1e7b9eb97..79fe9038032c 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/drain_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/drain_command.ex @@ -25,14 +25,16 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.DrainCommand do case :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :drain, [], timeout) do # Server does not support maintenance mode {:badrpc, {:EXIT, {:undef, _}}} -> {:error, :unsupported} - {:badrpc, _} = err -> err - other -> other + {:badrpc, _} = err -> err + other -> other end end def output({:error, :unsupported}, %{node: node_name}) do - {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage, "Maintenance mode is not supported by node #{node_name}"} + {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage(), + "Maintenance mode is not supported by node #{node_name}"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "drain" @@ -45,10 +47,12 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.DrainCommand do def help_section(), do: :upgrade - def description(), do: "Puts the node in maintenance mode. Such nodes will not serve any client traffic or host any primary queue replicas" + def description(), + do: + "Puts the node in maintenance mode. Such nodes will not serve any client traffic or host any primary queue replicas" def banner(_, %{node: node_name}) do - "Will put node #{node_name} into maintenance mode. " - <> "The node will no longer serve any client traffic!" + "Will put node #{node_name} into maintenance mode. " <> + "The node will no longer serve any client traffic!" end end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/post_upgrade_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/post_upgrade_command.ex index a7899adf2197..d0cb57a5699e 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/post_upgrade_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/post_upgrade_command.ex @@ -33,7 +33,6 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.PostUpgradeCommand do def banner([], _) do "Executing post upgrade tasks...\n" <> - "Rebalancing queue masters..." + "Rebalancing queue masters..." end - end diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/revive_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/revive_command.ex index e50e3768438b..ea663ba538b3 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/revive_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/upgrade/commands/revive_command.ex @@ -27,14 +27,16 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.ReviveCommand do case :rabbit_misc.rpc_call(node_name, :rabbit_maintenance, :revive, [], timeout) do # Server does not support maintenance mode {:badrpc, {:EXIT, {:undef, _}}} -> {:error, :unsupported} - {:badrpc, _} = err -> err - other -> other + {:badrpc, _} = err -> err + other -> other end end def output({:error, :unsupported}, %{node: node_name}) do - {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage, "Maintenance mode is not supported by node #{node_name}"} + {:error, RabbitMQ.CLI.Core.ExitCodes.exit_usage(), + "Maintenance mode is not supported by node #{node_name}"} end + use RabbitMQ.CLI.DefaultOutput def usage, do: "revive" @@ -47,10 +49,12 @@ defmodule RabbitMQ.CLI.Upgrade.Commands.ReviveCommand do def help_section(), do: :upgrade - def description(), do: "Puts the node out of maintenance and into regular operating mode. Such nodes will again serve client traffic and host primary queue replicas" + def description(), + do: + "Puts the node out of maintenance and into regular operating mode. Such nodes will again serve client traffic and host primary queue replicas" def banner(_, %{node: node_name}) do - "Will put node #{node_name} back into regular operating mode. " - <> "The node will again serve client traffic and host primary queue replicas." + "Will put node #{node_name} back into regular operating mode. " <> + "The node will again serve client traffic and host primary queue replicas." end end diff --git a/deps/rabbitmq_cli/lib/rabbitmqctl.ex b/deps/rabbitmq_cli/lib/rabbitmqctl.ex index c6e4d0a48cd0..41d18da13fae 100644 --- a/deps/rabbitmq_cli/lib/rabbitmqctl.ex +++ b/deps/rabbitmq_cli/lib/rabbitmqctl.ex @@ -14,6 +14,7 @@ defmodule RabbitMQCtl do Output, Parser } + alias RabbitMQ.CLI.{CommandBehaviour, FormatterBehaviour} alias RabbitMQ.CLI.Ctl.Commands.HelpCommand @@ -37,23 +38,27 @@ defmodule RabbitMQCtl do # this invocation is considered to be invalid. curl and grep do the # same thing. - {:error, ExitCodes.exit_usage(), Enum.join(HelpCommand.all_usage(parsed_options), "")}; + {:error, ExitCodes.exit_usage(), Enum.join(HelpCommand.all_usage(parsed_options), "")} end + def exec_command(["--help"] = unparsed_command, _) do {_args, parsed_options, _} = Parser.parse_global(unparsed_command) # the user asked for --help and we are displaying it to her, # reporting a success - {:ok, ExitCodes.exit_ok(), Enum.join(HelpCommand.all_usage(parsed_options), "")}; + {:ok, ExitCodes.exit_ok(), Enum.join(HelpCommand.all_usage(parsed_options), "")} end + def exec_command(["--version"] = _unparsed_command, opts) do # rewrite `--version` as `version` exec_command(["version"], opts) end + def exec_command(["--auto-complete" | args], opts) do # rewrite `--auto-complete` as `autocomplete` exec_command(["autocomplete" | args], opts) end + def exec_command(unparsed_command, output_fun) do {command, command_name, arguments, parsed_options, invalid} = Parser.parse(unparsed_command) @@ -91,9 +96,10 @@ defmodule RabbitMQCtl do try do do_exec_parsed_command(unparsed_command, output_fun, arguments, command, options) - catch error_type, error -> - maybe_print_stacktrace(error_type, error, __STACKTRACE__, options) - format_error(error, options, command) + catch + error_type, error -> + maybe_print_stacktrace(error_type, error, __STACKTRACE__, options) + format_error(error, options, command) end end end @@ -101,7 +107,8 @@ defmodule RabbitMQCtl do def do_exec_parsed_command(unparsed_command, output_fun, arguments, command, options) do case options[:help] do true -> - {:ok, ExitCodes.exit_ok(), HelpCommand.command_usage(command, options)}; + {:ok, ExitCodes.exit_ok(), HelpCommand.command_usage(command, options)} + _ -> {arguments, options} = command.merge_defaults(arguments, options) @@ -110,13 +117,18 @@ defmodule RabbitMQCtl do case Helpers.normalise_node_option(options) do {:error, _} = err -> format_error(err, options, command) + {:ok, options} -> # The code below implements a tiny decision tree that has # to do with CLI argument and environment state validation. case command.validate(arguments, options) do :ok -> # then optionally validate execution environment - case CommandBehaviour.validate_execution_environment(command, arguments, options) do + case CommandBehaviour.validate_execution_environment( + command, + arguments, + options + ) do :ok -> result = proceed_to_execution(command, arguments, options) handle_command_output(result, command, options, output_fun) @@ -151,7 +163,8 @@ defmodule RabbitMQCtl do defp maybe_run_command(command, arguments, options) do try do command.run(arguments, options) |> command.output(options) - catch error_type, error -> + catch + error_type, error -> maybe_print_stacktrace(error_type, error, __STACKTRACE__, options) format_error(error, options, command) end @@ -160,21 +173,27 @@ defmodule RabbitMQCtl do def maybe_print_stacktrace(error_type, :undef = error, stacktrace, _opts) do do_print_stacktrace(error_type, error, stacktrace) end + def maybe_print_stacktrace(error_type, :function_clause = error, stacktrace, _opts) do do_print_stacktrace(error_type, error, stacktrace) end + def maybe_print_stacktrace(error_type, :badarg = error, stacktrace, _opts) do do_print_stacktrace(error_type, error, stacktrace) end + def maybe_print_stacktrace(error_type, {:case_clause, _val} = error, stacktrace, _opts) do do_print_stacktrace(error_type, error, stacktrace) end + def maybe_print_stacktrace(error_type, error, stacktrace, %{print_stacktrace: true}) do do_print_stacktrace(error_type, error, stacktrace) end + def maybe_print_stacktrace(_error_type, _error, _stacktrace, %{print_stacktrace: false}) do nil end + def maybe_print_stacktrace(_error_type, _error, _stacktrace, _opts) do nil end @@ -244,11 +263,13 @@ defmodule RabbitMQCtl do defp merge_defaults_node(%{} = opts) do longnames_opt = Config.get_option(:longnames, opts) + try do default_rabbit_nodename = Helpers.get_rabbit_hostname(longnames_opt) Map.merge(%{node: default_rabbit_nodename}, opts) - catch _error_type, _err -> - opts + catch + _error_type, _err -> + opts end end @@ -282,8 +303,11 @@ defmodule RabbitMQCtl do defp maybe_print_banner(command, args, opts) do # Suppress banner if a machine-readable formatter is used formatter = Map.get(opts, :formatter) + case FormatterBehaviour.machine_readable?(formatter) do - true -> nil + true -> + nil + false -> case command.banner(args, opts) do nil -> @@ -305,9 +329,7 @@ defmodule RabbitMQCtl do err = format_validation_error(err_detail) base_error = - "Error (argument validation): #{err}\nArguments given:\n\t#{ - unparsed_command |> Enum.join(" ") - }" + "Error (argument validation): #{err}\nArguments given:\n\t#{unparsed_command |> Enum.join(" ")}" validation_error_output(err_detail, base_error, command, options) end @@ -378,17 +400,20 @@ defmodule RabbitMQCtl do defp format_error({:error, {:node_name, :hostname_not_allowed}}, _, _) do {:error, ExitCodes.exit_dataerr(), - "Unsupported node name: hostname is invalid (possibly contains unsupported characters).\nIf using FQDN node names, use the -l / --longnames argument."} + "Unsupported node name: hostname is invalid (possibly contains unsupported characters).\nIf using FQDN node names, use the -l / --longnames argument."} end + defp format_error({:error, {:node_name, :invalid_node_name_head}}, _, _) do {:error, ExitCodes.exit_dataerr(), - "Unsupported node name: node name head (the part before the @) is invalid. Only alphanumerics, _ and - characters are allowed.\nIf using FQDN node names, use the -l / --longnames argument"} + "Unsupported node name: node name head (the part before the @) is invalid. Only alphanumerics, _ and - characters are allowed.\nIf using FQDN node names, use the -l / --longnames argument"} end + defp format_error({:error, {:node_name, err_reason} = result}, opts, module) do op = CommandModules.module_to_command(module) node = opts[:node] || "(failed to parse or compute default value)" + {:error, ExitCodes.exit_code_for(result), - "Error: operation #{op} failed due to invalid node name (node: #{node}, reason: #{err_reason}).\nIf using FQDN node names, use the -l / --longnames argument"} + "Error: operation #{op} failed due to invalid node name (node: #{node}, reason: #{err_reason}).\nIf using FQDN node names, use the -l / --longnames argument"} end defp format_error({:error, {:badrpc_multi, :nodedown, [node | _]} = result}, opts, _) do @@ -416,9 +441,7 @@ defmodule RabbitMQCtl do op = CommandModules.module_to_command(module) {:error, ExitCodes.exit_code_for(result), - "Error: operation #{op} on node #{opts[:node]} timed out. Timeout value used: #{ - opts[:timeout] - }"} + "Error: operation #{op} on node #{opts[:node]} timed out. Timeout value used: #{opts[:timeout]}"} end defp format_error({:error, {:badrpc, {:timeout, to}} = result}, opts, module) do @@ -432,17 +455,20 @@ defmodule RabbitMQCtl do op = CommandModules.module_to_command(module) {:error, ExitCodes.exit_code_for({:timeout, to}), - "Error: operation #{op} on node #{opts[:node]} timed out. Timeout value used: #{to}. #{ - warning - }"} + "Error: operation #{op} on node #{opts[:node]} timed out. Timeout value used: #{to}. #{warning}"} end defp format_error({:error, {:no_such_vhost, vhost} = result}, _opts, _) do {:error, ExitCodes.exit_code_for(result), "Virtual host '#{vhost}' does not exist"} end - defp format_error({:error, {:incompatible_version, local_version, remote_version} = result}, _opts, _) do - {:error, ExitCodes.exit_code_for(result), "Detected potential version incompatibility. CLI tool version: #{local_version}, server: #{remote_version}"} + defp format_error( + {:error, {:incompatible_version, local_version, remote_version} = result}, + _opts, + _ + ) do + {:error, ExitCodes.exit_code_for(result), + "Detected potential version incompatibility. CLI tool version: #{local_version}, server: #{remote_version}"} end defp format_error({:error, {:timeout, to} = result}, opts, module) do @@ -469,9 +495,7 @@ defmodule RabbitMQCtl do # Plugins defp format_error({:error, {:enabled_plugins_mismatch, cli_path, node_path}}, opts, _module) do {:error, ExitCodes.exit_dataerr(), - "Could not update enabled plugins file at #{cli_path}: target node #{opts[:node]} uses a different path (#{ - node_path - })"} + "Could not update enabled plugins file at #{cli_path}: target node #{opts[:node]} uses a different path (#{node_path})"} end defp format_error({:error, {:cannot_read_enabled_plugins_file, path, :eacces}}, _opts, _module) do @@ -499,16 +523,20 @@ defmodule RabbitMQCtl do defp format_error({:error, :check_failed}, %{formatter: "json"}, _) do {:error, ExitCodes.exit_unavailable(), nil} end + defp format_error({:error, :check_failed}, _, _) do {:error, ExitCodes.exit_unavailable(), nil} end + defp format_error({:error, :check_failed, err}, %{formatter: "json"}, _) when is_map(err) do {:ok, res} = JSON.encode(err) {:error, ExitCodes.exit_unavailable(), res} end + defp format_error({:error, :check_failed, err}, %{formatter: "json"}, _) do {:error, ExitCodes.exit_unavailable(), err} end + defp format_error({:error, :check_failed, err}, _, _) do {:error, ExitCodes.exit_unavailable(), err} end @@ -524,6 +552,7 @@ defmodule RabbitMQCtl do {:ok, res} = JSON.encode(err) {:error, ExitCodes.exit_unavailable(), res} end + defp format_error({:error, exit_code, err}, %{formatter: "json"}, _) when is_map(err) do {:ok, res} = JSON.encode(err) {:error, exit_code, res} @@ -582,9 +611,10 @@ defmodule RabbitMQCtl do defp maybe_with_distribution(command, options, code) do try do maybe_with_distribution_without_catch(command, options, code) - catch error_type, error -> - maybe_print_stacktrace(error_type, error, __STACKTRACE__, options) - format_error(error, options, command) + catch + error_type, error -> + maybe_print_stacktrace(error_type, error, __STACKTRACE__, options) + format_error(error, options, command) end end diff --git a/deps/rabbitmq_cli/mix.exs b/deps/rabbitmq_cli/mix.exs index d661b2ffcb5e..a34f72ee2053 100644 --- a/deps/rabbitmq_cli/mix.exs +++ b/deps/rabbitmq_cli/mix.exs @@ -10,6 +10,7 @@ defmodule RabbitMQCtl.MixfileBase do def project do [ app: :rabbitmqctl, +<<<<<<< HEAD version: "3.10.0-dev", elixir: ">= 1.10.4 and < 1.15.0", build_embedded: Mix.env == :prod, @@ -17,6 +18,13 @@ defmodule RabbitMQCtl.MixfileBase do escript: [main_module: RabbitMQCtl, emu_args: "-hidden", path: "escript/rabbitmqctl"], +======= + version: "3.11.0", + elixir: ">= 1.13.4 and < 1.15.0", + build_embedded: Mix.env() == :prod, + start_permanent: Mix.env() == :prod, + escript: [main_module: RabbitMQCtl, emu_args: "-hidden", path: "escript/rabbitmqctl"], +>>>>>>> 059978e6fa (mix format rabbitmq_cli) deps: deps(), aliases: aliases(), xref: [ @@ -47,55 +55,62 @@ defmodule RabbitMQCtl.MixfileBase do :stdout_formatter ] ] - ] + ] end # Configuration for the OTP application # # Type "mix help compile.app" for more information def application do - [applications: [:logger], - env: [scopes: ['rabbitmq-plugins': :plugins, - rabbitmqctl: :ctl, - 'rabbitmq-diagnostics': :diagnostics, - 'rabbitmq-queues': :queues, - 'rabbitmq-streams': :streams, - 'rabbitmq-upgrade': :upgrade, - 'rabbitmq-tanzu': :tanzu - ]] + [ + applications: [:logger], + env: [ + scopes: [ + "rabbitmq-plugins": :plugins, + rabbitmqctl: :ctl, + "rabbitmq-diagnostics": :diagnostics, + "rabbitmq-queues": :queues, + "rabbitmq-streams": :streams, + "rabbitmq-upgrade": :upgrade, + "rabbitmq-tanzu": :tanzu + ] + ] ] - |> add_modules(Mix.env) + |> add_modules(Mix.env()) end - defp add_modules(app, :test) do # There are issues with building a package without this line ¯\_(ツ)_/¯ - Mix.Project.get - path = Mix.Project.compile_path + Mix.Project.get() + path = Mix.Project.compile_path() mods = modules_from(Path.wildcard("#{path}/*.beam")) - test_modules = [RabbitMQ.CLI.Ctl.Commands.DuckCommand, - RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand, - RabbitMQ.CLI.Ctl.Commands.UglyDucklingCommand, - RabbitMQ.CLI.Plugins.Commands.StorkCommand, - RabbitMQ.CLI.Plugins.Commands.HeronCommand, - RabbitMQ.CLI.Custom.Commands.CrowCommand, - RabbitMQ.CLI.Custom.Commands.RavenCommand, - RabbitMQ.CLI.Seagull.Commands.SeagullCommand, - RabbitMQ.CLI.Seagull.Commands.PacificGullCommand, - RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - RabbitMQ.CLI.Seagull.Commands.HermannGullCommand, - RabbitMQ.CLI.Wolf.Commands.CanisLupusCommand, - RabbitMQ.CLI.Wolf.Commands.CanisLatransCommand, - RabbitMQ.CLI.Wolf.Commands.CanisAureusCommand - ] - [{:modules, mods ++ test_modules |> Enum.sort} | app] + + test_modules = [ + RabbitMQ.CLI.Ctl.Commands.DuckCommand, + RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand, + RabbitMQ.CLI.Ctl.Commands.UglyDucklingCommand, + RabbitMQ.CLI.Plugins.Commands.StorkCommand, + RabbitMQ.CLI.Plugins.Commands.HeronCommand, + RabbitMQ.CLI.Custom.Commands.CrowCommand, + RabbitMQ.CLI.Custom.Commands.RavenCommand, + RabbitMQ.CLI.Seagull.Commands.SeagullCommand, + RabbitMQ.CLI.Seagull.Commands.PacificGullCommand, + RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, + RabbitMQ.CLI.Seagull.Commands.HermannGullCommand, + RabbitMQ.CLI.Wolf.Commands.CanisLupusCommand, + RabbitMQ.CLI.Wolf.Commands.CanisLatransCommand, + RabbitMQ.CLI.Wolf.Commands.CanisAureusCommand + ] + + [{:modules, (mods ++ test_modules) |> Enum.sort()} | app] end + defp add_modules(app, _) do app end defp modules_from(beams) do - Enum.map beams, &(&1 |> Path.basename |> Path.rootname(".beam") |> String.to_atom) + Enum.map(beams, &(&1 |> Path.basename() |> Path.rootname(".beam") |> String.to_atom())) end # Dependencies can be Hex packages: @@ -123,51 +138,52 @@ defmodule RabbitMQCtl.MixfileBase do {:csv, "~> 2.4.0"}, {:stdout_formatter, "~> 0.2.3"}, {:observer_cli, "~> 1.7.3"}, - {:amqp, "~> 2.1.0", only: :test}, {:dialyxir, "~> 0.5", only: :test, runtime: false}, {:temp, "~> 0.4", only: :test}, {:x509, "~> 0.7", only: :test} ] - rabbitmq_deps = case System.get_env("DEPS_DIR") do - nil -> - # rabbitmq_cli is built as a standalone Elixir application. - [ - {:rabbit_common, "~> 3.8.0"}, - {:amqp_client, "~> 3.8.0", only: :test} - ] - deps_dir -> - # rabbitmq_cli is built as part of RabbitMQ. - - # Mix is confused by any `rebar.{config,lock}` we might have left in - # `rabbit_common` or `amqp_client`. So just remove those files to be - # safe, as they are generated when we publish to Hex.pm only. - for dir <- ["rabbit_common", "amqp_client"] do - for file <- ["rebar.config", "rebar.lock"] do - File.rm(Path.join([deps_dir, dir, file])) + rabbitmq_deps = + case System.get_env("DEPS_DIR") do + nil -> + # rabbitmq_cli is built as a standalone Elixir application. + [ + {:rabbit_common, "~> 3.8.0"}, + {:amqp_client, "~> 3.8.0", only: :test} + ] + + deps_dir -> + # rabbitmq_cli is built as part of RabbitMQ. + + # Mix is confused by any `rebar.{config,lock}` we might have left in + # `rabbit_common` or `amqp_client`. So just remove those files to be + # safe, as they are generated when we publish to Hex.pm only. + for dir <- ["rabbit_common", "amqp_client"] do + for file <- ["rebar.config", "rebar.lock"] do + File.rm(Path.join([deps_dir, dir, file])) + end end - end - - make_cmd = System.get_env("MAKE", "make") - is_bazel = System.get_env("IS_BAZEL") != nil - - [ - { - :rabbit_common, - path: Path.join(deps_dir, "rabbit_common"), - compile: (if is_bazel, do: false, else: make_cmd), - override: true - }, - { - :amqp_client, - path: Path.join(deps_dir, "amqp_client"), - compile: (if is_bazel, do: false, else: make_cmd), - override: true, - only: :test - }, - ] - end + + make_cmd = System.get_env("MAKE", "make") + is_bazel = System.get_env("IS_BAZEL") != nil + + [ + { + :rabbit_common, + path: Path.join(deps_dir, "rabbit_common"), + compile: if(is_bazel, do: false, else: make_cmd), + override: true + }, + { + :amqp_client, + path: Path.join(deps_dir, "amqp_client"), + compile: if(is_bazel, do: false, else: make_cmd), + override: true, + only: :test + } + ] + end elixir_deps ++ rabbitmq_deps end @@ -176,24 +192,24 @@ defmodule RabbitMQCtl.MixfileBase do [ make_deps: [ "deps.get", - "deps.compile", + "deps.compile" ], make_app: [ "compile", - "escript.build", + "escript.build" ], make_all: [ "deps.get", "deps.compile", "compile", - "escript.build", + "escript.build" ], make_all_in_src_archive: [ "deps.get --only prod", "deps.compile", "compile", - "escript.build", - ], + "escript.build" + ] ] end end diff --git a/deps/rabbitmq_cli/test/core/args_processing_test.exs b/deps/rabbitmq_cli/test/core/args_processing_test.exs index 18c67d3a4a6e..e34ef64a7085 100644 --- a/deps/rabbitmq_cli/test/core/args_processing_test.exs +++ b/deps/rabbitmq_cli/test/core/args_processing_test.exs @@ -22,12 +22,13 @@ defmodule ArgsProcessingTest do defp all_commands() do RabbitMQ.CLI.Core.CommandModules.load_commands(:all, %{}) - |> Map.values + |> Map.values() end defp line_filter([_, description]) do Regex.match?(~r/must be one of/, description) end + defp line_filter(line) do Regex.match?(~r/must be one of/, line) end @@ -44,8 +45,10 @@ defmodule ArgsProcessingTest do test "defaults are merged with positinal args", _context do commands = all_commands() - Enum.each(commands, - fn(command) -> + + Enum.each( + commands, + fn command -> command.merge_defaults([], %{}) command.merge_defaults(["arg"], %{}) command.merge_defaults(["two", "args"], %{}) @@ -53,7 +56,8 @@ defmodule ArgsProcessingTest do command.merge_defaults([], %{unknown: "option"}) command.merge_defaults(["arg"], %{unknown: "option"}) - end) + end + ) end # this test parses info keys mentioned in the usage_additional section @@ -61,19 +65,26 @@ defmodule ArgsProcessingTest do # or a mix of commas and spaces test "comma-separated info items are supported", context do commands = list_commands() - Enum.each(commands, fn(command) -> - items_usage = case command.usage_additional() do - # find the line with info items, ignore the rest - list when is_list(list) -> - # list items can be strings or pairs - Enum.filter(list, &line_filter/1) |> List.first |> Enum.join(" ") - string -> - string - end + + Enum.each(commands, fn command -> + items_usage = + case command.usage_additional() do + # find the line with info items, ignore the rest + list when is_list(list) -> + # list items can be strings or pairs + Enum.filter(list, &line_filter/1) |> List.first() |> Enum.join(" ") + + string -> + string + end + # info_item, info_item2, … - case Regex.run(~r/.*one of (.*)$/, items_usage, [capture: :all_but_first]) do - nil -> - throw "Command #{command} does not list info items in usage_additional or the format has changed. Output: #{items_usage}" + case Regex.run(~r/.*one of (.*)$/, items_usage, capture: :all_but_first) do + nil -> + throw( + "Command #{command} does not list info items in usage_additional or the format has changed. Output: #{items_usage}" + ) + [info_items] -> :ok = command.validate([info_items], context[:opts]) :ok = command.validate(String.split(info_items, " "), context[:opts]) diff --git a/deps/rabbitmq_cli/test/core/auto_complete_test.exs b/deps/rabbitmq_cli/test/core/auto_complete_test.exs index d410ec66400d..a6027e126f2c 100644 --- a/deps/rabbitmq_cli/test/core/auto_complete_test.exs +++ b/deps/rabbitmq_cli/test/core/auto_complete_test.exs @@ -4,16 +4,17 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AutoCompleteTest do use ExUnit.Case, async: false @subject RabbitMQ.CLI.AutoComplete - test "Auto-completes a command" do ["canis_aureus", "canis_latrans", "canis_lupus"] = @subject.complete("rabbitmqctl", ["canis"]) - ["canis_aureus", "canis_latrans", "canis_lupus"] = @subject.complete("rabbitmqctl", ["canis_"]) + + ["canis_aureus", "canis_latrans", "canis_lupus"] = + @subject.complete("rabbitmqctl", ["canis_"]) + ["canis_latrans", "canis_lupus"] = @subject.complete("rabbitmqctl", ["canis_l"]) ["canis_latrans"] = @subject.complete("rabbitmqctl", ["canis_la"]) ["canis_aureus"] = @subject.complete("rabbitmqctl", ["canis_a"]) @@ -38,11 +39,13 @@ defmodule AutoCompleteTest do scopes = Application.get_env(:rabbitmqctl, :scopes) scopes_with_wolf = Keyword.put(scopes, :rabbitmq_wolf, :wolf) Application.put_env(:rabbitmqctl, :scopes, scopes_with_wolf) - on_exit(fn() -> + + on_exit(fn -> Application.put_env(:rabbitmqctl, :scopes, scopes) end) - ["canis_aureus", "canis_latrans", "canis_lupus"] = @subject.complete("rabbitmq_wolf", ["canis"]) + ["canis_aureus", "canis_latrans", "canis_lupus"] = + @subject.complete("rabbitmq_wolf", ["canis"]) end test "Auto-completes scoped command with --script-name flag" do @@ -54,10 +57,10 @@ defmodule RabbitMQ.CLI.Wolf.Commands.CanisLupusCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["canis_lupus"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok def switches(), do: [colour: :string, dingo: :boolean, dog: :boolean] def scopes, do: [:ctl, :wolf] end @@ -66,10 +69,10 @@ defmodule RabbitMQ.CLI.Wolf.Commands.CanisLatransCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["canis_latrans"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok def scopes, do: [:ctl, :wolf] end @@ -77,9 +80,9 @@ defmodule RabbitMQ.CLI.Wolf.Commands.CanisAureusCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["canis_aureus"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok def scopes, do: [:ctl, :wolf] end diff --git a/deps/rabbitmq_cli/test/core/command_modules_test.exs b/deps/rabbitmq_cli/test/core/command_modules_test.exs index 8617415a22ce..ea2ef464157a 100644 --- a/deps/rabbitmq_cli/test/core/command_modules_test.exs +++ b/deps/rabbitmq_cli/test/core/command_modules_test.exs @@ -15,17 +15,18 @@ defmodule CommandModulesTest do set_scope(:none) Application.put_env(:rabbitmqctl, :commands, nil) end) + :ok end test "command modules has existing commands" do assert @subject.load_commands(:all, %{})["duck"] == - RabbitMQ.CLI.Ctl.Commands.DuckCommand + RabbitMQ.CLI.Ctl.Commands.DuckCommand end test "command with multiple underscores shows up in map" do assert @subject.load_commands(:all, %{})["gray_goose"] == - RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand + RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand end test "command modules does not have non-existent commands" do @@ -98,7 +99,6 @@ defmodule CommandModulesTest do # SeagullCommand has scopes() defined as [:plugins, :custom] assert custom_commands["seagull"] == RabbitMQ.CLI.Seagull.Commands.SeagullCommand - end ## ------------------- commands/0 tests -------------------- @@ -123,46 +123,45 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DuckCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["duck"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["gray_goose"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule RabbitMQ.CLI.Ctl.Commands.UglyDucklingCommand do end - # Mock command modules for Plugins defmodule RabbitMQ.CLI.Plugins.Commands.StorkCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["stork"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule RabbitMQ.CLI.Plugins.Commands.HeronCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["heron"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end # Mock command modules for Custom @@ -171,32 +170,30 @@ defmodule RabbitMQ.CLI.Custom.Commands.CrowCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["crow"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok - def scopes(), do: [:custom, ] + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok + def scopes(), do: [:custom] end defmodule RabbitMQ.CLI.Custom.Commands.RavenCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["raven"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule RabbitMQ.CLI.Seagull.Commands.SeagullCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["seagull"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok def scopes(), do: [:plugins, :custom] end - - diff --git a/deps/rabbitmq_cli/test/core/default_output_test.exs b/deps/rabbitmq_cli/test/core/default_output_test.exs index f567c5cc9693..81434bc93acf 100644 --- a/deps/rabbitmq_cli/test/core/default_output_test.exs +++ b/deps/rabbitmq_cli/test/core/default_output_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule DefaultOutputTest do use ExUnit.Case, async: false @@ -14,15 +13,19 @@ defmodule DefaultOutputTest do test "ok with message is passed as is" do assert match?({:ok, :message}, ExampleCommand.output({:ok, :message}, %{})) - assert match?({:ok, {:complex, "message"}}, ExampleCommand.output({:ok, {:complex, "message"}}, %{})) + + assert match?( + {:ok, {:complex, "message"}}, + ExampleCommand.output({:ok, {:complex, "message"}}, %{}) + ) end test "enumerable is passed as stream" do assert match?({:stream, 'list'}, ExampleCommand.output({:ok, 'list'}, %{})) assert match?({:stream, 'list'}, ExampleCommand.output('list', %{})) - assert match?({:stream, [1,2,3]}, ExampleCommand.output({:ok, [1,2,3]}, %{})) - assert match?({:stream, [1,2,3]}, ExampleCommand.output([1,2,3], %{})) + assert match?({:stream, [1, 2, 3]}, ExampleCommand.output({:ok, [1, 2, 3]}, %{})) + assert match?({:stream, [1, 2, 3]}, ExampleCommand.output([1, 2, 3], %{})) stream = Stream.timer(10000) assert match?({:stream, ^stream}, ExampleCommand.output({:ok, stream}, %{})) @@ -30,11 +33,9 @@ defmodule DefaultOutputTest do end test "badrpc is an error" do - {:error, {:badrpc, :nodedown}} = - ExampleCommand.output({:badrpc, :nodedown}, %{}) + {:error, {:badrpc, :nodedown}} = ExampleCommand.output({:badrpc, :nodedown}, %{}) - {:error, {:badrpc, :timeout}} = - ExampleCommand.output({:badrpc, :timeout}, %{}) + {:error, {:badrpc, :timeout}} = ExampleCommand.output({:badrpc, :timeout}, %{}) end test "unknown atom is error" do @@ -50,8 +51,10 @@ defmodule DefaultOutputTest do end test "error_string is converted to string" do - assert match?({:error, "I am charlist"}, - ExampleCommand.output({:error_string, 'I am charlist'}, %{})) + assert match?( + {:error, "I am charlist"}, + ExampleCommand.output({:error_string, 'I am charlist'}, %{}) + ) end test "error is formatted" do @@ -71,25 +74,30 @@ defmodule DefaultOutputTest do end test "custom output function can be defined" do - assert {:error, 125, "Non standard"} == ExampleCommandWithCustomOutput.output(:non_standard_output, %{}) + assert {:error, 125, "Non standard"} == + ExampleCommandWithCustomOutput.output(:non_standard_output, %{}) end test "default output works even if custom output is defined" do assert :ok == ExampleCommandWithCustomOutput.output(:ok, %{}) - assert {:ok, {:complex, "message"}} == ExampleCommandWithCustomOutput.output({:ok, {:complex, "message"}}, %{}) - assert {:stream, [1,2,3]} == ExampleCommandWithCustomOutput.output({:ok, [1,2,3]}, %{}) - assert {:stream, [1,2,3]} == ExampleCommandWithCustomOutput.output([1,2,3], %{}) + assert {:ok, {:complex, "message"}} == + ExampleCommandWithCustomOutput.output({:ok, {:complex, "message"}}, %{}) + + assert {:stream, [1, 2, 3]} == ExampleCommandWithCustomOutput.output({:ok, [1, 2, 3]}, %{}) + assert {:stream, [1, 2, 3]} == ExampleCommandWithCustomOutput.output([1, 2, 3], %{}) assert {:error, {:badrpc, :nodedown}} == - ExampleCommandWithCustomOutput.output({:badrpc, :nodedown}, %{}) + ExampleCommandWithCustomOutput.output({:badrpc, :nodedown}, %{}) + assert {:error, {:badrpc, :timeout}} == - ExampleCommandWithCustomOutput.output({:badrpc, :timeout}, %{}) + ExampleCommandWithCustomOutput.output({:badrpc, :timeout}, %{}) error = %{i: [am: "arbitrary", error: 1]} {:error, ^error} = ExampleCommandWithCustomOutput.output({:error, error}, %{}) - assert {:error, "I am string"} == ExampleCommandWithCustomOutput.output({:error_string, "I am string"}, %{}) + assert {:error, "I am string"} == + ExampleCommandWithCustomOutput.output({:error_string, "I am string"}, %{}) val = "foo" assert match?({:ok, ^val}, ExampleCommandWithCustomOutput.output(val, %{})) @@ -110,5 +118,6 @@ defmodule ExampleCommandWithCustomOutput do def output(:non_standard_output, _) do {:error, 125, "Non standard"} end + use RabbitMQ.CLI.DefaultOutput end diff --git a/deps/rabbitmq_cli/test/core/distribution_test.exs b/deps/rabbitmq_cli/test/core/distribution_test.exs index 00dd872ab475..a2fc5e49539f 100644 --- a/deps/rabbitmq_cli/test/core/distribution_test.exs +++ b/deps/rabbitmq_cli/test/core/distribution_test.exs @@ -19,12 +19,14 @@ defmodule DistributionTest do :net_kernel.stop() System.delete_env("RABBITMQ_ERLANG_COOKIE") end) + try do :nocookie = Node.get_cookie() catch # one of net_kernel processes is not running ¯\_(ツ)_/¯ :exit, _ -> :ok end + System.put_env("RABBITMQ_ERLANG_COOKIE", "mycookie") opts = %{} Distribution.start(opts) @@ -35,12 +37,14 @@ defmodule DistributionTest do on_exit(fn -> :net_kernel.stop() end) + try do :nocookie = Node.get_cookie() catch # one of net_kernel processes is not running ¯\_(ツ)_/¯ :exit, _ -> :ok end + opts = %{erlang_cookie: :mycookie} Distribution.start(opts) :mycookie = Node.get_cookie() diff --git a/deps/rabbitmq_cli/test/core/helpers_test.exs b/deps/rabbitmq_cli/test/core/helpers_test.exs index 4d1068201523..26702bf3b2d3 100644 --- a/deps/rabbitmq_cli/test/core/helpers_test.exs +++ b/deps/rabbitmq_cli/test/core/helpers_test.exs @@ -14,7 +14,7 @@ defmodule HelpersTest do ## --------------------- get_rabbit_hostname()/0 tests ------------------------- test "RabbitMQ hostname is properly formed" do - assert Helpers.get_rabbit_hostname() |> Atom.to_string =~ ~r/rabbit@\w+/ + assert Helpers.get_rabbit_hostname() |> Atom.to_string() =~ ~r/rabbit@\w+/ end ## ------------------- memory_unit* tests -------------------- @@ -24,21 +24,23 @@ defmodule HelpersTest do end test "an invalid number fails " do - assert memory_unit_absolute("lots", "gigantibytes") == {:bad_argument, ["lots", "gigantibytes"]} + assert memory_unit_absolute("lots", "gigantibytes") == + {:bad_argument, ["lots", "gigantibytes"]} + assert memory_unit_absolute(-1, "gigantibytes") == {:bad_argument, [-1, "gigantibytes"]} end test "valid number and unit returns a valid result " do - assert memory_unit_absolute(10, "k") == 10240 - assert memory_unit_absolute(10, "kiB") == 10240 - assert memory_unit_absolute(10, "M") == 10485760 - assert memory_unit_absolute(10, "MiB") == 10485760 - assert memory_unit_absolute(10, "G") == 10737418240 - assert memory_unit_absolute(10, "GiB")== 10737418240 - assert memory_unit_absolute(10, "kB")== 10000 - assert memory_unit_absolute(10, "MB")== 10000000 - assert memory_unit_absolute(10, "GB")== 10000000000 - assert memory_unit_absolute(10, "") == 10 + assert memory_unit_absolute(10, "k") == 10240 + assert memory_unit_absolute(10, "kiB") == 10240 + assert memory_unit_absolute(10, "M") == 10_485_760 + assert memory_unit_absolute(10, "MiB") == 10_485_760 + assert memory_unit_absolute(10, "G") == 10_737_418_240 + assert memory_unit_absolute(10, "GiB") == 10_737_418_240 + assert memory_unit_absolute(10, "kB") == 10000 + assert memory_unit_absolute(10, "MB") == 10_000_000 + assert memory_unit_absolute(10, "GB") == 10_000_000_000 + assert memory_unit_absolute(10, "") == 10 end ## ------------------- Helpers.normalise_node_option tests -------------------- @@ -118,12 +120,14 @@ defmodule HelpersTest do test "locate plugin with version number in filename" do plugins_directory_03 = fixture_plugins_path("plugins-subdirectory-03") rabbitmq_home = :rabbit_misc.rpc_call(node(), :code, :lib_dir, [:rabbit]) - opts = %{plugins_dir: to_string(plugins_directory_03), - rabbitmq_home: rabbitmq_home} + opts = %{plugins_dir: to_string(plugins_directory_03), rabbitmq_home: rabbitmq_home} desc = 'A mock RabbitMQ plugin to be used in tests' vsn = '0.1.0' - assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_03, desc, vsn}) == false + + assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_03, desc, vsn}) == + false + require_rabbit_and_plugins(opts) Application.load(:mock_rabbitmq_plugins_03) assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_03, desc, vsn}) @@ -132,15 +136,16 @@ defmodule HelpersTest do test "locate plugin without version number in filename" do plugins_directory_04 = fixture_plugins_path("plugins-subdirectory-04") rabbitmq_home = :rabbit_misc.rpc_call(node(), :code, :lib_dir, [:rabbit]) - opts = %{plugins_dir: to_string(plugins_directory_04), - rabbitmq_home: rabbitmq_home} + opts = %{plugins_dir: to_string(plugins_directory_04), rabbitmq_home: rabbitmq_home} desc = 'A mock RabbitMQ plugin to be used in tests' vsn = 'rolling' - assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_04, desc, vsn}) == false + + assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_04, desc, vsn}) == + false + require_rabbit_and_plugins(opts) Application.load(:mock_rabbitmq_plugins_04) assert Enum.member?(Application.loaded_applications(), {:mock_rabbitmq_plugins_04, desc, vsn}) end - end diff --git a/deps/rabbitmq_cli/test/core/information_unit_test.exs b/deps/rabbitmq_cli/test/core/information_unit_test.exs index 568b687b2d14..15a223744dd8 100644 --- a/deps/rabbitmq_cli/test/core/information_unit_test.exs +++ b/deps/rabbitmq_cli/test/core/information_unit_test.exs @@ -4,20 +4,23 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule InformationUnitTest do use ExUnit.Case, async: true alias RabbitMQ.CLI.InformationUnit, as: IU test "bytes, MB, GB, TB are known units" do - Enum.each(["bytes", "mb", "MB", "gb", "GB", "tb", "TB"], - fn x -> assert IU.known_unit?(x) end) + Enum.each( + ["bytes", "mb", "MB", "gb", "GB", "tb", "TB"], + fn x -> assert IU.known_unit?(x) end + ) end test "glip-glops, millibars, gold pressed latinum bars and looney and are not known units" do - Enum.each(["glip-glops", "millibars", "gold pressed latinum bars", "looney"], - fn x -> assert not IU.known_unit?(x) end) + Enum.each( + ["glip-glops", "millibars", "gold pressed latinum bars", "looney"], + fn x -> assert not IU.known_unit?(x) end + ) end test "conversion to bytes" do @@ -27,18 +30,18 @@ defmodule InformationUnitTest do end test "conversion to MB" do - assert IU.convert(1000000, "mb") == 1.0 - assert IU.convert(9500000, "mb") == 9.5 - assert IU.convert(97893000, "mb") == 97.893 - assert IU.convert(978930000, "mb") == 978.93 + assert IU.convert(1_000_000, "mb") == 1.0 + assert IU.convert(9_500_000, "mb") == 9.5 + assert IU.convert(97_893_000, "mb") == 97.893 + assert IU.convert(978_930_000, "mb") == 978.93 end test "conversion to GB" do - assert IU.convert(978930000, "gb") == 0.9789 + assert IU.convert(978_930_000, "gb") == 0.9789 - assert IU.convert(1000000000, "gb") == 1.0 - assert IU.convert(9500000000, "gb") == 9.5 - assert IU.convert(97893000000, "gb") == 97.893 - assert IU.convert(978930000000, "gb") == 978.93 + assert IU.convert(1_000_000_000, "gb") == 1.0 + assert IU.convert(9_500_000_000, "gb") == 9.5 + assert IU.convert(97_893_000_000, "gb") == 97.893 + assert IU.convert(978_930_000_000, "gb") == 978.93 end end diff --git a/deps/rabbitmq_cli/test/core/json_stream_test.exs b/deps/rabbitmq_cli/test/core/json_stream_test.exs index ab3bebd62c58..68bbcfe7b6ee 100644 --- a/deps/rabbitmq_cli/test/core/json_stream_test.exs +++ b/deps/rabbitmq_cli/test/core/json_stream_test.exs @@ -10,15 +10,16 @@ defmodule JsonStreamTest do @formatter RabbitMQ.CLI.Formatters.JsonStream test "format_output map with atom keys is converted to JSON object" do - assert @formatter.format_output(%{a: :apple, b: :beer}, %{}) == "{\"a\":\"apple\",\"b\":\"beer\"}" + assert @formatter.format_output(%{a: :apple, b: :beer}, %{}) == + "{\"a\":\"apple\",\"b\":\"beer\"}" end test "format_output map with binary keys is converted to JSON object" do - assert @formatter.format_output(%{"a" => :apple, "b" => :beer}, %{}) == "{\"a\":\"apple\",\"b\":\"beer\"}" + assert @formatter.format_output(%{"a" => :apple, "b" => :beer}, %{}) == + "{\"a\":\"apple\",\"b\":\"beer\"}" end test "format_output empty binary is converted to empty JSON array" do assert @formatter.format_output("", %{}) == "" end - end diff --git a/deps/rabbitmq_cli/test/core/listeners_test.exs b/deps/rabbitmq_cli/test/core/listeners_test.exs index 266413c6faa9..e0f74ad7d88b 100644 --- a/deps/rabbitmq_cli/test/core/listeners_test.exs +++ b/deps/rabbitmq_cli/test/core/listeners_test.exs @@ -11,52 +11,64 @@ defmodule CoreListenersTest do import RabbitCommon.Records test "listener record translation to a map" do - assert listener_map(listener(node: :rabbit@mercurio, - protocol: :stomp, - ip_address: {0,0,0,0,0,0,0,0}, - port: 61613)) == - %{ - interface: "[::]", - node: :rabbit@mercurio, - port: 61613, - protocol: :stomp, - purpose: "STOMP" - } + assert listener_map( + listener( + node: :rabbit@mercurio, + protocol: :stomp, + ip_address: {0, 0, 0, 0, 0, 0, 0, 0}, + port: 61613 + ) + ) == + %{ + interface: "[::]", + node: :rabbit@mercurio, + port: 61613, + protocol: :stomp, + purpose: "STOMP" + } end test "[human-readable] protocol labels" do assert protocol_label(:amqp) == "AMQP 0-9-1 and AMQP 1.0" - assert protocol_label(:'amqp/ssl') == "AMQP 0-9-1 and AMQP 1.0 over TLS" + assert protocol_label(:"amqp/ssl") == "AMQP 0-9-1 and AMQP 1.0 over TLS" assert protocol_label(:mqtt) == "MQTT" - assert protocol_label(:'mqtt/ssl') == "MQTT over TLS" + assert protocol_label(:"mqtt/ssl") == "MQTT over TLS" assert protocol_label(:stomp) == "STOMP" - assert protocol_label(:'stomp/ssl') == "STOMP over TLS" + assert protocol_label(:"stomp/ssl") == "STOMP over TLS" assert protocol_label(:http) == "HTTP API" assert protocol_label(:https) == "HTTP API over TLS (HTTPS)" - assert protocol_label(:'https/web-stomp') == "STOMP over WebSockets and TLS (HTTPS)" - assert protocol_label(:'https/web-mqtt') == "MQTT over WebSockets and TLS (HTTPS)" + assert protocol_label(:"https/web-stomp") == "STOMP over WebSockets and TLS (HTTPS)" + assert protocol_label(:"https/web-mqtt") == "MQTT over WebSockets and TLS (HTTPS)" - assert protocol_label(:'http/prometheus') == "Prometheus exporter API over HTTP" - assert protocol_label(:'https/prometheus') == "Prometheus exporter API over TLS (HTTPS)" + assert protocol_label(:"http/prometheus") == "Prometheus exporter API over HTTP" + assert protocol_label(:"https/prometheus") == "Prometheus exporter API over TLS (HTTPS)" end test "listener expiring within" do validityInDays = 10 validity = X509.Certificate.Validity.days_from_now(validityInDays) ca_key = X509.PrivateKey.new_ec(:secp256r1) - ca = X509.Certificate.self_signed(ca_key, - "/C=US/ST=CA/L=San Francisco/O=Megacorp/CN=Megacorp Intermediate CA", - template: :root_ca, - validity: validity - ) + + ca = + X509.Certificate.self_signed( + ca_key, + "/C=US/ST=CA/L=San Francisco/O=Megacorp/CN=Megacorp Intermediate CA", + template: :root_ca, + validity: validity + ) + pem = X509.Certificate.to_pem(ca) opts = [{:certfile, {:pem, pem}}, {:cacertfile, {:pem, pem}}] - listener = listener(node: :rabbit@mercurio, - protocol: :stomp, - ip_address: {0,0,0,0,0,0,0,0}, - port: 61613, - opts: opts) + + listener = + listener( + node: :rabbit@mercurio, + protocol: :stomp, + ip_address: {0, 0, 0, 0, 0, 0, 0, 0}, + port: 61613, + opts: opts + ) assert not listener_expiring_within(listener, 86400 * (validityInDays - 5)) assert listener_expiring_within(listener, 86400 * (validityInDays + 5)) diff --git a/deps/rabbitmq_cli/test/core/os_pid_test.exs b/deps/rabbitmq_cli/test/core/os_pid_test.exs index 2d110f591fc3..1af74654c63c 100644 --- a/deps/rabbitmq_cli/test/core/os_pid_test.exs +++ b/deps/rabbitmq_cli/test/core/os_pid_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule OsPidTest do use ExUnit.Case, async: false import TestHelper @@ -19,36 +18,48 @@ defmodule OsPidTest do test "with a valid pid file returns an integer value" do path = fixture_file_path("valid_pidfile.pid") - assert (File.exists?(path) and File.regular?(path)) + assert File.exists?(path) and File.regular?(path) assert @subject.read_pid_from_file(path, false) == 13566 end test "with a valid pid file that includes spaces returns an integer value" do path = fixture_file_path("valid_pidfile_with_spaces.pid") - assert (File.exists?(path) and File.regular?(path)) + assert File.exists?(path) and File.regular?(path) assert @subject.read_pid_from_file(path, false) == 83777 end test "with an empty file" do path = fixture_file_path("empty_pidfile.pid") - assert (File.exists?(path) and File.regular?(path)) - assert match?({:error, :could_not_read_pid_from_file, _}, @subject.read_pid_from_file(path, false)) + assert File.exists?(path) and File.regular?(path) + + assert match?( + {:error, :could_not_read_pid_from_file, _}, + @subject.read_pid_from_file(path, false) + ) end test "with a non-empty file full of garbage (that doesn't parse)" do path = fixture_file_path("invalid_pidfile.pid") - assert (File.exists?(path) and File.regular?(path)) - assert match?({:error, :could_not_read_pid_from_file, _}, @subject.read_pid_from_file(path, false)) + assert File.exists?(path) and File.regular?(path) + + assert match?( + {:error, :could_not_read_pid_from_file, _}, + @subject.read_pid_from_file(path, false) + ) end test "with a file that does not exist" do path = fixture_file_path("pidfile_that_does_not_exist_128787df8s7f8%4&^.pid") assert !File.exists?(path) - assert match?({:error, :could_not_read_pid_from_file, _}, @subject.read_pid_from_file(path, false)) + + assert match?( + {:error, :could_not_read_pid_from_file, _}, + @subject.read_pid_from_file(path, false) + ) end end end diff --git a/deps/rabbitmq_cli/test/core/parser_test.exs b/deps/rabbitmq_cli/test/core/parser_test.exs index b483db1fdd7d..3823132c67ef 100644 --- a/deps/rabbitmq_cli/test/core/parser_test.exs +++ b/deps/rabbitmq_cli/test/core/parser_test.exs @@ -9,10 +9,10 @@ defmodule RabbitMQ.CLI.Seagull.Commands.HerringGullCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["herring_gull"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok def switches(), do: [herring: :string, garbage: :boolean] def aliases(), do: [h: :herring, g: :garbage] end @@ -21,20 +21,20 @@ defmodule RabbitMQ.CLI.Seagull.Commands.PacificGullCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["pacific_gull"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule RabbitMQ.CLI.Seagull.Commands.HermannGullCommand do @behaviour RabbitMQ.CLI.CommandBehaviour use RabbitMQ.CLI.DefaultOutput def usage(), do: ["hermann_gull"] - def validate(_,_), do: :ok - def merge_defaults(_,_), do: {[], %{}} - def banner(_,_), do: "" - def run(_,_), do: :ok + def validate(_, _), do: :ok + def merge_defaults(_, _), do: {[], %{}} + def banner(_, _), do: "" + def run(_, _), do: :ok end defmodule ParserTest do @@ -48,9 +48,11 @@ defmodule ParserTest do Code.ensure_loaded(RabbitMQ.CLI.Seagull.Commands.HerringGullCommand) Code.ensure_loaded(RabbitMQ.CLI.Seagull.Commands.PacificGullCommand) set_scope(:seagull) + on_exit(fn -> set_scope(:none) end) + :ok end @@ -67,51 +69,52 @@ defmodule ParserTest do end test "no commands, no options (empty array)" do - assert @subject.parse_global([]) == {[],%{}, []} + assert @subject.parse_global([]) == {[], %{}, []} end test "one arity 1 command, one double-dash quiet flag" do assert @subject.parse_global(["sandwich", "pastrami", "--quiet"]) == - {["sandwich", "pastrami"], %{quiet: true}, []} + {["sandwich", "pastrami"], %{quiet: true}, []} end test "one arity 1 command, one single-dash quiet flag" do assert @subject.parse_global(["sandwich", "pastrami", "-q"]) == - {["sandwich", "pastrami"], %{quiet: true}, []} + {["sandwich", "pastrami"], %{quiet: true}, []} end test "one arity 1 command, one double-dash silent flag" do assert @subject.parse_global(["sandwich", "pastrami", "--silent"]) == - {["sandwich", "pastrami"], %{silent: true}, []} + {["sandwich", "pastrami"], %{silent: true}, []} end test "one arity 1 command, one single-dash silent flag" do assert @subject.parse_global(["sandwich", "pastrami", "-s"]) == - {["sandwich", "pastrami"], %{silent: true}, []} + {["sandwich", "pastrami"], %{silent: true}, []} end test "one arity 0 command, one single-dash node option" do assert @subject.parse_global(["sandwich", "-n", "rabbitmq@localhost"]) == - {["sandwich"], %{node: :rabbitmq@localhost}, []} + {["sandwich"], %{node: :rabbitmq@localhost}, []} end test "one arity 1 command, one single-dash node option" do assert @subject.parse_global(["sandwich", "pastrami", "-n", "rabbitmq@localhost"]) == - {["sandwich", "pastrami"], %{node: :rabbitmq@localhost}, []} + {["sandwich", "pastrami"], %{node: :rabbitmq@localhost}, []} end test "one arity 1 command, one single-dash node option and one quiet flag" do assert @subject.parse_global(["sandwich", "pastrami", "-n", "rabbitmq@localhost", "--quiet"]) == - {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, quiet: true}, []} + {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, quiet: true}, []} end test "single-dash node option before command" do assert @subject.parse_global(["-n", "rabbitmq@localhost", "sandwich", "pastrami"]) == - {["sandwich", "pastrami"], %{node: :rabbitmq@localhost}, []} + {["sandwich", "pastrami"], %{node: :rabbitmq@localhost}, []} end test "no commands, one double-dash node option" do - assert @subject.parse_global(["--node=rabbitmq@localhost"]) == {[], %{node: :rabbitmq@localhost}, []} + assert @subject.parse_global(["--node=rabbitmq@localhost"]) == + {[], %{node: :rabbitmq@localhost}, []} end test "no commands, one single-dash -p option" do @@ -121,175 +124,197 @@ defmodule ParserTest do test "global parse treats command-specific arguments as invalid (ignores them)" do command_line = ["seagull", "--herring", "atlantic", "-g", "-p", "my_vhost"] {args, options, invalid} = @subject.parse_global(command_line) + assert {args, options, invalid} == - {["seagull", "atlantic"], %{vhost: "my_vhost"}, [{"--herring", nil}, {"-g", nil}]} + {["seagull", "atlantic"], %{vhost: "my_vhost"}, [{"--herring", nil}, {"-g", nil}]} end test "global parse treats command-specific arguments that are separated by an equals sign as invalid (ignores them)" do command_line = ["seagull", "--herring=atlantic", "-g", "-p", "my_vhost"] {args, options, invalid} = @subject.parse_global(command_line) + assert {args, options, invalid} == - {["seagull"], %{vhost: "my_vhost"}, [{"--herring", nil}, {"-g", nil}]} + {["seagull"], %{vhost: "my_vhost"}, [{"--herring", nil}, {"-g", nil}]} end test "command-specific parse recognizes command switches" do command_line = ["seagull", "--herring", "atlantic", "-g", "-p", "my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse_command_specific(command_line, command) == - {["seagull"], %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} + {["seagull"], %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} end test "command-specific parse recognizes command switches that are separated by an equals sign" do command_line = ["seagull", "--herring=atlantic", "-g", "-p", "my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse_command_specific(command_line, command) == - {["seagull"], %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} + {["seagull"], %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} end test "command-specific switches and aliases are optional" do command_line = ["seagull", "-p", "my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.PacificGullCommand + assert @subject.parse_command_specific(command_line, command) == - {["seagull"], %{vhost: "my_vhost"}, []} + {["seagull"], %{vhost: "my_vhost"}, []} end test "--timeout can be specified before command" do # for backwards compatibility - assert @subject.parse_global(["-n", "rabbitmq@localhost", "--timeout", "5", "sandwich", "pastrami"]) == - {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, timeout: 5}, []} + assert @subject.parse_global([ + "-n", + "rabbitmq@localhost", + "--timeout", + "5", + "sandwich", + "pastrami" + ]) == + {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, timeout: 5}, []} end test "-t can be specified before command" do # for backwards compatibility assert @subject.parse_global(["-n", "rabbitmq@localhost", "-t", "5", "sandwich", "pastrami"]) == - {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, timeout: 5}, []} + {["sandwich", "pastrami"], %{node: :rabbitmq@localhost, timeout: 5}, []} end test "parse/1 returns command name" do command_line = ["pacific_gull", "fly", "-p", "my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.PacificGullCommand + assert @subject.parse(command_line) == - {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} + {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} end test "parse/1 returns command name when a global flag comes before the command" do command_line = ["-p", "my_vhost", "pacific_gull", "fly"] command = RabbitMQ.CLI.Seagull.Commands.PacificGullCommand + assert @subject.parse(command_line) == - {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} + {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} end test "parse/1 returns command name when a global flag separated by an equals sign comes before the command" do command_line = ["-p=my_vhost", "pacific_gull", "fly"] command = RabbitMQ.CLI.Seagull.Commands.PacificGullCommand + assert @subject.parse(command_line) == - {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} + {command, "pacific_gull", ["fly"], %{vhost: "my_vhost"}, []} end test "parse/1 returns :no_command when given an empty argument list" do command_line = ["-p", "my_vhost"] + assert @subject.parse(command_line) == - {:no_command, "", [], %{vhost: "my_vhost"}, []} + {:no_command, "", [], %{vhost: "my_vhost"}, []} end test "parse/1 returns :no_command and command name when command isn't known" do command_line = ["atlantic_gull", "-p", "my_vhost"] + assert @subject.parse(command_line) == - {:no_command, "atlantic_gull", [], %{vhost: "my_vhost"}, []} + {:no_command, "atlantic_gull", [], %{vhost: "my_vhost"}, []} end test "parse/1 returns :no command if command-specific options come before the command" do command_line = ["--herring", "atlantic", "herring_gull", "-p", "my_vhost"] + assert @subject.parse(command_line) == - {:no_command, "atlantic", ["herring_gull"], - %{vhost: "my_vhost"}, [{"--herring", nil}]} + {:no_command, "atlantic", ["herring_gull"], %{vhost: "my_vhost"}, + [{"--herring", nil}]} end test "parse/1 returns command name if a global option comes before the command" do command_line = ["-p", "my_vhost", "herring_gull"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", [], %{vhost: "my_vhost"}, []} + {command, "herring_gull", [], %{vhost: "my_vhost"}, []} end test "parse/1 returns command name if multiple global options come before the command" do command_line = ["-p", "my_vhost", "-q", "-n", "rabbit@test", "herring_gull"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", [], %{vhost: "my_vhost", node: :rabbit@test, quiet: true}, []} + {command, "herring_gull", [], %{vhost: "my_vhost", node: :rabbit@test, quiet: true}, + []} end test "parse/1 returns command name if multiple global options separated by an equals sign come before the command" do command_line = ["-p=my_vhost", "-q", "--node=rabbit@test", "herring_gull"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", [], %{vhost: "my_vhost", node: :rabbit@test, quiet: true}, []} + {command, "herring_gull", [], %{vhost: "my_vhost", node: :rabbit@test, quiet: true}, + []} end test "parse/1 returns command with command specific options" do - command_line = ["herring_gull", "--herring", "atlantic", - "-g", "fly", "-p", "my_vhost"] + command_line = ["herring_gull", "--herring", "atlantic", "-g", "fly", "-p", "my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", ["fly"], - %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} + {command, "herring_gull", ["fly"], + %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} end test "parse/1 returns command with command specific options that are separated by an equals sign" do - command_line = ["herring_gull", "--herring=atlantic", - "-g", "fly", "-p=my_vhost"] + command_line = ["herring_gull", "--herring=atlantic", "-g", "fly", "-p=my_vhost"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", ["fly"], - %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} + {command, "herring_gull", ["fly"], + %{vhost: "my_vhost", herring: "atlantic", garbage: true}, []} end test "parse/1 expands command-defined aliases" do command_line = ["herring_gull", "fly", "-g"] command = RabbitMQ.CLI.Seagull.Commands.HerringGullCommand + assert @subject.parse(command_line) == - {command, "herring_gull", ["fly"], %{garbage: true}, []} + {command, "herring_gull", ["fly"], %{garbage: true}, []} end test "parse/1 returns invalid/extra options for command" do - command_line = ["pacific_gull", "fly", - "--herring", "atlantic", - "-p", "my_vhost"] + command_line = ["pacific_gull", "fly", "--herring", "atlantic", "-p", "my_vhost"] pacific_gull = RabbitMQ.CLI.Seagull.Commands.PacificGullCommand + assert @subject.parse(command_line) == - {pacific_gull, "pacific_gull", ["fly", "atlantic"], - %{vhost: "my_vhost"}, - [{"--herring", nil}]} + {pacific_gull, "pacific_gull", ["fly", "atlantic"], %{vhost: "my_vhost"}, + [{"--herring", nil}]} end test "parse/1 suggests similar command" do # One letter difference assert @subject.parse(["pacific_gulf"]) == - {{:suggest, "pacific_gull"}, "pacific_gulf", [], %{}, []} + {{:suggest, "pacific_gull"}, "pacific_gulf", [], %{}, []} # One letter missing assert @subject.parse(["pacific_gul"]) == - {{:suggest, "pacific_gull"}, "pacific_gul", [], %{}, []} + {{:suggest, "pacific_gull"}, "pacific_gul", [], %{}, []} # One letter extra assert @subject.parse(["pacific_gulll"]) == - {{:suggest, "pacific_gull"}, "pacific_gulll", [], %{}, []} + {{:suggest, "pacific_gull"}, "pacific_gulll", [], %{}, []} # Five letter difference assert @subject.parse(["pacifistcatl"]) == - {{:suggest, "pacific_gull"}, "pacifistcatl", [], %{}, []} + {{:suggest, "pacific_gull"}, "pacifistcatl", [], %{}, []} # Five letters missing assert @subject.parse(["pacific"]) == - {{:suggest, "pacific_gull"}, "pacific", [], %{}, []} + {{:suggest, "pacific_gull"}, "pacific", [], %{}, []} # Closest to similar assert @subject.parse(["herrdog_gull"]) == - {{:suggest, "herring_gull"}, "herrdog_gull", [], %{}, []} + {{:suggest, "herring_gull"}, "herrdog_gull", [], %{}, []} # Closest to similar assert @subject.parse(["hermaug_gull"]) == - {{:suggest, "hermann_gull"}, "hermaug_gull", [], %{}, []} + {{:suggest, "hermann_gull"}, "hermaug_gull", [], %{}, []} end @tag cd: "fixtures" @@ -306,64 +331,52 @@ defmodule ParserTest do aliases_file_name = "aliases.ini" File.write(aliases_file_name, aliases) - on_exit(fn() -> + + on_exit(fn -> File.rm(aliases_file_name) end) assert @subject.parse(["larus_pacificus", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.PacificGullCommand, - "larus_pacificus", - [], - %{aliases_file: aliases_file_name}, - []} + {RabbitMQ.CLI.Seagull.Commands.PacificGullCommand, "larus_pacificus", [], + %{aliases_file: aliases_file_name}, []} assert @subject.parse(["gull_with_herring", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - "gull_with_herring", - [], - %{aliases_file: aliases_file_name, herring: "atlantic"}, - []} + {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, "gull_with_herring", [], + %{aliases_file: aliases_file_name, herring: "atlantic"}, []} assert @subject.parse(["flying_gull", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - "flying_gull", - ["fly"], - %{aliases_file: aliases_file_name}, - []} + {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, "flying_gull", ["fly"], + %{aliases_file: aliases_file_name}, []} assert @subject.parse(["garbage_gull", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - "garbage_gull", - [], - %{aliases_file: aliases_file_name, garbage: true}, - []} + {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, "garbage_gull", [], + %{aliases_file: aliases_file_name, garbage: true}, []} assert @subject.parse(["complex_gull", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - "complex_gull", - ["eat"], - %{aliases_file: aliases_file_name, garbage: true, herring: "pacific", formatter: "erlang"}, - []} + {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, "complex_gull", ["eat"], + %{ + aliases_file: aliases_file_name, + garbage: true, + herring: "pacific", + formatter: "erlang" + }, []} assert @subject.parse(["invalid_gull", "--aliases-file", aliases_file_name]) == - {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, - "invalid_gull", - [], - %{aliases_file: aliases_file_name}, - [{"--invalid", nil}]} + {RabbitMQ.CLI.Seagull.Commands.HerringGullCommand, "invalid_gull", [], + %{aliases_file: aliases_file_name}, [{"--invalid", nil}]} assert @subject.parse(["unknown_gull", "--aliases-file", aliases_file_name]) == - {:no_command, "unknown_gull", [], %{aliases_file: aliases_file_name}, []} + {:no_command, "unknown_gull", [], %{aliases_file: aliases_file_name}, []} File.rm(aliases_file_name) - - assert capture_io(:stderr, - fn -> - assert @subject.parse(["larus_pacificus", "--aliases-file", aliases_file_name]) == - {:no_command, "larus_pacificus", [], %{aliases_file: aliases_file_name}, []} - end) =~ "Error reading aliases file" - + assert capture_io( + :stderr, + fn -> + assert @subject.parse(["larus_pacificus", "--aliases-file", aliases_file_name]) == + {:no_command, "larus_pacificus", [], %{aliases_file: aliases_file_name}, + []} + end + ) =~ "Error reading aliases file" end - end diff --git a/deps/rabbitmq_cli/test/core/rpc_stream_test.exs b/deps/rabbitmq_cli/test/core/rpc_stream_test.exs index cadd303f23e4..58047be7ea28 100644 --- a/deps/rabbitmq_cli/test/core/rpc_stream_test.exs +++ b/deps/rabbitmq_cli/test/core/rpc_stream_test.exs @@ -7,88 +7,165 @@ defmodule RpcStreamTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - :ok - end test "emit empty list" do - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list, [[]], :infinity, []]) + items = + receive_list_items_to_list([Kernel.node(), TestHelper, :emit_list, [[]], :infinity, []]) assert [] == items end test "emit list without filters" do - list = [:one, :two, :three] - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list, [list], :infinity, []]) + list = [:one, :two, :three] + + items = + receive_list_items_to_list([Kernel.node(), TestHelper, :emit_list, [list], :infinity, []]) assert list == items end - test "emit list with filters" do list = [[one: 1, two: 2, three: 3], [one: 11, two: 12, three: 13]] - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list, [list], :infinity, [:one, :two]]) + + items = + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list, + [list], + :infinity, + [:one, :two] + ]) assert [[one: 1, two: 2], [one: 11, two: 12]] == items end test "emit list of lists with filters" do - list = [[[one: 1, two: 2, three: 3], [one: 11, two: 12, three: 13]], - [[one: 21, two: 22, three: 23], [one: 31, two: 32, three: 33]]] - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list, [list], :infinity, [:one, :two]]) - - assert [[[one: 1, two: 2], [one: 11, two: 12]], [[one: 21, two: 22], [one: 31, two: 32]]] == items + list = [ + [[one: 1, two: 2, three: 3], [one: 11, two: 12, three: 13]], + [[one: 21, two: 22, three: 23], [one: 31, two: 32, three: 33]] + ] + + items = + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list, + [list], + :infinity, + [:one, :two] + ]) + + assert [[[one: 1, two: 2], [one: 11, two: 12]], [[one: 21, two: 22], [one: 31, two: 32]]] == + items end test "emission timeout 0 return badrpc" do - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list, [[]], 0, []]) + items = receive_list_items_to_list([Kernel.node(), TestHelper, :emit_list, [[]], 0, []]) assert [{:badrpc, {:timeout, 0.0}}] == items end test "emission timeout return badrpc with timeout value in seconds" do - timeout_fun = fn(x) -> :timer.sleep(1000); x end - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list_map, [[1,2,3], timeout_fun], 100, []]) + timeout_fun = fn x -> + :timer.sleep(1000) + x + end + + items = + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list_map, + [[1, 2, 3], timeout_fun], + 100, + [] + ]) + assert [{:badrpc, {:timeout, 0.1}}] == items end test "emission timeout in progress return badrpc with timeout value in seconds as last element" do - timeout_fun = fn(x) -> :timer.sleep(100); x end - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list_map, [[1,2,3], timeout_fun], 150, []]) + timeout_fun = fn x -> + :timer.sleep(100) + x + end + + items = + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list_map, + [[1, 2, 3], timeout_fun], + 150, + [] + ]) + assert [1, {:badrpc, {:timeout, 0.15}}] == items end test "parallel emission do not mix values" do - {:ok, agent} = Agent.start_link(fn() -> :init end) - list1 = [:one, :two, :three] - list2 = [:dog, :cat, :pig] + {:ok, agent} = Agent.start_link(fn -> :init end) + list1 = [:one, :two, :three] + list2 = [:dog, :cat, :pig] # Adding timeout to make sure emissions are executed in parallel - timeout_fun = fn(x) -> :timer.sleep(10); x end - Agent.update(agent, - fn(:init) -> - receive_list_items_to_list([Kernel.node, TestHelper, :emit_list_map, [list2, timeout_fun], :infinity, []]) - end) - items1 = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list_map, [list1, timeout_fun], :infinity, []]) - items2 = Agent.get(agent, fn(x) -> x end) + timeout_fun = fn x -> + :timer.sleep(10) + x + end + + Agent.update( + agent, + fn :init -> + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list_map, + [list2, timeout_fun], + :infinity, + [] + ]) + end + ) + + items1 = + receive_list_items_to_list([ + Kernel.node(), + TestHelper, + :emit_list_map, + [list1, timeout_fun], + :infinity, + [] + ]) + + items2 = Agent.get(agent, fn x -> x end) assert items1 == list1 assert items2 == list2 end test "can receive from multiple emission sources in parallel" do - list1 = [:one, :two, :three] - list2 = [:dog, :cat, :pig] - items = receive_list_items_to_list([Kernel.node, TestHelper, :emit_list_multiple_sources, [list1, list2], :infinity, []], 2) + list1 = [:one, :two, :three] + list2 = [:dog, :cat, :pig] + + items = + receive_list_items_to_list( + [Kernel.node(), TestHelper, :emit_list_multiple_sources, [list1, list2], :infinity, []], + 2 + ) + assert Kernel.length(list1 ++ list2) == Kernel.length(items) assert MapSet.new(list1 ++ list2) == MapSet.new(items) end def receive_list_items_to_list(args, chunks \\ 1) do res = Kernel.apply(RpcStream, :receive_list_items, args ++ [chunks]) + case Enumerable.impl_for(res) do - nil -> res; - _ -> Enum.to_list(res) + nil -> res + _ -> Enum.to_list(res) end end end diff --git a/deps/rabbitmq_cli/test/core/table_formatter_test.exs b/deps/rabbitmq_cli/test/core/table_formatter_test.exs index 60bf2060f105..165e0ba1cf9a 100644 --- a/deps/rabbitmq_cli/test/core/table_formatter_test.exs +++ b/deps/rabbitmq_cli/test/core/table_formatter_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule TableFormatterTest do use ExUnit.Case, async: false @@ -12,35 +11,79 @@ defmodule TableFormatterTest do test "format_output tab-separates map values" do assert @formatter.format_output(%{a: :apple, b: :beer}, %{}) == ["a\tb", "apple\tbeer"] - assert @formatter.format_output(%{a: :apple, b: :beer, c: 1}, %{}) == ["a\tb\tc", "apple\tbeer\t1"] - assert @formatter.format_output(%{a: "apple", b: 'beer', c: 1}, %{}) == ["a\tb\tc", "apple\t\"beer\"\t1"] + + assert @formatter.format_output(%{a: :apple, b: :beer, c: 1}, %{}) == [ + "a\tb\tc", + "apple\tbeer\t1" + ] + + assert @formatter.format_output(%{a: "apple", b: 'beer', c: 1}, %{}) == [ + "a\tb\tc", + "apple\t\"beer\"\t1" + ] end test "format_output tab-separates keyword values" do assert @formatter.format_output([a: :apple, b: :beer], %{}) == ["a\tb", "apple\tbeer"] - assert @formatter.format_output([a: :apple, b: :beer, c: 1], %{}) == ["a\tb\tc", "apple\tbeer\t1"] - assert @formatter.format_output([a: "apple", b: 'beer', c: 1], %{}) == ["a\tb\tc", "apple\t\"beer\"\t1"] + + assert @formatter.format_output([a: :apple, b: :beer, c: 1], %{}) == [ + "a\tb\tc", + "apple\tbeer\t1" + ] + + assert @formatter.format_output([a: "apple", b: 'beer', c: 1], %{}) == [ + "a\tb\tc", + "apple\t\"beer\"\t1" + ] end test "format_stream tab-separates map values" do - assert @formatter.format_stream([%{a: :apple, b: :beer, c: 1}, - %{a: "aadvark", b: 'bee', c: 2}], %{}) - |> Enum.to_list == - ["a\tb\tc", "apple\tbeer\t1", "aadvark\t\"bee\"\t2"] + assert @formatter.format_stream( + [%{a: :apple, b: :beer, c: 1}, %{a: "aadvark", b: 'bee', c: 2}], + %{} + ) + |> Enum.to_list() == + ["a\tb\tc", "apple\tbeer\t1", "aadvark\t\"bee\"\t2"] end test "format_stream tab-separates keyword values" do - assert @formatter.format_stream([[a: :apple, b: :beer, c: 1], - [a: "aadvark", b: 'bee', c: 2]], %{}) - |> Enum.to_list == - ["a\tb\tc", "apple\tbeer\t1", "aadvark\t\"bee\"\t2"] + assert @formatter.format_stream( + [[a: :apple, b: :beer, c: 1], [a: "aadvark", b: 'bee', c: 2]], + %{} + ) + |> Enum.to_list() == + ["a\tb\tc", "apple\tbeer\t1", "aadvark\t\"bee\"\t2"] end test "format_output formats non-string values with inspect recursively" do - assert @formatter.format_output(%{a: :apple, b: "beer", c: {:carp, "fish"}, d: [door: :way], e: %{elk: "horn", for: :you}}, %{}) == - ["a\tb\tc\td\te", "apple\tbeer\t{carp, fish}\t[{door, way}]\t\#{elk => horn, for => you}"] + assert @formatter.format_output( + %{ + a: :apple, + b: "beer", + c: {:carp, "fish"}, + d: [door: :way], + e: %{elk: "horn", for: :you} + }, + %{} + ) == + [ + "a\tb\tc\td\te", + "apple\tbeer\t{carp, fish}\t[{door, way}]\t\#{elk => horn, for => you}" + ] - assert @formatter.format_output(%{a: :apple, b: "beer", c: {:carp, {:small, :fish}}, d: [door: {:way, "big"}], e: %{elk: [horn: :big]}}, %{}) == - ["a\tb\tc\td\te", "apple\tbeer\t{carp, {small, fish}}\t[{door, {way, big}}]\t\#{elk => [{horn, big}]}"] + assert @formatter.format_output( + %{ + a: :apple, + b: "beer", + c: {:carp, {:small, :fish}}, + d: [door: {:way, "big"}], + e: %{elk: [horn: :big]} + }, + %{} + ) == + [ + "a\tb\tc\td\te", + "apple\tbeer\t{carp, {small, fish}}\t[{door, {way, big}}]\t\#{elk => [{horn, big}]}" + ] end end diff --git a/deps/rabbitmq_cli/test/ctl/add_user_command_test.exs b/deps/rabbitmq_cli/test/ctl/add_user_command_test.exs index ec21691da9b0..740e41b42d36 100644 --- a/deps/rabbitmq_cli/test/ctl/add_user_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/add_user_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AddUserCommandTest do use ExUnit.Case, async: false import TestHelper @@ -28,7 +27,7 @@ defmodule AddUserCommandTest do test "validate: too many positional arguments fails" do assert @command.validate(["user", "password", "extra"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: two arguments passes" do @@ -41,7 +40,10 @@ defmodule AddUserCommandTest do @tag user: "", password: "password" test "validate: an empty username fails", context do - assert match?({:validation_failure, {:bad_argument, _}}, @command.validate([context[:user], context[:password]], context[:opts])) + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate([context[:user], context[:password]], context[:opts]) + ) end # Blank passwords are currently allowed, they make sense @@ -62,20 +64,23 @@ defmodule AddUserCommandTest do @tag user: "someone", password: "password" test "run: default case completes successfully", context do assert @command.run([context[:user], context[:password]], context[:opts]) == :ok - assert list_users() |> Enum.count(fn(record) -> record[:user] == context[:user] end) == 1 + assert list_users() |> Enum.count(fn record -> record[:user] == context[:user] end) == 1 end @tag user: "someone", password: "password" test "run: adding an existing user returns an error", context do add_user(context[:user], context[:password]) - assert @command.run([context[:user], context[:password]], context[:opts]) == {:error, {:user_already_exists, context[:user]}} - assert list_users() |> Enum.count(fn(record) -> record[:user] == context[:user] end) == 1 + + assert @command.run([context[:user], context[:password]], context[:opts]) == + {:error, {:user_already_exists, context[:user]}} + + assert list_users() |> Enum.count(fn record -> record[:user] == context[:user] end) == 1 end @tag user: "someone", password: "password" test "banner", context do - assert @command.banner([context[:user], context[:password]], context[:opts]) - =~ ~r/Adding user \"#{context[:user]}\" \.\.\./ + assert @command.banner([context[:user], context[:password]], context[:opts]) =~ + ~r/Adding user \"#{context[:user]}\" \.\.\./ end @tag user: "someone" diff --git a/deps/rabbitmq_cli/test/ctl/add_vhost_command_test.exs b/deps/rabbitmq_cli/test/ctl/add_vhost_command_test.exs index 783cf6244567..af4a6ec614e4 100644 --- a/deps/rabbitmq_cli/test/ctl/add_vhost_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/add_vhost_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AddVhostCommandTest do use ExUnit.Case, async: false import TestHelper @@ -33,20 +32,30 @@ defmodule AddVhostCommandTest do test "validate: one argument passes validation" do assert @command.validate(["new-vhost"], %{}) == :ok assert @command.validate(["new-vhost"], %{description: "Used by team A"}) == :ok - assert @command.validate(["new-vhost"], %{description: "Used by team A for QA purposes", tags: "qa,team-a"}) == :ok - assert @command.validate(["new-vhost"], %{description: "Used by team A for QA purposes", tags: "qa,team-a", default_queue_type: "quorum"}) == :ok + + assert @command.validate(["new-vhost"], %{ + description: "Used by team A for QA purposes", + tags: "qa,team-a" + }) == :ok + + assert @command.validate(["new-vhost"], %{ + description: "Used by team A for QA purposes", + tags: "qa,team-a", + default_queue_type: "quorum" + }) == :ok end @tag vhost: @vhost test "run: passing a valid vhost name to a running RabbitMQ node succeeds", context do assert @command.run([context[:vhost]], context[:opts]) == :ok - assert list_vhosts() |> Enum.count(fn(record) -> record[:name] == context[:vhost] end) == 1 + assert list_vhosts() |> Enum.count(fn record -> record[:name] == context[:vhost] end) == 1 end @tag vhost: "" - test "run: passing an empty string for vhost name with a running RabbitMQ node still succeeds", context do + test "run: passing an empty string for vhost name with a running RabbitMQ node still succeeds", + context do assert @command.run([context[:vhost]], context[:opts]) == :ok - assert list_vhosts() |> Enum.count(fn(record) -> record[:name] == context[:vhost] end) == 1 + assert list_vhosts() |> Enum.count(fn record -> record[:name] == context[:vhost] end) == 1 end test "run: attempt to use an unreachable node returns a nodedown" do @@ -55,15 +64,15 @@ defmodule AddVhostCommandTest do end test "run: adding the same host twice is idempotent", context do - add_vhost context[:vhost] + add_vhost(context[:vhost]) assert @command.run([context[:vhost]], context[:opts]) == :ok - assert list_vhosts() |> Enum.count(fn(record) -> record[:name] == context[:vhost] end) == 1 + assert list_vhosts() |> Enum.count(fn record -> record[:name] == context[:vhost] end) == 1 end @tag vhost: @vhost test "banner", context do - assert @command.banner([context[:vhost]], context[:opts]) - =~ ~r/Adding vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:vhost]], context[:opts]) =~ + ~r/Adding vhost \"#{context[:vhost]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/authenticate_user_command_test.exs b/deps/rabbitmq_cli/test/ctl/authenticate_user_command_test.exs index 506dfad3672d..fbc5a404a470 100644 --- a/deps/rabbitmq_cli/test/ctl/authenticate_user_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/authenticate_user_command_test.exs @@ -4,13 +4,12 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AuthenticateUserCommandTest do use ExUnit.Case, async: false import TestHelper - @command RabbitMQ.CLI.Ctl.Commands. AuthenticateUserCommand - @user "user1" + @command RabbitMQ.CLI.Ctl.Commands.AuthenticateUserCommand + @user "user1" @password "password" setup_all do @@ -31,7 +30,7 @@ defmodule AuthenticateUserCommandTest do test "validate: too many positional arguments fails" do assert @command.validate(["user", "password", "extra"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: one argument passes" do @@ -54,28 +53,34 @@ defmodule AuthenticateUserCommandTest do @tag user: @user, password: "treachery" test "run: a valid username and invalid password returns refused", context do - assert {:refused, _, _, _} = @command.run([context[:user], context[:password]], context[:opts]) + assert {:refused, _, _, _} = + @command.run([context[:user], context[:password]], context[:opts]) end @tag user: "interloper", password: @password test "run: an invalid username returns refused", context do - assert {:refused, _, _, _} = @command.run([context[:user], context[:password]], context[:opts]) + assert {:refused, _, _, _} = + @command.run([context[:user], context[:password]], context[:opts]) end @tag user: @user, password: @password test "banner", context do - assert @command.banner([context[:user], context[:password]], context[:opts]) - =~ ~r/Authenticating user/ - assert @command.banner([context[:user], context[:password]], context[:opts]) - =~ ~r/"#{context[:user]}"/ + assert @command.banner([context[:user], context[:password]], context[:opts]) =~ + ~r/Authenticating user/ + + assert @command.banner([context[:user], context[:password]], context[:opts]) =~ + ~r/"#{context[:user]}"/ end test "output: refused error", context do user = "example_user" - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_dataerr - assert match?({:error, ^exit_code, - "Error: failed to authenticate user \"example_user\"\n" <> - "Unable to foo"}, - @command.output({:refused, user, "Unable to ~s", ["foo"]}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_dataerr() + + assert match?( + {:error, ^exit_code, + "Error: failed to authenticate user \"example_user\"\n" <> + "Unable to foo"}, + @command.output({:refused, user, "Unable to ~s", ["foo"]}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/autocomplete_command_test.exs b/deps/rabbitmq_cli/test/ctl/autocomplete_command_test.exs index 52b3c8d0269c..f8f4d2ead069 100644 --- a/deps/rabbitmq_cli/test/ctl/autocomplete_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/autocomplete_command_test.exs @@ -4,17 +4,17 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AutocompleteCommandTest do use ExUnit.Case, async: true import TestHelper @command RabbitMQ.CLI.Ctl.Commands.AutocompleteCommand setup do - {:ok, opts: %{ - script_name: "rabbitmqctl", - node: get_rabbit_hostname() - }} + {:ok, + opts: %{ + script_name: "rabbitmqctl", + node: get_rabbit_hostname() + }} end test "shows up in help" do diff --git a/deps/rabbitmq_cli/test/ctl/await_online_nodes_command_test.exs b/deps/rabbitmq_cli/test/ctl/await_online_nodes_command_test.exs index bf9eeb574d19..c2d0b5b261f3 100644 --- a/deps/rabbitmq_cli/test/ctl/await_online_nodes_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/await_online_nodes_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AwaitOnlineNodesCommandTest do use ExUnit.Case, async: false import TestHelper @@ -32,13 +31,12 @@ defmodule AwaitOnlineNodesCommandTest do end test "run: a call to an unreachable RabbitMQ node returns a nodedown" do - opts = %{node: :jake@thedog, timeout: 200} + opts = %{node: :jake@thedog, timeout: 200} assert match?({:badrpc, _}, @command.run(["1"], opts)) end test "banner", context do - assert @command.banner(["1"], context[:opts]) - =~ ~r/Will wait for at least 1 nodes to join the cluster of #{context[:opts][:node]}. Timeout: 300 seconds./ + assert @command.banner(["1"], context[:opts]) =~ + ~r/Will wait for at least 1 nodes to join the cluster of #{context[:opts][:node]}. Timeout: 300 seconds./ end - end diff --git a/deps/rabbitmq_cli/test/ctl/await_startup_command_test.exs b/deps/rabbitmq_cli/test/ctl/await_startup_command_test.exs index 554ec5ee772e..7b739ddac0f6 100644 --- a/deps/rabbitmq_cli/test/ctl/await_startup_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/await_startup_command_test.exs @@ -30,7 +30,7 @@ defmodule AwaitStartupCommandTest do test "validate: with extra arguments returns an arg count error", context do assert @command.validate(["extra"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: request to a non-existent node returns a badrpc" do diff --git a/deps/rabbitmq_cli/test/ctl/cancel_sync_command_test.exs b/deps/rabbitmq_cli/test/ctl/cancel_sync_command_test.exs index 8503e6ab5f4b..5c67836cceb8 100644 --- a/deps/rabbitmq_cli/test/ctl/cancel_sync_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/cancel_sync_command_test.exs @@ -25,25 +25,26 @@ defmodule CancelSyncQueueCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname(), - vhost: @vhost - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + vhost: @vhost + }} end test "validate: specifying no queue name is reported as an error", context do assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} + {:validation_failure, :not_enough_args} end test "validate: specifying two queue names is reported as an error", context do assert @command.validate(["q1", "q2"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: specifying three queue names is reported as an error", context do assert @command.validate(["q1", "q2", "q3"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: specifying one queue name succeeds", context do diff --git a/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs b/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs index 8fcb7de3aeda..834a0f8712a8 100644 --- a/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/change_cluster_node_type_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2016-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ChangeClusterNodeTypeCommandTest do use ExUnit.Case, async: false import TestHelper @@ -24,15 +23,17 @@ defmodule ChangeClusterNodeTypeCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname() - }} + {:ok, + opts: %{ + node: get_rabbit_hostname() + }} end test "validate: node type of disc, disk, and ram pass validation", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["foo"], context[:opts])) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["foo"], context[:opts]) + ) assert :ok == @command.validate(["ram"], context[:opts]) assert :ok == @command.validate(["disc"], context[:opts]) @@ -41,44 +42,49 @@ defmodule ChangeClusterNodeTypeCommandTest do test "validate: providing no arguments fails validation", context do assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} + {:validation_failure, :not_enough_args} end + test "validate: providing too many arguments fails validation", context do assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end # TODO - #test "run: change ram node to disc node", context do - #end + # test "run: change ram node to disc node", context do + # end # TODO - #test "run: change disk node to ram node", context do - #end + # test "run: change disk node to ram node", context do + # end test "run: request to a node with running RabbitMQ app fails", context do - assert match?( - {:error, :mnesia_unexpectedly_running}, - @command.run(["ram"], context[:opts])) + assert match?( + {:error, :mnesia_unexpectedly_running}, + @command.run(["ram"], context[:opts]) + ) end test "run: request to an unreachable node returns a badrpc", _context do opts = %{node: :jake@thedog, timeout: 200} + assert match?( - {:badrpc, :nodedown}, - @command.run(["ram"], opts)) + {:badrpc, :nodedown}, + @command.run(["ram"], opts) + ) end test "banner", context do assert @command.banner(["ram"], context[:opts]) =~ - ~r/Turning #{get_rabbit_hostname()} into a ram node/ + ~r/Turning #{get_rabbit_hostname()} into a ram node/ end test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, - "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + assert match?( + {:error, ^exit_code, "Mnesia is still running on node " <> _}, + @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/change_password_command_test.exs b/deps/rabbitmq_cli/test/ctl/change_password_command_test.exs index 3a415085dd05..52840d9d16f4 100644 --- a/deps/rabbitmq_cli/test/ctl/change_password_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/change_password_command_test.exs @@ -10,13 +10,12 @@ ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ChangePasswordCommandTest do use ExUnit.Case, async: false import TestHelper - @command RabbitMQ.CLI.Ctl.Commands. ChangePasswordCommand - @user "user1" + @command RabbitMQ.CLI.Ctl.Commands.ChangePasswordCommand + @user "user1" @password "password" setup_all do @@ -37,7 +36,7 @@ defmodule ChangePasswordCommandTest do test "validate: too many positional arguments fails" do assert @command.validate(["user", "password", "extra"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: two arguments passes" do @@ -67,14 +66,16 @@ defmodule ChangePasswordCommandTest do @tag user: "interloper", password: "new_password" test "run: an invalid user returns an error", context do - assert @command.run([context[:user], context[:password]], context[:opts]) == {:error, {:no_such_user, "interloper"}} + assert @command.run([context[:user], context[:password]], context[:opts]) == + {:error, {:no_such_user, "interloper"}} end @tag user: @user, password: @password test "banner", context do - assert @command.banner([context[:user], context[:password]], context[:opts]) - =~ ~r/Changing password for user/ - assert @command.banner([context[:user], context[:password]], context[:opts]) - =~ ~r/"#{context[:user]}"/ + assert @command.banner([context[:user], context[:password]], context[:opts]) =~ + ~r/Changing password for user/ + + assert @command.banner([context[:user], context[:password]], context[:opts]) =~ + ~r/"#{context[:user]}"/ end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_global_parameter_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_global_parameter_command_test.exs index 9f2e9f0c385a..1907359ef1b2 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_global_parameter_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_global_parameter_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearGlobalParameterCommandTest do use ExUnit.Case, async: false import TestHelper @@ -21,7 +20,7 @@ defmodule ClearGlobalParameterCommandTest do setup context do on_exit(context, fn -> - clear_global_parameter context[:key] + clear_global_parameter(context[:key]) end) { @@ -35,15 +34,17 @@ defmodule ClearGlobalParameterCommandTest do test "validate: expects a single argument" do assert @command.validate(["one"], %{}) == :ok assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this is", "too many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this is", "too many"], %{}) == + {:validation_failure, :too_many_args} end @tag key: @key test "run: when global parameter does not exist, returns an error", context do assert @command.run( - [context[:key]], - context[:opts] - ) == {:error_string, 'Parameter does not exist'} + [context[:key]], + context[:opts] + ) == {:error_string, 'Parameter does not exist'} end test "run: throws a badrpc when instructed to contact an unreachable RabbitMQ node" do @@ -56,9 +57,9 @@ defmodule ClearGlobalParameterCommandTest do set_global_parameter(context[:key], @value) assert @command.run( - [context[:key]], - context[:opts] - ) == :ok + [context[:key]], + context[:opts] + ) == :ok assert_parameter_empty(context) end @@ -67,20 +68,23 @@ defmodule ClearGlobalParameterCommandTest do test "banner", context do set_global_parameter(context[:key], @value) - s = @command.banner( - [context[:key]], - context[:opts] - ) + s = + @command.banner( + [context[:key]], + context[:opts] + ) assert s =~ ~r/Clearing global runtime parameter/ assert s =~ ~r/"#{context[:key]}"/ end defp assert_parameter_empty(context) do - parameter = list_global_parameters() - |> Enum.filter(fn(param) -> - param[:key] == context[:key] - end) + parameter = + list_global_parameters() + |> Enum.filter(fn param -> + param[:key] == context[:key] + end) + assert parameter === [] end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_operator_policy_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_operator_policy_command_test.exs index 834caf89f7ec..91913b882f4c 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_operator_policy_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_operator_policy_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearOperatorPolicyCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,10 +17,10 @@ defmodule ClearOperatorPolicyCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -66,9 +65,9 @@ defmodule ClearOperatorPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end test "run: an unreachable node throws a badrpc" do @@ -76,7 +75,6 @@ defmodule ClearOperatorPolicyCommandTest do assert match?({:badrpc, _}, @command.run([@key], opts)) end - @tag pattern: @pattern, key: @key, vhost: @vhost test "run: if policy exists, returns ok and removes it", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) @@ -84,9 +82,9 @@ defmodule ClearOperatorPolicyCommandTest do set_operator_policy(context[:vhost], context[:key], context[:pattern], @value) assert @command.run( - [context[:key]], - vhost_opts - ) == :ok + [context[:key]], + vhost_opts + ) == :ok assert_operator_policy_does_not_exist(context) end @@ -96,9 +94,9 @@ defmodule ClearOperatorPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end @tag key: @key, pattern: @pattern, value: @value, vhost: @vhost @@ -106,22 +104,25 @@ defmodule ClearOperatorPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_operator_policy(context[:vhost], context[:key], context[:pattern], @value) - s = @command.banner( - [context[:key]], - vhost_opts - ) + s = + @command.banner( + [context[:key]], + vhost_opts + ) assert s =~ ~r/Clearing operator policy/ assert s =~ ~r/"#{context[:key]}"/ end defp assert_operator_policy_does_not_exist(context) do - policy = context[:vhost] - |> list_operator_policies - |> Enum.filter(fn(param) -> - param[:pattern] == context[:pattern] and - param[:key] == context[:key] - end) + policy = + context[:vhost] + |> list_operator_policies + |> Enum.filter(fn param -> + param[:pattern] == context[:pattern] and + param[:key] == context[:key] + end) + assert policy === [] end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_parameter_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_parameter_command_test.exs index 4f08234cb600..e7f600633e54 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_parameter_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_parameter_command_test.exs @@ -4,14 +4,13 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearParameterCommandTest do use ExUnit.Case, async: false import TestHelper @command RabbitMQ.CLI.Ctl.Commands.ClearParameterCommand @vhost "test1" - @root "/" + @root "/" @component_name "federation-upstream" @key "reconnect-delay" @value "{\"uri\":\"amqp://127.0.0.1:5672\"}" @@ -19,12 +18,12 @@ defmodule ClearParameterCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -32,7 +31,7 @@ defmodule ClearParameterCommandTest do setup context do on_exit(context, fn -> - clear_parameter context[:vhost], context[:component_name], context[:key] + clear_parameter(context[:vhost], context[:component_name], context[:key]) end) { @@ -64,9 +63,9 @@ defmodule ClearParameterCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:component_name], context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:component_name], context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end test "run: throws a badrpc when instructed to contact an unreachable RabbitMQ node" do @@ -74,7 +73,6 @@ defmodule ClearParameterCommandTest do assert match?({:badrpc, _}, @command.run([@component_name, @key], opts)) end - @tag component_name: @component_name, key: @key, vhost: @vhost test "run: returns ok and clears parameter, if it exists", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) @@ -82,9 +80,9 @@ defmodule ClearParameterCommandTest do set_parameter(context[:vhost], context[:component_name], context[:key], @value) assert @command.run( - [context[:component_name], context[:key]], - vhost_opts - ) == :ok + [context[:component_name], context[:key]], + vhost_opts + ) == :ok assert_parameter_empty(context) end @@ -92,10 +90,11 @@ defmodule ClearParameterCommandTest do @tag component_name: "bad-component-name", key: @key, value: @value, vhost: @root test "run: an invalid component_name returns a 'parameter does not exist' error", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) + assert @command.run( - [context[:component_name], context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:component_name], context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} assert list_parameters(context[:vhost]) == [] end @@ -105,9 +104,9 @@ defmodule ClearParameterCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:component_name], context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:component_name], context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end @tag component_name: @component_name, key: @key, value: @value, vhost: @vhost @@ -115,10 +114,11 @@ defmodule ClearParameterCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_parameter(context[:vhost], context[:component_name], context[:key], @value) - s = @command.banner( - [context[:component_name], context[:key]], - vhost_opts - ) + s = + @command.banner( + [context[:component_name], context[:key]], + vhost_opts + ) assert s =~ ~r/Clearing runtime parameter/ assert s =~ ~r/"#{context[:key]}"/ @@ -127,12 +127,14 @@ defmodule ClearParameterCommandTest do end defp assert_parameter_empty(context) do - parameter = context[:vhost] - |> list_parameters - |> Enum.filter(fn(param) -> - param[:component_name] == context[:component_name] and - param[:key] == context[:key] - end) + parameter = + context[:vhost] + |> list_parameters + |> Enum.filter(fn param -> + param[:component_name] == context[:component_name] and + param[:key] == context[:key] + end) + assert parameter === [] end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_password_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_password_command_test.exs index 0843ca3970e3..653a3f94e37b 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_password_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_password_command_test.exs @@ -10,13 +10,12 @@ ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearPasswordCommandTest do use ExUnit.Case, async: false import TestHelper - @command RabbitMQ.CLI.Ctl.Commands. ClearPasswordCommand - @user "user1" + @command RabbitMQ.CLI.Ctl.Commands.ClearPasswordCommand + @user "user1" @password "password" setup_all do @@ -34,8 +33,9 @@ defmodule ClearPasswordCommandTest do test "validate: argument count is correct" do assert @command.validate(["username"], %{}) == :ok assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} + assert @command.validate(["username", "extra"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end @tag user: @user, password: @password @@ -51,7 +51,8 @@ defmodule ClearPasswordCommandTest do @tag user: "interloper" test "run: An invalid username returns a no-such-user error message", context do - assert @command.run([context[:user]], context[:opts]) == {:error, {:no_such_user, "interloper"}} + assert @command.run([context[:user]], context[:opts]) == + {:error, {:no_such_user, "interloper"}} end @tag user: @user diff --git a/deps/rabbitmq_cli/test/ctl/clear_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_permissions_command_test.exs index 89bfe8c45791..74a48bfb0d6c 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_permissions_command_test.exs @@ -10,13 +10,12 @@ ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearPermissionsTest do use ExUnit.Case, async: false import TestHelper - @command RabbitMQ.CLI.Ctl.Commands. ClearPermissionsCommand - @user "user1" + @command RabbitMQ.CLI.Ctl.Commands.ClearPermissionsCommand + @user "user1" @password "password" @default_vhost "/" @specific_vhost "vhost1" @@ -58,7 +57,8 @@ defmodule ClearPermissionsTest do @tag user: "fake_user" test "run: can't clear permissions for non-existing user", context do - assert @command.run([context[:user]], context[:opts]) == {:error, {:no_such_user, context[:user]}} + assert @command.run([context[:user]], context[:opts]) == + {:error, {:no_such_user, context[:user]}} end @tag user: @user, vhost: @default_vhost @@ -66,7 +66,7 @@ defmodule ClearPermissionsTest do assert @command.run([context[:user]], context[:opts]) == :ok assert list_permissions(@default_vhost) - |> Enum.filter(fn(record) -> record[:user] == context[:user] end) == [] + |> Enum.filter(fn record -> record[:user] == context[:user] end) == [] end test "run: on an invalid node, return a badrpc message" do @@ -81,12 +81,13 @@ defmodule ClearPermissionsTest do assert @command.run([context[:user]], context[:opts]) == :ok assert list_permissions(context[:vhost]) - |> Enum.filter(fn(record) -> record[:user] == context[:user] end) == [] + |> Enum.filter(fn record -> record[:user] == context[:user] end) == [] end @tag user: @user, vhost: "bad_vhost" test "run: on an invalid vhost, return no_such_vhost error", context do - assert @command.run([context[:user]], context[:opts]) == {:error, {:no_such_vhost, context[:vhost]}} + assert @command.run([context[:user]], context[:opts]) == + {:error, {:no_such_vhost, context[:vhost]}} end @tag user: @user, vhost: @specific_vhost diff --git a/deps/rabbitmq_cli/test/ctl/clear_policy_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_policy_command_test.exs index b30f21810c1a..66287127d677 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_policy_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_policy_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearPolicyCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,12 +17,12 @@ defmodule ClearPolicyCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -31,7 +30,7 @@ defmodule ClearPolicyCommandTest do setup context do on_exit(context, fn -> - clear_policy context[:vhost], context[:key] + clear_policy(context[:vhost], context[:key]) end) { @@ -68,9 +67,9 @@ defmodule ClearPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end test "run: an unreachable node throws a badrpc" do @@ -78,7 +77,6 @@ defmodule ClearPolicyCommandTest do assert match?({:badrpc, _}, @command.run([@key], opts)) end - @tag pattern: @pattern, key: @key, vhost: @vhost test "run: if policy exists, returns ok and removes it", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) @@ -86,9 +84,9 @@ defmodule ClearPolicyCommandTest do set_policy(context[:vhost], context[:key], context[:pattern], @value) assert @command.run( - [context[:key]], - vhost_opts - ) == :ok + [context[:key]], + vhost_opts + ) == :ok assert_policy_does_not_exist(context) end @@ -98,9 +96,9 @@ defmodule ClearPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key]], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [context[:key]], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end @tag key: @key, pattern: @pattern, value: @value, vhost: @vhost @@ -108,22 +106,25 @@ defmodule ClearPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_policy(context[:vhost], context[:key], context[:pattern], @value) - s = @command.banner( - [context[:key]], - vhost_opts - ) + s = + @command.banner( + [context[:key]], + vhost_opts + ) assert s =~ ~r/Clearing policy/ assert s =~ ~r/"#{context[:key]}"/ end defp assert_policy_does_not_exist(context) do - policy = context[:vhost] - |> list_policies - |> Enum.filter(fn(param) -> - param[:pattern] == context[:pattern] and - param[:key] == context[:key] - end) + policy = + context[:vhost] + |> list_policies + |> Enum.filter(fn param -> + param[:pattern] == context[:pattern] and + param[:key] == context[:key] + end) + assert policy === [] end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_topic_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_topic_permissions_command_test.exs index 2b5fb6e12a99..867ff1caed89 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_topic_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_topic_permissions_command_test.exs @@ -10,13 +10,12 @@ ## The Initial Developer of the Original Code is GoPivotal, Inc. ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearTopicPermissionsTest do use ExUnit.Case, async: false import TestHelper - @command RabbitMQ.CLI.Ctl.Commands. ClearTopicPermissionsCommand - @user "user1" + @command RabbitMQ.CLI.Ctl.Commands.ClearTopicPermissionsCommand + @user "user1" @password "password" @specific_vhost "vhost1" @@ -38,6 +37,7 @@ defmodule ClearTopicPermissionsTest do setup context do set_topic_permissions(@user, @specific_vhost, "amq.topic", "^a", "^b") set_topic_permissions(@user, @specific_vhost, "topic1", "^a", "^b") + { :ok, opts: %{node: get_rabbit_hostname(), vhost: context[:vhost]} @@ -53,17 +53,21 @@ defmodule ClearTopicPermissionsTest do assert @command.validate(["username"], %{}) == :ok assert @command.validate(["username", "exchange"], %{}) == :ok assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag user: "fake_user" test "run: can't clear topic permissions for non-existing user", context do - assert @command.run([context[:user]], context[:opts]) == {:error, {:no_such_user, context[:user]}} + assert @command.run([context[:user]], context[:opts]) == + {:error, {:no_such_user, context[:user]}} end @tag user: @user, vhost: "bad_vhost" test "run: on an invalid vhost, return no_such_vhost error", context do - assert @command.run([context[:user]], context[:opts]) == {:error, {:no_such_vhost, context[:vhost]}} + assert @command.run([context[:user]], context[:opts]) == + {:error, {:no_such_vhost, context[:vhost]}} end @tag user: @user, vhost: @specific_vhost @@ -93,15 +97,15 @@ defmodule ClearTopicPermissionsTest do test "banner with username only", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:user]], vhost_opts) - =~ ~r/Clearing topic permissions for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:user]], vhost_opts) =~ + ~r/Clearing topic permissions for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ end @tag user: @user, vhost: @specific_vhost test "banner with username and exchange name", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:user], "amq.topic"], vhost_opts) - =~ ~r/Clearing topic permissions on \"amq.topic\" for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:user], "amq.topic"], vhost_opts) =~ + ~r/Clearing topic permissions on \"amq.topic\" for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/clear_user_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_user_limits_command_test.exs index eb05a875bc9e..0e504596295d 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_user_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_user_limits_command_test.exs @@ -19,10 +19,10 @@ defmodule ClearUserLimitsCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_user @user, @password + add_user(@user, @password) on_exit([], fn -> - delete_user @user + delete_user(@user) end) :ok @@ -48,7 +48,9 @@ defmodule ClearUserLimitsCommandTest do test "validate: providing too many arguments fails validation" do assert @command.validate(["is", "too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end test "run: an unreachable node throws a badrpc" do @@ -63,9 +65,9 @@ defmodule ClearUserLimitsCommandTest do assert get_user_limits(@user) != [] assert @command.run( - [@user, @limittype], - context[:opts] - ) == :ok + [@user, @limittype], + context[:opts] + ) == :ok assert get_user_limits(@user) == %{} end @@ -76,40 +78,38 @@ defmodule ClearUserLimitsCommandTest do assert get_user_limits(@user) != [] assert @command.run( - [@user, "all"], - context[:opts] - ) == :ok + [@user, "all"], + context[:opts] + ) == :ok assert get_user_limits(@user) == %{} end @tag user: "bad-user" test "run: a non-existent user returns an error", context do - assert @command.run( - [context[:user], @limittype], - context[:opts] - ) == {:error, {:no_such_user, "bad-user"}} + [context[:user], @limittype], + context[:opts] + ) == {:error, {:no_such_user, "bad-user"}} end test "banner: for a limit type", context do - - s = @command.banner( - [@user, @limittype], - context[:opts] - ) + s = + @command.banner( + [@user, @limittype], + context[:opts] + ) assert s == "Clearing \"#{@limittype}\" limit for user \"#{@user}\" ..." end test "banner: for all", context do - - s = @command.banner( - [@user, "all"], - context[:opts] - ) + s = + @command.banner( + [@user, "all"], + context[:opts] + ) assert s == "Clearing all limits for user \"#{@user}\" ..." end - end diff --git a/deps/rabbitmq_cli/test/ctl/clear_vhost_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/clear_vhost_limits_command_test.exs index 4dd681c9018b..4cdf64026df1 100644 --- a/deps/rabbitmq_cli/test/ctl/clear_vhost_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/clear_vhost_limits_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClearVhostLimitsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -16,10 +15,10 @@ defmodule ClearVhostLimitsCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -61,7 +60,6 @@ defmodule ClearVhostLimitsCommandTest do assert match?({:badrpc, _}, @command.run([], opts)) end - @tag vhost: @vhost test "run: if limits exist, returns ok and clears them", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) @@ -71,9 +69,9 @@ defmodule ClearVhostLimitsCommandTest do assert get_vhost_limits(context[:vhost]) != [] assert @command.run( - [], - vhost_opts - ) == :ok + [], + vhost_opts + ) == :ok assert get_vhost_limits(context[:vhost]) == %{} end @@ -83,21 +81,21 @@ defmodule ClearVhostLimitsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [], - vhost_opts - ) == {:error_string, 'Parameter does not exist'} + [], + vhost_opts + ) == {:error_string, 'Parameter does not exist'} end @tag vhost: @vhost test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - s = @command.banner( - [], - vhost_opts - ) + s = + @command.banner( + [], + vhost_opts + ) assert s =~ ~r/Clearing vhost \"#{context[:vhost]}\" limits .../ end - end diff --git a/deps/rabbitmq_cli/test/ctl/close_all_connections_command_test.exs b/deps/rabbitmq_cli/test/ctl/close_all_connections_command_test.exs index f08969f3195d..692830d8f20a 100644 --- a/deps/rabbitmq_cli/test/ctl/close_all_connections_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/close_all_connections_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule CloseAllConnectionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -36,7 +35,9 @@ defmodule CloseAllConnectionsCommandTest do end test "validate: with an invalid number of arguments returns an arg count error", context do - assert @command.validate(["random", "explanation"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate(["random", "explanation"], context[:opts]) == + {:validation_failure, :too_many_args} + assert @command.validate([], context[:opts]) == {:validation_failure, :not_enough_args} end @@ -44,8 +45,9 @@ defmodule CloseAllConnectionsCommandTest do assert @command.validate(["explanation"], context[:opts]) == :ok end - test "run: a close connections request in an existing vhost with all defaults closes all connections", context do - with_connection(@vhost, fn(_) -> + test "run: a close connections request in an existing vhost with all defaults closes all connections", + context do + with_connection(@vhost, fn _ -> node = @helpers.normalise_node(context[:node], :shortnames) nodes = @helpers.nodes_in_cluster(node) [[vhost: @vhost]] = fetch_connection_vhosts(node, nodes) @@ -57,8 +59,9 @@ defmodule CloseAllConnectionsCommandTest do end) end - test "run: close a limited number of connections in an existing vhost closes a subset of connections", context do - with_connections([@vhost, @vhost, @vhost], fn(_) -> + test "run: close a limited number of connections in an existing vhost closes a subset of connections", + context do + with_connections([@vhost, @vhost, @vhost], fn _ -> node = @helpers.normalise_node(context[:node], :shortnames) nodes = @helpers.nodes_in_cluster(node) [[vhost: @vhost], [vhost: @vhost], [vhost: @vhost]] = fetch_connection_vhosts(node, nodes) @@ -70,18 +73,27 @@ defmodule CloseAllConnectionsCommandTest do end test "run: a close connections request for a non-existing vhost does nothing", context do - with_connection(@vhost, fn(_) -> + with_connection(@vhost, fn _ -> node = @helpers.normalise_node(context[:node], :shortnames) nodes = @helpers.nodes_in_cluster(node) [[vhost: @vhost]] = fetch_connection_vhosts(node, nodes) - opts = %{node: node, vhost: "non_existent-9288737", global: false, per_connection_delay: 0, limit: 0} + + opts = %{ + node: node, + vhost: "non_existent-9288737", + global: false, + per_connection_delay: 0, + limit: 0 + } + assert {:ok, "Closed 0 connections"} == @command.run(["test"], opts) assert fetch_connection_vhosts(node, nodes) == [[vhost: @vhost]] end) end - test "run: a close connections request to an existing node with --global (all vhosts)", context do - with_connection(@vhost, fn(_) -> + test "run: a close connections request to an existing node with --global (all vhosts)", + context do + with_connection(@vhost, fn _ -> node = @helpers.normalise_node(context[:node], :shortnames) nodes = @helpers.nodes_in_cluster(node) [[vhost: @vhost]] = fetch_connection_vhosts(node, nodes) @@ -93,7 +105,15 @@ defmodule CloseAllConnectionsCommandTest do end test "run: a close_all_connections request to non-existent RabbitMQ node returns a badrpc" do - opts = %{node: :jake@thedog, vhost: @vhost, global: true, per_connection_delay: 0, limit: 0, timeout: 200} + opts = %{ + node: :jake@thedog, + vhost: @vhost, + global: true, + per_connection_delay: 0, + limit: 0, + timeout: 200 + } + assert match?({:badrpc, _}, @command.run(["test"], opts)) end @@ -114,7 +134,14 @@ defmodule CloseAllConnectionsCommandTest do end test "banner for global option" do - opts = %{node: :test@localhost, vhost: "burrow", global: true, per_connection_delay: 0, limit: 0} + opts = %{ + node: :test@localhost, + vhost: "burrow", + global: true, + per_connection_delay: 0, + limit: 0 + } + s = @command.banner(["some reason"], opts) assert s =~ ~r/Closing all connections to node test@localhost/ assert s =~ ~r/some reason/ @@ -125,23 +152,29 @@ defmodule CloseAllConnectionsCommandTest do end defp fetch_connection_vhosts(node, nodes, retries) do - stream = RpcStream.receive_list_items(node, - :rabbit_networking, - :emit_connection_info_all, - [nodes, [:vhost]], - :infinity, - [:vhost], - Kernel.length(nodes)) - xs = Enum.to_list(stream) - - case {xs, retries} do - {xs, 0} -> - xs - {[], n} when n >= 0 -> - Process.sleep(10) - fetch_connection_vhosts(node, nodes, retries - 1) - _ -> - xs - end + stream = + RpcStream.receive_list_items( + node, + :rabbit_networking, + :emit_connection_info_all, + [nodes, [:vhost]], + :infinity, + [:vhost], + Kernel.length(nodes) + ) + + xs = Enum.to_list(stream) + + case {xs, retries} do + {xs, 0} -> + xs + + {[], n} when n >= 0 -> + Process.sleep(10) + fetch_connection_vhosts(node, nodes, retries - 1) + + _ -> + xs + end end end diff --git a/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs b/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs index 26c0553175bd..11c55f7a63db 100644 --- a/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/close_all_user_connections_command_test.exs @@ -25,10 +25,11 @@ defmodule CloseAllUserConnectionsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "validate: with an invalid number of arguments returns an arg count error", context do @@ -47,11 +48,14 @@ defmodule CloseAllUserConnectionsCommandTest do Application.ensure_all_started(:amqp) # open a localhost connection with default username {:ok, _conn} = AMQP.Connection.open(virtual_host: @vhost) - - await_condition(fn -> - conns = fetch_user_connections("guest", context) - length(conns) > 0 - end, 10000) + + await_condition( + fn -> + conns = fetch_user_connections("guest", context) + length(conns) > 0 + end, + 10000 + ) # make sure there is a connection to close conns = fetch_user_connections("guest", context) @@ -65,16 +69,21 @@ defmodule CloseAllUserConnectionsCommandTest do # finally, make sure we can close guest's connections assert :ok == @command.run(["guest", "test"], context[:opts]) - await_condition(fn -> - conns = fetch_user_connections("guest", context) - length(conns) == 0 - end, 10000) + + await_condition( + fn -> + conns = fetch_user_connections("guest", context) + length(conns) == 0 + end, + 10000 + ) conns = fetch_user_connections("guest", context) assert length(conns) == 0 end - test "run: a close connections request on for a non existing user returns successfully", context do + test "run: a close connections request on for a non existing user returns successfully", + context do assert match?( :ok, @command.run(["yeti", "test"], context[:opts]) diff --git a/deps/rabbitmq_cli/test/ctl/close_connection_command_test.exs b/deps/rabbitmq_cli/test/ctl/close_connection_command_test.exs index 0d1271a67f5b..277ddb090c31 100644 --- a/deps/rabbitmq_cli/test/ctl/close_connection_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/close_connection_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule CloseConnectionCommandTest do use ExUnit.Case, async: false import TestHelper @@ -32,7 +31,9 @@ defmodule CloseConnectionCommandTest do end test "validate: with an invalid number of arguments returns an arg count error", context do - assert @command.validate(["pid", "explanation", "extra"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate(["pid", "explanation", "extra"], context[:opts]) == + {:validation_failure, :too_many_args} + assert @command.validate(["pid"], context[:opts]) == {:validation_failure, :not_enough_args} end @@ -41,7 +42,7 @@ defmodule CloseConnectionCommandTest do end test "run: a close connection request on an existing connection", context do - with_connection("/", fn(_) -> + with_connection("/", fn _ -> Process.sleep(500) node = @helpers.normalise_node(context[:node], :shortnames) nodes = @helpers.nodes_in_cluster(node) @@ -52,9 +53,14 @@ defmodule CloseConnectionCommandTest do end) end - test "run: a close connection request on for a non existing connection returns successfully", context do - assert match?(:ok, - @command.run(["<#{node()}.2.121.12>", "test"], %{node: @helpers.normalise_node(context[:node], :shortnames)})) + test "run: a close connection request on for a non existing connection returns successfully", + context do + assert match?( + :ok, + @command.run(["<#{node()}.2.121.12>", "test"], %{ + node: @helpers.normalise_node(context[:node], :shortnames) + }) + ) end test "run: a close_connection request on nonexistent RabbitMQ node returns a badrpc" do @@ -73,24 +79,29 @@ defmodule CloseConnectionCommandTest do end defp fetch_connection_pids(node, nodes, retries) do - stream = RpcStream.receive_list_items(node, - :rabbit_networking, - :emit_connection_info_all, - [nodes, [:pid]], - :infinity, - [:pid], - Kernel.length(nodes)) - xs = Enum.to_list(stream) - - case {xs, retries} do - {xs, 0} -> - xs - {[], n} when n >= 0 -> - Process.sleep(100) - fetch_connection_pids(node, nodes, retries - 1) - _ -> - xs - end + stream = + RpcStream.receive_list_items( + node, + :rabbit_networking, + :emit_connection_info_all, + [nodes, [:pid]], + :infinity, + [:pid], + Kernel.length(nodes) + ) + + xs = Enum.to_list(stream) + + case {xs, retries} do + {xs, 0} -> + xs + + {[], n} when n >= 0 -> + Process.sleep(100) + fetch_connection_pids(node, nodes, retries - 1) + + _ -> + xs + end end - end diff --git a/deps/rabbitmq_cli/test/ctl/cluster_status_command_test.exs b/deps/rabbitmq_cli/test/ctl/cluster_status_command_test.exs index e582355e7a92..92cf8270ed5c 100644 --- a/deps/rabbitmq_cli/test/ctl/cluster_status_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/cluster_status_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ClusterStatusCommandTest do use ExUnit.Case, async: false import TestHelper diff --git a/deps/rabbitmq_cli/test/ctl/decode_command_test.exs b/deps/rabbitmq_cli/test/ctl/decode_command_test.exs index 93b5a05b6f6d..e7d5224b7358 100644 --- a/deps/rabbitmq_cli/test/ctl/decode_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/decode_command_test.exs @@ -9,11 +9,12 @@ defmodule DecodeCommandTest do @command RabbitMQ.CLI.Ctl.Commands.DecodeCommand setup _context do - {:ok, opts: %{ - cipher: :rabbit_pbe.default_cipher, - hash: :rabbit_pbe.default_hash, - iterations: :rabbit_pbe.default_iterations - }} + {:ok, + opts: %{ + cipher: :rabbit_pbe.default_cipher(), + hash: :rabbit_pbe.default_hash(), + iterations: :rabbit_pbe.default_iterations() + }} end test "validate: providing exactly 2 positional arguments passes", context do @@ -21,8 +22,10 @@ defmodule DecodeCommandTest do end test "validate: providing no positional arguments fails", context do - assert match?({:validation_failure, {:not_enough_args, _}}, - @command.validate([], context[:opts])) + assert match?( + {:validation_failure, {:not_enough_args, _}}, + @command.validate([], context[:opts]) + ) end test "validate: providing one positional argument passes", context do @@ -30,35 +33,51 @@ defmodule DecodeCommandTest do end test "validate: providing three or more positional argument fails", context do - assert match?({:validation_failure, :too_many_args}, - @command.validate(["value", "secret", "incorrect"], context[:opts])) + assert match?( + {:validation_failure, :too_many_args}, + @command.validate(["value", "secret", "incorrect"], context[:opts]) + ) end test "validate: hash and cipher must be supported", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{cipher: :funny_cipher})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{cipher: :funny_cipher}) + ) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{hash: :funny_hash})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{hash: :funny_hash}) + ) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{cipher: :funny_cipher, hash: :funny_hash})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{cipher: :funny_cipher, hash: :funny_hash}) + ) + ) + assert :ok == @command.validate(["value", "secret"], context[:opts]) end test "validate: number of iterations must greater than 0", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: 0})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: 0})) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: -1})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: -1})) + ) + assert :ok == @command.validate(["value", "secret"], context[:opts]) end @@ -76,19 +95,30 @@ defmodule DecodeCommandTest do cipher = context[:opts][:cipher] hash = context[:opts][:hash] iterations = context[:opts][:iterations] - output = {:encrypted, _encrypted} = :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, secret) + + output = + {:encrypted, _encrypted} = + :rabbit_pbe.encrypt_term(cipher, hash, iterations, passphrase, secret) {:encrypted, encrypted} = output # decode plain value - assert {:ok, secret} === @command.run([format_as_erlang_term(encrypted), passphrase], context[:opts]) + assert {:ok, secret} === + @command.run([format_as_erlang_term(encrypted), passphrase], context[:opts]) + # decode {encrypted, ...} tuple form - assert {:ok, secret} === @command.run([format_as_erlang_term(output), passphrase], context[:opts]) + assert {:ok, secret} === + @command.run([format_as_erlang_term(output), passphrase], context[:opts]) # wrong passphrase - assert match?({:error, _}, - @command.run([format_as_erlang_term(encrypted), "wrong/passphrase"], context[:opts])) - assert match?({:error, _}, - @command.run([format_as_erlang_term(output), "wrong passphrase"], context[:opts])) + assert match?( + {:error, _}, + @command.run([format_as_erlang_term(encrypted), "wrong/passphrase"], context[:opts]) + ) + + assert match?( + {:error, _}, + @command.run([format_as_erlang_term(output), "wrong passphrase"], context[:opts]) + ) end defp format_as_erlang_term(value) do diff --git a/deps/rabbitmq_cli/test/ctl/delete_queue_command_test.exs b/deps/rabbitmq_cli/test/ctl/delete_queue_command_test.exs index b0971b89613d..7ee51b3d4d3c 100644 --- a/deps/rabbitmq_cli/test/ctl/delete_queue_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/delete_queue_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule DeleteQueueCommandTest do use ExUnit.Case, async: false import TestHelper @@ -20,48 +19,51 @@ defmodule DeleteQueueCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - vhost: @vhost, - timeout: context[:test_timeout], - if_empty: false, - if_unused: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + vhost: @vhost, + timeout: context[:test_timeout], + if_empty: false, + if_unused: false + }} end test "merge_defaults: defaults can be overridden" do - assert @command.merge_defaults([], %{}) == {[], %{vhost: "/", if_empty: false, if_unused: false}} + assert @command.merge_defaults([], %{}) == + {[], %{vhost: "/", if_empty: false, if_unused: false}} + assert @command.merge_defaults([], %{vhost: "non_default", if_empty: true}) == - {[], %{vhost: "non_default", if_empty: true, if_unused: false}} + {[], %{vhost: "non_default", if_empty: true, if_unused: false}} end test "validate: providing no queue name fails validation", context do assert match?( - {:validation_failure, :not_enough_args}, - @command.validate([], context[:opts]) - ) + {:validation_failure, :not_enough_args}, + @command.validate([], context[:opts]) + ) end test "validate: providing an empty queue name fails validation", context do assert match?( - {:validation_failure, {:bad_argument, "queue name cannot be an empty string"}}, - @command.validate([""], context[:opts]) - ) + {:validation_failure, {:bad_argument, "queue name cannot be an empty string"}}, + @command.validate([""], context[:opts]) + ) end test "validate: providing a non-blank queue name and -u succeeds", context do assert @command.validate(["a-queue"], %{ - node: get_rabbit_hostname(), - vhost: @vhost, - timeout: context[:test_timeout], - if_unused: false - }) == :ok + node: get_rabbit_hostname(), + vhost: @vhost, + timeout: context[:test_timeout], + if_unused: false + }) == :ok end @tag test_timeout: 30000 test "run: request to an existent queue on active node succeeds", context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) on_exit(context, fn -> delete_vhost(@vhost) end) q = "foo" @@ -81,8 +83,8 @@ defmodule DeleteQueueCommandTest do @tag test_timeout: 0 test "run: timeout causes command to return a bad RPC", context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) on_exit(context, fn -> delete_vhost(@vhost) end) q = "foo" @@ -96,11 +98,13 @@ defmodule DeleteQueueCommandTest do end test "defaults to vhost /" do - assert @command.merge_defaults(["foo"], %{bar: "baz"}) == {["foo"], %{bar: "baz", vhost: "/", if_unused: false, if_empty: false}} + assert @command.merge_defaults(["foo"], %{bar: "baz"}) == + {["foo"], %{bar: "baz", vhost: "/", if_unused: false, if_empty: false}} end test "validate: with extra arguments returns an arg count error" do - assert @command.validate(["queue-name", "extra"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["queue-name", "extra"], %{}) == + {:validation_failure, :too_many_args} end test "validate: with no arguments returns an arg count error" do @@ -112,8 +116,13 @@ defmodule DeleteQueueCommandTest do end test "banner informs that vhost's queue is deleted" do - assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: false, if_unused: false}) == "Deleting queue 'my-q' on vhost '/foo' ..." - assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: true, if_unused: false}) == "Deleting queue 'my-q' on vhost '/foo' if queue is empty ..." - assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: true, if_unused: true}) == "Deleting queue 'my-q' on vhost '/foo' if queue is empty and if queue is unused ..." + assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: false, if_unused: false}) == + "Deleting queue 'my-q' on vhost '/foo' ..." + + assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: true, if_unused: false}) == + "Deleting queue 'my-q' on vhost '/foo' if queue is empty ..." + + assert @command.banner(["my-q"], %{vhost: "/foo", if_empty: true, if_unused: true}) == + "Deleting queue 'my-q' on vhost '/foo' if queue is empty and if queue is unused ..." end end diff --git a/deps/rabbitmq_cli/test/ctl/delete_user_command_test.exs b/deps/rabbitmq_cli/test/ctl/delete_user_command_test.exs index 97f09654a91b..0f67a40bb4a4 100644 --- a/deps/rabbitmq_cli/test/ctl/delete_user_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/delete_user_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule DeleteUserCommandTest do use ExUnit.Case, async: false import TestHelper @@ -36,7 +35,7 @@ defmodule DeleteUserCommandTest do test "run: A valid username returns ok", context do assert @command.run([context[:user]], context[:opts]) == :ok - assert list_users() |> Enum.count(fn(record) -> record[:user] == context[:user] end) == 0 + assert list_users() |> Enum.count(fn record -> record[:user] == context[:user] end) == 0 end test "run: An invalid Rabbit node returns a bad rpc message" do diff --git a/deps/rabbitmq_cli/test/ctl/delete_vhost_command_test.exs b/deps/rabbitmq_cli/test/ctl/delete_vhost_command_test.exs index 057f0789dc93..7355de9b04df 100644 --- a/deps/rabbitmq_cli/test/ctl/delete_vhost_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/delete_vhost_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule DeleteVhostCommandTest do use ExUnit.Case, async: false import TestHelper @@ -35,14 +34,14 @@ defmodule DeleteVhostCommandTest do test "run: A valid name to an active RabbitMQ node is successful", context do assert @command.run([context[:vhost]], context[:opts]) == :ok - assert list_vhosts() |> Enum.count(fn(record) -> record[:name] == context[:vhost] end) == 0 + assert list_vhosts() |> Enum.count(fn record -> record[:name] == context[:vhost] end) == 0 end @tag vhost: "" test "run: An empty string to an active RabbitMQ node is successful", context do assert @command.run([context[:vhost]], context[:opts]) == :ok - assert list_vhosts() |> Enum.count(fn(record) -> record[:name] == context[:vhost] end) == 0 + assert list_vhosts() |> Enum.count(fn record -> record[:name] == context[:vhost] end) == 0 end test "run: A call to invalid or inactive RabbitMQ node returns a nodedown" do @@ -54,8 +53,9 @@ defmodule DeleteVhostCommandTest do @tag vhost: @vhost test "run: Deleting the same host twice results in a host not found message", context do @command.run([context[:vhost]], context[:opts]) + assert @command.run([context[:vhost]], context[:opts]) == - {:error, {:no_such_vhost, context[:vhost]}} + {:error, {:no_such_vhost, context[:vhost]}} end @tag vhost: @vhost diff --git a/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs b/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs index f8a3e62920d7..054a815cccf1 100644 --- a/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs +++ b/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2018-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule EnableFeatureFlagCommandTest do use ExUnit.Case, async: false import TestHelper @@ -17,28 +16,47 @@ defmodule EnableFeatureFlagCommandTest do # Define an arbitrary feature flag for the test. node = get_rabbit_hostname() + new_feature_flags = %{ - @feature_flag => - %{desc: "My feature flag", + @feature_flag => %{ + desc: "My feature flag", provided_by: :EnableFeatureFlagCommandTest, +<<<<<<< HEAD stability: :stable}} :ok = :rabbit_misc.rpc_call( node, :rabbit_feature_flags, :initialize_registry, [new_feature_flags]) +======= + stability: :stable + } + } + + :ok = + :rabbit_misc.rpc_call( + node, + :rabbit_feature_flags, + :inject_test_feature_flags, + [new_feature_flags] + ) +>>>>>>> 059978e6fa (mix format rabbitmq_cli) { :ok, - opts: %{node: get_rabbit_hostname()}, - feature_flag: @feature_flag + opts: %{node: get_rabbit_hostname()}, feature_flag: @feature_flag } end test "validate: wrong number of arguments results in arg count errors" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["ff_from_enable_ff_testsuite", "whoops"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["ff_from_enable_ff_testsuite", "whoops"], %{}) == + {:validation_failure, :too_many_args} end test "validate: passing an empty string for feature_flag name is an arg error", context do - assert match?({:validation_failure, {:bad_argument, _}}, @command.validate([""], context[:opts])) + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate([""], context[:opts]) + ) end test "run: passing a valid feature_flag name to a running RabbitMQ node succeeds", context do @@ -52,19 +70,19 @@ defmodule EnableFeatureFlagCommandTest do end test "run: enabling the same feature flag twice is idempotent", context do - enable_feature_flag context[:feature_flag] + enable_feature_flag(context[:feature_flag]) assert @command.run([Atom.to_string(context[:feature_flag])], context[:opts]) == :ok assert list_feature_flags(:enabled) |> Map.has_key?(context[:feature_flag]) end test "run: enabling all feature flags succeeds", context do - enable_feature_flag context[:feature_flag] + enable_feature_flag(context[:feature_flag]) assert @command.run(["all"], context[:opts]) == :ok assert list_feature_flags(:enabled) |> Map.has_key?(context[:feature_flag]) end test "banner", context do - assert @command.banner([context[:feature_flag]], context[:opts]) - =~ ~r/Enabling feature flag \"#{context[:feature_flag]}\" \.\.\./ + assert @command.banner([context[:feature_flag]], context[:opts]) =~ + ~r/Enabling feature flag \"#{context[:feature_flag]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/encode_command_test.exs b/deps/rabbitmq_cli/test/ctl/encode_command_test.exs index f03e20e4436e..a9cacd73eca0 100644 --- a/deps/rabbitmq_cli/test/ctl/encode_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/encode_command_test.exs @@ -10,11 +10,12 @@ defmodule EncodeCommandTest do @command RabbitMQ.CLI.Ctl.Commands.EncodeCommand setup _context do - {:ok, opts: %{ - cipher: :rabbit_pbe.default_cipher, - hash: :rabbit_pbe.default_hash, - iterations: :rabbit_pbe.default_iterations - }} + {:ok, + opts: %{ + cipher: :rabbit_pbe.default_cipher(), + hash: :rabbit_pbe.default_hash(), + iterations: :rabbit_pbe.default_iterations() + }} end test "validate: providing exactly 2 positional arguments passes", context do @@ -27,35 +28,51 @@ defmodule EncodeCommandTest do end test "validate: providing three or more positional argument fails", context do - assert match?({:validation_failure, :too_many_args}, - @command.validate(["value", "secret", "incorrect"], context[:opts])) + assert match?( + {:validation_failure, :too_many_args}, + @command.validate(["value", "secret", "incorrect"], context[:opts]) + ) end test "validate: hash and cipher must be supported", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{cipher: :funny_cipher})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{cipher: :funny_cipher}) + ) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{hash: :funny_hash})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{hash: :funny_hash}) + ) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{cipher: :funny_cipher, hash: :funny_hash})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["value", "secret"], + Map.merge(context[:opts], %{cipher: :funny_cipher, hash: :funny_hash}) + ) + ) + assert :ok == @command.validate(["value", "secret"], context[:opts]) end test "validate: number of iterations must greater than 0", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: 0})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: 0})) + ) + assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: -1})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["value", "secret"], Map.merge(context[:opts], %{iterations: -1})) + ) + assert :ok == @command.validate(["value", "secret"], context[:opts]) end @@ -79,9 +96,18 @@ defmodule EncodeCommandTest do {:ok, output} = @command.run([secret_as_erlang_term, passphrase], context[:opts]) {:encrypted, encrypted} = output # decode plain value - assert secret === :rabbit_pbe.decrypt_term(cipher, hash, iterations, passphrase, {:plaintext, secret}) + assert secret === + :rabbit_pbe.decrypt_term(cipher, hash, iterations, passphrase, {:plaintext, secret}) + # decode {encrypted, ...} tuple form - assert secret === :rabbit_pbe.decrypt_term(cipher, hash, iterations, passphrase, {:encrypted, encrypted}) + assert secret === + :rabbit_pbe.decrypt_term( + cipher, + hash, + iterations, + passphrase, + {:encrypted, encrypted} + ) end defp format_as_erlang_term(value) do diff --git a/deps/rabbitmq_cli/test/ctl/environment_command_test.exs b/deps/rabbitmq_cli/test/ctl/environment_command_test.exs index 7f801d54dcd3..03cecf986f81 100644 --- a/deps/rabbitmq_cli/test/ctl/environment_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/environment_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule EnvironmentCommandTest do use ExUnit.Case, async: false import TestHelper @@ -39,7 +38,7 @@ defmodule EnvironmentCommandTest do end test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Application environment of node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Application environment of node #{get_rabbit_hostname()}/ end end diff --git a/deps/rabbitmq_cli/test/ctl/eval_command_test.exs b/deps/rabbitmq_cli/test/ctl/eval_command_test.exs index 92a2d7766721..afaae851ec07 100644 --- a/deps/rabbitmq_cli/test/ctl/eval_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/eval_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule EvalCommandTest do use ExUnit.Case, async: false import TestHelper @@ -28,12 +27,17 @@ defmodule EvalCommandTest do test "validate: empty expression to eval fails validation" do assert @command.validate([""], %{}) == {:validation_failure, "Expression must not be blank"} - assert @command.validate(["", "foo"], %{}) == {:validation_failure, "Expression must not be blank"} + + assert @command.validate(["", "foo"], %{}) == + {:validation_failure, "Expression must not be blank"} end test "validate: syntax error in expression to eval fails validation" do - assert @command.validate(["foo bar"], %{}) == {:validation_failure, "syntax error before: bar"} - assert @command.validate(["foo bar", "foo"], %{}) == {:validation_failure, "syntax error before: bar"} + assert @command.validate(["foo bar"], %{}) == + {:validation_failure, "syntax error before: bar"} + + assert @command.validate(["foo bar", "foo"], %{}) == + {:validation_failure, "syntax error before: bar"} end test "run: request to a non-existent node returns a badrpc", _context do @@ -58,8 +62,8 @@ defmodule EvalCommandTest do test "run: returns stdout output", context do assert capture_io(fn -> - assert @command.run(["io:format(\"output\")."], context[:opts]) == {:ok, :ok} - end) == "output" + assert @command.run(["io:format(\"output\")."], context[:opts]) == {:ok, :ok} + end) == "output" end test "run: passes parameters to the expression as positional/numerical variables", context do @@ -69,6 +73,6 @@ defmodule EvalCommandTest do test "run: passes globally recognised options as named variables", context do assert @command.run(["{_vhost, _node}."], Map.put(context[:opts], :vhost, "a-node")) == - {:ok, {"a-node", context[:opts][:node]}} + {:ok, {"a-node", context[:opts][:node]}} end end diff --git a/deps/rabbitmq_cli/test/ctl/eval_file_command_test.exs b/deps/rabbitmq_cli/test/ctl/eval_file_command_test.exs index 74cb272f985d..066d47a14f09 100644 --- a/deps/rabbitmq_cli/test/ctl/eval_file_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/eval_file_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule EvalFileCommandTest do use ExUnit.Case, async: false import TestHelper diff --git a/deps/rabbitmq_cli/test/ctl/exec_command_test.exs b/deps/rabbitmq_cli/test/ctl/exec_command_test.exs index bb839f5434ee..072cb174b59d 100644 --- a/deps/rabbitmq_cli/test/ctl/exec_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/exec_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ExecCommandTest do use ExUnit.Case, async: false @@ -43,5 +42,4 @@ defmodule ExecCommandTest do {:ok, ^opts} = @command.run(["options"], opts) {:ok, 123} = @command.run(["options[:option]"], opts) end - end diff --git a/deps/rabbitmq_cli/test/ctl/export_definitions_command_test.exs b/deps/rabbitmq_cli/test/ctl/export_definitions_command_test.exs index 3506b1ea8078..682202fdc0b4 100644 --- a/deps/rabbitmq_cli/test/ctl/export_definitions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/export_definitions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ExportDefinitionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,11 +17,12 @@ defmodule ExportDefinitionsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - format: context[:format] || "json" - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + format: context[:format] || "json" + }} end test "merge_defaults: defaults to JSON for format" do @@ -37,6 +37,7 @@ defmodule ExportDefinitionsCommandTest do test "merge_defaults: format is case insensitive" do assert @command.merge_defaults([valid_file_path()], %{format: "JSON"}) == {[valid_file_path()], %{format: "json"}} + assert @command.merge_defaults([valid_file_path()], %{format: "Erlang"}) == {[valid_file_path()], %{format: "erlang"}} end @@ -55,11 +56,13 @@ defmodule ExportDefinitionsCommandTest do end test "validate: unsupported format fails validation", context do - assert match?({:validation_failure, {:bad_argument, _}}, - @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "yolo"}))) + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "yolo"})) + ) end - test "validate: no positional arguments fails validation", context do + test "validate: no positional arguments fails validation", context do assert @command.validate([], context[:opts]) == {:validation_failure, :not_enough_args} end @@ -70,16 +73,21 @@ defmodule ExportDefinitionsCommandTest do end test "validate: supports JSON and Erlang formats", context do - assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "json"})) == :ok - assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "erlang"})) == :ok + assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "json"})) == + :ok + + assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "erlang"})) == + :ok end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - result = @command.run([valid_file_path()], - %{node: :jake@thedog, - timeout: context[:test_timeout], - format: "json"}) + result = + @command.run( + [valid_file_path()], + %{node: :jake@thedog, timeout: context[:test_timeout], format: "json"} + ) + assert match?({:badrpc, _}, result) end @@ -90,13 +98,15 @@ defmodule ExportDefinitionsCommandTest do end @tag format: "erlang" - test "run: returns a list of definitions when target is stdout and format is Erlang Terms", context do + test "run: returns a list of definitions when target is stdout and format is Erlang Terms", + context do {:ok, map} = @command.run(["-"], context[:opts]) assert Map.has_key?(map, :rabbitmq_version) end @tag format: "json" - test "run: writes to a file and returns nil when target is a file and format is JSON", context do + test "run: writes to a file and returns nil when target is a file and format is JSON", + context do File.rm(valid_file_path()) {:ok, nil} = @command.run([valid_file_path()], context[:opts]) @@ -125,7 +135,8 @@ defmodule ExportDefinitionsCommandTest do end @tag format: "erlang" - test "run: writes to a file and returns nil when target is a file and format is Erlang Terms", context do + test "run: writes to a file and returns nil when target is a file and format is Erlang Terms", + context do File.rm(valid_file_path()) {:ok, nil} = @command.run([valid_file_path()], context[:opts]) diff --git a/deps/rabbitmq_cli/test/ctl/force_gc_command_test.exs b/deps/rabbitmq_cli/test/ctl/force_gc_command_test.exs index b9583931d321..688165398ee4 100644 --- a/deps/rabbitmq_cli/test/ctl/force_gc_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/force_gc_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ForceGcCommandTest do use ExUnit.Case, async: false import TestHelper @@ -27,7 +26,6 @@ defmodule ForceGcCommandTest do {:ok, opts: %{node: get_rabbit_hostname(), timeout: 200}} end - test "merge_defaults: merge not defaults" do assert @command.merge_defaults([], %{}) == {[], %{}} end diff --git a/deps/rabbitmq_cli/test/ctl/force_reset_command_test.exs b/deps/rabbitmq_cli/test/ctl/force_reset_command_test.exs index 5b695302f402..99f7091685bb 100644 --- a/deps/rabbitmq_cli/test/ctl/force_reset_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/force_reset_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ForceResetCommandTest do use ExUnit.Case, async: false import TestHelper @@ -32,9 +31,9 @@ defmodule ForceResetCommandTest do end test "run: force reset request to an active node with a stopped rabbit app succeeds", context do - add_vhost "some_vhost" + add_vhost("some_vhost") # ensure the vhost really does exist - assert vhost_exists? "some_vhost" + assert vhost_exists?("some_vhost") stop_rabbitmq_app() assert :ok == @command.run([], context[:opts]) start_rabbitmq_app() @@ -43,10 +42,10 @@ defmodule ForceResetCommandTest do end test "run: reset request to an active node with a running rabbit app fails", context do - add_vhost "some_vhost" - assert vhost_exists? "some_vhost" + add_vhost("some_vhost") + assert vhost_exists?("some_vhost") assert match?({:error, :mnesia_unexpectedly_running}, @command.run([], context[:opts])) - assert vhost_exists? "some_vhost" + assert vhost_exists?("some_vhost") end test "run: request to a non-existent node returns a badrpc" do @@ -55,14 +54,16 @@ defmodule ForceResetCommandTest do end test "banner", context do - assert @command.banner([], context[:opts]) =~ ~r/Forcefully resetting node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Forcefully resetting node #{get_rabbit_hostname()}/ end test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, - "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + assert match?( + {:error, ^exit_code, "Mnesia is still running on node " <> _}, + @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/help_command_test.exs b/deps/rabbitmq_cli/test/ctl/help_command_test.exs index d30a4d98c736..21bea479299e 100644 --- a/deps/rabbitmq_cli/test/ctl/help_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/help_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule HelpCommandTest do use ExUnit.Case, async: false import TestHelper @@ -28,7 +27,7 @@ defmodule HelpCommandTest do test "validate: providing two or more position arguments fails validation" do assert @command.validate(["extra1", "extra2"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: prints basic usage info" do @@ -39,38 +38,43 @@ defmodule HelpCommandTest do end test "run: ctl command usage info is printed if command is specified" do - ctl_commands = CommandModules.module_map - |> Enum.filter(fn({_name, command_mod}) -> - to_string(command_mod) =~ ~r/^RabbitMQ\.CLI\.Ctl\.Commands/ - end) - |> Enum.map(fn({name, _}) -> name end) + ctl_commands = + CommandModules.module_map() + |> Enum.filter(fn {_name, command_mod} -> + to_string(command_mod) =~ ~r/^RabbitMQ\.CLI\.Ctl\.Commands/ + end) + |> Enum.map(fn {name, _} -> name end) IO.inspect(ctl_commands) + Enum.each( ctl_commands, - fn(command) -> + fn command -> assert @command.run([command], %{}) =~ ~r/#{command}/ - end) + end + ) end test "run prints command info" do - ctl_commands = CommandModules.module_map - |> Enum.filter(fn({_name, command_mod}) -> - to_string(command_mod) =~ ~r/^RabbitMQ\.CLI\.Ctl\.Commands/ - end) - |> Enum.map(fn({name, _}) -> name end) + ctl_commands = + CommandModules.module_map() + |> Enum.filter(fn {_name, command_mod} -> + to_string(command_mod) =~ ~r/^RabbitMQ\.CLI\.Ctl\.Commands/ + end) + |> Enum.map(fn {name, _} -> name end) Enum.each( ctl_commands, - fn(command) -> + fn command -> {:ok, lines} = @command.run([], %{}) output = Enum.join(lines, "\n") assert output =~ ~r/\n\s+#{command}.*\n/ - end) + end + ) end test "run: exits with the code of OK" do assert @command.output({:ok, "Help string"}, %{}) == - {:ok, "Help string"} + {:ok, "Help string"} end end diff --git a/deps/rabbitmq_cli/test/ctl/import_definitions_command_test.exs b/deps/rabbitmq_cli/test/ctl/import_definitions_command_test.exs index f3c49f0c502e..cffb418fe9b9 100644 --- a/deps/rabbitmq_cli/test/ctl/import_definitions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/import_definitions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ImportDefinitionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,11 +17,12 @@ defmodule ImportDefinitionsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - format: context[:format] || "json" - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + format: context[:format] || "json" + }} end test "merge_defaults: defaults to JSON for format" do @@ -37,6 +37,7 @@ defmodule ImportDefinitionsCommandTest do test "merge_defaults: format is case insensitive" do assert @command.merge_defaults([valid_file_path()], %{format: "JSON"}) == {[valid_file_path()], %{format: "json", skip_if_unchanged: false}} + assert @command.merge_defaults([valid_file_path()], %{format: "Erlang"}) == {[valid_file_path()], %{format: "erlang", skip_if_unchanged: false}} end @@ -51,8 +52,10 @@ defmodule ImportDefinitionsCommandTest do end test "validate: unsupported format fails validation", context do - assert match?({:validation_failure, {:bad_argument, _}}, - @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "yolo"}))) + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "yolo"})) + ) end test "validate: more than one positional argument fails validation", context do @@ -61,16 +64,21 @@ defmodule ImportDefinitionsCommandTest do end test "validate: supports JSON and Erlang formats", context do - assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "json"})) == :ok - assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "erlang"})) == :ok + assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "json"})) == + :ok + + assert @command.validate([valid_file_path()], Map.merge(context[:opts], %{format: "erlang"})) == + :ok end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - result = @command.run([valid_file_path()], - %{node: :jake@thedog, - timeout: context[:test_timeout], - format: "json"}) + result = + @command.run( + [valid_file_path()], + %{node: :jake@thedog, timeout: context[:test_timeout], format: "json"} + ) + assert match?({:badrpc, _}, result) end @@ -84,7 +92,11 @@ defmodule ImportDefinitionsCommandTest do @tag format: "json" test "run: imports definitions from a file when --skip-if-unchanged is provided", context do - assert :ok == @command.run([valid_file_path()], Map.merge(context[:opts], %{skip_if_unchanged: true})) + assert :ok == + @command.run( + [valid_file_path()], + Map.merge(context[:opts], %{skip_if_unchanged: true}) + ) # clean up the state we've modified clear_parameter("/", "federation-upstream", "up-1") diff --git a/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs b/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs index 2a9c7ec861e4..7301b5139eb9 100644 --- a/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/join_cluster_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2016-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule JoinClusterCommandTest do use ExUnit.Case, async: false import TestHelper @@ -24,49 +23,56 @@ defmodule JoinClusterCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname(), - disc: true, - ram: false, - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + disc: true, + ram: false + }} end test "validate: specifying both --disc and --ram is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["a"], Map.merge(context[:opts], %{disc: true, ram: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["a"], Map.merge(context[:opts], %{disc: true, ram: true})) + ) end + test "validate: specifying no target node is reported as an error", context do assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} + {:validation_failure, :not_enough_args} end + test "validate: specifying multiple target nodes is reported as an error", context do assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end # TODO - #test "run: successful join as a disc node", context do - #end + # test "run: successful join as a disc node", context do + # end # TODO - #test "run: successful join as a RAM node", context do - #end + # test "run: successful join as a RAM node", context do + # end test "run: joining self is invalid", context do stop_rabbitmq_app() + assert match?( - {:error, :cannot_cluster_node_with_itself}, - @command.run([context[:opts][:node]], context[:opts])) + {:error, :cannot_cluster_node_with_itself}, + @command.run([context[:opts][:node]], context[:opts]) + ) + start_rabbitmq_app() end # TODO test "run: request to an active node fails", context do - assert match?( - {:error, :mnesia_unexpectedly_running}, - @command.run([context[:opts][:node]], context[:opts])) + assert match?( + {:error, :mnesia_unexpectedly_running}, + @command.run([context[:opts][:node]], context[:opts]) + ) end test "run: request to a non-existent node returns a badrpc", context do @@ -76,29 +82,35 @@ defmodule JoinClusterCommandTest do ram: false, timeout: 200 } + assert match?( - {:badrpc, _}, - @command.run([context[:opts][:node]], opts)) + {:badrpc, _}, + @command.run([context[:opts][:node]], opts) + ) end test "run: joining a non-existent node returns a badrpc", context do stop_rabbitmq_app() + assert match?( - {:badrpc_multi, _, [_]}, - @command.run([:jake@thedog], context[:opts])) + {:badrpc_multi, _, [_]}, + @command.run([:jake@thedog], context[:opts]) + ) + start_rabbitmq_app() end test "banner", context do assert @command.banner(["a"], context[:opts]) =~ - ~r/Clustering node #{get_rabbit_hostname()} with a/ + ~r/Clustering node #{get_rabbit_hostname()} with a/ end test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, - "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + assert match?( + {:error, ^exit_code, "Mnesia is still running on node " <> _}, + @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_bindings_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_bindings_command_test.exs index dae237732239..e5c6c776e883 100644 --- a/deps/rabbitmq_cli/test/ctl/list_bindings_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_bindings_command_test.exs @@ -14,11 +14,13 @@ defmodule ListBindingsCommandTest do end setup context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) + on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) + { :ok, opts: %{ @@ -30,7 +32,9 @@ defmodule ListBindingsCommandTest do end test "merge_defaults: adds all keys if none specificed", context do - default_keys = ~w(source_name source_kind destination_name destination_kind routing_key arguments) + default_keys = + ~w(source_name source_kind destination_name destination_kind routing_key arguments) + declare_queue("test_queue", @vhost) :timer.sleep(100) @@ -45,27 +49,29 @@ defmodule ListBindingsCommandTest do test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: returns multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "source_name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["source_name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["source_kind", "oink", "source_name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["source_name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0}}] + [{:badrpc, {:timeout, 0.0}}] end test "run: no bindings for no queues", context do @@ -75,8 +81,9 @@ defmodule ListBindingsCommandTest do test "run: can filter info keys", context do wanted_keys = ~w(source_name destination_name routing_key) declare_queue("test_queue", @vhost) + assert run_command_to_list(@command, [wanted_keys, context[:opts]]) == - [[source_name: "", destination_name: "test_queue", routing_key: "test_queue"]] + [[source_name: "", destination_name: "test_queue", routing_key: "test_queue"]] end test "banner" do diff --git a/deps/rabbitmq_cli/test/ctl/list_channels_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_channels_command_test.exs index 6ccf6022112c..0942a58a0265 100644 --- a/deps/rabbitmq_cli/test/ctl/list_channels_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_channels_command_test.exs @@ -33,46 +33,59 @@ defmodule ListChannelsCommandTest do } end - test "merge_defaults: default channel info keys are pid, user, consumer_count, and messages_unacknowledged", context do - assert match?({~w(pid user consumer_count messages_unacknowledged), _}, @command.merge_defaults([], context[:opts])) + test "merge_defaults: default channel info keys are pid, user, consumer_count, and messages_unacknowledged", + context do + assert match?( + {~w(pid user consumer_count messages_unacknowledged), _}, + @command.merge_defaults([], context[:opts]) + ) end test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: returns multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: returns bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "pid"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["user", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["user", "oink", "pid"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: zero timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["user"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0}}] + [{:badrpc, {:timeout, 0.0}}] end test "run: multiple channels on multiple connections", context do node_name = get_rabbit_hostname() close_all_connections(node_name) - existent_channels = :rabbit_misc.rpc_call(node_name,:rabbit_channel, :list, []) - with_channel("/", fn(_channel1) -> - with_channel("/", fn(_channel2) -> - all_channels = run_command_to_list(@command, [["pid", "user", "connection"], context[:opts]]) - channels = Enum.filter(all_channels, - fn(ch) -> - not Enum.member?(existent_channels, ch[:pid]) - end) + existent_channels = :rabbit_misc.rpc_call(node_name, :rabbit_channel, :list, []) + + with_channel("/", fn _channel1 -> + with_channel("/", fn _channel2 -> + all_channels = + run_command_to_list(@command, [["pid", "user", "connection"], context[:opts]]) + + channels = + Enum.filter( + all_channels, + fn ch -> + not Enum.member?(existent_channels, ch[:pid]) + end + ) + chan1 = Enum.at(channels, 0) chan2 = Enum.at(channels, 1) assert Keyword.keys(chan1) == ~w(pid user connection)a @@ -87,15 +100,22 @@ defmodule ListChannelsCommandTest do test "run: multiple channels on single connection", context do node_name = get_rabbit_hostname() close_all_connections(get_rabbit_hostname()) - with_connection("/", fn(conn) -> - existent_channels = :rabbit_misc.rpc_call(node_name,:rabbit_channel, :list, []) + + with_connection("/", fn conn -> + existent_channels = :rabbit_misc.rpc_call(node_name, :rabbit_channel, :list, []) {:ok, _} = AMQP.Channel.open(conn) {:ok, _} = AMQP.Channel.open(conn) - all_channels = run_command_to_list(@command, [["pid", "user", "connection"], context[:opts]]) - channels = Enum.filter(all_channels, - fn(ch) -> - not Enum.member?(existent_channels, ch[:pid]) - end) + + all_channels = + run_command_to_list(@command, [["pid", "user", "connection"], context[:opts]]) + + channels = + Enum.filter( + all_channels, + fn ch -> + not Enum.member?(existent_channels, ch[:pid]) + end + ) chan1 = Enum.at(channels, 0) chan2 = Enum.at(channels, 1) @@ -109,9 +129,12 @@ defmodule ListChannelsCommandTest do test "run: info keys order is preserved", context do close_all_connections(get_rabbit_hostname()) - with_channel("/", fn(_channel) -> - channels = run_command_to_list(@command, [~w(connection vhost name pid number user), context[:opts]]) - chan = Enum.at(channels, 0) + + with_channel("/", fn _channel -> + channels = + run_command_to_list(@command, [~w(connection vhost name pid number user), context[:opts]]) + + chan = Enum.at(channels, 0) assert Keyword.keys(chan) == ~w(connection vhost name pid number user)a end) end diff --git a/deps/rabbitmq_cli/test/ctl/list_ciphers_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_ciphers_command_test.exs index 6f600ba5d8aa..c01d11cf07be 100644 --- a/deps/rabbitmq_cli/test/ctl/list_ciphers_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_ciphers_command_test.exs @@ -22,8 +22,8 @@ defmodule ListCiphersCommandTest do test "run: lists ciphers", _context do assert match?( - {:ok, _}, - @command.run([], %{}) - ) + {:ok, _}, + @command.run([], %{}) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_connections_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_connections_command_test.exs index 9cfcb8787feb..23994f4ab0d5 100644 --- a/deps/rabbitmq_cli/test/ctl/list_connections_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_connections_command_test.exs @@ -30,7 +30,8 @@ defmodule ListConnectionsCommandTest do end test "merge_defaults: user, peer_host, peer_port and state by default" do - assert @command.merge_defaults([], %{}) == {~w(user peer_host peer_port state), @default_options} + assert @command.merge_defaults([], %{}) == + {~w(user peer_host peer_port state), @default_options} end test "merge_defaults: includes table headers by default", _context do @@ -40,51 +41,54 @@ defmodule ListConnectionsCommandTest do test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "peer_host"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["user", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["user", "oink", "peer_host"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0}}] + [{:badrpc, {:timeout, 0.0}}] end test "run: filter single key", context do vhost = "/" - with_connection(vhost, fn(_conn) -> + + with_connection(vhost, fn _conn -> conns = run_command_to_list(@command, [["name"], context[:opts]]) - assert (Enum.map(conns, &Keyword.keys/1) |> Enum.uniq) == [[:name]] - assert Enum.any?(conns, fn(conn) -> conn[:name] != nil end) + assert Enum.map(conns, &Keyword.keys/1) |> Enum.uniq() == [[:name]] + assert Enum.any?(conns, fn conn -> conn[:name] != nil end) end) end test "run: show connection vhost", context do vhost = "custom_vhost" - add_vhost vhost - set_permissions @user, vhost, [".*", ".*", ".*"] + add_vhost(vhost) + set_permissions(@user, vhost, [".*", ".*", ".*"]) + on_exit(fn -> - delete_vhost vhost + delete_vhost(vhost) end) - with_connection(vhost, fn(_conn) -> + + with_connection(vhost, fn _conn -> conns = run_command_to_list(@command, [["vhost"], context[:opts]]) - assert (Enum.map(conns, &Keyword.keys/1) |> Enum.uniq) == [[:vhost]] - assert Enum.any?(conns, fn(conn) -> conn[:vhost] == vhost end) + assert Enum.map(conns, &Keyword.keys/1) |> Enum.uniq() == [[:vhost]] + assert Enum.any?(conns, fn conn -> conn[:vhost] == vhost end) end) end - - end diff --git a/deps/rabbitmq_cli/test/ctl/list_consumers_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_consumers_command_test.exs index d49313162a42..463fb591e04b 100644 --- a/deps/rabbitmq_cli/test/ctl/list_consumers_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_consumers_command_test.exs @@ -17,11 +17,13 @@ defmodule ListConsumersCommandTest do end setup context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) + on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) + { :ok, opts: %{ @@ -34,33 +36,36 @@ defmodule ListConsumersCommandTest do test "merge_defaults: defaults can be overridden" do assert @command.merge_defaults([], %{}) == {@info_keys, @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {@info_keys, %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {@info_keys, %{vhost: "non_default", table_headers: true}} end test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: returns multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "queue_name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["queue_name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["channel_pid", "oink", "queue_name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: zero timeout causes command to return badrpc", context do - assert run_command_to_list(@command, [["queue_name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0}}] + assert run_command_to_list(@command, [["queue_name"], context[:opts]]) == + [{:badrpc, {:timeout, 0.0}}] end test "run: no consumers for no open connections", context do @@ -74,17 +79,23 @@ defmodule ListConsumersCommandTest do info_keys_s = ~w(queue_name channel_pid consumer_tag ack_required prefetch_count arguments) info_keys_a = Enum.map(info_keys_s, &String.to_atom/1) declare_queue(queue_name, @vhost) - with_channel(@vhost, fn(channel) -> - {:ok, _} = AMQP.Basic.consume(channel, queue_name, nil, [consumer_tag: consumer_tag]) + + with_channel(@vhost, fn channel -> + {:ok, _} = AMQP.Basic.consume(channel, queue_name, nil, consumer_tag: consumer_tag) :timer.sleep(100) [[consumer]] = run_command_to_list(@command, [info_keys_s, context[:opts]]) assert info_keys_a == Keyword.keys(consumer) assert consumer[:consumer_tag] == consumer_tag assert consumer[:queue_name] == queue_name - assert Keyword.delete(consumer, :channel_pid) == - [queue_name: queue_name, consumer_tag: consumer_tag, - ack_required: true, prefetch_count: 0, arguments: []] + assert Keyword.delete(consumer, :channel_pid) == + [ + queue_name: queue_name, + consumer_tag: consumer_tag, + ack_required: true, + prefetch_count: 0, + arguments: [] + ] end) end @@ -93,17 +104,29 @@ defmodule ListConsumersCommandTest do queue_name2 = "test_queue2" declare_queue("test_queue1", @vhost) declare_queue("test_queue2", @vhost) - with_channel(@vhost, fn(channel) -> + + with_channel(@vhost, fn channel -> {:ok, tag1} = AMQP.Basic.consume(channel, queue_name1) {:ok, tag2} = AMQP.Basic.consume(channel, queue_name2) {:ok, tag3} = AMQP.Basic.consume(channel, queue_name2) :timer.sleep(100) + try do - consumers = run_command_to_list(@command, [["queue_name", "consumer_tag"], context[:opts]]) - {[[consumer1]], [consumers2]} = Enum.split_with(consumers, fn([_]) -> true; ([_,_]) -> false end) + consumers = + run_command_to_list(@command, [["queue_name", "consumer_tag"], context[:opts]]) + + {[[consumer1]], [consumers2]} = + Enum.split_with(consumers, fn + [_] -> true + [_, _] -> false + end) + assert [queue_name: queue_name1, consumer_tag: tag1] == consumer1 - assert Keyword.equal?([{tag2, queue_name2}, {tag3, queue_name2}], - for([queue_name: q, consumer_tag: t] <- consumers2, do: {t, q})) + + assert Keyword.equal?( + [{tag2, queue_name2}, {tag3, queue_name2}], + for([queue_name: q, consumer_tag: t] <- consumers2, do: {t, q}) + ) after AMQP.Basic.cancel(channel, tag1) AMQP.Basic.cancel(channel, tag2) @@ -114,20 +137,39 @@ defmodule ListConsumersCommandTest do test "run: active and activity status fields are set properly when requested", context do queue_types = ["classic", "quorum"] - Enum.each queue_types, fn queue_type -> + + Enum.each(queue_types, fn queue_type -> queue_name = "active-activity-status-fields-" <> queue_type declare_queue(queue_name, @vhost, true, false, [{"x-queue-type", :longstr, queue_type}]) :timer.sleep(200) - with_channel(@vhost, fn(channel) -> + + with_channel(@vhost, fn channel -> {:ok, tag1} = AMQP.Basic.consume(channel, queue_name) {:ok, tag2} = AMQP.Basic.consume(channel, queue_name) {:ok, tag3} = AMQP.Basic.consume(channel, queue_name) :timer.sleep(100) + try do - consumers = List.first(run_command_to_list(@command, [["queue_name", "consumer_tag", "active", "activity_status"], context[:opts]])) - assert Keyword.equal?([{tag1, queue_name, true, :up}, - {tag2, queue_name, true, :up}, {tag3, queue_name, true, :up}], - for([queue_name: q, consumer_tag: t, active: a, activity_status: as] <- consumers, do: {t, q, a, as})) + consumers = + List.first( + run_command_to_list(@command, [ + ["queue_name", "consumer_tag", "active", "activity_status"], + context[:opts] + ]) + ) + + assert Keyword.equal?( + [ + {tag1, queue_name, true, :up}, + {tag2, queue_name, true, :up}, + {tag3, queue_name, true, :up} + ], + for( + [queue_name: q, consumer_tag: t, active: a, activity_status: as] <- + consumers, + do: {t, q, a, as} + ) + ) after AMQP.Basic.cancel(channel, tag1) AMQP.Basic.cancel(channel, tag2) @@ -136,31 +178,73 @@ defmodule ListConsumersCommandTest do delete_queue(queue_name, @vhost) end end) - end + end) end - test "run: active and activity status fields are set properly when requested and single active consumer is enabled", context do + test "run: active and activity status fields are set properly when requested and single active consumer is enabled", + context do queue_types = ["classic", "quorum"] - Enum.each queue_types, fn queue_type -> + + Enum.each(queue_types, fn queue_type -> queue_name = "single-active-consumer-" <> queue_type - declare_queue(queue_name, @vhost, true, false, - [{"x-single-active-consumer", :bool, true}, {"x-queue-type", :longstr, queue_type}]) + + declare_queue(queue_name, @vhost, true, false, [ + {"x-single-active-consumer", :bool, true}, + {"x-queue-type", :longstr, queue_type} + ]) + :timer.sleep(200) - with_channel(@vhost, fn(channel) -> + + with_channel(@vhost, fn channel -> {:ok, tag1} = AMQP.Basic.consume(channel, queue_name) {:ok, tag2} = AMQP.Basic.consume(channel, queue_name) {:ok, tag3} = AMQP.Basic.consume(channel, queue_name) :timer.sleep(100) + try do - consumers = List.first(run_command_to_list(@command, [["queue_name", "consumer_tag", "active", "activity_status"], context[:opts]])) - assert Keyword.equal?([{tag1, queue_name, true, :single_active}, - {tag2, queue_name, false, :waiting}, {tag3, queue_name, false, :waiting}], - for([queue_name: q, consumer_tag: t, active: a, activity_status: as] <- consumers, do: {t, q, a, as})) + consumers = + List.first( + run_command_to_list(@command, [ + ["queue_name", "consumer_tag", "active", "activity_status"], + context[:opts] + ]) + ) + + assert Keyword.equal?( + [ + {tag1, queue_name, true, :single_active}, + {tag2, queue_name, false, :waiting}, + {tag3, queue_name, false, :waiting} + ], + for( + [queue_name: q, consumer_tag: t, active: a, activity_status: as] <- + consumers, + do: {t, q, a, as} + ) + ) + AMQP.Basic.cancel(channel, tag1) :timer.sleep(100) - consumers = List.first(run_command_to_list(@command, [["queue_name", "consumer_tag", "active", "activity_status"], context[:opts]])) - assert Keyword.equal?([{tag2, queue_name, true, :single_active}, {tag3, queue_name, false, :waiting}], - for([queue_name: q, consumer_tag: t, active: a, activity_status: as] <- consumers, do: {t, q, a, as})) + + consumers = + List.first( + run_command_to_list(@command, [ + ["queue_name", "consumer_tag", "active", "activity_status"], + context[:opts] + ]) + ) + + assert Keyword.equal?( + [ + {tag2, queue_name, true, :single_active}, + {tag3, queue_name, false, :waiting} + ], + for( + [queue_name: q, consumer_tag: t, active: a, activity_status: as] <- + consumers, + do: {t, q, a, as} + ) + ) after AMQP.Basic.cancel(channel, tag2) AMQP.Basic.cancel(channel, tag3) @@ -168,7 +252,7 @@ defmodule ListConsumersCommandTest do delete_queue(queue_name, @vhost) end end) - end + end) end test "fill_consumer_active_fields: add missing fields if necessary" do @@ -182,32 +266,36 @@ defmodule ListConsumersCommandTest do activity_status: :up, arguments: [] ] - assert @command.fill_consumer_active_fields({[ - consumer38 - ], {1, :continue}}) == {[consumer38], {1, :continue}} - - assert @command.fill_consumer_active_fields({[ - [ - queue_name: {:resource, "/", :queue, "queue2"}, - channel_pid: "", - consumer_tag: "ctag2", - ack_required: false, - prefetch_count: 0, - arguments: [] - ] - ], {1, :continue}}) == {[ - [ - queue_name: {:resource, "/", :queue, "queue2"}, - channel_pid: "", - consumer_tag: "ctag2", - ack_required: false, - prefetch_count: 0, - active: true, - activity_status: :up, - arguments: [] - ] - ], {1, :continue}} - end + assert @command.fill_consumer_active_fields( + {[ + consumer38 + ], {1, :continue}} + ) == {[consumer38], {1, :continue}} + assert @command.fill_consumer_active_fields( + {[ + [ + queue_name: {:resource, "/", :queue, "queue2"}, + channel_pid: "", + consumer_tag: "ctag2", + ack_required: false, + prefetch_count: 0, + arguments: [] + ] + ], {1, :continue}} + ) == + {[ + [ + queue_name: {:resource, "/", :queue, "queue2"}, + channel_pid: "", + consumer_tag: "ctag2", + ack_required: false, + prefetch_count: 0, + active: true, + activity_status: :up, + arguments: [] + ] + ], {1, :continue}} + end end diff --git a/deps/rabbitmq_cli/test/ctl/list_exchanges_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_exchanges_command_test.exs index fd89cfd06624..33fc7fb02991 100644 --- a/deps/rabbitmq_cli/test/ctl/list_exchanges_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_exchanges_command_test.exs @@ -7,13 +7,15 @@ defmodule ListExchangesCommandTest do @vhost "test1" @user "guest" @default_timeout :infinity - @default_exchanges [{"amq.direct", :direct}, - {"amq.fanout", :fanout}, - {"amq.match", :headers}, - {"amq.rabbitmq.trace", :topic}, - {"amq.headers", :headers}, - {"amq.topic", :topic}, - {"", :direct}] + @default_exchanges [ + {"amq.direct", :direct}, + {"amq.fanout", :fanout}, + {"amq.match", :headers}, + {"amq.rabbitmq.trace", :topic}, + {"amq.headers", :headers}, + {"amq.topic", :topic}, + {"", :direct} + ] @default_options %{vhost: "/", table_headers: true} defp default_exchange_names() do @@ -28,11 +30,13 @@ defmodule ListExchangesCommandTest do end setup context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) + on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) + { :ok, opts: %{ @@ -45,64 +49,72 @@ defmodule ListExchangesCommandTest do end test "merge_defaults: should include name and type when no arguments provided and add default vhost to opts" do - assert @command.merge_defaults([], %{}) - == {["name", "type"], @default_options} + assert @command.merge_defaults([], %{}) == + {["name", "type"], @default_options} end test "merge_defaults: defaults can be overridden" do assert @command.merge_defaults([], %{}) == {["name", "type"], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {["name", "type"], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {["name", "type"], %{vhost: "non_default", table_headers: true}} end test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: returns multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "type"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["name", "oink", "type"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: zero timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0}}] + [{:badrpc, {:timeout, 0.0}}] end test "run: show default exchanges by default", context do assert MapSet.new(run_command_to_list(@command, [["name"], context[:opts]])) == - MapSet.new(for {ex_name, _ex_type} <- @default_exchanges, do: [name: ex_name]) + MapSet.new(for {ex_name, _ex_type} <- @default_exchanges, do: [name: ex_name]) end test "run: default options test", context do exchange_name = "test_exchange" declare_exchange(exchange_name, @vhost) - assert MapSet.new(run_command_to_list(@command, [["name", "type"], context[:opts]])) == - MapSet.new( - for({ex_name, ex_type} <- @default_exchanges, do: [name: ex_name, type: ex_type]) ++ - [[name: exchange_name, type: :direct]]) + + assert MapSet.new(run_command_to_list(@command, [["name", "type"], context[:opts]])) == + MapSet.new( + for({ex_name, ex_type} <- @default_exchanges, do: [name: ex_name, type: ex_type]) ++ + [[name: exchange_name, type: :direct]] + ) end test "run: list multiple exchanges", context do declare_exchange("test_exchange_1", @vhost, :direct) declare_exchange("test_exchange_2", @vhost, :fanout) - non_default_exchanges = run_command_to_list(@command, [["name", "type"], context[:opts]]) - |> without_default_exchanges + + non_default_exchanges = + run_command_to_list(@command, [["name", "type"], context[:opts]]) + |> without_default_exchanges + assert_set_equal( non_default_exchanges, - [[name: "test_exchange_1", type: :direct], - [name: "test_exchange_2", type: :fanout]]) + [[name: "test_exchange_1", type: :direct], [name: "test_exchange_2", type: :fanout]] + ) end def assert_set_equal(one, two) do @@ -112,49 +124,63 @@ defmodule ListExchangesCommandTest do test "run: info keys filter single key", context do declare_exchange("test_exchange_1", @vhost) declare_exchange("test_exchange_2", @vhost) - non_default_exchanges = run_command_to_list(@command, [["name"], context[:opts]]) - |> without_default_exchanges + + non_default_exchanges = + run_command_to_list(@command, [["name"], context[:opts]]) + |> without_default_exchanges + assert_set_equal( non_default_exchanges, - [[name: "test_exchange_1"], - [name: "test_exchange_2"]]) + [[name: "test_exchange_1"], [name: "test_exchange_2"]] + ) end - test "run: info keys add additional keys", context do declare_exchange("durable_exchange", @vhost, :direct, true) declare_exchange("auto_delete_exchange", @vhost, :fanout, false, true) - non_default_exchanges = run_command_to_list(@command, [["name", "type", "durable", "auto_delete"], context[:opts]]) - |> without_default_exchanges + + non_default_exchanges = + run_command_to_list(@command, [["name", "type", "durable", "auto_delete"], context[:opts]]) + |> without_default_exchanges + assert_set_equal( non_default_exchanges, - [[name: "auto_delete_exchange", type: :fanout, durable: false, auto_delete: true], - [name: "durable_exchange", type: :direct, durable: true, auto_delete: false]]) + [ + [name: "auto_delete_exchange", type: :fanout, durable: false, auto_delete: true], + [name: "durable_exchange", type: :direct, durable: true, auto_delete: false] + ] + ) end test "run: specifying a vhost returns the targeted vhost exchanges", context do other_vhost = "other_vhost" - add_vhost other_vhost + add_vhost(other_vhost) + on_exit(fn -> - delete_vhost other_vhost + delete_vhost(other_vhost) end) + declare_exchange("test_exchange_1", @vhost) declare_exchange("test_exchange_2", other_vhost) - non_default_exchanges1 = run_command_to_list(@command, [["name"], context[:opts]]) - |> without_default_exchanges - non_default_exchanges2 = run_command_to_list(@command, [["name"], %{context[:opts] | :vhost => other_vhost}]) - |> without_default_exchanges + non_default_exchanges1 = + run_command_to_list(@command, [["name"], context[:opts]]) + |> without_default_exchanges + + non_default_exchanges2 = + run_command_to_list(@command, [["name"], %{context[:opts] | :vhost => other_vhost}]) + |> without_default_exchanges assert non_default_exchanges1 == [[name: "test_exchange_1"]] assert non_default_exchanges2 == [[name: "test_exchange_2"]] end defp without_default_exchanges(xs) do - Enum.filter(xs, - fn(x) -> - not Enum.member?(default_exchange_names(), x[:name]) - end) + Enum.filter( + xs, + fn x -> + not Enum.member?(default_exchange_names(), x[:name]) + end + ) end - end diff --git a/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs index b2cf1ad52ad8..a80bd4017b2b 100644 --- a/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs @@ -18,19 +18,43 @@ defmodule ListFeatureFlagsCommandTest do # Define an arbitrary feature flag for the test. node = get_rabbit_hostname() + new_feature_flags = %{ - @flag1 => - %{desc: "My feature flag #1", + @flag1 => %{ + desc: "My feature flag #1", provided_by: :ListFeatureFlagsCommandTest, - stability: :stable}, - @flag2 => - %{desc: "My feature flag #2", + stability: :stable + }, + @flag2 => %{ + desc: "My feature flag #2", provided_by: :ListFeatureFlagsCommandTest, +<<<<<<< HEAD stability: :stable}} :ok = :rabbit_misc.rpc_call( node, :rabbit_feature_flags, :initialize_registry, [new_feature_flags]) :ok = :rabbit_misc.rpc_call( node, :rabbit_feature_flags, :enable_all, []) +======= + stability: :stable + } + } + + :ok = + :rabbit_misc.rpc_call( + node, + :rabbit_feature_flags, + :inject_test_feature_flags, + [new_feature_flags] + ) + + :ok = + :rabbit_misc.rpc_call( + node, + :rabbit_feature_flags, + :enable_all, + [] + ) +>>>>>>> 059978e6fa (mix format rabbitmq_cli) name_result = [ [{:name, @flag1}], @@ -44,8 +68,7 @@ defmodule ListFeatureFlagsCommandTest do { :ok, - name_result: name_result, - full_result: full_result + name_result: name_result, full_result: full_result } end @@ -62,21 +85,23 @@ defmodule ListFeatureFlagsCommandTest do test "validate: return bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["name", "oink", "state"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end test "run: on a bad RabbitMQ node, return a badrpc" do @@ -87,32 +112,35 @@ defmodule ListFeatureFlagsCommandTest do @tag test_timeout: :infinity test "run: with the name tag, print just the names", context do matches_found = @command.run(["name"], context[:opts]) - assert Enum.all?(context[:name_result], fn(feature_name) -> - Enum.find(matches_found, fn(found) -> found == feature_name end) - end) + + assert Enum.all?(context[:name_result], fn feature_name -> + Enum.find(matches_found, fn found -> found == feature_name end) + end) end @tag test_timeout: :infinity test "run: duplicate args do not produce duplicate entries", context do # checks to ensure that all expected feature flags are in the results matches_found = @command.run(["name", "name"], context[:opts]) - assert Enum.all?(context[:name_result], fn(feature_name) -> - Enum.find(matches_found, fn(found) -> found == feature_name end) - end) + + assert Enum.all?(context[:name_result], fn feature_name -> + Enum.find(matches_found, fn found -> found == feature_name end) + end) end @tag test_timeout: 30000 test "run: sufficiently long timeouts don't interfere with results", context do matches_found = @command.run(["name", "state"], context[:opts]) - assert Enum.all?(context[:full_result], fn(feature_name) -> - Enum.find(matches_found, fn(found) -> found == feature_name end) - end) + + assert Enum.all?(context[:full_result], fn feature_name -> + Enum.find(matches_found, fn found -> found == feature_name end) + end) end @tag test_timeout: 0, username: "guest" test "run: timeout causes command to return a bad RPC", context do assert @command.run(["name", "state"], context[:opts]) == - {:badrpc, :timeout} + {:badrpc, :timeout} end @tag test_timeout: :infinity diff --git a/deps/rabbitmq_cli/test/ctl/list_global_parameters_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_global_parameters_command_test.exs index eabd6a36286a..275b5317a6e1 100644 --- a/deps/rabbitmq_cli/test/ctl/list_global_parameters_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_global_parameters_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListGlobalParametersCommandTest do use ExUnit.Case, async: false import TestHelper @@ -21,25 +20,27 @@ defmodule ListGlobalParametersCommandTest do setup context do on_exit(fn -> - clear_global_parameter context[:key] + clear_global_parameter(context[:key]) end) { :ok, opts: %{ node: get_rabbit_hostname(), - timeout: (context[:timeout] || :infinity), + timeout: context[:timeout] || :infinity } } end test "validate: wrong number of arguments leads to an arg count error" do - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag key: @key, value: @value test "run: a well-formed command returns list of global parameters", context do set_global_parameter(context[:key], @value) + @command.run([], context[:opts]) |> assert_parameter_list(context) end @@ -52,35 +53,40 @@ defmodule ListGlobalParametersCommandTest do test "run: multiple parameters returned in list", context do initial = for param <- @command.run([], context[:opts]), do: Map.new(param) + parameters = [ %{name: :global_param_1, value: "{\"key1\":\"value1\"}"}, %{name: :global_param_2, value: "{\"key2\":\"value2\"}"} ] - - Enum.each(parameters, fn(%{name: name, value: value}) -> + Enum.each(parameters, fn %{name: name, value: value} -> set_global_parameter(name, value) + on_exit(fn -> clear_global_parameter(name) end) end) parameters = initial ++ parameters - params = for param <- @command.run([], context[:opts]), do: Map.new(param) + params = for param <- @command.run([], context[:opts]), do: Map.new(param) assert MapSet.new(params) == MapSet.new(parameters) end @tag key: @key, value: @value test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Listing global runtime parameters \.\.\./ + assert @command.banner([], context[:opts]) =~ + ~r/Listing global runtime parameters \.\.\./ end # Checks each element of the first parameter against the expected context values defp assert_parameter_list(params, context) do [param | _] = params - assert MapSet.new(param) == MapSet.new([name: context[:key], - value: context[:value]]) + + assert MapSet.new(param) == + MapSet.new( + name: context[:key], + value: context[:value] + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_hashes_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_hashes_command_test.exs index 2869479a8a1f..372893ec26ae 100644 --- a/deps/rabbitmq_cli/test/ctl/list_hashes_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_hashes_command_test.exs @@ -22,8 +22,8 @@ defmodule ListHashesCommandTest do test "run: lists hashes", _context do assert match?( - {:ok, _}, - @command.run([], %{}) - ) + {:ok, _}, + @command.run([], %{}) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_operator_policies_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_operator_policies_command_test.exs index 6c86fe844102..3c8ad0f5e102 100644 --- a/deps/rabbitmq_cli/test/ctl/list_operator_policies_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_operator_policies_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListOperatorPoliciesCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule ListOperatorPoliciesCommandTest do @command RabbitMQ.CLI.Ctl.Commands.ListOperatorPoliciesCommand @vhost "test1" - @root "/" + @root "/" @key "message-expiry" @pattern "^queue\." @value "{\"message-ttl\":10}" @@ -22,10 +21,10 @@ defmodule ListOperatorPoliciesCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -33,13 +32,14 @@ defmodule ListOperatorPoliciesCommandTest do setup context do on_exit(fn -> - clear_operator_policy context[:vhost], context[:key] + clear_operator_policy(context[:vhost], context[:key]) end) + { :ok, opts: %{ node: get_rabbit_hostname(), - timeout: (context[:timeout] || :infinity), + timeout: context[:timeout] || :infinity, vhost: context[:vhost], apply_to: @apply_to, priority: 0 @@ -49,20 +49,24 @@ defmodule ListOperatorPoliciesCommandTest do test "merge_defaults: default vhost is '/'" do assert @command.merge_defaults([], %{}) == {[], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {[], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {[], %{vhost: "non_default", table_headers: true}} end test "validate: providing too many arguments fails validation" do assert @command.validate(["many"], %{}) == {:validation_failure, :too_many_args} assert @command.validate(["too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag key: @key, pattern: @pattern, value: @value, vhost: @vhost test "run: a well-formed, host-specific command returns list of policies", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_operator_policy(context[:vhost], context[:key], context[:pattern], @value) + @command.run([], vhost_opts) |> assert_operator_policy_list(context) end @@ -75,8 +79,8 @@ defmodule ListOperatorPoliciesCommandTest do @tag key: @key, pattern: @pattern, value: @value, vhost: @root test "run: a well-formed command with no vhost runs against the default one", context do - set_operator_policy("/", context[:key], context[:pattern], @value) + on_exit(fn -> clear_operator_policy("/", context[:key]) end) @@ -96,25 +100,40 @@ defmodule ListOperatorPoliciesCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag vhost: @vhost test "run: when multiple policies exist in the vhost, returns them all", context do policies = [ - %{vhost: @vhost, name: "some-policy", pattern: "foo", definition: "{\"message-ttl\":10}", 'apply-to': "all", priority: 0}, - %{vhost: @vhost, name: "other-policy", pattern: "bar", definition: "{\"expires\":20}", 'apply-to': "all", priority: 0} + %{ + vhost: @vhost, + name: "some-policy", + pattern: "foo", + definition: "{\"message-ttl\":10}", + "apply-to": "all", + priority: 0 + }, + %{ + vhost: @vhost, + name: "other-policy", + pattern: "bar", + definition: "{\"expires\":20}", + "apply-to": "all", + priority: 0 + } ] + policies - |> Enum.map( - fn(%{name: name, pattern: pattern, definition: value}) -> - set_operator_policy(context[:vhost], name, pattern, value) - on_exit(fn -> - clear_operator_policy(context[:vhost], name) - end) - end) + |> Enum.map(fn %{name: name, pattern: pattern, definition: value} -> + set_operator_policy(context[:vhost], name, pattern, value) + + on_exit(fn -> + clear_operator_policy(context[:vhost], name) + end) + end) pols = for policy <- @command.run([], context[:opts]), do: Map.new(policy) @@ -125,18 +144,22 @@ defmodule ListOperatorPoliciesCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([], vhost_opts) - =~ ~r/Listing operator policy overrides for vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([], vhost_opts) =~ + ~r/Listing operator policy overrides for vhost \"#{context[:vhost]}\" \.\.\./ end # Checks each element of the first policy against the expected context values defp assert_operator_policy_list(policies, context) do [policy] = policies - assert MapSet.new(policy) == MapSet.new([name: context[:key], - pattern: context[:pattern], - definition: context[:value], - vhost: context[:vhost], - priority: context[:opts][:priority], - "apply-to": context[:opts][:apply_to]]) + + assert MapSet.new(policy) == + MapSet.new( + name: context[:key], + pattern: context[:pattern], + definition: context[:value], + vhost: context[:vhost], + priority: context[:opts][:priority], + "apply-to": context[:opts][:apply_to] + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_parameters_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_parameters_command_test.exs index f42e55353ac5..19ea2df4ba4b 100644 --- a/deps/rabbitmq_cli/test/ctl/list_parameters_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_parameters_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListParametersCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule ListParametersCommandTest do @command RabbitMQ.CLI.Ctl.Commands.ListParametersCommand @vhost "test1" - @root "/" + @root "/" @component_name "federation-upstream" @key "reconnect-delay" @value "{\"uri\":\"amqp://\"}" @@ -22,29 +21,31 @@ defmodule ListParametersCommandTest do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home} + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home + } set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], :online, node, opts) - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit(fn -> set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -52,13 +53,14 @@ defmodule ListParametersCommandTest do setup context do on_exit(fn -> - clear_parameter context[:vhost], context[:component_name], context[:key] + clear_parameter(context[:vhost], context[:component_name], context[:key]) end) + { :ok, opts: %{ node: get_rabbit_hostname(), - timeout: (context[:timeout] || :infinity), + timeout: context[:timeout] || :infinity, vhost: context[:vhost] } } @@ -66,18 +68,21 @@ defmodule ListParametersCommandTest do test "merge_defaults: defaults can be overridden" do assert @command.merge_defaults([], %{}) == {[], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {[], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {[], %{vhost: "non_default", table_headers: true}} end test "validate: wrong number of arguments leads to an arg count error" do - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag component_name: @component_name, key: @key, value: @value, vhost: @vhost test "run: a well-formed, host-specific command returns list of parameters", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_parameter(context[:vhost], context[:component_name], context[:key], @value) + @command.run([], vhost_opts) |> assert_parameter_list(context) end @@ -90,8 +95,8 @@ defmodule ListParametersCommandTest do @tag component_name: @component_name, key: @key, value: @value, vhost: @root test "run: a well-formed command with no vhost runs against the default", context do - set_parameter("/", context[:component_name], context[:key], @value) + on_exit(fn -> clear_parameter("/", context[:component_name], context[:key]) end) @@ -111,9 +116,9 @@ defmodule ListParametersCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag vhost: @vhost @@ -122,14 +127,15 @@ defmodule ListParametersCommandTest do %{component: "federation-upstream", name: "my-upstream", value: "{\"uri\":\"amqp://\"}"}, %{component: "exchange-delete-in-progress", name: "my-key", value: "{\"foo\":\"bar\"}"} ] + parameters - |> Enum.map( - fn(%{component: component, name: name, value: value}) -> - set_parameter(context[:vhost], component, name, value) - on_exit(fn -> - clear_parameter(context[:vhost], component, name) - end) - end) + |> Enum.map(fn %{component: component, name: name, value: value} -> + set_parameter(context[:vhost], component, name, value) + + on_exit(fn -> + clear_parameter(context[:vhost], component, name) + end) + end) params = for param <- @command.run([], context[:opts]), do: Map.new(param) @@ -140,15 +146,19 @@ defmodule ListParametersCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([], vhost_opts) - =~ ~r/Listing runtime parameters for vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([], vhost_opts) =~ + ~r/Listing runtime parameters for vhost \"#{context[:vhost]}\" \.\.\./ end # Checks each element of the first parameter against the expected context values defp assert_parameter_list(params, context) do [param] = params - assert MapSet.new(param) == MapSet.new([component: context[:component_name], - name: context[:key], - value: context[:value]]) + + assert MapSet.new(param) == + MapSet.new( + component: context[:component_name], + name: context[:key], + value: context[:value] + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_permissions_command_test.exs index eda8f001afb9..2b416050f0c6 100644 --- a/deps/rabbitmq_cli/test/ctl/list_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -13,18 +12,18 @@ defmodule ListPermissionsCommandTest do @vhost "test1" @user "guest" - @root "/" + @root "/" @default_timeout :infinity @default_options %{vhost: "/", table_headers: true} setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost - set_permissions @user, @vhost, ["^guest-.*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, ["^guest-.*", ".*", ".*"]) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -47,8 +46,9 @@ defmodule ListPermissionsCommandTest do test "merge_defaults: defaults can be overridden" do assert @command.merge_defaults([], %{}) == {[], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {[], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {[], %{vhost: "non_default", table_headers: true}} end test "validate: invalid parameters yield an arg count error" do @@ -64,29 +64,31 @@ defmodule ListPermissionsCommandTest do @tag test_timeout: @default_timeout, vhost: @vhost test "run: specifying a vhost returns the targeted vhost permissions", context do assert @command.run( - [], - Map.merge(context[:opts], %{vhost: @vhost}) - ) == [[user: "guest", configure: "^guest-.*", write: ".*", read: ".*"]] + [], + Map.merge(context[:opts], %{vhost: @vhost}) + ) == [[user: "guest", configure: "^guest-.*", write: ".*", read: ".*"]] end @tag test_timeout: 30000 test "run: sufficiently long timeouts don't interfere with results", context do results = @command.run([], context[:opts]) - Enum.all?([[user: "guest", configure: ".*", write: ".*", read: ".*"]], fn(perm) -> - Enum.find(results, fn(found) -> found == perm end) + + Enum.all?([[user: "guest", configure: ".*", write: ".*", read: ".*"]], fn perm -> + Enum.find(results, fn found -> found == perm end) end) end @tag test_timeout: 0 test "run: timeout causes command to return a bad RPC", context do assert @command.run([], context[:opts]) == - {:badrpc, :timeout} + {:badrpc, :timeout} end @tag vhost: @root test "banner", context do ctx = Map.merge(context[:opts], %{vhost: @vhost}) - assert @command.banner([], ctx ) - =~ ~r/Listing permissions for vhost \"#{Regex.escape(ctx[:vhost])}\" \.\.\./ + + assert @command.banner([], ctx) =~ + ~r/Listing permissions for vhost \"#{Regex.escape(ctx[:vhost])}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/list_policies_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_policies_command_test.exs index 49ef6ee856b8..8d361c4d7dcb 100644 --- a/deps/rabbitmq_cli/test/ctl/list_policies_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_policies_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListPoliciesCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule ListPoliciesCommandTest do @command RabbitMQ.CLI.Ctl.Commands.ListPoliciesCommand @vhost "test1" - @default_vhost "/" + @default_vhost "/" @key "federate" @pattern "^fed\." @value "{\"federation-upstream-set\":\"all\"}" @@ -22,27 +21,26 @@ defmodule ListPoliciesCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - on_exit(fn -> - clear_policy context[:vhost], context[:key] + clear_policy(context[:vhost], context[:key]) end) { :ok, opts: %{ node: get_rabbit_hostname(), - timeout: (context[:timeout] || :infinity), + timeout: context[:timeout] || :infinity, vhost: context[:vhost], apply_to: @apply_to, priority: 0 @@ -52,20 +50,24 @@ defmodule ListPoliciesCommandTest do test "merge_defaults: default vhost is '/'" do assert @command.merge_defaults([], %{}) == {[], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {[], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {[], %{vhost: "non_default", table_headers: true}} end test "validate: providing too many arguments fails validation" do assert @command.validate(["many"], %{}) == {:validation_failure, :too_many_args} assert @command.validate(["too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag key: @key, pattern: @pattern, value: @value, vhost: @vhost test "run: a well-formed, host-specific command returns list of policies", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) set_policy(context[:vhost], context[:key], context[:pattern], @value) + @command.run([], vhost_opts) |> assert_policy_list(context) end @@ -79,6 +81,7 @@ defmodule ListPoliciesCommandTest do @tag key: @key, pattern: @pattern, value: @value, vhost: @default_vhost test "run: a well-formed command with no vhost runs against the default one", context do set_policy("/", context[:key], context[:pattern], @value) + on_exit(fn -> clear_policy("/", context[:key]) end) @@ -98,25 +101,40 @@ defmodule ListPoliciesCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag vhost: @vhost test "run: when multiple policies exist in the vhost, returns them all", context do policies = [ - %{vhost: @vhost, name: "some-policy", pattern: "foo", definition: "{\"federation-upstream-set\":\"all\"}", 'apply-to': "all", priority: 0}, - %{vhost: @vhost, name: "other-policy", pattern: "bar", definition: "{\"ha-mode\":\"all\"}", 'apply-to': "all", priority: 0} + %{ + vhost: @vhost, + name: "some-policy", + pattern: "foo", + definition: "{\"federation-upstream-set\":\"all\"}", + "apply-to": "all", + priority: 0 + }, + %{ + vhost: @vhost, + name: "other-policy", + pattern: "bar", + definition: "{\"ha-mode\":\"all\"}", + "apply-to": "all", + priority: 0 + } ] + policies - |> Enum.map( - fn(%{name: name, pattern: pattern, definition: value}) -> - set_policy(context[:vhost], name, pattern, value) - on_exit(fn -> - clear_policy(context[:vhost], name) - end) - end) + |> Enum.map(fn %{name: name, pattern: pattern, definition: value} -> + set_policy(context[:vhost], name, pattern, value) + + on_exit(fn -> + clear_policy(context[:vhost], name) + end) + end) pols = for policy <- @command.run([], context[:opts]), do: Map.new(policy) @@ -127,18 +145,22 @@ defmodule ListPoliciesCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([], vhost_opts) - =~ ~r/Listing policies for vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([], vhost_opts) =~ + ~r/Listing policies for vhost \"#{context[:vhost]}\" \.\.\./ end # Checks each element of the first policy against the expected context values defp assert_policy_list(policies, context) do [policy | _] = policies - assert MapSet.new(policy) == MapSet.new([name: context[:key], - pattern: context[:pattern], - definition: context[:value], - vhost: context[:vhost], - priority: context[:opts][:priority], - "apply-to": context[:opts][:apply_to]]) + + assert MapSet.new(policy) == + MapSet.new( + name: context[:key], + pattern: context[:pattern], + definition: context[:value], + vhost: context[:vhost], + priority: context[:opts][:priority], + "apply-to": context[:opts][:apply_to] + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/list_queues_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_queues_command_test.exs index a6635c79339f..d753d77961c9 100644 --- a/deps/rabbitmq_cli/test/ctl/list_queues_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_queues_command_test.exs @@ -24,11 +24,13 @@ defmodule ListQueuesCommandTest do end setup context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) + on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) + { :ok, opts: %{ @@ -49,40 +51,54 @@ defmodule ListQueuesCommandTest do test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "messages"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["name", "oink", "messages"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.0, "Some queue(s) are unresponsive, use list_unresponsive_queues command."}}] + [ + {:badrpc, + {:timeout, 0.0, + "Some queue(s) are unresponsive, use list_unresponsive_queues command."}} + ] end @tag test_timeout: 1 - test "run: command timeout (several thousands queues in 1ms) return badrpc with timeout value in seconds", context do + test "run: command timeout (several thousands queues in 1ms) return badrpc with timeout value in seconds", + context do # we assume it will take longer than 1 ms to list thousands of queues n = 5000 + for i <- 1..n do - declare_queue("test_queue_" <> Integer.to_string(i), @vhost) + declare_queue("test_queue_" <> Integer.to_string(i), @vhost) end + assert run_command_to_list(@command, [["name"], context[:opts]]) == - [{:badrpc, {:timeout, 0.001, "Some queue(s) are unresponsive, use list_unresponsive_queues command."}}] + [ + {:badrpc, + {:timeout, 0.001, + "Some queue(s) are unresponsive, use list_unresponsive_queues command."}} + ] + for i <- 1..n do - delete_queue("test_queue_" <> Integer.to_string(i), @vhost) + delete_queue("test_queue_" <> Integer.to_string(i), @vhost) end end @@ -92,18 +108,22 @@ defmodule ListQueuesCommandTest do publish_messages(@vhost, "test_queue_1", 3) declare_queue("test_queue_2", @vhost) publish_messages(@vhost, "test_queue_2", 1) - assert Keyword.equal?(run_command_to_list(@command, [["name", "messages"], context[:opts]]), - [[name: "test_queue_1", messages: 3], - [name: "test_queue_2", messages: 1]]) + + assert Keyword.equal?( + run_command_to_list(@command, [["name", "messages"], context[:opts]]), + [[name: "test_queue_1", messages: 3], [name: "test_queue_2", messages: 1]] + ) end @tag test_timeout: 5000 test "run: info keys filter single key", context do declare_queue("test_queue_1", @vhost) declare_queue("test_queue_2", @vhost) - assert Keyword.equal?(run_command_to_list(@command, [["name"], context[:opts]]), - [[name: "test_queue_1"], - [name: "test_queue_2"]]) + + assert Keyword.equal?( + run_command_to_list(@command, [["name"], context[:opts]]), + [[name: "test_queue_1"], [name: "test_queue_2"]] + ) end @tag test_timeout: 5000 @@ -112,10 +132,17 @@ defmodule ListQueuesCommandTest do publish_messages(@vhost, "durable_queue", 3) declare_queue("auto_delete_queue", @vhost, false, true) publish_messages(@vhost, "auto_delete_queue", 1) + assert Keyword.equal?( - run_command_to_list(@command, [["name", "messages", "durable", "auto_delete"], context[:opts]]), - [[name: "durable_queue", messages: 3, durable: true, auto_delete: false], - [name: "auto_delete_queue", messages: 1, durable: false, auto_delete: true]]) + run_command_to_list(@command, [ + ["name", "messages", "durable", "auto_delete"], + context[:opts] + ]), + [ + [name: "durable_queue", messages: 3, durable: true, auto_delete: false], + [name: "auto_delete_queue", messages: 1, durable: false, auto_delete: true] + ] + ) end @tag test_timeout: 5000 @@ -124,22 +151,33 @@ defmodule ListQueuesCommandTest do publish_messages(@vhost, "durable_queue", 3) declare_queue("auto_delete_queue", @vhost, false, true) publish_messages(@vhost, "auto_delete_queue", 1) + assert Keyword.equal?( - run_command_to_list(@command, [["messages", "durable", "name", "auto_delete"], context[:opts]]), - [[messages: 3, durable: true, name: "durable_queue", auto_delete: false], - [messages: 1, durable: false, name: "auto_delete_queue", auto_delete: true]]) + run_command_to_list(@command, [ + ["messages", "durable", "name", "auto_delete"], + context[:opts] + ]), + [ + [messages: 3, durable: true, name: "durable_queue", auto_delete: false], + [messages: 1, durable: false, name: "auto_delete_queue", auto_delete: true] + ] + ) end @tag test_timeout: 5000 test "run: specifying a vhost returns the targeted vhost queues", context do other_vhost = "other_vhost" - add_vhost other_vhost + add_vhost(other_vhost) + on_exit(fn -> - delete_vhost other_vhost + delete_vhost(other_vhost) end) + declare_queue("test_queue_1", @vhost) declare_queue("test_queue_2", other_vhost) assert run_command_to_list(@command, [["name"], context[:opts]]) == [[name: "test_queue_1"]] - assert run_command_to_list(@command, [["name"], %{context[:opts] | :vhost => other_vhost}]) == [[name: "test_queue_2"]] + + assert run_command_to_list(@command, [["name"], %{context[:opts] | :vhost => other_vhost}]) == + [[name: "test_queue_2"]] end end diff --git a/deps/rabbitmq_cli/test/ctl/list_topic_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_topic_permissions_command_test.exs index 8de1f2536aac..54d6a6c93630 100644 --- a/deps/rabbitmq_cli/test/ctl/list_topic_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_topic_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListTopicPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -14,7 +13,7 @@ defmodule ListTopicPermissionsCommandTest do @vhost "test1" @user "user1" @password "password" - @root "/" + @root "/" @default_timeout :infinity @default_options %{vhost: "/", table_headers: true} @@ -29,7 +28,7 @@ defmodule ListTopicPermissionsCommandTest do on_exit([], fn -> clear_topic_permissions(@user, @vhost) delete_user(@user) - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -52,8 +51,9 @@ defmodule ListTopicPermissionsCommandTest do test "merge_defaults: defaults can be overridden" do assert @command.merge_defaults([], %{}) == {[], @default_options} - assert @command.merge_defaults([], %{vhost: "non_default"}) == {[], %{vhost: "non_default", - table_headers: true}} + + assert @command.merge_defaults([], %{vhost: "non_default"}) == + {[], %{vhost: "non_default", table_headers: true}} end test "validate: does not expect any parameter" do @@ -70,16 +70,18 @@ defmodule ListTopicPermissionsCommandTest do test "run: specifying a vhost returns the topic permissions for the targeted vhost", context do permissions = @command.run([], Map.merge(context[:opts], %{vhost: @vhost})) assert Enum.count(permissions) == 2 + assert Enum.sort(permissions) == [ - [user: @user, exchange: "amq.topic", write: "^a", read: "^b"], - [user: @user, exchange: "topic1", write: "^a", read: "^b"] - ] + [user: @user, exchange: "amq.topic", write: "^a", read: "^b"], + [user: @user, exchange: "topic1", write: "^a", read: "^b"] + ] end @tag vhost: @root test "banner", context do ctx = Map.merge(context[:opts], %{vhost: @vhost}) - assert @command.banner([], ctx ) - =~ ~r/Listing topic permissions for vhost \"#{Regex.escape(ctx[:vhost])}\" \.\.\./ + + assert @command.banner([], ctx) =~ + ~r/Listing topic permissions for vhost \"#{Regex.escape(ctx[:vhost])}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/list_user_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_user_limits_command_test.exs index 7b0370f94023..4b15da293942 100644 --- a/deps/rabbitmq_cli/test/ctl/list_user_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_user_limits_command_test.exs @@ -55,21 +55,24 @@ defmodule ListUserLimitsCommandTest do end test "run: a well-formed user specific command returns an empty json object if there are no limits" do - assert @command.run([], %{node: get_rabbit_hostname(), - user: @user}) == "{}" + assert @command.run([], %{node: get_rabbit_hostname(), user: @user}) == "{}" end test "run: list limits for all users", context do add_user(@user1, @password1) - on_exit(fn() -> + + on_exit(fn -> delete_user(@user1) end) + set_user_limits(@user, @connection_limit_defn) set_user_limits(@user1, @channel_limit_defn) assert Enum.sort(@command.run([], context[:opts])) == - Enum.sort([[user: @user, limits: @connection_limit_defn], - [user: @user1, limits: @channel_limit_defn]]) + Enum.sort([ + [user: @user, limits: @connection_limit_defn], + [user: @user1, limits: @channel_limit_defn] + ]) end test "run: list limits for a single user", context do @@ -77,7 +80,7 @@ defmodule ListUserLimitsCommandTest do set_user_limits(@user, @connection_limit_defn) assert @command.run([], user_opts) == - [[user: @user, limits: @connection_limit_defn]] + [[user: @user, limits: @connection_limit_defn]] end test "run: an unreachable node throws a badrpc" do @@ -90,14 +93,15 @@ defmodule ListUserLimitsCommandTest do test "run: providing a non-existent user reports an error", _context do s = "non-existent-user" - assert @command.run([], %{node: get_rabbit_hostname(), - user: s}) == {:error, {:no_such_user, s}} + assert @command.run([], %{node: get_rabbit_hostname(), user: s}) == + {:error, {:no_such_user, s}} end test "banner", context do - assert @command.banner([], %{user: context[:user]}) - == "Listing limits for user \"#{context[:user]}\" ..." - assert @command.banner([], %{global: true}) - == "Listing limits for all users ..." + assert @command.banner([], %{user: context[:user]}) == + "Listing limits for user \"#{context[:user]}\" ..." + + assert @command.banner([], %{global: true}) == + "Listing limits for all users ..." end end diff --git a/deps/rabbitmq_cli/test/ctl/list_user_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_user_permissions_command_test.exs index ddd44c0e0129..3fa102f3ecb1 100644 --- a/deps/rabbitmq_cli/test/ctl/list_user_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_user_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListUserPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -20,10 +19,10 @@ defmodule ListUserPermissionsCommandTest do setup context do default_result = [ [ - {:vhost,<<"/">>}, - {:configure,<<".*">>}, - {:write,<<".*">>}, - {:read,<<".*">>} + {:vhost, <<"/">>}, + {:configure, <<".*">>}, + {:write, <<".*">>}, + {:read, <<".*">>} ] ] @@ -38,30 +37,33 @@ defmodule ListUserPermissionsCommandTest do } end -## -------------------------------- Usage ------------------------------------- + ## -------------------------------- Usage ------------------------------------- test "validate: wrong number of arguments results in an arg count error" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["guest", "extra"], %{}) == {:validation_failure, :too_many_args} end -## ------------------------------- Username ----------------------------------- + ## ------------------------------- Username ----------------------------------- @tag test_timeout: :infinity, username: "guest" test "run: valid user returns a list of permissions", context do results = @command.run([context[:username]], context[:opts]) - assert Enum.all?(context[:result], fn(perm) -> - Enum.find(results, fn(found) -> found == perm end) - end) + + assert Enum.all?(context[:result], fn perm -> + Enum.find(results, fn found -> found == perm end) + end) end @tag test_timeout: :infinity, username: "interloper" test "run: invalid user returns a no-such-user error", context do assert @command.run( - [context[:username]], context[:opts]) == context[:no_such_user] + [context[:username]], + context[:opts] + ) == context[:no_such_user] end -## --------------------------------- Flags ------------------------------------ + ## --------------------------------- Flags ------------------------------------ test "run: unreachable RabbitMQ node returns a badrpc" do assert match?({:badrpc, _}, @command.run(["guest"], %{node: :jake@thedog, timeout: 200})) @@ -70,22 +72,23 @@ defmodule ListUserPermissionsCommandTest do @tag test_timeout: 30000, username: "guest" test "run: long user-defined timeout doesn't interfere with operation", context do results = @command.run([context[:username]], context[:opts]) - Enum.all?(context[:result], fn(perm) -> - Enum.find(results, fn(found) -> found == perm end) + + Enum.all?(context[:result], fn perm -> + Enum.find(results, fn found -> found == perm end) end) end @tag test_timeout: 0, username: "guest" test "run: timeout causes command to return a bad RPC", context do assert @command.run( - [context[:username]], - context[:opts] - ) == context[:timeout] + [context[:username]], + context[:opts] + ) == context[:timeout] end @tag test_timeout: :infinity test "banner", context do - assert @command.banner( [context[:username]], context[:opts]) - =~ ~r/Listing permissions for user \"#{context[:username]}\" \.\.\./ + assert @command.banner([context[:username]], context[:opts]) =~ + ~r/Listing permissions for user \"#{context[:username]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/list_user_topic_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_user_topic_permissions_command_test.exs index edf935de771b..9edaafdff68f 100644 --- a/deps/rabbitmq_cli/test/ctl/list_user_topic_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_user_topic_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListUserTopicPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -35,14 +34,14 @@ defmodule ListUserTopicPermissionsCommandTest do } end -## -------------------------------- Usage ------------------------------------- + ## -------------------------------- Usage ------------------------------------- test "validate: expect username argument" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["guest", "extra"], %{}) == {:validation_failure, :too_many_args} end -## ------------------------------- Username ----------------------------------- + ## ------------------------------- Username ----------------------------------- @tag test_timeout: :infinity, username: "guest" test "run: valid user returns a list of topic permissions", context do @@ -53,10 +52,12 @@ defmodule ListUserTopicPermissionsCommandTest do @tag test_timeout: :infinity, username: "interloper" test "run: invalid user returns a no-such-user error", context do assert @command.run( - [context[:username]], context[:opts]) == context[:no_such_user] + [context[:username]], + context[:opts] + ) == context[:no_such_user] end -## --------------------------------- Flags ------------------------------------ + ## --------------------------------- Flags ------------------------------------ test "run: throws a badrpc when instructed to contact an unreachable RabbitMQ node" do opts = %{node: :jake@thedog, timeout: 200} @@ -66,7 +67,7 @@ defmodule ListUserTopicPermissionsCommandTest do @tag test_timeout: :infinity test "banner", context do - assert @command.banner( [context[:username]], context[:opts]) - =~ ~r/Listing topic permissions for user \"#{context[:username]}\" \.\.\./ + assert @command.banner([context[:username]], context[:opts]) =~ + ~r/Listing topic permissions for user \"#{context[:username]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/list_users_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_users_command_test.exs index bcfdb84b2b18..01dbc855170f 100644 --- a/deps/rabbitmq_cli/test/ctl/list_users_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_users_command_test.exs @@ -4,31 +4,30 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListUsersCommandTest do use ExUnit.Case, async: false import TestHelper @command RabbitMQ.CLI.Ctl.Commands.ListUsersCommand - @user "user1" + @user "user1" @password "password" - @guest "guest" + @guest "guest" setup_all do RabbitMQ.CLI.Core.Distribution.start() std_result = [ - [{:user,@guest},{:tags,[:administrator]}], - [{:user,@user},{:tags,[]}] + [{:user, @guest}, {:tags, [:administrator]}], + [{:user, @user}, {:tags, []}] ] {:ok, std_result: std_result} end setup context do - add_user @user, @password - on_exit([], fn -> delete_user @user end) + add_user(@user, @password) + on_exit([], fn -> delete_user(@user) end) {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout]}} end @@ -41,9 +40,9 @@ defmodule ListUsersCommandTest do test "run: On a successful query, return an array of lists of tuples", context do matches_found = @command.run([], context[:opts]) - assert Enum.all?(context[:std_result], fn(user) -> - Enum.find(matches_found, fn(found) -> found == user end) - end) + assert Enum.all?(context[:std_result], fn user -> + Enum.find(matches_found, fn found -> found == user end) + end) end test "run: On an invalid rabbitmq node, return a bad rpc" do @@ -55,20 +54,20 @@ defmodule ListUsersCommandTest do # checks to ensure that all expected users are in the results matches_found = @command.run([], context[:opts]) - assert Enum.all?(context[:std_result], fn(user) -> - Enum.find(matches_found, fn(found) -> found == user end) - end) + assert Enum.all?(context[:std_result], fn user -> + Enum.find(matches_found, fn found -> found == user end) + end) end @tag test_timeout: 0 test "run: timeout causes command to return a bad RPC", context do assert @command.run([], context[:opts]) == - {:badrpc, :timeout} + {:badrpc, :timeout} end @tag test_timeout: :infinity test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Listing users \.\.\./ + assert @command.banner([], context[:opts]) =~ + ~r/Listing users \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/list_vhost_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_vhost_limits_command_test.exs index f07d40672ad7..26786d37c624 100644 --- a/deps/rabbitmq_cli/test/ctl/list_vhost_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_vhost_limits_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListVhostLimitsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -19,10 +18,10 @@ defmodule ListVhostLimitsCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok @@ -48,36 +47,46 @@ defmodule ListVhostLimitsCommandTest do end test "merge_defaults: does not change defined vhost" do - assert match?({[], %{vhost: "test_vhost"}}, @command.merge_defaults([], %{vhost: "test_vhost"})) + assert match?( + {[], %{vhost: "test_vhost"}}, + @command.merge_defaults([], %{vhost: "test_vhost"}) + ) end test "validate: providing arguments fails validation" do assert @command.validate(["many"], %{}) == {:validation_failure, :too_many_args} assert @command.validate(["too", "many"], %{}) == {:validation_failure, :too_many_args} assert @command.validate(["is", "too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end test "run: a well-formed command returns an empty list if there are no limits", context do assert @command.run([], context[:opts]) == [] end - test "run: a well-formed vhost specific command returns an empty list if there are no limits", context do + test "run: a well-formed vhost specific command returns an empty list if there are no limits", + context do vhost_opts = Map.put(context[:opts], :vhost, @vhost) assert @command.run([], vhost_opts) == [] end test "run: list limits for all vhosts", context do add_vhost(@vhost1) - on_exit(fn() -> + + on_exit(fn -> delete_vhost(@vhost1) end) + set_vhost_limits(@vhost, @connection_limit_defn) set_vhost_limits(@vhost1, @queue_limit_defn) assert Enum.sort(@command.run([], context[:opts])) == - Enum.sort([[vhost: @vhost, limits: @connection_limit_defn], - [vhost: @vhost1, limits: @queue_limit_defn]]) + Enum.sort([ + [vhost: @vhost, limits: @connection_limit_defn], + [vhost: @vhost1, limits: @queue_limit_defn] + ]) end test "run: list limits for a single vhost", context do @@ -85,7 +94,7 @@ defmodule ListVhostLimitsCommandTest do set_vhost_limits(@vhost, @connection_limit_defn) assert @command.run([], vhost_opts) == - [[vhost: @vhost, limits: @connection_limit_defn]] + [[vhost: @vhost, limits: @connection_limit_defn]] end test "run: an unreachable node throws a badrpc" do @@ -98,14 +107,15 @@ defmodule ListVhostLimitsCommandTest do test "run: providing a non-existent vhost reports an error", _context do s = "non-existent-vhost-a9sd89" - assert @command.run([], %{node: get_rabbit_hostname(), - vhost: s}) == {:error, {:no_such_vhost, s}} + assert @command.run([], %{node: get_rabbit_hostname(), vhost: s}) == + {:error, {:no_such_vhost, s}} end test "banner", context do - assert @command.banner([], %{vhost: context[:vhost]}) - == "Listing limits for vhost \"#{context[:vhost]}\" ..." - assert @command.banner([], %{global: true}) - == "Listing limits for all vhosts ..." + assert @command.banner([], %{vhost: context[:vhost]}) == + "Listing limits for vhost \"#{context[:vhost]}\" ..." + + assert @command.banner([], %{global: true}) == + "Listing limits for all vhosts ..." end end diff --git a/deps/rabbitmq_cli/test/ctl/list_vhosts_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_vhosts_command_test.exs index 76f46af422d6..21f2cced79fe 100644 --- a/deps/rabbitmq_cli/test/ctl/list_vhosts_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_vhosts_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ListVhostsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -13,18 +12,18 @@ defmodule ListVhostsCommandTest do @vhost1 "test1" @vhost2 "test2" - @root "/" + @root "/" setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost1 - add_vhost @vhost2 - trace_off @root + add_vhost(@vhost1) + add_vhost(@vhost2) + trace_off(@root) on_exit([], fn -> - delete_vhost @vhost1 - delete_vhost @vhost2 + delete_vhost(@vhost1) + delete_vhost(@vhost2) end) name_result = [ @@ -73,21 +72,23 @@ defmodule ListVhostsCommandTest do test "validate: return bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "tracing"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["name", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["name", "oink", "tracing"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end test "run: on a bad RabbitMQ node, return a badrpc" do @@ -100,57 +101,63 @@ defmodule ListVhostsCommandTest do test "run: with the name tag, print just the names", context do # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["name"], context[:opts]) - assert Enum.all?(context[:name_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:name_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) end @tag test_timeout: :infinity test "run: with the tracing tag, print just say if tracing is on", context do # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["tracing"], context[:opts]) - assert Enum.all?(context[:tracing_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:tracing_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) end @tag test_timeout: :infinity test "run: with name and tracing keys, print both", context do # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["name", "tracing"], context[:opts]) - assert Enum.all?(context[:full_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:full_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["tracing", "name"], context[:opts]) - assert Enum.all?(context[:transposed_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:transposed_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) end @tag test_timeout: :infinity test "run: duplicate args do not produce duplicate entries", context do # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["name", "name"], context[:opts]) - assert Enum.all?(context[:name_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:name_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) end @tag test_timeout: 30000 test "run: sufficiently long timeouts don't interfere with results", context do # checks to ensure that all expected vhosts are in the results matches_found = @command.run(["name", "tracing"], context[:opts]) - assert Enum.all?(context[:full_result], fn(vhost) -> - Enum.find(matches_found, fn(found) -> found == vhost end) - end) + + assert Enum.all?(context[:full_result], fn vhost -> + Enum.find(matches_found, fn found -> found == vhost end) + end) end @tag test_timeout: 0, username: "guest" test "run: timeout causes command to return a bad RPC", context do assert @command.run(["name", "tracing"], context[:opts]) == - {:badrpc, :timeout} + {:badrpc, :timeout} end @tag test_timeout: :infinity diff --git a/deps/rabbitmq_cli/test/ctl/node_health_check_command_test.exs b/deps/rabbitmq_cli/test/ctl/node_health_check_command_test.exs index 12ff786bfba6..3aac2d30b3ac 100644 --- a/deps/rabbitmq_cli/test/ctl/node_health_check_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/node_health_check_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule NodeHealthCheckCommandTest do use ExUnit.Case, async: false import TestHelper diff --git a/deps/rabbitmq_cli/test/ctl/ping_command_test.exs b/deps/rabbitmq_cli/test/ctl/ping_command_test.exs index 347013a4a833..817c85ae31a4 100644 --- a/deps/rabbitmq_cli/test/ctl/ping_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/ping_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule PingCommandTest do use ExUnit.Case, async: false import TestHelper @@ -48,7 +47,7 @@ defmodule PingCommandTest do end test "banner", context do - banner = @command.banner([], context[:opts]) + banner = @command.banner([], context[:opts]) assert banner =~ ~r/Will ping/ assert banner =~ ~r/#{get_rabbit_hostname()}/ diff --git a/deps/rabbitmq_cli/test/ctl/purge_queue_command_test.exs b/deps/rabbitmq_cli/test/ctl/purge_queue_command_test.exs index 9891175f15fe..bb90ba6f1a66 100644 --- a/deps/rabbitmq_cli/test/ctl/purge_queue_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/purge_queue_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule PurgeQueueCommandTest do use ExUnit.Case, async: false import TestHelper @@ -20,11 +19,12 @@ defmodule PurgeQueueCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - vhost: @vhost, - timeout: context[:test_timeout] - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + vhost: @vhost, + timeout: context[:test_timeout] + }} end test "merge_defaults: defaults can be overridden" do @@ -34,8 +34,8 @@ defmodule PurgeQueueCommandTest do @tag test_timeout: 30000 test "request to an existent queue on active node succeeds", context do - add_vhost @vhost - set_permissions @user, @vhost, [".*", ".*", ".*"] + add_vhost(@vhost) + set_permissions(@user, @vhost, [".*", ".*", ".*"]) on_exit(context, fn -> delete_vhost(@vhost) end) q = "foo" @@ -71,7 +71,8 @@ defmodule PurgeQueueCommandTest do end test "validate: with extra arguments returns an arg count error" do - assert @command.validate(["queue-name", "extra"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["queue-name", "extra"], %{}) == + {:validation_failure, :too_many_args} end test "validate: with no arguments returns an arg count error" do @@ -83,6 +84,7 @@ defmodule PurgeQueueCommandTest do end test "banner informs that vhost's queue is purged" do - assert @command.banner(["my-q"], %{vhost: "/foo"}) == "Purging queue 'my-q' in vhost '/foo' ..." + assert @command.banner(["my-q"], %{vhost: "/foo"}) == + "Purging queue 'my-q' in vhost '/foo' ..." end end diff --git a/deps/rabbitmq_cli/test/ctl/report_command_test.exs b/deps/rabbitmq_cli/test/ctl/report_command_test.exs index f207ab8c2b9b..5939c92e2f35 100644 --- a/deps/rabbitmq_cli/test/ctl/report_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/report_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ReportTest do use ExUnit.Case, async: false import TestHelper @@ -23,11 +22,11 @@ defmodule ReportTest do test "validate: with extra arguments, status returns an arg count error", context do assert @command.validate(["extra"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: report request to a reachable node succeeds", context do - output = @command.run([], context[:opts]) |> Enum.to_list + output = @command.run([], context[:opts]) |> Enum.to_list() assert_stream_without_errors(output) end @@ -38,7 +37,7 @@ defmodule ReportTest do end test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Reporting server status of node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Reporting server status of node #{get_rabbit_hostname()}/ end end diff --git a/deps/rabbitmq_cli/test/ctl/reset_command_test.exs b/deps/rabbitmq_cli/test/ctl/reset_command_test.exs index 8bded4737722..c5e590ca1d8a 100644 --- a/deps/rabbitmq_cli/test/ctl/reset_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/reset_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ResetCommandTest do use ExUnit.Case, async: false import TestHelper @@ -32,21 +31,21 @@ defmodule ResetCommandTest do end test "run: reset request to an active node with a stopped rabbit app succeeds", context do - add_vhost "some_vhost" - #ensure the vhost really does exist - assert vhost_exists? "some_vhost" + add_vhost("some_vhost") + # ensure the vhost really does exist + assert vhost_exists?("some_vhost") stop_rabbitmq_app() assert :ok == @command.run([], context[:opts]) start_rabbitmq_app() - #check that the created vhost no longer exists + # check that the created vhost no longer exists assert match?([_], list_vhosts()) end test "run: reset request to an active node with a running rabbit app fails", context do - add_vhost "some_vhost" - assert vhost_exists? "some_vhost" + add_vhost("some_vhost") + assert vhost_exists?("some_vhost") assert match?({:error, :mnesia_unexpectedly_running}, @command.run([], context[:opts])) - assert vhost_exists? "some_vhost" + assert vhost_exists?("some_vhost") end test "run: request to a non-existent node returns a badrpc" do @@ -59,10 +58,11 @@ defmodule ResetCommandTest do end test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, - "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + assert match?( + {:error, ^exit_code, "Mnesia is still running on node " <> _}, + @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/restart_vhost_command_test.exs b/deps/rabbitmq_cli/test/ctl/restart_vhost_command_test.exs index c8d2fe7c4868..725c5832006e 100644 --- a/deps/rabbitmq_cli/test/ctl/restart_vhost_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/restart_vhost_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2016-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule RestartVhostCommandTest do use ExUnit.Case, async: false import TestHelper @@ -20,27 +19,32 @@ defmodule RestartVhostCommandTest do @timeout 10000 setup do - {:ok, opts: %{ - node: get_rabbit_hostname(), - vhost: @vhost, - timeout: @timeout - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + vhost: @vhost, + timeout: @timeout + }} end test "validate: specifying arguments is reported as an error", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} + assert @command.validate(["a", "b"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} + assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: request to a non-existent node returns a badrpc", _context do opts = %{node: :jake@thedog, vhost: @vhost, timeout: @timeout} + assert match?( - {:badrpc, _}, - @command.run([], opts)) + {:badrpc, _}, + @command.run([], opts) + ) end test "banner", context do @@ -67,11 +71,12 @@ defmodule RestartVhostCommandTest do # defp setup_vhosts do - add_vhost @vhost + add_vhost(@vhost) # give the vhost a chance to fully start and initialise :timer.sleep(1000) + on_exit(fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) end @@ -79,15 +84,17 @@ defmodule RestartVhostCommandTest do case :rpc.call(node_name, :rabbit_vhost_sup_sup, :get_vhost_sup, [vhost]) do {:ok, sup} -> case :lists.keyfind(:msg_store_persistent, 1, :supervisor.which_children(sup)) do - {_, pid, _, _} -> - Process.exit(pid, :foo) - :timer.sleep(5000) - force_vhost_failure(node_name, vhost); - false -> - Process.exit(sup, :foo) - :timer.sleep(5000) - force_vhost_failure(node_name, vhost) - end; + {_, pid, _, _} -> + Process.exit(pid, :foo) + :timer.sleep(5000) + force_vhost_failure(node_name, vhost) + + false -> + Process.exit(sup, :foo) + :timer.sleep(5000) + force_vhost_failure(node_name, vhost) + end + {:error, {:vhost_supervisor_not_running, _}} -> :ok end diff --git a/deps/rabbitmq_cli/test/ctl/resume_listeners_command_test.exs b/deps/rabbitmq_cli/test/ctl/resume_listeners_command_test.exs index 9b1e03607696..c7b8ea34994e 100644 --- a/deps/rabbitmq_cli/test/ctl/resume_listeners_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/resume_listeners_command_test.exs @@ -16,6 +16,7 @@ defmodule ResumeListenersCommandTest do resume_all_client_listeners() node_name = get_rabbit_hostname() + on_exit(fn -> resume_all_client_listeners() close_all_connections(node_name) @@ -38,7 +39,7 @@ defmodule ResumeListenersCommandTest do test "validate: with extra arguments returns an arg count error", context do assert @command.validate(["extra"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: request to a non-existent node returns a badrpc" do diff --git a/deps/rabbitmq_cli/test/ctl/set_cluster_name_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_cluster_name_command_test.exs index a0852522e46e..4466b53cc841 100644 --- a/deps/rabbitmq_cli/test/ctl/set_cluster_name_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_cluster_name_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetClusterNameCommandTest do use ExUnit.Case, async: false import TestHelper @@ -59,5 +58,4 @@ defmodule SetClusterNameCommandTest do s = @command.banner(["annoyyou"], %{}) assert s == "Setting cluster name to annoyyou ..." end - end diff --git a/deps/rabbitmq_cli/test/ctl/set_disk_free_limit_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_disk_free_limit_command_test.exs index 80f0e1511f5f..e926b9e37c9b 100644 --- a/deps/rabbitmq_cli/test/ctl/set_disk_free_limit_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_disk_free_limit_command_test.exs @@ -4,14 +4,13 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetDiskFreeLimitCommandTest do use ExUnit.Case, async: false import TestHelper @command RabbitMQ.CLI.Ctl.Commands.SetDiskFreeLimitCommand - @default_limit 1048576 + @default_limit 1_048_576 setup_all do RabbitMQ.CLI.Core.Distribution.start() @@ -21,11 +20,11 @@ defmodule SetDiskFreeLimitCommandTest do on_exit([], fn -> set_disk_free_limit(@default_limit) end) - end setup context do - context[:tag] # silences warnings + # silences warnings + context[:tag] on_exit([], fn -> set_disk_free_limit(@default_limit) end) {:ok, opts: %{node: get_rabbit_hostname()}} @@ -39,58 +38,59 @@ defmodule SetDiskFreeLimitCommandTest do @tag limit: "2097152bytes" test "run: an invalid string input returns a bad arg and does not change the limit", context do assert @command.validate([context[:limit]], context[:opts]) == - {:validation_failure, :bad_argument} + {:validation_failure, :bad_argument} end test "validate: valid fractional inputs return an ok", context do assert @command.validate( - ["mem_relative", "0.0"], - context[:opts] - ) == :ok + ["mem_relative", "0.0"], + context[:opts] + ) == :ok assert @command.validate( - ["mem_relative", "0.5"], - context[:opts] - ) == :ok + ["mem_relative", "0.5"], + context[:opts] + ) == :ok assert @command.validate( - ["mem_relative", "1.8"], - context[:opts] - ) == :ok + ["mem_relative", "1.8"], + context[:opts] + ) == :ok end test "validate: a value outside the accepted range returns an error", context do - assert @command.validate( - ["mem_relative", "-1.0"], - context[:opts] - ) == {:validation_failure, :bad_argument} + assert @command.validate( + ["mem_relative", "-1.0"], + context[:opts] + ) == {:validation_failure, :bad_argument} end @tag fraction: "1.3" test "validate: a valid float string input returns ok", context do assert @command.validate( - ["mem_relative", context[:fraction]], - context[:opts] - ) == :ok + ["mem_relative", context[:fraction]], + context[:opts] + ) == :ok end @tag fraction: "1.3salt" test "validate: an invalid string input returns a bad argument", context do assert @command.validate( - ["mem_relative", context[:fraction]], - context[:opts] - ) == {:validation_failure, :bad_argument} + ["mem_relative", context[:fraction]], + context[:opts] + ) == {:validation_failure, :bad_argument} end -## ------------------------ validate mem_relative command ------------------------------------------- + ## ------------------------ validate mem_relative command ------------------------------------------- test "validate: an invalid number of mem_relative arguments results in an arg count error" do assert @command.validate(["mem_relative"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["mem_relative", 1.3, "extra"], %{}) == {:validation_failure, :too_many_args} - end + assert @command.validate(["mem_relative", 1.3, "extra"], %{}) == + {:validation_failure, :too_many_args} + end -## ------------------------ run absolute command ------------------------------------------- + ## ------------------------ run absolute command ------------------------------------------- @tag test_timeout: 3000 test "run: an invalid node returns a bad rpc" do @@ -100,22 +100,24 @@ defmodule SetDiskFreeLimitCommandTest do assert match?({:badrpc, _}, @command.run(args, opts)) end - @tag limit: 2097152 + @tag limit: 2_097_152 test "run: a valid integer input returns an ok and sets the disk free limit", context do assert @command.run([context[:limit]], context[:opts]) == :ok assert status()[:disk_free_limit] === context[:limit] end - @tag limit: 2097152.0 - test "run: a valid non-fractional float input returns an ok and sets the disk free limit", context do + @tag limit: 2_097_152.0 + test "run: a valid non-fractional float input returns an ok and sets the disk free limit", + context do assert @command.run([context[:limit]], context[:opts]) == :ok assert status()[:disk_free_limit] === round(context[:limit]) end - @tag limit: 2097152.9 - test "run: a valid fractional float input returns an ok and sets the disk free limit", context do + @tag limit: 2_097_152.9 + test "run: a valid fractional float input returns an ok and sets the disk free limit", + context do assert @command.run([context[:limit]], context[:opts]) == :ok - assert status()[:disk_free_limit] === context[:limit] |> Float.floor |> round + assert status()[:disk_free_limit] === context[:limit] |> Float.floor() |> round end @tag limit: "2097152" @@ -127,47 +129,46 @@ defmodule SetDiskFreeLimitCommandTest do @tag limit: "2MB" test "run: an valid unit string input returns an ok and changes the limit", context do assert @command.run([context[:limit]], context[:opts]) == :ok - assert status()[:disk_free_limit] === 2000000 + assert status()[:disk_free_limit] === 2_000_000 end -## ------------------------ run relative command ------------------------------------------- + ## ------------------------ run relative command ------------------------------------------- @tag fraction: 1 test "run: an integer input returns ok", context do assert @command.run( - ["mem_relative", context[:fraction]], - context[:opts] - ) == :ok + ["mem_relative", context[:fraction]], + context[:opts] + ) == :ok end @tag fraction: 1.1 test "run: a factional input returns ok", context do assert @command.run( - ["mem_relative", context[:fraction]], - context[:opts] - ) == :ok + ["mem_relative", context[:fraction]], + context[:opts] + ) == :ok end - test "banner: returns absolute message", context do - assert @command.banner(["10"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to 10 bytes .../ + assert @command.banner(["10"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to 10 bytes .../ - assert @command.banner(["-10"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to -10 bytes .../ + assert @command.banner(["-10"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to -10 bytes .../ - assert @command.banner(["sandwich"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to sandwich bytes .../ + assert @command.banner(["sandwich"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to sandwich bytes .../ end test "banner: returns memory-relative message", context do - assert @command.banner(["mem_relative", "1.3"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to 1\.3 times the total RAM \.\.\./ + assert @command.banner(["mem_relative", "1.3"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to 1\.3 times the total RAM \.\.\./ - assert @command.banner(["mem_relative", "-1.3"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to -1\.3 times the total RAM \.\.\./ + assert @command.banner(["mem_relative", "-1.3"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to -1\.3 times the total RAM \.\.\./ - assert @command.banner(["mem_relative", "sandwich"], context[:opts]) - =~ ~r/Setting disk free limit on #{get_rabbit_hostname()} to sandwich times the total RAM \.\.\./ + assert @command.banner(["mem_relative", "sandwich"], context[:opts]) =~ + ~r/Setting disk free limit on #{get_rabbit_hostname()} to sandwich times the total RAM \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/set_global_parameter_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_global_parameter_command_test.exs index 848f29a0b8f6..e9482bf9923b 100644 --- a/deps/rabbitmq_cli/test/ctl/set_global_parameter_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_global_parameter_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetGlobalParameterCommandTest do use ExUnit.Case, async: false import TestHelper @@ -22,13 +21,13 @@ defmodule SetGlobalParameterCommandTest do setup context do on_exit(context, fn -> - clear_global_parameter context[:key] + clear_global_parameter(context[:key]) end) { :ok, opts: %{ - node: get_rabbit_hostname(), + node: get_rabbit_hostname() } } end @@ -36,15 +35,17 @@ defmodule SetGlobalParameterCommandTest do test "validate: expects a key and a value" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["insufficient"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag key: @key, value: @value test "run: expects a key and a value", context do assert @command.run( - [context[:key], context[:value]], - context[:opts] - ) == :ok + [context[:key], context[:value]], + context[:opts] + ) == :ok assert_parameter_fields(context) end @@ -58,25 +59,29 @@ defmodule SetGlobalParameterCommandTest do @tag key: @key, value: "bad-value" test "run: a value that fails to parse as JSON returns a decoding error", context do initial = list_global_parameters() - assert match?({:error_string, _}, - @command.run([context[:key], context[:value]], - context[:opts])) + + assert match?( + {:error_string, _}, + @command.run( + [context[:key], context[:value]], + context[:opts] + ) + ) assert list_global_parameters() == initial end @tag key: @key, value: @value test "banner", context do - assert @command.banner([context[:key], context[:value]], context[:opts]) - =~ ~r/Setting global runtime parameter \"#{context[:key]}\" to \"#{context[:value]}\" \.\.\./ + assert @command.banner([context[:key], context[:value]], context[:opts]) =~ + ~r/Setting global runtime parameter \"#{context[:key]}\" to \"#{context[:value]}\" \.\.\./ end # Checks each element of the first parameter against the expected context values defp assert_parameter_fields(context) do - result_param = list_global_parameters() |> List.first + result_param = list_global_parameters() |> List.first() assert result_param[:value] == context[:value] assert result_param[:name] == context[:key] end - end diff --git a/deps/rabbitmq_cli/test/ctl/set_log_level_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_log_level_command_test.exs index b4108219ba59..18f18a7d00d5 100644 --- a/deps/rabbitmq_cli/test/ctl/set_log_level_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_log_level_command_test.exs @@ -12,9 +12,7 @@ defmodule SetLogLevelCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - {:ok, - log_level: "debug", - opts: %{node: get_rabbit_hostname()}} + {:ok, log_level: "debug", opts: %{node: get_rabbit_hostname()}} end test "validate: with a single known level succeeds", context do @@ -26,7 +24,8 @@ defmodule SetLogLevelCommandTest do end test "validate: with extra arguments returns an arg count error", context do - assert @command.validate([context[:log_level], "whoops"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate([context[:log_level], "whoops"], context[:opts]) == + {:validation_failure, :too_many_args} end test "run: request to a named, active node succeeds", context do @@ -39,6 +38,7 @@ defmodule SetLogLevelCommandTest do end test "banner", context do - assert @command.banner([context[:log_level]], context[:opts]) == "Setting log level to \"debug\" ..." + assert @command.banner([context[:log_level]], context[:opts]) == + "Setting log level to \"debug\" ..." end end diff --git a/deps/rabbitmq_cli/test/ctl/set_operator_policy_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_operator_policy_command_test.exs index 5911132a3268..594431dc357c 100644 --- a/deps/rabbitmq_cli/test/ctl/set_operator_policy_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_operator_policy_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetOperatorPolicyCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule SetOperatorPolicyCommandTest do @command RabbitMQ.CLI.Ctl.Commands.SetOperatorPolicyCommand @vhost "test1" - @root "/" + @root "/" @key "message-expiry" @pattern "^queue\." @value "{\"message-ttl\":10}" @@ -22,17 +21,16 @@ defmodule SetOperatorPolicyCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - on_exit(context, fn -> clear_operator_policy(context[:vhost], context[:key]) end) @@ -54,7 +52,10 @@ defmodule SetOperatorPolicyCommandTest do end test "merge_defaults: does not change defined vhost" do - assert match?({[], %{vhost: "test_vhost"}}, @command.merge_defaults([], %{vhost: "test_vhost"})) + assert match?( + {[], %{vhost: "test_vhost"}}, + @command.merge_defaults([], %{vhost: "test_vhost"}) + ) end test "merge_defaults: default apply_to is \"all\"" do @@ -74,7 +75,8 @@ defmodule SetOperatorPolicyCommandTest do end test "validate: providing too many arguments fails validation" do - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag pattern: @pattern, key: @key, value: @value, vhost: @vhost @@ -82,9 +84,9 @@ defmodule SetOperatorPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key], context[:pattern], context[:value]], - vhost_opts - ) == :ok + [context[:key], context[:pattern], context[:value]], + vhost_opts + ) == :ok assert_operator_policy_fields(context) end @@ -100,16 +102,20 @@ defmodule SetOperatorPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key], context[:pattern], context[:value]], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:key], context[:pattern], context[:value]], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag pattern: @pattern, key: @key, value: "bad-value", vhost: @root test "run: an invalid value returns a JSON decoding error", context do - assert match?({:error_string, _}, - @command.run([context[:key], context[:pattern], context[:value]], - context[:opts])) + assert match?( + {:error_string, _}, + @command.run( + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) + ) assert list_operator_policies(context[:vhost]) == [] end @@ -117,9 +123,11 @@ defmodule SetOperatorPolicyCommandTest do @tag pattern: @pattern, key: @key, value: "{\"foo\":\"bar\"}", vhost: @root test "run: invalid policy returns an error", context do assert @command.run( - [context[:key], context[:pattern], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\n[{<<"foo">>,<<"bar">>}] are not recognised policy settings\n'} + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) == + {:error_string, + 'Validation failed\n\n[{<<"foo">>,<<"bar">>}] are not recognised policy settings\n'} assert list_operator_policies(context[:vhost]) == [] end @@ -127,9 +135,9 @@ defmodule SetOperatorPolicyCommandTest do @tag pattern: @pattern, key: @key, value: "{}", vhost: @root test "run: an empty JSON object value returns an error", context do assert @command.run( - [context[:key], context[:pattern], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\nno policy provided\n'} + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) == {:error_string, 'Validation failed\n\nno policy provided\n'} assert list_operator_policies(context[:vhost]) == [] end @@ -138,13 +146,13 @@ defmodule SetOperatorPolicyCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:key], context[:pattern], context[:value]], vhost_opts) - == "Setting operator policy override \"#{context[:key]}\" for pattern \"#{context[:pattern]}\" to \"#{context[:value]}\" with priority \"#{context[:opts][:priority]}\" for vhost \"#{context[:vhost]}\" \.\.\." + assert @command.banner([context[:key], context[:pattern], context[:value]], vhost_opts) == + "Setting operator policy override \"#{context[:key]}\" for pattern \"#{context[:pattern]}\" to \"#{context[:value]}\" with priority \"#{context[:opts][:priority]}\" for vhost \"#{context[:vhost]}\" \.\.\." end # Checks each element of the first policy against the expected context values defp assert_operator_policy_fields(context) do - result_policy = context[:vhost] |> list_operator_policies |> List.first + result_policy = context[:vhost] |> list_operator_policies |> List.first() assert result_policy[:definition] == context[:value] assert result_policy[:vhost] == context[:vhost] assert result_policy[:pattern] == context[:pattern] diff --git a/deps/rabbitmq_cli/test/ctl/set_parameter_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_parameter_command_test.exs index 50a2543dee23..1460934c65fd 100644 --- a/deps/rabbitmq_cli/test/ctl/set_parameter_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_parameter_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetParameterCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule SetParameterCommandTest do @command RabbitMQ.CLI.Ctl.Commands.SetParameterCommand @vhost "test1" - @root "/" + @root "/" @component_name "federation-upstream" @key "reconnect-delay" @value "{\"uri\":\"amqp://127.0.0.1:5672\"}" @@ -20,12 +19,12 @@ defmodule SetParameterCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) # featured in a definitions file imported by other tests @@ -36,8 +35,9 @@ defmodule SetParameterCommandTest do setup context do on_exit(context, fn -> - clear_parameter context[:vhost], context[:component_name], context[:key] + clear_parameter(context[:vhost], context[:component_name], context[:key]) end) + { :ok, opts: %{ @@ -50,14 +50,20 @@ defmodule SetParameterCommandTest do @tag component_name: @component_name, key: @key, value: @value, vhost: @root test "merge_defaults: a well-formed command with no vhost runs against the default" do assert match?({_, %{vhost: "/"}}, @command.merge_defaults([], %{})) - assert match?({_, %{vhost: "non_default"}}, @command.merge_defaults([], %{vhost: "non_default"})) + + assert match?( + {_, %{vhost: "non_default"}}, + @command.merge_defaults([], %{vhost: "non_default"}) + ) end test "validate: wrong number of arguments leads to an arg count error" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["insufficient"], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["not", "enough"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag component_name: @component_name, key: @key, value: @value, vhost: @vhost @@ -65,9 +71,9 @@ defmodule SetParameterCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:component_name], context[:key], context[:value]], - vhost_opts - ) == :ok + [context[:component_name], context[:key], context[:value]], + vhost_opts + ) == :ok assert_parameter_fields(context) end @@ -81,9 +87,11 @@ defmodule SetParameterCommandTest do @tag component_name: "bad-component-name", key: @key, value: @value, vhost: @root test "run: an invalid component_name returns a validation failed error", context do assert @command.run( - [context[:component_name], context[:key], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\ncomponent #{context[:component_name]} not found\n'} + [context[:component_name], context[:key], context[:value]], + context[:opts] + ) == + {:error_string, + 'Validation failed\n\ncomponent #{context[:component_name]} not found\n'} assert list_parameters(context[:vhost]) == [] end @@ -93,16 +101,20 @@ defmodule SetParameterCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:component_name], context[:key], context[:value]], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:component_name], context[:key], context[:value]], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag component_name: @component_name, key: @key, value: "bad-value", vhost: @root test "run: an invalid value returns a JSON decoding error", context do - assert match?({:error_string, _}, - @command.run([context[:component_name], context[:key], context[:value]], - context[:opts])) + assert match?( + {:error_string, _}, + @command.run( + [context[:component_name], context[:key], context[:value]], + context[:opts] + ) + ) assert list_parameters(context[:vhost]) == [] end @@ -110,9 +122,9 @@ defmodule SetParameterCommandTest do @tag component_name: @component_name, key: @key, value: "{}", vhost: @root test "run: an empty JSON object value returns a key \"uri\" not found error", context do assert @command.run( - [context[:component_name], context[:key], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\nKey "uri" not found in reconnect-delay\n'} + [context[:component_name], context[:key], context[:value]], + context[:opts] + ) == {:error_string, 'Validation failed\n\nKey "uri" not found in reconnect-delay\n'} assert list_parameters(context[:vhost]) == [] end @@ -121,13 +133,13 @@ defmodule SetParameterCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:component_name], context[:key], context[:value]], vhost_opts) - =~ ~r/Setting runtime parameter \"#{context[:key]}\" for component \"#{context[:component_name]}\" to \"#{context[:value]}\" in vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:component_name], context[:key], context[:value]], vhost_opts) =~ + ~r/Setting runtime parameter \"#{context[:key]}\" for component \"#{context[:component_name]}\" to \"#{context[:value]}\" in vhost \"#{context[:vhost]}\" \.\.\./ end # Checks each element of the first parameter against the expected context values defp assert_parameter_fields(context) do - result_param = context[:vhost] |> list_parameters |> List.first + result_param = context[:vhost] |> list_parameters |> List.first() assert result_param[:value] == context[:value] assert result_param[:component] == context[:component_name] diff --git a/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs index c2628f27288b..142f7ce29895 100644 --- a/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -13,24 +12,23 @@ defmodule SetPermissionsCommandTest do @vhost "test1" @user "guest" - @root "/" + @root "/" setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - on_exit(context, fn -> - set_permissions context[:user], context[:vhost], [".*", ".*", ".*"] + set_permissions(context[:user], context[:vhost], [".*", ".*", ".*"]) end) { @@ -51,8 +49,12 @@ defmodule SetPermissionsCommandTest do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["insufficient"], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["not", "enough"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["not", "quite", "enough"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this", "is", "way", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["not", "quite", "enough"], %{}) == + {:validation_failure, :not_enough_args} + + assert @command.validate(["this", "is", "way", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag user: @user, vhost: @vhost @@ -60,11 +62,11 @@ defmodule SetPermissionsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:user], "^#{context[:user]}-.*", ".*", ".*"], - vhost_opts - ) == :ok + [context[:user], "^#{context[:user]}-.*", ".*", ".*"], + vhost_opts + ) == :ok - u = Enum.find(list_permissions(context[:vhost]), fn(x) -> x[:user] == context[:user] end) + u = Enum.find(list_permissions(context[:vhost]), fn x -> x[:user] == context[:user] end) assert u[:configure] == "^#{context[:user]}-.*" end @@ -77,9 +79,9 @@ defmodule SetPermissionsCommandTest do @tag user: "interloper", vhost: @root test "run: an invalid user returns a no-such-user error", context do assert @command.run( - [context[:user], "^#{context[:user]}-.*", ".*", ".*"], - context[:opts] - ) == {:error, {:no_such_user, context[:user]}} + [context[:user], "^#{context[:user]}-.*", ".*", ".*"], + context[:opts] + ) == {:error, {:no_such_user, context[:user]}} end @tag user: @user, vhost: "wintermute" @@ -87,20 +89,20 @@ defmodule SetPermissionsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:user], "^#{context[:user]}-.*", ".*", ".*"], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:user], "^#{context[:user]}-.*", ".*", ".*"], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag user: @user, vhost: @root test "run: invalid regex patterns returns an error", context do assert @command.run( - [context[:user], "^#{context[:user]}-.*", ".*", "*"], - context[:opts] - ) == {:error, {:invalid_regexp, '*', {'nothing to repeat', 0}}} + [context[:user], "^#{context[:user]}-.*", ".*", "*"], + context[:opts] + ) == {:error, {:invalid_regexp, '*', {'nothing to repeat', 0}}} # asserts that the failed command didn't change anything - u = Enum.find(list_permissions(context[:vhost]), fn(x) -> x[:user] == context[:user] end) + u = Enum.find(list_permissions(context[:vhost]), fn x -> x[:user] == context[:user] end) assert u == [user: context[:user], configure: ".*", write: ".*", read: ".*"] end @@ -108,7 +110,7 @@ defmodule SetPermissionsCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:user], "^#{context[:user]}-.*", ".*", ".*"], vhost_opts) - =~ ~r/Setting permissions for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:user], "^#{context[:user]}-.*", ".*", ".*"], vhost_opts) =~ + ~r/Setting permissions for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/set_policy_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_policy_command_test.exs index 0422933ecb13..41ea57278d00 100644 --- a/deps/rabbitmq_cli/test/ctl/set_policy_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_policy_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetPolicyCommandTest do use ExUnit.Case, async: false import TestHelper @@ -12,7 +11,7 @@ defmodule SetPolicyCommandTest do @command RabbitMQ.CLI.Ctl.Commands.SetPolicyCommand @vhost "test1" - @root "/" + @root "/" @key "federate" @pattern "^fed\." @value "{\"federation-upstream-set\":\"all\"}" @@ -22,21 +21,20 @@ defmodule SetPolicyCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) enable_federation_plugin() on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - on_exit(context, fn -> - clear_policy context[:vhost], context[:key] + clear_policy(context[:vhost], context[:key]) end) { @@ -56,7 +54,10 @@ defmodule SetPolicyCommandTest do end test "merge_defaults: does not change defined vhost" do - assert match?({[], %{vhost: "test_vhost"}}, @command.merge_defaults([], %{vhost: "test_vhost"})) + assert match?( + {[], %{vhost: "test_vhost"}}, + @command.merge_defaults([], %{vhost: "test_vhost"}) + ) end test "merge_defaults: default apply_to is \"all\"" do @@ -76,7 +77,8 @@ defmodule SetPolicyCommandTest do end test "validate: providing too many arguments fails validation" do - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag pattern: @pattern, key: @key, value: @value, vhost: @vhost @@ -84,9 +86,9 @@ defmodule SetPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key], context[:pattern], context[:value]], - vhost_opts - ) == :ok + [context[:key], context[:pattern], context[:value]], + vhost_opts + ) == :ok assert_policy_fields(context) end @@ -102,16 +104,20 @@ defmodule SetPolicyCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:key], context[:pattern], context[:value]], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:key], context[:pattern], context[:value]], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag pattern: @pattern, key: @key, value: "bad-value", vhost: @root test "run: an invalid value returns a JSON decoding error", context do - assert match?({:error_string, _}, - @command.run([context[:key], context[:pattern], context[:value]], - context[:opts])) + assert match?( + {:error_string, _}, + @command.run( + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) + ) assert list_policies(context[:vhost]) == [] end @@ -119,9 +125,11 @@ defmodule SetPolicyCommandTest do @tag pattern: @pattern, key: @key, value: "{\"foo\":\"bar\"}", vhost: @root test "run: invalid policy returns an error", context do assert @command.run( - [context[:key], context[:pattern], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\n[{<<"foo">>,<<"bar">>}] are not recognised policy settings\n'} + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) == + {:error_string, + 'Validation failed\n\n[{<<"foo">>,<<"bar">>}] are not recognised policy settings\n'} assert list_policies(context[:vhost]) == [] end @@ -129,9 +137,9 @@ defmodule SetPolicyCommandTest do @tag pattern: @pattern, key: @key, value: "{}", vhost: @root test "run: an empty JSON object value returns an error", context do assert @command.run( - [context[:key], context[:pattern], context[:value]], - context[:opts] - ) == {:error_string, 'Validation failed\n\nno policy provided\n'} + [context[:key], context[:pattern], context[:value]], + context[:opts] + ) == {:error_string, 'Validation failed\n\nno policy provided\n'} assert list_policies(context[:vhost]) == [] end @@ -140,8 +148,8 @@ defmodule SetPolicyCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:key], context[:pattern], context[:value]], vhost_opts) - == "Setting policy \"#{context[:key]}\" for pattern \"#{context[:pattern]}\" to \"#{context[:value]}\" with priority \"#{context[:opts][:priority]}\" for vhost \"#{context[:vhost]}\" \.\.\." + assert @command.banner([context[:key], context[:pattern], context[:value]], vhost_opts) == + "Setting policy \"#{context[:key]}\" for pattern \"#{context[:pattern]}\" to \"#{context[:value]}\" with priority \"#{context[:opts][:priority]}\" for vhost \"#{context[:vhost]}\" \.\.\." end @tag pattern: "ha_", key: "ha_policy_test", vhost: @vhost @@ -190,25 +198,28 @@ defmodule SetPolicyCommandTest do def pass_validation(context, value) do assert @command.run( - [context[:key], context[:pattern], value], - context[:opts] - ) == :ok + [context[:key], context[:pattern], value], + context[:opts] + ) == :ok + assert_policy_fields(Map.merge(context, %{value: value})) end def fail_validation(context, value) do - result = @command.run( - [context[:key], context[:pattern], value], - context[:opts] - ) + result = + @command.run( + [context[:key], context[:pattern], value], + context[:opts] + ) + assert {:error_string, _} = result {:error_string, msg} = result - assert "Validation failed"<>_ = to_string(msg) + assert "Validation failed" <> _ = to_string(msg) end # Checks each element of the first policy against the expected context values defp assert_policy_fields(context) do - result_policy = context[:vhost] |> list_policies |> List.first + result_policy = context[:vhost] |> list_policies |> List.first() assert result_policy[:definition] == context[:value] assert result_policy[:vhost] == context[:vhost] assert result_policy[:pattern] == context[:pattern] diff --git a/deps/rabbitmq_cli/test/ctl/set_topic_permissions_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_topic_permissions_command_test.exs index f117f5a78907..b666d7f3e89c 100644 --- a/deps/rabbitmq_cli/test/ctl/set_topic_permissions_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_topic_permissions_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetTopicPermissionsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -13,24 +12,23 @@ defmodule SetTopicPermissionsCommandTest do @vhost "test1" @user "guest" - @root "/" + @root "/" setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - on_exit(context, fn -> - clear_topic_permissions context[:user], context[:vhost] + clear_topic_permissions(context[:user], context[:vhost]) end) { @@ -51,8 +49,12 @@ defmodule SetTopicPermissionsCommandTest do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["insufficient"], %{}) == {:validation_failure, :not_enough_args} assert @command.validate(["not", "enough"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["still", "not", "enough"], %{}) == {:validation_failure, :not_enough_args} - assert @command.validate(["this", "is", "way", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["still", "not", "enough"], %{}) == + {:validation_failure, :not_enough_args} + + assert @command.validate(["this", "is", "way", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end @tag user: @user, vhost: @vhost @@ -60,9 +62,9 @@ defmodule SetTopicPermissionsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:user], "amq.topic", "^a", "^b"], - vhost_opts - ) == :ok + [context[:user], "amq.topic", "^a", "^b"], + vhost_opts + ) == :ok assert List.first(list_user_topic_permissions(context[:user]))[:write] == "^a" assert List.first(list_user_topic_permissions(context[:user]))[:read] == "^b" @@ -77,9 +79,9 @@ defmodule SetTopicPermissionsCommandTest do @tag user: "interloper", vhost: @root test "run: an invalid user returns a no-such-user error", context do assert @command.run( - [context[:user], "amq.topic", "^a", "^b"], - context[:opts] - ) == {:error, {:no_such_user, context[:user]}} + [context[:user], "amq.topic", "^a", "^b"], + context[:opts] + ) == {:error, {:no_such_user, context[:user]}} end @tag user: @user, vhost: "wintermute" @@ -87,9 +89,9 @@ defmodule SetTopicPermissionsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:user], "amq.topic", "^a", "^b"], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:user], "amq.topic", "^a", "^b"], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} assert Enum.count(list_user_topic_permissions(context[:user])) == 0 end @@ -97,10 +99,13 @@ defmodule SetTopicPermissionsCommandTest do @tag user: @user, vhost: @root test "run: invalid regex patterns return error", context do n = Enum.count(list_user_topic_permissions(context[:user])) - {:error, {:invalid_regexp, _, _}} = @command.run( - [context[:user], "amq.topic", "[", "^b"], - context[:opts] - ) + + {:error, {:invalid_regexp, _, _}} = + @command.run( + [context[:user], "amq.topic", "[", "^b"], + context[:opts] + ) + assert Enum.count(list_user_topic_permissions(context[:user])) == n end @@ -108,7 +113,7 @@ defmodule SetTopicPermissionsCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:user], "amq.topic", "^a", "^b"], vhost_opts) - =~ ~r/Setting topic permissions on \"amq.topic\" for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ + assert @command.banner([context[:user], "amq.topic", "^a", "^b"], vhost_opts) =~ + ~r/Setting topic permissions on \"amq.topic\" for user \"#{context[:user]}\" in vhost \"#{context[:vhost]}\" \.\.\./ end end diff --git a/deps/rabbitmq_cli/test/ctl/set_user_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_user_limits_command_test.exs index 6179267396ef..2d339616b113 100644 --- a/deps/rabbitmq_cli/test/ctl/set_user_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_user_limits_command_test.exs @@ -19,10 +19,10 @@ defmodule SetUserLimitsCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_user @user, @password + add_user(@user, @password) on_exit([], fn -> - delete_user @user + delete_user(@user) end) :ok @@ -53,34 +53,34 @@ defmodule SetUserLimitsCommandTest do test "validate: providing too many arguments fails validation" do assert @command.validate(["is", "too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end test "run: a well-formed, host-specific command returns okay", context do assert @command.run( - [context[:user], - @conn_definition], - context[:opts] - ) == :ok + [context[:user], @conn_definition], + context[:opts] + ) == :ok assert_limits(context, @conn_definition) clear_user_limits(context[:user]) assert @command.run( - [context[:user], - @channel_definition], - context[:opts] - ) == :ok + [context[:user], @channel_definition], + context[:opts] + ) == :ok assert_limits(context, @channel_definition) end - test "run: a well-formed command to set both max-connections and max-channels returns okay", context do + test "run: a well-formed command to set both max-connections and max-channels returns okay", + context do assert @command.run( - [context[:user], - @definition], - context[:opts] - ) == :ok + [context[:user], @definition], + context[:opts] + ) == :ok assert_limits(context, @definition) end @@ -93,37 +93,36 @@ defmodule SetUserLimitsCommandTest do @tag user: "non-existent-user" test "run: providing a non-existent user reports an error", context do - assert @command.run( - [context[:user], - @conn_definition], - context[:opts] - ) == {:error, {:no_such_user, context[:user]}} + [context[:user], @conn_definition], + context[:opts] + ) == {:error, {:no_such_user, context[:user]}} end test "run: an invalid definition returns a JSON decoding error", context do - assert match?({:error_string, _}, - @command.run( - [context[:user], - ["this_is_not_json"]], - context[:opts])) + assert match?( + {:error_string, _}, + @command.run( + [context[:user], ["this_is_not_json"]], + context[:opts] + ) + ) assert get_user_limits(context[:user]) == %{} end test "run: invalid limit returns an error", context do assert @command.run( - [context[:user], - "{\"foo\":\"bar\"}"], - context[:opts] - ) == {:error_string, 'Unrecognised terms [{<<"foo">>,<<"bar">>}] in user-limits'} + [context[:user], "{\"foo\":\"bar\"}"], + context[:opts] + ) == {:error_string, 'Unrecognised terms [{<<"foo">>,<<"bar">>}] in user-limits'} assert get_user_limits(context[:user]) == %{} end test "banner", context do - assert @command.banner([context[:user], context[:conn_definition]], context[:opts]) - == "Setting user limits to \"#{context[:conn_definition]}\" for user \"#{context[:user]}\" ..." + assert @command.banner([context[:user], context[:conn_definition]], context[:opts]) == + "Setting user limits to \"#{context[:conn_definition]}\" for user \"#{context[:user]}\" ..." end # diff --git a/deps/rabbitmq_cli/test/ctl/set_user_tags_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_user_tags_command_test.exs index 74f9b2a3f218..204de9cbb5d3 100644 --- a/deps/rabbitmq_cli/test/ctl/set_user_tags_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_user_tags_command_test.exs @@ -4,20 +4,19 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetUserTagsCommandTest do use ExUnit.Case, async: false import TestHelper @command RabbitMQ.CLI.Ctl.Commands.SetUserTagsCommand - @user "user1" + @user "user1" @password "password" setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_user @user, @password + add_user(@user, @password) on_exit([], fn -> delete_user(@user) @@ -27,7 +26,8 @@ defmodule SetUserTagsCommandTest do end setup context do - context[:user] # silences warnings + # silences warnings + context[:user] on_exit([], fn -> set_user_tags(context[:user], []) end) {:ok, opts: %{node: get_rabbit_hostname()}} @@ -44,16 +44,17 @@ defmodule SetUserTagsCommandTest do end @tag user: @user, tags: [:emperor] - test "run: on a single optional argument, add a flag to the user", context do + test "run: on a single optional argument, add a flag to the user", context do @command.run( [context[:user] | context[:tags]], context[:opts] ) - result = Enum.find( - list_users(), - fn(record) -> record[:user] == context[:user] end - ) + result = + Enum.find( + list_users(), + fn record -> record[:user] == context[:user] end + ) assert result[:tags] == context[:tags] end @@ -61,84 +62,84 @@ defmodule SetUserTagsCommandTest do @tag user: "interloper", tags: [:emperor] test "run: when user does not exist, returns an error", context do assert @command.run( - [context[:user] | context[:tags]], - context[:opts] - ) == {:error, {:no_such_user, context[:user]}} + [context[:user] | context[:tags]], + context[:opts] + ) == {:error, {:no_such_user, context[:user]}} end @tag user: @user, tags: [:emperor, :generalissimo] - test "run: with multiple optional arguments, adds multiple tags", context do + test "run: with multiple optional arguments, adds multiple tags", context do @command.run( [context[:user] | context[:tags]], context[:opts] ) - result = Enum.find( - list_users(), - fn(record) -> record[:user] == context[:user] end - ) + result = + Enum.find( + list_users(), + fn record -> record[:user] == context[:user] end + ) assert result[:tags] == context[:tags] end @tag user: @user, tags: [:emperor] - test "run: without optional arguments, clears user tags", context do - + test "run: without optional arguments, clears user tags", context do set_user_tags(context[:user], context[:tags]) @command.run([context[:user]], context[:opts]) - result = Enum.find( - list_users(), - fn(record) -> record[:user] == context[:user] end - ) + result = + Enum.find( + list_users(), + fn record -> record[:user] == context[:user] end + ) assert result[:tags] == [] end @tag user: @user, tags: [:emperor] - test "run: identical calls are idempotent", context do - + test "run: identical calls are idempotent", context do set_user_tags(context[:user], context[:tags]) assert @command.run( - [context[:user] | context[:tags]], - context[:opts] - ) == :ok - - result = Enum.find( - list_users(), - fn(record) -> record[:user] == context[:user] end - ) + [context[:user] | context[:tags]], + context[:opts] + ) == :ok + + result = + Enum.find( + list_users(), + fn record -> record[:user] == context[:user] end + ) assert result[:tags] == context[:tags] end @tag user: @user, old_tags: [:emperor], new_tags: [:generalissimo] - test "run: overwrites existing tags", context do - + test "run: overwrites existing tags", context do set_user_tags(context[:user], context[:old_tags]) assert @command.run( - [context[:user] | context[:new_tags]], - context[:opts] - ) == :ok - - result = Enum.find( - list_users(), - fn(record) -> record[:user] == context[:user] end - ) + [context[:user] | context[:new_tags]], + context[:opts] + ) == :ok + + result = + Enum.find( + list_users(), + fn record -> record[:user] == context[:user] end + ) assert result[:tags] == context[:new_tags] end @tag user: @user, tags: ["imperator"] - test "banner", context do + test "banner", context do assert @command.banner( - [context[:user] | context[:tags]], - context[:opts] - ) - =~ ~r/Setting tags for user \"#{context[:user]}\" to \[#{context[:tags]}\] \.\.\./ + [context[:user] | context[:tags]], + context[:opts] + ) =~ + ~r/Setting tags for user \"#{context[:user]}\" to \[#{context[:tags]}\] \.\.\./ end - end diff --git a/deps/rabbitmq_cli/test/ctl/set_vhost_limits_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_vhost_limits_command_test.exs index b5c679b02f02..725bd5595111 100644 --- a/deps/rabbitmq_cli/test/ctl/set_vhost_limits_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_vhost_limits_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetVhostLimitsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -17,17 +16,16 @@ defmodule SetVhostLimitsCommandTest do setup_all do RabbitMQ.CLI.Core.Distribution.start() - add_vhost @vhost + add_vhost(@vhost) on_exit([], fn -> - delete_vhost @vhost + delete_vhost(@vhost) end) :ok end setup context do - vhost = context[:vhost] || @vhost clear_vhost_limits(vhost) @@ -52,7 +50,10 @@ defmodule SetVhostLimitsCommandTest do end test "merge_defaults: does not change defined vhost" do - assert match?({[], %{vhost: "test_vhost"}}, @command.merge_defaults([], %{vhost: "test_vhost"})) + assert match?( + {[], %{vhost: "test_vhost"}}, + @command.merge_defaults([], %{vhost: "test_vhost"}) + ) end test "validate: providing too few arguments fails validation" do @@ -62,14 +63,16 @@ defmodule SetVhostLimitsCommandTest do test "validate: providing too many arguments fails validation" do assert @command.validate(["too", "many"], %{}) == {:validation_failure, :too_many_args} assert @command.validate(["is", "too", "many"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["this", "is", "too", "many"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["this", "is", "too", "many"], %{}) == + {:validation_failure, :too_many_args} end test "run: a well-formed, host-specific command returns okay", context do assert @command.run( - [context[:definition]], - context[:opts] - ) == :ok + [context[:definition]], + context[:opts] + ) == :ok assert_limits(context) end @@ -85,40 +88,43 @@ defmodule SetVhostLimitsCommandTest do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) assert @command.run( - [context[:definition]], - vhost_opts - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:definition]], + vhost_opts + ) == {:error, {:no_such_vhost, context[:vhost]}} end test "run: an invalid definition returns a JSON decoding error", context do - assert match?({:error_string, _}, - @command.run(["bad_value"], context[:opts])) + assert match?( + {:error_string, _}, + @command.run(["bad_value"], context[:opts]) + ) assert get_vhost_limits(context[:vhost]) == %{} end test "run: invalid limit returns an error", context do assert @command.run( - ["{\"foo\":\"bar\"}"], - context[:opts] - ) == {:error_string, 'Validation failed\n\nUnrecognised terms [{<<"foo">>,<<"bar">>}] in limits\n'} + ["{\"foo\":\"bar\"}"], + context[:opts] + ) == + {:error_string, + 'Validation failed\n\nUnrecognised terms [{<<"foo">>,<<"bar">>}] in limits\n'} assert get_vhost_limits(context[:vhost]) == %{} end test "run: an empty JSON object definition unsets all limits for vhost", context do - assert @command.run( - [@definition], - context[:opts] - ) == :ok + [@definition], + context[:opts] + ) == :ok assert_limits(context) assert @command.run( - ["{}"], - context[:opts] - ) == :ok + ["{}"], + context[:opts] + ) == :ok assert get_vhost_limits(context[:vhost]) == %{} end @@ -126,8 +132,8 @@ defmodule SetVhostLimitsCommandTest do test "banner", context do vhost_opts = Map.merge(context[:opts], %{vhost: context[:vhost]}) - assert @command.banner([context[:definition]], vhost_opts) - == "Setting vhost limits to \"#{context[:definition]}\" for vhost \"#{context[:vhost]}\" ..." + assert @command.banner([context[:definition]], vhost_opts) == + "Setting vhost limits to \"#{context[:definition]}\" for vhost \"#{context[:vhost]}\" ..." end defp assert_limits(context) do diff --git a/deps/rabbitmq_cli/test/ctl/set_vhost_tags_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_vhost_tags_command_test.exs index 44cde783c966..ce93a4cc982b 100644 --- a/deps/rabbitmq_cli/test/ctl/set_vhost_tags_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_vhost_tags_command_test.exs @@ -4,14 +4,13 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule SetVhostTagsCommandTest do use ExUnit.Case, async: false import TestHelper @command RabbitMQ.CLI.Ctl.Commands.SetVhostTagsCommand - @vhost "vhost99-tests" + @vhost "vhost99-tests" setup_all do RabbitMQ.CLI.Core.Distribution.start() @@ -43,13 +42,14 @@ defmodule SetVhostTagsCommandTest do end @tag vhost: @vhost - test "run: with a single optional argument, adds a single tag", context do + test "run: with a single optional argument, adds a single tag", context do @command.run([context[:vhost], :qa], context[:opts]) - result = Enum.find( - list_vhosts(), - fn(record) -> record[:vhost] == context[:vhost] end - ) + result = + Enum.find( + list_vhosts(), + fn record -> record[:vhost] == context[:vhost] end + ) assert result[:tags] == context[:tags] end @@ -59,81 +59,84 @@ defmodule SetVhostTagsCommandTest do delete_vhost(context[:vhost]) assert @command.run( - [context[:vhost]], - context[:opts] - ) == {:error, {:no_such_vhost, context[:vhost]}} + [context[:vhost]], + context[:opts] + ) == {:error, {:no_such_vhost, context[:vhost]}} end @tag user: @vhost, tags: [:qa, :limited] - test "run: with multiple optional arguments, adds multiple tags", context do + test "run: with multiple optional arguments, adds multiple tags", context do @command.run( [context[:vhost] | context[:tags]], context[:opts] ) - result = Enum.find( - list_vhosts(), - fn(record) -> record[:vhost] == context[:vhost] end - ) + result = + Enum.find( + list_vhosts(), + fn record -> record[:vhost] == context[:vhost] end + ) assert result[:tags] == context[:tags] end @tag user: @vhost, tags: [:qa] - test "run: with no optional arguments, clears virtual host tags", context do + test "run: with no optional arguments, clears virtual host tags", context do set_vhost_tags(context[:vhost], context[:tags]) @command.run([context[:vhost]], context[:opts]) - result = Enum.find( - list_vhosts(), - fn(record) -> record[:vhost] == context[:vhost] end - ) + result = + Enum.find( + list_vhosts(), + fn record -> record[:vhost] == context[:vhost] end + ) assert result[:tags] == [] end @tag user: @vhost, tags: [:qa] - test "run: identical calls are idempotent", context do + test "run: identical calls are idempotent", context do set_vhost_tags(context[:vhost], context[:tags]) assert @command.run( - [context[:vhost] | context[:tags]], - context[:opts] - ) == :ok - - result = Enum.find( - list_vhosts(), - fn(record) -> record[:vhost] == context[:vhost] end - ) + [context[:vhost] | context[:tags]], + context[:opts] + ) == :ok + + result = + Enum.find( + list_vhosts(), + fn record -> record[:vhost] == context[:vhost] end + ) assert result[:tags] == context[:tags] end @tag user: @vhost, old_tags: [:qa], new_tags: [:limited] - test "run: overwrites existing tags them", context do + test "run: overwrites existing tags them", context do set_vhost_tags(context[:vhost], context[:old_tags]) assert @command.run( - [context[:vhost] | context[:new_tags]], - context[:opts] - ) == :ok - - result = Enum.find( - list_vhosts(), - fn(record) -> record[:vhost] == context[:vhost] end - ) + [context[:vhost] | context[:new_tags]], + context[:opts] + ) == :ok + + result = + Enum.find( + list_vhosts(), + fn record -> record[:vhost] == context[:vhost] end + ) assert result[:tags] == context[:new_tags] end @tag user: @vhost, tags: ["abc"] - test "banner", context do + test "banner", context do assert @command.banner( - [context[:vhost] | context[:tags]], - context[:opts] - ) - =~ ~r/Setting tags for virtual host \"#{context[:vhost]}\" to \[#{context[:tags]}\] \.\.\./ + [context[:vhost] | context[:tags]], + context[:opts] + ) =~ + ~r/Setting tags for virtual host \"#{context[:vhost]}\" to \[#{context[:tags]}\] \.\.\./ end - end diff --git a/deps/rabbitmq_cli/test/ctl/set_vm_memory_high_watermark_command_test.exs b/deps/rabbitmq_cli/test/ctl/set_vm_memory_high_watermark_command_test.exs index bd9719ab40b9..080c471ea648 100644 --- a/deps/rabbitmq_cli/test/ctl/set_vm_memory_high_watermark_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/set_vm_memory_high_watermark_command_test.exs @@ -29,7 +29,9 @@ defmodule SetVmMemoryHighWatermarkCommandTest do test "validate: a string returns an error", context do assert @command.validate(["sandwich"], context[:opts]) == {:validation_failure, :bad_argument} - assert @command.validate(["0.4sandwich"], context[:opts]) == {:validation_failure, :bad_argument} + + assert @command.validate(["0.4sandwich"], context[:opts]) == + {:validation_failure, :bad_argument} end test "validate: valid numerical value returns valid", context do @@ -56,15 +58,21 @@ defmodule SetVmMemoryHighWatermarkCommandTest do end test "validate: a negative number returns a bad argument", context do - assert @command.validate(["-0.1"], context[:opts]) == {:validation_failure, {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} + assert @command.validate(["-0.1"], context[:opts]) == + {:validation_failure, + {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} end test "validate: a percentage returns a bad argument", context do - assert @command.validate(["40"], context[:opts]) == {:validation_failure, {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} + assert @command.validate(["40"], context[:opts]) == + {:validation_failure, + {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} end test "validate: a value greater than 1.0 returns a bad argument", context do - assert @command.validate(["1.1"], context[:opts]) == {:validation_failure, {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} + assert @command.validate(["1.1"], context[:opts]) == + {:validation_failure, + {:bad_argument, "The threshold should be a fraction between 0.0 and 1.0"}} end @tag test_timeout: 3000 @@ -75,7 +83,7 @@ defmodule SetVmMemoryHighWatermarkCommandTest do assert match?({:badrpc, _}, @command.run(args, opts)) end -## ---------------------------- Absolute tests -------------------------------- + ## ---------------------------- Absolute tests -------------------------------- test "validate: an absolute call without an argument returns not enough args" do assert @command.validate(["absolute"], %{}) == {:validation_failure, :not_enough_args} @@ -83,55 +91,65 @@ defmodule SetVmMemoryHighWatermarkCommandTest do test "validate: an absolute call with too many arguments returns too many args" do assert @command.validate(["absolute", "too", "many"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: a single absolute integer return valid", context do - assert @command.validate(["absolute","10"], context[:opts]) == :ok + assert @command.validate(["absolute", "10"], context[:opts]) == :ok end + test "run: a single absolute integer return ok", context do - assert @command.run(["absolute","10"], context[:opts]) == :ok + assert @command.run(["absolute", "10"], context[:opts]) == :ok assert status()[:vm_memory_high_watermark] == {:absolute, memory_unit_absolute(10, "")} end test "validate: a single absolute integer with an invalid memory unit fails ", context do - assert @command.validate(["absolute","10bytes"], context[:opts]) == {:validation_failure, {:bad_argument, "Invalid units."}} + assert @command.validate(["absolute", "10bytes"], context[:opts]) == + {:validation_failure, {:bad_argument, "Invalid units."}} end test "validate: a single absolute float with a valid memory unit fails ", context do - assert @command.validate(["absolute","10.0MB"], context[:opts]) == {:validation_failure, {:bad_argument, "The threshold should be an integer."}} + assert @command.validate(["absolute", "10.0MB"], context[:opts]) == + {:validation_failure, {:bad_argument, "The threshold should be an integer."}} end test "validate: a single absolute float with an invalid memory unit fails ", context do - assert @command.validate(["absolute","10.0bytes"], context[:opts]) == {:validation_failure, {:bad_argument, "The threshold should be an integer."}} + assert @command.validate(["absolute", "10.0bytes"], context[:opts]) == + {:validation_failure, {:bad_argument, "The threshold should be an integer."}} end test "validate: a single absolute string fails ", context do - assert @command.validate(["absolute","large"], context[:opts]) == {:validation_failure, :bad_argument} + assert @command.validate(["absolute", "large"], context[:opts]) == + {:validation_failure, :bad_argument} end test "validate: a single absolute string with a valid unit fails ", context do - assert @command.validate(["absolute","manyGB"], context[:opts]) == {:validation_failure, :bad_argument} + assert @command.validate(["absolute", "manyGB"], context[:opts]) == + {:validation_failure, :bad_argument} end test "run: a single absolute integer with memory units return ok", context do memory_units() |> Enum.each(fn mu -> arg = "10#{mu}" - assert @command.run(["absolute",arg], context[:opts]) == :ok + assert @command.run(["absolute", arg], context[:opts]) == :ok assert status()[:vm_memory_high_watermark] == {:absolute, memory_unit_absolute(10, mu)} end) end test "run: low watermark sets alarm", context do old_watermark = status()[:vm_memory_high_watermark] - on_exit(fn() -> - args = case old_watermark do - {:absolute, val} -> ["absolute", to_string(val)]; - other -> [to_string(other)] - end + + on_exit(fn -> + args = + case old_watermark do + {:absolute, val} -> ["absolute", to_string(val)] + other -> [to_string(other)] + end + @command.run(args, context[:opts]) end) + ## this will trigger an alarm @command.run(["absolute", "2000"], context[:opts]) @@ -139,24 +157,24 @@ defmodule SetVmMemoryHighWatermarkCommandTest do end test "banner: absolute memory request prints info message", context do - assert @command.banner(["absolute", "10"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to 10 bytes .../ + assert @command.banner(["absolute", "10"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to 10 bytes .../ - assert @command.banner(["absolute", "-10"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to -10 bytes .../ + assert @command.banner(["absolute", "-10"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to -10 bytes .../ - assert @command.banner(["absolute", "sandwich"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to sandwich bytes .../ + assert @command.banner(["absolute", "sandwich"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to sandwich bytes .../ end test "banner, relative memory", context do - assert @command.banner(["0.7"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to 0.7 .../ + assert @command.banner(["0.7"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to 0.7 .../ - assert @command.banner(["-0.7"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to -0.7 .../ + assert @command.banner(["-0.7"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to -0.7 .../ - assert @command.banner(["sandwich"], context[:opts]) - =~ ~r/Setting memory threshold on #{get_rabbit_hostname()} to sandwich .../ + assert @command.banner(["sandwich"], context[:opts]) =~ + ~r/Setting memory threshold on #{get_rabbit_hostname()} to sandwich .../ end end diff --git a/deps/rabbitmq_cli/test/ctl/shutdown_command_test.exs b/deps/rabbitmq_cli/test/ctl/shutdown_command_test.exs index 153c136c4b01..9ba722845c53 100644 --- a/deps/rabbitmq_cli/test/ctl/shutdown_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/shutdown_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ShutdownCommandTest do use ExUnit.Case, async: false import TestHelper @@ -30,8 +29,10 @@ defmodule ShutdownCommandTest do end test "validate: in wait mode, checks if local and target node hostnames match" do - assert match?({:validation_failure, {:unsupported_target, _}}, - @command.validate([], %{wait: true, node: :'rabbit@some.remote.hostname'})) + assert match?( + {:validation_failure, {:unsupported_target, _}}, + @command.validate([], %{wait: true, node: :"rabbit@some.remote.hostname"}) + ) end test "validate: in wait mode, always assumes @localhost nodes are local" do diff --git a/deps/rabbitmq_cli/test/ctl/start_app_command_test.exs b/deps/rabbitmq_cli/test/ctl/start_app_command_test.exs index bdd8632842bc..e3c394226029 100644 --- a/deps/rabbitmq_cli/test/ctl/start_app_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/start_app_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule StartAppCommandTest do use ExUnit.Case, async: false import TestHelper diff --git a/deps/rabbitmq_cli/test/ctl/status_command_test.exs b/deps/rabbitmq_cli/test/ctl/status_command_test.exs index 03ab6cb8fc94..8cff02025f09 100644 --- a/deps/rabbitmq_cli/test/ctl/status_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/status_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule StatusCommandTest do use ExUnit.Case, async: false import TestHelper diff --git a/deps/rabbitmq_cli/test/ctl/stop_app_command_test.exs b/deps/rabbitmq_cli/test/ctl/stop_app_command_test.exs index 60551b21891a..af2b4efbc0be 100644 --- a/deps/rabbitmq_cli/test/ctl/stop_app_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/stop_app_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule StopAppCommandTest do use ExUnit.Case, async: false import TestHelper @@ -44,6 +43,7 @@ defmodule StopAppCommandTest do end test "banner", context do - assert @command.banner([], context[:opts]) =~ ~r/Stopping rabbit application on node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Stopping rabbit application on node #{get_rabbit_hostname()}/ end end diff --git a/deps/rabbitmq_cli/test/ctl/stop_command_test.exs b/deps/rabbitmq_cli/test/ctl/stop_command_test.exs index 2f1dca2eaedc..80594e3aa4f4 100644 --- a/deps/rabbitmq_cli/test/ctl/stop_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/stop_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule StopCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,8 +17,7 @@ defmodule StopCommandTest do end setup do - {:ok, opts: %{node: get_rabbit_hostname(), - idempotent: false}} + {:ok, opts: %{node: get_rabbit_hostname(), idempotent: false}} end test "validate accepts no arguments", context do @@ -31,7 +29,8 @@ defmodule StopCommandTest do end test "validate: with extra arguments returns an arg count error", context do - assert @command.validate(["/path/to/pidfile.pid", "extra"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate(["/path/to/pidfile.pid", "extra"], context[:opts]) == + {:validation_failure, :too_many_args} end # NB: as this commands shuts down the Erlang vm it isn't really practical to test it here @@ -47,6 +46,7 @@ defmodule StopCommandTest do end test "banner", context do - assert @command.banner([], context[:opts]) =~ ~r/Stopping and halting node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Stopping and halting node #{get_rabbit_hostname()}/ end end diff --git a/deps/rabbitmq_cli/test/ctl/suspend_listeners_command_test.exs b/deps/rabbitmq_cli/test/ctl/suspend_listeners_command_test.exs index 88beb768fd42..9b2c23807866 100644 --- a/deps/rabbitmq_cli/test/ctl/suspend_listeners_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/suspend_listeners_command_test.exs @@ -16,6 +16,7 @@ defmodule SuspendListenersCommandTest do resume_all_client_listeners() node_name = get_rabbit_hostname() + on_exit(fn -> resume_all_client_listeners() close_all_connections(node_name) @@ -38,7 +39,7 @@ defmodule SuspendListenersCommandTest do test "validate: with extra arguments returns an arg count error", context do assert @command.validate(["extra"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: request to a non-existent node returns a badrpc" do diff --git a/deps/rabbitmq_cli/test/ctl/sync_queue_command_test.exs b/deps/rabbitmq_cli/test/ctl/sync_queue_command_test.exs index 3d3f866dd051..780ff43f86e9 100644 --- a/deps/rabbitmq_cli/test/ctl/sync_queue_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/sync_queue_command_test.exs @@ -25,25 +25,26 @@ defmodule SyncQueueCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname(), - vhost: @vhost - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + vhost: @vhost + }} end test "validate: specifying no queue name is reported as an error", context do assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} + {:validation_failure, :not_enough_args} end test "validate: specifying two queue names is reported as an error", context do assert @command.validate(["q1", "q2"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: specifying three queue names is reported as an error", context do assert @command.validate(["q1", "q2", "q3"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: specifying one queue name succeeds", context do diff --git a/deps/rabbitmq_cli/test/ctl/trace_off_command_test.exs b/deps/rabbitmq_cli/test/ctl/trace_off_command_test.exs index 0ea53774cbea..b938e3c2c3eb 100644 --- a/deps/rabbitmq_cli/test/ctl/trace_off_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/trace_off_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule TraceOffCommandTest do use ExUnit.Case, async: false import TestHelper @@ -72,7 +71,7 @@ defmodule TraceOffCommandTest do @tag vhost: @default_vhost test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Stopping tracing for vhost "#{context[:vhost]}" .../ + assert @command.banner([], context[:opts]) =~ + ~r/Stopping tracing for vhost "#{context[:vhost]}" .../ end end diff --git a/deps/rabbitmq_cli/test/ctl/trace_on_command_test.exs b/deps/rabbitmq_cli/test/ctl/trace_on_command_test.exs index 4db58772a140..ec249b0447a0 100644 --- a/deps/rabbitmq_cli/test/ctl/trace_on_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/trace_on_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule TraceOnCommandTest do use ExUnit.Case, async: false import TestHelper @@ -73,7 +72,7 @@ defmodule TraceOnCommandTest do @tag vhost: @default_vhost test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Starting tracing for vhost "#{context[:vhost]}" .../ + assert @command.banner([], context[:opts]) =~ + ~r/Starting tracing for vhost "#{context[:vhost]}" .../ end end diff --git a/deps/rabbitmq_cli/test/ctl/update_cluster_nodes_command_test.exs b/deps/rabbitmq_cli/test/ctl/update_cluster_nodes_command_test.exs index b94c21f1be16..f35d734f67ca 100644 --- a/deps/rabbitmq_cli/test/ctl/update_cluster_nodes_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/update_cluster_nodes_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2016-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule UpdateClusterNodesCommandTest do use ExUnit.Case, async: false import TestHelper @@ -24,26 +23,30 @@ defmodule UpdateClusterNodesCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname() - }} + {:ok, + opts: %{ + node: get_rabbit_hostname() + }} end test "validate: providing too few arguments fails validation", context do assert @command.validate([], context[:opts]) == - {:validation_failure, :not_enough_args} + {:validation_failure, :not_enough_args} end test "validate: providing too many arguments fails validation", context do assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: specifying self as seed node fails validation", context do stop_rabbitmq_app() + assert match?( - {:error, :cannot_cluster_node_with_itself}, - @command.run([context[:opts][:node]], context[:opts])) + {:error, :cannot_cluster_node_with_itself}, + @command.run([context[:opts][:node]], context[:opts]) + ) + start_rabbitmq_app() end @@ -52,29 +55,35 @@ defmodule UpdateClusterNodesCommandTest do node: :jake@thedog, timeout: 200 } + assert match?( - {:badrpc, :nodedown}, - @command.run([context[:opts][:node]], opts)) + {:badrpc, :nodedown}, + @command.run([context[:opts][:node]], opts) + ) end test "run: specifying an unreachable node as seed returns a badrpc", context do stop_rabbitmq_app() + assert match?( - {:badrpc_multi, _, [_]}, - @command.run([:jake@thedog], context[:opts])) + {:badrpc_multi, _, [_]}, + @command.run([:jake@thedog], context[:opts]) + ) + start_rabbitmq_app() end test "banner", context do assert @command.banner(["a"], context[:opts]) =~ - ~r/Will seed #{get_rabbit_hostname()} from a on next start/ + ~r/Will seed #{get_rabbit_hostname()} from a on next start/ end test "output mnesia is running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, - "Mnesia is still running on node " <> _}, - @command.output({:error, :mnesia_unexpectedly_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + assert match?( + {:error, ^exit_code, "Mnesia is still running on node " <> _}, + @command.output({:error, :mnesia_unexpectedly_running}, context[:opts]) + ) end end diff --git a/deps/rabbitmq_cli/test/ctl/version_command_test.exs b/deps/rabbitmq_cli/test/ctl/version_command_test.exs index 76216b6cf0a9..a7bc42ad8bcf 100644 --- a/deps/rabbitmq_cli/test/ctl/version_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/version_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule VersionCommandTest do use ExUnit.Case diff --git a/deps/rabbitmq_cli/test/ctl/wait_command_test.exs b/deps/rabbitmq_cli/test/ctl/wait_command_test.exs index c1fd604245e2..6c5d2e977ce6 100644 --- a/deps/rabbitmq_cli/test/ctl/wait_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/wait_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule WaitCommandTest do use ExUnit.Case, async: false import TestHelper @@ -22,44 +21,44 @@ defmodule WaitCommandTest do RabbitMQ.CLI.Core.Distribution.start() rabbitmq_home = :rabbit_misc.rpc_call(get_rabbit_hostname(), :code, :lib_dir, [:rabbit]) - {:ok, opts: %{node: get_rabbit_hostname(), - rabbitmq_home: rabbitmq_home, - timeout: 500}} + {:ok, opts: %{node: get_rabbit_hostname(), rabbitmq_home: rabbitmq_home, timeout: 500}} end - test "validate: cannot have both pid and pidfile", context do {:validation_failure, "Cannot specify both pid and pidfile"} = @command.validate(["pid_file"], Map.merge(context[:opts], %{pid: 123})) end test "validate: should have either pid or pidfile", context do - {:validation_failure, "No pid or pidfile specified"} = - @command.validate([], context[:opts]) + {:validation_failure, "No pid or pidfile specified"} = @command.validate([], context[:opts]) end test "validate: with more than one argument returns an arg count error", context do - assert @command.validate(["pid_file", "extra"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate(["pid_file", "extra"], context[:opts]) == + {:validation_failure, :too_many_args} end test "run: times out waiting for non-existent pid file", context do - {:error, {:timeout, _}} = @command.run(["pid_file"], context[:opts]) |> Enum.to_list |> List.last + {:error, {:timeout, _}} = + @command.run(["pid_file"], context[:opts]) |> Enum.to_list() |> List.last() end test "run: fails if pid process does not exist", context do non_existent_pid = get_non_existent_os_pid() + {:error, :process_not_running} = @command.run([], Map.merge(context[:opts], %{pid: non_existent_pid})) - |> Enum.to_list - |> List.last + |> Enum.to_list() + |> List.last() end test "run: times out if unable to communicate with the node", context do pid = String.to_integer(System.get_pid()) + {:error, {:timeout, _}} = @command.run([], Map.merge(context[:opts], %{pid: pid, node: :nonode@nohost})) - |> Enum.to_list - |> List.last + |> Enum.to_list() + |> List.last() end test "run: happy path", context do @@ -79,21 +78,30 @@ defmodule WaitCommandTest do end test "output: process not running error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, "Error: process is not running."}, - @command.output({:error, :process_not_running}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + + assert match?( + {:error, ^exit_code, "Error: process is not running."}, + @command.output({:error, :process_not_running}, context[:opts]) + ) end test "output: garbage in pid file error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, "Error: garbage in pid file."}, - @command.output({:error, {:garbage_in_pid_file, "somefile"}}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + + assert match?( + {:error, ^exit_code, "Error: garbage in pid file."}, + @command.output({:error, {:garbage_in_pid_file, "somefile"}}, context[:opts]) + ) end test "output: could not read pid error", context do - exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software - assert match?({:error, ^exit_code, "Error: could not read pid. Detail: something wrong"}, - @command.output({:error, {:could_not_read_pid, "something wrong"}}, context[:opts])) + exit_code = RabbitMQ.CLI.Core.ExitCodes.exit_software() + + assert match?( + {:error, ^exit_code, "Error: could not read pid. Detail: something wrong"}, + @command.output({:error, {:could_not_read_pid, "something wrong"}}, context[:opts]) + ) end test "output: default output is fine", context do @@ -107,7 +115,7 @@ defmodule WaitCommandTest do def get_non_existent_os_pid(pid \\ 2) do case :rabbit_misc.is_os_process_alive(to_charlist(pid)) do - true -> get_non_existent_os_pid(pid + 1) + true -> get_non_existent_os_pid(pid + 1) false -> pid end end diff --git a/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs index 70a2bfda6410..cfc5a4fc4a08 100644 --- a/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs @@ -24,10 +24,11 @@ defmodule AlarmsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -44,7 +45,10 @@ defmodule AlarmsCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: when target node has no alarms in effect, returns an empty list", context do @@ -55,9 +59,11 @@ defmodule AlarmsCommandTest do test "run: when target node has an alarm in effect, returns it", context do old_watermark = status()[:vm_memory_high_watermark] - on_exit(fn() -> + + on_exit(fn -> set_vm_memory_high_watermark(old_watermark) end) + # 2000 bytes will trigger an alarm set_vm_memory_high_watermark({:absolute, 2000}) diff --git a/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs index f5b64282e3fa..5f4aa9e785af 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs @@ -24,10 +24,11 @@ defmodule CheckAlarmsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -44,7 +45,10 @@ defmodule CheckAlarmsCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when target node has no alarms in effect, returns an empty list", context do @@ -55,9 +59,11 @@ defmodule CheckAlarmsCommandTest do test "run: when target node has an alarm in effect, returns it", context do old_watermark = status()[:vm_memory_high_watermark] - on_exit(fn() -> + + on_exit(fn -> set_vm_memory_high_watermark(old_watermark) end) + # 2000 bytes will trigger an alarm set_vm_memory_high_watermark({:absolute, 2000}) @@ -67,7 +73,6 @@ defmodule CheckAlarmsCommandTest do set_vm_memory_high_watermark(old_watermark) end - test "output: when target node has no alarms in effect, returns a success", context do assert [] == status()[:alarms] @@ -85,17 +90,18 @@ defmodule CheckAlarmsCommandTest do ], [ :file_descriptor_limit, - {{:resource_limit, :disk, :hare@warp10}, []}, - {{:resource_limit, :memory, :hare@warp10}, []}, - {{:resource_limit, :disk, :rabbit@warp10}, []}, + {{:resource_limit, :disk, :hare@warp10}, []}, + {{:resource_limit, :memory, :hare@warp10}, []}, + {{:resource_limit, :disk, :rabbit@warp10}, []}, {{:resource_limit, :memory, :rabbit@warp10}, []} ] ] do - assert match?({:error, _, _}, @command.output(input, context[:opts])) + assert match?({:error, _, _}, @command.output(input, context[:opts])) end end - test "output: when target node has an alarm in effect and --silent is passed, returns a silent failure", _context do + test "output: when target node has an alarm in effect and --silent is passed, returns a silent failure", + _context do for input <- [ [ :file_descriptor_limit @@ -106,13 +112,13 @@ defmodule CheckAlarmsCommandTest do ], [ :file_descriptor_limit, - {{:resource_limit, :disk, :hare@warp10}, []}, - {{:resource_limit, :memory, :hare@warp10}, []}, - {{:resource_limit, :disk, :rabbit@warp10}, []}, + {{:resource_limit, :disk, :hare@warp10}, []}, + {{:resource_limit, :memory, :hare@warp10}, []}, + {{:resource_limit, :disk, :rabbit@warp10}, []}, {{:resource_limit, :memory, :rabbit@warp10}, []} ] ] do - assert {:error, :check_failed} == @command.output(input, %{silent: true}) + assert {:error, :check_failed} == @command.output(input, %{silent: true}) end end end diff --git a/deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs index 0aaf66c70750..61eac97bfba9 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs @@ -24,10 +24,11 @@ defmodule CheckLocalAlarmsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -44,7 +45,10 @@ defmodule CheckLocalAlarmsCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when target node has no alarms in effect, returns an empty list", context do @@ -55,9 +59,11 @@ defmodule CheckLocalAlarmsCommandTest do test "run: when target node has a local alarm in effect, returns it", context do old_watermark = status()[:vm_memory_high_watermark] - on_exit(fn() -> + + on_exit(fn -> set_vm_memory_high_watermark(old_watermark) end) + # 2000 bytes will trigger an alarm set_vm_memory_high_watermark({:absolute, 2000}) @@ -81,16 +87,17 @@ defmodule CheckLocalAlarmsCommandTest do ], [ :file_descriptor_limit, - {{:resource_limit, :disk, get_rabbit_hostname()}, []}, + {{:resource_limit, :disk, get_rabbit_hostname()}, []}, {{:resource_limit, :memory, get_rabbit_hostname()}, []} ] ] do - assert match?({:error, _}, @command.output(input, context[:opts])) + assert match?({:error, _}, @command.output(input, context[:opts])) end end # note: it's run/2 that filters out non-local alarms - test "output: when target node has an alarm in effect and --silent is passed, returns a silent failure", _context do + test "output: when target node has an alarm in effect and --silent is passed, returns a silent failure", + _context do for input <- [ [ :file_descriptor_limit @@ -101,11 +108,11 @@ defmodule CheckLocalAlarmsCommandTest do ], [ :file_descriptor_limit, - {{:resource_limit, :disk, get_rabbit_hostname()}, []}, + {{:resource_limit, :disk, get_rabbit_hostname()}, []}, {{:resource_limit, :memory, get_rabbit_hostname()}, []} ] ] do - assert {:error, :check_failed} == @command.output(input, %{silent: true}) + assert {:error, :check_failed} == @command.output(input, %{silent: true}) end end end diff --git a/deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs index 845a7b6f1d88..4e618932719d 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs @@ -17,10 +17,11 @@ defmodule CheckPortConnectivityCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: provides a default timeout" do @@ -37,23 +38,26 @@ defmodule CheckPortConnectivityCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: tries to connect to every inferred active listener", context do assert match?({true, _}, @command.run([], context[:opts])) end - test "output: when all connections succeeded, returns a success", context do assert match?({:ok, _}, @command.output({true, []}, context[:opts])) end # note: it's run/2 that filters out non-local alarms test "output: when target node has a local alarm in effect, returns a failure", context do - failure = {:listener, :rabbit@mercurio, :lolz, 'mercurio', - {0, 0, 0, 0, 0, 0, 0, 0}, 7761613, - [backlog: 128, nodelay: true]} + failure = + {:listener, :rabbit@mercurio, :lolz, 'mercurio', {0, 0, 0, 0, 0, 0, 0, 0}, 7_761_613, + [backlog: 128, nodelay: true]} + assert match?({:error, _}, @command.output({false, [failure]}, context[:opts])) end end diff --git a/deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs index 7c0428c19031..2202ee73fd1b 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs @@ -17,10 +17,11 @@ defmodule CheckPortListenerCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -41,7 +42,10 @@ defmodule CheckPortListenerCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([61613], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([61613], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when a listener for the protocol is active, returns a success", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs index a6aef88bc1a6..c100294ac43b 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs @@ -17,10 +17,11 @@ defmodule CheckProtocolListenerCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -41,7 +42,10 @@ defmodule CheckProtocolListenerCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run(["stomp"], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run(["stomp"], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when a listener for the protocol is active, returns a success", context do @@ -54,7 +58,8 @@ defmodule CheckProtocolListenerCommandTest do end end - test "run: when a listener for the protocol is not active or unknown, returns an error", context do + test "run: when a listener for the protocol is not active or unknown, returns an error", + context do assert match?({false, _, _}, @command.run(["non-existent-proto"], context[:opts])) end diff --git a/deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs index ab89d1e89e30..de66e4288cd4 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs @@ -23,10 +23,11 @@ defmodule CheckRunningCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -43,7 +44,10 @@ defmodule CheckRunningCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when the RabbitMQ app is booted and started, returns true", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs index 2fab76ae9b35..a170b22bdc4c 100644 --- a/deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs @@ -17,10 +17,11 @@ defmodule CheckVirtualHostsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: is a no-op" do @@ -37,7 +38,10 @@ defmodule CheckVirtualHostsCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "output: when all virtual hosts are reported as up, returns a success", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs index 2ee5edddb8e1..1cd1abca59b7 100644 --- a/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule CipherSuitesCommandTest do use ExUnit.Case import TestHelper @@ -18,12 +17,13 @@ defmodule CipherSuitesCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - format: context[:format] || "openssl", - all: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + format: context[:format] || "openssl", + all: false + }} end test "merge_defaults: defaults to the OpenSSL format" do @@ -31,8 +31,12 @@ defmodule CipherSuitesCommandTest do end test "merge_defaults: format is case insensitive" do - assert @command.merge_defaults([], %{format: "OpenSSL"}) == {[], %{format: "openssl", all: false}} - assert @command.merge_defaults([], %{format: "Erlang"}) == {[], %{format: "erlang", all: false}} + assert @command.merge_defaults([], %{format: "OpenSSL"}) == + {[], %{format: "openssl", all: false}} + + assert @command.merge_defaults([], %{format: "Erlang"}) == + {[], %{format: "erlang", all: false}} + assert @command.merge_defaults([], %{format: "Map"}) == {[], %{format: "map", all: false}} end @@ -41,7 +45,8 @@ defmodule CipherSuitesCommandTest do end test "validate: treats positional arguments as a failure", context do - assert @command.validate(["extra-arg"], context[:opts]) == {:validation_failure, :too_many_args} + assert @command.validate(["extra-arg"], context[:opts]) == + {:validation_failure, :too_many_args} end test "validate: treats empty positional arguments and default switches as a success", context do @@ -56,13 +61,16 @@ defmodule CipherSuitesCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag format: "openssl" test "run: returns a list of cipher suites in OpenSSL format", context do res = @command.run([], context[:opts]) - for cipher <- res, do: assert true == is_list(cipher) + for cipher <- res, do: assert(true == is_list(cipher)) # the list is long and its values are environment-specific, # so we simply assert that it is non-empty. MK. assert length(res) > 0 @@ -72,7 +80,7 @@ defmodule CipherSuitesCommandTest do test "run: returns a list of cipher suites in erlang format", context do res = @command.run([], context[:opts]) - for cipher <- res, do: assert true = is_tuple(cipher) + for cipher <- res, do: assert(true = is_tuple(cipher)) # the list is long and its values are environment-specific, # so we simply assert that it is non-empty. MK. assert length(res) > 0 @@ -81,7 +89,7 @@ defmodule CipherSuitesCommandTest do @tag format: "map" test "run: returns a list of cipher suites in map format", context do res = @command.run([], context[:opts]) - for cipher <- res, do: assert true = is_map(cipher) + for cipher <- res, do: assert(true = is_map(cipher)) # the list is long and its values are environment-specific, # so we simply assert that it is non-empty. MK. assert length(res) > 0 @@ -97,5 +105,4 @@ defmodule CipherSuitesCommandTest do assert length(all_suites) > length(default_suites) assert length(default_suites -- all_suites) == 0 end - end diff --git a/deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs index caa959ce4469..859b460cb5e5 100644 --- a/deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule CommandLineArgumentsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -21,13 +20,14 @@ defmodule CommandLineArgumentsCommandTest do {:ok, opts: %{node: get_rabbit_hostname(), timeout: :infinity}} end - test "validate: with extra arguments, command line arguments returns an arg count error", context do + test "validate: with extra arguments, command line arguments returns an arg count error", + context do assert @command.validate(["extra"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "run: command line arguments request to a reachable node succeeds", context do - output = @command.run([], context[:opts]) |> Enum.to_list + output = @command.run([], context[:opts]) |> Enum.to_list() assert_stream_without_errors(output) end @@ -38,7 +38,7 @@ defmodule CommandLineArgumentsCommandTest do end test "banner", context do - assert @command.banner([], context[:opts]) - =~ ~r/Command line arguments of node #{get_rabbit_hostname()}/ + assert @command.banner([], context[:opts]) =~ + ~r/Command line arguments of node #{get_rabbit_hostname()}/ end end diff --git a/deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs index b11cdb38c236..63c3d4daab07 100644 --- a/deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs @@ -15,7 +15,7 @@ defmodule ConsumeEventStreamCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,18 +25,18 @@ defmodule ConsumeEventStreamCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - duration: :infinity, - pattern: ".*" - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + duration: :infinity, + pattern: ".*" + }} end test "merge_defaults: duration defaults to infinity, pattern to anything" do - assert @command.merge_defaults([], %{}) == {[], %{duration: :infinity, - pattern: ".*", - quiet: true}} + assert @command.merge_defaults([], %{}) == + {[], %{duration: :infinity, pattern: ".*", quiet: true}} end test "validate: treats positional arguments as a failure" do @@ -49,25 +49,30 @@ defmodule ConsumeEventStreamCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: consumes events for N seconds", context do - stream = @command.run([], Map.merge(context[:opts], %{duration: 5})) - :rpc.call(get_rabbit_hostname(), :rabbit_event, :notify, [String.to_atom("event_type1"), - [{String.to_atom("args"), 1}]]) - :rpc.call(get_rabbit_hostname(), :rabbit_event, :notify, [String.to_atom("event_type2"), - [{String.to_atom("pid"), self()}]]) + :rpc.call(get_rabbit_hostname(), :rabbit_event, :notify, [ + String.to_atom("event_type1"), + [{String.to_atom("args"), 1}] + ]) + + :rpc.call(get_rabbit_hostname(), :rabbit_event, :notify, [ + String.to_atom("event_type2"), + [{String.to_atom("pid"), self()}] + ]) - event1 = Enum.find(stream, nil, fn x -> Keyword.get(x, :event, nil) == "event.type1" end) - event2 = Enum.find(stream, nil, fn x -> Keyword.get(x, :event, nil) == "event.type2" end) + event1 = Enum.find(stream, nil, fn x -> Keyword.get(x, :event, nil) == "event.type1" end) + event2 = Enum.find(stream, nil, fn x -> Keyword.get(x, :event, nil) == "event.type2" end) assert event1 != nil assert event2 != nil assert Keyword.get(event1, :args, nil) == 1 assert is_binary(Keyword.get(event2, :pid, nil)) - end - end diff --git a/deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs index 7a2b4295c74c..59999815abf7 100644 --- a/deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs @@ -24,12 +24,15 @@ defmodule DisbleAuthAttemptSourceTrackingCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end - @tag test_timeout: 3000 + @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 15000 diff --git a/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs index dd54d6eed93d..a2cee7c4073e 100644 --- a/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs @@ -24,12 +24,15 @@ defmodule DiscoverPeersCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 15000 diff --git a/deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs index c55ac6134be8..6f1ccfb45ab4 100644 --- a/deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs @@ -24,12 +24,15 @@ defmodule EnableAuthAttemptSourceTrackingCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end - @tag test_timeout: 3000 + @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 15000 diff --git a/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs index 5dff653989b2..725cc31080fa 100644 --- a/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ErlangCookieHashCommandTest do use ExUnit.Case import TestHelper @@ -18,10 +17,11 @@ defmodule ErlangCookieHashCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} end test "merge_defaults: nothing to do" do @@ -46,5 +46,4 @@ defmodule ErlangCookieHashCommandTest do res = @command.run([], context[:opts]) assert is_bitstring(res) end - end diff --git a/deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs index 3bdaa645e234..c72b760024f1 100644 --- a/deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ErlangVersionCommandTest do use ExUnit.Case import TestHelper @@ -18,12 +17,13 @@ defmodule ErlangVersionCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - details: false, - offline: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + details: false, + offline: false + }} end test "merge_defaults: defaults to remote version and abbreviated output" do @@ -52,7 +52,10 @@ defmodule ErlangVersionCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, details: false}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, details: false})) + ) end test "run: returns Erlang/OTP version on the target node", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs index fc7c2595a97b..065e0a535d05 100644 --- a/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs @@ -23,10 +23,11 @@ defmodule IsBootingCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -43,7 +44,10 @@ defmodule IsBootingCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when the RabbitMQ app is fully booted and running, returns false", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs index 120af9d7d7b9..40ec65e26e28 100644 --- a/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs @@ -23,10 +23,11 @@ defmodule IsRunningCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -43,7 +44,10 @@ defmodule IsRunningCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: when the RabbitMQ app is booted and started, returns true", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs index ccaac33d9b94..3e35a487ba71 100644 --- a/deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs @@ -24,12 +24,15 @@ defmodule ListNetworkInterfacesCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end - @tag test_timeout: 3000 + @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 15000 diff --git a/deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs index c6ac28a340e0..7bf9c9566255 100644 --- a/deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs @@ -24,12 +24,15 @@ defmodule ListNodeAuthAttemptStatsCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end - @tag test_timeout: 3000 + @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 15000 diff --git a/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs index fc20cae7fc92..b9d3951ce11f 100644 --- a/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs @@ -24,10 +24,11 @@ defmodule ListenersCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -44,20 +45,24 @@ defmodule ListenersCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: returns a list of node-local listeners", context do xs = @command.run([], context[:opts]) |> listener_maps assert length(xs) >= 3 + for p <- [5672, 61613, 25672] do assert Enum.any?(xs, fn %{port: port} -> port == p end) end end test "output: returns a formatted list of node-local listeners", context do - raw = @command.run([], context[:opts]) + raw = @command.run([], context[:opts]) {:ok, msg} = @command.output(raw, context[:opts]) for p <- [5672, 61613, 25672] do @@ -66,11 +71,12 @@ defmodule ListenersCommandTest do end test "output: when formatter is JSON, returns an array of listener maps", context do - raw = @command.run([], context[:opts]) + raw = @command.run([], context[:opts]) {:ok, doc} = @command.output(raw, Map.merge(%{formatter: "json"}, context[:opts])) - xs = doc["listeners"] + xs = doc["listeners"] assert length(xs) >= 3 + for p <- [5672, 61613, 25672] do assert Enum.any?(xs, fn %{port: port} -> port == p end) end diff --git a/deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs index 4700b96a0fbd..8dcc141701d8 100644 --- a/deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs @@ -15,7 +15,7 @@ defmodule LogLocationCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,15 +25,16 @@ defmodule LogLocationCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - all: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + all: false + }} end test "merge_defaults: all is false" do - assert @command.merge_defaults([], %{}) == {[], %{all: :false}} + assert @command.merge_defaults([], %{}) == {[], %{all: false}} end test "validate: treats positional arguments as a failure" do @@ -41,12 +42,15 @@ defmodule LogLocationCommandTest do end test "validate: treats empty positional arguments and default switches as a success" do - assert @command.validate([], %{all: :false}) == :ok + assert @command.validate([], %{all: false}) == :ok end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: prints default log location", context do @@ -60,16 +64,21 @@ defmodule LogLocationCommandTest do test "run: shows all log locations", context do # This assumes default configuration - [logfile, upgrade_log_file | _] = - @command.run([], Map.merge(context[:opts], %{all: true})) + [logfile, upgrade_log_file | _] = @command.run([], Map.merge(context[:opts], %{all: true})) log_message = "checking the default log file when checking all" :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(log_message)]) wait_for_log_message(log_message, logfile) log_message_upgrade = "checking the upgrade log file when checking all" - :rpc.call(get_rabbit_hostname(), - :rabbit_log, :log, [:upgrade, :error, to_charlist(log_message_upgrade), []]) + + :rpc.call(get_rabbit_hostname(), :rabbit_log, :log, [ + :upgrade, + :error, + to_charlist(log_message_upgrade), + [] + ]) + wait_for_log_message(log_message_upgrade, upgrade_log_file) end end diff --git a/deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs index c9502ca6d510..39eb64f488cf 100644 --- a/deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs @@ -15,7 +15,7 @@ defmodule LogTailCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,11 +25,12 @@ defmodule LogTailCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - number: 50 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + number: 50 + }} end test "merge_defaults: number is 50" do @@ -46,36 +47,48 @@ defmodule LogTailCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: shows last 50 lines from the log by default", context do clear_log_files() + log_messages = - Enum.map(:lists.seq(1, 50), - fn(n) -> - message = "Getting log tail #{n}" - :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) - message - end) + Enum.map( + :lists.seq(1, 50), + fn n -> + message = "Getting log tail #{n}" + :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) + message + end + ) + wait_for_log_message("Getting log tail 50") lines = @command.run([], context[:opts]) assert Enum.count(lines) == 50 - Enum.map(Enum.zip(log_messages, lines), - fn({message, line}) -> - assert String.match?(line, Regex.compile!(message)) - end) + Enum.map( + Enum.zip(log_messages, lines), + fn {message, line} -> + assert String.match?(line, Regex.compile!(message)) + end + ) end test "run: returns N lines", context do ## Log a bunch of lines - Enum.map(:lists.seq(1, 50), - fn(n) -> - message = "More lines #{n}" - :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) - message - end) + Enum.map( + :lists.seq(1, 50), + fn n -> + message = "More lines #{n}" + :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) + message + end + ) + wait_for_log_message("More lines 50") assert Enum.count(@command.run([], Map.merge(context[:opts], %{number: 20}))) == 20 assert Enum.count(@command.run([], Map.merge(context[:opts], %{number: 30}))) == 30 @@ -85,23 +98,27 @@ defmodule LogTailCommandTest do test "run: may return less than N lines if N is high", context do clear_log_files() ## Log a bunch of lines - Enum.map(:lists.seq(1, 100), - fn(n) -> - message = "More lines #{n}" - :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) - message - end) + Enum.map( + :lists.seq(1, 100), + fn n -> + message = "More lines #{n}" + :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist(message)]) + message + end + ) + wait_for_log_message("More lines 50") assert Enum.count(@command.run([], Map.merge(context[:opts], %{number: 50}))) == 50 assert Enum.count(@command.run([], Map.merge(context[:opts], %{number: 200}))) < 200 end def clear_log_files() do - [_|_] = logs = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) - Enum.map(logs, fn(log) -> + [_ | _] = logs = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) + + Enum.map(logs, fn log -> case log do '' -> :ok - _ -> File.write(log, "") + _ -> File.write(log, "") end end) end diff --git a/deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs index e0e4dc06f629..9468632fc996 100644 --- a/deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs @@ -15,7 +15,7 @@ defmodule LogTailStreamCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,11 +25,12 @@ defmodule LogTailStreamCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - duration: :infinity - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + duration: :infinity + }} end test "merge_defaults: duration defaults to infinity" do @@ -46,7 +47,10 @@ defmodule LogTailStreamCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: streams messages for N seconds", context do @@ -81,16 +85,19 @@ defmodule LogTailStreamCommandTest do end def ensure_log_file() do - [log|_] = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) + [log | _] = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) ensure_file(log, 100) end def ensure_file(log, 0) do flunk("timed out trying to ensure the log file #{log}") end + def ensure_file(log, attempts) do case File.exists?(log) do - true -> :ok + true -> + :ok + false -> :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [to_charlist("Ping")]) :timer.sleep(100) @@ -99,8 +106,9 @@ defmodule LogTailStreamCommandTest do end def delete_log_files() do - [_|_] = logs = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) - Enum.map(logs, fn(log) -> + [_ | _] = logs = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) + + Enum.map(logs, fn log -> File.rm(log) end) end diff --git a/deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs index 3b70966d1caf..af1cb2267be9 100644 --- a/deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule MaybeStuckCommandTest do use ExUnit.Case import TestHelper @@ -18,10 +17,11 @@ defmodule MaybeStuckCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 15000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 15000 + }} end test "merge_defaults: returns inputs" do @@ -38,7 +38,10 @@ defmodule MaybeStuckCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 0 diff --git a/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs index 8f7ffb14dc50..0027635e5c66 100644 --- a/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs @@ -23,19 +23,20 @@ defmodule MemoryBreakdownCommandTest do end setup do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: 5000, - unit: "gb" - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: 5000, + unit: "gb" + }} end test "validate: specifying a positional argument fails validation", context do assert @command.validate(["abc"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} assert @command.validate(["abc", "def"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: specifying no positional arguments and no options succeeds", context do @@ -56,7 +57,8 @@ defmodule MemoryBreakdownCommandTest do test "validate: specifying glip-glops as a --unit fails validation", context do assert @command.validate([], Map.merge(context[:opts], %{unit: "glip-glops"})) == - {:validation_failure, "unit 'glip-glops' is not supported. Please use one of: bytes, mb, gb"} + {:validation_failure, + "unit 'glip-glops' is not supported. Please use one of: bytes, mb, gb"} end test "run: request to a non-existent RabbitMQ node returns a nodedown" do diff --git a/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs index 8ff97abb0b0b..5241dd0b0c7d 100644 --- a/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ObserverCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,11 +17,12 @@ defmodule ObserverCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - interval: 5, - timeout: context[:test_timeout] || 15000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + interval: 5, + timeout: context[:test_timeout] || 15000 + }} end test "merge_defaults: injects a default interval of 5s" do diff --git a/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs index 254b41c9f279..5da754614167 100644 --- a/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs @@ -15,7 +15,7 @@ defmodule OsEnvCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,11 +25,12 @@ defmodule OsEnvCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - all: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + all: false + }} end test "merge_defaults: merges no defaults" do @@ -46,7 +47,10 @@ defmodule OsEnvCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: returns defined RabbitMQ-specific environment variables", context do @@ -55,8 +59,8 @@ defmodule OsEnvCommandTest do # Only variables that are used by RABBITMQ are returned. # They can be prefixed with RABBITMQ_ or not, rabbit_env tries both # when filtering env variables down. - assert Enum.any?(vars, fn({k, _v}) -> - String.starts_with?(k, "RABBITMQ_") or String.starts_with?(k, "rabbitmq_") - end) + assert Enum.any?(vars, fn {k, _v} -> + String.starts_with?(k, "RABBITMQ_") or String.starts_with?(k, "rabbitmq_") + end) end end diff --git a/deps/rabbitmq_cli/test/diagnostics/remote_shell_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/remote_shell_command_test.exs index ad03cd06f432..5b7a7fa77909 100644 --- a/deps/rabbitmq_cli/test/diagnostics/remote_shell_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/remote_shell_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule RemoteShellCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,10 +17,11 @@ defmodule RemoteShellCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 15000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 15000 + }} end test "merge_defaults: nothing to do" do diff --git a/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs index 2019154f0cb1..3fde46332afb 100644 --- a/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs @@ -14,7 +14,8 @@ defmodule ResolveHostnameCommandTest do RabbitMQ.CLI.Core.Distribution.start() start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) + on_exit([], fn -> start_rabbitmq_app() end) @@ -23,12 +24,13 @@ defmodule ResolveHostnameCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - address_family: "ipv4", - offline: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + address_family: "ipv4", + offline: false + }} end test "merge_defaults: defaults to IPv4 address family" do @@ -40,15 +42,20 @@ defmodule ResolveHostnameCommandTest do end test "validate: treats positional arguments as a failure" do - assert @command.validate(["elixir-lang.org", "extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["elixir-lang.org", "extra-arg"], %{}) == + {:validation_failure, :too_many_args} end test "validate: address family other than IPv4 or IPv6 fails validation" do - assert match?({:validation_failure, {:bad_argument, _}}, - @command.validate(["elixir-lang.org"], %{address_family: "ipv5"})) - - assert match?({:validation_failure, {:bad_argument, _}}, - @command.validate(["elixir-lang.org"], %{address_family: "IPv5"})) + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate(["elixir-lang.org"], %{address_family: "ipv5"}) + ) + + assert match?( + {:validation_failure, {:bad_argument, _}}, + @command.validate(["elixir-lang.org"], %{address_family: "IPv5"}) + ) end test "validate: IPv4 for address family passes validation" do @@ -69,7 +76,7 @@ defmodule ResolveHostnameCommandTest do test "run: returns a resolution result", context do case @command.run(["github.com"], context[:opts]) do - {:ok, _hostent} -> :ok + {:ok, _hostent} -> :ok {:error, :nxdomain} -> :ok other -> flunk("hostname resolution returned #{other}") end @@ -77,7 +84,7 @@ defmodule ResolveHostnameCommandTest do test "run with --offline: returns a resolution result", context do case @command.run(["github.com"], Map.merge(context[:opts], %{offline: true})) do - {:ok, _hostent} -> :ok + {:ok, _hostent} -> :ok {:error, :nxdomain} -> :ok other -> flunk("hostname resolution returned #{other}") end diff --git a/deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs index 001371ed3726..08a8767d65a6 100644 --- a/deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs @@ -15,7 +15,7 @@ defmodule ResolverInfoCommandTest do start_rabbitmq_app() - ExUnit.configure([max_cases: 1]) + ExUnit.configure(max_cases: 1) on_exit([], fn -> start_rabbitmq_app() @@ -25,11 +25,12 @@ defmodule ResolverInfoCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - offline: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + offline: false + }} end test "merge_defaults: defaults to offline mode" do @@ -46,7 +47,10 @@ defmodule ResolverInfoCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})) + ) end test "run: returns host resolver (inetrc) information", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs index 34ab7b9c635e..fd3672c69436 100644 --- a/deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule RuntimeThreadStatsCommandTest do use ExUnit.Case import TestHelper @@ -18,26 +17,29 @@ defmodule RuntimeThreadStatsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 10000, - sample_interval: 1 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 10000, + sample_interval: 1 + }} end - test "validate: providing no arguments passes validation", context do assert @command.validate([], context[:opts]) == :ok end test "validate: providing any arguments fails validation", context do assert @command.validate(["a"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end @tag test_timeout: 2000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end @tag test_timeout: 6000 diff --git a/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs index 369592522a38..a8e2dbff63e3 100644 --- a/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs @@ -35,32 +35,38 @@ defmodule SchemaInfoCommandTest do test "validate: returns bad_info_key on a single bad arg", context do assert @command.validate(["quack"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} end test "validate: returns multiple bad args return a list of bad info key values", context do assert @command.validate(["quack", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink, :quack]}} + {:validation_failure, {:bad_info_key, [:oink, :quack]}} end test "validate: return bad_info_key on mix of good and bad args", context do assert @command.validate(["quack", "cookie"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:quack]}} + {:validation_failure, {:bad_info_key, [:quack]}} + assert @command.validate(["access_mode", "oink"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} + assert @command.validate(["access_mode", "oink", "name"], context[:opts]) == - {:validation_failure, {:bad_info_key, [:oink]}} + {:validation_failure, {:bad_info_key, [:oink]}} end @tag test_timeout: 0 test "run: timeout causes command to return badrpc", context do assert run_command_to_list(@command, [["source_name"], context[:opts]]) == - {:badrpc, :timeout} + {:badrpc, :timeout} end test "run: can filter info keys", context do wanted_keys = ~w(name access_mode) - assert match?([[name: _, access_mode: _] | _], run_command_to_list(@command, [wanted_keys, context[:opts]])) + + assert match?( + [[name: _, access_mode: _] | _], + run_command_to_list(@command, [wanted_keys, context[:opts]]) + ) end test "banner" do diff --git a/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs index 72c32e32f139..aac9ed39dafc 100644 --- a/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule ServerVersionCommandTest do use ExUnit.Case import TestHelper @@ -18,10 +17,11 @@ defmodule ServerVersionCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: nothing to do" do @@ -38,7 +38,10 @@ defmodule ServerVersionCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end test "run: returns RabbitMQ version on the target node", context do diff --git a/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs index 0e38a0461e48..28f80a64dd2b 100644 --- a/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs +++ b/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs @@ -17,10 +17,11 @@ defmodule TlsVersionsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "merge_defaults: is a no-op" do @@ -37,11 +38,15 @@ defmodule TlsVersionsCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], %{node: :jake@thedog}))) + assert match?( + {:badrpc, _}, + @command.run([], Map.merge(context[:opts], %{node: :jake@thedog})) + ) end - test "run when formatter is set to JSON: return a document with a list of supported TLS versions", context do - m = @command.run([], Map.merge(context[:opts], %{formatter: "json"})) |> Map.new + test "run when formatter is set to JSON: return a document with a list of supported TLS versions", + context do + m = @command.run([], Map.merge(context[:opts], %{formatter: "json"})) |> Map.new() xs = Map.get(m, :available) # assert that we have a list and tlsv1.2 is included @@ -50,7 +55,7 @@ defmodule TlsVersionsCommandTest do end test "run and output: return a list of supported TLS versions", context do - m = @command.run([], context[:opts]) + m = @command.run([], context[:opts]) {:ok, res} = @command.output(m, context[:opts]) # assert that we have a list and tlsv1.2 is included diff --git a/deps/rabbitmq_cli/test/json_formatting.exs b/deps/rabbitmq_cli/test/json_formatting.exs index c0e35e2ad39f..04ac9351c81f 100644 --- a/deps/rabbitmq_cli/test/json_formatting.exs +++ b/deps/rabbitmq_cli/test/json_formatting.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule JSONFormattingTest do use ExUnit.Case, async: false import ExUnit.CaptureIO @@ -24,9 +23,12 @@ defmodule JSONFormattingTest do node = to_string(get_rabbit_hostname()) command = ["status", "-n", node, "--formatter=json"] - output = capture_io(:stdio, fn -> - error_check(command, exit_ok()) - end) + + output = + capture_io(:stdio, fn -> + error_check(command, exit_ok()) + end) + {:ok, doc} = JSON.decode(output) assert Map.has_key?(doc, "memory") @@ -45,9 +47,12 @@ defmodule JSONFormattingTest do node = to_string(get_rabbit_hostname()) command = ["cluster_status", "-n", node, "--formatter=json"] - output = capture_io(:stdio, fn -> - error_check(command, exit_ok()) - end) + + output = + capture_io(:stdio, fn -> + error_check(command, exit_ok()) + end) + {:ok, doc} = JSON.decode(output) assert Enum.member?(doc["disk_nodes"], node) diff --git a/deps/rabbitmq_cli/test/plugins/directories_command_test.exs b/deps/rabbitmq_cli/test/plugins/directories_command_test.exs index cae418717a68..0ee4f7549ec1 100644 --- a/deps/rabbitmq_cli/test/plugins/directories_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/directories_command_test.exs @@ -14,33 +14,34 @@ defmodule DirectoriesCommandTest do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) - {:ok, plugins_expand_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_expand_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + + {:ok, plugins_expand_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_expand_dir]) rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) - {:ok, opts: %{ - plugins_file: plugins_file, - plugins_dir: plugins_dir, - plugins_expand_dir: plugins_expand_dir, - rabbitmq_home: rabbitmq_home, + {:ok, + opts: %{ + plugins_file: plugins_file, + plugins_dir: plugins_dir, + plugins_expand_dir: plugins_expand_dir, + rabbitmq_home: rabbitmq_home }} end setup context do { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end @@ -58,45 +59,53 @@ defmodule DirectoriesCommandTest do test "validate: providing any arguments fails validation", context do assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: setting both --online and --offline to false fails validation", context do assert @command.validate([], Map.merge(context[:opts], %{online: false, offline: false})) == - {:validation_failure, {:bad_argument, "Cannot set online and offline to false"}} + {:validation_failure, {:bad_argument, "Cannot set online and offline to false"}} end test "validate: setting both --online and --offline to true fails validation", context do assert @command.validate([], Map.merge(context[:opts], %{online: true, offline: true})) == - {:validation_failure, {:bad_argument, "Cannot set both online and offline"}} + {:validation_failure, {:bad_argument, "Cannot set both online and offline"}} end - test "validate_execution_environment: when --offline is used, specifying a non-existent enabled_plugins_file passes validation", context do + test "validate_execution_environment: when --offline is used, specifying a non-existent enabled_plugins_file passes validation", + context do opts = context[:opts] |> Map.merge(%{offline: true, enabled_plugins_file: "none"}) assert @command.validate_execution_environment([], opts) == :ok end - test "validate_execution_environment: when --offline is used, specifying a non-existent plugins_dir fails validation", context do + test "validate_execution_environment: when --offline is used, specifying a non-existent plugins_dir fails validation", + context do opts = context[:opts] |> Map.merge(%{offline: true, plugins_dir: "none"}) - assert @command.validate_execution_environment([], opts) == {:validation_failure, :plugins_dir_does_not_exist} + + assert @command.validate_execution_environment([], opts) == + {:validation_failure, :plugins_dir_does_not_exist} end - test "validate_execution_environment: when --online is used, specifying a non-existent enabled_plugins_file passes validation", context do + test "validate_execution_environment: when --online is used, specifying a non-existent enabled_plugins_file passes validation", + context do opts = context[:opts] |> Map.merge(%{online: true, enabled_plugins_file: "none"}) assert @command.validate_execution_environment([], opts) == :ok end - test "validate_execution_environment: when --online is used, specifying a non-existent plugins_dir passes validation", context do + test "validate_execution_environment: when --online is used, specifying a non-existent plugins_dir passes validation", + context do opts = context[:opts] |> Map.merge(%{online: true, plugins_dir: "none"}) assert @command.validate_execution_environment([], opts) == :ok end - test "run: when --online is used, lists plugin directories", context do opts = Map.merge(context[:opts], %{online: true}) - dirs = %{plugins_dir: to_string(Map.get(opts, :plugins_dir)), - plugins_expand_dir: to_string(Map.get(opts, :plugins_expand_dir)), - enabled_plugins_file: to_string(Map.get(opts, :plugins_file))} + + dirs = %{ + plugins_dir: to_string(Map.get(opts, :plugins_dir)), + plugins_expand_dir: to_string(Map.get(opts, :plugins_expand_dir)), + enabled_plugins_file: to_string(Map.get(opts, :plugins_file)) + } assert @command.run([], opts) == {:ok, dirs} end diff --git a/deps/rabbitmq_cli/test/plugins/disable_plugins_command_test.exs b/deps/rabbitmq_cli/test/plugins/disable_plugins_command_test.exs index 22132293e020..da68c485d16c 100644 --- a/deps/rabbitmq_cli/test/plugins/disable_plugins_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/disable_plugins_command_test.exs @@ -16,24 +16,32 @@ defmodule DisablePluginsCommandTest do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) - IO.puts("plugins disable tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}") + IO.puts( + "plugins disable tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}" + ) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - IO.puts("plugins disable tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to") - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - online: false, offline: false, - all: false} + IO.puts( + "plugins disable tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to" + ) + + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + online: false, + offline: false, + all: false + } on_exit(fn -> set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) @@ -43,156 +51,237 @@ defmodule DisablePluginsCommandTest do end setup context do - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], - :online, - get_rabbit_hostname(), - context[:opts]) - + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + get_rabbit_hostname(), + context[:opts] + ) { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end test "validate: specifying both --online and --offline is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["a"], Map.merge(context[:opts], %{online: true, offline: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["a"], Map.merge(context[:opts], %{online: true, offline: true})) + ) end test "validate: not specifying plugins to enable is reported as invalid", context do assert match?( - {:validation_failure, :not_enough_args}, - @command.validate([], Map.merge(context[:opts], %{online: true, offline: false})) - ) + {:validation_failure, :not_enough_args}, + @command.validate([], Map.merge(context[:opts], %{online: true, offline: false})) + ) end - test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{enabled_plugins_file: "none"})) == :ok + test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{enabled_plugins_file: "none"}) + ) == :ok end - test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{plugins_dir: "none"})) == - {:validation_failure, :plugins_dir_does_not_exist} + test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{plugins_dir: "none"}) + ) == + {:validation_failure, :plugins_dir_does_not_exist} end - test "node is inaccessible, writes out enabled plugins file and returns implicitly enabled plugin list", context do + test "node is inaccessible, writes out enabled plugins file and returns implicitly enabled plugin list", + context do assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) - assert [[:rabbitmq_federation], - %{mode: :offline, disabled: [:rabbitmq_stomp], set: [:rabbitmq_federation]}] == - Enum.to_list(test_stream) + @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) + + assert [ + [:rabbitmq_federation], + %{mode: :offline, disabled: [:rabbitmq_stomp], set: [:rabbitmq_federation]} + ] == + Enum.to_list(test_stream) + assert {:ok, [[:rabbitmq_federation]]} == :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] == - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end - test "in offline mode, writes out enabled plugins and reports implicitly enabled plugin list", context do - assert {:stream, test_stream} = @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_federation], - %{mode: :offline, disabled: [:rabbitmq_stomp], set: [:rabbitmq_federation]}] == Enum.to_list(test_stream) + test "in offline mode, writes out enabled plugins and reports implicitly enabled plugin list", + context do + assert {:stream, test_stream} = + @command.run( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [ + [:rabbitmq_federation], + %{mode: :offline, disabled: [:rabbitmq_stomp], set: [:rabbitmq_federation]} + ] == Enum.to_list(test_stream) + assert {:ok, [[:rabbitmq_federation]]} == :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] == - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end - test "in offline mode, removes implicitly enabled plugins when the last explicitly enabled one is removed", context do + test "in offline mode, removes implicitly enabled plugins when the last explicitly enabled one is removed", + context do assert {:stream, test_stream0} = - @command.run(["rabbitmq_federation"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_stomp], - %{mode: :offline, disabled: [:rabbitmq_federation], set: [:rabbitmq_stomp]}] == Enum.to_list(test_stream0) + @command.run( + ["rabbitmq_federation"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [ + [:rabbitmq_stomp], + %{mode: :offline, disabled: [:rabbitmq_federation], set: [:rabbitmq_stomp]} + ] == Enum.to_list(test_stream0) + assert {:ok, [[:rabbitmq_stomp]]} == :file.consult(context[:opts][:enabled_plugins_file]) assert {:stream, test_stream1} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[], - %{mode: :offline, disabled: [:rabbitmq_stomp], set: []}] == - Enum.to_list(test_stream1) + @command.run( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [[], %{mode: :offline, disabled: [:rabbitmq_stomp], set: []}] == + Enum.to_list(test_stream1) + assert {:ok, [[]]} = :file.consult(context[:opts][:enabled_plugins_file]) end test "updates plugin list and stops disabled plugins", context do - assert {:stream, test_stream0} = - @command.run(["rabbitmq_stomp"], context[:opts]) - assert [[:rabbitmq_federation], - %{mode: :online, - started: [], stopped: [:rabbitmq_stomp], - disabled: [:rabbitmq_stomp], - set: [:rabbitmq_federation]}] == - Enum.to_list(test_stream0) + assert {:stream, test_stream0} = @command.run(["rabbitmq_stomp"], context[:opts]) + + assert [ + [:rabbitmq_federation], + %{ + mode: :online, + started: [], + stopped: [:rabbitmq_stomp], + disabled: [:rabbitmq_stomp], + set: [:rabbitmq_federation] + } + ] == + Enum.to_list(test_stream0) + assert {:ok, [[:rabbitmq_federation]]} == :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation] == - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + + assert {:stream, test_stream1} = @command.run(["rabbitmq_federation"], context[:opts]) + + assert [ + [], + %{ + mode: :online, + started: [], + stopped: [:rabbitmq_federation], + disabled: [:rabbitmq_federation], + set: [] + } + ] == + Enum.to_list(test_stream1) - assert {:stream, test_stream1} = - @command.run(["rabbitmq_federation"], context[:opts]) - assert [[], - %{mode: :online, - started: [], stopped: [:rabbitmq_federation], - disabled: [:rabbitmq_federation], - set: []}] == - Enum.to_list(test_stream1) assert {:ok, [[]]} == :file.consult(context[:opts][:enabled_plugins_file]) - assert Enum.empty?(Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, []))) + + assert Enum.empty?( + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + ) end test "can disable multiple plugins at once", context do - assert {:stream, test_stream} = @command.run(["rabbitmq_stomp", "rabbitmq_federation"], context[:opts]) + assert {:stream, test_stream} = + @command.run(["rabbitmq_stomp", "rabbitmq_federation"], context[:opts]) + [[], m0] = Enum.to_list(test_stream) - m1 = m0 |> Map.update!(:stopped, &Enum.sort/1) - |> Map.update!(:disabled, &Enum.sort/1) + + m1 = + m0 + |> Map.update!(:stopped, &Enum.sort/1) + |> Map.update!(:disabled, &Enum.sort/1) + expected_list = Enum.sort([:rabbitmq_federation, :rabbitmq_stomp]) - assert [[], - %{mode: :online, - started: [], - stopped: expected_list, - disabled: expected_list, - set: []} - ] == [[], m1] + + assert [ + [], + %{ + mode: :online, + started: [], + stopped: expected_list, + disabled: expected_list, + set: [] + } + ] == [[], m1] + assert {:ok, [[]]} == :file.consult(context[:opts][:enabled_plugins_file]) - assert Enum.empty?(Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, []))) + + assert Enum.empty?( + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + ) end test "disabling a dependency disables all plugins that depend on it", context do assert {:stream, test_stream} = @command.run(["amqp_client"], context[:opts]) [[], m0] = Enum.to_list(test_stream) - m1 = m0 |> Map.update!(:stopped, &Enum.sort/1) - |> Map.update!(:disabled, &Enum.sort/1) + + m1 = + m0 + |> Map.update!(:stopped, &Enum.sort/1) + |> Map.update!(:disabled, &Enum.sort/1) expected_list = Enum.sort([:rabbitmq_federation, :rabbitmq_stomp]) - assert [[], - %{mode: :online, - started: [], - stopped: expected_list, - disabled: expected_list, - set: []} - ] == [[], m1] + + assert [ + [], + %{ + mode: :online, + started: [], + stopped: expected_list, + disabled: expected_list, + set: [] + } + ] == [[], m1] assert {:ok, [[]]} == :file.consult(context[:opts][:enabled_plugins_file]) - assert Enum.empty?(Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, []))) + + assert Enum.empty?( + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + ) end test "formats enabled plugins mismatch errors", context do err = {:enabled_plugins_mismatch, '/tmp/a/cli/path', '/tmp/a/server/path'} + assert {:error, ExitCodes.exit_dataerr(), - "Could not update enabled plugins file at /tmp/a/cli/path: target node #{context[:opts][:node]} uses a different path (/tmp/a/server/path)"} - == @command.output({:error, err}, context[:opts]) + "Could not update enabled plugins file at /tmp/a/cli/path: target node #{context[:opts][:node]} uses a different path (/tmp/a/server/path)"} == + @command.output({:error, err}, context[:opts]) end test "formats enabled plugins write errors", context do err1 = {:cannot_write_enabled_plugins_file, "/tmp/a/path", :eacces} + assert {:error, ExitCodes.exit_dataerr(), "Could not update enabled plugins file at /tmp/a/path: the file does not exist or permission was denied (EACCES)"} == - @command.output({:error, err1}, context[:opts]) + @command.output({:error, err1}, context[:opts]) err2 = {:cannot_write_enabled_plugins_file, "/tmp/a/path", :enoent} + assert {:error, ExitCodes.exit_dataerr(), "Could not update enabled plugins file at /tmp/a/path: the file does not exist (ENOENT)"} == - @command.output({:error, err2}, context[:opts]) + @command.output({:error, err2}, context[:opts]) end end diff --git a/deps/rabbitmq_cli/test/plugins/enable_plugins_command_test.exs b/deps/rabbitmq_cli/test/plugins/enable_plugins_command_test.exs index 5ac976fb4699..0c16f46662e9 100644 --- a/deps/rabbitmq_cli/test/plugins/enable_plugins_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/enable_plugins_command_test.exs @@ -16,98 +16,132 @@ defmodule EnablePluginsCommandTest do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) - IO.puts("plugins enable tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}") + IO.puts( + "plugins enable tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}" + ) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - IO.puts("plugins enable tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to") - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - online: false, offline: false, - all: false} + IO.puts( + "plugins enable tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to" + ) + + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + online: false, + offline: false, + all: false + } on_exit(fn -> set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) end) - {:ok, opts: opts} end setup context do - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], - :online, - get_rabbit_hostname(), - context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + get_rabbit_hostname(), + context[:opts] + ) { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end test "validate: specifying both --online and --offline is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["a"], Map.merge(context[:opts], %{online: true, offline: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate(["a"], Map.merge(context[:opts], %{online: true, offline: true})) + ) end test "validate: not specifying any plugins to enable is reported as invalid", context do assert match?( - {:validation_failure, :not_enough_args}, - @command.validate([], Map.merge(context[:opts], %{online: true, offline: false})) - ) + {:validation_failure, :not_enough_args}, + @command.validate([], Map.merge(context[:opts], %{online: true, offline: false})) + ) end - test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{enabled_plugins_file: "none"})) == :ok + test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{enabled_plugins_file: "none"}) + ) == :ok end - test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{plugins_dir: "none"})) == - {:validation_failure, :plugins_dir_does_not_exist} + test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{plugins_dir: "none"}) + ) == + {:validation_failure, :plugins_dir_does_not_exist} end - test "if node is inaccessible, writes enabled plugins file and reports implicitly enabled plugin list", context do + test "if node is inaccessible, writes enabled plugins file and reports implicitly enabled plugin list", + context do # Clears enabled plugins file set_enabled_plugins([], :offline, :nonode, context[:opts]) assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) - assert [[:rabbitmq_stomp], - %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]}] == - Enum.to_list(test_stream) + @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) + + assert [ + [:rabbitmq_stomp], + %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]} + ] == + Enum.to_list(test_stream) + check_plugins_enabled([:rabbitmq_stomp], context) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] == - currently_active_plugins(context) + currently_active_plugins(context) end - test "in offline mode, writes enabled plugins and reports implicitly enabled plugin list", context do + test "in offline mode, writes enabled plugins and reports implicitly enabled plugin list", + context do # Clears enabled plugins file set_enabled_plugins([], :offline, :nonode, context[:opts]) assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_stomp], - %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]}] == - Enum.to_list(test_stream) + @command.run( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [ + [:rabbitmq_stomp], + %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]} + ] == + Enum.to_list(test_stream) + check_plugins_enabled([:rabbitmq_stomp], context) + assert_equal_sets( [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], - currently_active_plugins(context)) + currently_active_plugins(context) + ) end test "adds additional plugins to those already enabled", context do @@ -115,17 +149,35 @@ defmodule EnablePluginsCommandTest do set_enabled_plugins([], :offline, :nonode, context[:opts]) assert {:stream, test_stream0} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_stomp], - %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]}] == - Enum.to_list(test_stream0) + @command.run( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [ + [:rabbitmq_stomp], + %{mode: :offline, enabled: [:rabbitmq_stomp], set: [:rabbitmq_stomp]} + ] == + Enum.to_list(test_stream0) + check_plugins_enabled([:rabbitmq_stomp], context) + assert {:stream, test_stream1} = - @command.run(["rabbitmq_federation"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_federation, :rabbitmq_stomp], - %{mode: :offline, enabled: [:rabbitmq_federation], - set: [:rabbitmq_federation, :rabbitmq_stomp]}] == - Enum.to_list(test_stream1) + @command.run( + ["rabbitmq_federation"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [ + [:rabbitmq_federation, :rabbitmq_stomp], + %{ + mode: :offline, + enabled: [:rabbitmq_federation], + set: [:rabbitmq_federation, :rabbitmq_stomp] + } + ] == + Enum.to_list(test_stream1) + check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context) end @@ -133,29 +185,43 @@ defmodule EnablePluginsCommandTest do # Clears enabled plugins file and stop all plugins set_enabled_plugins([], :online, context[:opts][:node], context[:opts]) - assert {:stream, test_stream0} = - @command.run(["rabbitmq_stomp"], context[:opts]) - assert [[:rabbitmq_stomp], - %{mode: :online, - started: [:rabbitmq_stomp], stopped: [], - enabled: [:rabbitmq_stomp], - set: [:rabbitmq_stomp]}] == - Enum.to_list(test_stream0) + assert {:stream, test_stream0} = @command.run(["rabbitmq_stomp"], context[:opts]) + + assert [ + [:rabbitmq_stomp], + %{ + mode: :online, + started: [:rabbitmq_stomp], + stopped: [], + enabled: [:rabbitmq_stomp], + set: [:rabbitmq_stomp] + } + ] == + Enum.to_list(test_stream0) check_plugins_enabled([:rabbitmq_stomp], context) assert_equal_sets([:amqp_client, :rabbitmq_stomp], currently_active_plugins(context)) - {:stream, test_stream1} = - @command.run(["rabbitmq_federation"], context[:opts]) - assert [[:rabbitmq_federation, :rabbitmq_stomp], - %{mode: :online, - started: [:rabbitmq_federation], stopped: [], - enabled: [:rabbitmq_federation], - set: [:rabbitmq_federation, :rabbitmq_stomp]}] == - Enum.to_list(test_stream1) + {:stream, test_stream1} = @command.run(["rabbitmq_federation"], context[:opts]) + + assert [ + [:rabbitmq_federation, :rabbitmq_stomp], + %{ + mode: :online, + started: [:rabbitmq_federation], + stopped: [], + enabled: [:rabbitmq_federation], + set: [:rabbitmq_federation, :rabbitmq_stomp] + } + ] == + Enum.to_list(test_stream1) check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context) - assert_equal_sets([:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], currently_active_plugins(context)) + + assert_equal_sets( + [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], + currently_active_plugins(context) + ) end test "can enable multiple plugins at once", context do @@ -163,33 +229,43 @@ defmodule EnablePluginsCommandTest do set_enabled_plugins([], :online, context[:opts][:node], context[:opts]) assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp", "rabbitmq_federation"], context[:opts]) - assert [[:rabbitmq_federation, :rabbitmq_stomp], - %{mode: :online, - started: [:rabbitmq_federation, :rabbitmq_stomp], stopped: [], - enabled: [:rabbitmq_federation, :rabbitmq_stomp], - set: [:rabbitmq_federation, :rabbitmq_stomp]}] == - Enum.to_list(test_stream) + @command.run(["rabbitmq_stomp", "rabbitmq_federation"], context[:opts]) + + assert [ + [:rabbitmq_federation, :rabbitmq_stomp], + %{ + mode: :online, + started: [:rabbitmq_federation, :rabbitmq_stomp], + stopped: [], + enabled: [:rabbitmq_federation, :rabbitmq_stomp], + set: [:rabbitmq_federation, :rabbitmq_stomp] + } + ] == + Enum.to_list(test_stream) + check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context) - assert_equal_sets([:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], currently_active_plugins(context)) + assert_equal_sets( + [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], + currently_active_plugins(context) + ) end test "does not enable an already implicitly enabled plugin", context do # Clears enabled plugins file and stop all plugins set_enabled_plugins([:rabbitmq_federation], :online, context[:opts][:node], context[:opts]) - assert {:stream, test_stream} = - @command.run(["amqp_client"], context[:opts]) - assert [[:rabbitmq_federation], - %{mode: :online, - started: [], stopped: [], - enabled: [], - set: [:rabbitmq_federation]}] == - Enum.to_list(test_stream) + assert {:stream, test_stream} = @command.run(["amqp_client"], context[:opts]) + + assert [ + [:rabbitmq_federation], + %{mode: :online, started: [], stopped: [], enabled: [], set: [:rabbitmq_federation]} + ] == + Enum.to_list(test_stream) + check_plugins_enabled([:rabbitmq_federation], context) - assert [:amqp_client, :rabbitmq_federation] == - currently_active_plugins(context) + assert [:amqp_client, :rabbitmq_federation] == + currently_active_plugins(context) end test "run: does not enable plugins with unmet version requirements", context do @@ -199,17 +275,16 @@ defmodule EnablePluginsCommandTest do opts = get_opts_with_plugins_directories(context, [plugins_directory]) switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) - {:stream, _} = - @command.run(["mock_rabbitmq_plugin_for_3_9"], opts) + {:stream, _} = @command.run(["mock_rabbitmq_plugin_for_3_9"], opts) check_plugins_enabled([:mock_rabbitmq_plugin_for_3_9], context) # Not changed {:error, _version_error} = @command.run(["mock_rabbitmq_plugin_for_3_7"], opts) check_plugins_enabled([:mock_rabbitmq_plugin_for_3_9], context) - end - test "run: does not enable plugins with unmet version requirements even when enabling all plugins", context do + test "run: does not enable plugins with unmet version requirements even when enabling all plugins", + context do set_enabled_plugins([], :online, context[:opts][:node], context[:opts]) plugins_directory = fixture_plugins_path("plugins_with_version_requirements") @@ -224,20 +299,23 @@ defmodule EnablePluginsCommandTest do test "formats enabled plugins mismatch errors", context do err = {:enabled_plugins_mismatch, '/tmp/a/cli/path', '/tmp/a/server/path'} + assert {:error, ExitCodes.exit_dataerr(), - "Could not update enabled plugins file at /tmp/a/cli/path: target node #{context[:opts][:node]} uses a different path (/tmp/a/server/path)"} - == @command.output({:error, err}, context[:opts]) + "Could not update enabled plugins file at /tmp/a/cli/path: target node #{context[:opts][:node]} uses a different path (/tmp/a/server/path)"} == + @command.output({:error, err}, context[:opts]) end test "formats enabled plugins write errors", context do err1 = {:cannot_write_enabled_plugins_file, "/tmp/a/path", :eacces} + assert {:error, ExitCodes.exit_dataerr(), "Could not update enabled plugins file at /tmp/a/path: the file does not exist or permission was denied (EACCES)"} == - @command.output({:error, err1}, context[:opts]) + @command.output({:error, err1}, context[:opts]) err2 = {:cannot_write_enabled_plugins_file, "/tmp/a/path", :enoent} + assert {:error, ExitCodes.exit_dataerr(), "Could not update enabled plugins file at /tmp/a/path: the file does not exist (ENOENT)"} == - @command.output({:error, err2}, context[:opts]) + @command.output({:error, err2}, context[:opts]) end end diff --git a/deps/rabbitmq_cli/test/plugins/is_enabled_command_test.exs b/deps/rabbitmq_cli/test/plugins/is_enabled_command_test.exs index af2900228b7e..bbb8e70170c8 100644 --- a/deps/rabbitmq_cli/test/plugins/is_enabled_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/is_enabled_command_test.exs @@ -14,46 +14,50 @@ defmodule PluginIsEnabledCommandTest do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - online: false, offline: false} + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + online: false, + offline: false + } on_exit(fn -> set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) end) - {:ok, opts: opts} end setup context do { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end - - test "validate: specifying both --online and --offline is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate(["rabbitmq_stomp"], Map.merge(context[:opts], %{online: true, offline: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{online: true, offline: true}) + ) + ) end test "validate: not specifying any plugins to check is reported as invalid", context do @@ -61,43 +65,60 @@ defmodule PluginIsEnabledCommandTest do assert match?({:validation_failure, :not_enough_args}, @command.validate([], opts)) end - test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", context do - assert @command.validate_execution_environment(["rabbitmq_stomp"], - Map.merge(context[:opts], %{online: false, - offline: true, - enabled_plugins_file: "none"})) == :ok + test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", + context do + assert @command.validate_execution_environment( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{ + online: false, + offline: true, + enabled_plugins_file: "none" + }) + ) == :ok end - test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", context do - opts = context[:opts] |> Map.merge(%{online: false, - offline: true, - plugins_dir: "none"}) + test "validate_execution_environment: specifying a non-existent plugins_dir is reported as an error", + context do + opts = context[:opts] |> Map.merge(%{online: false, offline: true, plugins_dir: "none"}) assert @command.validate_execution_environment(["rabbitmq_stomp"], opts) == - {:validation_failure, :plugins_dir_does_not_exist} + {:validation_failure, :plugins_dir_does_not_exist} end test "run: when given a single enabled plugin, reports it as such", context do opts = context[:opts] |> Map.merge(%{online: true, offline: false}) - assert match?({:ok, _}, - assert @command.run(["rabbitmq_stomp"], opts)) + + assert match?( + {:ok, _}, + assert(@command.run(["rabbitmq_stomp"], opts)) + ) end test "run: when given a list of actually enabled plugins, reports them as such", context do opts = context[:opts] |> Map.merge(%{online: true, offline: false}) - assert match?({:ok, _}, - assert @command.run(["rabbitmq_stomp", "rabbitmq_federation"], opts)) + + assert match?( + {:ok, _}, + assert(@command.run(["rabbitmq_stomp", "rabbitmq_federation"], opts)) + ) end test "run: when given a list of non-existent plugins, reports them as not enabled", context do opts = context[:opts] |> Map.merge(%{online: true, offline: false}) - assert match?({:error, _}, - assert @command.run(["rabbitmq_xyz", "abc_xyz"], opts)) + + assert match?( + {:error, _}, + assert(@command.run(["rabbitmq_xyz", "abc_xyz"], opts)) + ) end - test "run: when given a list with one non-existent plugin, reports the group as not [all] enabled", context do + test "run: when given a list with one non-existent plugin, reports the group as not [all] enabled", + context do opts = context[:opts] |> Map.merge(%{online: true, offline: false}) - assert match?({:error, _}, - assert @command.run(["rabbitmq_stomp", "abc_xyz"], opts)) + + assert match?( + {:error, _}, + assert(@command.run(["rabbitmq_stomp", "abc_xyz"], opts)) + ) end end diff --git a/deps/rabbitmq_cli/test/plugins/list_plugins_command_test.exs b/deps/rabbitmq_cli/test/plugins/list_plugins_command_test.exs index 33d9420435e5..102648ca826f 100644 --- a/deps/rabbitmq_cli/test/plugins/list_plugins_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/list_plugins_command_test.exs @@ -11,38 +11,50 @@ defmodule ListPluginsCommandTest do @command RabbitMQ.CLI.Plugins.Commands.ListCommand def reset_enabled_plugins_to_preconfigured_defaults(context) do - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], :online, - get_rabbit_hostname(), context[:opts]) + get_rabbit_hostname(), + context[:opts] + ) end setup_all do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) - IO.puts("plugins list tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}") + + IO.puts( + "plugins list tests default env: enabled plugins = #{plugins_file}, plugins dir = #{plugins_dir}, RabbitMQ home directory = #{rabbitmq_home}" + ) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - IO.puts("plugins list tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to") - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - minimal: false, verbose: false, - enabled: false, implicitly_enabled: false} + IO.puts( + "plugins list tests will assume tnat #{Enum.join(enabled_plugins, ",")} is the list of enabled plugins to revert to" + ) + + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + minimal: false, + verbose: false, + enabled: false, + implicitly_enabled: false + } on_exit(fn -> set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) end) - {:ok, opts: opts} end @@ -51,137 +63,205 @@ defmodule ListPluginsCommandTest do { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end test "validate: specifying both --minimal and --verbose is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate([], Map.merge(context[:opts], %{minimal: true, verbose: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate([], Map.merge(context[:opts], %{minimal: true, verbose: true})) + ) end test "validate: specifying multiple patterns is reported as an error", context do assert @command.validate(["a", "b", "c"], context[:opts]) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end - test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{enabled_plugins_file: "none"})) == :ok + test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{enabled_plugins_file: "none"}) + ) == :ok end - test "validate_execution_environment: specifying non existent plugins_dir is reported as an error", context do - assert @command.validate_execution_environment(["a"], Map.merge(context[:opts], %{plugins_dir: "none"})) == - {:validation_failure, :plugins_dir_does_not_exist} + test "validate_execution_environment: specifying non existent plugins_dir is reported as an error", + context do + assert @command.validate_execution_environment( + ["a"], + Map.merge(context[:opts], %{plugins_dir: "none"}) + ) == + {:validation_failure, :plugins_dir_does_not_exist} end test "will report list of plugins from file for stopped node", context do node = context[:opts][:node] :ok = :rabbit_misc.rpc_call(node, :application, :stop, [:rabbitmq_stomp]) + on_exit(fn -> :rabbit_misc.rpc_call(node, :application, :start, [:rabbitmq_stomp]) end) - assert %{status: :node_down, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: false}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: false}]} = - @command.run([".*"], Map.merge(context[:opts], %{node: :nonode})) + + assert %{ + status: :node_down, + plugins: [ + %{name: :rabbitmq_federation, enabled: :enabled, running: false}, + %{name: :rabbitmq_stomp, enabled: :enabled, running: false} + ] + } = @command.run([".*"], Map.merge(context[:opts], %{node: :nonode})) end test "will report list of started plugins for started node", context do node = context[:opts][:node] :ok = :rabbit_misc.rpc_call(node, :application, :stop, [:rabbitmq_stomp]) + on_exit(fn -> :rabbit_misc.rpc_call(node, :application, :start, [:rabbitmq_stomp]) end) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: false}]} = - @command.run([".*"], context[:opts]) + + assert %{ + status: :running, + plugins: [ + %{name: :rabbitmq_federation, enabled: :enabled, running: true}, + %{name: :rabbitmq_stomp, enabled: :enabled, running: false} + ] + } = @command.run([".*"], context[:opts]) end test "will report description and dependencies for verbose mode", context do - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true, description: _, dependencies: [:amqp_client]}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true, description: _, dependencies: [:amqp_client]}]} = - @command.run([".*"], Map.merge(context[:opts], %{verbose: true})) + assert %{ + status: :running, + plugins: [ + %{ + name: :rabbitmq_federation, + enabled: :enabled, + running: true, + description: _, + dependencies: [:amqp_client] + }, + %{ + name: :rabbitmq_stomp, + enabled: :enabled, + running: true, + description: _, + dependencies: [:amqp_client] + } + ] + } = @command.run([".*"], Map.merge(context[:opts], %{verbose: true})) end test "will report plugin names in minimal mode", context do - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = - @command.run([".*"], Map.merge(context[:opts], %{minimal: true})) + assert %{status: :running, plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = + @command.run([".*"], Map.merge(context[:opts], %{minimal: true})) end test "by default lists all plugins", context do set_enabled_plugins([:rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + on_exit(fn -> - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + context[:opts][:node], + context[:opts] + ) end) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}, - %{name: :rabbitmq_stomp, enabled: :not_enabled, running: false}]} = - @command.run([".*"], context[:opts]) + + assert %{ + status: :running, + plugins: [ + %{name: :rabbitmq_federation, enabled: :enabled, running: true}, + %{name: :rabbitmq_stomp, enabled: :not_enabled, running: false} + ] + } = @command.run([".*"], context[:opts]) end test "with enabled flag lists only explicitly enabled plugins", context do set_enabled_plugins([:rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + on_exit(fn -> - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + context[:opts][:node], + context[:opts] + ) end) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}]} = - @command.run([".*"], Map.merge(context[:opts], %{enabled: true})) + + assert %{ + status: :running, + plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}] + } = @command.run([".*"], Map.merge(context[:opts], %{enabled: true})) end test "with implicitly_enabled flag lists explicitly and implicitly enabled plugins", context do set_enabled_plugins([:rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + on_exit(fn -> - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + context[:opts][:node], + context[:opts] + ) end) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}]} = - @command.run([".*"], Map.merge(context[:opts], %{implicitly_enabled: true})) + + assert %{ + status: :running, + plugins: [%{name: :rabbitmq_federation, enabled: :enabled, running: true}] + } = @command.run([".*"], Map.merge(context[:opts], %{implicitly_enabled: true})) end test "will filter plugins by name with pattern provided", context do set_enabled_plugins([:rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + on_exit(fn -> - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], :online, context[:opts][:node], context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + context[:opts][:node], + context[:opts] + ) end) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation}]} = - @command.run(["fede"], Map.merge(context[:opts], %{minimal: true})) - assert %{status: :running, - plugins: [%{name: :rabbitmq_stomp}]} = - @command.run(["stomp$"], Map.merge(context[:opts], %{minimal: true})) + + assert %{status: :running, plugins: [%{name: :rabbitmq_federation}]} = + @command.run(["fede"], Map.merge(context[:opts], %{minimal: true})) + + assert %{status: :running, plugins: [%{name: :rabbitmq_stomp}]} = + @command.run(["stomp$"], Map.merge(context[:opts], %{minimal: true})) end - test "validate: validation is OK when we use multiple plugins directories, one of them does not exist", context do + test "validate: validation is OK when we use multiple plugins directories, one of them does not exist", + context do opts = get_opts_with_non_existing_plugins_directory(context) assert @command.validate([], opts) == :ok end - test "validate: validation is OK when we use multiple plugins directories, directories do exist", context do + test "validate: validation is OK when we use multiple plugins directories, directories do exist", + context do opts = get_opts_with_existing_plugins_directory(context) assert @command.validate([], opts) == :ok end - test "should succeed when using multiple plugins directories, one of them does not exist", context do + test "should succeed when using multiple plugins directories, one of them does not exist", + context do opts = get_opts_with_non_existing_plugins_directory(context) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = + + assert %{status: :running, plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = @command.run([".*"], Map.merge(opts, %{minimal: true})) end - - test "should succeed when using multiple plugins directories, directories do exist and do contain plugins", context do + test "should succeed when using multiple plugins directories, directories do exist and do contain plugins", + context do opts = get_opts_with_existing_plugins_directory(context) - assert %{status: :running, - plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = + + assert %{status: :running, plugins: [%{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = @command.run([".*"], Map.merge(opts, %{minimal: true})) end @@ -190,24 +270,47 @@ defmodule ListPluginsCommandTest do opts = get_opts_with_plugins_directories(context, [plugins_directory]) switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) reset_enabled_plugins_to_preconfigured_defaults(context) - assert %{status: :running, - plugins: [%{name: :mock_rabbitmq_plugins_01}, %{name: :mock_rabbitmq_plugins_02}, - %{name: :rabbitmq_federation}, %{name: :rabbitmq_stomp}]} = - @command.run([".*"], Map.merge(opts, %{minimal: true})) + + assert %{ + status: :running, + plugins: [ + %{name: :mock_rabbitmq_plugins_01}, + %{name: :mock_rabbitmq_plugins_02}, + %{name: :rabbitmq_federation}, + %{name: :rabbitmq_stomp} + ] + } = @command.run([".*"], Map.merge(opts, %{minimal: true})) end test "will report list of plugins with latest version picked", context do plugins_directory_01 = fixture_plugins_path("plugins-subdirectory-01") plugins_directory_02 = fixture_plugins_path("plugins-subdirectory-02") - opts = get_opts_with_plugins_directories(context, [plugins_directory_01, plugins_directory_02]) + + opts = + get_opts_with_plugins_directories(context, [plugins_directory_01, plugins_directory_02]) + switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) reset_enabled_plugins_to_preconfigured_defaults(context) - assert %{status: :running, - plugins: [%{name: :mock_rabbitmq_plugins_01, enabled: :not_enabled, running: false, version: '0.2.0'}, - %{name: :mock_rabbitmq_plugins_02, enabled: :not_enabled, running: false, version: '0.2.0'}, - %{name: :rabbitmq_federation, enabled: :enabled, running: true}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true}]} = - @command.run([".*"], opts) + + assert %{ + status: :running, + plugins: [ + %{ + name: :mock_rabbitmq_plugins_01, + enabled: :not_enabled, + running: false, + version: '0.2.0' + }, + %{ + name: :mock_rabbitmq_plugins_02, + enabled: :not_enabled, + running: false, + version: '0.2.0' + }, + %{name: :rabbitmq_federation, enabled: :enabled, running: true}, + %{name: :rabbitmq_stomp, enabled: :enabled, running: true} + ] + } = @command.run([".*"], opts) end test "will report both running and pending upgrade versions", context do @@ -215,21 +318,59 @@ defmodule ListPluginsCommandTest do plugins_directory_02 = fixture_plugins_path("plugins-subdirectory-02") opts = get_opts_with_plugins_directories(context, [plugins_directory_01]) switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) - set_enabled_plugins([:mock_rabbitmq_plugins_02, :rabbitmq_federation, :rabbitmq_stomp], - :online, get_rabbit_hostname(), opts) - assert %{status: :running, - plugins: [%{name: :mock_rabbitmq_plugins_01, enabled: :not_enabled, running: false, version: '0.2.0'}, - %{name: :mock_rabbitmq_plugins_02, enabled: :enabled, running: true, version: '0.1.0', running_version: '0.1.0'}, - %{name: :rabbitmq_federation, enabled: :enabled, running: true}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true}]} = - @command.run([".*"], opts) - opts = get_opts_with_plugins_directories(context, [plugins_directory_01, plugins_directory_02]) + + set_enabled_plugins( + [:mock_rabbitmq_plugins_02, :rabbitmq_federation, :rabbitmq_stomp], + :online, + get_rabbit_hostname(), + opts + ) + + assert %{ + status: :running, + plugins: [ + %{ + name: :mock_rabbitmq_plugins_01, + enabled: :not_enabled, + running: false, + version: '0.2.0' + }, + %{ + name: :mock_rabbitmq_plugins_02, + enabled: :enabled, + running: true, + version: '0.1.0', + running_version: '0.1.0' + }, + %{name: :rabbitmq_federation, enabled: :enabled, running: true}, + %{name: :rabbitmq_stomp, enabled: :enabled, running: true} + ] + } = @command.run([".*"], opts) + + opts = + get_opts_with_plugins_directories(context, [plugins_directory_01, plugins_directory_02]) + switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) - assert %{status: :running, - plugins: [%{name: :mock_rabbitmq_plugins_01, enabled: :not_enabled, running: false, version: '0.2.0'}, - %{name: :mock_rabbitmq_plugins_02, enabled: :enabled, running: true, version: '0.2.0', running_version: '0.1.0'}, - %{name: :rabbitmq_federation, enabled: :enabled, running: true}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true}]} = - @command.run([".*"], opts) + + assert %{ + status: :running, + plugins: [ + %{ + name: :mock_rabbitmq_plugins_01, + enabled: :not_enabled, + running: false, + version: '0.2.0' + }, + %{ + name: :mock_rabbitmq_plugins_02, + enabled: :enabled, + running: true, + version: '0.2.0', + running_version: '0.1.0' + }, + %{name: :rabbitmq_federation, enabled: :enabled, running: true}, + %{name: :rabbitmq_stomp, enabled: :enabled, running: true} + ] + } = @command.run([".*"], opts) end end diff --git a/deps/rabbitmq_cli/test/plugins/plugins_formatter_test.exs b/deps/rabbitmq_cli/test/plugins/plugins_formatter_test.exs index 9bf185d7e015..de70cb1e5f89 100644 --- a/deps/rabbitmq_cli/test/plugins/plugins_formatter_test.exs +++ b/deps/rabbitmq_cli/test/plugins/plugins_formatter_test.exs @@ -4,42 +4,123 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule PluginsFormatterTest do use ExUnit.Case, async: false @formatter RabbitMQ.CLI.Formatters.Plugins test "format_output with --silent and --minimal" do - result = @formatter.format_output( - %{status: :running, - plugins: [%{name: :amqp_client, enabled: :implicit, running: true, version: '3.7.0', running_version: nil}, - %{name: :mock_rabbitmq_plugins_01, enabled: :not_enabled, running: false, version: '0.2.0', running_version: nil}, - %{name: :mock_rabbitmq_plugins_02, enabled: :enabled, running: true, version: '0.2.0', running_version: '0.1.0'}, - %{name: :rabbitmq_federation, enabled: :enabled, running: true, version: '3.7.0', running_version: nil}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true, version: '3.7.0', running_version: nil}], - format: :minimal}, %{node: "rabbit@localhost", silent: true}) - assert result == ["amqp_client", - "mock_rabbitmq_plugins_01", - "mock_rabbitmq_plugins_02", - "rabbitmq_federation", - "rabbitmq_stomp"] + result = + @formatter.format_output( + %{ + status: :running, + plugins: [ + %{ + name: :amqp_client, + enabled: :implicit, + running: true, + version: '3.7.0', + running_version: nil + }, + %{ + name: :mock_rabbitmq_plugins_01, + enabled: :not_enabled, + running: false, + version: '0.2.0', + running_version: nil + }, + %{ + name: :mock_rabbitmq_plugins_02, + enabled: :enabled, + running: true, + version: '0.2.0', + running_version: '0.1.0' + }, + %{ + name: :rabbitmq_federation, + enabled: :enabled, + running: true, + version: '3.7.0', + running_version: nil + }, + %{ + name: :rabbitmq_stomp, + enabled: :enabled, + running: true, + version: '3.7.0', + running_version: nil + } + ], + format: :minimal + }, + %{node: "rabbit@localhost", silent: true} + ) + + assert result == [ + "amqp_client", + "mock_rabbitmq_plugins_01", + "mock_rabbitmq_plugins_02", + "rabbitmq_federation", + "rabbitmq_stomp" + ] end test "format_output pending upgrade version message" do - result = @formatter.format_output( - %{status: :running, - plugins: [%{name: :amqp_client, enabled: :implicit, running: true, version: '3.7.0', running_version: nil}, - %{name: :mock_rabbitmq_plugins_01, enabled: :not_enabled, running: false, version: '0.2.0', running_version: nil}, - %{name: :mock_rabbitmq_plugins_02, enabled: :enabled, running: true, version: '0.2.0', running_version: '0.1.0'}, - %{name: :rabbitmq_federation, enabled: :enabled, running: true, version: '3.7.0', running_version: nil}, - %{name: :rabbitmq_stomp, enabled: :enabled, running: true, version: '3.7.0', running_version: nil}], - format: :normal}, %{node: "rabbit@localhost"}) - assert result == [" Configured: E = explicitly enabled; e = implicitly enabled", - " | Status: * = running on rabbit@localhost", " |/", - "[e*] amqp_client 3.7.0", "[ ] mock_rabbitmq_plugins_01 0.2.0", - "[E*] mock_rabbitmq_plugins_02 0.1.0 (pending upgrade to 0.2.0)", - "[E*] rabbitmq_federation 3.7.0", "[E*] rabbitmq_stomp 3.7.0"] - end + result = + @formatter.format_output( + %{ + status: :running, + plugins: [ + %{ + name: :amqp_client, + enabled: :implicit, + running: true, + version: '3.7.0', + running_version: nil + }, + %{ + name: :mock_rabbitmq_plugins_01, + enabled: :not_enabled, + running: false, + version: '0.2.0', + running_version: nil + }, + %{ + name: :mock_rabbitmq_plugins_02, + enabled: :enabled, + running: true, + version: '0.2.0', + running_version: '0.1.0' + }, + %{ + name: :rabbitmq_federation, + enabled: :enabled, + running: true, + version: '3.7.0', + running_version: nil + }, + %{ + name: :rabbitmq_stomp, + enabled: :enabled, + running: true, + version: '3.7.0', + running_version: nil + } + ], + format: :normal + }, + %{node: "rabbit@localhost"} + ) + assert result == [ + " Configured: E = explicitly enabled; e = implicitly enabled", + " | Status: * = running on rabbit@localhost", + " |/", + "[e*] amqp_client 3.7.0", + "[ ] mock_rabbitmq_plugins_01 0.2.0", + "[E*] mock_rabbitmq_plugins_02 0.1.0 (pending upgrade to 0.2.0)", + "[E*] rabbitmq_federation 3.7.0", + "[E*] rabbitmq_stomp 3.7.0" + ] + end end diff --git a/deps/rabbitmq_cli/test/plugins/set_plugins_command_test.exs b/deps/rabbitmq_cli/test/plugins/set_plugins_command_test.exs index 8229415b386b..b71349d66798 100644 --- a/deps/rabbitmq_cli/test/plugins/set_plugins_command_test.exs +++ b/deps/rabbitmq_cli/test/plugins/set_plugins_command_test.exs @@ -10,134 +10,184 @@ defmodule SetPluginsCommandTest do @command RabbitMQ.CLI.Plugins.Commands.SetCommand - setup_all do RabbitMQ.CLI.Core.Distribution.start() node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) {:ok, [enabled_plugins]} = :file.consult(plugins_file) - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - online: false, offline: false} + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + online: false, + offline: false + } on_exit(fn -> - set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(),opts) + set_enabled_plugins(enabled_plugins, :online, get_rabbit_hostname(), opts) end) {:ok, opts: opts} end setup context do - - set_enabled_plugins([:rabbitmq_stomp, :rabbitmq_federation], - :online, - get_rabbit_hostname(), - context[:opts]) + set_enabled_plugins( + [:rabbitmq_stomp, :rabbitmq_federation], + :online, + get_rabbit_hostname(), + context[:opts] + ) { :ok, - opts: Map.merge(context[:opts], %{ - node: get_rabbit_hostname(), - timeout: 1000 - }) + opts: + Map.merge(context[:opts], %{ + node: get_rabbit_hostname(), + timeout: 1000 + }) } end test "validate: specifying both --online and --offline is reported as invalid", context do assert match?( - {:validation_failure, {:bad_argument, _}}, - @command.validate([], Map.merge(context[:opts], %{online: true, offline: true})) - ) + {:validation_failure, {:bad_argument, _}}, + @command.validate([], Map.merge(context[:opts], %{online: true, offline: true})) + ) end - test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", context do - assert @command.validate_execution_environment([], Map.merge(context[:opts], %{enabled_plugins_file: "none"})) == - :ok + test "validate_execution_environment: specifying a non-existent enabled_plugins_file is fine", + context do + assert @command.validate_execution_environment( + [], + Map.merge(context[:opts], %{enabled_plugins_file: "none"}) + ) == + :ok end - test "validate_execution_environment: specifying non existent plugins_dir is reported as an error", context do - assert @command.validate_execution_environment([], Map.merge(context[:opts], %{plugins_dir: "none"})) == - {:validation_failure, :plugins_dir_does_not_exist} + test "validate_execution_environment: specifying non existent plugins_dir is reported as an error", + context do + assert @command.validate_execution_environment( + [], + Map.merge(context[:opts], %{plugins_dir: "none"}) + ) == + {:validation_failure, :plugins_dir_does_not_exist} end - test "will write enabled plugins file if node is inaccessible and report implicitly enabled list", context do + test "will write enabled plugins file if node is inaccessible and report implicitly enabled list", + context do assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) - assert [[:rabbitmq_stomp], - %{mode: :offline, set: [:rabbitmq_stomp]}] = - Enum.to_list(test_stream) + @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{node: :nonode})) + + assert [[:rabbitmq_stomp], %{mode: :offline, set: [:rabbitmq_stomp]}] = + Enum.to_list(test_stream) + assert {:ok, [[:rabbitmq_stomp]]} = :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] = - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end test "will write enabled plugins in offline mode and report implicitly enabled list", context do assert {:stream, test_stream} = - @command.run(["rabbitmq_stomp"], Map.merge(context[:opts], %{offline: true, online: false})) - assert [[:rabbitmq_stomp], - %{mode: :offline, set: [:rabbitmq_stomp]}] = - Enum.to_list(test_stream) + @command.run( + ["rabbitmq_stomp"], + Map.merge(context[:opts], %{offline: true, online: false}) + ) + + assert [[:rabbitmq_stomp], %{mode: :offline, set: [:rabbitmq_stomp]}] = + Enum.to_list(test_stream) + assert {:ok, [[:rabbitmq_stomp]]} = :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] = - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end test "will update list of plugins and start/stop enabled/disabled plugins", context do assert {:stream, test_stream0} = @command.run(["rabbitmq_stomp"], context[:opts]) - assert [[:rabbitmq_stomp], - %{mode: :online, - started: [], stopped: [:rabbitmq_federation], - set: [:rabbitmq_stomp]}] = - Enum.to_list(test_stream0) + + assert [ + [:rabbitmq_stomp], + %{ + mode: :online, + started: [], + stopped: [:rabbitmq_federation], + set: [:rabbitmq_stomp] + } + ] = Enum.to_list(test_stream0) + assert {:ok, [[:rabbitmq_stomp]]} = :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_stomp] = - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + assert {:stream, test_stream1} = @command.run(["rabbitmq_federation"], context[:opts]) - assert [[:rabbitmq_federation], - %{mode: :online, - started: [:rabbitmq_federation], stopped: [:rabbitmq_stomp], - set: [:rabbitmq_federation]}] = - Enum.to_list(test_stream1) + + assert [ + [:rabbitmq_federation], + %{ + mode: :online, + started: [:rabbitmq_federation], + stopped: [:rabbitmq_stomp], + set: [:rabbitmq_federation] + } + ] = Enum.to_list(test_stream1) + assert {:ok, [[:rabbitmq_federation]]} = :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation] = - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end test "can disable all plugins", context do assert {:stream, test_stream} = @command.run([], context[:opts]) - assert [[], - %{mode: :online, - started: [], stopped: [:rabbitmq_federation, :rabbitmq_stomp], - set: []}] = - Enum.to_list(test_stream) + + assert [ + [], + %{ + mode: :online, + started: [], + stopped: [:rabbitmq_federation, :rabbitmq_stomp], + set: [] + } + ] = Enum.to_list(test_stream) + assert {:ok, [[]]} = :file.consult(context[:opts][:enabled_plugins_file]) - assert [] = Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + + assert [] = + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end test "can set multiple plugins", context do set_enabled_plugins([], :online, get_rabbit_hostname(), context[:opts]) + assert {:stream, test_stream} = - @command.run(["rabbitmq_federation", "rabbitmq_stomp"], context[:opts]) - assert [[:rabbitmq_federation, :rabbitmq_stomp], - %{mode: :online, - started: [:rabbitmq_federation, :rabbitmq_stomp], - stopped: [], - set: [:rabbitmq_federation, :rabbitmq_stomp]}] = - Enum.to_list(test_stream) + @command.run(["rabbitmq_federation", "rabbitmq_stomp"], context[:opts]) + + assert [ + [:rabbitmq_federation, :rabbitmq_stomp], + %{ + mode: :online, + started: [:rabbitmq_federation, :rabbitmq_stomp], + stopped: [], + set: [:rabbitmq_federation, :rabbitmq_stomp] + } + ] = Enum.to_list(test_stream) + assert {:ok, [[:rabbitmq_federation, :rabbitmq_stomp]]} = - :file.consult(context[:opts][:enabled_plugins_file]) + :file.consult(context[:opts][:enabled_plugins_file]) + assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] = - Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) + Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, [])) end test "run: does not enable plugins with unmet version requirements", context do @@ -147,7 +197,6 @@ defmodule SetPluginsCommandTest do opts = get_opts_with_plugins_directories(context, [plugins_directory]) switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir]) - {:stream, _} = @command.run(["mock_rabbitmq_plugin_for_3_9"], opts) check_plugins_enabled([:mock_rabbitmq_plugin_for_3_9], context) diff --git a/deps/rabbitmq_cli/test/queues/add_member_command_test.exs b/deps/rabbitmq_cli/test/queues/add_member_command_test.exs index 71705ccb2cd0..d7a024c579d3 100644 --- a/deps/rabbitmq_cli/test/queues/add_member_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/add_member_command_test.exs @@ -17,13 +17,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.AddMemberCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: when no arguments are provided, returns a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -33,8 +33,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.AddMemberCommandTest do end test "validate: when three or more arguments are provided, returns a failure" do - assert @command.validate(["quorum-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["quorum-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate( + ["quorum-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], + %{} + ) == {:validation_failure, :too_many_args} end test "validate: treats two positional arguments and default switches as a success" do @@ -43,7 +48,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.AddMemberCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a", "rabbit@new-node"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a", "rabbit@new-node"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/check_if_node_is_mirror_sync_critical_command_test.exs b/deps/rabbitmq_cli/test/queues/check_if_node_is_mirror_sync_critical_command_test.exs index cbab5a6470bb..120157f3babd 100644 --- a/deps/rabbitmq_cli/test/queues/check_if_node_is_mirror_sync_critical_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/check_if_node_is_mirror_sync_critical_command_test.exs @@ -17,10 +17,11 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsMirrorSyncCriticalCommandTes end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "validate: accepts no positional arguments" do @@ -29,8 +30,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsMirrorSyncCriticalCommandTes test "validate: any positional arguments fail validation" do assert @command.validate(["quorum-queue-a"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "two"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "two", "three"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "two"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "two", "three"], %{}) == + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 diff --git a/deps/rabbitmq_cli/test/queues/check_if_node_is_quorum_critical_command_test.exs b/deps/rabbitmq_cli/test/queues/check_if_node_is_quorum_critical_command_test.exs index 3a1b8abf3495..af81671639a4 100644 --- a/deps/rabbitmq_cli/test/queues/check_if_node_is_quorum_critical_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/check_if_node_is_quorum_critical_command_test.exs @@ -17,10 +17,11 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsQuorumCriticalCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end test "validate: accepts no positional arguments" do @@ -29,8 +30,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.CheckIfNodeIsQuorumCriticalCommandTest do test "validate: any positional arguments fail validation" do assert @command.validate(["quorum-queue-a"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "two"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "two", "three"], %{}) == {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "two"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "two", "three"], %{}) == + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 diff --git a/deps/rabbitmq_cli/test/queues/delete_member_command_test.exs b/deps/rabbitmq_cli/test/queues/delete_member_command_test.exs index 6880de639909..2473ad8eb459 100644 --- a/deps/rabbitmq_cli/test/queues/delete_member_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/delete_member_command_test.exs @@ -17,13 +17,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.DeleteMemberCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: when no arguments are provided, returns a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -33,8 +33,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.DeleteMemberCommandTest do end test "validate: when three or more arguments are provided, returns a failure" do - assert @command.validate(["quorum-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["quorum-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate( + ["quorum-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], + %{} + ) == {:validation_failure, :too_many_args} end test "validate: treats two positional arguments and default switches as a success" do @@ -43,7 +48,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.DeleteMemberCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a", "rabbit@new-node"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a", "rabbit@new-node"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/grow_command_test.exs b/deps/rabbitmq_cli/test/queues/grow_command_test.exs index d0d459065bd4..5c88c7ca793e 100644 --- a/deps/rabbitmq_cli/test/queues/grow_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/grow_command_test.exs @@ -17,20 +17,19 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - vhost_pattern: ".*", - queue_pattern: ".*", - errors_only: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + vhost_pattern: ".*", + queue_pattern: ".*", + errors_only: false + }} end test "merge_defaults: defaults to reporting complete results" do assert @command.merge_defaults([], %{}) == - {[], %{vhost_pattern: ".*", - queue_pattern: ".*", - errors_only: false}} + {[], %{vhost_pattern: ".*", queue_pattern: ".*", errors_only: false}} end test "validate: when no arguments are provided, returns a failure" do @@ -51,17 +50,22 @@ defmodule RabbitMQ.CLI.Queues.Commands.GrowCommandTest do test "validate: when a node and something else is provided, returns a failure" do assert @command.validate(["quorum-queue-a", "banana"], %{}) == - {:validation_failure, "strategy 'banana' is not recognised."} + {:validation_failure, "strategy 'banana' is not recognised."} end test "validate: when three arguments are provided, returns a failure" do assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a", "all"], - Map.merge(context[:opts], %{node: :jake@thedog, timeout: 200}))) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a", "all"], + Map.merge(context[:opts], %{node: :jake@thedog, timeout: 200}) + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/peek_command_test.exs b/deps/rabbitmq_cli/test/queues/peek_command_test.exs index 567de4f4d224..7732d4078bda 100644 --- a/deps/rabbitmq_cli/test/queues/peek_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/peek_command_test.exs @@ -18,13 +18,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: treats no arguments as a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -35,6 +35,7 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommandTest do test "validate: when two or more arguments are provided, returns a failure" do assert @command.validate(["quorum-queue-a", "1"], %{}) == :ok + assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} end @@ -53,7 +54,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.PeekCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a", "1"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a", "1"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/quorum_status_command_test.exs b/deps/rabbitmq_cli/test/queues/quorum_status_command_test.exs index ec694db9ba5a..1dd43921d680 100644 --- a/deps/rabbitmq_cli/test/queues/quorum_status_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/quorum_status_command_test.exs @@ -17,13 +17,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.QuorumStatusCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: treats no arguments as a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -33,13 +33,21 @@ defmodule RabbitMQ.CLI.Queues.Commands.QuorumStatusCommandTest do end test "validate: when two or more arguments are provided, returns a failure" do - assert @command.validate(["quorum-queue-a", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["quorum-queue-a", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/reclaim_quorum_memory_command_test.exs b/deps/rabbitmq_cli/test/queues/reclaim_quorum_memory_command_test.exs index bec7bab50d01..853986a329aa 100644 --- a/deps/rabbitmq_cli/test/queues/reclaim_quorum_memory_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/reclaim_quorum_memory_command_test.exs @@ -17,13 +17,13 @@ defmodule RabbitMQ.CLI.Queues.Commands.ReclaimQuorumMemoryCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: treats no arguments as a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -33,13 +33,21 @@ defmodule RabbitMQ.CLI.Queues.Commands.ReclaimQuorumMemoryCommandTest do end test "validate: when two or more arguments are provided, returns a failure" do - assert @command.validate(["quorum-queue-a", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["quorum-queue-a", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/shrink_command_test.exs b/deps/rabbitmq_cli/test/queues/shrink_command_test.exs index 8441deaeb0fd..7f30df8b0672 100644 --- a/deps/rabbitmq_cli/test/queues/shrink_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/shrink_command_test.exs @@ -17,11 +17,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - errors_only: false - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + errors_only: false + }} end test "merge_defaults: defaults to reporting complete results" do @@ -38,9 +39,10 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommandTest do test "validate: when three or more arguments are provided, returns a failure" do assert @command.validate(["quorum-queue-a", "one-extra-arg"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} + assert @command.validate(["quorum-queue-a", "extra-arg", "another-extra-arg"], %{}) == - {:validation_failure, :too_many_args} + {:validation_failure, :too_many_args} end test "validate: treats one positional arguments and default switches as a success" do @@ -49,7 +51,12 @@ defmodule RabbitMQ.CLI.Queues.Commands.ShrinkCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc", context do - assert match?({:badrpc, _}, @command.run(["quorum-queue-a"], - Map.merge(context[:opts], %{node: :jake@thedog, vhost: "/", timeout: 200}))) + assert match?( + {:badrpc, _}, + @command.run( + ["quorum-queue-a"], + Map.merge(context[:opts], %{node: :jake@thedog, vhost: "/", timeout: 200}) + ) + ) end end diff --git a/deps/rabbitmq_cli/test/queues/stream_status_command_test.exs b/deps/rabbitmq_cli/test/queues/stream_status_command_test.exs index edcdd6e2a204..34198713d26e 100644 --- a/deps/rabbitmq_cli/test/queues/stream_status_command_test.exs +++ b/deps/rabbitmq_cli/test/queues/stream_status_command_test.exs @@ -17,13 +17,13 @@ defmodule RabbitMQ.CLI.Streams.Commands.StreamStatusCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: treats no arguments as a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -33,13 +33,21 @@ defmodule RabbitMQ.CLI.Streams.Commands.StreamStatusCommandTest do end test "validate: when two or more arguments are provided, returns a failure" do - assert @command.validate(["stream-queue-a", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["stream-queue-a", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["stream-queue-a", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["stream-queue-a", "extra-arg", "another-extra-arg"], %{}) == + {:validation_failure, :too_many_args} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["stream-queue-a"], - %{node: :jake@thedog, vhost: "/", timeout: 200, tracking: false})) + assert match?( + {:badrpc, _}, + @command.run( + ["stream-queue-a"], + %{node: :jake@thedog, vhost: "/", timeout: 200, tracking: false} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/rabbitmqctl_test.exs b/deps/rabbitmq_cli/test/rabbitmqctl_test.exs index c6b085daad87..6892d8bab8cc 100644 --- a/deps/rabbitmq_cli/test/rabbitmqctl_test.exs +++ b/deps/rabbitmq_cli/test/rabbitmqctl_test.exs @@ -4,14 +4,12 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule RabbitMQCtlTest do use ExUnit.Case, async: false import ExUnit.CaptureIO import RabbitMQ.CLI.Core.ExitCodes import TestHelper - setup_all do RabbitMQ.CLI.Core.Distribution.start() @@ -26,30 +24,34 @@ defmodule RabbitMQCtlTest do test "--help option prints help for the command and exits with an OK" do command = ["status", "--help"] + assert capture_io(fn -> - error_check(command, exit_ok()) - end) =~ ~r/Usage/ + error_check(command, exit_ok()) + end) =~ ~r/Usage/ end test "bare --help prints general help and exits with an OK" do command = ["--help"] + assert capture_io(fn -> - error_check(command, exit_ok()) - end) =~ ~r/Usage/ + error_check(command, exit_ok()) + end) =~ ~r/Usage/ end test "help [command] prints help for the command and exits with an OK" do command = ["help", "status"] + assert capture_io(fn -> - error_check(command, exit_ok()) - end) =~ ~r/Usage/ + error_check(command, exit_ok()) + end) =~ ~r/Usage/ end test "bare help command prints general help and exits with an OK" do command = ["help"] + assert capture_io(fn -> - error_check(command, exit_ok()) - end) =~ ~r/Usage/ + error_check(command, exit_ok()) + end) =~ ~r/Usage/ end # @@ -58,53 +60,63 @@ defmodule RabbitMQCtlTest do test "print error message on a bad connection" do command = ["status", "-n", "sandwich@pastrami"] + assert capture_io(:stderr, fn -> - error_check(command, exit_unavailable()) - end) =~ ~r/unable to perform an operation on node 'sandwich@pastrami'/ + error_check(command, exit_unavailable()) + end) =~ ~r/unable to perform an operation on node 'sandwich@pastrami'/ end test "when an RPC call times out, prints a timeout message" do command = ["list_users", "-t", "0"] + assert capture_io(:stderr, fn -> - error_check(command, exit_tempfail()) - end) =~ ~r/Error: operation list_users on node #{get_rabbit_hostname()} timed out. Timeout value used: 0/ + error_check(command, exit_tempfail()) + end) =~ + ~r/Error: operation list_users on node #{get_rabbit_hostname()} timed out. Timeout value used: 0/ end test "when authentication fails, prints an authentication error message" do - add_user "kirk", "khaaaaaan" + add_user("kirk", "khaaaaaan") command = ["authenticate_user", "kirk", "makeitso"] - assert capture_io(:stderr, - fn -> error_check(command, exit_dataerr()) - end) =~ ~r/Error: failed to authenticate user \"kirk\"/ - delete_user "kirk" + + assert capture_io( + :stderr, + fn -> error_check(command, exit_dataerr()) end + ) =~ ~r/Error: failed to authenticate user \"kirk\"/ + + delete_user("kirk") end test "when invoked without arguments, displays a generic usage message and exits with a non-zero code" do command = [] + assert capture_io(:stderr, fn -> - error_check(command, exit_usage()) - end) =~ ~r/usage/i + error_check(command, exit_usage()) + end) =~ ~r/usage/i end test "when invoked with only a --help, shows a generic usage message and exits with a success" do command = ["--help"] + assert capture_io(:stdio, fn -> - error_check(command, exit_ok()) - end) =~ ~r/usage/i + error_check(command, exit_ok()) + end) =~ ~r/usage/i end test "when invoked with --help [command], shows a generic usage message and exits with a success" do command = ["--help", "status"] + assert capture_io(:stdio, fn -> - error_check(command, exit_ok()) - end) =~ ~r/usage/i + error_check(command, exit_ok()) + end) =~ ~r/usage/i end test "when no command name is provided, displays usage" do command = ["-n", "sandwich@pastrami"] + assert capture_io(:stderr, fn -> - error_check(command, exit_usage()) - end) =~ ~r/usage/i + error_check(command, exit_usage()) + end) =~ ~r/usage/i end test "short node name without the host part connects properly" do @@ -114,16 +126,20 @@ defmodule RabbitMQCtlTest do test "a non-existent command results in help message displayed" do command = ["not_real"] + assert capture_io(:stderr, fn -> - error_check(command, exit_usage()) - end) =~ ~r/Usage/ + error_check(command, exit_usage()) + end) =~ ~r/Usage/ end test "a command that's been provided extra arguments exits with a reasonable error code" do command = ["status", "extra"] - output = capture_io(:stderr, fn -> - error_check(command, exit_usage()) - end) + + output = + capture_io(:stderr, fn -> + error_check(command, exit_usage()) + end) + assert output =~ ~r/too many arguments/ assert output =~ ~r/Usage/ assert output =~ ~r/status/ @@ -131,9 +147,12 @@ defmodule RabbitMQCtlTest do test "a command that's been provided insufficient arguments exits with a reasonable error code" do command = ["list_user_permissions"] - output = capture_io(:stderr, fn -> - error_check(command, exit_usage()) - end) + + output = + capture_io(:stderr, fn -> + error_check(command, exit_usage()) + end) + assert output =~ ~r/not enough arguments/ assert output =~ ~r/Usage/ assert output =~ ~r/list_user_permissions/ @@ -151,31 +170,34 @@ defmodule RabbitMQCtlTest do test "a mcommand with an unsupported option as the first command-line arg fails gracefully" do command1 = ["--invalid=true", "list_permissions", "-p", "/"] + assert capture_io(:stderr, fn -> - error_check(command1, exit_usage()) - end) =~ ~r/Invalid options for this command/ + error_check(command1, exit_usage()) + end) =~ ~r/Invalid options for this command/ command2 = ["--node", "rabbit", "status", "quack"] + assert capture_io(:stderr, fn -> - error_check(command2, exit_usage()) - end) =~ ~r/too many arguments./ + error_check(command2, exit_usage()) + end) =~ ~r/too many arguments./ command3 = ["--node", "rabbit", "add_user"] + assert capture_io(:stderr, fn -> - error_check(command3, exit_usage()) - end) =~ ~r/not enough arguments./ + error_check(command3, exit_usage()) + end) =~ ~r/not enough arguments./ end -## ------------------------- Default Flags ------------------------------------ + ## ------------------------- Default Flags ------------------------------------ test "an empty node option is filled with the default rabbit node" do assert RabbitMQCtl.merge_all_defaults(%{})[:node] == - TestHelper.get_rabbit_hostname() + TestHelper.get_rabbit_hostname() end test "a non-empty node option is not overwritten" do assert RabbitMQCtl.merge_all_defaults(%{node: :jake@thedog})[:node] == - :jake@thedog + :jake@thedog end test "an empty timeout option is set to infinity" do @@ -192,14 +214,16 @@ defmodule RabbitMQCtlTest do test "any flags that aren't global or command-specific cause a bad option" do command1 = ["status", "--nod=rabbit"] + assert capture_io(:stderr, fn -> - error_check(command1, exit_usage()) - end) =~ ~r/Invalid options for this command/ + error_check(command1, exit_usage()) + end) =~ ~r/Invalid options for this command/ command2 = ["list_permissions", "-o", "/"] + assert capture_io(:stderr, fn -> - error_check(command2, exit_usage()) - end) =~ ~r/Invalid options for this command/ + error_check(command2, exit_usage()) + end) =~ ~r/Invalid options for this command/ end # @@ -210,8 +234,17 @@ defmodule RabbitMQCtlTest do # Note: these are not script name (scope) aware without --script-name # but the actual command invoked in a shell will be check_output(["--auto-complete", "list_q"], "list_queues\n") - check_output(["--auto-complete", "list_con", "--script-name", "rabbitmq-diagnostics"], "list_connections\nlist_consumers\n") - check_output(["--auto-complete", "--script-name", "rabbitmq-diagnostics", "mem"], "memory_breakdown\n") + + check_output( + ["--auto-complete", "list_con", "--script-name", "rabbitmq-diagnostics"], + "list_connections\nlist_consumers\n" + ) + + check_output( + ["--auto-complete", "--script-name", "rabbitmq-diagnostics", "mem"], + "memory_breakdown\n" + ) + check_output(["--auto-complete", "--script-name", "rabbitmq-queues", "add_m"], "add_member\n") end @@ -219,39 +252,54 @@ defmodule RabbitMQCtlTest do # Note: these are not script name (scope) aware without --script-name # but the actual command invoked in a shell will be check_output(["autocomplete", "list_q"], "list_queues\n") - check_output(["autocomplete", "list_con", "--script-name", "rabbitmq-diagnostics"], "list_connections\nlist_consumers\n") - check_output(["autocomplete", "--script-name", "rabbitmq-diagnostics", "mem"], "memory_breakdown\n") + + check_output( + ["autocomplete", "list_con", "--script-name", "rabbitmq-diagnostics"], + "list_connections\nlist_consumers\n" + ) + + check_output( + ["autocomplete", "--script-name", "rabbitmq-diagnostics", "mem"], + "memory_breakdown\n" + ) + check_output(["autocomplete", "--script-name", "rabbitmq-queues", "add_m"], "add_member\n") end defp check_output(cmd, out) do assert capture_io(fn -> - error_check(cmd, exit_ok()) - end) == out + error_check(cmd, exit_ok()) + end) == out end - -## ------------------------- Error formatting --------------------------------- + ## ------------------------- Error formatting --------------------------------- test "badrpc nodedown error" do exit_code = exit_unavailable() node = :example@node + {:error, ^exit_code, message} = - RabbitMQCtl.handle_command_output( - {:error, {:badrpc, :nodedown}}, - :no_command, %{node: node}, - fn(output, _, _) -> output end) + RabbitMQCtl.handle_command_output( + {:error, {:badrpc, :nodedown}}, + :no_command, + %{node: node}, + fn output, _, _ -> output end + ) assert message =~ ~r/Error: unable to perform an operation on node/ assert message =~ ~r/DIAGNOSTICS/ assert message =~ ~r/attempted to contact/ localnode = :non_existent_node@localhost + {:error, ^exit_code, message} = - RabbitMQCtl.handle_command_output( - {:error, {:badrpc, :nodedown}}, - :no_command, %{node: localnode}, - fn(output, _, _) -> output end) + RabbitMQCtl.handle_command_output( + {:error, {:badrpc, :nodedown}}, + :no_command, + %{node: localnode}, + fn output, _, _ -> output end + ) + assert message =~ ~r/DIAGNOSTICS/ assert message =~ ~r/attempted to contact/ assert message =~ ~r/suggestion: start the node/ @@ -261,41 +309,54 @@ defmodule RabbitMQCtlTest do exit_code = exit_tempfail() timeout = 1000 nodename = :node@host - err_msg = "Error: operation example on node node@host timed out. Timeout value used: #{timeout}" + + err_msg = + "Error: operation example on node node@host timed out. Timeout value used: #{timeout}" + {:error, ^exit_code, ^err_msg} = RabbitMQCtl.handle_command_output( - {:error, {:badrpc, :timeout}}, - ExampleCommand, %{timeout: timeout, node: nodename}, - fn(output, _, _) -> output end) + {:error, {:badrpc, :timeout}}, + ExampleCommand, + %{timeout: timeout, node: nodename}, + fn output, _, _ -> output end + ) end test "generic error" do exit_code = exit_unavailable() + {:error, ^exit_code, "Error:\nerror message"} = RabbitMQCtl.handle_command_output( {:error, "error message"}, - :no_command, %{}, - fn(output, _, _) -> output end) + :no_command, + %{}, + fn output, _, _ -> output end + ) end test "inspect arbitrary error" do exit_code = exit_unavailable() error = %{i: [am: "arbitrary", error: 1]} inspected = inspect(error) + {:error, ^exit_code, "Error:\n" <> ^inspected} = RabbitMQCtl.handle_command_output( {:error, error}, - :no_command, %{}, - fn(output, _, _) -> output end) + :no_command, + %{}, + fn output, _, _ -> output end + ) end test "atom error" do exit_code = exit_unavailable() + {:error, ^exit_code, "Error:\nerror_message"} = RabbitMQCtl.handle_command_output( {:error, :error_message}, - :no_command, %{}, - fn(output, _, _) -> output end) + :no_command, + %{}, + fn output, _, _ -> output end + ) end - end diff --git a/deps/rabbitmq_cli/test/streams/add_replica_command_test.exs b/deps/rabbitmq_cli/test/streams/add_replica_command_test.exs index 5549342f0f5b..8f82f6214ed8 100644 --- a/deps/rabbitmq_cli/test/streams/add_replica_command_test.exs +++ b/deps/rabbitmq_cli/test/streams/add_replica_command_test.exs @@ -18,13 +18,13 @@ defmodule RabbitMQ.CLI.Streams.Commands.AddReplicaCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: when no arguments are provided, returns a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -34,8 +34,13 @@ defmodule RabbitMQ.CLI.Streams.Commands.AddReplicaCommandTest do end test "validate: when three or more arguments are provided, returns a failure" do - assert @command.validate(["stream-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["stream-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["stream-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate( + ["stream-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], + %{} + ) == {:validation_failure, :too_many_args} end test "validate: treats two positional arguments and default switches as a success" do @@ -44,7 +49,12 @@ defmodule RabbitMQ.CLI.Streams.Commands.AddReplicaCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["stream-queue-a", "rabbit@new-node"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["stream-queue-a", "rabbit@new-node"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/streams/delete_replica_command_test.exs b/deps/rabbitmq_cli/test/streams/delete_replica_command_test.exs index 63f1cd5c8388..215797517a17 100644 --- a/deps/rabbitmq_cli/test/streams/delete_replica_command_test.exs +++ b/deps/rabbitmq_cli/test/streams/delete_replica_command_test.exs @@ -18,14 +18,14 @@ defmodule RabbitMQ.CLI.Streams.Commands.DeleteReplicaCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000, - vhost: "/" - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000, + vhost: "/" + }} end - test "validate: when no arguments are provided, returns a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -35,23 +35,35 @@ defmodule RabbitMQ.CLI.Streams.Commands.DeleteReplicaCommandTest do end test "validate: when three or more arguments are provided, returns a failure" do - assert @command.validate(["stream-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["stream-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["stream-queue-a", "rabbit@new-node", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate( + ["stream-queue-a", "rabbit@new-node", "extra-arg", "another-extra-arg"], + %{} + ) == {:validation_failure, :too_many_args} end test "validate: treats two positional arguments and default switches as a success" do assert @command.validate(["stream-queue-a", "rabbit@new-node"], %{}) == :ok end - test "run: trying to delete the last member of a stream should fail and return a meaningful message", context do + test "run: trying to delete the last member of a stream should fail and return a meaningful message", + context do declare_stream("test_stream_1", "/") + assert @command.run(["test_stream_1", get_rabbit_hostname()], context[:opts]) == {:error, "Cannot delete the last member of a stream"} end @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["stream-queue-a", "rabbit@new-node"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["stream-queue-a", "rabbit@new-node"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end end diff --git a/deps/rabbitmq_cli/test/streams/set_stream_retention_policy_command_test.exs b/deps/rabbitmq_cli/test/streams/set_stream_retention_policy_command_test.exs index 2900d7eb25ee..146dfbce09e0 100644 --- a/deps/rabbitmq_cli/test/streams/set_stream_retention_policy_command_test.exs +++ b/deps/rabbitmq_cli/test/streams/set_stream_retention_policy_command_test.exs @@ -18,13 +18,13 @@ defmodule RabbitMQ.CLI.Streams.Commands.SetStreamRetentionPolicyCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 30000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 30000 + }} end - test "validate: when no arguments are provided, returns a failure" do assert @command.validate([], %{}) == {:validation_failure, :not_enough_args} end @@ -34,8 +34,11 @@ defmodule RabbitMQ.CLI.Streams.Commands.SetStreamRetentionPolicyCommandTest do end test "validate: when three or more arguments are provided, returns a failure" do - assert @command.validate(["stream-queue-a", "1D", "one-extra-arg"], %{}) == {:validation_failure, :too_many_args} - assert @command.validate(["stream-queue-a", "1D", "extra-arg", "another-extra-arg"], %{}) == {:validation_failure, :too_many_args} + assert @command.validate(["stream-queue-a", "1D", "one-extra-arg"], %{}) == + {:validation_failure, :too_many_args} + + assert @command.validate(["stream-queue-a", "1D", "extra-arg", "another-extra-arg"], %{}) == + {:validation_failure, :too_many_args} end test "validate: treats two positional arguments and default switches as a success" do @@ -44,12 +47,22 @@ defmodule RabbitMQ.CLI.Streams.Commands.SetStreamRetentionPolicyCommandTest do @tag test_timeout: 3000 test "run: targeting an unreachable node throws a badrpc" do - assert match?({:badrpc, _}, @command.run(["stream-queue-a", "1Y"], - %{node: :jake@thedog, vhost: "/", timeout: 200})) + assert match?( + {:badrpc, _}, + @command.run( + ["stream-queue-a", "1Y"], + %{node: :jake@thedog, vhost: "/", timeout: 200} + ) + ) end test "run: targeting an unknown queue returns an error", context do - assert match?({:error, _}, @command.run(["stream-queue-a", "1Y"], - Map.merge(context[:opts], %{vhost: "/"}))) + assert match?( + {:error, _}, + @command.run( + ["stream-queue-a", "1Y"], + Map.merge(context[:opts], %{vhost: "/"}) + ) + ) end end diff --git a/deps/rabbitmq_cli/test/test_helper.exs b/deps/rabbitmq_cli/test/test_helper.exs index 0ad6044729f9..48878e32bb84 100644 --- a/deps/rabbitmq_cli/test/test_helper.exs +++ b/deps/rabbitmq_cli/test/test_helper.exs @@ -5,10 +5,12 @@ ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. four_hours = 240 * 60 * 1000 + ExUnit.configure( exclude: [disabled: true], module_load_timeout: four_hours, - timeout: four_hours) + timeout: four_hours +) ExUnit.start() @@ -64,13 +66,18 @@ defmodule TestHelper do end def add_user(name, password) do - :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :add_user, - [name, password, "acting-user"]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :add_user, [ + name, + password, + "acting-user" + ]) end def delete_user(name) do - :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :delete_user, - [name, "acting-user"]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :delete_user, [ + name, + "acting-user" + ]) end def list_users() do @@ -86,7 +93,11 @@ defmodule TestHelper do end def set_user_tags(name, tags) do - :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :set_tags, [name, tags, "acting-user"]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :set_tags, [ + name, + tags, + "acting-user" + ]) end def set_vhost_tags(name, tags) do @@ -94,15 +105,30 @@ defmodule TestHelper do end def authenticate_user(name, password) do - :rpc.call(get_rabbit_hostname(), :rabbit_access_control,:check_user_pass_login, [name, password]) + :rpc.call(get_rabbit_hostname(), :rabbit_access_control, :check_user_pass_login, [ + name, + password + ]) end def set_parameter(vhost, component_name, key, value) do - :ok = :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :parse_set, [vhost, component_name, key, value, :nouser]) + :ok = + :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :parse_set, [ + vhost, + component_name, + key, + value, + :nouser + ]) end def clear_parameter(vhost, component_name, key) do - :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :clear, [vhost, component_name, key, <<"acting-user">>]) + :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :clear, [ + vhost, + component_name, + key, + <<"acting-user">> + ]) end def list_parameters(vhost) do @@ -110,13 +136,19 @@ defmodule TestHelper do end def set_global_parameter(key, value) do - :ok = :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :parse_set_global, - [key, value, "acting-user"]) + :ok = + :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :parse_set_global, [ + key, + value, + "acting-user" + ]) end def clear_global_parameter(key) do - :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :clear_global, - [key, "acting-user"]) + :rpc.call(get_rabbit_hostname(), :rabbit_runtime_parameters, :clear_global, [ + key, + "acting-user" + ]) end def list_global_parameters() do @@ -124,7 +156,14 @@ defmodule TestHelper do end def set_permissions(user, vhost, [conf, write, read]) do - :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :set_permissions, [user, vhost, conf, write, read, "acting-user"]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :set_permissions, [ + user, + vhost, + conf, + write, + read, + "acting-user" + ]) end def list_policies(vhost) do @@ -134,7 +173,17 @@ defmodule TestHelper do def set_policy(vhost, name, pattern, value) do {:ok, decoded} = :rabbit_json.try_decode(value) parsed = :maps.to_list(decoded) - :ok = :rpc.call(get_rabbit_hostname(), :rabbit_policy, :set, [vhost, name, pattern, parsed, 0, "all", "acting-user"]) + + :ok = + :rpc.call(get_rabbit_hostname(), :rabbit_policy, :set, [ + vhost, + name, + pattern, + parsed, + 0, + "all", + "acting-user" + ]) end def clear_policy(vhost, key) do @@ -148,18 +197,41 @@ defmodule TestHelper do def set_operator_policy(vhost, name, pattern, value) do {:ok, decoded} = :rabbit_json.try_decode(value) parsed = :maps.to_list(decoded) - :ok = :rpc.call(get_rabbit_hostname(), :rabbit_policy, :set_op, [vhost, name, pattern, parsed, 0, "all", "acting-user"]) + + :ok = + :rpc.call(get_rabbit_hostname(), :rabbit_policy, :set_op, [ + vhost, + name, + pattern, + parsed, + 0, + "all", + "acting-user" + ]) end def clear_operator_policy(vhost, key) do :rpc.call(get_rabbit_hostname(), :rabbit_policy, :delete_op, [vhost, key, "acting-user"]) end - def declare_queue(name, vhost, durable \\ false, auto_delete \\ false, args \\ [], owner \\ :none) do + def declare_queue( + name, + vhost, + durable \\ false, + auto_delete \\ false, + args \\ [], + owner \\ :none + ) do queue_name = :rabbit_misc.r(vhost, :queue, name) - :rpc.call(get_rabbit_hostname(), - :rabbit_amqqueue, :declare, - [queue_name, durable, auto_delete, args, owner, "acting-user"]) + + :rpc.call(get_rabbit_hostname(), :rabbit_amqqueue, :declare, [ + queue_name, + durable, + auto_delete, + args, + owner, + "acting-user" + ]) end def declare_stream(name, vhost) do @@ -168,23 +240,40 @@ defmodule TestHelper do def delete_queue(name, vhost) do queue_name = :rabbit_misc.r(vhost, :queue, name) - :rpc.call(get_rabbit_hostname(), - :rabbit_amqqueue, :delete, - [queue_name, false, false, "acting-user"]) + + :rpc.call(get_rabbit_hostname(), :rabbit_amqqueue, :delete, [ + queue_name, + false, + false, + "acting-user" + ]) end def lookup_queue(name, vhost) do queue_name = :rabbit_misc.r(vhost, :queue, name) - :rpc.call(get_rabbit_hostname(), - :rabbit_amqqueue, :lookup, - [queue_name]) - end - - def declare_exchange(name, vhost, type \\ :direct, durable \\ false, auto_delete \\ false, internal \\ false, args \\ []) do + :rpc.call(get_rabbit_hostname(), :rabbit_amqqueue, :lookup, [queue_name]) + end + + def declare_exchange( + name, + vhost, + type \\ :direct, + durable \\ false, + auto_delete \\ false, + internal \\ false, + args \\ [] + ) do exchange_name = :rabbit_misc.r(vhost, :exchange, name) - :rpc.call(get_rabbit_hostname(), - :rabbit_exchange, :declare, - [exchange_name, type, durable, auto_delete, internal, args, "acting-user"]) + + :rpc.call(get_rabbit_hostname(), :rabbit_exchange, :declare, [ + exchange_name, + type, + durable, + auto_delete, + internal, + args, + "acting-user" + ]) end def list_permissions(vhost) do @@ -199,11 +288,11 @@ defmodule TestHelper do def set_topic_permissions(user, vhost, exchange, writePerm, readPerm) do :rpc.call( - get_rabbit_hostname(), - :rabbit_auth_backend_internal, - :set_topic_permissions, - [user, vhost, exchange, writePerm, readPerm, "acting-user"], - :infinity + get_rabbit_hostname(), + :rabbit_auth_backend_internal, + :set_topic_permissions, + [user, vhost, exchange, writePerm, readPerm, "acting-user"], + :infinity ) end @@ -218,14 +307,14 @@ defmodule TestHelper do end def clear_topic_permissions(user, vhost) do - :rpc.call( - get_rabbit_hostname(), - :rabbit_auth_backend_internal, - :clear_topic_permissions, - [user, vhost, "acting-user"], - :infinity - ) - end + :rpc.call( + get_rabbit_hostname(), + :rabbit_auth_backend_internal, + :clear_topic_permissions, + [user, vhost, "acting-user"], + :infinity + ) + end def set_vm_memory_high_watermark(limit) do :rpc.call(get_rabbit_hostname(), :vm_memory_monitor, :set_vm_memory_high_watermark, [limit]) @@ -235,7 +324,6 @@ defmodule TestHelper do :rpc.call(get_rabbit_hostname(), :rabbit_disk_monitor, :set_disk_free_limit, [limit]) end - # # App lifecycle # @@ -245,15 +333,20 @@ defmodule TestHelper do end def await_rabbitmq_startup_with_retries(0) do - throw({:error, "Failed to call rabbit.await_startup/0 with retries: node #{get_rabbit_hostname()} was down"}) + throw( + {:error, + "Failed to call rabbit.await_startup/0 with retries: node #{get_rabbit_hostname()} was down"} + ) end + def await_rabbitmq_startup_with_retries(retries_left) do case :rabbit_misc.rpc_call(get_rabbit_hostname(), :rabbit, :await_startup, []) do :ok -> - :ok + :ok + {:badrpc, :nodedown} -> - :timer.sleep(50) - await_rabbitmq_startup_with_retries(retries_left - 1) + :timer.sleep(50) + await_rabbitmq_startup_with_retries(retries_left - 1) end end @@ -265,12 +358,15 @@ defmodule TestHelper do def await_condition_with_retries(_fun, 0) do throw({:error, "Condition did not materialize"}) end + def await_condition_with_retries(fun, retries_left) do case fun.() do - true -> :ok - _ -> - :timer.sleep(50) - await_condition_with_retries(fun, retries_left - 1) + true -> + :ok + + _ -> + :timer.sleep(50) + await_condition_with_retries(fun, retries_left - 1) end end @@ -311,17 +407,20 @@ defmodule TestHelper do end def with_channel(vhost, fun) do - with_connection(vhost, - fn(conn) -> + with_connection( + vhost, + fn conn -> {:ok, chan} = AMQP.Channel.open(conn) AMQP.Confirm.select(chan) fun.(chan) - end) + end + ) end def with_connection(vhost, fun) do Application.ensure_all_started(:amqp) {:ok, conn} = AMQP.Connection.open(virtual_host: vhost) + ExUnit.Callbacks.on_exit(fn -> try do :amqp_connection.close(conn, 1000) @@ -329,15 +428,19 @@ defmodule TestHelper do :exit, _ -> :ok end end) + fun.(conn) end def with_connections(vhosts, fun) do Application.ensure_all_started(:amqp) - conns = for v <- vhosts do - {:ok, conn} = AMQP.Connection.open(virtual_host: v) - conn - end + + conns = + for v <- vhosts do + {:ok, conn} = AMQP.Connection.open(virtual_host: v) + conn + end + ExUnit.Callbacks.on_exit(fn -> try do for c <- conns, do: :amqp_connection.close(c, 1000) @@ -345,23 +448,25 @@ defmodule TestHelper do :exit, _ -> :ok end end) + fun.(conns) end def message_count(vhost, queue_name) do - with_channel(vhost, fn(channel) -> + with_channel(vhost, fn channel -> {:ok, %{message_count: mc}} = AMQP.Queue.declare(channel, queue_name) mc end) end def publish_messages(vhost, queue_name, count) do - with_channel(vhost, fn(channel) -> + with_channel(vhost, fn channel -> AMQP.Queue.purge(channel, queue_name) + for i <- 1..count do - AMQP.Basic.publish(channel, "", queue_name, - "test_message" <> Integer.to_string(i)) + AMQP.Basic.publish(channel, "", queue_name, "test_message" <> Integer.to_string(i)) end + AMQP.Confirm.wait_for_confirms(channel, 30) end) end @@ -372,11 +477,14 @@ defmodule TestHelper do end def await_no_client_connections_with_iterations(_node, n) when n <= 0 do - flunk "Ran out of retries, still have active client connections" + flunk("Ran out of retries, still have active client connections") end + def await_no_client_connections_with_iterations(node, n) when n > 0 do case :rpc.call(node, :rabbit_networking, :connections_local, []) do - [] -> :ok + [] -> + :ok + _xs -> :timer.sleep(10) await_no_client_connections_with_iterations(node, n - 1) @@ -401,12 +509,14 @@ defmodule TestHelper do for pid <- :rpc.call(node, :rabbit_networking, :connections_local, []) do :rpc.call(node, :rabbit_networking, :close_connection, [pid, :force_closed]) end + await_no_client_connections(node, 5000) end def expect_client_connection_failure() do expect_client_connection_failure("/") end + def expect_client_connection_failure(vhost) do Application.ensure_all_started(:amqp) assert {:error, :econnrefused} == AMQP.Connection.open(virtual_host: vhost) @@ -459,12 +569,14 @@ defmodule TestHelper do end def emit_list_multiple_sources(list1, list2, ref, pid) do - pids = for list <- [list1, list2], do: Kernel.spawn_link(TestHelper, :emit_list, [list, ref, pid]) + pids = + for list <- [list1, list2], do: Kernel.spawn_link(TestHelper, :emit_list, [list, ref, pid]) + :rabbit_control_misc.await_emitters_termination(pids) end def emit_list(list, ref, pid) do - emit_list_map(list, &(&1), ref, pid) + emit_list_map(list, & &1, ref, pid) end def emit_list_map(list, fun, ref, pid) do @@ -473,14 +585,15 @@ defmodule TestHelper do def run_command_to_list(command, args) do res = Kernel.apply(command, :run, args) + case Enumerable.impl_for(res) do - nil -> res; - _ -> Enum.to_list(res) + nil -> res + _ -> Enum.to_list(res) end end def vhost_exists?(vhost) do - Enum.any?(list_vhosts(), fn(v) -> v[:name] == vhost end) + Enum.any?(list_vhosts(), fn v -> v[:name] == vhost end) end def set_enabled_plugins(plugins, mode, node, opts) do @@ -495,35 +608,51 @@ defmodule TestHelper do def enable_federation_plugin() do node = get_rabbit_hostname() - {:ok, plugins_file} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :enabled_plugins_file]) - {:ok, plugins_dir} = :rabbit_misc.rpc_call(node, - :application, :get_env, - [:rabbit, :plugins_dir]) + + {:ok, plugins_file} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :enabled_plugins_file]) + + {:ok, plugins_dir} = + :rabbit_misc.rpc_call(node, :application, :get_env, [:rabbit, :plugins_dir]) + rabbitmq_home = :rabbit_misc.rpc_call(node, :code, :lib_dir, [:rabbit]) {:ok, [_enabled_plugins]} = :file.consult(plugins_file) - opts = %{enabled_plugins_file: plugins_file, - plugins_dir: plugins_dir, - rabbitmq_home: rabbitmq_home, - online: true, offline: false} + opts = %{ + enabled_plugins_file: plugins_file, + plugins_dir: plugins_dir, + rabbitmq_home: rabbitmq_home, + online: true, + offline: false + } plugins = currently_active_plugins(%{opts: %{node: node}}) + case Enum.member?(plugins, :rabbitmq_federation) do - true -> :ok + true -> + :ok + false -> - set_enabled_plugins(plugins ++ [:rabbitmq_federation], :online, get_rabbit_hostname(), opts) + set_enabled_plugins( + plugins ++ [:rabbitmq_federation], + :online, + get_rabbit_hostname(), + opts + ) end end def set_vhost_limits(vhost, limits) do - :rpc.call(get_rabbit_hostname(), - :rabbit_vhost_limit, :parse_set, [vhost, limits, <<"acting-user">>]) + :rpc.call(get_rabbit_hostname(), :rabbit_vhost_limit, :parse_set, [ + vhost, + limits, + <<"acting-user">> + ]) end + def get_vhost_limits(vhost) do :rpc.call(get_rabbit_hostname(), :rabbit_vhost_limit, :list, [vhost]) - |> Map.new + |> Map.new() end def clear_vhost_limits(vhost) do @@ -539,23 +668,29 @@ defmodule TestHelper do end def set_user_limits(user, limits) do - :rpc.call(get_rabbit_hostname(), - :rabbit_auth_backend_internal, :set_user_limits, [user, limits, <<"acting-user">>]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :set_user_limits, [ + user, + limits, + <<"acting-user">> + ]) end def get_user_limits(user) do :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :get_user_limits, [user]) - |> Map.new + |> Map.new() end def clear_user_limits(user) do - clear_user_limits user, "max-connections" - clear_user_limits user, "max-channels" + clear_user_limits(user, "max-connections") + clear_user_limits(user, "max-channels") end def clear_user_limits(user, limittype) do - :rpc.call(get_rabbit_hostname(), - :rabbit_auth_backend_internal, :clear_user_limits, [user, limittype, <<"acting-user">>]) + :rpc.call(get_rabbit_hostname(), :rabbit_auth_backend_internal, :clear_user_limits, [ + user, + limittype, + <<"acting-user">> + ]) end def set_scope(scope) do @@ -566,11 +701,18 @@ defmodule TestHelper do end def switch_plugins_directories(old_value, new_value) do - :rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env, - [:rabbit, :plugins_dir, new_value]) + :rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env, [ + :rabbit, + :plugins_dir, + new_value + ]) + ExUnit.Callbacks.on_exit(fn -> - :rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env, - [:rabbit, :plugins_dir, old_value]) + :rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env, [ + :rabbit, + :plugins_dir, + old_value + ]) end) end @@ -588,9 +730,11 @@ defmodule TestHelper do def get_opts_with_existing_plugins_directory(context) do extra_plugin_directory = System.tmp_dir!() |> Path.join("existing_rabbitmq_dummy_plugins") File.mkdir!(extra_plugin_directory) + ExUnit.Callbacks.on_exit(fn -> File.rm_rf(extra_plugin_directory) end) + get_opts_with_plugins_directories(context, [extra_plugin_directory]) end @@ -606,30 +750,40 @@ defmodule TestHelper do end def assert_stream_without_errors(stream) do - true = Enum.all?(stream, fn({:error, _}) -> false; - ({:error, _, _}) -> false; - (_) -> true end) + true = + Enum.all?(stream, fn + {:error, _} -> false + {:error, _, _} -> false + _ -> true + end) end def wait_for_log_message(message, file \\ nil, attempts \\ 100) do ## Assume default log is the first one - log_file = case file do - nil -> - [default_log | _] = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) - default_log - _ -> file - end + log_file = + case file do + nil -> + [default_log | _] = :rpc.call(get_rabbit_hostname(), :rabbit, :log_locations, []) + default_log + + _ -> + file + end + case File.read(log_file) do {:ok, data} -> case String.match?(data, Regex.compile!(message)) do - true -> :ok + true -> + :ok + false -> :timer.sleep(100) wait_for_log_message(message, log_file, attempts - 1) end + _ -> :timer.sleep(100) - wait_for_log_message(message, log_file, attempts - 1) + wait_for_log_message(message, log_file, attempts - 1) end end end diff --git a/deps/rabbitmq_cli/test/upgrade/await_online_quorum_plus_one_command_test.exs b/deps/rabbitmq_cli/test/upgrade/await_online_quorum_plus_one_command_test.exs index c169f9ff5de0..bbc784102268 100644 --- a/deps/rabbitmq_cli/test/upgrade/await_online_quorum_plus_one_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/await_online_quorum_plus_one_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AwaitOnlineQuorumPlusOneCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,10 +17,11 @@ defmodule AwaitOnlineQuorumPlusOneCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} end test "merge_defaults: overrides a timeout" do @@ -41,5 +41,4 @@ defmodule AwaitOnlineQuorumPlusOneCommandTest do opts = %{node: :jake@thedog, timeout: 200} assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], opts))) end - end diff --git a/deps/rabbitmq_cli/test/upgrade/await_online_synchronized_mirror_command_test.exs b/deps/rabbitmq_cli/test/upgrade/await_online_synchronized_mirror_command_test.exs index 7089dada2cc8..ff96712dec4b 100644 --- a/deps/rabbitmq_cli/test/upgrade/await_online_synchronized_mirror_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/await_online_synchronized_mirror_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule AwaitOnlineSynchronizedMirrorsCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,10 +17,11 @@ defmodule AwaitOnlineSynchronizedMirrorsCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} end test "merge_defaults: overrides a timeout" do @@ -41,5 +41,4 @@ defmodule AwaitOnlineSynchronizedMirrorsCommandTest do opts = %{node: :jake@thedog, timeout: 200} assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], opts))) end - end diff --git a/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs b/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs index 90e6c7aeb501..a58f8b6a33ab 100644 --- a/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs @@ -23,12 +23,20 @@ defmodule DrainCommandTest do end setup context do +<<<<<<< HEAD enable_feature_flag(:maintenance_mode_status) {:ok, opts: %{ node: get_rabbit_hostname(), timeout: context[:test_timeout] || 5000 }} +======= + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} +>>>>>>> 059978e6fa (mix format rabbitmq_cli) end test "merge_defaults: nothing to do" do diff --git a/deps/rabbitmq_cli/test/upgrade/post_upgrade_command_test.exs b/deps/rabbitmq_cli/test/upgrade/post_upgrade_command_test.exs index e77390ecf063..3f6aa845f984 100644 --- a/deps/rabbitmq_cli/test/upgrade/post_upgrade_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/post_upgrade_command_test.exs @@ -4,7 +4,6 @@ ## ## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. - defmodule PostUpgradeCommandTest do use ExUnit.Case, async: false import TestHelper @@ -18,10 +17,11 @@ defmodule PostUpgradeCommandTest do end setup context do - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} end test "merge_defaults: nothing to do" do @@ -45,5 +45,4 @@ defmodule PostUpgradeCommandTest do test "run: returns an OK", context do assert match?({:ok, _}, @command.run([], context[:opts])) end - end diff --git a/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs b/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs index ba39c9046972..087cfb080507 100644 --- a/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs @@ -23,12 +23,20 @@ defmodule ReviveCommandTest do end setup context do +<<<<<<< HEAD enable_feature_flag(:maintenance_mode_status) {:ok, opts: %{ node: get_rabbit_hostname(), timeout: context[:test_timeout] || 5000 }} +======= + {:ok, + opts: %{ + node: get_rabbit_hostname(), + timeout: context[:test_timeout] || 5000 + }} +>>>>>>> 059978e6fa (mix format rabbitmq_cli) end test "merge_defaults: nothing to do" do From 810aee789f6bf21f3a89fb5f1ab74033d8a6dce6 Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 18:56:48 +0100 Subject: [PATCH 30/49] remove deprecated and replace with import Config module (cherry picked from commit 345a580f6d63eac8a6c7b06e57a3938ab06b7c01) (cherry picked from commit 5cc730e50f9db551925d2b46bdc9292b8470bdb3) --- deps/rabbitmq_cli/config/config.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rabbitmq_cli/config/config.exs b/deps/rabbitmq_cli/config/config.exs index 3cc55242115f..570a8258b517 100644 --- a/deps/rabbitmq_cli/config/config.exs +++ b/deps/rabbitmq_cli/config/config.exs @@ -6,7 +6,7 @@ # This file is responsible for configuring your application # and its dependencies with the aid of the Mix.Config module. -use Mix.Config +import Config # This configuration is loaded before any dependency and is restricted # to this project. If another project depends on this project, this From e79a85c132bcf20feb8feb751e1560627e4491ba Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 19:07:08 +0100 Subject: [PATCH 31/49] add rabbitmq_cli format check on make/mix task aliases (cherry picked from commit c4b42f6c508633131fa1514fd68acbd31ca3418f) (cherry picked from commit 27dae04ab1486bf16871f7c6a8a25b263af29e32) --- deps/rabbitmq_cli/mix.exs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deps/rabbitmq_cli/mix.exs b/deps/rabbitmq_cli/mix.exs index a34f72ee2053..b54dfe0b8093 100644 --- a/deps/rabbitmq_cli/mix.exs +++ b/deps/rabbitmq_cli/mix.exs @@ -195,18 +195,21 @@ defmodule RabbitMQCtl.MixfileBase do "deps.compile" ], make_app: [ + "format --check-formatted", "compile", "escript.build" ], make_all: [ "deps.get", "deps.compile", + "format --check-formatted", "compile", "escript.build" ], make_all_in_src_archive: [ "deps.get --only prod", "deps.compile", + "format --check-formatted", "compile", "escript.build" ] From 075df4027c76aff00e8e853987d519087a27484d Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 19:37:53 +0100 Subject: [PATCH 32/49] update contribution notes with rabbitmq_cli formatting instructions (cherry picked from commit febb4f6a17fcdd3a561ee0c8b4441bc68ad006b8) (cherry picked from commit d8f9b4618dd3159820a89035a3ec1951a70fc0db) --- CONTRIBUTING.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 44de22c86cef..40effb190675 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ The process is fairly standard: * Fork the repository or repositories you plan on contributing to * Run `make` * Create a branch with a descriptive name in the relevant repositories - * Make your changes, run tests, commit with a [descriptive message](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork + * Make your changes, run tests, ensure correct code formatting, commit with a [descriptive message](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), push to your fork * Submit pull requests with an explanation what has been changed and **why** * Submit a filled out and signed [Contributor Agreement](https://cla.pivotal.io/) if needed (see below) * Be patient. We will get to your pull request eventually @@ -43,6 +43,17 @@ make ct-cluster_rename t=cluster_size_3:partial_one_by_one Test output is in the `logs/` subdirectory. +## Formatting the RabbitMQ CLI + +The RabbitMQ CLI uses the standard [Elixir code formatter](https://hexdocs.pm/mix/main/Mix.Tasks.Format.html). To ensure correct code formatting of the CLI: + +``` +cd deps/rabbitmq_cli +mix format +``` + +Running `make` in `deps/rabbitmq_cli` will validate the CLI formatting and issue any necessary warnings. + ## Code of Conduct See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). From 4d5941fb00f86f68fa138e0e133ed2fad33a2bcb Mon Sep 17 00:00:00 2001 From: Ayanda Dube Date: Sun, 2 Oct 2022 23:40:19 +0100 Subject: [PATCH 33/49] extend contribution note on cli format checking (cherry picked from commit 82181983515a72cef342f9f846754cb616067ef3) (cherry picked from commit 01994ed5b1cb002abdcc29425b0c55df212121cc) --- CONTRIBUTING.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 40effb190675..add4ce967ebf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,7 +52,11 @@ cd deps/rabbitmq_cli mix format ``` -Running `make` in `deps/rabbitmq_cli` will validate the CLI formatting and issue any necessary warnings. +Running `make` will validate the CLI formatting and issue any necessary warnings. Alternatively, run the format checker in the `deps/rabbitmq_cli` directory: + +``` +mix format --check-formatted +``` ## Code of Conduct From 2b0855f33596cf09cc25da070dc32509170b16fd Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Tue, 4 Oct 2022 11:23:09 +0400 Subject: [PATCH 34/49] CLI: resolve conflicts and reformat --- .../lib/rabbitmq/cli/core/feature_flags.ex | 26 ----------- .../cli/ctl/commands/add_vhost_command.ex | 44 +------------------ deps/rabbitmq_cli/mix.exs | 12 +---- .../test/ctl/enable_feature_flag_test.exs | 8 +--- .../ctl/list_feature_flags_command_test.exs | 10 +---- .../test/upgrade/drain_command_test.exs | 7 --- .../test/upgrade/revive_command_test.exs | 7 --- 7 files changed, 5 insertions(+), 109 deletions(-) diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex index d4acfddd81e4..b7600f176331 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/core/feature_flags.ex @@ -5,36 +5,10 @@ ## Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. defmodule RabbitMQ.CLI.Core.FeatureFlags do - # # API # -<<<<<<< HEAD -======= - def is_enabled_remotely(node_name, feature_flag) do - case :rabbit_misc.rpc_call(node_name, :rabbit_feature_flags, :is_enabled, [feature_flag]) do - true -> true - false -> false - {:error, _} = error -> error - end - end - - def assert_feature_flag_enabled(node_name, feature_flag, success_fun) do - case is_enabled_remotely(node_name, feature_flag) do - true -> - success_fun.() - - false -> - {:error, ExitCodes.exit_dataerr(), - "The #{feature_flag} feature flag is not enabled on the target node"} - - {:error, _} = error -> - error - end - end - ->>>>>>> 059978e6fa (mix format rabbitmq_cli) def feature_flag_lines(feature_flags) do feature_flags |> Enum.map(fn %{name: name, state: state} -> diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex index 9f1214dd4e3e..5158bdeedcd7 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex @@ -19,13 +19,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do use RabbitMQ.CLI.Core.AcceptsOnePositionalArgument use RabbitMQ.CLI.Core.RequiresRabbitAppRunning -<<<<<<< HEAD - def run([vhost], %{node: node_name, description: desc, tags: tags, default_queue_type: default_qt}) do - meta = %{description: desc, - tags: parse_tags(tags), - default_queue_type: default_qt} - :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, meta, Helpers.cli_acting_user()]) -======= def run([vhost], %{ node: node_name, description: desc, @@ -33,34 +26,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do default_queue_type: default_qt }) do meta = %{description: desc, tags: parse_tags(tags), default_queue_type: default_qt} - # check if the respective feature flag is enabled - case default_qt do - "quorum" -> - FeatureFlags.assert_feature_flag_enabled(node_name, :quorum_queue, fn -> - :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ - vhost, - meta, - Helpers.cli_acting_user() - ]) - end) - - "stream" -> - FeatureFlags.assert_feature_flag_enabled(node_name, :stream_queue, fn -> - :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ - vhost, - meta, - Helpers.cli_acting_user() - ]) - end) - - _ -> - :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [ - vhost, - meta, - Helpers.cli_acting_user() - ]) - end ->>>>>>> 059978e6fa (mix format rabbitmq_cli) + + :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, meta, Helpers.cli_acting_user()]) end def run([vhost], %{node: node_name, description: desc, tags: tags}) do @@ -76,13 +43,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost, Helpers.cli_acting_user()]) end -<<<<<<< HEAD -======= - def output({:error, :invalid_queue_type}, _opts) do - {:error, ExitCodes.exit_usage(), "Unsupported default queue type"} - end - ->>>>>>> 059978e6fa (mix format rabbitmq_cli) use RabbitMQ.CLI.DefaultOutput def usage, diff --git a/deps/rabbitmq_cli/mix.exs b/deps/rabbitmq_cli/mix.exs index b54dfe0b8093..64aad5c48603 100644 --- a/deps/rabbitmq_cli/mix.exs +++ b/deps/rabbitmq_cli/mix.exs @@ -10,21 +10,11 @@ defmodule RabbitMQCtl.MixfileBase do def project do [ app: :rabbitmqctl, -<<<<<<< HEAD - version: "3.10.0-dev", - elixir: ">= 1.10.4 and < 1.15.0", - build_embedded: Mix.env == :prod, - start_permanent: Mix.env == :prod, - escript: [main_module: RabbitMQCtl, - emu_args: "-hidden", - path: "escript/rabbitmqctl"], -======= - version: "3.11.0", + version: "3.10.9", elixir: ">= 1.13.4 and < 1.15.0", build_embedded: Mix.env() == :prod, start_permanent: Mix.env() == :prod, escript: [main_module: RabbitMQCtl, emu_args: "-hidden", path: "escript/rabbitmqctl"], ->>>>>>> 059978e6fa (mix format rabbitmq_cli) deps: deps(), aliases: aliases(), xref: [ diff --git a/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs b/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs index 054a815cccf1..c709898ca5d1 100644 --- a/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs +++ b/deps/rabbitmq_cli/test/ctl/enable_feature_flag_test.exs @@ -21,11 +21,6 @@ defmodule EnableFeatureFlagCommandTest do @feature_flag => %{ desc: "My feature flag", provided_by: :EnableFeatureFlagCommandTest, -<<<<<<< HEAD - stability: :stable}} - :ok = :rabbit_misc.rpc_call( - node, :rabbit_feature_flags, :initialize_registry, [new_feature_flags]) -======= stability: :stable } } @@ -34,10 +29,9 @@ defmodule EnableFeatureFlagCommandTest do :rabbit_misc.rpc_call( node, :rabbit_feature_flags, - :inject_test_feature_flags, + :initialize_registry, [new_feature_flags] ) ->>>>>>> 059978e6fa (mix format rabbitmq_cli) { :ok, diff --git a/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs b/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs index a80bd4017b2b..0ba17709e0c0 100644 --- a/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs +++ b/deps/rabbitmq_cli/test/ctl/list_feature_flags_command_test.exs @@ -28,13 +28,6 @@ defmodule ListFeatureFlagsCommandTest do @flag2 => %{ desc: "My feature flag #2", provided_by: :ListFeatureFlagsCommandTest, -<<<<<<< HEAD - stability: :stable}} - :ok = :rabbit_misc.rpc_call( - node, :rabbit_feature_flags, :initialize_registry, [new_feature_flags]) - :ok = :rabbit_misc.rpc_call( - node, :rabbit_feature_flags, :enable_all, []) -======= stability: :stable } } @@ -43,7 +36,7 @@ defmodule ListFeatureFlagsCommandTest do :rabbit_misc.rpc_call( node, :rabbit_feature_flags, - :inject_test_feature_flags, + :initialize_registry, [new_feature_flags] ) @@ -54,7 +47,6 @@ defmodule ListFeatureFlagsCommandTest do :enable_all, [] ) ->>>>>>> 059978e6fa (mix format rabbitmq_cli) name_result = [ [{:name, @flag1}], diff --git a/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs b/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs index a58f8b6a33ab..ea645553c0b1 100644 --- a/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/drain_command_test.exs @@ -23,20 +23,13 @@ defmodule DrainCommandTest do end setup context do -<<<<<<< HEAD enable_feature_flag(:maintenance_mode_status) - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} -======= {:ok, opts: %{ node: get_rabbit_hostname(), timeout: context[:test_timeout] || 5000 }} ->>>>>>> 059978e6fa (mix format rabbitmq_cli) end test "merge_defaults: nothing to do" do diff --git a/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs b/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs index 087cfb080507..f0060caa53d7 100644 --- a/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs +++ b/deps/rabbitmq_cli/test/upgrade/revive_command_test.exs @@ -23,20 +23,13 @@ defmodule ReviveCommandTest do end setup context do -<<<<<<< HEAD enable_feature_flag(:maintenance_mode_status) - {:ok, opts: %{ - node: get_rabbit_hostname(), - timeout: context[:test_timeout] || 5000 - }} -======= {:ok, opts: %{ node: get_rabbit_hostname(), timeout: context[:test_timeout] || 5000 }} ->>>>>>> 059978e6fa (mix format rabbitmq_cli) end test "merge_defaults: nothing to do" do From 667bda6fd42f8acc0207ff99d26002348267a39b Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Tue, 4 Oct 2022 12:51:30 +0200 Subject: [PATCH 35/49] Bump elixir version in actions --- .github/workflows/test-mixed-versions.yaml | 2 +- .github/workflows/test.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-mixed-versions.yaml b/.github/workflows/test-mixed-versions.yaml index 48ae70cbc8dc..b10b50e99543 100644 --- a/.github/workflows/test-mixed-versions.yaml +++ b/.github/workflows/test-mixed-versions.yaml @@ -73,7 +73,7 @@ jobs: matrix: include: - erlang_version: "24" - elixir_version: 1.12.3 + elixir_version: 1.13.4 #! - erlang_version: "25" #! elixir_version: 1.13.4 timeout-minutes: 60 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c7051fd0e872..fe674e6baecb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -76,7 +76,7 @@ jobs: matrix: include: - erlang_version: "24" - elixir_version: 1.12.3 + elixir_version: 1.13.4 #! - erlang_version: "25" #! elixir_version: 1.13.4 timeout-minutes: 60 From e0459d9c0d83877331f98b8345ae82b263aba87d Mon Sep 17 00:00:00 2001 From: Karl Nilsson Date: Fri, 30 Sep 2022 16:20:50 +0100 Subject: [PATCH 36/49] Ensure consumer msg_id state is synchronised By returning the next msg id for a merged consumer the rabbit_fifo_client can set it's next expected msg_id accordingly and avoid triggering a fetch of "missing" messages from the queue. (cherry picked from commit 63f01c8c6c3f7535cfe5a22bcc4227384daf76ee) (cherry picked from commit 878160f8cb68d2be8a674952c290dc51709df480) # Conflicts: # deps/rabbit/src/rabbit_fifo.erl --- deps/rabbit/src/rabbit_fifo.erl | 52 ++++++++++++++++++------- deps/rabbit/src/rabbit_fifo_client.erl | 38 ++++++++++++------ deps/rabbit/test/quorum_queue_SUITE.erl | 50 +++++++++++++++++++++++- 3 files changed, 113 insertions(+), 27 deletions(-) diff --git a/deps/rabbit/src/rabbit_fifo.erl b/deps/rabbit/src/rabbit_fifo.erl index 5910de24e58c..db11e5c2e7ed 100644 --- a/deps/rabbit/src/rabbit_fifo.erl +++ b/deps/rabbit/src/rabbit_fifo.erl @@ -75,11 +75,6 @@ -export([update_header/4]). -endif. --define(SETTLE_V2, '$s'). --define(RETURN_V2, '$r'). --define(DISCARD_V2, '$d'). --define(CREDIT_V2, '$c'). - %% command records representing all the protocol actions that are supported -record(enqueue, {pid :: option(pid()), seq :: option(msg_seqno()), @@ -362,9 +357,9 @@ apply(#{index := Index, %% a dequeue using the same consumer_id isn't possible at this point {State0, {dequeue, empty}}; _ -> - State1 = update_consumer(Meta, ConsumerId, ConsumerMeta, - {once, 1, simple_prefetch}, 0, - State0), + {_, State1} = update_consumer(Meta, ConsumerId, ConsumerMeta, + {once, 1, simple_prefetch}, 0, + State0), case checkout_one(Meta, false, State1, []) of {success, _, MsgId, ?MSG(RaftIdx, Header), ExpiredMsg, State2, Effects0} -> {State4, Effects1} = case Settlement of @@ -405,9 +400,19 @@ apply(#{index := Idx} = Meta, apply(Meta, #checkout{spec = Spec, meta = ConsumerMeta, consumer_id = {_, Pid} = ConsumerId}, State0) -> Priority = get_priority_from_args(ConsumerMeta), - State1 = update_consumer(Meta, ConsumerId, ConsumerMeta, Spec, Priority, State0), + {Consumer, State1} = update_consumer(Meta, ConsumerId, ConsumerMeta, + Spec, Priority, State0), {State2, Effs} = activate_next_consumer(State1, []), - checkout(Meta, State0, State2, [{monitor, process, Pid} | Effs]); + #consumer{checked_out = Checked, + credit = Credit, + delivery_count = DeliveryCount, + next_msg_id = NextMsgId} = Consumer, + %% reply with a consumer summary + Reply = {ok, #{next_msg_id => NextMsgId, + credit => Credit, + delivery_count => DeliveryCount, + num_checked_out => map_size(Checked)}}, + checkout(Meta, State0, State2, [{monitor, process, Pid} | Effs], Reply); apply(#{index := Index}, #purge{}, #?MODULE{messages_total = Total, returns = Returns, @@ -1785,9 +1790,12 @@ return_all(Meta, #?MODULE{consumers = Cons} = State0, Effects0, ConsumerId, return_one(Meta, MsgId, Msg, S, E, ConsumerId) end, {State, Effects0}, lists:sort(maps:to_list(Checked))). +checkout(Meta, OldState, State0, Effects0) -> + checkout(Meta, OldState, State0, Effects0, ok). + checkout(#{index := Index} = Meta, #?MODULE{cfg = #cfg{resource = _QName}} = OldState, - State0, Effects0) -> + State0, Effects0, Reply) -> {#?MODULE{cfg = #cfg{dead_letter_handler = DLH}, dlx = DlxState0} = State1, ExpiredMsg, Effects1} = checkout0(Meta, checkout_one(Meta, false, State0, Effects0), #{}), @@ -1798,9 +1806,9 @@ checkout(#{index := Index} = Meta, Effects2 = DlxDeliveryEffects ++ Effects1, case evaluate_limit(Index, false, OldState, State2, Effects2) of {State, false, Effects} when ExpiredMsg == false -> - {State, ok, Effects}; + {State, Reply, Effects}; {State, _, Effects} -> - update_smallest_raft_index(Index, State, Effects) + update_smallest_raft_index(Index, Reply, State, Effects) end. checkout0(Meta, {success, ConsumerId, MsgId, @@ -2094,7 +2102,7 @@ update_consumer(Meta, {Tag, Pid} = ConsumerId, ConsumerMeta, credit_mode = Mode}, credit = Credit} end, - update_or_remove_sub(Meta, ConsumerId, Consumer, State0); + {Consumer, update_or_remove_sub(Meta, ConsumerId, Consumer, State0)}; update_consumer(Meta, {Tag, Pid} = ConsumerId, ConsumerMeta, {Life, Credit, Mode} = Spec, Priority, #?MODULE{cfg = #cfg{consumer_strategy = single_active}, @@ -2106,15 +2114,27 @@ update_consumer(Meta, {Tag, Pid} = ConsumerId, ConsumerMeta, %% one, then merge case active_consumer(Cons0) of {ConsumerId, #consumer{status = up} = Consumer0} -> +<<<<<<< HEAD Consumer = merge_consumer(Consumer0, ConsumerMeta, Spec, Priority), update_or_remove_sub(Meta, ConsumerId, Consumer, State0); +======= + Consumer = merge_consumer(Meta, Consumer0, ConsumerMeta, + Spec, Priority), + {Consumer, update_or_remove_sub(Meta, ConsumerId, Consumer, State0)}; +>>>>>>> 878160f8cb (Ensure consumer msg_id state is synchronised) undefined when is_map_key(ConsumerId, Cons0) -> %% there is no active consumer and the current consumer is in the %% consumers map and thus must be cancelled, in this case we can just %% merge and effectively make this the current active one Consumer0 = maps:get(ConsumerId, Cons0), +<<<<<<< HEAD Consumer = merge_consumer(Consumer0, ConsumerMeta, Spec, Priority), update_or_remove_sub(Meta, ConsumerId, Consumer, State0); +======= + Consumer = merge_consumer(Meta, Consumer0, ConsumerMeta, + Spec, Priority), + {Consumer, update_or_remove_sub(Meta, ConsumerId, Consumer, State0)}; +>>>>>>> 878160f8cb (Ensure consumer msg_id state is synchronised) _ -> %% add as a new waiting consumer Consumer = #consumer{cfg = #consumer_cfg{tag = Tag, @@ -2125,7 +2145,9 @@ update_consumer(Meta, {Tag, Pid} = ConsumerId, ConsumerMeta, credit_mode = Mode}, credit = Credit}, - State0#?MODULE{waiting_consumers = Waiting ++ [{ConsumerId, Consumer}]} + {Consumer, + State0#?MODULE{waiting_consumers = + Waiting ++ [{ConsumerId, Consumer}]}} end. merge_consumer(#consumer{cfg = CCfg, checked_out = Checked} = Consumer, diff --git a/deps/rabbit/src/rabbit_fifo_client.erl b/deps/rabbit/src/rabbit_fifo_client.erl index f227c4f9668a..f43b25201cc4 100644 --- a/deps/rabbit/src/rabbit_fifo_client.erl +++ b/deps/rabbit/src/rabbit_fifo_client.erl @@ -386,14 +386,25 @@ checkout(ConsumerTag, NumUnsettled, CreditMode, Meta, %% ??? Ack = maps:get(ack, Meta, true), - SDels = maps:update_with(ConsumerTag, - fun (V) -> - V#consumer{ack = Ack} - end, - #consumer{last_msg_id = -1, - ack = Ack}, CDels0), - try_process_command(Servers, Cmd, State0#state{consumer_deliveries = SDels}). - + case try_process_command(Servers, Cmd, State0) of + {ok, Reply, Leader} -> + LastMsgId = case Reply of + ok -> + %% this is the pre 3.11.1 / 3.10.9 + %% reply format + -1; + {ok, #{next_msg_id := NextMsgId}} -> + NextMsgId - 1 + end, + SDels = maps:update_with( + ConsumerTag, fun (C) -> C#consumer{ack = Ack} end, + #consumer{last_msg_id = LastMsgId, + ack = Ack}, CDels0), + {ok, State0#state{leader = Leader, + consumer_deliveries = SDels}}; + Err -> + Err + end. -spec query_single_active_consumer(state()) -> {ok, term()} | {error, term()} | {timeout, term()}. @@ -448,7 +459,12 @@ cancel_checkout(ConsumerTag, #state{consumer_deliveries = CDels} = State0) -> ConsumerId = {ConsumerTag, self()}, Cmd = rabbit_fifo:make_checkout(ConsumerId, cancel, #{}), State = State0#state{consumer_deliveries = maps:remove(ConsumerTag, CDels)}, - try_process_command(Servers, Cmd, State). + case try_process_command(Servers, Cmd, State) of + {ok, _, Leader} -> + {ok, State#state{leader = Leader}}; + Err -> + Err + end. %% @doc Purges all the messages from a rabbit_fifo queue and returns the number %% of messages purged. @@ -653,8 +669,8 @@ untracked_enqueue([Node | _], Msg) -> try_process_command([Server | Rem], Cmd, #state{cfg = #cfg{timeout = Timeout}} = State) -> case ra:process_command(Server, Cmd, Timeout) of - {ok, _, Leader} -> - {ok, State#state{leader = Leader}}; + {ok, _, _} = Res -> + Res; Err when length(Rem) =:= 0 -> Err; _ -> diff --git a/deps/rabbit/test/quorum_queue_SUITE.erl b/deps/rabbit/test/quorum_queue_SUITE.erl index fa8b33dad650..c8f1d8ec3316 100644 --- a/deps/rabbit/test/quorum_queue_SUITE.erl +++ b/deps/rabbit/test/quorum_queue_SUITE.erl @@ -148,7 +148,8 @@ all_tests() -> per_message_ttl_mixed_expiry, per_message_ttl_expiration_too_high, consumer_priorities, - cancel_consumer_gh_3729 + cancel_consumer_gh_3729, + cancel_and_consume_with_same_tag ]. memory_tests() -> @@ -2826,6 +2827,53 @@ cancel_consumer_gh_3729(Config) -> ok = rabbit_ct_client_helpers:close_channel(Ch). +cancel_and_consume_with_same_tag(Config) -> + %% https://github.com/rabbitmq/rabbitmq-server/issues/5927 + QQ = ?config(queue_name, Config), + + Server = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename), + Ch = rabbit_ct_client_helpers:open_channel(Config, Server), + + ExpectedDeclareRslt0 = #'queue.declare_ok'{queue = QQ, message_count = 0, consumer_count = 0}, + DeclareRslt0 = declare(Ch, QQ, [{<<"x-queue-type">>, longstr, <<"quorum">>}]), + ?assertMatch(ExpectedDeclareRslt0, DeclareRslt0), + + ok = publish(Ch, QQ), + + ok = subscribe(Ch, QQ, false), + + DeliveryTag = receive + {#'basic.deliver'{delivery_tag = D}, _} -> + D + after 5000 -> + flush(100), + ct:fail("basic.deliver timeout") + end, + + ok = cancel(Ch), + + ok = subscribe(Ch, QQ, false), + + ok = publish(Ch, QQ), + + receive + {#'basic.deliver'{delivery_tag = _}, _} -> + ok + after 5000 -> + flush(100), + ct:fail("basic.deliver timeout 2") + end, + + + amqp_channel:cast(Ch, #'basic.ack'{delivery_tag = DeliveryTag, + multiple = true}), + + ok = cancel(Ch), + + + + ok. + leader_locator_client_local(Config) -> [Server1 | _] = Servers = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Q = ?config(queue_name, Config), From 5d04545821ba89d289ca015e3f4850ecc100d932 Mon Sep 17 00:00:00 2001 From: Karl Nilsson Date: Mon, 3 Oct 2022 14:55:52 +0100 Subject: [PATCH 37/49] Change rabbit_fifo_client get_missing_deliveries to use aux_command As since QQ v2 we don't ever keep any messages in memory and we need to read them from the log. The only way to do this is by using an aux command. Execute get_checked_out query on local members if possible This reduces the change of crashing a QQ member during a live upgrade where the follower does not have the appropriate code in handle_aux (cherry picked from commit 25a6ec3919eb5ca8869b2631cc4492a1655e7697) (cherry picked from commit 8ede23029ea5ca9791272aa6854e23bc6f3e682e) --- deps/rabbit/src/rabbit_fifo.erl | 22 ++++++++++++ deps/rabbit/src/rabbit_fifo_client.erl | 39 ++++++++++++++++------ deps/rabbit/test/rabbit_fifo_int_SUITE.erl | 36 +++++++++++++++++++- 3 files changed, 85 insertions(+), 12 deletions(-) diff --git a/deps/rabbit/src/rabbit_fifo.erl b/deps/rabbit/src/rabbit_fifo.erl index db11e5c2e7ed..974142642fe7 100644 --- a/deps/rabbit/src/rabbit_fifo.erl +++ b/deps/rabbit/src/rabbit_fifo.erl @@ -1004,6 +1004,28 @@ handle_aux(leader, cast, {#return{msg_ids = MsgIds, _ -> {no_reply, Aux0, Log0} end; +handle_aux(_, _, {get_checked_out, ConsumerId, MsgIds}, + Aux0, Log0, #?MODULE{cfg = #cfg{}, + consumers = Consumers}) -> + case Consumers of + #{ConsumerId := #consumer{checked_out = Checked}} -> + {Log, IdMsgs} = + maps:fold( + fun (MsgId, ?MSG(Idx, Header), {L0, Acc}) -> + %% it is possible this is not found if the consumer + %% crashed and the message got removed + case ra_log:fetch(Idx, L0) of + {{_, _, {_, _, Cmd, _}}, L} -> + Msg = get_msg(Cmd), + {L, [{MsgId, {Header, Msg}} | Acc]}; + {undefined, L} -> + {L, Acc} + end + end, {Log0, []}, maps:with(MsgIds, Checked)), + {reply, {ok, IdMsgs}, Aux0, Log}; + _ -> + {reply, {error, consumer_not_found}, Aux0, Log0} + end; handle_aux(leader, cast, {#return{} = Ret, Corr, Pid}, Aux0, Log, #?MODULE{}) -> %% for returns with a delivery limit set we can just return as before diff --git a/deps/rabbit/src/rabbit_fifo_client.erl b/deps/rabbit/src/rabbit_fifo_client.erl index f43b25201cc4..8fd8577aad4e 100644 --- a/deps/rabbit/src/rabbit_fifo_client.erl +++ b/deps/rabbit/src/rabbit_fifo_client.erl @@ -764,7 +764,7 @@ handle_delivery(Leader, {delivery, Tag, [{FstId, _} | _] = IdMsgs}, %% When the node is disconnected the leader will return all checked %% out messages to the main queue to ensure they don't get stuck in %% case the node never comes back. - case get_missing_deliveries(Leader, Prev+1, FstId-1, Tag) of + case get_missing_deliveries(State0, Prev+1, FstId-1, Tag) of {protocol_error, _, _, _} = Err -> Err; Missing -> @@ -824,22 +824,22 @@ update_consumer(Tag, LastId, DelCntIncr, Consumers). -get_missing_deliveries(Leader, From, To, ConsumerTag) -> +get_missing_deliveries(State, From, To, ConsumerTag) -> + %% find local server ConsumerId = consumer_id(ConsumerTag), - % ?INFO("get_missing_deliveries for ~w from ~b to ~b", - % [ConsumerId, From, To]), - Query = fun (State) -> - rabbit_fifo:get_checked_out(ConsumerId, From, To, State) - end, - case ra:local_query(Leader, Query, ?COMMAND_TIMEOUT) of - {ok, {_, Missing}, _} -> + rabbit_log:debug("get_missing_deliveries for ~w from ~b to ~b", + [ConsumerId, From, To]), + Cmd = {get_checked_out, ConsumerId, lists:seq(From, To)}, + ServerId = find_local_or_leader(State), + case ra:aux_command(ServerId, Cmd) of + {ok, Missing} -> Missing; {error, Error} -> {protocol_error, internal_error, "Cannot query missing deliveries from ~p: ~p", - [Leader, Error]}; + [ServerId, Error]}; {timeout, _} -> {protocol_error, internal_error, "Cannot query missing deliveries from ~p: timeout", - [Leader]} + [ServerId]} end. pick_server(#state{leader = undefined, @@ -922,6 +922,23 @@ cancel_timer(#state{timer_state = Ref} = State) -> erlang:cancel_timer(Ref, [{async, true}, {info, false}]), State#state{timer_state = undefined}. +find_local_or_leader(#state{leader = Leader, + cfg = #cfg{servers = Servers}}) -> + case find_local(Servers) of + undefined -> + Leader; + ServerId -> + ServerId + end. + +find_local([{_, N} = ServerId | _]) when N == node() -> + ServerId; +find_local([_ | Rem]) -> + find_local(Rem); +find_local([]) -> + undefined. + + find_leader([]) -> undefined; find_leader([Server | Servers]) -> diff --git a/deps/rabbit/test/rabbit_fifo_int_SUITE.erl b/deps/rabbit/test/rabbit_fifo_int_SUITE.erl index 3a667eab733b..c2ddf695bb4d 100644 --- a/deps/rabbit/test/rabbit_fifo_int_SUITE.erl +++ b/deps/rabbit/test/rabbit_fifo_int_SUITE.erl @@ -30,6 +30,7 @@ all_tests() -> dequeue, discard, cancel_checkout, + lost_delivery, credit, untracked_enqueue, flow, @@ -410,6 +411,38 @@ cancel_checkout(Config) -> {ok, _, {_, _, _, _, m1}, F5} = rabbit_fifo_client:dequeue(<<"d1">>, settled, F5), ok. +lost_delivery(Config) -> + ClusterName = ?config(cluster_name, Config), + ServerId = ?config(node_id, Config), + ok = start_cluster(ClusterName, [ServerId]), + F0 = rabbit_fifo_client:init(ClusterName, [ServerId], 4), + {ok, F1} = rabbit_fifo_client:enqueue(m1, F0), + {_, _, F2} = process_ra_events( + receive_ra_events(1, 0), F1, [], [], fun (_, S) -> S end), + {ok, F3} = rabbit_fifo_client:checkout(<<"tag">>, 10, simple_prefetch, #{}, F2), + %% drop a delivery, simulating e.g. a full distribution buffer + receive + {ra_event, _, Evt} -> + ct:pal("dropping event ~p", [Evt]), + ok + after 500 -> + exit(await_ra_event_timeout) + end, + % send another message + {ok, F4} = rabbit_fifo_client:enqueue(m2, F3), + %% this hsould trigger the fifo client to fetch any missing messages + %% from the server + {_, _, _F5} = process_ra_events( + receive_ra_events(1, 1), F4, [], [], + fun ({deliver, _, _, Dels}, S) -> + [{_, _, _, _, M1}, + {_, _, _, _, M2}] = Dels, + ?assertEqual(m1, M1), + ?assertEqual(m2, M2), + S + end), + ok. + credit(Config) -> ClusterName = ?config(cluster_name, Config), ServerId = ?config(node_id, Config), @@ -592,7 +625,8 @@ process_ra_events(Events, State) -> process_ra_events([], State0, Acc, Actions0, _DeliveryFun) -> {Acc, Actions0, State0}; -process_ra_events([{ra_event, From, Evt} | Events], State0, Acc, Actions0, DeliveryFun) -> +process_ra_events([{ra_event, From, Evt} | Events], State0, Acc, + Actions0, DeliveryFun) -> case rabbit_fifo_client:handle_ra_event(From, Evt, State0) of {ok, State1, Actions1} -> {Msgs, Actions, State} = From 38de62f2638926da357a522a0e3ab36b3aa63dfd Mon Sep 17 00:00:00 2001 From: Karl Nilsson Date: Tue, 4 Oct 2022 13:24:43 +0100 Subject: [PATCH 38/49] fix merge conflicts --- deps/rabbit/src/rabbit_fifo.erl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/deps/rabbit/src/rabbit_fifo.erl b/deps/rabbit/src/rabbit_fifo.erl index 974142642fe7..759d669a613d 100644 --- a/deps/rabbit/src/rabbit_fifo.erl +++ b/deps/rabbit/src/rabbit_fifo.erl @@ -2136,27 +2136,15 @@ update_consumer(Meta, {Tag, Pid} = ConsumerId, ConsumerMeta, %% one, then merge case active_consumer(Cons0) of {ConsumerId, #consumer{status = up} = Consumer0} -> -<<<<<<< HEAD Consumer = merge_consumer(Consumer0, ConsumerMeta, Spec, Priority), - update_or_remove_sub(Meta, ConsumerId, Consumer, State0); -======= - Consumer = merge_consumer(Meta, Consumer0, ConsumerMeta, - Spec, Priority), {Consumer, update_or_remove_sub(Meta, ConsumerId, Consumer, State0)}; ->>>>>>> 878160f8cb (Ensure consumer msg_id state is synchronised) undefined when is_map_key(ConsumerId, Cons0) -> %% there is no active consumer and the current consumer is in the %% consumers map and thus must be cancelled, in this case we can just %% merge and effectively make this the current active one Consumer0 = maps:get(ConsumerId, Cons0), -<<<<<<< HEAD Consumer = merge_consumer(Consumer0, ConsumerMeta, Spec, Priority), - update_or_remove_sub(Meta, ConsumerId, Consumer, State0); -======= - Consumer = merge_consumer(Meta, Consumer0, ConsumerMeta, - Spec, Priority), {Consumer, update_or_remove_sub(Meta, ConsumerId, Consumer, State0)}; ->>>>>>> 878160f8cb (Ensure consumer msg_id state is synchronised) _ -> %% add as a new waiting consumer Consumer = #consumer{cfg = #consumer_cfg{tag = Tag, From fe02a06327065333781da367dc1be2dbac48b79a Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Tue, 4 Oct 2022 13:56:24 +0200 Subject: [PATCH 39/49] Add 'mix format --check-formatted' to the rabbitmqctl_tests in bazel to match the check on the Makefile side that was recently introduced (cherry picked from commit a71ff1341e75a4fcb32139e7a2e36a2116e914f2) (cherry picked from commit e14cf06e34ea98d8b364d147c90d8cade0b6294c) --- deps/rabbitmq_cli/BUILD.bazel | 1 + deps/rabbitmq_cli/rabbitmqctl.bzl | 4 ++-- deps/rabbitmq_cli/rabbitmqctl_test.bzl | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/deps/rabbitmq_cli/BUILD.bazel b/deps/rabbitmq_cli/BUILD.bazel index d2e759683865..3f5a8bc82ee0 100644 --- a/deps/rabbitmq_cli/BUILD.bazel +++ b/deps/rabbitmq_cli/BUILD.bazel @@ -52,6 +52,7 @@ rabbitmqctl_test( srcs = [ "mix.exs", "config/config.exs", + ".formatter.exs", ] + glob([ "lib/**/*.ex", "test/**/*.exs", diff --git a/deps/rabbitmq_cli/rabbitmqctl.bzl b/deps/rabbitmq_cli/rabbitmqctl.bzl index a0fa89ab98ae..e26c9e43f56c 100644 --- a/deps/rabbitmq_cli/rabbitmqctl.bzl +++ b/deps/rabbitmq_cli/rabbitmqctl.bzl @@ -76,8 +76,8 @@ export LC_ALL="en_US.UTF-8" MIX_INVOCATION_DIR="{mix_invocation_dir}" -cp -R {package_dir}/config ${{MIX_INVOCATION_DIR}}/config -cp -R {package_dir}/lib ${{MIX_INVOCATION_DIR}}/lib +cp -r {package_dir}/config ${{MIX_INVOCATION_DIR}}/config +cp -r {package_dir}/lib ${{MIX_INVOCATION_DIR}}/lib cp {package_dir}/mix.exs ${{MIX_INVOCATION_DIR}}/mix.exs cd ${{MIX_INVOCATION_DIR}} diff --git a/deps/rabbitmq_cli/rabbitmqctl_test.bzl b/deps/rabbitmq_cli/rabbitmqctl_test.bzl index 41965b15c835..b1a2547b5747 100644 --- a/deps/rabbitmq_cli/rabbitmqctl_test.bzl +++ b/deps/rabbitmq_cli/rabbitmqctl_test.bzl @@ -56,6 +56,7 @@ ln -s ${{PWD}}/{package_dir}/config ${{TEST_UNDECLARED_OUTPUTS_DIR}} ln -s ${{PWD}}/{package_dir}/lib ${{TEST_UNDECLARED_OUTPUTS_DIR}} ln -s ${{PWD}}/{package_dir}/test ${{TEST_UNDECLARED_OUTPUTS_DIR}} ln -s ${{PWD}}/{package_dir}/mix.exs ${{TEST_UNDECLARED_OUTPUTS_DIR}} +ln -s ${{PWD}}/{package_dir}/.formatter.exs ${{TEST_UNDECLARED_OUTPUTS_DIR}} INITIAL_DIR=${{PWD}} cd ${{TEST_UNDECLARED_OUTPUTS_DIR}} @@ -73,6 +74,7 @@ if [ ! -d _build/${{MIX_ENV}}/lib/rabbit_common ]; then cp -r ${{DEPS_DIR}}/* _build/${{MIX_ENV}}/lib fi "${{ABS_ELIXIR_HOME}}"/bin/mix deps.compile +"${{ABS_ELIXIR_HOME}}"/bin/mix format --check-formatted "${{ABS_ELIXIR_HOME}}"/bin/mix compile # due to https://github.com/elixir-lang/elixir/issues/7699 we From 338395eb765a70bc2f7ad65ad8bf2faf6da96f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aitor=20P=C3=A9rez=20Cedres?= <1515757+Zerpet@users.noreply.github.com> Date: Wed, 5 Oct 2022 17:28:59 +0100 Subject: [PATCH 40/49] Update Stream protocol document As per conversation with @acogoluegnes, the frame `SaslHandshakeRequest` does not have a field `mechanism`. This field actually used in `SaslHandshakeResponse` and `SaslAuthenticateRequest` frames. (cherry picked from commit 1ce96c0ae5b1e6fad4dfff978ec81d759b076af0) (cherry picked from commit 0824fdb11a2c8f00fb0e6dcad3f32a9f7f0547e2) --- deps/rabbitmq_stream/docs/PROTOCOL.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/deps/rabbitmq_stream/docs/PROTOCOL.adoc b/deps/rabbitmq_stream/docs/PROTOCOL.adoc index 72ca7d986e8b..401dc81ef6a8 100644 --- a/deps/rabbitmq_stream/docs/PROTOCOL.adoc +++ b/deps/rabbitmq_stream/docs/PROTOCOL.adoc @@ -499,7 +499,6 @@ SaslHandshakeRequest => Key Version CorrelationId Mechanism Key => uint16 // 0x0012 Version => uint16 CorrelationId => uint32 - Mechanism => string SaslHandshakeResponse => Key Version CorrelationId ResponseCode [Mechanisms] Key => uint16 // 0x8012 From 28664b389068d16fa79c2e8e0491150d563f9526 Mon Sep 17 00:00:00 2001 From: Alex Valiushko Date: Wed, 5 Oct 2022 20:22:22 -0700 Subject: [PATCH 41/49] fix docs for rabbitmqctl restart_vhost (cherry picked from commit 2e7692da5b081dc7431d372cf28b7013efbaa874) (cherry picked from commit 37f401f24e25318bc8c4652e8823ed81e62670ac) --- deps/rabbit/docs/rabbitmqctl.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/rabbit/docs/rabbitmqctl.8 b/deps/rabbit/docs/rabbitmqctl.8 index bb6d2d4e768e..4814de7e0005 100644 --- a/deps/rabbit/docs/rabbitmqctl.8 +++ b/deps/rabbit/docs/rabbitmqctl.8 @@ -1760,10 +1760,10 @@ Suppresses the parameter. .El .\" ------------------------------------------------------------------ -.It Cm restart_vhost Ar vhost +.It Cm restart_vhost Oo Fl p Ar vhost Oc .Bl -tag -width Ds .It Ar vhost -The name of the virtual host entry to restart. +The name of the virtual host entry to restart, defaulting to "/". .El .Pp Restarts a failed vhost data stores and queues. From 6209a9e23b10e17ecc1e7ae6d3343ee13f98e6b7 Mon Sep 17 00:00:00 2001 From: Karl Nilsson Date: Tue, 4 Oct 2022 15:41:43 +0100 Subject: [PATCH 42/49] Refactor quorum queue periodic metric emission Primarily to avoid the transient process that is spawned every Ra "tick" to query the quorum queue process for information that could be passed in when the process is spawned. Refactored to make use of the overview map instead of a custom tuple. Also use ets:lookup_element where applicable (cherry picked from commit 3f53846c709ba0a858ad2873096e4a87a3d2bef4) (cherry picked from commit 76cc0ee40d3752fc74d4551d4e52cd75edac24a8) --- deps/rabbit/src/rabbit_fifo.erl | 37 ++++--- deps/rabbit/src/rabbit_quorum_queue.erl | 136 +++++++++++------------- deps/rabbit/test/rabbit_fifo_SUITE.erl | 17 ++- 3 files changed, 99 insertions(+), 91 deletions(-) diff --git a/deps/rabbit/src/rabbit_fifo.erl b/deps/rabbit/src/rabbit_fifo.erl index 759d669a613d..838dd235f8ff 100644 --- a/deps/rabbit/src/rabbit_fifo.erl +++ b/deps/rabbit/src/rabbit_fifo.erl @@ -864,26 +864,14 @@ state_enter0(_, _, Effects) -> Effects. -spec tick(non_neg_integer(), state()) -> ra_machine:effects(). -tick(Ts, #?MODULE{cfg = #cfg{name = Name, - resource = QName}, - msg_bytes_enqueue = EnqueueBytes, - msg_bytes_checkout = CheckoutBytes, - dlx = DlxState} = State) -> +tick(Ts, #?MODULE{cfg = #cfg{name = _Name, + resource = QName}} = State) -> case is_expired(Ts, State) of true -> [{mod_call, rabbit_quorum_queue, spawn_deleter, [QName]}]; false -> - {_, MsgBytesDiscard} = rabbit_fifo_dlx:stat(DlxState), - Metrics = {Name, - messages_ready(State), - num_checked_out(State), % checked out - messages_total(State), - query_consumer_count(State), % Consumers - EnqueueBytes, - CheckoutBytes, - MsgBytesDiscard}, [{mod_call, rabbit_quorum_queue, - handle_tick, [QName, Metrics, all_nodes(State)]}] + handle_tick, [QName, overview(State), all_nodes(State)]}] end. -spec overview(state()) -> map(). @@ -894,7 +882,8 @@ overview(#?MODULE{consumers = Cons, msg_bytes_enqueue = EnqueueBytes, msg_bytes_checkout = CheckoutBytes, cfg = Cfg, - dlx = DlxState} = State) -> + dlx = DlxState, + waiting_consumers = WaitingConsumers} = State) -> Conf = #{name => Cfg#cfg.name, resource => Cfg#cfg.resource, release_cursor_interval => Cfg#cfg.release_cursor_interval, @@ -906,9 +895,18 @@ overview(#?MODULE{consumers = Cons, msg_ttl => Cfg#cfg.msg_ttl, delivery_limit => Cfg#cfg.delivery_limit }, + SacOverview = case active_consumer(Cons) of + {SacConsumerId, _} -> + NumWaiting = length(WaitingConsumers), + #{single_active_consumer_id => SacConsumerId, + single_active_num_waiting_consumers => NumWaiting}; + _ -> + #{} + end, Overview = #{type => ?MODULE, config => Conf, - num_consumers => maps:size(Cons), + num_consumers => map_size(Cons), + num_active_consumers => query_consumer_count(State), num_checked_out => num_checked_out(State), num_enqueuers => maps:size(Enqs), num_ready_messages => messages_ready(State), @@ -920,9 +918,10 @@ overview(#?MODULE{consumers = Cons, enqueue_message_bytes => EnqueueBytes, checkout_message_bytes => CheckoutBytes, in_memory_message_bytes => 0, %% backwards compat - smallest_raft_index => smallest_raft_index(State)}, + smallest_raft_index => smallest_raft_index(State) + }, DlxOverview = rabbit_fifo_dlx:overview(DlxState), - maps:merge(Overview, DlxOverview). + maps:merge(maps:merge(Overview, DlxOverview), SacOverview). -spec get_checked_out(consumer_id(), msg_id(), msg_id(), state()) -> [delivery_msg()]. diff --git a/deps/rabbit/src/rabbit_quorum_queue.erl b/deps/rabbit/src/rabbit_quorum_queue.erl index b2118a61aeae..490b91a87e09 100644 --- a/deps/rabbit/src/rabbit_quorum_queue.erl +++ b/deps/rabbit/src/rabbit_quorum_queue.erl @@ -435,7 +435,18 @@ spawn_notify_decorators(QName, Fun, Args) -> catch notify_decorators(QName, Fun, Args). handle_tick(QName, - {Name, MR, MU, M, C, MsgBytesReady, MsgBytesUnack, MsgBytesDiscard}, + #{config := #{name := Name}, + num_active_consumers := NumConsumers, + num_checked_out := NumCheckedOut, + num_ready_messages := NumReadyMsgs, + num_messages := NumMessages, + enqueue_message_bytes := EnqueueBytes, + checkout_message_bytes := CheckoutBytes, + num_discarded := NumDiscarded, + num_discard_checked_out := NumDiscardedCheckedOut, + discard_message_bytes := DiscardBytes, + discard_checkout_message_bytes := DiscardCheckoutBytes, + smallest_raft_index := _} = Overview, Nodes) -> %% this makes calls to remote processes so cannot be run inside the %% ra server @@ -443,22 +454,37 @@ handle_tick(QName, _ = spawn( fun() -> try - R = reductions(Name), - rabbit_core_metrics:queue_stats(QName, MR, MU, M, R), - Util = case C of + Reductions = reductions(Name), + rabbit_core_metrics:queue_stats(QName, NumReadyMsgs, + NumCheckedOut, NumMessages, + Reductions), + Util = case NumConsumers of 0 -> 0; _ -> rabbit_fifo:usage(Name) end, - Infos = [{consumers, C}, + Keys = ?STATISTICS_KEYS -- [consumers, + messages_dlx, + message_bytes_dlx, + single_active_consumer_pid, + single_active_consumer_ctag + ], + {SacTag, SacPid} = maps:get(single_active_consumer_id, + Overview, {'', ''}), + MsgBytesDiscarded = DiscardBytes + DiscardCheckoutBytes, + MsgBytes = EnqueueBytes + CheckoutBytes + MsgBytesDiscarded, + Infos = [{consumers, NumConsumers}, {consumer_capacity, Util}, {consumer_utilisation, Util}, - {message_bytes_ready, MsgBytesReady}, - {message_bytes_unacknowledged, MsgBytesUnack}, - {message_bytes, MsgBytesReady + MsgBytesUnack + MsgBytesDiscard}, - {message_bytes_persistent, MsgBytesReady + MsgBytesUnack + MsgBytesDiscard}, - {messages_persistent, M} - - | infos(QName, ?STATISTICS_KEYS -- [consumers])], + {message_bytes_ready, EnqueueBytes}, + {message_bytes_unacknowledged, CheckoutBytes}, + {message_bytes, MsgBytes}, + {message_bytes_persistent, MsgBytes}, + {messages_persistent, NumMessages}, + {messages_dlx, NumDiscarded + NumDiscardedCheckedOut}, + {message_bytes_dlx, MsgBytesDiscarded}, + {single_active_consumer_ctag, SacTag}, + {single_active_consumer_pid, SacPid} + | infos(QName, Keys)], rabbit_core_metrics:queue_stats(QName, Infos), ok = repair_leader_record(QName, Self), ExpectedNodes = rabbit_nodes:all(), @@ -884,8 +910,6 @@ deliver(QSs, #delivery{message = #basic_message{content = Content0} = Msg, state_info(S) -> #{pending_raft_commands => rabbit_fifo_client:pending_size(S)}. - - -spec infos(rabbit_types:r('queue')) -> rabbit_types:infos(). infos(QName) -> infos(QName, ?STATISTICS_KEYS). @@ -976,9 +1000,11 @@ cluster_state(Name) -> case whereis(Name) of undefined -> down; _ -> - case ets:lookup(ra_state, Name) of - [{_, recover}] -> recovering; - _ -> running + case ets_lookup_element(ra_state, Name, 2, undefined) of + recover -> + recovering; + _ -> + running end end. @@ -1232,7 +1258,8 @@ queue_length(Q) -> Name = amqqueue:get_name(Q), case ets:lookup(ra_metrics, Name) of [] -> 0; - [{_, _, SnapIdx, _, _, LastIdx, _}] -> LastIdx - SnapIdx + [{_, _, SnapIdx, _, _, LastIdx, _}] -> + LastIdx - SnapIdx end. get_replicas(Q) -> @@ -1374,20 +1401,10 @@ i(messages, Q) when ?is_amqqueue(Q) -> quorum_messages(QName); i(messages_ready, Q) when ?is_amqqueue(Q) -> QName = amqqueue:get_name(Q), - case ets:lookup(queue_coarse_metrics, QName) of - [{_, MR, _, _, _}] -> - MR; - [] -> - 0 - end; + ets_lookup_element(queue_coarse_metrics, QName, 2, 0); i(messages_unacknowledged, Q) when ?is_amqqueue(Q) -> QName = amqqueue:get_name(Q), - case ets:lookup(queue_coarse_metrics, QName) of - [{_, _, MU, _, _}] -> - MU; - [] -> - 0 - end; + ets_lookup_element(queue_coarse_metrics, QName, 3, 0); i(policy, Q) -> case rabbit_policy:name(Q) of none -> ''; @@ -1405,12 +1422,8 @@ i(effective_policy_definition, Q) -> end; i(consumers, Q) when ?is_amqqueue(Q) -> QName = amqqueue:get_name(Q), - case ets:lookup(queue_metrics, QName) of - [{_, M, _}] -> - proplists:get_value(consumers, M, 0); - [] -> - 0 - end; + Consumers = ets_lookup_element(queue_metrics, QName, 2, []), + proplists:get_value(consumers, Consumers, 0); i(memory, Q) when ?is_amqqueue(Q) -> {Name, _} = amqqueue:get_pid(Q), try @@ -1429,10 +1442,7 @@ i(state, Q) when ?is_amqqueue(Q) -> end; i(local_state, Q) when ?is_amqqueue(Q) -> {Name, _} = amqqueue:get_pid(Q), - case ets:lookup(ra_state, Name) of - [{_, State}] -> State; - _ -> not_member - end; + ets_lookup_element(ra_state, Name, 2, not_member); i(garbage_collection, Q) when ?is_amqqueue(Q) -> {Name, _} = amqqueue:get_pid(Q), try @@ -1477,27 +1487,9 @@ i(single_active_consumer_ctag, Q) when ?is_amqqueue(Q) -> end; i(type, _) -> quorum; i(messages_ram, Q) when ?is_amqqueue(Q) -> - QPid = amqqueue:get_pid(Q), - case ra:local_query(QPid, - fun rabbit_fifo:query_in_memory_usage/1) of - {ok, {_, {Length, _}}, _} -> - Length; - {error, _} -> - 0; - {timeout, _} -> - 0 - end; + 0; i(message_bytes_ram, Q) when ?is_amqqueue(Q) -> - QPid = amqqueue:get_pid(Q), - case ra:local_query(QPid, - fun rabbit_fifo:query_in_memory_usage/1) of - {ok, {_, {_, Bytes}}, _} -> - Bytes; - {error, _} -> - 0; - {timeout, _} -> - 0 - end; + 0; i(messages_dlx, Q) when ?is_amqqueue(Q) -> QPid = amqqueue:get_pid(Q), case ra:local_query(QPid, @@ -1524,11 +1516,10 @@ i(_K, _Q) -> ''. open_files(Name) -> case whereis(Name) of - undefined -> {node(), 0}; - Pid -> case ets:lookup(ra_open_file_metrics, Pid) of - [] -> {node(), 0}; - [{_, Count}] -> {node(), Count} - end + undefined -> + {node(), 0}; + Pid -> + {node(), ets_lookup_element(ra_open_file_metrics, Pid, 2, 0)} end. leader(Q) when ?is_amqqueue(Q) -> @@ -1582,12 +1573,7 @@ is_process_alive(Name, Node) -> -spec quorum_messages(rabbit_amqqueue:name()) -> non_neg_integer(). quorum_messages(QName) -> - case ets:lookup(queue_coarse_metrics, QName) of - [{_, _, _, M, _}] -> - M; - [] -> - 0 - end. + ets_lookup_element(queue_coarse_metrics, QName, 4, 0). quorum_ctag(Int) when is_integer(Int) -> integer_to_binary(Int); @@ -1712,3 +1698,11 @@ erpc_timeout(Node, _) infinity; erpc_timeout(_, Timeout) -> Timeout. + +ets_lookup_element(Tbl, Key, Pos, Default) -> + try ets:lookup_element(Tbl, Key, Pos) of + V -> V + catch + _:badarg -> + Default + end. diff --git a/deps/rabbit/test/rabbit_fifo_SUITE.erl b/deps/rabbit/test/rabbit_fifo_SUITE.erl index 99a657d5a703..9450897c42d7 100644 --- a/deps/rabbit/test/rabbit_fifo_SUITE.erl +++ b/deps/rabbit/test/rabbit_fifo_SUITE.erl @@ -602,7 +602,14 @@ tick_test(_) -> [{mod_call, rabbit_quorum_queue, handle_tick, [#resource{}, - {?FUNCTION_NAME, 1, 1, 2, 1, 3, 3, 0}, + #{config := #{name := ?FUNCTION_NAME}, + num_consumers := 1, + num_checked_out := 1, + num_ready_messages := 1, + num_messages := 2, + enqueue_message_bytes := 3, + checkout_message_bytes := 3, + num_discarded := _Discards}, [_Node] ]}] = rabbit_fifo:tick(1, S4), ok. @@ -765,6 +772,7 @@ single_active_consumer_basic_get_test(_) -> {_State, {error, {unsupported, single_active_consumer}}} = apply(meta(2), rabbit_fifo:make_checkout(Cid, {dequeue, unsettled}, #{}), State1), + ok. single_active_consumer_revive_test(_) -> @@ -853,6 +861,10 @@ single_active_consumer_test(_) -> % the first registered consumer is the active one, the others are waiting ?assertEqual(1, map_size(State1#rabbit_fifo.consumers)), ?assertMatch(#{C1 := _}, State1#rabbit_fifo.consumers), + + ?assertMatch(#{single_active_consumer_id := C1, + single_active_num_waiting_consumers := 3}, + rabbit_fifo:overview(State1)), ?assertEqual(3, length(rabbit_fifo:query_waiting_consumers(State1))), ?assertNotEqual(false, lists:keyfind(C2, 1, rabbit_fifo:query_waiting_consumers(State1))), ?assertNotEqual(false, lists:keyfind(C3, 1, rabbit_fifo:query_waiting_consumers(State1))), @@ -866,6 +878,9 @@ single_active_consumer_test(_) -> ?assertEqual(1, map_size(State2#rabbit_fifo.consumers)), ?assertMatch(#{C1 := _}, State2#rabbit_fifo.consumers), % the cancelled consumer has been removed from waiting consumers + ?assertMatch(#{single_active_consumer_id := C1, + single_active_num_waiting_consumers := 2}, + rabbit_fifo:overview(State2)), ?assertEqual(2, length(rabbit_fifo:query_waiting_consumers(State2))), ?assertNotEqual(false, lists:keyfind(C2, 1, rabbit_fifo:query_waiting_consumers(State2))), ?assertNotEqual(false, lists:keyfind(C4, 1, rabbit_fifo:query_waiting_consumers(State2))), From 6ddca2ddb2c099319352f931531d88703aa21b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20G=C3=B6m=C3=B6ri?= Date: Wed, 5 Oct 2022 01:00:05 +0200 Subject: [PATCH 43/49] Load plugins in dependency order When enabling a plugin on the fly, the dir of the plugin and its dependencies are added to the load path (and their modules are loaded). There are some libraries which require their dependencies to be loaded before they are (e.g lz4 requires host_triple to load the NIF module). During `rabbit_plugins:prepare_plugins/1`, `dependencies/3` gathers the wanted apps in the right order (every app comes after its deps) however `validate_plugins/1` used to reverse their order, so later code loading in `prepare_plugin/2` happened in the wrong order. This is now fixed, so `validate_plugins/1` preserves the order of apps. (cherry picked from commit 3b422d34b707965cac0ae628288ef2be2e6ed4ac) (cherry picked from commit fb24017a4eac76250eccee6ca39dd06b0c3d039f) --- deps/rabbit/src/rabbit_plugins.erl | 54 ++++++++++--------- .../test/unit_plugin_versioning_SUITE.erl | 8 +-- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/deps/rabbit/src/rabbit_plugins.erl b/deps/rabbit/src/rabbit_plugins.erl index 0e0659c6a0b0..950bbfccbb17 100644 --- a/deps/rabbit/src/rabbit_plugins.erl +++ b/deps/rabbit/src/rabbit_plugins.erl @@ -319,32 +319,34 @@ validate_plugins(Plugins) -> validate_plugins(Plugins, RabbitVersion). validate_plugins(Plugins, BrokerVersion) -> - lists:foldl( - fun(#plugin{name = Name, - broker_version_requirements = BrokerVersionReqs, - dependency_version_requirements = DepsVersions} = Plugin, - {Plugins0, Errors}) -> - case is_version_supported(BrokerVersion, BrokerVersionReqs) of - true -> - case BrokerVersion of - "0.0.0" -> - rabbit_log:warning( - "Running development version of the broker." - " Requirement ~p for plugin ~p is ignored.", - [BrokerVersionReqs, Name]); - _ -> ok - end, - case check_plugins_versions(Name, Plugins0, DepsVersions) of - ok -> {[Plugin | Plugins0], Errors}; - {error, Err} -> {Plugins0, [{Name, Err} | Errors]} - end; - false -> - Error = [{broker_version_mismatch, BrokerVersion, BrokerVersionReqs}], - {Plugins0, [{Name, Error} | Errors]} - end - end, - {[],[]}, - Plugins). + {ValidPlugins, Problems} = + lists:foldl( + fun(#plugin{name = Name, + broker_version_requirements = BrokerVersionReqs, + dependency_version_requirements = DepsVersions} = Plugin, + {Plugins0, Errors}) -> + case is_version_supported(BrokerVersion, BrokerVersionReqs) of + true -> + case BrokerVersion of + "0.0.0" -> + rabbit_log:warning( + "Running development version of the broker." + " Requirement ~p for plugin ~p is ignored.", + [BrokerVersionReqs, Name]); + _ -> ok + end, + case check_plugins_versions(Name, Plugins0, DepsVersions) of + ok -> {[Plugin | Plugins0], Errors}; + {error, Err} -> {Plugins0, [{Name, Err} | Errors]} + end; + false -> + Error = [{broker_version_mismatch, BrokerVersion, BrokerVersionReqs}], + {Plugins0, [{Name, Error} | Errors]} + end + end, + {[],[]}, + Plugins), + {lists:reverse(ValidPlugins), Problems}. check_plugins_versions(PluginName, AllPlugins, RequiredVersions) -> ExistingVersions = [{Name, Vsn} diff --git a/deps/rabbit/test/unit_plugin_versioning_SUITE.erl b/deps/rabbit/test/unit_plugin_versioning_SUITE.erl index 33ea8d6cd5ef..ade79555b6ac 100644 --- a/deps/rabbit/test/unit_plugin_versioning_SUITE.erl +++ b/deps/rabbit/test/unit_plugin_versioning_SUITE.erl @@ -149,10 +149,10 @@ plugin_validation(_Config) -> {Valid, Invalid} = rabbit_plugins:validate_plugins(Plugins, RabbitVersion), Errors = lists:reverse(Invalid), - ExpectedValid = lists:reverse(lists:map(fun(#plugin{name = Name}) -> - Name - end, - Valid)) + ExpectedValid = lists:map(fun(#plugin{name = Name}) -> + Name + end, + Valid) end, Examples), ok. From 6d9e502a5e4f4de7da51a5f19a74fedf9a6f6a95 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Thu, 6 Oct 2022 16:12:16 -0700 Subject: [PATCH 44/49] Upgrade cuttlefish to 3.1.0 Related to https://github.com/rabbitmq/opportunities/issues/207 (cherry picked from commit 02e3e0046f64252a79846cb3f1560383fb863076) (cherry picked from commit 625ef1c14aea6fd7c3f6379a1ff151976888860f) # Conflicts: # deps/rabbit/apps/rabbitmq_prelaunch/Makefile --- MODULE.bazel | 4 ++-- deps/rabbit/apps/rabbitmq_prelaunch/Makefile | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index a8f1c4f2f7e0..be7dd7262768 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -162,8 +162,8 @@ erlang_package.git_package( erlang_package.hex_package( name = "cuttlefish", - sha256 = "3feff3ae4ed1f0ca6df87ac89235068fbee9242ee85d2ac17fb1b8ce0e30f1a6", - version = "3.0.1", + sha256 = "d3ef90bd2f5923477ab772fbda5cd5ad088438e4fd56801b455b87ada9f46fa3", + version = "3.1.0", ) erlang_package.hex_package( diff --git a/deps/rabbit/apps/rabbitmq_prelaunch/Makefile b/deps/rabbit/apps/rabbitmq_prelaunch/Makefile index c95d0979074c..c5cb07bb3126 100644 --- a/deps/rabbit/apps/rabbitmq_prelaunch/Makefile +++ b/deps/rabbit/apps/rabbitmq_prelaunch/Makefile @@ -3,8 +3,13 @@ PROJECT_DESCRIPTION = RabbitMQ prelaunch setup PROJECT_VERSION = 1.0.0 PROJECT_MOD = rabbit_prelaunch_app +<<<<<<< HEAD DEPS = rabbit_common cuttlefish jsx dep_cuttlefish = hex 3.0.1 +======= +DEPS = rabbit_common cuttlefish thoas +dep_cuttlefish = hex 3.1.0 +>>>>>>> 625ef1c14a (Upgrade cuttlefish to 3.1.0) DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk From aaa99c54473e4b037d7849881956f970ed6027f9 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 8 Oct 2022 09:30:06 +0400 Subject: [PATCH 45/49] Resolve a dependency conflict --- deps/rabbit/apps/rabbitmq_prelaunch/Makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/deps/rabbit/apps/rabbitmq_prelaunch/Makefile b/deps/rabbit/apps/rabbitmq_prelaunch/Makefile index c5cb07bb3126..9cbf8250d5f2 100644 --- a/deps/rabbit/apps/rabbitmq_prelaunch/Makefile +++ b/deps/rabbit/apps/rabbitmq_prelaunch/Makefile @@ -3,13 +3,8 @@ PROJECT_DESCRIPTION = RabbitMQ prelaunch setup PROJECT_VERSION = 1.0.0 PROJECT_MOD = rabbit_prelaunch_app -<<<<<<< HEAD DEPS = rabbit_common cuttlefish jsx -dep_cuttlefish = hex 3.0.1 -======= -DEPS = rabbit_common cuttlefish thoas dep_cuttlefish = hex 3.1.0 ->>>>>>> 625ef1c14a (Upgrade cuttlefish to 3.1.0) DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk From e99bfbae90fbf00fb09bb1e87b9adc9895dc6416 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 8 Oct 2022 03:31:45 +0000 Subject: [PATCH 46/49] Adopt otp 24.3.4.6 (cherry picked from commit bdcb55f81b0178fe881ad6e4ab2112848bc5a06a) (cherry picked from commit deb9b71f53aa804f2dbc581eb0305021d8620c4e) --- MODULE.bazel | 4 ++-- WORKSPACE | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index be7dd7262768..86167dc4ecb6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -41,8 +41,8 @@ erlang_config.internal_erlang_from_github_release( erlang_config.internal_erlang_from_github_release( name = "24", - sha256 = "0b57d49e62958350676e8f32a39008d420dca4bc20f2d7e38c0671ab2ba62f14", - version = "24.3.4.5", + sha256 = "8444ff9abe23aea268adbb95463561fc222c965052d35d7c950b17be01c3ad82", + version = "24.3.4.6", ) erlang_config.internal_erlang_from_github_release( diff --git a/WORKSPACE b/WORKSPACE index 231cb4c5fa2f..5e7b822698fc 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -71,9 +71,9 @@ http_file( http_file( name = "otp_src_24", - downloaded_file_path = "OTP-24.3.4.5.tar.gz", - sha256 = "4831e329ed61ee49f5a5a5e89ad52fd97468325654f17a1892c5664ea4b490f5", - urls = ["https://github.com/erlang/otp/archive/OTP-24.3.4.5.tar.gz"], + downloaded_file_path = "OTP-24.3.4.6.tar.gz", + sha256 = "dc3d2c54eeb093e0dc9a0fe493bc69d6dfac0affbe77c9e3c935aa86c0f63cd5", + urls = ["https://github.com/erlang/otp/archive/OTP-24.3.4.6.tar.gz"], ) http_file( @@ -139,8 +139,8 @@ erlang_config( ), internal_erlang_from_github_release( name = "24", - sha256 = "0b57d49e62958350676e8f32a39008d420dca4bc20f2d7e38c0671ab2ba62f14", - version = "24.3.4.5", + sha256 = "8444ff9abe23aea268adbb95463561fc222c965052d35d7c950b17be01c3ad82", + version = "24.3.4.6", ), internal_erlang_from_github_release( name = "25_0", From 0dd396843fbdada9ddcd6c761d946045a055987f Mon Sep 17 00:00:00 2001 From: Karl Nilsson Date: Fri, 30 Sep 2022 09:45:40 +0100 Subject: [PATCH 47/49] Introduce new feature flag to avoid crashing channel. When a delivery or credit_reply is sent from a node running 3.11.0 or 3.10.8 to an older node. (cherry picked from commit 2ad9f1320ad634ee05c2c519200f251fc92df0f9) --- deps/rabbit/src/rabbit_classic_queue.erl | 12 ++++++++++-- deps/rabbit/src/rabbit_core_ff.erl | 8 ++++++++ deps/rabbitmq_management/test/clustering_SUITE.erl | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/deps/rabbit/src/rabbit_classic_queue.erl b/deps/rabbit/src/rabbit_classic_queue.erl index d25caf31b430..578a440761fe 100644 --- a/deps/rabbit/src/rabbit_classic_queue.erl +++ b/deps/rabbit/src/rabbit_classic_queue.erl @@ -297,6 +297,8 @@ handle_event({down, Pid, Info}, #?STATE{qref = QRef, {ok, State0#?STATE{unconfirmed = U}, [{rejected, QRef, MsgIds} | Actions0]} end; +handle_event({send_drained, _} = Action, State) -> + {ok, State, [Action]}; handle_event({send_credit_reply, _} = Action, State) -> {ok, State, [Action]}. @@ -542,7 +544,7 @@ send_rejection(Pid, QName, MsgSeqNo) -> end. deliver_to_consumer(Pid, QName, CTag, AckRequired, Message) -> - case rabbit_queue_type:is_supported() of + case has_classic_queue_type_delivery_support() of true -> Deliver = {deliver, CTag, AckRequired, [Message]}, Evt = {queue_event, QName, Deliver}, @@ -553,7 +555,7 @@ deliver_to_consumer(Pid, QName, CTag, AckRequired, Message) -> end. send_drained(Pid, QName, CTagCredits) -> - case rabbit_queue_type:is_supported() of + case has_classic_queue_type_delivery_support() of true -> gen_server:cast(Pid, {queue_event, QName, {send_drained, CTagCredits}}); @@ -569,3 +571,9 @@ send_credit_reply(Pid, QName, Len) when is_integer(Len) -> false -> gen_server2:cast(Pid, {send_credit_reply, Len}) end. + +has_classic_queue_type_delivery_support() -> + %% some queue_events were missed in the initial queue_type implementation + %% this feature flag enables those and completes the initial queue type + %% API for classic queues + rabbit_feature_flags:is_enabled(classic_queue_type_delivery_support). diff --git a/deps/rabbit/src/rabbit_core_ff.erl b/deps/rabbit/src/rabbit_core_ff.erl index 2eb34de8321f..5c1a2f9fe869 100644 --- a/deps/rabbit/src/rabbit_core_ff.erl +++ b/deps/rabbit/src/rabbit_core_ff.erl @@ -71,6 +71,14 @@ classic_mirrored_queue_version_migration(_FeatureName, _FeatureProps, _Enable) -> ok. +-rabbit_feature_flag( + {classic_queue_type_delivery_support, + #{desc => "Bug fix for classic queue deliveries using mixed versions", + doc_url => "https://github.com/rabbitmq/rabbitmq-server/issues/5931", + stability => stable, + depends_on => [stream_queue] + }}). + %% ------------------------------------------------------------------- %% Quorum queues. %% ------------------------------------------------------------------- diff --git a/deps/rabbitmq_management/test/clustering_SUITE.erl b/deps/rabbitmq_management/test/clustering_SUITE.erl index 881650aef0e4..6749f9adeab0 100644 --- a/deps/rabbitmq_management/test/clustering_SUITE.erl +++ b/deps/rabbitmq_management/test/clustering_SUITE.erl @@ -18,6 +18,7 @@ -import(rabbit_mgmt_test_util, [http_get/2, http_put/4, http_delete/3]). -import(rabbit_misc, [pget/2]). +-compile(nowarn_export_all). -compile(export_all). all() -> @@ -252,6 +253,9 @@ queue_on_other_node(Config) -> ok. queue_with_multiple_consumers(Config) -> + ok = rabbit_ct_broker_helpers:enable_feature_flag(Config, stream_queue), + %% this may not be supported in mixed mode + _ = rabbit_ct_broker_helpers:enable_feature_flag(Config, classic_queue_type_delivery_support), {ok, Chan} = amqp_connection:open_channel(?config(conn, Config)), Q = <<"multi-consumer-queue1">>, _ = queue_declare(Chan, Q), From 9bda277d5aa66c39014c4f1d58038d5d7de2703a Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 8 Oct 2022 13:23:54 +0400 Subject: [PATCH 48/49] Compile --- deps/rabbit/src/rabbit_core_ff.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/deps/rabbit/src/rabbit_core_ff.erl b/deps/rabbit/src/rabbit_core_ff.erl index 5c1a2f9fe869..e521ee536c6f 100644 --- a/deps/rabbit/src/rabbit_core_ff.erl +++ b/deps/rabbit/src/rabbit_core_ff.erl @@ -68,17 +68,17 @@ migration_fun => {?MODULE, user_limits_migration} }}). +-rabbit_feature_flag( + {classic_queue_type_delivery_support, + #{desc => "Bug fix for classic queue deliveries using mixed versions", + doc_url => "https://github.com/rabbitmq/rabbitmq-server/issues/5931", + stability => stable, + depends_on => [stream_queue] + }}). + classic_mirrored_queue_version_migration(_FeatureName, _FeatureProps, _Enable) -> ok. --rabbit_feature_flag( - {classic_queue_type_delivery_support, - #{desc => "Bug fix for classic queue deliveries using mixed versions", - doc_url => "https://github.com/rabbitmq/rabbitmq-server/issues/5931", - stability => stable, - depends_on => [stream_queue] - }}). - %% ------------------------------------------------------------------- %% Quorum queues. %% ------------------------------------------------------------------- From 61a20709c64f43db2a27569074765bf0428a5507 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sat, 8 Oct 2022 14:37:17 +0400 Subject: [PATCH 49/49] AMQP 1.0: fix a merge/resolution artifact in BUILD.bazel --- deps/rabbitmq_amqp1_0/BUILD.bazel | 3 --- 1 file changed, 3 deletions(-) diff --git a/deps/rabbitmq_amqp1_0/BUILD.bazel b/deps/rabbitmq_amqp1_0/BUILD.bazel index 8957f98a8d0a..8892dc930ad4 100644 --- a/deps/rabbitmq_amqp1_0/BUILD.bazel +++ b/deps/rabbitmq_amqp1_0/BUILD.bazel @@ -86,9 +86,6 @@ suites = [ deps = [ "//deps/amqp10_common:erlang_app", ], - runtime_deps = [ - "//deps/amqp10_client:erlang_app", - ], ), rabbitmq_integration_suite( PACKAGE,