aboutsummaryrefslogtreecommitdiffstats
path: root/lib/runtime_tools
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-05-03 15:24:59 +0200
committerSverker Eriksson <[email protected]>2016-05-04 19:53:38 +0200
commitce0e097aaa206922bcb59babbd28a0e0355b59f8 (patch)
treeeb5afc2f23936ea928bd616c65787db4b86e1aab /lib/runtime_tools
parent9265763bafb2e744a42693686a14fa214ebef261 (diff)
downloadotp-ce0e097aaa206922bcb59babbd28a0e0355b59f8.tar.gz
otp-ce0e097aaa206922bcb59babbd28a0e0355b59f8.tar.bz2
otp-ce0e097aaa206922bcb59babbd28a0e0355b59f8.zip
runtime_tools: Add dbg tests for receive trace patterns
Diffstat (limited to 'lib/runtime_tools')
-rw-r--r--lib/runtime_tools/test/dbg_SUITE.erl115
1 files changed, 113 insertions, 2 deletions
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(),