aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sasl/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sasl/test')
-rw-r--r--lib/sasl/test/Makefile4
-rw-r--r--lib/sasl/test/installer.erl562
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl318
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup2
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl4
-rw-r--r--lib/sasl/test/systools_SUITE.erl271
-rw-r--r--lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app6
-rw-r--r--lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup12
-rw-r--r--lib/sasl/test/test_lib.hrl3
9 files changed, 947 insertions, 235 deletions
diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile
index 65be134462..91a8c42484 100644
--- a/lib/sasl/test/Makefile
+++ b/lib/sasl/test/Makefile
@@ -36,6 +36,8 @@ MODULES= \
ERL_FILES= $(MODULES:%=%.erl)
+HRL_FILES= test_lib.hrl
+
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
INSTALL_PROGS= $(TARGET_FILES)
@@ -84,7 +86,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) sasl.spec sasl.cover $(EMAKEFILE) $(RELSYSDIR)
chmod -R u+w $(RELSYSDIR)
@tar cfh - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl
index f5ceab0dc4..d77b0e8538 100644
--- a/lib/sasl/test/installer.erl
+++ b/lib/sasl/test/installer.erl
@@ -19,20 +19,32 @@
-module(installer).
+-include("test_lib.hrl").
+
%%-compile(export_all).
-export([install_1/2]).
-export([install_2/1]).
-export([install_3/2]).
--export([install_3a/1]).
+-export([install_6a/1]).
-export([install_4/1]).
-export([install_5/1]).
-export([install_5a/1]).
-export([install_6/1]).
-export([install_7/1]).
+-export([install_7a/1]).
-export([install_8/1]).
+-export([install_8a/1]).
-export([install_9/1]).
-export([install_10/1]).
-export([install_11/1]).
+-export([install_12/1]).
+-export([install_13/1]).
+-export([install_14/1]).
+-export([upgrade_restart_1/2]).
+-export([upgrade_restart_1a/1]).
+-export([upgrade_restart_2/1]).
+-export([upgrade_restart_2a/1]).
+-export([upgrade_restart_3/1]).
-export([client1_1/4]).
-export([client2/3]).
-export([stop/1]).
@@ -46,28 +58,35 @@
-define(fail(Term), exit({?MODULE, ?LINE, Term})).
-define(fail_line(Line,Term), exit({?MODULE, Line, Term})).
--define(check_release(Vsn,Status,Apps),
- check_release(TestNode,node(),Vsn,Status,Apps,?LINE)).
--define(check_release_client(Node,Vsn,Status,Apps),
- check_release(TestNode,Node,Vsn,Status,Apps,?LINE)).
+-define(check_release_states(States),
+ check_release_states(TestNode,node(),States,?LINE)).
+-define(check_release_states_client(Node,States),
+ check_release_states(TestNode,Node,States,?LINE)).
+
+-define(check_release_lib(Vsn,Apps),
+ check_release_lib(TestNode,node(),Vsn,Apps,?LINE)).
+-define(check_release_lib_client(Node,Vsn,Apps),
+ check_release_lib(TestNode,Node,Vsn,Apps,?LINE)).
-define(check_running_app(App,Vsn),
check_running_app(TestNode,node(),App,Vsn,?LINE)).
-define(check_running_app_client(Node,App,Vsn),
check_running_app(TestNode,Node,App,Vsn,?LINE)).
+-define(check_disallowed_calls,check_disallowed_calls(TestNode,?LINE)).
+
install_1(TestNode,PrivDir) ->
?print([TestNode]),
?print(["install_1 start"]),
+ ?check_release_states([permanent]),
% Unpack and install P1H
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
- ?print(["unpack_release P1H ok"]),
- ?check_release("P1H",unpacked,["a-1.0"]),
+ ?check_release_states([permanent,unpacked]),
+ ?check_release_lib("P1H",["a-1.0"]),
{ok,"P1G",[new_appl]} = release_handler:install_release("P1H"),
- ?print(["install_release P1H ok"]),
- ?check_release("P1H",current,["a-1.0"]),
+ ?check_release_states([permanent,current]),
?check_running_app(a,"1.0"),
X = a:a(),
?print(["X", X]),
@@ -81,172 +100,337 @@ install_2(TestNode) ->
?print(["install_2 start"]),
% Check that P1H is still unpacked, install it and make_permanent
- ?check_release("P1H",unpacked,["a-1.0"]),
- ?print(["install_2 P1H unpacked"]),
+ ?check_release_states([permanent,unpacked]),
{ok,"P1G",[new_appl]} = release_handler:install_release("P1H"),
?print(["install_2 install_release ok"]),
- ?check_release("P1H",current,["a-1.0"]),
+ ?check_release_states([permanent,current]),
+ ?check_running_app(a,"1.0"),
+ ok = release_handler:make_permanent("P1H"),
+ ?print(["install_2 make permanent P1H ok"]),
+ ?check_release_states([old,permanent]),
?check_running_app(a,"1.0"),
- ok = release_handler:make_permanent("P1H").
+ ok.
% release_handler_SUITE will reboot this node now!
install_3(TestNode,PrivDir) ->
?print(["install_3 start"]),
% Check that P1H is permanent
- ?check_release("P1H",permanent,["a-1.0"]),
+ ?check_release_states([old,permanent]),
+ ?check_running_app(a,"1.0"),
X = a:a(),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
% Unpack and install P1I
{ok, "P1I"} = unpack_release(PrivDir,"rel2"),
- ?print(["install_3 unpack_release P1I ok"]),
- ?check_release("P1I",unpacked,["a-1.1"]),
+ ?check_release_states([old,permanent,unpacked]),
+ ?check_release_lib("P1I",["a-1.1"]),
{ok,"P1H",[{extra, gott}]} = release_handler:check_install_release("P1I"),
+ ?print(["install_3 check_install_release P1I ok"]),
{error,_} = release_handler:check_install_release("P1J"),
+ ?print(["install_3 check_install_release P1J fails - ok"]),
{ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"),
- ?print(["install_3 install_release P1I ok"]),
- ?check_release("P1I",current,["a-1.1"]),
+ ?check_release_states([old,permanent,current]),
?check_running_app(a,"1.1"),
X2 = a:a(),
{key2, newval2} = lists:keyfind(key2, 1, X2),
{key1, val1} = lists:keyfind(key1, 1, X2),
{ok, bval} = a:b(),
+ ?print(["install_3 env ok"]),
- % Unpack and install P2A
+ % Unpack P2A
{ok, "P2A"} = unpack_release(PrivDir,"rel3"),
- ?print(["install_3 unpack_release P2A ok"]),
- ?check_release("P2A",unpacked,["a-1.1"]),
+ ?check_release_states([old,permanent,current,unpacked]),
+ ?check_release_lib("P2A",["a-1.1"]),
{ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"),
?print(["install_3 check_install_release P2A ok"]),
- ok = release_handler:make_permanent("P1I"),
- ?print(["install_3 make_permanent P1I ok"]),
- ?check_release("P1I",permanent,["a-1.1"]),
ok.
+ % release_handler_SUITE will reboot this node now!
+
+install_4(TestNode) ->
+ ?print(["install_4 start"]),
-install_3a(TestNode) ->
- {ok, "P1I", [new_emu]} = release_handler:install_release("P2A"),
+ %% Check that P1H is the one that is used
+ ?check_release_states([old,permanent,unpacked,unpacked]),
+ ?check_running_app(a,"1.0"),
+
+ %% Install P2A
+ {continue_after_restart, "P1H", [new_emu,new_appl]} =
+ release_handler:install_release("P2A"),
%% Node is rebooted by the release_handler:install_release
%% (init:reboot) because P2A includes a new erts vsn and the relup
%% file contains a 'restart_new_emulator' instruction.
- ?print(["install_3 P2A installed"]),
+ ?print(["install_4 P2A installed"]),
ok.
+install_5(TestNode) ->
+ ?print(["install_5 start"]),
-install_4(TestNode) ->
- ?print(["install_4 start"]),
+ %% Check that the upgrade was done via a temporary release due to
+ %% new emulator version.
+ {"SASL-test","__new_emulator__P1H"} = init:script_id(),
+
+ %% Check that P2A is in use.
+ ?check_release_states([old,permanent,unpacked,current]),
+ ?check_running_app(a,"1.1"),
+ X = a:a(),
+ {key2, newval2} = lists:keyfind(key2, 1, X),
+ {key1, val1} = lists:keyfind(key1, 1, X),
+ {ok, bval} = a:b(),
+ ?print(["install_5 check env ok"]),
+ ok.
+
+install_5a(TestNode) ->
+ ?print(["install_5a start"]),
+
+ %% Install P1I (this will be a downgrade)
+ {ok, "P1I", [old_emu]} = release_handler:install_release("P1I"),
+ %% Node is rebooted by the release_handler:install_release
+ %% (init:reboot) because P2A includes a new erts vsn and the relup
+ %% file contains a 'restart_new_emulator' instruction.
+ ?print(["install_5a P1I installed"]),
+ ok.
+
+install_6(TestNode) ->
+ ?print(["install_6 start"]),
+
+ %% Check that P1I is used
+ ?check_release_states([old,permanent,current,old]),
+ ?check_running_app(a,"1.1"),
+
+ %% Make P1I permanent
+ ok = release_handler:make_permanent("P1I"),
+ ?check_release_states([old,old,permanent,old]),
+ ?check_running_app(a,"1.1"),
+ ok.
+
+install_6a(TestNode) ->
+ %% Install P2A
+ {continue_after_restart, "P1I", [new_emu]} =
+ release_handler:install_release("P2A"),
+ %% Node is rebooted by the release_handler:install_release
+ %% (init:reboot) because P2A includes a new erts vsn and the relup
+ %% file contains a 'restart_new_emulator' instruction.
+ ?print(["install_6a P2A installed"]),
+ ok.
+
+install_7(TestNode) ->
+ ?print(["install_7 start"]),
+
+ %% Check that the upgrade was done via a temporary release due to
+ %% new emulator version.
+ {"SASL-test","__new_emulator__P1I"} = init:script_id(),
% Check that P2A is in use.
- ?check_release("P2A",current,["a-1.1"]),
+ ?check_release_states([old,old,permanent,current]),
?check_running_app(a,"1.1"),
X = a:a(),
{key2, newval2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
{ok, bval} = a:b(),
+ ?print(["install_7 check env ok"]),
ok.
- % release_handler_SUITE will reboot this node now!
-install_5(TestNode) ->
- ?print(["install_5 start"]),
+install_7a(TestNode) ->
+ %% Install P1H (this will be a downgrade)
+ {ok, "P1H", [old_emu,old_appl]} = release_handler:install_release("P1H"),
+ %% Node is rebooted by the release_handler:install_release
+ %% (init:reboot) because P2A includes a new erts vsn and the relup
+ %% file contains a 'restart_new_emulator' instruction.
+ ?print(["install_7a P1H installed"]),
+ ok.
- % Check that P1I is used
- {ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"),
+install_8(TestNode) ->
+ ?print(["install_8 start"]),
+
+ %% Check that P1H is used
+ ?check_release_states([old,current,permanent,old]),
+ ?check_running_app(a,"1.0"),
+ {ok,"P1H",[new_emu,new_appl]} = release_handler:check_install_release("P2A"),
+ ?print(["install_8 check_install_release P2A ok"]),
+
+ %% Install P1I and check that it is permanent
+ {ok,"P1H",[{extra, gott}]} = release_handler:install_release("P1I"),
+ ?check_release_states([old,old,permanent,old]),
+ ?check_running_app(a,"1.1"),
ok.
-install_5a(TestNode) ->
+install_8a(TestNode) ->
% Install P2A again
- {ok, "P1I", [new_emu]} = release_handler:install_release("P2A"),
+ {continue_after_restart, "P1I", [new_emu]} =
+ release_handler:install_release("P2A"),
%% Node is rebooted by the release_handler:install_release
%% (init:reboot) because P2A includes a new erts vsn and the relup
%% file contains a 'restart_new_emulator' instruction.
- ?print(["install_5 P2A installed"]),
+ ?print(["install_8a P2A installed"]),
ok.
-install_6(TestNode) ->
- ?print(["install_6 start"]),
+install_9(TestNode) ->
+ ?print(["install_9 start"]),
+
+ %% Check that the upgrade was done via a temporary release due to
+ %% new emulator version.
+ {"SASL-test","__new_emulator__P1I"} = init:script_id(),
% Check that P2A is used
- ?check_release("P2A",current,["a-1.1"]),
+ ?check_release_states([old,old,permanent,current]),
?check_running_app(a,"1.1"),
X = a:a(),
{key2, newval2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
{ok, bval} = a:b(),
- ok = release_handler:make_permanent("P2A").
+ ?print(["install_9 check env ok"]),
+ ok = release_handler:make_permanent("P2A"),
+ ?check_release_states([old,old,old,permanent]),
+ ?check_running_app(a,"1.1"),
+ ok.
% release_handler_SUITE will reboot this node now!
-install_7(TestNode) ->
- ?print(["install_7 start"]),
+install_10(TestNode) ->
+ ?print(["install_10 start"]),
% Check that P2A is used
- ?check_release("P2A",permanent,["a-1.1"]),
+ ?check_release_states([old,old,old,permanent]),
+ ?check_running_app(a,"1.1"),
% Install old P1H
ok = release_handler:reboot_old_release("P1H"),
+ ?print(["install_10 reboot_old ok"]),
ok.
-install_8(TestNode) ->
- ?print(["install_8 start"]),
+
+install_11(TestNode) ->
+ ?print(["install_11 start"]),
% Check that P1H is permanent
- ?check_release("P1H",permanent,["a-1.0"]),
+ ?check_release_states([old,permanent,old,old]),
+ ?check_running_app(a,"1.0"),
X = a:a(),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
+ ?print(["install_11 check env ok"]),
%% Remove P1I and P2A and check that a-1.1 and erts-<latest> are removed
ok = release_handler:remove_release("P2A"),
+ ?check_release_states([old,permanent,old]),
ok = release_handler:remove_release("P1I"),
+ ?check_release_states([old,permanent]),
{ok, Libs} = file:list_dir(code:lib_dir()),
{_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()),
true = lists:member("stdlib-"++StdlibVsn, Libs),
true = lists:member("a-1.0", Libs),
false = lists:member("a-1.1", Libs),
{ok, Dirs} = file:list_dir(code:root_dir()),
- ["erts-4.4"] = lists:filter(fun(Dir) -> lists:prefix("erts-",Dir) end, Dirs),
+ ErtsDir = "erts-"++?ertsvsn,
+ [ErtsDir] = lists:filter(fun(Dir) -> lists:prefix("erts-",Dir) end, Dirs),
+ ?print(["install_11 file checks ok"]),
ok.
% release_handler_SUITE will reboot this node now!
-install_9(TestNode) ->
- ?print(["install_9 start"]),
+install_12(TestNode) ->
+ ?print(["install_12 start"]),
% Check that P1H is permanent
- ?check_release("P1H",permanent,["a-1.0"]),
+ ?check_release_states([old,permanent]),
+ ?check_running_app(a,"1.0"),
X = a:a(),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
+ ?print(["install_12 check env ok"]),
% Install old P1G
ok = release_handler:reboot_old_release("P1G"),
+ ?print(["install_12 reboot_old ok"]),
ok.
-install_10(TestNode) ->
- ?print(["install_10 start"]),
+install_13(TestNode) ->
+ ?print(["install_13 start"]),
% Check that P1G is permanent
- ?check_release("P1G",permanent,[]),
- ?check_release("P1H",old,["a-1.0"]),
+ ?check_release_states([permanent,old]),
+ false = lists:keysearch(a,1,application:loaded_applications()),
+ ?print(["install_13 no a application found - ok"]),
%% Remove P1H and check that both versions of application a is removed
ok = release_handler:remove_release("P1H"),
+ ?check_release_states([permanent]),
{ok, Libs} = file:list_dir(code:lib_dir()),
{_,_,StdlibVsn} = lists:keyfind(stdlib,1,application:which_applications()),
true = lists:member("stdlib-"++StdlibVsn, Libs),
false = lists:member("a-1.0", Libs),
false = lists:member("a-1.1", Libs),
+ ?print(["install_13 file checks ok"]),
ok.
% release_handler_SUITE will reboot this node now!
-install_11(TestNode) ->
- ?print(["install_11 start"]),
+install_14(TestNode) ->
+ ?print(["install_14 start"]),
% Check that P1G is permanent
- ?check_release("P1G",permanent,[]),
+ ?check_release_states([permanent]),
+ false = lists:keysearch(a,1,application:loaded_applications()),
+ ?print(["install_13 no a application found - ok"]),
+ ok.
+
+
+%%%-----------------------------------------------------------------
+%%% Ths test checks that an upgrade which both upgrades to a new
+%%% emulator version, and had a restart_emulator option to
+%%% systools:make_relup will be restarted twice on upgrade.
+%%% (On downgrade it will happen only once.)
+upgrade_restart_1(TestNode,PrivDir) ->
+ ?print([TestNode]),
+ ?print(["upgrade_restart_1 start"]),
+ ?check_release_states([permanent]),
+
+ {ok, "P2B"} = unpack_release(PrivDir,"rel4"),
+ ?check_release_states([permanent,unpacked]),
+ ?check_release_lib("P2B",["a-1.1"]),
+ ok.
+
+upgrade_restart_1a(TestNode) ->
+ ?print(["upgrade_restart_1a start"]),
+
+ {continue_after_restart,"P1G",[new_emu,add_appl]} =
+ release_handler:install_release("P2B"),
+ ?print(["upgrade_restart_1a P2B installed"]),
+ ok.
+
+upgrade_restart_2(TestNode) ->
+ ?print(["upgrade_restart_2 start"]),
+
+ %% Check that the node has been restarted once more after the tmp release
+ {"SASL-test","P2B"} = init:script_id(),
+ ?check_release_states([permanent,current]),
+ ?check_running_app(a,"1.1"),
+
+ ok = release_handler:make_permanent("P2B"),
+ ?check_release_states([old,permanent]),
+
ok.
+upgrade_restart_2a(TestNode) ->
+ ?print(["upgrade_restart_2a start"]),
+
+ {ok,"P1G",[old_emu,rm_appl]} = release_handler:install_release("P1G"),
+ ?print(["upgrade_restart_2a P1G installed"]),
+ ok.
+
+upgrade_restart_3(TestNode) ->
+ ?print(["upgrade_restart_3 start"]),
+
+ %% Ideally we should test that the node has only been restarted
+ %% once... but that's not so easy. Let's just check that P1G is running.
+ ?check_release_states([current,permanent]),
+ false = lists:keysearch(a,1,application:loaded_applications()),
+ ?print(["upgrade_restart_3 no a application found - ok"]),
+
+ ok.
+
+
%%-----------------------------------------------------------------
@@ -272,6 +456,8 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) ->
Node = start_client(TestNode,client1,ClientSname),
trace_disallowed_calls(Node),
+ ?check_release_states_client(Node,[permanent]),
+
%% Check env var for SASL on client node
SaslEnv = rpc:call(Node, application, get_all_env, [sasl]),
?print([{client1_1,sasl_env},SaslEnv]),
@@ -300,13 +486,14 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) ->
%% as default. But it is given here in order to force hitting the
%% release_handler:check_path function so it can be checked that
%% it does not use file:read_file_info on the client node, see
- %% trace_disallowed_calls/1 and check_disallowed_calls/0 below.
+ %% trace_disallowed_calls/1 and check_disallowed_calls/2 below.
%% (OTP-9142)
{ok, "P1H"} = rpc:call(Node, release_handler, set_unpacked,
[filename:join(P1HDir, "rel1.rel"),
[{a,"1.0",filename:join(MasterDir,lib)}]]),
- ?check_release_client(Node,"P1H",unpacked,["a-1.0"]),
+ ?check_release_states_client(Node,[permanent,unpacked]),
+ ?check_release_lib_client(Node,"P1H",["a-1.0"]),
ok = rpc:call(Node, release_handler, install_file,
["P1H", filename:join(P1HDir, "start.boot")]),
@@ -323,13 +510,16 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) ->
{ok,"P1G",[new_appl]} =
rpc:call(Node, release_handler, install_release, ["P1H"]),
+ ?check_release_states_client(Node,[permanent,current]),
+ ?check_running_app_client(Node,a,"1.0"),
+
Apps = rpc:call(Node, application, which_applications, []),
{a,"A CXC 138 11","1.0"} = lists:keyfind(a, 1, Apps),
X = rpc:call(Node, a, a, []),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
- check_disallowed_calls(),
+ ?check_disallowed_calls,
reboot(TestNode,Node),
trace_disallowed_calls(Node),
@@ -339,17 +529,17 @@ client1_2(TestNode,PrivDir,Node) ->
?print(["client1_2 start"]),
%% Check that P1H is still unpacked, install it and make_permanent
- ?check_release_client(Node,"P1H",unpacked,["a-1.0"]),
+ ?check_release_states_client(Node,[permanent,unpacked]),
{ok,"P1G",[new_appl]} =
rpc:call(Node, release_handler, install_release, ["P1H"]),
- ?check_release_client(Node,"P1H",current,["a-1.0"]),
+ ?check_release_states_client(Node,[permanent,current]),
?check_running_app_client(Node,a,"1.0"),
ok = rpc:call(Node, release_handler, make_permanent, ["P1H"]),
- ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
+ ?check_release_states_client(Node,[old,permanent]),
- check_disallowed_calls(),
+ ?check_disallowed_calls,
reboot(TestNode,Node),
trace_disallowed_calls(Node),
@@ -359,10 +549,8 @@ client1_3(TestNode,PrivDir,Node) ->
?print(["client1_3 start"]),
%% Check that P1H is permanent
- ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
- X = rpc:call(Node, a, a, []),
- {key2, val2} = lists:keyfind(key2, 1, X),
- {key1, val1} = lists:keyfind(key1, 1, X),
+ ?check_release_states_client(Node,[old,permanent]),
+ ?check_running_app_client(Node,a,"1.0"),
%% Unpack P1I on master
{ok, "P1I"} = unpack_release(PrivDir,"rel2"),
@@ -374,7 +562,8 @@ client1_3(TestNode,PrivDir,Node) ->
{ok, "P1I"} = rpc:call(Node, release_handler, set_unpacked,
[filename:join(P1IDir, "rel2.rel"),[]]),
- ?check_release_client(Node,"P1I",unpacked,["a-1.1"]),
+ ?check_release_states_client(Node,[old,permanent,unpacked]),
+ ?check_release_lib_client(Node,"P1I",["a-1.1"]),
ok = rpc:call(Node, release_handler, install_file,
["P1I", filename:join(P1IDir, "start.boot")]),
@@ -389,6 +578,7 @@ client1_3(TestNode,PrivDir,Node) ->
{ok,"P1H",[{extra, gott}]} =
rpc:call(Node, release_handler, install_release, ["P1I"]),
+ ?check_release_states_client(Node,[old,permanent,current]),
?check_running_app_client(Node,a,"1.1"),
X2 = rpc:call(Node, a, a, []),
{key2, newval2} = lists:keyfind(key2, 1, X2),
@@ -404,6 +594,9 @@ client1_3(TestNode,PrivDir,Node) ->
rpc:call(Node, release_handler, set_unpacked,
[filename:join(P2ADir, "rel3.rel"),[]]),
+ ?check_release_states_client(Node,[old,permanent,current,unpacked]),
+ ?check_release_lib_client(Node,"P2A",["a-1.1"]),
+
ok = rpc:call(Node, release_handler, install_file,
["P2A", filename:join(P2ADir, "start.boot")]),
ok = rpc:call(Node, release_handler, install_file,
@@ -413,66 +606,136 @@ client1_3(TestNode,PrivDir,Node) ->
{ok, "P1I", [new_emu]} =
rpc:call(Node, release_handler, check_install_release, ["P2A"]),
+
+ %% Reboot from P1H
+ ?check_disallowed_calls,
+ reboot(TestNode,Node),
+ trace_disallowed_calls(Node),
+
+ client1_4(TestNode,Node).
+
+client1_4(TestNode,Node) ->
+ ?print(["client1_4 start"]),
+
+ %% check that P1H is used
+ ?check_release_states_client(Node,[old,permanent,unpacked,unpacked]),
+
+ %% since the install_release below reboot the node...
+ ?check_disallowed_calls,
+ cover_client(TestNode,Node,stop_cover),
+
+ {continue_after_restart, "P1H", [new_emu,new_appl]} =
+ rpc:call(Node, release_handler, install_release, ["P2A"]),
+ %% Reboots the client !
+
+ check_reboot(TestNode,Node),
+ trace_disallowed_calls(Node),
+
+ client1_5(TestNode,Node).
+
+client1_5(TestNode,Node) ->
+ ?print(["client1_5 start"]),
+
+ %% Check that P2A is in use.
+ ?check_release_states_client(Node,[old,permanent,unpacked,current]),
+ ?check_running_app_client(Node,a,"1.1"),
+ X = rpc:call(Node, a, a, []),
+ {key2, newval2} = lists:keyfind(key2, 1, X),
+ {key1, val1} = lists:keyfind(key1, 1, X),
+ {ok, bval} = rpc:call(Node, a, b, []),
+
+ %% since the install_release below reboot the node...
+ ?check_disallowed_calls,
+ cover_client(TestNode,Node,stop_cover),
+
+ {ok,"P1I",[old_emu]} =
+ rpc:call(Node, release_handler, install_release, ["P1I"]),
+
+ check_reboot(TestNode,Node),
+ trace_disallowed_calls(Node),
+
+ client1_6(TestNode,Node).
+
+client1_6(TestNode,Node) ->
+ ?print(["client1_6 start"]),
+
+ ?check_release_states_client(Node,[old,permanent,current,old]),
+ ?check_running_app_client(Node,a,"1.1"),
+
ok = rpc:call(Node, release_handler, make_permanent, ["P1I"]),
- ?check_release_client(Node,"P1I",permanent,["a-1.1"]),
+ ?check_release_states_client(Node,[old,old,permanent,old]),
%% since the install_release below reboot the node...
- check_disallowed_calls(),
+ ?check_disallowed_calls,
cover_client(TestNode,Node,stop_cover),
- {ok, "P1I", [new_emu]} =
+ {continue_after_restart, "P1I", [new_emu]} =
rpc:call(Node, release_handler, install_release, ["P2A"]),
%% Reboots the client !
check_reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_4(TestNode,Node).
+ client1_7(TestNode,Node).
-client1_4(TestNode,Node) ->
- ?print(["client1_4 start"]),
+client1_7(TestNode,Node) ->
+ ?print(["client1_7 start"]),
%% Check that P2A is in use.
- ?check_release_client(Node,"P2A",current,["a-1.1"]),
+ ?check_release_states_client(Node,[old,old,permanent,current]),
?check_running_app_client(Node,a,"1.1"),
X = rpc:call(Node, a, a, []),
{key2, newval2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
{ok, bval} = rpc:call(Node, a, b, []),
- %% Reboot from P1I
- check_disallowed_calls(),
- reboot(TestNode,Node),
+ %% since the install_release below reboot the node...
+ ?check_disallowed_calls,
+ cover_client(TestNode,Node,stop_cover),
+
+ {ok,"P1H",[old_emu,old_appl]} =
+ rpc:call(Node, release_handler, install_release, ["P1H"]),
+
+ check_reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_5(TestNode,Node).
+ client1_8(TestNode,Node).
-client1_5(TestNode,Node) ->
- ?print(["client1_5 start"]),
+client1_8(TestNode,Node) ->
+ ?print(["client1_8 start"]),
- %% Check that P1I is used
- {ok, "P1I", [new_emu]} =
+ %% Check that P1H is used
+ ?check_release_states_client(Node,[old,current,permanent,old]),
+ ?check_running_app_client(Node,a,"1.0"),
+ {ok, "P1H", [new_emu,new_appl]} =
rpc:call(Node, release_handler, check_install_release, ["P2A"]),
+
+ {ok,"P1H",[{extra, gott}]} =
+ rpc:call(Node, release_handler, install_release, ["P1I"]),
+ ?check_release_states_client(Node,[old,old,permanent,old]),
+ ?check_running_app_client(Node,a,"1.1"),
+
+
%% since the install_release below will reboot the node...
- check_disallowed_calls(),
+ ?check_disallowed_calls,
cover_client(TestNode,Node,stop_cover),
%% Install P2A again
- {ok, "P1I", [new_emu]} =
+ {continue_after_restart, "P1I", [new_emu]} =
rpc:call(Node, release_handler, install_release, ["P2A"]),
%% We are rebooted again.
check_reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_6(TestNode,Node).
+ client1_9(TestNode,Node).
-client1_6(TestNode,Node) ->
- ?print(["client1_6 start"]),
+client1_9(TestNode,Node) ->
+ ?print(["client1_9 start"]),
%% Check that P2A is used
- ?check_release_client(Node,"P2A",current,["a-1.1"]),
+ ?check_release_states_client(Node,[old,old,permanent,current]),
?check_running_app_client(Node,a,"1.1"),
X = rpc:call(Node, a, a, []),
{key2, newval2} = lists:keyfind(key2, 1, X),
@@ -481,22 +744,23 @@ client1_6(TestNode,Node) ->
%% Make P2A permanent
ok = rpc:call(Node, release_handler, make_permanent, ["P2A"]),
+ ?check_release_states_client(Node,[old,old,old,permanent]),
%% Reboot from P2A
- check_disallowed_calls(),
+ ?check_disallowed_calls,
reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_7(TestNode,Node).
+ client1_10(TestNode,Node).
-client1_7(TestNode,Node) ->
- ?print(["client1_7 start"]),
+client1_10(TestNode,Node) ->
+ ?print(["client1_10 start"]),
%% Check that P2A is used
- ?check_release_client(Node,"P2A",permanent,["a-1.1"]),
+ ?check_release_states_client(Node,[old,old,old,permanent]),
%% since the reboot_old_release below will reboot the node
- check_disallowed_calls(),
+ ?check_disallowed_calls,
cover_client(TestNode,Node,stop_cover),
%% Install old P1H
@@ -505,41 +769,45 @@ client1_7(TestNode,Node) ->
check_reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_8(TestNode,Node).
+ client1_11(TestNode,Node).
-client1_8(TestNode,Node) ->
- ?print(["client1_8 start"]),
+client1_11(TestNode,Node) ->
+ ?print(["client1_11 start"]),
%% Check that P1H is permanent
- ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
+ ?check_release_states_client(Node,[old,permanent,old,old]),
+ ?check_running_app_client(Node,a,"1.0"),
X = rpc:call(Node, a, a, []),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
- %% Remove P1I and P2I from client
+ %% Remove P1I and P2A from client
ok = rpc:call(Node, release_handler, set_removed, ["P2A"]),
+ ?check_release_states_client(Node,[old,permanent,old]),
ok = rpc:call(Node, release_handler, set_removed, ["P1I"]),
+ ?check_release_states_client(Node,[old,permanent]),
- check_disallowed_calls(),
- reboot(TestNode,Node),
- trace_disallowed_calls(Node),
-
- client1_9(TestNode,Node).
-
-client1_9(TestNode,Node) ->
- ?print(["client1_9 start"]),
-
- %% Check that P2A and P1I does not exists and that PiH is permanent.
+ %% Check that P2A and P1I does not exists
Rels = rpc:call(Node, release_handler, which_releases, []),
false = lists:keysearch("P2A", 2, Rels),
false = lists:keysearch("P1I", 2, Rels),
- ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
X = rpc:call(Node, a, a, []),
{key2, val2} = lists:keyfind(key2, 1, X),
{key1, val1} = lists:keyfind(key1, 1, X),
+ ?check_disallowed_calls,
+ reboot(TestNode,Node),
+ trace_disallowed_calls(Node),
+
+ client1_12(TestNode,Node).
+
+client1_12(TestNode,Node) ->
+ ?print(["client1_12 start"]),
+
+ ?check_release_states_client(Node,[old,permanent]),
+
%% since the reboot_old_release below will reboot the node
- check_disallowed_calls(),
+ ?check_disallowed_calls,
cover_client(TestNode,Node,stop_cover),
%% Install old P1G
@@ -548,33 +816,34 @@ client1_9(TestNode,Node) ->
check_reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_10(TestNode,Node).
+ client1_13(TestNode,Node).
-client1_10(TestNode,Node) ->
- ?print(["client1_10 start"]),
+client1_13(TestNode,Node) ->
+ ?print(["client1_13 start"]),
%% Check that P1G is permanent
- ?check_release_client(Node,"P1G",permanent,[]),
- ?check_release_client(Node,"P1H",old,["a-1.0"]),
+ ?check_release_states_client(Node,[permanent,old]),
{error,client_node} = rpc:call(Node,release_handler,remove_release,["P1H"]),
ok = rpc:call(Node, release_handler, set_removed, ["P1H"]),
+ ?check_release_states_client(Node,[permanent]),
- check_disallowed_calls(),
+ ?check_disallowed_calls,
reboot(TestNode,Node),
trace_disallowed_calls(Node),
- client1_11(TestNode,Node).
+ client1_14(TestNode,Node).
-client1_11(TestNode,Node) ->
- ?print(["client1_11 start"]),
+client1_14(TestNode,Node) ->
+ ?print(["client1_14 start"]),
%% Check that P1G is permanent
- ?check_release_client(Node,"P1G",permanent,[]),
+ ?check_release_states_client(Node,[permanent]),
- check_disallowed_calls(),
+ ?check_disallowed_calls,
stop_client(TestNode,Node), %% TEST IS OK !!
net_kernel:monitor_nodes(false),
+ %% Remove releases from master
ok = release_handler:remove_release("P2A"),
ok = release_handler:remove_release("P1I"),
ok = release_handler:remove_release("P1H"),
@@ -595,9 +864,10 @@ trace_disallowed_calls(Node) ->
rpc:call(Node,dbg,p,[all,call]),
rpc:call(Node,dbg,tp,[file,[{'_',[],[{message,{caller}}]}]]).
-check_disallowed_calls() ->
+check_disallowed_calls(TestNode,Line) ->
receive
Trace when element(1,Trace)==trace ->
+ ?print_line(Line,["Disallowed function called",Trace]),
exit({disallowed_function_call,Trace})
after 0 ->
ok
@@ -628,7 +898,7 @@ start_client_unix(TestNode,Sname,Node) ->
start_client_win32(TestNode,Client,ClientSname) ->
Name = atom_to_list(ClientSname) ++ "_P1G",
RootDir = code:root_dir(),
- ErtsBinDir = filename:join(RootDir,"erts-4.4/bin"),
+ ErtsBinDir = filename:join([RootDir,"erts-"++?ertsvsn,"bin"]),
{ClientArgs,RelClientDir} = rh_test_lib:get_client_args(Client,ClientSname,
RootDir),
@@ -729,8 +999,10 @@ client2(TestNode,PrivDir,ClientSname) ->
ok
end,
+ %% Unpack P1H on master
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
+ %% Try to set P1H unpacked on client
Root = code:root_dir(),
{error,{bad_masters,[Master2]}} =
rpc:call(Node, release_handler, set_unpacked,
@@ -755,15 +1027,17 @@ stop(Now) ->
unpack_p1h(TestNode,PrivDir) ->
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
- ?check_release("P1H",unpacked,["a-1.0"]),
+ ?check_release_states([permanent,unpacked]),
+ ?check_release_lib("P1H",["a-1.0"]),
ok.
permanent_p1h(TestNode) ->
- ?check_release("P1H",unpacked,["a-1.0"]),
+ ?check_release_states([permanent,unpacked]),
+ ?check_release_lib("P1H",["a-1.0"]),
{ok,"P1G",[new_appl]} = release_handler:install_release("P1H"),
- ?check_release("P1H",current,["a-1.0"]),
+ ?check_release_states([permanent,current]),
ok = release_handler:make_permanent("P1H"),
- ?check_release("P1H",permanent,["a-1.0"]),
+ ?check_release_states([old,permanent]),
ok.
@@ -779,24 +1053,38 @@ registered_loop(_Name) ->
exit(killed)
end.
-check_release(TestNode,Node,Vsn,Status,Apps,Line) ->
+%% Checks that the list of states for all releases (sorted on vsn)
+%% equals the input States
+check_release_states(TestNode,Node,States,Line) ->
+ case rpc:call(Node,release_handler,which_releases,[]) of
+ {badrpc,_}=Error ->
+ ?fail_line(Line,{check_release_states,Node,States,Error});
+ Rels ->
+ ?print_line(Line,["check_release_states:", Rels]),
+ States = [Status || {_,_,_,Status} <- lists:keysort(2,Rels)],
+ ok
+ end.
+
+%% Check that the given release (Vsn) sees the correct vsn of App.
+check_release_lib(TestNode,Node,Vsn,Apps,Line) ->
case rpc:call(Node,release_handler,which_releases,[]) of
{badrpc,_}=Error ->
- ?fail_line(Line,{check_release,Node,Vsn,Status,Error});
+ ?fail_line(Line,{check_release_lib,Node,Vsn,Apps,Error});
Rels ->
- ?print_line(Line,["check_release:", Rels]),
- {"SASL-test", Vsn, Libs, Status} = lists:keyfind(Vsn, 2, Rels),
+ ?print_line(Line,["check_release_lib:", Rels]),
+ {"SASL-test", Vsn, Libs, _Status} = lists:keyfind(Vsn, 2, Rels),
true = lists:all(fun(App) -> lists:member(App,Libs) end,Apps),
ok
end.
+%% Check that the given Vsn of App is executed
check_running_app(TestNode,Node,App,Vsn,Line) ->
case rpc:call(Node,application,which_applications,[]) of
{badrpc,_}=Error ->
?fail_line(Line,{check_running_app,Node,App,Vsn,Error});
Apps ->
?print_line(Line,["check_running_app:", Apps]),
- {App, _, Vsn} = lists:keyfind(a, 1, Apps),
+ {App, _, Vsn} = lists:keyfind(App, 1, Apps),
ok
end.
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index af2183bfff..c2930b1039 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -19,6 +19,7 @@
-module(release_handler_SUITE).
-include_lib("common_test/include/ct.hrl").
+-include("test_lib.hrl").
-compile(export_all).
@@ -30,6 +31,7 @@ suite() ->
[{ct_hooks, [ts_install_cth]}].
init_per_suite(Config) ->
+ init_priv_dir(Config),
application:start(sasl),
Config.
@@ -69,6 +71,7 @@ groups() ->
{release_single,[],
[
upgrade,
+ upgrade_restart,
client1,
client2
]},
@@ -82,7 +85,7 @@ groups() ->
init_per_group(release, Config) ->
Dog = ?t:timetrap(?default_timeout),
P1gInstall = filename:join(priv_dir(Config),p1g_install),
- ok = do_create_p1g(Config,P1gInstall),
+ ok = create_p1g(Config,P1gInstall),
ok = create_p1h(Config),
?t:timetrap_cancel(Dog);
@@ -95,6 +98,7 @@ init_per_group(release_single, Config) ->
%% Create some more releases to upgrade to
ok = create_p1i(Config),
ok = create_p2a(Config),
+ ok = create_p2b(Config),
?t:timetrap_cancel(Dog);
@@ -155,7 +159,7 @@ end_per_group(release, Config) ->
{win32,_} -> delete_all_services();
_ -> ok
end,
- delete_release(Config),
+ clean_priv_dir(Config,true),
?t:timetrap_cancel(Dog),
Config;
end_per_group(_GroupName, Config) ->
@@ -191,7 +195,10 @@ end_per_testcase(Case, Config) ->
FailDir = filename:join(SaveDir,lists:concat(["failed-",Case])),
ok = filelib:ensure_dir(filename:join(FailDir,"*")),
- LogDirs = filelib:wildcard(filename:join([PrivDir,"*",log])),
+ LogDirs =
+ filelib:wildcard(filename:join([PrivDir,"*",log])) ++
+ filelib:wildcard(filename:join([PrivDir,"*",clients,
+ type1,"*",log])),
lists:foreach(
fun(LogDir) ->
@@ -236,7 +243,7 @@ break(Config) ->
?t:break(priv_dir(Config)),
ok.
-%% Test upgrade and downgrade of erts
+%% Test upgrade and downgrade of erts and other apps on embedded node
upgrade(Conf) when is_list(Conf) ->
reg_print_proc(), %% starts a printer process on test_server node
?t:format("upgrade ~p~n",[reg_print_proc]),
@@ -259,54 +266,75 @@ upgrade(Conf) when is_list(Conf) ->
stop_cover(TestNode),
reboot_and_wait(TestNode,"install_2",[a]),
- %% check that P1H is permanent, unpack and install P1I, unpack and install P2A
- TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]),
+ %% check that P1H is permanent, unpack and install P1I, unpack P2A
ok = rpc_inst(TestNode, install_3, [PrivDir]),
stop_cover(TestNode),
- ok = rpc_inst(TestNode, install_3a, []),
- wait_nodes_up([{TestNode,TestNodeInit1}],"install_3",[a]),
+ reboot_and_wait(TestNode,"install_3",[a]),
- %% check that P2A is used, reboot from P1I
- ok = rpc_inst(TestNode, install_4, []),
+ %% check that P1H is used, install P2A
+ TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]),
stop_cover(TestNode),
- reboot_and_wait(TestNode,"install_4",[a]),
+ ok = rpc_inst(TestNode, install_4, []),
+ wait_nodes_up([{TestNode,TestNodeInit1}],"install_4",[a]),
- %% check that P1I, reinstall P2A
+ %% check that P2A is used, then downgrade to P1I
TestNodeInit2 = rpc:call(TestNode,erlang,whereis,[init]),
ok = rpc_inst(TestNode, install_5, []),
stop_cover(TestNode),
ok = rpc_inst(TestNode, install_5a, []),
wait_nodes_up([{TestNode,TestNodeInit2}],"install_5",[a]),
- %% check that P2A is used, make P2A permanent
+ %% Check that P1I is used, then make P1I permanent and install P2A
+ TestNodeInit3 = rpc:call(TestNode,erlang,whereis,[init]),
ok = rpc_inst(TestNode, install_6, []),
stop_cover(TestNode),
- reboot_and_wait(TestNode,"install_6",[a]),
+ ok = rpc_inst(TestNode, install_6a, []),
+ wait_nodes_up([{TestNode,TestNodeInit3}],"install_6",[a]),
- %% check that P2A is permanent, install old P1H
- TestNodeInit3 = rpc:call(TestNode,erlang,whereis,[init]),
- stop_cover(TestNode),
+ %% check that P2A is used, then downgrade to P1H
+ TestNodeInit4 = rpc:call(TestNode,erlang,whereis,[init]),
ok = rpc_inst(TestNode, install_7, []),
- wait_nodes_up([{TestNode,TestNodeInit3}],"install_7",[a]),
+ stop_cover(TestNode),
+ ok = rpc_inst(TestNode, install_7a, []),
+ wait_nodes_up([{TestNode,TestNodeInit4}],"install_7",[a]),
- %% check that P1H is permanent, remove P1I and P2A
+ %% check that P1H is used, then install P1I and check that it is permanent
+ %% then reinstall P2A
+ TestNodeInit5 = rpc:call(TestNode,erlang,whereis,[init]),
ok = rpc_inst(TestNode, install_8, []),
stop_cover(TestNode),
- reboot_and_wait(TestNode,"install_8",[a]),
+ ok = rpc_inst(TestNode, install_8a, []),
+ wait_nodes_up([{TestNode,TestNodeInit5}],"install_8",[a]),
+
+ %% check that P2A is used, make P2A permanent
+ ok = rpc_inst(TestNode, install_9, []),
+ stop_cover(TestNode),
+ reboot_and_wait(TestNode,"install_9",[a]),
+
+ %% check that P2A is permanent, reboot to old P1H
+ TestNodeInit6 = rpc:call(TestNode,erlang,whereis,[init]),
+ stop_cover(TestNode),
+ ok = rpc_inst(TestNode, install_10, []),
+ wait_nodes_up([{TestNode,TestNodeInit6}],"install_10",[a]),
+
+ %% check that P1H is permanent, remove P1I and P2A
+ ok = rpc_inst(TestNode, install_11, []),
+ stop_cover(TestNode),
+ reboot_and_wait(TestNode,"install_11",[a]),
%% check that P1H is permanent, reboot old P1G
- TestNodeInit4 = rpc:call(TestNode,erlang,whereis,[init]),
+ TestNodeInit7 = rpc:call(TestNode,erlang,whereis,[init]),
stop_cover(TestNode),
- ok = rpc_inst(TestNode, install_9, []),
- wait_nodes_up([{TestNode,TestNodeInit4}],"install_9"),
+ ok = rpc_inst(TestNode, install_12, []),
+ wait_nodes_up([{TestNode,TestNodeInit7}],"install_12"),
%% check that P1G is permanent, remove P1H
- ok = rpc_inst(TestNode, install_10, []),
+ ok = rpc_inst(TestNode, install_13, []),
stop_cover(TestNode),
- reboot_and_wait(TestNode,"install_10"),
+ reboot_and_wait(TestNode,"install_13"),
%% check that P1G is permanent
- ok = rpc_inst(TestNode, install_11, []),
+ ok = rpc_inst(TestNode, install_14, []),
ok.
@@ -323,6 +351,46 @@ reboot_and_wait(Node,Tag,Apps) ->
wait_nodes_up([{Node,InitPid}],Tag,Apps).
+%% Test upgrade and downgrade of erts in combination with the
+%% restart_emulator option to systools:make_relup. For upgrade, this
+%% should cause one restart before the upgrade code, and one
+%% after. For downgrade, there will be one restart only - at the end.
+upgrade_restart(Conf) when is_list(Conf) ->
+ reg_print_proc(), %% starts a printer process on test_server node
+ ?t:format("upgrade_restart ~p~n",[reg_print_proc]),
+ PrivDir = priv_dir(Conf),
+ Sname = tc_sname(Conf), % nodename for use in this testcase
+
+ %% Copy the P1G release to a directory for use in this testcase
+ ok = copy_installed(Conf,p1g_install,[Sname]),
+
+ %% start the test node
+ [TestNode] = start_nodes(Conf,[Sname],"upgrade_restart start"),
+
+ %% unpack and install P2B
+ TestNodeInit1 = rpc:call(TestNode,erlang,whereis,[init]),
+ ok = rpc_inst(TestNode, upgrade_restart_1, [PrivDir]),
+ stop_cover(TestNode),
+ ok = rpc_inst(TestNode, upgrade_restart_1a, []),
+ wait_nodes_up([{TestNode,TestNodeInit1}],"upgrade_restart_1",[a]),
+
+ %% install P1G
+ TestNodeInit2 = rpc:call(TestNode,erlang,whereis,[init]),
+ ok = rpc_inst(TestNode, upgrade_restart_2, []),
+ stop_cover(TestNode),
+ ok = rpc_inst(TestNode, upgrade_restart_2a, []),
+ wait_nodes_up([{TestNode,TestNodeInit2}],"upgrade_restart_2",[]),
+
+ %% Check that P1G is going again
+ ok = rpc_inst(TestNode, upgrade_restart_3, []),
+
+ ok.
+
+upgrade_restart(cleanup,Config) ->
+ TestNode = tc_full_node_name(Config),
+ ok = stop_nodes([TestNode]).
+
+
%% Test upgrade and downgrade of erts, diskless
client1(Conf) when is_list(Conf) ->
reg_print_proc(), %% starts a printer process on test_server node
@@ -1147,11 +1215,10 @@ target_system(Conf) when is_list(Conf) ->
%% Create the .rel file
- ErtsVsn = erlang:system_info(version),
RelName = filename:join(TargetCreateDir,"ts-1.0"),
RelFile = RelName++".rel",
RelVsn = "R1A",
- create_rel_file(RelFile,RelName,RelVsn,ErtsVsn,[{a, "1.0"}]),
+ create_rel_file(RelFile,RelName,RelVsn,current,[{a, "1.0"}]),
%% Build the target_system module
ExamplesEbin = filename:join([code:lib_dir(sasl),examples,ebin]),
@@ -1179,11 +1246,12 @@ target_system(Conf) when is_list(Conf) ->
code:del_path(TSPath),
%% Check that all files exist in installation
- true = filelib:is_dir(filename:join(TargetInstallDir,"erts-"++ErtsVsn)),
+ ErtsDir = app_dir(erts,current),
+ true = filelib:is_dir(filename:join(TargetInstallDir,ErtsDir)),
LibDir = filename:join(TargetInstallDir,lib),
- {ok,KernelVsn} = application:get_key(kernel,vsn),
- {ok,StdlibVsn} = application:get_key(stdlib,vsn),
- {ok,SaslVsn} = application:get_key(sasl,vsn),
+ KernelVsn = vsn(kernel,current),
+ StdlibVsn = vsn(stdlib,current),
+ SaslVsn = vsn(sasl,current),
true = filelib:is_dir(filename:join(LibDir,"kernel-"++KernelVsn)),
true = filelib:is_dir(filename:join(LibDir,"stdlib-"++StdlibVsn)),
true = filelib:is_dir(filename:join(LibDir,"sasl-"++SaslVsn)),
@@ -1205,6 +1273,7 @@ target_system(Conf) when is_list(Conf) ->
true = filelib:is_regular(filename:join(BinDir,to_erl)),
%% Check content of files
+ ErtsVsn = vsn(erts,current),
{ok,SED} = file:read_file(filename:join(RelDir,"start_erl.data")),
[ErtsVsn,RelVsn] = string:tokens(binary_to_list(SED),"\s\n"),
ok.
@@ -1456,7 +1525,7 @@ copy_client(Conf,Master,Sname,Client) ->
ok.
-delete_release(Conf) ->
+clean_priv_dir(Conf,Save) ->
PrivDir = priv_dir(Conf),
{ok, OrigWd} = file:get_cwd(),
@@ -1466,7 +1535,7 @@ delete_release(Conf) ->
{ok, Dirs} = file:list_dir(PrivDir),
?t:format("======== deleting ~p~n",[Dirs]),
- ok = delete_release_os(Dirs--["save"]),
+ ok = clean_dirs_os(Dirs,Save),
{ok,Remaining} = file:list_dir(PrivDir),
?t:format("======== remaining ~p~n",[Remaining]),
@@ -1474,7 +1543,7 @@ delete_release(Conf) ->
[] ->
ok;
_ ->
- delete_release_os(Remaining),
+ clean_dirs_os(Remaining,Save),
Remaining2 = file:list_dir(PrivDir),
?t:format("======== remaining after second try ~p~n",[Remaining2])
end,
@@ -1483,22 +1552,22 @@ delete_release(Conf) ->
ok.
-delete_release_os(Dirs) ->
+clean_dirs_os(Dirs,Save) ->
case os:type() of
{unix, _} ->
- delete_release_unix(Dirs);
+ clean_dirs_unix(Dirs,Save);
{win32, _} ->
- delete_release_win32(Dirs);
+ clean_dirs_win32(Dirs,Save);
Os ->
test_server:fail({error, {not_yet_implemented_os, Os}})
end.
-delete_release_unix([]) ->
+clean_dirs_unix([],_) ->
ok;
-delete_release_unix(["save"|Dirs]) ->
- delete_release_unix(Dirs);
-delete_release_unix([Dir|Dirs]) ->
+clean_dirs_unix(["save"|Dirs],Save) when Save ->
+ clean_dirs_unix(Dirs,Save);
+clean_dirs_unix([Dir|Dirs],Save) ->
Rm = string:concat("rm -rf ", Dir),
?t:format("============== COMMAND ~p~n",[Rm]),
case file:list_dir(Dir) of
@@ -1515,13 +1584,13 @@ delete_release_unix([Dir|Dirs]) ->
?t:format("------- ls -al ~p~n",[os:cmd("ls -al " ++ Dir)])
end,
- delete_release_unix(Dirs).
+ clean_dirs_unix(Dirs,Save).
-delete_release_win32([]) ->
+clean_dirs_win32([],_) ->
ok;
-delete_release_win32(["save"|Dirs]) ->
- delete_release_win32(Dirs);
-delete_release_win32([Dir|Dirs]) ->
+clean_dirs_win32(["save"|Dirs],Save) when Save ->
+ clean_dirs_win32(Dirs,Save);
+clean_dirs_win32([Dir|Dirs],Save) ->
Rm =
case filelib:is_dir(Dir) of
true ->
@@ -1531,7 +1600,7 @@ delete_release_win32([Dir|Dirs]) ->
end,
?t:format("============== COMMAND ~p~n",[Rm]),
[] = os:cmd(Rm),
- delete_release_win32(Dirs).
+ clean_dirs_win32(Dirs,Save).
node_name(Sname) when is_atom(Sname) ->
@@ -1657,9 +1726,17 @@ priv_dir(Conf) ->
%% filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash
%% Due to problem with long paths on windows => creating a new
%% priv_dir under data_dir
+ filename:absname(filename:join(?config(data_dir, Conf),priv_dir)).
+
+init_priv_dir(Conf) ->
Dir = filename:absname(filename:join(?config(data_dir, Conf),priv_dir)),
- filelib:ensure_dir(filename:join(Dir,"*")),
- Dir.
+ case filelib:is_dir(Dir) of
+ true ->
+ clean_priv_dir(Conf,false);
+ false ->
+ ok
+ end,
+ filelib:ensure_dir(filename:join(Dir,"*")).
latest_version(Dir) ->
List = filelib:wildcard(Dir ++ "*"),
@@ -1694,14 +1771,22 @@ stop_print_proc() ->
%% Create the first target release, vsn P1G. This release is used for
%% all test cases in {group,release}
-create_p1g(Conf,Sname) ->
- do_create_p1g(Conf,filename:join(priv_dir(Conf),Sname)).
-
-do_create_p1g(Conf,TargetDir) ->
- PrivDir = priv_dir(Conf),
+create_p1g(Conf,TargetDir) ->
DataDir = ?config(data_dir,Conf),
- ErtsVsn = "4.4",
- ErtsDir = "erts-"++ErtsVsn,
+ PrivDir = priv_dir(Conf),
+ ErtsDir = app_dir(erts,old),
+ KernelDir = app_dir(kernel,old),
+ StdlibDir = app_dir(stdlib,old),
+
+ %% Fake earlier version of kernel and stdlib
+ SystemLib = system_lib(PrivDir),
+ ok = filelib:ensure_dir(filename:join(SystemLib,"*")),
+ KernelLib = code:lib_dir(kernel),
+ StdlibLib = code:lib_dir(stdlib),
+ ok = copy_tree(Conf,KernelLib,KernelDir,SystemLib),
+ ok = copy_tree(Conf,StdlibLib,StdlibDir,SystemLib),
+ fix_version(SystemLib,kernel),
+ fix_version(SystemLib,stdlib),
%% Create dirs
BinDir = filename:join(TargetDir,bin),
@@ -1745,17 +1830,15 @@ do_create_p1g(Conf,TargetDir) ->
RelFileName = filename:join(RelDir,RelName),
RelFile = RelFileName ++ ".rel",
ok = filelib:ensure_dir(RelFile),
- LibPath = filename:join([DataDir,lib,"*",ebin]),
- TarFile = create_basic_release(Conf, RelFile, RelVsn, {ErtsVsn,false},
- LibPath, [], [], [], []),
+ TarFile = create_basic_release(Conf,RelFile,RelVsn,{old,false}),
%% Extract tar file in target directory (i.e. same directory as erts etc.)
ok = erl_tar:extract(TarFile, [{cwd, TargetDir}, compressed]),
%% Create start_erl.data
StartErlDataFile = filename:join([ReleasesDir, "start_erl.data"]),
- StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]),
+ StartErlData = io_lib:fwrite("~s ~s~n", [vsn(erts,old), RelVsn]),
ok = file:write_file(StartErlDataFile, StartErlData),
%% Create RELEASES
@@ -1763,60 +1846,98 @@ do_create_p1g(Conf,TargetDir) ->
ok.
+fix_version(SystemLib,App) ->
+ FromVsn = vsn(App,current),
+ ToVsn = vsn(App,old),
+ Rootname = filename:join([SystemLib,app_dir(App,old),ebin,atom_to_list(App)]),
+
+ AppFile = Rootname ++ ".app",
+ {ok,OrigApp} = file:read_file(AppFile),
+ ok = file:write_file(AppFile,re:replace(OrigApp,FromVsn,ToVsn,
+ [{return,binary}])),
+ AppupFile = Rootname ++ ".appup",
+ {ok,OrigAppup} = file:read_file(AppupFile),
+ ok = file:write_file(AppupFile,re:replace(OrigAppup,FromVsn,ToVsn,
+ [{return,binary}])).
+
+
%% Create version P1H - which is P1G + a-1.0
%% Must have run create_p1g first!!
create_p1h(Conf) ->
- create_upgrade_release(Conf,"rel1","P1H",{"4.4",false},[{a,"1.0"}],
- [{a,[{key2,val2}]}],{"rel0",[new_appl]}).
+ create_upgrade_release(Conf,"rel1","P1H",{old,false},[{a,"1.0"}],
+ [{a,[{key2,val2}]}],[{"rel0",[new_appl]}]).
%% Create version P1I - which is P1H, but with application a upgraded to a-1.1
%% Must have run create_p1h first!!
create_p1i(Conf) ->
- create_upgrade_release(Conf,"rel2","P1I",{"4.4",false},[{a,"1.1"}],
+ create_upgrade_release(Conf,"rel2","P1I",{old,false},[{a,"1.1"}],
[{a,[{key2,newval2}]}],
- {"rel1",[{extra,gott}]}).
+ [{"rel1",[{extra,gott}]}]).
%% Create version P2A - which is P1I, but with erts-<latest>
%% Must have run create_p1i first!!
create_p2a(Conf) ->
- ErtsVsn = erlang:system_info(version),
- create_upgrade_release(Conf,"rel3","P2A",{ErtsVsn,code:root_dir()},
+ create_upgrade_release(Conf,"rel3","P2A",{current,code:root_dir()},
+ [{a,"1.1"}],[{a,[{key2,newval2}]}],
+ [{"rel1",[new_emu,new_appl]},{"rel2",[new_emu]}],
+ [{"rel1",[old_emu,old_appl]},{"rel2",[old_emu]}]).
+
+%% Create version P2B - which is P2A, but with relup containing an
+%% extra reboot.
+%% Can be upgraded to from P1G - so must have run create_p1g first!!
+create_p2b(Conf) ->
+ create_upgrade_release(Conf,"rel4","P2B",{current,code:root_dir()},
[{a,"1.1"}],[{a,[{key2,newval2}]}],
- {"rel2",[new_emu]}).
+ [{"rel0",[new_emu,add_appl]}],
+ [{"rel0",[old_emu,rm_appl]}],
+ [restart_emulator]).
%% Create a release tar package which can be installed on top of P1G
-create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,{UpFromName,Descr}) ->
+create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom) ->
+ create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,[]).
+create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,DownTo) ->
+ create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom,DownTo,[]).
+create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,UpFrom0,DownTo0,RelupOpts) ->
PrivDir = priv_dir(Conf),
- DataDir = ?config(data_dir,Conf),
-
RelDir = filename:join(PrivDir,RelName),
RelFileName = filename:join(RelDir,RelName),
RelFile = RelFileName ++ ".rel",
ok = filelib:ensure_dir(RelFile),
- LibPath = filename:join([DataDir,lib,"*",ebin]),
- UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr}],
+ UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr} ||
+ {UpFromName,Descr} <- UpFrom0],
+ DownTo = [{filename:join([PrivDir,DownToName,DownToName]),Descr} ||
+ {DownToName,Descr} <- DownTo0],
- create_basic_release(Conf, RelFile, RelVsn, Erts, LibPath,
- Apps, Config, UpFrom, []),
+ create_basic_release(Conf,RelFile,RelVsn,Erts,Apps,Config,
+ UpFrom,DownTo,RelupOpts),
ok.
%% Create .rel, .script, .boot, sys.config and tar
-create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) ->
+create_basic_release(Conf,RelFile,RelVsn,{Erts,ErtsDir}) ->
+ create_basic_release(Conf, RelFile,RelVsn,{Erts,ErtsDir},[],[],[],[],[]).
+create_basic_release(Conf,RelFile,RelVsn,{Erts,ErtsDir},ExtraApps,Config,UpFrom,DownTo,RelupOpts) ->
+ DataDir = ?config(data_dir,Conf),
+ PrivDir = priv_dir(Conf),
+ SystemLib = system_lib(PrivDir),
+ LibPath = [filename:join([SystemLib,"*",ebin]),
+ filename:join([DataDir,lib,"*",ebin])],
+
RelDir = filename:dirname(RelFile),
RelFileName = filename:rootname(RelFile),
%% Create .rel file
- create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps),
+ create_installer_rel_file(RelFile,RelVsn,Erts,ExtraApps),
%% Generate .script and .boot
ok = systools:make_script(RelFileName,
- [{path,[LibPath]},
+ [{path,LibPath},
{outdir,RelDir}]),
%% Generate relup
- ok = systools:make_relup(RelFileName,UpFrom,DownTo,[{path,[LibPath]},
- {outdir,RelDir}]),
+ ok = systools:make_relup(RelFileName,UpFrom,DownTo,[{path,LibPath},
+ {outdir,RelDir} |
+ RelupOpts]),
%% Create sys.config
ok = write_term_file(filename:join(RelDir,"sys.config"),Config),
@@ -1824,7 +1945,7 @@ create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Co
%% Create tar file (i.e. collect all lib/app-*/* and system files)
ok = systools:make_tar(RelFileName,
- [{path,[LibPath]},
+ [{path,LibPath},
{outdir,RelDir} |
case ErtsDir of
false -> [];
@@ -1841,18 +1962,19 @@ create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Co
TarFileName.
%% Create a .rel file
-create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps) ->
- create_rel_file(RelFile,"SASL-test",RelVsn,ErtsVsn,
+create_installer_rel_file(RelFile,RelVsn,Erts,ExtraApps) ->
+ create_rel_file(RelFile,"SASL-test",RelVsn,Erts,
[{installer,"1.0"}|ExtraApps]).
-create_rel_file(RelFile,RelName,RelVsn,ErtsVsn,ExtraApps) ->
- {ok,KernelVsn} = application:get_key(kernel,vsn),
- {ok,StdlibVsn} = application:get_key(stdlib,vsn),
- {ok,SaslVsn} = application:get_key(sasl,vsn),
+create_rel_file(RelFile,RelName,RelVsn,Erts,ExtraApps) ->
+ ErtsVsn = vsn(erts,Erts),
+ KernelVsn = vsn(kernel,Erts),
+ StdlibVsn = vsn(stdlib,Erts),
+ SaslVsn = vsn(sasl,current),
application:load(tools),
- {ok,ToolsVsn} = application:get_key(tools,vsn),
+ ToolsVsn = vsn(tools,current),
application:load(runtime_tools),
- {ok,RuntimeToolsVsn} = application:get_key(runtime_tools,vsn),
+ RuntimeToolsVsn = vsn(runtime_tools,current),
RelFileContent = {release,
{RelName, RelVsn},
@@ -2033,7 +2155,7 @@ start_node_unix(Sname,NodeDir) ->
start_node_win32(Sname,NodeDir) ->
Name = atom_to_list(Sname) ++ "_P1G",
- ErtsBinDir = filename:join(NodeDir,"erts-4.4/bin"),
+ ErtsBinDir = filename:join([NodeDir,app_dir(erts,old),"bin"]),
StartErlArgs = rh_test_lib:get_start_erl_args(NodeDir),
ServiceArgs = rh_test_lib:get_service_args(NodeDir, Sname, StartErlArgs),
@@ -2158,7 +2280,6 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) ->
RelDir = filename:join(Dir,"rel_" ++ RelVsn),
Rel = filename:join([RelDir,"rel_" ++ RelVsn]),
ok = filelib:ensure_dir(Rel),
- ErtsVsn = erlang:system_info(version),
{Apps,Paths} =
lists:foldl(fun({App,Vsn,Lib},{As,Ps}) ->
@@ -2168,7 +2289,7 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) ->
{[],[]},
AppDirs),
- create_rel_file(Rel++".rel",RelName,RelVsn,ErtsVsn,Apps),
+ create_rel_file(Rel++".rel",RelName,RelVsn,current,Apps),
%% Generate boot scripts
ok = systools:make_script(Rel,[local,
@@ -2217,3 +2338,16 @@ modify_tar_win32(Conf, TarFileName) ->
[ok = erl_tar:add(T,filename:join(TmpDir,F),F,[]) || F <- Fs],
ok = erl_tar:close(T),
ok.
+
+app_dir(App,Vsn) ->
+ atom_to_list(App) ++ "-" ++ vsn(App,Vsn).
+vsn(erts,old) -> ?ertsvsn;
+vsn(kernel,old) -> ?kernelvsn;
+vsn(stdlib,old) -> ?stdlibvsn;
+vsn(erts,current) -> erlang:system_info(version);
+vsn(App,current) ->
+ {ok,Vsn} = application:get_key(App,vsn),
+ Vsn.
+
+system_lib(PrivDir) ->
+ filename:join(PrivDir,"system_lib").
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup
index 05db4cb541..6ef67b869e 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/ebin/a.appup
@@ -1,3 +1,3 @@
{"1.1",
[{"1.0",[{update,a,{advanced,extra_par}}]}],
- []}.
+ [{"1.0",[{update,a,{advanced,extra_par}}]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
index c082ad5339..1050e53f35 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.1/src/a.erl
@@ -51,4 +51,6 @@ terminate(_Reason, _State) ->
ok.
code_change(1, Extra, State) ->
- {ok, {state, bval}}.
+ {ok, {state, bval}};
+code_change({down,1},Extra,State) ->
+ {ok, state}.
diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl
index e352247d44..a3e97c4543 100644
--- a/lib/sasl/test/systools_SUITE.erl
+++ b/lib/sasl/test/systools_SUITE.erl
@@ -51,8 +51,8 @@
exref_tar/1, link_tar/1, otp_9507/1]).
-export([ normal_relup/1, abnormal_relup/1, no_appup_relup/1,
bad_appup_relup/1, app_start_type_relup/1, otp_3065/1]).
--export([
- otp_6226/1]).
+-export([otp_6226/1]).
+-export([normal_hybrid/1,hybrid_no_old_sasl/1,hybrid_no_new_sasl/1]).
-export([init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2]).
@@ -67,7 +67,7 @@ suite() ->
[{ct_hooks, [ts_install_cth]}].
all() ->
- [{group, script}, {group, tar}, {group, relup},
+ [{group, script}, {group, tar}, {group, relup}, {group, hybrid},
{group, tickets}].
groups() ->
@@ -85,6 +85,7 @@ groups() ->
{relup, [],
[normal_relup, abnormal_relup, no_appup_relup,
bad_appup_relup, app_start_type_relup]},
+ {hybrid, [], [normal_hybrid,hybrid_no_old_sasl,hybrid_no_new_sasl]},
{tickets, [], [otp_6226]}].
init_per_group(_GroupName, Config) ->
@@ -1143,6 +1144,8 @@ normal_relup(Config) when is_list(Config) ->
?line {LatestDir,LatestName} = create_script(latest0,Config),
?line {_LatestDir1,LatestName1} = create_script(latest1,Config),
?line {_LatestDir2,LatestName2} = create_script(latest2,Config),
+ ?line {_LatestDir1CurrErts,LatestName1CurrErts} =
+ create_script(latest1_current_erts,Config),
?line DataDir = filename:absname(?copydir),
?line LibDir = [fname([DataDir, d_normal, lib])],
@@ -1160,6 +1163,31 @@ normal_relup(Config) when is_list(Config) ->
?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]),
?line ok = check_restart_emulator(),
+ %% Check that new erts version generates a restart_new_emulator
+ %% instruction
+ %% (One erts_vsn_changed warning for upgrade and one for downgrade)
+ ?line {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} =
+ systools:make_relup(LatestName,
+ [LatestName1CurrErts],
+ [LatestName1CurrErts],
+ [{path, P},silent]),
+ ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]),
+ ?line ok = check_restart_emulator_diff_erts(),
+
+
+ %% Check that new erts version generates a restart_new_emulator
+ %% instruction, and can be combined with restart_emulator opt.
+ %% (One erts_vsn_changed warning for upgrade and one for downgrade)
+ ?line {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} =
+ systools:make_relup(LatestName,
+ [LatestName1CurrErts],
+ [LatestName1CurrErts],
+ [{path, P},restart_emulator,silent]),
+ ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]),
+ ?line ok = check_restart_emulator(),
+ ?line ok = check_restart_emulator_diff_erts(),
+
+
%% This is the ultra normal case
?line ok = systools:make_relup(LatestName, [LatestName1], [LatestName1],
[{path, P}]),
@@ -1222,6 +1250,12 @@ check_restart_emulator() ->
restart_new_emulator = lists:last(Dn),
ok.
+check_restart_emulator_diff_erts() ->
+ {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup),
+ [restart_new_emulator|_] = Up,
+ restart_new_emulator = lists:last(Dn),
+ ok.
+
%% make_relup
%%
no_appup_relup(suite) -> [];
@@ -1371,6 +1405,168 @@ app_start_type_relup(Config) when is_list(Config) ->
ok.
+%% For upgrade of erts - create a boot file which is a hybrid between
+%% old and new release - i.e. starts erts, kernel, stdlib, sasl from
+%% new release, all other apps from old release.
+normal_hybrid(Config) ->
+ ?line {ok, OldDir} = file:get_cwd(),
+ ?line {Dir1,Name1} = create_script(latest1_sasl,Config),
+ ?line {_Dir2,Name2} = create_script(current_all_sasl,Config),
+
+ ?line DataDir = filename:absname(?copydir),
+ ?line LibDir = [fname([DataDir, d_normal, lib])],
+ ?line P = [fname([LibDir, '*', ebin]),
+ fname([DataDir, lib, kernel, ebin]),
+ fname([DataDir, lib, stdlib, ebin]),
+ fname([DataDir, lib, sasl, ebin])],
+
+ ?line ok = file:set_cwd(Dir1),
+
+ ?line {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]),
+ ?line {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]),
+ ?line {ok,Boot1} = file:read_file(Name1 ++ ".boot"),
+ ?line {ok,Boot2} = file:read_file(Name2 ++ ".boot"),
+
+ ?line ok = file:set_cwd(OldDir),
+
+ ?line BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"},
+ ?line {ok,Hybrid} = systools_make:make_boot_hybrid("tmp_vsn",Boot1,Boot2,
+ BasePaths, [dummy,args]),
+
+ ?line {script,{"Test release 4","tmp_vsn"},Script} = binary_to_term(Hybrid),
+ ct:log("~p.~n",[Script]),
+
+ %% Check that all paths to base apps are replaced by paths from BaseLib
+ Boot1Str = io_lib:format("~p~n",[binary_to_term(Boot1)]),
+ HybridStr = io_lib:format("~p~n",[binary_to_term(Hybrid)]),
+ ReOpts = [global,{capture,first,list},unicode],
+ ?line {match,OldKernelMatch} = re:run(Boot1Str,"kernel-[0-9\.]+",ReOpts),
+ ?line {match,OldStdlibMatch} = re:run(Boot1Str,"stdlib-[0-9\.]+",ReOpts),
+ ?line {match,OldSaslMatch} = re:run(Boot1Str,"sasl-[0-9\.]+",ReOpts),
+
+ ?line nomatch = re:run(HybridStr,"kernel-[0-9\.]+",ReOpts),
+ ?line nomatch = re:run(HybridStr,"stdlib-[0-9\.]+",ReOpts),
+ ?line nomatch = re:run(HybridStr,"sasl-[0-9\.]+",ReOpts),
+ ?line {match,NewKernelMatch} = re:run(HybridStr,"testkernelpath",ReOpts),
+ ?line {match,NewStdlibMatch} = re:run(HybridStr,"teststdlibpath",ReOpts),
+ ?line {match,NewSaslMatch} = re:run(HybridStr,"testsaslpath",ReOpts),
+
+ NewKernelN = length(NewKernelMatch),
+ ?line NewKernelN = length(OldKernelMatch),
+ NewStdlibN = length(NewStdlibMatch),
+ ?line NewStdlibN = length(OldStdlibMatch),
+ NewSaslN = length(NewSaslMatch),
+ ?line NewSaslN = length(OldSaslMatch),
+
+ %% Check that application load instruction has correct versions
+ Apps = application:loaded_applications(),
+ {_,_,KernelVsn} = lists:keyfind(kernel,1,Apps),
+ {_,_,StdlibVsn} = lists:keyfind(stdlib,1,Apps),
+ {_,_,SaslVsn} = lists:keyfind(sasl,1,Apps),
+
+ ?line [KernelInfo] = [I || {kernelProcess,application_controller,
+ {application_controller,start,
+ [{application,kernel,I}]}} <- Script],
+ ?line [StdlibInfo] = [I || {apply,
+ {application,load,
+ [{application,stdlib,I}]}} <- Script],
+ ?line [SaslInfo] = [I || {apply,
+ {application,load,
+ [{application,sasl,I}]}} <- Script],
+
+ ?line {vsn,KernelVsn} = lists:keyfind(vsn,1,KernelInfo),
+ ?line {vsn,StdlibVsn} = lists:keyfind(vsn,1,StdlibInfo),
+ ?line {vsn,SaslVsn} = lists:keyfind(vsn,1,SaslInfo),
+
+ %% Check that new_emulator_upgrade call is added
+ ?line [_,{apply,{release_handler,new_emulator_upgrade,[dummy,args]}}|_] =
+ lists:reverse(Script),
+
+ %% Check that db-1.0 and fe-3.1 are used (i.e. vsns from old release)
+ %% And that fe is in there (it exists in old rel but not in new)
+ ?line {match,DbMatch} = re:run(HybridStr,"db-[0-9\.]+",ReOpts),
+ ?line {match,[_|_]=FeMatch} = re:run(HybridStr,"fe-[0-9\.]+",ReOpts),
+ ?line true = lists:all(fun(["db-1.0"]) -> true;
+ (_) -> false
+ end,
+ DbMatch),
+ ?line true = lists:all(fun(["fe-3.1"]) -> true;
+ (_) -> false
+ end,
+ FeMatch),
+
+ %% Check that script has same length as old script, plus one (the
+ %% new_emulator_upgrade apply)
+ {_,_,Old} = binary_to_term(Boot1),
+ OldLength = length(Old),
+ NewLength = length(Script),
+ ?line NewLength = OldLength + 1,
+
+ ok.
+
+%% Check that systools_make:make_boot_hybrid fails with a meaningful
+%% error message if the FromBoot does not include the sasl
+%% application.
+hybrid_no_old_sasl(Config) ->
+ ?line {ok, OldDir} = file:get_cwd(),
+ ?line {Dir1,Name1} = create_script(latest1,Config),
+ ?line {_Dir2,Name2} = create_script(current_all_sasl,Config),
+
+ ?line DataDir = filename:absname(?copydir),
+ ?line LibDir = [fname([DataDir, d_normal, lib])],
+ ?line P = [fname([LibDir, '*', ebin]),
+ fname([DataDir, lib, kernel, ebin]),
+ fname([DataDir, lib, stdlib, ebin]),
+ fname([DataDir, lib, sasl, ebin])],
+
+ ?line ok = file:set_cwd(Dir1),
+
+ ?line {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]),
+ ?line {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]),
+ ?line {ok,Boot1} = file:read_file(Name1 ++ ".boot"),
+ ?line {ok,Boot2} = file:read_file(Name2 ++ ".boot"),
+
+ ?line BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"},
+ ?line {error,{app_not_replaced,sasl}} =
+ systools_make:make_boot_hybrid("tmp_vsn",Boot1,Boot2,
+ BasePaths,[dummy,args]),
+
+ ?line ok = file:set_cwd(OldDir),
+ ok.
+
+
+%% Check that systools_make:make_boot_hybrid fails with a meaningful
+%% error message if the ToBoot does not include the sasl
+%% application.
+hybrid_no_new_sasl(Config) ->
+ ?line {ok, OldDir} = file:get_cwd(),
+ ?line {Dir1,Name1} = create_script(latest1_sasl,Config),
+ ?line {_Dir2,Name2} = create_script(current_all_no_sasl,Config),
+
+ ?line DataDir = filename:absname(?copydir),
+ ?line LibDir = [fname([DataDir, d_normal, lib])],
+ ?line P = [fname([LibDir, '*', ebin]),
+ fname([DataDir, lib, kernel, ebin]),
+ fname([DataDir, lib, stdlib, ebin]),
+ fname([DataDir, lib, sasl, ebin])],
+
+ ?line ok = file:set_cwd(Dir1),
+
+ ?line {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]),
+ ?line {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]),
+ ?line {ok,Boot1} = file:read_file(Name1 ++ ".boot"),
+ ?line {ok,Boot2} = file:read_file(Name2 ++ ".boot"),
+
+ ?line BasePaths = {"testkernelpath","teststdlibpath","testsaslpath"},
+ ?line {error,{app_not_found,sasl}} =
+ systools_make:make_boot_hybrid("tmp_vsn",Boot1,Boot2,
+ BasePaths,[dummy,args]),
+
+ ?line ok = file:set_cwd(OldDir),
+ ok.
+
+
+
otp_6226(suite) ->
[];
otp_6226(doc) ->
@@ -1709,6 +1905,36 @@ create_script(latest1,Config) ->
[]),
?line ok = file:close(Fd),
{filename:dirname(Name), filename:basename(Name)};
+create_script(latest1_sasl,Config) ->
+ ?line PrivDir = ?privdir,
+ ?line Name = fname(PrivDir, latest_sasl),
+ ?line {ok,Fd} = file:open(Name++".rel",write),
+ ?line RelfileContent =
+ {release,{"Test release 2", "LATEST1_SASL"},
+ {erts,"4.4"},
+ [{kernel,"1.0"},
+ {stdlib,"1.0"},
+ {sasl,"1.0"},
+ {db,"1.0"},
+ {fe,"3.1"}]},
+ ?line io:format(Fd,"~p.~n",[RelfileContent]),
+ ?line ok = file:close(Fd),
+ {filename:dirname(Name), filename:basename(Name)};
+create_script(latest1_current_erts,Config) ->
+ ?line PrivDir = ?privdir,
+ ?line Name = fname(PrivDir, 'latest_current_erts'),
+ ?line ErtsVer = erlang:system_info(version),
+ ?line {ok,Fd} = file:open(Name++".rel",write),
+ ?line RelfileContent =
+ {release,{"Test release 2", "LATEST1_CURRENT_ERTS"},
+ {erts,ErtsVer},
+ [{kernel,"1.0"}, % fake - will never happen for real that
+ {stdlib,"1.0"}, % erts changes verson but not kernel and stdlib.
+ {db,"1.0"},
+ {fe,"3.1"}]},
+ ?line io:format(Fd,"~p.~n",[RelfileContent]),
+ ?line ok = file:close(Fd),
+ {filename:dirname(Name), filename:basename(Name)};
create_script(latest2,Config) ->
?line PrivDir = ?privdir,
?line Name = fname(PrivDir, 'latest-2'),
@@ -1813,8 +2039,47 @@ create_script(latest_app_start_type2,Config) ->
{stdlib,StdlibVer} | OtherAppsRel]},
?line io:format(Fd,"~p.~n",[RelfileContent]),
?line ok = file:close(Fd),
+ {filename:dirname(Name), filename:basename(Name)};
+create_script(current_all_no_sasl,Config) ->
+ ?line PrivDir = ?privdir,
+ ?line Name = fname(PrivDir, 'current_all_no_sasl'),
+ ?line ErtsVer = erlang:system_info(version),
+ ?line Apps = application_controller:which_applications(),
+ ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps),
+ ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps),
+ ?line {ok,Fd} = file:open(Name++".rel",write),
+ ?line RelfileContent =
+ {release,{"Test release 4", "CURRENT_ALL_NO_SASL"},
+ {erts,ErtsVer},
+ [{kernel,KernelVer},
+ {stdlib,StdlibVer},
+ {db,"2.1"},
+ {fe,"3.1"}]},
+ ?line io:format(Fd,"~p.~n",[RelfileContent]),
+ ?line ok = file:close(Fd),
+ {filename:dirname(Name), filename:basename(Name)};
+create_script(current_all_sasl,Config) ->
+ ?line PrivDir = ?privdir,
+ ?line Name = fname(PrivDir, 'current_all_sasl'),
+ ?line ErtsVer = erlang:system_info(version),
+ ?line application:load(sasl),
+ ?line Apps = application_controller:loaded_applications(),
+ ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps),
+ ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps),
+ ?line {value,{_,_,SaslVer}} = lists:keysearch(sasl,1,Apps),
+ ?line {ok,Fd} = file:open(Name++".rel",write),
+ ?line RelfileContent =
+ {release,{"Test release 4", "CURRENT_ALL_SASL"},
+ {erts,ErtsVer},
+ [{kernel,KernelVer},
+ {stdlib,StdlibVer},
+ {sasl,SaslVer},
+ {db,"2.1"}]},% fe left out here on purpose - for normal_hybrid test
+ ?line io:format(Fd,"~p.~n",[RelfileContent]),
+ ?line ok = file:close(Fd),
{filename:dirname(Name), filename:basename(Name)}.
+
create_include_files(inc1, Config) ->
?line PrivDir = ?privdir,
?line Name = fname(PrivDir, inc1),
diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app
new file mode 100644
index 0000000000..aaeb37fa4d
--- /dev/null
+++ b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.app
@@ -0,0 +1,6 @@
+{application, sasl,
+ [{description, "FAKE SASL"},
+ {vsn, "1.0"},
+ {modules, []},
+ {registered, []},
+ {applications, []}]}.
diff --git a/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup
new file mode 100644
index 0000000000..796a1e7368
--- /dev/null
+++ b/lib/sasl/test/systools_SUITE_data/lib/sasl/ebin/sasl.appup
@@ -0,0 +1,12 @@
+%%
+%% Fake release upgrade script for sasl
+%%
+
+{
+ "1.0",
+ [
+ ],
+
+ [
+ ]
+}.
diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl
new file mode 100644
index 0000000000..eeef721647
--- /dev/null
+++ b/lib/sasl/test/test_lib.hrl
@@ -0,0 +1,3 @@
+-define(ertsvsn,"4.4").
+-define(kernelvsn,"2.14.3").
+-define(stdlibvsn,"1.17.3").