directory.
-cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, TestDir) ->
+cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, Stop, TestDir) ->
write_default_cross_coverlog(TestDir),
{ok,CoverLog} = file:open(filename:join(TestDir, ?coverlog_name), [write]),
@@ -5479,7 +5479,7 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, TestDir) ->
io:fwrite(CoverLog, "Excluded module(s): ~p
\n", [Excluded]),
- Coverage = cover_analyse(Analyse, AnalyseMods),
+ Coverage = cover_analyse(Analyse, AnalyseMods, Stop),
case lists:filter(fun({_M,{_,_,_}}) -> false;
(_) -> true
@@ -5496,17 +5496,17 @@ cover_analyse({App,CoverInfo}, Analyse, AnalyseMods, TestDir) ->
file:write_file(filename:join(TestDir, ?cover_total),
term_to_binary(TotPercent)).
-cover_analyse(Analyse, AnalyseMods) ->
+cover_analyse(Analyse, AnalyseMods, Stop) ->
TestDir = get(test_server_log_dir_base),
case get(test_server_ctrl_job_sock) of
undefined ->
%% local target
- test_server:cover_analyse({Analyse,TestDir}, AnalyseMods);
+ test_server:cover_analyse({Analyse,TestDir}, AnalyseMods, Stop);
JobSock ->
%% remote target
request(JobSock, {sync_apply,{test_server,
cover_analyse,
- [Analyse,AnalyseMods]}}),
+ [Analyse,AnalyseMods, Stop]}}),
read_job_sock_loop(JobSock)
end.
diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl
index 57d1b8806e..741dd483f5 100644
--- a/lib/test_server/src/ts_run.erl
+++ b/lib/test_server/src/ts_run.erl
@@ -368,7 +368,7 @@ make_common_test_args(Args0, Options0, _Vars) ->
io:format("No cover file found for ~p~n",[App]),
[];
{value,{cover,_App,File,_Analyse}} ->
- [{cover,to_list(File)}];
+ [{cover,to_list(File)},{cover_stop,false}];
false ->
[]
end,
--
cgit v1.2.3
From 3d4ea1aa4226e10b6daab29ae34f60deb0ecd7a9 Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Mon, 22 Oct 2012 16:13:50 +0200
Subject: [common_test, test_server] Don't flush cover if cover is not running
ct_slave, ct_test_support and test_server_test_lib always called
cover:flush/1 when stopping slave nodes. If cover was not running,
this would cause cover_server to be started and thus
test_server:is_cover/0 to return true afterwards. This has been
corrected.
---
lib/common_test/src/ct_slave.erl | 9 +++++++--
lib/common_test/test/ct_test_support.erl | 10 ++++++++--
lib/test_server/test/test_server_test_lib.erl | 7 ++++++-
3 files changed, 21 insertions(+), 5 deletions(-)
(limited to 'lib')
diff --git a/lib/common_test/src/ct_slave.erl b/lib/common_test/src/ct_slave.erl
index 6f7e83d852..cb05423497 100644
--- a/lib/common_test/src/ct_slave.erl
+++ b/lib/common_test/src/ct_slave.erl
@@ -430,8 +430,13 @@ wait_for_node_alive(Node, N) ->
% call init:stop on a remote node
do_stop(ENode) ->
- MainCoverNode = cover:get_main_node(),
- rpc:call(MainCoverNode,cover,flush,[ENode]),
+ case test_server:is_cover() of
+ true ->
+ MainCoverNode = cover:get_main_node(),
+ rpc:call(MainCoverNode,cover,flush,[ENode]);
+ false ->
+ ok
+ end,
spawn(ENode, init, stop, []),
wait_for_node_dead(ENode, 5).
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index c05b6d87c0..afc8dc4bb7 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -117,7 +117,10 @@ end_per_suite(Config) ->
CTNode = proplists:get_value(ct_node, Config),
PrivDir = proplists:get_value(priv_dir, Config),
true = rpc:call(CTNode, code, del_path, [filename:join(PrivDir,"")]),
- cover:flush(CTNode),
+ case test_server:is_cover() of
+ true -> cover:flush(CTNode);
+ false -> ok
+ end,
slave:stop(CTNode),
ok.
@@ -149,7 +152,10 @@ end_per_testcase(_TestCase, Config) ->
case wait_for_ct_stop(CTNode) of
%% Common test was not stopped to we restart node.
false ->
- cover:flush(CTNode),
+ case test_server:is_cover() of
+ true -> cover:flush(CTNode);
+ false -> ok
+ end,
slave:stop(CTNode),
start_slave(Config,proplists:get_value(trace_level,Config)),
{fail, "Could not stop common_test"};
diff --git a/lib/test_server/test/test_server_test_lib.erl b/lib/test_server/test/test_server_test_lib.erl
index 0dabc17173..4e89abf308 100644
--- a/lib/test_server/test/test_server_test_lib.erl
+++ b/lib/test_server/test/test_server_test_lib.erl
@@ -83,7 +83,12 @@ start_slave(Config,_Level) ->
post_end_per_testcase(_TC, Config, Return, State) ->
Node = proplists:get_value(node, Config),
- cover:flush(Node),
+ case test_server:is_cover() of
+ true ->
+ cover:flush(Node);
+ false ->
+ ok
+ end,
slave:stop(Node),
{Return, State}.
--
cgit v1.2.3
From 572d2497a4b9cbb2e5e158a303bfe593d7f03bab Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Mon, 22 Oct 2012 17:14:10 +0200
Subject: [common_test] Add test suite for code coverage support
---
lib/common_test/test/Makefile | 3 +-
lib/common_test/test/ct_cover_SUITE.erl | 249 +++++++++++++++++++++
.../test/ct_cover_SUITE_data/cover_SUITE.erl | 148 ++++++++++++
.../test/ct_cover_SUITE_data/cover_test_mod.erl | 4 +
.../test/ct_cover_SUITE_data/test.cover | 1 +
5 files changed, 404 insertions(+), 1 deletion(-)
create mode 100644 lib/common_test/test/ct_cover_SUITE.erl
create mode 100644 lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
create mode 100644 lib/common_test/test/ct_cover_SUITE_data/cover_test_mod.erl
create mode 100644 lib/common_test/test/ct_cover_SUITE_data/test.cover
(limited to 'lib')
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index 652a9f6efe..3de33688da 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -54,7 +54,8 @@ MODULES= \
ct_shell_SUITE \
ct_system_error_SUITE \
ct_snmp_SUITE \
- ct_group_leader_SUITE
+ ct_group_leader_SUITE \
+ ct_cover_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl
new file mode 100644
index 0000000000..55599950c9
--- /dev/null
+++ b/lib/common_test/test/ct_cover_SUITE.erl
@@ -0,0 +1,249 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2012. 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/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_cover_SUITE
+%%%
+%%% Description:
+%%% Test code cover analysis support
+%%%
+%%%-------------------------------------------------------------------
+-module(ct_cover_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+-define(mod, cover_test_mod).
+-define(cover_spec_file,"test.cover").
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case test_server:is_cover() of
+ true ->
+ {skip,"Test server is running cover already - skipping"};
+ false ->
+ ct_test_support:init_per_suite(Config)
+ end.
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ Node = fullname(existing_node),
+ case lists:member(Node,nodes()) of
+ true -> rpc:call(Node,erlang,halt,[]);
+ false -> ok
+ end,
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [
+ default,
+ cover_stop_true,
+ cover_stop_false,
+ slave,
+ slave_start_slave,
+ cover_node_option,
+ ct_cover_add_remove_nodes
+ ].
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%% Check that cover is collected from test node
+%% Also check that cover is by default stopped after test is completed
+default(Config) ->
+ {ok,Events} = run_test(default,Config),
+ false = check_cover(Config),
+ check_calls(1,Events),
+ ok.
+
+%% Check that cover is stopped when cover_stop option is set to true
+cover_stop_true(Config) ->
+ {ok,_Events} = run_test(cover_stop_true,[{cover_stop,true}],Config),
+ false = check_cover(Config).
+
+%% Check that cover is not stopped when cover_stop option is set to false
+cover_stop_false(Config) ->
+ {ok,_Events} = run_test(cover_stop_false,[{cover_stop,false}],Config),
+ {true,[],[?mod]} = check_cover(Config),
+ CTNode = proplists:get_value(ct_node, Config),
+ ok = rpc:call(CTNode,cover,stop,[]),
+ false = check_cover(Config),
+ ok.
+
+%% Let test node start a slave node - check that cover is collected
+%% from both nodes
+slave(Config) ->
+ {ok,Events} = run_test(slave,slave,[],Config),
+ check_calls(2,Events),
+ ok.
+
+%% Let test node start a slave node which in turn starts another slave
+%% node - check that cover is collected from all three nodes
+slave_start_slave(Config) ->
+ {ok,Events} = run_test(slave_start_slave,slave_start_slave,[],Config),
+ check_calls(3,Events),
+ ok.
+
+%% Start a slave node before test starts - the node is listed in cover
+%% spec file.
+%% Check that cover is collected from test node and slave node.
+cover_node_option(Config) ->
+ {ok, HostStr}=inet:gethostname(),
+ Host = list_to_atom(HostStr),
+ DataDir = ?config(data_dir,Config),
+ {ok,Node} = ct_slave:start(Host,existing_node,
+ [{erl_flags,"-pa " ++ DataDir}]),
+ false = check_cover(Node),
+ CoverFile = add_to_cover_file("node_opt.cover",[{nodes,[Node]}],Config),
+ {ok,Events} = run_test(cover_node_option,cover_node_option,
+ [{cover,CoverFile}],Config),
+ check_calls(2,Events),
+ {ok,Node} = ct_slave:stop(existing_node),
+ ok.
+
+%% Test ct_cover:add_nodes/1 and ct_cover:remove_nodes/1
+%% Check that cover is collected from added node
+ct_cover_add_remove_nodes(Config) ->
+ {ok, HostStr}=inet:gethostname(),
+ Host = list_to_atom(HostStr),
+ DataDir = ?config(data_dir,Config),
+ {ok,Node} = ct_slave:start(Host,existing_node,
+ [{erl_flags,"-pa " ++ DataDir}]),
+ false = check_cover(Node),
+ {ok,Events} = run_test(ct_cover_add_remove_nodes,ct_cover_add_remove_nodes,
+ [],Config),
+ check_calls(2,Events),
+ {ok,Node} = ct_slave:stop(existing_node),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+run_test(Label,Config) ->
+ run_test(Label,[],Config).
+run_test(Label,ExtraOpts,Config) ->
+ run_test(Label,default,ExtraOpts,Config).
+run_test(Label,Testcase,ExtraOpts,Config) ->
+ DataDir = ?config(data_dir, Config),
+ Suite = filename:join(DataDir, "cover_SUITE"),
+ DefaultCover = filename:join(DataDir, ?cover_spec_file),
+ Cover = proplists:get_value(cover,ExtraOpts,DefaultCover),
+ RestOpts = lists:keydelete(cover,1,ExtraOpts),
+ {Opts,ERPid} = setup([{suite,Suite},{testcase,Testcase},
+ {cover,Cover},{label,Label}] ++ RestOpts, Config),
+ execute(Label, Testcase, Opts, ERPid, Config).
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+execute(Name, Testcase, Opts, ERPid, Config) ->
+ ok = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(Name,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config),
+ Opts),
+ TestEvents = events_to_check(Testcase),
+ R = ct_test_support:verify_events(TestEvents, Events, Config),
+ {R,Events}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+
+events_to_check(Testcase) ->
+ OneTest =
+ [{?eh,start_logging,{'DEF','RUNDIR'}}] ++
+ [{?eh,tc_done,{cover_SUITE,Testcase,ok}}] ++
+ [{?eh,stop_logging,[]}],
+
+ %% 2 tests (ct:run_test + script_start) is default
+ OneTest ++ OneTest.
+
+check_cover(Config) when is_list(Config) ->
+ CTNode = proplists:get_value(ct_node, Config),
+ check_cover(CTNode);
+check_cover(Node) when is_atom(Node) ->
+ case rpc:call(Node,test_server,is_cover,[]) of
+ true ->
+ {true,
+ rpc:call(Node,cover,which_nodes,[]),
+ rpc:call(Node,cover,modules,[])};
+ false ->
+ false
+ end.
+
+%% Check that each coverlog includes N calls to ?mod:foo/0
+check_calls(N,Events) ->
+ CoverLogs =
+ [filename:join(filename:dirname(TCLog),"all.coverdata") ||
+ {ct_test_support_eh,
+ {event,tc_logfile,ct@falco,
+ {{cover_SUITE,init_per_suite},TCLog}}} <- Events],
+ do_check_logs(N,CoverLogs).
+
+do_check_logs(N,[CoverLog|CoverLogs]) ->
+ {ok,_} = cover:start(),
+ ok = cover:import(CoverLog),
+ {ok,[{{?mod,foo,0},N}]} = cover:analyse(?mod,calls,function),
+ ok = cover:stop(),
+ do_check_logs(N,CoverLogs);
+do_check_logs(_,[]) ->
+ ok.
+
+fullname(Name) ->
+ {ok,Host} = inet:gethostname(),
+ list_to_atom(atom_to_list(Name) ++ "@" ++ Host).
+
+add_to_cover_file(CoverFileName,Terms,Config) ->
+ DataDir = ?config(data_dir,Config),
+ DefaultFile = filename:join(DataDir,?cover_spec_file),
+ NewFile = filename:join(DataDir,CoverFileName),
+ {ok,_} = file:copy(DefaultFile,NewFile),
+ {ok,Fd} = file:open(NewFile,[append]),
+ lists:foreach(fun(Term) ->
+ file:write(Fd,io_lib:format("~p.~n",[Term]))
+ end,Terms),
+ ok = file:close(Fd),
+ NewFile.
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
new file mode 100644
index 0000000000..e84f545fe8
--- /dev/null
+++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
@@ -0,0 +1,148 @@
+%%--------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2012. 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/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% File: cover_SUITE.erl
+%%
+%% Description:
+%% This file contains the test cases for the code coverage support
+%%
+%% @author Support
+%% @doc Test of code coverage support in common_test
+%% @end
+%%----------------------------------------------------------------------
+%%----------------------------------------------------------------------
+-module(cover_SUITE).
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+
+suite() ->
+ [].
+
+all() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(Case, Config) ->
+ %% try apply(?MODULE,Case,[cleanup,Config])
+ %% catch error:undef -> ok
+ %% end,
+
+ kill_slaves(Case,nodes()),
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% Test cases
+break(_Config) ->
+ test_server:break(""),
+ ok.
+
+default(Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ cover_test_mod:foo(),
+ ok.
+
+slave(Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ cover_test_mod:foo(),
+ N1 = nodename(slave,1),
+ {ok,Node} = ct_slave:start(N1),
+ cover_compiled = rpc:call(Node,code,which,[cover_test_mod]),
+ rpc:call(Node,cover_test_mod,foo,[]),
+ {ok,Node} = ct_slave:stop(N1),
+ ok.
+
+slave_start_slave(Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ cover_test_mod:foo(),
+ N1 = nodename(slave_start_slave,1),
+ N2 = nodename(slave_start_slave,2),
+ {ok,Node} = ct_slave:start(N1),
+ cover_compiled = rpc:call(Node,code,which,[cover_test_mod]),
+ rpc:call(Node,cover_test_mod,foo,[]),
+ {ok,Node2} = rpc:call(Node,ct_slave,start,[N2]),
+ rpc:call(Node2,cover_test_mod,foo,[]),
+ {ok,Node2} = rpc:call(Node,ct_slave,stop,[N2]),
+ {ok,Node} = ct_slave:stop(N1),
+ ok.
+
+cover_node_option(Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ cover_test_mod:foo(),
+ Node = fullname(existing_node),
+ cover_compiled = rpc:call(Node,code,which,[cover_test_mod]),
+ rpc:call(Node,cover_test_mod,foo,[]),
+ ok.
+
+ct_cover_add_remove_nodes(Config) ->
+ cover_compiled = code:which(cover_test_mod),
+ cover_test_mod:foo(),
+ Node = fullname(existing_node),
+ Beam = rpc:call(Node,code,which,[cover_test_mod]),
+ false = (Beam == cover_compiled),
+
+ rpc:call(Node,cover_test_mod,foo,[]), % should not be collected
+ {ok,[Node]} = ct_cover:add_nodes([Node]),
+ cover_compiled = rpc:call(Node,code,which,[cover_test_mod]),
+ rpc:call(Node,cover_test_mod,foo,[]), % should be collected
+ ok = ct_cover:remove_nodes([Node]),
+ rpc:call(Node,cover_test_mod,foo,[]), % should not be collected
+
+ Beam = rpc:call(Node,code,which,[cover_test_mod]),
+
+ ok.
+
+%%%-----------------------------------------------------------------
+%%% Internal
+nodename(Case,N) ->
+ list_to_atom(nodeprefix(Case) ++ integer_to_list(N)).
+
+nodeprefix(Case) ->
+ atom_to_list(?MODULE) ++ "_" ++ atom_to_list(Case) ++ "_node".
+
+
+fullname(Name) ->
+ {ok,Host} = inet:gethostname(),
+ list_to_atom(atom_to_list(Name) ++ "@" ++ Host).
+
+kill_slaves(Case, [Node|Nodes]) ->
+ Prefix = nodeprefix(Case),
+ case lists:prefix(Prefix,atom_to_list(Node)) of
+ true ->
+ rpc:call(Node,erlang,halt,[]);
+ _ ->
+ ok
+ end,
+ kill_slaves(Case,Nodes);
+kill_slaves(_,[]) ->
+ ok.
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_test_mod.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_test_mod.erl
new file mode 100644
index 0000000000..d4f69452c3
--- /dev/null
+++ b/lib/common_test/test/ct_cover_SUITE_data/cover_test_mod.erl
@@ -0,0 +1,4 @@
+-module(cover_test_mod).
+-compile(export_all).
+foo() ->
+ ok.
diff --git a/lib/common_test/test/ct_cover_SUITE_data/test.cover b/lib/common_test/test/ct_cover_SUITE_data/test.cover
new file mode 100644
index 0000000000..a1baa8531c
--- /dev/null
+++ b/lib/common_test/test/ct_cover_SUITE_data/test.cover
@@ -0,0 +1 @@
+{incl_mods,[cover_test_mod]}.
--
cgit v1.2.3
From ef640faa6cffeeb44e4f1e4973720c0abe470246 Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Tue, 23 Oct 2012 17:50:43 +0200
Subject: Include all kernel modules in code coverage analysis
---
lib/kernel/test/kernel.cover | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/kernel/test/kernel.cover b/lib/kernel/test/kernel.cover
index f6967ca651..af1dd7eaad 100644
--- a/lib/kernel/test/kernel.cover
+++ b/lib/kernel/test/kernel.cover
@@ -1,3 +1,3 @@
%% -*- erlang -*-
-{incl_mods,[gen_udp,inet6_udp,inet_res,inet_dns]}.
+{incl_app,kernel,details}.
--
cgit v1.2.3
From 66a6e7caa4b7b64566d08fd5e93ce250773a50a7 Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Wed, 24 Oct 2012 14:52:36 +0200
Subject: [common_test] Add test for OTP-9956
OTP-9956
Test that the test suite itself can be cover compiled, and that
data_dir is still set correctly.
---
lib/common_test/test/ct_cover_SUITE.erl | 76 ++++++++++++++--------
.../test/ct_cover_SUITE_data/cover_SUITE.erl | 8 +++
.../cover_SUITE_data/.gitignore | 0
.../test/ct_cover_SUITE_data/test.cover | 1 -
4 files changed, 57 insertions(+), 28 deletions(-)
create mode 100644 lib/common_test/test/ct_cover_SUITE_data/cover_SUITE_data/.gitignore
delete mode 100644 lib/common_test/test/ct_cover_SUITE_data/test.cover
(limited to 'lib')
diff --git a/lib/common_test/test/ct_cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE.erl
index 55599950c9..bebfce70d0 100644
--- a/lib/common_test/test/ct_cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE.erl
@@ -32,8 +32,8 @@
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
+-define(suite, cover_SUITE).
-define(mod, cover_test_mod).
--define(cover_spec_file,"test.cover").
%%--------------------------------------------------------------------
%% TEST SERVER CALLBACK FUNCTIONS
@@ -76,7 +76,8 @@ all() ->
slave,
slave_start_slave,
cover_node_option,
- ct_cover_add_remove_nodes
+ ct_cover_add_remove_nodes,
+ otp_9956
].
%%--------------------------------------------------------------------
@@ -88,7 +89,7 @@ all() ->
default(Config) ->
{ok,Events} = run_test(default,Config),
false = check_cover(Config),
- check_calls(1,Events),
+ check_calls(Events,1),
ok.
%% Check that cover is stopped when cover_stop option is set to true
@@ -109,14 +110,14 @@ cover_stop_false(Config) ->
%% from both nodes
slave(Config) ->
{ok,Events} = run_test(slave,slave,[],Config),
- check_calls(2,Events),
+ check_calls(Events,2),
ok.
%% Let test node start a slave node which in turn starts another slave
%% node - check that cover is collected from all three nodes
slave_start_slave(Config) ->
{ok,Events} = run_test(slave_start_slave,slave_start_slave,[],Config),
- check_calls(3,Events),
+ check_calls(Events,3),
ok.
%% Start a slave node before test starts - the node is listed in cover
@@ -129,10 +130,11 @@ cover_node_option(Config) ->
{ok,Node} = ct_slave:start(Host,existing_node,
[{erl_flags,"-pa " ++ DataDir}]),
false = check_cover(Node),
- CoverFile = add_to_cover_file("node_opt.cover",[{nodes,[Node]}],Config),
+ CoverSpec = default_cover_file_content() ++ [{nodes,[Node]}],
+ CoverFile = create_cover_file(cover_node_option,CoverSpec,Config),
{ok,Events} = run_test(cover_node_option,cover_node_option,
[{cover,CoverFile}],Config),
- check_calls(2,Events),
+ check_calls(Events,2),
{ok,Node} = ct_slave:stop(existing_node),
ok.
@@ -147,10 +149,18 @@ ct_cover_add_remove_nodes(Config) ->
false = check_cover(Node),
{ok,Events} = run_test(ct_cover_add_remove_nodes,ct_cover_add_remove_nodes,
[],Config),
- check_calls(2,Events),
+ check_calls(Events,2),
{ok,Node} = ct_slave:stop(existing_node),
ok.
+%% Test that the test suite itself can be cover compiled and that
+%% data_dir is set correctly (OTP-9956)
+otp_9956(Config) ->
+ CoverFile = create_cover_file(otp_9956,[{incl_mods,[?suite]}],Config),
+ {ok,Events} = run_test(otp_9956,otp_9956,[{cover,CoverFile}],Config),
+ check_calls(Events,{?suite,otp_9956,1},1),
+ ok.
+
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
@@ -161,12 +171,17 @@ run_test(Label,ExtraOpts,Config) ->
run_test(Label,default,ExtraOpts,Config).
run_test(Label,Testcase,ExtraOpts,Config) ->
DataDir = ?config(data_dir, Config),
- Suite = filename:join(DataDir, "cover_SUITE"),
- DefaultCover = filename:join(DataDir, ?cover_spec_file),
- Cover = proplists:get_value(cover,ExtraOpts,DefaultCover),
+ Suite = filename:join(DataDir, ?suite),
+ CoverFile =
+ case proplists:get_value(cover,ExtraOpts) of
+ undefined ->
+ create_default_cover_file(Label,Config);
+ CF ->
+ CF
+ end,
RestOpts = lists:keydelete(cover,1,ExtraOpts),
{Opts,ERPid} = setup([{suite,Suite},{testcase,Testcase},
- {cover,Cover},{label,Label}] ++ RestOpts, Config),
+ {cover,CoverFile},{label,Label}] ++ RestOpts, Config),
execute(Label, Testcase, Opts, ERPid, Config).
setup(Test, Config) ->
@@ -195,7 +210,7 @@ reformat(Events, EH) ->
events_to_check(Testcase) ->
OneTest =
[{?eh,start_logging,{'DEF','RUNDIR'}}] ++
- [{?eh,tc_done,{cover_SUITE,Testcase,ok}}] ++
+ [{?eh,tc_done,{?suite,Testcase,ok}}] ++
[{?eh,stop_logging,[]}],
%% 2 tests (ct:run_test + script_start) is default
@@ -215,35 +230,42 @@ check_cover(Node) when is_atom(Node) ->
end.
%% Check that each coverlog includes N calls to ?mod:foo/0
-check_calls(N,Events) ->
+check_calls(Events,N) ->
+ check_calls(Events,{?mod,foo,0},N).
+check_calls(Events,MFA,N) ->
CoverLogs =
[filename:join(filename:dirname(TCLog),"all.coverdata") ||
{ct_test_support_eh,
{event,tc_logfile,ct@falco,
- {{cover_SUITE,init_per_suite},TCLog}}} <- Events],
- do_check_logs(N,CoverLogs).
+ {{?suite,init_per_suite},TCLog}}} <- Events],
+ do_check_logs(CoverLogs,MFA,N).
-do_check_logs(N,[CoverLog|CoverLogs]) ->
+do_check_logs([CoverLog|CoverLogs],{Mod,_,_} = MFA,N) ->
{ok,_} = cover:start(),
ok = cover:import(CoverLog),
- {ok,[{{?mod,foo,0},N}]} = cover:analyse(?mod,calls,function),
+ {ok,Calls} = cover:analyse(Mod,calls,function),
ok = cover:stop(),
- do_check_logs(N,CoverLogs);
-do_check_logs(_,[]) ->
+ {MFA,N} = lists:keyfind(MFA,1,Calls),
+ do_check_logs(CoverLogs,MFA,N);
+do_check_logs([],_,_) ->
ok.
fullname(Name) ->
{ok,Host} = inet:gethostname(),
list_to_atom(atom_to_list(Name) ++ "@" ++ Host).
-add_to_cover_file(CoverFileName,Terms,Config) ->
- DataDir = ?config(data_dir,Config),
- DefaultFile = filename:join(DataDir,?cover_spec_file),
- NewFile = filename:join(DataDir,CoverFileName),
- {ok,_} = file:copy(DefaultFile,NewFile),
- {ok,Fd} = file:open(NewFile,[append]),
+default_cover_file_content() ->
+ [{incl_mods,[?mod]}].
+
+create_default_cover_file(Filename,Config) ->
+ create_cover_file(Filename,default_cover_file_content(),Config).
+
+create_cover_file(Filename,Terms,Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ File = filename:join(PrivDir,Filename) ++ ".cover",
+ {ok,Fd} = file:open(File,[write]),
lists:foreach(fun(Term) ->
file:write(Fd,io_lib:format("~p.~n",[Term]))
end,Terms),
ok = file:close(Fd),
- NewFile.
+ File.
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
index e84f545fe8..fdc3323f0a 100644
--- a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
+++ b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE.erl
@@ -122,6 +122,14 @@ ct_cover_add_remove_nodes(Config) ->
ok.
+otp_9956(Config) ->
+ cover_compiled = code:which(?MODULE),
+ DataDir = ?config(data_dir,Config),
+ absolute = filename:pathtype(DataDir),
+ true = filelib:is_dir(DataDir),
+ ok.
+
+
%%%-----------------------------------------------------------------
%%% Internal
nodename(Case,N) ->
diff --git a/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE_data/.gitignore b/lib/common_test/test/ct_cover_SUITE_data/cover_SUITE_data/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/common_test/test/ct_cover_SUITE_data/test.cover b/lib/common_test/test/ct_cover_SUITE_data/test.cover
deleted file mode 100644
index a1baa8531c..0000000000
--- a/lib/common_test/test/ct_cover_SUITE_data/test.cover
+++ /dev/null
@@ -1 +0,0 @@
-{incl_mods,[cover_test_mod]}.
--
cgit v1.2.3
From b6fe934ea73f8eeaaa70b786f53ee6e8f2a52d2c Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Wed, 24 Oct 2012 16:55:45 +0200
Subject: Use code:lib_dir instead of code:which to get application directory
code_SUITE:ext_mod_dep used code:which(kernel) to get the path to the
kernel ebin directory. This failed when kernel was cover compiled,
since code:which then returns 'cover_compiled'. Using code:lib_dir
instead solved the problem.
---
lib/kernel/test/code_SUITE.erl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 5e0300639e..d7424c0c9a 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -684,8 +684,8 @@ ext_mod_dep(Config) when is_list(Config) ->
xref:set_default(s, [{verbose,false},{warnings,false},
{builtins,true},{recurse,true}]),
xref:set_library_path(s, code:get_path()),
- xref:add_directory(s, filename:dirname(code:which(kernel))),
- xref:add_directory(s, filename:dirname(code:which(lists))),
+ xref:add_directory(s, filename:join(code:lib_dir(kernel),"ebin")),
+ xref:add_directory(s, filename:join(code:lib_dir(stdlib),"ebin")),
case catch ext_mod_dep2() of
{'EXIT', Reason} ->
xref:stop(s),
--
cgit v1.2.3
From fe9ed2938a02869b1df9554b32e4c4c453e6995c Mon Sep 17 00:00:00 2001
From: Siri Hansen
Date: Wed, 24 Oct 2012 18:48:11 +0200
Subject: [test_server] Add option {start_cover,false} to
test_server:start_node
By default the test server will start cover on all nodes when the test
is run with code coverage analysis. To make sure cover is not started
on a new node, this option can be set.
This can be useful if the test itself starts cover or if the new node
for some reason can not run cover compiled code.
---
lib/test_server/doc/src/test_server.xml | 14 +++++++++++++-
lib/test_server/src/test_server.erl | 5 ++++-
2 files changed, 17 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/test_server/doc/src/test_server.xml b/lib/test_server/doc/src/test_server.xml
index 5bfa42c36f..841cbfbe91 100644
--- a/lib/test_server/doc/src/test_server.xml
+++ b/lib/test_server/doc/src/test_server.xml
@@ -5,7 +5,7 @@
2007
- 2011
+ 2012
Ericsson AB, All Rights Reserved
@@ -529,6 +529,18 @@ Only valid for peer nodes. Note that slave nodes always
analogy with os:getenv/1), which removes the
environment variable. Only valid for peer nodes. Not
available on VxWorks.