diff options
author | dcorbacho <dparracorbacho@piotal.io> | 2020-11-18 14:27:41 +0000 |
---|---|---|
committer | dcorbacho <dparracorbacho@piotal.io> | 2020-11-18 14:27:41 +0000 |
commit | f23a51261d9502ec39df0f8db47ba6b22aa7659f (patch) | |
tree | 53dcdf46e7dc2c14e81ee960bce8793879b488d3 /deps/rabbitmq_cli/test/diagnostics | |
parent | afa2c2bf6c7e0e9b63f4fb53dc931c70388e1c82 (diff) | |
parent | 9f6d64ec4a4b1eeac24d7846c5c64fd96798d892 (diff) | |
download | rabbitmq-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')
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 |