diff options
Diffstat (limited to 'deps/rabbitmq_event_exchange/test/system_SUITE.erl')
-rw-r--r-- | deps/rabbitmq_event_exchange/test/system_SUITE.erl | 490 |
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. |