1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2009-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-module(reltool_server_SUITE). 21 22-compile([export_all, nowarn_export_all]). 23 24-include_lib("reltool/src/reltool.hrl"). 25-include("reltool_test_lib.hrl"). 26-include_lib("common_test/include/ct.hrl"). 27-include_lib("kernel/include/file.hrl"). 28 29-define(NODE_NAME, '__RELTOOL__TEMPORARY_TEST__NODE__'). 30-define(WORK_DIR, "reltool_work_dir"). 31 32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33%% Initialization functions. 34 35init_per_suite(Config) -> 36 {ok,Cwd} = file:get_cwd(), 37 ?ignore(file:make_dir(?WORK_DIR)), 38 [{cwd,Cwd}|reltool_test_lib:init_per_suite(Config)]. 39 40end_per_suite(Config) -> 41 reltool_test_lib:end_per_suite(Config). 42 43init_per_testcase(Func,Config) -> 44 Node = full_node_name(?NODE_NAME), 45 case net_adm:ping(Node) of 46 pong -> stop_node(Node); 47 pang -> ok 48 end, 49 reltool_test_lib:init_per_testcase(Func,Config). 50end_per_testcase(Func,Config) -> 51 ok = file:set_cwd(filename:join(?config(cwd,Config),?WORK_DIR)), 52 {ok,All} = file:list_dir("."), 53 Files = [F || F <- All, false == lists:prefix("save.",F)], 54 case ?config(tc_status,Config) of 55 ok -> 56 ok; 57 _Fail -> 58 SaveDir = "save."++atom_to_list(Func), 59 ok = file:make_dir(SaveDir), 60 save_test_result(Files,SaveDir) 61 end, 62 rm_files(Files), 63 ok = file:set_cwd(?config(cwd,Config)), 64 reltool_test_lib:end_per_testcase(Func,Config). 65 66 67save_test_result(Files,DestDir) -> 68 Tar = "copy.tar", 69 ok = erl_tar:create(Tar, Files), 70 ok = erl_tar:extract(Tar, [{cwd,DestDir}]), 71 ok = file:delete(Tar), 72 ok. 73 74rm_files([F | Fs]) -> 75 case file:read_file_info(F) of 76 {ok,#file_info{type=directory}} -> 77 rm_dir(F); 78 {ok,_Regular} -> 79 ok = file:delete(F) 80 end, 81 rm_files(Fs); 82rm_files([]) -> 83 ok. 84 85rm_dir(Dir) -> 86 {ok,Files} = file:list_dir(Dir), 87 rm_files([filename:join(Dir, F) || F <- Files]), 88 ok = file:del_dir(Dir). 89 90 91 92 93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 94%% SUITE specification 95 96suite() -> [{ct_hooks,[ts_install_cth]}]. 97 98all() -> 99 [start_server, 100 set_config, 101 get_config, 102 create_release, 103 create_release_sort, 104 create_script, 105 create_script_without_dot_erlang, 106 create_script_sort, 107 create_target, 108 create_target_unicode, 109 create_embedded, 110 create_standalone, 111 create_standalone_beam, 112 create_standalone_app, 113 create_standalone_app_clash, 114 create_multiple_standalone, 115 create_old_target, 116 create_slim, 117 eval_target_spec, 118 otp_9135, 119 otp_9229_dupl_mod_exclude_app, 120 otp_9229_dupl_mod_exclude_mod, 121 dupl_mod_in_app_file, 122 include_non_existing_app, 123 exclude_non_existing_app, 124 get_apps, 125 get_mod, 126 get_sys, 127 set_app_and_undo, 128 set_apps_and_undo, 129 set_apps_inlined, 130 set_sys_and_undo, 131 load_config_and_undo, 132 load_config_fail, 133 load_config_escript_path, 134 load_config_same_escript_source, 135 load_config_same_escript_beam, 136 load_config_add_escript, 137 reset_config_and_undo, 138 gen_rel_files, 139 save_config, 140 dependencies, 141 mod_incl_cond_derived, 142 dep_in_app_not_xref, 143 use_selected_vsn, 144 use_selected_vsn_relative_path, 145 non_standard_vsn_id, 146 undefined_regexp, 147 windows_erl_libs]. 148 149groups() -> 150 []. 151 152init_per_group(_GroupName, Config) -> 153 Config. 154 155end_per_group(_GroupName, Config) -> 156 Config. 157 158 159%% The test cases 160 161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 162%% A dummy break test case which is NOT in all(), but can be run 163%% directly from the command line with ct_run. It just does a 164%% test_server:break()... 165break(_Config) -> 166 test_server:break(""), 167 ok. 168 169 170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 171%% Start a server process and check that it does not crash 172 173start_server(_Config) -> 174 {ok, Pid} = ?msym({ok, _}, reltool:start_server([])), 175 Libs = reltool_test_lib:erl_libs(), 176 StrippedDefault = 177 case Libs of 178 [] -> {sys, []}; 179 _ -> {sys, [{lib_dirs, Libs}]} 180 end, 181 ?m({ok, StrippedDefault}, reltool:get_config(Pid)), 182 ?m(ok, reltool:stop(Pid)), 183 ok. 184 185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 186%% Start a server process and check that it does not crash 187 188set_config(_Config) -> 189 Libs = reltool_test_lib:erl_libs(), 190 Default = 191 {sys, 192 [ 193 {mod_cond, all}, 194 {incl_cond, derived}, 195 {root_dir, code:root_dir()}, 196 {lib_dirs, Libs} 197 ]}, 198 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Default}])), 199 StrippedDefault = 200 case Libs of 201 [] -> {sys, []}; 202 _ -> {sys, [{lib_dirs, Libs}]} 203 end, 204 ?m({ok, StrippedDefault}, reltool:get_config(Pid)), 205 206 ?m(ok, reltool:stop(Pid)), 207 ok. 208 209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 210%% Check that get_config returns the expected derivates and defaults 211%% as specified 212get_config(_Config) -> 213 214 KVsn = latest(kernel), 215 StdVsn = latest(stdlib), 216 SaslVsn = latest(sasl), 217 218 LibDir = code:lib_dir(), 219 KLibDir = filename:join(LibDir,"kernel-"++KVsn), 220 StdLibDir = filename:join(LibDir,"stdlib-"++StdVsn), 221 SaslLibDir = filename:join(LibDir,"sasl-"++SaslVsn), 222 223 Libs = reltool_test_lib:erl_libs(), 224 LibDirs = 225 case Libs of 226 [] -> []; 227 _ -> [{lib_dirs,Libs}] 228 end, 229 230 Sys = {sys,LibDirs ++ 231 [{incl_cond, exclude}, 232 {app,kernel,[{incl_cond,include}]}, 233 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}]}, 234 {app,stdlib,[{incl_cond,include},{lib_dir,StdLibDir}]}]}, 235 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 236 ?m({ok, Sys}, reltool:get_config(Pid)), 237 ?m({ok, Sys}, reltool:get_config(Pid,false,false)), 238 239 %% Include derived info 240 case Libs of 241 [] -> 242 ?msym({ok,{sys,[{incl_cond, exclude}, 243 {erts,[]}, 244 {app,kernel,[{incl_cond,include},{mod,_,[]}|_]}, 245 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}, 246 {mod,_,[]}|_]}, 247 {app,stdlib,[{incl_cond,include},{lib_dir,StdLibDir}, 248 {mod,_,[]}|_]}]}}, 249 reltool:get_config(Pid,false,true)); 250 _ -> 251 ?msym({ok,{sys,[{lib_dirs,Libs}, 252 {incl_cond, exclude}, 253 {erts,[]}, 254 {app,kernel,[{incl_cond,include},{mod,_,[]}|_]}, 255 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}, 256 {mod,_,[]}|_]}, 257 {app,stdlib,[{incl_cond,include},{lib_dir,StdLibDir}, 258 {mod,_,[]}|_]}]}}, 259 reltool:get_config(Pid,false,true)) 260 end, 261 262 %% Include defaults 263 ?msym({ok,{sys,[{root_dir,_}, 264 {lib_dirs,_}, 265 {mod_cond,all}, 266 {incl_cond,exclude}, 267 {app,kernel,[{incl_cond,include},{vsn,undefined}, 268 {lib_dir,undefined}]}, 269 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}, 270 {lib_dir,undefined}]}, 271 {app,stdlib,[{incl_cond,include},{vsn,undefined}, 272 {lib_dir,StdLibDir}]}, 273 {boot_rel,"start_clean"}, 274 {rel,"no_dot_erlang","1.0",[],[{load_dot_erlang,false}]}, 275 {rel,"start_clean","1.0",[],[{load_dot_erlang,true}]}, 276 {rel,"start_sasl","1.0",[sasl],[{load_dot_erlang,true}]}, 277 {emu_name,"beam"}, 278 {relocatable,true}, 279 {profile,development}, 280 {incl_sys_filters,[".*"]}, 281 {excl_sys_filters,[]}, 282 {incl_app_filters,[".*"]}, 283 {excl_app_filters,[]}, 284 {incl_archive_filters,[".*"]}, 285 {excl_archive_filters,["^include$","^priv$"]}, 286 {archive_opts,[]}, 287 {rel_app_type,permanent}, 288 {app_file,keep}, 289 {debug_info,keep}]}}, 290 reltool:get_config(Pid,true,false)), 291 292 %% Include both defaults and derived info 293 ?msym({ok,{sys,[{root_dir,_}, 294 {lib_dirs,_}, 295 {mod_cond,all}, 296 {incl_cond,exclude}, 297 {erts,[]}, 298 {app,kernel,[{incl_cond,include},{vsn,KVsn}, 299 {lib_dir,KLibDir},{mod,_,[]}|_]}, 300 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}, 301 {lib_dir,SaslLibDir},{mod,_,[]}|_]}, 302 {app,stdlib,[{incl_cond,include},{vsn,StdVsn}, 303 {lib_dir,StdLibDir},{mod,_,[]}|_]}, 304 {boot_rel,"start_clean"}, 305 {rel,"no_dot_erlang","1.0",[],[{load_dot_erlang,false}]}, 306 {rel,"start_clean","1.0",[],[{load_dot_erlang,true}]}, 307 {rel,"start_sasl","1.0",[sasl],[{load_dot_erlang,true}]}, 308 {emu_name,"beam"}, 309 {relocatable,true}, 310 {profile,development}, 311 {incl_sys_filters,[".*"]}, 312 {excl_sys_filters,[]}, 313 {incl_app_filters,[".*"]}, 314 {excl_app_filters,[]}, 315 {incl_archive_filters,[".*"]}, 316 {excl_archive_filters,["^include$","^priv$"]}, 317 {archive_opts,[]}, 318 {rel_app_type,permanent}, 319 {app_file,keep}, 320 {debug_info,keep}]}}, 321 reltool:get_config(Pid,true,true)), 322 323 ?m(ok, reltool:stop(Pid)), 324 ok. 325 326 327%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 328%% OTP-9135, test that app_file option can be set to all | keep | strip 329 330otp_9135(_Config) -> 331 Libs = reltool_test_lib:erl_libs(), 332 StrippedDefaultSys = 333 case Libs of 334 [] -> []; 335 _ -> [{lib_dirs, Libs}] 336 end, 337 338 Config1 = {sys,[{app_file, keep}]}, % this is the default 339 {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, Config1}])), 340 ?m({ok, {sys,StrippedDefaultSys}}, reltool:get_config(Pid1)), 341 ?m(ok, reltool:stop(Pid1)), 342 343 Config2 = {sys,[{app_file, strip}]}, 344 {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, Config2}])), 345 ExpectedConfig2 = StrippedDefaultSys++[{app_file,strip}], 346 ?m({ok, {sys,ExpectedConfig2}}, reltool:get_config(Pid2)), 347 ?m(ok, reltool:stop(Pid2)), 348 349 Config3 = {sys,[{app_file, all}]}, 350 {ok, Pid3} = ?msym({ok, _}, reltool:start_server([{config, Config3}])), 351 ExpectedConfig3 = StrippedDefaultSys++[{app_file,all}], 352 ?m({ok, {sys,ExpectedConfig3}}, reltool:get_config(Pid3)), 353 ?m(ok, reltool:stop(Pid3)), 354 ok. 355 356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 357%% Generate releases 358 359create_release(_Config) -> 360 %% Configure the server 361 RelName = "Just testing...", 362 RelVsn = "1.0", 363 Config = 364 {sys, 365 [ 366 {lib_dirs, []}, 367 {boot_rel, RelName}, 368 {rel, RelName, RelVsn, [kernel, stdlib]} 369 ]}, 370 %% Generate release 371 ErtsVsn = erlang:system_info(version), 372 Apps = application:loaded_applications(), 373 {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps), 374 {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps), 375 Rel = {release, {RelName, RelVsn}, 376 {erts, ErtsVsn}, 377 [{kernel, KernelVsn}, {stdlib, StdlibVsn}]}, 378 ?m({ok, Rel}, reltool:get_rel([{config, Config}], RelName)), 379 ok. 380 381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 382%% Generate releases and make sure order of applications specified in 383%% 'rel' parameter is preserved and that included applications are 384%% started before the including application. 385%% Circular dependencies shall also be detected and cause error. 386 387create_release_sort(Config) -> 388 DataDir = ?config(data_dir,Config), 389 %% Configure the server 390 RelName1 = "MnesiaFirst", 391 RelName2 = "SaslFirst", 392 RelName3 = "Include-both", 393 RelName4 = "Include-only-app", 394 RelName5 = "Include-only-rel", 395 RelName6 = "Auto-add-missing-apps", 396 RelName7 = "Circular", 397 RelName8 = "Include-rel-alter-order", 398 RelName9 = "Include-none-overwrite", 399 RelName10= "Uses-order-as-rel", 400 RelName11= "Auto-add-dont-overwrite-load", 401 RelVsn = "1.0", 402 %% Application z (.app file): 403 %% includes [tools, mnesia] 404 %% uses [kernel, stdlib, sasl, inets, unknown] 405 %% where unknown is optional dependency 406 Sys = 407 {sys, 408 [ 409 {lib_dirs, [filename:join(DataDir,"sort_apps")]}, 410 {boot_rel, RelName1}, 411 {rel, RelName1, RelVsn, [stdlib, kernel, mnesia, sasl]}, 412 {rel, RelName2, RelVsn, [stdlib, kernel, sasl, mnesia]}, 413 {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools, mnesia]}, 414 {rel, RelName4, RelVsn, [stdlib, kernel, z, mnesia, tools]}, 415 {rel, RelName5, RelVsn, [stdlib, kernel, {sasl,[tools]}]}, 416 {rel, RelName6, RelVsn, [z]}, 417 {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, 418 {rel, RelName8, RelVsn, [stdlib, kernel, {z,[mnesia,tools]}]}, 419 {rel, RelName9, RelVsn, [stdlib, kernel, {z,[]}]}, 420 {rel, RelName10, RelVsn, [stdlib, kernel, {z,[]}, inets, sasl]}, 421 {rel, RelName11, RelVsn, [stdlib, kernel, z, {inets, load}]}, 422 {incl_cond,exclude}, 423 {mod_cond,app}, 424 {app,kernel,[{incl_cond,include}]}, 425 {app,stdlib,[{incl_cond,include}]}, 426 {app,mnesia,[{incl_cond,include}]}, 427 {app,sasl,[{incl_cond,include}]}, 428 {app,inets,[{incl_cond,include}]}, 429 {app,x,[{incl_cond,include}]}, 430 {app,y,[{incl_cond,include}]}, 431 {app,z,[{incl_cond,include}]}, 432 {app,tools,[{mod_cond,app},{incl_cond,include}]} 433 ]}, 434 %% Generate release 435 ?msym({ok, {release, {RelName1, RelVsn}, 436 {erts, _}, 437 [{kernel, _}, 438 {stdlib, _}, 439 {mnesia, _}, 440 {sasl, _}]}}, 441 reltool:get_rel([{config, Sys}], RelName1)), 442 443 ?msym({ok, {release, {RelName2, RelVsn}, 444 {erts, _}, 445 [{kernel, _}, 446 {stdlib, _}, 447 {sasl, _}, 448 {mnesia, _}]}}, 449 reltool:get_rel([{config, Sys}], RelName2)), 450 451 ?msym({ok, {release, {RelName3, RelVsn}, 452 {erts, _}, 453 [{kernel, _}, 454 {stdlib, _}, 455 {sasl, _}, 456 {inets, _}, 457 {tools, _}, 458 {z, _, [tools]}, 459 {mnesia, _}]}}, 460 reltool:get_rel([{config, Sys}], RelName3)), 461 462 ?msym({ok, {release, {RelName4, RelVsn}, 463 {erts, _}, 464 [{kernel, _}, 465 {stdlib, _}, 466 {sasl, _}, 467 {inets, _}, 468 {mnesia, _}, 469 {tools, _}, 470 {z, _}]}}, 471 reltool:get_rel([{config, Sys}], RelName4)), 472 473 ?m({error,"sasl: These applications are used by release " 474 "Include-only-rel but are missing as included_applications " 475 "in the app file: [tools]"}, 476 reltool:get_rel([{config, Sys}], RelName5)), 477 478 ?msym({ok, {release, {RelName6, RelVsn}, 479 {erts, _}, 480 [{kernel, _}, 481 {stdlib, _}, 482 {sasl, _}, 483 {inets, _}, 484 {tools, _}, 485 {mnesia, _}, 486 {z, _}]}}, 487 reltool:get_rel([{config, Sys}], RelName6)), 488 489 ?m({error,"Circular dependencies: [x,y]"}, 490 reltool:get_rel([{config, Sys}], RelName7)), 491 492 ?msym({ok, {release, {RelName8, RelVsn}, 493 {erts, _}, 494 [{kernel, _}, 495 {stdlib, _}, 496 {sasl, _}, 497 {inets, _}, 498 {mnesia, _}, 499 {tools, _}, 500 {z, _, [mnesia,tools]}]}}, 501 reltool:get_rel([{config, Sys}], RelName8)), 502 503 ?msym({ok,{release,{RelName9,RelVsn}, 504 {erts,_}, 505 [{kernel,_}, 506 {stdlib,_}, 507 {sasl, _}, 508 {inets, _}, 509 {z,_,[]}]}}, 510 reltool:get_rel([{config, Sys}], RelName9)), 511 512 ?msym({ok,{release,{RelName10,RelVsn}, 513 {erts,_}, 514 [{kernel,_}, 515 {stdlib,_}, 516 {inets, _}, 517 {sasl, _}, 518 {z,_,[]}]}}, 519 reltool:get_rel([{config, Sys}], RelName10)), 520 521 ?msym({ok,{release,{RelName11,RelVsn}, 522 {erts,_}, 523 [{kernel,_}, 524 {stdlib,_}, 525 {sasl, _}, 526 {inets, _, load}, 527 {tools, _}, 528 {mnesia, _}, 529 {z,_}]}}, 530 reltool:get_rel([{config, Sys}], RelName11)), 531 532 ok. 533 534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 535%% Generate boot scripts 536 537create_script(_Config) -> 538 %% Configure the server 539 RelName = "Just testing", 540 RelVsn = "1.0", 541 Config = 542 {sys, 543 [ 544 {lib_dirs, []}, 545 {boot_rel, RelName}, 546 {rel, RelName, RelVsn, [stdlib, kernel]} 547 ]}, 548 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Config}])), 549 550 %% Generate release file 551 ErtsVsn = erlang:system_info(version), 552 Apps = application:loaded_applications(), 553 {value, {_, _, KernelVsn}} = lists:keysearch(kernel, 1, Apps), 554 {value, {_, _, StdlibVsn}} = lists:keysearch(stdlib, 1, Apps), 555 Rel = {release, 556 {RelName, RelVsn}, 557 {erts, ErtsVsn}, 558 [{kernel, KernelVsn}, {stdlib, StdlibVsn}]}, 559 ?m({ok, Rel}, reltool:get_rel(Pid, RelName)), 560 ?m(ok, file:write_file(filename:join([?WORK_DIR, RelName ++ ".rel"]), 561 io_lib:format("~p.\n", [Rel]))), 562 563 %% Generate script file 564 {ok, Cwd} = file:get_cwd(), 565 ?m(ok, file:set_cwd(?WORK_DIR)), 566 ?m(ok, systools:make_script(RelName, [])), 567 {ok, [OrigScript]} = ?msym({ok, [_]}, file:consult(RelName ++ ".script")), 568 ?m(ok, file:set_cwd(Cwd)), 569 {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)), 570 %% OrigScript2 = sort_script(OrigScript), 571 %% Script2 = sort_script(Script), 572 %% ?m(OrigScript2, Script2), 573 574 ?m(equal, diff_script(OrigScript, Script)), 575 576 %% A release defaults to load_dot_erlang == true 577 {script, {RelName, RelVsn}, ScriptInstructions} = Script, 578 ?m(true, lists:member({apply,{c,erlangrc,[]}}, ScriptInstructions)), 579 580 %% Stop server 581 ?m(ok, reltool:stop(Pid)), 582 ok. 583 584create_script_without_dot_erlang(_Config) -> 585 %% Configure the server 586 RelName = "Just testing", 587 RelVsn = "1.0", 588 Config = 589 {sys, 590 [ 591 {lib_dirs, []}, 592 {boot_rel, RelName}, 593 {rel, RelName, RelVsn, [stdlib, kernel], [{load_dot_erlang, false}]} 594 ]}, 595 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Config}])), 596 597 %% Confirm that load_dot_erlang == false was used 598 {ok, Script} = ?msym({ok, _}, reltool:get_script(Pid, RelName)), 599 {script, {RelName, RelVsn}, ScriptInstructions} = Script, 600 ?m(false, lists:member({apply,{c,erlangrc,[]}}, ScriptInstructions)), 601 602 %% Stop server 603 ?m(ok, reltool:stop(Pid)), 604 ok. 605 606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 607%% Test creation of .script with different sorting of applications and 608%% included applications. 609%% Test that result is equal to what systools produces 610create_script_sort(Config) -> 611 DataDir = ?config(data_dir,Config), 612 %% Configure the server 613 RelName1 = "MnesiaFirst", 614 RelName2 = "SaslFirst", 615 RelName3 = "Include-both", 616 RelName4 = "Include-only-app", 617 RelName5 = "Include-only-rel", 618 RelName6 = "Auto-add-missing-apps", 619 RelName7 = "Circular", 620 RelName8 = "Include-rel-alter-order", 621 RelName9 = "Include-none-overwrite", 622 RelName10= "Uses-order-as-rel", 623 RelVsn = "1.0", 624 LibDir = filename:join(DataDir,"sort_apps"), 625 %% Application z (.app file): 626 %% includes [tools, mnesia] 627 %% uses [kernel, stdlib, sasl, inets, unknown] 628 %% where unknown is optional dependency 629 Sys = 630 {sys, 631 [ 632 {lib_dirs, [LibDir]}, 633 {boot_rel, RelName1}, 634 {rel, RelName1, RelVsn, [stdlib, kernel, mnesia, sasl]}, 635 {rel, RelName2, RelVsn, [stdlib, kernel, sasl, mnesia]}, 636 {rel, RelName3, RelVsn, [stdlib, kernel, {z,[tools]}, tools, mnesia]}, 637 {rel, RelName4, RelVsn, [stdlib, kernel, z, mnesia, tools]}, 638 {rel, RelName5, RelVsn, [stdlib, kernel, {sasl,[tools]}]}, 639 {rel, RelName6, RelVsn, [z]}, 640 {rel, RelName7, RelVsn, [stdlib, kernel, mnesia, y, sasl, x]}, 641 {rel, RelName8, RelVsn, [stdlib, kernel, {z,[mnesia,tools]}]}, 642 {rel, RelName9, RelVsn, [stdlib, kernel, {z,[]}]}, 643 {rel, RelName10, RelVsn, [stdlib, kernel, {z,[]}, inets, sasl]}, 644 {incl_cond,exclude}, 645 {mod_cond,app}, 646 {app,kernel,[{incl_cond,include}]}, 647 {app,stdlib,[{incl_cond,include}]}, 648 {app,mnesia,[{incl_cond,include}]}, 649 {app,sasl,[{incl_cond,include}]}, 650 {app,inets,[{incl_cond,include}]}, 651 {app,x,[{incl_cond,include}]}, 652 {app,y,[{incl_cond,include}]}, 653 {app,z,[{incl_cond,include}]}, 654 {app,tools,[{mod_cond,app},{incl_cond,include}]} 655 ]}, 656 657 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 658 659 %% Generate release files 660 application:load(sasl), 661 application:load(inets), 662 application:load(mnesia), 663 application:load(tools), 664 {ok,KernelVsn} = application:get_key(kernel,vsn), 665 {ok,StdlibVsn} = application:get_key(stdlib,vsn), 666 {ok,SaslVsn} = application:get_key(sasl,vsn), 667 {ok,InetsVsn} = application:get_key(inets,vsn), 668 {ok,MnesiaVsn} = application:get_key(mnesia,vsn), 669 {ok,ToolsVsn} = application:get_key(tools,vsn), 670 ErtsVsn = erlang:system_info(version), 671 672 Rel1 = {release, {RelName1,RelVsn}, {erts,ErtsVsn}, 673 [{kernel,KernelVsn}, 674 {stdlib,StdlibVsn}, 675 {mnesia,MnesiaVsn}, 676 {sasl,SaslVsn}]}, 677 FullName1 = filename:join(?WORK_DIR,RelName1), 678 ?m(ok, file:write_file(FullName1 ++ ".rel", io_lib:format("~p.\n", [Rel1]))), 679 Rel2 = {release, {RelName2,RelVsn}, {erts,ErtsVsn}, 680 [{kernel,KernelVsn}, 681 {stdlib,StdlibVsn}, 682 {sasl,SaslVsn}, 683 {mnesia,MnesiaVsn}]}, 684 FullName2 = filename:join(?WORK_DIR,RelName2), 685 ?m(ok, file:write_file(FullName2 ++ ".rel", io_lib:format("~p.\n", [Rel2]))), 686 Rel3 = {release, {RelName3,RelVsn}, {erts,ErtsVsn}, 687 [{kernel,KernelVsn}, 688 {stdlib,StdlibVsn}, 689 {z,"1.0",[tools]}, 690 {tools,ToolsVsn}, 691 {mnesia,MnesiaVsn}, 692 {sasl,SaslVsn}, 693 {inets,InetsVsn}]}, 694 FullName3 = filename:join(?WORK_DIR,RelName3), 695 ?m(ok, file:write_file(FullName3 ++ ".rel", io_lib:format("~p.\n", [Rel3]))), 696 Rel4 = {release, {RelName4,RelVsn}, {erts,ErtsVsn}, 697 [{kernel,KernelVsn}, 698 {stdlib,StdlibVsn}, 699 {z,"1.0"}, 700 {mnesia,MnesiaVsn}, 701 {tools,ToolsVsn}, 702 {sasl,SaslVsn}, 703 {inets,InetsVsn}]}, 704 FullName4 = filename:join(?WORK_DIR,RelName4), 705 ?m(ok, file:write_file(FullName4 ++ ".rel", io_lib:format("~p.\n", [Rel4]))), 706 Rel5 = {release, {RelName5,RelVsn}, {erts,ErtsVsn}, 707 [{kernel,KernelVsn}, 708 {stdlib,StdlibVsn}, 709 {sasl,SaslVsn,[tools]}, 710 {tools,ToolsVsn}]}, 711 FullName5 = filename:join(?WORK_DIR,RelName5), 712 ?m(ok, file:write_file(FullName5 ++ ".rel", io_lib:format("~p.\n", [Rel5]))), 713 Rel6 = {release, {RelName6,RelVsn}, {erts,ErtsVsn}, 714 [{kernel,KernelVsn}, 715 {stdlib,StdlibVsn}, 716 {sasl,SaslVsn}, 717 {inets,InetsVsn}, 718 {tools,ToolsVsn}, 719 {mnesia,MnesiaVsn}, 720 {z,"1.0"}]}, 721 FullName6 = filename:join(?WORK_DIR,RelName6), 722 ?m(ok, file:write_file(FullName6 ++ ".rel", io_lib:format("~p.\n", [Rel6]))), 723 Rel7 = {release, {RelName7,RelVsn}, {erts,ErtsVsn}, 724 [{kernel,KernelVsn}, 725 {stdlib,StdlibVsn}, 726 {mnesia,MnesiaVsn}, 727 {y,"1.0"}, 728 {sasl,SaslVsn}, 729 {x,"1.0"}]}, 730 FullName7 = filename:join(?WORK_DIR,RelName7), 731 ?m(ok, file:write_file(FullName7 ++ ".rel", io_lib:format("~p.\n", [Rel7]))), 732 Rel8 = {release, {RelName8,RelVsn}, {erts,ErtsVsn}, 733 [{kernel,KernelVsn}, 734 {stdlib,StdlibVsn}, 735 {z,"1.0",[mnesia,tools]}, 736 {sasl,SaslVsn}, 737 {inets,InetsVsn}, 738 {mnesia,MnesiaVsn}, 739 {tools,ToolsVsn}]}, 740 FullName8 = filename:join(?WORK_DIR,RelName8), 741 ?m(ok, file:write_file(FullName8 ++ ".rel", io_lib:format("~p.\n", [Rel8]))), 742 Rel9 = {release, {RelName9,RelVsn}, {erts,ErtsVsn}, 743 [{kernel,KernelVsn}, 744 {stdlib,StdlibVsn}, 745 {z,"1.0",[]}, 746 {sasl,SaslVsn}, 747 {inets,InetsVsn}]}, 748 FullName9 = filename:join(?WORK_DIR,RelName9), 749 ?m(ok, file:write_file(FullName9 ++ ".rel", io_lib:format("~p.\n", [Rel9]))), 750 Rel10 = {release, {RelName10,RelVsn}, {erts,ErtsVsn}, 751 [{kernel,KernelVsn}, 752 {stdlib,StdlibVsn}, 753 {z,"1.0",[]}, 754 {inets,InetsVsn}, 755 {sasl,SaslVsn}]}, 756 FullName10 = filename:join(?WORK_DIR,RelName10), 757 ?m(ok, file:write_file(FullName10 ++ ".rel", io_lib:format("~p.\n", [Rel10]))), 758 759 %% Generate script files with systools and reltool and compare 760 ZPath = filename:join([LibDir,"*",ebin]), 761 762 ?msym({ok,_,_}, systools_make_script(FullName1,ZPath)), 763 {ok, [SystoolsScript1]} = ?msym({ok,[_]}, file:consult(FullName1++".script")), 764 {ok, Script1} = ?msym({ok, _}, reltool:get_script(Pid, RelName1)), 765 ?m(equal, diff_script(SystoolsScript1, Script1)), 766 767 ?msym({ok,_,_}, systools_make_script(FullName2,ZPath)), 768 {ok, [SystoolsScript2]} = ?msym({ok,[_]}, file:consult(FullName2++".script")), 769 {ok, Script2} = ?msym({ok, _}, reltool:get_script(Pid, RelName2)), 770 ?m(equal, diff_script(SystoolsScript2, Script2)), 771 772 ?msym({ok,_,_}, systools_make_script(FullName3,ZPath)), 773 {ok, [SystoolsScript3]} = ?msym({ok,[_]}, file:consult(FullName3++".script")), 774 {ok, Script3} = ?msym({ok, _}, reltool:get_script(Pid, RelName3)), 775 ?m(equal, diff_script(SystoolsScript3, Script3)), 776 777 ?msym({ok,_,_}, systools_make_script(FullName4,ZPath)), 778 {ok, [SystoolsScript4]} = ?msym({ok,[_]}, file:consult(FullName4++".script")), 779 {ok, Script4} = ?msym({ok, _}, reltool:get_script(Pid, RelName4)), 780 ?m(equal, diff_script(SystoolsScript4, Script4)), 781 782 ?msym({error,_,[{error_reading,{sasl,{override_include,_}}}]}, 783 systools_make_script(FullName5,ZPath)), 784 ?m({error,"sasl: These applications are used by release " 785 "Include-only-rel but are missing as included_applications " 786 "in the app file: [tools]"}, 787 reltool:get_script(Pid, RelName5)), 788 789 ?msym({ok,_,_}, systools_make_script(FullName6,ZPath)), 790 {ok, [SystoolsScript6]} = ?msym({ok,[_]}, file:consult(FullName6++".script")), 791 {ok, Script6} = ?msym({ok, _}, reltool:get_script(Pid, RelName6)), 792 ?m(equal, diff_script(SystoolsScript6, Script6)), 793 794 ?msym({error,_,{circular_dependencies,_}}, 795 systools_make_script(FullName7,ZPath)), 796 ?m({error,"Circular dependencies: [x,y]"}, 797 reltool:get_script(Pid, RelName7)), 798 799 ?msym({ok,_,_}, systools_make_script(FullName8,ZPath)), 800 {ok, [SystoolsScript8]} = ?msym({ok,[_]}, file:consult(FullName8++".script")), 801 {ok, Script8} = ?msym({ok, _}, reltool:get_script(Pid, RelName8)), 802 ?m(equal, diff_script(SystoolsScript8, Script8)), 803 804 ?msym({ok,_,_}, systools_make_script(FullName9,ZPath)), 805 {ok, [SystoolsScript9]} = ?msym({ok,[_]}, file:consult(FullName9++".script")), 806 {ok, Script9} = ?msym({ok, _}, reltool:get_script(Pid, RelName9)), 807 ?m(equal, diff_script(SystoolsScript9, Script9)), 808 809 ?msym({ok,_,_}, systools_make_script(FullName10,ZPath)), 810 {ok, [SystoolsScript10]} = ?msym({ok,[_]}, file:consult(FullName10++".script")), 811 {ok, Script10} = ?msym({ok, _}, reltool:get_script(Pid, RelName10)), 812 ?m(equal, diff_script(SystoolsScript10, Script10)), 813 814 %% Stop server 815 ?m(ok, reltool:stop(Pid)), 816 ok. 817 818 819systools_make_script(Name,Path) -> 820 systools:make_script(Name,[{path,[Path]},{outdir,?WORK_DIR},silent]). 821 822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 823%% Generate target system 824 825create_target(_Config) -> 826 %% Configure the server 827 RelName1 = "Just testing", 828 RelName2 = "Just testing with SASL", 829 RelVsn = "1.0", 830 Config = 831 {sys, 832 [ 833 {root_dir, code:root_dir()}, 834 {lib_dirs, []}, 835 {boot_rel, RelName2}, 836 {rel, RelName1, RelVsn, [stdlib, kernel]}, 837 {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, 838 {app, sasl, [{incl_cond, include}]} 839 ]}, 840 841 %% Generate target file 842 TargetDir = filename:join([?WORK_DIR, "target_development"]), 843 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 844 ?m(ok, file:make_dir(TargetDir)), 845 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Config}])]), 846 ok = ?m(ok, reltool:create_target([{config, Config}], TargetDir)), 847 848 Erl = filename:join([TargetDir, "bin", "erl"]), 849 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 850 ?msym(ok, stop_node(Node)), 851 852 ok. 853 854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 855%% Generate target system 856 857create_target_unicode(Config) -> 858 DataDir = ?config(data_dir,Config), 859 860 %% If file name translation mode is unicode, then use unicode 861 %% characters release name (which will be used as file name for 862 %% .rel, .script and .boot), and install the release under a path 863 %% which icludes unicode characters. 864 {RelNamePrefix,TargetDirName} = 865 case file:native_name_encoding() of 866 utf8 -> 867 {"Unicode test αβ","target_unicode_αβ"} ; 868 latin1 -> 869 {"Unicode test","target_unicode"} 870 end, 871 872 %% Configure the server 873 RelName1 = RelNamePrefix, 874 RelName2 = RelNamePrefix ++ " with SASL", 875 RelVsn = "1.0", 876 Sys = 877 {sys, 878 [ 879 {root_dir, code:root_dir()}, 880 {lib_dirs, [filename:join(DataDir,"unicode")]}, 881 {app_file, all}, 882 {incl_cond,exclude}, 883 {boot_rel, RelName2}, 884 {rel, RelName1, RelVsn, [stdlib, kernel, ua]}, 885 {rel, RelName2, RelVsn, [sasl, stdlib, kernel, ua]}, 886 {app, kernel, [{incl_cond, include}]}, 887 {app, stdlib, [{incl_cond, include}]}, 888 {app, sasl, [{incl_cond, include}]}, 889 {app, ua, [{incl_cond, include}]} 890 ]}, 891 892 %% Generate target file 893 TargetDir = filename:join([?WORK_DIR, TargetDirName]), 894 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 895 ?m(ok, file:make_dir(TargetDir)), 896 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 897 ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), 898 899 %% Start a node 900 Erl = filename:join([TargetDir, "bin", "erl"]), 901 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 902 903 904 %% The ua application has a unicode string as description - check 905 %% that it is translated correctly. 906 wait_for_app(Node,ua,50), 907 Apps = rpc:call(Node,application,which_applications,[]), 908 ?m({ua,"Application for testing unicode in reltool - αβ","1.0"}, 909 lists:keyfind(ua,1,Apps)), 910 911 %% Check that the release name is correct (really only 912 %% insteresting if file name translation mode is utf8) 913 [{RelName,_,_,_}] = 914 ?msym([{_,_,_,_}],rpc:call(Node,release_handler,which_releases,[])), 915 ?m(true,lists:prefix(RelNamePrefix,RelName)), 916 917 ?msym(ok, stop_node(Node)), 918 919 ok. 920 921%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 922%% Generate embedded target system 923 924create_embedded(_Config) -> 925 %% Configure the server 926 RelName1 = "Just testing", 927 RelName2 = "Just testing with SASL", 928 RelVsn = "1.0", 929 Config = 930 {sys, 931 [ 932 {lib_dirs, []}, 933 {profile, embedded}, 934 {boot_rel, RelName2}, 935 {rel, RelName1, RelVsn, [stdlib, kernel]}, 936 {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, 937 {app, sasl, [{incl_cond, include}]} 938 ]}, 939 940 %% Generate target file 941 TargetDir = filename:join([?WORK_DIR, "target_embedded"]), 942 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 943 ?m(ok, file:make_dir(TargetDir)), 944 ok = ?m(ok, reltool:create_target([{config, Config}], TargetDir)), 945 946 Erl = filename:join([TargetDir, "bin", "erl"]), 947 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 948 ?msym(ok, stop_node(Node)), 949 950 ok. 951 952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 953%% Generate standalone system 954 955create_standalone(_Config) -> 956 %% Configure the server 957 ExDir = code:lib_dir(reltool, examples), 958 EscriptName = "display_args", 959 Escript = filename:join([ExDir, EscriptName]), 960 Config = 961 {sys, 962 [ 963 {lib_dirs, []}, 964 {escript, Escript, [{incl_cond, include}]}, 965 {profile, standalone} 966 ]}, 967 968 %% Generate target file 969 TargetDir = filename:join([?WORK_DIR, "target_standalone"]), 970 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 971 ?m(ok, file:make_dir(TargetDir)), 972 ok = ?m(ok, reltool:create_target([{config, Config}], TargetDir)), 973 974 %% Start the target system and fetch root dir 975 BinDir = filename:join([TargetDir, "bin"]), 976 Erl = filename:join([BinDir, "erl"]), 977 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 978 RootDir = ?ignore(rpc:call(Node, code, root_dir, [])), 979 ?msym(ok, stop_node(Node)), 980 981 %% Execute escript 982 Expected = s2b(["Root dir: ", RootDir, "\n" 983 "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", 984 "Emuarg: [\"emuvalue\"]\n", 985 "ExitCode:0"]), 986 io:format("Expected: ~ts\n", [Expected]), 987 ?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")), 988 989 ok. 990 991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 992%% Generate standalone system with inlined beam file 993 994create_standalone_beam(Config) -> 995 %% Read beam file 996 DataDir = ?config(data_dir,Config), 997 BeamFile = filename:join([DataDir,escript,"someapp-1.0",ebin,"mymod.beam"]), 998 {ok,BeamBin} = file:read_file(BeamFile), 999 1000 %% Create the escript 1001 EscriptName = "mymod.escript", 1002 Escript = filename:join(?WORK_DIR,EscriptName), 1003 ok = escript:create(Escript,[shebang,{beam,BeamBin}]), 1004 ok = file:change_mode(Escript,8#00744), 1005 1006 %% Configure the server 1007 Sys = 1008 {sys, 1009 [ 1010 {lib_dirs, []}, 1011 {escript, Escript, [{incl_cond, include}]}, 1012 {profile, standalone} 1013 ]}, 1014 1015 %% Generate target file 1016 TargetDir = filename:join([?WORK_DIR, "target_standalone_beam"]), 1017 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1018 ?m(ok, file:make_dir(TargetDir)), 1019 ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), 1020 1021 %% Start the target system and fetch root dir 1022 BinDir = filename:join([TargetDir, "bin"]), 1023 Erl = filename:join([BinDir, "erl"]), 1024 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1025 RootDir = ?ignore(rpc:call(Node, code, root_dir, [])), 1026 ?msym(ok, stop_node(Node)), 1027 1028 %% Execute escript 1029 Expected = s2b(["Module: mymod\n" 1030 "Root dir: ", RootDir, "\n" 1031 "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", 1032 "ExitCode:0"]), 1033 io:format("Expected: ~ts\n", [Expected]), 1034 ?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")), 1035 1036 ok. 1037 1038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1039%% Generate standalone system with inlined archived application 1040 1041create_standalone_app(Config) -> 1042 %% Create archive 1043 DataDir = ?config(data_dir,Config), 1044 EscriptDir = filename:join(DataDir,escript), 1045 {ok,{_Archive,Bin}} = zip:create("someapp-1.0.ez",["someapp-1.0"], 1046 [memory, 1047 {cwd,EscriptDir}, 1048 {compress,all}, 1049 {uncompress,[".beam",".app"]}]), 1050 1051 %% Create the escript 1052 EscriptName = "someapp.escript", 1053 Escript = filename:join(?WORK_DIR,EscriptName), 1054 ok = escript:create(Escript,[shebang, 1055 {emu_args,"-escript main mymod"}, 1056 {archive,Bin}]), 1057 ok = file:change_mode(Escript,8#00744), 1058 1059 %% Configure the server 1060 Sys = 1061 {sys, 1062 [ 1063 {lib_dirs, []}, 1064 {escript, Escript, [{incl_cond, include}]}, 1065 {profile, standalone} 1066 ]}, 1067 1068 %% Generate target file 1069 TargetDir = filename:join([?WORK_DIR, "target_standalone_app"]), 1070 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1071 ?m(ok, file:make_dir(TargetDir)), 1072 ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), 1073 1074 %% Start the target system and fetch root dir 1075 BinDir = filename:join([TargetDir, "bin"]), 1076 Erl = filename:join([BinDir, "erl"]), 1077 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1078 RootDir = ?ignore(rpc:call(Node, code, root_dir, [])), 1079 ?msym(ok, stop_node(Node)), 1080 1081 %% Execute escript 1082 Expected = s2b(["Module: mymod\n" 1083 "Root dir: ", RootDir, "\n" 1084 "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", 1085 "ExitCode:0"]), 1086 io:format("Expected: ~ts\n", [Expected]), 1087 ?m(Expected, run(BinDir, EscriptName, "-arg1 arg2 arg3")), 1088 1089 ok. 1090 1091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1092%% Generate standalone system with inlined archived application 1093%% Check that the inlined app cannot be explicitly configured 1094 1095create_standalone_app_clash(Config) -> 1096 %% Create archive 1097 DataDir = ?config(data_dir,Config), 1098 EscriptDir = filename:join(DataDir,escript), 1099 {ok,{_Archive,Bin}} = zip:create("someapp-1.0.ez",["someapp-1.0"], 1100 [memory, 1101 {cwd,EscriptDir}, 1102 {compress,all}, 1103 {uncompress,[".beam",".app"]}]), 1104 1105 %% Create the escript 1106 EscriptName = "someapp.escript", 1107 Escript = filename:join(?WORK_DIR,EscriptName), 1108 ok = escript:create(Escript,[shebang, 1109 {emu_args,"-escript main mymod"}, 1110 {archive,Bin}]), 1111 ok = file:change_mode(Escript,8#00744), 1112 1113 %% Configure the server 1114 Sys = 1115 {sys, 1116 [ 1117 {lib_dirs, []}, 1118 {escript, Escript, [{incl_cond, include}]}, 1119 {profile, standalone}, 1120 {app, someapp, [{incl_cond,include}]} 1121 ]}, 1122 1123 ?msym({error,"someapp: Application name clash. Escript "++_}, 1124 reltool:start_server([{config,Sys}])), 1125 ok. 1126 1127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1128%% Generate standalone system with multiple escripts 1129 1130create_multiple_standalone(Config) -> 1131 %% First escript 1132 ExDir = code:lib_dir(reltool, examples), 1133 EscriptName1 = "display_args", 1134 Escript1 = filename:join([ExDir, EscriptName1]), 1135 1136 %% Second escript 1137 DataDir = ?config(data_dir,Config), 1138 BeamFile = filename:join([DataDir,escript,"someapp-1.0",ebin,"mymod.beam"]), 1139 {ok,BeamBin} = file:read_file(BeamFile), 1140 EscriptName2 = "mymod.escript", 1141 Escript2 = filename:join(?WORK_DIR,EscriptName2), 1142 ok = escript:create(Escript2,[shebang,{beam,BeamBin}]), 1143 ok = file:change_mode(Escript2,8#00744), 1144 1145 %% Configure server 1146 Sys = 1147 {sys, 1148 [ 1149 {lib_dirs, []}, 1150 {escript, Escript1, [{incl_cond, include}]}, 1151 {escript, Escript2, [{incl_cond, include}]}, 1152 {profile, standalone} 1153 ]}, 1154 1155 %% Generate target system 1156 TargetDir = filename:join([?WORK_DIR, "target_multiple_standalone"]), 1157 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1158 ?m(ok, file:make_dir(TargetDir)), 1159 ok = ?m(ok, reltool:create_target([{config,Sys}], TargetDir)), 1160 1161 %% Start the target system and fetch root dir 1162 BinDir = filename:join([TargetDir, "bin"]), 1163 Erl = filename:join([BinDir, "erl"]), 1164 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1165 RootDir = ?ignore(rpc:call(Node, code, root_dir, [])), 1166 ?msym(ok, stop_node(Node)), 1167 1168 %% Execute escript1 1169 Expected1 = s2b(["Root dir: ", RootDir, "\n" 1170 "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", 1171 "Emuarg: [\"emuvalue\"]\n", 1172 "ExitCode:0"]), 1173 io:format("Expected1: ~ts\n", [Expected1]), 1174 ?m(Expected1, run(BinDir, EscriptName1, "-arg1 arg2 arg3")), 1175 1176 1177 %% Execute escript2 1178 Expected2 = s2b(["Module: mymod\n" 1179 "Root dir: ", RootDir, "\n" 1180 "Script args: [\"-arg1\",\"arg2\",\"arg3\"]\n", 1181 "ExitCode:0"]), 1182 io:format("Expected2: ~ts\n", [Expected2]), 1183 ?m(Expected2, run(BinDir, EscriptName2, "-arg1 arg2 arg3")), 1184 1185 ok. 1186 1187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1188%% Generate old type of target system 1189create_old_target(_Config) -> 1190 1191 %% Configure the server 1192 RelName1 = "Just testing", 1193 RelName2 = "Just testing with SASL", 1194 RelVsn = "1.0", 1195 Config = 1196 {sys, 1197 [ 1198 {lib_dirs, []}, 1199 {boot_rel, RelName2}, 1200 {rel, RelName1, RelVsn, [stdlib, kernel]}, 1201 {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, 1202 {relocatable, false}, % Implies explicit old style installation 1203 {app, sasl, [{incl_cond, include}]} 1204 ]}, 1205 1206 %% Generate target file 1207 TargetDir = filename:join([?WORK_DIR, "target_old_style"]), 1208 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1209 ?m(ok, file:make_dir(TargetDir)), 1210 ok = ?m(ok, reltool:create_target([{config, Config}], TargetDir)), 1211 1212 ok = ?m(ok, reltool:install(RelName2, TargetDir)), 1213 1214 Erl = filename:join([TargetDir, "bin", "erl"]), 1215 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1216 ?msym(ok, stop_node(Node)), 1217 1218 ok. 1219 1220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1221%% Generate target system 1222 1223create_slim(Config) -> 1224 %% Configure the server 1225 RelName = "slim", 1226 RelVsn = "1.0", 1227 1228 DataDir = ?config(data_dir,Config), 1229 LibDir = filename:join(DataDir,"slim"), 1230 1231 Sys = 1232 {sys, 1233 [ 1234 {root_dir, code:root_dir()}, 1235 {lib_dirs, []}, 1236 {boot_rel, RelName}, 1237 {rel, RelName, RelVsn, [sasl, stdlib, kernel, a]}, 1238 {app, sasl, [{incl_cond, include}]}, 1239 {app, a, [{incl_cond, include}, 1240 {lib_dir,filename:join(LibDir,"a-1.0")}]}, 1241 {excl_lib,otp_root} 1242 ]}, 1243 1244 %% Generate target file 1245 TargetDir = filename:absname(filename:join([?WORK_DIR, "target_slim"])), 1246 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1247 ?m(ok, file:make_dir(TargetDir)), 1248 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 1249 ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), 1250 1251 TargetLibDir = filename:join(TargetDir,"lib"), 1252 TargetRelDir = filename:join(TargetDir,"releases"), 1253 TargetRelVsnDir = filename:join(TargetRelDir,RelVsn), 1254 1255 {ok,["a-1.0.ez"]} = file:list_dir(TargetLibDir), 1256 1257 RootDir = code:root_dir(), 1258 Erl = filename:join([RootDir, "bin", "erl"]), 1259 Args = ["-boot_var", "RELTOOL_EXT_LIB", TargetLibDir, 1260 "-boot", filename:join(TargetRelVsnDir,RelName), 1261 "-sasl", "releases_dir", "\""++TargetRelDir++"\""], 1262 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl, Args)), 1263 ?msym(RootDir, rpc:call(Node, code, root_dir, [])), 1264 wait_for_app(Node,sasl,50), 1265 ?msym([{RelName,RelVsn,_,permanent}], 1266 rpc:call(Node,release_handler,which_releases,[])), 1267 ?msym(ok, stop_node(Node)), 1268 1269 ok. 1270 1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1272%% Generate target system with eval_target_spec/3 1273 1274eval_target_spec(_Config) -> 1275 %% Configure the server 1276 RelName1 = "Just testing", 1277 RelName2 = "Just testing with SASL", 1278 RelVsn = "1.0", 1279 Config = 1280 {sys, 1281 [ 1282 {root_dir, code:root_dir()}, 1283 {lib_dirs, []}, 1284 {boot_rel, RelName2}, 1285 {rel, RelName1, RelVsn, [stdlib, kernel]}, 1286 {rel, RelName2, RelVsn, [sasl, stdlib, kernel]}, 1287 {app, sasl, [{incl_cond, include}]} 1288 ]}, 1289 1290 %% Generate target file 1291 TargetDir = filename:join([?WORK_DIR, "eval_target_spec"]), 1292 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1293 ?m(ok, file:make_dir(TargetDir)), 1294 {ok, Spec} = ?msym({ok,_}, reltool:get_target_spec([{config, Config}])), 1295 ok = ?m(ok, reltool:eval_target_spec(Spec, code:root_dir(), TargetDir)), 1296 1297 Erl = filename:join([TargetDir, "bin", "erl"]), 1298 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1299 ?msym(ok, stop_node(Node)), 1300 1301 ok. 1302 1303%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1304%% OTP-9229 - handle duplicated module names, i.e. same module name 1305%% exists in two applications. 1306 1307%% Include on app, exclude the other 1308otp_9229_dupl_mod_exclude_app(Config) -> 1309 DataDir = ?config(data_dir,Config), 1310 LibDir = filename:join(DataDir,"otp_9229"), 1311 1312 %% Configure the server 1313 ExclApp = 1314 {sys, 1315 [ 1316 {root_dir, code:root_dir()}, 1317 {lib_dirs, [LibDir]}, 1318 {incl_cond,exclude}, 1319 {app,x,[{incl_cond,include}]}, 1320 {app,y,[{incl_cond,exclude}]}, 1321 {app,kernel,[{incl_cond,include}]}, 1322 {app,stdlib,[{incl_cond,include}]}, 1323 {app,sasl,[{incl_cond,include}]} 1324 ]}, 1325 1326 %% Generate target file 1327 TargetDir = filename:join([?WORK_DIR, "target_dupl_mod_excl_app"]), 1328 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1329 ?m(ok, file:make_dir(TargetDir)), 1330 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, ExclApp}])]), 1331 ?m({ok,["Module mylib exists in applications x and y. Using module from application x."]}, reltool:get_status([{config, ExclApp}])), 1332 ok = ?m(ok, reltool:create_target([{config, ExclApp}], TargetDir)), 1333 1334 Erl = filename:join([TargetDir, "bin", "erl"]), 1335 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1336 1337 AbsTargetDir = filename:absname(TargetDir), 1338 XArchive = "x-1.0.ez", 1339 AbsXArchive = filename:join([AbsTargetDir,lib,XArchive]), 1340 XEbin = ["ebin","x-1.0",XArchive], 1341 YArchive = "y-1.0.ez", 1342 AbsYArchive = filename:join([AbsTargetDir,lib,YArchive]), 1343 1344 ?m(true, filelib:is_file(AbsXArchive)), 1345 ?m(XEbin, mod_path(Node,x)), 1346 ?m(XEbin, mod_path(Node,mylib)), 1347 ?m(false, filelib:is_file(AbsYArchive)), 1348 ?m(non_existing, mod_path(Node,y)), 1349 1350 ?msym(ok, stop_node(Node)), 1351 1352 ok. 1353 1354%% Include both apps, but exclude common module from one app 1355otp_9229_dupl_mod_exclude_mod(Config) -> 1356 DataDir = ?config(data_dir,Config), 1357 LibDir = filename:join(DataDir,"otp_9229"), 1358 1359 %% Configure the server 1360 ExclMod = 1361 {sys, 1362 [ 1363 {root_dir, code:root_dir()}, 1364 {lib_dirs, [LibDir]}, 1365 {incl_cond,exclude}, 1366 {app,x,[{incl_cond,include}]}, 1367 {app,y,[{incl_cond,include},{mod, mylib,[{incl_cond,exclude}]}]}, 1368 {app,kernel,[{incl_cond,include}]}, 1369 {app,stdlib,[{incl_cond,include}]}, 1370 {app,sasl,[{incl_cond,include}]} 1371 ]}, 1372 1373 %% Generate target file 1374 TargetDir = filename:join([?WORK_DIR, "target_dupl_mod_excl_mod"]), 1375 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1376 ?m(ok, file:make_dir(TargetDir)), 1377 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, ExclMod}])]), 1378 ?m({ok,["Module mylib exists in applications x and y. Using module from application x."]}, reltool:get_status([{config, ExclMod}])), 1379 ok = ?m(ok, reltool:create_target([{config, ExclMod}], TargetDir)), 1380 1381 Erl = filename:join([TargetDir, "bin", "erl"]), 1382 {ok, Node} = ?msym({ok, _}, start_node(?NODE_NAME, Erl)), 1383 1384 AbsTargetDir = filename:absname(TargetDir), 1385 XArchive = "x-1.0.ez", 1386 AbsXArchive = filename:join([AbsTargetDir,lib,XArchive]), 1387 XEbin = ["ebin","x-1.0",XArchive], 1388 YArchive = "y-1.0.ez", 1389 AbsYArchive = filename:join([AbsTargetDir,lib,YArchive]), 1390 YEbin = ["ebin","y-1.0",YArchive], 1391 1392 ?m(true, filelib:is_file(AbsXArchive)), 1393 ?m(XEbin, mod_path(Node,x)), 1394 ?m(XEbin, mod_path(Node,mylib)), 1395 ?m(true, filelib:is_file(AbsYArchive)), 1396 ?m(YEbin, mod_path(Node,y)), 1397 1398 %% Remove path to XEbin and check that mylib is not located in YEbin 1399 Mylib = rpc:call(Node,code,which,[mylib]), 1400 rpc:call(Node,code,del_path,[filename:dirname(Mylib)]), 1401 ?m(non_existing, mod_path(Node,mylib)), 1402 1403 ?msym(ok, stop_node(Node)), 1404 1405 ok. 1406 1407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1408%% Test that if a module is duplicated in a .app file, then a warning 1409%% is produced, but target can still be created. 1410dupl_mod_in_app_file(Config) -> 1411 DataDir = ?config(data_dir,Config), 1412 LibDir = filename:join(DataDir,"dupl_mod"), 1413 1414 %% Configure the server 1415 Sys = 1416 {sys, 1417 [ 1418 {lib_dirs, [LibDir]}, 1419 {incl_cond,exclude}, 1420 {app,a,[{incl_cond,include}]}, 1421 {app,kernel,[{incl_cond,include}]}, 1422 {app,stdlib,[{incl_cond,include}]}, 1423 {app,sasl,[{incl_cond,include}]} 1424 ]}, 1425 1426 %% Generate target file 1427 TargetDir = filename:join([?WORK_DIR, "target_dupl_mod_in_app_file"]), 1428 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1429 ?m(ok, file:make_dir(TargetDir)), 1430 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 1431 ?m({ok,["Module a duplicated in app file for application a."]}, 1432 reltool:get_status([{config, Sys}])), 1433 1434 %%! test that only one module installed (in spec) 1435 1436 ok. 1437 1438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1439%% Test that a reasonable error message is returned if an application 1440%% is missing 1441include_non_existing_app(_Config) -> 1442 %% Configure the server 1443 Sys = 1444 {sys, 1445 [ 1446 {incl_cond,exclude}, 1447 {app,foobar,[{incl_cond,include}]}, 1448 {app,kernel,[{incl_cond,include}]}, 1449 {app,stdlib,[{incl_cond,include}]}, 1450 {app,sasl,[{incl_cond,include}]} 1451 ]}, 1452 1453 %% Generate target file 1454 TargetDir = filename:join([?WORK_DIR, "target_include_non_existing_app"]), 1455 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1456 ?m(ok, file:make_dir(TargetDir)), 1457 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 1458 ?m({error,"foobar: Missing application directory."}, 1459 reltool:get_status([{config, Sys}])), 1460 1461 ok. 1462 1463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1464%% Test that if a missing application is explicitly excluded a warning 1465%% should be issued. 1466exclude_non_existing_app(_Config) -> 1467 %% Configure the server 1468 Sys = 1469 {sys, 1470 [ 1471 {incl_cond,exclude}, 1472 {app,foobar,[{incl_cond,exclude}]}, 1473 {app,kernel,[{incl_cond,include}]}, 1474 {app,stdlib,[{incl_cond,include}]}, 1475 {app,sasl,[{incl_cond,include}]} 1476 ]}, 1477 1478 %% Generate target file 1479 TargetDir = filename:join([?WORK_DIR, "target_exclude_non_existing_app"]), 1480 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 1481 ?m(ok, file:make_dir(TargetDir)), 1482 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 1483 ?m({ok,["foobar: Missing application directory."]}, 1484 reltool:get_status([{config, Sys}])), 1485 1486 ok. 1487 1488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1489%% Test the interface used by the GUI: 1490%% get_app 1491%% get_apps 1492%% set_app 1493%% set_apps 1494%% load_config 1495%% reset_config 1496%% 1497%% Also, for each operation which manipulates the config, test 1498%% get_status and undo_config. 1499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1500get_apps(_Config) -> 1501 Sys = {sys,[{app,kernel,[{incl_cond,include}]}, 1502 {app,sasl,[{incl_cond,include}]}, 1503 {app,stdlib,[{incl_cond,include}]}, 1504 {app,tools,[{incl_cond,derived}]}, 1505 {app,runtime_tools,[{incl_cond,exclude}]}]}, 1506 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1507 1508 {ok,Sasl} = ?msym({ok,#app{name=sasl}}, reltool_server:get_app(Pid,sasl)), 1509 {ok,[#app{name=kernel}, 1510 #app{name=sasl}=Sasl, 1511 #app{name=stdlib}] = White} = 1512 ?msym({ok,_}, reltool_server:get_apps(Pid,whitelist)), 1513 {ok,[#app{name=runtime_tools}] = Black} = 1514 ?msym({ok,_}, reltool_server:get_apps(Pid,blacklist)), 1515 1516 {ok,Derived} = ?msym({ok,_}, reltool_server:get_apps(Pid,derived)), 1517 true = lists:keymember(tools,#app.name,Derived), 1518 1519 {ok,Source} = ?msym({ok,_}, reltool_server:get_apps(Pid,source)), 1520 true = lists:keymember(common_test,#app.name,Source), 1521 1522 %% Check that the four lists are disjoint 1523 Number = length(White) + length(Black) + length(Derived) + length(Source), 1524 WN = lists:usort([N || #app{name=N} <- White]), 1525 BN = lists:usort([N || #app{name=N} <- Black]), 1526 DN = lists:usort([N || #app{name=N} <- Derived]), 1527 SN = lists:usort([N || #app{name=N} <- Source]), 1528 AllN = lists:umerge([WN,BN,DN,SN]), 1529 ?m(Number,length(AllN)), 1530 1531 ?m(ok, reltool:stop(Pid)), 1532 ok. 1533 1534 1535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1536get_mod(_Config) -> 1537 Sys = {sys,[{app,kernel,[{incl_cond,include}]}, 1538 {app,sasl,[{incl_cond,include}]}, 1539 {app,stdlib,[{incl_cond,include}]}, 1540 {app,tools,[{incl_cond,derived}]}, 1541 {app,runtime_tools,[{incl_cond,exclude}]}]}, 1542 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1543 1544 %% Read app and get a module from the #app record 1545 {ok,Tools} = ?msym({ok,#app{name=tools}}, reltool_server:get_app(Pid,tools)), 1546 Cover = lists:keyfind(cover,#mod.name,Tools#app.mods), 1547 1548 %% get_mod - and check that it is equal to the one in #app.mods 1549 ?m({ok,Cover}, reltool_server:get_mod(Pid,cover)), 1550 1551 ?m(ok, reltool:stop(Pid)), 1552 ok. 1553 1554 1555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1556get_sys(_Config) -> 1557 Sys = {sys,[{app,kernel,[{incl_cond,include}]}, 1558 {app,sasl,[{incl_cond,include}]}, 1559 {app,stdlib,[{incl_cond,include}]}, 1560 {app,tools,[{incl_cond,derived}]}, 1561 {app,runtime_tools,[{incl_cond,exclude}]}]}, 1562 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1563 1564 RootDir = code:root_dir(), 1565 ?msym({ok,#sys{root_dir=RootDir,apps=undefined}},reltool_server:get_sys(Pid)), 1566 1567 ?m(ok, reltool:stop(Pid)), 1568 ok. 1569 1570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1571set_app_and_undo(Config) -> 1572 Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]}, 1573 {incl_cond, exclude}, 1574 {app,a,[{incl_cond,include}]}, 1575 {app,kernel,[{incl_cond,include}]}, 1576 {app,sasl,[{incl_cond,include}]}, 1577 {app,stdlib,[{incl_cond,include}]}, 1578 {app,tools,[{incl_cond,include}]}]}, 1579 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1580 ?m({ok, Sys}, reltool:get_config(Pid)), 1581 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1582 1583 %% Get app and mod 1584 {ok,Tools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1585 {ok,Cover} = ?msym({ok,#mod{name=cover, is_included=true}}, 1586 reltool_server:get_mod(Pid,cover)), 1587 1588 %% Exclude one module with set_app 1589 ExclCover = Cover#mod{incl_cond=exclude}, 1590 Mods = Tools#app.mods, 1591 Tools1 = Tools#app{mods = lists:keyreplace(cover,#mod.name,Mods,ExclCover)}, 1592 {ok,ToolsNoCover,["a: Cannot parse app file"++_|_]} = 1593 ?msym({ok,_,["a: Cannot parse app file"++_|_]}, 1594 reltool_server:set_app(Pid,Tools1)), 1595 ?msym({ok,["a: Cannot parse app file"++_]}, reltool_server:get_status(Pid)), 1596 1597 %% Check that the module is no longer included 1598 ?m({ok,ToolsNoCover}, reltool_server:get_app(Pid,tools)), 1599 {ok,NoIncludeCover} = ?msym({ok,#mod{name=cover, is_included=false}}, 1600 reltool_server:get_mod(Pid,cover)), 1601 1602 %% Undo 1603 ?m(ok, reltool_server:undo_config(Pid)), 1604 ?m({ok,Tools}, reltool_server:get_app(Pid,tools)), 1605 ?m({ok,Cover}, reltool_server:get_mod(Pid,cover)), 1606 ?msym({ok,["a: Cannot parse app file"++_]}, reltool_server:get_status(Pid)), 1607 1608 %% Undo again, to check that it toggles 1609 ?msym(ok, reltool_server:undo_config(Pid)), 1610 ?m({ok,ToolsNoCover}, reltool_server:get_app(Pid,tools)), 1611 ?m({ok,NoIncludeCover}, reltool_server:get_mod(Pid,cover)), 1612 ?msym({ok,["a: Cannot parse app file"++_]}, reltool_server:get_status(Pid)), 1613 1614 ?m(ok, reltool:stop(Pid)), 1615 ok. 1616 1617 1618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1619set_apps_and_undo(Config) -> 1620 Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]}, 1621 {incl_cond, exclude}, 1622 {app,kernel,[{incl_cond,include}]}, 1623 {app,sasl,[{incl_cond,include}]}, 1624 {app,stdlib,[{incl_cond,include}]}, 1625 {app,tools,[{incl_cond,include}]}]}, 1626 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1627 ?m({ok, Sys}, reltool:get_config(Pid)), 1628 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1629 1630 %% Get app and mod 1631 {ok,Tools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1632 ?m(true, Tools#app.is_pre_included), 1633 ?m(true, Tools#app.is_included), 1634 {ok,Cover} = ?msym({ok,#mod{name=cover, is_included=true}}, 1635 reltool_server:get_mod(Pid,cover)), 1636 1637 %% Exclude one application with set_apps 1638 ExclTools = Tools#app{incl_cond=exclude}, 1639 ?msym({ok,["a: Cannot parse app file"++_]}, 1640 reltool_server:set_apps(Pid,[ExclTools])), 1641 ?msym({ok,["a: Cannot parse app file"++_]}, reltool_server:get_status(Pid)), 1642 1643 %% Check that the app and its modules (one of them) are no longer included 1644 {ok,NoTools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1645 ?m(false, NoTools#app.is_pre_included), 1646 ?m(false, NoTools#app.is_included), 1647 {ok,NoIncludeCover} = ?msym({ok,#mod{name=cover, is_included=false}}, 1648 reltool_server:get_mod(Pid,cover)), 1649 1650 %% Undo 1651 ?m(ok, reltool_server:undo_config(Pid)), 1652 ?m({ok,Tools}, reltool_server:get_app(Pid,tools)), 1653 ?m({ok,Cover}, reltool_server:get_mod(Pid,cover)), 1654 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1655 1656 %% Undo again, to check that it toggles 1657 ?m(ok, reltool_server:undo_config(Pid)), 1658 ?m({ok,NoTools}, reltool_server:get_app(Pid,tools)), 1659 ?m({ok,NoIncludeCover}, reltool_server:get_mod(Pid,cover)), 1660 ?msym({ok,["a: Cannot parse app file"++_]}, reltool_server:get_status(Pid)), 1661 1662 ?m(ok, reltool:stop(Pid)), 1663 ok. 1664 1665 1666%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1667%% Test that escript can be configured, but not its inlined applications 1668set_apps_inlined(Config) -> 1669 %% Create archive 1670 DataDir = ?config(data_dir,Config), 1671 EscriptDir = filename:join(DataDir,escript), 1672 {ok,{_Archive,Bin}} = zip:create("someapp-1.0.ez",["someapp-1.0"], 1673 [memory, 1674 {cwd,EscriptDir}, 1675 {compress,all}, 1676 {uncompress,[".beam",".app"]}]), 1677 1678 %% Create the escript 1679 EscriptName = "someapp.escript", 1680 Escript = filename:join(?WORK_DIR,EscriptName), 1681 ok = escript:create(Escript,[shebang, 1682 {emu_args,"-escript main mymod"}, 1683 {archive,Bin}]), 1684 ok = file:change_mode(Escript,8#00744), 1685 1686 %% Configure the server 1687 Sys = {sys,[{incl_cond, exclude}, 1688 {escript,Escript,[]}, 1689 {app,kernel,[{incl_cond,include}]}, 1690 {app,sasl,[{incl_cond,include}]}, 1691 {app,stdlib,[{incl_cond,include}]}]}, 1692 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1693 ?msym({ok,[]},reltool_server:get_status(Pid)), 1694 1695 %% Get app and mod 1696 {ok,EApp} = ?msym({ok,_}, reltool_server:get_app(Pid,'*escript* someapp')), 1697 {ok,Someapp} = ?msym({ok,_}, reltool_server:get_app(Pid,someapp)), 1698 ?m(undefined, EApp#app.incl_cond), 1699 ?m(undefined, Someapp#app.incl_cond), 1700 ?m(false, Someapp#app.is_included), 1701 ?m(false, Someapp#app.is_pre_included), 1702 1703 %% Include escript 1704 EApp1 = EApp#app{incl_cond=include}, 1705 ?m({ok,[]}, reltool_server:set_apps(Pid,[EApp1])), 1706 ExpectedEApp = EApp1#app{is_included=true,is_pre_included=true}, 1707 ?m({ok,ExpectedEApp}, reltool_server:get_app(Pid,'*escript* someapp')), 1708 {ok,Someapp1} = ?msym({ok,_}, reltool_server:get_app(Pid,someapp)), 1709 ?m(include, Someapp1#app.incl_cond), 1710 ?m(true, Someapp1#app.is_included), 1711 ?m(true, Someapp1#app.is_pre_included), 1712 1713 %% Check that inlined app cannot be configured 1714 Someapp2 = Someapp1#app{incl_cond=exclude}, 1715 ?msym({error, 1716 "Application someapp is inlined in '*escript* someapp'. " 1717 "Can not change configuration for an inlined application."}, 1718 reltool_server:set_apps(Pid,[Someapp2])), 1719 ?m({ok,Someapp1}, reltool_server:get_app(Pid,someapp)), 1720 1721 %% Exclude escript 1722 {ok,EApp2} = ?msym({ok,_}, reltool_server:get_app(Pid,'*escript* someapp')), 1723 EApp3 = EApp2#app{incl_cond=exclude}, 1724 ?m({ok,[]}, reltool_server:set_apps(Pid,[EApp3])), 1725 ExpectedEApp3 = EApp3#app{is_included=false,is_pre_included=false}, 1726 ?m({ok,ExpectedEApp3}, reltool_server:get_app(Pid,'*escript* someapp')), 1727 {ok,Someapp3} = ?msym({ok,_}, reltool_server:get_app(Pid,someapp)), 1728 ?m(exclude, Someapp3#app.incl_cond), 1729 ?m(false, Someapp3#app.is_included), 1730 ?m(false, Someapp3#app.is_pre_included), 1731 1732 ?m(ok, reltool:stop(Pid)), 1733 ok. 1734 1735 1736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1737set_sys_and_undo(Config) -> 1738 Sys1 = {sys,[{incl_cond, exclude}, 1739 {app,kernel,[{incl_cond,include}]}, 1740 {app,sasl,[{incl_cond,include}]}, 1741 {app,stdlib,[{incl_cond,include}]}, 1742 {app,tools,[{incl_cond,include}]}]}, 1743 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 1744 ?m({ok,[]}, reltool_server:get_status(Pid)), 1745 1746 %% Read sys record 1747 {ok, SysRec} = reltool_server:get_sys(Pid), 1748 1749 %% Set lib dirs by call to set_sys 1750 NewLib = filename:join(datadir(Config),"faulty_app_file"), 1751 NewLibDirs = [NewLib | SysRec#sys.lib_dirs], 1752 NewSysRec = SysRec#sys{lib_dirs=NewLibDirs}, 1753 ?msym({ok,["a: Cannot parse app file"++_]}, 1754 reltool_server:set_sys(Pid, NewSysRec)), 1755 ?m({ok,NewSysRec}, reltool_server:get_sys(Pid)), 1756 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1757 1758 %% Undo 1759 ?m(ok, reltool_server:undo_config(Pid)), 1760 ?m({ok,SysRec}, reltool_server:get_sys(Pid)), 1761 ?m({ok,[]}, reltool_server:get_status(Pid)), 1762 1763 %% Undo again, to check that it toggles 1764 ?m(ok,reltool_server:undo_config(Pid)), 1765 ?m({ok,NewSysRec}, reltool_server:get_sys(Pid)), 1766 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1767 1768 ?m(ok, reltool:stop(Pid)), 1769 ok. 1770 1771%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1772load_config_and_undo(Config) -> 1773 Sys1 = {sys,Cfg1=[{incl_cond, exclude}, 1774 {app,kernel,[{incl_cond,include}]}, 1775 {app,sasl,[{incl_cond,include}]}, 1776 {app,stdlib,[{incl_cond,include}]}, 1777 {app,tools,[{incl_cond,include}]}]}, 1778 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 1779 Libs = reltool_test_lib:erl_libs(), 1780 Sys11 = 1781 case Libs of 1782 [] -> Sys1; 1783 _ -> {sys, [{lib_dirs, Libs}|Cfg1]} 1784 end, 1785 ?m({ok, Sys11}, reltool:get_config(Pid)), 1786 ?m({ok,[]}, reltool_server:get_status(Pid)), 1787 1788 %% Get app and mod 1789 {ok,Tools1} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1790 ?m(true, Tools1#app.is_pre_included), 1791 ?m(true, Tools1#app.is_included), 1792 {ok,Cover1} = ?msym({ok,#mod{name=cover, 1793 is_included=true, 1794 is_pre_included=true}}, 1795 reltool_server:get_mod(Pid,cover)), 1796 1797 %% Change tools from include to derived by loading new config 1798 Sys2 = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]}, 1799 {app,a,[{incl_cond,include}]}, 1800 {app,kernel,[{incl_cond,include}]}, 1801 {app,sasl,[{incl_cond,include}]}, 1802 {app,stdlib,[{incl_cond,include}]}, 1803 {app,tools,[{incl_cond,derived}]}]}, 1804 ?msym({ok,["a: Cannot parse app file"++_]}, 1805 reltool_server:load_config(Pid,Sys2)), 1806%%% OTP-0702, 15) ?m({ok, Sys2}, reltool:get_config(Pid)), 1807%%% Note that {incl_cond,exclude} is removed compared to Sys1 - 1808%%% config is merged, not overwritten - is this correct??? 1809 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1810 1811 %% Check that tools is included (since it is used by sasl) but not 1812 %% pre-included (neither included or excluded => undefined) 1813 {ok,Tools2} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1814 ?m(undefined, Tools2#app.is_pre_included), 1815 ?m(true, Tools2#app.is_included), 1816 {ok,Cover2} = ?msym({ok,#mod{name=cover, 1817 is_included=true, 1818 is_pre_included=undefined}}, 1819 reltool_server:get_mod(Pid,cover)), 1820 1821 %% Undo 1822 ?m(ok, reltool_server:undo_config(Pid)), 1823 ?m({ok,Tools1}, reltool_server:get_app(Pid,tools)), 1824 ?m({ok,Cover1}, reltool_server:get_mod(Pid,cover)), 1825 ?m({ok,[]}, reltool_server:get_status(Pid)), 1826 1827 %% Undo again, to check that it toggles 1828 ?m(ok, reltool_server:undo_config(Pid)), 1829 ?m({ok,Tools2}, reltool_server:get_app(Pid,tools)), 1830 ?m({ok,Cover2}, reltool_server:get_mod(Pid,cover)), 1831 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 1832 1833 ?m(ok, reltool:stop(Pid)), 1834 ok. 1835 1836 1837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1838%% Test that load_config is properly rolled back if it fails 1839load_config_fail(_Config) -> 1840 Sys1 = {sys,Cfg1=[{incl_cond, exclude}, 1841 {app,kernel,[{incl_cond,include}]}, 1842 {app,sasl,[{incl_cond,include}]}, 1843 {app,stdlib,[{incl_cond,include}]}, 1844 {app,tools,[{incl_cond,include}]}]}, 1845 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 1846 Libs = reltool_test_lib:erl_libs(), 1847 Sys11 = 1848 case Libs of 1849 [] -> Sys1; 1850 _ -> {sys, [{lib_dirs, Libs}|Cfg1]} 1851 end, 1852 ?m({ok, Sys11}, reltool:get_config(Pid)), 1853 ?m({ok,[]}, reltool_server:get_status(Pid)), 1854 1855 %% Get app and mod 1856 {ok,Tools} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 1857 1858 %% Try to load a config with a faulty rel statement (includes a 1859 %% non-existing application) 1860 Sys2 = {sys,[{incl_cond, exclude}, 1861 {boot_rel, "faulty_rel"}, 1862 {rel, "faulty_rel", "1.0", [kernel, sasl, stdlib, xxx]}, 1863 {app,kernel,[{incl_cond,include}]}, 1864 {app,sasl,[{incl_cond,include}]}, 1865 {app,stdlib,[{incl_cond,include}]}]}, 1866 ?msym({error,"Release \"faulty_rel\" uses non existing application xxx"}, 1867 reltool_server:load_config(Pid,Sys2)), 1868 1869 %% Check that a rollback is done to the old configuration 1870 ?m({ok, Sys11}, reltool:get_config(Pid,false,false)), 1871 1872 %% and that tools is not changed (i.e. that the new configuration 1873 %% is not applied) 1874 ?m({ok,Tools}, reltool_server:get_app(Pid,tools)), 1875 1876 ?m(ok, reltool:stop(Pid)), 1877 ok. 1878 1879 1880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1881%% Load config with escript 1882 1883load_config_escript_path(Config) -> 1884 %% Create escript 1885 DataDir = ?config(data_dir,Config), 1886 BeamFile = filename:join([DataDir,escript,"someapp-1.0",ebin,"mymod.beam"]), 1887 {ok,BeamBin} = file:read_file(BeamFile), 1888 EscriptName = "mymod.escript", 1889 Escript = filename:join(?WORK_DIR,EscriptName), 1890 ok = escript:create(Escript,[shebang,{beam,BeamBin}]), 1891 ok = file:change_mode(Escript,8#00744), 1892 1893 %% Start reltool_server with one escript in configuration 1894 EscriptSys = 1895 {sys, 1896 [ 1897 {lib_dirs, []}, 1898 {escript, Escript, [{incl_cond, include}]}, 1899 {profile, standalone} 1900 ]}, 1901 1902 {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, EscriptSys}])), 1903 {ok,[#app{name='*escript* mymod'}=A]} = 1904 ?msym({ok,[_]}, reltool_server:get_apps(Pid1,whitelist)), 1905 ?m(ok, reltool:stop(Pid1)), 1906 1907 1908 %% Do same again, but now start reltool first with simple config, 1909 %% then add escript by loading new configuration and check that 1910 %% #app is the same 1911 SimpleSys = 1912 {sys, 1913 [ 1914 {lib_dirs, []} 1915 ]}, 1916 1917 {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, SimpleSys}])), 1918 ?m({ok,[]}, reltool_server:get_apps(Pid2,whitelist)), 1919 ?m({ok,[]}, reltool_server:load_config(Pid2,EscriptSys)), 1920 ?m({ok,[A]}, reltool_server:get_apps(Pid2,whitelist)), 1921 1922 ?m(ok, reltool:stop(Pid2)), 1923 1924 ok. 1925 1926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1927%% Load config with same (source) escript twice and check that the 1928%% application information is not changed. 1929 1930load_config_same_escript_source(_Config) -> 1931 %% Create escript 1932 ExDir = code:lib_dir(reltool, examples), 1933 EscriptName = "display_args", 1934 Escript = filename:join([ExDir, EscriptName]), 1935 1936 %% Start reltool_server with one escript in configuration 1937 Sys = 1938 {sys, 1939 [ 1940 {lib_dirs, []}, 1941 {escript, Escript, [{incl_cond, include}]}, 1942 {profile, standalone} 1943 ]}, 1944 1945 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1946% {ok,[#app{name='*escript* display_args'}]} = 1947 ?msym({ok,[#app{name='*escript* display_args',mods=[_]}]}, 1948 reltool_server:get_apps(Pid,whitelist)), 1949 1950 %% Load the same config again, then check that app is not changed 1951 ?m({ok,[]}, reltool_server:load_config(Pid,Sys)), 1952 ?msym({ok,[#app{name='*escript* display_args',mods=[_]}]}, 1953 reltool_server:get_apps(Pid,whitelist)), 1954 1955 ?m(ok, reltool:stop(Pid)), 1956 1957 ok. 1958 1959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1960%% Load config with same (beam) escript twice and check that the 1961%% application information is not changed. 1962 1963load_config_same_escript_beam(Config) -> 1964 %% Create escript 1965 DataDir = ?config(data_dir,Config), 1966 BeamFile = filename:join([DataDir,escript,"someapp-1.0",ebin,"mymod.beam"]), 1967 {ok,BeamBin} = file:read_file(BeamFile), 1968 EscriptName = "mymod.escript", 1969 Escript = filename:join(?WORK_DIR,EscriptName), 1970 ok = escript:create(Escript,[shebang,{beam,BeamBin}]), 1971 ok = file:change_mode(Escript,8#00744), 1972 1973 %% Start reltool_server with one escript in configuration 1974 Sys = 1975 {sys, 1976 [ 1977 {lib_dirs, []}, 1978 {escript, Escript, [{incl_cond, include}]}, 1979 {profile, standalone} 1980 ]}, 1981 1982 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 1983 {ok,[#app{name='*escript* mymod'}=A]} = 1984 ?msym({ok,[_]}, reltool_server:get_apps(Pid,whitelist)), 1985 1986 %% Load the same config again, then check that app is not changed 1987 ?m({ok,[]}, reltool_server:load_config(Pid,Sys)), 1988 ?m({ok,[A]}, reltool_server:get_apps(Pid,whitelist)), 1989 1990 ?m(ok, reltool:stop(Pid)), 1991 1992 ok. 1993 1994%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1995%% Load config with escript 1996 1997load_config_add_escript(Config) -> 1998 %% First escript 1999 ExDir = code:lib_dir(reltool, examples), 2000 EscriptName1 = "display_args", 2001 Escript1 = filename:join([ExDir, EscriptName1]), 2002 2003 %% Second escript 2004 DataDir = ?config(data_dir,Config), 2005 BeamFile = filename:join([DataDir,escript,"someapp-1.0",ebin,"mymod.beam"]), 2006 {ok,BeamBin} = file:read_file(BeamFile), 2007 EscriptName2 = "mymod.escript", 2008 Escript2 = filename:join(?WORK_DIR,EscriptName2), 2009 ok = escript:create(Escript2,[shebang,{beam,BeamBin}]), 2010 ok = file:change_mode(Escript2,8#00744), 2011 2012 %% Start reltool_server with one escript in configuration 2013 Sys1 = 2014 {sys, 2015 [ 2016 {lib_dirs, []}, 2017 {escript, Escript2, [{incl_cond, include}]}, 2018 {profile, standalone} 2019 ]}, 2020 2021 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 2022 2023 %% Add second escript by loading new configuration 2024 Sys2 = 2025 {sys, 2026 [ 2027 {lib_dirs, []}, 2028 {escript, Escript1, [{incl_cond, include}]}, 2029 {escript, Escript2, [{incl_cond, include}]}, 2030 {profile, standalone} 2031 ]}, 2032 2033 {ok,[]} = ?m({ok,[]}, reltool_server:load_config(Pid,Sys2)), 2034 {ok,[#app{name='*escript* display_args'}, 2035 #app{name='*escript* mymod'}]} = 2036 ?msym({ok,[_,_]}, reltool_server:get_apps(Pid,whitelist)), 2037 2038 ?m(ok, reltool:stop(Pid)), 2039 2040 ok. 2041 2042%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2043reset_config_and_undo(Config) -> 2044 Sys1 = {sys,[{lib_dirs,[filename:join(datadir(Config),"faulty_app_file")]}, 2045 {incl_cond, exclude}, 2046 {app,a,[{incl_cond,include}]}, 2047 {app,kernel,[{incl_cond,include}]}, 2048 {app,sasl,[{incl_cond,include}]}, 2049 {app,stdlib,[{incl_cond,include}]}, 2050 {app,tools,[{incl_cond,include}]}]}, 2051 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 2052 ?m({ok, Sys1}, reltool:get_config(Pid)), 2053 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 2054 2055 %% Get app and mod 2056 {ok,Tools1} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 2057 ?m(true, Tools1#app.is_pre_included), 2058 ?m(true, Tools1#app.is_included), 2059 {ok,Cover1} = ?msym({ok,#mod{name=cover, 2060 is_included=true, 2061 is_pre_included=true}}, 2062 reltool_server:get_mod(Pid,cover)), 2063 2064 %% Exclude tools by loading new config 2065 Sys2 = {sys,[{incl_cond, exclude}, 2066 {app,kernel,[{incl_cond,include}]}, 2067 {app,sasl,[{incl_cond,include}]}, 2068 {app,stdlib,[{incl_cond,include}]}, 2069 {app,tools,[{incl_cond,exclude}]}]}, 2070 ?m({ok,[]}, reltool_server:load_config(Pid,Sys2)), 2071 ?m({ok,[]}, reltool_server:get_status(Pid)), 2072 2073 %% Check that tools is excluded 2074 {ok,Tools2} = ?msym({ok,_}, reltool_server:get_app(Pid,tools)), 2075 ?m(false, Tools2#app.is_pre_included), 2076 ?m(false, Tools2#app.is_included), 2077 {ok,Cover2} = ?msym({ok,#mod{name=cover, 2078 is_included=false, 2079 is_pre_included=false}}, 2080 reltool_server:get_mod(Pid,cover)), 2081 2082 %% Reset 2083 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:reset_config(Pid)), 2084 ?m({ok,Tools1}, reltool_server:get_app(Pid,tools)), 2085 ?m({ok,Cover1}, reltool_server:get_mod(Pid,cover)), 2086 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 2087 2088 %% Undo 2089 ?m(ok, reltool_server:undo_config(Pid)), 2090 ?m({ok,Tools2}, reltool_server:get_app(Pid,tools)), 2091 ?m({ok,Cover2}, reltool_server:get_mod(Pid,cover)), 2092 ?m({ok,[]}, reltool_server:get_status(Pid)), 2093 2094 %% Undo again, to check that it toggles 2095 ?m(ok, reltool_server:undo_config(Pid)), 2096 ?m({ok,Tools1}, reltool_server:get_app(Pid,tools)), 2097 ?m({ok,Cover1}, reltool_server:get_mod(Pid,cover)), 2098 ?msym({ok,["a: Cannot parse app file"++_]},reltool_server:get_status(Pid)), 2099 2100 ?m(ok, reltool:stop(Pid)), 2101 ok. 2102 2103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2104gen_rel_files(_Config) -> 2105 %% Configure the server 2106 RelName = "gen_fel_files_test", 2107 RelVsn = "1.0", 2108 Sys = 2109 {sys, 2110 [ 2111 {lib_dirs, []}, 2112 {boot_rel, RelName}, 2113 {rel, RelName, RelVsn, [kernel, stdlib]} 2114 ]}, 2115 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 2116 2117 %% Generate .rel, .script and .boot 2118 Dir = filename:join(?WORK_DIR,"gen_rel_files"), 2119 ok = file:make_dir(Dir), 2120 ?m({ok,[]}, reltool_server:gen_rel_files(Pid,Dir)), 2121 2122 Script = RelName ++ ".script", 2123 Rel = RelName ++ ".rel", 2124 Boot = RelName ++ ".boot", 2125 {ok,Files} = ?msym({ok,_}, file:list_dir(Dir)), 2126 [Boot,Rel,Script] = lists:sort(Files), 2127 2128 %% Check that contents is reasonable 2129 {ok,[S]} = ?msym({ok,[{script,_,_}]},file:consult(filename:join(Dir,Script))), 2130 ?msym({ok,[{release,_,_,_}]}, file:consult(filename:join(Dir,Rel))), 2131 {ok,Bin} = ?msym({ok,_}, file:read_file(filename:join(Dir,Boot))), 2132 ?m(S,binary_to_term(Bin)), 2133 2134 ?m(ok, reltool:stop(Pid)), 2135 ok. 2136 2137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2138save_config(Config) -> 2139 PrivDir = ?config(priv_dir,Config), 2140 Sys = {sys,Cfg=[{incl_cond, exclude}, 2141 {app,kernel,[{incl_cond,include}]}, 2142 {app,sasl,[{incl_cond,include}]}, 2143 {app,stdlib,[{incl_cond,include}]}]}, 2144 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 2145 Libs = reltool_test_lib:erl_libs(), 2146 Sys1 = 2147 case Libs of 2148 [] -> Sys; 2149 _ -> {sys, [{lib_dirs, Libs}|Cfg]} 2150 end, 2151 ?m({ok, Sys1}, reltool:get_config(Pid)), 2152 2153 Simple = filename:join(PrivDir,"save_simple.reltool"), 2154 ?m(ok, reltool_server:save_config(Pid,Simple,false,false)), 2155 ?m({ok,[Sys1]}, file:consult(Simple)), 2156 2157 Derivates = filename:join(PrivDir,"save_derivates.reltool"), 2158 ?m(ok, reltool_server:save_config(Pid,Derivates,false,true)), 2159 case Libs of 2160 [] -> 2161 ?msym({ok,[{sys,[{incl_cond, exclude}, 2162 {erts,[]}, 2163 {app,kernel,[{incl_cond,include},{mod,_,[]}|_]}, 2164 {app,sasl,[{incl_cond,include},{mod,_,[]}|_]}, 2165 {app,stdlib,[{incl_cond,include},{mod,_,[]}|_]}]}]}, 2166 file:consult(Derivates)); 2167 _ -> 2168 ?msym({ok,[{sys,[{lib_dirs,Libs}, 2169 {incl_cond, exclude}, 2170 {erts,[]}, 2171 {app,kernel,[{incl_cond,include},{mod,_,[]}|_]}, 2172 {app,sasl,[{incl_cond,include},{mod,_,[]}|_]}, 2173 {app,stdlib,[{incl_cond,include},{mod,_,[]}|_]}]}]}, 2174 file:consult(Derivates)) 2175 end, 2176 2177 Defaults = filename:join(PrivDir,"save_defaults.reltool"), 2178 ?m(ok, reltool_server:save_config(Pid,Defaults,true,false)), 2179 ?msym({ok,[{sys,[{root_dir,_}, 2180 {lib_dirs,_}, 2181 {mod_cond,all}, 2182 {incl_cond,exclude}, 2183 {app,kernel,[{incl_cond,include},{vsn,undefined}, 2184 {lib_dir,undefined}]}, 2185 {app,sasl,[{incl_cond,include},{vsn,undefined}, 2186 {lib_dir,undefined}]}, 2187 {app,stdlib,[{incl_cond,include},{vsn,undefined}, 2188 {lib_dir,undefined}]}, 2189 {boot_rel,"start_clean"}, 2190 {rel,"no_dot_erlang","1.0",[],[{load_dot_erlang,false}]}, 2191 {rel,"start_clean","1.0",[],[{load_dot_erlang,true}]}, 2192 {rel,"start_sasl","1.0",[sasl],[{load_dot_erlang,true}]}, 2193 {emu_name,"beam"}, 2194 {relocatable,true}, 2195 {profile,development}, 2196 {incl_sys_filters,[".*"]}, 2197 {excl_sys_filters,[]}, 2198 {incl_app_filters,[".*"]}, 2199 {excl_app_filters,[]}, 2200 {incl_archive_filters,[".*"]}, 2201 {excl_archive_filters,["^include$","^priv$"]}, 2202 {archive_opts,[]}, 2203 {rel_app_type,permanent}, 2204 {app_file,keep}, 2205 {debug_info,keep}]}]}, 2206 file:consult(Defaults)), 2207 2208 KVsn = latest(kernel), 2209 StdVsn = latest(stdlib), 2210 SaslVsn = latest(sasl), 2211 2212 LibDir = code:lib_dir(), 2213 KLibDir = filename:join(LibDir,"kernel-"++KVsn), 2214 StdLibDir = filename:join(LibDir,"stdlib-"++StdVsn), 2215 SaslLibDir = filename:join(LibDir,"sasl-"++SaslVsn), 2216 2217 All = filename:join(PrivDir,"save_all.reltool"), 2218 ?m(ok, reltool_server:save_config(Pid,All,true,true)), 2219 ?msym({ok,[{sys,[{root_dir,_}, 2220 {lib_dirs,_}, 2221 {mod_cond,all}, 2222 {incl_cond,exclude}, 2223 {erts,[]}, 2224 {app,kernel,[{incl_cond,include},{vsn,KVsn}, 2225 {lib_dir,KLibDir},{mod,_,[]}|_]}, 2226 {app,sasl,[{incl_cond,include},{vsn,SaslVsn}, 2227 {lib_dir,SaslLibDir},{mod,_,[]}|_]}, 2228 {app,stdlib,[{incl_cond,include},{vsn,StdVsn}, 2229 {lib_dir,StdLibDir},{mod,_,[]}|_]}, 2230 {boot_rel,"start_clean"}, 2231 {rel,"no_dot_erlang","1.0",[],[{load_dot_erlang,false}]}, 2232 {rel,"start_clean","1.0",[],[{load_dot_erlang,true}]}, 2233 {rel,"start_sasl","1.0",[sasl],[{load_dot_erlang,true}]}, 2234 {emu_name,"beam"}, 2235 {relocatable,true}, 2236 {profile,development}, 2237 {incl_sys_filters,[".*"]}, 2238 {excl_sys_filters,[]}, 2239 {incl_app_filters,[".*"]}, 2240 {excl_app_filters,[]}, 2241 {incl_archive_filters,[".*"]}, 2242 {excl_archive_filters,["^include$","^priv$"]}, 2243 {archive_opts,[]}, 2244 {rel_app_type,permanent}, 2245 {app_file,keep}, 2246 {debug_info,keep}]}]}, 2247 file:consult(All)), 2248 2249 ?m(ok, reltool:stop(Pid)), 2250 ok. 2251 2252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2253%% Test calculation of dependencies 2254%% The following test applications are used 2255%% 2256%% x-1.0: x1.erl x2.erl x3.erl 2257%% \ / (x2 calls y1, x3 calls y2) 2258%% y-1.0: y0.erl y1.erl y2.erl 2259%% \ (y1 calls z1) 2260%% z-1.0 z1.erl 2261%% 2262%% Test includes x and derives y and z. 2263%% 2264dependencies(Config) -> 2265 %% Default: all modules included => y and z are included (derived) 2266 Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2267 {incl_cond, exclude}, 2268 {app,kernel,[{incl_cond,include}]}, 2269 {app,sasl,[{incl_cond,include}]}, 2270 {app,stdlib,[{incl_cond,include}]}, 2271 {app,x,[{incl_cond,include}]}, 2272 {app,y,[{incl_cond,derived}]}, 2273 {app,z,[{incl_cond,derived}]}]}, 2274 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 2275 2276 ?msym({ok,[#app{name=kernel}, 2277 #app{name=sasl}, 2278 #app{name=stdlib}, 2279 #app{name=x,uses_apps=[y]}]}, 2280 reltool_server:get_apps(Pid,whitelist)), 2281 {ok, Der} = ?msym({ok,_}, 2282 reltool_server:get_apps(Pid,derived)), 2283 ?msym([#app{name=y,uses_apps=[z]}, 2284 #app{name=z}], 2285 rm_missing_app(Der)), 2286 ?msym({ok,[]}, 2287 reltool_server:get_apps(Pid,source)), 2288 2289 %% Excluding x2 => y still included since y2 is used by x3 2290 %% z still included since z1 is used by y1 2291 Sys2 = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2292 {incl_cond, exclude}, 2293 {app,kernel,[{incl_cond,include}]}, 2294 {app,sasl,[{incl_cond,include}]}, 2295 {app,stdlib,[{incl_cond,include}]}, 2296 {app,x,[{incl_cond,include},{mod,x2,[{incl_cond,exclude}]}]}, 2297 {app,y,[{incl_cond,derived}]}, 2298 {app,z,[{incl_cond,derived}]}]}, 2299 ?m({ok,[]}, reltool_server:load_config(Pid,Sys2)), 2300 ?msym({ok,[#app{name=kernel}, 2301 #app{name=sasl}, 2302 #app{name=stdlib}, 2303 #app{name=x,uses_apps=[y]}]}, 2304 reltool_server:get_apps(Pid,whitelist)), 2305 {ok, Der2} = ?msym({ok,_}, 2306 reltool_server:get_apps(Pid,derived)), 2307 ?msym([#app{name=y,uses_apps=[z]}, 2308 #app{name=z}], 2309 rm_missing_app(Der2)), 2310 ?msym({ok,[]}, 2311 reltool_server:get_apps(Pid,source)), 2312 2313 %% Excluding x3 => y still included since y1 is used by x2 2314 %% z still included since z1 is used by y1 2315 Sys3 = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2316 {incl_cond, exclude}, 2317 {app,kernel,[{incl_cond,include}]}, 2318 {app,sasl,[{incl_cond,include}]}, 2319 {app,stdlib,[{incl_cond,include}]}, 2320 {app,x,[{incl_cond,include},{mod,x3,[{incl_cond,exclude}]}]}, 2321 {app,y,[{incl_cond,derived}]}, 2322 {app,z,[{incl_cond,derived}]}]}, 2323 ?m({ok,[]}, reltool_server:load_config(Pid,Sys3)), 2324 ?msym({ok,[#app{name=kernel}, 2325 #app{name=sasl}, 2326 #app{name=stdlib}, 2327 #app{name=x,uses_apps=[y]}]}, 2328 reltool_server:get_apps(Pid,whitelist)), 2329 {ok, Der3} = ?msym({ok,_}, 2330 reltool_server:get_apps(Pid,derived)), 2331 ?msym([#app{name=y,uses_apps=[z]}, 2332 #app{name=z}], 2333 rm_missing_app(Der3)), 2334 ?msym({ok,[]}, 2335 reltool_server:get_apps(Pid,source)), 2336 2337 %% Excluding x2 and x3 => y and z excluded 2338 Sys4 = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2339 {incl_cond, exclude}, 2340 {app,kernel,[{incl_cond,include}]}, 2341 {app,sasl,[{incl_cond,include}]}, 2342 {app,stdlib,[{incl_cond,include}]}, 2343 {app,x,[{incl_cond,include}, 2344 {mod,x2,[{incl_cond,exclude}]}, 2345 {mod,x3,[{incl_cond,exclude}]}]}, 2346 {app,y,[{incl_cond,derived}]}, 2347 {app,z,[{incl_cond,derived}]}]}, 2348 ?m({ok,[]}, reltool_server:load_config(Pid,Sys4)), 2349 ?msym({ok,[#app{name=kernel}, 2350 #app{name=sasl}, 2351 #app{name=stdlib}, 2352 #app{name=x,uses_apps=[]}]}, 2353 reltool_server:get_apps(Pid,whitelist)), 2354 {ok, Der4} = ?msym({ok,_}, 2355 reltool_server:get_apps(Pid,derived)), 2356 ?msym([], rm_missing_app(Der4)), 2357 ?msym({ok,[#app{name=y}, 2358 #app{name=z}]}, 2359 reltool_server:get_apps(Pid,source)), 2360 2361 %% Excluding y1 => y still included since y2 is used by x3 2362 %% z excluded since not used by any other than y1 2363 Sys5 = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2364 {incl_cond, exclude}, 2365 {app,kernel,[{incl_cond,include}]}, 2366 {app,sasl,[{incl_cond,include}]}, 2367 {app,stdlib,[{incl_cond,include}]}, 2368 {app,x,[{incl_cond,include}]}, 2369 {app,y,[{incl_cond,derived}, 2370 {mod,y1,[{incl_cond,exclude}]}]}, 2371 {app,z,[{incl_cond,derived}]}]}, 2372 ?m({ok,[]}, reltool_server:load_config(Pid,Sys5)), 2373 ?msym({ok,[#app{name=kernel}, 2374 #app{name=sasl}, 2375 #app{name=stdlib}, 2376 #app{name=x,uses_apps=[y]}]}, 2377 reltool_server:get_apps(Pid,whitelist)), 2378 {ok, Der5} = ?msym({ok,_}, 2379 reltool_server:get_apps(Pid,derived)), 2380 ?msym([#app{name=y,uses_apps=[]}], rm_missing_app(Der5)), 2381 ?msym({ok,[#app{name=z}]}, 2382 reltool_server:get_apps(Pid,source)), 2383 2384 ?m(ok, reltool:stop(Pid)), 2385 ok. 2386 2387 2388%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2389%% Test that incl_cond on mod level overwrites mod_cond on app level 2390%% Uses same test applications as dependencies/1 above 2391mod_incl_cond_derived(Config) -> 2392 %% In app y: mod_cond=none means no module shall be included 2393 %% but mod_cond is overwritten by incl_cond on mod level 2394 Sys = {sys,[{lib_dirs,[filename:join(datadir(Config),"dependencies")]}, 2395 {incl_cond, exclude}, 2396 {app,kernel,[{incl_cond,include}]}, 2397 {app,sasl,[{incl_cond,include}]}, 2398 {app,stdlib,[{incl_cond,include}]}, 2399 {app,x,[{incl_cond,include}]}, 2400 {app,y,[{incl_cond,include}, 2401 {mod_cond,none}, 2402 {mod,y0,[{incl_cond,derived}]}, 2403 {mod,y2,[{incl_cond,derived}]}]}]}, 2404 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 2405 2406 ?msym({ok,[#app{name=kernel}, 2407 #app{name=sasl}, 2408 #app{name=stdlib}, 2409 #app{name=x,uses_apps=[y]}, 2410 #app{name=y,uses_apps=[]}]}, 2411 reltool_server:get_apps(Pid,whitelist)), 2412 {ok, Der} = ?msym({ok,_},reltool_server:get_apps(Pid,derived)), 2413 ?msym([], rm_missing_app(Der)), 2414 ?msym({ok,[]}, reltool_server:get_apps(Pid,source)), 2415 2416 %% 1. check that y0 is not included since it has 2417 %% incl_cond=derived, but is not used by any other module. 2418 ?msym({ok,#mod{is_included=undefined}}, reltool_server:get_mod(Pid,y0)), 2419 2420 %% 2. check that y1 is excluded since it has undefined incl_cond 2421 %% on mod level, so mod_cond on app level shall be used. 2422 ?msym({ok,#mod{is_included=false}}, reltool_server:get_mod(Pid,y1)), 2423 2424 %% 3. check that y2 is included since it has incl_cond=derived and 2425 %% is used by x3. 2426 ?msym({ok,#mod{is_included=true}}, reltool_server:get_mod(Pid,y2)), 2427 2428 ok. 2429 2430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2431%% ERL-167, OTP-11993: For applications that are not included in a 2432%% release spec ('rel'), dependencies in the .app files are not 2433%% considered - only those found with xref. 2434dep_in_app_not_xref(Config) -> 2435 RelName = "Just testing...", 2436 RelVsn = "1.0", 2437 Sys = 2438 {sys, 2439 [ 2440 {lib_dirs,[filename:join(datadir(Config),"dep_in_app_not_xref")]}, 2441 {incl_cond,exclude}, 2442 {incl_archive_filters,[]}, 2443 {erts,[{incl_cond,exclude}]}, 2444 {boot_rel, RelName}, 2445 {rel, RelName, RelVsn, [kernel, stdlib]}, 2446 {app,kernel,[{incl_cond,include}]}, 2447 {app,stdlib,[{incl_cond,include}]}, 2448 {app,x,[{incl_cond,include}]}, 2449 {app,y,[{incl_cond,derived}]}, 2450 {app,z,[{incl_cond,derived}]} 2451 ]}, 2452 2453 TargetDir = filename:join([?WORK_DIR, "target_dep_in_app_not_xref"]), 2454 ?m(ok, reltool_utils:recursive_delete(TargetDir)), 2455 ?m(ok, file:make_dir(TargetDir)), 2456 ?log("SPEC: ~p\n", [reltool:get_target_spec([{config, Sys}])]), 2457 ok = ?m(ok, reltool:create_target([{config, Sys}], TargetDir)), 2458 ?log("~p~n",[file:list_dir(filename:join([TargetDir,"lib"]))]), 2459 2460 ?m(true, filelib:is_dir(filename:join([TargetDir,"lib","y-1.0"]))), 2461 ?m(true, filelib:is_dir(filename:join([TargetDir,"lib","z-1.0"]))), 2462 ok. 2463 2464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2465use_selected_vsn(Config) -> 2466 LibDir1 = filename:join(datadir(Config),"use_selected_vsn"), 2467 B1Dir = filename:join(LibDir1,"b-1.0"), 2468 B3Dir = filename:join(LibDir1,"b-3.0"), 2469 2470 LibDir2 = filename:join(LibDir1,"lib2"), 2471 B2Dir = filename:join(LibDir2,"b-2.0"), 2472 2473 %%----------------------------------------------------------------- 2474 %% Pre-selected vsn of app b 2475 Sys1 = {sys,[{lib_dirs,[LibDir1]}, 2476 {incl_cond, exclude}, 2477 {app,kernel,[{incl_cond,include}]}, 2478 {app,sasl,[{incl_cond,include}]}, 2479 {app,stdlib,[{incl_cond,include}]}, 2480 {app,b,[{incl_cond,include},{vsn,"1.0"}]}]}, 2481 {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 2482 {ok,B11} = ?msym({ok,#app{vsn="1.0",active_dir=B1Dir}}, 2483 reltool_server:get_app(Pid1,b)), 2484 2485 %% Change from a pre-selected vsn to use a specific dir 2486 ?msym({ok, #app{vsn ="3.0", active_dir = B3Dir}, []}, 2487 reltool_server:set_app(Pid1, 2488 B11#app{active_dir = B3Dir, 2489 use_selected_vsn = dir, 2490 label = undefined, 2491 vsn = undefined, 2492 info = undefined})), 2493 ?m(ok, reltool:stop(Pid1)), 2494 2495 2496 %%----------------------------------------------------------------- 2497 %% Pre-selected vsn of app b 2498 Sys2 = {sys,[{lib_dirs,[LibDir1]}, 2499 {incl_cond, exclude}, 2500 {app,kernel,[{incl_cond,include}]}, 2501 {app,sasl,[{incl_cond,include}]}, 2502 {app,stdlib,[{incl_cond,include}]}, 2503 {app,b,[{incl_cond,include},{vsn,"1.0"}]}]}, 2504 {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, Sys2}])), 2505 {ok,B21} = ?msym({ok,#app{vsn="1.0",active_dir=B1Dir}}, 2506 reltool_server:get_app(Pid2,b)), 2507 2508 %% Change from a pre-selected vsn to use latest 2509 ?msym({ok, #app{vsn ="3.0", active_dir = B3Dir}, []}, 2510 reltool_server:set_app(Pid2, 2511 B21#app{use_selected_vsn=undefined, 2512 label = undefined, 2513 vsn = undefined, 2514 info = undefined})), 2515 ?m(ok, reltool:stop(Pid2)), 2516 2517 2518 %%----------------------------------------------------------------- 2519 %% Pre-selected directory for app b 2520 Sys3 = {sys,[{lib_dirs,[LibDir1]}, 2521 {incl_cond, exclude}, 2522 {app,kernel,[{incl_cond,include}]}, 2523 {app,sasl,[{incl_cond,include}]}, 2524 {app,stdlib,[{incl_cond,include}]}, 2525 {app,b,[{incl_cond,include},{lib_dir,B2Dir}]}]}, 2526 {ok, Pid3} = ?msym({ok, _}, reltool:start_server([{config, Sys3}])), 2527% test_server:break("Pid3 = list_to_pid(\""++pid_to_list(Pid3)++"\")."), 2528 {ok,B31} = ?msym({ok,#app{vsn="2.0",active_dir=B2Dir}}, 2529 reltool_server:get_app(Pid3,b)), 2530 %% Change from a pre-selected dir to use latest 2531 {ok,B32,_} = ?msym({ok, #app{vsn ="3.0", active_dir = B3Dir}, []}, 2532 reltool_server:set_app(Pid3, 2533 B31#app{use_selected_vsn=undefined, 2534 label = undefined, 2535 vsn = undefined, 2536 info = undefined})), 2537 %% Change back to use selected dir 2538 {ok,B33,_} = ?msym({ok, #app{vsn ="3.0", active_dir = B3Dir}, []}, 2539 reltool_server:set_app(Pid3, 2540 B32#app{use_selected_vsn = dir})), 2541 %% use dir 1 2542 {ok,B34,_} = ?msym({ok, #app{vsn ="1.0", active_dir = B1Dir}, []}, 2543 reltool_server:set_app(Pid3, 2544 B33#app{active_dir = B1Dir, 2545 label = undefined, 2546 vsn = undefined, 2547 info = undefined})), 2548 %% use dir 2 2549 {ok,B35,_} = ?msym({ok, #app{vsn ="2.0", active_dir = B2Dir}, []}, 2550 reltool_server:set_app(Pid3, 2551 B34#app{active_dir = B2Dir, 2552 label = undefined, 2553 vsn = undefined, 2554 info = undefined})), 2555 %% use dir 3 2556 ?msym({ok, #app{vsn ="3.0", active_dir = B3Dir}, []}, 2557 reltool_server:set_app(Pid3, 2558 B35#app{active_dir = B3Dir, 2559 label = undefined, 2560 vsn = undefined, 2561 info = undefined})), 2562 ?m(ok, reltool:stop(Pid3)), 2563 ok. 2564 2565 2566%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2567use_selected_vsn_relative_path(Config) -> 2568 LibDir = filename:join([datadir(Config),"use_selected_vsn","b-1.0"]), 2569 RelDir = filename:join(LibDir,"rel"), 2570 2571 {ok,Cwd} = file:get_cwd(), 2572 ok = file:set_cwd(RelDir), 2573 2574 Sys = {sys,[{incl_cond, exclude}, 2575 {app,kernel,[{incl_cond,include}]}, 2576 {app,sasl,[{incl_cond,include}]}, 2577 {app,stdlib,[{incl_cond,include}]}, 2578 {app,b,[{incl_cond,include},{lib_dir,".."}]}]}, 2579 {ok, Pid} = ?msym({ok, _}, reltool:start_server([{config, Sys}])), 2580 2581 ?msym({ok,#app{vsn="1.0",active_dir=LibDir}},reltool_server:get_app(Pid,b)), 2582 2583 ?m(ok, reltool:stop(Pid)), 2584 2585 ok = file:set_cwd(Cwd), 2586 ok. 2587 2588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2589%% Test that reltool recognizes an application with its real name even 2590%% though it uses non standard format for its version number (in the 2591%% directory name) 2592non_standard_vsn_id(Config) -> 2593 LibDir = filename:join(datadir(Config),"non_standard_vsn_id"), 2594 B1Dir = filename:join(LibDir,"b-first"), 2595 B2Dir = filename:join(LibDir,"b-second"), 2596 2597 %%----------------------------------------------------------------- 2598 %% Default vsn of app b 2599 Sys1 = {sys,[{lib_dirs,[LibDir]}, 2600 {incl_cond, exclude}, 2601 {app,kernel,[{incl_cond,include}]}, 2602 {app,sasl,[{incl_cond,include}]}, 2603 {app,stdlib,[{incl_cond,include}]}, 2604 {app,b,[{incl_cond,include}]}]}, 2605 {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, Sys1}])), 2606 ?msym({ok,#app{vsn="first",active_dir=B1Dir,sorted_dirs=[B1Dir,B2Dir]}}, 2607 reltool_server:get_app(Pid1,b)), 2608 2609 %%----------------------------------------------------------------- 2610 %% Pre-selected vsn of app b 2611 Sys2 = {sys,[{lib_dirs,[LibDir]}, 2612 {incl_cond, exclude}, 2613 {app,kernel,[{incl_cond,include}]}, 2614 {app,sasl,[{incl_cond,include}]}, 2615 {app,stdlib,[{incl_cond,include}]}, 2616 {app,b,[{incl_cond,include},{vsn,"second"}]}]}, 2617 {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, Sys2}])), 2618 ?msym({ok,#app{vsn="second",active_dir=B2Dir,sorted_dirs=[B1Dir,B2Dir]}}, 2619 reltool_server:get_app(Pid2,b)), 2620 ok. 2621 2622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2623undefined_regexp(_Config) -> 2624 ?msym({ok,_}, 2625 reltool:get_config([{sys,[{app,asn1,[{excl_app_filters, 2626 {add, ["^priv"]}}]}]}])), 2627 ok. 2628 2629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2630%% Checks that reltool_utils can correctly read Windows ERL_LIBS 2631 2632windows_erl_libs(_Config) -> 2633 WinErlLibs = 2634 "C:\\Program Files\\Erlang Libs;C:\\Program Files\\More Erlang Libs", 2635 Ret = reltool_utils:erl_libs(WinErlLibs, {win32, nt}), 2636 ?m(["C:\\Program Files\\Erlang Libs","C:\\Program Files\\More Erlang Libs"], 2637 Ret), 2638 ok. 2639 2640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2641%% Library functions 2642 2643datadir(Config) -> 2644 %% Removes the trailing slash... 2645 filename:nativename(?config(data_dir,Config)). 2646 2647latest(App) -> 2648 AppStr = atom_to_list(App), 2649 AppDirs = filelib:wildcard(filename:join(code:lib_dir(),AppStr++"-*")), 2650 [LatestAppDir|_] = lists:reverse(AppDirs), 2651 [_,Vsn] = string:lexemes(filename:basename(LatestAppDir),"-"), 2652 Vsn. 2653 2654rm_missing_app(Apps) -> 2655 lists:keydelete(?MISSING_APP_NAME,#app.name,Apps). 2656 2657%% We will compare the script generated by systools with 2658%% the script generated by Reltool. 2659%% 2660%% The systools script may include additional modules in 2661%% the first primLoad command (as a pure optimization). 2662%% Therefore, we cannot compare the primLoad commands 2663%% directly. Instead we will collect all modules from 2664%% all primLoad commands in each script. The same 2665%% modules must be loaded by both scripts. In addition, 2666%% the error_handler module must be included in the 2667%% first primLoad in each script. 2668 2669diff_script(Script, Script) -> 2670 equal; 2671diff_script({script, Rel, Commands1}, {script, Rel, Commands2}) -> 2672 case diff_cmds(Commands1, Commands2) of 2673 equal -> 2674 Loaded = diff_get_prim_load(Commands1), 2675 case diff_get_prim_load(Commands2) of 2676 Loaded -> 2677 equal; 2678 Other -> 2679 io:format("Only loaded by systools: ~p", 2680 [Loaded--Other]), 2681 io:format("Only loaded by reltool: ~p", 2682 [Other--Loaded]), 2683 ct:fail(different_prim_loads) 2684 end; 2685 Error -> 2686 Error 2687 end; 2688diff_script({script, Rel1, _}, {script, Rel2, _}) -> 2689 {error, {Rel1, Rel2}}. 2690 2691diff_cmds([{primLoad, Ms1}=Cmd1 | Commands1], 2692 [{primLoad, Ms2}=Cmd2 | Commands2]) -> 2693 case lists:member(error_handler, Ms1) xor 2694 lists:member(error_handler, Ms2) of 2695 false -> 2696 %% error_handler either present in both or 2697 %% absent in both. 2698 diff_cmds(Commands1, Commands2); 2699 true -> 2700 %% error_handler only present in one primLoad. 2701 %% Not OK. 2702 {diff, missing_error_handler, 2703 {expected, Cmd1}, {actual, Cmd2}} 2704 end; 2705diff_cmds([Cmd | Commands1], [Cmd | Commands2]) -> 2706 diff_cmds(Commands1, Commands2); 2707diff_cmds([Cmd1 | _Commands1], [Cmd2 | _Commands2]) -> 2708 {diff, {expected, Cmd1}, {actual, Cmd2}}; 2709diff_cmds([], []) -> 2710 equal. 2711 2712diff_get_prim_load(Cmds) -> 2713 L = [Ms || {primLoad, Ms} <- Cmds], 2714 lists:sort(lists:flatten(L)). 2715 2716os_cmd(Cmd) when is_list(Cmd) -> 2717 %% Call the plain os:cmd with an echo command appended to print command status 2718 %% io:format("os:cmd(~p).\n", [Cmd]), 2719 case os:cmd(Cmd++";echo \"#$?\"") of 2720 %% There is (as far as I can tell) only one thing that will match this 2721 %% and that is too silly to ever be used, but... 2722 []-> 2723 {99, []}; 2724 Return-> 2725 %% Find the position of the status code wich is last in the string 2726 %% prepended with # 2727 case string:split(Return, "$#", trailing) of 2728 [_] -> %% This happens only if the sh command pipe is somehow interrupted 2729 {98, Return}; 2730 [Result, Status0] -> 2731 {list_to_integer(string:trim(Status0)), Result} 2732 end 2733 end. 2734 2735%% Returns the location (directory) of the given module. Split, 2736%% reverted and relative to the lib dir. 2737mod_path(Node,Mod) -> 2738 case rpc:call(Node,code,which,[Mod]) of 2739 Path when is_list(Path) -> 2740 lists:takewhile( 2741 fun("lib") -> false; 2742 (_) -> true 2743 end, 2744 lists:reverse(filename:split(filename:dirname(Path)))); 2745 Other -> 2746 Other 2747 end. 2748 2749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2750%% Node handling 2751 2752start_node(Name, ErlPath) -> 2753 start_node(Name, ErlPath, []). 2754start_node(Name, ErlPath, Args0) -> 2755 FullName = full_node_name(Name), 2756 Args = mk_node_args(Name, Args0), 2757 io:format("Starting node ~p: ~ts~n", 2758 [FullName, lists:flatten([[X," "] || X <- [ErlPath|Args]])]), 2759 %io:format("open_port({spawn_executable, ~p}, [{args,~p}])~n",[ErlPath,Args]), 2760 case open_port({spawn_executable, ErlPath}, [{args,Args}]) of 2761 Port when is_port(Port) -> 2762 %% no need to close port since node is detached (see 2763 %% mk_node_args) so port will be closed anyway. 2764 case ping_node(FullName, 50) of 2765 ok -> {ok, FullName}; 2766 Other -> exit({failed_to_start_node, FullName, Other}) 2767 end; 2768 Error -> 2769 exit({failed_to_start_node, FullName, Error}) 2770 end. 2771 2772stop_node(Node) -> 2773 rpc:call(Node,erlang,halt,[]), 2774 wait_for_node_down(Node,50). 2775 2776wait_for_node_down(Node,0) -> 2777 ct:fail({cant_terminate_node,Node}); 2778wait_for_node_down(Node,N) -> 2779 case net_adm:ping(Node) of 2780 pong -> 2781 timer:sleep(1000), 2782 wait_for_node_down(Node,N-1); 2783 pang -> 2784 ok 2785 end. 2786 2787mk_node_args(Name, Args) -> 2788 Pa = filename:dirname(code:which(?MODULE)), 2789 NameSw = case net_kernel:longnames() of 2790 false -> "-sname"; 2791 true -> "-name"; 2792 _ -> exit(not_distributed_node) 2793 end, 2794 {ok, Pwd} = file:get_cwd(), 2795 NameStr = atom_to_list(Name), 2796 ["-detached", 2797 %% Don't want to try to run the debug emulator here 2798 "-emu_type","opt", 2799 NameSw, NameStr, 2800 "-pa", Pa, 2801 "-env", "ERL_CRASH_DUMP", Pwd ++ "/erl_crash_dump." ++ NameStr, 2802 "-setcookie", atom_to_list(erlang:get_cookie()) 2803 | Args]. 2804 2805full_node_name(PreName) -> 2806 HostSuffix = lists:dropwhile(fun ($@) -> false; (_) -> true end, 2807 atom_to_list(node())), 2808 list_to_atom(atom_to_list(PreName) ++ HostSuffix). 2809 2810ping_node(_Node, 0) -> 2811 {error, net_adm}; 2812ping_node(Node, N) when is_integer(N), N > 0 -> 2813 case catch net_adm:ping(Node) of 2814 pong -> 2815 wait_for_process(Node, code_server, 50); 2816 _ -> 2817 timer:sleep(1000), 2818 ping_node(Node, N-1) 2819 end. 2820 2821wait_for_process(_Node, Name, 0) -> 2822 {error, Name}; 2823wait_for_process(Node, Name, N) when is_integer(N), N > 0 -> 2824 case rpc:call(Node, erlang, whereis, [Name]) of 2825 undefined -> 2826 timer:sleep(1000), 2827 wait_for_process(Node, Name, N-1); 2828 {badrpc, _} = Reason -> 2829 erlang:error({Reason, Node}); 2830 Pid when is_pid(Pid) -> 2831 ok 2832 end. 2833 2834wait_for_app(_Node, Name, 0) -> 2835 {error, Name}; 2836wait_for_app(Node, Name, N) when is_integer(N), N > 0 -> 2837 case rpc:call(Node,application,which_applications,[]) of 2838 {badrpc,Reason} -> 2839 ct:fail({failed_to_get_applications,Reason}); 2840 Apps -> 2841 case lists:member(Name,Apps) of 2842 false -> 2843 timer:sleep(1000), 2844 wait_for_app(Node, Name, N-1); 2845 true -> 2846 ok 2847 end 2848 end. 2849 2850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2851%% Run escript 2852 2853run(Dir, Script, Args) -> 2854 Cmd0 = filename:rootname(Script) ++ " " ++ Args, 2855 Cmd = case os:type() of 2856 {win32,_} -> filename:nativename(Dir) ++ "\\" ++ Cmd0; 2857 _ -> Cmd0 2858 end, 2859 do_run(Dir, Cmd). 2860 2861run(Dir, Opts, Script, Args) -> 2862 Cmd0 = filename:rootname(Script) ++ " " ++ Args, 2863 Cmd = case os:type() of 2864 {win32,_} -> Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0; 2865 _ -> Opts ++ " " ++ Dir ++ "/" ++ Cmd0 2866 end, 2867 do_run(Dir, Cmd). 2868 2869do_run(Dir, Cmd) -> 2870 io:format("Run: ~p\n", [Cmd]), 2871 Env = [{"PATH",Dir++":"++os:getenv("PATH")}, 2872 {"ERL_FLAGS",""}, % Make sure no flags are set that can override 2873 {"ERL_ZFLAGS",""}], % any of the flags set in the escript. 2874 Port = open_port({spawn,Cmd}, [exit_status,eof,in,{env,Env}]), 2875 Res = get_data(Port, []), 2876 receive 2877 {Port,{exit_status,ExitCode}} -> 2878 s2b([Res,"ExitCode:"++integer_to_list(ExitCode)]) 2879 end. 2880 2881get_data(Port, SoFar) -> 2882 receive 2883 {Port,{data,Bytes}} -> 2884 get_data(Port, [SoFar|Bytes]); 2885 {Port,eof} -> 2886 erlang:port_close(Port), 2887 SoFar 2888 end. 2889 2890expected_output([data_dir|T], Data) -> 2891 Slash = case os:type() of 2892 {win32,_} -> "\\"; 2893 _ -> "/" 2894 end, 2895 [filename:nativename(Data)++Slash|expected_output(T, Data)]; 2896expected_output([H|T], Data) -> 2897 [H|expected_output(T, Data)]; 2898expected_output([], _) -> 2899 []; 2900expected_output(Bin, _) when is_binary(Bin) -> 2901 Bin. 2902 2903%% Convert the given list to a binary with the same encoding as the 2904%% file name translation mode 2905s2b(List) -> 2906 Enc = file:native_name_encoding(), 2907 unicode:characters_to_binary(List,Enc,Enc). 2908