diff options
Diffstat (limited to 'lib/sasl')
18 files changed, 417 insertions, 107 deletions
diff --git a/lib/sasl/doc/src/release_handler.xml b/lib/sasl/doc/src/release_handler.xml index 7f32100d4b..bd4a513750 100644 --- a/lib/sasl/doc/src/release_handler.xml +++ b/lib/sasl/doc/src/release_handler.xml @@ -492,7 +492,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). </section> <funcs> <func> - <name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>upgrade_app(App, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Upgrade to a new application version</fsummary> <type> <v>App = atom()</v> @@ -521,14 +521,21 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). does.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when finding or evaluating the script.</p> + <p>If the <c>restart_new_emulator</c> instruction is found in + the script, <c>upgrade_app/2</c> will return + <c>{error,restart_new_emulator}</c>. The reason for this is + that this instruction requires that a new version of the + emulator is started before the rest of the upgrade + instructions can be executed, and this can only be done by + <c>install_release/1,2</c>.</p> </desc> </func> <func> <name>downgrade_app(App, Dir) -></name> - <name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>downgrade_app(App, OldVsn, Dir) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Downgrade to a previous application version</fsummary> <type> <v>App = atom()</v> @@ -562,7 +569,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). does.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when finding or evaluating the script.</p> </desc> @@ -638,7 +645,7 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). </desc> </func> <func> - <name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_new_emulator | {error, Reason}</name> + <name>eval_appup_script(App, ToVsn, ToDir, Script) -> {ok, Unpurged} | restart_emulator | {error, Reason}</name> <fsummary>Evaluate an application upgrade or downgrade script</fsummary> <type> <v>App = atom()</v> @@ -651,8 +658,8 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <desc> <p>Evaluates an application upgrade or downgrade script <c>Script</c>, the result from calling - <seealso marker="#upgrade_app/2">upgrade_app/2</seealso> or - <seealso marker="#downgrade_app/3">downgrade_app/2,3</seealso>, + <seealso marker="#upgrade_app/2">upgrade_script/2</seealso> or + <seealso marker="#downgrade_app/3">downgrade_script/3</seealso>, exactly in the same way as <seealso marker="#install_release/1">install_release/1,2</seealso> does.</p> @@ -663,9 +670,16 @@ release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]). <c>.appup</c> files should be located under <c>Dir/ebin</c>.</p> <p>Returns <c>{ok, Unpurged}</c> if evaluating the script is successful, where <c>Unpurged</c> is a list of unpurged - modules, or <c>restart_new_emulator</c> if this instruction is + modules, or <c>restart_emulator</c> if this instruction is encountered in the script, or <c>{error, Reason}</c> if an error occurred when evaluating the script.</p> + <p>If the <c>restart_new_emulator</c> instruction is found in + the script, <c>eval_appup_script/4</c> will return + <c>{error,restart_new_emulator}</c>. The reason for this is + that this instruction requires that a new version of the + emulator is started before the rest of the upgrade + instructions can be executed, and this can only be done by + <c>install_release/1,2</c>.</p> </desc> </func> </funcs> diff --git a/lib/sasl/doc/src/systools.xml b/lib/sasl/doc/src/systools.xml index fa2fcbf534..1b90f0d4ee 100644 --- a/lib/sasl/doc/src/systools.xml +++ b/lib/sasl/doc/src/systools.xml @@ -138,8 +138,9 @@ <fsummary>Generate a boot script <c>.script/.boot</c>.</fsummary> <type> <v>Name = string()</v> - <v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref | {exref,[App]}] - | silent | {outdir,Dir} | warnings_as_errors</v> + <v>Opt = src_tests | {path,[Dir]} | local | {variables,[Var]} | exref | + {exref,[App]}] | silent | {outdir,Dir} | no_warn_sasl | + warnings_as_errors</v> <v> Dir = string()</v> <v> Var = {VarName,Prefix}</v> <v> VarName = Prefix = string()</v> @@ -195,6 +196,10 @@ <p>The applications are sorted according to the dependencies between the applications. Where there are no dependencies, the order in the <c>.rel</c> file is kept.</p> + <p>If <c>sasl</c> is not included as an application in + the <c>.rel</c> file, a warning is emitted because such a + release can not be used in an upgrade. To turn of this + warning, add the option <c>no_warn_sasl</c>.</p> <p>All files are searched for in the current path. It is assumed that the <c>.app</c> and <c>.beam</c> files for an application is located in the same directory. The <c>.erl</c> @@ -225,7 +230,7 @@ <p>Example: If the option <c>{variables,[{"TEST","lib"}]}</c> is supplied, and <c>myapp.app</c> is found in <c>lib/myapp/ebin</c>, then the path to this application in - the boot script will be <c>$TEST/myapp-1/ebin"</c>. If + the boot script will be <c>"$TEST/myapp-1/ebin"</c>. If <c>myapp.app</c> is found in <c>lib/test</c>, then the path will be <c>$TEST/test/myapp-1/ebin</c>.</p> <p>The checks performed before the boot script is generated can diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl index 4e8cb4628c..b6ef8582c4 100644 --- a/lib/sasl/src/release_handler.erl +++ b/lib/sasl/src/release_handler.erl @@ -1050,38 +1050,50 @@ new_emulator_make_tmp_release(CurrentRelease,ToRelease,RelDir,Opts,Masters) -> CurrentVsn = CurrentRelease#release.vsn, ToVsn = ToRelease#release.vsn, TmpVsn = ?tmp_vsn(CurrentVsn), - BaseApps = [kernel,stdlib,sasl], - BaseLibs = [{App,Vsn,Lib} || {App,Vsn,Lib} <- ToRelease#release.libs, - lists:member(App,BaseApps)], - check_base_libs(BaseLibs,ToVsn), - OldBaseLibs = [{App,Vsn,Lib} || {App,Vsn,Lib} <- CurrentRelease#release.libs, - lists:member(App,BaseApps)], - check_base_libs(OldBaseLibs,CurrentVsn), - RestLibs = [{App,Vsn,Lib} || {App,Vsn,Lib} <- CurrentRelease#release.libs, - not lists:member(App,BaseApps)], - TmpRelease = CurrentRelease#release{vsn=TmpVsn, - erts_vsn=ToRelease#release.erts_vsn, - libs = BaseLibs ++ RestLibs, - status = unpacked}, - new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs, - RelDir,Opts,Masters), - new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn,RelDir,Masters), - {TmpVsn,TmpRelease}. - -check_base_libs([_,_,_]=BaseLibs,_Vsn) -> - [Kernel,Sasl,Stdlib] = lists:keysort(1,BaseLibs), - [Kernel,Stdlib,Sasl]; -check_base_libs(SomeMissing,Vsn) -> - find_missing(SomeMissing,[kernel,stdlib,sasl],Vsn). - -find_missing(SomeMissing,[H|T],Vsn) -> - case lists:keymember(H,1,SomeMissing) of - true -> - find_missing(SomeMissing,T,Vsn); - false -> - throw({error,{missing_base_app,Vsn,H}}) + case get_base_libs(ToRelease#release.libs) of + {ok,{Kernel,Stdlib,Sasl}=BaseLibs,_} -> + case get_base_libs(ToRelease#release.libs) of + {ok,_,RestLibs} -> + TmpErtsVsn = ToRelease#release.erts_vsn, + TmpLibs = [Kernel,Stdlib,Sasl|RestLibs], + TmpRelease = CurrentRelease#release{vsn=TmpVsn, + erts_vsn=TmpErtsVsn, + libs = TmpLibs, + status = unpacked}, + new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn, + BaseLibs,RelDir,Opts,Masters), + new_emulator_make_hybrid_config(CurrentVsn,ToVsn,TmpVsn, + RelDir,Masters), + {TmpVsn,TmpRelease}; + {error,{missing,Missing}} -> + throw({error,{missing_base_app,CurrentVsn,Missing}}) + end; + {error,{missing,Missing}} -> + throw({error,{missing_base_app,ToVsn,Missing}}) end. +%% Get kernel, stdlib and sasl libs, +%% and also return the rest of the libs as a list. +%% Return error if any of kernel, stdlib or sasl does not exist. +get_base_libs(Libs) -> + get_base_libs(Libs,undefined,undefined,undefined,[]). +get_base_libs([{kernel,_,_}=Kernel|Libs],undefined,Stdlib,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([{stdlib,_,_}=Stdlib|Libs],Kernel,undefined,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([{sasl,_,_}=Sasl|Libs],Kernel,Stdlib,undefined,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,Rest); +get_base_libs([Lib|Libs],Kernel,Stdlib,Sasl,Rest) -> + get_base_libs(Libs,Kernel,Stdlib,Sasl,[Lib|Rest]); +get_base_libs([],undefined,_Stdlib,_Sasl,_Rest) -> + {error,{missing,kernel}}; +get_base_libs([],_Kernel,undefined,_Sasl,_Rest) -> + {error,{missing,stdlib}}; +get_base_libs([],_Kernel,_Stdlib,undefined,_Rest) -> + {error,{missing,sasl}}; +get_base_libs([],Kernel,Stdlib,Sasl,Rest) -> + {ok,{Kernel,Stdlib,Sasl},lists:reverse(Rest)}. + new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs,RelDir,Opts,Masters) -> FromBootFile = filename:join([RelDir,CurrentVsn,"start.boot"]), ToBootFile = filename:join([RelDir,ToVsn,"start.boot"]), @@ -1090,9 +1102,10 @@ new_emulator_make_hybrid_boot(CurrentVsn,ToVsn,TmpVsn,BaseLibs,RelDir,Opts,Maste Args = [ToVsn,Opts], {ok,FromBoot} = read_file(FromBootFile,Masters), {ok,ToBoot} = read_file(ToBootFile,Masters), - [KernelPath,SaslPath,StdlibPath] = - [filename:join(Path,ebin) || {_,_,Path} <- lists:keysort(1,BaseLibs)], - Paths = {KernelPath,StdlibPath,SaslPath}, + {{_,_,KernelPath},{_,_,SaslPath},{_,_,StdlibPath}} = BaseLibs, + Paths = {filename:join(KernelPath,"ebin"), + filename:join(StdlibPath,"ebin"), + filename:join(SaslPath,"ebin")}, case systools_make:make_hybrid_boot(TmpVsn,FromBoot,ToBoot,Paths,Args) of {ok,TmpBoot} -> write_file(TmpBootFile,TmpBoot,Masters); diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl index b4b288646f..37275eff45 100644 --- a/lib/sasl/src/release_handler_1.erl +++ b/lib/sasl/src/release_handler_1.erl @@ -459,7 +459,9 @@ eval({apply, {M, F, A}}, EvalState) -> apply(M, F, A), EvalState; eval(restart_emulator, _EvalState) -> - throw(restart_emulator). + throw(restart_emulator); +eval(restart_new_emulator, _EvalState) -> + throw(restart_new_emulator). get_opt(Tag, EvalState, Default) -> case lists:keysearch(Tag, 1, EvalState#eval_state.opts) of diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index ce37f3c2ce..1c14027805 100644 --- a/lib/sasl/src/systools_make.erl +++ b/lib/sasl/src/systools_make.erl @@ -58,6 +58,7 @@ %% {variables,[{Name,AbsString}]} %% {machine, jam | beam | vee} %% exref | {exref, [AppName]} +%% no_warn_sasl %%----------------------------------------------------------------- make_script(RelName) when is_list(RelName) -> @@ -88,7 +89,8 @@ make_script(RelName, Output, Flags) when is_list(RelName), Path = make_set(Path1 ++ code:get_path()), ModTestP = {member(src_tests, Flags),xref_p(Flags)}, case get_release(RelName, Path, ModTestP, machine(Flags)) of - {ok, Release, Appls, Warnings} -> + {ok, Release, Appls, Warnings0} -> + Warnings = wsasl(Flags, Warnings0), case systools_lib:werror(Flags, Warnings) of true -> return(ok,Warnings,Flags); @@ -112,7 +114,13 @@ make_script(RelName, _Output, Flags) when is_list(Flags) -> make_script(RelName, _Output, Flags) -> badarg(Flags,[RelName, Flags]). -%% Inlined. + +wsasl(Options, Warnings) -> + case lists:member(no_warn_sasl,Options) of + true -> lists:delete({warning,missing_sasl},Warnings); + false -> Warnings + end. + badarg(BadArg, Args) -> erlang:error({badarg,BadArg}, Args). @@ -1970,90 +1978,67 @@ get_flag(_,_) -> false. %% Check Options for make_script check_args_script(Args) -> - cas(Args, - {undef, undef, undef, undef, undef, undef, undef, undef, - undef, []}). + cas(Args, []). -cas([], {_Path,_Sil,_Loc,_Test,_Var,_Mach,_Xref,_XrefApps,_Werror, X}) -> +cas([], X) -> X; %%% path --------------------------------------------------------------- -cas([{path, P} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(P) -> +cas([{path, P} | Args], X) when is_list(P) -> case check_path(P) of ok -> - cas(Args, {P, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{path,P}]}) + cas(Args, X++[{path,P}]) end; %%% silent ------------------------------------------------------------- -cas([silent | Args], {Path, _Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, silent, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([silent | Args], X) -> + cas(Args, X); %%% local -------------------------------------------------------------- -cas([local | Args], {Path, Sil, _Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, local, Test, Var, Mach, Xref, XrefApps, - Werror, X}); +cas([local | Args], X) -> + cas(Args, X); %%% src_tests ------------------------------------------------------- -cas([src_tests | Args], {Path, Sil, Loc, _Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, - {Path, Sil, Loc, src_tests, Var, Mach, Xref, Werror, XrefApps,X}); +cas([src_tests | Args], X) -> + cas(Args, X); %%% variables ---------------------------------------------------------- -cas([{variables, V} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(V) -> +cas([{variables, V} | Args], X) when is_list(V) -> case check_vars(V) of ok -> - cas(Args, - {Path, Sil, Loc, Test, V, Mach, Xref, XrefApps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X++[{variables, V}]}) + cas(Args, X++[{variables, V}]) end; %%% machine ------------------------------------------------------------ -cas([{machine, M} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_atom(M) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{machine, M} | Args], X) when is_atom(M) -> + cas(Args, X); %%% exref -------------------------------------------------------------- -cas([exref | Args], {Path, Sil, Loc, Test, Var, Mach, _Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, exref, XrefApps, Werror, X}); +cas([exref | Args], X) -> + cas(Args, X); %%% exref Apps --------------------------------------------------------- -cas([{exref, Apps} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Apps) -> +cas([{exref, Apps} | Args], X) when is_list(Apps) -> case check_apps(Apps) of ok -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, Apps, Werror, X}); + cas(Args, X); error -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, - Xref, XrefApps, Werror, X++[{exref, Apps}]}) + cas(Args, X++[{exref, Apps}]) end; %%% outdir Dir --------------------------------------------------------- -cas([{outdir, Dir} | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) when is_list(Dir) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([{outdir, Dir} | Args], X) when is_list(Dir) -> + cas(Args, X); %%% otp_build (secret, not documented) --------------------------------- -cas([otp_build | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); +cas([otp_build | Args], X) -> + cas(Args, X); +%%% warnings_as_errors ------------------------------------------------- +cas([warnings_as_errors | Args], X) -> + cas(Args, X); +%%% no_warn_sasl ------------------------------------------------------- +cas([no_warn_sasl | Args], X) -> + cas(Args, X); %%% no_module_tests (kept for backwards compatibility, but ignored) ---- -cas([no_module_tests | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, X}); -%%% warnings_as_errors (kept for backwards compatibility, but ignored) ---- -cas([warnings_as_errors | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, - XrefApps, _Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - warnings_as_errors, X}); +cas([no_module_tests | Args], X) -> + cas(Args, X); %%% ERROR -------------------------------------------------------------- -cas([Y | Args], {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, - Werror, X}) -> - cas(Args, {Path, Sil, Loc, Test, Var, Mach, Xref, XrefApps, Werror, - X++[Y]}). +cas([Y | Args], X) -> + cas(Args, X++[Y]). diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl index 11f8bbe4fe..454fe26323 100644 --- a/lib/sasl/test/release_handler_SUITE.erl +++ b/lib/sasl/test/release_handler_SUITE.erl @@ -60,7 +60,8 @@ 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, + instructions, eval_appup, eval_appup_with_restart, + supervisor_which_children_timeout, release_handler_which_releases, install_release_syntax_check]. groups() -> @@ -1226,6 +1227,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 +1243,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 +1266,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), diff --git a/lib/sasl/test/release_handler_SUITE_data/Makefile.src b/lib/sasl/test/release_handler_SUITE_data/Makefile.src index edb446413d..6f40088161 100644 --- a/lib/sasl/test/release_handler_SUITE_data/Makefile.src +++ b/lib/sasl/test/release_handler_SUITE_data/Makefile.src @@ -50,7 +50,13 @@ APP= \ app1_app2/lib2/app1-2.0/ebin/app1.@EMULATOR@ \ app1_app2/lib2/app2-1.0/ebin/app2_sup.@EMULATOR@ \ app1_app2/lib2/app2-1.0/ebin/app2_server.@EMULATOR@ \ - app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@ + app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1_sup.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1_server.@EMULATOR@ \ + app1_app2/lib3/app1-3.0/ebin/app1.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1_sup.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1_server.@EMULATOR@ \ + app1_app2/lib4/app1-4.0/ebin/app1.@EMULATOR@ OTP2740= \ otp_2740/vsn_atom.@EMULATOR@ \ @@ -183,6 +189,22 @@ app1_app2/lib2/app2-1.0/ebin/app2.@EMULATOR@: app1_app2/lib2/app2-1.0/src/app2.e erlc $(EFLAGS) -oapp1_app2/lib2/app2-1.0/ebin app1_app2/lib2/app2-1.0/src/app2.erl +app1_app2/lib3/app1-3.0/ebin/app1_sup.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1_sup.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1_sup.erl +app1_app2/lib3/app1-3.0/ebin/app1_server.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1_server.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1_server.erl +app1_app2/lib3/app1-3.0/ebin/app1.@EMULATOR@: app1_app2/lib3/app1-3.0/src/app1.erl + erlc $(EFLAGS) -oapp1_app2/lib3/app1-3.0/ebin app1_app2/lib3/app1-3.0/src/app1.erl + + +app1_app2/lib4/app1-4.0/ebin/app1_sup.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1_sup.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1_sup.erl +app1_app2/lib4/app1-4.0/ebin/app1_server.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1_server.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1_server.erl +app1_app2/lib4/app1-4.0/ebin/app1.@EMULATOR@: app1_app2/lib4/app1-4.0/src/app1.erl + erlc $(EFLAGS) -oapp1_app2/lib4/app1-4.0/ebin app1_app2/lib4/app1-4.0/src/app1.erl + + otp_2740/vsn_atom.@EMULATOR@: otp_2740/vsn_atom.erl erlc $(EFLAGS) -ootp_2740 otp_2740/vsn_atom.erl otp_2740/vsn_list.@EMULATOR@: otp_2740/vsn_list.erl diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app new file mode 100644 index 0000000000..4adc0540c4 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.app @@ -0,0 +1,9 @@ +{application, app1, + [{description, "very simple example application"}, + {id, "app1"}, + {vsn, "3.0"}, + {modules, [app1, app1_sup, app1_server]}, + {registered, [harry]}, + {applications, [kernel, stdlib, sasl]}, + {env, [{var,val2}]}, + {mod, {app1, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup new file mode 100644 index 0000000000..a5cdfe9fcc --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/ebin/app1.appup @@ -0,0 +1,4 @@ +{"3.0", + [{"1.0", [{load_module, app1_server},restart_emulator]}], + [{"1.0", [{load_module, app1_server},restart_emulator]}] +}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl new file mode 100644 index 0000000000..f123c8f470 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1.erl @@ -0,0 +1,22 @@ +-module(app1). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). +-export([config_change/3]). + +start(_Type, _StartArgs) -> + case app1_sup:start_link() of + {ok, Pid} -> + {ok, Pid}; + Error -> + Error + end. + +stop(_State) -> + ok. + +config_change(Changed, _New, _Removed) -> + catch ets:insert(otp_6162, hd(Changed)), + ok. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl new file mode 100644 index 0000000000..660d095ebf --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_server.erl @@ -0,0 +1,35 @@ +-module(app1_server). + +-behaviour(gen_server). + +%% API +-export([start_link/0]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, harry}, ?MODULE, [], []). + +init([]) -> + {ok, []}. + +handle_call(error, _From, State) -> + Reply = error, + {reply, Reply, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl new file mode 100644 index 0000000000..e6ad9b6967 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib3/app1-3.0/src/app1_sup.erl @@ -0,0 +1,17 @@ +-module(app1_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +start_link() -> + supervisor:start_link(?MODULE, []). + +init([]) -> + AChild = {harry,{app1_server,start_link,[]}, + permanent,2000,worker,[app1_server]}, + {ok,{{one_for_all,0,1}, [AChild]}}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app new file mode 100644 index 0000000000..243bc21f02 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.app @@ -0,0 +1,9 @@ +{application, app1, + [{description, "very simple example application"}, + {id, "app1"}, + {vsn, "4.0"}, + {modules, [app1, app1_sup, app1_server]}, + {registered, [harry]}, + {applications, [kernel, stdlib, sasl]}, + {env, [{var,val2}]}, + {mod, {app1, []}}]}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup new file mode 100644 index 0000000000..72535c8b34 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/ebin/app1.appup @@ -0,0 +1,4 @@ +{"4.0", + [{"3.0", [restart_new_emulator]}], + [{"3.0", [restart_new_emulator]}] +}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl new file mode 100644 index 0000000000..f123c8f470 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1.erl @@ -0,0 +1,22 @@ +-module(app1). + +-behaviour(application). + +%% Application callbacks +-export([start/2, stop/1]). +-export([config_change/3]). + +start(_Type, _StartArgs) -> + case app1_sup:start_link() of + {ok, Pid} -> + {ok, Pid}; + Error -> + Error + end. + +stop(_State) -> + ok. + +config_change(Changed, _New, _Removed) -> + catch ets:insert(otp_6162, hd(Changed)), + ok. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl new file mode 100644 index 0000000000..660d095ebf --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_server.erl @@ -0,0 +1,35 @@ +-module(app1_server). + +-behaviour(gen_server). + +%% API +-export([start_link/0]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, harry}, ?MODULE, [], []). + +init([]) -> + {ok, []}. + +handle_call(error, _From, State) -> + Reply = error, + {reply, Reply, State}; +handle_call(_Request, _From, State) -> + Reply = ok, + {reply, Reply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl new file mode 100644 index 0000000000..e6ad9b6967 --- /dev/null +++ b/lib/sasl/test/release_handler_SUITE_data/app1_app2/lib4/app1-4.0/src/app1_sup.erl @@ -0,0 +1,17 @@ +-module(app1_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +start_link() -> + supervisor:start_link(?MODULE, []). + +init([]) -> + AChild = {harry,{app1_server,start_link,[]}, + permanent,2000,worker,[app1_server]}, + {ok,{{one_for_all,0,1}, [AChild]}}. diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl index 892c4994e8..beb1e48ca7 100644 --- a/lib/sasl/test/systools_SUITE.erl +++ b/lib/sasl/test/systools_SUITE.erl @@ -411,6 +411,9 @@ no_sasl_script(Config) when is_list(Config) -> ?line {ok, _ , [{warning,missing_sasl}]} = systools:make_script(LatestName,[{path, P},silent]), + ?line {ok, _ , []} = + systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]), + ?line ok = file:set_cwd(OldDir), ok. |