inviso_tool_suite.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 968 行 · 第 1/3 页

ERL
968
字号
			   Nodes),
    ?l lists:foreach(fun(P)->
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[P,flags]],
					{flags,[call]},
					10),
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[{math,module_info,1},traced]],
					{traced,local},
					10)
		     end,
		     TestProcs),

    %% Create a history file.
    ?l AbsFileName=filename:join(PrivDir,"dist_history.his"),
    ?l {ok,AbsFileName}=inviso_tool:save_history(AbsFileName),
    ?l {ok,_FileInfo}=file:read_file_info(AbsFileName),

    %% Stop the tracing of the test process.
    ?l inviso_tool:sync_dtc(tracecase1,id1),
    ?l lists:foreach(fun(P)->
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[P,flags]],
					{flags,[]},
					10),
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[{math,module_info,1},traced]],
					{traced,false},
					10)
		     end,
		     TestProcs),
    %% Now stop the session.
    ?l stop_inviso_tool_session(CNode,1,Nodes),
    %% Restart the session using the previously saved history.
    ?l {ok,{2,_InvisoReturn}}=inviso_tool:restore_session(AbsFileName),
    ?l ok=poll(inviso_tool,get_activities,[],{ok,[]},10),
    %% Check that the history has been redone.
    ?l lists:foreach(fun(P)->
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[P,flags]],
					{flags,[call]},
					10),
			     ?l ok=poll(rpc,
					call,
					[node(P),erlang,trace_info,[{math,module_info,1},traced]],
					{traced,local},
					10)
		     end,
		     TestProcs),
    ?l {ok,_NodeResults1}=inviso_tool:inviso(tpl,[math,module_info,0,[]]),
    %% Also check that the restored history now is our history.
    ?l {ok,{AutostartData,_NodeResults2}}=
	inviso_tool:get_autostart_data(Nodes,{dependency,infinity}),
    ?l FNameInit=filename:join(DataDir,"tracecase_init.trc"),
    ?l FName1=filename:join(DataDir,"tracecase1_on.trc"),
    ?l [{file,{FNameInit,[]}},
	{file,{FName1,[{'ProcessName',inviso_tool_test_proc}]}},
	{binary,_}]=AutostartData,
    ?l stop_inviso_tool_session(CNode,2,Nodes),
    ?l NodeCounters=lists:foldl(fun(N,Acc)->[{_,X}]=rpc:call(N,ets,lookup,[test_proc_tab,counter]),
					    [{N,X}|Acc]
				end,
				[],
				Nodes),
    %% Remove the patterns set by the initial tracecase.
    ?l lists:foreach(fun(N)->rpc:call(N,
				      erlang,
				      trace_pattern,
				      [{lists,module_info,1},false,[local]])
		     end,
		     Nodes),
    %% Now we want to test that we can do restore on the current session.
    ?l {ok,{3,_InvisoReturn2}}=inviso_tool:restore_session(),
    ?l ok=poll(inviso_tool,get_activities,[],{ok,[]},10),
    %% Check that the history has been redone yet again.
    ?l lists:foreach(fun({N,X})->
			     [{counter,Y}]=
				 rpc:call(N,ets,lookup,[test_proc_tab,counter]),
			     Y=X+1
		     end,
		     NodeCounters),
    ?l lists:foreach(fun(N)->
			     {traced,local}=
				 rpc:call(N,erlang,trace_info,[{lists,module_info,1},traced])
		     end,
		     Nodes),

    ?l {error,session_active}=inviso_tool:reset_nodes(Nodes),
    %% Now stop the session and check that we can clear the nodes.
    ?l stop_inviso_tool_session(CNode,3,Nodes),
    ?l lists:foreach(fun(N)->{traced,local}=
				 rpc:call(N,erlang,trace_info,[{lists,module_info,1},traced])
		     end,
		     Nodes),
    ?l {ok,NodeResults3}=inviso_tool:reset_nodes(Nodes),
    ?l true=check_noderesults(Nodes,{ok,{new,running}},NodeResults3),
    ?l lists:foreach(fun(N)->{traced,false}=
				 rpc:call(N,erlang,trace_info,[{lists,module_info,1},traced])
		     end,
		     Nodes),
    ?l stop_inviso_tool(CNode,Nodes),
    ok.

%% ==============================================================================
%% Help functions.
%% ==============================================================================
    
%% Help function starting the inviso_tool with runtime components at Nodes
%% and the inviso control component at CNode. OtherOpts shall contain all other
%% necessary options except nodes and c_node. Returns nothing significant.
start_inviso_tool(Nodes,CNode,OtherOpts) -> 
    ?l Options=[{nodes,Nodes},{c_node,CNode}|OtherOpts],
    ?l {ok,_Pid}=inviso_tool:start(Options),
    ?l ok=poll(erlang,whereis,[inviso_tool],fun(X)->true=is_pid(X) end,10),
    %% Now the runtime components shall be started but no tracing started.
    ?l lists:foreach(fun(N)->ok=poll(rpc,
				     call,
				     [CNode,inviso,get_status,[[N]]],
				     fun({ok,[{_N,{ok,{new,running}}}]})->true;
					(_) ->false
				     end,
				     10)
		     end,
		     Nodes),
    true.
%% -----------------------------------------------------------------------------

%% Stops the inviso_tool.
stop_inviso_tool(CNode,Nodes) ->
    ?l {ok,_NodeResults}=inviso_tool:stop(),
    ?l ok=poll(erlang,whereis,[inviso_tool],undefined,10),
    %% Check that all inviso components are gone.
    ?l ok=poll(rpc,call,[CNode,erlang,whereis,[inviso_c]],undefined,10),
    ?l lists:foreach(fun(N)->ok=poll(rpc,
				     call,
				     [N,erlang,whereis,[inviso_rt]],
				     undefined,
				     10)
		     end,
		     Nodes),
    true.
%% -----------------------------------------------------------------------------

%% Starts a trace session. Returns the InvisoReturn part of the return value.
start_inviso_tool_session(CNode,MoreTDGargs,SessionNr,Nodes) ->
    ?l {ok,{SessionNr,InvisoReturn}}=inviso_tool:start_session(MoreTDGargs),
    %% Now check that all nodes are tracing.
    ?l lists:foreach(fun(N)->ok=poll(rpc,
				     call,
				     [CNode,inviso,get_status,[[N]]],
				     fun({ok,[{_N,{ok,{tracing,running}}}]})->true;
					(_) ->false
				     end,
				     10),
			     %% Check that the initial trace case is executed.
			     ?l ok=poll(rpc,
					call,
					[N,erlang,trace_info,[{lists,module_info,1},traced]],
					{traced,local},
					10)
		     end,
		     Nodes),
    InvisoReturn.
%% -----------------------------------------------------------------------------

%% Stops a trace session.
stop_inviso_tool_session(CNode,SessionNr,Nodes) ->
    ?l {ok,{SessionNr,NodeResults}}=inviso_tool:stop_session(),
    ?l true=check_noderesults(Nodes,ok,NodeResults),
    %% Now the runtimes shall not be tracing any longer.
    ?l lists:foreach(fun(N)->ok=poll(rpc,
				     call,
				     [CNode,inviso,get_status,[[N]]],
				     fun({ok,[{_N,{ok,{idle,running}}}]})->true;
					(_) ->false
				     end,
				     10)
		     end,
		     Nodes),
    true.
%% -----------------------------------------------------------------------------

%% Help function checking that there is a Result for each node in Nodes.
%% Returns 'true' if successful.
check_noderesults(Nodes,Fun,[{Node,Result}|Rest]) when function(Fun) ->
    case Fun({Node,Result}) of
	true ->
	    case lists:member(Node,Nodes) of
		true ->
		    check_noderesults(lists:delete(Node,Nodes),Fun,Rest);
		false ->                     % Not good.
		    unknown_node_in_returnvalue
	    end;
	_ ->
	    illegal_result
    end;
check_noderesults(Nodes,Result,[{Node,Result}|Rest]) ->
    case lists:member(Node,Nodes) of
	true ->
	    check_noderesults(lists:delete(Node,Nodes),Result,Rest);
	false ->                             % Not good.
	    unknown_node_in_returnvalue
    end;
check_noderesults([],_,[]) ->
    true;
check_noderesults(X,Y,Z) ->
    io:format("Bad arguments to check noderesults:~w~n~w~n~w~n",[X,Y,Z]),
    false.
%% ------------------------------------------------------------------------------

%% Help function which waits for a function call to become Result. This is useful
%% if what we are waiting for can happend independantly of indications we have
%% access to.
poll(_,_,_,_,0) ->
    error;
poll(M,F,Args,Result,Times) ->
    try apply(M,F,Args) of
	What when function(Result) ->
	    case Result(What) of
		true ->
		    ok;
		X ->
		    io:format("Poll: ~w:~w ~w ~w ~w~n",[M,F,Args,Result,X]),
		    timer:sleep(100),
		    poll(M,F,Args,Result,Times-1)
	    end;
	Result ->
	    ok;
	X ->
	    io:format("Poll: ~w:~w ~w ~w ~w~n",[M,F,Args,Result,X]),
	    timer:sleep(100),
	    poll(M,F,Args,Result,Times-1)
    catch
	error:Reason ->
	    io:format("Apply in suite-function poll/5 failed, ~w~n",[Reason]),
	    timer:sleep(100),
	    poll(M,F,Args,Result,Times-1)
    end.
%% ------------------------------------------------------------------------------

%% ------------------------------------------------------------------------------
%% The Tracer Data Generator function.
%% ------------------------------------------------------------------------------

-define(I2L(Arg),integer_to_list(Arg)).

tdg(Node,{{Y,Mo,D},{H,Mi,S}},PrivDir) ->
    NameStr=atom_to_list(Node)++"_"++?I2L(Y)++"-"++?I2L(Mo)++"-"++?I2L(D)++"_"++
	?I2L(H)++"-"++?I2L(Mi)++"-"++?I2L(S),
    LogTD={file,filename:join(PrivDir,NameStr++".log")},
    TiTD={file,filename:join(PrivDir,NameStr++".ti")},
    [{trace,LogTD},{ti,TiTD}].
%% ------------------------------------------------------------------------------


%% ------------------------------------------------------------------------------
%% Handling the test server Config.
%% ------------------------------------------------------------------------------

insert_remotenode_config(Name,Node,Config) ->
    [{remotenode,Name,Node}|Config].
%% ------------------------------------------------------------------------------

insert_timetraphandle_config(Handle,Config) ->
    [{timetraphandle,Handle}|Config].
%% ------------------------------------------------------------------------------

get_remotenode_config(Name,Config) ->
    {value,{_,_,Node}}=lists:keysearch(Name,2,Config),
    Node.
%% ------------------------------------------------------------------------------

get_timetraphandle_config(Config) ->
    {value,{_,Handle}}=lists:keysearch(timetraphandle,1,Config),
    Handle.
%% ------------------------------------------------------------------------------

get_remotenodes_config([{remotenode,_Name,Node}|Config]) ->
    [Node|get_remotenodes_config(Config)];
get_remotenodes_config([_|Config]) ->
    get_remotenodes_config(Config);
get_remotenodes_config([]) ->
    [].
%% ------------------------------------------------------------------------------

remove_remotenode_config(Name,Config) ->
    lists:keydelete(Name,2,Config).
%% ------------------------------------------------------------------------------

remove_timetraphandle_config(Config) ->
    lists:keydelete(timetraphandle,1,Config).
%% ------------------------------------------------------------------------------


%% ==============================================================================
%% Code for a test process which can be started.
%% ==============================================================================

%% The test proc is also responsible for owning a side effect table. The table
%% can be updated by tracecases.
test_proc_init() ->
    register(inviso_tool_test_proc,self()),
    ets:new(test_proc_tab,[named_table,public]),
    ets:insert(test_proc_tab,{counter,0}),
    test_proc_loop().

test_proc_loop() ->
    receive
	{apply,M,F,Args} ->
	    apply(M,F,Args),
	    test_proc_loop();
	X ->
	    io:format("Got ~w~n",[X]),
	    test_proc_loop()
    end.
%% ------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?