1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2012-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21%% Test suite for the systools module. 22%% 23%% The systools module is a wrapper for a number of modules that 24%% handle large parts of the release building functionality 25%% (e.g. checking app files, building a tar file, building 26%% release upgrad scripts. 27%% 28 29 30-module(systools_SUITE). 31 32-compile(export_all). 33 34%%-define(debug, true). 35 36-include_lib("common_test/include/ct.hrl"). 37-define(format(S, A), ok). 38-define(datadir, ?config(data_dir, Config)). 39-define(privdir, ?config(priv_dir, Config)). 40-define(copydir, ?config(copy_dir, Config)). 41 42-include_lib("kernel/include/file.hrl"). 43 44-import(lists, [foldl/3]). 45 46-define(default_timeout, ?t:minutes(20)). 47 48 49%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 51suite() -> 52 [{ct_hooks, [ts_install_cth]}]. 53 54all() -> 55 [{group, script}, {group, tar}, {group, relup}, {group, hybrid}, 56 {group, options}]. 57 58groups() -> 59 [{script, [], 60 [script_options, normal_script, start_script, unicode_script, no_mod_vsn_script, 61 wildcard_script, variable_script, abnormal_script, 62 no_sasl_script, no_dot_erlang_script, 63 src_tests_script, crazy_script, 64 included_script, included_override_script, 65 included_fail_script, included_bug_script, exref_script, 66 duplicate_modules_script, 67 otp_3065_circular_dependenies, included_and_used_sort_script]}, 68 {tar, [], 69 [tar_options, relname_tar, normal_tar, no_mod_vsn_tar, system_files_tar, 70 system_src_file_tar, invalid_system_files_tar, variable_tar, 71 src_tests_tar, var_tar, exref_tar, link_tar, no_sasl_tar, 72 otp_9507_path_ebin, additional_files_tar, erts_tar]}, 73 {relup, [], 74 [normal_relup, restart_relup, abnormal_relup, no_sasl_relup, 75 no_appup_relup, bad_appup_relup, app_start_type_relup, regexp_relup, 76 replace_app_relup 77 ]}, 78 {hybrid, [], [normal_hybrid,hybrid_no_old_sasl,hybrid_no_new_sasl]}, 79 {options, [], [otp_6226_outdir,app_file_defaults]}]. 80 81init_per_group(_GroupName, Config) -> 82 Config. 83 84end_per_group(_GroupName, Config) -> 85 Config. 86 87%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 88 89 90init_per_suite(Config) when is_list(Config) -> 91 %% To use in end_per_testcase 92 Path = code:get_path(), 93 {ok,Cwd} = file:get_cwd(), 94 95 %% Make of copy of the data directory. 96 DataDir = ?datadir, 97 PrivDir = ?privdir, 98 CopyDir = fname(PrivDir, "datacopy"), 99 ok = file:make_dir(CopyDir), 100 TarFile = fname(PrivDir, "datacopy.tgz"), 101 ok = file:set_cwd(DataDir), 102 ok = erl_tar:create(TarFile, ["."], [compressed]), 103 ok = erl_tar:extract(TarFile, [compressed, {cwd,CopyDir}]), 104 ok = file:delete(TarFile), 105 106 %% Compile source files in the copy directory. 107 Sources = filelib:wildcard(fname([CopyDir,'*','*','*','*','*.erl'])), 108 lists:foreach(fun compile_source/1, Sources), 109 110 [{copy_dir, CopyDir}, {cwd,Cwd}, {path,Path} | Config]. 111 112compile_source(File) -> 113 %% The compiler will no longer create a Beam file 114 %% with a module name that does not match the output 115 %% file, so we must compile to a binary and write 116 %% the output file ourselves. 117 U = filename:dirname(filename:dirname(File)), 118 Base = filename:rootname(filename:basename(File)), 119 OutFile = filename:join([U,"ebin",Base++".beam"]), 120 OutFileTemp = OutFile ++ "#", 121 {ok,_,Code} = compile:file(File, [binary]), 122 ok = file:write_file(OutFileTemp, Code), 123 file:rename(OutFileTemp, OutFile). 124 125end_per_suite(Config) when is_list(Config) -> 126 rh_test_lib:clean_dir(?privdir), 127 Config. 128 129init_per_testcase(link_tar, Config) -> 130 case os:type() of 131 {unix, _} -> init_per_testcase(dummy, Config); 132 {win32, _} -> {skip, "Skip on windows"} 133 end; 134init_per_testcase(_Case, Config) -> 135 Dog = test_server:timetrap(?default_timeout), 136 [{watchdog, Dog}|Config]. 137 138end_per_testcase(Case, Config) -> 139 try apply(?MODULE,Case,[cleanup,Config]) 140 catch error:undef -> ok 141 end, 142 Dog=?config(watchdog, Config), 143 test_server:timetrap_cancel(Dog), 144 case {?config(path,Config),?config(cwd,Config)} of 145 {undefined,undefined} -> 146 ok; 147 {Path,Cwd} -> 148 true = code:set_path(Path), 149 ok = file:set_cwd(Cwd) 150 end, 151 ok. 152 153 154 155%% Usage: 156%% systools:make_script("RelName") 157%% Make a boot file from RelName.rel. 158%% Generates RelName.{script,boot} 159%% systools:make_tar("RelName") 160%% Make a release package from RelName.rel. 161%% Generates RelName.tar,Z 162%% systools:script2boot(File) 163%% File.script -> File.boot 164%% systools:make_relup("Target", ["UpFromRel"...], ["DownToRel"...], Opts) 165%% Gather all appup scripts to the relup file 166%% 167 168 169%% make_script: Check illegal script options 170script_options(Config) when is_list(Config) -> 171 {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = 172 (catch systools:make_script("release", [{path,["Path",12,"Another"]}])), 173 {'EXIT',{{badarg,[sillent]}, _}} = 174 (catch systools:make_script("release", 175 [{path,["Path","Another"]},sillent])), 176 {'EXIT',{{badarg,[locall]}, _}} = 177 (catch systools:make_script("release", 178 [{path,["Path","Another"]},locall])), 179 {'EXIT',{{badarg,[src_testsxx]}, _}} = 180 (catch systools:make_script("release", 181 [{path,["Path"]},src_testsxx])), 182 {'EXIT',{{badarg,[{variables, {"TEST", "/home/lib"}}]}, _}} = 183 (catch systools:make_script("release", 184 [{variables, {"TEST", "/home/lib"}}])), 185 {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = 186 (catch systools:make_script("release", 187 [{variables, [{a, b}, {"a", "b"}]}])), 188 {'EXIT',{{badarg,[exreff]}, _}} = 189 (catch systools:make_script("release", 190 [{path,["Path","Another"]},exreff])), 191 {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = 192 (catch systools:make_script("release", [{exref,["appl"]}])), 193 {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = 194 (catch systools:make_script("release", [{machine,"appl"}])), 195 ok. 196 197 198%% make_script: Check that normal case 199normal_script(Config) when is_list(Config) -> 200 {ok, OldDir} = file:get_cwd(), 201 PSAVE = code:get_path(), % Save path 202 203 {LatestDir, LatestName} = create_script(latest,Config), 204 205 DataDir = filename:absname(?copydir), 206 LibDir = fname([DataDir, d_normal, lib]), 207 P1 = fname([LibDir, 'db-2.1', ebin]), 208 P2 = fname([LibDir, 'fe-3.1', ebin]), 209 210 true = code:add_patha(P1), 211 true = code:add_patha(P2), 212 213 ok = file:set_cwd(LatestDir), 214 215 ok = systools:make_script(filename:basename(LatestName)), 216 {ok, _} = read_script_file(LatestName), % Check readabillity 217 218 %% Check the same but w. silent flag 219 {ok, _, []} = systools:make_script(LatestName, [silent]), 220 {ok, _, []} = systools:make_script(LatestName, [silent,warnings_as_errors]), 221 222 %% Use the local option 223 ok = systools:make_script(LatestName, [local]), 224 ok = check_script_path(LatestName), 225 226 %% use the path option 227 code:set_path(PSAVE), % Restore path 228 %% Mess up std path: 229 true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), 230 true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), 231 232 error = systools:make_script(LatestName), %should fail 233 ok = systools:make_script(LatestName,[{path, [P1, P2]}]), 234 235 ok = file:set_cwd(OldDir), 236 code:set_path(PSAVE), % Restore path 237 ok. 238 239%% make_script: Check that script can be named start.script 240start_script(Config) when is_list(Config) -> 241 {ok, OldDir} = file:get_cwd(), 242 PSAVE = code:get_path(), % Save path 243 244 {LatestDir, LatestName} = create_script(latest,Config), 245 246 DataDir = filename:absname(?copydir), 247 LibDir = fname([DataDir, d_normal, lib]), 248 P1 = fname([LibDir, 'db-2.1', ebin]), 249 P2 = fname([LibDir, 'fe-3.1', ebin]), 250 251 true = code:add_patha(P1), 252 true = code:add_patha(P2), 253 254 ok = file:set_cwd(LatestDir), 255 256 ok = systools:make_script(filename:basename(LatestName), [{script_name, "start"}]), 257 {ok, _} = read_script_file("start"), % Check readabillity 258 259 ok = file:set_cwd(OldDir), 260 code:set_path(PSAVE), % Restore path 261 ok. 262 263%% make_script: Test make_script with unicode .app file 264unicode_script(Config) when is_list(Config) -> 265 UnicodeStr = [945,946], % alhpa beta in greek letters 266 267 {LatestDir, LatestName} = create_script({unicode,UnicodeStr},Config), 268 269 DataDir = filename:absname(?copydir), 270 UnicodeApp = fname([DataDir, "d_unicode", "lib", "ua-1.0"]), 271 TarFile = fname(?privdir, "unicode_app.tgz"), 272 {ok, Tar} = erl_tar:open(TarFile, [write, compressed]), 273 ok = erl_tar:add(Tar, UnicodeApp, "ua-1.0", [compressed]), 274 ok = erl_tar:close(Tar), 275 276 UnicodeLibDir = fname([DataDir, "d_unicode", UnicodeStr]), 277 P1 = fname([UnicodeLibDir, "ua-1.0", "ebin"]), 278 279 %% Need to do this on a separate node to make sure it has unicode 280 %% filename mode (+fnu*) 281 {ok,HostStr} = inet:gethostname(), 282 Host = list_to_atom(HostStr), 283 {ok,Node} = ct_slave:start(Host,unicode_script_node,[{erl_flags,"+fnui"}]), 284 285 ok = rpc:call(Node,erl_tar,extract, 286 [TarFile, [{cwd,UnicodeLibDir},compressed]]), 287 288 true = rpc:call(Node,code,add_patha,[P1]), 289 290 ok = rpc:call(Node,file,set_cwd,[LatestDir]), 291 292 ok = rpc:call(Node,systools,make_script,[filename:basename(LatestName), 293 [local]]), 294 295 {ok, Script} = rpc:call(Node,file,consult,[LatestName++".script"]), 296 297 %% For debug purpose - print script to log 298 io:format("~tp~n",[Script]), 299 300 %% check that script contains unicode strings in 301 %% 1. release version (set in ?MODULE:do_create_script) 302 [{script,{"Test release",UnicodeStr},Instr}] = Script, 303 304 %% 2. application description (set in ua.app in data dir) 305 [AppInfo] = [X || {apply,{application,load,[{application,ua,X}]}} <- Instr], 306 {description,UnicodeStr} = lists:keyfind(description,1,AppInfo), 307 308 %% 3. path (directory name where unicode_app.tgz is extracted) 309 true = lists:member({path,[P1]},Instr), 310 311 %% If all is good, delete the unicode dir to avoid lingering files 312 %% on windows. 313 rpc:call(Node,code,add_pathz,[filename:dirname(code:which(?MODULE))]), 314 rpc:call(Node,?MODULE,delete_tree,[UnicodeLibDir]), 315 316 ok. 317 318unicode_script(cleanup,Config) -> 319 _ = ct_slave:stop(unicode_script_node), 320 file:delete(fname(?privdir, "unicode_app.tgz")), 321 ok. 322 323 324%% make_script: 325%% Modules specified without version in .app file (db-3.1). 326%% Note that this is now the normal way - i.e. systools now ignores 327%% the module versions in the .app file. 328no_mod_vsn_script(Config) when is_list(Config) -> 329 {ok, OldDir} = file:get_cwd(), 330 PSAVE = code:get_path(), % Save path 331 332 {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), 333 334 DataDir = filename:absname(?copydir), 335 LibDir = fname([DataDir, d_normal, lib]), 336 P1 = fname([LibDir, 'db-3.1', ebin]), 337 P2 = fname([LibDir, 'fe-3.1', ebin]), 338 339 true = code:add_patha(P1), 340 true = code:add_patha(P2), 341 342 ok = file:set_cwd(LatestDir), 343 344 ok = systools:make_script(filename:basename(LatestName)), 345 {ok, _} = read_script_file(LatestName), % Check readabillity 346 347 %% Check the same but w. silent flag 348 {ok, _, []} = systools:make_script(LatestName, [silent]), 349 350 %% Use the local option 351 ok = systools:make_script(LatestName, [local]), 352 ok = check_script_path(LatestName), 353 354 %% use the path option 355 code:set_path(PSAVE), % Restore path 356 %% Mess up std path: 357 true = code:add_patha(fname([LibDir, 'db-1.0', ebin])), 358 true = code:add_patha(fname([LibDir, 'fe-2.1', ebin])), 359 360 error = systools:make_script(LatestName), %should fail 361 ok = systools:make_script(LatestName, 362 [{path, [P1, P2]}]), 363 364 ok = file:set_cwd(OldDir), 365 code:set_path(PSAVE), % Restore path 366 ok. 367 368 369%% make_script: Check that make_script handles wildcards in path. 370wildcard_script(Config) when is_list(Config) -> 371 {ok, OldDir} = file:get_cwd(), 372 373 {LatestDir, LatestName} = create_script(latest,Config), 374 375 DataDir = filename:absname(?copydir), 376 LibDir = fname([DataDir, d_normal, lib]), 377 WildDir = fname([LibDir, '*', ebin]), 378 379 ok = file:set_cwd(LatestDir), 380 381 error = systools:make_script(filename:basename(LatestName)), 382 383 ok = systools:make_script(LatestName, 384 [{path, [WildDir]}]), 385 386 {ok, _} = read_script_file(LatestName), % Check readabillity 387 388 ok = file:set_cwd(OldDir), 389 ok. 390 391 392%% make_script: Add own installation dependent variable in script. 393variable_script(Config) when is_list(Config) -> 394 {ok, OldDir} = file:get_cwd(), 395 396 {LatestDir, LatestName} = create_script(latest,Config), 397 398 DataDir = filename:absname(?copydir), 399 LibDir = fname([DataDir, d_normal, lib]), 400 P = [fname([LibDir, 'db-2.1', ebin]), 401 fname([LibDir, 'fe-3.1', ebin])], 402 403 ok = file:set_cwd(LatestDir), 404 405 ok = systools:make_script(LatestName, 406 [{path, P}, 407 {variables, [{"TEST", LibDir}]}]), 408 409 %% Check variables 410 ok = check_var_script_file([fname(['$TEST', 'db-2.1', ebin]), 411 fname(['$TEST', 'fe-3.1', ebin])], 412 P, 413 LatestName), 414 415 ok = file:set_cwd(OldDir), 416 ok. 417 418%% make_script: Abnormal cases. 419abnormal_script(Config) when is_list(Config) -> 420 {ok, OldDir} = file:get_cwd(), 421 422 {LatestDir, LatestName} = create_script(latest,Config), 423 424 DataDir = filename:absname(?copydir), 425 426 ok = file:set_cwd(LatestDir), 427 LibDir = fname([DataDir, d_bad_app_vsn, lib]), 428 P = [fname([LibDir, 'db-2.1', ebin]), 429 fname([LibDir, 'fe-3.1', ebin])], 430 431 %% Check wrong app vsn 432 error = systools:make_script(LatestName, [{path, P}]), 433 {error, 434 systools_make, 435 [{error_reading, {db, {no_valid_version, 436 {{"should be","2.1"}, 437 {"found file", _, "2.0"}}}}}]} = 438 systools:make_script(LatestName, [silent, {path, P}]), 439 440 ok = file:set_cwd(OldDir), 441 ok. 442 443 444%% make_script: Create script without sasl appl. Check warning. 445no_sasl_script(Config) when is_list(Config) -> 446 {ok, OldDir} = file:get_cwd(), 447 448 {LatestDir, LatestName} = create_script(latest1_no_sasl,Config), 449 450 DataDir = filename:absname(?copydir), 451 LibDir = [fname([DataDir, d_normal, lib])], 452 P = [fname([LibDir, '*', ebin]), 453 fname([DataDir, lib, kernel, ebin]), 454 fname([DataDir, lib, stdlib, ebin]), 455 fname([DataDir, lib, sasl, ebin])], 456 457 ok = file:set_cwd(LatestDir), 458 459 {ok, _ , [{warning,missing_sasl}]} = 460 systools:make_script(LatestName,[{path, P},silent]), 461 462 {error, systools_make, {warnings_treated_as_errors,[missing_sasl]}} = 463 systools:make_script(LatestName,[{path, P},silent,warnings_as_errors]), 464 465 {ok, _ , []} = 466 systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]), 467 468 {ok, _ , []} = 469 systools:make_script(LatestName,[{path, P},silent, no_warn_sasl, 470 warnings_as_errors]), 471 472 ok = file:set_cwd(OldDir), 473 ok. 474 475%% make_script: Create script with no_dot_erlang. Check script contents. 476no_dot_erlang_script(Config) when is_list(Config) -> 477 {ok, OldDir} = file:get_cwd(), 478 479 {LatestDir, LatestName} = create_script(latest1_no_sasl,Config), 480 481 DataDir = filename:absname(?copydir), 482 LibDir = [fname([DataDir, d_normal, lib])], 483 P = [fname([LibDir, '*', ebin]), 484 fname([DataDir, lib, kernel, ebin]), 485 fname([DataDir, lib, stdlib, ebin]), 486 fname([DataDir, lib, sasl, ebin])], 487 488 ok = file:set_cwd(LatestDir), 489 490 {ok, _ , []} = 491 systools:make_script(LatestName,[{path, P},silent, no_warn_sasl]), 492 {ok, [{_, _, LoadDotErlang}]} = read_script_file(LatestName), 493 [erlangrc] = [E || {apply, {c, E, []}} <- LoadDotErlang], 494 495 {ok, _ , []} = 496 systools:make_script(LatestName,[{path, P},silent, no_warn_sasl, no_dot_erlang]), 497 {ok, [{_, _, DoNotLoadDotErlang}]} = read_script_file(LatestName), 498 [] = [E || {apply, {c, E, []}} <- DoNotLoadDotErlang], 499 500 ok = file:set_cwd(OldDir), 501 ok. 502 503 504%% make_script: Do not check date of object file or that source code 505%% can be found. 506src_tests_script(Config) when is_list(Config) -> 507 {ok, OldDir} = file:get_cwd(), 508 PSAVE = code:get_path(), % Save path 509 510 {LatestDir, LatestName} = create_script(latest,Config), 511 BootFile = LatestName ++ ".boot", 512 513 DataDir = filename:absname(?copydir), 514 LibDir = fname([DataDir, d_missing_src, lib]), 515 P1 = fname([LibDir, 'db-2.1', ebin]), 516 P2 = fname([LibDir, 'fe-3.1', ebin]), 517 N = [P1, P2], 518 519 ok = file:set_cwd(LatestDir), 520 521 %% Manipulate the modification date of a beam file so it seems 522 %% older than its .erl file 523 Erl = filename:join([P1,"..","src","db1.erl"]), 524 {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), 525 Beam = filename:join(P1,"db1.beam"), 526 ok=file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), 527 528 %% Remove a .erl file 529 Erl2 = filename:join([P1,"..","src","db2.erl"]), 530 file:delete(Erl2), 531 532 %% Then make script 533 534 %% .boot file should not exist 535 ok = file:delete(BootFile), 536 false = filelib:is_regular(BootFile), 537 %% With warnings_as_errors and src_tests option, an error should be issued 538 {error, systools_make, 539 {warnings_treated_as_errors, [{obj_out_of_date,_}, 540 {source_not_found,_}]}} = 541 systools:make_script(LatestName, [silent, {path, N}, src_tests, 542 warnings_as_errors]), 543 error = 544 systools:make_script(LatestName, [{path, N}, src_tests, 545 warnings_as_errors]), 546 547 %% due to warnings_as_errors .boot file should still not exist 548 false = filelib:is_regular(BootFile), 549 550 %% Two warnings should be issued when src_tests is given 551 %% 1. old object code for db1.beam 552 %% 2. missing source code for db2.beam 553 {ok, _, [{warning,{obj_out_of_date,_}}, 554 {warning,{source_not_found,_}}]} = 555 systools:make_script(LatestName, [silent, {path, N}, src_tests]), 556 557 %% .boot file should exist now 558 true = filelib:is_regular(BootFile), 559 560 %% Without the src_tests option, no warning should be issued 561 {ok, _, []} = 562 systools:make_script(LatestName, [silent, {path, N}]), 563 564 %% Check that the old no_module_tests option (from the time when 565 %% it was default to do the src_test) is ignored 566 {ok, _, [{warning,{obj_out_of_date,_}}, 567 {warning,{source_not_found,_}}]} = 568 systools:make_script(LatestName, [silent, 569 {path, N}, 570 no_module_tests, 571 src_tests]), 572 573 ok = file:set_cwd(OldDir), 574 code:set_path(PSAVE), 575 ok. 576 577%% make_script: Do the crazy cases. 578crazy_script(Config) when is_list(Config) -> 579 {ok, OldDir} = file:get_cwd(), 580 581 {LatestDir, LatestName} = create_script(latest, Config), 582 583 DataDir = filename:absname(?copydir), 584 LibDir = fname([DataDir, d_normal, lib]), 585 P = [fname([LibDir, 'db-2.1', ebin]), 586 fname([LibDir, 'fe-3.1', ebin])], 587 588 ok = file:set_cwd(LatestDir), 589 590 %% Run with bad path 591 error = systools:make_script(LatestName), 592 {error, _, [{error_reading, _}, {error_reading, _}]} = 593 systools:make_script(LatestName, [silent]), 594 595 %% Run with .rel file lacking kernel 596 {LatestDir2, LatestName2} = create_script(latest_nokernel, Config), 597 ok = file:set_cwd(LatestDir2), 598 599 error = systools:make_script(LatestName2), 600 {error, _, {missing_mandatory_app,kernel}} = 601 systools:make_script(LatestName2, [silent,{path,P}]), 602 603 %% Run with .rel file with non-permanent kernel 604 {LatestDir3, LatestName3} = create_script(latest_kernel_start_type, Config), 605 ok = file:set_cwd(LatestDir3), 606 607 error = systools:make_script(LatestName3), 608 {error, _, {mandatory_app,kernel,load}} = 609 systools:make_script(LatestName3, [silent,{path,P}]), 610 611 %% Run with .rel file with non-permanent stdlib 612 {LatestDir4, LatestName4} = create_script(latest_stdlib_start_type, Config), 613 ok = file:set_cwd(LatestDir4), 614 615 error = systools:make_script(LatestName4), 616 {error, _, {mandatory_app,stdlib,load}} = 617 systools:make_script(LatestName4, [silent,{path,P}]), 618 619 %% Run with .rel file lacking stdlib 620 {LatestDir5, LatestName5} = create_script(latest_no_stdlib, Config), 621 ok = file:set_cwd(LatestDir5), 622 623 error = systools:make_script(LatestName5), 624 {error, _, {missing_mandatory_app,stdlib}} = 625 systools:make_script(LatestName5, [silent,{path,P}]), 626 627 ok = file:set_cwd(OldDir), 628 ok. 629 630%% make_script: Check that make_script handles generation of script 631%% for applications with included applications. 632included_script(Config) when is_list(Config) -> 633 {ok, OldDir} = file:get_cwd(), 634 {LatestDir, LatestName} = create_include_files(inc1, Config), 635 ok = file:set_cwd(LatestDir), 636 ok = systools:make_script(LatestName), 637 ok = check_include_script(LatestName, 638 [t1, t2, t3, t5, t4, t6], 639 [t1, t3, t6]), 640 ok = file:set_cwd(OldDir), 641 ok. 642 643%% make_script: Check that make_script handles generation of script 644%% for applications with included applications which are override by 645%% the .rel file. 646included_override_script(Config) when is_list(Config) -> 647 {ok, OldDir} = file:get_cwd(), 648 {LatestDir, LatestName} = create_include_files(inc2, Config), 649 ok = file:set_cwd(LatestDir), 650 ok = systools:make_script(LatestName), 651 ok = check_include_script(LatestName, 652 [t1, t2, t3, t4, t6, t5], 653 [t1, t3, t6, t5]), 654 655 {_, LatestName1} = create_include_files(inc3, Config), 656 ok = systools:make_script(LatestName1), 657 ok = check_include_script(LatestName1, 658 [t3, t5, t4, t6, t1, t2], 659 [t3, t6, t1, t2]), 660 661 {_, LatestName2} = create_include_files(inc4, Config), 662 ok = systools:make_script(LatestName2), 663 ok = check_include_script(LatestName2, 664 [t3, t4, t6, t5, t1, t2], 665 [t3, t6, t5, t1, t2]), 666 667 {_, LatestName3} = create_include_files(inc5, Config), 668 ok = systools:make_script(LatestName3), 669 ok = check_include_script(LatestName3, 670 [t3, t4, t6, t1, t2], 671 [t3, t6, t1, t2]), 672 673 ok = file:set_cwd(OldDir), 674 ok. 675 676%% make_script: Check that make_script handles errors then generating 677%% script with included applications. 678included_fail_script(Config) when is_list(Config) -> 679 {ok, OldDir} = file:get_cwd(), 680 {LatestDir, LatestName} = create_include_files(inc6, Config), 681 ok = file:set_cwd(LatestDir), 682 {error, _, {undefined_applications,[t2]}} = 683 systools:make_script(LatestName, [silent]), 684 685 {_, LatestName1} = create_include_files(inc7, Config), 686 {error, _, {duplicate_include,[{{t5,t7,_,_},{t5,t6,_,_}}]}} = 687 systools:make_script(LatestName1, [silent]), 688 689 {_, LatestName3} = create_include_files(inc9, Config), 690 {error, _, {circular_dependencies,[{t10,_},{t8,_}]}} = 691 systools:make_script(LatestName3, [silent]), 692 693 {_, LatestName4} = create_include_files(inc10, Config), 694 {error, _, [{error_reading,{t9,{override_include,[t7]}}}]} = 695 systools:make_script(LatestName4, [silent]), 696 697 ok = file:set_cwd(OldDir), 698 ok. 699 700%% make_script: Check that make_script handles generation of script 701%% with difficult dependency for included applications. 702included_bug_script(Config) when is_list(Config) -> 703 {ok, OldDir} = file:get_cwd(), 704 {LatestDir, LatestName} = create_include_files(inc11, Config), 705 ok = file:set_cwd(LatestDir), 706 ok = systools:make_script(LatestName), 707 ok = check_include_script(LatestName, 708 [t13, t11, t12], 709 [t11, t12]), 710 ok = file:set_cwd(OldDir), 711 ok. 712 713 714%% make_script: Circular dependencies in systools:make_script(). 715otp_3065_circular_dependenies(Config) when is_list(Config) -> 716 {ok, OldDir} = file:get_cwd(), 717 {LatestDir, LatestName} = 718 create_include_files(otp_3065_circular_dependenies, Config), 719 ok = file:set_cwd(LatestDir), 720 ok = systools:make_script(LatestName), 721 ok = check_include_script(LatestName, 722 [aa12, chAts, chTraffic], 723 [chTraffic]), 724 ok = file:set_cwd(OldDir), 725 ok. 726 727%% Test sorting of included applications and used applications 728included_and_used_sort_script(Config) when is_list(Config) -> 729 {ok, OldDir} = file:get_cwd(), 730 {LatestDir1, LatestName1} = create_include_files(sort_apps, Config), 731 ok = file:set_cwd(LatestDir1), 732 ok = systools:make_script(LatestName1), 733 ok = check_include_script(LatestName1, 734 [t20,t19,t18,t17,t16,t15,t14],[t20,t19,t18,t14]), 735 736 {LatestDir2, LatestName2} = create_include_files(sort_apps_rev, Config), 737 ok = file:set_cwd(LatestDir2), 738 ok = systools:make_script(LatestName2), 739 ok = check_include_script(LatestName2, 740 [t18,t19,t20,t15,t16,t17,t14],[t18,t19,t20,t14]), 741 742 ok = file:set_cwd(OldDir), 743 ok. 744 745 746%% make_script: Check that make_script exref option works. 747exref_script(Config) when is_list(Config) -> 748 {ok, OldDir} = file:get_cwd(), 749 PSAVE = code:get_path(), % Save path 750 751 {LatestDir, LatestName} = create_script(latest,Config), 752 753 DataDir = filename:absname(?copydir), 754 LibDir = fname([DataDir, d_normal, lib]), 755 P = [fname([LibDir, 'db-2.1', ebin]), 756 fname([LibDir, 'fe-3.1', ebin])], 757 758 ok = file:set_cwd(LatestDir), 759 760 {ok, _, []} = systools:make_script(LatestName, [{path,P}, silent]), 761 762 %% Complete exref 763 {ok, _, W1} = 764 systools:make_script(LatestName, [exref, {path,P}, silent]), 765 check_exref_warnings(with_db1, W1), 766 {ok, _} = read_script_file(LatestName), % Check readabillity 767 768 %% Only exref the db application. 769 {ok, _, W2} = 770 systools:make_script(LatestName, [{exref,[db]}, {path,P}, silent]), 771 check_exref_warnings(with_db1, W2), 772 {ok, _} = read_script_file(LatestName), % Check readabillity 773 774 %% Only exref the fe application. 775 {ok, _, W3} = 776 systools:make_script(LatestName, [{exref,[fe]}, {path,P}, silent]), 777 check_exref_warnings(without_db1, W3), 778 {ok, _} = read_script_file(LatestName), % Check readabillity 779 780 %% exref the db and stdlib applications. 781 {ok, _, W4} = 782 systools:make_script(LatestName, [{exref,[db,stdlib]}, {path,P}, silent]), 783 check_exref_warnings(with_db1, W4), 784 {ok, _} = read_script_file(LatestName), % Check readabillity 785 ok = file:set_cwd(OldDir), 786 code:set_path(PSAVE), % Restore path 787 ok. 788 789check_exref_warnings(with_db1, W) -> 790 case get_exref(undef, W) of 791 {ok, [{db2,non_existing_func,0}, 792 {fe2,non_existing_func,0}, 793 {lists,non_existing_func,1}]} -> 794 ok; 795 {ok, L} -> 796 test_server:fail({exref_warning_undef, L}); 797 _E -> 798 test_server:fail({bad_undef,_E}) 799 end; 800check_exref_warnings(without_db1, W) -> 801 case get_exref(undef, W) of 802 false -> 803 ok; 804 {ok, L} -> 805 test_server:fail({exref_warning_undef, L}) 806 end. 807 808get_exref(undef, W) -> filter(no_hipe(get_exref1(exref_undef, W))). 809 810filter(false) -> 811 false; 812filter({ok, W}) -> 813 {ok, filter(W)}; 814filter(L) -> 815 lists:filter(fun%({hipe_consttab,_,_}) -> false; 816 ({int,_,_}) -> false; 817 ({i,_,_}) -> false; 818 ({crypto,_,_}) -> false; 819 (_) -> true 820 end, 821 L). 822 823get_exref1(T, [{warning, {T, Value}}|_]) -> {ok, Value}; 824get_exref1(T, [_|W]) -> get_exref1(T, W); 825get_exref1(_, []) -> false. 826 827no_hipe(false) -> 828 false; 829no_hipe({ok, Value}) -> 830 case erlang:system_info(hipe_architecture) of 831 undefined -> 832 Hipe = "hipe", 833 Fun = fun({M,_,_}) -> not lists:prefix(Hipe, atom_to_list(M)) end, 834 NewValue = lists:filter(Fun, Value), 835 {ok, NewValue}; 836 _Arch -> 837 {ok, Value} 838 end. 839 840%% duplicate_modules_script: Check that make_script rejects two 841%% applications providing the same module. 842duplicate_modules_script(Config) when is_list(Config) -> 843 {ok, OldDir} = file:get_cwd(), 844 845 {LatestDir, LatestName} = create_script(duplicate_modules,Config), 846 847 DataDir = filename:absname(?copydir), 848 849 ok = file:set_cwd(LatestDir), 850 LibDir = fname([DataDir, d_duplicate_modules, lib]), 851 P = [fname([LibDir, 'app1-1.0', ebin]), 852 fname([LibDir, 'app2-1.0', ebin])], 853 854 %% Check wrong app vsn 855 error = systools:make_script(LatestName, [{path, P}]), 856 {error, 857 systools_make, 858 {duplicate_modules, [ 859 {{myapp,app1,_}, {myapp,app2,_}} 860 ] 861 } 862 } = systools:make_script(LatestName, [silent, {path, P}]), 863 864 ok = file:set_cwd(OldDir), 865 ok. 866 867%% tar_options: Check illegal tar options. 868tar_options(Config) when is_list(Config) -> 869 {'EXIT',{{badarg,[{path,["Path",12,"Another"]}]}, _}} = 870 (catch systools:make_tar("release", [{path,["Path",12,"Another"]}])), 871 {'EXIT',{{badarg,[sillent]}, _}} = 872 (catch systools:make_tar("release", 873 [{path,["Path","Another"]},sillent])), 874 {'EXIT',{{badarg,[{dirs,["dirs"]}]}, _}} = 875 (catch systools:make_tar("release", [{dirs, ["dirs"]}])), 876 {'EXIT',{{badarg,[{erts, illegal}]}, _}} = 877 (catch systools:make_tar("release", [{erts, illegal}])), 878 {'EXIT',{{badarg,[src_testsxx]}, _}} = 879 (catch systools:make_tar("release", 880 [{path,["Path"]},src_testsxx])), 881 {'EXIT',{{badarg,[{variables, [{a, b}, {"a", "b"}]}]}, _}} = 882 (catch systools:make_tar("release", 883 [{variables, [{a, b}, {"a", "b"}]}])), 884 {'EXIT',{{badarg,[{var_tar, illegal}]}, _}} = 885 (catch systools:make_tar("release", [{var_tar, illegal}])), 886 {'EXIT',{{badarg,[exreff]}, _}} = 887 (catch systools:make_tar("release", 888 [{path,["Path","Another"]},exreff])), 889 {'EXIT',{{badarg,[{exref,["appl"]}]}, _}} = 890 (catch systools:make_tar("release", [{exref,["appl"]}])), 891 {'EXIT',{{badarg,[{machine, "appl"}]}, _}} = 892 (catch systools:make_tar("release", [{machine,"appl"}])), 893 ok. 894 895 896%% make_tar: Check case of start.boot 897normal_tar(Config) when is_list(Config) -> 898 {ok, OldDir} = file:get_cwd(), 899 900 {LatestDir, LatestName} = create_script(latest,Config), 901 902 DataDir = filename:absname(?copydir), 903 LibDir = fname([DataDir, d_normal, lib]), 904 P = [fname([LibDir, 'db-2.1', ebin]), 905 fname([LibDir, 'fe-3.1', ebin])], 906 907 ok = file:set_cwd(LatestDir), 908 909 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}, {script_name, "start"}]), 910 ok = systools:make_tar(LatestName, [{path, P}]), 911 ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), 912 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), 913 ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), 914 915 ok = file:set_cwd(OldDir), 916 ok. 917 918%% make_tar: Check case of relname.boot 919relname_tar(Config) when is_list(Config) -> 920 {ok, OldDir} = file:get_cwd(), 921 922 {LatestDir, LatestName} = create_script(latest,Config), 923 924 DataDir = filename:absname(?copydir), 925 LibDir = fname([DataDir, d_normal, lib]), 926 P = [fname([LibDir, 'db-2.1', ebin]), 927 fname([LibDir, 'fe-3.1', ebin])], 928 929 ok = file:set_cwd(LatestDir), 930 931 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}, {script_name, LatestName}]), 932 ok = systools:make_tar(LatestName, [{path, P}]), 933 ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), 934 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), 935 ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), 936 937 ok = file:set_cwd(OldDir), 938 ok. 939 940%% make_tar: Modules specified without version in .app file (db-3.1). 941%% Note that this is now the normal way - i.e. systools now ignores 942%% the module versions in the .app file. 943no_mod_vsn_tar(Config) when is_list(Config) -> 944 {ok, OldDir} = file:get_cwd(), 945 946 {LatestDir, LatestName} = create_script(latest_no_mod_vsn,Config), 947 948 DataDir = filename:absname(?copydir), 949 LibDir = fname([DataDir, d_normal, lib]), 950 P = [fname([LibDir, 'db-3.1', ebin]), 951 fname([LibDir, 'fe-3.1', ebin])], 952 953 ok = file:set_cwd(LatestDir), 954 955 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]), 956 ok = systools:make_tar(LatestName, [{path, P}]), 957 ok = check_tar(fname([lib,'db-3.1',ebin,'db.app']), LatestName), 958 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), 959 ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), 960 961 ok = file:set_cwd(OldDir), 962 ok. 963 964 965%% make_tar: Check that relup or sys.config are included if they exist 966system_files_tar(Config) -> 967 {ok, OldDir} = file:get_cwd(), 968 969 {LatestDir, LatestName} = create_script(latest,Config), 970 971 DataDir = filename:absname(?copydir), 972 LibDir = fname([DataDir, d_normal, lib]), 973 P = [fname([LibDir, 'db-2.1', ebin]), 974 fname([LibDir, 'fe-3.1', ebin])], 975 976 ok = file:set_cwd(LatestDir), 977 978 %% Add dummy relup and sys.config 979 ok = file:write_file("sys.config","[].\n"), 980 ok = file:write_file("relup","{\"LATEST\",[],[]}.\n"), 981 982 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]), 983 ok = systools:make_tar(LatestName, [{path, P}]), 984 ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 985 ok = check_tar(fname(["releases","LATEST","relup"]), LatestName), 986 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), 987 ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 988 ok = check_tar(fname(["releases","LATEST","relup"]), LatestName), 989 990 ok = file:set_cwd(OldDir), 991 992 ok. 993 994%% make_tar: Check that extra_files are included in the tarball 995additional_files_tar(Config) -> 996 {ok, OldDir} = file:get_cwd(), 997 998 {LatestDir, LatestName} = create_script(latest,Config), 999 1000 DataDir = filename:absname(?copydir), 1001 LibDir = fname([DataDir, d_normal, lib]), 1002 P = [fname([LibDir, 'db-2.1', ebin]), 1003 fname([LibDir, 'fe-3.1', ebin])], 1004 1005 ok = file:set_cwd(LatestDir), 1006 1007 %% Add dummy relup and sys.config 1008 ok = file:write_file("sys.config","[].\n"), 1009 ok = file:write_file("relup","{\"LATEST\",[],[]}.\n"), 1010 1011 %% unrelated files that must be included explicitly 1012 RandomFile = "somefile", 1013 ok = file:write_file(RandomFile,"hello\n"), 1014 1015 TopLevelDir = "some_dir", 1016 TopLevelFile = filename:join(TopLevelDir, "top_level_file"), 1017 1018 filelib:ensure_dir(TopLevelFile), 1019 ok = file:write_file(TopLevelFile, "hello there\n"), 1020 1021 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]), 1022 ok = systools:make_tar(LatestName, [{path, P}]), 1023 ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 1024 ok = check_tar(fname(["releases","LATEST","relup"]), LatestName), 1025 %% random file should not be in this tarball 1026 {error, _} = check_tar(fname(["releases","LATEST",RandomFile]), LatestName), 1027 1028 RandomFilePathInTar = filename:join(["releases", "LATEST", RandomFile]), 1029 1030 {ok, _, []} = systools:make_tar(LatestName, 1031 [{path, P}, silent, 1032 {extra_files, [{RandomFile, RandomFilePathInTar}, 1033 {TopLevelDir, TopLevelDir}]}]), 1034 ok = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 1035 ok = check_tar(fname(["releases","LATEST","relup"]), LatestName), 1036 1037 %% random file and dir should be in this tarball 1038 ok = check_tar(fname(["releases","LATEST",RandomFile]), LatestName), 1039 ok = check_tar(fname([TopLevelFile]), LatestName), 1040 1041 ok = file:set_cwd(OldDir), 1042 1043 ok. 1044 1045system_files_tar(cleanup,Config) -> 1046 Dir = ?privdir, 1047 file:delete(filename:join(Dir,"sys.config")), 1048 file:delete(filename:join(Dir,"relup")), 1049 ok. 1050 1051erts_tar(Config) -> 1052 1053 {ok, OldDir} = file:get_cwd(), 1054 1055 {LatestDir, LatestName} = create_script(current_all,Config), 1056 1057 ERTS_VSN = erlang:system_info(version), 1058 ERTS_DIR = fname(["erts-" ++ ERTS_VSN,bin]), 1059 1060 %% List of all expected executable files in erts/bin 1061 %% This list needs to be kept up to date whenever a file is 1062 %% added or removed. 1063 {Default, Ignored} = 1064 case os:type() of 1065 {unix,_} -> 1066 {["beam.smp","dyn_erl","epmd","erl","erl_call","erl_child_setup", 1067 "erlexec","erl.src","escript","heart","inet_gethost","run_erl", 1068 "start","start_erl.src","start.src","to_erl"], 1069 ["ct_run","dialyzer","erlc","typer","yielding_c_fun"]}; 1070 {win32, _} -> 1071 {["beam.smp.pdb","erl.exe", 1072 "erl.pdb","erl_log.exe","erlexec.dll","erlsrv.exe","heart.exe", 1073 "start_erl.exe","werl.exe","beam.smp.dll", 1074 "epmd.exe","erl.ini","erl_call.exe", 1075 "erlexec.pdb","escript.exe","inet_gethost.exe","werl.pdb"], 1076 ["dialyzer.exe","erlc.exe","yielding_c_fun.exe","ct_run.exe","typer.exe"]} 1077 end, 1078 1079 ErtsTarContent = 1080 fun(TarName) -> 1081 lists:sort( 1082 [filename:basename(File) 1083 || File <- tar_contents(TarName), 1084 string:equal(filename:dirname(File),ERTS_DIR), 1085 %% Filter out beam.*.smp.* 1086 re:run(filename:basename(File), "beam\\.[^\\.]+\\.smp(\\.dll)?") == nomatch, 1087 %% Filter out any erl_child_setup.* 1088 re:run(filename:basename(File), "erl_child_setup\\..*") == nomatch 1089 ]) 1090 end, 1091 1092 DataDir = filename:absname(?copydir), 1093 LibDir = fname([DataDir, d_normal, lib]), 1094 P = [fname([LibDir, 'db-2.1', ebin])], 1095 1096 ok = file:set_cwd(LatestDir), 1097 1098 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}, {script_name, "start"}]), 1099 ok = systools:make_tar(LatestName, [{path, P}, {erts, code:root_dir()}]), 1100 ErtsContent = ErtsTarContent(LatestName), 1101 1102 case lists:sort(Default) of 1103 ErtsContent -> 1104 ok; 1105 Expected -> 1106 ct:pal("Content: ~p",[ErtsContent]), 1107 ct:pal("Expected: ~p",[Expected]), 1108 ct:fail("Incorrect erts bin content") 1109 end, 1110 1111 ok = systools:make_tar(LatestName, [{path, P}, 1112 {erts, code:root_dir()}, 1113 erts_all]), 1114 ErtsAllContent = ErtsTarContent(LatestName), 1115 1116 case lists:sort(Default ++ Ignored) of 1117 ErtsAllContent -> 1118 ok; 1119 ExpectedIgn -> 1120 ct:pal("Content: ~p",[ErtsAllContent]), 1121 ct:pal("Expected: ~p",[ExpectedIgn]), 1122 ct:fail("Incorrect erts bin content") 1123 end, 1124 1125 ok = file:set_cwd(OldDir), 1126 ok. 1127 1128 1129%% make_tar: Check that sys.config.src and not sys.config is included 1130system_src_file_tar(Config) -> 1131 {ok, OldDir} = file:get_cwd(), 1132 1133 {LatestDir, LatestName} = create_script(latest,Config), 1134 1135 DataDir = filename:absname(?copydir), 1136 LibDir = fname([DataDir, d_normal, lib]), 1137 P = [fname([LibDir, 'db-2.1', ebin]), 1138 fname([LibDir, 'fe-3.1', ebin])], 1139 1140 ok = file:set_cwd(LatestDir), 1141 1142 %% Add dummy sys.config and sys.config.src 1143 ok = file:write_file("sys.config.src","[${SOMETHING}].\n"), 1144 ok = file:write_file("sys.config","[].\n"), 1145 1146 {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), 1147 ok = systools:make_tar(LatestName, [{path, P}]), 1148 ok = check_tar(fname(["releases","LATEST","sys.config.src"]), LatestName), 1149 {error, _} = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 1150 {ok, _, _} = systools:make_tar(LatestName, [{path, P}, silent]), 1151 ok = check_tar(fname(["releases","LATEST","sys.config.src"]), LatestName), 1152 {error, _} = check_tar(fname(["releases","LATEST","sys.config"]), LatestName), 1153 1154 ok = file:set_cwd(OldDir), 1155 1156 ok. 1157 1158system_src_file_tar(cleanup,Config) -> 1159 Dir = ?privdir, 1160 file:delete(filename:join(Dir,"sys.config")), 1161 file:delete(filename:join(Dir,"sys.config.src")), 1162 ok. 1163 1164%% make_tar: Check that make_tar fails if relup or sys.config exist 1165%% but do not have valid content 1166invalid_system_files_tar(Config) -> 1167 {ok, OldDir} = file:get_cwd(), 1168 1169 {LatestDir, LatestName} = create_script(latest,Config), 1170 1171 DataDir = filename:absname(?copydir), 1172 LibDir = fname([DataDir, d_normal, lib]), 1173 P = [fname([LibDir, 'db-2.1', ebin]), 1174 fname([LibDir, 'fe-3.1', ebin])], 1175 1176 ok = file:set_cwd(LatestDir), 1177 1178 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]), 1179 1180 %% Add dummy relup and sys.config - faulty sys.config 1181 ok = file:write_file("sys.config","[]\n"), %!!! syntax error - missing '.' 1182 ok = file:write_file("relup","{\"LATEST\",[],[]}.\n"), 1183 1184 error = systools:make_tar(LatestName, [{path, P}]), 1185 {error,_,{tar_error,{add,"sys.config",[{error,_}]}}} = 1186 systools:make_tar(LatestName, [{path, P}, silent]), 1187 1188 %% Add dummy relup and sys.config - faulty sys.config 1189 ok = file:write_file("sys.config","[x,y].\n"), %!!! faulty format 1190 ok = file:write_file("relup","{\"LATEST\",[],[]}.\n"), 1191 1192 error = systools:make_tar(LatestName, [{path, P}]), 1193 {error,_,{tar_error,{add,"sys.config",[invalid_format]}}} = 1194 systools:make_tar(LatestName, [{path, P}, silent]), 1195 1196 %% Add dummy relup and sys.config - faulty relup 1197 ok = file:write_file("sys.config","[]\n"), 1198 ok = file:write_file("relup","{\"LATEST\"\n"), %!!! syntax error - truncated 1199 1200 error = systools:make_tar(LatestName, [{path, P}]), 1201 {error,_,{tar_error,{add,"relup",[{error,_}]}}} = 1202 systools:make_tar(LatestName, [{path, P}, silent]), 1203 1204 %% Add dummy relup and sys.config - faulty relup 1205 ok = file:write_file("sys.config","[]\n"), 1206 ok = file:write_file("relup","[].\n"), %!!! faulty format 1207 1208 error = systools:make_tar(LatestName, [{path, P}]), 1209 {error,_,{tar_error,{add,"relup",[invalid_format]}}} = 1210 systools:make_tar(LatestName, [{path, P}, silent]), 1211 1212 ok = file:set_cwd(OldDir), 1213 1214 ok. 1215 1216invalid_system_files_tar(cleanup,Config) -> 1217 Dir = ?privdir, 1218 file:delete(filename:join(Dir,"sys.config")), 1219 file:delete(filename:join(Dir,"relup")), 1220 ok. 1221 1222 1223%% make_tar: Use variable and create separate tar (included in generated tar). 1224variable_tar(Config) when is_list(Config) -> 1225 {ok, OldDir} = file:get_cwd(), 1226 1227 {LatestDir, LatestName} = create_script(latest,Config), 1228 1229 DataDir = filename:absname(?copydir), 1230 LibDir = fname([DataDir, d_normal, lib]), 1231 P = [fname([LibDir, 'db-2.1', ebin]), 1232 fname([LibDir, 'fe-3.1', ebin])], 1233 1234 ok = file:set_cwd(LatestDir), 1235 1236 {ok, _, []} = systools:make_script(LatestName, 1237 [silent, 1238 {path, P}, 1239 {variables,[{"TEST", LibDir}]}]), 1240 1241 ok = systools:make_tar(LatestName, [{path, P}, 1242 {variables,[{"TEST", LibDir}]}]), 1243 ok = check_var_tar("TEST", LatestName), 1244 1245 {ok, _, []} = systools:make_tar(LatestName, 1246 [{path, P}, silent, 1247 {variables,[{"TEST", LibDir}]}]), 1248 ok = check_var_tar("TEST", LatestName), 1249 1250 ok = file:set_cwd(OldDir), 1251 ok. 1252 1253%% make_tar: Check that symlinks in applications are handled correctly. 1254link_tar(Config) when is_list(Config) -> 1255 {ok, OldDir} = file:get_cwd(), 1256 1257 {LatestDir, LatestName} = create_script(latest,Config), 1258 1259 DataDir = filename:absname(?copydir), 1260 LibDir = fname([DataDir, d_links, lib]), 1261 P = [fname([LibDir, 'db-2.1', ebin]), 1262 fname([LibDir, 'fe-3.1', ebin])], 1263 1264 %% Make some links 1265 Db1Erl = fname(['db-2.1',src,'db1.erl']), 1266 NormalDb1Erl = fname([DataDir,d_normal,lib,Db1Erl]), 1267 LinkDb1Erl = fname([LibDir, Db1Erl]), 1268 ok = file:make_symlink(NormalDb1Erl, LinkDb1Erl), 1269 Db1Beam = fname(['db-2.1',ebin,'db1.beam']), 1270 NormalDb1Beam = fname([DataDir,d_normal,lib,Db1Beam]), 1271 LinkDb1Beam = fname([LibDir, Db1Beam]), 1272 ok = file:make_symlink(NormalDb1Beam, LinkDb1Beam), 1273 FeApp = fname(['fe-3.1',ebin,'fe.app']), 1274 NormalFeApp = fname([DataDir,d_normal,lib,FeApp]), 1275 LinkFeApp = fname([LibDir, FeApp]), 1276 ok = file:make_symlink(NormalFeApp, LinkFeApp), 1277 1278 %% Create the tar and check that the linked files are included as 1279 %% regular files 1280 ok = file:set_cwd(LatestDir), 1281 1282 {ok,_,[]} = systools:make_script(LatestName, [{path, P},silent]), 1283 1284 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent]), 1285 ok = check_tar_regular(?privdir, 1286 [fname([lib,FeApp]), 1287 fname([lib,Db1Beam])], 1288 LatestName), 1289 1290 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, 1291 {dirs, [src]}]), 1292 ok = check_tar_regular(?privdir, 1293 [fname([lib,FeApp]), 1294 fname([lib,Db1Beam]), 1295 fname([lib,Db1Erl])], 1296 LatestName), 1297 1298 ok = file:set_cwd(OldDir), 1299 ok. 1300 1301%% make_tar: Do not check date of object file or that source code can be found. 1302src_tests_tar(Config) when is_list(Config) -> 1303 {ok, OldDir} = file:get_cwd(), 1304 1305 {LatestDir, LatestName} = create_script(latest,Config), 1306 1307 DataDir = filename:absname(?copydir), 1308 LibDir = fname([DataDir, d_missing_src, lib]), 1309 P1 = fname([LibDir, 'db-2.1', ebin]), 1310 P2 = fname([LibDir, 'fe-3.1', ebin]), 1311 P = [P1, P2], 1312 1313 ok = file:set_cwd(LatestDir), 1314 1315 %% Manipulate the modification date of a beam file so it seems 1316 %% older than the .erl file 1317 Erl = filename:join([P1,"..","src","db1.erl"]), 1318 {ok, FileInfo=#file_info{mtime={{Y,M,D},T}}} = file:read_file_info(Erl), 1319 Beam = filename:join(P1,"db1.beam"), 1320 ok = file:write_file_info(Beam, FileInfo#file_info{mtime={{Y-1,M,D},T}}), 1321 1322 %% Remove a .erl file 1323 Erl2 = filename:join([P1,"..","src","db2.erl"]), 1324 file:delete(Erl2), 1325 1326 ok = systools:make_script(LatestName, [{path, P}]), 1327 1328 %% Then make tar - two warnings should be issued when 1329 %% src_tests is given 1330 %% 1. old object code for db1.beam 1331 %% 2. missing source code for db2.beam 1332 {ok, _, [{warning,{obj_out_of_date,_}}, 1333 {warning,{source_not_found,_}}]} = 1334 systools:make_tar(LatestName, [{path, P}, silent, 1335 {dirs, [src]}, 1336 src_tests]), 1337 ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), 1338 1339 %% Without the src_tests option, no warning should be issued 1340 {ok, _, []} = systools:make_tar(LatestName, [{path, P}, silent, 1341 {dirs, [src]}]), 1342 ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), 1343 1344 %% Check that the old no_module_tests option (from the time when 1345 %% it was default to do the src_test) is ignored 1346 {ok, _, [{warning,{obj_out_of_date,_}}, 1347 {warning,{source_not_found,_}}]} = 1348 systools:make_tar(LatestName, [{path, P}, silent, 1349 {dirs, [src]}, 1350 no_module_tests, 1351 src_tests]), 1352 ok = check_tar(fname([lib,'db-2.1',src,'db1.erl']), LatestName), 1353 1354 ok = file:set_cwd(OldDir), 1355 ok. 1356 1357 1358%% make_tar: Check that make_tar handles generation and placement of 1359%% tar files for variables outside the main tar file. 1360%% Test the {var_tar, include | ownfile | omit} optio. 1361var_tar(Config) when is_list(Config) -> 1362 {ok, OldDir} = file:get_cwd(), 1363 PSAVE = code:get_path(), % Save path 1364 1365 {LatestDir, LatestName} = create_script(latest,Config), 1366 1367 DataDir = filename:absname(?copydir), 1368 LibDir = fname([DataDir, d_normal, lib]), 1369 P = [fname([LibDir, 'db-2.1', ebin]), 1370 fname([LibDir, 'fe-3.1', ebin])], 1371 1372 ok = file:set_cwd(LatestDir), 1373 1374 {ok, _, []} = systools:make_script(LatestName, 1375 [silent, 1376 {path, P}, 1377 {variables,[{"TEST", LibDir}]}]), 1378 1379 ok = systools:make_tar(LatestName, [{path, P}, 1380 {var_tar, ownfile}, 1381 {variables,[{"TEST", LibDir}]}]), 1382 1383 true = exists_tar_file("TEST"), %% Also removes the file ! 1384 {error, {not_generated, _}} = check_var_tar("TEST", LatestName), 1385 1386 ok = systools:make_tar(LatestName, [{path, P}, 1387 {var_tar, omit}, 1388 {variables,[{"TEST", LibDir}]}]), 1389 1390 {error, {not_generated, _}} = check_var_tar("TEST", LatestName), 1391 false = exists_tar_file("TEST"), 1392 1393 ok = systools:make_tar(LatestName, [{path, P}, 1394 {var_tar, include}, 1395 {variables,[{"TEST", LibDir}]}]), 1396 1397 ok = check_var_tar("TEST", LatestName), 1398 false = exists_tar_file("TEST"), 1399 1400 ok = file:set_cwd(OldDir), 1401 code:set_path(PSAVE), 1402 ok. 1403 1404 1405%% make_tar: Check exref option. 1406exref_tar(Config) when is_list(Config) -> 1407 {ok, OldDir} = file:get_cwd(), 1408 1409 {LatestDir, LatestName} = create_script(latest,Config), 1410 1411 DataDir = filename:absname(?copydir), 1412 LibDir = fname([DataDir, d_normal, lib]), 1413 P = [fname([LibDir, 'db-2.1', ebin]), 1414 fname([LibDir, 'fe-3.1', ebin])], 1415 1416 ok = file:set_cwd(LatestDir), 1417 1418 {ok, _, []} = systools:make_script(LatestName, [silent, {path, P}]), 1419 1420 %% Complete exref 1421 {ok, _, W1} = 1422 systools:make_tar(LatestName, [exref, {path, P}, silent]), 1423 check_exref_warnings(with_db1, W1), 1424 ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), 1425 1426 %% Only exref the db application. 1427 {ok, _, W2} = 1428 systools:make_tar(LatestName, [{exref, [db]}, {path, P}, silent]), 1429 check_exref_warnings(with_db1, W2), 1430 ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), 1431 1432 %% Only exref the fe application. 1433 {ok, _, W3} = 1434 systools:make_tar(LatestName, [{exref, [fe]}, {path, P}, silent]), 1435 check_exref_warnings(without_db1, W3), 1436 ok = check_tar(fname([lib,'db-2.1',ebin,'db.app']), LatestName), 1437 1438 %% exref the db and stdlib applications. 1439 {ok, _, W4} = 1440 systools:make_tar(LatestName, [{exref, [db, stdlib]}, 1441 {path, P}, silent]), 1442 check_exref_warnings(with_db1, W4), 1443 ok = check_tar(fname([lib,'fe-3.1',ebin,'fe.app']), LatestName), 1444 1445 ok = file:set_cwd(OldDir), 1446 ok. 1447 1448%% make_tar: Create tar without sasl appl. Check warning. 1449no_sasl_tar(Config) when is_list(Config) -> 1450 {ok, OldDir} = file:get_cwd(), 1451 1452 {LatestDir, LatestName} = create_script(latest1_no_sasl,Config), 1453 1454 DataDir = filename:absname(?copydir), 1455 LibDir = fname([DataDir, d_normal, lib]), 1456 P = [fname([LibDir, '*', ebin]), 1457 fname([DataDir, lib, kernel, ebin]), 1458 fname([DataDir, lib, stdlib, ebin]), 1459 fname([DataDir, lib, sasl, ebin])], 1460 1461 ok = file:set_cwd(LatestDir), 1462 1463 {ok, _, _} = systools:make_script(LatestName, [silent, {path, P}]), 1464 ok = systools:make_tar(LatestName, [{path, P}]), 1465 {ok, _, [{warning,missing_sasl}]} = 1466 systools:make_tar(LatestName, [{path, P}, silent]), 1467 {ok, _, []} = 1468 systools:make_tar(LatestName, [{path, P}, silent, no_warn_sasl]), 1469 {ok, _, []} = 1470 systools:make_tar(LatestName, [{path, P}, silent, no_warn_sasl, 1471 warnings_as_errors]), 1472 TarFile = LatestName ++ ".tar.gz", 1473 true = filelib:is_regular(TarFile), 1474 ok = file:delete(TarFile), 1475 {error, systools_make, {warnings_treated_as_errors,[missing_sasl]}} = 1476 systools:make_tar(LatestName, [{path, P}, silent, warnings_as_errors]), 1477 error = 1478 systools:make_tar(LatestName, [{path, P}, warnings_as_errors]), 1479 false = filelib:is_regular(TarFile), 1480 1481 ok = file:set_cwd(OldDir), 1482 ok. 1483 1484%% make_tar: OTP-9507 - make_tar failed when path given as just 'ebin'. 1485otp_9507_path_ebin(Config) when is_list(Config) -> 1486 {ok, OldDir} = file:get_cwd(), 1487 1488 {LatestDir, LatestName} = create_script(latest_small,Config), 1489 1490 DataDir = filename:absname(?copydir), 1491 LibDir = fname([DataDir, d_normal, lib]), 1492 FeDir = fname([LibDir, 'fe-3.1']), 1493 1494 ok = file:set_cwd(FeDir), 1495 1496 RelName = fname([LatestDir,LatestName]), 1497 1498 P1 = ["./ebin", 1499 fname([DataDir, lib, kernel, ebin]), 1500 fname([DataDir, lib, stdlib, ebin]), 1501 fname([DataDir, lib, sasl, ebin])], 1502 {ok, _, []} = systools:make_script(RelName, [silent, {path, P1}]), 1503 ok = systools:make_tar(RelName, [{path, P1}]), 1504 Content1 = tar_contents(RelName), 1505 1506 P2 = ["ebin", 1507 fname([DataDir, lib, kernel, ebin]), 1508 fname([DataDir, lib, stdlib, ebin]), 1509 fname([DataDir, lib, sasl, ebin])], 1510 1511 %% Tickets solves the following line - it used to fail with 1512 %% {function_clause,[{filename,join,[[]]},...} 1513 ok = systools:make_tar(RelName, [{path, P2}]), 1514 Content2 = tar_contents(RelName), 1515 true = (Content1 == Content2), 1516 1517 ok = file:set_cwd(OldDir), 1518 1519 ok. 1520 1521 1522%% make_relup: Check normal case 1523normal_relup(Config) when is_list(Config) -> 1524 {ok, OldDir} = file:get_cwd(), 1525 1526 {LatestDir,LatestName} = create_script(latest0,Config), 1527 {_LatestDir1,LatestName1} = create_script(latest1,Config), 1528 {_LatestDir2,LatestName2} = create_script(latest2,Config), 1529 1530 DataDir = filename:absname(?copydir), 1531 LibDir = [fname([DataDir, d_normal, lib])], 1532 P = [fname([LibDir, '*', ebin]), 1533 fname([DataDir, lib, kernel, ebin]), 1534 fname([DataDir, lib, stdlib, ebin]), 1535 fname([DataDir, lib, sasl, ebin])], 1536 1537 ok = file:set_cwd(LatestDir), 1538 1539 %% This is the ultra normal case 1540 ok = systools:make_relup(LatestName, [LatestName1], [LatestName1], 1541 [{path, P}]), 1542 ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), 1543 {ok, Relup, _, []} = 1544 systools:make_relup(LatestName, [LatestName1], [LatestName1], 1545 [{path, P}, silent]), 1546 ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), 1547 1548 %% file should not be written if warnings_as_errors is enabled. 1549 %% delete before running tests. 1550 ok = file:delete("relup"), 1551 1552 %% Check that warnings are treated as errors 1553 error = 1554 systools:make_relup(LatestName, [LatestName2], [LatestName1], 1555 [{path, P}, warnings_as_errors]), 1556 {error, systools_relup, 1557 {warnings_treated_as_errors,[pre_R15_emulator_upgrade, 1558 {erts_vsn_changed, _}]}} = 1559 systools:make_relup(LatestName, [LatestName2], [LatestName1], 1560 [{path, P}, silent, warnings_as_errors]), 1561 1562 %% relup file should not exist 1563 false = filelib:is_regular("relup"), 1564 1565 %% Check that warnings get through 1566 ok = systools:make_relup(LatestName, [LatestName2], [LatestName1], 1567 [{path, P}]), 1568 ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), 1569 {ok, _, _, [pre_R15_emulator_upgrade,{erts_vsn_changed, _}]} = 1570 systools:make_relup(LatestName, [LatestName2], [LatestName1], 1571 [{path, P}, silent]), 1572 ok = check_relup([{fe, "3.1"}, {db, "2.1"}], [{db, "1.0"}]), 1573 1574 %% relup file should exist now 1575 true = filelib:is_regular("relup"), 1576 1577 %% file should not be written if noexec option is used. 1578 %% delete before running tests. 1579 ok = file:delete("relup"), 1580 {ok,Relup,_,[]} = 1581 systools:make_relup(LatestName, [LatestName1], [LatestName1], 1582 [{path, P}, noexec]), 1583 false = filelib:is_regular("relup"), 1584 1585 ok = file:set_cwd(OldDir), 1586 ok. 1587 1588 1589%% make_relup: Test relup which includes emulator restart. 1590restart_relup(Config) when is_list(Config) -> 1591 {ok, OldDir} = file:get_cwd(), 1592 1593 {LatestDir,LatestName} = create_script(latest0,Config), 1594 {_LatestDir1,LatestName1} = create_script(latest1,Config), 1595 {_LatestDir0CurrErts,LatestName0CurrErts} = 1596 create_script(latest0_current_erts,Config), 1597 {_CurrentAllDir,CurrentAllName} = create_script(current_all,Config), 1598 {_CurrentAllFutErtsDir,CurrentAllFutErtsName} = 1599 create_script(current_all_future_erts,Config), 1600 {_CurrentAllFutSaslDir,CurrentAllFutSaslName} = 1601 create_script(current_all_future_sasl,Config), 1602 1603 DataDir = filename:absname(?copydir), 1604 LibDir = [fname([DataDir, d_normal, lib])], 1605 P = [fname([LibDir, '*', ebin]), 1606 fname([DataDir, lib, kernel, ebin]), 1607 fname([DataDir, lib, stdlib, ebin]), 1608 fname([DataDir, lib, sasl, ebin]), 1609 fname([DataDir, lib, 'sasl-9.9', ebin])], 1610 1611 ok = file:set_cwd(LatestDir), 1612 1613 %% OTP-2561: Check that the option 'restart_emulator' generates a 1614 %% "restart_emulator" instruction. 1615 {ok, _ , _, []} = 1616 systools:make_relup(LatestName, [LatestName1], [LatestName1], 1617 [{path, P},restart_emulator,silent]), 1618 ok = check_relup([{db, "2.1"}], [{db, "1.0"}]), 1619 ok = check_restart_emulator(), 1620 1621 1622 %% Pre-R15 to Post-R15 upgrade 1623 {ok, _ , _, Ws} = 1624 systools:make_relup(LatestName0CurrErts, 1625 [LatestName1], 1626 [LatestName1], 1627 [{path, P},silent]), 1628 ok = check_relup([{db,"2.1"}], [{db, "1.0"}]), 1629 ok = check_pre_to_post_r15_restart_emulator(), 1630 ok = check_pre_to_post_r15_warnings(Ws), 1631 1632 1633 %% Check that new sasl version generates a restart_new_emulator 1634 %% instruction 1635 {ok, _ , _, []} = 1636 systools:make_relup(CurrentAllFutSaslName, 1637 [CurrentAllName], 1638 [CurrentAllName], 1639 [{path, P},silent]), 1640 ok = check_relup([{fe, "3.1"}], []), 1641 ok = check_restart_emulator_diff_coreapp(), 1642 1643 1644 %% Check that new erts version generates a restart_new_emulator 1645 %% instruction, if FromSaslVsn >= R15SaslVsn 1646 %% (One erts_vsn_changed warning for upgrade and one for downgrade) 1647 {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} = 1648 systools:make_relup(CurrentAllFutErtsName, 1649 [CurrentAllName], 1650 [CurrentAllName], 1651 [{path, P},silent]), 1652 ok = check_relup([{fe, "3.1"}], []), 1653 ok = check_restart_emulator_diff_coreapp(), 1654 1655 1656 %% Check that new erts version generates a restart_new_emulator 1657 %% instruction, and can be combined with restart_emulator opt. 1658 %% (One erts_vsn_changed warning for upgrade and one for downgrade) 1659 {ok, _ , _, [{erts_vsn_changed,_},{erts_vsn_changed,_}]} = 1660 systools:make_relup(CurrentAllFutErtsName, 1661 [CurrentAllName], 1662 [CurrentAllName], 1663 [{path, P},restart_emulator,silent]), 1664 ok = check_relup([{fe, "3.1"}], []), 1665 ok = check_restart_emulator(), 1666 ok = check_restart_emulator_diff_coreapp(), 1667 1668 ok = file:set_cwd(OldDir), 1669 ok. 1670 1671 1672%% This test fails if wrong version numbers are seen in the relup file 1673%% or if any application is missing. This was triggered by OTP-1360. 1674check_relup(UpVsnL, DnVsnL) -> 1675 {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), 1676 [] = foldl(fun(X, Acc) -> 1677 true = lists:member(X, Acc), 1678 lists:delete(X, Acc) end, 1679 UpVsnL, 1680 [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Up]), 1681 [] = foldl(fun(X, Acc) -> 1682 true = lists:member(X, Acc), 1683 lists:delete(X, Acc) end, 1684 DnVsnL, 1685 [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Dn]), 1686 ok. 1687 1688check_relup_up_only(UpVsnL) -> 1689 {ok, [{_V1, [{_, _, Up}], []}]} = file:consult(relup), 1690 [] = foldl(fun(X, Acc) -> 1691 true = lists:member(X, Acc), 1692 lists:delete(X, Acc) end, 1693 UpVsnL, 1694 [{App, Vsn} || {load_object_code,{App,Vsn,_}} <- Up]), 1695 ok. 1696 1697check_restart_emulator() -> 1698 {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), 1699 restart_emulator = lists:last(Up), 1700 restart_emulator = lists:last(Dn), 1701 ok. 1702 1703check_restart_emulator_up_only() -> 1704 {ok, [{_V1, [{_, _, Up}], []}]} = file:consult(relup), 1705 restart_emulator = lists:last(Up), 1706 ok. 1707 1708check_restart_emulator_diff_coreapp() -> 1709 {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), 1710 [restart_new_emulator|_] = Up, 1711 restart_emulator = lists:last(Dn), 1712 ok. 1713 1714check_pre_to_post_r15_restart_emulator() -> 1715 {ok, [{_V1, [{_, _, Up}], [{_, _, Dn}]}]} = file:consult(relup), 1716 restart_new_emulator = lists:last(Up), 1717 restart_emulator = lists:last(Dn), 1718 ok. 1719 1720check_pre_to_post_r15_warnings(Ws) -> 1721 true = lists:member(pre_R15_emulator_upgrade,Ws), 1722 ok. 1723 1724%% make_relup: Check that appup files may be missing, but only if we 1725%% don't need them. 1726no_appup_relup(Config) when is_list(Config) -> 1727 {ok, OldDir} = file:get_cwd(), 1728 1729 {LatestDir,LatestName} = create_script(latest_small,Config), 1730 {_LatestDir0,LatestName0} = create_script(latest_small0,Config), 1731 {_LatestDir1,LatestName1} = create_script(latest_small1,Config), 1732 1733 DataDir = filename:absname(?copydir), 1734 1735 ok = file:set_cwd(LatestDir), 1736 1737 %% Check that appup might be missing 1738 P1 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), 1739 fname([DataDir, lib, kernel, ebin]), 1740 fname([DataDir, lib, stdlib, ebin]), 1741 fname([DataDir, lib, sasl, ebin])], 1742 ok = 1743 systools:make_relup(LatestName, [LatestName], [], [{path, P1}]), 1744 {ok,_, _, []} = 1745 systools:make_relup(LatestName, [LatestName], [], 1746 [silent, {path, P1}]), 1747 1748 %% Check that appup might NOT be missing when we need it 1749 P2 = [fname([DataDir, d_no_appup, lib, 'fe-3.1', ebin]), 1750 fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), 1751 fname([DataDir, lib, kernel, ebin]), 1752 fname([DataDir, lib, stdlib, ebin]), 1753 fname([DataDir, lib, sasl, ebin])], 1754 error = 1755 systools:make_relup(LatestName, [LatestName0], [], [{path, P2}]), 1756 {error,_,{file_problem, {_,{error,{open,_,_}}}}} = 1757 systools:make_relup(LatestName, [], [LatestName0], 1758 [silent, {path, P2}]), 1759 1760 %% Check that appups missing vsn traps 1761 P3 = [fname([DataDir, d_no_appup, lib, 'fe-2.1', ebin]), 1762 fname([DataDir, d_no_appup, lib, 'fe-500.18.7', ebin]), 1763 fname([DataDir, lib, kernel, ebin]), 1764 fname([DataDir, lib, stdlib, ebin]), 1765 fname([DataDir, lib, sasl, ebin])], 1766 1767 error = 1768 systools:make_relup(LatestName0, [LatestName1], [], [{path, P3}]), 1769 {error,_,{no_relup, _, _, _}} = 1770 systools:make_relup(LatestName0, [], [LatestName1], 1771 [silent, {path, P3}]), 1772 1773 ok = file:set_cwd(OldDir), 1774 ok. 1775 1776%% make_relup: Check that badly written appup files are detected. 1777bad_appup_relup(Config) when is_list(Config) -> 1778 {ok, OldDir} = file:get_cwd(), 1779 1780 {LatestDir,LatestName} = create_script(latest_small,Config), 1781 {_LatestDir0,LatestName0} = create_script(latest_small0,Config), 1782 1783 DataDir = filename:absname(?copydir), 1784 N2 = [fname([DataDir, d_bad_appup, lib, 'fe-3.1', ebin]), 1785 fname([DataDir, d_bad_appup, lib, 'fe-2.1', ebin]), 1786 fname([DataDir, lib, kernel, ebin]), 1787 fname([DataDir, lib, stdlib, ebin]), 1788 fname([DataDir, lib, sasl, ebin])], 1789 1790 ok = file:set_cwd(LatestDir), 1791 1792 %% Check that bad appup is trapped 1793 error = 1794 systools:make_relup(LatestName, [LatestName0], [], [{path, N2}]), 1795 {error,_,{file_problem, {_, {error, {parse,_, _}}}}} = 1796 systools:make_relup(LatestName, [], [LatestName0], 1797 [silent, {path, N2}]), 1798 1799 ok = file:set_cwd(OldDir), 1800 ok. 1801 1802%% make_relup: Check some abnormal cases. 1803abnormal_relup(Config) when is_list(Config) -> 1804 {ok, OldDir} = file:get_cwd(), 1805 1806 {LatestDir,LatestName} = create_script(latest0,Config), 1807 {_LatestDir1,LatestName1} = create_script(latest1,Config), 1808 1809 %% Check wrong app vsn 1810 DataDir = filename:absname(?copydir), 1811 P = [fname([DataDir, d_bad_app_vsn, lib, 'db-2.1', ebin]), 1812 fname([DataDir, d_bad_app_vsn, lib, 'fe-3.1', ebin]), 1813 fname([DataDir, lib, kernel, ebin]), 1814 fname([DataDir, lib, stdlib, ebin]), 1815 fname([DataDir, lib, sasl, ebin])], 1816 1817 ok = file:set_cwd(LatestDir), 1818 1819 error = systools:make_relup(LatestName, [LatestName1], [LatestName1], 1820 [{path, P}]), 1821 R0 = systools:make_relup(LatestName, [LatestName1], [LatestName1], 1822 [silent, {path, P}]), 1823 {error,systools_make, 1824 [{error_reading,{db,{no_valid_version, 1825 {{"should be","2.1"}, 1826 {"found file", _, "2.0"}}}}}]} = R0, 1827 ok = file:set_cwd(OldDir), 1828 ok. 1829 1830 1831%% make_relup: Check relup cannot be created is sasl is not in rel file. 1832no_sasl_relup(Config) when is_list(Config) -> 1833 {ok, OldDir} = file:get_cwd(), 1834 {Dir1,Name1} = create_script(latest1_no_sasl,Config), 1835 {_Dir2,Name2} = create_script(latest1,Config), 1836 1837 DataDir = filename:absname(?copydir), 1838 LibDir = [fname([DataDir, d_normal, lib])], 1839 P = [fname([LibDir, '*', ebin]), 1840 fname([DataDir, lib, kernel, ebin]), 1841 fname([DataDir, lib, stdlib, ebin]), 1842 fname([DataDir, lib, sasl, ebin])], 1843 1844 ok = file:set_cwd(Dir1), 1845 1846 error = systools:make_relup(Name2, [Name1], [Name1], [{path, P}]), 1847 R1 = systools:make_relup(Name2, [Name1], [Name1],[silent, {path, P}]), 1848 {error,systools_relup,{missing_sasl,_}} = R1, 1849 1850 error = systools:make_relup(Name1, [Name2], [Name2], [{path, P}]), 1851 R2 = systools:make_relup(Name1, [Name2], [Name2],[silent, {path, P}]), 1852 {error,systools_relup,{missing_sasl,_}} = R2, 1853 1854 ok = file:set_cwd(OldDir), 1855 ok. 1856 1857 1858%% make_relup: Check that application start type is used in relup 1859app_start_type_relup(Config) when is_list(Config) -> 1860 %% This might fail if some applications are not available, if so 1861 %% skip the test case. 1862 try create_script(latest_app_start_type2,Config) of 1863 {Dir2,Name2} -> 1864 app_start_type_relup(Dir2,Name2,Config) 1865 catch throw:{error,Reason} -> 1866 {skip,Reason} 1867 end. 1868 1869app_start_type_relup(Dir2,Name2,Config) -> 1870 PrivDir = ?config(priv_dir, Config), 1871 {Dir1,Name1} = create_script(latest_app_start_type1,Config), 1872 1873 Release1 = filename:join(Dir1,Name1), 1874 Release2 = filename:join(Dir2,Name2), 1875 1876 {ok, Release2Relup, systools_relup, []} = systools:make_relup(Release2, [Release1], [Release1], [{outdir, PrivDir}, silent]), 1877 {"LATEST_APP_START_TYPE2", 1878 [{"LATEST_APP_START_TYPE1",[], UpInstructions}], 1879 [{"LATEST_APP_START_TYPE1",[], DownInstructions}]} = Release2Relup, 1880 %% ?t:format("Up: ~p",[UpInstructions]), 1881 %% ?t:format("Dn: ~p",[DownInstructions]), 1882 [{load_object_code, {mnesia, _, _}}, 1883 {load_object_code, {runtime_tools, _, _}}, 1884 {load_object_code, {snmp, _, _}}, 1885 {load_object_code, {xmerl, _, _}}, 1886 point_of_no_return 1887 | UpInstructionsT] = UpInstructions, 1888 true = lists:member({apply,{application,start,[mnesia,permanent]}}, UpInstructionsT), 1889 true = lists:member({apply,{application,start,[runtime_tools,transient]}}, UpInstructionsT), 1890 true = lists:member({apply,{application,load,[snmp]}}, UpInstructionsT), 1891 false = lists:any(fun({apply,{application,_,[xmerl|_]}}) -> true; (_) -> false end, UpInstructionsT), 1892 [point_of_no_return | DownInstructionsT] = DownInstructions, 1893 true = lists:member({apply,{application,stop,[mnesia]}}, DownInstructionsT), 1894 true = lists:member({apply,{application,stop,[runtime_tools]}}, DownInstructionsT), 1895 true = lists:member({apply,{application,stop,[snmp]}}, DownInstructionsT), 1896 true = lists:member({apply,{application,stop,[xmerl]}}, DownInstructionsT), 1897 true = lists:member({apply,{application,unload,[mnesia]}}, DownInstructionsT), 1898 true = lists:member({apply,{application,unload,[runtime_tools]}}, DownInstructionsT), 1899 true = lists:member({apply,{application,unload,[snmp]}}, DownInstructionsT), 1900 true = lists:member({apply,{application,unload,[xmerl]}}, DownInstructionsT), 1901 ok. 1902 1903 1904%% make_relup: Check that regexp can be used in .appup for UpFromVsn 1905%% and DownToVsn. 1906regexp_relup(Config) -> 1907 {ok, OldDir} = file:get_cwd(), 1908 1909 {LatestDir,LatestName} = create_script(latest_small,Config), 1910 {_LatestDir0,LatestName0} = create_script(latest_small0,Config), 1911 {_LatestDir1,LatestName1} = create_script(latest_small2,Config), 1912 1913 DataDir = filename:absname(?copydir), 1914 P = [fname([DataDir, d_regexp_appup, lib, '*', ebin]), 1915 fname([DataDir, lib, kernel, ebin]), 1916 fname([DataDir, lib, stdlib, ebin]), 1917 fname([DataDir, lib, sasl, ebin])], 1918 1919 ok = file:set_cwd(LatestDir), 1920 1921 %% Upgrade fe 2.1 -> 3.1, and downgrade 2.1 -> 3.1 1922 %% Shall match the first entry if fe-3.1 appup. 1923 {ok, _, _, []} = 1924 systools:make_relup(LatestName, [LatestName0], [LatestName0], 1925 [{path, P}, silent]), 1926 ok = check_relup([{fe, "3.1"}], [{fe, "2.1"}]), 1927 1928 %% Upgrade fe 2.1.1 -> 3.1 1929 %% Shall match the second entry in fe-3.1 appup. Have added a 1930 %% restart_emulator instruction there to distinguish it from 1931 %% the first entry... 1932 {ok, _, _, []} = 1933 systools:make_relup(LatestName, [LatestName1], [], [{path, P}, silent]), 1934 ok = check_relup_up_only([{fe, "3.1"}]), 1935 ok = check_restart_emulator_up_only(), 1936 1937 %% Attempt downgrade fe 3.1 -> 2.1.1 1938 %% Shall not match any entry!! 1939 {error,systools_relup,{no_relup,_,_,_}} = 1940 systools:make_relup(LatestName, [], [LatestName1], [{path, P}, silent]), 1941 1942 ok = file:set_cwd(OldDir), 1943 1944 ok. 1945 1946%% make_relup: Replace an application dependency with another 1947%% The key part here is that the new application should be 1948%% started before the old one is stopped. 1949replace_app_relup(Config) when is_list(Config) -> 1950 {ok, OldDir} = file:get_cwd(), 1951 1952 {LatestDir,LatestName} = create_script(replace_app0,Config), 1953 {_LatestDir1,LatestName1} = create_script(replace_app1,Config), 1954 1955 DataDir = filename:absname(?copydir), 1956 LibDir = [fname([DataDir, d_replace_app, lib])], 1957 P = [fname([LibDir, '*', ebin]), 1958 fname([DataDir, lib, kernel, ebin]), 1959 fname([DataDir, lib, stdlib, ebin]), 1960 fname([DataDir, lib, sasl, ebin])], 1961 1962 ok = file:set_cwd(LatestDir), 1963 1964 ok = systools:make_relup(LatestName, [LatestName1], [LatestName1], 1965 [{path, P}]), 1966 1967 check_start_stop_order([{start,gh},{stop,fe}], [{start,fe},{stop,gh}]), 1968 1969 ok = file:set_cwd(OldDir), 1970 ok. 1971 1972 1973check_start_stop_order(UpOrder, DownOrder) -> 1974 1975 {ok, [{_V0, [{_V1, [], Up}], 1976 [{_V1, [], Down}] 1977 }]} = file:consult(relup), 1978 1979 GetAppStartStop = fun(Instr) -> 1980 [{Action,App} || {apply,{application,Action,[App|_]}} <- Instr, 1981 lists:member(Action,[start,stop])] 1982 end, 1983 1984 case GetAppStartStop(Up) of 1985 UpOrder -> ok; 1986 ActualUpOrder -> 1987 ct:fail("Incorrect upgrade order.~nExpected: ~p~nGot:~p", 1988 [UpOrder,ActualUpOrder]) 1989 end, 1990 1991 case GetAppStartStop(Down) of 1992 DownOrder -> ok; 1993 ActualDownOrder -> 1994 ct:fail("Incorrect down order.~nExpected: ~p~nGot:~p", 1995 [DownOrder,ActualDownOrder]) 1996 end, 1997 1998 ok. 1999 2000%% make_hybrid_boot: Normal case. 2001%% For upgrade of erts - create a boot file which is a hybrid between 2002%% old and new release - i.e. starts erts, kernel, stdlib, sasl from 2003%% new release, all other apps from old release. 2004normal_hybrid(Config) -> 2005 {ok, OldDir} = file:get_cwd(), 2006 {Dir1,Name1} = create_script(latest1,Config), 2007 {_Dir2,Name2} = create_script(current_all,Config), 2008 2009 DataDir = filename:absname(?copydir), 2010 LibDir = [fname([DataDir, d_normal, lib])], 2011 P = [fname([LibDir, '*', ebin]), 2012 fname([DataDir, lib, kernel, ebin]), 2013 fname([DataDir, lib, stdlib, ebin]), 2014 fname([DataDir, lib, sasl, ebin])], 2015 2016 ok = file:set_cwd(Dir1), 2017 2018 {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]), 2019 {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]), 2020 {ok,Boot1} = file:read_file(Name1 ++ ".boot"), 2021 {ok,Boot2} = file:read_file(Name2 ++ ".boot"), 2022 2023 ok = file:set_cwd(OldDir), 2024 2025 {ok,Hybrid} = systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2, 2026 [dummy,args]), 2027 2028 {script,{"Test release","tmp_vsn"},Script} = binary_to_term(Hybrid), 2029 ct:log("~p.~n",[Script]), 2030 2031 %% Check that all paths to base apps are replaced by paths from BaseLib 2032 Boot1Str = io_lib:format("~p~n",[binary_to_term(Boot1)]), 2033 Boot2Str = io_lib:format("~p~n",[binary_to_term(Boot2)]), 2034 HybridStr = io_lib:format("~p~n",[binary_to_term(Hybrid)]), 2035 ReOpts = [global,{capture,first,list},unicode], 2036 {match,OldKernelMatch} = re:run(Boot1Str,"kernel-[0-9\.]+",ReOpts), 2037 {match,OldStdlibMatch} = re:run(Boot1Str,"stdlib-[0-9\.]+",ReOpts), 2038 {match,OldSaslMatch} = re:run(Boot1Str,"sasl-[0-9\.]+",ReOpts), 2039 2040 {match,NewKernelMatch} = re:run(Boot2Str,"kernel-[0-9\.]+",ReOpts), 2041 {match,NewStdlibMatch} = re:run(Boot2Str,"stdlib-[0-9\.]+",ReOpts), 2042 {match,NewSaslMatch} = re:run(Boot2Str,"sasl-[0-9\.]+",ReOpts), 2043 2044 {match,NewKernelMatch} = re:run(HybridStr,"kernel-[0-9\.]+",ReOpts), 2045 {match,NewStdlibMatch} = re:run(HybridStr,"stdlib-[0-9\.]+",ReOpts), 2046 {match,NewSaslMatch} = re:run(HybridStr,"sasl-[0-9\.]+",ReOpts), 2047 2048 NewKernelN = length(NewKernelMatch), 2049 NewKernelN = length(OldKernelMatch), 2050 NewStdlibN = length(NewStdlibMatch), 2051 NewStdlibN = length(OldStdlibMatch), 2052 NewSaslN = length(NewSaslMatch), 2053 NewSaslN = length(OldSaslMatch), 2054 2055 %% Check that kernelProcesses are taken from new boot script 2056 {script,_,Script2} = binary_to_term(Boot2), 2057 NewKernelProcs = [KP || KP={kernelProcess,_,_} <- Script2], 2058 NewKernelProcs = [KP || KP={kernelProcess,_,_} <- Script], 2059 2060 %% Check that application load instruction has correct versions 2061 Apps = application:loaded_applications(), 2062 {_,_,KernelVsn} = lists:keyfind(kernel,1,Apps), 2063 {_,_,StdlibVsn} = lists:keyfind(stdlib,1,Apps), 2064 {_,_,SaslVsn} = lists:keyfind(sasl,1,Apps), 2065 2066 [KernelInfo] = [I || {kernelProcess,application_controller, 2067 {application_controller,start, 2068 [{application,kernel,I}]}} <- Script], 2069 [StdlibInfo] = [I || {apply, 2070 {application,load, 2071 [{application,stdlib,I}]}} <- Script], 2072 [SaslInfo] = [I || {apply, 2073 {application,load, 2074 [{application,sasl,I}]}} <- Script], 2075 2076 {vsn,KernelVsn} = lists:keyfind(vsn,1,KernelInfo), 2077 {vsn,StdlibVsn} = lists:keyfind(vsn,1,StdlibInfo), 2078 {vsn,SaslVsn} = lists:keyfind(vsn,1,SaslInfo), 2079 2080 %% Check that new_emulator_upgrade call is added 2081 [_,{apply,{release_handler,new_emulator_upgrade,[dummy,args]}}|_] = 2082 lists:reverse(Script), 2083 2084 %% Check that db-1.0 and fe-3.1 are used (i.e. vsns from old release) 2085 %% And that fe is in there (it exists in old rel but not in new) 2086 {match,DbMatch} = re:run(HybridStr,"db-[0-9\.]+",ReOpts), 2087 {match,[_|_]=FeMatch} = re:run(HybridStr,"fe-[0-9\.]+",ReOpts), 2088 true = lists:all(fun(["db-1.0"]) -> true; 2089 (_) -> false 2090 end, 2091 DbMatch), 2092 true = lists:all(fun(["fe-3.1"]) -> true; 2093 (_) -> false 2094 end, 2095 FeMatch), 2096 2097 %% Check that script has same length as old script, plus one (the 2098 %% new_emulator_upgrade apply) 2099 {_,_,Old} = binary_to_term(Boot1), 2100 OldLength = length(Old), 2101 NewLength = length(Script), 2102 NewLength = OldLength + 1, 2103 2104 ok. 2105 2106%% make_hybrid_boot: No sasl in from-release. 2107%% Check that systools_make:make_hybrid_boot fails with a meaningful 2108%% error message if the FromBoot does not include the sasl 2109%% application. 2110hybrid_no_old_sasl(Config) -> 2111 {ok, OldDir} = file:get_cwd(), 2112 {Dir1,Name1} = create_script(latest1_no_sasl,Config), 2113 {_Dir2,Name2} = create_script(current_all,Config), 2114 2115 DataDir = filename:absname(?copydir), 2116 LibDir = [fname([DataDir, d_normal, lib])], 2117 P = [fname([LibDir, '*', ebin]), 2118 fname([DataDir, lib, kernel, ebin]), 2119 fname([DataDir, lib, stdlib, ebin]), 2120 fname([DataDir, lib, sasl, ebin])], 2121 2122 ok = file:set_cwd(Dir1), 2123 2124 {ok, _ , [{warning,missing_sasl}]} = 2125 systools:make_script(Name1,[{path, P},silent]), 2126 {ok, _ , []} = systools:make_script(Name2,[{path, P},silent]), 2127 {ok,Boot1} = file:read_file(Name1 ++ ".boot"), 2128 {ok,Boot2} = file:read_file(Name2 ++ ".boot"), 2129 2130 {error,{app_not_replaced,sasl}} = 2131 systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2,[dummy,args]), 2132 2133 ok = file:set_cwd(OldDir), 2134 ok. 2135 2136 2137%% make_hybrid_boot: No sasl in to-release. 2138%% Check that systools_make:make_hybrid_boot fails with a meaningful 2139%% error message if the ToBoot does not include the sasl 2140%% application. 2141hybrid_no_new_sasl(Config) -> 2142 {ok, OldDir} = file:get_cwd(), 2143 {Dir1,Name1} = create_script(latest1,Config), 2144 {_Dir2,Name2} = create_script(current_all_no_sasl,Config), 2145 2146 DataDir = filename:absname(?copydir), 2147 LibDir = [fname([DataDir, d_normal, lib])], 2148 P = [fname([LibDir, '*', ebin]), 2149 fname([DataDir, lib, kernel, ebin]), 2150 fname([DataDir, lib, stdlib, ebin]), 2151 fname([DataDir, lib, sasl, ebin])], 2152 2153 ok = file:set_cwd(Dir1), 2154 2155 {ok, _ , []} = systools:make_script(Name1,[{path, P},silent]), 2156 {ok, _ , [{warning,missing_sasl}]} = 2157 systools:make_script(Name2,[{path, P},silent]), 2158 {ok,Boot1} = file:read_file(Name1 ++ ".boot"), 2159 {ok,Boot2} = file:read_file(Name2 ++ ".boot"), 2160 2161 {error,{app_not_found,sasl}} = 2162 systools_make:make_hybrid_boot("tmp_vsn",Boot1,Boot2,[dummy,args]), 2163 2164 ok = file:set_cwd(OldDir), 2165 ok. 2166 2167 2168 2169%% options: {outdir,Dir} option 2170otp_6226_outdir(Config) when is_list(Config) -> 2171 PrivDir = ?privdir, 2172 {ok, OldDir} = file:get_cwd(), 2173 2174 {LatestDir, LatestName} = create_script(latest0,Config), 2175 {_LatestDir, LatestName1} = create_script(latest1,Config), 2176 2177 DataDir = filename:absname(?copydir), 2178 LibDir = fname([DataDir, d_normal, lib]), 2179 P = [fname([LibDir, 'db-2.1', ebin]), 2180 fname([LibDir, 'db-1.0', ebin]), 2181 fname([LibDir, 'fe-3.1', ebin]), 2182 fname([DataDir, lib, kernel, ebin]), 2183 fname([DataDir, lib, stdlib, ebin]), 2184 fname([DataDir, lib, sasl, ebin])], 2185 2186 ok = file:set_cwd(LatestDir), 2187 2188 2189 %% Create an outdir1 directory 2190 ok = file:make_dir("outdir1"), 2191 2192 %% ==== Now test systools:make_script ==== 2193 %% a) badarg 2194 {'EXIT', {{badarg,[{outdir,outdir1}]}, _}} = 2195 (catch systools:make_script(LatestName, [{outdir,outdir1}, 2196 {path,P},silent])), 2197 2198 %% b) absolute path 2199 Outdir1 = filename:join(PrivDir, "outdir1"), 2200 {ok,_,[]} = systools:make_script(LatestName, [{outdir,Outdir1}, 2201 {path,P},silent]), 2202 Script1 = filename:join(Outdir1, LatestName ++ ".script"), 2203 Boot1 = filename:join(Outdir1, LatestName ++ ".boot"), 2204 true = filelib:is_file(Script1), 2205 true = filelib:is_file(Boot1), 2206 ok = file:delete(Script1), 2207 ok = file:delete(Boot1), 2208 2209 %% c) relative path 2210 {ok,_,[]} = systools:make_script(LatestName, [{outdir,"./outdir1"}, 2211 {path,P},silent]), 2212 true = filelib:is_file(Script1), 2213 true = filelib:is_file(Boot1), 2214 ok = file:delete(Script1), 2215 ok = file:delete(Boot1), 2216 2217 %% d) absolute but incorrect path 2218 Outdir2 = filename:join(PrivDir, "outdir2"), 2219 Script2 = filename:join(Outdir2, LatestName ++ ".script"), 2220 {error,_,{open,Script2,_}} = 2221 systools:make_script(LatestName, [{outdir,Outdir2},{path,P},silent]), 2222 2223 %% e) relative but incorrect path 2224 {error,_,{open,_,_}} = 2225 systools:make_script(LatestName, [{outdir,"./outdir2"},{path,P},silent]), 2226 2227 %% f) with .rel in another directory than cwd 2228 ok = file:set_cwd(Outdir1), 2229 {ok,_,[]} = systools:make_script(filename:join(PrivDir, LatestName), 2230 [{outdir,"."},{path,P},silent]), 2231 true = filelib:is_file(LatestName ++ ".script"), 2232 true = filelib:is_file(LatestName ++ ".boot"), 2233 ok = file:delete(LatestName ++ ".script"), 2234 ok = file:delete(LatestName ++ ".boot"), 2235 ok = file:set_cwd(LatestDir), 2236 2237 %% ==== Now test systools:make_tar ===== 2238 {ok,_,[]} = systools:make_script(LatestName, [{path,P},silent]), 2239 %% a) badarg 2240 {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = 2241 (catch systools:make_tar(LatestName,[{outdir,outdir1},{path,P},silent])), 2242 2243 %% b) absolute path 2244 {ok,_,[]} = systools:make_tar(LatestName, [{outdir,Outdir1}, 2245 {path,P},silent]), 2246 Tar1 = filename:join(Outdir1,LatestName++".tar.gz"), 2247 true = filelib:is_file(Tar1), 2248 ok = file:delete(Tar1), 2249 2250 %% c) relative path 2251 {ok,_,[]} = systools:make_tar(LatestName, [{outdir,"./outdir1"}, 2252 {path,P},silent]), 2253 true = filelib:is_file(Tar1), 2254 ok = file:delete(Tar1), 2255 2256 %% d) absolute but incorrect path 2257 Tar2 = filename:join(Outdir2,LatestName++".tar.gz"), 2258 {error,_,{tar_error,{open,Tar2,{Tar2,enoent}}}} = 2259 systools:make_tar(LatestName, [{outdir,Outdir2},{path,P},silent]), 2260 2261 %% e) relative but incorrect path 2262 {error,_,{tar_error,{open,_,_}}} = 2263 systools:make_tar(LatestName, [{outdir,"./outdir2"},{path,P},silent]), 2264 2265 %% f) with .rel in another directory than cwd 2266 ok = file:set_cwd(Outdir1), 2267 {ok,_,[]} = systools:make_tar(filename:join(PrivDir, LatestName), 2268 [{outdir,"."},{path,P},silent]), 2269 true = filelib:is_file(Tar1), 2270 ok = file:set_cwd(LatestDir), 2271 2272 %% ===== Now test systools:make_relup ===== 2273 %% a) badarg 2274 {'EXIT', {{badarg, [{outdir,outdir1}]}, _}} = 2275 (catch systools:make_relup(LatestName,[LatestName1],[LatestName1], 2276 [{outdir,outdir1}, 2277 {path,P},silent])), 2278 2279 %% b) absolute path 2280 Relup = filename:join(Outdir1, "relup"), 2281 {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], 2282 [{outdir,Outdir1}, 2283 {path,P},silent]), 2284 true = filelib:is_file(Relup), 2285 ok = file:delete(Relup), 2286 2287 %% c) relative path 2288 {ok,_,_,[]} = systools:make_relup(LatestName,[LatestName1],[LatestName1], 2289 [{outdir,"./outdir1"}, 2290 {path,P},silent]), 2291 true = filelib:is_file(Relup), 2292 ok = file:delete(Relup), 2293 2294 %% d) absolute but incorrect path 2295 {error,_,{file_problem,{"relup",{open,enoent}}}} = 2296 systools:make_relup(LatestName,[LatestName1],[LatestName1], 2297 [{outdir,Outdir2},{path,P},silent]), 2298 2299 %% e) relative but incorrect path 2300 {error,_,{file_problem,{"relup",{open,enoent}}}} = 2301 systools:make_relup(LatestName,[LatestName1],[LatestName1], 2302 [{outdir,"./outdir2"},{path,P},silent]), 2303 2304 %% f) with .rel in another directory than cwd 2305 %% -- not necessary to test since relup by default is placed in 2306 %% cwd, not in the same directory as the .rel file -- 2307 2308 %% Change back to previous working directory 2309 ok = file:set_cwd(OldDir), 2310 ok. 2311 2312 2313%% Test that all default values can be used as values in the .app file 2314app_file_defaults(Config) -> 2315 PrivDir = ?config(priv_dir,Config), 2316 Name = app1, 2317 NameStr = atom_to_list(Name), 2318 Vsn = "1.0", 2319 AppSpec = app_spec(Name,#{vsn=>"1.0"}), 2320 ok = file:write_file(filename:join(PrivDir,NameStr ++ ".app"), 2321 io_lib:format("~p.~n",[AppSpec])), 2322 {ok,_} = systools_make:read_application(NameStr,Vsn,[PrivDir],[]), 2323 ok. 2324 2325app_spec(Name,New) -> 2326 {application,Name,app_spec(New)}. 2327 2328app_spec(New) -> 2329 Default = #{description => "", 2330 id => "", 2331 vsn => "", 2332 modules => [], 2333 maxP => infinity, 2334 maxT => infinity, 2335 registered => [], 2336 included_applications => [], 2337 applications => [], 2338 env => [], 2339 mod => [], 2340 start_phases => undefined, 2341 runtime_dependencies => []}, 2342 maps:to_list(maps:merge(Default,New)). 2343 2344%%%%%% 2345%%%%%% Utilities 2346%%%%%% 2347 2348check_script_path(RelName) -> 2349 {ok, [Conts]} = read_script_file(RelName), 2350 {script, {_, _}, ListOfThings} = Conts, 2351 case lists:keysearch(path, 1, ListOfThings) of 2352 {value, {path, [$$,$R,$O,$O,$T | _]}} -> %"$ROOT..." 2353 false; 2354 _ -> ok 2355 end. 2356 2357check_var_script_file(VarDirs, NoExistDirs, RelName) -> 2358 {ok, [Conts]} = read_script_file(RelName), 2359 {script, {_, _}, ListOfThings} = Conts, 2360 AllPaths = lists:append(lists:map(fun({path, P}) -> P; 2361 (_) -> [] 2362 end, 2363 ListOfThings)), 2364 case lists:filter(fun(VarDir) -> lists:member(VarDir, AllPaths) end, 2365 VarDirs) of 2366 VarDirs -> 2367 ok; 2368 _ -> 2369 test_server:fail("All variable dirs not in generated script") 2370 end, 2371 case lists:filter(fun(NoExistDir) -> lists:member(NoExistDir, AllPaths) end, 2372 NoExistDirs) of 2373 [] -> 2374 ok; 2375 _ -> 2376 test_server:fail("Unexpected dirs in generated script") 2377 end. 2378 2379check_include_script(RelName, ExpectedLoad, ExpectedStart) -> 2380 {ok, [Conts]} = read_script_file(RelName), 2381 {script, {_, _}, ListOfThings} = Conts, 2382 2383 %% Check that the applications are loaded in given order ! 2384 ActualLoad = 2385 [App || {apply,{application,load,[{application,App,_}]}} <- ListOfThings, 2386 App=/=kernel, 2387 App=/=stdlib], 2388 2389 if ActualLoad =:= ExpectedLoad -> ok; 2390 true -> test_server:fail({bad_load_order, ActualLoad, ExpectedLoad}) 2391 end, 2392 2393 %% Check that applications are started in given order ! 2394 ActualStart = 2395 [App || {apply,{application,start_boot,[App|_]}} <- ListOfThings, 2396 App =/= kernel, 2397 App =/= stdlib], 2398 2399 if ActualStart =:= ExpectedStart -> ok; 2400 true -> test_server:fail({bad_start_order, ActualStart,ExpectedStart}) 2401 end, 2402 2403 ok. 2404 2405read_script_file(RelName) -> 2406 file:consult(RelName ++ ".script"). 2407 2408check_var_tar(Variable, RelName) -> 2409 Expected = tar_name(Variable), 2410 case check_tar(Expected,RelName) of 2411 ok -> 2412 ok; 2413 {error, {erroneous_tar_file, _, missing, _}} -> 2414 {error, {not_generated, Expected}} 2415 end. 2416 2417exists_tar_file(Name) -> 2418 File = tar_name(Name), 2419 case filelib:is_regular(File) of 2420 true -> 2421 ok = file:delete(File), 2422 true; 2423 _ -> 2424 false 2425 end. 2426 2427%% Take a snap of the generated tar file and check if a certain 2428%% file is included. 2429%% This ensures at least that the tar file is generated. 2430check_tar(File, RelName) -> 2431 TarContents = tar_contents(RelName), 2432 case lists:member(File,TarContents) of 2433 true -> ok; 2434 _ -> {error, {erroneous_tar_file, tar_name(RelName), missing, File}} 2435 end. 2436 2437%% Check that the given files exist in the tar file, and that they are 2438%% not symlinks 2439check_tar_regular(PrivDir, Files, RelName) -> 2440 TmpDir = fname(PrivDir,tmp), 2441 ok = file:make_dir(TmpDir), 2442 ok = erl_tar:extract(tar_name(RelName), 2443 [{files,Files},{cwd,TmpDir},compressed]), 2444 R = lists:foldl(fun(File,Acc) -> 2445 case file:read_link_info(fname(TmpDir,File)) of 2446 {ok,#file_info{type=regular}} -> 2447 Acc; 2448 {ok,#file_info{type=Other}} -> 2449 [{File,Other}|Acc]; 2450 _ -> 2451 [{File,missing}|Acc] 2452 end 2453 end, 2454 [], 2455 Files), 2456 delete_tree(TmpDir), 2457 case R of 2458 [] -> 2459 ok; 2460 NotThere -> 2461 {error,{erroneous_tar_file,tar_name(RelName),NotThere}} 2462 end. 2463 2464delete_tree(Dir) -> 2465 case filelib:is_dir(Dir) of 2466 true -> 2467 {ok,Files} = file:list_dir(Dir), 2468 lists:foreach(fun(File) -> delete_tree(filename:join(Dir,File)) end, 2469 Files), 2470 file:del_dir(Dir); 2471 false -> 2472 ok = file:delete(Dir) 2473 end. 2474 2475tar_contents(Name) -> 2476 {ok, Cont} = erl_tar:table(tar_name(Name), [compressed]), 2477 Cont. 2478 2479tar_name(Name) -> 2480 Name ++ ".tar.gz". 2481 2482create_script(latest,Config) -> 2483 Apps = core_apps(current) ++ [{db,"2.1"},{fe,"3.1"}], 2484 do_create_script(latest,Config,"4.4",Apps); 2485create_script(latest_no_mod_vsn,Config) -> 2486 Apps = core_apps(current) ++ [{db,"3.1"},{fe,"3.1"}], 2487 do_create_script(latest_no_mod_vsn,Config,"4.4",Apps); 2488create_script(latest0,Config) -> 2489 Apps = core_apps("1.0") ++ [{db,"2.1"},{fe,"3.1"}], 2490 do_create_script(latest0,Config,"4.4",Apps); 2491create_script(latest0_current_erts,Config) -> 2492 Apps = core_apps("1.0") ++ [{db,"2.1"},{fe,"3.1"}], 2493 do_create_script(latest0_current_erts,Config,current,Apps); 2494create_script(latest1,Config) -> 2495 Apps = core_apps("1.0") ++ [{db,"1.0"},{fe,"3.1"}], 2496 do_create_script(latest1,Config,"4.4",Apps); 2497create_script(latest1_no_sasl,Config) -> 2498 Apps = [{kernel,"1.0"},{stdlib,"1.0"},{db,"1.0"},{fe,"3.1"}], 2499 do_create_script(latest1_no_sasl,Config,"4.4",Apps); 2500create_script(latest2,Config) -> 2501 Apps = core_apps("1.0") ++ [{db,"1.0"},{fe,"2.1"}], 2502 do_create_script(latest2,Config,"4.3",Apps); 2503create_script(latest_small,Config) -> 2504 Apps = core_apps("1.0") ++ [{fe,"3.1"}], 2505 do_create_script(latest_small,Config,"4.4",Apps); 2506create_script(latest_small0,Config) -> %Differs in fe vsn 2507 Apps = core_apps("1.0") ++ [{fe,"2.1"}], 2508 do_create_script(latest_small0,Config,"4.4",Apps); 2509create_script(latest_small1,Config) -> 2510 Apps = core_apps("1.0") ++ [{fe,"500.18.7"}], 2511 do_create_script(latest_small1,Config,"4.4",Apps); 2512create_script(latest_small2,Config) -> 2513 Apps = core_apps("1.0") ++ [{fe,"2.1.1"}], 2514 do_create_script(latest_small2,Config,"4.4",Apps); 2515create_script(latest_nokernel,Config) -> 2516 Apps = [{db,"2.1"},{fe,"3.1"}], 2517 do_create_script(latest_nokernel,Config,"4.4",Apps); 2518create_script(latest_kernel_start_type,Config) -> 2519 Apps = [{kernel,"1.0",load},{stdlib,"1.0"},{db,"2.1"},{fe,"3.1"}], 2520 do_create_script(latest_kernel_start_type,Config,"4.4",Apps); 2521create_script(latest_stdlib_start_type,Config) -> 2522 Apps = [{kernel,"1.0"},{stdlib,"1.0",load},{db,"2.1"},{fe,"3.1"}], 2523 do_create_script(latest_stdlib_start_type,Config,"4.4",Apps); 2524create_script(latest_no_stdlib,Config) -> 2525 Apps = [{kernel,"1.0"},{db,"2.1"},{fe,"3.1"}], 2526 do_create_script(latest_no_stdlib,Config,"4.4",Apps); 2527create_script(latest_app_start_type1,Config) -> 2528 Apps = core_apps(current), 2529 do_create_script(latest_app_start_type1,Config,current,Apps); 2530create_script(latest_app_start_type2,Config) -> 2531 OtherApps = [{mnesia,current,permanent}, 2532 {runtime_tools,current,transient}, 2533 {snmp,current,load}, 2534 {xmerl,current,none}], 2535 Apps = core_apps(current) ++ OtherApps, 2536 do_create_script(latest_app_start_type2,Config,current,Apps); 2537create_script(current_all_no_sasl,Config) -> 2538 Apps = [{kernel,current},{stdlib,current},{db,"2.1"},{fe,"3.1"}], 2539 do_create_script(current_all_no_sasl,Config,current,Apps); 2540create_script(current_all,Config) -> 2541 Apps = core_apps(current) ++ [{db,"2.1"}], 2542 do_create_script(current_all,Config,current,Apps); 2543create_script(current_all_future_erts,Config) -> 2544 Apps = core_apps(current) ++ [{db,"2.1"},{fe,"3.1"}], 2545 do_create_script(current_all_future_erts,Config,"99.99",Apps); 2546create_script(current_all_future_sasl,Config) -> 2547 Apps = [{kernel,current},{stdlib,current},{sasl,"9.9"},{db,"2.1"},{fe,"3.1"}], 2548 do_create_script(current_all_future_sasl,Config,current,Apps); 2549create_script({unicode,RelVsn},Config) -> 2550 Apps = core_apps(current) ++ [{ua,"1.0"}], 2551 do_create_script(unicode,RelVsn,Config,current,Apps); 2552create_script(duplicate_modules,Config) -> 2553 Apps = core_apps(current) ++ [{app1,"1.0"},{app2,"1.0"}], 2554 do_create_script(duplicate_modules,Config,current,Apps); 2555create_script(replace_app0,Config) -> 2556 Apps = core_apps(current) ++ [{db,"1.1"},{gh,"1.0"}], 2557 do_create_script(repace_app0,Config,current,Apps); 2558create_script(replace_app1,Config) -> 2559 Apps = core_apps(current) ++ [{db,"1.0"},{fe,"2.1"}], 2560 do_create_script(repace_app1,Config,current,Apps). 2561 2562 2563do_create_script(Id,Config,ErtsVsn,AppVsns) -> 2564 do_create_script(Id,string:to_upper(atom_to_list(Id)),Config,ErtsVsn,AppVsns). 2565do_create_script(Id,RelVsn,Config,ErtsVsn,AppVsns) -> 2566 PrivDir = ?privdir, 2567 Name = fname(PrivDir, Id), 2568 {ok,Fd} = file:open(Name++".rel",write), 2569 RelfileContent = 2570 {release,{"Test release", RelVsn}, 2571 {erts,erts_vsn(ErtsVsn)}, 2572 app_vsns(AppVsns)}, 2573 io:format(Fd,"~p.~n",[RelfileContent]), 2574 ok = file:close(Fd), 2575 {filename:dirname(Name), filename:basename(Name)}. 2576 2577core_apps(Vsn) -> 2578 [{App,Vsn} || App <- [kernel,stdlib,sasl]]. 2579 2580app_vsns(AppVsns) -> 2581 [{App,app_vsn(App,Vsn)} || {App,Vsn} <- AppVsns] ++ 2582 [{App,app_vsn(App,Vsn),Type} || {App,Vsn,Type} <- AppVsns]. 2583app_vsn(App,current) -> 2584 case application:load(App) of 2585 Ok when Ok==ok; Ok=={error,{already_loaded,App}} -> 2586 {ok,Vsn} = application:get_key(App,vsn), 2587 Vsn; 2588 Error -> 2589 throw(Error) 2590 end; 2591app_vsn(_App,Vsn) -> 2592 Vsn. 2593 2594erts_vsn(current) -> erlang:system_info(version); 2595erts_vsn(Vsn) -> Vsn. 2596 2597 2598create_include_files(inc1, Config) -> 2599 PrivDir = ?privdir, 2600 Name = fname(PrivDir, inc1), 2601 create_apps(PrivDir), 2602 2603 Apps = application_controller:which_applications(), 2604 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2605 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2606 2607 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2608 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2609 ++ StdlibVer ++ "\"},\n" 2610 " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" 2611 " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" 2612 " {t1, \"1.0\"}]}.\n", 2613 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2614 {filename:dirname(Name), filename:basename(Name)}; 2615 2616create_include_files(inc2, Config) -> 2617 PrivDir = ?privdir, 2618 Name = fname(PrivDir, inc2), 2619 create_apps(PrivDir), 2620 2621 Apps = application_controller:which_applications(), 2622 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2623 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2624 2625 %% t6 does not include t5 ! 2626 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2627 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2628 ++ StdlibVer ++ "\"},\n" 2629 " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" 2630 " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" 2631 " {t1, \"1.0\"}]}.\n", 2632 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2633 {filename:dirname(Name), filename:basename(Name)}; 2634 2635create_include_files(inc3, Config) -> 2636 PrivDir = ?privdir, 2637 Name = fname(PrivDir, inc3), 2638 create_apps(PrivDir), 2639 2640 Apps = application_controller:which_applications(), 2641 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2642 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2643 2644 %% t3 does not include t2 ! 2645 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2646 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2647 ++ StdlibVer ++ "\"},\n" 2648 " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" 2649 " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" 2650 " {t1, \"1.0\"}]}.\n", 2651 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2652 {filename:dirname(Name), filename:basename(Name)}; 2653 2654create_include_files(inc4, Config) -> 2655 PrivDir = ?privdir, 2656 Name = fname(PrivDir, inc4), 2657 create_apps(PrivDir), 2658 2659 Apps = application_controller:which_applications(), 2660 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2661 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2662 2663 %% t3 does not include t2 ! 2664 %% t6 does not include t5 ! 2665 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2666 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2667 ++ StdlibVer ++ "\"},\n" 2668 " {t6, \"1.0\", [t4]}, {t5, \"1.0\"}, \n" 2669 " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" 2670 " {t1, \"1.0\"}]}.\n", 2671 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2672 {filename:dirname(Name), filename:basename(Name)}; 2673 2674create_include_files(inc5, Config) -> 2675 PrivDir = ?privdir, 2676 Name = fname(PrivDir, inc5), 2677 create_apps(PrivDir), 2678 2679 Apps = application_controller:which_applications(), 2680 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2681 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2682 2683 %% t6 does not include t5 ! 2684 %% exclude t5. 2685 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2686 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2687 ++ StdlibVer ++ "\"},\n" 2688 " {t6, \"1.0\", [t4]}, \n" 2689 " {t4, \"1.0\"}, {t3, \"1.0\", []}, {t2, \"1.0\"}, \n" 2690 " {t1, \"1.0\"}]}.\n", 2691 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2692 {filename:dirname(Name), filename:basename(Name)}; 2693 2694create_include_files(inc6, Config) -> 2695 PrivDir = ?privdir, 2696 Name = fname(PrivDir, inc6), 2697 create_apps(PrivDir), 2698 2699 Apps = application_controller:which_applications(), 2700 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2701 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2702 2703 %% t3 does include non existing t2 ! 2704 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2705 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2706 ++ StdlibVer ++ "\"},\n" 2707 " {t6, \"1.0\"}, {t5, \"1.0\"}, \n" 2708 " {t4, \"1.0\"}, {t3, \"1.0\"}, \n" 2709 " {t1, \"1.0\"}]}.\n", 2710 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2711 {filename:dirname(Name), filename:basename(Name)}; 2712 2713create_include_files(inc7, Config) -> 2714 PrivDir = ?privdir, 2715 Name = fname(PrivDir, inc7), 2716 create_apps(PrivDir), 2717 create_app(t7, PrivDir), 2718 2719 Apps = application_controller:which_applications(), 2720 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2721 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2722 2723 %% t7 and t6 does include t5 ! 2724 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2725 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2726 ++ StdlibVer ++ "\"},\n" 2727 " {t7, \"1.0\"}, {t6, \"1.0\"}, {t5, \"1.0\"}, \n" 2728 " {t4, \"1.0\"}, {t3, \"1.0\"}, {t2, \"1.0\"}, \n" 2729 " {t1, \"1.0\"}]}.\n", 2730 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2731 {filename:dirname(Name), filename:basename(Name)}; 2732 2733create_include_files(inc8, Config) -> 2734 PrivDir = ?privdir, 2735 Name = fname(PrivDir, inc8), 2736 create_circular_apps(PrivDir), 2737 2738 Apps = application_controller:which_applications(), 2739 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2740 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2741 2742 %% t8 uses t9 and t10 includes t9 ! 2743 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2744 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2745 ++ StdlibVer ++ "\"},\n" 2746 " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\"}]}.\n", 2747 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2748 {filename:dirname(Name), filename:basename(Name)}; 2749 2750create_include_files(inc9, Config) -> 2751 PrivDir = ?privdir, 2752 Name = fname(PrivDir, inc9), 2753 create_circular_apps(PrivDir), 2754 2755 Apps = application_controller:which_applications(), 2756 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2757 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2758 2759 %% t8 uses t9, t9 uses t10 and t10 includes t8 ==> circular !! 2760 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2761 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2762 ++ StdlibVer ++ "\"},\n" 2763 " {t8, \"1.0\"}, {t9, \"1.0\"}, {t10, \"1.0\", [t8]}]}.\n", 2764 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2765 {filename:dirname(Name), filename:basename(Name)}; 2766 2767create_include_files(inc10, Config) -> 2768 PrivDir = ?privdir, 2769 Name = fname(PrivDir, inc10), 2770 create_circular_apps(PrivDir), 2771 2772 Apps = application_controller:which_applications(), 2773 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2774 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2775 2776 %% t9 tries to include not specified (in .app file) application ! 2777 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2778 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2779 ++ StdlibVer ++ "\"},\n" 2780 " {t8, \"1.0\"}, {t9, \"1.0\", [t7]}, {t10, \"1.0\"}]}.\n", 2781 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2782 {filename:dirname(Name), filename:basename(Name)}; 2783 2784create_include_files(inc11, Config) -> 2785 PrivDir = ?privdir, 2786 Name = fname(PrivDir, inc11), 2787 create_apps2(PrivDir), 2788 2789 Apps = application_controller:which_applications(), 2790 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2791 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2792 2793 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2794 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2795 ++ StdlibVer ++ "\"},\n" 2796 " {t11, \"1.0\"}, \n" 2797 " {t12, \"1.0\"}, \n" 2798 " {t13, \"1.0\"}]}.\n", 2799 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2800 {filename:dirname(Name), filename:basename(Name)}; 2801 2802create_include_files(otp_3065_circular_dependenies, Config) -> 2803 PrivDir = ?privdir, 2804 Name = fname(PrivDir, otp_3065_circular_dependenies), 2805 create_apps_3065(PrivDir), 2806 2807 Apps = application_controller:which_applications(), 2808 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2809 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2810 2811 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2812 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2813 ++ StdlibVer ++ "\"},\n" 2814 " {chAts, \"1.0\"}, {aa12, \"1.0\"}, \n" 2815 " {chTraffic, \"1.0\"}]}.\n", 2816 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2817 {filename:dirname(Name), filename:basename(Name)}; 2818 2819create_include_files(sort_apps, Config) -> 2820 PrivDir = ?privdir, 2821 Name = fname(PrivDir, sort_apps), 2822 create_sort_apps(PrivDir), 2823 2824 Apps = application_controller:which_applications(), 2825 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2826 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2827 2828 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2829 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2830 ++ StdlibVer ++ "\"},\n" 2831 " {t14, \"1.0\"}, \n" 2832 " {t20, \"1.0\"}, \n" 2833 " {t19, \"1.0\"}, \n" 2834 " {t18, \"1.0\"}, \n" 2835 " {t17, \"1.0\"}, \n" 2836 " {t16, \"1.0\"}, \n" 2837 " {t15, \"1.0\"}]}.\n", 2838 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2839 {filename:dirname(Name), filename:basename(Name)}; 2840 2841create_include_files(sort_apps_rev, Config) -> 2842 PrivDir = ?privdir, 2843 Name = fname(PrivDir, sort_apps_rev), 2844 create_sort_apps(PrivDir), 2845 2846 Apps = application_controller:which_applications(), 2847 {value,{_,_,KernelVer}} = lists:keysearch(kernel,1,Apps), 2848 {value,{_,_,StdlibVer}} = lists:keysearch(stdlib,1,Apps), 2849 2850 Rel = "{release, {\"test\",\"R1A\"}, {erts, \"45\"},\n" 2851 " [{kernel, \"" ++ KernelVer ++ "\"}, {stdlib, \"" 2852 ++ StdlibVer ++ "\"},\n" 2853 " {t14, \"1.0\"}, \n" 2854 " {t18, \"1.0\"}, \n" 2855 " {t19, \"1.0\"}, \n" 2856 " {t20, \"1.0\"}, \n" 2857 " {t15, \"1.0\"}, \n" 2858 " {t16, \"1.0\"}, \n" 2859 " {t17, \"1.0\"}]}.\n", 2860 file:write_file(Name ++ ".rel", list_to_binary(Rel)), 2861 {filename:dirname(Name), filename:basename(Name)}. 2862 2863 2864create_apps(Dir) -> 2865 T1 = "{application, t1,\n" 2866 " [{vsn, \"1.0\"},\n" 2867 " {description, \"test\"},\n" 2868 " {modules, []},\n" 2869 " {applications, [kernel, stdlib]},\n" 2870 " {registered, []}]}.\n", 2871 file:write_file(fname(Dir, 't1.app'), list_to_binary(T1)), 2872 2873 T2 = "{application, t2,\n" 2874 " [{vsn, \"1.0\"},\n" 2875 " {description, \"test\"},\n" 2876 " {modules, []},\n" 2877 " {applications, [t1]},\n" 2878 " {registered, []}]}.\n", 2879 file:write_file(fname(Dir, 't2.app'), list_to_binary(T2)), 2880 2881 T3 = "{application, t3,\n" 2882 " [{vsn, \"1.0\"},\n" 2883 " {description, \"test\"},\n" 2884 " {modules, []},\n" 2885 " {applications, []},\n" 2886 " {included_applications, [t2]},\n" 2887 " {registered, []}]}.\n", 2888 file:write_file(fname(Dir, 't3.app'), list_to_binary(T3)), 2889 2890 T4 = "{application, t4,\n" 2891 " [{vsn, \"1.0\"},\n" 2892 " {description, \"test\"},\n" 2893 " {modules, []},\n" 2894 " {applications, [t3]},\n" 2895 " {included_applications, []},\n" 2896 " {registered, []}]}.\n", 2897 file:write_file(fname(Dir, 't4.app'), list_to_binary(T4)), 2898 2899 T5 = "{application, t5,\n" 2900 " [{vsn, \"1.0\"},\n" 2901 " {description, \"test\"},\n" 2902 " {modules, []},\n" 2903 " {applications, [t3]},\n" 2904 " {included_applications, []},\n" 2905 " {registered, []}]}.\n", 2906 file:write_file(fname(Dir, 't5.app'), list_to_binary(T5)), 2907 2908 T6 = "{application, t6,\n" 2909 " [{vsn, \"1.0\"},\n" 2910 " {description, \"test\"},\n" 2911 " {modules, []},\n" 2912 " {applications, []},\n" 2913 " {included_applications, [t4, t5]},\n" 2914 " {registered, []}]}.\n", 2915 file:write_file(fname(Dir, 't6.app'), list_to_binary(T6)). 2916 2917create_app(t7, Dir) -> 2918 T7 = "{application, t7,\n" 2919 " [{vsn, \"1.0\"},\n" 2920 " {description, \"test\"},\n" 2921 " {modules, []},\n" 2922 " {applications, []},\n" 2923 " {included_applications, [t5]},\n" 2924 " {registered, []}]}.\n", 2925 file:write_file(fname(Dir, 't7.app'), list_to_binary(T7)). 2926 2927create_circular_apps(Dir) -> 2928 T8 = "{application, t8,\n" 2929 " [{vsn, \"1.0\"},\n" 2930 " {description, \"test\"},\n" 2931 " {modules, []},\n" 2932 " {applications, [t9]},\n" 2933 " {included_applications, []},\n" 2934 " {registered, []}]}.\n", 2935 file:write_file(fname(Dir, 't8.app'), list_to_binary(T8)), 2936 2937 T9 = "{application, t9,\n" 2938 " [{vsn, \"1.0\"},\n" 2939 " {description, \"test\"},\n" 2940 " {modules, []},\n" 2941 " {applications, [t10]},\n" 2942 " {included_applications, []},\n" 2943 " {registered, []}]}.\n", 2944 file:write_file(fname(Dir, 't9.app'), list_to_binary(T9)), 2945 2946 T10 = "{application, t10,\n" 2947 " [{vsn, \"1.0\"},\n" 2948 " {description, \"test\"},\n" 2949 " {modules, []},\n" 2950 " {applications, []},\n" 2951 " {included_applications, [t8, t9]},\n" 2952 " {registered, []}]}.\n", 2953 file:write_file(fname(Dir, 't10.app'), list_to_binary(T10)). 2954 2955create_apps2(Dir) -> 2956 T11 = "{application, t11,\n" 2957 " [{vsn, \"1.0\"},\n" 2958 " {description, \"test\"},\n" 2959 " {modules, []},\n" 2960 " {applications, []},\n" 2961 " {included_applications, [t13]},\n" 2962 " {registered, []}]}.\n", 2963 file:write_file(fname(Dir, 't11.app'), list_to_binary(T11)), 2964 2965 T12 = "{application, t12,\n" 2966 " [{vsn, \"1.0\"},\n" 2967 " {description, \"test\"},\n" 2968 " {modules, []},\n" 2969 " {applications, [t11]},\n" 2970 " {registered, []}]}.\n", 2971 file:write_file(fname(Dir, 't12.app'), list_to_binary(T12)), 2972 2973 T13 = "{application, t13,\n" 2974 " [{vsn, \"1.0\"},\n" 2975 " {description, \"test\"},\n" 2976 " {modules, []},\n" 2977 " {applications, []},\n" 2978 " {included_applications, []},\n" 2979 " {registered, []}]}.\n", 2980 file:write_file(fname(Dir, 't13.app'), list_to_binary(T13)). 2981 2982 2983 2984create_apps_3065(Dir) -> 2985 T11 = "{application, chTraffic,\n" 2986 " [{vsn, \"1.0\"},\n" 2987 " {description, \"test\"},\n" 2988 " {modules, []},\n" 2989 " {applications, []},\n" 2990 " {included_applications, [chAts]},\n" 2991 " {registered, []}]}.\n", 2992 file:write_file(fname(Dir, 'chTraffic.app'), list_to_binary(T11)), 2993 2994 T12 = "{application, chAts,\n" 2995 " [{vsn, \"1.0\"},\n" 2996 " {description, \"test\"},\n" 2997 " {modules, []},\n" 2998 " {applications, []},\n" 2999 " {included_applications, [aa12]},\n" 3000 " {registered, []}]}.\n", 3001 file:write_file(fname(Dir, 'chAts.app'), list_to_binary(T12)), 3002 3003 T13 = "{application, aa12,\n" 3004 " [{vsn, \"1.0\"},\n" 3005 " {description, \"test\"},\n" 3006 " {modules, []},\n" 3007 " {applications, [chAts]},\n" 3008 " {included_applications, []},\n" 3009 " {registered, []}]}.\n", 3010 file:write_file(fname(Dir, 'aa12.app'), list_to_binary(T13)). 3011 3012create_sort_apps(Dir) -> 3013 T14 = "{application, t14,\n" 3014 " [{vsn, \"1.0\"},\n" 3015 " {description, \"test\"},\n" 3016 " {modules, []},\n" 3017 " {applications, [t18,t20,t19]},\n" 3018 " {included_applications, [t15,t17,t16]},\n" 3019 " {registered, []}]}.\n", 3020 file:write_file(fname(Dir, 't14.app'), list_to_binary(T14)), 3021 3022 T15 = "{application, t15,\n" 3023 " [{vsn, \"1.0\"},\n" 3024 " {description, \"test\"},\n" 3025 " {modules, []},\n" 3026 " {applications, []},\n" 3027 " {included_applications, []},\n" 3028 " {registered, []}]}.\n", 3029 file:write_file(fname(Dir, 't15.app'), list_to_binary(T15)), 3030 3031 T16 = "{application, t16,\n" 3032 " [{vsn, \"1.0\"},\n" 3033 " {description, \"test\"},\n" 3034 " {modules, []},\n" 3035 " {applications, []},\n" 3036 " {included_applications, []},\n" 3037 " {registered, []}]}.\n", 3038 file:write_file(fname(Dir, 't16.app'), list_to_binary(T16)), 3039 3040 T17 = "{application, t17,\n" 3041 " [{vsn, \"1.0\"},\n" 3042 " {description, \"test\"},\n" 3043 " {modules, []},\n" 3044 " {applications, []},\n" 3045 " {included_applications, []},\n" 3046 " {registered, []}]}.\n", 3047 file:write_file(fname(Dir, 't17.app'), list_to_binary(T17)), 3048 3049 T18 = "{application, t18,\n" 3050 " [{vsn, \"1.0\"},\n" 3051 " {description, \"test\"},\n" 3052 " {modules, []},\n" 3053 " {applications, []},\n" 3054 " {included_applications, []},\n" 3055 " {registered, []}]}.\n", 3056 file:write_file(fname(Dir, 't18.app'), list_to_binary(T18)), 3057 3058 T19 = "{application, t19,\n" 3059 " [{vsn, \"1.0\"},\n" 3060 " {description, \"test\"},\n" 3061 " {modules, []},\n" 3062 " {applications, []},\n" 3063 " {included_applications, []},\n" 3064 " {registered, []}]}.\n", 3065 file:write_file(fname(Dir, 't19.app'), list_to_binary(T19)), 3066 3067 T20 = "{application, t20,\n" 3068 " [{vsn, \"1.0\"},\n" 3069 " {description, \"test\"},\n" 3070 " {modules, []},\n" 3071 " {applications, []},\n" 3072 " {included_applications, []},\n" 3073 " {registered, []}]}.\n", 3074 file:write_file(fname(Dir, 't20.app'), list_to_binary(T20)). 3075 3076fname(N) -> 3077 filename:join(N). 3078 3079fname(Dir, Basename) -> 3080 filename:join(Dir, Basename). 3081