4
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
19
19
-module(gen_server_SUITE).
21
-include("test_server.hrl").
21
-include_lib("test_server/include/test_server.hrl").
22
22
-include_lib("kernel/include/inet.hrl").
24
-export([init_per_testcase/2, fin_per_testcase/2]).
24
-export([init_per_testcase/2, end_per_testcase/2]).
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]).
27
28
-export([start/1, crash/1, call/1, cast/1, cast_fast/1,
28
29
info/1, abcast/1, multicall/1, multicall_down/1,
29
30
call_remote1/1, call_remote2/1, call_remote3/1,
30
31
call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1,
31
32
spec_init_local_registered_parent/1,
32
33
spec_init_global_registered_parent/1,
33
otp_5854/1, hibernate/1, otp_7669/1
34
otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1,
35
error_format_status/1, call_with_huge_message_queue/1
43
45
% The gen_server behaviour
44
46
-export([init/1, handle_call/3, handle_cast/2,
45
handle_info/2, terminate/2]).
48
[start, crash, call, cast, cast_fast, info,
49
abcast, multicall, multicall_down, call_remote1,
50
call_remote2, call_remote3, call_remote_n1,
51
call_remote_n2, call_remote_n3, spec_init,
47
handle_info/2, terminate/2, format_status/2]).
49
suite() -> [{ct_hooks,[ts_install_cth]}].
52
[start, crash, call, cast, cast_fast, info, abcast,
53
multicall, multicall_down, call_remote1, call_remote2,
54
call_remote3, call_remote_n1, call_remote_n2,
55
call_remote_n3, spec_init,
52
56
spec_init_local_registered_parent,
53
spec_init_global_registered_parent,
54
otp_5854,hibernate,otp_7669].
57
spec_init_global_registered_parent, otp_5854, hibernate,
58
otp_7669, call_format_status, error_format_status,
59
call_with_huge_message_queue].
64
init_per_suite(Config) ->
67
end_per_suite(_Config) ->
70
init_per_group(_GroupName, Config) ->
73
end_per_group(_GroupName, Config) ->
56
77
-define(default_timeout, ?t:minutes(1)).
79
init_per_testcase(Case, Config) when Case == call_remote1;
82
Case == call_remote_n1;
83
Case == call_remote_n2;
84
Case == call_remote_n3 ->
85
{ok,N} = start_node(hubba),
86
?line Dog = ?t:timetrap(?default_timeout),
87
[{node,N},{watchdog, Dog} | Config];
58
88
init_per_testcase(_Case, Config) ->
59
89
?line Dog = ?t:timetrap(?default_timeout),
60
90
[{watchdog, Dog} | Config].
61
fin_per_testcase(_Case, Config) ->
91
end_per_testcase(_Case, Config) ->
92
case proplists:get_value(node, Config) of
96
test_server:stop_node(N)
62
98
Dog = ?config(watchdog, Config),
63
99
test_server:timetrap_cancel(Dog),
887
921
?MODULE, stop, []),
888
922
?line undefined = global:whereis_name(?MODULE).
924
%% Verify that sys:get_status correctly calls our format_status/2 fun
926
call_format_status(suite) ->
928
call_format_status(doc) ->
929
["Test that sys:get_status/1,2 calls format_status/2"];
930
call_format_status(Config) when is_list(Config) ->
931
?line {ok, Pid} = gen_server:start_link({local, call_format_status},
933
?line Status1 = sys:get_status(call_format_status),
934
?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data1]} = Status1,
935
?line [format_status_called | _] = lists:reverse(Data1),
936
?line Status2 = sys:get_status(call_format_status, 5000),
937
?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data2]} = Status2,
938
?line [format_status_called | _] = lists:reverse(Data2),
940
%% check that format_status can handle a name being a pid (atom is
941
%% already checked by the previous test)
942
?line {ok, Pid3} = gen_server:start_link(gen_server_SUITE, [], []),
943
?line Status3 = sys:get_status(Pid3),
944
?line {status, Pid3, _Mod, [_PDict3, running, _Parent, _, Data3]} = Status3,
945
?line [format_status_called | _] = lists:reverse(Data3),
947
%% check that format_status can handle a name being a term other than a
949
GlobalName1 = {global, "CallFormatStatus"},
950
?line {ok, Pid4} = gen_server:start_link(GlobalName1,
951
gen_server_SUITE, [], []),
952
?line Status4 = sys:get_status(Pid4),
953
?line {status, Pid4, _Mod, [_PDict4, running, _Parent, _, Data4]} = Status4,
954
?line [format_status_called | _] = lists:reverse(Data4),
955
GlobalName2 = {global, {name, "term"}},
956
?line {ok, Pid5} = gen_server:start_link(GlobalName2,
957
gen_server_SUITE, [], []),
958
?line Status5 = sys:get_status(GlobalName2),
959
?line {status, Pid5, _Mod, [_PDict5, running, _Parent, _, Data5]} = Status5,
960
?line [format_status_called | _] = lists:reverse(Data5),
963
%% Verify that error termination correctly calls our format_status/2 fun
965
error_format_status(suite) ->
967
error_format_status(doc) ->
968
["Test that an error termination calls format_status/2"];
969
error_format_status(Config) when is_list(Config) ->
970
?line error_logger_forwarder:register(),
971
OldFl = process_flag(trap_exit, true),
972
State = "called format_status",
973
?line {ok, Pid} = gen_server:start_link(?MODULE, {state, State}, []),
974
?line {'EXIT',{crashed,_}} = (catch gen_server:call(Pid, crash)),
976
{'EXIT', Pid, crashed} ->
980
{error,_GroupLeader,{Pid,
981
"** Generic server"++_,
982
[Pid,crash,State,crashed]}} ->
985
?line io:format("Unexpected: ~p", [Other]),
989
process_flag(trap_exit, OldFl),
992
%% Test that the time for a huge message queue is not
993
%% significantly slower than with an empty message queue.
994
call_with_huge_message_queue(Config) when is_list(Config) ->
995
?line Pid = spawn_link(fun echo_loop/0),
997
?line {Time,ok} = tc(fun() -> calls(10, Pid) end),
999
?line [self() ! {msg,N} || N <- lists:seq(1, 500000)],
1000
erlang:garbage_collect(),
1001
?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end),
1002
io:format("Time for empty message queue: ~p", [Time]),
1003
io:format("Time for huge message queue: ~p", [NewTime]),
1005
case (NewTime+1) / (Time+1) of
1009
io:format("Q = ~p", [Q]),
1016
{ultimate_answer,42} = call(Pid, {ultimate_answer,42}),
1020
gen_server:call(Pid, Msg, infinity).
1023
timer:tc(erlang, apply, [Fun,[]]).
1027
{'$gen_call',{Pid,Ref},Msg} ->
890
1032
%%--------------------------------------------------------------
891
1033
%% Help functions to spec_init_*
892
1034
start_link(Init, Options) ->