Merge branch 'master' into rabbitmq-server-release-12

This commit is contained in:
Michael Klishin 2017-01-27 18:33:19 +03:00
commit 2a9c24af2c
15 changed files with 151 additions and 58 deletions

View File

@ -16,10 +16,6 @@
defmodule RabbitMQ.CLI.Formatters.Plugins do
@behaviour RabbitMQ.CLI.FormatterBehaviour
def format_error(err, _) when is_binary(err) do
err
end
def format_output(%{status: status, format: format, plugins: plugins},
options) do
legend(status, format, options) ++ format_plugins(plugins, format)

View File

@ -18,6 +18,7 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
alias RabbitMQ.CLI.Core.ExitCodes, as: ExitCodes
@behaviour RabbitMQ.CLI.CommandBehaviour
@ -42,7 +43,7 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
{:validation_failure, {:bad_argument, "Cannot set both online and offline"}}
end
def validate(_, opts) do
def validate(plugins, opts) do
:ok
|> validate_step(fn() -> Helpers.require_rabbit(opts) end)
|> validate_step(fn() -> PluginHelpers.enabled_plugins_file(opts) end)
@ -69,11 +70,19 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
end
def run(plugin_names, %{all: all_flag, node: node_name} = opts) do
def run(plugin_names, %{all: all_flag} = opts) do
plugins = case all_flag do
false -> for s <- plugin_names, do: String.to_atom(s);
true -> PluginHelpers.plugin_names(PluginHelpers.list(opts))
end
case PluginHelpers.validate_plugins(plugins, opts) do
:ok -> do_run(plugins, opts)
other -> other
end
end
def do_run(plugins, %{node: node_name} = opts) do
%{online: online, offline: offline} = opts
enabled = PluginHelpers.read_enabled(opts)
@ -112,10 +121,9 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
end
def output({:error, err}, _opts) do
{:error, err}
{:error, ExitCodes.exit_software(), to_string(err)}
end
def output({:stream, stream}, _opts) do
{:stream, stream}
end
end

View File

@ -18,6 +18,7 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
alias RabbitMQ.CLI.Core.ExitCodes, as: ExitCodes
@behaviour RabbitMQ.CLI.CommandBehaviour
@ -34,7 +35,7 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
{:validation_failure, {:bad_argument, "Cannot set both online and offline"}}
end
def validate(_, opts) do
def validate(plugins, opts) do
:ok
|> validate_step(fn() -> Helpers.require_rabbit(opts) end)
|> validate_step(fn() -> PluginHelpers.enabled_plugins_file(opts) end)
@ -58,7 +59,15 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
end
def run(plugins, %{node: node_name} = opts) do
def run(plugin_names, opts) do
plugins = for s <- plugin_names, do: String.to_atom(s)
case PluginHelpers.validate_plugins(plugins, opts) do
:ok -> do_run(plugins, opts)
other -> other
end
end
def do_run(plugins, %{node: node_name} = opts) do
%{online: online, offline: offline} = opts
mode = case {online, offline} do
@ -82,7 +91,7 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
end
def output({:error, err}, _opts) do
{:error, err}
{:error, ExitCodes.exit_software(), to_string(err)}
end
def output({:stream, stream}, _opts) do
{:stream, stream}

View File

@ -70,6 +70,28 @@ defmodule RabbitMQ.CLI.Plugins.Helpers do
end
end
def validate_plugins(requested_plugins, opts) do
## Maybe check all plugins
plugins = case opts do
%{all: true} -> plugin_names(list(opts))
_ -> requested_plugins
end
all = list(opts)
deps = :rabbit_plugins.dependencies(false, plugins, all)
deps_plugins = Enum.filter(all, fn(plugin) ->
name = plugin_name(plugin)
Enum.member?(plugins, name)
end)
validate_res = :rabbit_plugins.validate_plugins(deps_plugins)
case :rabbit_plugins.validate_plugins(deps_plugins) do
{_, []} -> :ok;
{_, invalid} -> {:error, :rabbit_plugins.format_invalid_plugins(invalid)}
end
end
def plugin_name(plugin) do
plugin(name: name) = plugin
name

View File

@ -0,0 +1,10 @@
{application, mock_rabbitmq_plugin_for_3_8, [
{description, "New project"},
{vsn, "0.1.0"},
{modules, ['mock_rabbitmq_plugins_01_app','mock_rabbitmq_plugins_01_sup']},
{registered, [mock_rabbitmq_plugins_01_sup]},
{applications, [kernel,stdlib,rabbit_common]},
{mod, {mock_rabbitmq_plugins_01_app, []}},
{env, []},
{broker_version_requirements, ["3.8.0"]}
]}.

View File

@ -120,7 +120,7 @@ defmodule EnablePluginsCommandTest do
assert [[:amqp_client, :rabbitmq_stomp],
%{mode: :offline, enabled: [:amqp_client, :rabbitmq_stomp], set: [:amqp_client, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream)
assert {:ok, [[:rabbitmq_stomp]]} == :file.consult(context[:opts][:enabled_plugins_file])
check_plugins_enabled([:rabbitmq_stomp], context)
assert [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp] ==
currently_active_plugins(context)
end
@ -134,8 +134,7 @@ defmodule EnablePluginsCommandTest do
assert [[:amqp_client, :rabbitmq_stomp],
%{mode: :offline, enabled: [:amqp_client, :rabbitmq_stomp], set: [:amqp_client, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream)
assert {:ok, [[:rabbitmq_stomp]]} == :file.consult(context[:opts][:enabled_plugins_file])
check_plugins_enabled([:rabbitmq_stomp], context)
assert_equal_sets(
[:amqp_client, :rabbitmq_federation, :rabbitmq_stomp],
currently_active_plugins(context))
@ -150,17 +149,14 @@ defmodule EnablePluginsCommandTest do
assert [[:amqp_client, :rabbitmq_stomp],
%{mode: :offline, enabled: [:amqp_client, :rabbitmq_stomp], set: [:amqp_client, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream0)
assert {:ok, [[:rabbitmq_stomp]]} == :file.consult(context[:opts][:enabled_plugins_file])
check_plugins_enabled([:rabbitmq_stomp], context)
assert {:stream, test_stream1} =
@command.run(["rabbitmq_federation"], Map.merge(context[:opts], %{offline: true, online: false}))
assert [[:amqp_client, :rabbitmq_federation, :rabbitmq_stomp],
%{mode: :offline, enabled: [:rabbitmq_federation],
set: [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream1)
{:ok, [xs]} = :file.consult(context[:opts][:enabled_plugins_file])
assert_equal_sets([:rabbitmq_stomp, :rabbitmq_federation], xs)
check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context)
end
test "updates plugin list and starts newly enabled plugins", context do
@ -175,9 +171,8 @@ defmodule EnablePluginsCommandTest do
enabled: [:amqp_client, :rabbitmq_stomp],
set: [:amqp_client, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream0)
assert {:ok, [xs]} = :file.consult(context[:opts][:enabled_plugins_file])
assert_equal_sets([:rabbitmq_stomp], xs)
check_plugins_enabled([:rabbitmq_stomp], context)
assert_equal_sets([:amqp_client, :rabbitmq_stomp], currently_active_plugins(context))
{:stream, test_stream1} =
@ -188,9 +183,8 @@ defmodule EnablePluginsCommandTest do
enabled: [:rabbitmq_federation],
set: [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream1)
assert {:ok, [xs]} = :file.consult(context[:opts][:enabled_plugins_file])
assert_equal_sets([:rabbitmq_stomp, :rabbitmq_federation], xs)
check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context)
assert_equal_sets([:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], currently_active_plugins(context))
end
@ -206,9 +200,8 @@ defmodule EnablePluginsCommandTest do
enabled: [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp],
set: [:amqp_client, :rabbitmq_federation, :rabbitmq_stomp]}] ==
Enum.to_list(test_stream)
assert {:ok, [xs]} = :file.consult(context[:opts][:enabled_plugins_file])
check_plugins_enabled([:rabbitmq_stomp, :rabbitmq_federation], context)
assert_equal_sets([:rabbitmq_stomp, :rabbitmq_federation], xs)
assert_equal_sets([:amqp_client, :rabbitmq_federation, :rabbitmq_stomp], currently_active_plugins(context))
end
@ -223,13 +216,39 @@ defmodule EnablePluginsCommandTest do
enabled: [],
set: [:amqp_client, :rabbitmq_federation]}] ==
Enum.to_list(test_stream)
assert {:ok, [[:rabbitmq_federation]]} == :file.consult(context[:opts][:enabled_plugins_file])
check_plugins_enabled([:rabbitmq_federation], context)
assert [:amqp_client, :rabbitmq_federation] ==
currently_active_plugins(context)
end
defp assert_equal_sets(a, b) do
assert MapSet.equal?(MapSet.new(a), MapSet.new(b))
test "run: does not enable plugins with unmet version requirements", context do
set_enabled_plugins([], :online, context[:opts][:node], context[:opts])
plugins_directory = fixture_plugins_path("plugins_with_version_requirements")
opts = get_opts_with_plugins_directories(context, [plugins_directory])
switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir])
{:stream, _} = @command.run(["mock_rabbitmq_plugin_for_3_7"], opts)
check_plugins_enabled([:mock_rabbitmq_plugin_for_3_7], context)
{:error, _version_error} =
@command.run(["mock_rabbitmq_plugin_for_3_8"], opts)
## Not changed
check_plugins_enabled([:mock_rabbitmq_plugin_for_3_7], context)
end
test "run: does not enable plugins with unmet version requirements even when enabling all plugins", context do
set_enabled_plugins([], :online, context[:opts][:node], context[:opts])
plugins_directory = fixture_plugins_path("plugins_with_version_requirements")
opts = get_opts_with_plugins_directories(context, [plugins_directory])
opts = Map.merge(opts, %{all: true})
switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir])
{:error, _version_error} = @command.run([], opts)
check_plugins_enabled([], context)
end
end

View File

@ -276,34 +276,4 @@ defmodule ListPluginsCommandTest do
%{name: :rabbitmq_stomp, enabled: :enabled, running: true}]} =
@command.run([".*"], opts)
end
defp switch_plugins_directories(old_value, new_value) do
:rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env,
[:rabbit, :plugins_dir, new_value])
on_exit(fn ->
:rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env,
[:rabbit, :plugins_dir, old_value])
end)
end
defp get_opts_with_non_existing_plugins_directory(context) do
get_opts_with_plugins_directories(context, ["/tmp/non_existing_rabbitmq_dummy_plugins"])
end
defp get_opts_with_plugins_directories(context, plugins_directories) do
opts = context[:opts]
plugins_dir = opts[:plugins_dir]
all_directories = Enum.join([to_string(plugins_dir) | plugins_directories], Helpers.separator())
%{opts | plugins_dir: to_char_list(all_directories)}
end
defp get_opts_with_existing_plugins_directory(context) do
extra_plugin_directory = System.tmp_dir!() |> Path.join("existing_rabbitmq_dummy_plugins")
File.mkdir!(extra_plugin_directory)
on_exit(fn ->
File.rm_rf(extra_plugin_directory)
end)
get_opts_with_plugins_directories(context, [extra_plugin_directory])
end
end

View File

@ -177,4 +177,21 @@ defmodule SetPluginsCommandTest do
Enum.sort(:rabbit_misc.rpc_call(context[:opts][:node], :rabbit_plugins, :active, []))
end
test "run: does not enable plugins with unmet version requirements", context do
set_enabled_plugins([], :online, context[:opts][:node], context[:opts])
plugins_directory = fixture_plugins_path("plugins_with_version_requirements")
opts = get_opts_with_plugins_directories(context, [plugins_directory])
switch_plugins_directories(context[:opts][:plugins_dir], opts[:plugins_dir])
{:stream, _} = @command.run(["mock_rabbitmq_plugin_for_3_7"], opts)
check_plugins_enabled([:mock_rabbitmq_plugin_for_3_7], context)
{:error, _version_error} =
@command.run(["mock_rabbitmq_plugin_for_3_8"], opts)
check_plugins_enabled([:mock_rabbitmq_plugin_for_3_7], context)
end
end

View File

@ -21,6 +21,7 @@ defmodule TestHelper do
alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers
alias RabbitMQ.CLI.Core.Config, as: Config
alias RabbitMQ.CLI.Core.CommandModules, as: CommandModules
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
def get_rabbit_hostname() do
RabbitMQ.CLI.Core.Helpers.get_rabbit_hostname()
@ -420,4 +421,45 @@ defmodule TestHelper do
Application.put_env(:rabbitmqctl, :scopes, scopes)
CommandModules.load(%{})
end
def switch_plugins_directories(old_value, new_value) do
:rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env,
[:rabbit, :plugins_dir, new_value])
ExUnit.Callbacks.on_exit(fn ->
:rabbit_misc.rpc_call(get_rabbit_hostname(), :application, :set_env,
[:rabbit, :plugins_dir, old_value])
end)
end
def get_opts_with_non_existing_plugins_directory(context) do
get_opts_with_plugins_directories(context, ["/tmp/non_existing_rabbitmq_dummy_plugins"])
end
def get_opts_with_plugins_directories(context, plugins_directories) do
opts = context[:opts]
plugins_dir = opts[:plugins_dir]
all_directories = Enum.join([to_string(plugins_dir) | plugins_directories], Helpers.separator())
%{opts | plugins_dir: to_char_list(all_directories)}
end
def get_opts_with_existing_plugins_directory(context) do
extra_plugin_directory = System.tmp_dir!() |> Path.join("existing_rabbitmq_dummy_plugins")
File.mkdir!(extra_plugin_directory)
ExUnit.Callbacks.on_exit(fn ->
File.rm_rf(extra_plugin_directory)
end)
get_opts_with_plugins_directories(context, [extra_plugin_directory])
end
def check_plugins_enabled(plugins, context) do
{:ok, [xs]} = :file.consult(context[:opts][:enabled_plugins_file])
assert_equal_sets(plugins, xs)
end
def assert_equal_sets(a, b) do
asorted = Enum.sort(a)
bsorted = Enum.sort(b)
assert asorted == bsorted
end
end