aboutsummaryrefslogtreecommitdiffstats
path: root/lib/reltool
diff options
context:
space:
mode:
Diffstat (limited to 'lib/reltool')
-rw-r--r--lib/reltool/src/reltool.hrl6
-rw-r--r--lib/reltool/src/reltool_server.erl59
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl391
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/ebin/a.app1
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl49
-rw-r--r--lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl37
6 files changed, 509 insertions, 34 deletions
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl
index 93f47f6381..8e80c80e10 100644
--- a/lib/reltool/src/reltool.hrl
+++ b/lib/reltool/src/reltool.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -199,8 +199,8 @@
used_by_mods :: [mod_name()],
uses_apps :: [app_name()],
used_by_apps :: [app_name()],
- is_pre_included :: boolean(),
- is_included :: boolean(),
+ is_pre_included :: boolean() | undefined,
+ is_included :: boolean() | undefined,
rels :: [rel_name()]
}).
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 692baea0a4..fdb9e08a90 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -254,7 +254,7 @@ loop(#state{common = C, sys = Sys} = S) ->
{S2, Status} = parse_options(S#state.options),
S3 = shrink_sys(S2),
{S4, Status2} = refresh(S3, true, Status),
- {S5, Status3} = analyse(S4#state{old_sys = S4#state.sys}, Status2),
+ {S5, Status3} = analyse(S4#state{old_sys = S#state.sys}, Status2),
S6 =
case Status3 of
{ok, _Warnings} ->
@@ -266,11 +266,11 @@ loop(#state{common = C, sys = Sys} = S) ->
reltool_utils:reply(ReplyTo, Ref, Status3),
?MODULE:loop(S6);
{call, ReplyTo, Ref, undo_config} ->
- reltool_utils:reply(ReplyTo, Ref, ok),
S2 = S#state{sys = S#state.old_sys,
old_sys = S#state.sys,
status = S#state.old_status,
old_status = S#state.status},
+ reltool_utils:reply(ReplyTo, Ref, ok),
?MODULE:loop(S2);
{call, ReplyTo, Ref, {get_rel, RelName}} ->
Sys = S#state.sys,
@@ -319,19 +319,21 @@ loop(#state{common = C, sys = Sys} = S) ->
?MODULE:loop(S);
{call, ReplyTo, Ref, {set_app, App}} ->
{S2, Status} = do_set_app(S, App, {ok, []}),
- {S3, Status2} = analyse(S2, Status),
- case Status2 of
- {ok, Warnings} ->
- App2 = ?KEYSEARCH(App#app.name,
- #app.name,
- (S3#state.sys)#sys.apps),
- reltool_utils:reply(ReplyTo, Ref, {ok, App2, Warnings}),
- ?MODULE:loop(S3);
- {error, Reason} ->
- %% Keep old state
- reltool_utils:reply(ReplyTo, Ref, {error, Reason}),
- ?MODULE:loop(S)
- end;
+ {S3, Status2} = analyse(S2#state{old_sys=S#state.sys}, Status),
+ {S4, Reply} =
+ case Status2 of
+ {ok, Warnings} ->
+ App2 = ?KEYSEARCH(App#app.name,
+ #app.name,
+ (S3#state.sys)#sys.apps),
+ {S3#state{status=Status2, old_status=S#state.status},
+ {ok, App2, Warnings}};
+ {error, _} ->
+ %% Keep old state
+ {S, Status2}
+ end,
+ reltool_utils:reply(ReplyTo, Ref, Reply),
+ ?MODULE:loop(S4);
{call, ReplyTo, Ref, {get_apps, Kind}} ->
AppNames =
case Kind of
@@ -361,9 +363,17 @@ loop(#state{common = C, sys = Sys} = S) ->
lists:foldl(fun(A, {X, Y}) -> do_set_app(X, A, Y) end,
{S, {ok, []}},
Apps),
- {S3, Status2} = analyse(S2, Status),
+ {S3, Status2} = analyse(S2#state{old_sys = S#state.sys}, Status),
+ S4 =
+ case Status2 of
+ {ok, _Warnings} ->
+ S3#state{status=Status2, old_status=S#state.status};
+ {error, _} ->
+ %% Keep old state
+ S
+ end,
reltool_utils:reply(ReplyTo, Ref, Status2),
- ?MODULE:loop(S3);
+ ?MODULE:loop(S4);
{call, ReplyTo, Ref, get_sys} ->
reltool_utils:reply(ReplyTo, Ref, {ok, Sys#sys{apps = undefined}}),
?MODULE:loop(S);
@@ -374,19 +384,16 @@ loop(#state{common = C, sys = Sys} = S) ->
(Sys2#sys.lib_dirs =/= Sys#sys.lib_dirs) orelse
(Sys2#sys.escripts =/= Sys#sys.escripts),
{S3, Status} = refresh(S2, Force, {ok, []}),
- {S4, Status2} =
- analyse(S3#state{old_sys = S#state.sys}, Status),
- {S5, Status3} =
+ {S4, Status2} = analyse(S3#state{old_sys = S#state.sys}, Status),
+ S5 =
case Status2 of
{ok, _Warnings} -> % BUGBUG: handle warnings
- {S4#state{status = Status2,
- old_status = S#state.status},
- Status2};
+ S4#state{status = Status2, old_status = S#state.status};
{error, _} ->
%% Keep old state
- {S, Status2}
+ S
end,
- reltool_utils:reply(ReplyTo, Ref, Status3),
+ reltool_utils:reply(ReplyTo, Ref, Status2),
?MODULE:loop(S5);
{call, ReplyTo, Ref, get_status} ->
reltool_utils:reply(ReplyTo, Ref, S#state.status),
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index 9ed79e8c95..588db837e4 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,6 +24,7 @@
-compile(export_all).
+-include_lib("reltool/src/reltool.hrl").
-include("reltool_test_lib.hrl").
-include_lib("common_test/include/ct.hrl").
@@ -51,10 +52,12 @@ end_per_testcase(Func,Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [start_server, set_config, create_release,
+ [start_server, set_config, get_config, create_release,
create_script, create_target, create_embedded,
create_standalone, create_old_target,
- otp_9135, otp_9229_exclude_app, otp_9229_exclude_mod].
+ otp_9135, otp_9229_exclude_app, otp_9229_exclude_mod,
+ get_apps, set_app_and_undo, set_apps_and_undo,
+ load_config_and_undo, reset_config_and_undo, save_config].
groups() ->
[].
@@ -112,6 +115,83 @@ set_config(_Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Check that get_config returns the expected derivates and defaults
+%% as specified
+get_config(_Config) ->
+ Sys = {sys,[{incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])),
+ ?m({ok, Sys}, reltool:get_config(Pid)),
+ ?m({ok, Sys}, reltool:get_config(Pid,false,false)),
+
+ ?msym({ok,{sys,[{incl_cond, exclude},
+ {erts,[]},
+ {app,kernel,[{incl_cond,include},{mod,_,[]}|_]},
+ {app,sasl,[{incl_cond,include},{mod,_,[]}|_]},
+ {app,stdlib,[{incl_cond,include},{mod,_,[]}|_]}]}},
+ reltool:get_config(Pid,false,true)),
+
+ ?msym({ok,{sys,[{root_dir,_},
+ {lib_dirs,_},
+ {mod_cond,all},
+ {incl_cond,exclude},
+ {app,kernel,[{incl_cond,include},{vsn,undefined}]},
+ {app,sasl,[{incl_cond,include},{vsn,undefined}]},
+ {app,stdlib,[{incl_cond,include},{vsn,undefined}]},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,development},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}},
+ reltool:get_config(Pid,true,false)),
+
+ KVsn = latest(kernel),
+ StdVsn = latest(stdlib),
+
+ ?msym({ok,{sys,[{root_dir,_},
+ {lib_dirs,_},
+ {mod_cond,all},
+ {incl_cond,exclude},
+ {erts,[]},
+ {app,kernel,[{incl_cond,include},{vsn,KVsn},{mod,_,[]}|_]},
+ {app,sasl,[{incl_cond,include},{vsn,_},{mod,_,[]}|_]},
+ {app,stdlib,[{incl_cond,include},{vsn,StdVsn},{mod,_,[]}|_]},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,development},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}},
+ reltool:get_config(Pid,true,true)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% OTP-9135, test that app_file option can be set to all | keep | strip
otp_9135(TestInfo) when is_atom(TestInfo) ->
@@ -389,7 +469,7 @@ otp_9229_exclude_app(Config) ->
?m(ok, reltool_utils:recursive_delete(TargetDir)),
?m(ok, file:make_dir(TargetDir)),
?log("SPEC: ~p\n", [reltool:get_target_spec([{config, ExclApp}])]),
- {ok,["Module mylib exists in applications x and y. Using module from application x."]} = reltool:get_status([{config, ExclApp}]),
+ ?m({ok,["Module mylib exists in applications x and y. Using module from application x."]}, reltool:get_status([{config, ExclApp}])),
?m(ok, reltool:create_target([{config, ExclApp}], TargetDir)),
Erl = filename:join([TargetDir, "bin", "erl"]),
@@ -436,7 +516,7 @@ otp_9229_exclude_mod(Config) ->
?m(ok, reltool_utils:recursive_delete(TargetDir)),
?m(ok, file:make_dir(TargetDir)),
?log("SPEC: ~p\n", [reltool:get_target_spec([{config, ExclMod}])]),
- {ok,["Module mylib exists in applications x and y. Using module from application x."]} = reltool:get_status([{config, ExclMod}]),
+ ?m({ok,["Module mylib exists in applications x and y. Using module from application x."]}, reltool:get_status([{config, ExclMod}])),
?m(ok, reltool:create_target([{config, ExclMod}], TargetDir)),
Erl = filename:join([TargetDir, "bin", "erl"]),
@@ -466,7 +546,296 @@ otp_9229_exclude_mod(Config) ->
ok.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Test the interface used by the GUI:
+%% get_app
+%% get_apps
+%% set_app
+%% set_apps
+%% load_config
+%% reset_config
+%%
+%% Also, for each operation which manipulates the config test
+%% undo_config - that it is properly undone, and that warnings are
+%% re-displayed.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+get_apps(_Config) ->
+ Sys = {sys,[{app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,derived}]},
+ {app,runtime_tools,[{incl_cond,exclude}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])),
+
+ {ok,Sasl} = ?msym({ok,#app{name=sasl}}, reltool_server:get_app(Pid,sasl)),
+ {ok,[#app{name=kernel},
+ #app{name=sasl}=Sasl,
+ #app{name=stdlib}] = White} =
+ ?msym({ok,_}, reltool_server:get_apps(Pid,whitelist)),
+ {ok,[#app{name=runtime_tools}] = Black} =
+ ?msym({ok,_}, reltool_server:get_apps(Pid,blacklist)),
+
+ {ok,Derived} = ?msym({ok,_}, reltool_server:get_apps(Pid,derived)),
+ true = lists:keymember(tools,#app.name,Derived),
+
+ {ok,Source} = ?msym({ok,_}, reltool_server:get_apps(Pid,source)),
+ true = lists:keymember(common_test,#app.name,Source),
+
+ %% Check that the four lists are disjoint
+ Number = length(White) + length(Black) + length(Derived) + length(Source),
+ WN = lists:usort([N || #app{name=N} <- White]),
+ BN = lists:usort([N || #app{name=N} <- Black]),
+ DN = lists:usort([N || #app{name=N} <- Derived]),
+ SN = lists:usort([N || #app{name=N} <- Source]),
+ AllN = lists:umerge([WN,BN,DN,SN]),
+ ?m(Number,length(AllN)),
+
+ ?m(ok, reltool:stop(Pid)),
+
+ ok.
+
+set_app_and_undo(Config) ->
+ Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]},
+ {incl_cond, exclude},
+ {app,a,[{incl_cond,include}]},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])),
+ ?m({ok, Sys}, reltool:get_config(Pid)),
+
+ %% Exclude one module with set_app
+ {ok,Tools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ Mods = Tools#app.mods,
+ Cover = lists:keyfind(cover,#mod.name,Mods),
+ ExclCover = Cover#mod{incl_cond=exclude},
+ Tools1 = Tools#app{mods = lists:keyreplace(cover,#mod.name,Mods,ExclCover)},
+ {ok,ToolsNoCover,[]} = ?msym({ok,_,[]}, reltool_server:set_app(Pid,Tools1)),
+ ?m({ok,ToolsNoCover}, reltool_server:get_app(Pid,tools)),
+
+ %% Undo
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,Tools}, reltool_server:get_app(Pid,tools)),
+ %%! warning can come twice here... :(
+ ?msym({ok,["a: Cannot parse app file"++_|_]}, reltool:get_status(Pid)),
+
+ %% Undo again, to check that it toggles
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,ToolsNoCover}, reltool_server:get_app(Pid,tools)),
+ ?m({ok,[]}, reltool:get_status(Pid)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+set_apps_and_undo(Config) ->
+ Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]},
+ {incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])),
+ ?m({ok, Sys}, reltool:get_config(Pid)),
+
+ %% Exclude one application with set_apps
+ {ok,Tools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ExclTools = Tools#app{incl_cond=exclude},
+ ?m({ok,[]}, reltool_server:set_apps(Pid,[ExclTools])),
+ {ok,NoTools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ?m(false, NoTools#app.is_pre_included),
+ ?m(false, NoTools#app.is_included),
+
+ %% Undo
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,Tools}, reltool_server:get_app(Pid,tools)),
+ %%! warning can come twice here... :(
+ ?msym({ok,["a: Cannot parse app file"++_|_]}, reltool:get_status(Pid)),
+
+ %% Undo again, to check that it toggles
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,NoTools}, reltool_server:get_app(Pid,tools)),
+ ?m({ok,[]}, reltool:get_status(Pid)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+load_config_and_undo(Config) ->
+ Sys1 = {sys,[{incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])),
+ ?m({ok, Sys1}, reltool:get_config(Pid)),
+
+ %% Check that tools is included
+ {ok,Tools1} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ?m(true, Tools1#app.is_pre_included),
+ ?m(true, Tools1#app.is_included),
+
+ %% Exclude one application with set_apps
+ Sys2 = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]},
+ {incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,derived}]},
+ {app,a,[{incl_cond,include}]}]},
+ ?msym({ok,["a: Cannot parse app file"++_]},
+ reltool_server:load_config(Pid,Sys2)),
+
+ %% Check that tools is included (since it is used by sasl) but not
+ %% pre-included (neither included or excluded => undefined)
+ {ok,Tools2} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ?m(undefined, Tools2#app.is_pre_included),
+ ?m(true, Tools2#app.is_included),
+
+ %% Undo
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,Tools1}, reltool_server:get_app(Pid,tools)),
+ ?m({ok,[]}, reltool:get_status(Pid)),
+
+ %% Undo again, to check that it toggles
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,Tools2}, reltool_server:get_app(Pid,tools)),
+ ?msym({ok,["a: Cannot parse app file"++_]}, reltool:get_status(Pid)),
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+reset_config_and_undo(Config) ->
+ Sys1 = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]},
+ {incl_cond, exclude},
+ {app,a,[{incl_cond,include}]},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])),
+ ?m({ok, Sys1}, reltool:get_config(Pid)),
+
+ %% Check that tools is included
+ {ok,Tools1} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ?m(true, Tools1#app.is_pre_included),
+ ?m(true, Tools1#app.is_included),
+
+ %% Exclude one application with set_apps
+ Sys2 = {sys,[{incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,tools,[{incl_cond,exclude}]}]},
+ ?m({ok,[]}, reltool_server:load_config(Pid,Sys2)),
+
+ %% Check that tools is excluded
+ {ok,Tools2} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)),
+ ?m(false, Tools2#app.is_pre_included),
+ ?m(false, Tools2#app.is_included),
+
+ %% Reset
+ %%! warning can come twice here... :(
+ ?msym({ok,["a: Cannot parse app file"++_|_]},
+ reltool_server:reset_config(Pid)),
+ ?m({ok,Tools1}, reltool_server:get_app(Pid,tools)),
+
+ %% Undo again, to check that it toggles
+ ?m(ok, reltool_server:undo_config(Pid)),
+ ?m({ok,Tools2}, reltool_server:get_app(Pid,tools)),
+ ?m({ok,[]}, reltool:get_status(Pid)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+save_config(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Sys = {sys,[{incl_cond, exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]}]},
+ {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])),
+ ?m({ok, Sys}, reltool:get_config(Pid)),
+
+ Simple = filename:join(PrivDir,"save_simple.reltool"),
+ ?m(ok, reltool_server:save_config(Pid,Simple,false,false)),
+ ?m({ok,[Sys]}, file:consult(Simple)),
+
+ Derivates = filename:join(PrivDir,"save_derivates.reltool"),
+ ?m(ok, reltool_server:save_config(Pid,Derivates,false,true)),
+ ?msym({ok,[{sys,[{incl_cond, exclude},
+ {erts,[]},
+ {app,kernel,[{incl_cond,include},{mod,_,[]}|_]},
+ {app,sasl,[{incl_cond,include},{mod,_,[]}|_]},
+ {app,stdlib,[{incl_cond,include},{mod,_,[]}|_]}]}]},
+ file:consult(Derivates)),
+
+ Defaults = filename:join(PrivDir,"save_defaults.reltool"),
+ ?m(ok, reltool_server:save_config(Pid,Defaults,true,false)),
+ ?msym({ok,[{sys,[{root_dir,_},
+ {lib_dirs,_},
+ {mod_cond,all},
+ {incl_cond,exclude},
+ {app,kernel,[{incl_cond,include},{vsn,undefined}]},
+ {app,sasl,[{incl_cond,include},{vsn,undefined}]},
+ {app,stdlib,[{incl_cond,include},{vsn,undefined}]},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,development},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}]},
+ file:consult(Defaults)),
+
+ KVsn = latest(kernel),
+ StdVsn = latest(stdlib),
+
+ All = filename:join(PrivDir,"save_all.reltool"),
+ ?m(ok, reltool_server:save_config(Pid,All,true,true)),
+ ?msym({ok,[{sys,[{root_dir,_},
+ {lib_dirs,_},
+ {mod_cond,all},
+ {incl_cond,exclude},
+ {erts,[]},
+ {app,kernel,[{incl_cond,include},{vsn,KVsn},{mod,_,[]}|_]},
+ {app,sasl,[{incl_cond,include},{vsn,_},{mod,_,[]}|_]},
+ {app,stdlib,[{incl_cond,include},{vsn,StdVsn},{mod,_,[]}|_]},
+ {boot_rel,"start_clean"},
+ {rel,"start_clean","1.0",[]},
+ {rel,"start_sasl","1.0",[sasl]},
+ {emu_name,"beam"},
+ {relocatable,true},
+ {profile,development},
+ {incl_sys_filters,[".*"]},
+ {excl_sys_filters,[]},
+ {incl_app_filters,[".*"]},
+ {excl_app_filters,[]},
+ {incl_archive_filters,[".*"]},
+ {excl_archive_filters,["^include$","^priv$"]},
+ {archive_opts,[]},
+ {rel_app_type,permanent},
+ {app_file,keep},
+ {debug_info,keep}]}]},
+ file:consult(All)),
+
+ ?m(ok, reltool:stop(Pid)),
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -478,6 +847,18 @@ erl_libs() ->
LibStr -> string:tokens(LibStr, ":;")
end.
+datadir(Config) ->
+ %% Removes the trailing slash...
+ filename:nativename(?config(data_dir,Config)).
+
+latest(App) ->
+ AppStr = atom_to_list(App),
+ AppDirs = filelib:wildcard(filename:join(code:lib_dir(),AppStr++"-*")),
+ [LatestAppDir|_] = lists:reverse(AppDirs),
+ [_,Vsn] = string:tokens(filename:basename(LatestAppDir),"-"),
+ Vsn.
+
+
diff_script(Script, Script) ->
equal;
diff_script({script, Rel, Commands1}, {script, Rel, Commands2}) ->
diff --git a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/ebin/a.app b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/ebin/a.app
new file mode 100644
index 0000000000..ea77103598
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/ebin/a.app
@@ -0,0 +1 @@
+faulty app file
diff --git a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl
new file mode 100644
index 0000000000..bb500bed69
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a.erl
@@ -0,0 +1,49 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(a).
+
+
+-behaviour(gen_server).
+
+-vsn(1).
+
+%% External exports
+-export([start_link/0, a/0]).
+%% Internal exports
+-export([init/1, handle_call/3, handle_info/2, terminate/2]).
+
+start_link() -> gen_server:start_link({local, aa}, a, [], []).
+
+a() -> gen_server:call(aa, a).
+
+%%-----------------------------------------------------------------
+%% Callback functions from gen_server
+%%-----------------------------------------------------------------
+init([]) ->
+ process_flag(trap_exit, true),
+ {ok, state}.
+
+handle_call(a, _From, State) ->
+ X = application:get_all_env(a),
+ {reply, X, State}.
+
+handle_info(_, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
diff --git a/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
new file mode 100644
index 0000000000..a141c1767b
--- /dev/null
+++ b/lib/reltool/test/reltool_server_SUITE_data/faulty_app_file/a-1.0/src/a_sup.erl
@@ -0,0 +1,37 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(a_sup).
+
+
+-behaviour(supervisor).
+
+%% External exports
+-export([start/2]).
+
+%% Internal exports
+-export([init/1]).
+
+start(_, _) ->
+ supervisor:start_link({local, a_sup}, a_sup, []).
+
+init([]) ->
+ SupFlags = {one_for_one, 4, 3600},
+ Config = {a,
+ {a, start_link, []},
+ permanent, 2000, worker, [a]},
+ {ok, {SupFlags, [Config]}}.