aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test')
-rw-r--r--lib/kernel/test/Makefile2
-rw-r--r--lib/kernel/test/application_SUITE.erl188
-rw-r--r--lib/kernel/test/application_SUITE_data/deadlock/deadlock.app2
-rw-r--r--lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl12
-rw-r--r--lib/kernel/test/code_SUITE.erl927
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl27
-rw-r--r--lib/kernel/test/file_SUITE.erl14
-rw-r--r--lib/kernel/test/file_name_SUITE.erl1
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl454
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl114
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl109
-rw-r--r--lib/kernel/test/global_SUITE_data/global_trace.erl1
-rw-r--r--lib/kernel/test/inet_SUITE.erl103
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl51
-rw-r--r--lib/kernel/test/kernel_SUITE.erl116
-rw-r--r--lib/kernel/test/kernel_smoke.spec9
-rw-r--r--lib/kernel/test/os_SUITE.erl26
-rw-r--r--lib/kernel/test/os_SUITE_data/my_echo.c28
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl3
-rw-r--r--lib/kernel/test/sendfile_SUITE.erl90
-rw-r--r--lib/kernel/test/zlib_SUITE.erl11
21 files changed, 1629 insertions, 659 deletions
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index cb11d4e899..f1b8a105ed 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -145,7 +145,7 @@ release_tests_spec: make_emakefile
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(APP_FILES) "$(RELSYSDIR)"
- $(INSTALL_DATA) kernel.spec $(EMAKEFILE)\
+ $(INSTALL_DATA) kernel.spec kernel_smoke.spec $(EMAKEFILE)\
$(COVERFILE) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 1ff291be54..c6cbd1a0ef 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. 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
@@ -33,10 +33,10 @@
permit_false_start_local/1, permit_false_start_dist/1, script_start/1,
nodedown_start/1, init2973/0, loop2973/0, loop5606/1]).
--export([config_change/1,
+-export([config_change/1, persistent_env/1,
distr_changed_tc1/1, distr_changed_tc2/1,
- ensure_started/1,
- shutdown_func/1, do_shutdown/1, shutdown_timeout/1]).
+ ensure_started/1, ensure_all_started/1,
+ shutdown_func/1, do_shutdown/1, shutdown_timeout/1, shutdown_deadlock/1]).
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
@@ -52,8 +52,10 @@ all() ->
[failover, failover_comp, permissions, load,
load_use_cache, ensure_started, {group, reported_bugs}, start_phases,
script_start, nodedown_start, permit_false_start_local,
- permit_false_start_dist, get_key, get_env,
- {group, distr_changed}, config_change, shutdown_func, shutdown_timeout].
+ permit_false_start_dist, get_key, get_env, ensure_all_started,
+ {group, distr_changed}, config_change, shutdown_func, shutdown_timeout,
+ shutdown_deadlock,
+ persistent_env].
groups() ->
[{reported_bugs, [],
@@ -960,7 +962,7 @@ nodedown_start(Conf) when is_list(Conf) ->
ensure_started(suite) -> [];
ensure_started(doc) -> ["Test application:ensure_started/1."];
-ensure_started(Conf) ->
+ensure_started(_Conf) ->
{ok, Fd} = file:open("app1.app", [write]),
w_app1(Fd),
@@ -978,6 +980,85 @@ ensure_started(Conf) ->
ok = application:unload(app1),
ok.
+ensure_all_started(suite) -> [];
+ensure_all_started(doc) -> ["Test application:ensure_all_started/1-2."];
+ensure_all_started(_Conf) ->
+
+ {ok, Fd1} = file:open("app1.app", [write]),
+ w_app1(Fd1),
+ file:close(Fd1),
+ {ok, Fd9} = file:open("app9.app", [write]),
+ w_app9(Fd9),
+ file:close(Fd9),
+ {ok, Fd10} = file:open("app10.app", [write]),
+ w_app10_dep9(Fd10),
+ file:close(Fd10),
+ {ok, FdErr} = file:open("app_chain_error.app", [write]),
+ w_app(FdErr, app_chain_error()),
+ file:close(FdErr),
+ {ok, FdErr2} = file:open("app_chain_error2.app", [write]),
+ w_app(FdErr2, app_chain_error2()),
+ file:close(FdErr2),
+
+ %% Single app start/stop
+ false = lists:keyfind(app1, 1, application:which_applications()),
+ {ok, [app1]} = application:ensure_all_started(app1), % app1 started
+ {app1, _, _} = lists:keyfind(app1, 1, application:which_applications()),
+ {ok, []} = application:ensure_all_started(app1), % no start needed
+ ok = application:stop(app1),
+ false = lists:keyfind(app1, 1, application:which_applications()),
+ ok = application:unload(app1),
+
+ %% App or dependency not found.
+ Name = hopefully_not_an_existing_app_file,
+ {error,{Name, {"no such file or directory", _ }}} =
+ application:ensure_all_started(Name),
+
+ %% Start dependencies.
+ {error, {not_started, app9}} = application:start(app10),
+ {ok, [app9,app10]} = application:ensure_all_started(app10, temporary),
+ {app9, _, _} = lists:keyfind(app9, 1, application:which_applications()),
+ {app10, _, _} = lists:keyfind(app10, 1, application:which_applications()),
+ %% Only report apps/dependencies that actually needed to start
+ ok = application:stop(app10),
+ ok = application:unload(app10),
+ {ok, [app10]} = application:ensure_all_started(app10, temporary),
+ ok = application:stop(app9),
+ ok = application:unload(app9),
+ ok = application:stop(app10),
+ ok = application:unload(app10),
+
+ %% Deeper failure chain. We have the following dependencies:
+ %% app_chain_error -> app_chain_error2
+ %% app_chain_error2 -> app10
+ %% app_chain_error2 -> hopefully_not_an_existing_app
+ %% app10 -> app 9
+ %% First we have none running and we expect to have neither app9
+ %% nor app10 running after failing to start
+ %% hopefully_not_an_existing_app
+ {error, {hopefully_not_an_existing_app, {"no such file or directory", _}}}=
+ application:ensure_all_started(app_chain_error),
+ false = lists:keyfind(app9, 1, application:which_applications()),
+ false = lists:keyfind(app10, 1, application:which_applications()),
+ false = lists:keyfind(app_chain_error2,1,application:which_applications()),
+ false = lists:keyfind(app_chain_error, 1, application:which_applications()),
+ %% Here we will have app9 already running, and app10 should be
+ %% able to boot fine.
+ %% In this dependency failing, we expect app9 to still be running, but
+ %% not app10 after failing to start hopefully_not_an_existing_app
+ {ok, [app9]} = application:ensure_all_started(app9, temporary),
+ {error, {hopefully_not_an_existing_app, {"no such file or directory", _}}}=
+ application:ensure_all_started(app_chain_error),
+ {app9, _, _} = lists:keyfind(app9, 1, application:which_applications()),
+ false = lists:keyfind(app10, 1, application:which_applications()),
+ false = lists:keyfind(app_chain_error2,1,application:which_applications()),
+ false = lists:keyfind(app_chain_error, 1, application:which_applications()),
+ ok = application:stop(app9),
+ ok = application:unload(app9),
+ ok = application:unload(app10),
+ ok = application:unload(app_chain_error2),
+ ok = application:unload(app_chain_error),
+ ok.
%%%-----------------------------------------------------------------
%%% Testing of reported bugs and other tickets.
@@ -1908,6 +1989,50 @@ get_appls([_ | T], Res) ->
get_appls([], Res) ->
Res.
+persistent_env(suite) ->
+ [];
+persistent_env(doc) ->
+ ["Test set_env/4 and unset_env/3 with persistent true"];
+persistent_env(Conf) when is_list(Conf) ->
+ ok = application:set_env(appinc, own2, persist, [{persistent, true}]),
+ ok = application:set_env(appinc, key1, persist, [{persistent, true}]),
+
+ %% own_env1 and own2 are set in appinc
+ ok = application:load(appinc()),
+ {ok, value1} = application:get_env(appinc, own_env1),
+ {ok, persist} = application:get_env(appinc, own2),
+ {ok, persist} = application:get_env(appinc, key1),
+
+ %% Changing the environment after loaded reflects and should persist
+ ok = application:set_env(appinc, own_env1, persist, [{persistent, true}]),
+ {ok, persist} = application:get_env(appinc, own_env1),
+ {ok, persist} = application:get_env(appinc, own2),
+ {ok, persist} = application:get_env(appinc, key1),
+
+ %% On reload, own_env1, own2 and key1 should all persist
+ ok = application:unload(appinc),
+ ok = application:load(appinc()),
+ {ok, persist} = application:get_env(appinc, own_env1),
+ {ok, persist} = application:get_env(appinc, own2),
+ {ok, persist} = application:get_env(appinc, key1),
+
+ %% Unset own_env1 and key1, own2 should still persist
+ ok = application:unset_env(appinc, own_env1, [{persistent, true}]),
+ ok = application:unset_env(appinc, key1, [{persistent, true}]),
+ undefined = application:get_env(appinc, own_env1),
+ {ok, persist} = application:get_env(appinc, own2),
+ undefined = application:get_env(appinc, key1),
+
+ %% own_env1 should be back to its application value on reload
+ ok = application:unload(appinc),
+ ok = application:load(appinc()),
+ {ok, value1} = application:get_env(appinc, own_env1),
+ {ok, persist} = application:get_env(appinc, own2),
+ undefined = application:get_env(appinc, key1),
+
+ %% Clean up
+ ok = application:unload(appinc).
+
%%%-----------------------------------------------------------------
%%% Tests the 'shutdown_func' kernel config parameter
%%%-----------------------------------------------------------------
@@ -1972,7 +2097,32 @@ shutdown_timeout(Config) when is_list(Config) ->
end,
ok.
+%%%-----------------------------------------------------------------
+%%% Provokes a (previous) application shutdown deadlock
+%%%-----------------------------------------------------------------
+shutdown_deadlock(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir,Config),
+ code:add_path(filename:join([DataDir,deadlock])),
+ %% ok = rpc:call(Cp1, application, start, [sasl]),
+ ok = application:start(deadlock),
+ Tester = self(),
+ application:set_env(deadlock, fail_stop, Tester),
+ spawn(fun() -> Tester ! {stop, application:stop(deadlock)} end),
+ receive
+ {deadlock, Server} ->
+ spawn(fun() ->
+ Master = application_controller:get_master(deadlock),
+ Child = application_master:get_child(Master),
+ Tester ! {child, Child}
+ end),
+ timer:sleep(100),
+ erlang:display({self(), "Sending Continue", Server}),
+ Server ! continue
+ end,
+ [_|_] = application:which_applications(),
+ application:unload(deadlock), % clean up!
+ ok.
%%-----------------------------------------------------------------
@@ -2125,6 +2275,24 @@ app_start_error() ->
{applications, [kernel]},
{mod, {app_start_error, []}}]}.
+app_chain_error() ->
+ {application, app_chain_error,
+ [{description, "ERTS CXC 138 ce"},
+ {vsn, "2.0"},
+ {modules, []},
+ {registered, []},
+ {applications, [kernel, app_chain_error2]},
+ {mod, {ch_sup, {app_chain_error, 20,20}}}]}.
+
+app_chain_error2() ->
+ {application, app_chain_error2,
+ [{description, "ERTS CXC 138 ce2"},
+ {vsn, "2.0"},
+ {modules, []},
+ {registered, []},
+ {applications, [kernel, app10, hopefully_not_an_existing_app]},
+ {mod, {ch_sup, {app_chain_error2, 21,21}}}]}.
+
app_group_leader() ->
{application, group_leader,
[{description, "GROUP_LEADER CXC 138 11"},
@@ -2374,6 +2542,12 @@ w_app7(Fd) ->
w_app8(Fd) ->
io:format(Fd, "~p.\n", [app8()]).
+w_app9(Fd) ->
+ io:format(Fd, "~p.\n", [app9()]).
+
+w_app10_dep9(Fd) ->
+ io:format(Fd, "~p.\n", [app10_dep9()]).
+
w_app_start_error(Fd) ->
io:format(Fd, "~p.\n", [app_start_error()]).
diff --git a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app
index 0c1001bed6..233c7a3f76 100644
--- a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app
+++ b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.app
@@ -4,5 +4,5 @@
{applications, [kernel, stdlib, sasl]},
{modules, [deadlock]},
{mod, {deadlock, []}},
- {env, [{fail_start, false}]}
+ {env, [{fail_start, false}, {fail_stop, false}]}
]}.
diff --git a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl
index 5f68bf9078..3ef6105371 100644
--- a/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl
+++ b/lib/kernel/test/application_SUITE_data/deadlock/deadlock.erl
@@ -21,7 +21,7 @@ init([sup]) ->
{ok, {{one_for_one, 5, 10}, [
{
sasl_syslog_dm, {?MODULE, start_link, []},
- permanent, brutal_kill, worker,
+ permanent, 25000, worker,
[deadlock]
}
]}};
@@ -32,6 +32,8 @@ init([sup]) ->
init([child]) ->
case application:get_env(deadlock, fail_start) of
{ok, false} ->
+ process_flag(trap_exit, true),
+ io:format("~p: Traps exit~n",[?MODULE]),
%% we must not fail on the first init, otherwise supervisor
%% terminates immediately
{ok, []};
@@ -50,6 +52,14 @@ handle_info(_Msg, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
+ case application:get_env(deadlock, fail_stop) of
+ {ok, false} -> ok;
+ {ok, Tester} ->
+ Tester ! {deadlock, self()},
+ io:format("~p: Waiting in terminate (~p)~n",[?MODULE,Tester]),
+ receive continue -> ok end
+ end,
+ io:format("~p: terminates~n", [?MODULE]),
ok.
code_change(_OldVsn, State, _Extra) ->
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index fc17db2745..42b81d16b3 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -23,7 +23,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,
@@ -35,7 +36,7 @@
on_load_embedded/1, on_load_errors/1, big_boot_embedded/1,
native_early_modules/1, get_mode/1]).
--export([init_per_testcase/2, end_per_testcase/2,
+-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1,
sticky_compiler/1]).
@@ -48,10 +49,10 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
+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,
@@ -62,7 +63,7 @@ all() ->
on_load_binary, on_load_embedded, on_load_errors,
big_boot_embedded, native_early_modules, get_mode].
-groups() ->
+groups() ->
[].
init_per_group(_GroupName, Config) ->
@@ -76,10 +77,10 @@ init_per_suite(Config) ->
%% the module name does not match the filename, so
%% we must compile to a binary and write the Beam file
%% ourselves.
- ?line Dir = filename:dirname(code:which(?MODULE)),
- ?line File = filename:join(Dir, "code_a_test"),
- ?line {ok,code_b_test,Code} = compile:file(File, [binary]),
- ?line ok = file:write_file(File++".beam", Code),
+ Dir = filename:dirname(code:which(?MODULE)),
+ File = filename:join(Dir, "code_a_test"),
+ {ok,code_b_test,Code} = compile:file(File, [binary]),
+ ok = file:write_file(File++".beam", Code),
Config.
end_per_suite(Config) ->
@@ -98,7 +99,7 @@ init_per_testcase(_Func, Config) ->
P=code:get_path(),
[{watchdog, Dog}, {code_path, P}|Config].
-end_per_testcase(TC, Config) when TC == mult_lib_roots;
+end_per_testcase(TC, Config) when TC == mult_lib_roots;
TC == big_boot_embedded ->
{ok, HostName} = inet:gethostname(),
NodeName = list_to_atom(atom_to_list(TC)++"@"++HostName),
@@ -121,51 +122,49 @@ set_path(doc) -> [];
set_path(Config) when is_list(Config) ->
P = code:get_path(),
NonExDir = filename:join(?config(priv_dir, Config), ?t:temp_name("hej")),
- ?line {'EXIT',_} = (catch code:set_path({a})),
- ?line {error, bad_directory} = (catch code:set_path([{a}])),
- ?line {error, bad_directory} = code:set_path(NonExDir),
- ?line P = code:get_path(), % still the same path.
- ?line true = code:set_path(P), % set the same path again.
- ?line P = code:get_path(), % still the same path.
+ {'EXIT',_} = (catch code:set_path({a})),
+ {error, bad_directory} = (catch code:set_path([{a}])),
+ {error, bad_directory} = code:set_path(NonExDir),
+ P = code:get_path(), % still the same path.
+ true = code:set_path(P), % set the same path again.
+ P = code:get_path(), % still the same path.
LibDir = code:lib_dir(),
- ?line true = code:set_path([LibDir | P]),
- ?line [LibDir | P] = code:get_path(),
- ?line true = code:set_path([LibDir]),
- ?line [LibDir] = code:get_path(),
+ true = code:set_path([LibDir | P]),
+ [LibDir | P] = code:get_path(),
+ true = code:set_path([LibDir]),
+ [LibDir] = code:get_path(),
ok.
get_path(suite) -> [];
get_path(doc) -> [];
get_path(Config) when is_list(Config) ->
- ?line P = code:get_path(),
+ P = code:get_path(),
% test that all directories are strings (lists).
- ?line [] = lists:filter(fun(Dir) when is_list(Dir) ->
- false;
- (_) ->
- true
- end,
- P),
+ [] = lists:filter(fun
+ (Dir) when is_list(Dir) -> false;
+ (_) -> true
+ end, P),
ok.
add_path(suite) -> [];
add_path(doc) -> [];
add_path(Config) when is_list(Config) ->
P = code:get_path(),
- ?line {'EXIT',_} = (catch code:add_path({})),
- ?line {'EXIT',_} = (catch code:add_patha({})),
- ?line {'EXIT',_} = (catch code:add_pathz({})),
- ?line {error, bad_directory} = code:add_path("xyz"),
- ?line {error, bad_directory} = code:add_patha("xyz"),
- ?line {error, bad_directory} = code:add_pathz("xyz"),
+ {'EXIT',_} = (catch code:add_path({})),
+ {'EXIT',_} = (catch code:add_patha({})),
+ {'EXIT',_} = (catch code:add_pathz({})),
+ {error, bad_directory} = code:add_path("xyz"),
+ {error, bad_directory} = code:add_patha("xyz"),
+ {error, bad_directory} = code:add_pathz("xyz"),
LibDir = code:lib_dir(),
- ?line true = code:add_path(LibDir),
- ?line LibDir = lists:last(code:get_path()),
+ true = code:add_path(LibDir),
+ LibDir = lists:last(code:get_path()),
code:set_path(P),
- ?line true = code:add_pathz(LibDir),
- ?line LibDir = lists:last(code:get_path()),
+ true = code:add_pathz(LibDir),
+ LibDir = lists:last(code:get_path()),
code:set_path(P),
- ?line true = code:add_patha(LibDir),
- ?line [LibDir|_] = code:get_path(),
+ true = code:add_patha(LibDir),
+ [LibDir|_] = code:get_path(),
code:set_path(P),
ok.
@@ -173,134 +172,134 @@ add_paths(suite) -> [];
add_paths(doc) -> [];
add_paths(Config) when is_list(Config) ->
P = code:get_path(),
- ?line ok = code:add_paths([{}]),
- ?line ok = code:add_pathsa([{}]),
- ?line ok = code:add_pathsz([{}]),
- ?line ok = code:add_paths(["xyz"]),
- ?line ok = code:add_pathsa(["xyz"]),
- ?line ok = code:add_pathsz(["xyz"]),
+ ok = code:add_paths([{}]),
+ ok = code:add_pathsa([{}]),
+ ok = code:add_pathsz([{}]),
+ ok = code:add_paths(["xyz"]),
+ ok = code:add_pathsa(["xyz"]),
+ ok = code:add_pathsz(["xyz"]),
P = code:get_path(), % check that no directory is added.
LibDir = code:lib_dir(),
- ?line ok = code:add_paths([LibDir]),
- ?line LibDir = lists:last(code:get_path()),
+ ok = code:add_paths([LibDir]),
+ LibDir = lists:last(code:get_path()),
code:set_path(P),
- ?line ok = code:add_pathsz([LibDir]),
- ?line LibDir = lists:last(code:get_path()),
+ ok = code:add_pathsz([LibDir]),
+ LibDir = lists:last(code:get_path()),
code:set_path(P),
- ?line ok = code:add_pathsa([LibDir]),
- ?line [LibDir|P] = code:get_path(),
+ ok = code:add_pathsa([LibDir]),
+ [LibDir|P] = code:get_path(),
code:set_path(P),
RootDir = code:root_dir(),
Res = P ++ [LibDir, RootDir],
- ?line ok = code:add_paths([LibDir, RootDir]),
- ?line Res = code:get_path(),
+ ok = code:add_paths([LibDir, RootDir]),
+ Res = code:get_path(),
code:set_path(P),
- ?line ok = code:add_pathsz([LibDir, RootDir]),
- ?line Res = code:get_path(),
+ ok = code:add_pathsz([LibDir, RootDir]),
+ Res = code:get_path(),
code:set_path(P),
- ?line ok = code:add_pathsa([LibDir, RootDir]),
- ?line [RootDir, LibDir|P] = code:get_path(),
+ ok = code:add_pathsa([LibDir, RootDir]),
+ [RootDir, LibDir|P] = code:get_path(),
code:set_path(P),
- ?line ok = code:add_paths([LibDir, "xyz"]),
+ ok = code:add_paths([LibDir, "xyz"]),
Res1 = P ++ [LibDir],
- ?line Res1 = code:get_path(),
+ Res1 = code:get_path(),
code:set_path(P),
- ?line ok = code:add_pathsz([LibDir, "xyz"]),
- ?line Res1 = code:get_path(),
+ ok = code:add_pathsz([LibDir, "xyz"]),
+ Res1 = code:get_path(),
code:set_path(P),
- ?line ok = code:add_pathsa([LibDir, "xyz"]),
- ?line [LibDir|P] = code:get_path(),
+ ok = code:add_pathsa([LibDir, "xyz"]),
+ [LibDir|P] = code:get_path(),
code:set_path(P),
ok.
del_path(suite) -> [];
del_path(doc) -> [];
del_path(Config) when is_list(Config) ->
- ?line P = code:get_path(),
+ P = code:get_path(),
test_server:format("Initial code:get_path()=~p~n",[P]),
- ?line {'EXIT',_} = (catch code:del_path(3)),
- ?line false = code:del_path(my_dummy_name),
- ?line false = code:del_path("/kdlk/my_dummy_dir"),
+ {'EXIT',_} = (catch code:del_path(3)),
+ false = code:del_path(my_dummy_name),
+ false = code:del_path("/kdlk/my_dummy_dir"),
Dir = filename:join([code:lib_dir(kernel),"ebin"]),
test_server:format("kernel dir: ~p~n",[Dir]),
- ?line true = code:del_path(kernel),
+ 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]),
- ?line NewP = ReferenceP, % check that dir is deleted
+ NewP = ReferenceP, % check that dir is deleted
code:set_path(P),
- ?line true = code:del_path(Dir),
+ true = code:del_path(Dir),
NewP1 = code:get_path(),
- ?line NewP1 = lists:delete(Dir,P), % check that dir is deleted
+ NewP1 = lists:delete(Dir,P), % check that dir is deleted
code:set_path(P),
ok.
replace_path(suite) -> [];
replace_path(doc) -> [];
replace_path(Config) when is_list(Config) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line P = code:get_path(),
- ?line {'EXIT',_} = (catch code:replace_path(3,"")),
- ?line {error, bad_name} = code:replace_path(dummy_name,""),
- ?line {error, bad_name} = code:replace_path(kernel,
+ PrivDir = ?config(priv_dir, Config),
+ P = code:get_path(),
+ {'EXIT',_} = (catch code:replace_path(3,"")),
+ {error, bad_name} = code:replace_path(dummy_name,""),
+ {error, bad_name} = code:replace_path(kernel,
"/kdlk/my_dummy_dir"),
- ?line {error, bad_directory} = code:replace_path(kernel,
+ {error, bad_directory} = code:replace_path(kernel,
"/kdlk/kernel-1.2"),
- ?line P = code:get_path(), % Check that path is not changed.
+ P = code:get_path(), % Check that path is not changed.
- ?line ok = file:set_cwd(PrivDir),
+ ok = file:set_cwd(PrivDir),
%% Replace an existing application.
file:make_dir("./kernel-2.11"),
{ok, Cwd} = file:get_cwd(),
NewDir = Cwd ++ "/kernel-2.11",
- ?line true = code:replace_path(kernel, NewDir),
- ?line NewDir = code:lib_dir(kernel),
- ?line true = code:set_path(P), %Reset path
- ?line ok = file:del_dir("./kernel-2.11"),
+ true = code:replace_path(kernel, NewDir),
+ NewDir = code:lib_dir(kernel),
+ true = code:set_path(P), %Reset path
+ ok = file:del_dir("./kernel-2.11"),
%% Add a completly new application.
NewAppName = 'blurf_blarfer',
- ?line NewAppDir = filename:join(Cwd, atom_to_list(NewAppName) ++ "-6.33.1"),
- ?line ok = file:make_dir(NewAppDir),
- ?line true = code:replace_path(NewAppName, NewAppDir),
- ?line NewAppDir = code:lib_dir(NewAppName),
- ?line NewAppDir = lists:last(code:get_path()),
- ?line true = code:set_path(P), %Reset path
- ?line ok = file:del_dir(NewAppDir),
+ NewAppDir = filename:join(Cwd, atom_to_list(NewAppName) ++ "-6.33.1"),
+ ok = file:make_dir(NewAppDir),
+ true = code:replace_path(NewAppName, NewAppDir),
+ NewAppDir = code:lib_dir(NewAppName),
+ NewAppDir = lists:last(code:get_path()),
+ true = code:set_path(P), %Reset path
+ ok = file:del_dir(NewAppDir),
ok.
dir_disappeared(suite) -> [];
dir_disappeared(doc) -> ["OTP-3977"];
dir_disappeared(Config) when is_list(Config) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Dir = filename:join(PrivDir, "temp"),
- ?line ok = file:make_dir(Dir),
- ?line true = code:add_path(Dir),
- ?line ok = file:del_dir(Dir),
- ?line non_existing = code:which(bubbelskrammel),
+ PrivDir = ?config(priv_dir, Config),
+ Dir = filename:join(PrivDir, "temp"),
+ ok = file:make_dir(Dir),
+ true = code:add_path(Dir),
+ ok = file:del_dir(Dir),
+ non_existing = code:which(bubbelskrammel),
ok.
load_file(suite) -> [];
load_file(doc) -> [];
load_file(Config) when is_list(Config) ->
- ?line {error, nofile} = code:load_file(duuuumy_mod),
- ?line {error, badfile} = code:load_file(code_a_test),
- ?line {'EXIT', _} = (catch code:load_file(123)),
- ?line {module, code_b_test} = code:load_file(code_b_test),
+ {error, nofile} = code:load_file(duuuumy_mod),
+ {error, badfile} = code:load_file(code_a_test),
+ {'EXIT', _} = (catch code:load_file(123)),
+ {module, code_b_test} = code:load_file(code_b_test),
TestDir = test_dir(),
code:stick_dir(TestDir),
- ?line {error, sticky_directory} = code:load_file(code_b_test),
+ {error, sticky_directory} = code:load_file(code_b_test),
code:unstick_dir(TestDir),
ok.
@@ -311,30 +310,30 @@ load_abs(suite) -> [];
load_abs(doc) -> [];
load_abs(Config) when is_list(Config) ->
TestDir = test_dir(),
- ?line {error, nofile} = code:load_abs(TestDir ++ "/duuuumy_mod"),
- ?line {error, badfile} = code:load_abs(TestDir ++ "/code_a_test"),
- ?line {'EXIT', _} = (catch code:load_abs({})),
- ?line {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
+ {error, nofile} = code:load_abs(TestDir ++ "/duuuumy_mod"),
+ {error, badfile} = code:load_abs(TestDir ++ "/code_a_test"),
+ {'EXIT', _} = (catch code:load_abs({})),
+ {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
code:stick_dir(TestDir),
- ?line {error, sticky_directory} = code:load_abs(TestDir ++ "/code_b_test"),
+ {error, sticky_directory} = code:load_abs(TestDir ++ "/code_b_test"),
code:unstick_dir(TestDir),
ok.
ensure_loaded(suite) -> [];
ensure_loaded(doc) -> [];
ensure_loaded(Config) when is_list(Config) ->
- ?line {module, lists} = code:ensure_loaded(lists),
+ {module, lists} = code:ensure_loaded(lists),
case init:get_argument(mode) of
{ok, [["embedded"]]} ->
- ?line {error, embedded} = code:ensure_loaded(code_b_test),
- ?line {error, badarg} = code:ensure_loaded(34),
+ {error, embedded} = code:ensure_loaded(code_b_test),
+ {error, badarg} = code:ensure_loaded(34),
ok;
_ ->
- ?line {error, nofile} = code:ensure_loaded(duuuumy_mod),
- ?line {error, badfile} = code:ensure_loaded(code_a_test),
- ?line {'EXIT', _} = (catch code:ensure_loaded(34)),
- ?line {module, code_b_test} = code:ensure_loaded(code_b_test),
- ?line {module, code_b_test} = code:ensure_loaded(code_b_test),
+ {error, nofile} = code:ensure_loaded(duuuumy_mod),
+ {error, badfile} = code:ensure_loaded(code_a_test),
+ {'EXIT', _} = (catch code:ensure_loaded(34)),
+ {module, code_b_test} = code:ensure_loaded(code_b_test),
+ {module, code_b_test} = code:ensure_loaded(code_b_test),
ok
end.
@@ -343,15 +342,15 @@ delete(doc) -> [];
delete(Config) when is_list(Config) ->
OldFlag = process_flag(trap_exit, true),
code:purge(code_b_test),
- ?line Pid = code_b_test:do_spawn(),
- ?line true = code:delete(code_b_test),
- ?line {'EXIT',_} = (catch code:delete(122)),
- ?line false = code_b_test:check_exit(Pid),
- ?line false = code:delete(code_b_test),
- ?line false = code_b_test:check_exit(Pid),
+ Pid = code_b_test:do_spawn(),
+ true = code:delete(code_b_test),
+ {'EXIT',_} = (catch code:delete(122)),
+ false = code_b_test:check_exit(Pid),
+ false = code:delete(code_b_test),
+ false = code_b_test:check_exit(Pid),
exit(Pid,kill),
- ?line true = code_b_test:check_exit(Pid),
- ?line false = code:delete(code_b_test),
+ true = code_b_test:check_exit(Pid),
+ false = code:delete(code_b_test),
code:purge(code_b_test),
process_flag(trap_exit, OldFlag),
ok.
@@ -361,31 +360,67 @@ purge(doc) -> [];
purge(Config) when is_list(Config) ->
OldFlag = process_flag(trap_exit, true),
code:purge(code_b_test),
- ?line {'EXIT',_} = (catch code:purge({})),
- ?line false = code:purge(code_b_test),
- ?line Pid = code_b_test:do_spawn(),
- ?line true = code:delete(code_b_test),
- ?line false = code_b_test:check_exit(Pid),
- ?line true = code:purge(code_b_test),
- ?line true = code_b_test:check_exit(Pid),
+ {'EXIT',_} = (catch code:purge({})),
+ false = code:purge(code_b_test),
+ Pid = code_b_test:do_spawn(),
+ true = code:delete(code_b_test),
+ false = code_b_test:check_exit(Pid),
+ true = code:purge(code_b_test),
+ true = code_b_test:check_exit(Pid),
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) ->
OldFlag = process_flag(trap_exit, true),
code:purge(code_b_test),
- ?line {'EXIT',_} = (catch code:soft_purge(23)),
- ?line true = code:soft_purge(code_b_test),
- ?line Pid = code_b_test:do_spawn(),
- ?line true = code:delete(code_b_test),
- ?line false = code_b_test:check_exit(Pid),
- ?line false = code:soft_purge(code_b_test),
- ?line false = code_b_test:check_exit(Pid),
+ {'EXIT',_} = (catch code:soft_purge(23)),
+ true = code:soft_purge(code_b_test),
+ Pid = code_b_test:do_spawn(),
+ true = code:delete(code_b_test),
+ false = code_b_test:check_exit(Pid),
+ false = code:soft_purge(code_b_test),
+ false = code_b_test:check_exit(Pid),
exit(Pid,kill),
- ?line true = code_b_test:check_exit(Pid),
- ?line true = code:soft_purge(code_b_test),
+ true = code_b_test:check_exit(Pid),
+ true = code:soft_purge(code_b_test),
process_flag(trap_exit, OldFlag),
ok.
@@ -394,12 +429,12 @@ is_loaded(doc) -> [];
is_loaded(Config) when is_list(Config) ->
code:purge(code_b_test),
code:delete(code_b_test),
- ?line false = code:is_loaded(duuuuuumy_mod),
- ?line {'EXIT',_} = (catch code:is_loaded(23)),
- ?line {file, preloaded} = code:is_loaded(init),
+ false = code:is_loaded(duuuuuumy_mod),
+ {'EXIT',_} = (catch code:is_loaded(23)),
+ {file, preloaded} = code:is_loaded(init),
TestDir = test_dir(),
- ?line {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
- ?line {file, _Loaded} = code:is_loaded(code_b_test),
+ {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
+ {file, _Loaded} = code:is_loaded(code_b_test),
code:purge(code_b_test),
code:delete(code_b_test),
ok.
@@ -413,21 +448,19 @@ all_loaded(Config) when is_list(Config) ->
end.
all_loaded_1() ->
- ?line Preloaded = [{M,preloaded} || M <- lists:sort(erlang:pre_loaded())],
+ Preloaded = [{M,preloaded} || M <- lists:sort(erlang:pre_loaded())],
- ?line Loaded0 = lists:sort(code:all_loaded()),
- ?line all_unique(Loaded0),
- ?line Loaded1 = lists:keysort(2, Loaded0),
- ?line Loaded2 = match_and_remove(Preloaded, Loaded1),
+ Loaded0 = lists:sort(code:all_loaded()),
+ all_unique(Loaded0),
+ Loaded1 = lists:keysort(2, Loaded0),
+ Loaded2 = match_and_remove(Preloaded, Loaded1),
ObjExt = code:objfile_extension(),
- ?line [] = lists:filter(fun({Mod,AbsName}) when is_atom(Mod),
- is_list(AbsName) ->
- Mod =/= list_to_atom(filename:basename(AbsName,
- ObjExt));
- (_) -> true
- end,
- Loaded2),
+ [] = lists:filter(fun
+ ({Mod,AbsName}) when is_atom(Mod), is_list(AbsName) ->
+ Mod =/= list_to_atom(filename:basename(AbsName, ObjExt));
+ (_) -> true
+ end, Loaded2),
ok.
match_and_remove([], List) -> List;
@@ -442,19 +475,19 @@ load_binary(doc) -> [];
load_binary(Config) when is_list(Config) ->
TestDir = test_dir(),
File = TestDir ++ "/code_b_test" ++ code:objfile_extension(),
- ?line {ok,Bin} = file:read_file(File),
- ?line {'EXIT',_} = (catch code:load_binary(12, File, Bin)),
- ?line {'EXIT',_} = (catch code:load_binary(code_b_test, 12, Bin)),
- ?line {'EXIT',_} = (catch code:load_binary(code_b_test, File, 12)),
- ?line {module, code_b_test} = code:load_binary(code_b_test, File, Bin),
+ {ok,Bin} = file:read_file(File),
+ {'EXIT',_} = (catch code:load_binary(12, File, Bin)),
+ {'EXIT',_} = (catch code:load_binary(code_b_test, 12, Bin)),
+ {'EXIT',_} = (catch code:load_binary(code_b_test, File, 12)),
+ {module, code_b_test} = code:load_binary(code_b_test, File, Bin),
code:stick_dir(TestDir),
- ?line {error, sticky_directory} = code:load_binary(code_b_test, File, Bin),
+ {error, sticky_directory} = code:load_binary(code_b_test, File, Bin),
code:unstick_dir(TestDir),
code:purge(code_b_test),
code:delete(code_b_test),
ok.
-upgrade(Config) ->
+upgrade(Config) ->
DataDir = ?config(data_dir, Config),
%%T = [beam, hipe],
@@ -462,28 +495,28 @@ upgrade(Config) ->
[upgrade_do(DataDir, Client, U1, U2, O1, O2)
|| Client<-T, U1<-T, U2<-T, O1<-T, O2<-T],
-
+
ok.
upgrade_do(DataDir, Client, U1, U2, O1, O2) ->
- compile_load(upgrade_client, DataDir, undefined, Client),
+ compile_load(upgrade_client, DataDir, undefined, Client),
upgrade_client:run(DataDir, U1, U2, O1, O2),
ok.
compile_load(Mod, Dir, Ver, CodeType) ->
Version = case Ver of
- undefined ->
- io:format("Compiling '~p' as ~p\n", [Mod, CodeType]),
- [];
- _ ->
- io:format("Compiling version ~p of '~p' as ~p\n",
- [Ver, Mod, CodeType]),
- [{d,list_to_atom("VERSION_" ++ integer_to_list(Ver))}]
- end,
+ undefined ->
+ io:format("Compiling '~p' as ~p\n", [Mod, CodeType]),
+ [];
+ _ ->
+ io:format("Compiling version ~p of '~p' as ~p\n",
+ [Ver, Mod, CodeType]),
+ [{d,list_to_atom("VERSION_" ++ integer_to_list(Ver))}]
+ end,
Target = case CodeType of
- beam -> [];
- hipe -> [native]
- end,
+ beam -> [];
+ hipe -> [native]
+ end,
CompOpts = [binary, report] ++ Target ++ Version,
Src = filename:join(Dir, atom_to_list(Mod) ++ ".erl"),
@@ -497,17 +530,17 @@ compile_load(Mod, Dir, Ver, CodeType) ->
dir_req(suite) -> [];
dir_req(doc) -> [];
dir_req(Config) when is_list(Config) ->
- ?line {ok,[[Root0]]} = init:get_argument(root),
- ?line Root = filename:join([Root0]), % Normalised form.
- ?line Root = code:root_dir(),
+ {ok,[[Root0]]} = init:get_argument(root),
+ Root = filename:join([Root0]), % Normalised form.
+ Root = code:root_dir(),
LibDir = Root ++ "/lib",
- ?line LibDir = code:lib_dir(),
- ?line code:compiler_dir(),
- ?line {error, bad_name} = code:lib_dir(duuumy),
- ?line KernLib = code:lib_dir(kernel),
- ?line Priv = KernLib ++ "/priv",
- ?line Priv = code:priv_dir(kernel),
- ?line {error, bad_name} = code:priv_dir(duuumy),
+ LibDir = code:lib_dir(),
+ code:compiler_dir(),
+ {error, bad_name} = code:lib_dir(duuumy),
+ KernLib = code:lib_dir(kernel),
+ Priv = KernLib ++ "/priv",
+ Priv = code:priv_dir(kernel),
+ {error, bad_name} = code:priv_dir(duuumy),
ok.
object_code(suite) -> [];
@@ -517,19 +550,19 @@ object_code(Config) when is_list(Config) ->
P = code:get_path(),
P = code:get_path(),
code:add_path(TestDir),
- ?line {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
+ {module, code_b_test} = code:load_abs(TestDir ++ "/code_b_test"),
LoadedFile = filename:absname(TestDir ++ "/code_b_test" ++
code:objfile_extension()),
- ?line case code:get_object_code(code_b_test) of
+ case code:get_object_code(code_b_test) of
{code_b_test,Bin,LoadedFile} when is_binary(Bin) ->
ok
end,
code:purge(code_b_test),
code:delete(code_b_test),
- ?line error = code:get_object_code(dddddddduuuuuuumy),
- ?line {'EXIT',_} = (catch code:get_object_code(23)),
- ?line code:set_path(P),
- ?line P=code:get_path(),
+ error = code:get_object_code(dddddddduuuuuuumy),
+ {'EXIT',_} = (catch code:get_object_code(23)),
+ code:set_path(P),
+ P=code:get_path(),
ok.
set_path_file(suite) -> [];
@@ -537,17 +570,17 @@ set_path_file(doc) -> ["Test that set_path does not accept ",
"files as pathnames (known previous bug)"];
set_path_file(Config) when is_list(Config) ->
File=filename:join(?config(priv_dir, Config), "testfil"),
- ?line ok=file:write_file(File, list_to_binary("lite data")),
- ?line {error, bad_directory}=code:set_path([File]).
+ ok=file:write_file(File, list_to_binary("lite data")),
+ {error, bad_directory}=code:set_path([File]).
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)),
- ?line {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa \""++MyDir++"\""}]),
+ {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa \""++MyDir++"\""}]),
File=filename:join([?config(data_dir, Config), "calendar"]),
- ?line Ret=rpc:call(Node, ?MODULE, sticky_compiler, [File]),
+ Ret=rpc:call(Node, ?MODULE, sticky_compiler, [File]),
case Ret of
fail ->
?t:fail("c:c allowed a sticky module to be compiled and loaded.");
@@ -607,70 +640,70 @@ add_del_path(Config) when is_list(Config) ->
Dir1 = filename:join(DDir,"dummy_app-1.0/ebin"),
Dir2 = filename:join(DDir,"dummy_app-2.0/ebin"),
code:add_patha(Dir1),
- ?line PrivDir1 = filename:join(DDir,"dummy_app-1.0/priv"),
- ?line PrivDir1 = code:priv_dir(dummy_app),
- ?line code:add_path(Dir2), % put last in path
- ?line PrivDir1 = code:priv_dir(dummy_app),
- ?line code:del_path(Dir2),
- ?line PrivDir1 = code:priv_dir(dummy_app),
+ PrivDir1 = filename:join(DDir,"dummy_app-1.0/priv"),
+ PrivDir1 = code:priv_dir(dummy_app),
+ code:add_path(Dir2), % put last in path
+ PrivDir1 = code:priv_dir(dummy_app),
+ code:del_path(Dir2),
+ PrivDir1 = code:priv_dir(dummy_app),
ok.
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],
+ [TestServerPath|_] = [Path || Path <- code:get_path(),
+ re:run(Path,"test_server/?$",[unicode]) /= nomatch],
%% test non-clashing entries
%% remove TestServerPath to prevent clash with test-server path
- ?line true = code:del_path(TestServerPath),
- ?line true = code:add_path(DDir++"foobar-0.1/ebin"),
- ?line true = code:add_path(DDir++"zork-0.8/ebin"),
+ true = code:del_path(TestServerPath),
+ true = code:add_path(DDir++"foobar-0.1/ebin"),
+ true = code:add_path(DDir++"zork-0.8/ebin"),
test_server:capture_start(),
- ?line ok = code:clash(),
+ ok = code:clash(),
test_server:capture_stop(),
- ?line [OKMsg|_] = test_server:capture_get(),
- ?line true = lists:prefix("** Found 0 name clashes", OKMsg),
- ?line true = code:set_path(P),
+ [OKMsg|_] = test_server:capture_get(),
+ true = lists:prefix("** Found 0 name clashes", OKMsg),
+ true = code:set_path(P),
%% test clashing entries
%% remove TestServerPath to prevent clash with test-server path
- ?line true = code:del_path(TestServerPath),
- ?line true = code:add_path(DDir++"foobar-0.1/ebin"),
- ?line true = code:add_path(DDir++"foobar-0.1.ez/foobar-0.1/ebin"),
+ true = code:del_path(TestServerPath),
+ true = code:add_path(DDir++"foobar-0.1/ebin"),
+ true = code:add_path(DDir++"foobar-0.1.ez/foobar-0.1/ebin"),
test_server:capture_start(),
- ?line ok = code:clash(),
+ ok = code:clash(),
test_server:capture_stop(),
- ?line [ClashMsg|_] = test_server:capture_get(),
- ?line {match, [" hides "]} = re:run(ClashMsg, "\\*\\* .*( hides ).*",
+ [ClashMsg|_] = test_server:capture_get(),
+ {match, [" hides "]} = re:run(ClashMsg, "\\*\\* .*( hides ).*",
[{capture,all_but_first,list}]),
- ?line true = code:set_path(P),
+ true = code:set_path(P),
%% test "Bad path can't read"
%% remove TestServerPath to prevent clash with test-server path
Priv = ?config(priv_dir, Config),
- ?line true = code:del_path(TestServerPath),
+ true = code:del_path(TestServerPath),
TmpEzFile = Priv++"foobar-0.tmp.ez",
- ?line {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile),
- ?line true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"),
+ {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile),
+ true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"),
case os:type() of
{win32,_} ->
- %% The file wont be deleted on windows until it's closed, why we
+ %% The file wont be deleted on windows until it's closed, why we
%% need to rename instead.
- ?line ok = file:rename(TmpEzFile,TmpEzFile++".moved");
+ ok = file:rename(TmpEzFile,TmpEzFile++".moved");
_ ->
- ?line ok = file:delete(TmpEzFile)
+ ok = file:delete(TmpEzFile)
end,
test_server:capture_start(),
- ?line ok = code:clash(),
+ ok = code:clash(),
test_server:capture_stop(),
- ?line [BadPathMsg|_] = test_server:capture_get(),
- ?line true = lists:prefix("** Bad path can't read", BadPathMsg),
- ?line true = code:set_path(P),
+ [BadPathMsg|_] = test_server:capture_get(),
+ true = lists:prefix("** Bad path can't read", BadPathMsg),
+ true = code:set_path(P),
file:delete(TmpEzFile++".moved"), %% Only effect on windows
ok.
@@ -687,7 +720,7 @@ ext_mod_dep(Config) when is_list(Config) ->
xref:add_directory(s, filename:join(code:lib_dir(kernel),"ebin")),
xref:add_directory(s, filename:join(code:lib_dir(stdlib),"ebin")),
case catch ext_mod_dep2() of
- {'EXIT', Reason} ->
+ {'EXIT', Reason} ->
xref:stop(s),
exit(Reason);
Else ->
@@ -699,7 +732,7 @@ ext_mod_dep(Config) when is_list(Config) ->
end.
ext_mod_dep2() ->
- Exports0 = code_server:module_info(exports) --
+ Exports0 = code_server:module_info(exports) --
[{module_info,0},{module_info,1}],
Exports = [{code_server,M,A} || {M,A} <- Exports0],
case analyse(Exports, [], [], 0) of
@@ -709,17 +742,17 @@ ext_mod_dep2() ->
{not_verified,ErrCnt}
end.
-analyse([], [], Visited, ErrCnt) ->
+analyse([], [], Visited, ErrCnt) ->
{Visited,ErrCnt};
analyse([], [This={M,F,A}|Path], Visited, ErrCnt0) ->
%% The code_server has been granted to use the following modules,
- %% These modules should be loaded by code.erl before
+ %% These modules should be loaded by code.erl before
%% the code_server is started.
OK = [erlang, os, prim_file, erl_prim_loader, init, ets,
code_server, lists, lists_sort, unicode, binary, filename,
gb_sets, gb_trees, hipe_unified_loader, hipe_bifs,
prim_zip, zlib],
- ErrCnt1 =
+ ErrCnt1 =
case lists:member(M, OK) or erlang:is_builtin(M,F,A) of
true ->
0;
@@ -729,7 +762,7 @@ analyse([], [This={M,F,A}|Path], Visited, ErrCnt0) ->
{Visited, ErrCnt1+ErrCnt0};
analyse([MFA|R], Path, Visited0, ErrCnt0) ->
case lists:member(MFA,Visited0) of
- false ->
+ false ->
{Visited,ErrCnt1} = analyse2(MFA, Path, Visited0),
analyse(R, Path, Visited, ErrCnt1+ErrCnt0);
true ->
@@ -814,7 +847,7 @@ check_funs({'$M_EXPR','$F_EXPR',_},
{code_server,start_link,1}]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',_},
[{erlang,spawn_link,1},{code_server,start_link,1}]) -> 0;
-check_funs({'$M_EXPR',module_info,1},
+check_funs({'$M_EXPR',module_info,1},
[{hipe_unified_loader,patch_to_emu_step1,1} | _]) -> 0;
check_funs({'$M_EXPR','$F_EXPR',2},
[{lists,foldl,3},
@@ -829,7 +862,7 @@ check_funs({'$M_EXPR','$F_EXPR',1},
check_funs({'$M_EXPR',warning_msg,2},
[{code_server,finish_on_load_report,2} | _]) -> 0;
%% This is cheating! /raimo
-%%
+%%
%% check_funs(This = {M,_,_}, Path) ->
%% case catch atom_to_list(M) of
%% [$h,$i,$p,$e | _] ->
@@ -861,9 +894,9 @@ load_cached(suite) ->
load_cached(doc) ->
[];
load_cached(Config) when is_list(Config) ->
- ?line Priv = ?config(priv_dir, Config),
- ?line WD = filename:dirname(code:which(?MODULE)),
- ?line {ok,Node} =
+ Priv = ?config(priv_dir, Config),
+ WD = filename:dirname(code:which(?MODULE)),
+ {ok,Node} =
?t:start_node(code_cache_node, peer, [{args,
"-pa \"" ++ WD ++ "\""},
{erl, [this]}]),
@@ -873,7 +906,7 @@ load_cached(Config) when is_list(Config) ->
_ -> false
end
end,
- ?line Tabs = rpc:call(Node, ets, all, []),
+ Tabs = rpc:call(Node, ets, all, []),
case rpc:call(Node, lists, any, [CCTabCreated,Tabs]) of
true ->
?t:stop_node(Node),
@@ -881,25 +914,25 @@ load_cached(Config) when is_list(Config) ->
false ->
ok
end,
- ?line rpc:call(Node, code, del_path, [Priv]),
- ?line rpc:call(Node, code, add_pathz, [Priv]),
+ rpc:call(Node, code, del_path, [Priv]),
+ rpc:call(Node, code, add_pathz, [Priv]),
FullModName = Priv ++ "/code_cache_test",
- ?line {ok,Dev} = file:open(FullModName ++ ".erl", [write]),
- ?line io:format(Dev, "-module(code_cache_test). -export([a/0]). a() -> ok.~n", []),
- ?line ok = file:close(Dev),
- ?line {ok,code_cache_test} = compile:file(FullModName, [{outdir,Priv}]),
+ {ok,Dev} = file:open(FullModName ++ ".erl", [write]),
+ io:format(Dev, "-module(code_cache_test). -export([a/0]). a() -> ok.~n", []),
+ ok = file:close(Dev),
+ {ok,code_cache_test} = compile:file(FullModName, [{outdir,Priv}]),
F = fun load_loop/2,
N = 1000,
- ?line {T0,T1} = rpc:call(Node, erlang, apply, [F, [N,code_cache_test]]),
+ {T0,T1} = rpc:call(Node, erlang, apply, [F, [N,code_cache_test]]),
TNoCache = now_diff(T1, T0),
- ?line rpc:call(Node, code, rehash, []),
- ?line {T2,T3} = rpc:call(Node, erlang, apply, [F, [N,code_cache_test]]),
- ?line TCache = now_diff(T3, T2),
+ rpc:call(Node, code, rehash, []),
+ {T2,T3} = rpc:call(Node, erlang, apply, [F, [N,code_cache_test]]),
+ TCache = now_diff(T3, T2),
AvgNoCache = TNoCache/N,
AvgCache = TCache/N,
- ?line io:format("Avg. load time (no_cache/cache): ~w/~w~n", [AvgNoCache,AvgCache]),
+ io:format("Avg. load time (no_cache/cache): ~w/~w~n", [AvgNoCache,AvgCache]),
?t:stop_node(Node),
if AvgNoCache =< AvgCache ->
?t:fail("Cache not working properly.");
@@ -916,7 +949,7 @@ load_loop(N, M, T0) ->
code:delete(M),
code:purge(M),
load_loop(N-1, M, T0).
-
+
now_diff({A2, B2, C2}, {A1, B1, C1}) ->
((A2-A1)*1000000 + B2-B1)*1000000 + C2-C1.
@@ -925,30 +958,30 @@ start_node_with_cache(suite) ->
start_node_with_cache(doc) ->
[];
start_node_with_cache(Config) when is_list(Config) ->
- ?line {ok,Node} =
- ?t:start_node(code_cache_node, peer, [{args,
+ {ok,Node} =
+ ?t:start_node(code_cache_node, peer, [{args,
"-code_path_cache"},
{erl, [this]}]),
- ?line Tabs = rpc:call(Node, ets, all, []),
+ Tabs = rpc:call(Node, ets, all, []),
io:format("Tabs: ~w~n", [Tabs]),
CCTabCreated = fun(Tab) ->
case rpc:call(Node, ets, info, [Tab,name]) of
code_cache -> true;
_ -> false
end
- end,
- ?line true = lists:any(CCTabCreated, Tabs),
+ end,
+ true = lists:any(CCTabCreated, Tabs),
?t:stop_node(Node),
ok.
-
+
add_and_rehash(suite) ->
[];
add_and_rehash(doc) ->
[];
add_and_rehash(Config) when is_list(Config) ->
- ?line Priv = ?config(priv_dir, Config),
- ?line WD = filename:dirname(code:which(?MODULE)),
- ?line {ok,Node} =
+ Priv = ?config(priv_dir, Config),
+ WD = filename:dirname(code:which(?MODULE)),
+ {ok,Node} =
?t:start_node(code_cache_node, peer, [{args,
"-pa \"" ++ WD ++ "\""},
{erl, [this]}]),
@@ -958,7 +991,7 @@ add_and_rehash(Config) when is_list(Config) ->
_ -> false
end
end,
- ?line Tabs0 = rpc:call(Node, ets, all, []),
+ Tabs0 = rpc:call(Node, ets, all, []),
case rpc:call(Node, lists, any, [CCTabCreated,Tabs0]) of
true ->
?t:stop_node(Node),
@@ -966,36 +999,36 @@ add_and_rehash(Config) when is_list(Config) ->
false ->
ok
end,
- ?line ok = rpc:call(Node, code, rehash, []), % create cache
- ?line Tabs1 = rpc:call(Node, ets, all, []),
- ?line true = rpc:call(Node, lists, any, [CCTabCreated,Tabs1]), % cache table created
- ?line ok = rpc:call(Node, code, rehash, []),
+ ok = rpc:call(Node, code, rehash, []), % create cache
+ Tabs1 = rpc:call(Node, ets, all, []),
+ true = rpc:call(Node, lists, any, [CCTabCreated,Tabs1]), % cache table created
+ ok = rpc:call(Node, code, rehash, []),
OkDir = filename:join(Priv, ""),
BadDir = filename:join(Priv, "guggemuffsussiputt"),
- ?line CP = [OkDir | rpc:call(Node, code, get_path, [])],
- ?line true = rpc:call(Node, code, set_path, [CP]),
+ CP = [OkDir | rpc:call(Node, code, get_path, [])],
+ true = rpc:call(Node, code, set_path, [CP]),
CP1 = [BadDir | CP],
- ?line {error,_} = rpc:call(Node, code, set_path, [CP1]),
- ?line true = rpc:call(Node, code, del_path, [OkDir]),
- ?line true = rpc:call(Node, code, add_path, [OkDir]),
- ?line true = rpc:call(Node, code, add_path, [OkDir]),
- ?line {error,_} = rpc:call(Node, code, add_path, [BadDir]),
- ?line ok = rpc:call(Node, code, rehash, []),
+ {error,_} = rpc:call(Node, code, set_path, [CP1]),
+ true = rpc:call(Node, code, del_path, [OkDir]),
+ true = rpc:call(Node, code, add_path, [OkDir]),
+ true = rpc:call(Node, code, add_path, [OkDir]),
+ {error,_} = rpc:call(Node, code, add_path, [BadDir]),
+ ok = rpc:call(Node, code, rehash, []),
?t:stop_node(Node),
ok.
-
+
where_is_file_no_cache(suite) ->
[];
where_is_file_no_cache(doc) ->
[];
where_is_file_no_cache(Config) when is_list(Config) ->
- ?line {T,KernelBeamFile} = timer:tc(code, where_is_file, ["kernel.beam"]),
+ {T,KernelBeamFile} = timer:tc(code, where_is_file, ["kernel.beam"]),
io:format("Load time: ~w ms~n", [T]),
- ?line KernelEbinDir = filename:dirname(KernelBeamFile),
- ?line AppFile = filename:join(KernelEbinDir, "kernel.app"),
- ?line AppFile = code:where_is_file("kernel.app"),
- ?line non_existing = code:where_is_file("kernel"), % no such file
+ KernelEbinDir = filename:dirname(KernelBeamFile),
+ AppFile = filename:join(KernelEbinDir, "kernel.app"),
+ AppFile = code:where_is_file("kernel.app"),
+ non_existing = code:where_is_file("kernel"), % no such file
ok.
where_is_file_cached(suite) ->
@@ -1003,97 +1036,97 @@ where_is_file_cached(suite) ->
where_is_file_cached(doc) ->
[];
where_is_file_cached(Config) when is_list(Config) ->
- ?line {ok,Node} =
- ?t:start_node(code_cache_node, peer, [{args,
+ {ok,Node} =
+ ?t:start_node(code_cache_node, peer, [{args,
"-code_path_cache"},
{erl, [this]}]),
- ?line Tabs = rpc:call(Node, ets, all, []),
+ Tabs = rpc:call(Node, ets, all, []),
io:format("Tabs: ~w~n", [Tabs]),
CCTabCreated = fun(Tab) ->
case rpc:call(Node, ets, info, [Tab,name]) of
code_cache -> true;
_ -> false
end
- end,
- ?line true = lists:any(CCTabCreated, Tabs),
- ?line KernelBeamFile = rpc:call(Node, code, where_is_file, ["kernel.beam"]),
- ?line {T,KernelBeamFile} = rpc:call(Node, timer, tc, [code,where_is_file,["kernel.beam"]]),
+ end,
+ true = lists:any(CCTabCreated, Tabs),
+ KernelBeamFile = rpc:call(Node, code, where_is_file, ["kernel.beam"]),
+ {T,KernelBeamFile} = rpc:call(Node, timer, tc, [code,where_is_file,["kernel.beam"]]),
io:format("Load time: ~w ms~n", [T]),
- ?line KernelEbinDir = rpc:call(Node, filename, dirname, [KernelBeamFile]),
- ?line AppFile = rpc:call(Node, filename, join, [KernelEbinDir,"kernel.app"]),
- ?line AppFile = rpc:call(Node, code, where_is_file, ["kernel.app"]),
- ?line non_existing = rpc:call(Node, code, where_is_file, ["kernel"]), % no such file
+ KernelEbinDir = rpc:call(Node, filename, dirname, [KernelBeamFile]),
+ AppFile = rpc:call(Node, filename, join, [KernelEbinDir,"kernel.app"]),
+ AppFile = rpc:call(Node, code, where_is_file, ["kernel.app"]),
+ non_existing = rpc:call(Node, code, where_is_file, ["kernel"]), % no such file
?t:stop_node(Node),
ok.
-
+
purge_stacktrace(suite) ->
[];
purge_stacktrace(doc) ->
["Test that stacktrace is deleted when purging a referred module"];
purge_stacktrace(Config) when is_list(Config) ->
- ?line code:purge(code_b_test),
+ code:purge(code_b_test),
try code_b_test:call(fun(b) -> ok end, a)
catch
error:function_clause ->
- ?line code:load_file(code_b_test),
- ?line case erlang:get_stacktrace() of
+ code:load_file(code_b_test),
+ case erlang:get_stacktrace() of
[{?MODULE,_,[a],_},
{code_b_test,call,2,_},
{?MODULE,purge_stacktrace,1,_}|_] ->
- ?line false = code:purge(code_b_test),
- ?line [] = erlang:get_stacktrace()
+ false = code:purge(code_b_test),
+ [] = erlang:get_stacktrace()
end
end,
try code_b_test:call(nofun, 2)
catch
error:function_clause ->
- ?line code:load_file(code_b_test),
- ?line case erlang:get_stacktrace() of
+ code:load_file(code_b_test),
+ case erlang:get_stacktrace() of
[{code_b_test,call,[nofun,2],_},
{?MODULE,purge_stacktrace,1,_}|_] ->
- ?line false = code:purge(code_b_test),
- ?line [] = erlang:get_stacktrace()
+ false = code:purge(code_b_test),
+ [] = erlang:get_stacktrace()
end
end,
Args = [erlang,error,[badarg]],
try code_b_test:call(erlang, error, [badarg,Args])
catch
error:badarg ->
- ?line code:load_file(code_b_test),
- ?line case erlang:get_stacktrace() of
+ code:load_file(code_b_test),
+ case erlang:get_stacktrace() of
[{code_b_test,call,Args,_},
{?MODULE,purge_stacktrace,1,_}|_] ->
- ?line false = code:purge(code_b_test),
- ?line [] = erlang:get_stacktrace()
+ false = code:purge(code_b_test),
+ [] = erlang:get_stacktrace()
end
end,
ok.
mult_lib_roots(Config) when is_list(Config) ->
- ?line DataDir = filename:join(?config(data_dir, Config), "mult_lib_roots"),
- ?line mult_lib_compile(DataDir, "my_dummy_app-b/ebin/lists"),
- ?line mult_lib_compile(DataDir,
+ DataDir = filename:join(?config(data_dir, Config), "mult_lib_roots"),
+ mult_lib_compile(DataDir, "my_dummy_app-b/ebin/lists"),
+ mult_lib_compile(DataDir,
"my_dummy_app-c/ebin/code_SUITE_mult_root_module"),
%% Set up ERL_LIBS and start a slave node.
ErlLibs = filename:join(DataDir, "first_root") ++ mult_lib_sep() ++
filename:join(DataDir, "second_root"),
- ?line {ok,Node} =
+ {ok,Node} =
?t:start_node(mult_lib_roots, slave,
[{args,"-env ERL_LIBS "++ErlLibs}]),
- ?line TSPath = filename:dirname(code:which(test_server)),
- ?line Path0 = rpc:call(Node, code, get_path, []),
- ?line [TSPath,"."|Path1] = Path0,
- ?line [Kernel|Path2] = Path1,
- ?line [Stdlib|Path3] = Path2,
- ?line mult_lib_verify_lib(Kernel, "kernel"),
- ?line mult_lib_verify_lib(Stdlib, "stdlib"),
- ?line [Lib1,Lib2,Lib3,Lib4,Lib5|Path] = Path3,
+ TSPath = filename:dirname(code:which(test_server)),
+ Path0 = rpc:call(Node, code, get_path, []),
+ [TSPath,"."|Path1] = Path0,
+ [Kernel|Path2] = Path1,
+ [Stdlib|Path3] = Path2,
+ mult_lib_verify_lib(Kernel, "kernel"),
+ mult_lib_verify_lib(Stdlib, "stdlib"),
+ [Lib1,Lib2,Lib3,Lib4,Lib5|Path] = Path3,
+
-
["first_root/my_dummy_app-a/ebin",
"first_root/my_dummy_app-b/ebin",
"first_root/my_dummy_app-c/ebin",
@@ -1103,7 +1136,7 @@ mult_lib_roots(Config) when is_list(Config) ->
E <- lists:sort([Lib1,Lib2,Lib3,Lib4,Lib5])],
io:format("~p\n", [Path]),
- ?line true = rpc:call(Node, code_SUITE_mult_root_module, works_fine, []),
+ true = rpc:call(Node, code_SUITE_mult_root_module, works_fine, []),
ok.
@@ -1113,7 +1146,7 @@ mult_lib_compile(Root, Last) ->
Dir = filename:dirname(Name),
{ok,Mod} = compile:file(Name, [report,{outdir,Dir}]),
ok.
-
+
mult_lib_sep() ->
case os:type() of
{win32,_} -> ";";
@@ -1123,23 +1156,23 @@ mult_lib_sep() ->
mult_lib_verify_lib(Path, Expected) ->
Dir = filename:basename(filename:dirname(Path)),
true = lists:prefix(Expected, Dir).
-
+
mult_lib_remove_prefix([H|T1], [H|T2]) ->
mult_lib_remove_prefix(T1, T2);
mult_lib_remove_prefix([$/|T], []) -> T.
bad_erl_libs(Config) when is_list(Config) ->
- ?line {ok,Node} =
+ {ok,Node} =
?t:start_node(mult_lib_roots, slave,
[{args,"-env ERL_LIBS "}]),
- ?line ?t:stop_node(Node),
+ ?t:stop_node(Node),
- ?line {ok,Node2} =
+ {ok,Node2} =
?t:start_node(mult_lib_roots, slave,
[{args,"-env ERL_LIBS /no/such/dir"}]),
- ?line ?t:stop_node(Node2),
+ ?t:stop_node(Node2),
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1158,55 +1191,55 @@ do_code_archive(Config, Root, StripVsn) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
App = code_archive_dict,
VsnBase = atom_to_list(App) ++ "-1.0",
- Base =
+ Base =
case StripVsn of
true -> atom_to_list(App);
false -> VsnBase
end,
Ext = init:archive_extension(),
RootDir = filename:join([PrivDir, Root]),
- ?line ok = file:make_dir(RootDir),
+ ok = file:make_dir(RootDir),
Archive = filename:join([RootDir, VsnBase ++ Ext]),
- ?line {ok, _} = zip:create(Archive, [VsnBase],
+ {ok, _} = zip:create(Archive, [VsnBase],
[{compress, []}, {cwd, DataDir}]),
- ?line {ok, _} = zip:extract(Archive, [{cwd, PrivDir}]),
+ {ok, _} = zip:extract(Archive, [{cwd, PrivDir}]),
case StripVsn of
true ->
- ?line ok = file:rename(filename:join([PrivDir, VsnBase]),
+ ok = file:rename(filename:join([PrivDir, VsnBase]),
filename:join([PrivDir, Base]));
false ->
ok
end,
-
+
io:format("DEBUG: ~p\n", [?LINE]),
%% Compile the code
- ?line ok = compile_app(PrivDir, Base),
-
+ ok = compile_app(PrivDir, Base),
+
%% Create the archive
- ?line ok = file:delete(Archive),
- ?line {ok, _} = zip:create(Archive, [Base],
+ ok = file:delete(Archive),
+ {ok, _} = zip:create(Archive, [Base],
[{compress, []}, {cwd, PrivDir}]),
%% Set up ERL_LIBS and start a slave node.
- ?line {ok, Node} =
+ {ok, Node} =
?t:start_node(code_archive, slave,
[{args,"-env ERL_LIBS " ++ RootDir}]),
- ?line CodePath = rpc:call(Node, code, get_path, []),
+ CodePath = rpc:call(Node, code, get_path, []),
AppEbin = filename:join([Archive, Base, "ebin"]),
io:format("AppEbin: ~p\n", [AppEbin]),
io:format("CodePath: ~p\n", [CodePath]),
io:format("Archive: ~p\n", [erl_prim_loader:read_file_info(Archive)]),
- ?line true = lists:member(AppEbin, CodePath),
+ true = lists:member(AppEbin, CodePath),
%% Start the app
- ?line ok = rpc:call(Node, application, start, [App]),
-
+ ok = rpc:call(Node, application, start, [App]),
+
%% Access the app priv dir
AppPrivDir = rpc:call(Node, code, priv_dir, [App]),
- ?line AppPrivFile = filename:join([AppPrivDir, "code_archive.txt"]),
+ AppPrivFile = filename:join([AppPrivDir, "code_archive.txt"]),
io:format("AppPrivFile: ~p\n", [AppPrivFile]),
- ?line {ok, _Bin, _Path} =
+ {ok, _Bin, _Path} =
rpc:call(Node, erl_prim_loader, get_file, [AppPrivFile]),
%% Use the app
@@ -1221,14 +1254,14 @@ do_code_archive(Config, Root, StripVsn) when is_list(Config) ->
error = rpc:call(Node, App, find, [Tab, Key]),
ok = rpc:call(Node, App, erase, [Tab]),
- ?line ?t:stop_node(Node),
+ ?t:stop_node(Node),
ok.
compile_app(TopDir, AppName) ->
AppDir = filename:join([TopDir, AppName]),
SrcDir = filename:join([AppDir, "src"]),
OutDir = filename:join([AppDir, "ebin"]),
- ?line {ok, Files} = file:list_dir(SrcDir),
+ {ok, Files} = file:list_dir(SrcDir),
compile_files(Files, SrcDir, OutDir).
compile_files([File | Files], SrcDir, OutDir) ->
@@ -1253,27 +1286,27 @@ big_boot_embedded(doc) ->
["Test that a boot file with (almost) all of OTP can be used to start an"
" embeddedd system."];
big_boot_embedded(Config) when is_list(Config) ->
- ?line {BootArg,AppsInBoot} = create_big_boot(Config),
- ?line {ok, Node} =
+ {BootArg,AppsInBoot} = create_big_boot(Config),
+ {ok, Node} =
?t:start_node(big_boot_embedded, slave,
[{args,"-boot "++BootArg++" -mode embedded"}]),
- ?line RemoteNodeApps =
- [ {X,Y} || {X,_,Y} <-
+ RemoteNodeApps =
+ [ {X,Y} || {X,_,Y} <-
rpc:call(Node,application,loaded_applications,[]) ],
- ?line true = lists:sort(AppsInBoot) =:= lists:sort(RemoteNodeApps),
+ true = lists:sort(AppsInBoot) =:= lists:sort(RemoteNodeApps),
ok.
on_load(Config) when is_list(Config) ->
Master = on_load_test_case_process,
- ?line Data = filename:join([?config(data_dir, Config),"on_load"]),
- ?line ok = file:set_cwd(Data),
- ?line up_to_date = make:all([{d,'MASTER',Master}]),
+ Data = filename:join([?config(data_dir, Config),"on_load"]),
+ ok = file:set_cwd(Data),
+ up_to_date = make:all([{d,'MASTER',Master}]),
%% Register a name for this process.
- ?line register(Master, self()),
-
- ?line {_,Ref} = spawn_monitor(fun() ->
+ register(Master, self()),
+
+ {_,Ref} = spawn_monitor(fun() ->
exit(on_load_a:data())
end),
receive
@@ -1285,8 +1318,8 @@ on_load(Config) when is_list(Config) ->
receive
{on_load_c,PidC} -> ok
end,
-
- ?line Refs = on_load_massive_spawn(lists:seq(1, 50)),
+
+ Refs = on_load_massive_spawn(lists:seq(1, 50)),
receive after 7 -> ok end,
PidC ! go,
@@ -1304,13 +1337,13 @@ on_load(Config) when is_list(Config) ->
receive
{'DOWN',Ref,process,_,Res} ->
- ?line [a,b,c] = Res
+ [a,b,c] = Res
end,
on_load_wait_for_all(Refs),
receive
Any ->
- ?line ?t:fail({unexpected,Any})
+ ?t:fail({unexpected,Any})
after 10 ->
ok
end.
@@ -1377,13 +1410,13 @@ on_load_embedded(Config) when is_list(Config) ->
end.
on_load_embedded_1(Config) ->
- ?line DataDir = ?config(data_dir, Config),
+ DataDir = ?config(data_dir, Config),
%% Link the on_load_app application into the lib directory.
- ?line LibRoot = code:lib_dir(),
- ?line LinkName = filename:join(LibRoot, "on_load_app-1.0"),
- ?line OnLoadApp = filename:join(DataDir, "on_load_app-1.0"),
- ?line del_link(LinkName),
+ LibRoot = code:lib_dir(),
+ LinkName = filename:join(LibRoot, "on_load_app-1.0"),
+ OnLoadApp = filename:join(DataDir, "on_load_app-1.0"),
+ del_link(LinkName),
io:format("LinkName :~p, OnLoadApp: ~p~n",[LinkName,OnLoadApp]),
case file:make_symlink(OnLoadApp, LinkName) of
{error,enotsup} ->
@@ -1392,28 +1425,28 @@ on_load_embedded_1(Config) ->
end,
%% Compile the code.
- ?line OnLoadAppEbin = filename:join(LinkName, "ebin"),
- ?line {ok,_ } = compile:file(filename:join([OnLoadApp,"src",
+ OnLoadAppEbin = filename:join(LinkName, "ebin"),
+ {ok,_ } = compile:file(filename:join([OnLoadApp,"src",
"on_load_embedded"]),
[{outdir,OnLoadAppEbin}]),
%% Create and compile a boot file.
- ?line true = code:add_pathz(OnLoadAppEbin),
+ true = code:add_pathz(OnLoadAppEbin),
Options = case is_source_dir() of
true -> [local];
false -> []
end,
- ?line BootScript = create_boot(Config, Options),
- ?line true = code:del_path(OnLoadAppEbin),
+ BootScript = create_boot(Config, Options),
+ true = code:del_path(OnLoadAppEbin),
%% Start the node and check that the on_load function was run.
- ?line {ok,Node} = start_node(on_load_embedded,
+ {ok,Node} = start_node(on_load_embedded,
"-mode embedded -boot " ++ BootScript),
ok = rpc:call(Node, on_load_embedded, status, []),
%% Clean up.
- ?line stop_node(Node),
- ?line ok = del_link(LinkName).
+ stop_node(Node),
+ ok = del_link(LinkName).
del_link(LinkName) ->
case file:delete(LinkName) of
@@ -1421,100 +1454,94 @@ del_link(LinkName) ->
file:del_dir(LinkName);
Other ->
Other
- end.
+ end.
create_boot(Config, Options) ->
- ?line {ok, OldDir} = file:get_cwd(),
- ?line {LatestDir,LatestName} = create_script(Config),
- ?line ok = file:set_cwd(LatestDir),
- ?line ok = systools:make_script(LatestName, Options),
- ?line ok = file:set_cwd(OldDir),
+ {ok, OldDir} = file:get_cwd(),
+ {LatestDir,LatestName} = create_script(Config),
+ ok = file:set_cwd(LatestDir),
+ ok = systools:make_script(LatestName, Options),
+ ok = file:set_cwd(OldDir),
filename:join(LatestDir, LatestName).
create_script(Config) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Name = PrivDir ++ "on_load_test",
- ?line Apps = application_controller:which_applications(),
- ?line {value,{_,_,KernelVer}} = lists:keysearch(kernel, 1, Apps),
- ?line {value,{_,_,StdlibVer}} = lists:keysearch(stdlib, 1, Apps),
- ?line {ok,Fd} = file:open(Name ++ ".rel", [write]),
- ?line io:format(Fd,
+ PrivDir = ?config(priv_dir, Config),
+ Name = PrivDir ++ "on_load_test",
+ Apps = application_controller:which_applications(),
+ {value,{_,_,KernelVer}} = lists:keysearch(kernel, 1, Apps),
+ {value,{_,_,StdlibVer}} = lists:keysearch(stdlib, 1, Apps),
+ {ok,Fd} = file:open(Name ++ ".rel", [write]),
+ io:format(Fd,
"{release, {\"Test release 3\", \"P2A\"}, \n"
" {erts, \"9.42\"}, \n"
" [{kernel, \"~s\"}, {stdlib, \"~s\"},"
" {on_load_app, \"1.0\"}]}.\n",
[KernelVer,StdlibVer]),
- ?line file:close(Fd),
+ file:close(Fd),
{filename:dirname(Name),filename:basename(Name)}.
create_big_boot(Config) ->
- ?line {ok, OldDir} = file:get_cwd(),
- ?line {Options,Local} = case is_source_dir() of
- true -> {[no_module_tests,local],true};
- _ -> {[no_module_tests],false}
+ {ok, OldDir} = file:get_cwd(),
+ {Options,Local} = case is_source_dir() of
+ true -> {[no_module_tests,local],true};
+ _ -> {[no_module_tests],false}
end,
- ?line {LatestDir,LatestName,Apps} = create_big_script(Config,Local),
- ?line ok = file:set_cwd(LatestDir),
- ?line ok = systools:make_script(LatestName, Options),
- ?line ok = file:set_cwd(OldDir),
+ {LatestDir,LatestName,Apps} = create_big_script(Config,Local),
+ ok = file:set_cwd(LatestDir),
+ ok = systools:make_script(LatestName, Options),
+ ok = file:set_cwd(OldDir),
{filename:join(LatestDir, LatestName),Apps}.
-% The following apps cannot be loaded
+% The following apps cannot be loaded
% hipe .app references (or can reference) files that have no
% corresponding beam file (if hipe is not enabled)
-filter_app("hipe",_) ->
- false;
+filter_app("hipe",_) -> false;
% Dialyzer and typer depends on hipe
-filter_app("dialyzer",_) ->
- false;
-filter_app("typer",_) ->
- false;
+filter_app("dialyzer",_) -> false;
+filter_app("typer",_) -> false;
% Orber requires explicit configuration
-filter_app("orber",_) ->
- false;
+filter_app("orber",_) -> false;
% cos* depends on orber
-filter_app("cos"++_,_) ->
- false;
+filter_app("cos"++_,_) -> false;
% ic has a mod instruction in the app file but no corresponding start function
-filter_app("ic",_) ->
- false;
+filter_app("ic",_) -> false;
% Netconf has some dependency that I really do not understand (maybe like orber)
-filter_app("netconf",_) ->
- false;
+filter_app("netconf",_) -> false;
% Safe has the same kind of error in the .app file as ic
-filter_app("safe",_) ->
- false;
+filter_app("safe",_) -> false;
% Comte cannot be started in the "usual" way
-filter_app("comte",_) ->
- false;
+filter_app("comte",_) -> false;
% OS_mon does not find it's port program when running cerl
-filter_app("os_mon",true) ->
- false;
+filter_app("os_mon",true) -> false;
+% erts is not a "real" app either =/
+filter_app("erts",_) -> false;
% Other apps should be OK.
-filter_app(_,_) ->
- true.
+filter_app(_,_) -> true.
create_big_script(Config,Local) ->
- ?line PrivDir = ?config(priv_dir, Config),
- ?line Name = filename:join(PrivDir,"full_script_test"),
- ?line InitialApplications=application:loaded_applications(),
+ PrivDir = ?config(priv_dir, Config),
+ Name = filename:join(PrivDir,"full_script_test"),
+ InitialApplications=application:loaded_applications(),
%% Applications left loaded by the application suite, unload them!
- ?line UnloadFix=[app0,app1,app2,group_leader,app_start_error],
- ?line [application:unload(Leftover) ||
+ UnloadFix=[app0,app1,app2,group_leader,app_start_error],
+ [application:unload(Leftover) ||
Leftover <- UnloadFix,
lists:keymember(Leftover,1,InitialApplications) ],
%% Now we should have only "real" applications...
- ?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)],
- ?line Apps = [ {N,V} || {N,_,V} <- application:loaded_applications()],
- ?line {ok,Fd} = file:open(Name ++ ".rel", [write]),
- ?line io:format(Fd,
+ [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,
"{release, {\"Test release 3\", \"P2A\"}, \n"
" {erts, \"9.42\"}, \n"
" ~p}.\n",
[Apps]),
- ?line file:close(Fd),
- ?line NewlyLoaded =
+ file:close(Fd),
+ NewlyLoaded =
application:loaded_applications() -- InitialApplications,
- ?line [ application:unload(N) || {N,_,_} <- NewlyLoaded],
+ [ application:unload(N) || {N,_,_} <- NewlyLoaded],
{filename:dirname(Name),filename:basename(Name),Apps}.
is_source_dir() ->
@@ -1523,35 +1550,35 @@ is_source_dir() ->
on_load_errors(Config) when is_list(Config) ->
Master = on_load_error_test_case_process,
- ?line register(Master, self()),
+ register(Master, self()),
- ?line Data = filename:join([?config(data_dir, Config),"on_load_errors"]),
- ?line ok = file:set_cwd(Data),
- ?line up_to_date = make:all([{d,'MASTER',Master}]),
+ Data = filename:join([?config(data_dir, Config),"on_load_errors"]),
+ ok = file:set_cwd(Data),
+ up_to_date = make:all([{d,'MASTER',Master}]),
- ?line do_on_load_error(an_atom),
+ do_on_load_error(an_atom),
- ?line error_logger:add_report_handler(?MODULE, self()),
+ error_logger:add_report_handler(?MODULE, self()),
- ?line do_on_load_error({something,terrible,is,wrong}),
+ do_on_load_error({something,terrible,is,wrong}),
receive
Any1 ->
- ?line {_, "The on_load function"++_,
+ {_, "The on_load function"++_,
[on_load_error,
{something,terrible,is,wrong},_]} = Any1
end,
- ?line do_on_load_error(fail), %Cause exception.
+ do_on_load_error(fail), %Cause exception.
receive
Any2 ->
- ?line {_, "The on_load function"++_,
+ {_, "The on_load function"++_,
[on_load_error,{failed,[_|_]},_]} = Any2
end,
%% There should be no more messages.
receive
Unexpected ->
- ?line ?t:fail({unexpected,Unexpected})
+ ?t:fail({unexpected,Unexpected})
after 10 ->
ok
end,
@@ -1559,14 +1586,14 @@ on_load_errors(Config) when is_list(Config) ->
ok.
do_on_load_error(ReturnValue) ->
- ?line {_,Ref} = spawn_monitor(fun() ->
+ {_,Ref} = spawn_monitor(fun() ->
exit(on_load_error:main())
end),
receive {on_load_error,ErrorPid} -> ok end,
- ?line ErrorPid ! ReturnValue,
+ ErrorPid ! ReturnValue,
receive
{'DOWN',Ref,process,_,Exit} ->
- ?line {undef,[{on_load_error,main,[],_}|_]} = Exit
+ {undef,[{on_load_error,main,[],_}|_]} = Exit
end.
native_early_modules(suite) -> [];
@@ -1580,10 +1607,10 @@ native_early_modules(Config) when is_list(Config) ->
end.
native_early_modules_1(Architecture) ->
- ?line {lists, ListsBinary, _ListsFilename} = code:get_object_code(lists),
- ?line ChunkName = hipe_unified_loader:chunk_name(Architecture),
- ?line NativeChunk = beam_lib:chunks(ListsBinary, [ChunkName]),
- ?line IsHipeCompiled = case NativeChunk of
+ {lists, ListsBinary, _ListsFilename} = code:get_object_code(lists),
+ ChunkName = hipe_unified_loader:chunk_name(Architecture),
+ NativeChunk = beam_lib:chunks(ListsBinary, [ChunkName]),
+ IsHipeCompiled = case NativeChunk of
{ok,{_,[{_,Bin}]}} when is_binary(Bin) -> true;
{error, beam_lib, _} -> false
end,
@@ -1591,10 +1618,10 @@ native_early_modules_1(Architecture) ->
false ->
{skip,"OTP apparently not configured with --enable-native-libs"};
true ->
- ?line true = lists:all(fun code:is_module_native/1,
- [ets,file,filename,gb_sets,gb_trees,
- %%hipe_unified_loader, no_native as workaround
- lists,os]),
+ true = lists:all(fun code:is_module_native/1,
+ [ets,file,filename,gb_sets,gb_trees,
+ %%hipe_unified_loader, no_native as workaround
+ lists,os]),
ok
end.
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 35502a1d27..b2ca3bdbc2 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2013. 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
@@ -24,7 +24,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([get_path/1, set_path/1, get_file/1,
+-export([get_path/1, set_path/1, get_file/1, normalize_and_backslash/1,
inet_existing/1, inet_coming_up/1, inet_disconnects/1,
multiple_slaves/1, file_requests/1,
local_archive/1, remote_archive/1,
@@ -39,7 +39,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [get_path, set_path, get_file, inet_existing,
+ [get_path, set_path, get_file,
+ normalize_and_backslash, inet_existing,
inet_coming_up, inet_disconnects, multiple_slaves,
file_requests, local_archive, remote_archive,
primary_archive, virtual_dir_in_archive].
@@ -107,6 +108,26 @@ get_file(Config) when is_list(Config) ->
?line error = erl_prim_loader:get_file({dummy}),
ok.
+normalize_and_backslash(Config) ->
+ %% Test OTP-11170
+ case os:type() of
+ {win32,_} ->
+ {skip, "not on windows"};
+ _ ->
+ test_normalize_and_backslash(Config)
+ end.
+test_normalize_and_backslash(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Dir = filename:join(PrivDir,"\\"),
+ File = filename:join(Dir,"file-OTP-11170"),
+ ok = file:make_dir(Dir),
+ ok = file:write_file(File,"a file to test OTP-11170"),
+ {ok,["file-OTP-11170"]} = file:list_dir(Dir),
+ {ok,["file-OTP-11170"]} = erl_prim_loader:list_dir(Dir),
+ ok = file:delete(File),
+ ok = file:del_dir(Dir),
+ ok.
+
inet_existing(doc) -> ["Start a node using the 'inet' loading method, ",
"from an already started boot server."];
inet_existing(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index e4c8f0ffaf..c75639ae7e 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -805,6 +805,20 @@ new_modes(Config) when is_list(Config) ->
?line {ok, [$\[]} = ?FILE_MODULE:read(Fd6, 1),
?line ok = ?FILE_MODULE:close(Fd6),
+ %% write and sync
+ case ?FILE_MODULE:open(Name1, [write, sync]) of
+ {ok, Fd7} ->
+ ok = io:write(Fd7, Marker),
+ ok = io:put_chars(Fd7, ".\n"),
+ ok = ?FILE_MODULE:close(Fd7),
+ {ok, Fd8} = ?FILE_MODULE:open(Name1, [read]),
+ {ok, Marker} = io:read(Fd8, prompt),
+ ok = ?FILE_MODULE:close(Fd8);
+ {error, enotsup} ->
+ %% for platforms that don't support the sync option
+ ok
+ end,
+
?line [] = flush(),
?line test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 0c8082026a..9354af2e41 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -1,5 +1,4 @@
-module(file_name_SUITE).
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index e89cb44797..881aaed429 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1,4 +1,4 @@
-%%
+%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
@@ -35,8 +35,11 @@
open_unihoming_ipv6_socket/1,
open_multihoming_ipv6_socket/1,
open_multihoming_ipv4_and_ipv6_socket/1,
- basic_stream/1, xfer_stream_min/1, peeloff_active_once/1,
- peeloff_active_true/1, buffers/1]).
+ basic_stream/1, xfer_stream_min/1, active_n/1,
+ peeloff_active_once/1, peeloff_active_true/1, peeloff_active_n/1,
+ buffers/1,
+ names_unihoming_ipv4/1, names_unihoming_ipv6/1,
+ names_multihoming_ipv4/1, names_multihoming_ipv6/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -46,9 +49,11 @@ all() ->
open_multihoming_ipv4_socket,
open_unihoming_ipv6_socket,
open_multihoming_ipv6_socket,
- open_multihoming_ipv4_and_ipv6_socket,
+ open_multihoming_ipv4_and_ipv6_socket, active_n,
basic_stream, xfer_stream_min, peeloff_active_once,
- peeloff_active_true, buffers].
+ peeloff_active_true, peeloff_active_n, buffers,
+ names_unihoming_ipv4, names_unihoming_ipv6,
+ names_multihoming_ipv4, names_multihoming_ipv6].
groups() ->
[].
@@ -107,7 +112,7 @@ xfer_min(Config) when is_list(Config) ->
?line {ok,Sb} = gen_sctp:open([{type,seqpacket}]),
?line {ok,Pb} = inet:port(Sb),
?line ok = gen_sctp:listen(Sb, true),
-
+
?line {ok,Sa} = gen_sctp:open(),
?line {ok,Pa} = inet:port(Sa),
?line {ok,#sctp_assoc_change{state=comm_up,
@@ -118,18 +123,18 @@ xfer_min(Config) when is_list(Config) ->
gen_sctp:connect(Sa, Loopback, Pb, []),
?line {SbAssocId,SaOutboundStreams,SaInboundStreams} =
case recv_event(log_ok(gen_sctp:recv(Sb, infinity))) of
- {Loopback,Pa,
- #sctp_assoc_change{state=comm_up,
- error=0,
- outbound_streams=SbOutboundStreams,
- inbound_streams=SbInboundStreams,
- assoc_id=AssocId}} ->
- {AssocId,SbInboundStreams,SbOutboundStreams};
- {Loopback,Pa,
- #sctp_paddr_change{state=addr_confirmed,
- addr={Loopback,Pa},
- error=0,
- assoc_id=AssocId}} ->
+ {Loopback,Pa,
+ #sctp_assoc_change{state=comm_up,
+ error=0,
+ outbound_streams=SbOutboundStreams,
+ inbound_streams=SbInboundStreams,
+ assoc_id=AssocId}} ->
+ {AssocId,SbInboundStreams,SbOutboundStreams};
+ {Loopback,Pa,
+ #sctp_paddr_change{state=addr_confirmed,
+ addr={Loopback,Pa},
+ error=0,
+ assoc_id=AssocId}} ->
{Loopback,Pa,
#sctp_assoc_change{state=comm_up,
error=0,
@@ -148,17 +153,20 @@ xfer_min(Config) when is_list(Config) ->
assoc_id=SbAssocId}],
Data} -> ok;
Event1 ->
- {Loopback,Pa,
- #sctp_paddr_change{addr = {Loopback,_},
- state = addr_available,
- error = 0,
- assoc_id = SbAssocId}} =
- recv_event(Event1),
- {ok,{Loopback,
- Pa,
- [#sctp_sndrcvinfo{stream=Stream,
- assoc_id=SbAssocId}],
- Data}} = gen_sctp:recv(Sb, infinity)
+ case recv_event(Event1) of
+ {Loopback,Pa,
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = State,
+ error = 0,
+ assoc_id = SbAssocId}}
+ when State =:= addr_available;
+ State =:= addr_confirmed ->
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} = log_ok(gen_sctp:recv(Sb, infinity))
+ end
end,
?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data),
?line case log_ok(gen_sctp:recv(Sa, infinity)) of
@@ -197,7 +205,7 @@ xfer_min(Config) when is_list(Config) ->
recv_event(log_ok(gen_sctp:recv(Sb, infinity))),
?line ok = gen_sctp:close(Sa),
?line ok = gen_sctp:close(Sb),
-
+
?line receive
Msg -> test_server:fail({received,Msg})
after 17 -> ok
@@ -216,7 +224,7 @@ xfer_active(Config) when is_list(Config) ->
?line {ok,Sb} = gen_sctp:open([{active,true}]),
?line {ok,Pb} = inet:port(Sb),
?line ok = gen_sctp:listen(Sb, true),
-
+
?line {ok,Sa} = gen_sctp:open([{active,true}]),
?line {ok,Pa} = inet:port(Sa),
?line ok = gen_sctp:connect_init(Sa, Loopback, Pb, []),
@@ -348,7 +356,7 @@ def_sndrcvinfo(Config) when is_list(Config) ->
%%
?line S1 =
log_ok(gen_sctp:open(
- 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])),
+ 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])),
?LOGVAR(S1),
?line P1 =
log_ok(inet:port(S1)),
@@ -455,18 +463,22 @@ def_sndrcvinfo(Config) when is_list(Config) ->
stream=1, ppid=0, context=0, assoc_id=S1AssocId}],
<<"3: ",Data/binary>>} -> ok;
Event2 ->
- {Loopback,P2,
- #sctp_paddr_change{
- addr={Loopback,_}, state=addr_available,
- error=0, assoc_id=S1AssocId}} =
- recv_event(Event2),
- ?line case log_ok(gen_sctp:recv(S1)) of
- {Loopback,P2,
- [#sctp_sndrcvinfo{
- stream=1, ppid=0, context=0,
- assoc_id=S1AssocId}],
- <<"3: ",Data/binary>>} -> ok
- end
+ case recv_event(Event2) of
+ {Loopback,P2,
+ #sctp_paddr_change{
+ addr={Loopback,_},
+ state=State,
+ error=0, assoc_id=S1AssocId}}
+ when State =:= addr_available;
+ State =:= addr_confirmed ->
+ ?line case log_ok(gen_sctp:recv(S1)) of
+ {Loopback,P2,
+ [#sctp_sndrcvinfo{
+ stream=1, ppid=0, context=0,
+ assoc_id=S1AssocId}],
+ <<"3: ",Data/binary>>} -> ok
+ end
+ end
end,
?line ok =
do_from_other_process(
@@ -509,6 +521,13 @@ log_ok(X) -> log(ok(X)).
ok({ok,X}) -> X.
+err([], Result) ->
+ erlang:error(Result);
+err([Reason|_], {error,Reason}) ->
+ ok;
+err([_|Reasons], Result) ->
+ err(Reasons, Result).
+
log(X) ->
io:format("LOG[~w]: ~p~n", [self(),X]),
X.
@@ -529,57 +548,57 @@ api_open_close(Config) when is_list(Config) ->
?line {ok,S1} = gen_sctp:open(0),
?line {ok,P} = inet:port(S1),
?line ok = gen_sctp:close(S1),
-
+
?line {ok,S2} = gen_sctp:open(P),
?line {ok,P} = inet:port(S2),
?line ok = gen_sctp:close(S2),
-
+
?line {ok,S3} = gen_sctp:open([{port,P}]),
?line {ok,P} = inet:port(S3),
?line ok = gen_sctp:close(S3),
-
+
?line {ok,S4} = gen_sctp:open(P, []),
?line {ok,P} = inet:port(S4),
?line ok = gen_sctp:close(S4),
-
+
?line {ok,S5} = gen_sctp:open(P, [{ifaddr,any}]),
?line {ok,P} = inet:port(S5),
?line ok = gen_sctp:close(S5),
?line ok = gen_sctp:close(S5),
-
+
?line try gen_sctp:close(0)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open({})
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(-1)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(65536)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(make_ref(), [])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, {})
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, [make_ref()])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open([{invalid_option,0}])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, [{mode,invalid_mode}])
catch error:badarg -> ok
end,
@@ -591,11 +610,11 @@ api_listen(suite) ->
[];
api_listen(Config) when is_list(Config) ->
?line Localhost = {127,0,0,1},
-
+
?line try gen_sctp:listen(0, true)
catch error:badarg -> ok
end,
-
+
?line {ok,S} = gen_sctp:open(),
?line {ok,Pb} = inet:port(S),
?line try gen_sctp:listen(S, not_allowed_for_listen)
@@ -603,7 +622,7 @@ api_listen(Config) when is_list(Config) ->
end,
?line ok = gen_sctp:close(S),
?line {error,closed} = gen_sctp:listen(S, true),
-
+
?line {ok,Sb} = gen_sctp:open(Pb),
?line {ok,Sa} = gen_sctp:open(),
?line case gen_sctp:connect(Sa, localhost, Pb, []) of
@@ -615,8 +634,8 @@ api_listen(Config) when is_list(Config) ->
gen_sctp:recv(Sa, infinity);
{error,#sctp_assoc_change{state=cant_assoc}} ->
ok%;
- %% {error,{Localhost,Pb,_,#sctp_assoc_change{state=cant_assoc}}} ->
- %% ok
+ %% {error,{Localhost,Pb,_,#sctp_assoc_change{state=cant_assoc}}} ->
+ %% ok
end,
?line ok = gen_sctp:listen(Sb, true),
?line {ok,#sctp_assoc_change{state=comm_up,
@@ -767,6 +786,106 @@ implicit_inet6(S1, Addr) ->
end,
?line ok = gen_sctp:close(S2).
+active_n(doc) ->
+ "Verify {active,N} socket management";
+active_n(suite) ->
+ [];
+active_n(Config) when is_list(Config) ->
+ N = 3,
+ S1 = ok(gen_sctp:open([{active,N}])),
+ [{active,N}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,-N}]),
+ receive
+ {sctp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,sctp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,0}]),
+ receive
+ {sctp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,sctp_passive_failure})
+ end,
+ ok = inet:setopts(S1, [{active,32767}]),
+ {error,einval} = inet:setopts(S1, [{active,1}]),
+ {error,einval} = inet:setopts(S1, [{active,-32769}]),
+ ok = inet:setopts(S1, [{active,-32768}]),
+ receive
+ {sctp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,sctp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,N}]),
+ ok = inet:setopts(S1, [{active,true}]),
+ [{active,true}] = ok(inet:getopts(S1, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ ok = inet:setopts(S1, [{active,N}]),
+ ok = inet:setopts(S1, [{active,once}]),
+ [{active,once}] = ok(inet:getopts(S1, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ {error,einval} = inet:setopts(S1, [{active,32768}]),
+ ok = inet:setopts(S1, [{active,false}]),
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ ok = gen_sctp:listen(S1, true),
+ S1Port = ok(inet:port(S1)),
+ S2 = ok(gen_sctp:open(0, [{active,false}])),
+ Assoc = ok(gen_sctp:connect(S2, "localhost", S1Port, [])),
+ ok = inet:setopts(S1, [{active,N}]),
+ [{active,N}] = ok(inet:getopts(S1, [active])),
+ LoopFun = fun(Count, Count, _Fn) ->
+ receive
+ {sctp_passive,S1} ->
+ ok
+ after
+ 5000 ->
+ exit({error,timeout})
+ end;
+ (I, Count, Fn) ->
+ Msg = list_to_binary("message "++integer_to_list(I)),
+ ok = gen_sctp:send(S2, Assoc, 0, Msg),
+ receive
+ {sctp,S1,_,_,{[SR],Msg}} when is_record(SR, sctp_sndrcvinfo) ->
+ Fn(I+1, Count, Fn);
+ {sctp,S1,_,_,_} ->
+ %% ignore non-data messages
+ ok = inet:setopts(S1, [{active,1}]),
+ Fn(I, Count, Fn);
+ Other ->
+ exit({unexpected, Other})
+ after
+ 5000 ->
+ exit({error,timeout})
+ end
+ end,
+ ok = LoopFun(1, N, LoopFun),
+ S3 = ok(gen_sctp:open([{active,0}])),
+ receive
+ {sctp_passive,S3} ->
+ [{active,false}] = ok(inet:getopts(S3, [active]))
+ after
+ 5000 ->
+ exit({error,udp_passive})
+ end,
+ ok = gen_sctp:close(S3),
+ ok = gen_sctp:close(S2),
+ ok = gen_sctp:close(S1),
+ ok.
+
basic_stream(doc) ->
"Hello world stream socket";
basic_stream(suite) ->
@@ -840,23 +959,36 @@ xfer_stream_min(Config) when is_list(Config) ->
?line SbOutboundStreams = SaInboundStreams,
?line ?LOGVAR(SbOutboundStreams),
?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data),
- ?line case gen_sctp:recv(Sb, infinity) of
- {ok,{Loopback,
+ ?line case log_ok(gen_sctp:recv(Sb, infinity)) of
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} -> ok;
+ {Loopback,
+ Pa,[],
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = addr_available,
+ error = 0,
+ assoc_id = SbAssocId}} ->
+ {Loopback,
Pa,
[#sctp_sndrcvinfo{stream=Stream,
assoc_id=SbAssocId}],
- Data}} -> ok;
- {ok,{Loopback,
- Pa,[],
- #sctp_paddr_change{addr = {Loopback,_},
- state = addr_available,
- error = 0,
- assoc_id = SbAssocId}}} ->
- {ok,{Loopback,
- Pa,
- [#sctp_sndrcvinfo{stream=Stream,
- assoc_id=SbAssocId}],
- Data}} = gen_sctp:recv(Sb, infinity)
+ Data} = log_ok(gen_sctp:recv(Sb, infinity));
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = addr_confirmed,
+ error = 0,
+ assoc_id = SbAssocId}} ->
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} = log_ok(gen_sctp:recv(Sb, infinity))
end,
?line ok =
do_from_other_process(
@@ -941,6 +1073,14 @@ peeloff_active_true(suite) ->
peeloff_active_true(Config) ->
peeloff(Config, [{active,true}]).
+peeloff_active_n(doc) ->
+ "Peel off an SCTP stream socket ({active,N})";
+peeloff_active_n(suite) ->
+ [];
+
+peeloff_active_n(Config) ->
+ peeloff(Config, [{active,1}]).
+
peeloff(Config, SockOpts) when is_list(Config) ->
?line Addr = {127,0,0,1},
?line Stream = 0,
@@ -972,10 +1112,10 @@ peeloff(Config, SockOpts) when is_list(Config) ->
?line ?LOGVAR(S2Ai),
?line S1Ai =
receive
- {S1,{Addr,P2,
- #sctp_assoc_change{
- state=comm_up,
- assoc_id=AssocId1}}} -> AssocId1
+ {S1,{Addr,P2,
+ #sctp_assoc_change{
+ state=comm_up,
+ assoc_id=AssocId1}}} -> AssocId1
after Timeout ->
socket_bailout([S1,S2])
end,
@@ -1003,8 +1143,8 @@ peeloff(Config, SockOpts) when is_list(Config) ->
?line P3 = case P3_X of 0 -> P1; _ -> P3_X end,
?line [{_,#sctp_paddrinfo{assoc_id=S3Ai,state=active}}] =
socket_call(S3,
- {getopts,[{sctp_get_peer_addr_info,
- #sctp_paddrinfo{address={Addr,P2}}}]}),
+ {getopts,[{sctp_get_peer_addr_info,
+ #sctp_paddrinfo{address={Addr,P2}}}]}),
%%?line S3Ai = S1Ai,
?line ?LOGVAR(S3Ai),
%%
@@ -1087,9 +1227,9 @@ buffers(Config) when is_list(Config) ->
%%
?line socket_call(S1, {setopts,[{recbuf,Limit}]}),
?line Recbuf =
- case socket_call(S1, {getopts,[recbuf]}) of
- [{recbuf,RB1}] when RB1 >= Limit -> RB1
- end,
+ case socket_call(S1, {getopts,[recbuf]}) of
+ [{recbuf,RB1}] when RB1 >= Limit -> RB1
+ end,
?line Data = mk_data(Recbuf+Limit),
?line socket_call(S2, {setopts,[{sndbuf,Recbuf+Limit}]}),
?line socket_call(S2, {send,S2Ai,Stream,Data}),
@@ -1190,6 +1330,93 @@ open_multihoming_ipv4_and_ipv6_socket(Config) when is_list(Config) ->
{skip, Reason}
end.
+names_unihoming_ipv4(doc) ->
+ "Test inet:socknames/peernames on unihoming IPv4 sockets";
+names_unihoming_ipv4(suite) ->
+ [];
+names_unihoming_ipv4(Config) when is_list(Config) ->
+ ?line do_names(Config, inet, 1).
+
+names_unihoming_ipv6(doc) ->
+ "Test inet:socknames/peernames on unihoming IPv6 sockets";
+names_unihoming_ipv6(suite) ->
+ [];
+names_unihoming_ipv6(Config) when is_list(Config) ->
+ ?line do_names(Config, inet6, 1).
+
+names_multihoming_ipv4(doc) ->
+ "Test inet:socknames/peernames on multihoming IPv4 sockets";
+names_multihoming_ipv4(suite) ->
+ [];
+names_multihoming_ipv4(Config) when is_list(Config) ->
+ ?line do_names(Config, inet, 2).
+
+names_multihoming_ipv6(doc) ->
+ "Test inet:socknames/peernames on multihoming IPv6 sockets";
+names_multihoming_ipv6(suite) ->
+ [];
+names_multihoming_ipv6(Config) when is_list(Config) ->
+ ?line do_names(Config, inet6, 2).
+
+
+
+do_names(_, FamilySpec, AddressCount) ->
+ Fun =
+ fun (ServerSocket, _, ServerAssoc, ClientSocket, _, ClientAssoc) ->
+ ?line ServerSocknamesNoassoc =
+ lists:sort(ok(inet:socknames(ServerSocket))),
+ ?line ?LOGVAR(ServerSocknamesNoassoc),
+ ?line ServerSocknames =
+ lists:sort(ok(inet:socknames(ServerSocket, ServerAssoc))),
+ ?line ?LOGVAR(ServerSocknames),
+ ?line [_|_] =
+ ordsets:intersection
+ (ServerSocknamesNoassoc, ServerSocknames),
+ ?line ClientSocknamesNoassoc =
+ lists:sort(ok(inet:socknames(ClientSocket))),
+ ?line ?LOGVAR(ClientSocknamesNoassoc),
+ ?line ClientSocknames =
+ lists:sort(ok(inet:socknames(ClientSocket, ClientAssoc))),
+ ?line ?LOGVAR(ClientSocknames),
+ ?line [_|_] =
+ ordsets:intersection
+ (ClientSocknamesNoassoc, ClientSocknames),
+ ?line err([einval,enotconn], inet:peernames(ServerSocket)),
+ ?line ServerPeernames =
+ lists:sort(ok(inet:peernames(ServerSocket, ServerAssoc))),
+ ?line ?LOGVAR(ServerPeernames),
+ ?line err([einval,enotconn], inet:peernames(ClientSocket)),
+ ?line ClientPeernames =
+ lists:sort(ok(inet:peernames(ClientSocket, ClientAssoc))),
+ ?line ?LOGVAR(ClientPeernames),
+ ?line ServerSocknames = ClientPeernames,
+ ?line ClientSocknames = ServerPeernames,
+ ?line {ok,Socket} =
+ gen_sctp:peeloff(ServerSocket, ServerAssoc),
+ ?line SocknamesNoassoc =
+ lists:sort(ok(inet:socknames(Socket))),
+ ?line ?LOGVAR(SocknamesNoassoc),
+ ?line Socknames =
+ lists:sort(ok(inet:socknames(Socket, ServerAssoc))),
+ ?line ?LOGVAR(Socknames),
+ ?line true =
+ ordsets:is_subset(SocknamesNoassoc, Socknames),
+ ?line Peernames =
+ lists:sort(ok(inet:peernames(Socket, ServerAssoc))),
+ ?line ?LOGVAR(Peernames),
+ ?line ok = gen_sctp:close(Socket),
+ ?line Socknames = ClientPeernames,
+ ?line ClientSocknames = Peernames,
+ ok
+ end,
+ ?line case get_addrs_by_family(FamilySpec, AddressCount) of
+ {ok, Addresses} when length(Addresses) =:= AddressCount ->
+ ?line do_open_and_connect(Addresses, hd(Addresses), Fun);
+ {error, Reason} ->
+ {skip, Reason}
+ end.
+
+
get_addrs_by_family(Family, NumAddrs) ->
case os:type() of
@@ -1274,6 +1501,10 @@ f(F, A) ->
lists:flatten(io_lib:format(F, A)).
do_open_and_connect(ServerAddresses, AddressToConnectTo) ->
+ ?line Fun = fun (_, _, _, _, _, _) -> ok end,
+ ?line do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun).
+%%
+do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
?line ServerFamily = get_family_by_addrs(ServerAddresses),
?line io:format("Serving ~p addresses: ~p~n",
[ServerFamily, ServerAddresses]),
@@ -1284,14 +1515,26 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo) ->
?line ClientFamily = get_family_by_addr(AddressToConnectTo),
?line io:format("Connecting to ~p ~p~n",
[ClientFamily, AddressToConnectTo]),
- ?line S2 = ok(gen_sctp:open(0, [ClientFamily])),
+ ?line ClientOpts =
+ [ClientFamily |
+ case ClientFamily of
+ inet6 ->
+ [{ipv6_v6only,true}];
+ _ ->
+ []
+ end],
+ ?line S2 = ok(gen_sctp:open(0, ClientOpts)),
+ log(open),
%% Verify client can connect
- ?line #sctp_assoc_change{state=comm_up} =
+ ?line #sctp_assoc_change{state=comm_up} = S2Assoc =
ok(gen_sctp:connect(S2, AddressToConnectTo, P1, [])),
+ log(comm_up),
%% verify server side also receives comm_up from client
- ?line recv_comm_up_eventually(S1),
+ ?line S1Assoc = recv_comm_up_eventually(S1),
+ ?line Result = Fun(S1, ServerFamily, S1Assoc, S2, ClientFamily, S2Assoc),
?line ok = gen_sctp:close(S2),
- ?line ok = gen_sctp:close(S1).
+ ?line ok = gen_sctp:close(S1),
+ Result.
%% If at least one of the addresses is an ipv6 address, return inet6, else inet.
get_family_by_addrs(Addresses) ->
@@ -1306,9 +1549,11 @@ get_family_by_addr(Addr) when tuple_size(Addr) =:= 8 -> inet6.
recv_comm_up_eventually(S) ->
?line case ok(gen_sctp:recv(S)) of
- {_Addr, _Port, _Info, #sctp_assoc_change{state=comm_up}} ->
- ok;
- {_Addr, _Port, _Info, _OtherSctpMsg} ->
+ {_Addr, _Port, _Info,
+ #sctp_assoc_change{state=comm_up} = Assoc} ->
+ Assoc;
+ {_Addr, _Port, _Info, _OtherSctpMsg} = Msg ->
+ ?line log({unexpected,Msg}),
?line recv_comm_up_eventually(S)
end.
@@ -1367,10 +1612,10 @@ socket_bailout([]) ->
socket_history({State,Flush}) ->
{lists:keysort(
- 2,
- lists:flatten(
- [[{Key,Val} || Val <- Vals]
- || {Key,Vals} <- gb_trees:to_list(State)])),
+ 2,
+ lists:flatten(
+ [[{Key,Val} || Val <- Vals]
+ || {Key,Vals} <- gb_trees:to_list(State)])),
Flush}.
s_handler(Socket) ->
@@ -1453,7 +1698,7 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
#sctp_assoc_change{
state=comm_up,
inbound_streams=Is}}}|_]
- when 0 =< Stream, Stream < Is-> ok;
+ when 0 =< Stream, Stream < Is-> ok;
[] -> ok
end,
Key = {msg,AssocId,Stream},
@@ -1473,7 +1718,7 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
case {gb_get(Key, State),St} of
{[],_} -> ok;
{[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
- when St =:= comm_lost; St =:= shutdown_comp -> ok
+ when St =:= comm_lost; St =:= shutdown_comp -> ok
end,
NewState = gb_push(Key, Val, State),
Parent ! {self(),{Addr,Port,SAC}},
@@ -1489,8 +1734,9 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
[] -> ok
end,
case {gb_get({assoc_change,AssocId}, State),St} of
- {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],
- addr_available} -> ok;
+ {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
+ when St =:= addr_available;
+ St =:= addr_confirmed -> ok;
{[],addr_confirmed} -> ok
end,
Key = {paddr_change,AssocId},
@@ -1519,7 +1765,13 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
end.
again(Socket) ->
- inet:setopts(Socket, [{active,once}]).
+ receive
+ {sctp_passive,Socket} ->
+ [{active, false}] = ok(inet:getopts(Socket, [active])),
+ ok = inet:setopts(Socket,[{active,1}])
+ after 0 ->
+ ok = inet:setopts(Socket, [{active,once}])
+ end.
gb_push(Key, Val, GBT) ->
case gb_trees:lookup(Key, GBT) of
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index ee271fbdfa..ee8bfcceb1 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -25,7 +25,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
controlling_process/1, controlling_process_self/1,
- no_accept/1, close_with_pending_output/1,
+ no_accept/1, close_with_pending_output/1, active_n/1,
data_before_close/1, iter_max_socks/1, get_status/1,
passive_sockets/1, accept_closed_by_other_process/1,
init_per_testcase/2, end_per_testcase/2,
@@ -70,7 +70,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[controlling_process, controlling_process_self, no_accept,
close_with_pending_output, data_before_close,
- iter_max_socks, passive_sockets,
+ iter_max_socks, passive_sockets, active_n,
accept_closed_by_other_process, otp_3924, closed_socket,
shutdown_active, shutdown_passive, shutdown_pending,
default_options, http_bad_packet, busy_send,
@@ -407,6 +407,114 @@ send_loop(Sock, Data, Left) ->
ok = gen_tcp:send(Sock, Data),
send_loop(Sock, Data, Left-1).
+%% Test {active,N} option
+active_n(doc) ->
+ ["Verify operation of the {active,N} option."];
+active_n(suite) -> [];
+active_n(Config) when is_list(Config) ->
+ N = 3,
+ LS = ok(gen_tcp:listen(0, [{active,N}])),
+ [{active,N}] = ok(inet:getopts(LS, [active])),
+ ok = inet:setopts(LS, [{active,-N}]),
+ receive
+ {tcp_passive, LS} -> ok
+ after
+ 5000 ->
+ exit({error,tcp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(LS, [active])),
+ ok = inet:setopts(LS, [{active,0}]),
+ receive
+ {tcp_passive, LS} -> ok
+ after
+ 5000 ->
+ exit({error,tcp_passive_failure})
+ end,
+ ok = inet:setopts(LS, [{active,32767}]),
+ {error,einval} = inet:setopts(LS, [{active,1}]),
+ {error,einval} = inet:setopts(LS, [{active,-32769}]),
+ ok = inet:setopts(LS, [{active,-32768}]),
+ receive
+ {tcp_passive, LS} -> ok
+ after
+ 5000 ->
+ exit({error,tcp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(LS, [active])),
+ ok = inet:setopts(LS, [{active,N}]),
+ ok = inet:setopts(LS, [{active,true}]),
+ [{active,true}] = ok(inet:getopts(LS, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ ok = inet:setopts(LS, [{active,N}]),
+ ok = inet:setopts(LS, [{active,once}]),
+ [{active,once}] = ok(inet:getopts(LS, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ {error,einval} = inet:setopts(LS, [{active,32768}]),
+ ok = inet:setopts(LS, [{active,false}]),
+ [{active,false}] = ok(inet:getopts(LS, [active])),
+ Port = ok(inet:port(LS)),
+ C = ok(gen_tcp:connect("localhost", Port, [{active,N}])),
+ [{active,N}] = ok(inet:getopts(C, [active])),
+ S = ok(gen_tcp:accept(LS)),
+ ok = inet:setopts(S, [{active,N}]),
+ [{active,N}] = ok(inet:getopts(S, [active])),
+ repeat(3,
+ fun(I) ->
+ Msg = "message "++integer_to_list(I),
+ ok = gen_tcp:send(C, Msg),
+ receive
+ {tcp,S,Msg} ->
+ ok = gen_tcp:send(S, Msg)
+ after
+ 5000 ->
+ exit({error,timeout})
+ end,
+ receive
+ {tcp,C,Msg} ->
+ ok
+ after
+ 5000 ->
+ exit({error,timeout})
+ end
+ end),
+ receive
+ {tcp_passive,S} ->
+ [{active,false}] = ok(inet:getopts(S, [active]))
+ after
+ 5000 ->
+ exit({error,tcp_passive})
+ end,
+ receive
+ {tcp_passive,C} ->
+ [{active,false}] = ok(inet:getopts(C, [active]))
+ after
+ 5000 ->
+ exit({error,tcp_passive})
+ end,
+ LS2 = ok(gen_tcp:listen(0, [{active,0}])),
+ receive
+ {tcp_passive,LS2} ->
+ [{active,false}] = ok(inet:getopts(LS2, [active]))
+ after
+ 5000 ->
+ exit({error,tcp_passive})
+ end,
+ ok = gen_tcp:close(LS2),
+ ok = gen_tcp:close(C),
+ ok = gen_tcp:close(S),
+ ok = gen_tcp:close(LS),
+ ok.
+
-define(OTP_3924_MAX_DELAY, 100).
%% Taken out of the blue, but on intra host connections
%% I expect propagation of a close to be quite fast
@@ -2659,3 +2767,5 @@ oct_aloop(S,X,Times) ->
gen_tcp:close(S),
closed
end.
+
+ok({ok,V}) -> V.
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index cd768813cf..6bb41999c5 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -1,8 +1,7 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2013. 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
@@ -34,7 +33,7 @@
init_per_group/2,end_per_group/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
--export([send_to_closed/1,
+-export([send_to_closed/1, active_n/1,
buffer_size/1, binary_passive_recv/1, bad_address/1,
read_packets/1, open_fd/1, connect/1, implicit_inet6/1]).
@@ -43,7 +42,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[send_to_closed, buffer_size, binary_passive_recv,
bad_address, read_packets, open_fd, connect,
- implicit_inet6].
+ implicit_inet6, active_n].
groups() ->
[].
@@ -466,6 +465,108 @@ open_fd(Config) when is_list(Config) ->
?t:fail(io_lib:format("~w", [flush()]))
end.
+active_n(Config) when is_list(Config) ->
+ N = 3,
+ S1 = ok(gen_udp:open(0, [{active,N}])),
+ [{active,N}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,-N}]),
+ receive
+ {udp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,udp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,0}]),
+ receive
+ {udp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,udp_passive_failure})
+ end,
+ ok = inet:setopts(S1, [{active,32767}]),
+ {error,einval} = inet:setopts(S1, [{active,1}]),
+ {error,einval} = inet:setopts(S1, [{active,-32769}]),
+ ok = inet:setopts(S1, [{active,-32768}]),
+ receive
+ {udp_passive, S1} -> ok
+ after
+ 5000 ->
+ exit({error,udp_passive_failure})
+ end,
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ ok = inet:setopts(S1, [{active,N}]),
+ ok = inet:setopts(S1, [{active,true}]),
+ [{active,true}] = ok(inet:getopts(S1, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ ok = inet:setopts(S1, [{active,N}]),
+ ok = inet:setopts(S1, [{active,once}]),
+ [{active,once}] = ok(inet:getopts(S1, [active])),
+ receive
+ _ -> exit({error,active_n})
+ after
+ 0 ->
+ ok
+ end,
+ {error,einval} = inet:setopts(S1, [{active,32768}]),
+ ok = inet:setopts(S1, [{active,false}]),
+ [{active,false}] = ok(inet:getopts(S1, [active])),
+ S1Port = ok(inet:port(S1)),
+ S2 = ok(gen_udp:open(0, [{active,N}])),
+ S2Port = ok(inet:port(S2)),
+ [{active,N}] = ok(inet:getopts(S2, [active])),
+ ok = inet:setopts(S1, [{active,N}]),
+ [{active,N}] = ok(inet:getopts(S1, [active])),
+ lists:foreach(
+ fun(I) ->
+ Msg = "message "++integer_to_list(I),
+ ok = gen_udp:send(S2, "localhost", S1Port, Msg),
+ receive
+ {udp,S1,_,S2Port,Msg} ->
+ ok = gen_udp:send(S1, "localhost", S2Port, Msg)
+ after
+ 5000 ->
+ exit({error,timeout})
+ end,
+ receive
+ {udp,S2,_,S1Port,Msg} ->
+ ok
+ after
+ 5000 ->
+ exit({error,timeout})
+ end
+ end, lists:seq(1,N)),
+ receive
+ {udp_passive,S1} ->
+ [{active,false}] = ok(inet:getopts(S1, [active]))
+ after
+ 5000 ->
+ exit({error,udp_passive})
+ end,
+ receive
+ {udp_passive,S2} ->
+ [{active,false}] = ok(inet:getopts(S2, [active]))
+ after
+ 5000 ->
+ exit({error,udp_passive})
+ end,
+ S3 = ok(gen_udp:open(0, [{active,0}])),
+ receive
+ {udp_passive,S3} ->
+ [{active,false}] = ok(inet:getopts(S3, [active]))
+ after
+ 5000 ->
+ exit({error,udp_passive})
+ end,
+ ok = gen_udp:close(S3),
+ ok = gen_udp:close(S2),
+ ok = gen_udp:close(S1),
+ ok.
%
% Utils
diff --git a/lib/kernel/test/global_SUITE_data/global_trace.erl b/lib/kernel/test/global_SUITE_data/global_trace.erl
index 00bacf8f54..1396d86c79 100644
--- a/lib/kernel/test/global_SUITE_data/global_trace.erl
+++ b/lib/kernel/test/global_SUITE_data/global_trace.erl
@@ -1,4 +1,3 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index 62ba95e1a3..ed43749cc0 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -38,10 +38,10 @@
gethostnative_debug_level/0, gethostnative_debug_level/1,
getif/1,
getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1,
- parse_strict_address/1]).
+ parse_strict_address/1, simple_netns/1]).
-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
- kill_gethost/0, parallell_gethost/0]).
+ kill_gethost/0, parallell_gethost/0, test_netns/0]).
-export([init_per_testcase/2, end_per_testcase/2]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -53,7 +53,7 @@ all() ->
t_gethostnative, gethostnative_parallell, cname_loop,
gethostnative_debug_level, gethostnative_soft_restart,
getif, getif_ifr_name_overflow, getservbyname_overflow,
- getifaddrs, parse_strict_address].
+ getifaddrs, parse_strict_address, simple_netns].
groups() ->
[{parse, [], [parse_hosts, parse_address]}].
@@ -226,7 +226,7 @@ t_gethostbyname_v6(Config) when is_list(Config) ->
h_addr_list = [IP4]} = HEnt4,
{ok,IP46} =
inet_parse:ipv6_address(
- "::ffff:" ++ inet_parse:ntoa(IP4)),
+ "::ffff:" ++ inet:ntoa(IP4)),
check_elems(
[{HEnt#hostent.h_name,[Name,FullName]}])
end,
@@ -246,7 +246,7 @@ t_gethostbyname_v6(Config) when is_list(Config) ->
h_addr_list = [IP4F]} = HEnt4F,
{ok,IP46F} =
inet_parse:ipv6_address(
- "::ffff:" ++ inet_parse:ntoa(IP4F)),
+ "::ffff:" ++ inet:ntoa(IP4F)),
check_elems(
[{HEntF#hostent.h_name,[Name,FullName]}])
end;
@@ -1099,3 +1099,96 @@ toupper([C|Cs]) when is_integer(C) ->
end;
toupper([]) ->
[].
+
+
+simple_netns(Config) when is_list(Config) ->
+ {ok,U} = gen_udp:open(0),
+ case inet:setopts(U, [{netns,""}]) of
+ ok ->
+ jog_netns_opt(U),
+ ok = gen_udp:close(U),
+ %%
+ {ok,L} = gen_tcp:listen(0, []),
+ jog_netns_opt(L),
+ ok = gen_tcp:close(L),
+ %%
+ {ok,S} = gen_sctp:open(),
+ jog_netns_opt(S),
+ ok = gen_sctp:close(S);
+ {error,einval} ->
+ {skip,"setns() not supported"}
+ end.
+
+jog_netns_opt(S) ->
+ %% This is just jogging the option mechanics
+ ok = inet:setopts(S, [{netns,""}]),
+ {ok,[{netns,""}]} = inet:getopts(S, [netns]),
+ ok = inet:setopts(S, [{netns,"/proc/self/ns/net"}]),
+ {ok,[{netns,"/proc/self/ns/net"}]} = inet:getopts(S, [netns]),
+ ok.
+
+
+%% Manual test to be run outside test_server in an emulator
+%% started by root, in a machine with setns() support...
+test_netns() ->
+ DefaultIF = v1,
+ DefaultIP = {192,168,1,17},
+ Namespace = "test",
+ NamespaceIF = v2,
+ NamespaceIP = {192,168,1,18},
+ %%
+ DefaultIPString = inet_parse:ntoa(DefaultIP),
+ NamespaceIPString = inet_parse:ntoa(NamespaceIP),
+ cmd("ip netns add ~s",
+ [Namespace]),
+ cmd("ip link add name ~w type veth peer name ~w netns ~s",
+ [DefaultIF,NamespaceIF,Namespace]),
+ cmd("ip netns exec ~s ip addr add ~s/30 dev ~w",
+ [Namespace,NamespaceIPString,NamespaceIF]),
+ cmd("ip netns exec ~s ip link set ~w up",
+ [Namespace,NamespaceIF]),
+ cmd("ip addr add ~s/30 dev ~w",
+ [DefaultIPString,DefaultIF]),
+ cmd("ip link set ~w up",
+ [DefaultIF]),
+ try test_netns(
+ {DefaultIF,DefaultIP},
+ filename:join("/var/run/netns/", Namespace),
+ {NamespaceIF,NamespaceIP}) of
+ Result ->
+ io:put_chars(["#### Test done",io_lib:nl()]),
+ Result
+ after
+ cmd("ip link delete ~w type veth",
+ [DefaultIF]),
+ cmd("ip netns delete ~s",
+ [Namespace])
+ end.
+
+test_netns({DefaultIF,DefaultIP}, Namespace, {NamespaceIF,NamespaceIP}) ->
+ {ok,ListenSocket} = gen_tcp:listen(0, [{active,false}]),
+ {ok,[{addr,DefaultIP}]} = inet:ifget(ListenSocket, DefaultIF, [addr]),
+ {ok,ListenPort} = inet:port(ListenSocket),
+ {ok,ConnectSocket} =
+ gen_tcp:connect(
+ DefaultIP, ListenPort, [{active,false},{netns,Namespace}], 3000),
+ {ok,[{addr,NamespaceIP}]} = inet:ifget(ConnectSocket, NamespaceIF, [addr]),
+ {ok,ConnectPort} = inet:port(ConnectSocket),
+ {ok,AcceptSocket} = gen_tcp:accept(ListenSocket, 0),
+ {ok,AcceptPort} = inet:port(AcceptSocket),
+ {ok,{NamespaceIP,ConnectPort}} = inet:peername(AcceptSocket),
+ {ok,{DefaultIP,AcceptPort}} = inet:peername(ConnectSocket),
+ ok = gen_tcp:send(ConnectSocket, "data"),
+ ok = gen_tcp:close(ConnectSocket),
+ {ok,"data"} = gen_tcp:recv(AcceptSocket, 4, 1000),
+ {error,closed} = gen_tcp:recv(AcceptSocket, 1, 1000),
+ ok = gen_tcp:close(AcceptSocket),
+ ok = gen_tcp:close(ListenSocket).
+
+cmd(Cmd, Args) ->
+ cmd(io_lib:format(Cmd, Args)).
+%%
+cmd(CmdString) ->
+ io:put_chars(["# ",CmdString,io_lib:nl()]),
+ io:put_chars([os:cmd(CmdString++" ; echo ' =>' $?")]),
+ ok.
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index d7d9434b1f..a375adceea 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -22,7 +22,7 @@
init_per_group/2,end_per_group/2,
get_columns_and_rows/1, exit_initial/1, job_control_local/1,
job_control_remote/1,
- job_control_remote_noshell/1]).
+ job_control_remote_noshell/1,ctrl_keys/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% For spawn
@@ -41,7 +41,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[get_columns_and_rows, exit_initial, job_control_local,
- job_control_remote, job_control_remote_noshell].
+ job_control_remote, job_control_remote_noshell,
+ ctrl_keys].
groups() ->
[].
@@ -289,7 +290,51 @@ job_control_remote_noshell(Config) when is_list(Config) ->
?line stop_noshell_node(NSNode),
?line Res
end.
-
+
+ctrl_keys(suite) -> [];
+ctrl_keys(doc) -> ["Tests various control keys"];
+ctrl_keys(_Conf) when is_list(_Conf) ->
+ Cu=[$\^u],
+ Cw=[$\^w],
+ Home=[27,$O,$H],
+ End=[27,$O,$F],
+ rtnode([{putline,""},
+ {putline,"2."},
+ {getline,"2"},
+ {putline,"\"hello "++Cw++"world\"."}, % test <CTRL>+W
+ {getline,"\"world\""},
+ {putline,"\"hello "++Cu++"\"world\"."}, % test <CTRL>+U
+ {getline,"\"world\""},
+ {putline,"world\"."++Home++"\"hello "}, % test <HOME>
+ {getline,"\"hello world\""},
+ {putline,"world"++Home++"\"hello "++End++"\"."}, % test <END>
+ {getline,"\"hello world\""}]
+ ++wordLeft()++wordRight(),[]).
+
+
+wordLeft() ->
+ L1=[27,27,$[,$D],
+ L2=[27]++"[5D",
+ L3=[27]++"[1;5D",
+ wordLeft(L1)++wordLeft(L2)++wordLeft(L3).
+
+wordLeft(Chars) ->
+ End=[27,$O,$F],
+ [{putline,"\"world\""++Chars++"hello "++End++"."},
+ {getline,"\"hello world\""}].
+
+wordRight() ->
+ R1=[27,27,$[,$C],
+ R2=[27]++"[5C",
+ R3=[27]++"[1;5C",
+ wordRight(R1)++wordRight(R2)++wordRight(R3).
+
+wordRight(Chars) ->
+ Home=[27,$O,$H],
+ [{putline,"world"++Home++"\"hello "++Chars++"\"."},
+ {getline,"\"hello world\""}].
+
+
rtnode(C,N) ->
rtnode(C,N,[]).
rtnode(Commands,Nodename,ErlPrefix) ->
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index 0f29d895e5..78f5e93fc3 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. 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
@@ -23,9 +23,6 @@
-include_lib("test_server/include/test_server.hrl").
-% Default timetrap timeout (set in init_per_testcase).
--define(default_timeout, ?t:minutes(1)).
-
% Test server specific exports
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
@@ -59,11 +56,8 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(_Case, Config) ->
- ?line Dog=test_server:timetrap(?default_timeout),
- [{watchdog, Dog}|Config].
-end_per_testcase(_Case, Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
+ Config.
+end_per_testcase(_Case, _Config) ->
ok.
%
@@ -78,56 +72,80 @@ app_test(Config) when is_list(Config) ->
ok.
-%% Test that appup allows upgrade from/downgrade to a maximum of two
-%% major releases back.
+%% Test that appup allows upgrade from/downgrade to a maximum of one
+%% major release back.
appup_test(_Config) ->
- application:load(kernel),
- {_,_,Vsn} = lists:keyfind(kernel,1,application:loaded_applications()),
- AppupFile = filename:join([code:lib_dir(kernel),ebin,"kernel.appup"]),
+ appup_tests(kernel,create_test_vsns(kernel)).
+
+appup_tests(_App,{[],[]}) ->
+ {skip,"no previous releases available"};
+appup_tests(App,{OkVsns,NokVsns}) ->
+ application:load(App),
+ {_,_,Vsn} = lists:keyfind(App,1,application:loaded_applications()),
+ AppupFileName = atom_to_list(App) ++ ".appup",
+ AppupFile = filename:join([code:lib_dir(App),ebin,AppupFileName]),
{ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile),
ct:log("~p~n",[AppupScript]),
- {OkVsns,NokVsns} = create_test_vsns(Vsn),
+ ct:log("Testing ok versions: ~p~n",[OkVsns]),
check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}),
check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}),
+ ct:log("Testing not ok versions: ~p~n",[NokVsns]),
check_appup(NokVsns,UpFrom,error),
check_appup(NokVsns,DownTo,error),
ok.
-create_test_vsns(Current) ->
- [XStr,YStr|Rest] = string:tokens(Current,"."),
- X = list_to_integer(XStr),
- Y = list_to_integer(YStr),
- SecondMajor = vsn(X,Y-2),
- SecondMinor = SecondMajor ++ ".1.3",
- FirstMajor = vsn(X,Y-1),
- FirstMinor = FirstMajor ++ ".57",
- ThisMajor = vsn(X,Y),
- This =
- case Rest of
- [] ->
- [];
- ["1"] ->
- [ThisMajor];
- _ ->
- ThisMinor = ThisMajor ++ ".1",
- [ThisMajor,ThisMinor]
+create_test_vsns(App) ->
+ This = erlang:system_info(otp_release),
+ FirstMajor = previous_major(This),
+ SecondMajor = previous_major(FirstMajor),
+ Ok = app_vsn(App,[FirstMajor]),
+ Nok0 = app_vsn(App,[SecondMajor]),
+ Nok = case Ok of
+ [Ok1|_] ->
+ [Ok1 ++ ",1" | Nok0]; % illegal
+ _ ->
+ Nok0
+ end,
+ {Ok,Nok}.
+
+previous_major("17") ->
+ "r16";
+previous_major("r"++Rel) ->
+ "r"++previous_major(Rel);
+previous_major(Rel) ->
+ integer_to_list(list_to_integer(Rel)-1).
+
+app_vsn(App,[R|Rs]) ->
+ OldRel =
+ case test_server:is_release_available(R) of
+ true ->
+ {release,R};
+ false ->
+ case ct:get_config({otp_releases,list_to_atom(R)}) of
+ undefined ->
+ false;
+ Prog0 ->
+ case os:find_executable(Prog0) of
+ false ->
+ false;
+ Prog ->
+ {prog,Prog}
+ end
+ end
end,
- OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor],
-
- ThirdMajor = vsn(X,Y-3),
- ThirdMinor = ThirdMajor ++ ".10.12",
- Illegal = ThisMajor ++ ",1",
- Newer1Major = vsn(X,Y+1),
- Newer1Minor = Newer1Major ++ ".1",
- Newer2Major = ThisMajor ++ "1",
- NokVsns = [ThirdMajor,ThirdMinor,
- Illegal,
- Newer1Major,Newer1Minor,
- Newer2Major],
- {OkVsns,NokVsns}.
-
-vsn(X,Y) ->
- integer_to_list(X) ++ "." ++ integer_to_list(Y).
+ case OldRel of
+ false ->
+ app_vsn(App,Rs);
+ _ ->
+ {ok,N} = test_server:start_node(prevrel,peer,[{erl,[OldRel]}]),
+ _ = rpc:call(N,application,load,[App]),
+ As = rpc:call(N,application,loaded_applications,[]),
+ {_,_,V} = lists:keyfind(App,1,As),
+ test_server:stop_node(N),
+ [V|app_vsn(App,Rs)]
+ end;
+app_vsn(_App,[]) ->
+ [].
check_appup([Vsn|Vsns],Instrs,Expected) ->
case systools_relup:appup_search_for_version(Vsn, Instrs) of
diff --git a/lib/kernel/test/kernel_smoke.spec b/lib/kernel/test/kernel_smoke.spec
new file mode 100644
index 0000000000..e5d8273c56
--- /dev/null
+++ b/lib/kernel/test/kernel_smoke.spec
@@ -0,0 +1,9 @@
+{config, "../test_server/ts.config"}.
+{config, "../test_server/ts.unix.config"}.
+
+{cases,"../kernel_test", inet_SUITE,[t_gethostbyaddr,t_gethostbyname,
+ t_gethostbyaddr_v6,t_gethostbyname_v6,t_gethostnative,getifaddrs]}.
+{cases,"../kernel_test", inet_res_SUITE,[gethostbyaddr,gethostbyname,
+ gethostbyaddr_v6,gethostbyname_v6,basic]}.
+{cases,"../kernel_test", gen_tcp_echo_SUITE,[active_echo]}.
+{cases,"../kernel_test", heart_SUITE,[reboot]}.
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 73ed704ae3..9b474c4cdf 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -20,7 +20,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2]).
--export([space_in_cwd/1, quoting/1, space_in_name/1, bad_command/1,
+-export([space_in_cwd/1, quoting/1, cmd_unicode/1, space_in_name/1, bad_command/1,
find_executable/1, unix_comment_in_command/1, deep_list_command/1, evil/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -28,9 +28,8 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [space_in_cwd, quoting, space_in_name, bad_command,
- find_executable, unix_comment_in_command, deep_list_command,
- evil].
+ [space_in_cwd, quoting, cmd_unicode, space_in_name, bad_command,
+ find_executable, unix_comment_in_command, deep_list_command, evil].
groups() ->
[].
@@ -95,6 +94,21 @@ quoting(Config) when is_list(Config) ->
?line [] = receive_all(),
ok.
+
+cmd_unicode(doc) -> "Test that unicode arguments work.";
+cmd_unicode(suite) -> [];
+cmd_unicode(Config) when is_list(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line Echo = filename:join(DataDir, "my_echo"),
+
+ ?line comp("one", os:cmd(Echo ++ " one")),
+ ?line comp("one::two", os:cmd(Echo ++ " one two")),
+ ?line comp("åäö::ϼΩ", os:cmd(Echo ++ " åäö " ++ [1020, 937])),
+ ?t:sleep(5),
+ ?line [] = receive_all(),
+ ok.
+
+
space_in_name(doc) ->
"Test that program with a space in its name can be executed.";
space_in_name(suite) -> [];
@@ -302,8 +316,8 @@ comp(Expected, Got) ->
Expected ->
ok;
Other ->
- ok = io:format("Expected: ~s\n", [Expected]),
- ok = io:format("Got: ~s\n", [Other]),
+ ok = io:format("Expected: ~ts\n", [Expected]),
+ ok = io:format("Got: ~ts\n", [Other]),
test_server:fail()
end.
diff --git a/lib/kernel/test/os_SUITE_data/my_echo.c b/lib/kernel/test/os_SUITE_data/my_echo.c
index 2127511dd1..712c828bb5 100644
--- a/lib/kernel/test/os_SUITE_data/my_echo.c
+++ b/lib/kernel/test/os_SUITE_data/my_echo.c
@@ -1,3 +1,30 @@
+#ifdef __WIN32__
+#include <windows.h>
+
+int wmain(int argc, wchar_t **argv)
+{
+ char* sep = "";
+ int len;
+
+ /*
+ * Echo all arguments separated with '::', so that we can check that
+ * quotes are interpreted correctly.
+ */
+
+ while (argc-- > 1) {
+ char *utf8;
+ len = WideCharToMultiByte(CP_UTF8, 0, argv[1], -1, NULL, 0, NULL, NULL);
+ utf8 = malloc(len*sizeof(char));
+ WideCharToMultiByte(CP_UTF8, 0, argv++[1], -1, utf8, len, NULL, NULL);
+ printf("%s%s", sep, utf8);
+ free(utf8);
+ sep = "::";
+ }
+ putchar('\n');
+ return 0;
+}
+#else
+
#include <stdio.h>
int
@@ -17,3 +44,4 @@ main(int argc, char** argv)
putchar('\n');
return 0;
}
+#endif
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
index 5c4437d4d3..615251a257 100644
--- a/lib/kernel/test/ram_file_SUITE.erl
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -1,8 +1,7 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2013. 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
diff --git a/lib/kernel/test/sendfile_SUITE.erl b/lib/kernel/test/sendfile_SUITE.erl
index 4cf4c6489d..2c741232c4 100644
--- a/lib/kernel/test/sendfile_SUITE.erl
+++ b/lib/kernel/test/sendfile_SUITE.erl
@@ -24,7 +24,14 @@
-compile(export_all).
-all() ->
+all() -> [{group,async_threads},
+ {group,no_async_threads}].
+
+groups() ->
+ [{async_threads,[],tcs()},
+ {no_async_threads,[],tcs()}].
+
+tcs() ->
[t_sendfile_small
,t_sendfile_big_all
,t_sendfile_big_size
@@ -33,6 +40,7 @@ all() ->
,t_sendfile_offset
,t_sendfile_sendafter
,t_sendfile_recvafter
+ ,t_sendfile_recvafter_remoteclose
,t_sendfile_sendduring
,t_sendfile_recvduring
,t_sendfile_closeduring
@@ -63,6 +71,14 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
file:delete(proplists:get_value(big_file, Config)).
+init_per_group(async_threads,Config) ->
+ [{sendfile_opts,[{use_threads,true}]}|Config];
+init_per_group(no_async_threads,Config) ->
+ [{sendfile_opts,[{use_threads,false}]}|Config].
+
+end_per_group(_,_Config) ->
+ ok.
+
init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
TC == t_sendfile_sendduring ->
Filename = proplists:get_value(small_file, Config),
@@ -71,7 +87,7 @@ init_per_testcase(TC,Config) when TC == t_sendfile_recvduring;
{_Size, Data} = sendfile_file_info(Filename),
{ok,D} = file:open(Filename, [raw,binary,read]),
prim_file:sendfile(D, Sock, 0, 0, 0,
- [],[],false,false,false),
+ [],[],[]),
Data
end,
@@ -92,6 +108,7 @@ t_sendfile_small(Config) when is_list(Config) ->
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
+ %% Here we make sure to test the sendfile/2 api
{ok, Size} = file:sendfile(Filename, Sock),
Data
end,
@@ -101,6 +118,7 @@ t_sendfile_small(Config) when is_list(Config) ->
t_sendfile_many_small(Config) when is_list(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
error_logger:add_report_handler(?MODULE,[self()]),
@@ -109,7 +127,7 @@ t_sendfile_many_small(Config) when is_list(Config) ->
N = 10000,
{ok,D} = file:open(Filename,[read|FileOpts]),
[begin
- {ok,Size} = file:sendfile(D,Sock,0,0,[])
+ {ok,Size} = file:sendfile(D,Sock,0,0,SendfileOpts)
end || _I <- lists:seq(1,N)],
file:close(D),
Size*N
@@ -127,11 +145,12 @@ t_sendfile_many_small(Config) when is_list(Config) ->
t_sendfile_big_all(Config) when is_list(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
file:read_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
Size
end,
@@ -140,12 +159,13 @@ t_sendfile_big_all(Config) when is_list(Config) ->
t_sendfile_big_size(Config) ->
Filename = proplists:get_value(big_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
SendAll = fun(Sock) ->
{ok, #file_info{size = Size}} =
file:read_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok, Size} = file:sendfile(D, Sock,0,Size,[]),
+ {ok, Size} = file:sendfile(D, Sock,0,Size,SendfileOpts),
Size
end,
@@ -154,12 +174,13 @@ t_sendfile_big_size(Config) ->
t_sendfile_partial(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
SendSingle = fun(Sock) ->
{_Size, <<Data:5/binary,_/binary>>} =
sendfile_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok,5} = file:sendfile(D,Sock,0,5,[]),
+ {ok,5} = file:sendfile(D,Sock,0,5,SendfileOpts),
file:close(D),
Data
end,
@@ -170,14 +191,14 @@ t_sendfile_partial(Config) ->
{ok,D} = file:open(Filename,[read|FileOpts]),
{ok, <<FData/binary>>} = file:read(D,5),
FSend = fun(Sock) ->
- {ok,5} = file:sendfile(D,Sock,0,5,[]),
+ {ok,5} = file:sendfile(D,Sock,0,5,SendfileOpts),
FData
end,
ok = sendfile_send(FSend),
SSend = fun(Sock) ->
- {ok,3} = file:sendfile(D,Sock,5,3,[]),
+ {ok,3} = file:sendfile(D,Sock,5,3,SendfileOpts),
SData
end,
@@ -190,12 +211,13 @@ t_sendfile_partial(Config) ->
t_sendfile_offset(Config) ->
Filename = proplists:get_value(small_file, Config),
FileOpts = proplists:get_value(file_opts, Config, []),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{_Size, <<_:5/binary,Data:3/binary,_/binary>> = AllData} =
sendfile_file_info(Filename),
{ok,D} = file:open(Filename,[read|FileOpts]),
- {ok,3} = file:sendfile(D,Sock,5,3,[]),
+ {ok,3} = file:sendfile(D,Sock,5,3,SendfileOpts),
{ok, AllData} = file:read(D,100),
file:close(D),
Data
@@ -205,10 +227,11 @@ t_sendfile_offset(Config) ->
t_sendfile_sendafter(Config) ->
Filename = proplists:get_value(small_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
ok = gen_tcp:send(Sock, <<2>>),
<<Data/binary,2>>
end,
@@ -217,10 +240,11 @@ t_sendfile_sendafter(Config) ->
t_sendfile_recvafter(Config) ->
Filename = proplists:get_value(small_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{Size, Data} = sendfile_file_info(Filename),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
ok = gen_tcp:send(Sock, <<1>>),
{ok,<<1>>} = gen_tcp:recv(Sock, 1),
<<Data/binary,1>>
@@ -228,8 +252,28 @@ t_sendfile_recvafter(Config) ->
ok = sendfile_send(Send).
+%% This tests specifically for a bug fixed in 17.0
+t_sendfile_recvafter_remoteclose(Config) ->
+ Filename = proplists:get_value(small_file, Config),
+
+ Send = fun(Sock, SFServer) ->
+ {Size, _Data} = sendfile_file_info(Filename),
+ {ok, Size} = file:sendfile(Filename, Sock),
+
+ %% Make sure the remote end has been closed
+ SFServer ! stop,
+ timer:sleep(100),
+
+ %% In the bug this returned {error,ebadf}
+ {error,closed} = gen_tcp:recv(Sock, 1),
+ -1
+ end,
+
+ ok = sendfile_send({127,0,0,1},Send,0).
+
t_sendfile_sendduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
@@ -238,7 +282,7 @@ t_sendfile_sendduring(Config) ->
timer:sleep(50),
ok = gen_tcp:send(Sock, <<2>>)
end),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
Size+1
end,
@@ -246,6 +290,7 @@ t_sendfile_sendduring(Config) ->
t_sendfile_recvduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock) ->
{ok, #file_info{size = Size}} =
@@ -255,7 +300,7 @@ t_sendfile_recvduring(Config) ->
ok = gen_tcp:send(Sock, <<1>>),
{ok,<<1>>} = gen_tcp:recv(Sock, 1)
end),
- {ok, Size} = file:sendfile(Filename, Sock),
+ {ok, Size} = sendfile(Filename, Sock, SendfileOpts),
timer:sleep(1000),
Size+1
end,
@@ -264,6 +309,7 @@ t_sendfile_recvduring(Config) ->
t_sendfile_closeduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
Send = fun(Sock,SFServPid) ->
spawn_link(fun() ->
@@ -272,13 +318,14 @@ t_sendfile_closeduring(Config) ->
end),
case erlang:system_info(thread_pool_size) of
0 ->
- {error, closed} = file:sendfile(Filename, Sock);
+ {error, closed} = sendfile(Filename, Sock,
+ SendfileOpts);
_Else ->
%% This can return how much has been sent or
%% {error,closed} depending on OS.
%% How much is sent impossible to know as
%% the socket was closed mid sendfile
- case file:sendfile(Filename, Sock) of
+ case sendfile(Filename, Sock, SendfileOpts) of
{error, closed} ->
ok;
{ok, Size} when is_integer(Size) ->
@@ -292,6 +339,7 @@ t_sendfile_closeduring(Config) ->
t_sendfile_crashduring(Config) ->
Filename = proplists:get_value(big_file, Config),
+ SendfileOpts = proplists:get_value(sendfile_opts, Config),
error_logger:add_report_handler(?MODULE,[self()]),
@@ -300,7 +348,7 @@ t_sendfile_crashduring(Config) ->
timer:sleep(50),
exit(die)
end),
- {error, closed} = file:sendfile(Filename, Sock),
+ {error, closed} = sendfile(Filename, Sock, SendfileOpts),
-1
end,
process_flag(trap_exit,true),
@@ -395,6 +443,16 @@ sendfile_file_info(File) ->
{ok, Data} = file:read_file(File),
{Size, Data}.
+sendfile(Filename,Sock,Opts) ->
+ case file:open(Filename, [read, raw, binary]) of
+ {error, Reason} ->
+ {error, Reason};
+ {ok, Fd} ->
+ Res = file:sendfile(Fd, Sock, 0, 0, Opts),
+ _ = file:close(Fd),
+ Res
+ end.
+
%% Error handler
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index bd237cb513..3be6f39d95 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2013. 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
@@ -178,7 +178,7 @@ api_deflateInit(Config) when is_list(Config) ->
?m(ok,zlib:close(Z))
end, lists:seq(1,8)),
- Strategies = [filtered,huffman_only,default],
+ Strategies = [filtered,huffman_only,rle,default],
lists:foreach(fun(Strategy) ->
?line Z = zlib:open(),
?m(ok, zlib:deflateInit(Z,best_speed,deflated,-15,8,Strategy)),
@@ -220,7 +220,6 @@ api_deflateParams(Config) when is_list(Config) ->
?m(_, zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, none)),
?m(ok, zlib:deflateParams(Z1, best_compression, huffman_only)),
?m(_, zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, sync)),
- ?m({'EXIT',_}, zlib:deflateParams(Z1,best_speed, filtered)),
?m(ok, zlib:close(Z1)).
api_deflate(doc) -> "Test deflate";
@@ -565,8 +564,8 @@ intro(Config) when is_list(Config) ->
large_deflate(doc) -> "Test deflate large file, which had a bug reported on erlang-bugs";
large_deflate(suite) -> [];
large_deflate(Config) when is_list(Config) ->
- large_deflate().
-large_deflate() ->
+ large_deflate_do().
+large_deflate_do() ->
?line Z = zlib:open(),
?line Plain = rand_bytes(zlib:getBufSize(Z)*5),
?line ok = zlib:deflateInit(Z),
@@ -899,7 +898,7 @@ worker(Seed, FnATpl, Parent) ->
Parent ! self().
worker_loop(0, _FnATpl) ->
- large_deflate(), % the time consuming one as finale
+ large_deflate_do(), % the time consuming one as finale
ok;
worker_loop(N, FnATpl) ->
{F,A} = element(random:uniform(size(FnATpl)),FnATpl),