185 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Erlang
		
	
	
	
			
		
		
	
	
			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.
 |