diff options
Diffstat (limited to 'erts/emulator/test/system_info_SUITE.erl')
-rw-r--r-- | erts/emulator/test/system_info_SUITE.erl | 362 |
1 files changed, 186 insertions, 176 deletions
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index ceb4afb5cf..fdf4aab24d 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2017. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at %% -%% 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. +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. %% %% %CopyrightEnd% %% @@ -30,55 +31,26 @@ %-define(line_trace, 1). --include_lib("test_server/include/test_server.hrl"). - -%-compile(export_all). --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]). +-include_lib("common_test/include/ct.hrl"). --export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1, memory/1, - ets_limit/1]). +-export([all/0, suite/0]). --define(DEFAULT_TIMEOUT, ?t:minutes(2)). +-export([process_count/1, system_version/1, misc_smoke_tests/1, + heap_size/1, wordsize/1, memory/1, ets_limit/1, atom_limit/1, + atom_count/1]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 2}}]. all() -> [process_count, system_version, misc_smoke_tests, - heap_size, wordsize, memory, ets_limit]. - -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -init_per_testcase(_Case, Config) when is_list(Config) -> - Dog = ?t:timetrap(?DEFAULT_TIMEOUT), - [{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) when is_list(Config) -> - Dog = ?config(watchdog, Config), - ?t:timetrap_cancel(Dog), - ok. + heap_size, wordsize, memory, ets_limit, atom_limit, atom_count]. %%% %%% The test cases ------------------------------------------------------------- %%% -process_count(doc) -> []; -process_count(suite) -> []; process_count(Config) when is_list(Config) -> case catch erlang:system_info(modified_timing_level) of Level when is_integer(Level) -> @@ -91,37 +63,37 @@ process_count(Config) when is_list(Config) -> end. process_count_test() -> - ?line OldPrio = process_flag(priority, max), - ?line check_procs(10), - ?line check_procs(11234), - ?line check_procs(57), - ?line check_procs(1030), - ?line check_procs(687), - ?line check_procs(7923), - ?line check_procs(5302), - ?line check_procs(12456), - ?line check_procs(14), - ?line check_procs(1125), - ?line check_procs(236), - ?line check_procs(125), - ?line check_procs(2346), - ?line process_flag(priority, OldPrio), - ?line ok. + OldPrio = process_flag(priority, max), + check_procs(10), + check_procs(11234), + check_procs(57), + check_procs(1030), + check_procs(687), + check_procs(7923), + check_procs(5302), + check_procs(12456), + check_procs(14), + check_procs(1125), + check_procs(236), + check_procs(125), + check_procs(2346), + process_flag(priority, OldPrio), + ok. check_procs(N) -> - ?line CP = length(processes()), - ?line Procs = start_procs(N), - ?line check_pc(CP+N), - ?line stop_procs(Procs), - ?line check_pc(CP). + CP = length(processes()), + Procs = start_procs(N), + check_pc(CP+N), + stop_procs(Procs), + check_pc(CP). check_pc(E) -> - ?line P = length(processes()), - ?line SI = erlang:system_info(process_count), - ?line ?t:format("E=~p; P=~p; SI=~p~n", [E, P, SI]), - ?line E = P, - ?line P = SI. + P = length(processes()), + SI = erlang:system_info(process_count), + io:format("E=~p; P=~p; SI=~p~n", [E, P, SI]), + E = P, + P = SI. start_procs(N) -> lists:map(fun (_) -> @@ -142,54 +114,44 @@ stop_procs(PMs) -> end, PMs). -system_version(doc) -> []; -system_version(suite) -> []; system_version(Config) when is_list(Config) -> - ?line {comment, erlang:system_info(system_version)}. + {comment, erlang:system_info(system_version)}. -misc_smoke_tests(doc) -> []; -misc_smoke_tests(suite) -> []; misc_smoke_tests(Config) when is_list(Config) -> - ?line true = is_binary(erlang:system_info(info)), - ?line true = is_binary(erlang:system_info(procs)), - ?line true = is_binary(erlang:system_info(loaded)), - ?line true = is_binary(erlang:system_info(dist)), - ?line ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end, - ?line ok. + true = is_binary(erlang:system_info(info)), + true = is_binary(erlang:system_info(procs)), + true = is_binary(erlang:system_info(loaded)), + true = is_binary(erlang:system_info(dist)), + ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end, + true = lists:member(erlang:system_info(tolerant_timeofday), [enabled, disabled]), + ok. -heap_size(doc) -> []; -heap_size(suite) -> []; heap_size(Config) when is_list(Config) -> - ?line {min_bin_vheap_size, VHmin} = erlang:system_info(min_bin_vheap_size), - ?line {min_heap_size, Hmin} = erlang:system_info(min_heap_size), - ?line GCinf = erlang:system_info(garbage_collection), - ?line VHmin = proplists:get_value(min_bin_vheap_size, GCinf), - ?line Hmin = proplists:get_value(min_heap_size, GCinf), + {min_bin_vheap_size, VHmin} = erlang:system_info(min_bin_vheap_size), + {min_heap_size, Hmin} = erlang:system_info(min_heap_size), + GCinf = erlang:system_info(garbage_collection), + VHmin = proplists:get_value(min_bin_vheap_size, GCinf), + Hmin = proplists:get_value(min_heap_size, GCinf), ok. -wordsize(suite) -> - []; -wordsize(doc) -> - ["Tests the various wordsize variants"]; +%% Tests the various wordsize variants wordsize(Config) when is_list(Config) -> - ?line A = erlang:system_info(wordsize), - ?line true = is_integer(A), - ?line A = erlang:system_info({wordsize,internal}), - ?line B = erlang:system_info({wordsize,external}), - ?line true = A =< B, + A = erlang:system_info(wordsize), + true = is_integer(A), + A = erlang:system_info({wordsize,internal}), + B = erlang:system_info({wordsize,external}), + true = A =< B, case {B,A} of {4,4} -> {comment, "True 32-bit emulator"}; {8,8} -> {comment, "True 64-bit emulator"}; - {8,4} -> - {comment, "Halfword 64-bit emulator"}; Other -> exit({unexpected_wordsizes,Other}) end. -memory(doc) -> ["Verify that erlang:memory/0 and memory results in crashdump produce are similar"]; +%% Verify that erlang:memory/0 and memory results in crashdump produce are similar memory(Config) when is_list(Config) -> %% %% Verify that erlang:memory/0 and memory results in @@ -212,7 +174,7 @@ memory(Config) when is_list(Config) -> %% erts_debug:set_internal_state(available_internal_state, true), - %% Use a large heap size on the controling process in + %% Use a large heap size on the controlling process in %% order to avoid changes in its heap size during %% comparisons. MinHeapSize = process_flag(min_heap_size, 1024*1024), @@ -244,8 +206,7 @@ memory_test(_Config) -> end) end, 1000 div erlang:system_info(schedulers_online)) - end, - []), + end, []), cmp_memory(MWs, "spawn procs"), Ps = lists:flatten(DPs), @@ -253,23 +214,49 @@ memory_test(_Config) -> mem_workers_call(MWs, fun () -> lists:foreach(fun (P) -> link(P) end, Ps) - end, - []), + end, []), cmp_memory(MWs, "link procs"), mem_workers_call(MWs, fun () -> lists:foreach(fun (P) -> unlink(P) end, Ps) - end, - []), + end, []), cmp_memory(MWs, "unlink procs"), + mem_workers_call(MWs, + fun () -> + lists:foreach( + fun (P) -> + Tmr = erlang:start_timer(1 bsl 34, + P, + hello), + Tmrs = case get('BIF_TMRS') of + undefined -> []; + Rs -> Rs + end, + true = is_reference(Tmr), + put('BIF_TMRS', [Tmr|Tmrs]) + end, Ps) + end, []), + cmp_memory(MWs, "start BIF timer procs"), + + mem_workers_call(MWs, + fun () -> + lists:foreach(fun (Tmr) -> + true = is_reference(Tmr), + true = is_integer(erlang:cancel_timer(Tmr)) + end, get('BIF_TMRS')), + put('BIF_TMRS', undefined), + garbage_collect() + end, []), + erts_debug:set_internal_state(wait, deallocations), + cmp_memory(MWs, "cancel BIF timer procs"), + DMs = mem_workers_call(MWs, fun () -> lists:map(fun (P) -> monitor(process, P) end, Ps) - end, - []), + end, []), cmp_memory(MWs, "monitor procs"), Ms = lists:flatten(DMs), mem_workers_call(MWs, @@ -277,8 +264,7 @@ memory_test(_Config) -> lists:foreach(fun (M) -> demonitor(M) end, Ms) - end, - []), + end, []), cmp_memory(MWs, "demonitor procs"), mem_workers_call(MWs, @@ -286,8 +272,7 @@ memory_test(_Config) -> lists:foreach(fun (P) -> P ! {a, "message", make_ref()} end, Ps) - end, - []), + end, []), cmp_memory(MWs, "message procs"), mem_workers_call(MWs, @@ -310,8 +295,7 @@ memory_test(_Config) -> fun () -> put(binary_data, mapn(fun (_) -> list_to_binary(lists:duplicate(256,$?)) end, 100)) - end, - []), + end, []), cmp_memory(MWs, "store binary data"), @@ -319,17 +303,15 @@ memory_test(_Config) -> fun () -> put(binary_data, false), garbage_collect() - end, - []), + end, []), cmp_memory(MWs, "release binary data"), mem_workers_call(MWs, fun () -> - list_to_atom("an ugly atom "++integer_to_list(erlang:system_info(scheduler_id))), - list_to_atom("another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))), - list_to_atom("yet another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))) - end, - []), + _ = list_to_atom("an ugly atom "++integer_to_list(erlang:system_info(scheduler_id))), + _ = list_to_atom("another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))), + _ = list_to_atom("yet another ugly atom "++integer_to_list(erlang:system_info(scheduler_id))) + end, []), cmp_memory(MWs, "new atoms"), @@ -340,16 +322,14 @@ memory_test(_Config) -> ets:insert(T, {banan, lists:seq(1,1024)}), ets:insert(T, {appelsin, make_ref()}), put(ets_id, T) - end, - []), + end, []), cmp_memory(MWs, "store ets data"), mem_workers_call(MWs, fun () -> ets:delete(get(ets_id)), put(ets_id, false) - end, - []), + end, []), cmp_memory(MWs, "remove ets data"), lists:foreach(fun (MW) -> @@ -359,8 +339,7 @@ memory_test(_Config) -> receive {'DOWN', Mon, _, _, _} -> ok end - end, - MWs), + end, MWs), ok. mem_worker() -> @@ -375,22 +354,14 @@ mem_worker() -> mem_workers_call(MWs, Fun, Args) -> lists:foreach(fun (MW) -> - MW ! {call, self(), Fun, Args} - end, - MWs), + MW ! {call, self(), Fun, Args} + end, MWs), lists:map(fun (MW) -> - receive - {reply, MW, Res} -> - Res - end - end, - MWs). - -mem_workers_cast(MWs, Fun, Args) -> - lists:foreach(fun (MW) -> - MW ! {cast, self(), Fun, Args} - end, - MWs). + receive + {reply, MW, Res} -> + Res + end + end, MWs). spawn_mem_workers() -> spawn_mem_workers(erlang:system_info(schedulers_online)). @@ -403,7 +374,6 @@ spawn_mem_workers(N) -> link]) | spawn_mem_workers(N-1)]. - mem_get(X, Mem) -> case lists:keyfind(X, 1, Mem) of {X, Val} -> Val; @@ -471,25 +441,25 @@ cmp_memory(MWs, Str) -> "crash dump memory = ~p~n", [Str, EM, EDM]), - ?line check_sane_memory(EM), - ?line check_sane_memory(EDM), + check_sane_memory(EM), + check_sane_memory(EDM), %% We expect these to always give us exactly the same result - ?line cmp_memory(atom, EM, EDM, 1), - ?line cmp_memory(atom_used, EM, EDM, 1), - ?line cmp_memory(binary, EM, EDM, 1), - ?line cmp_memory(code, EM, EDM, 1), - ?line cmp_memory(ets, EM, EDM, 1), + cmp_memory(atom, EM, EDM, 1), + cmp_memory(atom_used, EM, EDM, 1), + cmp_memory(binary, EM, EDM, 1), + cmp_memory(code, EM, EDM, 1), + cmp_memory(ets, EM, EDM, 1), %% Total, processes, processes_used, and system will seldom %% give us exactly the same result since the two readings %% aren't taken atomically. - ?line cmp_memory(total, EM, EDM, 1.05), - ?line cmp_memory(processes, EM, EDM, 1.05), - ?line cmp_memory(processes_used, EM, EDM, 1.05), - ?line cmp_memory(system, EM, EDM, 1.05), + cmp_memory(total, EM, EDM, 1.05), + cmp_memory(processes, EM, EDM, 1.05), + cmp_memory(processes_used, EM, EDM, 1.05), + cmp_memory(system, EM, EDM, 1.05), ok. @@ -498,9 +468,18 @@ mapn(_Fun, 0) -> mapn(Fun, N) -> [Fun(N) | mapn(Fun, N-1)]. -ets_limit(doc) -> - "Verify system_info(ets_limit) reflects max ETS table settings."; -ets_limit(suite) -> []; + +get_node_name(Config) -> + list_to_atom(atom_to_list(?MODULE) + ++ "-" + ++ atom_to_list(proplists:get_value(testcase, Config)) + ++ "-" + ++ integer_to_list(erlang:system_time(second)) + ++ "-" + ++ integer_to_list(erlang:unique_integer([positive]))). + + +%% Verify system_info(ets_limit) reflects max ETS table settings. ets_limit(Config0) when is_list(Config0) -> Config = [{testcase,ets_limit}|Config0], true = is_integer(get_ets_limit(Config)), @@ -514,7 +493,7 @@ get_ets_limit(Config, EtsMax) -> 0 -> []; _ -> [{"ERL_MAX_ETS_TABLES", integer_to_list(EtsMax)}] end, - {ok, Node} = start_node(Config, Envs), + {ok, Node} = start_node_ets(Config, Envs), Me = self(), Ref = make_ref(), spawn_link(Node, @@ -530,19 +509,50 @@ get_ets_limit(Config, EtsMax) -> stop_node(Node), Res. -start_node(Config, Envs) when is_list(Config) -> +start_node_ets(Config, Envs) when is_list(Config) -> Pa = filename:dirname(code:which(?MODULE)), - {A, B, C} = now(), - Name = list_to_atom(atom_to_list(?MODULE) - ++ "-" - ++ atom_to_list(?config(testcase, Config)) - ++ "-" - ++ integer_to_list(A) - ++ "-" - ++ integer_to_list(B) - ++ "-" - ++ integer_to_list(C)), - ?t:start_node(Name, peer, [{args, "-pa "++Pa}, {env, Envs}]). + test_server:start_node(get_node_name(Config), peer, + [{args, "-pa "++Pa}, {env, Envs}]). + +start_node_atm(Config, AtomsMax) when is_list(Config) -> + Pa = filename:dirname(code:which(?MODULE)), + test_server:start_node(get_node_name(Config), peer, + [{args, "-pa "++ Pa ++ AtomsMax}]). stop_node(Node) -> - ?t:stop_node(Node). + test_server:stop_node(Node). + + +%% Verify system_info(atom_limit) reflects max atoms settings +%% (using " +t"). +atom_limit(Config0) when is_list(Config0) -> + Config = [{testcase,atom_limit}|Config0], + 2186042 = get_atom_limit(Config, " +t 2186042 "), + ok. + +get_atom_limit(Config, AtomsMax) -> + {ok, Node} = start_node_atm(Config, AtomsMax), + Me = self(), + Ref = make_ref(), + spawn_link(Node, + fun() -> + Res = erlang:system_info(atom_limit), + unlink(Me), + Me ! {Ref, Res} + end), + receive + {Ref, Res} -> + Res + end, + stop_node(Node), + Res. + +%% Verify that system_info(atom_count) works. +atom_count(Config) when is_list(Config) -> + Limit = erlang:system_info(atom_limit), + Count1 = erlang:system_info(atom_count), + list_to_atom(integer_to_list(erlang:unique_integer())), + Count2 = erlang:system_info(atom_count), + true = Limit >= Count2, + true = Count2 > Count1, + ok. |