diff options
author | Lukas Larsson <[email protected]> | 2011-05-18 16:21:34 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-05-18 16:21:34 +0200 |
commit | 15426ac367eed736c165a5bdbb1c051a87944f68 (patch) | |
tree | fcabce7847168a8416600fe35f94a411a5f73d6e /lib/sasl/test/systools_SUITE.erl | |
parent | 4cd0717b717803ce8f03a12de4bf89f452ed1df7 (diff) | |
parent | f44bbb331fb517e989d4d906b7f63ec110bbbc18 (diff) | |
download | otp-15426ac367eed736c165a5bdbb1c051a87944f68.tar.gz otp-15426ac367eed736c165a5bdbb1c051a87944f68.tar.bz2 otp-15426ac367eed736c165a5bdbb1c051a87944f68.zip |
Merge branch 'dev' of super:otp into dev
* 'dev' of super:otp: (166 commits)
Corrected documentation error and added examples to Users Guide
In TLS 1.1, failure to properly close a connection no longer requires that a session not be resumed. This is a change from TLS 1.0 to conform with widespread implementation practice. Erlang ssl will now in TLS 1.0 conform to the widespread implementation practice instead of the specification to avoid performance issues.
Add escript to bootstrap/bin
Remove unused variable warning in inet_res
Remove unused variable in epmd_port
Remove compiler warnings in inet_drv
Add SASL test suite
Allow same module name in multiple applications if explicitely excluded
Fix bugs concerning the option report_missing_types
Fix default encoding in SAX parser.
re: remove gratuitous "it " in manpage
Spelling in (backward *compatibility*) comment.
Improve erl_docgen's support for Dialyzer specs and types
dialyzer warning on mnesia_tm
Add documentation text about majority checking
add mnesia_majority_test suite
where_to_wlock optimization + change_table_majority/2
bug in mnesia_tm:needs_majority/2
optimize sticky_lock maj. check
check majority for sticky locks
...
Diffstat (limited to 'lib/sasl/test/systools_SUITE.erl')
-rw-r--r-- | lib/sasl/test/systools_SUITE.erl | 2112 |
1 files changed, 2112 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..9190b111ef --- /dev/null +++ b/lib/sasl/test/systools_SUITE.erl @@ -0,0 +1,2112 @@ +%% +%% %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]). +-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]}, + {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 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 - 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]), + + %% 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. + +%% 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"}]), + + %% 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"}]), + + ?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). |