aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/statistics_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/statistics_SUITE.erl')
-rw-r--r--erts/emulator/test/statistics_SUITE.erl431
1 files changed, 195 insertions, 236 deletions
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index df96b018a1..7d5b07f21f 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.erl
@@ -22,10 +22,7 @@
%% Tests the statistics/1 bif.
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- init_per_testcase/2,
- end_per_testcase/2,
+-export([all/0, suite/0, groups/0,
wall_clock_zero_diff/1, wall_clock_update/1,
runtime_zero_diff/1,
runtime_update/1, runtime_diff/1,
@@ -40,16 +37,9 @@
-include_lib("common_test/include/ct.hrl").
-init_per_testcase(_, Config) ->
- ?line Dog = test_server:timetrap(test_server:seconds(300)),
- [{watchdog, Dog}|Config].
-
-end_per_testcase(_, Config) ->
- Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- ok.
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap, {minutes, 4}}].
all() ->
[{group, wall_clock}, {group, runtime}, reductions,
@@ -65,61 +55,42 @@ groups() ->
[runtime_zero_diff, runtime_update, runtime_diff]},
{run_queue, [], [run_queue_one]}].
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-
%%% Testing statistics(wall_clock).
-
-
-wall_clock_zero_diff(doc) ->
- "Tests that the 'Wall clock since last call' element of the result "
- "is zero when statistics(runtime) is called twice in succession.";
+%% Tests that the 'Wall clock since last call' element of the result
+%% is zero when statistics(runtime) is called twice in succession.
wall_clock_zero_diff(Config) when is_list(Config) ->
wall_clock_zero_diff1(16).
wall_clock_zero_diff1(N) when N > 0 ->
- ?line {Time, _} = statistics(wall_clock),
- ?line case statistics(wall_clock) of
- {Time, 0} -> ok;
- _ -> wall_clock_zero_diff1(N-1)
+ {Time, _} = statistics(wall_clock),
+ case statistics(wall_clock) of
+ {Time, 0} -> ok;
+ _ -> wall_clock_zero_diff1(N-1)
end;
wall_clock_zero_diff1(0) ->
- ?line test_server:fail("Difference never zero.").
+ ct:fail("Difference never zero.").
-wall_clock_update(doc) ->
- "Test that the time differences returned by two calls to "
- "statistics(wall_clock) are compatible, and are within a small number "
- "of ms of the amount of real time we waited for.";
+%% Test that the time differences returned by two calls to
+%% statistics(wall_clock) are compatible, and are within a small number
+%% of ms of the amount of real time we waited for.
wall_clock_update(Config) when is_list(Config) ->
wall_clock_update1(6).
wall_clock_update1(N) when N > 0 ->
- ?line {T1_wc_time, _} = statistics(wall_clock),
- ?line receive after 1000 -> ok end,
- ?line {T2_wc_time, Wc_Diff} = statistics(wall_clock),
-
- ?line Wc_Diff = T2_wc_time - T1_wc_time,
- ?line test_server:format("Wall clock diff = ~p; should be = 1000..1040~n",
- [Wc_Diff]),
- case ?t:is_debug() of
- false ->
- ?line true = Wc_Diff =< 1040;
- true ->
- ?line true = Wc_Diff =< 2000 %Be more tolerant in debug-compiled emulator.
+ {T1_wc_time, _} = statistics(wall_clock),
+ receive after 1000 -> ok end,
+ {T2_wc_time, Wc_Diff} = statistics(wall_clock),
+
+ Wc_Diff = T2_wc_time - T1_wc_time,
+ io:format("Wall clock diff = ~p; should be = 1000..1040~n", [Wc_Diff]),
+ case test_server:is_debug() of
+ false ->
+ true = Wc_Diff =< 1040;
+ true ->
+ true = Wc_Diff =< 2000 %Be more tolerant in debug-compiled emulator.
end,
- ?line true = Wc_Diff >= 1000,
+ true = Wc_Diff >= 1000,
wall_clock_update1(N-1);
wall_clock_update1(0) ->
ok.
@@ -128,64 +99,60 @@ wall_clock_update1(0) ->
%%% Test statistics(runtime).
-runtime_zero_diff(doc) ->
- "Tests that the difference between the times returned from two consectuitive "
- "calls to statistics(runtime) is zero.";
+%% Tests that the difference between the times returned from two consectuitive
+%% calls to statistics(runtime) is zero.
runtime_zero_diff(Config) when is_list(Config) ->
- ?line runtime_zero_diff1(16).
+ runtime_zero_diff1(16).
runtime_zero_diff1(N) when N > 0 ->
- ?line {T1, _} = statistics(runtime),
- ?line case statistics(runtime) of
- {T1, 0} -> ok;
- _ -> runtime_zero_diff1(N-1)
- end;
+ {T1, _} = statistics(runtime),
+ case statistics(runtime) of
+ {T1, 0} -> ok;
+ _ -> runtime_zero_diff1(N-1)
+ end;
runtime_zero_diff1(0) ->
- ?line test_server:fail("statistics(runtime) never returned zero difference").
+ ct:fail("statistics(runtime) never returned zero difference").
-runtime_update(doc) ->
- "Test that the statistics(runtime) returns a substanstially "
- "updated difference after running a process that takes all CPU "
- " power of the Erlang process for a second.";
+%% Test that the statistics(runtime) returns a substanstially
+%% updated difference after running a process that takes all CPU
+%% power of the Erlang process for a second.
runtime_update(Config) when is_list(Config) ->
- case ?t:is_cover() of
- false ->
- ?line process_flag(priority, high),
- do_runtime_update(10);
- true ->
- {skip,"Cover-compiled"}
+ case test_server:is_cover() of
+ false ->
+ process_flag(priority, high),
+ do_runtime_update(10);
+ true ->
+ {skip,"Cover-compiled"}
end.
do_runtime_update(0) ->
{comment,"Never close enough"};
do_runtime_update(N) ->
- ?line {T1,Diff0} = statistics(runtime),
- ?line spawn_link(fun cpu_heavy/0),
+ {T1,Diff0} = statistics(runtime),
+ spawn_link(fun cpu_heavy/0),
receive after 1000 -> ok end,
- ?line {T2,Diff} = statistics(runtime),
- ?line true = is_integer(T1+T2+Diff0+Diff),
- ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, T2-T1 = ~p",
- [T1,T2,Diff,T2-T1]),
- ?line if
- T2 - T1 =:= Diff, 900 =< Diff, Diff =< 1500 -> ok;
- true -> do_runtime_update(N-1)
- end.
-
+ {T2,Diff} = statistics(runtime),
+ true = is_integer(T1+T2+Diff0+Diff),
+ io:format("T1 = ~p, T2 = ~p, Diff = ~p, T2-T1 = ~p", [T1,T2,Diff,T2-T1]),
+ if
+ T2 - T1 =:= Diff, 900 =< Diff, Diff =< 1500 -> ok;
+ true -> do_runtime_update(N-1)
+ end.
+
cpu_heavy() ->
cpu_heavy().
-runtime_diff(doc) ->
- "Test that the difference between two consecutive absolute runtimes is "
- "equal to the last relative runtime. The loop runs a lot of times since "
- "the bug which this test case tests for showed up only rarely.";
+%% Test that the difference between two consecutive absolute runtimes is
+%% equal to the last relative runtime. The loop runs a lot of times since
+%% the bug which this test case tests for showed up only rarely.
runtime_diff(Config) when is_list(Config) ->
runtime_diff1(1000).
runtime_diff1(N) when N > 0 ->
- ?line {T1_wc_time, _} = statistics(runtime),
- ?line do_much(),
- ?line {T2_wc_time, Wc_Diff} = statistics(runtime),
- ?line Wc_Diff = T2_wc_time - T1_wc_time,
+ {T1_wc_time, _} = statistics(runtime),
+ do_much(),
+ {T2_wc_time, Wc_Diff} = statistics(runtime),
+ Wc_Diff = T2_wc_time - T1_wc_time,
runtime_diff1(N-1);
runtime_diff1(0) ->
ok.
@@ -203,10 +170,9 @@ do_much(N) ->
do_much(N-1).
-reductions(doc) ->
- "Test that statistics(reductions) is callable, and that "
- "Total_Reductions and Reductions_Since_Last_Call make sense. "
- "(This to fail on pre-R3A version of JAM.";
+%% Test that statistics(reductions) is callable, and that
+%% Total_Reductions and Reductions_Since_Last_Call make sense.
+%% This to fail on pre-R3A version of JAM.
reductions(Config) when is_list(Config) ->
{Reductions, _} = statistics(reductions),
@@ -219,13 +185,13 @@ reductions(Config) when is_list(Config) ->
reductions(300, Reductions, Mask).
reductions(N, Previous, Mask) when N > 0 ->
- ?line {Reductions, Diff} = statistics(reductions),
- ?line build_some_garbage(),
- ?line if Reductions > 0 -> ok end,
- ?line if Diff >= 0 -> ok end,
+ {Reductions, Diff} = statistics(reductions),
+ build_some_garbage(),
+ if Reductions > 0 -> ok end,
+ if Diff >= 0 -> ok end,
io:format("Previous = ~p, Reductions = ~p, Diff = ~p, DiffShouldBe = ~p",
- [Previous, Reductions, Diff, (Reductions-Previous) band Mask]),
- ?line if Reductions == ((Previous+Diff) band Mask) -> reductions(N-1, Reductions, Mask) end;
+ [Previous, Reductions, Diff, (Reductions-Previous) band Mask]),
+ if Reductions == ((Previous+Diff) band Mask) -> reductions(N-1, Reductions, Mask) end;
reductions(0, _, _) ->
ok.
@@ -234,126 +200,123 @@ build_some_garbage() ->
%% a garbage collection in the scheduler.
processes().
-reductions_big(doc) ->
- "Test that the number of reductions can be returned as a big number.";
+%% Test that the number of reductions can be returned as a big number.
reductions_big(Config) when is_list(Config) ->
- ?line reductions_big_loop(),
+ reductions_big_loop(),
ok.
reductions_big_loop() ->
erlang:yield(),
case statistics(reductions) of
- {Red, Diff} when Red >= 16#7ffFFFF ->
- ok = io:format("Reductions = ~w, Diff = ~w", [Red, Diff]);
- _ ->
- reductions_big_loop()
+ {Red, Diff} when Red >= 16#7ffFFFF ->
+ ok = io:format("Reductions = ~w, Diff = ~w", [Red, Diff]);
+ _ ->
+ reductions_big_loop()
end.
%%% Tests of statistics(run_queue).
-run_queue_one(doc) ->
- "Tests that statistics(run_queue) returns 1 if we start a "
- "CPU-bound process.";
+%% Tests that statistics(run_queue) returns 1 if we start a
+%% CPU-bound process.
run_queue_one(Config) when is_list(Config) ->
- ?line MS = erlang:system_flag(multi_scheduling, block),
- ?line run_queue_one_test(Config),
- ?line erlang:system_flag(multi_scheduling, unblock),
+ MS = erlang:system_flag(multi_scheduling, block),
+ run_queue_one_test(Config),
+ erlang:system_flag(multi_scheduling, unblock),
case MS of
- blocked ->
- {comment,
- "Multi-scheduling blocked during test. This test-case "
- "was not written to work with multiple schedulers."};
- _ -> ok
+ blocked ->
+ {comment,
+ "Multi-scheduling blocked during test. This test-case "
+ "was not written to work with multiple schedulers."};
+ _ -> ok
end.
-
+
run_queue_one_test(Config) when is_list(Config) ->
- ?line _Hog = spawn_link(?MODULE, hog, [self()]),
- ?line receive
- hog_started -> ok
- end,
- ?line receive after 100 -> ok end, % Give hog a head start.
- ?line case statistics(run_queue) of
- N when N >= 1 -> ok;
- Other -> ?line ?t:fail({unexpected,Other})
- end,
+ _Hog = spawn_link(?MODULE, hog, [self()]),
+ receive
+ hog_started -> ok
+ end,
+ receive after 100 -> ok end, % Give hog a head start.
+ case statistics(run_queue) of
+ N when N >= 1 -> ok;
+ Other -> ct:fail({unexpected,Other})
+ end,
ok.
%% CPU-bound process, going at low priority. It will always be ready
%% to run.
hog(Pid) ->
- ?line process_flag(priority, low),
- ?line Pid ! hog_started,
- ?line Mon = erlang:monitor(process, Pid),
- ?line hog_iter(0, Mon).
+ process_flag(priority, low),
+ Pid ! hog_started,
+ Mon = erlang:monitor(process, Pid),
+ hog_iter(0, Mon).
hog_iter(N, Mon) when N > 0 ->
receive
- {'DOWN', Mon, _, _, _} -> ok
+ {'DOWN', Mon, _, _, _} -> ok
after 0 ->
- ?line hog_iter(N-1, Mon)
+ hog_iter(N-1, Mon)
end;
hog_iter(0, Mon) ->
- ?line hog_iter(10000, Mon).
+ hog_iter(10000, Mon).
%%% Tests of statistics(scheduler_wall_time).
-scheduler_wall_time(doc) ->
- "Tests that statistics(scheduler_wall_time) works as intended";
+%% Tests that statistics(scheduler_wall_time) works as intended
scheduler_wall_time(Config) when is_list(Config) ->
%% Should return undefined if system_flag is not turned on yet
undefined = statistics(scheduler_wall_time),
%% Turn on statistics
false = erlang:system_flag(scheduler_wall_time, true),
try
- Schedulers = erlang:system_info(schedulers_online),
- %% Let testserver and everyone else finish their work
- timer:sleep(1500),
- %% Empty load
- EmptyLoad = get_load(),
- {false, _} = {lists:any(fun(Load) -> Load > 50 end, EmptyLoad),EmptyLoad},
- MeMySelfAndI = self(),
- StartHog = fun() ->
- Pid = spawn(?MODULE, hog, [self()]),
- receive hog_started -> MeMySelfAndI ! go end,
- Pid
- end,
- P1 = StartHog(),
- %% Max on one, the other schedulers empty (hopefully)
- %% Be generous the process can jump between schedulers
- %% which is ok and we don't want the test to fail for wrong reasons
- _L1 = [S1Load|EmptyScheds1] = get_load(),
- {true,_} = {S1Load > 50,S1Load},
- {false,_} = {lists:any(fun(Load) -> Load > 50 end, EmptyScheds1),EmptyScheds1},
- {true,_} = {lists:sum(EmptyScheds1) < 60,EmptyScheds1},
-
- %% 50% load
- HalfHogs = [StartHog() || _ <- lists:seq(1, (Schedulers-1) div 2)],
- HalfLoad = lists:sum(get_load()) div Schedulers,
- if Schedulers < 2, HalfLoad > 80 -> ok; %% Ok only one scheduler online and one hog
- %% We want roughly 50% load
- HalfLoad > 40, HalfLoad < 60 -> ok;
- true -> exit({halfload, HalfLoad})
- end,
-
- %% 100% load
- LastHogs = [StartHog() || _ <- lists:seq(1, Schedulers div 2)],
- FullScheds = get_load(),
- {false,_} = {lists:any(fun(Load) -> Load < 80 end, FullScheds),FullScheds},
- FullLoad = lists:sum(FullScheds) div Schedulers,
- if FullLoad > 90 -> ok;
- true -> exit({fullload, FullLoad})
- end,
-
- [exit(Pid, kill) || Pid <- [P1|HalfHogs++LastHogs]],
- AfterLoad = get_load(),
- {false,_} = {lists:any(fun(Load) -> Load > 25 end, AfterLoad),AfterLoad},
- true = erlang:system_flag(scheduler_wall_time, false)
+ Schedulers = erlang:system_info(schedulers_online),
+ %% Let testserver and everyone else finish their work
+ timer:sleep(1500),
+ %% Empty load
+ EmptyLoad = get_load(),
+ {false, _} = {lists:any(fun(Load) -> Load > 50 end, EmptyLoad),EmptyLoad},
+ MeMySelfAndI = self(),
+ StartHog = fun() ->
+ Pid = spawn(?MODULE, hog, [self()]),
+ receive hog_started -> MeMySelfAndI ! go end,
+ Pid
+ end,
+ P1 = StartHog(),
+ %% Max on one, the other schedulers empty (hopefully)
+ %% Be generous the process can jump between schedulers
+ %% which is ok and we don't want the test to fail for wrong reasons
+ _L1 = [S1Load|EmptyScheds1] = get_load(),
+ {true,_} = {S1Load > 50,S1Load},
+ {false,_} = {lists:any(fun(Load) -> Load > 50 end, EmptyScheds1),EmptyScheds1},
+ {true,_} = {lists:sum(EmptyScheds1) < 60,EmptyScheds1},
+
+ %% 50% load
+ HalfHogs = [StartHog() || _ <- lists:seq(1, (Schedulers-1) div 2)],
+ HalfLoad = lists:sum(get_load()) div Schedulers,
+ if Schedulers < 2, HalfLoad > 80 -> ok; %% Ok only one scheduler online and one hog
+ %% We want roughly 50% load
+ HalfLoad > 40, HalfLoad < 60 -> ok;
+ true -> exit({halfload, HalfLoad})
+ end,
+
+ %% 100% load
+ LastHogs = [StartHog() || _ <- lists:seq(1, Schedulers div 2)],
+ FullScheds = get_load(),
+ {false,_} = {lists:any(fun(Load) -> Load < 80 end, FullScheds),FullScheds},
+ FullLoad = lists:sum(FullScheds) div Schedulers,
+ if FullLoad > 90 -> ok;
+ true -> exit({fullload, FullLoad})
+ end,
+
+ [exit(Pid, kill) || Pid <- [P1|HalfHogs++LastHogs]],
+ AfterLoad = get_load(),
+ {false,_} = {lists:any(fun(Load) -> Load > 25 end, AfterLoad),AfterLoad},
+ true = erlang:system_flag(scheduler_wall_time, false)
after
- erlang:system_flag(scheduler_wall_time, false)
+ erlang:system_flag(scheduler_wall_time, false)
end.
get_load() ->
@@ -367,62 +330,59 @@ load_percentage([{Id, WN, TN}|Ss], [{Id, WP, TP}|Ps]) ->
load_percentage([], []) -> [].
-garbage_collection(doc) ->
- "Tests that statistics(garbage_collection) is callable. "
- "It is not clear how to test anything more.";
+%% Tests that statistics(garbage_collection) is callable.
+%% It is not clear how to test anything more.
garbage_collection(Config) when is_list(Config) ->
- ?line Bin = list_to_binary(lists:duplicate(19999, 42)),
- ?line case statistics(garbage_collection) of
- {Gcs0,R,0} when is_integer(Gcs0), is_integer(R) ->
- ?line io:format("Reclaimed: ~p", [R]),
- ?line Gcs = garbage_collection_1(Gcs0, Bin),
- ?line io:format("Reclaimed: ~p",
- [element(2, statistics(garbage_collection))]),
- {comment,integer_to_list(Gcs-Gcs0)++" GCs"}
- end.
+ Bin = list_to_binary(lists:duplicate(19999, 42)),
+ case statistics(garbage_collection) of
+ {Gcs0,R,0} when is_integer(Gcs0), is_integer(R) ->
+ io:format("Reclaimed: ~p", [R]),
+ Gcs = garbage_collection_1(Gcs0, Bin),
+ io:format("Reclaimed: ~p",
+ [element(2, statistics(garbage_collection))]),
+ {comment,integer_to_list(Gcs-Gcs0)++" GCs"}
+ end.
garbage_collection_1(Gcs0, Bin) ->
case statistics(garbage_collection) of
- {Gcs,Reclaimed,0} when Gcs >= Gcs0 ->
- if
- Reclaimed > 16#7ffffff ->
- Gcs;
- true ->
- _ = binary_to_list(Bin),
- erlang:garbage_collect(),
- garbage_collection_1(Gcs, Bin)
- end
+ {Gcs,Reclaimed,0} when Gcs >= Gcs0 ->
+ if
+ Reclaimed > 16#7ffffff ->
+ Gcs;
+ true ->
+ _ = binary_to_list(Bin),
+ erlang:garbage_collect(),
+ garbage_collection_1(Gcs, Bin)
+ end
end.
-io(doc) ->
- "Tests that statistics(io) is callable. "
- "This could be improved to test something more.";
+%% Tests that statistics(io) is callable.
+%% This could be improved to test something more.
io(Config) when is_list(Config) ->
- ?line case statistics(io) of
- {{input,In},{output,Out}} when is_integer(In), is_integer(Out) -> ok
- end.
+ case statistics(io) of
+ {{input,In},{output,Out}} when is_integer(In), is_integer(Out) -> ok
+ end.
-badarg(doc) ->
- "Tests that some illegal arguments to statistics fails.";
+%% Tests that some illegal arguments to statistics fails.
badarg(Config) when is_list(Config) ->
- ?line case catch statistics(1) of
- {'EXIT', {badarg, _}} -> ok
- end,
- ?line case catch statistics(bad_atom) of
- {'EXIT', {badarg, _}} -> ok
- end.
+ case catch statistics(1) of
+ {'EXIT', {badarg, _}} -> ok
+ end,
+ case catch statistics(bad_atom) of
+ {'EXIT', {badarg, _}} -> ok
+ end.
tok_loop() ->
tok_loop().
run_queues_lengths_active_tasks(Config) ->
TokLoops = lists:map(fun (_) ->
- spawn_opt(fun () ->
- tok_loop()
- end,
- [link, {priority, low}])
- end,
- lists:seq(1,10)),
+ spawn_opt(fun () ->
+ tok_loop()
+ end,
+ [link, {priority, low}])
+ end,
+ lists:seq(1,10)),
TRQLs0 = statistics(total_run_queue_lengths),
TATs0 = statistics(total_active_tasks),
@@ -465,15 +425,14 @@ run_queues_lengths_active_tasks(Config) ->
erlang:system_flag(schedulers_online, SO),
lists:foreach(fun (P) ->
- unlink(P),
- exit(P, bang)
- end,
- TokLoops),
+ unlink(P),
+ exit(P, bang)
+ end,
+ TokLoops),
ok.
-msacc(doc) ->
- "Tests that statistics(microstate_statistics) works.";
+%% Tests that statistics(microstate_statistics) works.
msacc(Config) ->
%% Test if crypto nif is available
@@ -499,9 +458,9 @@ msacc(Config) ->
end, maps:to_list(msacc_sum_states()))
),
if Sum > 0 ->
- ok;
+ ok;
true ->
- ct:fail({no_states_triggered, MsaccStats})
+ ct:fail({no_states_triggered, MsaccStats})
end;
_ ->
@@ -517,7 +476,7 @@ msacc(Config) ->
%% aux will be zero if we do not have smp support
%% or no async threads
case erlang:system_info(smp_support) orelse
- erlang:system_info(thread_pool_size) > 0
+ erlang:system_info(thread_pool_size) > 0
of
false ->
ok;
@@ -581,4 +540,4 @@ msacc_sum_states() ->
NewValue = Value+maps:get(Key,Acc),
maps:update(Key, NewValue, Acc)
end, Cnt, Counters)
- end,InitialCounters,Stats).
+ end,InitialCounters,Stats).