Skip to content

Commit

Permalink
Merge pull request #4345 from esl/start-cover-on-mim1-v7
Browse files Browse the repository at this point in the history
Start cover on mim1 - second version
  • Loading branch information
JanuszJakubiec authored Jul 30, 2024
2 parents 9fb5603 + 8cf7c10 commit 9632038
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 103 deletions.
134 changes: 108 additions & 26 deletions big_tests/run_common_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -359,21 +359,22 @@ analyze_coverage(_, _) ->

prepare(Props) ->
Nodes = get_mongoose_nodes(Props),
maybe_compile_cover(Nodes).
maybe_compile_cover(Nodes),
block_nodes(Props).

maybe_compile_cover([]) ->
io:format("cover: skip cover compilation~n", []),
ok;
maybe_compile_cover(Nodes) ->
maybe_compile_cover([CoverNode|_] = Nodes) ->
io:format("cover: compiling modules for nodes ~p~n", [Nodes]),
import_code_paths(hd(Nodes)),

cover:start(Nodes),
cover_start(CoverNode, Nodes),
Dir = call(hd(Nodes), code, lib_dir, [mongooseim, ebin]),

%% Time is in microseconds
{Time, Compiled} = timer:tc(fun() ->
Results = cover:compile_beam_directory(Dir),
Results = cover_compile_dir(CoverNode, Dir),
Ok = [X || X = {ok, _} <- Results],
NotOk = Results -- Ok,
#{ok => length(Ok), failed => NotOk}
Expand All @@ -385,26 +386,26 @@ maybe_compile_cover(Nodes) ->
ok.

analyze(Props, CoverOpts) ->
unblock_nodes(Props),
io:format("Coverage analyzing~n"),
Nodes = get_mongoose_nodes(Props),
analyze(Props, CoverOpts, Nodes).

analyze(_Props, _CoverOpts, []) ->
ok;
analyze(_Props, CoverOpts, Nodes) ->
deduplicate_cover_server_console_prints(),
analyze(_Props, CoverOpts, [CoverNode|_] = Nodes) ->
%% Import small tests cover
Files = filelib:wildcard(repo_dir() ++ "/_build/**/cover/*.coverdata"),
io:format("Files: ~p", [Files]),
report_time("Import cover data into run_common_test node", fun() ->
[cover:import(File) || File <- Files]
[cover_import(CoverNode, File) || File <- Files]
end),
report_time("Export merged cover data", fun() ->
cover:export("/tmp/mongoose_combined.coverdata")
cover_export(CoverNode, "/tmp/mongoose_combined.coverdata")
end),
case os:getenv("GITHUB_RUN_ID") of
false ->
make_html(modules_to_analyze(CoverOpts));
make_html(CoverNode, modules_to_analyze(CoverNode, CoverOpts));
_ ->
ok
end,
Expand All @@ -414,11 +415,11 @@ analyze(_Props, CoverOpts, Nodes) ->
ok;
_ ->
report_time("Stopping cover on MongooseIM nodes", fun() ->
cover:stop([node()|Nodes])
cover_stop(CoverNode, Nodes)
end)
end.

make_html(Modules) ->
make_html(CoverNode, Modules) ->
{ok, Root} = file:get_cwd(),
SortScript = Root ++ "/priv/sorttable.js",
os:cmd("cp " ++ SortScript ++ " " ++ ?CT_REPORT),
Expand All @@ -437,11 +438,11 @@ make_html(Modules) ->
FileName = lists:flatten(io_lib:format("~s.COVER.html",[Module])),

%% We assume that import_code_paths/1 was called earlier
case cover:analyse(Module, module) of
case cover_analyse(CoverNode, Module) of
{ok, {Module, {C, NC}}} ->
file:write(File, row(atom_to_list(Module), C, NC, percent(C,NC),"coverage/"++FileName)),
FilePathC = filename:join([CoverageDir, FileName]),
catch cover:analyse_to_file(Module, FilePathC, [html]),
cover_analyse_to_html_file(CoverNode, Module, FilePathC),
{CAcc + C, NCAcc + NC};
Reason ->
error_logger:error_msg("issue=cover_analyse_failed module=~p reason=~p",
Expand Down Expand Up @@ -503,9 +504,9 @@ module_list(undefined) ->
module_list(ModuleList) ->
[ list_to_atom(L) || L <- string:tokens(ModuleList, ", ") ].

modules_to_analyze(true) ->
lists:usort(cover:imported_modules() ++ cover:modules());
modules_to_analyze(ModuleList) when is_list(ModuleList) ->
modules_to_analyze(CoverNode, true) ->
lists:usort(cover_all_modules(CoverNode));
modules_to_analyze(_CoverNode, ModuleList) when is_list(ModuleList) ->
ModuleList.

add({X1, X2, X3, X4},
Expand Down Expand Up @@ -581,6 +582,9 @@ host_param(Name, {_, Params}) ->
{Name, Param} = lists:keyfind(Name, 1, Params),
Param.

host_param(Name, {_, Params}, Default) ->
proplists:get_value(Name, Params, Default).

report_time(Description, Fun) ->
report_progress("~nExecuting ~ts~n", [Description]),
Start = os:timestamp(),
Expand Down Expand Up @@ -630,16 +634,6 @@ handle_file_error(_FileName, Other) ->

%% ------------------------------------------------------------------

%% cover_server process is using io:format too much.
%% This code removes duplicate io:formats.
%%
%% Example of a message we want to write only once:
%% "Analysis includes data from imported files" from cover.erl in Erlang/R19
deduplicate_cover_server_console_prints() ->
%% Set a new group leader for cover_server
CoverPid = whereis(cover_server),
dedup_proxy_group_leader:start_proxy_group_leader_for(CoverPid).

ct_run_dirs() ->
filelib:wildcard("ct_report/ct_run*").

Expand Down Expand Up @@ -721,3 +715,91 @@ assert_preset_present(Preset, PresetConfs) ->
error_logger:error_msg("Preset not found ~p~n", [Preset]),
error({preset_not_found, Preset})
end.

assert_list(X) when is_list(X) -> X.

%% We use mim1 as a main node.
%% Only the main node supports meck
%% (other nodes should not use meck for the cover compiled modules).
cover_start(CoverNode, Nodes) ->
{ok, _} = cover_call(CoverNode, start, [Nodes]),
CoverNode = cover_call(CoverNode, get_main_node, []),
ok.

cover_stop(CoverNode, Nodes) ->
cover_call(CoverNode, stop, [Nodes]).

cover_all_modules(CoverNode) ->
List1 = assert_list(cover_call(CoverNode, imported_modules, [])),
List2 = assert_list(cover_call(CoverNode, modules, [])),
List1 ++ List2.

cover_analyse_to_html_file(CoverNode, Module, FilePathC) ->
catch cover_call(CoverNode, analyse_to_file, [Module, FilePathC, [html]]).

cover_analyse(CoverNode, Module) ->
cover_call(CoverNode, analyse, [Module, module]).

cover_export(CoverNode, ToFile) ->
cover_call(CoverNode, export, [ToFile]).

cover_import(CoverNode, FromFile) ->
cover_call(CoverNode, import, [FromFile]).

cover_compile_dir(CoverNode, Dir) ->
cover_call(CoverNode, compile_beam_directory, [Dir]).

cover_call(CoverNode, Fun, Args) ->
rpc:call(CoverNode, cover, Fun, Args).

block_nodes(Props) ->
[block_node(Node, BlockNode, Props) || {Node, BlockNode} <- block_nodes_specs(Props)],
ok.

unblock_nodes(Props) ->
[unblock_node(Node, BlockNode, Props) || {Node, BlockNode} <- block_nodes_specs(Props)],
ok.

%% Reads `blocks_hosts' parameter for the host from `test.config'.
%% Returns a list of blocks to do like `[{mim, fed}]'.
block_nodes_specs(Props) ->
EnabledHosts = [ H || H <- get_all_hosts(Props), is_test_host_enabled(host_name(H)) ],
[{host_name(H), BlockName}
|| H <- EnabledHosts, BlockName <- host_param(blocks_hosts, H, []),
is_test_host_enabled(BlockName)].

host_name_to_node(Name, Props) ->
Hosts = get_all_hosts(Props),
Host = proplists:get_value(Name, Hosts, []),
case proplists:get_value(node, Host) of
undefined ->
error({host_name_to_node_failed, Name, Props});
Node ->
Node
end.

%% Do not allow node Name to talk to node BlockName
block_node(Name, BlockName, Props) ->
Node = host_name_to_node(Name, Props),
BlockNode = host_name_to_node(BlockName, Props),
rpc_call(Node, erlang, set_cookie, [BlockNode, make_bad_cookie(Name, BlockNode)]),
rpc_call(Node, erlang, disconnect_node, [BlockNode]),
Cond = fun() -> lists:member(BlockNode, rpc_call(Node, erlang, nodes, [])) end,
mongoose_helper:wait_until(Cond, false).

unblock_node(Name, BlockName, Props) ->
Node = host_name_to_node(Name, Props),
BlockNode = host_name_to_node(BlockName, Props),
DefCookie = rpc_call(Node, erlang, get_cookie, []),
rpc_call(Node, erlang, set_cookie, [BlockNode, DefCookie]).

make_bad_cookie(Name, BlockName) ->
list_to_atom(atom_to_list(Name) ++ "_blocks_" ++ atom_to_list(BlockName)).

rpc_call(Node, M, F, Args) ->
case rpc:call(Node, M, F, Args) of
{badrpc, Reason} ->
error({rpc_call_failed, Reason, Node, {M, F, Args}});
Res ->
Res
end.
73 changes: 0 additions & 73 deletions big_tests/src/dedup_proxy_group_leader.erl

This file was deleted.

3 changes: 2 additions & 1 deletion big_tests/test.config
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
{kicking_service_port, 8666},
{hidden_service_port, 8189},
{gd_endpoint_port, 5555},
{http_notifications_port, 8000}]},
{http_notifications_port, 8000},
{blocks_hosts, [reg]}]},
{mim2, [{node, mongooseim2@localhost},
{domain, <<"localhost">>},
{host_type, <<"localhost">>},
Expand Down
4 changes: 2 additions & 2 deletions big_tests/tests/mod_global_distrib_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -660,13 +660,13 @@ test_pm_with_graceful_reconnection_to_different_server(Config) ->
%% Pause Alice until Eve is reconnected
AliceNode = ct:get_config({hosts, mim, node}),
C2sPid = mongoose_helper:get_session_pid(Alice, #{node => AliceNode}),
ok = rpc(asia_node, sys, suspend, [C2sPid]),
ok = rpc:call(node(C2sPid), sys, suspend, [C2sPid]),

escalus_client:send(Alice, chat_with_seqnum(Eve, <<"Hi from Europe1!">>)),

NewEve = connect_from_spec(EveSpec2, Config),

ok = rpc(asia_node, sys, resume, [C2sPid]),
ok = rpc:call(node(C2sPid), sys, resume, [C2sPid]),


escalus_client:send(Alice, chat_with_seqnum(Eve, <<"Hi again from Europe1!">>)),
Expand Down
2 changes: 1 addition & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
[
{pc, "1.15.0"},
{provider_asn1, "0.3.0"},
{rebar3_codecov, "0.6.0"},
{rebar3_codecov, "0.7.0"},
{rebar3_lint, "2.0.1"}
]}.

Expand Down

0 comments on commit 9632038

Please sign in to comment.