diff options
author | Sverker Eriksson <[email protected]> | 2018-11-16 19:06:06 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2018-11-16 19:19:14 +0100 |
commit | 5b6eff964a61b32c1d02464e8fc6ef0c79a4badc (patch) | |
tree | 2b482cc8455c14db03860f204953935ffcb30199 | |
parent | aff44bcc16aa6aaf3c7efcef907ca25cbdb4ec8c (diff) | |
download | otp-5b6eff964a61b32c1d02464e8fc6ef0c79a4badc.tar.gz otp-5b6eff964a61b32c1d02464e8fc6ef0c79a4badc.tar.bz2 otp-5b6eff964a61b32c1d02464e8fc6ef0c79a4badc.zip |
erts: Refactor out erts_test_utils from node_container_SUITE
to be usable by other application tests.
-rw-r--r-- | erts/emulator/test/Makefile | 1 | ||||
-rw-r--r-- | erts/emulator/test/erts_test_utils.erl | 250 | ||||
-rw-r--r-- | erts/emulator/test/node_container_SUITE.erl | 236 |
3 files changed, 272 insertions, 215 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 6a064ec8d4..b66cc1b2a3 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -130,6 +130,7 @@ MODULES= \ ignore_cores \ dgawd_handler \ random_iolist \ + erts_test_utils \ crypto_reference NO_OPT= bs_bincomp \ diff --git a/erts/emulator/test/erts_test_utils.erl b/erts/emulator/test/erts_test_utils.erl new file mode 100644 index 0000000000..ac2f2435be --- /dev/null +++ b/erts/emulator/test/erts_test_utils.erl @@ -0,0 +1,250 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2018. All Rights Reserved. +%% +%% 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 +%% +%% 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% +%% + +-module(erts_test_utils). + +%% +%% THIS MODULE IS ALSO USED BY *OTHER* APPLICATIONS TEST CODE +%% + +-export([mk_ext_pid/3, + mk_ext_port/2, + mk_ext_ref/2, + check_node_dist/0, check_node_dist/1, check_node_dist/3]). + + + +-define(VERSION_MAGIC, 131). + +-define(ATOM_EXT, 100). +-define(REFERENCE_EXT, 101). +-define(PORT_EXT, 102). +-define(PID_EXT, 103). +-define(NEW_REFERENCE_EXT, 114). +-define(NEW_PID_EXT, $X). +-define(NEW_PORT_EXT, $Y). +-define(NEWER_REFERENCE_EXT, $Z). + +uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 -> + [(Uint bsr 24) band 16#ff, + (Uint bsr 16) band 16#ff, + (Uint bsr 8) band 16#ff, + Uint band 16#ff]; +uint32_be(Uint) -> + exit({badarg, uint32_be, [Uint]}). + + +uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 -> + [(Uint bsr 8) band 16#ff, + Uint band 16#ff]; +uint16_be(Uint) -> + exit({badarg, uint16_be, [Uint]}). + +uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 -> + Uint band 16#ff; +uint8(Uint) -> + exit({badarg, uint8, [Uint]}). + +pid_tag(bad_creation) -> ?PID_EXT; +pid_tag(Creation) when Creation =< 3 -> ?PID_EXT; +pid_tag(_Creation) -> ?NEW_PID_EXT. + +enc_creation(bad_creation) -> uint8(4); +enc_creation(Creation) when Creation =< 3 -> uint8(Creation); +enc_creation(Creation) -> uint32_be(Creation). + +mk_ext_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> + mk_ext_pid({atom_to_list(NodeName), Creation}, Number, Serial); +mk_ext_pid({NodeName, Creation}, Number, Serial) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + pid_tag(Creation), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint32_be(Serial), + enc_creation(Creation)])) of + Pid when is_pid(Pid) -> + Pid; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. + +port_tag(bad_creation) -> ?PORT_EXT; +port_tag(Creation) when Creation =< 3 -> ?PORT_EXT; +port_tag(_Creation) -> ?NEW_PORT_EXT. + +mk_ext_port({NodeName, Creation}, Number) when is_atom(NodeName) -> + mk_ext_port({atom_to_list(NodeName), Creation}, Number); +mk_ext_port({NodeName, Creation}, Number) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + port_tag(Creation), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + enc_creation(Creation)])) of + Port when is_port(Port) -> + Port; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_port, [{NodeName, Creation}, Number]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. + +ref_tag(bad_creation) -> ?NEW_REFERENCE_EXT; +ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT; +ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT. + +mk_ext_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), + is_list(Numbers) -> + mk_ext_ref({atom_to_list(NodeName), Creation}, Numbers); +mk_ext_ref({NodeName, Creation}, [Number]) when is_list(NodeName), + Creation =< 3, + is_integer(Number) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ?REFERENCE_EXT, + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + uint32_be(Number), + uint8(Creation)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end; +mk_ext_ref({NodeName, Creation}, Numbers) when is_list(NodeName), + is_list(Numbers) -> + case catch binary_to_term(list_to_binary([?VERSION_MAGIC, + ref_tag(Creation), + uint16_be(length(Numbers)), + ?ATOM_EXT, + uint16_be(length(NodeName)), + NodeName, + enc_creation(Creation), + lists:map(fun (N) -> + uint32_be(N) + end, + Numbers)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) + end. + + + +%% +%% Check reference counters for node- and dist entries. +%% +check_node_dist() -> + check_node_dist(fun(ErrMsg) -> + io:format("check_node_dist ERROR:\n~p\n", [ErrMsg]), + error + end). + +check_node_dist(Fail) -> + {{node_references, NodeRefs}, + {dist_references, DistRefs}} = + erts_debug:get_internal_state(node_and_dist_references), + check_node_dist(Fail, NodeRefs, DistRefs). + + + +check_node_dist(Fail, NodeRefs, DistRefs) -> + check_nd_refc({node(),erlang:system_info(creation)}, + NodeRefs, DistRefs, Fail). + + +check_nd_refc({ThisNodeName, ThisCreation}, NodeRefs, DistRefs, Fail) -> + case catch begin + check_refc(ThisNodeName,ThisCreation,"node table",NodeRefs), + check_refc(ThisNodeName,ThisCreation,"dist table",DistRefs), + ok + end of + ok -> + ok; + {'EXIT', Reason} -> + {Y,Mo,D} = date(), + {H,Mi,S} = time(), + ErrMsg = io_lib:format("~n" + "*** Reference count check of node ~w " + "failed (~p) at ~w~w~w ~w:~w:~w~n" + "*** Node table references:~n ~p~n" + "*** Dist table references:~n ~p~n", + [node(), Reason, Y, Mo, D, H, Mi, S, + NodeRefs, DistRefs]), + Fail(lists:flatten(ErrMsg)) + end. + + +check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) -> + lists:foreach( + fun ({Entry, Refc, ReferrerList}) -> + {DelayedDeleteTimer, + FoundRefs} = + lists:foldl( + fun ({Referrer, ReferencesList}, {DDT, A1}) -> + {case Referrer of + {system,delayed_delete_timer} -> + true; + {system,thread_progress_delete_timer} -> + true; + _ -> + DDT + end, + A1 + lists:foldl(fun ({_T,Rs},A2) -> + A2+Rs + end, + 0, + ReferencesList)} + end, + {false, 0}, + ReferrerList), + + %% Reference count equals found references? + case {Refc, FoundRefs, DelayedDeleteTimer} of + {X, X, _} -> + ok; + {0, 1, true} -> + ok; + _ -> + exit({invalid_reference_count, Table, Entry}) + end, + + %% All entries in table referred to? + case {Entry, Refc} of + {ThisNodeName, 0} -> ok; + {{ThisNodeName, ThisCreation}, 0} -> ok; + {_, 0} when DelayedDeleteTimer == false -> + exit({not_referred_entry_in_table, Table, Entry}); + {_, _} -> ok + end + + end, + EntryList), + ok. diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl index 300b4ed036..b3d8f9584d 100644 --- a/erts/emulator/test/node_container_SUITE.erl +++ b/erts/emulator/test/node_container_SUITE.erl @@ -938,15 +938,11 @@ nc_refc_check(Node) when is_atom(Node) -> io:format("Starting reference count check of node ~w~n", [Node]), spawn_link(Node, fun () -> - {{node_references, NodeRefs}, - {dist_references, DistRefs}} = ?ND_REFS, - check_nd_refc({node(), erlang:system_info(creation)}, - NodeRefs, - DistRefs, - fun (ErrMsg) -> - Self ! {Ref, ErrMsg, failed}, - exit(normal) - end), + erts_test_utils:check_node_dist( + fun (ErrMsg) -> + Self ! {Ref, ErrMsg, failed}, + exit(normal) + end), Self ! {Ref, succeded} end), receive @@ -958,98 +954,26 @@ nc_refc_check(Node) when is_atom(Node) -> ok end. -check_nd_refc({ThisNodeName, ThisCreation}, NodeRefs, DistRefs, Fail) -> - case catch begin - check_refc(ThisNodeName,ThisCreation,"node table",NodeRefs), - check_refc(ThisNodeName,ThisCreation,"dist table",DistRefs), - ok - end of - ok -> - ok; - {'EXIT', Reason} -> - {Y,Mo,D} = date(), - {H,Mi,S} = time(), - ErrMsg = io_lib:format("~n" - "*** Reference count check of node ~w " - "failed (~p) at ~w~w~w ~w:~w:~w~n" - "*** Node table references:~n ~p~n" - "*** Dist table references:~n ~p~n", - [node(), Reason, Y, Mo, D, H, Mi, S, - NodeRefs, DistRefs]), - Fail(lists:flatten(ErrMsg)) - end. - - -check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) -> - lists:foreach( - fun ({Entry, Refc, ReferrerList}) -> - {DelayedDeleteTimer, - FoundRefs} = - lists:foldl( - fun ({Referrer, ReferencesList}, {DDT, A1}) -> - {case Referrer of - {system,delayed_delete_timer} -> - true; - {system,thread_progress_delete_timer} -> - true; - _ -> - DDT - end, - A1 + lists:foldl(fun ({_T,Rs},A2) -> - A2+Rs - end, - 0, - ReferencesList)} - end, - {false, 0}, - ReferrerList), - - %% Reference count equals found references? - case {Refc, FoundRefs, DelayedDeleteTimer} of - {X, X, _} -> - ok; - {0, 1, true} -> - ok; - _ -> - exit({invalid_reference_count, Table, Entry}) - end, - - %% All entries in table referred to? - case {Entry, Refc} of - {ThisNodeName, 0} -> ok; - {{ThisNodeName, ThisCreation}, 0} -> ok; - {_, 0} when DelayedDeleteTimer == false -> - exit({not_referred_entry_in_table, Table, Entry}); - {_, _} -> ok - end - - end, - EntryList), - ok. - get_node_references({NodeName, Creation} = Node) when is_atom(NodeName), is_integer(Creation) -> {{node_references, NodeRefs}, {dist_references, DistRefs}} = ?ND_REFS, - check_nd_refc({node(), erlang:system_info(creation)}, - NodeRefs, - DistRefs, - fun (ErrMsg) -> - io:format("~s", [ErrMsg]), - ct:fail(reference_count_check_failed) - end), + erts_test_utils:check_node_dist( + fun (ErrMsg) -> + io:format("~s", [ErrMsg]), + ct:fail(reference_count_check_failed) + end, + NodeRefs, DistRefs), find_references(Node, NodeRefs). get_dist_references(NodeName) when is_atom(NodeName) -> {{node_references, NodeRefs}, {dist_references, DistRefs}} = ?ND_REFS, - check_nd_refc({node(), erlang:system_info(creation)}, - NodeRefs, - DistRefs, - fun (ErrMsg) -> - io:format("~s", [ErrMsg]), - ct:fail(reference_count_check_failed) - end), + erts_test_utils:check_node_dist(fun (ErrMsg) -> + io:format("~s", [ErrMsg]), + ct:fail(reference_count_check_failed) + end, + NodeRefs, DistRefs), find_references(NodeName, DistRefs). find_references(N, NRefList) -> @@ -1138,133 +1062,15 @@ get_nodename() -> ++ "@" ++ hostname()). - - --define(VERSION_MAGIC, 131). - --define(ATOM_EXT, 100). --define(REFERENCE_EXT, 101). --define(PORT_EXT, 102). --define(PID_EXT, 103). --define(NEW_REFERENCE_EXT, 114). --define(NEW_PID_EXT, $X). --define(NEW_PORT_EXT, $Y). --define(NEWER_REFERENCE_EXT, $Z). - -uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 -> - [(Uint bsr 24) band 16#ff, - (Uint bsr 16) band 16#ff, - (Uint bsr 8) band 16#ff, - Uint band 16#ff]; -uint32_be(Uint) -> - exit({badarg, uint32_be, [Uint]}). - - -uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 -> - [(Uint bsr 8) band 16#ff, - Uint band 16#ff]; -uint16_be(Uint) -> - exit({badarg, uint16_be, [Uint]}). - -uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 -> - Uint band 16#ff; -uint8(Uint) -> - exit({badarg, uint8, [Uint]}). - - -pid_tag(bad_creation) -> ?PID_EXT; -pid_tag(Creation) when Creation =< 3 -> ?PID_EXT; -pid_tag(_Creation) -> ?NEW_PID_EXT. - -enc_creation(bad_creation) -> uint8(4); -enc_creation(Creation) when Creation =< 3 -> uint8(Creation); -enc_creation(Creation) -> uint32_be(Creation). - -mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> - mk_pid({atom_to_list(NodeName), Creation}, Number, Serial); mk_pid({NodeName, Creation}, Number, Serial) -> - case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - pid_tag(Creation), - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - uint32_be(Serial), - enc_creation(Creation)])) of - Pid when is_pid(Pid) -> - Pid; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) - end. - -port_tag(bad_creation) -> ?PORT_EXT; -port_tag(Creation) when Creation =< 3 -> ?PORT_EXT; -port_tag(_Creation) -> ?NEW_PORT_EXT. + erts_test_utils:mk_ext_pid({NodeName, Creation}, Number, Serial). -mk_port({NodeName, Creation}, Number) when is_atom(NodeName) -> - mk_port({atom_to_list(NodeName), Creation}, Number); mk_port({NodeName, Creation}, Number) -> - case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - port_tag(Creation), - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - enc_creation(Creation)])) of - Port when is_port(Port) -> - Port; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_port, [{NodeName, Creation}, Number]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) - end. + erts_test_utils:mk_ext_port({NodeName, Creation}, Number). + +mk_ref({NodeName, Creation}, Numbers) -> + erts_test_utils:mk_ext_ref({NodeName, Creation}, Numbers). -ref_tag(bad_creation) -> ?NEW_REFERENCE_EXT; -ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT; -ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT. - -mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), - is_list(Numbers) -> - mk_ref({atom_to_list(NodeName), Creation}, Numbers); -mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName), - Creation =< 3, - is_integer(Number) -> - case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?REFERENCE_EXT, - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - uint8(Creation)])) of - Ref when is_reference(Ref) -> - Ref; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) - end; -mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName), - is_list(Numbers) -> - case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ref_tag(Creation), - uint16_be(length(Numbers)), - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - enc_creation(Creation), - lists:map(fun (N) -> - uint32_be(N) - end, - Numbers)])) of - Ref when is_reference(Ref) -> - Ref; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) - end. exec_loop() -> receive |