aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl2
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl63
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl95
-rw-r--r--lib/stdlib/test/supervisor_bridge_SUITE.erl42
4 files changed, 190 insertions, 12 deletions
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index a614d6595d..7fb8d54f2d 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -694,7 +694,7 @@ multicall_down(Config) when is_list(Config) ->
%% We use 'global' as a gen_server to call.
?line {Good, Bad} = gen_server:multi_call([Name, node()],
global_name_server,
- {whereis, gurkburk},
+ info,
3000),
io:format("good = ~p, bad = ~p~n", [Good, Bad]),
?line [Name] = Bad,
diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index 0cca030b3d..8a2cb5ea6b 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -33,8 +33,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
--export([app_test/1]).
--define(cases, [app_test]).
+-export([app_test/1, appup_test/1]).
%%
%% all/1
@@ -42,7 +41,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app_test].
+ [app_test, appup_test].
groups() ->
[].
@@ -79,3 +78,61 @@ app_test(Config) when is_list(Config) ->
?t:app_test(stdlib),
ok.
+%% Test that appup allows upgrade from/downgrade to a maximum of two
+%% major releases back.
+appup_test(_Config) ->
+ application:load(stdlib),
+ {_,_,Vsn} = lists:keyfind(stdlib,1,application:loaded_applications()),
+ AppupFile = filename:join([code:lib_dir(stdlib),ebin,"stdlib.appup"]),
+ {ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
+ ct:log("~p~n",[AppupScript]),
+ {OkVsns,NokVsns} = create_test_vsns(Vsn),
+ check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}),
+ check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}),
+ check_appup(NokVsns,UpFrom,error),
+ check_appup(NokVsns,DownTo,error),
+ ok.
+
+create_test_vsns(Current) ->
+ [XStr,YStr|Rest] = string:tokens(Current,"."),
+ X = list_to_integer(XStr),
+ Y = list_to_integer(YStr),
+ SecondMajor = vsn(X,Y-2),
+ SecondMinor = SecondMajor ++ ".1.3",
+ FirstMajor = vsn(X,Y-1),
+ FirstMinor = FirstMajor ++ ".57",
+ ThisMajor = vsn(X,Y),
+ This =
+ case Rest of
+ [] ->
+ [];
+ ["1"] ->
+ [ThisMajor];
+ _ ->
+ ThisMinor = ThisMajor ++ ".1",
+ [ThisMajor,ThisMinor]
+ end,
+ OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor],
+
+ ThirdMajor = vsn(X,Y-3),
+ ThirdMinor = ThirdMajor ++ ".10.12",
+ Illegal = ThisMajor ++ ",1",
+ Newer1Major = vsn(X,Y+1),
+ Newer1Minor = Newer1Major ++ ".1",
+ Newer2Major = ThisMajor ++ "1",
+ NokVsns = [ThirdMajor,ThirdMinor,
+ Illegal,
+ Newer1Major,Newer1Minor,
+ Newer2Major],
+ {OkVsns,NokVsns}.
+
+vsn(X,Y) ->
+ integer_to_list(X) ++ "." ++ integer_to_list(Y).
+
+check_appup([Vsn|Vsns],Instrs,Expected) ->
+ case systools_relup:appup_search_for_version(Vsn, Instrs) of
+ Expected -> check_appup(Vsns,Instrs,Expected);
+ Other -> ct:fail({unexpected_result_for_vsn,Vsn,Other})
+ end;
+check_appup([],_,_) ->
+ ok.
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index da6996cc9f..d3d140abbc 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -29,7 +29,8 @@
end_per_testcase/2]).
%% Internal export
--export([init/1, terminate_all_children/1]).
+-export([init/1, terminate_all_children/1,
+ middle9212/0, gen_server9212/0, handle_info/2]).
%% API tests
-export([ sup_start_normal/1, sup_start_ignore_init/1,
@@ -58,7 +59,8 @@
-export([child_unlink/1, tree/1, count_children_memory/1,
do_not_save_start_parameters_for_temporary_children/1,
do_not_save_child_specs_for_temporary_children/1,
- simple_one_for_one_scale_many_temporary_children/1]).
+ simple_one_for_one_scale_many_temporary_children/1,
+ simple_global_supervisor/1]).
%%-------------------------------------------------------------------------
@@ -77,7 +79,8 @@ all() ->
{group, abnormal_termination}, child_unlink, tree,
count_children_memory, do_not_save_start_parameters_for_temporary_children,
do_not_save_child_specs_for_temporary_children,
- simple_one_for_one_scale_many_temporary_children, temporary_bystander].
+ simple_one_for_one_scale_many_temporary_children, temporary_bystander,
+ simple_global_supervisor].
groups() ->
[{sup_start, [],
@@ -1388,6 +1391,92 @@ terminate_all_children([]) ->
done.
+%%-------------------------------------------------------------------------
+%% OTP-9212. Restart of global supervisor.
+simple_global_supervisor(_Config) ->
+ kill_supervisor(),
+ kill_worker(),
+ exit_worker(),
+ restart_worker(),
+ ok.
+
+kill_supervisor() ->
+ {Top, Sup2_1, Server_1} = start9212(),
+
+ %% Killing a supervisor isn't really supported, but try it anyway...
+ exit(Sup2_1, kill),
+ timer:sleep(200),
+ Sup2_2 = global:whereis_name(sup2),
+ Server_2 = global:whereis_name(server),
+ true = is_pid(Sup2_2),
+ true = is_pid(Server_2),
+ true = Sup2_1 =/= Sup2_2,
+ true = Server_1 =/= Server_2,
+
+ stop9212(Top).
+
+handle_info({fail, With, After}, _State) ->
+ timer:sleep(After),
+ erlang:error(With).
+
+kill_worker() ->
+ {Top, _Sup2, Server_1} = start9212(),
+ exit(Server_1, kill),
+ timer:sleep(200),
+ Server_2 = global:whereis_name(server),
+ true = is_pid(Server_2),
+ true = Server_1 =/= Server_2,
+ stop9212(Top).
+
+exit_worker() ->
+ %% Very much the same as kill_worker().
+ {Top, _Sup2, Server_1} = start9212(),
+ Server_1 ! {fail, normal, 0},
+ timer:sleep(200),
+ Server_2 = global:whereis_name(server),
+ true = is_pid(Server_2),
+ true = Server_1 =/= Server_2,
+ stop9212(Top).
+
+restart_worker() ->
+ {Top, _Sup2, Server_1} = start9212(),
+ ok = supervisor:terminate_child({global, sup2}, child),
+ {ok, _Child} = supervisor:restart_child({global, sup2}, child),
+ Server_2 = global:whereis_name(server),
+ true = is_pid(Server_2),
+ true = Server_1 =/= Server_2,
+ stop9212(Top).
+
+start9212() ->
+ Middle = {middle,{?MODULE,middle9212,[]}, permanent,2000,supervisor,[]},
+ InitResult = {ok, {{one_for_all,3,60}, [Middle]}},
+ {ok, TopPid} = start_link(InitResult),
+
+ Sup2 = global:whereis_name(sup2),
+ Server = global:whereis_name(server),
+ true = is_pid(Sup2),
+ true = is_pid(Server),
+ {TopPid, Sup2, Server}.
+
+stop9212(Top) ->
+ Old = process_flag(trap_exit, true),
+ exit(Top, kill),
+ timer:sleep(200),
+ undefined = global:whereis_name(sup2),
+ undefined = global:whereis_name(server),
+ check_exit([Top]),
+ _ = process_flag(trap_exit, Old),
+ ok.
+
+middle9212() ->
+ Child = {child, {?MODULE,gen_server9212,[]},permanent, 2000, worker, []},
+ InitResult = {ok, {{one_for_all,3,60}, [Child]}},
+ supervisor:start_link({global,sup2}, ?MODULE, InitResult).
+
+gen_server9212() ->
+ InitResult = {ok, []},
+ gen_server:start_link({global,server}, ?MODULE, InitResult, []).
+
%%-------------------------------------------------------------------------
terminate(Pid, Reason) when Reason =/= supervisor ->
diff --git a/lib/stdlib/test/supervisor_bridge_SUITE.erl b/lib/stdlib/test/supervisor_bridge_SUITE.erl
index c4d696564d..b3056ff41a 100644
--- a/lib/stdlib/test/supervisor_bridge_SUITE.erl
+++ b/lib/stdlib/test/supervisor_bridge_SUITE.erl
@@ -19,8 +19,9 @@
-module(supervisor_bridge_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,starting/1,
- mini_terminate/1,mini_die/1,badstart/1]).
--export([client/1,init/1,internal_loop_init/1,terminate/2]).
+ mini_terminate/1,mini_die/1,badstart/1,
+ simple_global_supervisor/1]).
+-export([client/1,init/1,internal_loop_init/1,terminate/2,server9212/0]).
-include_lib("test_server/include/test_server.hrl").
-define(bridge_name,supervisor_bridge_SUITE_server).
@@ -31,7 +32,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [starting, mini_terminate, mini_die, badstart].
+ [starting, mini_terminate, mini_die, badstart, simple_global_supervisor].
groups() ->
[].
@@ -138,7 +139,9 @@ init(3) ->
receive
{InternalPid,init_done} ->
{ok,InternalPid,self()}
- end.
+ end;
+init({4,Result}) ->
+ Result.
internal_loop_init(Parent) ->
register(?work_bridge_name, self()),
@@ -160,7 +163,9 @@ terminate(Reason,{Parent,Worker}) ->
io:format("Terminating bridge...\n"),
exit(Worker,kill),
Parent ! {dying,Reason},
- anything.
+ anything;
+terminate(_Reason, _State) ->
+ any.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -197,3 +202,30 @@ badstart(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% OTP-9212. Restart of global supervisor.
+
+simple_global_supervisor(suite) -> [];
+simple_global_supervisor(doc) -> "Globally registered supervisor.";
+simple_global_supervisor(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap({seconds,10}),
+
+ Child = {child, {?MODULE,server9212,[]}, permanent, 2000, worker, []},
+ InitResult = {ok, {{one_for_all,3,60}, [Child]}},
+ {ok, Sup} =
+ supervisor:start_link({local,bridge9212}, ?MODULE, {4,InitResult}),
+
+ BN_1 = global:whereis_name(?bridge_name),
+ ?line exit(BN_1, kill),
+ timer:sleep(200),
+ BN_2 = global:whereis_name(?bridge_name),
+ ?line true = is_pid(BN_2),
+ ?line true = BN_1 =/= BN_2,
+
+ ?line process_flag(trap_exit, true),
+ exit(Sup, kill),
+ ?line receive {'EXIT', Sup, killed} -> ok end,
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+server9212() ->
+ supervisor_bridge:start_link({global,?bridge_name}, ?MODULE, 3).