-module(ttb_helper). %%Nodes control
-compile(export_all).
%%API
%%get() -> client:get()
%%put(X) -> client:put(X)
%%msgs(N) -> N times client:put(test_msg)
%%clear() -> restart server
%%ensure_running() / stop() -> start/stop nodes
%%get_node(atom) -> return atom@hostname
-define(NODE_CMD(Name),
"erl -sname " ++ atom_to_list(Name) ++
" -pa .. -pa . -detached -run ttb_helper send_ok").
-define(REG_NAME, nc_testing).
new_fun() ->
fun(_, end_of_trace, _, Dict) -> io:format("~p~n", [dict:to_list(Dict)]);
(_, T, _, Dict) -> case element(2, T) of
{Pid, _, _} ->
dict:update_counter(Pid, 1, Dict);
Pid ->
dict:update_counter(Pid, 1, Dict)
end
end.
new_fun_2() ->
fun(_, end_of_trace, _, Dict) -> io:format("~p~n", [dict:to_list(Dict)]);
(_, T, _, Dict) -> case element(2, T) of
{_, Name, _} when is_atom(Name)->
dict:update_counter(Name, 1, Dict);
Pid ->
dict:update_counter(Pid, 1, Dict)
end
end.
ensure_running() ->
try_start_node(server),
try_start_node(client),
clear().
try_start_node(Node) ->
global:unregister_name(?REG_NAME),
global:register_name(?REG_NAME, self()),
global:sync(),
N = get_node(Node),
case net_adm:ping(N) of
pong ->
io:format("Node ~p already running~n", [N]);
_ ->
io:format("Starting node ~p... ~p ", [Node, os:cmd(?NODE_CMD(Node))]),
recv()
end.
clear() ->
s(server, stop, []),
init().
stop() ->
s(init, stop, []),
c(init, stop, []).
msgs(N) ->
[c(client, put, [test_msg]) || _ <- lists:seq(1, N)],
s(server, received, [a,b]),
[dbg:flush_trace_port(Node) || Node <- [get_node(client), get_node(server)]].
msgs_ip(N) ->
[c(client, put, [test_msg]) || _ <- lists:seq(1, N)],
s(server, received, [a,b]),
timer:sleep(100). %% allow trace messages to arrive over tcp/ip
run() ->
ttb({local, "A"}),
msgs(2),
c(erlang, whereis, [ttbt]).
get() -> c(client, get, []).
put(Thing) -> c(client, put, [Thing]).
get_node(Node) ->
{ok, Host} = inet:gethostname(),
list_to_atom(atom_to_list(Node) ++ "@" ++ Host).
trace_setup() ->
ttb:p(all, call),
ttb:tp(server, received, []),
ttb:tp(client, put, []),
ttb:tp(client, get, []).
ttb() -> ttb("A").
ttb(File) ->
ttb:tracer([get_node(client), get_node(server)], [{file, File}, resume]),
ttb:p(all, [call, timestamp]),
ttb:tp(client, put, []),
ttb:tp(client, get, []),
ttb:tp(server, received, []).
tc() ->
TC = example_config_gen:create_trace_case("dummy comment"),
Patterns = example_config_gen:create_pattern(client, put, 1, return),
Flags = example_config_gen:create_flags(all, call),
Merge = example_config_gen:create_merge_conf(show_handler(), "dummy merge comment"),
Merge2 = example_config_gen:create_merge_conf(undefined, "dummy merge comment"),
TC2 = example_config_gen:add_pattern(Patterns, TC),
TC3 = example_config_gen:add_flags(Flags, TC2),
TC4 = example_config_gen:add_merge_conf(Merge, TC3),
TC5 = example_config_gen:add_merge_conf(Merge2, TC4),
example_config_gen:add_nodes([get_node(client), get_node(server)], TC5).
show(X) ->
io:format(user, "Showing: ~p~n", [X]).
state_handler() ->
{fun(_,_,I,S) -> io:format(user, "Got from ~p: ~p~n", [I,S]), S+1 end, 0}.
show_handler() ->
{fun(A,B,_,_) -> io:format(A, "~p~n", [B]) end, []}.
opts() ->
[[get_node(client), get_node(server)],
[{server, received, '_', []},
{client, put, '_', []},
{client, get, '_', []}],
{all, call},
[{file, "TEST"}]].
overload_check(check) ->
true;
overload_check(_) ->
ok.
%%%Internal
s(M, F, A) -> rpc:call(get_node(server), M, F, A).
c(M, F, A) -> rpc:call(get_node(client), M, F, A).
send_ok() ->
pong = net_adm:ping(get_node(test)),
global:sync(),
global:send(?REG_NAME, node()).
init() ->
True = s(server, start, []),
io:format("ok1: ~p~n", [True]),
true = c(client, init, [get_node(server)]).
recv() ->
receive
Node ->
io:format("Node ~p ready.~n", [Node]),
ok
after 5000 ->
io:format("Startup failed~n",[]),
throw(startup_failed)
end.