4
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
19
19
-module(code_SUITE).
21
-include("test_server.hrl").
21
-include_lib("test_server/include/test_server.hrl").
23
-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
24
24
-export([set_path/1, get_path/1, add_path/1, add_paths/1, del_path/1,
25
25
replace_path/1, load_file/1, load_abs/1, ensure_loaded/1,
26
26
delete/1, purge/1, soft_purge/1, is_loaded/1, all_loaded/1,
27
27
load_binary/1, dir_req/1, object_code/1, set_path_file/1,
28
28
sticky_dir/1, pa_pz_option/1, add_del_path/1,
29
dir_disappeared/1, ext_mod_dep/1,
29
dir_disappeared/1, ext_mod_dep/1, clash/1,
30
30
load_cached/1, start_node_with_cache/1, add_and_rehash/1,
31
31
where_is_file_cached/1, where_is_file_no_cache/1,
32
32
purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1,
33
33
code_archive/1, code_archive2/1, on_load/1,
35
on_load_embedded/1, on_load_errors/1, native_early_modules/1]).
36
-export([init_per_testcase/2, fin_per_testcase/2,
37
-export([init_per_testcase/2, end_per_testcase/2,
37
38
init_per_suite/1, end_per_suite/1,
38
39
sticky_compiler/1]).
43
handle_event/2, handle_call/2, handle_info/2,
46
suite() -> [{ct_hooks,[ts_install_cth]}].
41
49
[set_path, get_path, add_path, add_paths, del_path,
42
50
replace_path, load_file, load_abs, ensure_loaded,
43
51
delete, purge, soft_purge, is_loaded, all_loaded,
44
52
load_binary, dir_req, object_code, set_path_file,
45
pa_pz_option, add_del_path,
46
dir_disappeared, ext_mod_dep,
47
load_cached, start_node_with_cache, add_and_rehash,
48
where_is_file_no_cache, where_is_file_cached,
49
purge_stacktrace, mult_lib_roots, bad_erl_libs,
50
code_archive, code_archive2, on_load, on_load_embedded].
53
pa_pz_option, add_del_path, dir_disappeared,
54
ext_mod_dep, clash, load_cached, start_node_with_cache,
55
add_and_rehash, where_is_file_no_cache,
56
where_is_file_cached, purge_stacktrace, mult_lib_roots,
57
bad_erl_libs, code_archive, code_archive2, on_load,
58
on_load_embedded, big_boot_embedded, on_load_errors,
59
native_early_modules].
64
init_per_group(_GroupName, Config) ->
67
end_per_group(_GroupName, Config) ->
52
70
init_per_suite(Config) ->
53
71
%% The compiler will no longer create a Beam file if
537
566
?line code:del_path(Dir2),
538
567
?line PrivDir1 = code:priv_dir(dummy_app),
571
clash(Config) when is_list(Config) ->
572
DDir = ?config(data_dir,Config)++"clash/",
575
%% test non-clashing entries
577
%% remove "." to prevent clash with test-server path
578
?line true = code:del_path("."),
579
?line true = code:add_path(DDir++"foobar-0.1/ebin"),
580
?line true = code:add_path(DDir++"zork-0.8/ebin"),
581
test_server:capture_start(),
582
?line ok = code:clash(),
583
test_server:capture_stop(),
584
?line [OKMsg|_] = test_server:capture_get(),
585
?line true = lists:prefix("** Found 0 name clashes", OKMsg),
586
?line true = code:set_path(P),
588
%% test clashing entries
590
%% remove "." to prevent clash with test-server path
591
?line true = code:del_path("."),
592
?line true = code:add_path(DDir++"foobar-0.1/ebin"),
593
?line true = code:add_path(DDir++"foobar-0.1.ez/foobar-0.1/ebin"),
594
test_server:capture_start(),
595
?line ok = code:clash(),
596
test_server:capture_stop(),
597
?line [ClashMsg|_] = test_server:capture_get(),
598
?line {match, [" hides "]} = re:run(ClashMsg, "\\*\\* .*( hides ).*",
599
[{capture,all_but_first,list}]),
600
?line true = code:set_path(P),
602
%% test "Bad path can't read"
604
%% remove "." to prevent clash with test-server path
605
Priv = ?config(priv_dir, Config),
606
?line true = code:del_path("."),
607
TmpEzFile = Priv++"foobar-0.tmp.ez",
608
?line {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile),
609
?line true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"),
612
%% The file wont be deleted on windows until it's closed, why we
613
%% need to rename instead.
614
?line ok = file:rename(TmpEzFile,TmpEzFile++".moved");
616
?line ok = file:delete(TmpEzFile)
618
test_server:capture_start(),
619
?line ok = code:clash(),
620
test_server:capture_stop(),
621
?line [BadPathMsg|_] = test_server:capture_get(),
622
?line true = lists:prefix("** Bad path can't read", BadPathMsg),
623
?line true = code:set_path(P),
624
file:delete(TmpEzFile++".moved"), %% Only effect on windows
542
627
ext_mod_dep(suite) ->
545
630
["Every module that the code_server uses should be preloaded, "
546
631
"this test case verifies that"];
547
632
ext_mod_dep(Config) when is_list(Config) ->
610
695
%%%% We need to check these manually...
611
696
% fun's are ok as long as they are defined locally.
612
697
check_funs({'$M_EXPR','$F_EXPR',_},
698
[{unicode,characters_to_binary_int,3},
699
{unicode,characters_to_binary,3},
700
{filename,filename_string_to_binary,1}|_]) -> 0;
701
check_funs({'$M_EXPR','$F_EXPR',_},
703
{unicode,characters_to_binary_int,3},
704
{unicode,characters_to_binary,3},
705
{filename,filename_string_to_binary,1}|_]) -> 0;
706
check_funs({'$M_EXPR','$F_EXPR',_},
707
[{unicode,do_o_binary2,2},
708
{unicode,do_o_binary,2},
710
{unicode,characters_to_binary_int,3},
711
{unicode,characters_to_binary,3},
712
{filename,filename_string_to_binary,1}|_]) -> 0;
713
check_funs({'$M_EXPR','$F_EXPR',_},
613
714
[{code_server,load_native_code,4},
614
715
{code_server,load_native_code_1,2},
615
716
{code_server,load_native_code,2},
1225
1354
?line file:close(Fd),
1226
1355
{filename:dirname(Name),filename:basename(Name)}.
1357
create_big_boot(Config) ->
1358
?line {ok, OldDir} = file:get_cwd(),
1359
?line {Options,Local} = case is_source_dir() of
1360
true -> {[no_module_tests,local],true};
1361
_ -> {[no_module_tests],false}
1363
?line {LatestDir,LatestName,Apps} = create_big_script(Config,Local),
1364
?line ok = file:set_cwd(LatestDir),
1365
?line ok = systools:make_script(LatestName, Options),
1366
?line ok = file:set_cwd(OldDir),
1367
{filename:join(LatestDir, LatestName),Apps}.
1369
% The following apps cannot be loaded
1370
% hipe .app references (or can reference) files that have no
1371
% corresponding beam file (if hipe is not enabled)
1372
filter_app("hipe",_) ->
1374
% Dialyzer and typer depends on hipe
1375
filter_app("dialyzer",_) ->
1377
filter_app("typer",_) ->
1379
% Orber requires explicit configuration
1380
filter_app("orber",_) ->
1382
% cos* depends on orber
1383
filter_app("cos"++_,_) ->
1385
% ic has a mod instruction in the app file but no corresponding start function
1386
filter_app("ic",_) ->
1388
% Netconf has some dependency that I really do not understand (maybe like orber)
1389
filter_app("netconf",_) ->
1391
% Safe has the same kind of error in the .app file as ic
1392
filter_app("safe",_) ->
1394
% OS_mon does not find it's port program when running cerl
1395
filter_app("os_mon",true) ->
1397
% Other apps should be OK.
1400
create_big_script(Config,Local) ->
1401
?line PrivDir = ?config(priv_dir, Config),
1402
?line Name = filename:join(PrivDir,"full_script_test"),
1403
?line InitialApplications=application:loaded_applications(),
1404
%% Applications left loaded by the application suite, unload them!
1405
?line UnloadFix=[app0,app1,app2,group_leader,app_start_error],
1406
?line [application:unload(Leftover) ||
1407
Leftover <- UnloadFix,
1408
lists:keymember(Leftover,1,InitialApplications) ],
1409
%% Now we should have only "real" applications...
1410
?line [application:load(list_to_atom(Y)) || {match,[Y]} <- [ re:run(X,code:lib_dir()++"/"++"([^/-]*).*/ebin",[{capture,[1],list}]) || X <- code:get_path()],filter_app(Y,Local)],
1411
?line Apps = [ {N,V} || {N,_,V} <- application:loaded_applications()],
1412
?line {ok,Fd} = file:open(Name ++ ".rel", write),
1414
"{release, {\"Test release 3\", \"P2A\"}, \n"
1415
" {erts, \"9.42\"}, \n"
1418
?line file:close(Fd),
1420
application:loaded_applications() -- InitialApplications,
1421
?line [ application:unload(N) || {N,_,_} <- NewlyLoaded],
1422
{filename:dirname(Name),filename:basename(Name),Apps}.
1228
1424
is_source_dir() ->
1229
1425
filename:basename(code:lib_dir(kernel)) =:= "kernel" andalso
1230
1426
filename:basename(code:lib_dir(stdlib)) =:= "stdlib".
1428
on_load_errors(Config) when is_list(Config) ->
1429
Master = on_load_error_test_case_process,
1430
?line register(Master, self()),
1432
?line Data = filename:join([?config(data_dir, Config),"on_load_errors"]),
1433
?line ok = file:set_cwd(Data),
1434
?line up_to_date = make:all([{d,'MASTER',Master}]),
1436
?line do_on_load_error(an_atom),
1438
?line error_logger:add_report_handler(?MODULE, self()),
1440
?line do_on_load_error({something,terrible,is,wrong}),
1443
?line {_, "The on_load function"++_,
1445
{something,terrible,is,wrong},_]} = Any1
1448
?line do_on_load_error(fail), %Cause exception.
1451
?line {_, "The on_load function"++_,
1452
[on_load_error,{failed,[_|_]},_]} = Any2
1455
%% There should be no more messages.
1458
?line ?t:fail({unexpected,Unexpected})
1465
do_on_load_error(ReturnValue) ->
1466
?line {_,Ref} = spawn_monitor(fun() ->
1467
exit(on_load_error:main())
1469
receive {on_load_error,ErrorPid} -> ok end,
1470
?line ErrorPid ! ReturnValue,
1472
{'DOWN',Ref,process,_,Exit} ->
1473
?line {undef,[{on_load_error,main,[]}|_]} = Exit
1476
native_early_modules(suite) -> [];
1477
native_early_modules(doc) -> ["Test that the native code of early loaded modules is loaded"];
1478
native_early_modules(Config) when is_list(Config) ->
1479
case erlang:system_info(hipe_architecture) of
1481
{skip,"Native code support is not enabled"};
1483
native_early_modules_1(Architecture)
1486
native_early_modules_1(Architecture) ->
1487
?line {lists, ListsBinary, _ListsFilename} = code:get_object_code(lists),
1488
?line ChunkName = hipe_unified_loader:chunk_name(Architecture),
1489
?line NativeChunk = beam_lib:chunks(ListsBinary, [ChunkName]),
1490
?line IsHipeCompiled = case NativeChunk of
1491
{ok,{_,[{_,Bin}]}} when is_binary(Bin) -> true;
1492
{error, beam_lib, _} -> false
1494
case IsHipeCompiled of
1496
{skip,"OTP apparently not configured with --enable-native-libs"};
1498
?line true = lists:all(fun code:is_module_native/1,
1499
[ets,file,filename,gb_sets,gb_trees,
1500
hipe_unified_loader,lists,os,packages]),
1504
%%-----------------------------------------------------------------
1505
%% error_logger handler.
1506
%% (Copied from stdlib/test/proc_lib_SUITE.erl.)
1507
%%-----------------------------------------------------------------
1511
handle_event({error, _GL, {emulator, _, _}}, Tester) ->
1513
handle_event({error, _GL, Msg}, Tester) ->
1516
handle_event(_Event, State) ->
1519
handle_info(_, State) ->
1522
handle_call(_Query, State) -> {ok, {error, bad_query}, State}.
1524
terminate(_Reason, State) ->
1528
%%% Common utility functions.
1232
1531
start_node(Name, Param) ->
1233
1532
?t:start_node(Name, slave, [{args, Param}]).