1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2010-2011. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: -module(receive_SUITE). 21: 22: %% Tests receive after. 23: 24: -include_lib("test_server/include/test_server.hrl"). 25: 26: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 27: init_per_group/2,end_per_group/2, 28: call_with_huge_message_queue/1,receive_in_between/1]). 29: 30: -export([init_per_testcase/2,end_per_testcase/2]). 31: 32: suite() -> [{ct_hooks,[ts_install_cth]}]. 33: 34: all() -> 35: [call_with_huge_message_queue, receive_in_between]. 36: 37: groups() -> 38: []. 39: 40: init_per_suite(Config) -> 41: Config. 42: 43: end_per_suite(_Config) -> 44: ok. 45: 46: init_per_group(_GroupName, Config) -> 47: Config. 48: 49: end_per_group(_GroupName, Config) -> 50: Config. 51: 52: 53: init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> 54: Dog=?t:timetrap(?t:minutes(3)), 55: [{watchdog, Dog}|Config]. 56: 57: end_per_testcase(_Func, Config) -> 58: Dog=?config(watchdog, Config), 59: ?t:timetrap_cancel(Dog). 60: 61: call_with_huge_message_queue(Config) when is_list(Config) -> 62: Pid = spawn_link(fun echo_loop/0), 63: 64: {Time,ok} = tc(fun() -> calls(10, Pid) end), 65: 66: [self() ! {msg,N} || N <- lists:seq(1, 500000)], 67: erlang:garbage_collect(), 68: {NewTime1,ok} = tc(fun() -> calls(10, Pid) end), 69: {NewTime2,ok} = tc(fun() -> calls(10, Pid) end), 70: 71: io:format("Time for empty message queue: ~p", [Time]), 72: io:format("Time1 for huge message queue: ~p", [NewTime1]), 73: io:format("Time2 for huge message queue: ~p", [NewTime2]), 74: 75: case hd(lists:sort([(NewTime1+1) / (Time+1), (NewTime2+1) / (Time+1)])) of 76: Q when Q < 10 -> 77: ok; 78: Q -> 79: io:format("Best Q = ~p", [Q]), 80: ?t:fail() 81: end, 82: ok. 83: 84: calls(0, _) -> ok; 85: calls(N, Pid) -> 86: {ok,{ultimate_answer,42}} = call(Pid, {ultimate_answer,42}), 87: calls(N-1, Pid). 88: 89: call(Pid, Msg) -> 90: Mref = erlang:monitor(process, Pid), 91: Pid ! {Mref,{self(),Msg}}, 92: receive 93: {Mref, Reply} -> 94: erlang:demonitor(Mref, [flush]), 95: {ok, Reply}; 96: {'DOWN', Mref, _, _, Reason} -> 97: exit(Reason) 98: end. 99: 100: receive_in_between(Config) when is_list(Config) -> 101: Pid = spawn_link(fun echo_loop/0), 102: [{ok,{a,b}} = call2(Pid, {a,b}) || _ <- lists:seq(1, 100000)], 103: ok. 104: 105: call2(Pid, Msg) -> 106: self() ! dummy, 107: Mref = erlang:monitor(process, Pid), 108: Pid ! {Mref,{self(),Msg}}, 109: receive_one(), 110: receive 111: {Mref,Reply} -> 112: erlang:demonitor(Mref, [flush]), 113: {ok,Reply}; 114: {'DOWN',Mref,_,_,Reason} -> 115: exit(Reason) 116: end. 117: 118: receive_one() -> 119: receive 120: dummy -> ok 121: end. 122: 123: %%% 124: %%% Common helpers. 125: %%% 126: 127: echo_loop() -> 128: receive 129: {Ref,{Pid,Msg}} -> 130: Pid ! {Ref,Msg}, 131: echo_loop() 132: end. 133: 134: tc(Fun) -> 135: timer:tc(erlang, apply, [Fun,[]]).