From e8fa9bb9e4c9bbd38371dc47791fd4c1f3d932ff Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 4 May 2016 14:55:45 +0200 Subject: runtime_tools: Add send tpe testcase --- lib/runtime_tools/test/dbg_SUITE.erl | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'lib/runtime_tools/test/dbg_SUITE.erl') diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl index 9c9d6ca352..db4aad7341 100644 --- a/lib/runtime_tools/test/dbg_SUITE.erl +++ b/lib/runtime_tools/test/dbg_SUITE.erl @@ -22,6 +22,7 @@ %% Test functions -export([all/0, suite/0, big/1, tiny/1, simple/1, message/1, distributed/1, port/1, + send/1, ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1, ip_port_busy/1, wrap_port/1, wrap_port_time/1, with_seq_trace/1, dead_suspend/1, local_trace/1, @@ -39,6 +40,7 @@ suite() -> all() -> [big, tiny, simple, message, distributed, port, ip_port, + send, file_port, file_port2, file_port_schedfix, ip_port_busy, wrap_port, wrap_port_time, with_seq_trace, dead_suspend, local_trace, saved_patterns, tracer_exit_on_stop, @@ -151,6 +153,74 @@ message(Config) when is_list(Config) -> {trace,S,call,{dbg,ln,[]},S}] = flush(), ok. +send(Config) when is_list(Config) -> + {ok, _} = start(), + try + S = self(), + Rcvr = spawn_link(fun F() -> + receive M -> + S ! M, + F() + end + end), + + {ok, [{matched, _, 1}]} = dbg:p(Rcvr, send), + R1 = Rcvr ! make_ref(), + receive R1 -> ok end, + [{trace, Rcvr, send, R1, S}] = flush(), + + {ok, [{matched, _node, 1}, {saved, 1}]} = dbg:tpe(send, [{[S,'_'],[],[]}]), + R2 = Rcvr ! make_ref(), + receive R2 -> ok end, + [{trace, Rcvr, send, R2, S}] = flush(), + + {ok, [{matched, _node, 1}, {saved, 2}]} = + dbg:tpe(send, [{['$1','_'],[{'==','$1',{self}}],[]}]), + R3 = Rcvr ! make_ref(), + receive R3 -> ok end, + [] = flush(), + + {ok, [{matched, _node, 1}, {saved, 3}]} = + dbg:tpe(send, [{['_','_'],[{'==',Rcvr,{self}}],[]}]), + R4 = Rcvr ! make_ref(), + receive R4 -> ok end, + [{trace, Rcvr, send, R4, S}] = flush(), + + {ok, [{matched, _node, 1}, {saved, 4}]} = + dbg:tpe(send, [{['_','_'],[{'==',Rcvr,{self}}],[{message, hello}]}]), + R5 = Rcvr ! make_ref(), + receive R5 -> ok end, + [{trace, Rcvr, send, R5, S, hello}] = flush(), + + {ok, [{matched, _node, 1}, {saved, 2}]} = dbg:tpe(send, 2), + R6 = Rcvr ! make_ref(), + receive R6 -> ok end, + [] = flush(), + + {ok, [{matched, _node, 1}]} = dbg:ctpe(send), + R7 = Rcvr ! make_ref(), + receive R7 -> ok end, + [{trace, Rcvr, send, R7, S, hello}] = flush(), + + R8 = make_ref(), + {ok, [{matched, _node, 1}, {saved, 5}]} = + dbg:tpe(send, [{['_','$2'],[{'==',R8,{element, 1, {element, 2, '$2'}}}], + [{message, hello}]}]), + Msg1 = Rcvr ! {test, {R8}, <<0:(8*1024)>>}, + receive Msg1 -> ok end, + [{trace, Rcvr, send, Msg1, S, hello}] = flush(), + + R9 = make_ref(), + Msg2 = Rcvr ! {test, {R9}, <<0:(8*1024)>>}, + receive Msg2 -> ok end, + [] = flush(), + + ok + + after + stop() + end. + %% Simple test of distributed tracing distributed(Config) when is_list(Config) -> {ok, _} = start(), @@ -859,6 +929,17 @@ flush(Acc) -> Acc end. +flush_trace() -> + flush_trace([]). +flush_trace(Acc) -> + receive + X when element(1,X) =:= trace; + element(1,X) =:= trace_ts + -> flush_trace(Acc ++ [X]) + after 1000 -> + Acc + end. + start() -> stop(), dbg:tracer(process, {fun myhandler/2, self()}). -- cgit v1.2.3 From 9265763bafb2e744a42693686a14fa214ebef261 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Tue, 3 May 2016 14:50:48 +0200 Subject: runtime_tools: more dbg send trace pattern tests --- lib/runtime_tools/test/dbg_SUITE.erl | 152 +++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 61 deletions(-) (limited to 'lib/runtime_tools/test/dbg_SUITE.erl') diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl index db4aad7341..4374141157 100644 --- a/lib/runtime_tools/test/dbg_SUITE.erl +++ b/lib/runtime_tools/test/dbg_SUITE.erl @@ -155,65 +155,76 @@ message(Config) when is_list(Config) -> send(Config) when is_list(Config) -> {ok, _} = start(), + Node = start_slave(), + rpc:call(Node, code, add_patha, + [filename:join(proplists:get_value(data_dir, Config), "..")]), try - S = self(), - Rcvr = spawn_link(fun F() -> - receive M -> - S ! M, - F() - end - end), + Echo = fun F() -> + receive {From, M} -> + From ! M, + F() + end + end, + Rcvr = spawn_link(Echo), + RemoteRcvr = spawn_link(Node, Echo), {ok, [{matched, _, 1}]} = dbg:p(Rcvr, send), - R1 = Rcvr ! make_ref(), - receive R1 -> ok end, - [{trace, Rcvr, send, R1, S}] = flush(), - {ok, [{matched, _node, 1}, {saved, 1}]} = dbg:tpe(send, [{[S,'_'],[],[]}]), - R2 = Rcvr ! make_ref(), - receive R2 -> ok end, - [{trace, Rcvr, send, R2, S}] = flush(), + send_test(Rcvr, make_ref(), true), + + %% Test that the test case process is the receiving process + send_test(Rcvr, [{[self(),'_'],[],[]}]), + %% Test that self() is not the receiving process {ok, [{matched, _node, 1}, {saved, 2}]} = dbg:tpe(send, [{['$1','_'],[{'==','$1',{self}}],[]}]), - R3 = Rcvr ! make_ref(), - receive R3 -> ok end, - [] = flush(), - - {ok, [{matched, _node, 1}, {saved, 3}]} = - dbg:tpe(send, [{['_','_'],[{'==',Rcvr,{self}}],[]}]), - R4 = Rcvr ! make_ref(), - receive R4 -> ok end, - [{trace, Rcvr, send, R4, S}] = flush(), - - {ok, [{matched, _node, 1}, {saved, 4}]} = - dbg:tpe(send, [{['_','_'],[{'==',Rcvr,{self}}],[{message, hello}]}]), - R5 = Rcvr ! make_ref(), - receive R5 -> ok end, - [{trace, Rcvr, send, R5, S, hello}] = flush(), - - {ok, [{matched, _node, 1}, {saved, 2}]} = dbg:tpe(send, 2), - R6 = Rcvr ! make_ref(), - receive R6 -> ok end, - [] = flush(), + send_test(Rcvr, make_ref(), false), + + %% Test that self() is the sending process + send_test(Rcvr, [{['_','_'],[{'==',Rcvr,{self}}],[]}]), + + %% Test attaching a message + send_test(Rcvr, [{['_','_'],[{'==',Rcvr,{self}}],[{message, hello}]}], + make_ref(), hello), + + %% Test using a saved trace pattern + send_test(Rcvr, 2, make_ref(), false), + %% Test clearing of trace pattern {ok, [{matched, _node, 1}]} = dbg:ctpe(send), - R7 = Rcvr ! make_ref(), - receive R7 -> ok end, - [{trace, Rcvr, send, R7, S, hello}] = flush(), - - R8 = make_ref(), - {ok, [{matched, _node, 1}, {saved, 5}]} = - dbg:tpe(send, [{['_','$2'],[{'==',R8,{element, 1, {element, 2, '$2'}}}], - [{message, hello}]}]), - Msg1 = Rcvr ! {test, {R8}, <<0:(8*1024)>>}, - receive Msg1 -> ok end, - [{trace, Rcvr, send, Msg1, S, hello}] = flush(), - - R9 = make_ref(), - Msg2 = Rcvr ! {test, {R9}, <<0:(8*1024)>>}, - receive Msg2 -> ok end, - [] = flush(), + send_test(Rcvr, make_ref(), true), + + %% Test complex message inspection + Ref = make_ref(), + send_test(Rcvr, + [{['_','$2'],[{'==',Ref,{element,1,{element,2,'$2'}}}],[]}], + {test, {Ref}, <<0:(8*1024)>>}, true), + + send_test(Rcvr, {test, {make_ref()}, <<0:(8*1024)>>}, false), + + %% Test send to remote process + remote_send_test(Rcvr, RemoteRcvr, [], make_ref(), true), + + remote_send_test(Rcvr, RemoteRcvr, + [{['$1','_'],[{'==',{node, '$1'},{node}}],[]}], + make_ref(), false), + + remote_send_test(Rcvr, RemoteRcvr, + [{['$1','_'],[{'==',{node, '$1'},Node}],[]}], + make_ref(), true), + + %% Test that distributed dbg works + dbg:tracer(Node, process, {fun myhandler/2, self()}), + Rcvr2 = spawn_link(Echo), + RemoteRcvr2 = spawn_link(Node, Echo), + dbg:p(Rcvr2, [send]), + dbg:p(RemoteRcvr2, [send]), + dbg:tpe(send, [{['_', hej],[],[]}]), + + send_test(Rcvr2, make_ref(), false), + send_test(RemoteRcvr2, make_ref(), false), + send_test(Rcvr2, hej, true), + send_test(RemoteRcvr2, hej, true), ok @@ -221,6 +232,36 @@ send(Config) when is_list(Config) -> stop() end. +send_test(Pid, Pattern, Msg, TraceEvent) -> + {ok, [{matched, _, _}, _]} = dbg:tpe(send, Pattern), + send_test(Pid, Msg, TraceEvent). +send_test(Pid, Pattern) -> + send_test(Pid, Pattern, make_ref(), true). +send_test(Pid, Msg, TraceEvent) -> + S = self(), + Pid ! {S, Msg}, + receive Msg -> ok end, + send_test_rcv(Pid, Msg, S, TraceEvent). + +remote_send_test(Pid, RPid, Pattern, Msg, TraceEvent) -> + dbg:tpe(send, Pattern), + TMsg = {self(), Msg}, + Pid ! {RPid, TMsg}, + receive Msg -> ok end, + send_test_rcv(Pid, TMsg, RPid, TraceEvent). + +send_test_rcv(Pid, Msg, S, TraceEvent) -> + case flush() of + [] when not TraceEvent -> + ok; + [{trace, Pid, send, Msg, S}] when TraceEvent -> + ok; + [{trace, Pid, send, Msg, S, Message}] when TraceEvent == Message -> + ok; + Else -> + ct:fail({got_unexpected_message, Else}) + end. + %% Simple test of distributed tracing distributed(Config) when is_list(Config) -> {ok, _} = start(), @@ -929,17 +970,6 @@ flush(Acc) -> Acc end. -flush_trace() -> - flush_trace([]). -flush_trace(Acc) -> - receive - X when element(1,X) =:= trace; - element(1,X) =:= trace_ts - -> flush_trace(Acc ++ [X]) - after 1000 -> - Acc - end. - start() -> stop(), dbg:tracer(process, {fun myhandler/2, self()}). -- cgit v1.2.3 From ce0e097aaa206922bcb59babbd28a0e0355b59f8 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Tue, 3 May 2016 15:24:59 +0200 Subject: runtime_tools: Add dbg tests for receive trace patterns --- lib/runtime_tools/test/dbg_SUITE.erl | 115 ++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) (limited to 'lib/runtime_tools/test/dbg_SUITE.erl') diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl index 4374141157..4b32696aa5 100644 --- a/lib/runtime_tools/test/dbg_SUITE.erl +++ b/lib/runtime_tools/test/dbg_SUITE.erl @@ -22,7 +22,7 @@ %% Test functions -export([all/0, suite/0, big/1, tiny/1, simple/1, message/1, distributed/1, port/1, - send/1, + send/1, recv/1, ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1, ip_port_busy/1, wrap_port/1, wrap_port_time/1, with_seq_trace/1, dead_suspend/1, local_trace/1, @@ -40,7 +40,7 @@ suite() -> all() -> [big, tiny, simple, message, distributed, port, ip_port, - send, + send, recv, file_port, file_port2, file_port_schedfix, ip_port_busy, wrap_port, wrap_port_time, with_seq_trace, dead_suspend, local_trace, saved_patterns, tracer_exit_on_stop, @@ -262,6 +262,117 @@ send_test_rcv(Pid, Msg, S, TraceEvent) -> ct:fail({got_unexpected_message, Else}) end. +recv(Config) when is_list(Config) -> + {ok, _} = start(), + Node = start_slave(), + rpc:call(Node, code, add_patha, + [filename:join(proplists:get_value(data_dir, Config), "..")]), + try + Echo = fun F() -> + receive {From, M} -> + From ! M, + F() + end + end, + Rcvr = spawn_link(Echo), + RemoteRcvr = spawn_link(Node, Echo), + + {ok, [{matched, _, 1}]} = dbg:p(Rcvr, 'receive'), + + recv_test(Rcvr, make_ref(), true), + + %% Test that the test case process is the sending process + recv_test(Rcvr, [{[node(), self(), '_'],[],[]}]), + + %% Test that self() is the not sending process + {ok, [{matched, _node, 1}, {saved, 2}]} = + dbg:tpe('receive', [{[node(), '$1','_'],[{'==','$1',{self}}],[]}]), + recv_test(Rcvr, make_ref(), false), + + %% Test that self() is the receiving process + recv_test(Rcvr, [{'_',[{'==',Rcvr,{self}}],[]}]), + + %% Test attaching a message + recv_test(Rcvr, [{'_',[{'==',Rcvr,{self}}],[{message, hello}]}], + make_ref(), hello), + + %% Test using a saved trace pattern + recv_test(Rcvr, 2, make_ref(), false), + + %% Test clearing of trace pattern + {ok, [{matched, _node, 1}]} = dbg:ctpe('receive'), + recv_test(Rcvr, make_ref(), true), + + %% Test complex message inspection + Ref = make_ref(), + recv_test(Rcvr, + [{[node(), '_','$2'],[{'==',Ref,{element,1, + {element,2, + {element,2,'$2'}}}}],[]}], + {test, {Ref}, <<0:(8*1024)>>}, true), + + recv_test(Rcvr, {test, {make_ref()}, <<0:(8*1024)>>}, false), + + %% Test recv to remote process + remote_recv_test(RemoteRcvr, Rcvr, [], make_ref(), true), + + remote_recv_test(RemoteRcvr, Rcvr, + [{['$1',undefined,'_'],[{'==','$1',{node}}],[]}], + make_ref(), false), + + remote_recv_test(RemoteRcvr, Rcvr, + [{['$1',undefined,'_'],[{'==','$1',Node}],[]}], + make_ref(), true), + + %% Test that distributed dbg works + dbg:tracer(Node, process, {fun myhandler/2, self()}), + Rcvr2 = spawn_link(Echo), + RemoteRcvr2 = spawn_link(Node, Echo), + dbg:p(Rcvr2, ['receive']), + dbg:p(RemoteRcvr2, ['receive']), + dbg:tpe('receive', [{[node(), '_', '$1'],[{'==',{element,2,'$1'}, hej}],[]}]), + + recv_test(Rcvr2, make_ref(), false), + recv_test(RemoteRcvr2, make_ref(), false), + recv_test(Rcvr2, hej, true), + recv_test(RemoteRcvr2, hej, true), + + ok + + after + stop() + end. + +recv_test(Pid, Pattern, Msg, TraceEvent) -> + {ok, [{matched, _, _}, _]} = dbg:tpe('receive', Pattern), + recv_test(Pid, Msg, TraceEvent). +recv_test(Pid, Pattern) -> + recv_test(Pid, Pattern, make_ref(), true). +recv_test(Pid, Msg, TraceEvent) -> + S = self(), + Pid ! {S, Msg}, + receive Msg -> ok end, + recv_test_rcv(Pid, {S, Msg}, TraceEvent). + +remote_recv_test(RPid, Pid, Pattern, Msg, TraceEvent) -> + dbg:tpe('receive', Pattern), + TMsg = {self(), Msg}, + RPid ! {Pid, TMsg}, + receive Msg -> ok end, + recv_test_rcv(Pid, TMsg, TraceEvent). + +recv_test_rcv(Pid, Msg, TraceEvent) -> + case flush() of + [] when not TraceEvent -> + ok; + [{trace, Pid, 'receive', Msg}] when TraceEvent -> + ok; + [{trace, Pid, 'receive', Msg, Message}] when TraceEvent == Message -> + ok; + Else -> + ct:fail({got_unexpected_message, Else}) + end. + %% Simple test of distributed tracing distributed(Config) when is_list(Config) -> {ok, _} = start(), -- cgit v1.2.3