rabbitmq-server/deps/rabbit/test/unit_priority_queue_SUITE.erl

185 lines
6.4 KiB
Erlang

%% 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) 2011-2021 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.