summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_cli/test/diagnostics
diff options
context:
space:
mode:
authordcorbacho <dparracorbacho@piotal.io>2020-11-18 14:27:41 +0000
committerdcorbacho <dparracorbacho@piotal.io>2020-11-18 14:27:41 +0000
commitf23a51261d9502ec39df0f8db47ba6b22aa7659f (patch)
tree53dcdf46e7dc2c14e81ee960bce8793879b488d3 /deps/rabbitmq_cli/test/diagnostics
parentafa2c2bf6c7e0e9b63f4fb53dc931c70388e1c82 (diff)
parent9f6d64ec4a4b1eeac24d7846c5c64fd96798d892 (diff)
downloadrabbitmq-server-git-stream-timestamp-offset.tar.gz
Merge remote-tracking branch 'origin/master' into stream-timestamp-offsetstream-timestamp-offset
Diffstat (limited to 'deps/rabbitmq_cli/test/diagnostics')
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs69
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs118
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs111
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs59
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs62
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs68
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs72
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs50
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs101
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs44
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs73
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs39
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs39
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs39
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs50
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/erlang_cookie_sources_command_test.exs37
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs72
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs72
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs72
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs39
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs39
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs78
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs98
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs115
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs107
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs48
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs72
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs44
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs62
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs85
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs65
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs50
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs69
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs48
-rw-r--r--deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs60
35 files changed, 2326 insertions, 0 deletions
diff --git a/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs
new file mode 100644
index 0000000000..70a2bfda64
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/alarms_command_test.exs
@@ -0,0 +1,69 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule AlarmsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+ import RabbitMQ.CLI.Core.Alarms, only: [alarm_types: 1]
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.AlarmsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when target node has no alarms in effect, returns an empty list", context do
+ assert [] == status()[:alarms]
+
+ assert @command.run([], context[:opts]) == []
+ end
+
+ test "run: when target node has an alarm in effect, returns it", context do
+ old_watermark = status()[:vm_memory_high_watermark]
+ on_exit(fn() ->
+ set_vm_memory_high_watermark(old_watermark)
+ end)
+ # 2000 bytes will trigger an alarm
+ set_vm_memory_high_watermark({:absolute, 2000})
+
+ assert [:memory] == alarm_types(status()[:alarms])
+ assert length(@command.run([], context[:opts])) == 1
+
+ set_vm_memory_high_watermark(old_watermark)
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs
new file mode 100644
index 0000000000..f5b64282e3
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_alarms_command_test.exs
@@ -0,0 +1,118 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckAlarmsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+ import RabbitMQ.CLI.Core.Alarms, only: [alarm_types: 1]
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckAlarmsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when target node has no alarms in effect, returns an empty list", context do
+ assert [] == status()[:alarms]
+
+ assert @command.run([], context[:opts]) == []
+ end
+
+ test "run: when target node has an alarm in effect, returns it", context do
+ old_watermark = status()[:vm_memory_high_watermark]
+ on_exit(fn() ->
+ set_vm_memory_high_watermark(old_watermark)
+ end)
+ # 2000 bytes will trigger an alarm
+ set_vm_memory_high_watermark({:absolute, 2000})
+
+ assert [:memory] == alarm_types(status()[:alarms])
+ assert length(@command.run([], context[:opts])) == 1
+
+ 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]
+
+ assert match?({:ok, _}, @command.output([], context[:opts]))
+ end
+
+ test "output: when target node has an alarm in effect, returns a failure", context do
+ for input <- [
+ [
+ :file_descriptor_limit
+ ],
+ [
+ :file_descriptor_limit,
+ {{:resource_limit, :disk, :hare@warp10}, []}
+ ],
+ [
+ :file_descriptor_limit,
+ {{: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]))
+ end
+ end
+
+ 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
+ ],
+ [
+ :file_descriptor_limit,
+ {{:resource_limit, :disk, :hare@warp10}, []}
+ ],
+ [
+ :file_descriptor_limit,
+ {{: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})
+ 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
new file mode 100644
index 0000000000..0aaf66c707
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_local_alarms_command_test.exs
@@ -0,0 +1,111 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckLocalAlarmsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+ import RabbitMQ.CLI.Core.Alarms, only: [alarm_types: 1]
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckLocalAlarmsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when target node has no alarms in effect, returns an empty list", context do
+ assert [] == status()[:alarms]
+
+ assert @command.run([], context[:opts]) == []
+ end
+
+ 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() ->
+ set_vm_memory_high_watermark(old_watermark)
+ end)
+ # 2000 bytes will trigger an alarm
+ set_vm_memory_high_watermark({:absolute, 2000})
+
+ assert [:memory] == alarm_types(status()[:alarms])
+ assert length(@command.run([], context[:opts])) == 1
+
+ set_vm_memory_high_watermark(old_watermark)
+ end
+
+ test "output: when target node has no local alarms in effect, returns a success", context do
+ assert [] == status()[:alarms]
+
+ assert match?({:ok, _}, @command.output([], 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
+ for input <- [
+ [
+ :file_descriptor_limit
+ ],
+ [
+ :file_descriptor_limit,
+ {{:resource_limit, :disk, get_rabbit_hostname()}, []},
+ {{:resource_limit, :memory, get_rabbit_hostname()}, []}
+ ]
+ ] do
+ 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
+ for input <- [
+ [
+ :file_descriptor_limit
+ ],
+ [
+ :file_descriptor_limit,
+ {{:resource_limit, :disk, :hare@warp10}, []}
+ ],
+ [
+ :file_descriptor_limit,
+ {{:resource_limit, :disk, get_rabbit_hostname()}, []},
+ {{:resource_limit, :memory, get_rabbit_hostname()}, []}
+ ]
+ ] do
+ 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
new file mode 100644
index 0000000000..845a7b6f1d
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_port_connectivity_command_test.exs
@@ -0,0 +1,59 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckPortConnectivityCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckPortConnectivityCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: provides a default timeout" do
+ assert @command.merge_defaults([], %{}) == {[], %{timeout: 30000}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ 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]}
+ 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
new file mode 100644
index 0000000000..7c0428c190
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_port_listener_command_test.exs
@@ -0,0 +1,62 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckPortListenerCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckPortListenerCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: when no arguments are provided, returns a failure" do
+ assert @command.validate([], %{}) == {:validation_failure, :not_enough_args}
+ end
+
+ test "validate: when two or more arguments are provided, returns a failure" do
+ assert @command.validate([5672, 61613], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats a single positional argument and default switches as a success" do
+ assert @command.validate([1883], %{}) == :ok
+ end
+
+ @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})))
+ end
+
+ test "run: when a listener for the protocol is active, returns a success", context do
+ assert match?({true, _}, @command.run([5672], context[:opts]))
+ end
+
+ test "run: when a listener on the port is not active or unknown, returns an error", context do
+ assert match?({false, _, _}, @command.run([47777], context[:opts]))
+ end
+
+ test "output: when a listener for the port is active, returns a success", context do
+ assert match?({:ok, _}, @command.output({true, 5672}, context[:opts]))
+ end
+
+ test "output: when a listener for the port is not active, returns an error", context do
+ assert match?({:error, _, _}, @command.output({false, 15672, []}, context[:opts]))
+ end
+end
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
new file mode 100644
index 0000000000..a6aef88bc1
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_protocol_listener_command_test.exs
@@ -0,0 +1,68 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckProtocolListenerCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckProtocolListenerCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: when no arguments are provided, returns a failure" do
+ assert @command.validate([], %{}) == {:validation_failure, :not_enough_args}
+ end
+
+ test "validate: when two or more arguments are provided, returns a failure" do
+ assert @command.validate(["amqp", "stomp"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats a single positional argument and default switches as a success" do
+ assert @command.validate(["mqtt"], %{}) == :ok
+ end
+
+ @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})))
+ end
+
+ test "run: when a listener for the protocol is active, returns a success", context do
+ assert match?({true, _}, @command.run(["amqp"], context[:opts]))
+ end
+
+ test "run: accepts a number of alternative protocol names/spellings", context do
+ for p <- ["amqp", "amqp1.0", "amqp10", "amqp091", "stomp1.2", "distribution"] do
+ assert match?({true, _}, @command.run([p], context[:opts]))
+ end
+ end
+
+ 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
+
+ test "output: when a listener for the protocol is active, returns a success", context do
+ assert match?({:ok, _}, @command.output({true, "amqp"}, context[:opts]))
+ end
+
+ test "output: when a listener for the protocol is not active, returns an error", context do
+ assert match?({:error, _}, @command.output({false, "http", []}, context[:opts]))
+ end
+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
new file mode 100644
index 0000000000..ab89d1e89e
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_running_command_test.exs
@@ -0,0 +1,72 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckRunningCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckRunningCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when the RabbitMQ app is booted and started, returns true", context do
+ await_rabbitmq_startup()
+
+ assert @command.run([], context[:opts])
+ end
+
+ test "run: when the RabbitMQ app is stopped, returns false", context do
+ stop_rabbitmq_app()
+
+ refute is_rabbitmq_app_running()
+ refute @command.run([], context[:opts])
+
+ start_rabbitmq_app()
+ end
+
+ test "output: when the result is true, returns successfully", context do
+ assert match?({:ok, _}, @command.output(true, context[:opts]))
+ end
+
+ # this is a check command
+ test "output: when the result is false, returns an error", context do
+ assert match?({:error, _}, @command.output(false, context[:opts]))
+ end
+end
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
new file mode 100644
index 0000000000..2fab76ae9b
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/check_virtual_hosts_command_test.exs
@@ -0,0 +1,50 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule CheckVirtualHostsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CheckVirtualHostsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: is a no-op" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "output: when all virtual hosts are reported as up, returns a success", context do
+ assert match?({:ok, _}, @command.output([], context[:opts]))
+ end
+
+ test "output: when target node reports a virtual host as down, returns a failure", context do
+ assert match?({:error, _}, @command.output(["a-down-vhost"], context[:opts]))
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs
new file mode 100644
index 0000000000..2ee5edddb8
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/cipher_suites_command_test.exs
@@ -0,0 +1,101 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule CipherSuitesCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CipherSuitesCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {: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
+ assert @command.merge_defaults([], %{}) == {[], %{format: "openssl", all: false}}
+ 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: "Map"}) == {[], %{format: "map", all: false}}
+ end
+
+ test "merge_defaults: format can be overridden" do
+ assert @command.merge_defaults([], %{format: "map"}) == {[], %{format: "map", all: false}}
+ end
+
+ test "validate: treats positional arguments as a failure", context do
+ 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
+ assert @command.validate([], context[:opts]) == :ok
+ end
+
+ test "validate: supports openssl, erlang and map formats", context do
+ assert @command.validate([], Map.merge(context[:opts], %{format: "openssl"})) == :ok
+ assert @command.validate([], Map.merge(context[:opts], %{format: "erlang"})) == :ok
+ assert @command.validate([], Map.merge(context[:opts], %{format: "map"})) == :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})))
+ 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)
+ # the list is long and its values are environment-specific,
+ # so we simply assert that it is non-empty. MK.
+ assert length(res) > 0
+ end
+
+ @tag format: "erlang"
+ 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)
+ # the list is long and its values are environment-specific,
+ # so we simply assert that it is non-empty. MK.
+ assert length(res) > 0
+ end
+
+ @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)
+ # the list is long and its values are environment-specific,
+ # so we simply assert that it is non-empty. MK.
+ assert length(res) > 0
+ end
+
+ test "run: returns more cipher suites when all suites requested", context do
+ default_suites_opts = Map.merge(context[:opts], %{all: false})
+ default_suites = @command.run([], default_suites_opts)
+
+ all_suites_opts = Map.merge(context[:opts], %{all: true})
+ all_suites = @command.run([], all_suites_opts)
+
+ 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
new file mode 100644
index 0000000000..caa959ce44
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/command_line_arguments_command_test.exs
@@ -0,0 +1,44 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule CommandLineArgumentsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.CommandLineArgumentsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup 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
+ assert @command.validate(["extra"], context[:opts]) ==
+ {: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
+
+ assert_stream_without_errors(output)
+ end
+
+ test "run: command line arguments request on nonexistent RabbitMQ node returns a badrpc" do
+ opts = %{node: :jake@thedog, timeout: 200}
+ assert match?({:badrpc, _}, @command.run([], opts))
+ end
+
+ test "banner", context do
+ 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
new file mode 100644
index 0000000000..b11cdb38c2
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/consume_event_stream_command_test.exs
@@ -0,0 +1,73 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ConsumeEventStreamCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ConsumeEventStreamCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {: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}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success", context do
+ assert @command.validate([], context[:opts]) == :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})))
+ 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()}]])
+
+
+ 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
new file mode 100644
index 0000000000..7a2b4295c7
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/disable_auth_attempt_source_tracking_command_test.exs
@@ -0,0 +1,39 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule DisbleAuthAttemptSourceTrackingCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.DisableAuthAttemptSourceTrackingCommand
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout]}}
+ 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}
+ 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})))
+ end
+
+ @tag test_timeout: 15000
+ test "run: disables source tracking for auth attempt stats", context do
+ assert :ok = @command.run([], context[:opts])
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs
new file mode 100644
index 0000000000..dd54d6eed9
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/discover_peers_command_test.exs
@@ -0,0 +1,39 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule DiscoverPeersCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.DiscoverPeersCommand
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout]}}
+ 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}
+ 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})))
+ end
+
+ @tag test_timeout: 15000
+ test "run: returns a list of nodes when the backend isn't configured", context do
+ assert match?({:ok, {[], _}}, @command.run([], context[:opts]))
+ end
+end
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
new file mode 100644
index 0000000000..c55ac6134b
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/enable_auth_attempt_source_tracking_command_test.exs
@@ -0,0 +1,39 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule EnableAuthAttemptSourceTrackingCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.EnableAuthAttemptSourceTrackingCommand
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout]}}
+ 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}
+ 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})))
+ end
+
+ @tag test_timeout: 15000
+ test "run: enables source tracking for auth attempt stats", context do
+ assert :ok = @command.run([], context[:opts])
+ end
+end
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
new file mode 100644
index 0000000000..5dff653989
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_hash_command_test.exs
@@ -0,0 +1,50 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule ErlangCookieHashCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieHashCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 5000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :ok
+ end
+
+ @tag test_timeout: 3000
+ test "run: targeting an unreachable node throws a badrpc", context do
+ opts = %{node: :jake@thedog, timeout: 200}
+ assert match?({:badrpc, _}, @command.run([], Map.merge(context[:opts], opts)))
+ end
+
+ test "run: returns the erlang cookie hash", context do
+ res = @command.run([], context[:opts])
+ assert is_bitstring(res)
+ end
+
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_sources_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_sources_command_test.exs
new file mode 100644
index 0000000000..794dd52a44
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/erlang_cookie_sources_command_test.exs
@@ -0,0 +1,37 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ErlangCookieSourcesCommandTest do
+ use ExUnit.Case, async: true
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ErlangCookieSourcesCommand
+
+ setup _context do
+ {:ok, opts: %{}}
+ end
+
+ test "merge_defaults: merges no defaults" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :ok
+ end
+
+ test "run: returns Erlang cookie sources info", context do
+ result = @command.run([], context[:opts])
+
+ assert result[:effective_user] != nil
+ assert result[:home_dir] != nil
+ assert result[:cookie_file_path] != nil
+ assert result[:cookie_file_exists] != nil
+ assert result[:cookie_file_access] != nil
+ 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
new file mode 100644
index 0000000000..3bdaa645e2
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/erlang_version_command_test.exs
@@ -0,0 +1,72 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule ErlangVersionCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ErlangVersionCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {: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
+ assert @command.merge_defaults([], %{}) == {[], %{details: false, offline: false}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :ok
+ end
+
+ test "validate: treats empty positional arguments and --details as a success" do
+ assert @command.validate([], %{details: true}) == :ok
+ end
+
+ test "validate: treats empty positional arguments and --offline as a success" do
+ assert @command.validate([], %{offline: true}) == :ok
+ end
+
+ test "validate: treats empty positional arguments, --details and --offline as a success" do
+ assert @command.validate([], %{details: true, offline: true}) == :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, details: false})))
+ end
+
+ test "run: returns Erlang/OTP version on the target node", context do
+ res = @command.run([], context[:opts])
+ assert is_bitstring(res)
+ end
+
+ test "run with --details: returns Erlang/OTP version on the target node", context do
+ res = @command.run([], Map.merge(%{details: true}, context[:opts]))
+ assert is_bitstring(res)
+ end
+
+ test "run: when --offline is used, returns local Erlang/OTP version", context do
+ res = @command.run([], Map.merge(context[:opts], %{offline: true}))
+ assert is_bitstring(res)
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs
new file mode 100644
index 0000000000..fc7c2595a9
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/is_booting_command_test.exs
@@ -0,0 +1,72 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule IsBootingCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.IsBootingCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when the RabbitMQ app is fully booted and running, returns false", context do
+ await_rabbitmq_startup()
+
+ refute @command.run([], context[:opts])
+ end
+
+ test "run: when the RabbitMQ app is stopped, returns false", context do
+ stop_rabbitmq_app()
+
+ refute is_rabbitmq_app_running()
+ refute @command.run([], context[:opts])
+
+ start_rabbitmq_app()
+ end
+
+ test "output: when the result is true, returns successfully", context do
+ assert match?({:ok, _}, @command.output(true, context[:opts]))
+ end
+
+ # this is an info command and not a check one
+ test "output: when the result is false, returns successfully", context do
+ assert match?({:ok, _}, @command.output(false, context[:opts]))
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs
new file mode 100644
index 0000000000..120af9d7d7
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/is_running_command_test.exs
@@ -0,0 +1,72 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule IsRunningCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.IsRunningCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: when the RabbitMQ app is booted and started, returns true", context do
+ await_rabbitmq_startup()
+
+ assert @command.run([], context[:opts])
+ end
+
+ test "run: when the RabbitMQ app is stopped, returns false", context do
+ stop_rabbitmq_app()
+
+ refute is_rabbitmq_app_running()
+ refute @command.run([], context[:opts])
+
+ start_rabbitmq_app()
+ end
+
+ test "output: when the result is true, returns successfully", context do
+ assert match?({:ok, _}, @command.output(true, context[:opts]))
+ end
+
+ # this is an info command and not a check one
+ test "output: when the result is false, returns successfully", context do
+ assert match?({:ok, _}, @command.output(false, context[:opts]))
+ end
+end
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
new file mode 100644
index 0000000000..ccaac33d9b
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/list_network_interfaces_command_test.exs
@@ -0,0 +1,39 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ListNetworkInterfacesCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ListNetworkInterfacesCommand
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout]}}
+ 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}
+ 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})))
+ end
+
+ @tag test_timeout: 15000
+ test "run: returns a map of interfaces", context do
+ assert match?(%{}, @command.run([], context[:opts]))
+ end
+end
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
new file mode 100644
index 0000000000..c6ac28a340
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/list_node_auth_attempt_stats_command_test.exs
@@ -0,0 +1,39 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ListNodeAuthAttemptStatsCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ListNodeAuthAttemptStatsCommand
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{node: get_rabbit_hostname(), timeout: context[:test_timeout], by_source: false}}
+ 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}
+ 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})))
+ end
+
+ @tag test_timeout: 15000
+ test "run: returns auth attempt stats", context do
+ assert is_list(@command.run([], context[:opts]))
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs
new file mode 100644
index 0000000000..fc20cae7fc
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/listeners_command_test.exs
@@ -0,0 +1,78 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ListenersCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+ import RabbitMQ.CLI.Core.Listeners, only: [listener_maps: 1]
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ListenersCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ 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])
+ {:ok, msg} = @command.output(raw, context[:opts])
+
+ for p <- [5672, 61613, 25672] do
+ assert msg =~ ~r/#{p}/
+ end
+ end
+
+ test "output: when formatter is JSON, returns an array of listener maps", context do
+ raw = @command.run([], context[:opts])
+ {:ok, doc} = @command.output(raw, Map.merge(%{formatter: "json"}, context[:opts]))
+ xs = doc["listeners"]
+
+ assert length(xs) >= 3
+ for p <- [5672, 61613, 25672] do
+ assert Enum.any?(xs, fn %{port: port} -> port == p end)
+ end
+ 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
new file mode 100644
index 0000000000..64a85fc519
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/log_location_command_test.exs
@@ -0,0 +1,98 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule LogLocationCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.LogLocationCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {: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}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ 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})))
+ end
+
+ test "run: prints default log location", context do
+ # Let Lager's log message rate lapse or else some messages
+ # we assert on might be dropped. MK.
+ Process.sleep(1000)
+ {:ok, logfile} = @command.run([], context[:opts])
+ log_message = "file location"
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, [log_message])
+ wait_for_log_message(log_message, logfile)
+ {:ok, log_file_data} = File.read(logfile)
+ assert String.match?(log_file_data, Regex.compile!(log_message))
+ end
+
+ test "run: shows all log locations", context do
+ # Let Lager's log message rate lapse or else some messages
+ # we assert on might be dropped. MK.
+ Process.sleep(1000)
+ # This assumes default configuration
+ [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, [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, log_message_upgrade, []])
+ wait_for_log_message(log_message_upgrade, upgrade_log_file)
+ end
+
+ test "run: fails if there is no log file configured", context do
+ {:ok, upgrade_file} = :rpc.call(get_rabbit_hostname(), :application, :get_env, [:rabbit, :lager_upgrade_file])
+ {:ok, default_file} = :rpc.call(get_rabbit_hostname(), :application, :get_env, [:rabbit, :lager_default_file])
+ on_exit([], fn ->
+ :rpc.call(get_rabbit_hostname(), :application, :set_env, [:rabbit, :lager_upgrade_file, upgrade_file])
+ :rpc.call(get_rabbit_hostname(), :application, :set_env, [:rabbit, :lager_default_file, default_file])
+ :rpc.call(get_rabbit_hostname(), :rabbit_lager, :configure_lager, [])
+ start_rabbitmq_app()
+ end)
+ stop_rabbitmq_app()
+ :rpc.call(get_rabbit_hostname(), :application, :unset_env, [:rabbit, :lager_upgrade_file])
+ :rpc.call(get_rabbit_hostname(), :application, :unset_env, [:rabbit, :lager_default_file])
+ :rpc.call(get_rabbit_hostname(), :application, :unset_env, [:rabbit, :log])
+ :rpc.call(get_rabbit_hostname(), :rabbit_lager, :configure_lager, [])
+ {:error, "No log files configured on the node"} = @command.run([], context[:opts])
+ 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
new file mode 100644
index 0000000000..fb19821d55
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/log_tail_command_test.exs
@@ -0,0 +1,115 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule LogTailCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.LogTailCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000,
+ number: 50
+ }}
+ end
+
+ test "merge_defaults: number is 50" do
+ assert @command.merge_defaults([], %{}) == {[], %{number: 50}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success", context do
+ assert @command.validate([], context[:opts]) == :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})))
+ end
+
+ test "run: shows last 50 lines from the log by default", context do
+ # Let Lager's log message rate lapse or else some messages
+ # we assert on might be dropped. MK.
+ Process.sleep(1000)
+ 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, [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)
+ end
+
+ test "run: returns N lines", context do
+ # Let Lager's log message rate lapse or else some messages
+ # we assert on might be dropped. MK.
+ Process.sleep(1000)
+
+ ## 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, [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
+ assert Enum.count(@command.run([], Map.merge(context[:opts], %{number: 40}))) == 40
+ end
+
+ test "run: may return less than N lines if N is high", context do
+ # Let Lager's log message rate lapse or else some messages
+ # we assert on might be dropped. MK.
+ Process.sleep(1000)
+ 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, [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_lager, :log_locations, [])
+ Enum.map(logs, fn(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
new file mode 100644
index 0000000000..4ad2785604
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/log_tail_stream_command_test.exs
@@ -0,0 +1,107 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule LogTailStreamCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.LogTailStreamCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000,
+ duration: :infinity
+ }}
+ end
+
+ test "merge_defaults: duration defaults to infinity" do
+ assert @command.merge_defaults([], %{}) == {[], %{duration: :infinity}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success", context do
+ assert @command.validate([], context[:opts]) == :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})))
+ end
+
+ test "run: streams messages for N seconds", context do
+ ensure_log_file()
+ time_before = System.system_time(:second)
+
+ stream = @command.run([], Map.merge(context[:opts], %{duration: 15}))
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, ["Message"])
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, ["Message1"])
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, ["Message2"])
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, ["Message3"])
+
+ # This may take a long time and fail with an ExUnit timeout
+ data = Enum.join(stream)
+
+ time_after = System.system_time(:second)
+
+ assert String.match?(data, ~r/Message/)
+ assert String.match?(data, ~r/Message1/)
+ assert String.match?(data, ~r/Message2/)
+ assert String.match?(data, ~r/Message3/)
+
+ time_spent = time_after - time_before
+ assert time_spent > 15
+ # This my take longer then duration but not too long
+ assert time_spent < 45
+ end
+
+ test "run: may return an error if there is no log", context do
+ delete_log_files()
+ {:error, :enoent} = @command.run([], Map.merge(context[:opts], %{duration: 5}))
+ end
+
+ def ensure_log_file() do
+ [log|_] = :rpc.call(get_rabbit_hostname(), :rabbit_lager, :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
+ false ->
+ :rpc.call(get_rabbit_hostname(), :rabbit_log, :error, ["Ping"])
+ :timer.sleep(100)
+ ensure_file(log, attempts - 1)
+ end
+ end
+
+ def delete_log_files() do
+ [_|_] = logs = :rpc.call(get_rabbit_hostname(), :rabbit_lager, :log_locations, [])
+ Enum.map(logs, fn(log) ->
+ File.rm(log)
+ end)
+ 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
new file mode 100644
index 0000000000..3b70966d1c
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/maybe_stuck_command_test.exs
@@ -0,0 +1,48 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule MaybeStuckCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.MaybeStuckCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 15000
+ }}
+ end
+
+ test "merge_defaults: returns inputs" do
+ assert @command.merge_defaults([], %{timeout: 30}) == {[], %{timeout: 30}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ @tag test_timeout: 0
+ test "run: timeout throws a badrpc", context do
+ assert @command.run([], context[:opts]) == {:badrpc, :timeout}
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs
new file mode 100644
index 0000000000..8f7ffb14dc
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/memory_breakdown_command_test.exs
@@ -0,0 +1,72 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2016-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule MemoryBreakdownCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.MemoryBreakdownCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup do
+ {: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}
+
+ assert @command.validate(["abc", "def"], context[:opts]) ==
+ {:validation_failure, :too_many_args}
+ end
+
+ test "validate: specifying no positional arguments and no options succeeds", context do
+ assert @command.validate([], context[:opts]) == :ok
+ end
+
+ test "validate: specifying gigabytes as a --unit succeeds", context do
+ assert @command.validate([], Map.merge(context[:opts], %{unit: "gb"})) == :ok
+ end
+
+ test "validate: specifying bytes as a --unit succeeds", context do
+ assert @command.validate([], Map.merge(context[:opts], %{unit: "bytes"})) == :ok
+ end
+
+ test "validate: specifying megabytes as a --unit succeeds", context do
+ assert @command.validate([], Map.merge(context[:opts], %{unit: "mb"})) == :ok
+ end
+
+ 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"}
+ end
+
+ test "run: request to a non-existent RabbitMQ node returns a nodedown" do
+ opts = %{node: :jake@thedog, timeout: 200, unit: "gb"}
+ assert match?({:badrpc, _}, @command.run([], opts))
+ end
+
+ test "banner", context do
+ s = @command.banner([], context[:opts])
+
+ assert s =~ ~r/Reporting memory breakdown on node/
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs
new file mode 100644
index 0000000000..8ff97abb0b
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/observer_command_test.exs
@@ -0,0 +1,44 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule ObserverCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ObserverCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ interval: 5,
+ timeout: context[:test_timeout] || 15000
+ }}
+ end
+
+ test "merge_defaults: injects a default interval of 5s" do
+ assert @command.merge_defaults([], %{}) == {[], %{interval: 5}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :ok
+ end
+
+ @tag test_timeout: 3000
+ test "run: targeting an unreachable node throws a badrpc" do
+ assert match?({:badrpc, _}, @command.run([], %{node: :jake@thedog, interval: 5}))
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs
new file mode 100644
index 0000000000..254b41c9f2
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/os_env_command_test.exs
@@ -0,0 +1,62 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule OsEnvCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.OsEnvCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000,
+ all: false
+ }}
+ end
+
+ test "merge_defaults: merges no defaults" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: returns defined RabbitMQ-specific environment variables", context do
+ vars = @command.run([], context[:opts])
+
+ # 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)
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs
new file mode 100644
index 0000000000..2019154f0c
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/resolve_hostname_command_test.exs
@@ -0,0 +1,85 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ResolveHostnameCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ResolveHostnameCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {: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
+ assert @command.merge_defaults([], %{}) == {[], %{address_family: "IPv4", offline: false}}
+ end
+
+ test "validate: a single positional argument passes validation" do
+ assert @command.validate(["rabbitmq.com"], %{}) == :ok
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ 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"}))
+ end
+
+ test "validate: IPv4 for address family passes validation" do
+ assert @command.validate(["elixir-lang.org"], %{address_family: "ipv4"}) == :ok
+ assert @command.validate(["elixir-lang.org"], %{address_family: "IPv4"}) == :ok
+ end
+
+ test "validate: IPv6 for address family passes validation" do
+ assert @command.validate(["elixir-lang.org"], %{address_family: "ipv6"}) == :ok
+ assert @command.validate(["elixir-lang.org"], %{address_family: "IPv6"}) == :ok
+ end
+
+ @tag test_timeout: 3000
+ test "run: targeting an unreachable node throws a badrpc", context do
+ opts = Map.merge(context[:opts], %{node: :jake@thedog, timeout: 100})
+ assert match?({:badrpc, _}, @command.run(["elixir-lang.org"], opts))
+ end
+
+ test "run: returns a resolution result", context do
+ case @command.run(["github.com"], context[:opts]) do
+ {:ok, _hostent} -> :ok
+ {:error, :nxdomain} -> :ok
+ other -> flunk("hostname resolution returned #{other}")
+ end
+ end
+
+ 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
+ {:error, :nxdomain} -> :ok
+ other -> flunk("hostname resolution returned #{other}")
+ end
+ end
+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
new file mode 100644
index 0000000000..001371ed37
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/resolver_info_command_test.exs
@@ -0,0 +1,65 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule ResolverInfoCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ResolverInfoCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ start_rabbitmq_app()
+
+ ExUnit.configure([max_cases: 1])
+
+ on_exit([], fn ->
+ start_rabbitmq_app()
+ end)
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000,
+ offline: false
+ }}
+ end
+
+ test "merge_defaults: defaults to offline mode" do
+ assert @command.merge_defaults([], %{}) == {[], %{offline: false}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: returns host resolver (inetrc) information", context do
+ result = @command.run([], context[:opts])
+
+ assert result["lookup"] != nil
+ assert result["hosts_file"] != nil
+ end
+
+ test "run: returns host resolver (inetrc) information with --offline", context do
+ result = @command.run([], Map.merge(context[:opts], %{offline: true}))
+
+ assert result["lookup"] != nil
+ assert result["hosts_file"] != nil
+ end
+end
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
new file mode 100644
index 0000000000..34ab7b9c63
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/runtime_thread_stats_command_test.exs
@@ -0,0 +1,50 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule RuntimeThreadStatsCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.RuntimeThreadStatsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {: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}
+ 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})))
+ end
+
+ @tag test_timeout: 6000
+ test "run: returns msacc-formatted output", context do
+ res = @command.run([], context[:opts])
+ # the output is long and its values are environment-specific,
+ # so we simply assert that it is non-empty. MK.
+ assert length(res) > 0
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs
new file mode 100644
index 0000000000..369592522a
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/schema_info_command_test.exs
@@ -0,0 +1,69 @@
+defmodule SchemaInfoCommandTest do
+ use ExUnit.Case, async: false
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.SchemaInfoCommand
+ @default_timeout :infinity
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {
+ :ok,
+ opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || @default_timeout
+ }
+ }
+ end
+
+ test "merge_defaults: adds all keys if none specificed", context do
+ default_keys = ~w(name cookie active_replicas user_properties)
+
+ {keys, _} = @command.merge_defaults([], context[:opts])
+ assert default_keys == keys
+ end
+
+ test "merge_defaults: includes table headers by default", _context do
+ {_, opts} = @command.merge_defaults([], %{})
+ assert opts[:table_headers]
+ 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]}}
+ 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]}}
+ 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]}}
+ assert @command.validate(["access_mode", "oink"], context[:opts]) ==
+ {:validation_failure, {:bad_info_key, [:oink]}}
+ assert @command.validate(["access_mode", "oink", "name"], context[:opts]) ==
+ {: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}
+ 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]]))
+ end
+
+ test "banner" do
+ assert String.starts_with?(@command.banner([], %{node: "node@node"}), "Asking node")
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs
new file mode 100644
index 0000000000..72c32e32f1
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/server_version_command_test.exs
@@ -0,0 +1,48 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+
+defmodule ServerVersionCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.ServerVersionCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: nothing to do" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ end
+
+ test "run: returns RabbitMQ version on the target node", context do
+ res = @command.run([], context[:opts])
+ assert is_bitstring(res)
+ end
+end
diff --git a/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs b/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs
new file mode 100644
index 0000000000..0e38a0461e
--- /dev/null
+++ b/deps/rabbitmq_cli/test/diagnostics/tls_versions_command_test.exs
@@ -0,0 +1,60 @@
+## This Source Code Form is subject to the terms of the Mozilla Public
+## License, v. 2.0. If a copy of the MPL was not distributed with this
+## file, You can obtain one at https://mozilla.org/MPL/2.0/.
+##
+## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
+
+defmodule TlsVersionsCommandTest do
+ use ExUnit.Case
+ import TestHelper
+
+ @command RabbitMQ.CLI.Diagnostics.Commands.TlsVersionsCommand
+
+ setup_all do
+ RabbitMQ.CLI.Core.Distribution.start()
+
+ :ok
+ end
+
+ setup context do
+ {:ok, opts: %{
+ node: get_rabbit_hostname(),
+ timeout: context[:test_timeout] || 30000
+ }}
+ end
+
+ test "merge_defaults: is a no-op" do
+ assert @command.merge_defaults([], %{}) == {[], %{}}
+ end
+
+ test "validate: treats positional arguments as a failure" do
+ assert @command.validate(["extra-arg"], %{}) == {:validation_failure, :too_many_args}
+ end
+
+ test "validate: treats empty positional arguments and default switches as a success" do
+ assert @command.validate([], %{}) == :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})))
+ 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
+ xs = Map.get(m, :available)
+
+ # assert that we have a list and tlsv1.2 is included
+ assert length(xs) > 0
+ assert Enum.member?(xs, :"tlsv1.2")
+ end
+
+ test "run and output: return a list of supported TLS versions", context do
+ m = @command.run([], context[:opts])
+ {:ok, res} = @command.output(m, context[:opts])
+
+ # assert that we have a list and tlsv1.2 is included
+ assert length(res) > 0
+ assert Enum.member?(res, :"tlsv1.2")
+ end
+end