-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(500). %% 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.