diff options
| author | Siri Hansen <[email protected]> | 2012-10-12 15:49:22 +0200 | 
|---|---|---|
| committer | Siri Hansen <[email protected]> | 2012-10-30 11:17:57 +0100 | 
| commit | 8179e41007922c059b8f9441f563edf694b8b315 (patch) | |
| tree | 5aa16454a445071af2f981ffd53c4f17b8bfeef3 | |
| parent | 6b57abc785818bccf8ee615d3071dc24fa54daca (diff) | |
| download | otp-8179e41007922c059b8f9441f563edf694b8b315.tar.gz otp-8179e41007922c059b8f9441f563edf694b8b315.tar.bz2 otp-8179e41007922c059b8f9441f563edf694b8b315.zip  | |
[cover] Add support for test_server
OTP-10523
* Added cover:flush(Nodes), which will fetch data from remote nodes
  without stopping cover on those nodes.
* Added cover:get_main_node(), which returns the node name of the main
  node. This is used by test_server to avoid {error,not_main_node}
  when a slave starts another slave (e.g. in test_server's own tests).
| -rw-r--r-- | lib/tools/doc/src/cover.xml | 15 | ||||
| -rw-r--r-- | lib/tools/src/cover.erl | 31 | ||||
| -rw-r--r-- | lib/tools/test/cover_SUITE.erl | 17 | 
3 files changed, 59 insertions, 4 deletions
diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml index 683acc025d..be0fd5bd47 100644 --- a/lib/tools/doc/src/cover.xml +++ b/lib/tools/doc/src/cover.xml @@ -5,7 +5,7 @@    <header>      <copyright>        <year>2001</year> -      <year>2011</year> +      <year>2012</year>        <holder>Ericsson AB, All Rights Reserved</holder>      </copyright>      <legalnotice> @@ -104,6 +104,8 @@        remove nodes. The same Cover compiled code will be loaded on each        node, and analysis will collect and sum up coverage data results        from all nodes.</p> +    <p>To only collect data from remote nodes without stopping +      <c>cover</c> on those nodes, use <c>cover:flush/1</c></p>    </description>    <funcs>      <func> @@ -477,6 +479,17 @@            remote nodes is fetched and stored on the main node.</p>        </desc>      </func> +    <func> +      <name>flush(Nodes) -> ok | {error,not_main_node}</name> +      <fsummary>Collect cover data from remote nodes.</fsummary> +      <type> +        <v>Nodes = [atom()]</v> +      </type> +      <desc> +        <p>Fetch data from the Cover database on the remote nodes and +        stored on the main node.</p> +      </desc> +    </func>    </funcs>    <section> diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index e21bd1b88c..fb65206938 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% Copyright Ericsson AB 2001-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 @@ -81,8 +81,9 @@  	 export/1, export/2, import/1,  	 modules/0, imported/0, imported_modules/0, which_nodes/0, is_compiled/1,  	 reset/1, reset/0, +	 flush/1,  	 stop/0, stop/1]). --export([remote_start/1]). +-export([remote_start/1,get_main_node/0]).  %-export([bump/5]).  -export([transform/4]). % for test purposes @@ -497,6 +498,19 @@ stop(Node) when is_atom(Node) ->  stop(Nodes) ->      call({stop,remove_myself(Nodes,[])}). +%% flush(Nodes) -> ok | {error,not_main_node} +%%   Nodes = [Node] | Node +%%   Node = atom() +%%   Error = {not_cover_compiled,Module} +flush(Node) when is_atom(Node) -> +    flush([Node]); +flush(Nodes) -> +    call({flush,remove_myself(Nodes,[])}). + +%% Used by test_server only. Not documented. +get_main_node() -> +    call(get_main_node). +  %% bump(Module, Function, Arity, Clause, Line)  %%   Module = Function = atom()  %%   Arity = Clause = Line = integer() @@ -710,6 +724,11 @@ main_process_loop(State) ->  	    State1 = State#main_state{nodes=State#main_state.nodes--Nodes},  	    main_process_loop(State1); +	{From, {flush,Nodes}} -> +	    remote_collect('_',Nodes,false), +	    reply(From, ok), +	    main_process_loop(State); +  	{From, stop} ->  	    lists:foreach(  	      fun(Node) ->  @@ -796,6 +815,10 @@ main_process_loop(State) ->  	    State1 = State#main_state{nodes=State#main_state.nodes--[node(Pid)]},  	    main_process_loop(State1); +	{From, get_main_node} -> +	    reply(From, node()), +	    main_process_loop(State); +  	get_status ->  	    io:format("~p~n",[State]),  	    main_process_loop(State) @@ -852,6 +875,10 @@ remote_process_loop(State) ->              unregister(?SERVER),  	    remote_reply(State#remote_state.main_node, ok); +	{From, get_main_node} -> +	    reply(From, State#remote_state.main_node), +	    remote_process_loop(State); +  	get_status ->  	    io:format("~p~n",[State]),  	    remote_process_loop(State); diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index c2c708d806..950c4ddbcb 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -326,14 +326,16 @@ distribution(Config) when is_list(Config) ->      ?line {ok,N1} = ?t:start_node(cover_SUITE_distribution1,slave,[]),      ?line {ok,N2} = ?t:start_node(cover_SUITE_distribution2,slave,[]),      ?line {ok,N3} = ?t:start_node(cover_SUITE_distribution3,slave,[]), +    ?line {ok,N4} = ?t:start_node(cover_SUITE_distribution4,slave,[]),      %% Check that an already compiled module is loaded on new nodes      ?line {ok,f} = cover:compile(f), -    ?line {ok,[_,_,_]} = cover:start(nodes()), +    ?line {ok,[_,_,_,_]} = cover:start(nodes()),      ?line cover_compiled = code:which(f),      ?line cover_compiled = rpc:call(N1,code,which,[f]),      ?line cover_compiled = rpc:call(N2,code,which,[f]),      ?line cover_compiled = rpc:call(N3,code,which,[f]), +    ?line cover_compiled = rpc:call(N4,code,which,[f]),      %% Check that a node cannot be started twice      ?line {ok,[]} = cover:start(N2), @@ -351,6 +353,7 @@ distribution(Config) when is_list(Config) ->      ?line cover_compiled = rpc:call(N1,code,which,[v]),      ?line cover_compiled = rpc:call(N2,code,which,[v]),      ?line cover_compiled = rpc:call(N3,code,which,[v]), +    ?line cover_compiled = rpc:call(N4,code,which,[v]),      %% this is lost when the node is killed      ?line rpc:call(N3,f,f2,[]), @@ -385,6 +388,18 @@ distribution(Config) when is_list(Config) ->      %% reset on the remote node(s))      ?line check_f_calls(1,1), +    %% Another checn that data is not fetched twice, i.e. when flushed +    %% then analyse should not add the same data again. +    ?line rpc:call(N4,f,f2,[]), +    ?line ok = cover:flush(N4), +    ?line check_f_calls(1,2), + +    %% Check that flush collects data so calls are not lost if node is killed +    ?line rpc:call(N4,f,f2,[]), +    ?line ok = cover:flush(N4), +    ?line rpc:call(N4,erlang,halt,[]), +    ?line check_f_calls(1,3), +      %% Check that stop() unloads on all nodes      ?line ok = cover:stop(),      ?line timer:sleep(100), %% Give nodes time to unload on slow machines.  | 
