aboutsummaryrefslogtreecommitdiffstats
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.erl261
1 files changed, 256 insertions, 5 deletions
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index 11f8bbe4fe..467d1226b3 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -59,9 +59,11 @@ win32_cases() ->
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,
- instructions, eval_appup, supervisor_which_children_timeout,
- release_handler_which_releases, install_release_syntax_check].
+ otp_9395_update_many_mods, otp_9395_rm_many_mods, otp_9864,
+ instructions, eval_appup, eval_appup_with_restart,
+ supervisor_which_children_timeout,
+ release_handler_which_releases, install_release_syntax_check,
+ upgrade_supervisor, upgrade_supervisor_fail].
groups() ->
[{release,[],
@@ -1203,6 +1205,163 @@ otp_9395_rm_many_mods(Conf) when is_list(Conf) ->
otp_9395_rm_many_mods(cleanup,_Conf) ->
stop_node(node_name(otp_9395_rm_many_mods)).
+otp_9864(Conf) ->
+ %% Set some paths
+ PrivDir = priv_dir(Conf),
+ Dir = filename:join(PrivDir,"otp_9864"),
+ RelDir = filename:join(?config(data_dir, Conf), "app1_app2"),
+ LibDir1 = filename:join(RelDir, "lib1"),
+ LibDir2 = filename:join(RelDir, "lib2"),
+
+ %% Create the releases
+ Rel1 = create_and_install_fake_first_release(Dir,
+ [{app1,"1.0",LibDir1},
+ {app2,"1.0",LibDir1}]),
+ Rel2 = create_fake_upgrade_release(Dir,
+ "2",
+ [{app1,"2.0",LibDir2},
+ {app2,"1.0",LibDir2}],
+ {[Rel1],[Rel1],[LibDir1]}),
+ Rel1Dir = filename:dirname(Rel1),
+ Rel2Dir = filename:dirname(Rel2),
+
+ %% Start a slave node
+ {ok, Node} = t_start_node(otp_9864, Rel1, filename:join(Rel1Dir,"sys.config")),
+
+ %% Unpack rel2 (make sure it does not work if an AppDir is bad)
+ LibDir3 = filename:join(RelDir, "lib3"),
+ {error, {no_such_directory, _}} =
+ rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", [{app1,"2.0",LibDir2}, {app2,"1.0",LibDir3}]]),
+ {ok, RelVsn2} =
+ rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", [{app1,"2.0",LibDir2}, {app2,"1.0",LibDir2}]]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "relup")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "start.boot")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "sys.config")]),
+
+ %% Install RelVsn2 without {update_paths, true} option
+ {ok, RelVsn1, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn2]),
+
+ %% Install RelVsn1 again
+ {ok, RelVsn1, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn1]),
+
+ TempRel2Dir = filename:join(Dir,"releases/2"),
+ file:make_symlink(TempRel2Dir, filename:join(TempRel2Dir, "foo_symlink_dir")),
+
+ %% This will fail if symlinks are not handled
+ ok = rpc:call(Node, release_handler, remove_release, [RelVsn2]),
+
+ ok.
+
+
+upgrade_supervisor(Conf) when is_list(Conf) ->
+ %% Set some paths
+ PrivDir = priv_dir(Conf),
+ Dir = filename:join(PrivDir,"upgrade_supervisor"),
+ LibDir = filename:join(?config(data_dir, Conf), "lib"),
+
+ %% Create the releases
+ Lib1 = [{a,"1.0",LibDir}],
+ Lib2 = [{a,"9.0",LibDir}],
+ Rel1 = create_and_install_fake_first_release(Dir,Lib1),
+ Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}),
+ Rel1Dir = filename:dirname(Rel1),
+ Rel2Dir = filename:dirname(Rel2),
+
+ %% Start a slave node
+ {ok, Node} = t_start_node(upgrade_supervisor, Rel1,
+ filename:join(Rel1Dir,"sys.config")),
+
+ %% Check path
+ Dir1 = filename:join([LibDir, "a-1.0"]),
+ Dir1 = rpc:call(Node, code, lib_dir, [a]),
+ ASupBeam1 = filename:join([Dir1,ebin,"a_sup.beam"]),
+ ASupBeam1 = rpc:call(Node, code, which, [a_sup]),
+
+ %% Install second release, with no changed modules
+ {ok, RelVsn2} = rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", Lib2]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "relup")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "start.boot")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "sys.config")]),
+
+ {ok, _RelVsn1, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn2]),
+
+ %% Check that libdir is changed
+ Dir2 = filename:join([LibDir, "a-9.0"]),
+ Dir2 = rpc:call(Node, code, lib_dir, [a]),
+ ASupBeam2 = filename:join([Dir2,ebin,"a_sup.beam"]),
+ ASupBeam2 = rpc:call(Node, code, which, [a_sup]),
+
+ %% Check that the restart strategy and child spec is updated
+ {status, _, {module, _}, [_, _, _, _, [_,_,{data,[{"State",State}]}]]} =
+ rpc:call(Node,sys,get_status,[a_sup]),
+ {state,_,RestartStrategy,[Child],_,_,_,_,_,_} = State,
+ one_for_all = RestartStrategy, % changed from one_for_one
+ {child,_,_,_,_,brutal_kill,_,_} = Child, % changed from timeout 2000
+
+ ok.
+
+%% Check that if the supervisor fails, then the upgrade is rolled back
+%% and an ok error message is returned
+upgrade_supervisor_fail(Conf) when is_list(Conf) ->
+ %% Set some paths
+ PrivDir = priv_dir(Conf),
+ Dir = filename:join(PrivDir,"upgrade_supervisor_fail"),
+ LibDir = filename:join(?config(data_dir, Conf), "lib"),
+
+ %% Create the releases
+ Lib1 = [{a,"1.0",LibDir}],
+ Lib2 = [{a,"9.1",LibDir}],
+ Rel1 = create_and_install_fake_first_release(Dir,Lib1),
+ Rel2 = create_fake_upgrade_release(Dir,"2",Lib2,{[Rel1],[Rel1],[LibDir]}),
+ Rel1Dir = filename:dirname(Rel1),
+ Rel2Dir = filename:dirname(Rel2),
+
+ %% Start a slave node
+ {ok, Node} = t_start_node(upgrade_supervisor_fail, Rel1,
+ filename:join(Rel1Dir,"sys.config")),
+
+ %% Check path
+ Dir1 = filename:join([LibDir, "a-1.0"]),
+ Dir1 = rpc:call(Node, code, lib_dir, [a]),
+ ASupBeam1 = filename:join([Dir1,ebin,"a_sup.beam"]),
+ ASupBeam1 = rpc:call(Node, code, which, [a_sup]),
+
+ %% Install second release, with no changed modules
+ {ok, RelVsn2} = rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", Lib2]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "relup")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "start.boot")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "sys.config")]),
+ ok = net_kernel:monitor_nodes(true),
+
+ {error,{code_change_failed,_Pid,a_sup,_Vsn,
+ {error,{invalid_shutdown,brutal_kil}}}} =
+ rpc:call(Node, release_handler, install_release, [RelVsn2]),
+
+ %% Check that the upgrade is terminated - normally this would mean
+ %% rollback, but since this testcase is very simplified the node
+ %% is not started with heart supervision and will therefore not be
+ %% restarted. So we just check that the node goes down.
+ receive {nodedown,Node} -> ok
+ after 10000 -> ct:fail(failed_upgrade_never_restarted_node)
+ end,
+
+ ok.
%% Test upgrade and downgrade of applications
@@ -1226,6 +1385,12 @@ eval_appup(Conf) when is_list(Conf) ->
App11Dir = code:lib_dir(app1),
ok = gen_server:call(harry, error),
+ %% Read appup script
+ {ok,"2.0",UpScript} = release_handler:upgrade_script(app1,App12Dir),
+ [{load_object_code,_},
+ point_of_no_return,
+ {load,_}] = UpScript,
+
%% Upgrade to app1-2.0
{ok, []} = release_handler:upgrade_app(app1, App12Dir),
App12Dir = code:lib_dir(app1),
@@ -1236,6 +1401,12 @@ eval_appup(Conf) when is_list(Conf) ->
%% (see myrel/lib2/app1-2.0/ebin/app1.app)
[{var,val2}] = ets:lookup(otp_6162, var),
+ %% Read appup script
+ {ok,DnScript} = release_handler:downgrade_script(app1,"1.0",App11Dir),
+ [{load_object_code,_},
+ point_of_no_return,
+ {load,_}] = DnScript,
+
%% Downgrade to app1-1.0
{ok, []} = release_handler:downgrade_app(app1,"1.0",App11Dir),
App11Dir = code:lib_dir(app1),
@@ -1253,6 +1424,85 @@ eval_appup(Conf) when is_list(Conf) ->
ok.
+%% Test upgrade and downgrade of applications when appup contains
+%% restart_emulator and restart_new_emulator instructions
+eval_appup_with_restart(Conf) when is_list(Conf) ->
+
+ %% Set some paths
+ RelDir = filename:join(?config(data_dir, Conf), "app1_app2"),
+ App11Dir = filename:join([RelDir, "lib1", "app1-1.0"]),
+ App13Dir = filename:join([RelDir, "lib3", "app1-3.0"]), %restart_emulator
+ App14Dir = filename:join([RelDir, "lib4", "app1-4.0"]), %restart_new_emulator
+ EbinDir1 = filename:join(App11Dir, "ebin"),
+ EbinDir3 = filename:join(App13Dir, "ebin"),
+ EbinDir4 = filename:join(App14Dir, "ebin"),
+
+ %% Start app1-1.0
+ code:add_patha(EbinDir1),
+ ok = application:start(app1),
+ App11Dir = code:lib_dir(app1),
+
+ %% Read appup script
+ {ok,"3.0",UpScript3} = release_handler:upgrade_script(app1,App13Dir),
+ [{load_object_code,_},
+ point_of_no_return,
+ {load,_},
+ restart_emulator] = UpScript3,
+
+ %% Upgrade to app1-3.0 - restart_emulator
+ restart_emulator = release_handler:upgrade_app(app1, App13Dir),
+ App13Dir = code:lib_dir(app1),
+
+ %% Fake full upgrade to 3.0
+ {ok,AppSpec} = file:consult(filename:join([App13Dir,"ebin","app1.app"])),
+ application_controller:change_application_data(AppSpec,[]),
+
+ %% Read appup script
+ {ok,"4.0",UpScript4} = release_handler:upgrade_script(app1,App14Dir),
+ [restart_new_emulator,point_of_no_return] = UpScript4,
+
+ %% Try pgrade to app1-4.0 - restart_new_emulator
+ {error,restart_new_emulator} = release_handler:upgrade_app(app1, App14Dir),
+ App13Dir = code:lib_dir(app1),
+
+ %% Read appup script
+ {ok,DnScript1} = release_handler:downgrade_script(app1,"1.0",App11Dir),
+ [{load_object_code,_},
+ point_of_no_return,
+ {load,_},
+ restart_emulator] = DnScript1,
+
+ %% Still running 3.0 - downgrade to app1-1.0 - restart_emulator
+ restart_emulator = release_handler:downgrade_app(app1,"1.0",App11Dir),
+ App11Dir = code:lib_dir(app1),
+
+ ok = application:stop(app1),
+ ok = application:unload(app1),
+ true = code:del_path(EbinDir1),
+
+ %% Start again as version 4.0
+ code:add_patha(EbinDir4),
+ ok = application:start(app1),
+ App14Dir = code:lib_dir(app1),
+
+ %% Read appup script
+ {ok,DnScript3} = release_handler:downgrade_script(app1,"3.0",App13Dir),
+ [point_of_no_return,restart_emulator] = DnScript3,
+
+ %% Downgrade to app1-3.0 - restart_new_emulator
+ restart_emulator = release_handler:downgrade_app(app1,"3.0",App13Dir),
+ App13Dir = code:lib_dir(app1),
+
+ ok = application:stop(app1),
+ ok = application:unload(app1),
+
+ true = code:del_path(EbinDir3),
+ false = code:del_path(EbinDir1),
+ false = code:del_path(EbinDir4),
+
+ ok.
+
+
%% Test the example/target_system.erl module
target_system(Conf) when is_list(Conf) ->
PrivDir = priv_dir(Conf),
@@ -1303,6 +1553,7 @@ target_system(Conf) when is_list(Conf) ->
KernelVsn = vsn(kernel,current),
StdlibVsn = vsn(stdlib,current),
SaslVsn = vsn(sasl,current),
+ RelFileBasename = filename:basename(RelFile),
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)),
@@ -1310,10 +1561,10 @@ target_system(Conf) when is_list(Conf) ->
RelDir = filename:join(TargetInstallDir,releases),
true = filelib:is_regular(filename:join(RelDir,"RELEASES")),
true = filelib:is_regular(filename:join(RelDir,"start_erl.data")),
- true = filelib:is_regular(filename:join(RelDir,
- filename:basename(RelFile))),
+ true = filelib:is_regular(filename:join(RelDir,RelFileBasename)),
true = filelib:is_dir(filename:join(RelDir,RelVsn)),
true = filelib:is_regular(filename:join([RelDir,RelVsn,"start.boot"])),
+ true = filelib:is_regular(filename:join([RelDir,RelVsn,RelFileBasename])),
BinDir = filename:join(TargetInstallDir,bin),
true = filelib:is_regular(filename:join(BinDir,"start.boot")),
true = filelib:is_regular(filename:join(BinDir,erl)),