summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_event_exchange/test/system_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'deps/rabbitmq_event_exchange/test/system_SUITE.erl')
-rw-r--r--deps/rabbitmq_event_exchange/test/system_SUITE.erl490
1 files changed, 490 insertions, 0 deletions
diff --git a/deps/rabbitmq_event_exchange/test/system_SUITE.erl b/deps/rabbitmq_event_exchange/test/system_SUITE.erl
new file mode 100644
index 0000000000..79b819b962
--- /dev/null
+++ b/deps/rabbitmq_event_exchange/test/system_SUITE.erl
@@ -0,0 +1,490 @@
+%% 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.
+%%
+
+-module(system_SUITE).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+-include_lib("amqp_client/include/amqp_client.hrl").
+
+-compile(export_all).
+
+-define(TAG, <<"user_who_performed_action">>).
+
+all() ->
+ [
+ queue_created,
+ authentication,
+ audit_queue,
+ audit_exchange,
+ audit_binding,
+ audit_vhost,
+ audit_vhost_deletion,
+ audit_channel,
+ audit_connection,
+ audit_direct_connection,
+ audit_consumer,
+ audit_vhost_internal_parameter,
+ audit_parameter,
+ audit_policy,
+ audit_vhost_limit,
+ audit_user,
+ audit_user_password,
+ audit_user_tags,
+ audit_permission,
+ audit_topic_permission,
+ resource_alarm,
+ unregister
+ ].
+
+%% -------------------------------------------------------------------
+%% Testsuite setup/teardown.
+%% -------------------------------------------------------------------
+
+init_per_suite(Config) ->
+ rabbit_ct_helpers:log_environment(),
+ Config1 = rabbit_ct_helpers:set_config(Config, [
+ {rmq_nodename_suffix, ?MODULE}
+ ]),
+ Config2 = rabbit_ct_helpers:run_setup_steps(Config1,
+ rabbit_ct_broker_helpers:setup_steps() ++
+ rabbit_ct_client_helpers:setup_steps()),
+ Config2.
+
+end_per_suite(Config) ->
+ rabbit_ct_helpers:run_teardown_steps(Config,
+ rabbit_ct_client_helpers:teardown_steps() ++
+ rabbit_ct_broker_helpers:teardown_steps()).
+
+init_per_group(_, Config) ->
+ Config.
+
+end_per_group(_, Config) ->
+ Config.
+
+init_per_testcase(Testcase, Config) ->
+ rabbit_ct_helpers:testcase_started(Config, Testcase).
+
+end_per_testcase(Testcase, Config) ->
+ rabbit_ct_helpers:testcase_finished(Config, Testcase).
+
+
+%% -------------------------------------------------------------------
+%% Testsuite cases
+%% -------------------------------------------------------------------
+
+%% Only really tests that we're not completely broken.
+queue_created(Config) ->
+ Now = os:system_time(seconds),
+
+ Ch = declare_event_queue(Config, <<"queue.*">>),
+
+ #'queue.declare_ok'{queue = Q2} =
+ amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
+
+ receive
+ {#'basic.deliver'{routing_key = Key},
+ #amqp_msg{props = #'P_basic'{headers = Headers, timestamp = TS}}} ->
+ %% timestamp is within the last 5 seconds
+ true = ((TS - Now) =< 5),
+ <<"queue.created">> = Key,
+ {longstr, Q2} = rabbit_misc:table_lookup(Headers, <<"name">>)
+ end,
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+
+authentication(Config) ->
+ Ch = declare_event_queue(Config, <<"user.#">>),
+ Conn2 = rabbit_ct_client_helpers:open_unmanaged_connection(Config, 0),
+
+ receive
+ {#'basic.deliver'{routing_key = Key},
+ #amqp_msg{props = #'P_basic'{headers = Headers}}} ->
+ <<"user.authentication.success">> = Key,
+ undefined = rabbit_misc:table_lookup(Headers, <<"vhost">>),
+ {longstr, _PeerHost} = rabbit_misc:table_lookup(Headers, <<"peer_host">>),
+ {bool, false} = rabbit_misc:table_lookup(Headers, <<"ssl">>)
+ end,
+
+ amqp_connection:close(Conn2),
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_queue(Config) ->
+ Ch = declare_event_queue(Config, <<"queue.*">>),
+
+ #'queue.declare_ok'{queue = Q} =
+ amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
+
+ User = proplists:get_value(rmq_username, Config),
+ receive_user_in_event(<<"queue.created">>, User),
+
+ #'queue.delete_ok'{} =
+ amqp_channel:call(Ch, #'queue.delete'{queue = Q}),
+
+ receive_user_in_event(<<"queue.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_exchange(Config) ->
+ Ch = declare_event_queue(Config, <<"exchange.*">>),
+
+ X = <<"exchange.audited">>,
+ #'exchange.declare_ok'{} =
+ amqp_channel:call(Ch, #'exchange.declare'{exchange = X,
+ type = <<"topic">>}),
+
+ User = proplists:get_value(rmq_username, Config),
+ receive_user_in_event(<<"exchange.created">>, User),
+
+ #'exchange.delete_ok'{} =
+ amqp_channel:call(Ch, #'exchange.delete'{exchange = X}),
+
+ receive_user_in_event(<<"exchange.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_binding(Config) ->
+ Ch = declare_event_queue(Config, <<"binding.*">>),
+ %% The binding to the event exchange itself is the first queued event
+ User = proplists:get_value(rmq_username, Config),
+ receive_user_in_event(<<"binding.created">>, User),
+
+ #'queue.declare_ok'{queue = Q} =
+ amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
+
+ #'queue.bind_ok'{} =
+ amqp_channel:call(Ch, #'queue.bind'{queue = Q,
+ exchange = <<"amq.direct">>,
+ routing_key = <<"test">>}),
+ receive_user_in_event(<<"binding.created">>, User),
+
+ #'queue.unbind_ok'{} =
+ amqp_channel:call(Ch, #'queue.unbind'{queue = Q,
+ exchange = <<"amq.direct">>,
+ routing_key = <<"test">>}),
+ receive_user_in_event(<<"binding.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_vhost(Config) ->
+ Ch = declare_event_queue(Config, <<"vhost.*">>),
+ User = <<"Bugs Bunny">>,
+
+ rabbit_ct_broker_helpers:add_vhost(Config, 0, <<"test-vhost">>, User),
+ receive_user_in_event(<<"vhost.created">>, User),
+
+ rabbit_ct_broker_helpers:delete_vhost(Config, 0, <<"test-vhost">>, User),
+ receive_user_in_event(<<"vhost.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_vhost_deletion(Config) ->
+ Ch = declare_event_queue(Config, <<"queue.*">>),
+ ConnUser = proplists:get_value(rmq_username, Config),
+ User = <<"Bugs Bunny">>,
+ Vhost = <<"test-vhost">>,
+
+ rabbit_ct_broker_helpers:add_vhost(Config, 0, Vhost, User),
+ rabbit_ct_broker_helpers:set_full_permissions(Config, ConnUser, Vhost),
+ Conn = rabbit_ct_client_helpers:open_unmanaged_connection(Config, 0, Vhost),
+ {ok, Ch2} = amqp_connection:open_channel(Conn),
+
+ %% The user that creates the queue is the connection one, not the vhost creator
+ #'queue.declare_ok'{queue = _Q} = amqp_channel:call(Ch2, #'queue.declare'{}),
+ receive_user_in_event(<<"queue.created">>, ConnUser),
+ ok = rabbit_ct_client_helpers:close_connection_and_channel(Conn, Ch2),
+
+ %% Validate that the user deleting the queue is the one used to delete the vhost,
+ %% not the original user that created the queue (the connection one)
+ rabbit_ct_broker_helpers:delete_vhost(Config, 0, Vhost, User),
+ receive_user_in_event(<<"queue.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_channel(Config) ->
+ Ch = declare_event_queue(Config, <<"channel.*">>),
+ User = proplists:get_value(rmq_username, Config),
+
+ Conn = rabbit_ct_client_helpers:open_unmanaged_connection(Config),
+ {ok, Ch2} = amqp_connection:open_channel(Conn),
+ receive_user_in_event(<<"channel.created">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch2),
+ receive_user_in_event(<<"channel.closed">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_connection(Config) ->
+ Ch = declare_event_queue(Config, <<"connection.*">>),
+ User = proplists:get_value(rmq_username, Config),
+
+ Conn = rabbit_ct_client_helpers:open_unmanaged_connection(Config),
+ receive_user_in_event(<<"connection.created">>, User),
+
+ %% Username is not available in connection_close
+ rabbit_ct_client_helpers:close_connection(Conn),
+ receive_event(<<"connection.closed">>, ?TAG, undefined),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_direct_connection(Config) ->
+ Ch = declare_event_queue(Config, <<"connection.*">>),
+ User = proplists:get_value(rmq_username, Config),
+
+ Conn = rabbit_ct_client_helpers:open_unmanaged_connection_direct(Config),
+ receive_user_in_event(<<"connection.created">>, User),
+
+ rabbit_ct_client_helpers:close_connection(Conn),
+ receive_event(<<"connection.closed">>, ?TAG, undefined),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_consumer(Config) ->
+ Ch = declare_event_queue(Config, <<"consumer.*">>),
+ User = proplists:get_value(rmq_username, Config),
+ receive_user_in_event(<<"consumer.created">>, User),
+
+ #'queue.declare_ok'{queue = Q} =
+ amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
+ amqp_channel:subscribe(Ch, #'basic.consume'{queue = Q, no_ack = true},
+ self()),
+ CTag = receive #'basic.consume_ok'{consumer_tag = C} -> C end,
+ receive_user_in_event(<<"consumer.created">>, User),
+
+ amqp_channel:call(Ch, #'basic.cancel'{consumer_tag = CTag}),
+ receive_user_in_event(<<"consumer.deleted">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_vhost_internal_parameter(Config) ->
+ Ch = declare_event_queue(Config, <<"parameter.*">>),
+ User = <<"Bugs Bunny">>,
+ Vhost = <<"test-vhost">>,
+
+ rabbit_ct_broker_helpers:add_vhost(Config, 0, Vhost, User),
+ rabbit_ct_broker_helpers:delete_vhost(Config, 0, Vhost, User),
+ receive_user_in_event(<<"parameter.set">>, User),
+ receive_user_in_event(<<"parameter.cleared">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_parameter(Config) ->
+ Ch = declare_event_queue(Config, <<"parameter.*">>),
+ VHost = proplists:get_value(rmq_vhost, Config),
+ User = <<"Bugs Bunny">>,
+
+ ok = rabbit_ct_broker_helpers:set_parameter(
+ Config, 0, VHost, <<"vhost-limits">>, <<"limits">>,
+ [{<<"max-connections">>, 200}], User),
+ receive_user_in_event(<<"parameter.set">>, User),
+
+ ok = rabbit_ct_broker_helpers:clear_parameter(
+ Config, 0, VHost, <<"vhost-limits">>, <<"limits">>, User),
+ receive_user_in_event(<<"parameter.cleared">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_policy(Config) ->
+ Ch = declare_event_queue(Config, <<"policy.*">>),
+ User = <<"Bugs Bunny">>,
+
+ rabbit_ct_broker_helpers:set_policy(Config, 0, <<".*">>, <<"all">>, <<"queues">>,
+ [{<<"ha-mode">>, <<"all">>}], User),
+ receive_user_in_event(<<"policy.set">>, User),
+
+ ok = rabbit_ct_broker_helpers:clear_policy(Config, 0, <<".*">>, User),
+ receive_user_in_event(<<"policy.cleared">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_vhost_limit(Config) ->
+ Ch = declare_event_queue(Config, <<"vhost.limits.*">>),
+ VHost = proplists:get_value(rmq_vhost, Config),
+ User = <<"Bugs Bunny">>,
+
+ ok = rabbit_ct_broker_helpers:set_parameter(
+ Config, 0, VHost, <<"vhost-limits">>, <<"limits">>,
+ [{<<"max-connections">>, 200}], User),
+ receive_user_in_event(<<"vhost.limits.set">>, User),
+
+ ok = rabbit_ct_broker_helpers:clear_parameter(
+ Config, 0, VHost, <<"vhost-limits">>, <<"limits">>, User),
+ receive_user_in_event(<<"vhost.limits.cleared">>, User),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_user(Config) ->
+ Ch = declare_event_queue(Config, <<"user.*">>),
+ ActingUser = <<"Bugs Bunny">>,
+ User = <<"Wabbit">>,
+
+ rabbit_ct_broker_helpers:add_user(Config, 0, User, User, ActingUser),
+ receive_user_in_event(<<"user.created">>, ActingUser),
+
+ rabbit_ct_broker_helpers:delete_user(Config, 0, User, ActingUser),
+ receive_user_in_event(<<"user.deleted">>, ActingUser),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_user_password(Config) ->
+ Ch = declare_event_queue(Config, <<"user.password.*">>),
+ ActingUser = <<"Bugs Bunny">>,
+ User = <<"Wabbit">>,
+
+ rabbit_ct_broker_helpers:add_user(Config, 0, User, User, ActingUser),
+ rabbit_ct_broker_helpers:change_password(Config, 0, User, <<"pass">>, ActingUser),
+ receive_user_in_event(<<"user.password.changed">>, ActingUser),
+
+ rabbit_ct_broker_helpers:clear_password(Config, 0, User, ActingUser),
+ receive_user_in_event(<<"user.password.cleared">>, ActingUser),
+ rabbit_ct_broker_helpers:delete_user(Config, 0, User, ActingUser),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_user_tags(Config) ->
+ Ch = declare_event_queue(Config, <<"user.tags.*">>),
+ ActingUser = <<"Bugs Bunny">>,
+ User = <<"Wabbit">>,
+
+ rabbit_ct_broker_helpers:add_user(Config, 0, User, User, ActingUser),
+ rabbit_ct_broker_helpers:set_user_tags(Config, 0, User, [management], ActingUser),
+ receive_user_in_event(<<"user.tags.set">>, ActingUser),
+
+ rabbit_ct_broker_helpers:delete_user(Config, 0, User, ActingUser),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_permission(Config) ->
+ Ch = declare_event_queue(Config, <<"permission.*">>),
+ VHost = proplists:get_value(rmq_vhost, Config),
+ ActingUser = <<"Bugs Bunny">>,
+ User = <<"Wabbit">>,
+
+ rabbit_ct_broker_helpers:add_user(Config, 0, User, User, ActingUser),
+ rabbit_ct_broker_helpers:set_permissions(Config, 0, User, VHost, <<".*">>,
+ <<".*">>, <<".*">>, ActingUser),
+ receive_user_in_event(<<"permission.created">>, ActingUser),
+
+ rabbit_ct_broker_helpers:clear_permissions(Config, 0, User, VHost, ActingUser),
+ receive_user_in_event(<<"permission.deleted">>, ActingUser),
+ rabbit_ct_broker_helpers:delete_user(Config, 0, User, ActingUser),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+audit_topic_permission(Config) ->
+ Ch = declare_event_queue(Config, <<"topic.permission.*">>),
+ VHost = proplists:get_value(rmq_vhost, Config),
+ ActingUser = <<"Bugs Bunny">>,
+ User = <<"Wabbit">>,
+
+ rabbit_ct_broker_helpers:add_user(Config, 0, User, User, ActingUser),
+ rabbit_ct_broker_helpers:rpc(
+ Config, 0, rabbit_auth_backend_internal, set_topic_permissions,
+ [User, VHost, <<"amq.topic">>, "^a", "^a", ActingUser]),
+ receive_user_in_event(<<"topic.permission.created">>, ActingUser),
+
+ rabbit_ct_broker_helpers:rpc(
+ Config, 0, rabbit_auth_backend_internal, clear_topic_permissions,
+ [User, VHost, ActingUser]),
+ receive_user_in_event(<<"topic.permission.deleted">>, ActingUser),
+ rabbit_ct_broker_helpers:delete_user(Config, 0, User, ActingUser),
+
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+resource_alarm(Config) ->
+ Ch = declare_event_queue(Config, <<"alarm.*">>),
+
+ Source = disk,
+ Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
+
+ rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_alarm, set_alarm,
+ [{{resource_limit, Source, Node}, []}]),
+ receive_event(<<"alarm.set">>),
+
+ rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_alarm, clear_alarm,
+ [{resource_limit, Source, Node}]),
+ receive_event(<<"alarm.cleared">>),
+ rabbit_ct_client_helpers:close_channel(Ch),
+ ok.
+
+unregister(Config) ->
+ X = rabbit_misc:r(<<"/">>, exchange, <<"amq.rabbitmq.event">>),
+
+ ?assertMatch({ok, _},
+ rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_exchange,
+ lookup, [X])),
+
+ rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_exchange_type_event,
+ unregister, []),
+
+ ?assertEqual({error, not_found},
+ rabbit_ct_broker_helpers:rpc(Config, 0, rabbit_exchange,
+ lookup, [X])),
+ ok.
+
+%% -------------------------------------------------------------------
+%% Helpers
+%% -------------------------------------------------------------------
+
+declare_event_queue(Config, RoutingKey) ->
+ Ch = rabbit_ct_client_helpers:open_channel(Config, 0),
+ #'queue.declare_ok'{queue = Q} =
+ amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
+ amqp_channel:call(Ch, #'queue.bind'{queue = Q,
+ exchange = <<"amq.rabbitmq.event">>,
+ routing_key = RoutingKey}),
+ amqp_channel:subscribe(Ch, #'basic.consume'{queue = Q, no_ack = true},
+ self()),
+ receive
+ #'basic.consume_ok'{} -> ok
+ end,
+ Ch.
+
+receive_user_in_event(Event, User) ->
+ receive_event(Event, ?TAG, {longstr, User}).
+
+receive_event(Event, Key, Value) ->
+ receive
+ {#'basic.deliver'{routing_key = RoutingKey},
+ #amqp_msg{props = #'P_basic'{headers = Headers}}} ->
+ Event = RoutingKey,
+ Value = rabbit_misc:table_lookup(Headers, Key)
+ after
+ 60000 ->
+ throw({receive_event_timeout, Event, Key, Value})
+ end.
+
+receive_event(Event) ->
+ receive
+ {#'basic.deliver'{routing_key = RoutingKey},
+ #amqp_msg{props = #'P_basic'{}}} ->
+ Event = RoutingKey
+ after
+ 60000 ->
+ throw({receive_event_timeout, Event})
+ end.