diff options
| -rw-r--r-- | test/unit_SUITE.erl | 1 | ||||
| -rw-r--r-- | test/unit_access_control_SUITE.erl | 463 | ||||
| -rw-r--r-- | test/unit_credit_flow_SUITE.erl | 99 | ||||
| -rw-r--r-- | test/unit_disk_monitor_SUITE.erl | 45 | ||||
| -rw-r--r-- | test/unit_inbroker_parallel_SUITE.erl | 474 | ||||
| -rw-r--r-- | test/unit_pg_local_SUITE.erl | 2 | ||||
| -rw-r--r-- | test/unit_priority_queue_SUITE.erl | 193 | ||||
| -rw-r--r-- | test/unit_stats_and_metrics_SUITE.erl | 4 | ||||
| -rw-r--r-- | test/unit_vm_memory_monitor_SUITE.erl | 60 |
9 files changed, 853 insertions, 488 deletions
diff --git a/test/unit_SUITE.erl b/test/unit_SUITE.erl index 3e8c586de9..2d697c6fd6 100644 --- a/test/unit_SUITE.erl +++ b/test/unit_SUITE.erl @@ -48,7 +48,6 @@ groups() -> pmerge, plmerge, merge_operator_policy_definitions, - priority_queue, rabbit_direct_extract_extra_auth_props, {supervisor2, [], [ check_shutdown_stop, diff --git a/test/unit_access_control_SUITE.erl b/test/unit_access_control_SUITE.erl new file mode 100644 index 0000000000..bfd75442f8 --- /dev/null +++ b/test/unit_access_control_SUITE.erl @@ -0,0 +1,463 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% https://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2011-2020 VMware, Inc. or its affiliates. All rights reserved. +%% + +-module(unit_access_control_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("kernel/include/file.hrl"). +-include_lib("amqp_client/include/amqp_client.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +-compile(export_all). + +all() -> + [ + {group, sequential_tests}, + {group, parallel_tests} + ]. + +groups() -> + [ + {parallel_tests, [parallel], [ + password_hashing, + unsupported_connection_refusal + ]}, + {sequential_tests, [], [ + login_with_credentials_but_no_password, + login_of_passwordless_user, + set_tags_for_passwordless_user, + change_password, + topic_matching, + auth_backend_internal_expand_topic_permission, + rabbit_direct_extract_extra_auth_props + ]} + ]. + +%% ------------------------------------------------------------------- +%% Testsuite setup/teardown +%% ------------------------------------------------------------------- + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + rabbit_ct_helpers:run_setup_steps(Config). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config). + +init_per_group(Group, Config) -> + Config1 = rabbit_ct_helpers:set_config(Config, [ + {rmq_nodename_suffix, Group}, + {rmq_nodes_count, 1} + ]), + rabbit_ct_helpers:run_steps(Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + +end_per_group(_Group, Config) -> + rabbit_ct_helpers:run_steps(Config, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()). + +init_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_started(Config, Testcase). + +end_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_finished(Config, Testcase). + +%% --------------------------------------------------------------------------- +%% Test Cases +%% --------------------------------------------------------------------------- + +password_hashing(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, password_hashing1, [Config]). + +password_hashing1(_Config) -> + rabbit_password_hashing_sha256 = rabbit_password:hashing_mod(), + application:set_env(rabbit, password_hashing_module, + rabbit_password_hashing_md5), + rabbit_password_hashing_md5 = rabbit_password:hashing_mod(), + application:set_env(rabbit, password_hashing_module, + rabbit_password_hashing_sha256), + rabbit_password_hashing_sha256 = rabbit_password:hashing_mod(), + + rabbit_password_hashing_sha256 = + rabbit_password:hashing_mod(rabbit_password_hashing_sha256), + rabbit_password_hashing_md5 = + rabbit_password:hashing_mod(rabbit_password_hashing_md5), + rabbit_password_hashing_md5 = + rabbit_password:hashing_mod(undefined), + + rabbit_password_hashing_md5 = + rabbit_auth_backend_internal:hashing_module_for_user( + #internal_user{}), + rabbit_password_hashing_md5 = + rabbit_auth_backend_internal:hashing_module_for_user( + #internal_user{ + hashing_algorithm = undefined + }), + rabbit_password_hashing_md5 = + rabbit_auth_backend_internal:hashing_module_for_user( + #internal_user{ + hashing_algorithm = rabbit_password_hashing_md5 + }), + + rabbit_password_hashing_sha256 = + rabbit_auth_backend_internal:hashing_module_for_user( + #internal_user{ + hashing_algorithm = rabbit_password_hashing_sha256 + }), + + passed. + +change_password(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, change_password1, [Config]). + +change_password1(_Config) -> + UserName = <<"test_user">>, + Password = <<"test_password">>, + case rabbit_auth_backend_internal:lookup_user(UserName) of + {ok, _} -> rabbit_auth_backend_internal:delete_user(UserName, <<"acting-user">>); + _ -> ok + end, + ok = application:set_env(rabbit, password_hashing_module, + rabbit_password_hashing_md5), + ok = rabbit_auth_backend_internal:add_user(UserName, Password, <<"acting-user">>), + {ok, #auth_user{username = UserName}} = + rabbit_auth_backend_internal:user_login_authentication( + UserName, [{password, Password}]), + ok = application:set_env(rabbit, password_hashing_module, + rabbit_password_hashing_sha256), + {ok, #auth_user{username = UserName}} = + rabbit_auth_backend_internal:user_login_authentication( + UserName, [{password, Password}]), + + NewPassword = <<"test_password1">>, + ok = rabbit_auth_backend_internal:change_password(UserName, NewPassword, + <<"acting-user">>), + {ok, #auth_user{username = UserName}} = + rabbit_auth_backend_internal:user_login_authentication( + UserName, [{password, NewPassword}]), + + {refused, _, [UserName]} = + rabbit_auth_backend_internal:user_login_authentication( + UserName, [{password, Password}]), + passed. + + +login_with_credentials_but_no_password(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, login_with_credentials_but_no_password1, [Config]). + +login_with_credentials_but_no_password1(_Config) -> + Username = <<"login_with_credentials_but_no_password-user">>, + Password = <<"login_with_credentials_but_no_password-password">>, + ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>), + + try + rabbit_auth_backend_internal:user_login_authentication(Username, + [{key, <<"value">>}]), + ?assert(false) + catch exit:{unknown_auth_props, Username, [{key, <<"value">>}]} -> + ok + end, + + ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>), + + passed. + +%% passwordless users are not supposed to be used with +%% this backend (and PLAIN authentication mechanism in general) +login_of_passwordless_user(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, login_of_passwordless_user1, [Config]). + +login_of_passwordless_user1(_Config) -> + Username = <<"login_of_passwordless_user-user">>, + Password = <<"">>, + ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>), + + ?assertMatch( + {refused, _Message, [Username]}, + rabbit_auth_backend_internal:user_login_authentication(Username, + [{password, <<"">>}])), + + ?assertMatch( + {refused, _Format, [Username]}, + rabbit_auth_backend_internal:user_login_authentication(Username, + [{password, ""}])), + + ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>), + + passed. + + +set_tags_for_passwordless_user(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, set_tags_for_passwordless_user1, [Config]). + +set_tags_for_passwordless_user1(_Config) -> + Username = <<"set_tags_for_passwordless_user">>, + Password = <<"set_tags_for_passwordless_user">>, + ok = rabbit_auth_backend_internal:add_user(Username, Password, + <<"acting-user">>), + ok = rabbit_auth_backend_internal:clear_password(Username, + <<"acting-user">>), + ok = rabbit_auth_backend_internal:set_tags(Username, [management], + <<"acting-user">>), + + ?assertMatch( + {ok, #internal_user{tags = [management]}}, + rabbit_auth_backend_internal:lookup_user(Username)), + + ok = rabbit_auth_backend_internal:set_tags(Username, [management, policymaker], + <<"acting-user">>), + + ?assertMatch( + {ok, #internal_user{tags = [management, policymaker]}}, + rabbit_auth_backend_internal:lookup_user(Username)), + + ok = rabbit_auth_backend_internal:set_tags(Username, [], + <<"acting-user">>), + + ?assertMatch( + {ok, #internal_user{tags = []}}, + rabbit_auth_backend_internal:lookup_user(Username)), + + ok = rabbit_auth_backend_internal:delete_user(Username, + <<"acting-user">>), + + passed. + + +rabbit_direct_extract_extra_auth_props(_Config) -> + {ok, CSC} = code_server_cache:start_link(), + % no protocol to extract + [] = rabbit_direct:extract_extra_auth_props( + {<<"guest">>, <<"guest">>}, <<"/">>, 1, + [{name,<<"127.0.0.1:52366 -> 127.0.0.1:1883">>}]), + % protocol to extract, but no module to call + [] = rabbit_direct:extract_extra_auth_props( + {<<"guest">>, <<"guest">>}, <<"/">>, 1, + [{protocol, {'PROTOCOL_WITHOUT_MODULE', "1.0"}}]), + % see rabbit_dummy_protocol_connection_info module + % protocol to extract, module that returns a client ID + [{client_id, <<"DummyClientId">>}] = rabbit_direct:extract_extra_auth_props( + {<<"guest">>, <<"guest">>}, <<"/">>, 1, + [{protocol, {'DUMMY_PROTOCOL', "1.0"}}]), + % protocol to extract, but error thrown in module + [] = rabbit_direct:extract_extra_auth_props( + {<<"guest">>, <<"guest">>}, <<"/">>, -1, + [{protocol, {'DUMMY_PROTOCOL', "1.0"}}]), + gen_server:stop(CSC), + ok. + +auth_backend_internal_expand_topic_permission(_Config) -> + ExpandMap = #{<<"username">> => <<"guest">>, <<"vhost">> => <<"default">>}, + %% simple case + <<"services/default/accounts/guest/notifications">> = + rabbit_auth_backend_internal:expand_topic_permission( + <<"services/{vhost}/accounts/{username}/notifications">>, + ExpandMap + ), + %% replace variable twice + <<"services/default/accounts/default/guest/notifications">> = + rabbit_auth_backend_internal:expand_topic_permission( + <<"services/{vhost}/accounts/{vhost}/{username}/notifications">>, + ExpandMap + ), + %% nothing to replace + <<"services/accounts/notifications">> = + rabbit_auth_backend_internal:expand_topic_permission( + <<"services/accounts/notifications">>, + ExpandMap + ), + %% the expand map isn't defined + <<"services/{vhost}/accounts/{username}/notifications">> = + rabbit_auth_backend_internal:expand_topic_permission( + <<"services/{vhost}/accounts/{username}/notifications">>, + undefined + ), + %% the expand map is empty + <<"services/{vhost}/accounts/{username}/notifications">> = + rabbit_auth_backend_internal:expand_topic_permission( + <<"services/{vhost}/accounts/{username}/notifications">>, + #{} + ), + ok. + +unsupported_connection_refusal(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, unsupported_connection_refusal1, [Config]). + +unsupported_connection_refusal1(Config) -> + H = ?config(rmq_hostname, Config), + P = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp), + [passed = test_unsupported_connection_refusal(H, P, V) || + V <- [<<"AMQP",9,9,9,9>>, <<"AMQP",0,1,0,0>>, <<"XXXX",0,0,9,1>>]], + passed. + +test_unsupported_connection_refusal(H, P, Header) -> + {ok, C} = gen_tcp:connect(H, P, [binary, {active, false}]), + ok = gen_tcp:send(C, Header), + {ok, <<"AMQP",0,0,9,1>>} = gen_tcp:recv(C, 8, 100), + ok = gen_tcp:close(C), + passed. + + +%% ------------------------------------------------------------------- +%% Topic matching. +%% ------------------------------------------------------------------- + +topic_matching(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, topic_matching1, [Config]). + +topic_matching1(_Config) -> + XName = #resource{virtual_host = <<"/">>, + kind = exchange, + name = <<"topic_matching-exchange">>}, + X0 = #exchange{name = XName, type = topic, durable = false, + auto_delete = false, arguments = []}, + X = rabbit_exchange_decorator:set(X0), + %% create + rabbit_exchange_type_topic:validate(X), + exchange_op_callback(X, create, []), + + %% add some bindings + Bindings = [#binding{source = XName, + key = list_to_binary(Key), + destination = #resource{virtual_host = <<"/">>, + kind = queue, + name = list_to_binary(Q)}, + args = Args} || + {Key, Q, Args} <- [{"a.b.c", "t1", []}, + {"a.*.c", "t2", []}, + {"a.#.b", "t3", []}, + {"a.b.b.c", "t4", []}, + {"#", "t5", []}, + {"#.#", "t6", []}, + {"#.b", "t7", []}, + {"*.*", "t8", []}, + {"a.*", "t9", []}, + {"*.b.c", "t10", []}, + {"a.#", "t11", []}, + {"a.#.#", "t12", []}, + {"b.b.c", "t13", []}, + {"a.b.b", "t14", []}, + {"a.b", "t15", []}, + {"b.c", "t16", []}, + {"", "t17", []}, + {"*.*.*", "t18", []}, + {"vodka.martini", "t19", []}, + {"a.b.c", "t20", []}, + {"*.#", "t21", []}, + {"#.*.#", "t22", []}, + {"*.#.#", "t23", []}, + {"#.#.#", "t24", []}, + {"*", "t25", []}, + {"#.b.#", "t26", []}, + {"args-test", "t27", + [{<<"foo">>, longstr, <<"bar">>}]}, + {"args-test", "t27", %% Note aliasing + [{<<"foo">>, longstr, <<"baz">>}]}]], + lists:foreach(fun (B) -> exchange_op_callback(X, add_binding, [B]) end, + Bindings), + + %% test some matches + test_topic_expect_match( + X, [{"a.b.c", ["t1", "t2", "t5", "t6", "t10", "t11", "t12", + "t18", "t20", "t21", "t22", "t23", "t24", + "t26"]}, + {"a.b", ["t3", "t5", "t6", "t7", "t8", "t9", "t11", + "t12", "t15", "t21", "t22", "t23", "t24", + "t26"]}, + {"a.b.b", ["t3", "t5", "t6", "t7", "t11", "t12", "t14", + "t18", "t21", "t22", "t23", "t24", "t26"]}, + {"", ["t5", "t6", "t17", "t24"]}, + {"b.c.c", ["t5", "t6", "t18", "t21", "t22", "t23", + "t24", "t26"]}, + {"a.a.a.a.a", ["t5", "t6", "t11", "t12", "t21", "t22", + "t23", "t24"]}, + {"vodka.gin", ["t5", "t6", "t8", "t21", "t22", "t23", + "t24"]}, + {"vodka.martini", ["t5", "t6", "t8", "t19", "t21", "t22", "t23", + "t24"]}, + {"b.b.c", ["t5", "t6", "t10", "t13", "t18", "t21", + "t22", "t23", "t24", "t26"]}, + {"nothing.here.at.all", ["t5", "t6", "t21", "t22", "t23", "t24"]}, + {"oneword", ["t5", "t6", "t21", "t22", "t23", "t24", + "t25"]}, + {"args-test", ["t5", "t6", "t21", "t22", "t23", "t24", + "t25", "t27"]}]), + %% remove some bindings + RemovedBindings = [lists:nth(1, Bindings), lists:nth(5, Bindings), + lists:nth(11, Bindings), lists:nth(19, Bindings), + lists:nth(21, Bindings), lists:nth(28, Bindings)], + exchange_op_callback(X, remove_bindings, [RemovedBindings]), + RemainingBindings = ordsets:to_list( + ordsets:subtract(ordsets:from_list(Bindings), + ordsets:from_list(RemovedBindings))), + + %% test some matches + test_topic_expect_match( + X, + [{"a.b.c", ["t2", "t6", "t10", "t12", "t18", "t20", "t22", + "t23", "t24", "t26"]}, + {"a.b", ["t3", "t6", "t7", "t8", "t9", "t12", "t15", + "t22", "t23", "t24", "t26"]}, + {"a.b.b", ["t3", "t6", "t7", "t12", "t14", "t18", "t22", + "t23", "t24", "t26"]}, + {"", ["t6", "t17", "t24"]}, + {"b.c.c", ["t6", "t18", "t22", "t23", "t24", "t26"]}, + {"a.a.a.a.a", ["t6", "t12", "t22", "t23", "t24"]}, + {"vodka.gin", ["t6", "t8", "t22", "t23", "t24"]}, + {"vodka.martini", ["t6", "t8", "t22", "t23", "t24"]}, + {"b.b.c", ["t6", "t10", "t13", "t18", "t22", "t23", + "t24", "t26"]}, + {"nothing.here.at.all", ["t6", "t22", "t23", "t24"]}, + {"oneword", ["t6", "t22", "t23", "t24", "t25"]}, + {"args-test", ["t6", "t22", "t23", "t24", "t25", "t27"]}]), + + %% remove the entire exchange + exchange_op_callback(X, delete, [RemainingBindings]), + %% none should match now + test_topic_expect_match(X, [{"a.b.c", []}, {"b.b.c", []}, {"", []}]), + passed. + +exchange_op_callback(X, Fun, Args) -> + rabbit_misc:execute_mnesia_transaction( + fun () -> rabbit_exchange:callback(X, Fun, transaction, [X] ++ Args) end), + rabbit_exchange:callback(X, Fun, none, [X] ++ Args). + +test_topic_expect_match(X, List) -> + lists:foreach( + fun ({Key, Expected}) -> + BinKey = list_to_binary(Key), + Message = rabbit_basic:message(X#exchange.name, BinKey, + #'P_basic'{}, <<>>), + Res = rabbit_exchange_type_topic:route( + X, #delivery{mandatory = false, + sender = self(), + message = Message}), + ExpectedRes = lists:map( + fun (Q) -> #resource{virtual_host = <<"/">>, + kind = queue, + name = list_to_binary(Q)} + end, Expected), + true = (lists:usort(ExpectedRes) =:= lists:usort(Res)) + end, List). diff --git a/test/unit_credit_flow_SUITE.erl b/test/unit_credit_flow_SUITE.erl new file mode 100644 index 0000000000..38267dbd9a --- /dev/null +++ b/test/unit_credit_flow_SUITE.erl @@ -0,0 +1,99 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% https://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2011-2020 VMware, Inc. or its affiliates. All rights reserved. +%% + +-module(unit_credit_flow_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +-compile(export_all). + +all() -> + [ + {group, sequential_tests} + ]. + +groups() -> + [ + {sequential_tests, [], [ + credit_flow_settings + ]} + ]. + +%% ------------------------------------------------------------------- +%% Testsuite setup/teardown +%% ------------------------------------------------------------------- + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + rabbit_ct_helpers:run_setup_steps(Config). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config). + +init_per_group(Group, Config) -> + Config1 = rabbit_ct_helpers:set_config(Config, [ + {rmq_nodename_suffix, Group}, + {rmq_nodes_count, 1} + ]), + rabbit_ct_helpers:run_steps(Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + +end_per_group(_Group, Config) -> + rabbit_ct_helpers:run_steps(Config, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()). + +init_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_started(Config, Testcase). + +end_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_finished(Config, Testcase). + + +%% --------------------------------------------------------------------------- +%% Test Cases +%% --------------------------------------------------------------------------- + +credit_flow_settings(Config) -> + rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, credit_flow_settings1, [Config]). + +credit_flow_settings1(_Config) -> + passed = test_proc(400, 200, {400, 200}), + passed = test_proc(600, 300), + passed. + +test_proc(InitialCredit, MoreCreditAfter) -> + test_proc(InitialCredit, MoreCreditAfter, {InitialCredit, MoreCreditAfter}). +test_proc(InitialCredit, MoreCreditAfter, Settings) -> + Pid = spawn(?MODULE, dummy, [Settings]), + Pid ! {credit, self()}, + {InitialCredit, MoreCreditAfter} = + receive + {credit, Val} -> Val + end, + passed. + +dummy(Settings) -> + credit_flow:send(self()), + receive + {credit, From} -> + From ! {credit, Settings}; + _ -> + dummy(Settings) + end. diff --git a/test/unit_disk_monitor_SUITE.erl b/test/unit_disk_monitor_SUITE.erl index 5e5099f01a..87ce6f8d2d 100644 --- a/test/unit_disk_monitor_SUITE.erl +++ b/test/unit_disk_monitor_SUITE.erl @@ -16,11 +16,8 @@ -module(unit_disk_monitor_SUITE). --include_lib("eunit/include/eunit.hrl"). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). --include_lib("kernel/include/file.hrl"). --include_lib("amqp_client/include/amqp_client.hrl"). -compile(export_all). @@ -28,19 +25,20 @@ all() -> [ - {group, non_parallel_tests} + {group, sequential_tests} ]. groups() -> [ - {non_parallel_tests, [], [ + {sequential_tests, [], [ disk_monitor, - disk_monitor_enable + disk_monitor_enable, + set_disk_free_limit_command ]} ]. %% ------------------------------------------------------------------- -%% Testsuite setup/teardown. +%% Testsuite setup/teardown %% ------------------------------------------------------------------- init_per_suite(Config) -> @@ -53,7 +51,7 @@ end_per_suite(Config) -> init_per_group(Group, Config) -> Config1 = rabbit_ct_helpers:set_config(Config, [ {rmq_nodename_suffix, Group}, - {rmq_nodes_count, 2} + {rmq_nodes_count, 1} ]), rabbit_ct_helpers:run_steps(Config1, rabbit_ct_broker_helpers:setup_steps() ++ @@ -71,6 +69,37 @@ end_per_testcase(Testcase, Config) -> rabbit_ct_helpers:testcase_finished(Config, Testcase). +%% ------------------------------------------------------------------- +%% Test cases +%% ------------------------------------------------------------------- + +set_disk_free_limit_command(Config) -> + passed = rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, set_disk_free_limit_command1, [Config]). + +set_disk_free_limit_command1(_Config) -> + %% use an absolute value + rabbit_disk_monitor:set_disk_free_limit("2000kiB"), + ?assertEqual(2048000, rabbit_disk_monitor:get_disk_free_limit()), + + %% Use an integer + rabbit_disk_monitor:set_disk_free_limit({mem_relative, 1}), + disk_free_limit_to_total_memory_ratio_is(1), + + %% Use a float + rabbit_disk_monitor:set_disk_free_limit({mem_relative, 1.5}), + disk_free_limit_to_total_memory_ratio_is(1.5), + + rabbit_disk_monitor:set_disk_free_limit("50MB"), + passed. + +disk_free_limit_to_total_memory_ratio_is(MemRatio) -> + ExpectedLimit = MemRatio * vm_memory_monitor:get_total_memory(), + % Total memory is unstable, so checking order + true = ExpectedLimit/rabbit_disk_monitor:get_disk_free_limit() < 1.2, + true = ExpectedLimit/rabbit_disk_monitor:get_disk_free_limit() > 0.98. + + disk_monitor(Config) -> passed = rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, disk_monitor1, [Config]). diff --git a/test/unit_inbroker_parallel_SUITE.erl b/test/unit_inbroker_parallel_SUITE.erl index 45a889cb20..f0d4b7b1c6 100644 --- a/test/unit_inbroker_parallel_SUITE.erl +++ b/test/unit_inbroker_parallel_SUITE.erl @@ -46,24 +46,11 @@ groups() -> max_length_bytes_drop_publish], [ {parallel_tests, [parallel], [ - amqp_connection_refusal, configurable_server_properties, credit_flow_settings, dynamic_mirroring, gen_server2_with_state, mcall, - {password_hashing, [], [ - password_hashing, - change_password - ]}, - {auth_backend_internal, [parallel], [ - login_with_credentials_but_no_password, - login_of_passwordless_user, - set_tags_for_passwordless_user - ]}, - set_disk_free_limit_command, - set_vm_memory_high_watermark_command, - topic_matching, max_message_size, {queue_max_length, [], [ @@ -284,39 +271,6 @@ requeue_one_by_one(Acks, VQ) -> VQM end, VQ, Acks). -%% --------------------------------------------------------------------------- -%% Credit flow. -%% --------------------------------------------------------------------------- - -credit_flow_settings(Config) -> - rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, credit_flow_settings1, [Config]). - -credit_flow_settings1(_Config) -> - passed = test_proc(400, 200, {400, 200}), - passed = test_proc(600, 300), - passed. - -test_proc(InitialCredit, MoreCreditAfter) -> - test_proc(InitialCredit, MoreCreditAfter, {InitialCredit, MoreCreditAfter}). -test_proc(InitialCredit, MoreCreditAfter, Settings) -> - Pid = spawn(?MODULE, dummy, [Settings]), - Pid ! {credit, self()}, - {InitialCredit, MoreCreditAfter} = - receive - {credit, Val} -> Val - end, - passed. - -dummy(Settings) -> - credit_flow:send(self()), - receive - {credit, From} -> - From ! {credit, Settings}; - _ -> - dummy(Settings) - end. - %% ------------------------------------------------------------------- %% dynamic_mirroring. %% ------------------------------------------------------------------- @@ -445,199 +399,12 @@ ok_or_empty_list([]) -> ok_or_empty_list(ok) -> ok. -%% --------------------------------------------------------------------------- -%% Password hashing. -%% --------------------------------------------------------------------------- - -password_hashing(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, password_hashing1, [Config]). - -password_hashing1(_Config) -> - rabbit_password_hashing_sha256 = rabbit_password:hashing_mod(), - application:set_env(rabbit, password_hashing_module, - rabbit_password_hashing_md5), - rabbit_password_hashing_md5 = rabbit_password:hashing_mod(), - application:set_env(rabbit, password_hashing_module, - rabbit_password_hashing_sha256), - rabbit_password_hashing_sha256 = rabbit_password:hashing_mod(), - - rabbit_password_hashing_sha256 = - rabbit_password:hashing_mod(rabbit_password_hashing_sha256), - rabbit_password_hashing_md5 = - rabbit_password:hashing_mod(rabbit_password_hashing_md5), - rabbit_password_hashing_md5 = - rabbit_password:hashing_mod(undefined), - - rabbit_password_hashing_md5 = - rabbit_auth_backend_internal:hashing_module_for_user( - #internal_user{}), - rabbit_password_hashing_md5 = - rabbit_auth_backend_internal:hashing_module_for_user( - #internal_user{ - hashing_algorithm = undefined - }), - rabbit_password_hashing_md5 = - rabbit_auth_backend_internal:hashing_module_for_user( - #internal_user{ - hashing_algorithm = rabbit_password_hashing_md5 - }), - - rabbit_password_hashing_sha256 = - rabbit_auth_backend_internal:hashing_module_for_user( - #internal_user{ - hashing_algorithm = rabbit_password_hashing_sha256 - }), - - passed. - -change_password(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, change_password1, [Config]). - -change_password1(_Config) -> - UserName = <<"test_user">>, - Password = <<"test_password">>, - case rabbit_auth_backend_internal:lookup_user(UserName) of - {ok, _} -> rabbit_auth_backend_internal:delete_user(UserName, <<"acting-user">>); - _ -> ok - end, - ok = application:set_env(rabbit, password_hashing_module, - rabbit_password_hashing_md5), - ok = rabbit_auth_backend_internal:add_user(UserName, Password, <<"acting-user">>), - {ok, #auth_user{username = UserName}} = - rabbit_auth_backend_internal:user_login_authentication( - UserName, [{password, Password}]), - ok = application:set_env(rabbit, password_hashing_module, - rabbit_password_hashing_sha256), - {ok, #auth_user{username = UserName}} = - rabbit_auth_backend_internal:user_login_authentication( - UserName, [{password, Password}]), - - NewPassword = <<"test_password1">>, - ok = rabbit_auth_backend_internal:change_password(UserName, NewPassword, - <<"acting-user">>), - {ok, #auth_user{username = UserName}} = - rabbit_auth_backend_internal:user_login_authentication( - UserName, [{password, NewPassword}]), - - {refused, _, [UserName]} = - rabbit_auth_backend_internal:user_login_authentication( - UserName, [{password, Password}]), - passed. - - -%% ------------------------------------------------------------------- -%% rabbit_auth_backend_internal -%% ------------------------------------------------------------------- - -login_with_credentials_but_no_password(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, login_with_credentials_but_no_password1, [Config]). - -login_with_credentials_but_no_password1(_Config) -> - Username = <<"login_with_credentials_but_no_password-user">>, - Password = <<"login_with_credentials_but_no_password-password">>, - ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>), - - try - rabbit_auth_backend_internal:user_login_authentication(Username, - [{key, <<"value">>}]), - ?assert(false) - catch exit:{unknown_auth_props, Username, [{key, <<"value">>}]} -> - ok - end, - - ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>), - - passed. - -%% passwordless users are not supposed to be used with -%% this backend (and PLAIN authentication mechanism in general) -login_of_passwordless_user(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, login_of_passwordless_user1, [Config]). - -login_of_passwordless_user1(_Config) -> - Username = <<"login_of_passwordless_user-user">>, - Password = <<"">>, - ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>), - - ?assertMatch( - {refused, _Message, [Username]}, - rabbit_auth_backend_internal:user_login_authentication(Username, - [{password, <<"">>}])), - - ?assertMatch( - {refused, _Format, [Username]}, - rabbit_auth_backend_internal:user_login_authentication(Username, - [{password, ""}])), - - ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>), - - passed. - - -set_tags_for_passwordless_user(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, set_tags_for_passwordless_user1, [Config]). - -set_tags_for_passwordless_user1(_Config) -> - Username = <<"set_tags_for_passwordless_user">>, - Password = <<"set_tags_for_passwordless_user">>, - ok = rabbit_auth_backend_internal:add_user(Username, Password, - <<"acting-user">>), - ok = rabbit_auth_backend_internal:clear_password(Username, - <<"acting-user">>), - ok = rabbit_auth_backend_internal:set_tags(Username, [management], - <<"acting-user">>), - - ?assertMatch( - {ok, #internal_user{tags = [management]}}, - rabbit_auth_backend_internal:lookup_user(Username)), - - ok = rabbit_auth_backend_internal:set_tags(Username, [management, policymaker], - <<"acting-user">>), - - ?assertMatch( - {ok, #internal_user{tags = [management, policymaker]}}, - rabbit_auth_backend_internal:lookup_user(Username)), - - ok = rabbit_auth_backend_internal:set_tags(Username, [], - <<"acting-user">>), - - ?assertMatch( - {ok, #internal_user{tags = []}}, - rabbit_auth_backend_internal:lookup_user(Username)), - - ok = rabbit_auth_backend_internal:delete_user(Username, - <<"acting-user">>), - - passed. %% ------------------------------------------------------------------- %% rabbitmqctl. %% ------------------------------------------------------------------- -amqp_connection_refusal(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, amqp_connection_refusal1, [Config]). - -amqp_connection_refusal1(Config) -> - H = ?config(rmq_hostname, Config), - P = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp), - [passed = test_amqp_connection_refusal(H, P, V) || - V <- [<<"AMQP",9,9,9,9>>, <<"AMQP",0,1,0,0>>, <<"XXXX",0,0,9,1>>]], - passed. - -test_amqp_connection_refusal(H, P, Header) -> - {ok, C} = gen_tcp:connect(H, P, [binary, {active, false}]), - ok = gen_tcp:send(C, Header), - {ok, <<"AMQP",0,0,9,1>>} = gen_tcp:recv(C, 8, 100), - ok = gen_tcp:close(C), - passed. - rabbitmqctl_list_consumers(Config, Node) -> {ok, StdOut} = rabbit_ct_broker_helpers:rabbitmqctl(Config, Node, ["list_consumers"]), @@ -656,60 +423,6 @@ test_ch_metrics(Fun, Timeout) -> test_ch_metrics(Fun, Timeout - 1000) end. -head_message_timestamp_statistics(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, head_message_timestamp1, [Config]). - -head_message_timestamp1(_Config) -> - %% Can't find a way to receive the ack here so can't test pending acks status - - application:set_env(rabbit, collect_statistics, fine), - - %% Set up a channel and queue - {_Writer, Ch} = test_spawn(), - rabbit_channel:do(Ch, #'queue.declare'{}), - QName = receive #'queue.declare_ok'{queue = Q0} -> Q0 - after ?TIMEOUT -> throw(failed_to_receive_queue_declare_ok) - end, - QRes = rabbit_misc:r(<<"/">>, queue, QName), - - {ok, Q1} = rabbit_amqqueue:lookup(QRes), - QPid = amqqueue:get_pid(Q1), - - %% Set up event receiver for queue - dummy_event_receiver:start(self(), [node()], [queue_stats]), - - %% Check timestamp is empty when queue is empty - Event1 = test_queue_statistics_receive_event(QPid, fun (E) -> proplists:get_value(name, E) == QRes end), - '' = proplists:get_value(head_message_timestamp, Event1), - - %% Publish two messages and check timestamp is that of first message - rabbit_channel:do(Ch, #'basic.publish'{exchange = <<"">>, - routing_key = QName}, - rabbit_basic:build_content(#'P_basic'{timestamp = 1}, <<"">>)), - rabbit_channel:do(Ch, #'basic.publish'{exchange = <<"">>, - routing_key = QName}, - rabbit_basic:build_content(#'P_basic'{timestamp = 2}, <<"">>)), - Event2 = test_queue_statistics_receive_event(QPid, fun (E) -> proplists:get_value(name, E) == QRes end), - 1 = proplists:get_value(head_message_timestamp, Event2), - - %% Get first message and check timestamp is that of second message - rabbit_channel:do(Ch, #'basic.get'{queue = QName, no_ack = true}), - Event3 = test_queue_statistics_receive_event(QPid, fun (E) -> proplists:get_value(name, E) == QRes end), - 2 = proplists:get_value(head_message_timestamp, Event3), - - %% Get second message and check timestamp is empty again - rabbit_channel:do(Ch, #'basic.get'{queue = QName, no_ack = true}), - Event4 = test_queue_statistics_receive_event(QPid, fun (E) -> proplists:get_value(name, E) == QRes end), - '' = proplists:get_value(head_message_timestamp, Event4), - - %% Teardown - rabbit_channel:do(Ch, #'queue.delete'{queue = QName}), - rabbit_channel:shutdown(Ch), - dummy_event_receiver:stop(), - - passed. - test_queue_statistics_receive_event(Q, Matcher) -> %% Q ! emit_stats, test_queue_statistics_receive_event1(Q, Matcher). @@ -751,149 +464,6 @@ test_spawn_remote() -> after ?TIMEOUT -> throw(failed_to_receive_result) end. -%% ------------------------------------------------------------------- -%% Topic matching. -%% ------------------------------------------------------------------- - -topic_matching(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, topic_matching1, [Config]). - -topic_matching1(_Config) -> - XName = #resource{virtual_host = <<"/">>, - kind = exchange, - name = <<"topic_matching-exchange">>}, - X0 = #exchange{name = XName, type = topic, durable = false, - auto_delete = false, arguments = []}, - X = rabbit_exchange_decorator:set(X0), - %% create - rabbit_exchange_type_topic:validate(X), - exchange_op_callback(X, create, []), - - %% add some bindings - Bindings = [#binding{source = XName, - key = list_to_binary(Key), - destination = #resource{virtual_host = <<"/">>, - kind = queue, - name = list_to_binary(Q)}, - args = Args} || - {Key, Q, Args} <- [{"a.b.c", "t1", []}, - {"a.*.c", "t2", []}, - {"a.#.b", "t3", []}, - {"a.b.b.c", "t4", []}, - {"#", "t5", []}, - {"#.#", "t6", []}, - {"#.b", "t7", []}, - {"*.*", "t8", []}, - {"a.*", "t9", []}, - {"*.b.c", "t10", []}, - {"a.#", "t11", []}, - {"a.#.#", "t12", []}, - {"b.b.c", "t13", []}, - {"a.b.b", "t14", []}, - {"a.b", "t15", []}, - {"b.c", "t16", []}, - {"", "t17", []}, - {"*.*.*", "t18", []}, - {"vodka.martini", "t19", []}, - {"a.b.c", "t20", []}, - {"*.#", "t21", []}, - {"#.*.#", "t22", []}, - {"*.#.#", "t23", []}, - {"#.#.#", "t24", []}, - {"*", "t25", []}, - {"#.b.#", "t26", []}, - {"args-test", "t27", - [{<<"foo">>, longstr, <<"bar">>}]}, - {"args-test", "t27", %% Note aliasing - [{<<"foo">>, longstr, <<"baz">>}]}]], - lists:foreach(fun (B) -> exchange_op_callback(X, add_binding, [B]) end, - Bindings), - - %% test some matches - test_topic_expect_match( - X, [{"a.b.c", ["t1", "t2", "t5", "t6", "t10", "t11", "t12", - "t18", "t20", "t21", "t22", "t23", "t24", - "t26"]}, - {"a.b", ["t3", "t5", "t6", "t7", "t8", "t9", "t11", - "t12", "t15", "t21", "t22", "t23", "t24", - "t26"]}, - {"a.b.b", ["t3", "t5", "t6", "t7", "t11", "t12", "t14", - "t18", "t21", "t22", "t23", "t24", "t26"]}, - {"", ["t5", "t6", "t17", "t24"]}, - {"b.c.c", ["t5", "t6", "t18", "t21", "t22", "t23", - "t24", "t26"]}, - {"a.a.a.a.a", ["t5", "t6", "t11", "t12", "t21", "t22", - "t23", "t24"]}, - {"vodka.gin", ["t5", "t6", "t8", "t21", "t22", "t23", - "t24"]}, - {"vodka.martini", ["t5", "t6", "t8", "t19", "t21", "t22", "t23", - "t24"]}, - {"b.b.c", ["t5", "t6", "t10", "t13", "t18", "t21", - "t22", "t23", "t24", "t26"]}, - {"nothing.here.at.all", ["t5", "t6", "t21", "t22", "t23", "t24"]}, - {"oneword", ["t5", "t6", "t21", "t22", "t23", "t24", - "t25"]}, - {"args-test", ["t5", "t6", "t21", "t22", "t23", "t24", - "t25", "t27"]}]), - %% remove some bindings - RemovedBindings = [lists:nth(1, Bindings), lists:nth(5, Bindings), - lists:nth(11, Bindings), lists:nth(19, Bindings), - lists:nth(21, Bindings), lists:nth(28, Bindings)], - exchange_op_callback(X, remove_bindings, [RemovedBindings]), - RemainingBindings = ordsets:to_list( - ordsets:subtract(ordsets:from_list(Bindings), - ordsets:from_list(RemovedBindings))), - - %% test some matches - test_topic_expect_match( - X, - [{"a.b.c", ["t2", "t6", "t10", "t12", "t18", "t20", "t22", - "t23", "t24", "t26"]}, - {"a.b", ["t3", "t6", "t7", "t8", "t9", "t12", "t15", - "t22", "t23", "t24", "t26"]}, - {"a.b.b", ["t3", "t6", "t7", "t12", "t14", "t18", "t22", - "t23", "t24", "t26"]}, - {"", ["t6", "t17", "t24"]}, - {"b.c.c", ["t6", "t18", "t22", "t23", "t24", "t26"]}, - {"a.a.a.a.a", ["t6", "t12", "t22", "t23", "t24"]}, - {"vodka.gin", ["t6", "t8", "t22", "t23", "t24"]}, - {"vodka.martini", ["t6", "t8", "t22", "t23", "t24"]}, - {"b.b.c", ["t6", "t10", "t13", "t18", "t22", "t23", - "t24", "t26"]}, - {"nothing.here.at.all", ["t6", "t22", "t23", "t24"]}, - {"oneword", ["t6", "t22", "t23", "t24", "t25"]}, - {"args-test", ["t6", "t22", "t23", "t24", "t25", "t27"]}]), - - %% remove the entire exchange - exchange_op_callback(X, delete, [RemainingBindings]), - %% none should match now - test_topic_expect_match(X, [{"a.b.c", []}, {"b.b.c", []}, {"", []}]), - passed. - -exchange_op_callback(X, Fun, Args) -> - rabbit_misc:execute_mnesia_transaction( - fun () -> rabbit_exchange:callback(X, Fun, transaction, [X] ++ Args) end), - rabbit_exchange:callback(X, Fun, none, [X] ++ Args). - -test_topic_expect_match(X, List) -> - lists:foreach( - fun ({Key, Expected}) -> - BinKey = list_to_binary(Key), - Message = rabbit_basic:message(X#exchange.name, BinKey, - #'P_basic'{}, <<>>), - Res = rabbit_exchange_type_topic:route( - X, #delivery{mandatory = false, - sender = self(), - message = Message}), - ExpectedRes = lists:map( - fun (Q) -> #resource{virtual_host = <<"/">>, - kind = queue, - name = list_to_binary(Q)} - end, Expected), - true = (lists:usort(ExpectedRes) =:= lists:usort(Res)) - end, List). - %% --------------------------------------------------------------------------- %% Unordered tests (originally from rabbit_tests.erl). %% --------------------------------------------------------------------------- @@ -1046,50 +616,6 @@ configurable_server_properties1(_Config) -> application:set_env(rabbit, server_properties, ServerProperties), passed. -set_disk_free_limit_command(Config) -> - passed = rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, set_disk_free_limit_command1, [Config]). - -set_disk_free_limit_command1(_Config) -> - rabbit_disk_monitor:set_disk_free_limit("2000kiB"), - 2048000 = rabbit_disk_monitor:get_disk_free_limit(), - - %% Use an integer - rabbit_disk_monitor:set_disk_free_limit({mem_relative, 1}), - disk_free_limit_to_total_memory_ratio_is(1), - - %% Use a float - rabbit_disk_monitor:set_disk_free_limit({mem_relative, 1.5}), - disk_free_limit_to_total_memory_ratio_is(1.5), - - rabbit_disk_monitor:set_disk_free_limit("50MB"), - passed. - -disk_free_limit_to_total_memory_ratio_is(MemRatio) -> - ExpectedLimit = MemRatio * vm_memory_monitor:get_total_memory(), - % Total memory is unstable, so checking order - true = ExpectedLimit/rabbit_disk_monitor:get_disk_free_limit() < 1.2, - true = ExpectedLimit/rabbit_disk_monitor:get_disk_free_limit() > 0.98. - -set_vm_memory_high_watermark_command(Config) -> - rabbit_ct_broker_helpers:rpc(Config, 0, - ?MODULE, set_vm_memory_high_watermark_command1, [Config]). - -set_vm_memory_high_watermark_command1(_Config) -> - MemLimitRatio = 1.0, - MemTotal = vm_memory_monitor:get_total_memory(), - - vm_memory_monitor:set_vm_memory_high_watermark(MemLimitRatio), - MemLimit = vm_memory_monitor:get_memory_limit(), - case MemLimit of - MemTotal -> ok; - _ -> MemTotalToMemLimitRatio = MemLimit * 100.0 / MemTotal / 100, - ct:fail( - "Expected memory high watermark to be ~p (~s), but it was ~p (~.1f)", - [MemTotal, MemLimitRatio, MemLimit, MemTotalToMemLimitRatio] - ) - end. - max_length_bytes_drop_head(Config) -> max_length_bytes_drop_head(Config, [{<<"x-overflow">>, longstr, <<"drop-head">>}]). diff --git a/test/unit_pg_local_SUITE.erl b/test/unit_pg_local_SUITE.erl index 852abc57eb..a5e9f065f6 100644 --- a/test/unit_pg_local_SUITE.erl +++ b/test/unit_pg_local_SUITE.erl @@ -18,8 +18,6 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). --include_lib("rabbit_common/include/rabbit.hrl"). --include_lib("rabbit_common/include/rabbit_framing.hrl"). -compile(export_all). diff --git a/test/unit_priority_queue_SUITE.erl b/test/unit_priority_queue_SUITE.erl new file mode 100644 index 0000000000..14533731f4 --- /dev/null +++ b/test/unit_priority_queue_SUITE.erl @@ -0,0 +1,193 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% https://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2011-2020 VMware, Inc. or its affiliates. All rights reserved. +%% + +-module(unit_priority_queue_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +-compile(export_all). + +all() -> + [ + {group, sequential_tests} + ]. + +groups() -> + [ + {sequential_tests, [], [ + priority_queue + ]} + ]. + + +priority_queue(_Config) -> + + false = priority_queue:is_queue(not_a_queue), + + %% empty Q + Q = priority_queue:new(), + {true, true, 0, [], []} = test_priority_queue(Q), + + %% 1-4 element no-priority Q + true = lists:all(fun (X) -> X =:= passed end, + lists:map(fun test_simple_n_element_queue/1, + lists:seq(1, 4))), + + %% 1-element priority Q + Q1 = priority_queue:in(foo, 1, priority_queue:new()), + {true, false, 1, [{1, foo}], [foo]} = + test_priority_queue(Q1), + + %% 2-element same-priority Q + Q2 = priority_queue:in(bar, 1, Q1), + {true, false, 2, [{1, foo}, {1, bar}], [foo, bar]} = + test_priority_queue(Q2), + + %% 2-element different-priority Q + Q3 = priority_queue:in(bar, 2, Q1), + {true, false, 2, [{2, bar}, {1, foo}], [bar, foo]} = + test_priority_queue(Q3), + + %% 1-element negative priority Q + Q4 = priority_queue:in(foo, -1, priority_queue:new()), + {true, false, 1, [{-1, foo}], [foo]} = test_priority_queue(Q4), + + %% merge 2 * 1-element no-priority Qs + Q5 = priority_queue:join(priority_queue:in(foo, Q), + priority_queue:in(bar, Q)), + {true, false, 2, [{0, foo}, {0, bar}], [foo, bar]} = + test_priority_queue(Q5), + + %% merge 1-element no-priority Q with 1-element priority Q + Q6 = priority_queue:join(priority_queue:in(foo, Q), + priority_queue:in(bar, 1, Q)), + {true, false, 2, [{1, bar}, {0, foo}], [bar, foo]} = + test_priority_queue(Q6), + + %% merge 1-element priority Q with 1-element no-priority Q + Q7 = priority_queue:join(priority_queue:in(foo, 1, Q), + priority_queue:in(bar, Q)), + {true, false, 2, [{1, foo}, {0, bar}], [foo, bar]} = + test_priority_queue(Q7), + + %% merge 2 * 1-element same-priority Qs + Q8 = priority_queue:join(priority_queue:in(foo, 1, Q), + priority_queue:in(bar, 1, Q)), + {true, false, 2, [{1, foo}, {1, bar}], [foo, bar]} = + test_priority_queue(Q8), + + %% merge 2 * 1-element different-priority Qs + Q9 = priority_queue:join(priority_queue:in(foo, 1, Q), + priority_queue:in(bar, 2, Q)), + {true, false, 2, [{2, bar}, {1, foo}], [bar, foo]} = + test_priority_queue(Q9), + + %% merge 2 * 1-element different-priority Qs (other way around) + Q10 = priority_queue:join(priority_queue:in(bar, 2, Q), + priority_queue:in(foo, 1, Q)), + {true, false, 2, [{2, bar}, {1, foo}], [bar, foo]} = + test_priority_queue(Q10), + + %% merge 2 * 2-element multi-different-priority Qs + Q11 = priority_queue:join(Q6, Q5), + {true, false, 4, [{1, bar}, {0, foo}, {0, foo}, {0, bar}], + [bar, foo, foo, bar]} = test_priority_queue(Q11), + + %% and the other way around + Q12 = priority_queue:join(Q5, Q6), + {true, false, 4, [{1, bar}, {0, foo}, {0, bar}, {0, foo}], + [bar, foo, bar, foo]} = test_priority_queue(Q12), + + %% merge with negative priorities + Q13 = priority_queue:join(Q4, Q5), + {true, false, 3, [{0, foo}, {0, bar}, {-1, foo}], [foo, bar, foo]} = + test_priority_queue(Q13), + + %% and the other way around + Q14 = priority_queue:join(Q5, Q4), + {true, false, 3, [{0, foo}, {0, bar}, {-1, foo}], [foo, bar, foo]} = + test_priority_queue(Q14), + + %% joins with empty queues: + Q1 = priority_queue:join(Q, Q1), + Q1 = priority_queue:join(Q1, Q), + + %% insert with priority into non-empty zero-priority queue + Q15 = priority_queue:in(baz, 1, Q5), + {true, false, 3, [{1, baz}, {0, foo}, {0, bar}], [baz, foo, bar]} = + test_priority_queue(Q15), + + %% 1-element infinity priority Q + Q16 = priority_queue:in(foo, infinity, Q), + {true, false, 1, [{infinity, foo}], [foo]} = test_priority_queue(Q16), + + %% add infinity to 0-priority Q + Q17 = priority_queue:in(foo, infinity, priority_queue:in(bar, Q)), + {true, false, 2, [{infinity, foo}, {0, bar}], [foo, bar]} = + test_priority_queue(Q17), + + %% and the other way around + Q18 = priority_queue:in(bar, priority_queue:in(foo, infinity, Q)), + {true, false, 2, [{infinity, foo}, {0, bar}], [foo, bar]} = + test_priority_queue(Q18), + + %% add infinity to mixed-priority Q + Q19 = priority_queue:in(qux, infinity, Q3), + {true, false, 3, [{infinity, qux}, {2, bar}, {1, foo}], [qux, bar, foo]} = + test_priority_queue(Q19), + + %% merge the above with a negative priority Q + Q20 = priority_queue:join(Q19, Q4), + {true, false, 4, [{infinity, qux}, {2, bar}, {1, foo}, {-1, foo}], + [qux, bar, foo, foo]} = test_priority_queue(Q20), + + %% merge two infinity priority queues + Q21 = priority_queue:join(priority_queue:in(foo, infinity, Q), + priority_queue:in(bar, infinity, Q)), + {true, false, 2, [{infinity, foo}, {infinity, bar}], [foo, bar]} = + test_priority_queue(Q21), + + %% merge two mixed priority with infinity queues + Q22 = priority_queue:join(Q18, Q20), + {true, false, 6, [{infinity, foo}, {infinity, qux}, {2, bar}, {1, foo}, + {0, bar}, {-1, foo}], [foo, qux, bar, foo, bar, foo]} = + test_priority_queue(Q22), + + passed. + +priority_queue_in_all(Q, L) -> + lists:foldl(fun (X, Acc) -> priority_queue:in(X, Acc) end, Q, L). + +priority_queue_out_all(Q) -> + case priority_queue:out(Q) of + {empty, _} -> []; + {{value, V}, Q1} -> [V | priority_queue_out_all(Q1)] + end. + +test_priority_queue(Q) -> + {priority_queue:is_queue(Q), + priority_queue:is_empty(Q), + priority_queue:len(Q), + priority_queue:to_list(Q), + priority_queue_out_all(Q)}. + +test_simple_n_element_queue(N) -> + Items = lists:seq(1, N), + Q = priority_queue_in_all(priority_queue:new(), Items), + ToListRes = [{0, X} || X <- Items], + {true, false, N, ToListRes, Items} = test_priority_queue(Q), + passed. diff --git a/test/unit_stats_and_metrics_SUITE.erl b/test/unit_stats_and_metrics_SUITE.erl index 67a26f700b..4b2ead9280 100644 --- a/test/unit_stats_and_metrics_SUITE.erl +++ b/test/unit_stats_and_metrics_SUITE.erl @@ -40,7 +40,7 @@ groups() -> ]. %% ------------------------------------------------------------------- -%% Testsuite setup/teardown. +%% Testsuite setup/teardown %% ------------------------------------------------------------------- init_per_suite(Config) -> @@ -53,7 +53,7 @@ end_per_suite(Config) -> init_per_group(Group, Config) -> Config1 = rabbit_ct_helpers:set_config(Config, [ {rmq_nodename_suffix, Group}, - {rmq_nodes_count, 2} + {rmq_nodes_count, 1} ]), rabbit_ct_helpers:run_steps(Config1, rabbit_ct_broker_helpers:setup_steps() ++ diff --git a/test/unit_vm_memory_monitor_SUITE.erl b/test/unit_vm_memory_monitor_SUITE.erl index 608d89ae6c..d95d4528f4 100644 --- a/test/unit_vm_memory_monitor_SUITE.erl +++ b/test/unit_vm_memory_monitor_SUITE.erl @@ -29,10 +29,49 @@ all() -> groups() -> [ {sequential_tests, [], [ - parse_line_linux + parse_line_linux, + set_vm_memory_high_watermark_command ]} ]. + +%% ------------------------------------------------------------------- +%% Testsuite setup/teardown +%% ------------------------------------------------------------------- + +init_per_suite(Config) -> + rabbit_ct_helpers:log_environment(), + rabbit_ct_helpers:run_setup_steps(Config). + +end_per_suite(Config) -> + rabbit_ct_helpers:run_teardown_steps(Config). + +init_per_group(Group, Config) -> + Config1 = rabbit_ct_helpers:set_config(Config, [ + {rmq_nodename_suffix, Group}, + {rmq_nodes_count, 1} + ]), + rabbit_ct_helpers:run_steps(Config1, + rabbit_ct_broker_helpers:setup_steps() ++ + rabbit_ct_client_helpers:setup_steps()). + +end_per_group(_Group, Config) -> + rabbit_ct_helpers:run_steps(Config, + rabbit_ct_client_helpers:teardown_steps() ++ + rabbit_ct_broker_helpers:teardown_steps()). + +init_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_started(Config, Testcase). + +end_per_testcase(Testcase, Config) -> + rabbit_ct_helpers:testcase_finished(Config, Testcase). + + +%% ------------------------------------------------------------------- +%% Test cases +%% ------------------------------------------------------------------- + + parse_line_linux(_Config) -> lists:foreach(fun ({S, {K, V}}) -> {K, V} = vm_memory_monitor:parse_line_linux(S) @@ -44,3 +83,22 @@ parse_line_linux(_Config) -> {"MemTotal 502968 kB", {'MemTotal', 515039232}}, {"MemTotal 50296866 ", {'MemTotal', 50296866}}]), ok. + +set_vm_memory_high_watermark_command(Config) -> + rabbit_ct_broker_helpers:rpc(Config, 0, + ?MODULE, set_vm_memory_high_watermark_command1, [Config]). + +set_vm_memory_high_watermark_command1(_Config) -> + MemLimitRatio = 1.0, + MemTotal = vm_memory_monitor:get_total_memory(), + + vm_memory_monitor:set_vm_memory_high_watermark(MemLimitRatio), + MemLimit = vm_memory_monitor:get_memory_limit(), + case MemLimit of + MemTotal -> ok; + _ -> MemTotalToMemLimitRatio = MemLimit * 100.0 / MemTotal / 100, + ct:fail( + "Expected memory high watermark to be ~p (~s), but it was ~p (~.1f)", + [MemTotal, MemLimitRatio, MemLimit, MemTotalToMemLimitRatio] + ) + end. |
