diff options
Diffstat (limited to 'lib/sasl/test/systools_SUITE.erl')
-rw-r--r-- | lib/sasl/test/systools_SUITE.erl | 2191 |
1 files changed, 2191 insertions, 0 deletions
diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl new file mode 100644 index 0000000000..e352247d44 --- /dev/null +++ b/lib/sasl/test/systools_SUITE.erl @@ -0,0 +1,2191 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2011. 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 +%% 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 online 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. +%% +%% %CopyrightEnd% +%% +%% +%% Test suite for the systools module. +%% +%% The systools module is a wrapper for a number of modules that +%% handle large parts of the release building functionality +%% (e.g. checking app files, building a tar file, building +%% release upgrad scripts. +%% + + +-module(systools_SUITE). + +%-define(debug, true). + +-include_lib("test_server/include/test_server.hrl"). +-define(format(S, A), ok). +-define(datadir, ?config(data_dir, Config)). +-define(privdir, ?config(priv_dir, Config)). +-define(copydir, ?config(copy_dir, Config)). + +-include_lib("kernel/include/file.hrl"). + +-export([all/0,suite/0,groups/0,init_per_group/2,end_per_group/2]). + +-export([ script_options/1, normal_script/1, no_mod_vsn_script/1, + wildcard_script/1, variable_script/1, + abnormal_script/1, src_tests_script/1, crazy_script/1, + warn_shadow_script/1, + included_script/1, included_override_script/1, + included_fail_script/1, included_bug_script/1, exref_script/1]). +-export([ tar_options/1, normal_tar/1, no_mod_vsn_tar/1, variable_tar/1, + src_tests_tar/1, shadow_tar/1, var_tar/1, + 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([init_per_suite/1, end_per_suite/1, + init_per_testcase/2, end_per_testcase/2]). + +-import(lists, [foldl/3]). + +-define(default_timeout, ?t:minutes(20)). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +suite() -> + [{ct_hooks, [ts_install_cth]}]. + +all() -> + [{group, script}, {group, tar}, {group, relup}, + {group, tickets}]. + +groups() -> + [{script, [], + [script_options, normal_script, no_mod_vsn_script, + wildcard_script, variable_script, abnormal_script, + src_tests_script, crazy_script, warn_shadow_script, + included_script, included_override_script, + included_fail_script, included_bug_script, exref_script, + otp_3065]}, + {tar, [], + [tar_options, normal_tar, no_mod_vsn_tar, variable_tar, + src_tests_tar, shadow_tar, var_tar, + exref_tar, link_tar, otp_9507]}, + {relup, [], + [normal_relup, abnormal_relup, no_appup_relup, + bad_appup_relup, app_start_type_relup]}, + {tickets, [], [otp_6226]}]. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +init_per_suite(Config) when is_list(Config) -> + %% Make of copy of the data directory. + DataDir = ?datadir, + PrivDir = ?privdir, + ?line CopyDir = fname(PrivDir, "datacopy"), + ?line TarFile = fname(PrivDir, "datacopy.tgz"), + ?line {ok, Tar} = erl_tar:open(TarFile, [write, compressed]), + ?line ok = erl_tar:add(Tar, DataDir, CopyDir, [compressed]), + ?line ok = erl_tar:close(Tar), + ?line ok = erl_tar:extract(TarFile, [compressed]), + ?line ok = file:delete(TarFile), + + %% Compile source files in the copy directory. + ?line Sources = filelib:wildcard(fname([CopyDir,'*','*','*','*','*.erl'])), + ?line lists:foreach(fun compile_source/1, Sources), + + %% To use in end_per_testcase + Path = code:get_path(), + {ok,Cwd} = file:get_cwd(), + + [{copy_dir, CopyDir}, {cwd,Cwd}, {path,Path} | Config]. + +compile_source(File) -> + %% The compiler will no longer create a Beam file + %% with a module name that does not match the output + %% file, so we must compile to a binary and write + %% the output file ourselves. + U = filename:dirname(filename:dirname(File)), + Base = filename:rootname(filename:basename(File)), + OutFile = filename:join([U,"ebin",Base++".beam"]), + OutFileTemp = OutFile ++ "#", + {ok,_,Code} = compile:file(File, [binary]), + ok = file:write_file(OutFileTemp, Code), + file:rename(OutFileTemp, OutFile). + +end_per_suite(Conf) when is_list(Conf) -> + %% Nothing. + Conf. + +init_per_testcase(link_tar, Config) -> + case os:type() of + {unix, _} -> init_per_testcase(dummy, Config); + {win32, _} -> {skip, "Skip on windows"} + end; +init_per_testcase(_Case, Config) -> + ?line Dog = test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + +end_per_testcase(_Case, Config) -> + Dog=?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + case {?config(path,Config),?config(cwd,Config)} of + {undefined,undefined} -> + ok; + {Path,Cwd} -> + true = code:set_path(Path), + ok = file:set_cwd(Cwd) + end, + ok. + + + +%% Usage: +%% systools:make_script("RelName") +%% Make a boot file from RelName.rel. +%% Generates RelName.{script,boot} +%% systools:make_tar("RelName") +%% Make a release package from RelName.rel. +%% Generates RelName.tar,Z +%% systools:script2boot(File) +%% File.script -> File.boot +%% systools:make_relup("Target", ["UpFromRel"...], ["DownToRel"...], Opts) +%% Gather all appup scripts to the relup file +%% + + +%% make_script +%% +script_options(suite) -> []; +script_options(doc) -> + ["Check illegal script options."]; +script_options(Config) when is_list(Config) -> + ?line {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = + (catch systools:make_script("release", [{path,["Path",12,"Another"]}])), + ?line {'EXIT',{{badarg,[sillent]}, _}} = + (catch systools:make_script("release", + [{path,["Path","Another"]},sillent])), + ?line {'EXIT',{{badarg,[locall]}, _}} = + (catch systools:make_script("release", + [{path,["Path","Another"]},locall])), + ?line {'EXIT',{{badarg,[src_testsxx]}, _}} = + (catch systools:make_script("release", + [{path,["Path"]},src_testsxx])), + ?line {'EXIT',{{badarg,[{variables, {"TEST", "/home/lib"}}]}, _}} = + (catch systools:make_script("release", + [{variables, {"TEST", "/home/lib"}}])), + ?line {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = + (catch systools:make_script("release", + [{variables, [{a, b}, {"a", "b"}]}])), + ?line {'EXIT',{{badarg,[exreff]}, _}} = + (catch systools:make_script("release", + [{path,["Path","Another"]},exreff])), + ?line {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = + (catch systools:make_script("release", [{exref,["appl"]}])), + ?line {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = + (catch systools:make_script("release", [{machine,"appl"}])), + ok. + + +%% make_script +%% +normal_script(suite) -> []; +normal_script(doc) -> + ["Check that make_script handles normal case."]; +normal_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P1 = fname([LibDir, 'db-2.1', ebin]), + ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + + ?line true = code:add_patha(P1), + ?line true = code:add_patha(P2), + + ?line ok = file:set_cwd(LatestDir), + + ?line ok = systools:make_script(filename:basename(LatestName)), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + %% Check the same but w. silent flag + ?line {ok, _, []} = systools:make_script(LatestName, [silent]), + + %% Use the local option + ?line ok = systools:make_script(LatestName, [local]), + ?line ok = check_script_path(LatestName), + + %% use the path option + ?line code:set_path(PSAVE), % Restore path + %% Mess up std path: + ?line true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), + ?line true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), + + ?line error = systools:make_script(LatestName), %should fail + ?line ok = systools:make_script(LatestName,[{path, [P1, P2]}]), + + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), % Restore path + ok. + + +%% make_script +%% +no_mod_vsn_script(suite) -> []; +no_mod_vsn_script(doc) -> + ["Check that make_script handles normal case.", + "Modules specified without version in .app file (db-3.1)." + "Note that this is now the normal way - i.e. systools now " + "ignores the module versions in the .app file."]; +no_mod_vsn_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P1 = fname([LibDir, 'db-3.1', ebin]), + ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + + ?line true = code:add_patha(P1), + ?line true = code:add_patha(P2), + + ?line ok = file:set_cwd(LatestDir), + + ?line ok = systools:make_script(filename:basename(LatestName)), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + %% Check the same but w. silent flag + ?line {ok, _, []} = systools:make_script(LatestName, [silent]), + + %% Use the local option + ?line ok = systools:make_script(LatestName, [local]), + ?line ok = check_script_path(LatestName), + + %% use the path option + ?line code:set_path(PSAVE), % Restore path + %% Mess up std path: + ?line true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), + ?line true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), + + ?line error = systools:make_script(LatestName), %should fail + ?line ok = systools:make_script(LatestName, + [{path, [P1, P2]}]), + + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), % Restore path + ok. + + +%% make_script +%% +wildcard_script(suite) -> []; +wildcard_script(doc) -> + ["Check that make_script handles wildcards in path."]; +wildcard_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line WildDir = fname([LibDir, '*', ebin]), + + ?line ok = file:set_cwd(LatestDir), + + ?line error = systools:make_script(filename:basename(LatestName)), + + ?line ok = systools:make_script(LatestName, + [{path, [WildDir]}]), + + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + ?line ok = file:set_cwd(OldDir), + ok. + + +%% make_script +%% +variable_script(suite) -> []; +variable_script(doc) -> + ["Add own installation dependent variable in script."]; +variable_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line ok = systools:make_script(LatestName, + [{path, P}, + {variables, [{"TEST", LibDir}]}]), + + %% Check variables + ?line ok = check_var_script_file([fname(['$TEST', 'db-2.1', ebin]), + fname(['$TEST', 'fe-3.1', ebin])], + P, + LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_script +%% +abnormal_script(suite) -> []; +abnormal_script(doc) -> + ["Abnormal cases."]; +abnormal_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + + ?line ok = file:set_cwd(LatestDir), + ?line LibDir = fname([DataDir, d_bad_app_vsn, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + %% Check wrong app vsn + ?line error = systools:make_script(LatestName, [{path, P}]), + ?line {error, + systools_make, + [{error_reading, {db, {no_valid_version, + {{"should be","2.1"}, + {"found file", _, "2.0"}}}}}]} = + systools:make_script(LatestName, [silent, {path, P}]), + + ?line ok = file:set_cwd(OldDir), + ok. + + +%% make_script +%% +src_tests_script(suite) -> []; +src_tests_script(doc) -> + ["Do not check date of object file or that source code can be found."]; +src_tests_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest,Config), + ?line BootFile = LatestName ++ ".boot", + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_missing_src, lib]), + ?line P1 = fname([LibDir, 'db-2.1', ebin]), + ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + N = [P1, P2], + + ?line ok = file:set_cwd(LatestDir), + + %% Manipulate the modification date of a beam file so it seems + %% older than its .erl file + ?line Erl = filename:join([P1,"..","src","db1.erl"]), + ?line {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), + ?line Beam = filename:join(P1,"db1.beam"), + ?line ok=file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), + + %% Remove a .erl file + ?line Erl2 = filename:join([P1,"..","src","db2.erl"]), + ?line file:delete(Erl2), + + %% Then make script + + %% .boot file should not exist + ?line ok = file:delete(BootFile), + ?line false = filelib:is_regular(BootFile), + %% With warnings_as_errors and src_tests option, an error should be issued + ?line error = + systools:make_script(LatestName, [silent, {path, N}, src_tests, + warnings_as_errors]), + ?line error = + systools:make_script(LatestName, [{path, N}, src_tests, + warnings_as_errors]), + + %% due to warnings_as_errors .boot file should still not exist + ?line false = filelib:is_regular(BootFile), + + %% Two warnings should be issued when src_tests is given + %% 1. old object code for db1.beam + %% 2. missing source code for db2.beam + ?line {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = + systools:make_script(LatestName, [silent, {path, N}, src_tests]), + + %% .boot file should exist now + ?line true = filelib:is_regular(BootFile), + + %% Without the src_tests option, no warning should be issued + ?line {ok, _, []} = + systools:make_script(LatestName, [silent, {path, N}]), + + %% Check that the old no_module_tests option (from the time when + %% it was default to do the src_test) is ignored + ?line {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = + systools:make_script(LatestName, [silent, + {path, N}, + no_module_tests, + src_tests]), + + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), + ok. + +%% make_script +%% +warn_shadow_script(suite) -> []; +warn_shadow_script(doc) -> + ["Check that jam file out of date warning doesn't", + "shadow bad module version error."]; +warn_shadow_script(Config) when is_list(Config) -> + %% This test has been removed since the 'vsn' attribute is + %% not used any more, starting with R6. No warning + %% 'obj_out_of_date' seemed to be generated. + true. + + +%% make_script +%% +crazy_script(suite) -> []; +crazy_script(doc) -> + ["Do the crazy cases."]; +crazy_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest, Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + %% Run with bad path + ?line error = systools:make_script(LatestName), + ?line {error, _, [{error_reading, _}, {error_reading, _}]} = + systools:make_script(LatestName, [silent]), + + %% Run with .rel file lacking kernel + ?line {LatestDir2, LatestName2} = create_script(latest_nokernel, Config), + ?line ok = file:set_cwd(LatestDir2), + + ?line error = systools:make_script(LatestName2), + ?line {error, _, {missing_mandatory_app,[kernel,stdlib]}} = + systools:make_script(LatestName2, [silent,{path,P}]), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_script +%% +included_script(suite) -> []; +included_script(doc) -> + ["Check that make_script handles generation of script", + "for applications with included applications."]; +included_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {LatestDir, LatestName} = create_include_files(inc1, Config), + ?line ok = file:set_cwd(LatestDir), + ?line ok = systools:make_script(LatestName), + ?line ok = check_include_script(LatestName, + [t1, t2, t3, t5, t4, t6], + [t1, t3, t6]), + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_script +%% +included_override_script(suite) -> []; +included_override_script(doc) -> + ["Check that make_script handles generation of script", + "for applications with included applications which are override by", + "the .rel file."]; +included_override_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {LatestDir, LatestName} = create_include_files(inc2, Config), + ?line ok = file:set_cwd(LatestDir), + ?line ok = systools:make_script(LatestName), + ?line ok = check_include_script(LatestName, + [t1, t2, t3, t4, t6, t5], + [t1, t3, t6, t5]), + + ?line {_, LatestName1} = create_include_files(inc3, Config), + ?line ok = systools:make_script(LatestName1), + ?line ok = check_include_script(LatestName1, + [t3, t5, t4, t6, t1, t2], + [t3, t6, t1, t2]), + + ?line {_, LatestName2} = create_include_files(inc4, Config), + ?line ok = systools:make_script(LatestName2), + ?line ok = check_include_script(LatestName2, + [t3, t4, t6, t5, t1, t2], + [t3, t6, t5, t1, t2]), + + ?line {_, LatestName3} = create_include_files(inc5, Config), + ?line ok = systools:make_script(LatestName3), + ?line ok = check_include_script(LatestName3, + [t3, t4, t6, t1, t2], + [t3, t6, t1, t2]), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_script +%% +included_fail_script(suite) -> []; +included_fail_script(doc) -> + ["Check that make_script handles errors then generating", + "script with included applications."]; +included_fail_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {LatestDir, LatestName} = create_include_files(inc6, Config), + ?line ok = file:set_cwd(LatestDir), + ?line {error, _, {undefined_applications,[t2]}} = + systools:make_script(LatestName, [silent]), + + ?line {_, LatestName1} = create_include_files(inc7, Config), + ?line {error, _, {duplicate_include,[{{t5,t7,_,_},{t5,t6,_,_}}]}} = + systools:make_script(LatestName1, [silent]), + + ?line {_, LatestName3} = create_include_files(inc9, Config), + ?line {error, _, {circular_dependencies,[{t10,_},{t8,_}]}} = + systools:make_script(LatestName3, [silent]), + + ?line {_, LatestName4} = create_include_files(inc10, Config), + ?line {error, _, [{error_reading,{t9,{override_include,[t7]}}}]} = + systools:make_script(LatestName4, [silent]), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_script +%% +included_bug_script(suite) -> []; +included_bug_script(doc) -> + ["Check that make_script handles generation of script", + "with difficult dependency for included applications."]; +included_bug_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {LatestDir, LatestName} = create_include_files(inc11, Config), + ?line ok = file:set_cwd(LatestDir), + ?line ok = systools:make_script(LatestName), + ?line ok = check_include_script(LatestName, + [t13, t11, t12], + [t11, t12]), + ?line ok = file:set_cwd(OldDir), + ok. + + +%% make_script +%% +otp_3065(suite) -> []; +otp_3065(doc) -> + ["Circular dependencies in systools:make_script()."]; +otp_3065(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {LatestDir, LatestName} = create_include_files(otp_3065, Config), + ?line ok = file:set_cwd(LatestDir), + ?line ok = systools:make_script(LatestName), + ?line ok = check_include_script(LatestName, + [aa12, chAts, chTraffic], + [chTraffic]), + ?line ok = file:set_cwd(OldDir), + ok. + + +%% make_script +%% +exref_script(suite) -> []; +exref_script(doc) -> + ["Check that make_script exref option works."]; +exref_script(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, [{path,P}, silent]), + + %% Complete exref + ?line {ok, _, W1} = + systools:make_script(LatestName, [exref, {path,P}, silent]), + ?line check_exref_warnings(with_db1, W1), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + %% Only exref the db application. + ?line {ok, _, W2} = + systools:make_script(LatestName, [{exref,[db]}, {path,P}, silent]), + ?line check_exref_warnings(with_db1, W2), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + %% Only exref the fe application. + ?line {ok, _, W3} = + systools:make_script(LatestName, [{exref,[fe]}, {path,P}, silent]), + ?line check_exref_warnings(without_db1, W3), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + + %% exref the db and stdlib applications. + ?line {ok, _, W4} = + systools:make_script(LatestName, [{exref,[db,stdlib]}, {path,P}, silent]), + ?line check_exref_warnings(with_db1, W4), + ?line {ok, _} = read_script_file(LatestName), % Check readabillity + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), % Restore path + ok. + +check_exref_warnings(with_db1, W) -> + case get_exref(undef, W) of + {ok, [{db2,non_existing_func,0}, + {fe2,non_existing_func,0}, + {lists,non_existing_func,1}]} -> + ok; + {ok, L} -> + test_server:fail({exref_warning_undef, L}); + _E -> + test_server:fail({bad_undef,_E}) + end; +check_exref_warnings(without_db1, W) -> + case get_exref(undef, W) of + false -> + ok; + {ok, L} -> + test_server:fail({exref_warning_undef, L}) + end. + +get_exref(undef, W) -> filter(no_hipe(get_exref1(exref_undef, W))). + +filter(false) -> + false; +filter({ok, W}) -> + {ok, filter(W)}; +filter(L) -> + lists:filter(fun%({hipe_consttab,_,_}) -> false; + ({int,_,_}) -> false; + ({i,_,_}) -> false; + ({crypto,_,_}) -> false; + (_) -> true + end, + L). + +get_exref1(T, [{warning, {T, Value}}|_]) -> {ok, Value}; +get_exref1(T, [_|W]) -> get_exref1(T, W); +get_exref1(_, []) -> false. + +no_hipe(false) -> + false; +no_hipe({ok, Value}) -> + case erlang:system_info(hipe_architecture) of + undefined -> + Hipe = "hipe", + Fun = fun({M,_,_}) -> not lists:prefix(Hipe, atom_to_list(M)) end, + NewValue = lists:filter(Fun, Value), + {ok, NewValue}; + _Arch -> + {ok, Value} + end. + +%% tar_options +%% +tar_options(suite) -> []; +tar_options(doc) -> + ["Check illegal tar options."]; +tar_options(Config) when is_list(Config) -> + ?line {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = + (catch systools:make_tar("release", [{path,["Path",12,"Another"]}])), + ?line {'EXIT',{{badarg,[sillent]}, _}} = + (catch systools:make_tar("release", + [{path,["Path","Another"]},sillent])), + ?line {'EXIT',{{badarg,[{dirs,["dirs"]}]}, _}} = + (catch systools:make_tar("release", [{dirs, ["dirs"]}])), + ?line {'EXIT',{{badarg,[{erts, illegal}]}, _}} = + (catch systools:make_tar("release", [{erts, illegal}])), + ?line {'EXIT',{{badarg,[src_testsxx]}, _}} = + (catch systools:make_tar("release", + [{path,["Path"]},src_testsxx])), + ?line {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = + (catch systools:make_tar("release", + [{variables, [{a, b}, {"a", "b"}]}])), + ?line {'EXIT',{{badarg,[{var_tar, illegal}]}, _}} = + (catch systools:make_tar("release", [{var_tar, illegal}])), + ?line {'EXIT',{{badarg,[exreff]}, _}} = + (catch systools:make_tar("release", + [{path,["Path","Another"]},exreff])), + ?line {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = + (catch systools:make_tar("release", [{exref,["appl"]}])), + ?line {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = + (catch systools:make_tar("release", [{machine,"appl"}])), + ok. + + +%% normal_tar +%% +normal_tar(suite) -> []; +normal_tar(doc) -> + ["Check normal case"]; +normal_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + ?line ok = systools:make_tar(LatestName, [{path, P}]), + ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + ?line {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% no_mod_vsn_tar +%% +no_mod_vsn_tar(suite) -> []; +no_mod_vsn_tar(doc) -> + ["Check normal case", + "Modules specified without version in .app file (db-3.1)." + "Note that this is now the normal way - i.e. systools now " + "ignores the module versions in the .app file."]; +no_mod_vsn_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-3.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + ?line ok = systools:make_tar(LatestName, [{path, P}]), + ?line ok = check_tar(fname([lib,'db-3.1',ebin,'db.app']), LatestName), + ?line {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% variable_tar +%% +variable_tar(suite) -> []; +variable_tar(doc) -> + ["Use variable and create separate tar (included in generated tar)."]; +variable_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, + [silent, + {path, P}, + {variables,[{"TEST", LibDir}]}]), + + ?line ok = systools:make_tar(LatestName, [{path, P}, + {variables,[{"TEST", LibDir}]}]), + ?line ok = check_var_tar("TEST", LatestName), + + ?line {ok, _, _} = systools:make_tar(LatestName, + [{path, P}, silent, + {variables,[{"TEST", LibDir}]}]), + ?line ok = check_var_tar("TEST", LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% link_tar +%% +link_tar(suite) -> []; +link_tar(doc) -> + ["Check that symlinks in applications are handled correctly"]; +link_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_links, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + %% Make some links + ?line Db1Erl = fname(['db-2.1',src,'db1.erl']), + ?line NormalDb1Erl = fname([DataDir,d_normal,lib,Db1Erl]), + ?line LinkDb1Erl = fname([LibDir, Db1Erl]), + ?line ok = file:make_symlink(NormalDb1Erl, LinkDb1Erl), + ?line Db1Beam = fname(['db-2.1',ebin,'db1.beam']), + ?line NormalDb1Beam = fname([DataDir,d_normal,lib,Db1Beam]), + ?line LinkDb1Beam = fname([LibDir, Db1Beam]), + ?line ok = file:make_symlink(NormalDb1Beam, LinkDb1Beam), + ?line FeApp = fname(['fe-3.1',ebin,'fe.app']), + ?line NormalFeApp = fname([DataDir,d_normal,lib,FeApp]), + ?line LinkFeApp = fname([LibDir, FeApp]), + ?line ok = file:make_symlink(NormalFeApp, LinkFeApp), + + %% Create the tar and check that the linked files are included as + %% regular files + ?line ok = file:set_cwd(LatestDir), + + ?line {ok,_,[]} = systools:make_script(LatestName, [{path, P},silent]), + + ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), + ?line ok = check_tar_regular(?privdir, + [fname([lib,FeApp]), + fname([lib,Db1Beam])], + LatestName), + + ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}]), + ?line ok = check_tar_regular(?privdir, + [fname([lib,FeApp]), + fname([lib,Db1Beam]), + fname([lib,Db1Erl])], + LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% src_tests_tar +%% +src_tests_tar(suite) -> []; +src_tests_tar(doc) -> + ["Do not check date of object file or that source code can be found."]; +src_tests_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_missing_src, lib]), + ?line P1 = fname([LibDir, 'db-2.1', ebin]), + ?line P2 = fname([LibDir, 'fe-3.1', ebin]), + P = [P1, P2], + + ?line ok = file:set_cwd(LatestDir), + + %% Manipulate the modification date of a beam file so it seems + %% older than the .erl file + Erl = filename:join([P1,"..","src","db1.erl"]), + {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), + Beam = filename:join(P1,"db1.beam"), + ok = file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), + + %% Remove a .erl file + ?line Erl2 = filename:join([P1,"..","src","db2.erl"]), + ?line file:delete(Erl2), + + ?line ok = systools:make_script(LatestName, [{path, P}]), + + %% Then make tar - two warnings should be issued when + %% src_tests is given + %% 1. old object code for db1.beam + %% 2. missing source code for db2.beam + ?line {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = + systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}, + src_tests]), + ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + + %% Without the src_tests option, no warning should be issued + ?line {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}]), + ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + + %% Check that the old no_module_tests option (from the time when + %% it was default to do the src_test) is ignored + ?line {ok, _, [{warning,{obj_out_of_date,_}}, + {warning,{source_not_found,_}}]} = + systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}, + no_module_tests, + src_tests]), + ?line ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% shadow_tar +%% +shadow_tar(suite) -> []; +shadow_tar(doc) -> + ["Check that jam file out of date warning doesn't", + "shadow bad module version error."]; +shadow_tar(Config) when is_list(Config) -> + % This test has been commented out since the 'vsn' attribute is not used + % any more, starting with R6. No warning 'obj_out_of_date' seemed to be + % generated. + true; +shadow_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, 'd_bad_mod+warn', lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {error, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), + ?line {error, _, _} = systools:make_tar(LatestName, [{path, P}, silent, + {dirs, [src]}]), + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), + ok. + + +%% var_tar +%% +var_tar(suite) -> []; +var_tar(doc) -> + ["Check that make_tar handles generation and placement of tar", + "files for variables outside the main tar file.", + "Test the {var_tar, include | ownfile | omit} option."]; +var_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line PSAVE = code:get_path(), % Save path + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, + [silent, + {path, P}, + {variables,[{"TEST", LibDir}]}]), + + ?line ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, ownfile}, + {variables,[{"TEST", LibDir}]}]), + + ?line true = exists_tar_file("TEST"), %% Also removes the file ! + ?line {error, {not_generated, _}} = check_var_tar("TEST", LatestName), + + ?line ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, omit}, + {variables,[{"TEST", LibDir}]}]), + + ?line {error, {not_generated, _}} = check_var_tar("TEST", LatestName), + ?line false = exists_tar_file("TEST"), + + ?line ok = systools:make_tar(LatestName, [{path, P}, + {var_tar, include}, + {variables,[{"TEST", LibDir}]}]), + + ?line ok = check_var_tar("TEST", LatestName), + ?line false = exists_tar_file("TEST"), + + ?line ok = file:set_cwd(OldDir), + ?line code:set_path(PSAVE), + ok. + + +%% exref_tar +%% +exref_tar(suite) -> []; +exref_tar(doc) -> + ["Check exref option."]; +exref_tar(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'fe-3.1', ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), + + %% Complete exref + ?line {ok, _, W1} = + systools:make_tar(LatestName, [exref, {path, P}, silent]), + ?line check_exref_warnings(with_db1, W1), + ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + + %% Only exref the db application. + ?line {ok, _, W2} = + systools:make_tar(LatestName, [{exref, [db]}, {path, P}, silent]), + ?line check_exref_warnings(with_db1, W2), + ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + + %% Only exref the fe application. + ?line {ok, _, W3} = + systools:make_tar(LatestName, [{exref, [fe]}, {path, P}, silent]), + ?line check_exref_warnings(without_db1, W3), + ?line ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), + + %% exref the db and stdlib applications. + ?line {ok, _, W4} = + systools:make_tar(LatestName, [{exref, [db, stdlib]}, + {path, P}, silent]), + ?line check_exref_warnings(with_db1, W4), + ?line ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), + + ?line ok = file:set_cwd(OldDir), + ok. + + + +%% otp_9507 +%% +otp_9507(suite) -> []; +otp_9507(doc) -> + ["make_tar failed when path given as just 'ebin'."]; +otp_9507(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest_small,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line FeDir = fname([LibDir, 'fe-3.1']), + + ?line ok = file:set_cwd(FeDir), + + RelName = fname([LatestDir,LatestName]), + + ?line P1 = ["./ebin", + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + ?line {ok, _, _} = systools:make_script(RelName, [silent, {path, P1}]), + ?line ok = systools:make_tar(RelName, [{path, P1}]), + ?line Content1 = tar_contents(RelName), + + ?line P2 = ["ebin", + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + %% Tickets solves the following line - it used to fail with + %% {function_clause,[{filename,join,[[]]},...} + ?line ok = systools:make_tar(RelName, [{path, P2}]), + ?line Content2 = tar_contents(RelName), + true = (Content1 == Content2), + + ?line ok = file:set_cwd(OldDir), + + ok. + + +%% The relup stuff. +%% +%% + + +%% make_relup +%% +normal_relup(suite) -> []; +normal_relup(doc) -> + ["Check normal case"]; +normal_relup(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir,LatestName} = create_script(latest0,Config), + ?line {_LatestDir1,LatestName1} = create_script(latest1,Config), + ?line {_LatestDir2,LatestName2} = create_script(latest2,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])], + + ?line ok = file:set_cwd(LatestDir), + + %% OTP-2561: Check that the option 'restart_emulator' generates a + %% "restart_new_emulator" instruction. + ?line {ok, _ , _, []} = + systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P},restart_emulator,silent]), + ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + ?line ok = check_restart_emulator(), + + %% This is the ultra normal case + ?line ok = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P}]), + ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + ?line {ok, _, _, []} = + systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P}, silent]), + ?line ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), + + %% file should not be written if warnings_as_errors is enabled. + %% delete before running tests. + ?line ok = file:delete("relup"), + + %% Check that warnings are treated as errors + ?line error = + systools:make_relup(LatestName, [LatestName2], [LatestName1], + [{path, P}, warnings_as_errors]), + ?line error = + systools:make_relup(LatestName, [LatestName2], [LatestName1], + [{path, P}, silent, warnings_as_errors]), + + %% relup file should not exist + ?line false = filelib:is_regular("relup"), + + %% Check that warnings get through + ?line ok = systools:make_relup(LatestName, [LatestName2], [LatestName1], + [{path, P}]), + ?line ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), + ?line {ok, _, _, [{erts_vsn_changed, _}]} = + systools:make_relup(LatestName, [LatestName2], [LatestName1], + [{path, P}, silent]), + ?line ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), + + %% relup file should exist now + ?line true = filelib:is_regular("relup"), + + ?line ok = file:set_cwd(OldDir), + ok. + + +%% This test fails if wrong version numbers are seen in the relup file +%% or if any application is missing. This was triggered by OTP-1360. +check_relup(UpVsnL, DnVsnL) -> + {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), + [] = foldl(fun(X, Acc) -> + true = lists:member(X, Acc), + lists:delete(X, Acc) end, + UpVsnL, + [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Up]), + [] = foldl(fun(X, Acc) -> + true = lists:member(X, Acc), + lists:delete(X, Acc) end, + DnVsnL, + [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Dn]), + ok. + +check_restart_emulator() -> + {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), + restart_new_emulator = lists:last(Up), + restart_new_emulator = lists:last(Dn), + ok. + +%% make_relup +%% +no_appup_relup(suite) -> []; +no_appup_relup(doc) -> + ["Check that appup files may be missing, but only if we don't need them."]; +no_appup_relup(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir,LatestName} = create_script(latest_small,Config), + ?line {_LatestDir0,LatestName0} = create_script(latest_small0,Config), + ?line {_LatestDir1,LatestName1} = create_script(latest_small1,Config), + + ?line DataDir = filename:absname(?copydir), + ?line P1 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + ?line ok = file:set_cwd(LatestDir), + + %% Check that appup might be missing + ?line ok = + systools:make_relup(LatestName, [LatestName], [], [{path, P1}]), + ?line {ok,_, _, []} = + systools:make_relup(LatestName, [LatestName], [], + [silent, {path, P1}]), + + %% Check that appup might NOT be missing when we need it + ?line error = + systools:make_relup(LatestName, [LatestName0], [], [{path, P1}]), + ?line {error,_,{file_problem, {_,{error,{open,_,_}}}}} = + systools:make_relup(LatestName, [], [LatestName0], + [silent, {path, P1}]), + + %% Check that appups missing vsn traps + ?line P2 = [fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + ?line error = + systools:make_relup(LatestName0, [LatestName1], [], [{path, P2}]), + ?line {error,_,{no_relup, _, _, _}} = + systools:make_relup(LatestName0, [], [LatestName1], + [silent, {path, P2}]), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_relup +%% +bad_appup_relup(suite) -> []; +bad_appup_relup(doc) -> + ["Check that badly written appup files are detected"]; +bad_appup_relup(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir,LatestName} = create_script(latest_small,Config), + ?line {_LatestDir0,LatestName0} = create_script(latest_small0,Config), + + ?line DataDir = filename:absname(?copydir), + ?line N2 = [fname([DataDir, d_bad_appup, lib, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + ?line ok = file:set_cwd(LatestDir), + + %% Check that bad appup is trapped + ?line error = + systools:make_relup(LatestName, [LatestName0], [], [{path, N2}]), + ?line {error,_,{file_problem, {_, {error, {parse,_, _}}}}} = + systools:make_relup(LatestName, [], [LatestName0], + [silent, {path, N2}]), + + ?line ok = file:set_cwd(OldDir), + ok. + +%% make_relup +%% +abnormal_relup(suite) -> []; +abnormal_relup(doc) -> + ["Check some abnormal cases"]; +abnormal_relup(Config) when is_list(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir,LatestName} = create_script(latest0,Config), + ?line {_LatestDir1,LatestName1} = create_script(latest1,Config), + + %% Check wrong app vsn + ?line DataDir = filename:absname(?copydir), + ?line P = [fname([DataDir, d_bad_app_vsn, lib, 'db-2.1', ebin]), + fname([DataDir, d_bad_app_vsn, lib, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + ?line ok = file:set_cwd(LatestDir), + + ?line error = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [{path, P}]), + ?line R0 = systools:make_relup(LatestName, [LatestName1], [LatestName1], + [silent, {path, P}]), + ?line {error,systools_make, + [{error_reading,{db,{no_valid_version, + {{"should be","2.1"}, + {"found file", _, "2.0"}}}}}]} = R0, + ?line ok = file:set_cwd(OldDir), + ok. + + +%% Check that application start type is used in relup +app_start_type_relup(suite) -> + []; +app_start_type_relup(doc) -> + ["Release upgrade file with various application start types"]; +app_start_type_relup(Config) when is_list(Config) -> + ?line PrivDir = ?config(priv_dir, Config), + ?line {Dir1,Name1} = create_script(latest_app_start_type1,Config), + ?line {Dir2,Name2} = create_script(latest_app_start_type2,Config), + ?line Release1 = filename:join(Dir1,Name1), + ?line Release2 = filename:join(Dir2,Name2), + + ?line {ok, Release2Relup, systools_relup, []} = systools:make_relup(Release2, [Release1], [Release1], [{outdir, PrivDir}, silent]), + ?line {"2", [{"1",[], UpInstructions}], [{"1",[], DownInstructions}]} = Release2Relup, + %% ?t:format("Up: ~p",[UpInstructions]), + %% ?t:format("Dn: ~p",[DownInstructions]), + ?line [{load_object_code, {mnesia, _, _}}, + {load_object_code, {sasl, _, _}}, + {load_object_code, {webtool, _, _}}, + {load_object_code, {snmp, _, _}}, + {load_object_code, {xmerl, _, _}}, + point_of_no_return + | UpInstructionsT] = UpInstructions, + ?line true = lists:member({apply,{application,start,[mnesia,permanent]}}, UpInstructionsT), + ?line true = lists:member({apply,{application,start,[sasl,transient]}}, UpInstructionsT), + ?line true = lists:member({apply,{application,start,[webtool,temporary]}}, UpInstructionsT), + ?line true = lists:member({apply,{application,load,[snmp]}}, UpInstructionsT), + ?line false = lists:any(fun({apply,{application,_,[xmerl|_]}}) -> true; (_) -> false end, UpInstructionsT), + ?line [point_of_no_return | DownInstructionsT] = DownInstructions, + ?line true = lists:member({apply,{application,stop,[mnesia]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,stop,[sasl]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,stop,[webtool]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,stop,[snmp]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,stop,[xmerl]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,unload,[mnesia]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,unload,[sasl]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,unload,[webtool]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,unload,[snmp]}}, DownInstructionsT), + ?line true = lists:member({apply,{application,unload,[xmerl]}}, DownInstructionsT), + ok. + + +otp_6226(suite) -> + []; +otp_6226(doc) -> + ["{outdir,Dir} option for systools:make_script()"]; +otp_6226(Config) when is_list(Config) -> + PrivDir = ?privdir, + ?line {ok, OldDir} = file:get_cwd(), + + ?line {LatestDir, LatestName} = create_script(latest0,Config), + ?line {_LatestDir, LatestName1} = create_script(latest1,Config), + + ?line DataDir = filename:absname(?copydir), + ?line LibDir = fname([DataDir, d_normal, lib]), + ?line P = [fname([LibDir, 'db-2.1', ebin]), + fname([LibDir, 'db-1.0', ebin]), + fname([LibDir, 'fe-3.1', ebin]), + fname([DataDir, lib, kernel, ebin]), + fname([DataDir, lib, stdlib, ebin])], + + ?line ok = file:set_cwd(LatestDir), + + + %% Create an outdir1 directory + ?line ok = file:make_dir("outdir1"), + + %% ==== Now test systools:make_script ==== + %% a) badarg + ?line {'EXIT', {{badarg,[{outdir,outdir1}]}, _}} = + (catch systools:make_script(LatestName, [{outdir,outdir1}, + {path,P},silent])), + + %% b) absolute path + Outdir1 = filename:join(PrivDir, "outdir1"), + ?line {ok,_,[]} = systools:make_script(LatestName, [{outdir,Outdir1}, + {path,P},silent]), + ?line Script1 = filename:join(Outdir1, LatestName ++ ".script"), + ?line Boot1 = filename:join(Outdir1, LatestName ++ ".boot"), + ?line true = filelib:is_file(Script1), + ?line true = filelib:is_file(Boot1), + ?line ok = file:delete(Script1), + ?line ok = file:delete(Boot1), + + %% c) relative path + ?line {ok,_,[]} = systools:make_script(LatestName, [{outdir,"./outdir1"}, + {path,P},silent]), + ?line true = filelib:is_file(Script1), + ?line true = filelib:is_file(Boot1), + ?line ok = file:delete(Script1), + ?line ok = file:delete(Boot1), + + %% d) absolute but incorrect path + ?line Outdir2 = filename:join(PrivDir, "outdir2"), + ?line Script2 = filename:join(Outdir2, LatestName ++ ".script"), + ?line {error,_,{open,Script2,_}} = + systools:make_script(LatestName, [{outdir,Outdir2},{path,P},silent]), + + %% e) relative but incorrect path + ?line {error,_,{open,_,_}} = + systools:make_script(LatestName, [{outdir,"./outdir2"},{path,P},silent]), + + %% f) with .rel in another directory than cwd + ?line ok = file:set_cwd(Outdir1), + ?line {ok,_,[]} = systools:make_script(filename:join(PrivDir, LatestName), + [{outdir,"."},{path,P},silent]), + ?line true = filelib:is_file(LatestName ++ ".script"), + ?line true = filelib:is_file(LatestName ++ ".boot"), + ?line ok = file:delete(LatestName ++ ".script"), + ?line ok = file:delete(LatestName ++ ".boot"), + ?line ok = file:set_cwd(LatestDir), + + %% ==== Now test systools:make_tar ===== + ?line {ok,_,[]} = systools:make_script(LatestName, [{path,P},silent]), + %% a) badarg + ?line {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = + (catch systools:make_tar(LatestName,[{outdir,outdir1},{path,P},silent])), + + %% b) absolute path + ?line {ok,_,[]} = systools:make_tar(LatestName, [{outdir,Outdir1}, + {path,P},silent]), + ?line Tar1 = filename:join(Outdir1,LatestName++".tar.gz"), + ?line true = filelib:is_file(Tar1), + ?line ok = file:delete(Tar1), + + %% c) relative path + ?line {ok,_,[]} = systools:make_tar(LatestName, [{outdir,"./outdir1"}, + {path,P},silent]), + ?line true = filelib:is_file(Tar1), + ?line ok = file:delete(Tar1), + + %% d) absolute but incorrect path + ?line Tar2 = filename:join(Outdir2,LatestName++".tar.gz"), + ?line {error,_,{tar_error,{open,Tar2,{Tar2,enoent}}}} = + systools:make_tar(LatestName, [{outdir,Outdir2},{path,P},silent]), + + %% e) relative but incorrect path + ?line {error,_,{tar_error,{open,_,_}}} = + systools:make_tar(LatestName, [{outdir,"./outdir2"},{path,P},silent]), + + %% f) with .rel in another directory than cwd + ?line ok = file:set_cwd(Outdir1), + ?line {ok,_,[]} = systools:make_tar(filename:join(PrivDir, LatestName), + [{outdir,"."},{path,P},silent]), + ?line true = filelib:is_file(Tar1), + ?line ok = file:set_cwd(LatestDir), + + %% ===== Now test systools:make_relup ===== + %% a) badarg + ?line {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = + (catch systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,outdir1}, + {path,P},silent])), + + %% b) absolute path + Relup = filename:join(Outdir1, "relup"), + ?line {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,Outdir1}, + {path,P},silent]), + ?line true = filelib:is_file(Relup), + ?line ok = file:delete(Relup), + + %% c) relative path + ?line {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,"./outdir1"}, + {path,P},silent]), + ?line true = filelib:is_file(Relup), + ?line ok = file:delete(Relup), + + %% d) absolute but incorrect path + ?line {error,_,{file_problem,{"relup",enoent}}} = + systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,Outdir2},{path,P},silent]), + + %% e) relative but incorrect path + ?line {error,_,{file_problem,{"relup",enoent}}} = + systools:make_relup(LatestName,[LatestName1],[LatestName1], + [{outdir,"./outdir2"},{path,P},silent]), + + %% f) with .rel in another directory than cwd + %% -- not necessary to test since relup by default is placed in + %% cwd, not in the same directory as the .rel file -- + + %% Change back to previous working directory + ?line ok = file:set_cwd(OldDir), + ok. + + +%%%%%% +%%%%%% Utilities +%%%%%% + +check_script_path(RelName) -> + {ok, [Conts]} = read_script_file(RelName), + {script, {_, _}, ListOfThings} = Conts, + case lists:keysearch(path, 1, ListOfThings) of + {value, {path, [$$,$R,$O,$O,$T | _]}} -> %"$ROOT..." + false; + _ -> ok + end. + +check_var_script_file(VarDirs, NoExistDirs, RelName) -> + {ok, [Conts]} = read_script_file(RelName), + {script, {_, _}, ListOfThings} = Conts, + AllPaths = lists:append(lists:map(fun({path, P}) -> P; + (_) -> [] + end, + ListOfThings)), + case lists:filter(fun(VarDir) -> lists:member(VarDir, AllPaths) end, + VarDirs) of + VarDirs -> + ok; + _ -> + test_server:fail("All variable dirs not in generated script") + end, + case lists:filter(fun(NoExistDir) -> lists:member(NoExistDir, AllPaths) end, + NoExistDirs) of + [] -> + ok; + _ -> + test_server:fail("Unexpected dirs in generated script") + end. + +check_include_script(RelName, ExpectedLoad, ExpectedStart) -> + {ok, [Conts]} = read_script_file(RelName), + {script, {_, _}, ListOfThings} = Conts, + + %% Check that the applications are loaded in given order ! + ActualLoad = + [App || {apply,{application,load,[{application,App,_}]}} <- ListOfThings, + App=/=kernel, + App=/=stdlib], + + if ActualLoad =:= ExpectedLoad -> ok; + true -> test_server:fail({bad_load_order, ActualLoad, ExpectedLoad}) + end, + + %% Check that applications are started in given order ! + ActualStart = + [App || {apply,{application,start_boot,[App|_]}} <- ListOfThings, + App =/= kernel, + App =/= stdlib], + + if ActualStart =:= ExpectedStart -> ok; + true -> test_server:fail({bad_start_order, ActualStart,ExpectedStart}) + end, + + ok. + +read_script_file(RelName) -> + file:consult(RelName ++ ".script"). + +check_var_tar(Variable, RelName) -> + Expected = tar_name(Variable), + case check_tar(Expected,RelName) of + ok -> + ok; + {error, {erroneous_tar_file, _, missing, _}} -> + {error, {not_generated, Expected}} + end. + +exists_tar_file(Name) -> + File = tar_name(Name), + case filelib:is_regular(File) of + true -> + ok = file:delete(File), + true; + _ -> + false + end. + +%% Take a snap of the generated tar file and check if a certain +%% file is included. +%% This ensures at least that the tar file is generated. +check_tar(File, RelName) -> + TarContents = tar_contents(RelName), + case lists:member(File,TarContents) of + true -> ok; + _ -> {error, {erroneous_tar_file, tar_name(RelName), missing, File}} + end. + +%% Check that the given files exist in the tar file, and that they are +%% not symlinks +check_tar_regular(PrivDir, Files, RelName) -> + TmpDir = fname(PrivDir,tmp), + ok = file:make_dir(TmpDir), + ok = erl_tar:extract(tar_name(RelName), + [{files,Files},{cwd,TmpDir},compressed]), + R = lists:foldl(fun(File,Acc) -> + case file:read_link_info(fname(TmpDir,File)) of + {ok,#file_info{type=regular}} -> + Acc; + {ok,#file_info{type=Other}} -> + [{File,Other}|Acc]; + _ -> + [{File,missing}|Acc] + end + end, + [], + Files), + delete_tree(TmpDir), + case R of + [] -> + ok; + NotThere -> + {error,{erroneous_tar_file,tar_name(RelName),NotThere}} + end. + +delete_tree(Dir) -> + case filelib:is_dir(Dir) of + true -> + {ok,Files} = file:list_dir(Dir), + lists:foreach(fun(File) -> delete_tree(filename:join(Dir,File)) end, + Files), + file:del_dir(Dir); + false -> + ok = file:delete(Dir) + end. + +tar_contents(Name) -> + {ok, Cont} = erl_tar:table(Name ++ ".tar.gz", [compressed]), + Cont. + +tar_name(Name) -> + Name ++ ".tar.gz". + +create_script(latest,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, latest), + ?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 io:format(Fd, + "{release, {\"Test release 3\", \"LATEST\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"~s\"}, {stdlib, \"~s\"}, \n" + " {db, \"2.1\"}, {fe, \"3.1\"}]}.\n", + [KernelVer,StdlibVer]), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_no_mod_vsn,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, latest), + ?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 io:format(Fd, + "{release, {\"Test release 3\", \"LATESTNOMOD\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"~s\"}, {stdlib, \"~s\"}, \n" + " {db, \"3.1\"}, {fe, \"3.1\"}]}.\n", + [KernelVer,StdlibVer]), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest0,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-1'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 2\", \"LATEST0\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {db, \"2.1\"}, {fe, \"3.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest1,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, latest), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 2\", \"LATEST1\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {db, \"1.0\"}, {fe, \"3.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest2,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-2'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 1\", \"LATEST2\"}, \n" + " {erts, \"4.3\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {db, \"1.0\"}, {fe, \"2.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_small,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-small'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 2\", \"LATEST_SMALL\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {fe, \"3.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_small0,Config) -> %Differs in fe vsn + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-small0'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 2\", \"LATEST_SMALL0\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {fe, \"2.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_small1,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-small1'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 2\", \"LATEST_SMALL1\"}, \n" + " {erts, \"4.4\"}, \n" + " [{kernel, \"1.0\"}, {stdlib, \"1.0\"}, \n" + " {fe, \"500.18.7\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_nokernel,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, 'latest-nokernel'), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line io:format(Fd, + "{release, {\"Test release 3\", \"LATEST_NOKERNEL\"}, \n" + " {erts, \"4.4\"}, \n" + " [{db, \"2.1\"}, {fe, \"3.1\"}]}.\n", + []), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_app_start_type1,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, latest_app_start_type1), + ?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", "1"}, + {erts,ErtsVer}, + [{kernel,KernelVer}, + {stdlib,StdlibVer}]}, + ?line io:format(Fd,"~p.~n",[RelfileContent]), + ?line ok = file:close(Fd), + {filename:dirname(Name), filename:basename(Name)}; +create_script(latest_app_start_type2,Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, latest_app_start_type2), + ?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 OtherApps = [{mnesia,permanent}, + {sasl,transient}, + {webtool,temporary}, + {snmp,load}, + {xmerl,none}], + ?line lists:foreach(fun({App,_}) -> application:load(App) end, + OtherApps), + ?line Loaded = application:loaded_applications(), + ?line OtherAppsRel = + lists:map(fun({App,StartType}) -> + {_,_,Ver} = lists:keyfind(App,1,Loaded), + {App,Ver,StartType} + end, + OtherApps), + ?line {ok,Fd} = file:open(Name++".rel",write), + ?line RelfileContent = + {release,{"Test release", "2"}, + {erts,ErtsVer}, + [{kernel,KernelVer}, + {stdlib,StdlibVer} | OtherAppsRel]}, + ?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), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc2, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc2), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t6 does not include t5 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc3, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc3), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t3 does not include t2 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc4, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc4), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t3 does not include t2 ! + %% t6 does not include t5 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc5, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc5), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t6 does not include t5 ! + %% exclude t5. + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\", [t4]}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc6, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc6), + create_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t3 does include non existing t2 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc7, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc7), + create_apps(PrivDir), + create_app(t7, PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t7 and t6 does include t5 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t7, \"1.0\"}, {t6, \"1.0\"}, {t5, \"1.0\"}, \n" + " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" + " {t1, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc8, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc8), + create_circular_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t8 uses t9 and t10 includes t9 ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc9, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc9), + create_circular_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t8 uses t9, t9 uses t10 and t10 includes t8 ==> circular !! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\", [t8]}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc10, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc10), + create_circular_apps(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + %% t9 tries to include not specified (in .app file) application ! + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t8, \"1.0\"}, {t9, \"1.0\", [t7]}, {t10, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(inc11, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, inc11), + create_apps2(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {t11, \"1.0\"}, \n" + " {t12, \"1.0\"}, \n" + " {t13, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}; + +create_include_files(otp_3065, Config) -> + ?line PrivDir = ?privdir, + ?line Name = fname(PrivDir, otp_3065), + create_apps_3065(PrivDir), + + ?line Apps = application_controller:which_applications(), + ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), + ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), + + Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" + " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" + ++ StdlibVer ++ "\"},\n" + " {chAts, \"1.0\"}, {aa12, \"1.0\"}, \n" + " {chTraffic, \"1.0\"}]}.\n", + file:write_file(Name ++ ".rel", list_to_binary(Rel)), + {filename:dirname(Name), filename:basename(Name)}. + +create_apps(Dir) -> + T1 = "{application, t1,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [kernel, stdlib]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't1.app'), list_to_binary(T1)), + + T2 = "{application, t2,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t1]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't2.app'), list_to_binary(T2)), + + T3 = "{application, t3,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t2]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't3.app'), list_to_binary(T3)), + + T4 = "{application, t4,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t3]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't4.app'), list_to_binary(T4)), + + T5 = "{application, t5,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t3]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't5.app'), list_to_binary(T5)), + + T6 = "{application, t6,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t4, t5]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't6.app'), list_to_binary(T6)). + +create_app(t7, Dir) -> + T7 = "{application, t7,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t5]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't7.app'), list_to_binary(T7)). + +create_circular_apps(Dir) -> + T8 = "{application, t8,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t9]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't8.app'), list_to_binary(T8)), + + T9 = "{application, t9,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t10]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't9.app'), list_to_binary(T9)), + + T10 = "{application, t10,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t8, t9]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't10.app'), list_to_binary(T10)). + +create_apps2(Dir) -> + T11 = "{application, t11,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [t13]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't11.app'), list_to_binary(T11)), + + T12 = "{application, t12,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [t11]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't12.app'), list_to_binary(T12)), + + T13 = "{application, t13,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 't13.app'), list_to_binary(T13)). + + + +create_apps_3065(Dir) -> + T11 = "{application, chTraffic,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [chAts]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 'chTraffic.app'), list_to_binary(T11)), + + T12 = "{application, chAts,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, []},\n" + " {included_applications, [aa12]},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 'chAts.app'), list_to_binary(T12)), + + T13 = "{application, aa12,\n" + " [{vsn, \"1.0\"},\n" + " {description, \"test\"},\n" + " {modules, []},\n" + " {applications, [chAts]},\n" + " {included_applications, []},\n" + " {registered, []}]}.\n", + file:write_file(fname(Dir, 'aa12.app'), list_to_binary(T13)). + +fname(N) -> + filename:join(N). + +fname(Dir, Basename) -> + filename:join(Dir, Basename). |