1-module(ttb_helper). %%Nodes control
2-compile(export_all).
3
4%%API
5%%get() -> client:get()
6%%put(X) -> client:put(X)
7%%msgs(N) -> N times client:put(test_msg)
8%%clear() -> restart server
9%%ensure_running() / stop() -> start/stop nodes
10%%get_node(atom) -> return atom@hostname
11
12-define(NODE_CMD(Name),
13	"erl -sname " ++ atom_to_list(Name) ++
14	" -pa .. -pa . -detached -run ttb_helper send_ok").
15-define(REG_NAME, nc_testing).
16
17new_fun() ->
18    fun(_, end_of_trace, _, Dict) -> io:format("~p~n", [dict:to_list(Dict)]);
19       (_, T, _, Dict) -> case element(2, T) of
20                              {Pid, _, _} ->
21                                  dict:update_counter(Pid, 1, Dict);
22                              Pid ->
23                                  dict:update_counter(Pid, 1, Dict)
24                          end
25    end.
26
27new_fun_2() ->
28    fun(_, end_of_trace, _, Dict) -> io:format("~p~n", [dict:to_list(Dict)]);
29       (_, T, _, Dict) ->  case element(2, T) of
30                               {_, Name, _} when is_atom(Name)->
31                                  dict:update_counter(Name, 1, Dict);
32                              Pid ->
33                                  dict:update_counter(Pid, 1, Dict)
34                          end
35
36    end.
37
38
39ensure_running() ->
40    try_start_node(server),
41    try_start_node(client),
42    clear().
43
44try_start_node(Node) ->
45    global:unregister_name(?REG_NAME),
46    global:register_name(?REG_NAME, self()),
47    global:sync(),
48    N = get_node(Node),
49    case net_adm:ping(N) of
50	pong ->
51	    io:format("Node ~p already running~n", [N]);
52	_ ->
53	    io:format("Starting node ~p... ~p ", [Node, os:cmd(?NODE_CMD(Node))]),
54	    recv()
55    end.
56
57clear() ->
58    s(server, stop, []),
59    init().
60
61stop() ->
62    s(init, stop, []),
63    c(init, stop, []).
64
65msgs(N) ->
66    [c(client, put, [test_msg]) || _ <- lists:seq(1, N)],
67    s(server, received, [a,b]),
68    [dbg:flush_trace_port(Node) || Node <- [get_node(client), get_node(server)]].
69
70msgs_ip(N) ->
71    [c(client, put, [test_msg]) || _ <- lists:seq(1, N)],
72    s(server, received, [a,b]),
73    %% This is a very high sleep, it is needed for some of the slower
74    %% test machines. Ideally we would want to be able to react to
75    %% when the actual tcp packets arrive, but I'm not sure that is possible..
76    timer:sleep(5000). %% allow trace messages to arrive over tcp/ip
77
78run() ->
79    ttb({local, "A"}),
80    msgs(2),
81    c(erlang, whereis, [ttbt]).
82
83get() -> c(client, get, []).
84put(Thing) -> c(client, put, [Thing]).
85
86get_node(Node) ->
87    {ok, Host} = inet:gethostname(),
88    list_to_atom(atom_to_list(Node) ++ "@" ++ Host).
89
90trace_setup() ->
91    ttb:p(all, call),
92    ttb:tp(server, received, []),
93    ttb:tp(client, put, []),
94    ttb:tp(client, get, []).
95
96ttb() -> ttb("A").
97ttb(File) ->
98    ttb:tracer([get_node(client), get_node(server)], [{file, File}, resume]),
99    ttb:p(all, [call, timestamp]),
100    ttb:tp(client, put, []),
101    ttb:tp(client, get, []),
102    ttb:tp(server, received, []).
103
104tc() ->
105    TC = example_config_gen:create_trace_case("dummy comment"),
106    Patterns = example_config_gen:create_pattern(client, put, 1, return),
107    Flags = example_config_gen:create_flags(all, call),
108    Merge = example_config_gen:create_merge_conf(show_handler(), "dummy merge comment"),
109    Merge2 = example_config_gen:create_merge_conf(undefined, "dummy merge comment"),
110    TC2 = example_config_gen:add_pattern(Patterns, TC),
111    TC3 = example_config_gen:add_flags(Flags, TC2),
112    TC4 = example_config_gen:add_merge_conf(Merge, TC3),
113    TC5 = example_config_gen:add_merge_conf(Merge2, TC4),
114    example_config_gen:add_nodes([get_node(client), get_node(server)], TC5).
115
116
117show(X) ->
118    io:format(user, "Showing: ~p~n", [X]).
119
120state_handler() ->
121    {fun(_,_,I,S) -> io:format(user, "Got from ~p: ~p~n", [I,S]), S+1 end, 0}.
122
123show_handler() ->
124    {fun(A,B,_,_) -> io:format(A, "~p~n", [B]) end, []}.
125
126opts() ->
127    [[get_node(client), get_node(server)],
128     [{server, received, '_', []},
129      {client, put, '_', []},
130      {client, get, '_', []}],
131     {all, call},
132     [{file, "TEST"}]].
133
134overload_check(check) ->
135    true;
136overload_check(_) ->
137    ok.
138%%%Internal
139s(M, F, A) -> rpc:call(get_node(server), M, F, A).
140c(M, F, A) -> rpc:call(get_node(client), M, F, A).
141
142send_ok() ->
143    pong = net_adm:ping(get_node(test)),
144    global:sync(),
145    global:send(?REG_NAME, node()).
146
147init() ->
148    True = s(server, start, []),
149    io:format("ok1: ~p~n", [True]),
150    true = c(client, init, [get_node(server)]).
151
152recv() ->
153    receive
154	Node ->
155	    io:format("Node ~p ready.~n", [Node]),
156            ok
157    after 5000 ->
158	    io:format("Startup failed~n",[]),
159	    throw(startup_failed)
160    end.
161