Range, samples and avg tests. Fixed JSON output tags.

This commit is contained in:
Diana Corbacho 2016-09-28 11:12:19 +01:00 committed by kjnilsson
parent 619211f792
commit 8ba208f05d
2 changed files with 258 additions and 60 deletions

View File

@ -614,8 +614,8 @@ format_rate(Type, {TP}, {RP}, {SP}, {STP}, Length)
when Type =:= queue_stats_publish;
Type =:= queue_exchange_stats_publish ->
[
{publish_out, TP},
{publish_out_details, [{rate, RP},
{publish, TP},
{publish_details, [{rate, RP},
{samples, SP}] ++ average(SP, STP, Length)}
];
format_rate(Type, {TR, TU, TM}, {RR, RU, RM}, {SR, SU, SM}, {STR, STU, STM},

View File

@ -15,6 +15,7 @@
-include_lib("proper/include/proper.hrl").
-include("rabbit_mgmt_metrics.hrl").
-include("rabbit_mgmt.hrl").
-compile(export_all).
@ -25,14 +26,26 @@ all() ->
groups() ->
[
{parallel_tests, [], [
format_rate_no_range_test,
format_zero_rate_no_range_test,
format_incremental_rate_no_range_test,
format_incremental_zero_rate_no_range_test,
format_total_no_range_test,
format_incremental_total_no_range_test
]}
{parallel_tests, [parallel], [
format_rate_no_range_test,
format_zero_rate_no_range_test,
format_incremental_rate_no_range_test,
format_incremental_zero_rate_no_range_test,
format_total_no_range_test,
format_incremental_total_no_range_test,
format_rate_range_test,
format_zero_rate_range_test,
format_incremental_rate_range_test,
format_incremental_zero_rate_range_test,
format_total_range_test,
format_incremental_total_range_test,
format_samples_range_test,
format_incremental_samples_range_test,
format_avg_rate_range_test,
format_incremental_avg_rate_range_test,
format_avg_range_test,
format_incremental_avg_range_test
]}
].
%% -------------------------------------------------------------------
@ -122,30 +135,21 @@ format_rate_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_rate_no_range, []).
format_rate_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_rate_format_no_range/0, [], 100).
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, rate_check(fun(Rate) -> Rate > 0 end),
false, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
prop_rate_format_no_range() ->
prop_format_no_range(large, rate_check(fun(Rate) -> Rate > 0 end), false).
rate_check(RateCheck) ->
fun(Results, _, Table) ->
Check =
fun(Detail) ->
Rate = proplists:get_value(rate, proplists:get_value(Detail, Results), 0),
RateCheck(Rate)
end,
lists:all(Check, details(Table))
end.
prop_format_no_range(SampleSize, Check, Incremental) ->
prop_format(Id, SampleSize, Check, Incremental, RangeFun) ->
?FORALL(
{{Table, Data}, Interval}, {content_gen(SampleSize), interval_gen()},
begin
{Slide, Total} = create_slide(Data, Interval, Incremental),
Id = sample_one,
{Slide, Total, Samples} = create_slide(Data, Interval, Incremental),
Range = RangeFun(Interval),
ets:insert(Table, {{Id, 5}, Slide}),
Results = rabbit_mgmt_stats:format(no_range, Table, Id, 5000),
Check(Results, Total, Table)
Results = rabbit_mgmt_stats:format(Range, Table, Id, 5000),
Check(Results, Total, Samples, Table)
end).
%% Rates for 1 or no samples will always be 0.0 as there aren't
@ -154,20 +158,22 @@ format_zero_rate_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_zero_rate_no_range, []).
format_zero_rate_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_zero_rate_format_no_range/0, [], 100).
prop_zero_rate_format_no_range() ->
prop_format_no_range(small, rate_check(fun(Rate) -> Rate == 0.0 end), false).
Fun = fun() ->
prop_format(?FUNCTION_NAME, small, rate_check(fun(Rate) -> Rate == 0.0 end),
false, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Rates for 3 or more monotonically increasing incremental samples will always be > 0
format_incremental_rate_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_rate_no_range, []).
format_incremental_rate_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_incremental_rate_format_no_range/0, [], 100).
prop_incremental_rate_format_no_range() ->
prop_format_no_range(large, rate_check(fun(Rate) -> Rate > 0 end), true).
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, rate_check(fun(Rate) -> Rate > 0 end),
true, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Rates for 1 or no samples will always be 0.0 as there aren't
%% enough datapoints to calculate the instant rate
@ -175,39 +181,151 @@ format_incremental_zero_rate_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_zero_rate_no_range, []).
format_incremental_zero_rate_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_incremental_zero_rate_format_no_range/0, [], 100).
prop_incremental_zero_rate_format_no_range() ->
prop_format_no_range(small, rate_check(fun(Rate) -> Rate == 0.0 end), true).
Fun = fun() ->
prop_format(?FUNCTION_NAME, small, rate_check(fun(Rate) -> Rate == 0.0 end),
true, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Checking totals
format_total_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_total_no_range, []).
format_total_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_total_format_no_range/0, [], 100).
prop_total_format_no_range() ->
prop_format_no_range(large, fun check_total/3, false).
check_total(Results, Totals, Table) ->
Expected = lists:zip(?stats_per_table(Table), tuple_to_list(Totals)),
lists:all(fun({K, _} = E) ->
case is_average_time(K) of
false -> lists:member(E, Results);
true -> lists:keymember(K, 1, Results)
end
end, Expected).
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_total/4, false, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_incremental_total_no_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_total_no_range, []).
format_incremental_total_no_range() ->
rabbit_ct_proper_helpers:run_proper(fun prop_incremental_total_format_no_range/0, [], 100).
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_total/4, true, fun no_range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
prop_incremental_total_format_no_range() ->
prop_format_no_range(large, fun check_total/3, true).
%%---------------------
%% Requests using range
%%---------------------
format_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_rate_range, []).
format_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, rate_check(fun(Rate) -> Rate > 0 end),
false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Rates for 1 or no samples will always be 0.0 as there aren't
%% enough datapoints to calculate the instant rate
format_zero_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_zero_rate_range, []).
format_zero_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, small, rate_check(fun(Rate) -> Rate == 0.0 end),
false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Rates for 3 or more monotonically increasing incremental samples will always be > 0
format_incremental_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_rate_range, []).
format_incremental_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, rate_check(fun(Rate) -> Rate > 0 end),
true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Rates for 1 or no samples will always be 0.0 as there aren't
%% enough datapoints to calculate the instant rate
format_incremental_zero_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_zero_rate_range, []).
format_incremental_zero_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, small, rate_check(fun(Rate) -> Rate == 0.0 end),
true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% Checking totals
format_total_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_total_range, []).
format_total_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_total/4, false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_incremental_total_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_total_range, []).
format_incremental_total_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_total/4, true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_samples_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_samples_range, []).
format_samples_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_samples/4, false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_incremental_samples_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_samples_range, []).
format_incremental_samples_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_samples/4, true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_avg_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_avg_rate_range, []).
format_avg_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_avg_rate/4, false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_incremental_avg_rate_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_avg_rate_range, []).
format_incremental_avg_rate_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_avg_rate/4, true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_avg_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_avg_range, []).
format_avg_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_avg/4, false, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
format_incremental_avg_range_test(Config) ->
true == rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, format_incremental_avg_range, []).
format_incremental_avg_range() ->
Fun = fun() ->
prop_format(?FUNCTION_NAME, large, fun check_avg/4, true, fun range/1)
end,
rabbit_ct_proper_helpers:run_proper(Fun, [], 100).
%% -------------------------------------------------------------------
%% Helpers
%% -------------------------------------------------------------------
@ -223,7 +341,7 @@ create_slide(Data, Interval, Incremental) ->
%% Use the samples as increments for data generation, so we have always increasing counters
Slide = exometer_slide:new(60 * 1000, [{interval, Interval}, {incremental, Incremental}]),
Sleep = min_wait(Interval, Data),
lists:foldl(fun(E, {Acc, Total}) ->
lists:foldl(fun(E, {Acc, Total, Samples}) ->
timer:sleep(Sleep),
NewTotal = add(E, Total),
Sample = case Incremental of
@ -233,8 +351,8 @@ create_slide(Data, Interval, Incremental) ->
true ->
E
end,
{exometer_slide:add_element(Sample, Acc), NewTotal}
end, {Slide, undefined}, Data).
{exometer_slide:add_element(Sample, Acc), NewTotal, [NewTotal | Samples]}
end, {Slide, undefined, []}, Data).
min_wait(_, []) ->
0;
@ -256,3 +374,83 @@ is_average_time(Atom) ->
_ ->
true
end.
rate_check(RateCheck) ->
fun(Results, _, _, Table) ->
Check =
fun(Detail) ->
Rate = proplists:get_value(rate, proplists:get_value(Detail, Results), 0),
RateCheck(Rate)
end,
lists:all(Check, details(Table))
end.
check_total(Results, Totals, _Samples, Table) ->
Expected = lists:zip(?stats_per_table(Table), tuple_to_list(Totals)),
lists:all(fun({K, _} = E) ->
case is_average_time(K) of
false -> lists:member(E, Results);
true -> lists:keymember(K, 1, Results)
end
end, Expected).
check_samples(Results, _Totals, Samples, Table) ->
Details = details(Table),
%% Lookup list for the position of the key in the stats tuple
Pairs = lists:zip(Details, lists:seq(1, length(Details))),
%% Check that all samples in the results match one of the samples in the inputs
lists:all(fun(Detail) ->
RSamples = get_from_detail(samples, Detail, Results),
lists:all(fun(RS) ->
Value = proplists:get_value(sample, RS),
case Value of
0 ->
true;
_ ->
lists:keymember(Value,
proplists:get_value(Detail, Pairs),
Samples)
end
end, RSamples)
end, Details)
%% ensure that not all samples are 0
andalso lists:all(fun(Detail) ->
RSamples = get_from_detail(samples, Detail, Results),
lists:any(fun(RS) ->
0 =/= proplists:get_value(sample, RS)
end, RSamples)
end, Details).
check_avg_rate(Results, _Totals, _Samples, Table) ->
Details = details(Table),
lists:all(fun(Detail) ->
AvgRate = get_from_detail(avg_rate, Detail, Results),
Samples = get_from_detail(samples, Detail, Results),
S2 = proplists:get_value(sample, hd(Samples)),
T2 = proplists:get_value(timestamp, hd(Samples)),
S1 = proplists:get_value(sample, lists:last(Samples)),
T1 = proplists:get_value(timestamp, lists:last(Samples)),
AvgRate == ((S2 - S1) * 1000 / (T2 - T1))
end, Details).
check_avg(Results, _Totals, _Samples, Table) ->
Details = details(Table),
lists:all(fun(Detail) ->
Avg = get_from_detail(avg, Detail, Results),
Samples = get_from_detail(samples, Detail, Results),
Sum = lists:sum([proplists:get_value(sample, S) || S <- Samples]),
Avg == (Sum / length(Samples))
end, Details).
get_from_detail(Tag, Detail, Results) ->
proplists:get_value(Tag, proplists:get_value(Detail, Results), []).
range(Interval) ->
Now = exometer_slide:timestamp(),
#range{first = Now - 500, last = Now, incr = Interval}.
no_range(_Interval) ->
no_range.