summaryrefslogtreecommitdiff
path: root/lib/sasl/test/release_handler_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sasl/test/release_handler_SUITE.erl')
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl493
1 files changed, 420 insertions, 73 deletions
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index f545590247..570e1bc1fe 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2021. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2022. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@
-module(release_handler_SUITE).
-include_lib("common_test/include/ct.hrl").
--include("test_lib.hrl").
+-include_lib("stdlib/include/assert.hrl").
+-include_lib("kernel/include/file.hrl").
-compile([export_all, nowarn_export_all]).
-export([scheduler_wall_time/0, garbage_collect/0]). %% rpc'ed
@@ -60,17 +61,16 @@ win32_cases() ->
%% Cases that can be run on all platforms
cases() ->
- [otp_2740, otp_2760, otp_5761, otp_9402, otp_9417,
- otp_9395_check_old_code, otp_9395_check_and_purge,
- otp_9395_update_many_mods, otp_9395_rm_many_mods,
+ [otp_9395_check_old_code,
instructions, eval_appup, eval_appup_with_restart,
- supervisor_which_children_timeout,
- release_handler_which_releases, install_release_syntax_check,
- upgrade_supervisor, upgrade_supervisor_fail, otp_9864,
- otp_10463_upgrade_script_regexp, no_dot_erlang, unicode_upgrade].
+ install_release_syntax_check,
+ otp_10463_upgrade_script_regexp, no_dot_erlang, move_system,
+ {group, absolute}, {group, relative}].
groups() ->
- [{release,[],
+ [{absolute,[],root_dir_cases()},
+ {relative,[],root_dir_cases()},
+ {release,[],
[
{group,release_single},
{group,release_gg}
@@ -87,6 +87,22 @@ groups() ->
upgrade_gg
]}].
+%% Testcases that are to be run with and without an absolute root dir
+root_dir_cases() ->
+ [supervisor_which_children_timeout,
+ release_handler_which_releases,
+ otp_2760,
+ otp_5761,
+ otp_9402,
+ otp_9417,
+ otp_9395_check_and_purge,
+ otp_9395_update_many_mods,
+ otp_9395_rm_many_mods,
+ otp_9864,
+ upgrade_supervisor,
+ upgrade_supervisor_fail,
+ unicode_upgrade].
+
%% {group,release}
%% Top group for all cases using run_erl
init_per_group(release, Config) ->
@@ -161,8 +177,10 @@ init_per_group(release_gg, Config0) ->
Snames),
test_server:timetrap_cancel(Dog),
- [{snames,Snames}|Config].
-
+ [{snames,Snames}|Config];
+init_per_group(Group, Config) when Group =:= absolute;
+ Group =:= relative ->
+ [{root_dir, Group}|Config].
end_per_group(release, Config) ->
Dog = test_server:timetrap(?default_timeout),
@@ -244,6 +262,252 @@ gg_node_snames(Config) ->
%%%-----------------------------------------------------------------
%%% TEST CASES
+%% Test that a release can be location independent (i.e., if all
+%% paths related to the release are relative to the ROOTDIR of the
+%% release, then one can move the release to a different directory and
+%% it should still work).
+move_system(Conf) when is_list(Conf) ->
+
+ DataDir = ?config(data_dir, Conf),
+ TestRootDir = filename:join(priv_dir(Conf), ?FUNCTION_NAME),
+ ErtsBinDir = filename:join("erts-" ++ find_vsn_app(erts), "bin"),
+
+ %% Remove old test data
+ file:del_dir_r(filename:join(TestRootDir,"system")),
+ file:del_dir_r(filename:join(TestRootDir,"system_moved")),
+ file:del_dir_r(filename:join(TestRootDir,"system_moved_again")),
+
+ %% Create TAR file for release A
+ ReleaseATarFile = create_release_package(DataDir, "hello_server", "A"),
+ SystemPath = filename:join(TestRootDir, "system"),
+ ok = erl_tar:extract(ReleaseATarFile, [{cwd, SystemPath}, compressed]),
+ RelDir = filename:join(SystemPath, "releases"),
+ SystemRelFile = filename:join(RelDir, "hello_server-A.rel"),
+
+ %% Create a location independent RELEASES file. Library paths in the releases
+ %% file are assumed to be relative to the RootDir.
+ ok = release_handler:create_RELEASES(RelDir, SystemRelFile, []),
+
+ %% Create the bin directory with links (or copies on windows) to the erts directory
+ file:make_dir(filename:join(SystemPath,"bin")),
+ case os:type() of
+ {win32, _} ->
+ {ok,_} = file:copy(
+ filelib:wildcard(filename:join([SystemPath,ErtsBinDir,"erl.exe"])),
+ filename:join([SystemPath,"bin","erl.exe"]));
+ _ ->
+ ok = file:make_symlink(
+ filename:join(["..",ErtsBinDir,"erl"]),
+ filename:join([SystemPath,"bin","erl"]))
+ end,
+
+ %% Test that the location independent system can start and run
+ {ok, Peer, Node} = start_remote_node(SystemPath, "A"),
+ hello = erpc:call(Node, app_callback_module, get_response, []),
+ peer:stop(Peer),
+
+ %% Should still work after copying the system and corrupting the source
+ NewSystemPath = filename:join(TestRootDir, "system_moved"),
+ copy_r(SystemPath, NewSystemPath),
+ [file:del_dir_r(F) || F <- filelib:wildcard(filename:join([SystemPath,"lib","stdlib*"]))],
+ file:del_dir_r(filename:join(SystemPath,"releases")),
+ {ok, MovedPeer, MovedNode} = start_remote_node(NewSystemPath, "A"),
+ hello = erpc:call(MovedNode, app_callback_module, get_response, []),
+ peer:stop(MovedPeer),
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %% Let us now try if a system upgrade also works with a location independent system %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ ReleaseBTarFile = create_release_package(DataDir, "hello_server_new", "B"),
+
+ BPackDest = filename:join([NewSystemPath, "releases", filename:basename(ReleaseBTarFile)]),
+ {ok, _ } = file:copy(ReleaseBTarFile, BPackDest),
+ BTarFileName = filename:basename(ReleaseBTarFile),
+ NameToUnpack = filename:rootname(BTarFileName, ".tar.gz"),
+ %% Start remote node with release A
+ {ok, PeerA, NodeA} = start_remote_node(NewSystemPath, "A"),
+
+ %% Set current working directory to something irrelevant as the
+ %% current working directory should not affect if a system is
+ %% location independent or not
+ ok = erpc:call(NodeA, file, set_cwd, ["/"]),
+ %% Let us check our app
+ hello = erpc:call(NodeA, app_callback_module, get_response, []),
+ %% Install the next release
+ {ok, "B"} = erpc:call(NodeA, release_handler, unpack_release, [NameToUnpack]),
+ %% We can now create relup file
+ AppUpSrc = filename:join([DataDir, "relocatable_release", "hello_server_new",
+ "ebin", "hello_server.appup"]),
+ AppUpDest = filename:join([NewSystemPath, "lib", "hello_server-B", "ebin", "hello_server.appup"]),
+ {ok, _} = file:copy(AppUpSrc, AppUpDest),
+ %% Run command to create the relup file
+ ok = systools:make_relup(
+ filename:join([NewSystemPath, "releases", "B", "hello_server-B"]),
+ [filename:join([NewSystemPath, "releases", "A", "hello_server-A"])],
+ [filename:join([NewSystemPath, "releases", "A", "hello_server-A"])],
+ [{outdir,filename:join([NewSystemPath, "releases","B"])},
+ {path,[NewSystemPath ++ "/lib/hello_server-A/ebin/",
+ NewSystemPath ++ "/lib/hello_server-B/ebin/"]}]
+ ),
+ %% Install the B version
+ {ok, "A", _} = erpc:call(NodeA, release_handler, install_release, ["B"]),
+ %% Check that the releases info looks ok
+ true = lists:any(fun({"hello_server", "B", _, current}) ->
+ true;
+ (_) ->
+ false
+ end,
+ erpc:call(NodeA, release_handler, which_releases, [])),
+ %% Make sure the old module gets replaced
+ ok = erpc:call(NodeA, app_callback_module, update, []),
+ %% Check that the upgrade worked
+ hej = erpc:call(NodeA, app_callback_module, get_response, []),
+
+ case os:type() of
+ {win32, _} ->
+ %% We cannot make release permanent on windows due to
+ %% not having permissions to edit services.
+ %% And symlinks to do not on windows, so we don't test
+ %% anything more there.
+ peer:stop(PeerA);
+ _ ->
+ move_system_unix(NodeA, PeerA, TestRootDir, ErtsBinDir, NewSystemPath)
+
+ end.
+
+move_system_unix(NodeA, PeerA, TestRootDir, ErtsBinDir, NewSystemPath) ->
+ %% Make the upgrade permanent
+ ok = erpc:call(NodeA, release_handler, make_permanent, ["B"]),
+ %% Check that it still works
+ hej = erpc:call(NodeA, app_callback_module, get_response, []),
+ true = lists:any(fun({"hello_server", "B", _, permanent}) ->
+ true;
+ (_) ->
+ false
+ end,
+ erpc:call(NodeA, release_handler, which_releases, [])),
+ ok = peer:stop(PeerA),
+
+ %% We will now move the install and check that everything still seems to be working fine
+ NewSystemPath2 = filename:join(TestRootDir, "system_moved_again"),
+ ok = file:rename(NewSystemPath, NewSystemPath2),
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %% Create a symlink to moved system and test that if we set the path to
+ %% contain the symlink it will work.
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ ok = file:make_symlink(
+ filename:join([NewSystemPath2, ErtsBinDir, "erl"]),
+ filename:join(TestRootDir, "erl")),
+
+ Name = peer:random_name(),
+ LinkNode = list_to_atom(Name++"@"++lists:last(string:split(atom_to_list(node()),"@"))),
+
+ %% We cannot use ?CT_PEER here because it uses spawn_executable and that
+ %% does not search the PATH for which program to run.
+ Port = open_port(
+ {spawn,"erl -sname " ++ Name ++ " -boot " ++
+ filename:join([NewSystemPath2, "releases", "B", "start"])},
+ [{env,[{"PATH",TestRootDir ++ ":" ++ os:getenv("PATH")}]}]),
+
+ %% Wait for node to start
+ receive _ -> ok end,
+
+ hej = erpc:call(LinkNode, app_callback_module, get_response, []),
+
+ true = catch port_close(Port),
+ ct:log("~p",[(fun F() -> receive M -> [M | F()] after 0 -> [] end end)()]),
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %% Test that we can do a downgrade of the moved system
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ {ok, PeerB, NodeB} = start_remote_node(NewSystemPath2, "B"),
+
+ %% Change current working directory to something irrelevant
+ ok = erpc:call(NodeB, file, set_cwd, ["/"]),
+ {ok, "/"} = erpc:call(NodeB, file, get_cwd, []),
+ %% Check that we are using version B
+ hej = erpc:call(NodeB, app_callback_module, get_response, []),
+ %% Downgrade to version A
+ {ok, "A", _} = erpc:call(NodeB, release_handler, install_release, ["A"]),
+ true = lists:any(fun({"hello_server", "A", _, current}) ->
+ true;
+ (_) ->
+ false
+ end,
+ erpc:call(NodeB, release_handler, which_releases, [])),
+ %% Make sure that the module is reloaded
+ ok = erpc:call(NodeB, app_callback_module, update, []),
+ %% Make sure that we are on version A
+ hello = erpc:call(NodeB, app_callback_module, get_response, []),
+ %% Make the downgrade permanent
+ ok = erpc:call(NodeB, release_handler, make_permanent, ["A"]),
+ %% Test that remove release works
+ ok = erpc:call(NodeB, release_handler, remove_release, ["B"]),
+ %% B should not exist anymore
+ false = lists:any(fun({"hello_server", "B", _, _}) ->
+ true;
+ (_) ->
+ false
+ end,
+ erpc:call(NodeB, release_handler, which_releases, [])),
+ ok = erpc:call(NodeB, app_callback_module, update, []),
+ %% We should still get hello
+ hello = erpc:call(NodeB, app_callback_module, get_response, []),
+ ok = peer:stop(PeerB),
+
+ ok.
+
+start_remote_node(SystemPath, RelVsn) ->
+ SystemErlPath = filename:join([SystemPath, "bin", "erl"]),
+ ?CT_PEER(#{ exec => SystemErlPath,
+ args => ["-boot",filename:join([SystemPath,"releases", RelVsn, "start"])]}).
+
+create_release_package(DataDir, SourceDir, RelVsn) ->
+ ReleaseSource = filename:join(DataDir, "relocatable_release"),
+ AppSrc = filename:join(ReleaseSource, SourceDir),
+ OldCWD = file:get_cwd(),
+ file:set_cwd(AppSrc),
+ os:cmd("erl -make"),
+ file:set_cwd(OldCWD),
+ RelFileScr = filename:join(ReleaseSource, "hello_server-"++ RelVsn ++".rel.src"),
+ RelFileDst = filename:join(ReleaseSource, "hello_server-"++ RelVsn ++".rel"),
+ {ok, RelFileTxt1} = file:read_file(RelFileScr),
+ RelFileTxt = fix_rel_file_vsns(["erts", "kernel", "stdlib", "sasl"],
+ RelFileTxt1),
+ ok = file:write_file(RelFileDst, RelFileTxt),
+ AppPath = filename:join([ReleaseSource, SourceDir, "ebin"]),
+ RelFileWithoutEnding = filename:join(ReleaseSource, "hello_server-" ++ RelVsn),
+ ok = systools:make_script(RelFileWithoutEnding, [local, {path, [AppPath]}]),
+ ok = systools:make_tar(RelFileWithoutEnding, [{erts, code:root_dir()}, {path, [AppPath]}]),
+ SystemPath = filename:join(ReleaseSource, "system"),
+ file:make_dir(SystemPath),
+ InitialTarPath = filename:join(ReleaseSource, "hello_server-"++ RelVsn ++".tar.gz"),
+ InitialTarPath.
+
+fix_rel_file_vsns(Apps, Txt) ->
+ Res =
+ lists:foldl(
+ fun(App, TxtAcc) ->
+ string:replace(TxtAcc,
+ "%" ++ App ++ "_VSN" ++ "%" ,
+ find_vsn_app(erlang:list_to_atom(App)))
+ end,
+ Txt,
+ Apps),
+ erlang:iolist_to_binary(lists:flatten(Res)).
+
+find_vsn_app(erts) ->
+ Str = erlang:system_info(system_version),
+ {match, [{Start, Len} | _]} = re:run(Str, "erts-(\\d\\.?)+"),
+ ErtsStr = string:substr(Str, Start+1, Len),
+ [_, Vsn] = string:split(ErtsStr, "-"),
+ Vsn;
+find_vsn_app(App) ->
+ Apps = application:which_applications(),
+ [Vsn] = [Vsn || {AppX, _, Vsn} <- Apps, AppX =:= App],
+ Vsn.
+
%% Executed instead of release group when no run_erl program exists
no_run_erl(Config) when is_list(Config) ->
@@ -390,7 +654,7 @@ upgrade_restart(Conf) when is_list(Conf) ->
ok ->
ok;
{wait,TestNodeInit2a} ->
- %% We catched the node too early - it was supposed to
+ %% We caught the node too early - it was supposed to
%% restart twice, so let's wait for one more restart.
wait_nodes_up([{TestNode,TestNodeInit2a}],"upgrade_restart_2a",[]),
ok = rpc_inst(TestNode, upgrade_restart_2a, [])
@@ -618,7 +882,7 @@ supervisor_which_children_timeout(Conf) ->
DataDir = ?config(data_dir,Conf),
LibDir = filename:join([DataDir,release_handler_timeouts]),
- Rel1 = create_and_install_fake_first_release(Dir,[{dummy,"0.1",LibDir}]),
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,[{dummy,"0.1",LibDir}]),
{ok, Node} = t_start_node(supervisor_which_children_timeout, Rel1, []),
Proc = rpc:call(Node, erlang, whereis, [dummy_sup_2]),
@@ -657,7 +921,7 @@ release_handler_which_releases(Conf) ->
DataDir = ?config(data_dir,Conf),
LibDir = filename:join([DataDir,release_handler_timeouts]),
- Rel1 = create_and_install_fake_first_release(Dir,[{dummy,"0.1",LibDir}]),
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,[{dummy,"0.1",LibDir}]),
{ok, Node} = t_start_node(release_handler_which_releases, Rel1, []),
Releases0 = rpc:call(Node, release_handler, which_releases, []),
@@ -713,7 +977,7 @@ otp_2760(Conf) ->
DataDir = ?config(data_dir,Conf),
LibDir = filename:join([DataDir,app1_app2,lib1]),
- Rel1 = create_and_install_fake_first_release(Dir,[{app1,"1.0",LibDir}]),
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,[{app1,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,"after",[],{[Rel1],[Rel1],[LibDir]}),
Rel2Dir = filename:dirname(Rel2),
@@ -751,7 +1015,7 @@ otp_5761(Conf) when is_list(Conf) ->
LibDir2 = filename:join(RelDir, "lib2"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{app1,"1.0",LibDir1},
{app2,"1.0",LibDir1}]),
Rel2 = create_fake_upgrade_release(Dir,
@@ -830,7 +1094,7 @@ otp_9402(Conf) when is_list(Conf) ->
LibDir = filename:join(?config(data_dir, Conf), "lib"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{a,"1.1",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
"2",
@@ -897,7 +1161,7 @@ otp_9417(Conf) when is_list(Conf) ->
LibDir = filename:join(?config(data_dir, Conf), "lib"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{b,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
"2",
@@ -1010,7 +1274,7 @@ otp_9395_check_and_purge(Conf) when is_list(Conf) ->
LibDir = filename:join(?config(data_dir, Conf), "lib"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{b,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
"2",
@@ -1076,7 +1340,7 @@ otp_9395_update_many_mods(Conf) when is_list(Conf) ->
LibDir = filename:join(?config(data_dir, Conf), "lib"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{many_mods,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
"2",
@@ -1191,7 +1455,7 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) ->
LibDir = filename:join(?config(data_dir, Conf), "lib"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{many_mods,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
"2",
@@ -1303,7 +1567,7 @@ do_otp_9864(Conf) ->
LibDir2 = filename:join(Dir, "lib2"),
%% Create the releases
- Rel1 = create_and_install_fake_first_release(Dir,
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,
[{app1,"1.0",LibDir1},
{app2,"1.0",LibDir1}]),
Rel2 = create_fake_upgrade_release(Dir,
@@ -1359,7 +1623,7 @@ upgrade_supervisor(Conf) when is_list(Conf) ->
%% Create the releases
Lib1 = [{a,"1.0",LibDir}],
Lib2 = [{a,"9.0",LibDir}],
- Rel1 = create_and_install_fake_first_release(Dir,Lib1),
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,Lib1),
Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}),
Rel1Dir = filename:dirname(Rel1),
Rel2Dir = filename:dirname(Rel2),
@@ -1416,7 +1680,7 @@ upgrade_supervisor_fail(Conf) when is_list(Conf) ->
%% Create the releases
Lib1 = [{a,"1.0",LibDir}],
Lib2 = [{a,"9.1",LibDir}],
- Rel1 = create_and_install_fake_first_release(Dir,Lib1),
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,Lib1),
Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}),
Rel1Dir = filename:dirname(Rel1),
Rel2Dir = filename:dirname(Rel2),
@@ -1814,15 +2078,34 @@ upgrade_gg(Conf) ->
%% start gg2 and gg6
[Gg2,Gg6] = start_nodes(Conf,[Gg2Sname,Gg6Sname],"upgrade_gg start gg2/gg6"),
+ %% Watch dog pulling out some more information in case we hang...
+ Nodes3 = [Gg1,Gg2,Gg4,Gg5,Gg6],
+ Tester = self(),
+ WD = spawn_link(fun () ->
+ receive after 7*60*1000 -> ok end,
+ ct:pal("7 minutes passed...~n", []),
+ erlang:suspend_process(Tester),
+ load_suite(Nodes3),
+ dump_info([node()|Nodes3]),
+ exit(operation_hang)
+ end),
+
%% reg proc on each of the nodes
ok = rpc:call(Gg2, installer, reg_proc, [reg2]),
ok = rpc:call(Gg6, installer, reg_proc, [reg6]),
- are_names_reg_gg(Gg1, [reg1, reg2, reg4, reg5, reg6]),
%% Check global group info
- Nodes3 = [Gg1,Gg2,Gg4,Gg5,Gg6],
[check_gg_info(Node,Nodes3,[],Nodes3--[Node]) || Node <- Nodes3],
+ OkList = lists:map(fun (_) -> ok end, Nodes3),
+ {OkList,[]} = rpc:multicall(Nodes3, global, sync, []),
+
+ are_names_reg_gg(Gg1, [reg1, reg2, reg4, reg5, reg6]),
+
+ unlink(WD),
+ exit(WD, kill),
+ false = is_process_alive(WD),
+
ok.
upgrade_gg(cleanup,Config) ->
@@ -1830,6 +2113,53 @@ upgrade_gg(cleanup,Config) ->
NodeNames = [node_name(Sname) || Sname <- Snames],
ok = stop_nodes(NodeNames).
+load_suite(Nodes) ->
+ {ok,Bin}=file:read_file(code:which(?MODULE)),
+ _ = rpc:multicall(Nodes, erlang, load_module, [?MODULE, Bin]),
+ ok.
+
+dump_info(Nodes) ->
+ GetLockerState = fun (TheLocker) ->
+ Mon = erlang:monitor(process, TheLocker),
+ TheLocker ! {get_state, self(), Mon},
+ receive
+ Msg when element(1, Msg) =:= Mon ->
+ erlang:demonitor(Mon, [flush]),
+ RList = tl(erlang:tuple_to_list(Msg)),
+ erlang:list_to_tuple([state | RList]);
+ {'DOWN', Mon, process, TheLocker, Reason} ->
+ {error, Reason}
+ after 60*1000 ->
+ erlang:demonitor(Mon, [flush]),
+ {error, timeout}
+ end
+ end,
+ GI = rpc:multicall(Nodes,
+ erlang,
+ apply,
+ [fun () ->
+ GlobalLocker = global:get_locker(),
+ {node(),
+ #{global_state => global:info(),
+ global_dict => process_info(whereis(global_name_server), dictionary),
+ global_locks_tab => ets:tab2list(global_locks),
+ global_names_tab => ets:tab2list(global_names),
+ global_names_ext_tab => ets:tab2list(global_names_ext),
+ global_pid_names_tab => ets:tab2list(global_pid_names),
+ global_pid_ids_tab => ets:tab2list(global_pid_ids),
+ global_lost_connections_tab => ets:tab2list(global_lost_connections),
+ global_node_resources_tag => ets:tab2list(global_node_resources),
+ global_locker_state => GetLockerState(GlobalLocker),
+ global_locker_info => process_info(GlobalLocker,
+ [status,
+ current_stacktrace,
+ messages,
+ dictionary]),
+ global_group_info => global_group:info()}}
+ end,
+ []],
+ 2*60*1000),
+ ct:pal("GI: ~p~n", [GI]).
%%%-----------------------------------------------------------------
%%% OTP-10463, Bug - release_handler could not handle regexp in appup
@@ -1926,7 +2256,7 @@ unicode_upgrade(Conf) ->
%% Create the releases
RelName = "unicode_rel_αβ",
- Rel1 = create_and_install_fake_first_release(Dir,{RelName,"1"},
+ Rel1 = create_and_install_fake_first_release(Conf,Dir,{RelName,"1"},
[{u,"1.0",LibDir}]),
Rel2 = create_fake_upgrade_release(Dir,
{RelName,"2"},
@@ -2241,7 +2571,7 @@ copy_tree(Conf, Src, NewName, DestDir) ->
TempTarName = filename:join(PrivDir, "temp_tar_file.tar"),
%% Not compressing tar file here since that would increase test
%% suite time by almost 100%, and the tar file is deleted
- %% imediately anyway.
+ %% immediately anyway.
{ok,Tar} = erl_tar:open(TempTarName, [write]),
ok = erl_tar:add(Tar, Src, NewName, []),
ok = erl_tar:close(Tar),
@@ -2405,6 +2735,17 @@ create_p1g(Conf,TargetDir) ->
filename:join([DataDir,lib,"installer-1.0",ebin])),
copy_file(filename:join(DataDir, "../rh_test_lib.beam"),
filename:join([DataDir,lib,"installer-1.0",ebin])),
+ copy_file(filename:join(DataDir, "../otp_vsns.beam"),
+ filename:join([DataDir,lib,"installer-1.0",ebin])),
+
+ InstPrivDir = filename:join([DataDir,lib,"installer-1.0","priv"]),
+ case file:read_file_info(InstPrivDir) of
+ {ok, _} ->
+ ok;
+ _ ->
+ ok = file:make_dir(InstPrivDir)
+ end,
+ copy_file(filename:join(DataDir, "../otp_versions.table"), InstPrivDir),
%% Create .rel, .script and .boot files
RelName = "rel0",
@@ -2583,48 +2924,31 @@ check_gg_info(Node,OtherAlive,OtherDead,Synced) ->
check_gg_info(Node,OtherAlive,OtherDead,Synced,N) ->
GGI = rpc:call(Node, global_group, info, []),
- GI = rpc:call(Node, global, info,[]),
- try do_check_gg_info(OtherAlive,OtherDead,Synced,GGI,GI)
- catch _:E:Stacktrace when N==0 ->
+ try do_check_gg_info(OtherAlive,OtherDead,Synced,GGI)
+ catch _:E:Stacktrace ->
test_server:format("~nERROR: check_gg_info failed for ~p:~n~p~n"
- "when GGI was: ~p~nand GI was: ~p~n",
- [Node,{E,Stacktrace},GGI,GI]),
- ct:fail("check_gg_info failed");
- _:E:Stacktrace ->
- test_server:format("~nWARNING: check_gg_info failed for ~p:~n~p~n"
- "when GGI was: ~p~nand GI was: ~p~n",
- [Node,{E,Stacktrace},GGI,GI]),
- timer:sleep(1000),
- check_gg_info(Node,OtherAlive,OtherDead,Synced,N-1)
+ "when GGI was: ~p~n",
+ [Node,{E,Stacktrace},GGI]),
+ if N == 0 ->
+ ct:fail("check_gg_info failed");
+ true ->
+ ok = rpc:call(Node, global_group, sync, []),
+ timer:sleep(1000),
+ check_gg_info(Node,OtherAlive,OtherDead,Synced,N-1)
+ end
end.
-do_check_gg_info(OtherAlive,OtherDead,Synced,GGI,GI) ->
+do_check_gg_info(OtherAlive,OtherDead,Synced,GGI) ->
{_,gg1} = lists:keyfind(own_group_name,1,GGI),
{_,synced} = lists:keyfind(state,1,GGI),
{_,AllNodes} = lists:keyfind(own_group_nodes,1,GGI),
true = lists:sort(AllNodes) =:= lists:sort(OtherAlive++OtherDead),
{_,[]} = lists:keyfind(sync_error,1,GGI),
{_,[{gg2,[_,_]}]} = lists:keyfind(other_groups,1,GGI),
-
- %% There is a known bug in global_group (OTP-9177) which causes
- %% the following to fail every now and then:
- %% {_,SyncedNodes} = lists:keyfind(synced_nodes,1,GGI),
- %% true = lists:sort(SyncedNodes) =:= lists:sort(Synced),
- %% {_,NoContact} = lists:keyfind(no_contact,1,GGI),
- %% true = lists:sort(NoContact) =:= lists:sort(OtherDead),
-
- %% Therefore we use global:info instead for this part
- {state,_,_,SyncedNodes,_,_,_,_,_,_,_} = GI,
+ {_,SyncedNodes} = lists:keyfind(synced_nodes,1,GGI),
true = lists:sort(SyncedNodes) =:= lists:sort(Synced),
-
- %% .. and we only check that all OtherDead are listed as
- %% no_contact (due to th bug there might be more nodes in this
- %% list)
{_,NoContact} = lists:keyfind(no_contact,1,GGI),
- true =
- lists:sort(OtherDead) =:=
- lists:sort([NC || NC <- NoContact,lists:member(NC,OtherDead)]),
-
+ true = lists:sort(NoContact) =:= lists:sort(OtherDead),
ok.
%% Return the configuration (to be inserted in sys.config) for global group tests
@@ -2650,7 +2974,7 @@ permanent_p1h(Node) ->
ok = rpc_inst(Node, permanent_p1h, []).
%% For each node in ToNodes, create a target installation which is
-%% indentical to the target installation for FromNode.
+%% identical to the target installation for FromNode.
copy_installed(Conf,FromNode,ToNodes) ->
PrivDir = priv_dir(Conf),
DataDir = ?config(data_dir,Conf),
@@ -2832,9 +3156,9 @@ cover_fun(Node,Func) ->
%% current running OTP release. It includes kernel, stdlib and sasl,
%% and possibly other applications if they are listed in AppDirs =
%% [{App,Vsn,LibDir}]
-create_and_install_fake_first_release(Dir,AppDirs) ->
- create_and_install_fake_first_release(Dir,init:script_id(),AppDirs).
-create_and_install_fake_first_release(Dir,{RelName,RelVsn},AppDirs) ->
+create_and_install_fake_first_release(Conf,Dir,AppDirs) ->
+ create_and_install_fake_first_release(Conf,Dir,init:script_id(),AppDirs).
+create_and_install_fake_first_release(Conf,Dir,{RelName,RelVsn},AppDirs) ->
{Rel,_} = create_fake_release(Dir,RelName,RelVsn,AppDirs),
ReleasesDir = filename:join(Dir, "releases"),
RelDir = filename:dirname(Rel),
@@ -2847,13 +3171,21 @@ create_and_install_fake_first_release(Dir,{RelName,RelVsn},AppDirs) ->
ok = copy_file(Rel++".boot",filename:join(RelVsnDir, "start.boot")),
ok = copy_file(filename:join(RelDir,"sys.config"),RelVsnDir),
- ok = release_handler:create_RELEASES(code:root_dir(),
- ReleasesDir,
- Rel++".rel",
- AppDirs),
-
+ case proplists:get_value(root_dir, Conf, relative) of
+ relative ->
+ ok = release_handler:create_RELEASES(
+ ReleasesDir,
+ Rel++".rel",
+ AppDirs);
+ absolute ->
+ ok = release_handler:create_RELEASES(
+ code:root_dir(),
+ ReleasesDir,
+ Rel++".rel",
+ AppDirs)
+ end,
Rel.
-
+
%% This function create a new release, including a relup file. It can
%% be upgraded to from the release created by
%% create_and_install_fake_first_release/2. Unpack first by calls to
@@ -2940,9 +3272,7 @@ modify_tar_win32(Conf, TarFileName) ->
app_dir(App,Vsn) ->
atom_to_list(App) ++ "-" ++ vsn(App,Vsn).
-vsn(erts,old) -> ?ertsvsn;
-vsn(kernel,old) -> ?kernelvsn;
-vsn(stdlib,old) -> ?stdlibvsn;
+vsn(App,old) -> rh_test_lib:old_app_vsn(App);
vsn(erts,current) -> erlang:system_info(version);
vsn(App,current) ->
{ok,Vsn} = application:get_key(App,vsn),
@@ -2950,3 +3280,20 @@ vsn(App,current) ->
system_lib(PrivDir) ->
filename:join(PrivDir,"system_lib").
+
+copy_r(Src, Dst) ->
+ {ok,S} = file:read_file_info(Src),
+ case S#file_info.type of
+ directory ->
+ {ok,Names} = file:list_dir(Src),
+ ok = filelib:ensure_dir(Dst),
+ ok = file:make_dir(Dst),
+ lists:foreach(
+ fun(Name) ->
+ copy_r(filename:join(Src, Name),
+ filename:join(Dst, Name))
+ end, Names);
+ _ ->
+ {ok,_NumBytesCopied} = file:copy(Src, Dst),
+ ok = file:write_file_info(Dst, S)
+ end.