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 + -
显示快捷键?