aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test/code_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test/code_SUITE.erl')
-rw-r--r--lib/kernel/test/code_SUITE.erl168
1 files changed, 111 insertions, 57 deletions
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index cd9359f2aa..ef5303defd 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
%% %CopyrightEnd%
%%
@@ -23,7 +24,8 @@
-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([set_path/1, get_path/1, add_path/1, add_paths/1, del_path/1,
replace_path/1, load_file/1, load_abs/1, ensure_loaded/1,
- delete/1, purge/1, soft_purge/1, is_loaded/1, all_loaded/1,
+ delete/1, purge/1, purge_many_exits/1, soft_purge/1, is_loaded/1,
+ all_loaded/1,
load_binary/1, dir_req/1, object_code/1, set_path_file/1,
upgrade/1,
sticky_dir/1, pa_pz_option/1, add_del_path/1,
@@ -36,8 +38,7 @@
native_early_modules/1, get_mode/1]).
-export([init_per_testcase/2, end_per_testcase/2,
- init_per_suite/1, end_per_suite/1,
- sticky_compiler/1]).
+ init_per_suite/1, end_per_suite/1]).
%% error_logger
-export([init/1,
@@ -51,10 +52,10 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[set_path, get_path, add_path, add_paths, del_path,
replace_path, load_file, load_abs, ensure_loaded,
- delete, purge, soft_purge, is_loaded, all_loaded,
+ delete, purge, purge_many_exits, soft_purge, is_loaded, all_loaded,
load_binary, dir_req, object_code, set_path_file,
upgrade,
- pa_pz_option, add_del_path, dir_disappeared,
+ sticky_dir, pa_pz_option, add_del_path, dir_disappeared,
ext_mod_dep, clash, load_cached, start_node_with_cache,
add_and_rehash, where_is_file_no_cache,
where_is_file_cached, purge_stacktrace, mult_lib_roots,
@@ -218,6 +219,13 @@ del_path(suite) -> [];
del_path(doc) -> [];
del_path(Config) when is_list(Config) ->
P = code:get_path(),
+ try
+ del_path_1(P)
+ after
+ code:set_path(P)
+ end.
+
+del_path_1(P) ->
test_server:format("Initial code:get_path()=~p~n",[P]),
{'EXIT',_} = (catch code:del_path(3)),
false = code:del_path(my_dummy_name),
@@ -225,19 +233,22 @@ del_path(Config) when is_list(Config) ->
Dir = filename:join([code:lib_dir(kernel),"ebin"]),
test_server:format("kernel dir: ~p~n",[Dir]),
-
true = code:del_path(kernel),
NewP = code:get_path(),
test_server:format("Path after removing 'kernel':~p~n",[NewP]),
ReferenceP = lists:delete(Dir,P),
test_server:format("Reference path:~p~n",[ReferenceP]),
NewP = ReferenceP, % check that dir is deleted
+ code:set_path(P),
+ %% An superfluous "/" should also work.
+ true = code:del_path("kernel/"),
+ NewP = ReferenceP, % check that dir is deleted
code:set_path(P),
+
true = code:del_path(Dir),
NewP1 = code:get_path(),
NewP1 = lists:delete(Dir,P), % check that dir is deleted
- code:set_path(P),
ok.
replace_path(suite) -> [];
@@ -369,6 +380,42 @@ purge(Config) when is_list(Config) ->
process_flag(trap_exit, OldFlag),
ok.
+purge_many_exits(Config) when is_list(Config) ->
+ OldFlag = process_flag(trap_exit, true),
+ code:purge(code_b_test),
+ {'EXIT',_} = (catch code:purge({})),
+ false = code:purge(code_b_test),
+ TPids = lists:map(fun (_) ->
+ {code_b_test:do_spawn(),
+ spawn_link(fun () ->
+ receive
+ after infinity -> ok
+ end
+ end)}
+ end,
+ lists:seq(1, 1000)),
+ % Give them time to start...
+ receive after 1000 -> ok end,
+ true = code:delete(code_b_test),
+ lists:foreach(fun ({Pid1, Pid2}) ->
+ true = erlang:is_process_alive(Pid1),
+ false = code_b_test:check_exit(Pid1),
+ true = erlang:is_process_alive(Pid2)
+ end, TPids),
+ true = code:purge(code_b_test),
+ lists:foreach(fun ({Pid1, Pid2}) ->
+ false = erlang:is_process_alive(Pid1),
+ true = code_b_test:check_exit(Pid1),
+ true = erlang:is_process_alive(Pid2),
+ exit(Pid2, kill)
+ end, TPids),
+ lists:foreach(fun ({_Pid1, Pid2}) ->
+ receive {'EXIT', Pid2, _} -> ok end
+ end, TPids),
+ process_flag(trap_exit, OldFlag),
+ ok.
+
+
soft_purge(suite) -> [];
soft_purge(doc) -> [];
soft_purge(Config) when is_list(Config) ->
@@ -540,35 +587,42 @@ sticky_dir(suite) -> [];
sticky_dir(doc) -> ["Test that a module with the same name as a module in ",
"a sticky directory cannot be loaded."];
sticky_dir(Config) when is_list(Config) ->
- MyDir=filename:dirname(code:which(?MODULE)),
- {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa \""++MyDir++"\""}]),
- File=filename:join([?config(data_dir, Config), "calendar"]),
- Ret=rpc:call(Node, ?MODULE, sticky_compiler, [File]),
+ Pa = filename:dirname(code:which(?MODULE)),
+ {ok,Node} = ?t:start_node(sticky_dir, slave, [{args,"-pa "++Pa}]),
+ Mods = [code,lists,erlang,init],
+ OutDir = filename:join(?config(priv_dir, Config), sticky_dir),
+ _ = file:make_dir(OutDir),
+ Ret = rpc:call(Node, erlang, apply,
+ [fun sticky_compiler/2,[Mods,OutDir]]),
case Ret of
- fail ->
- ?t:fail("c:c allowed a sticky module to be compiled and loaded.");
- ok ->
+ [] ->
ok;
Other ->
- test_server:format("Other: ~p",[Other])
+ io:format("~p\n", [Other]),
+ ?t:fail()
end,
- ?t:stop_node(Node).
+ ?t:stop_node(Node),
+ ok.
-sticky_compiler(File) ->
- Compiled=File++code:objfile_extension(),
- Dir=filename:dirname(File),
- code:add_patha(Dir),
- file:delete(Compiled),
- case c:c(File, [{outdir, Dir}]) of
- {ok, Module} ->
- case catch Module:test(apa) of
- {error, _} ->
- fail;
- {'EXIT', _} ->
- ok
- end;
- Other ->
- test_server:format("c:c(~p) returned: ~p",[File, Other]),
+sticky_compiler(Files, PrivDir) ->
+ code:add_patha(PrivDir),
+ Rets = [do_sticky_compile(F, PrivDir) || F <- Files],
+ [R || R <- Rets, R =/= ok].
+
+do_sticky_compile(Mod, Dir) ->
+ %% Make sure that the module is loaded. A module being sticky
+ %% only prevents it from begin reloaded, not from being loaded
+ %% from the wrong place to begin with.
+ Mod = Mod:module_info(module),
+ File = filename:append(Dir, atom_to_list(Mod)),
+ Src = io_lib:format("-module(~s).\n"
+ "-export([test/1]).\n"
+ "test(me) -> fail.\n", [Mod]),
+ ok = file:write_file(File++".erl", Src),
+ case c:c(File, [{outdir,Dir}]) of
+ {ok,Module} ->
+ Module:test(me);
+ {error,sticky_directory} ->
ok
end.
@@ -616,7 +670,7 @@ clash(Config) when is_list(Config) ->
DDir = ?config(data_dir,Config)++"clash/",
P = code:get_path(),
[TestServerPath|_] = [Path || Path <- code:get_path(),
- re:run(Path,"test_server/?$",[]) /= nomatch],
+ re:run(Path,"test_server/?$",[unicode]) /= nomatch],
%% test non-clashing entries
@@ -757,14 +811,6 @@ check_funs({'$M_EXPR','$F_EXPR',_},
{unicode,characters_to_binary,3},
{filename,filename_string_to_binary,1}|_]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
- [{code_server,load_native_code,4},
- {code_server,load_native_code_1,2},
- {code_server,load_native_code,2},
- {code_server,try_load_module,4},
- {code_server,do_load_binary,4},
- {code_server,handle_call,3},
- {code_server,loop,1}|_]) -> 0;
-check_funs({'$M_EXPR','$F_EXPR',_},
[{code_server,do_mod_call,4},
{code_server,handle_call,3}|_]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
@@ -813,8 +859,14 @@ check_funs({'$M_EXPR','$F_EXPR',_},
check_funs({'$M_EXPR',module_info,1},
[{hipe_unified_loader,patch_to_emu_step1,1} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,write_words,3} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,patch_label_or_labels,4} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
+ [{hipe_unified_loader,sort_and_write,5} | _]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',2},
[{lists,foldl,3},
- {hipe_unified_loader,sort_and_write,4} | _]) -> 0;
+ {hipe_unified_loader,sort_and_write,5} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',1},
[{lists,foreach,2},
{hipe_unified_loader,patch_consts,3} | _]) -> 0;
@@ -1343,8 +1395,9 @@ on_load_binary(_) ->
{tuple,6,[{atom,6,Mod},{call,6,{atom,6,self},[]}]}},
{'receive',7,[{clause,8,[{atom,8,go}],[],[{atom,8,ok}]}]}]}]},
{function,11,ok,0,[{clause,11,[],[],[{atom,11,true}]}]}],
- {ok,Mod,Bin} = compile:forms(Forms, [report]),
- [io:put_chars(erl_pp:form(F)) || F <- Forms],
+ Forms1 = erl_parse:new_anno(Forms),
+ {ok,Mod,Bin} = compile:forms(Forms1, [report]),
+ [io:put_chars(erl_pp:form(F)) || F <- Forms1],
{Pid1,Ref1} = spawn_monitor(fun() ->
code:load_binary(Mod, File, Bin),
@@ -1490,7 +1543,10 @@ create_big_script(Config,Local) ->
Leftover <- UnloadFix,
lists:keymember(Leftover,1,InitialApplications) ],
%% Now we should have only "real" applications...
- [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)],
+ [application:load(list_to_atom(Y))
+ || {match,[Y]} <- [re:run(X,code:lib_dir()++"/"++"([^/-]*).*/ebin",
+ [{capture,[1],list},unicode]) ||
+ X <- code:get_path()],filter_app(Y,Local)],
Apps = [ {N,V} || {N,_,V} <- application:loaded_applications()],
{ok,Fd} = file:open(Name ++ ".rel", [write]),
io:format(Fd,
@@ -1597,9 +1653,7 @@ get_mode(Config) when is_list(Config) ->
init(Tester) ->
{ok, Tester}.
-handle_event({error, _GL, {emulator, _, _}}, Tester) ->
- {ok, Tester};
-handle_event({error, _GL, Msg}, Tester) ->
+handle_event({warning_msg, _GL, Msg}, Tester) ->
Tester ! Msg,
{ok, Tester};
handle_event(_Event, State) ->