aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test')
-rw-r--r--lib/kernel/test/Makefile12
-rw-r--r--lib/kernel/test/application_SUITE.erl17
-rw-r--r--lib/kernel/test/code_SUITE.erl60
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl325
-rw-r--r--lib/kernel/test/file_SUITE.erl76
-rw-r--r--lib/kernel/test/file_name_SUITE.erl11
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl10
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c1
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl86
-rw-r--r--lib/kernel/test/inet_SUITE.erl2
-rw-r--r--lib/kernel/test/inet_res_SUITE.erl9
-rw-r--r--lib/kernel/test/init_SUITE.erl2
-rw-r--r--lib/kernel/test/kernel_config_SUITE.erl21
-rw-r--r--lib/kernel/test/logger_disk_log_h_SUITE.erl10
-rw-r--r--lib/kernel/test/logger_std_h_SUITE.erl57
-rw-r--r--lib/kernel/test/seq_trace_SUITE.erl7
16 files changed, 540 insertions, 166 deletions
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 8a6ffe7e72..6763a04d9f 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -57,6 +57,7 @@ MODULES= \
prim_file_SUITE \
ram_file_SUITE \
gen_tcp_api_SUITE \
+ gen_tcp_dist \
gen_tcp_echo_SUITE \
gen_tcp_misc_SUITE \
gen_udp_SUITE \
@@ -130,11 +131,17 @@ ERL_COMPILE_FLAGS +=
EBIN = .
+TARGETS = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-make_emakefile:
+gen_tcp_dist.erl: ../examples/gen_tcp_dist/src/gen_tcp_dist.erl
+ cp $< $@
+
+make_emakefile: $(ERL_FILES)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' \
> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
@@ -150,6 +157,9 @@ clean:
docs:
+targets: $(TARGETS)
+
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 94d7c17712..1ab554db7c 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -2020,18 +2020,11 @@ set_env_errors(Conf) when is_list(Conf) ->
"application: kernel; erroneous parameter: distributed" =
badarg_msg(fun() -> application:set_env([{kernel, [{distributed, config}]}]) end),
- %% This will raise in the future
- ct:capture_start(),
- _ = application:set_env([{foo, []}, {foo, []}]),
- timer:sleep(100),
- ct:capture_stop(),
- [_ | _] = string:find(ct:capture_get(), "duplicate application config: foo"),
-
- ct:capture_start(),
- _ = application:set_env([{foo, [{bar, baz}, {bar, bat}]}]),
- timer:sleep(100),
- ct:capture_stop(),
- [_ | _] = string:find(ct:capture_get(), "application: foo; duplicate parameter: bar"),
+ "duplicate application config: foo" =
+ badarg_msg(fun() -> application:set_env([{foo, []}, {foo, []}]) end),
+
+ "application: foo; duplicate parameter: bar" =
+ badarg_msg(fun() -> application:set_env([{foo, [{bar, baz}, {bar, bat}]}]) end),
ok.
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 1314316c13..6b133f8d6b 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -25,8 +25,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, purge_many_exits/1, soft_purge/1, is_loaded/1,
- all_loaded/1,
+ delete/1, purge/1, purge_many_exits/0, 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,
@@ -41,7 +41,7 @@
big_boot_embedded/1,
module_status/1,
native_early_modules/1, get_mode/1,
- normalized_paths/1]).
+ normalized_paths/1, mult_embedded_flags/1]).
-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1]).
@@ -55,7 +55,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{minutes,5}}].
+ {timetrap,{seconds,30}}].
all() ->
[set_path, get_path, add_path, add_paths, del_path,
@@ -72,7 +72,8 @@ all() ->
on_load_purge, on_load_self_call, on_load_pending,
on_load_deleted,
module_status,
- big_boot_embedded, native_early_modules, get_mode, normalized_paths].
+ big_boot_embedded, native_early_modules, get_mode, normalized_paths,
+ mult_embedded_flags].
%% These need to run in order
groups() -> [{sequence, [sequence], [on_load_update,
@@ -140,6 +141,11 @@ end_per_testcase(on_load_embedded, Config) ->
LinkName = proplists:get_value(link_name, Config),
_ = del_link(LinkName),
end_per_testcase(Config);
+end_per_testcase(upgrade, Config) ->
+ %% Make sure tracing is turned off even if the test times out.
+ erlang:trace_pattern({error_handler,undefined_function,3}, false, [global]),
+ erlang:trace(self(), false, [call]),
+ end_per_testcase(Config);
end_per_testcase(_Func, Config) ->
end_per_testcase(Config).
@@ -349,7 +355,7 @@ load_abs(Config) when is_list(Config) ->
ensure_loaded(Config) when is_list(Config) ->
{module, lists} = code:ensure_loaded(lists),
case init:get_argument(mode) of
- {ok, [["embedded"]]} ->
+ {ok, [["embedded"] | _]} ->
{error, embedded} = code:ensure_loaded(code_b_test),
{error, badarg} = code:ensure_loaded(34),
ok;
@@ -391,6 +397,9 @@ purge(Config) when is_list(Config) ->
process_flag(trap_exit, OldFlag),
ok.
+purge_many_exits() ->
+ [{timetrap, {minutes, 2}}].
+
purge_many_exits(Config) when is_list(Config) ->
OldFlag = process_flag(trap_exit, true),
@@ -525,7 +534,7 @@ upgrade(Config) ->
T = [beam, hipe],
[upgrade_do(DataDir, Client, T) || Client <- T],
- case hipe:llvm_support_available() of
+ case hipe:erllvm_is_supported() of
false -> ok;
true ->
T2 = [beam, hipe_llvm],
@@ -1021,6 +1030,13 @@ mult_lib_remove_prefix([H|T1], [H|T2]) ->
mult_lib_remove_prefix([$/|T], []) -> T.
bad_erl_libs(Config) when is_list(Config) ->
+ %% Preserve ERL_LIBS if set.
+ BadLibs0 = "/no/such/dir",
+ BadLibs =
+ case os:getenv("ERL_LIBS") of
+ false -> BadLibs0;
+ Libs -> BadLibs0 ++ ":" ++ Libs
+ end,
{ok,Node} =
test_server:start_node(bad_erl_libs, slave, []),
Code = rpc:call(Node,code,get_path,[]),
@@ -1028,10 +1044,9 @@ bad_erl_libs(Config) when is_list(Config) ->
{ok,Node2} =
test_server:start_node(bad_erl_libs, slave,
- [{args,"-env ERL_LIBS /no/such/dir"}]),
+ [{args,"-env ERL_LIBS " ++ BadLibs}]),
Code2 = rpc:call(Node,code,get_path,[]),
test_server:stop_node(Node2),
-
%% Test that code path is not affected by the faulty ERL_LIBS
Code = Code2,
@@ -1550,6 +1565,11 @@ on_load_update_code_1(3, Mod) ->
%% Test -on_load while trace feature 'on_load' is enabled (OTP-14612)
on_load_trace_on_load(Config) ->
+ %% 'on_load' enables tracing for all newly loaded modules, so we make a dry
+ %% run to ensure that ancillary modules like 'merl' won't be loaded during
+ %% the actual test.
+ on_load_update(Config),
+
Papa = self(),
Tracer = spawn_link(fun F() -> receive M -> Papa ! M end, F() end),
{tracer,[]} = erlang:trace_info(self(),tracer),
@@ -1817,6 +1837,28 @@ do_normalized_paths([M|Ms]) ->
do_normalized_paths([]) ->
ok.
+%% Make sure that the extra -mode flags are ignored
+mult_embedded_flags(_Config) ->
+ Modes = [{" -mode embedded", embedded},
+ {" -mode interactive", interactive},
+ {" -mode invalid", interactive}],
+
+ [ begin
+ {ArgMode, ExpectedMode} = Mode,
+ {ok, Node} = start_node(mode_test, ArgMode),
+ ExpectedMode = rpc:call(Node, code, get_mode, []),
+ true = stop_node(Node)
+ end || Mode <- Modes],
+
+ [ begin
+ {ArgIgnoredMode, _} = IgnoredMode,
+ {ArgRelevantMode, ExpectedMode} = RelevantMode,
+ {ok, Node} = start_node(mode_test, ArgRelevantMode ++ ArgIgnoredMode),
+ ExpectedMode = rpc:call(Node, code, get_mode, []),
+ true = stop_node(Node)
+ end || IgnoredMode <- Modes, RelevantMode <- Modes],
+ ok.
+
%% Test that module_status/1 behaves as expected
module_status(_Config) ->
case test_server:is_cover() of
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 5a8bbd56c4..c3a022df0a 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -40,7 +40,8 @@
monitor_nodes_errors/1,
monitor_nodes_combinations/1,
monitor_nodes_cleanup/1,
- monitor_nodes_many/1]).
+ monitor_nodes_many/1,
+ dist_ctrl_proc_smoke/1]).
%% Performs the test at another node.
-export([get_socket_priorities/0,
@@ -52,7 +53,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
--export([start_node/2]).
+-export([dist_cntrlr_output_test/2]).
-export([pinger/1]).
@@ -67,10 +68,11 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap,{minutes,4}}].
+ {timetrap,{minutes,12}}].
all() ->
- [tick, tick_change, nodenames, hostnames, illegal_nodenames,
+ [dist_ctrl_proc_smoke,
+ tick, tick_change, nodenames, hostnames, illegal_nodenames,
connect_node,
hidden_node, setopts,
table_waste, net_setuptime, inet_dist_options_options,
@@ -116,10 +118,12 @@ connect_node(Config) when is_list(Config) ->
ok.
tick(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
+ run_dist_configs(fun tick/2, Config).
+tick(DCfg, _Config) ->
%% First check that the normal case is OK!
- {ok, Node} = start_node(dist_test, "-pa " ++ PaDir),
+ [Name1, Name2] = get_nodenames(2, dist_test),
+ {ok, Node} = start_node(DCfg, Name1),
rpc:call(Node, erl_distribution_SUITE, tick_cli_test, [node()]),
erlang:monitor_node(Node, true),
@@ -143,14 +147,12 @@ tick(Config) when is_list(Config) ->
%% Set the ticktime on the server node to 100 secs so the server
%% node doesn't tick the client node within the interval ...
- {ok, ServNode} = start_node(dist_test_server,
- "-kernel net_ticktime 100 "
- "-pa " ++ PaDir),
+ {ok, ServNode} = start_node(DCfg, Name2,
+ "-kernel net_ticktime 100"),
rpc:call(ServNode, erl_distribution_SUITE, tick_serv_test, [Node, node()]),
- {ok, _} = start_node(dist_test,
- "-kernel net_ticktime 12 "
- "-pa " ++ PaDir),
+ {ok, Node} = start_node(DCfg, Name1,
+ "-kernel net_ticktime 12"),
rpc:call(Node, erl_distribution_SUITE, tick_cli_test, [ServNode]),
spawn_link(erl_distribution_SUITE, keep_conn, [Node]),
@@ -180,6 +182,9 @@ tick(Config) when is_list(Config) ->
%% Checks that pinging nonexistyent nodes does not waste space in distribution table.
table_waste(Config) when is_list(Config) ->
+ run_dist_configs(fun table_waste/2, Config).
+
+table_waste(DCfg, _Config) ->
{ok, HName} = inet:gethostname(),
F = fun(0,_F) -> [];
(N,F) ->
@@ -189,7 +194,7 @@ table_waste(Config) when is_list(Config) ->
F(N-1,F)
end,
F(256,F),
- {ok, N} = start_node(erl_distribution_300,""),
+ {ok, N} = start_node(DCfg, erl_distribution_300),
stop_node(N),
ok.
@@ -200,6 +205,9 @@ nodenames(Config) when is_list(Config) ->
legal("a-1@b"),
legal("a_1@b"),
+ %% Test that giving two -sname works as it should
+ test_node("a_1@b", false, long_or_short() ++ "a_0@b"),
+
illegal("cdé@a"),
illegal("te欢st@a").
@@ -253,8 +261,11 @@ illegal(Name) ->
test_node(Name) ->
test_node(Name, false).
test_node(Name, Illigal) ->
+ test_node(Name, Illigal, "").
+test_node(Name, Illigal, ExtraArgs) ->
ProgName = ct:get_progname(),
- Command = ProgName ++ " -noinput " ++ long_or_short() ++ Name ++
+ Command = ProgName ++ " -noinput " ++ ExtraArgs ++
+ long_or_short() ++ Name ++
" -eval \"net_adm:ping('" ++ atom_to_list(node()) ++ "')\"" ++
case Illigal of
true ->
@@ -295,13 +306,16 @@ gethostname() ->
%% Test that pinging an illegal nodename does not kill the node.
illegal_nodenames(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(erl_distribution_SUITE)),
- {ok, Node}=start_node(illegal_nodenames, "-pa " ++ PaDir),
+ run_dist_configs(fun illegal_nodenames/2, Config).
+
+illegal_nodenames(DCfg, _Config) ->
+ {ok, Node}=start_node(DCfg, illegal_nodenames),
monitor_node(Node, true),
RPid=rpc:call(Node, erlang, spawn,
[?MODULE, pinger, [self()]]),
receive
{RPid, pinged} ->
+ monitor_node(Node, false),
ok;
{nodedown, Node} ->
ct:fail("Remote node died.")
@@ -318,22 +332,25 @@ pinger(Starter) ->
%% Test that you can set the net_setuptime properly.
net_setuptime(Config) when is_list(Config) ->
+ run_dist_configs(fun net_setuptime/2, Config).
+
+net_setuptime(DCfg, _Config) ->
+
%% In this test case, we reluctantly accept shorter times than the given
%% setup time, because the connection attempt can end in a
%% "Host unreachable" error before the timeout fires.
- Res0 = do_test_setuptime("2"),
+ Res0 = do_test_setuptime(DCfg, "2"),
io:format("Res0 = ~p", [Res0]),
true = (Res0 =< 4000),
- Res1 = do_test_setuptime("0.3"),
+ Res1 = do_test_setuptime(DCfg, "0.3"),
io:format("Res1 = ~p", [Res1]),
true = (Res1 =< 500),
ok.
-do_test_setuptime(Setuptime) when is_list(Setuptime) ->
- PaDir = filename:dirname(code:which(?MODULE)),
- {ok, Node} = start_node(dist_setuptime_test, "-pa " ++ PaDir ++
- " -kernel net_setuptime " ++ Setuptime),
+do_test_setuptime(DCfg, Setuptime) when is_list(Setuptime) ->
+ {ok, Node} = start_node(DCfg, dist_setuptime_test,
+ "-kernel net_setuptime " ++ Setuptime),
Res = rpc:call(Node,?MODULE,time_ping,[?DUMMY_NODE]),
stop_node(Node),
Res.
@@ -399,32 +416,36 @@ tick_cli_test1(Node) ->
end.
setopts(Config) when is_list(Config) ->
+ run_dist_configs(fun setopts/2, Config).
+
+setopts(DCfg, _Config) ->
register(setopts_regname, self()),
[N1,N2,N3,N4] = get_nodenames(4, setopts),
- {_N1F,Port1} = start_node_unconnected(N1, ?MODULE, run_remote_test,
+ {_N1F,Port1} = start_node_unconnected(DCfg, N1, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()), "1", "ping"]),
0 = wait_for_port_exit(Port1),
- {_N2F,Port2} = start_node_unconnected(N2, ?MODULE, run_remote_test,
+ {_N2F,Port2} = start_node_unconnected(DCfg, N2, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()), "2", "ping"]),
0 = wait_for_port_exit(Port2),
{ok, LSock} = gen_tcp:listen(0, [{packet,2}, {active,false}]),
{ok, LTcpPort} = inet:port(LSock),
- {N3F,Port3} = start_node_unconnected(N3, ?MODULE, run_remote_test,
+ {N3F,Port3} = start_node_unconnected(DCfg, N3, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()),
"1", integer_to_list(LTcpPort)]),
wait_and_connect(LSock, N3F, Port3),
0 = wait_for_port_exit(Port3),
- {N4F,Port4} = start_node_unconnected(N4, ?MODULE, run_remote_test,
+ {N4F,Port4} = start_node_unconnected(DCfg, N4, ?MODULE, run_remote_test,
["setopts_do", atom_to_list(node()),
"2", integer_to_list(LTcpPort)]),
wait_and_connect(LSock, N4F, Port4),
0 = wait_for_port_exit(Port4),
+ unregister(setopts_regname),
ok.
wait_and_connect(LSock, NodeName, NodePort) ->
@@ -518,9 +539,9 @@ opt_from_nr("2") -> {nodelay, false}.
change_val(true) -> false;
change_val(false) -> true.
-start_node_unconnected(Name, Mod, Func, Args) ->
+start_node_unconnected(DCfg, Name, Mod, Func, Args) ->
FullName = full_node_name(Name),
- CmdLine = mk_node_cmdline(Name,Mod,Func,Args),
+ CmdLine = mk_node_cmdline(DCfg, Name,Mod,Func,Args),
io:format("Starting node ~p: ~s~n", [FullName, CmdLine]),
case open_port({spawn, CmdLine}, [exit_status]) of
Port when is_port(Port) ->
@@ -534,7 +555,7 @@ full_node_name(PreName) ->
atom_to_list(node())),
list_to_atom(atom_to_list(PreName) ++ HostSuffix).
-mk_node_cmdline(Name,Mod,Func,Args) ->
+mk_node_cmdline(DCfg, Name,Mod,Func,Args) ->
Static = "-noinput",
Pa = filename:dirname(code:which(?MODULE)),
Prog = case catch init:get_argument(progname) of
@@ -551,6 +572,7 @@ mk_node_cmdline(Name,Mod,Func,Args) ->
Prog ++ " "
++ Static ++ " "
++ NameSw ++ " " ++ NameStr
+ ++ " " ++ DCfg
++ " -pa " ++ Pa
++ " -env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ NameStr
++ " -setcookie " ++ atom_to_list(erlang:get_cookie())
@@ -560,7 +582,9 @@ mk_node_cmdline(Name,Mod,Func,Args) ->
%% OTP-4255.
tick_change(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(?MODULE)),
+ run_dist_configs(fun tick_change/2, Config).
+
+tick_change(DCfg, _Config) ->
[BN, CN] = get_nodenames(2, tick_change),
DefaultTT = net_kernel:get_net_ticktime(),
unchanged = net_kernel:set_net_ticktime(DefaultTT, 60),
@@ -577,14 +601,13 @@ tick_change(Config) when is_list(Config) ->
end,
wait_until(fun () -> 10 == net_kernel:get_net_ticktime() end),
- {ok, B} = start_node(BN, "-kernel net_ticktime 10 -pa " ++ PaDir),
- {ok, C} = start_node(CN, "-kernel net_ticktime 10 -hidden -pa "
- ++ PaDir),
+ {ok, B} = start_node(DCfg, BN, "-kernel net_ticktime 10"),
+ {ok, C} = start_node(DCfg, CN, "-kernel net_ticktime 10 -hidden"),
OTE = process_flag(trap_exit, true),
case catch begin
- run_tick_change_test(B, C, 10, 1, PaDir),
- run_tick_change_test(B, C, 1, 10, PaDir)
+ run_tick_change_test(DCfg, B, C, 10, 1),
+ run_tick_change_test(DCfg, B, C, 1, 10)
end of
{'EXIT', Reason} ->
stop_node(B),
@@ -626,7 +649,7 @@ wait_for_nodedowns(Tester, Ref) ->
end,
wait_for_nodedowns(Tester, Ref).
-run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
+run_tick_change_test(DCfg, B, C, PrevTT, TT) ->
[DN, EN] = get_nodenames(2, tick_change),
Tester = self(),
@@ -640,8 +663,8 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
wait_for_nodedowns(Tester, Ref)
end,
- {ok, D} = start_node(DN, "-kernel net_ticktime "
- ++ integer_to_list(PrevTT) ++ " -pa " ++ PaDir),
+ {ok, D} = start_node(DCfg, DN, "-kernel net_ticktime "
+ ++ integer_to_list(PrevTT)),
NMA = spawn_link(fun () -> MonitorNodes([B, C, D]) end),
NMB = spawn_link(B, fun () -> MonitorNodes([node(), C, D]) end),
@@ -674,8 +697,8 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
sleep(7),
change_initiated = rpc:call(C,net_kernel,set_net_ticktime,[TT,10]),
- {ok, E} = start_node(EN, "-kernel net_ticktime "
- ++ integer_to_list(TT) ++ " -pa " ++ PaDir),
+ {ok, E} = start_node(DCfg, EN, "-kernel net_ticktime "
+ ++ integer_to_list(TT)),
NME = spawn_link(E, fun () -> MonitorNodes([node(), B, C, D]) end),
NMA2 = spawn_link(fun () -> MonitorNodes([E]) end),
NMB2 = spawn_link(B, fun () -> MonitorNodes([E]) end),
@@ -735,12 +758,13 @@ run_tick_change_test(B, C, PrevTT, TT, PaDir) ->
%%
%% Basic test of hidden node.
hidden_node(Config) when is_list(Config) ->
- PaDir = filename:dirname(code:which(?MODULE)),
- VArgs = "-pa " ++ PaDir,
- HArgs = "-hidden -pa " ++ PaDir,
- {ok, V} = start_node(visible_node, VArgs),
+ run_dist_configs(fun hidden_node/2, Config).
+
+hidden_node(DCfg, _Config) ->
+ HArgs = "-hidden",
+ {ok, V} = start_node(DCfg, visible_node),
VMN = start_monitor_nodes_proc(V),
- {ok, H} = start_node(hidden_node, HArgs),
+ {ok, H} = start_node(DCfg, hidden_node, HArgs),
%% Connect visible_node -> hidden_node
connect_nodes(V, H),
test_nodes(V, H),
@@ -748,9 +772,9 @@ hidden_node(Config) when is_list(Config) ->
sleep(5),
check_monitor_nodes_res(VMN, H),
stop_node(V),
- {ok, H} = start_node(hidden_node, HArgs),
+ {ok, H} = start_node(DCfg, hidden_node, HArgs),
HMN = start_monitor_nodes_proc(H),
- {ok, V} = start_node(visible_node, VArgs),
+ {ok, V} = start_node(DCfg, visible_node),
%% Connect hidden_node -> visible_node
connect_nodes(H, V),
test_nodes(V, H),
@@ -850,9 +874,9 @@ do_inet_dist_options_options(Prio) ->
"-kernel inet_dist_connect_options "++PriorityString++" "
"-kernel inet_dist_listen_options "++PriorityString,
{ok,Node1} =
- start_node(inet_dist_options_1, InetDistOptions),
+ start_node("", inet_dist_options_1, InetDistOptions),
{ok,Node2} =
- start_node(inet_dist_options_2, InetDistOptions),
+ start_node("", inet_dist_options_2, InetDistOptions),
%%
pong =
rpc:call(Node1, net_adm, ping, [Node2]),
@@ -885,6 +909,9 @@ get_socket_priorities() ->
%%
monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_nodedown_reason/2, Config).
+
+monitor_nodes_nodedown_reason(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
@@ -892,10 +919,10 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
Names = get_numbered_nodenames(5, node),
[NN1, NN2, NN3, NN4, NN5] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2),
- {ok, N3} = start_node(NN3),
- {ok, N4} = start_node(NN4, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2),
+ {ok, N3} = start_node(DCfg, NN3),
+ {ok, N4} = start_node(DCfg, NN4, "-hidden"),
receive {nodeup, N1} -> ok end,
receive {nodeup, N2} -> ok end,
@@ -925,7 +952,7 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [nodedown_reason]),
- {ok, N5} = start_node(NN5),
+ {ok, N5} = start_node(DCfg, NN5),
stop_node(N5),
receive {nodeup, N5} -> ok end,
@@ -938,11 +965,14 @@ monitor_nodes_nodedown_reason(Config) when is_list(Config) ->
monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_complex_nodedown_reason/2, Config).
+
+monitor_nodes_complex_nodedown_reason(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
Me = self(),
ok = net_kernel:monitor_nodes(true, [nodedown_reason]),
[Name] = get_nodenames(1, monitor_nodes_complex_nodedown_reason),
- {ok, Node} = start_node(Name, ""),
+ {ok, Node} = start_node(DCfg, Name, ""),
Pid = spawn(Node,
fun() ->
Me ! {stuff,
@@ -981,16 +1011,19 @@ monitor_nodes_complex_nodedown_reason(Config) when is_list(Config) ->
%%
monitor_nodes_node_type(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_node_type/2, Config).
+
+monitor_nodes_node_type(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [{node_type, all}]),
Names = get_numbered_nodenames(9, node),
[NN1, NN2, NN3, NN4, NN5, NN6, NN7, NN8, NN9] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2),
- {ok, N3} = start_node(NN3, "-hidden"),
- {ok, N4} = start_node(NN4, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2),
+ {ok, N3} = start_node(DCfg, NN3, "-hidden"),
+ {ok, N4} = start_node(DCfg, NN4, "-hidden"),
receive {nodeup, N1} -> ok end,
receive {nodeup, N2} -> ok end,
@@ -1014,15 +1047,15 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
receive {nodedown, N4, [{node_type, hidden}]} -> ok end,
ok = net_kernel:monitor_nodes(false, [{node_type, all}]),
- {ok, N5} = start_node(NN5),
+ {ok, N5} = start_node(DCfg, NN5),
receive {nodeup, N5} -> ok end,
stop_node(N5),
receive {nodedown, N5} -> ok end,
ok = net_kernel:monitor_nodes(true, [{node_type, hidden}]),
- {ok, N6} = start_node(NN6),
- {ok, N7} = start_node(NN7, "-hidden"),
+ {ok, N6} = start_node(DCfg, NN6),
+ {ok, N7} = start_node(DCfg, NN7, "-hidden"),
receive {nodeup, N6} -> ok end,
@@ -1037,8 +1070,8 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [{node_type, hidden}]),
ok = net_kernel:monitor_nodes(false),
- {ok, N8} = start_node(NN8),
- {ok, N9} = start_node(NN9, "-hidden"),
+ {ok, N8} = start_node(DCfg, NN8),
+ {ok, N9} = start_node(DCfg, NN9, "-hidden"),
receive {nodeup, N8, [{node_type, visible}]} -> ok end,
stop_node(N8),
@@ -1058,6 +1091,9 @@ monitor_nodes_node_type(Config) when is_list(Config) ->
%%
monitor_nodes_misc(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_misc/2, Config).
+
+monitor_nodes_misc(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
ok = net_kernel:monitor_nodes(true),
ok = net_kernel:monitor_nodes(true, [{node_type, all}, nodedown_reason]),
@@ -1065,8 +1101,8 @@ monitor_nodes_misc(Config) when is_list(Config) ->
Names = get_numbered_nodenames(3, node),
[NN1, NN2, NN3] = Names,
- {ok, N1} = start_node(NN1),
- {ok, N2} = start_node(NN2, "-hidden"),
+ {ok, N1} = start_node(DCfg, NN1),
+ {ok, N2} = start_node(DCfg, NN2, "-hidden"),
receive {nodeup, N1} -> ok end,
@@ -1092,7 +1128,7 @@ monitor_nodes_misc(Config) when is_list(Config) ->
ok = net_kernel:monitor_nodes(false, [{node_type, all}, nodedown_reason]),
- {ok, N3} = start_node(NN3),
+ {ok, N3} = start_node(DCfg, NN3),
receive {nodeup, N3} -> ok end,
stop_node(N3),
receive {nodedown, N3} -> ok end,
@@ -1107,15 +1143,18 @@ monitor_nodes_misc(Config) when is_list(Config) ->
%% messages from Node and that {nodedown, Node} messages are
%% received after messages from Node.
monitor_nodes_otp_6481(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_otp_6481/2, Config).
+
+monitor_nodes_otp_6481(DCfg, Config) ->
io:format("Testing nodedown...~n"),
- monitor_nodes_otp_6481_test(Config, nodedown),
+ monitor_nodes_otp_6481_test(DCfg, Config, nodedown),
io:format("ok~n"),
io:format("Testing nodeup...~n"),
- monitor_nodes_otp_6481_test(Config, nodeup),
+ monitor_nodes_otp_6481_test(DCfg, Config, nodeup),
io:format("ok~n"),
ok.
-monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
+monitor_nodes_otp_6481_test(DCfg, Config, TestType) when is_list(Config) ->
MonNodeState = monitor_node_state(),
NodeMsg = make_ref(),
Me = self(),
@@ -1164,7 +1203,7 @@ monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
end
++ MonNodeState,
- {ok, Node} = start_node(Name, "", this),
+ {ok, Node} = start_node(DCfg, Name, "", this),
receive {nodeup, Node} -> ok end,
RemotePid = spawn(Node,
@@ -1249,17 +1288,20 @@ monitor_nodes_errors(Config) when is_list(Config) ->
ok.
monitor_nodes_combinations(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_combinations/2, Config).
+
+monitor_nodes_combinations(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
monitor_nodes_all_comb(true),
[VisibleName, HiddenName] = get_nodenames(2,
monitor_nodes_combinations),
- {ok, Visible} = start_node(VisibleName, ""),
+ {ok, Visible} = start_node(DCfg, VisibleName, ""),
receive_all_comb_nodeup_msgs(visible, Visible),
no_msgs(),
stop_node(Visible),
receive_all_comb_nodedown_msgs(visible, Visible, connection_closed),
no_msgs(),
- {ok, Hidden} = start_node(HiddenName, "-hidden"),
+ {ok, Hidden} = start_node(DCfg, HiddenName, "-hidden"),
receive_all_comb_nodeup_msgs(hidden, Hidden),
no_msgs(),
stop_node(Hidden),
@@ -1395,6 +1437,9 @@ monitor_nodes_cleanup(Config) when is_list(Config) ->
ok.
monitor_nodes_many(Config) when is_list(Config) ->
+ run_dist_configs(fun monitor_nodes_many/2, Config).
+
+monitor_nodes_many(DCfg, _Config) ->
MonNodeState = monitor_node_state(),
[Name] = get_nodenames(1, monitor_nodes_many),
%% We want to perform more than 2^16 net_kernel:monitor_nodes
@@ -1402,7 +1447,7 @@ monitor_nodes_many(Config) when is_list(Config) ->
No = (1 bsl 16) + 17,
repeat(fun () -> ok = net_kernel:monitor_nodes(true) end, No),
No = length(monitor_node_state()) - length(MonNodeState),
- {ok, Node} = start_node(Name),
+ {ok, Node} = start_node(DCfg, Name),
repeat(fun () -> receive {nodeup, Node} -> ok end end, No),
stop_node(Node),
repeat(fun () -> receive {nodedown, Node} -> ok end end, No),
@@ -1411,8 +1456,118 @@ monitor_nodes_many(Config) when is_list(Config) ->
MonNodeState = monitor_node_state(),
ok.
+dist_ctrl_proc_smoke(Config) when is_list(Config) ->
+ ThisNode = node(),
+ [Name1, Name2] = get_nodenames(2, dist_ctrl_proc_example_smoke),
+ GetSizeArg = " -gen_tcp_dist_output_loop "
+ ++ atom_to_list(?MODULE) ++ " "
+ ++ "dist_cntrlr_output_test",
+ {ok, Node1} = start_node("", Name1, "-proto_dist gen_tcp"),
+ {ok, Node2} = start_node("", Name2, "-proto_dist gen_tcp" ++ GetSizeArg),
+ pong = rpc:call(Node1, net_adm, ping, [Node2]),
+ NL1 = lists:sort([ThisNode, Node2]),
+ NL2 = lists:sort([ThisNode, Node1]),
+ NL1 = lists:sort(rpc:call(Node1, erlang, nodes, [])),
+ NL2 = lists:sort(rpc:call(Node2, erlang, nodes, [])),
+
+ %% Verify that we actually are executing the distribution
+ %% module we expect and also massage message passing over
+ %% it a bit...
+ Ps1 = rpc:call(Node1, erlang, processes, []),
+ try
+ lists:foreach(
+ fun (P) ->
+ case rpc:call(Node1, erlang, process_info, [P, current_stacktrace]) of
+ undefined ->
+ ok;
+ {current_stacktrace, StkTrace} ->
+ lists:foreach(fun ({gen_tcp_dist,
+ dist_cntrlr_output_loop,
+ 2, _}) ->
+ io:format("~p ~p~n", [P, StkTrace]),
+ throw(found_it);
+ (_) ->
+ ok
+ end, StkTrace)
+ end
+ end, Ps1),
+ exit({missing, dist_cntrlr_output_loop})
+ catch
+ throw:found_it -> ok
+ end,
+
+ Ps2 = rpc:call(Node2, erlang, processes, []),
+ try
+ lists:foreach(
+ fun (P) ->
+ case rpc:call(Node2, erlang, process_info, [P, current_stacktrace]) of
+ undefined ->
+ ok;
+ {current_stacktrace, StkTrace} ->
+ lists:foreach(fun ({erl_distribution_SUITE,
+ dist_cntrlr_output_loop,
+ 2, _}) ->
+ io:format("~p ~p~n", [P, StkTrace]),
+ throw(found_it);
+ (_) ->
+ ok
+ end, StkTrace)
+ end
+ end, Ps2),
+ exit({missing, dist_cntrlr_output_loop})
+ catch
+ throw:found_it -> ok
+ end,
+
+ stop_node(Node1),
+ stop_node(Node2),
+ ok.
+
%% Misc. functions
+run_dist_configs(Func, Config) ->
+ GetSizeArg = " -gen_tcp_dist_output_loop "
+ ++ atom_to_list(?MODULE) ++ " "
+ ++ "dist_cntrlr_output_test",
+ lists:map(fun ({DCfgName, DCfg}) ->
+ io:format("~n~n=== Running ~s configuration ===~n~n",
+ [DCfgName]),
+ Func(DCfg, Config)
+ end,
+ [{"default", ""},
+ {"gen_tcp_dist", "-proto_dist gen_tcp"},
+ {"gen_tcp_dist (get_size)", "-proto_dist gen_tcp" ++ GetSizeArg}]).
+
+dist_cntrlr_output_test(DHandle, Socket) ->
+ false = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ false = erlang:dist_ctrl_set_opt(DHandle, get_size, true),
+ true = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ true = erlang:dist_ctrl_set_opt(DHandle, get_size, false),
+ false = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ false = erlang:dist_ctrl_set_opt(DHandle, get_size, true),
+ true = erlang:dist_ctrl_get_opt(DHandle, get_size),
+ dist_cntrlr_output_loop(DHandle, Socket).
+
+dist_cntrlr_send_data(DHandle, Socket) ->
+ case erlang:dist_ctrl_get_data(DHandle) of
+ none ->
+ erlang:dist_ctrl_get_data_notification(DHandle);
+ {Size, Data} ->
+ Size = erlang:iolist_size(Data),
+ ok = gen_tcp:send(Socket, Data),
+ dist_cntrlr_send_data(DHandle, Socket)
+ end.
+
+dist_cntrlr_output_loop(DHandle, Socket) ->
+ receive
+ dist_data ->
+ %% Outgoing data from this node...
+ dist_cntrlr_send_data(DHandle, Socket);
+ _ ->
+ ok %% Drop garbage message...
+ end,
+ dist_cntrlr_output_loop(DHandle, Socket).
+
monitor_node_state() ->
erts_debug:set_internal_state(available_internal_state, true),
MonitoringNodes = erts_debug:get_internal_state(monitoring_nodes),
@@ -1438,25 +1593,25 @@ print_my_messages() ->
sleep(T) -> receive after T * 1000 -> ok end.
-start_node(Name, Param, this) ->
+start_node(DCfg, Name, Param, this) ->
NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, "this") ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, "this") ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [this]}]);
-start_node(Name, Param, Rel) when is_atom(Rel) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, Rel) when is_atom(Rel) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [{release, atom_to_list(Rel)}]}]);
-start_node(Name, Param, Rel) when is_list(Rel) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param, Rel) when is_list(Rel) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, peer, [{args, NewParam}, {erl, [{release, Rel}]}]).
-start_node(Name, Param) ->
- NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)),
+start_node(DCfg, Name, Param) ->
+ NewParam = Param ++ " -pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++ DCfg,
test_server:start_node(Name, slave, [{args, NewParam}]).
-start_node(Name) ->
- start_node(Name, "").
+start_node(DCfg, Name) ->
+ start_node(DCfg, Name, "").
stop_node(Node) ->
test_server:stop_node(Node).
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index a51025cba6..3bc8e6e828 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -2191,6 +2191,9 @@ unc_paths(Config) when is_list(Config) ->
{ok, _} = file:read_file_info("C:\\Windows\\explorer.exe"),
{ok, _} = file:read_file_info("\\\\localhost\\c$\\Windows\\explorer.exe"),
+ {ok, Files} = file:list_dir("C:\\Windows\\"),
+ {ok, Files} = file:list_dir("\\\\localhost\\c$\\Windows\\"),
+
{ok, Cwd} = file:get_cwd(),
try
@@ -3741,19 +3744,33 @@ otp_10852(Config) when is_list(Config) ->
ok = rpc_call(Node, read_file, [B]),
ok = rpc_call(Node, make_link, [B,B]),
case rpc_call(Node, make_symlink, [B,B]) of
- ok -> ok;
- {error, E} when (E =:= enotsup) or (E =:= eperm) ->
- {win32,_} = os:type()
+ {error, eilseq} ->
+ %% Some versions of OS X refuse to create files with illegal names.
+ {unix,darwin} = os:type();
+ {error, eperm} ->
+ %% The test user might not have permission to create symlinks.
+ {win32,_} = os:type();
+ ok ->
+ ok
end,
ok = rpc_call(Node, delete, [B]),
- ok = rpc_call(Node, make_dir, [B]),
+ case rpc_call(Node, make_dir, [B]) of
+ {error, eilseq} ->
+ {unix,darwin} = os:type();
+ ok ->
+ ok
+ end,
ok = rpc_call(Node, del_dir, [B]),
- ok = rpc_call(Node, write_file, [B,B]),
- {ok, Fd} = rpc_call(Node, open, [B,[read]]),
- ok = rpc_call(Node, close, [Fd]),
- {ok,0} = rpc_call(Node, copy, [B,B]),
- {ok, Fd2, B} = rpc_call(Node, path_open, [["."], B, [read]]),
- ok = rpc_call(Node, close, [Fd2]),
+ case rpc_call(Node, write_file, [B,B]) of
+ {error, eilseq} ->
+ {unix,darwin} = os:type();
+ ok ->
+ {ok, Fd} = rpc_call(Node, open, [B,[read]]),
+ ok = rpc_call(Node, close, [Fd]),
+ {ok,0} = rpc_call(Node, copy, [B,B]),
+ {ok, Fd2, B} = rpc_call(Node, path_open, [["."], B, [read]]),
+ ok = rpc_call(Node, close, [Fd2])
+ end,
true = test_server:stop_node(Node),
ok.
@@ -4497,15 +4514,18 @@ run_large_file_test(Config, Run, Name) ->
{{unix,sunos},OsVersion} when OsVersion < {5,5,1} ->
{skip,"Only supported on Win32, Unix or SunOS >= 5.5.1"};
{{unix,_},_} ->
- N = disc_free(proplists:get_value(priv_dir, Config)),
- io:format("Free disk: ~w KByte~n", [N]),
- if N < 5 * (1 bsl 20) ->
- %% Less than 5 GByte free
- {skip,"Less than 5 GByte free"};
- true ->
- do_run_large_file_test(Config, Run, Name)
- end;
- _ ->
+ case disc_free(proplists:get_value(priv_dir, Config)) of
+ error ->
+ {skip, "Failed to query disk space for priv_dir. "
+ "Is it on a remote file system?~n"};
+ N when N >= 5 * (1 bsl 20) ->
+ ct:pal("Free disk: ~w KByte~n", [N]),
+ do_run_large_file_test(Config, Run, Name);
+ N when N < 5 * (1 bsl 20) ->
+ ct:pal("Free disk: ~w KByte~n", [N]),
+ {skip,"Less than 5 GByte free"}
+ end;
+ _ ->
{skip,"Only supported on Win32, Unix or SunOS >= 5.5.1"}
end.
@@ -4539,12 +4559,18 @@ do_run_large_file_test(Config, Run, Name0) ->
disc_free(Path) ->
Data = disksup:get_disk_data(),
- {_,Tot,Perc} = hd(lists:filter(
- fun({P,_Size,_Full}) ->
- lists:prefix(filename:nativename(P),
- filename:nativename(Path))
- end, lists:reverse(lists:sort(Data)))),
- round(Tot * (1-(Perc/100))).
+
+ %% What partitions could Data be mounted on?
+ Partitions =
+ [D || {P, _Tot, _Perc}=D <- Data,
+ lists:prefix(filename:nativename(P), filename:nativename(Path))],
+
+ %% Sorting in descending order places the partition with the most specific
+ %% path first.
+ case lists:sort(fun erlang:'>='/2, Partitions) of
+ [{_,Tot, Perc} | _] -> round(Tot * (1-(Perc/100)));
+ [] -> error
+ end.
memsize() ->
{Tot,_Used,_} = memsup:get_memory_data(),
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 3afc647081..26cfd187c7 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -632,10 +632,13 @@ make_icky_dir(Mod, IckyDirName) ->
hopeless_darwin() ->
case {os:type(),os:version()} of
- {{unix,darwin},{Major,_,_}} when Major < 9 ->
- true;
- _ ->
- false
+ {{unix,darwin},{Major,_,_}} ->
+ %% icky file names worked between 10 and 17, but started returning
+ %% EILSEQ in 18. The check against 18 is exact in case newer
+ %% versions of Darwin support them again.
+ Major < 9 orelse Major =:= 18;
+ _ ->
+ false
end.
make_very_icky_dir(Mod, DirName) ->
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index a0ae792ba9..e4c489bd10 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1459,11 +1459,11 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo) ->
do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun).
%%
do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
- ServerFamily = get_family_by_addrs(ServerAddresses),
+ {ServerFamily, ServerOpts} = get_family_by_addrs(ServerAddresses),
io:format("Serving ~p addresses: ~p~n",
[ServerFamily, ServerAddresses]),
S1 = ok(gen_sctp:open(0, [{ip,Addr} || Addr <- ServerAddresses] ++
- [ServerFamily])),
+ [ServerFamily|ServerOpts])),
ok = gen_sctp:listen(S1, true),
P1 = ok(inet:port(S1)),
ClientFamily = get_family_by_addr(AddressToConnectTo),
@@ -1493,9 +1493,9 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
%% If at least one of the addresses is an ipv6 address, return inet6, else inet.
get_family_by_addrs(Addresses) ->
case lists:usort([get_family_by_addr(Addr) || Addr <- Addresses]) of
- [inet, inet6] -> inet6;
- [inet] -> inet;
- [inet6] -> inet6
+ [inet, inet6] -> {inet6, [{ipv6_v6only, false}]};
+ [inet] -> {inet, []};
+ [inet6] -> {inet6, []}
end.
get_family_by_addr(Addr) when tuple_size(Addr) =:= 4 -> inet;
diff --git a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
index b91dca61d4..96938f9071 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
+++ b/lib/kernel/test/gen_tcp_api_SUITE_data/gen_tcp_api_SUITE.c
@@ -30,6 +30,7 @@
#define sock_close(s) closesocket(s)
#else
#include <sys/socket.h>
+#include <unistd.h>
#define sock_close(s) close(s)
#endif
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index 1ff30012e1..421510f9d6 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -25,6 +25,7 @@
init_per_group/2,end_per_group/2,
controlling_process/1, controlling_process_self/1,
no_accept/1, close_with_pending_output/1, active_n/1,
+ active_n_closed/1,
data_before_close/1,
iter_max_socks/0, iter_max_socks/1,
get_status/1,
@@ -74,7 +75,7 @@ suite() ->
all() ->
[controlling_process, controlling_process_self, no_accept,
close_with_pending_output, data_before_close,
- iter_max_socks, passive_sockets, active_n,
+ iter_max_socks, passive_sockets, active_n, active_n_closed,
accept_closed_by_other_process, otp_3924, closed_socket,
shutdown_active, shutdown_passive, shutdown_pending,
show_econnreset_active, show_econnreset_active_once,
@@ -2123,8 +2124,39 @@ test_pktoptions(Family, Spec, CheckConnect, OSType, OSVer) ->
%%% {ok,<<"hi">>} = gen_tcp:recv(S1, 2, Timeout),
%%
%% Verify returned remote options
- {ok,[{pktoptions,OptsVals1}]} = inet:getopts(S1, [pktoptions]),
- {ok,[{pktoptions,OptsVals2}]} = inet:getopts(S2, [pktoptions]),
+ VerifyRemOpts =
+ fun(S, Role) ->
+ case inet:getopts(S, [pktoptions]) of
+ {ok, [{pktoptions, PktOpts1}]} ->
+ PktOpts1;
+ {ok, UnexpOK1} ->
+ io:format("Unexpected OK (~w): "
+ "~n ~p"
+ "~n", [Role, UnexpOK1]),
+ exit({unexpected_getopts_ok,
+ Role,
+ Spec,
+ TrueRecvOpts,
+ OptsVals,
+ OptsValsDefault,
+ UnexpOK1});
+ {error, UnexpERR1} ->
+ io:format("Unexpected ERROR (~w): "
+ "~n ~p"
+ "~n", [Role, UnexpERR1]),
+ exit({unexpected_getopts_failure,
+ Role,
+ Spec,
+ TrueRecvOpts,
+ OptsVals,
+ OptsValsDefault,
+ UnexpERR1})
+ end
+ end,
+ OptsVals1 = VerifyRemOpts(S1, dest),
+ OptsVals2 = VerifyRemOpts(S2, orig),
+ %% {ok,[{pktoptions,OptsVals1}]} = inet:getopts(S1, [pktoptions]),
+ %% {ok,[{pktoptions,OptsVals2}]} = inet:getopts(S2, [pktoptions]),
(Result1 = sets_eq(OptsVals1, OptsVals))
orelse io:format(
"Accept differs: ~p neq ~p~n", [OptsVals1,OptsVals]),
@@ -2588,7 +2620,51 @@ active_once_closed(Config) when is_list(Config) ->
ok = inet:setopts(A,[{active,once}]),
ok = receive {tcp_closed, A} -> ok after 1000 -> error end
end)().
-
+
+%% Check that active n and tcp_close messages behave as expected.
+active_n_closed(Config) when is_list(Config) ->
+ {ok, L} = gen_tcp:listen(0, [binary, {active, false}]),
+
+ P = self(),
+
+ {ok,Port} = inet:port(L),
+
+ spawn_link(fun() ->
+ Payload = <<0:50000/unit:8>>,
+ Cnt = 10000,
+ P ! {size,Cnt * byte_size(Payload)},
+ {ok, S} = gen_tcp:connect("localhost", Port, [binary, {active, false}]),
+ _ = [gen_tcp:send(S, Payload) || _ <- lists:seq(1, Cnt)],
+ gen_tcp:close(S)
+ end),
+
+ receive {size,SendSize} -> SendSize end,
+ {ok, S} = gen_tcp:accept(L),
+ inet:setopts(S, [{active, 10}]),
+ RecvSize =
+ (fun Server(Size) ->
+ receive
+ {tcp, S, Bin} ->
+ Server(byte_size(Bin) + Size);
+ {tcp_closed, S} ->
+ Size;
+ {tcp_passive, S} ->
+ inet:setopts(S, [{active, 10}]),
+ Server(Size);
+ Msg ->
+ io:format("~p~n", [Msg]),
+ Server(Size)
+ end
+ end)(0),
+
+ gen_tcp:close(L),
+
+ if SendSize =:= RecvSize ->
+ ok;
+ true ->
+ ct:fail("Send and Recv size not equal: ~p ~p",[SendSize, RecvSize])
+ end.
+
%% Test the send_timeout socket option.
send_timeout(Config) when is_list(Config) ->
Dir = filename:dirname(code:which(?MODULE)),
@@ -3467,7 +3543,7 @@ wait(Mref) ->
%% OTP-15536
%% Test that send error works correctly for delay_send
-delay_send_error(Config) ->
+delay_send_error(_Config) ->
{ok, LS} = gen_tcp:listen(0, [{reuseaddr, true}, {packet, 1}, {active, false}]),
{ok,{{0,0,0,0},PortNum}}=inet:sockname(LS),
P = spawn_link(
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index 5a2d809aa4..44ec7e7076 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -98,7 +98,7 @@ end_per_group(_GroupName, Config) ->
init_per_testcase(lookup_bad_search_option, Config) ->
Db = inet_db,
Key = res_lookup,
- %% The bad option can not enter through inet_db:set_lookup/1,
+ %% The bad option cannot enter through inet_db:set_lookup/1,
%% but through e.g .inetrc.
Prev = ets:lookup(Db, Key),
ets:delete(Db, Key),
diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index df6e48abae..6b545fa414 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -46,15 +46,16 @@
%% a temporary local nameserver BIND 8 or 9 that must be installed
%% on your machine.
%%
-%% For example, on Ubuntu 14.04, as root:
+%% For example, on Ubuntu 16.04 / 18.04, as root:
%% apt-get install bind9
%% Now, that is not enough since Apparmor will not allow
%% the nameserver daemon /usr/sbin/named to read from the test directory.
%% Assuming that you run tests in /ldisk/daily_build, and still on
-%% Ubuntu 14.04, make /usr/apparmor.d/local/usr.sbin.named contain:
+%% Ubuntu 14.04, make /etc/apparmor.d/local/usr.sbin.named contain:
%% /ldisk/daily_build/** r,
%% And yes; the trailing comma must be there...
-
+%% And yes; create the file if it does not exist.
+%% And yes; restart the apparmor daemon using "service apparmor restart"
suite() ->
@@ -531,7 +532,7 @@ edns0(Config) when is_list(Config) ->
case os:version() of
{M,V,_} when M < 5; M == 5, V =< 8 ->
%% In our test park only known platform
- %% with an DNS resolver that can not do
+ %% with an DNS resolver that cannot do
%% EDNS0.
{comment,"No EDNS0"}
end
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index 4f90260f98..a0154b2694 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -459,7 +459,7 @@ find_system_procs([], SysProcs) ->
SysProcs#sys_procs.prim_file];
find_system_procs([P|Ps], SysProcs) ->
case process_info(P, [initial_call, priority]) of
- [{initial_call,{otp_ring0,start,2}},_] ->
+ [{initial_call,{erl_init,start,2}},_] ->
undefined = SysProcs#sys_procs.init,
find_system_procs(Ps, SysProcs#sys_procs{init = P});
[{initial_call,{erts_code_purger,start,0}},_] ->
diff --git a/lib/kernel/test/kernel_config_SUITE.erl b/lib/kernel/test/kernel_config_SUITE.erl
index 9207025a2c..57c44c2498 100644
--- a/lib/kernel/test/kernel_config_SUITE.erl
+++ b/lib/kernel/test/kernel_config_SUITE.erl
@@ -21,7 +21,8 @@
-include_lib("common_test/include/ct.hrl").
--export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, sync/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ start_distribution_false/1, sync/1]).
-export([init_per_suite/1, end_per_suite/1]).
@@ -30,7 +31,7 @@ suite() ->
{timetrap,{minutes,2}}].
all() ->
- [sync].
+ [sync, start_distribution_false].
groups() ->
[].
@@ -59,12 +60,9 @@ from(H, [H | T]) -> T;
from(H, [_ | T]) -> from(H, T);
from(_, []) -> [].
-%%-----------------------------------------------------------------
-%% Test suite for sync_nodes. This is quite tricky.
-%%
+%% Test sync_nodes. This is quite tricky.
%% Should be started in a CC view with:
%% erl -sname XXX where XX not in [cp1, cp2]
-%%-----------------------------------------------------------------
sync(Conf) when is_list(Conf) ->
%% Write a config file
Dir = proplists:get_value(priv_dir,Conf),
@@ -106,9 +104,18 @@ wait_for_node(Node) ->
_Other -> wait_for_node(Node)
end.
-
stop_node(Node) ->
M = list_to_atom(lists:concat([Node,
[$@],
from($@,atom_to_list(node()))])),
rpc:cast(M, erlang, halt, []).
+
+start_distribution_false(Config) when is_list(Config) ->
+ %% When distribution is disabled, -sname/-name has no effect
+ Str = os:cmd(ct:get_progname()
+ ++ " -kernel start_distribution false"
+ ++ " -sname no_distribution"
+ ++ " -eval \"erlang:display(node())\""
+ ++ " -noshell -s erlang halt"),
+ "'nonode@nohost'" ++ _ = Str,
+ ok.
diff --git a/lib/kernel/test/logger_disk_log_h_SUITE.erl b/lib/kernel/test/logger_disk_log_h_SUITE.erl
index 9bbec42de8..36d98eaa25 100644
--- a/lib/kernel/test/logger_disk_log_h_SUITE.erl
+++ b/lib/kernel/test/logger_disk_log_h_SUITE.erl
@@ -293,7 +293,7 @@ logging(Config) ->
ok = start_and_add(Name, #{filter_default=>log,
formatter=>{?MODULE,self()}},
#{file => LogFile}),
- MsgFormatter = fun(Term) -> {io_lib:format("Term:~p",[Term]),[]} end,
+ MsgFormatter = fun(Term) -> {"Term:~p",[Term]} end,
logger:notice([{x,y}], #{report_cb => MsgFormatter}),
logger:notice([{x,y}], #{}),
ct:pal("Checking contents of ~p", [?log_no(LogFile,1)]),
@@ -1243,12 +1243,12 @@ restart_after(Config) ->
{Log,HConfig,DLHConfig} = start_handler(?MODULE, ?FUNCTION_NAME, Config),
NewHConfig1 =
HConfig#{config=>DLHConfig#{overload_kill_enable=>true,
- overload_kill_qlen=>10,
+ overload_kill_qlen=>4,
overload_kill_restart_after=>infinity}},
ok = logger:update_handler_config(?MODULE, NewHConfig1),
MRef1 = erlang:monitor(process, whereis(h_proc_name())),
%% kill handler
- send_burst({n,100}, {spawn,4,0}, {chars,79}, notice),
+ send_burst({n,100}, {spawn,5,0}, {chars,79}, notice),
receive
{'DOWN', MRef1, _, _, _Reason1} ->
file_delete(Log),
@@ -1265,13 +1265,13 @@ restart_after(Config) ->
RestartAfter = ?OVERLOAD_KILL_RESTART_AFTER,
NewHConfig2 =
HConfig#{config=>DLHConfig#{overload_kill_enable=>true,
- overload_kill_qlen=>10,
+ overload_kill_qlen=>4,
overload_kill_restart_after=>RestartAfter}},
ok = logger:update_handler_config(?MODULE, NewHConfig2),
Pid0 = whereis(h_proc_name()),
MRef2 = erlang:monitor(process, Pid0),
%% kill handler
- send_burst({n,100}, {spawn,4,0}, {chars,79}, notice),
+ send_burst({n,100}, {spawn,5,0}, {chars,79}, notice),
receive
{'DOWN', MRef2, _, _, _Reason2} ->
file_delete(Log),
diff --git a/lib/kernel/test/logger_std_h_SUITE.erl b/lib/kernel/test/logger_std_h_SUITE.erl
index 0c5516f82b..2b2d509860 100644
--- a/lib/kernel/test/logger_std_h_SUITE.erl
+++ b/lib/kernel/test/logger_std_h_SUITE.erl
@@ -71,6 +71,14 @@ init_per_group(_Group, Config) ->
end_per_group(_Group, _Config) ->
ok.
+init_per_testcase(reopen_changed_log=TC, Config) ->
+ case os:type() of
+ {win32,_} ->
+ {skip,"This test can only work with inodes, i.e. not on Windows"};
+ _ ->
+ ct:print("********** ~w **********", [TC]),
+ Config
+ end;
init_per_testcase(TestHooksCase, Config) when
TestHooksCase == write_failure;
TestHooksCase == sync_failure ->
@@ -124,6 +132,7 @@ all() ->
bad_input,
reconfig,
file_opts,
+ relative_file_path,
sync,
write_failure,
sync_failure,
@@ -685,6 +694,54 @@ file_opts(Config) ->
file_opts(cleanup, _Config) ->
logger:remove_handler(?MODULE).
+relative_file_path(_Config) ->
+ {ok,Dir} = file:get_cwd(),
+ AbsName1 = filename:join(Dir,?MODULE),
+ ok = logger:add_handler(?MODULE,
+ logger_std_h,
+ #{config => #{type=>file},
+ filter_default=>log,
+ filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]),
+ formatter=>{?MODULE,self()}}),
+ #{cb_state := #{handler_state := #{file:=AbsName1}}} =
+ logger_olp:info(h_proc_name()),
+ {ok,#{config := #{file:=AbsName1}}} =
+ logger:get_handler_config(?MODULE),
+ ok = logger:remove_handler(?MODULE),
+
+ RelName2 = filename:join(atom_to_list(?FUNCTION_NAME),
+ lists:concat([?FUNCTION_NAME,".log"])),
+ AbsName2 = filename:join(Dir,RelName2),
+ ok = logger:add_handler(?MODULE,
+ logger_std_h,
+ #{config => #{file => RelName2},
+ filter_default=>log,
+ filters=>?DEFAULT_HANDLER_FILTERS([?MODULE]),
+ formatter=>{?MODULE,self()}}),
+ #{cb_state := #{handler_state := #{file:=AbsName2}}} =
+ logger_olp:info(h_proc_name()),
+ {ok,#{config := #{file:=AbsName2}}} =
+ logger:get_handler_config(?MODULE),
+ logger:notice(M1=?msg,?domain),
+ ?check(M1),
+ B1 = ?bin(M1),
+ try_read_file(AbsName2, {ok,B1}, filesync_rep_int()),
+
+ ok = file:set_cwd(".."),
+ logger:notice(M2=?msg,?domain),
+ ?check(M2),
+ B20 = ?bin(M2),
+ B2 = <<B1/binary,B20/binary>>,
+ try_read_file(AbsName2, {ok,B2}, filesync_rep_int()),
+
+ {error,_} = logger:update_handler_config(?MODULE,config,#{file=>RelName2}),
+ ok = logger:update_handler_config(?MODULE,config,#{file=>AbsName2}),
+ ok = file:set_cwd(Dir),
+ ok = logger:update_handler_config(?MODULE,config,#{file=>RelName2}),
+ ok.
+relative_file_path(cleanup,_Config) ->
+ logger:remove_handler(?MODULE).
+
sync(Config) ->
Dir = ?config(priv_dir,Config),
diff --git a/lib/kernel/test/seq_trace_SUITE.erl b/lib/kernel/test/seq_trace_SUITE.erl
index 07a46ac51e..83a94ab087 100644
--- a/lib/kernel/test/seq_trace_SUITE.erl
+++ b/lib/kernel/test/seq_trace_SUITE.erl
@@ -19,6 +19,9 @@
%%
-module(seq_trace_SUITE).
+%% label_capability_mismatch needs to run a part of the test on an OTP 20 node.
+-compile(r20).
+
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2]).
@@ -362,7 +365,7 @@ do_incompatible_labels(Rel) ->
Mdir = filename:dirname(Dir),
true = rpc:call(Node,code,add_patha,[Mdir]),
seq_trace:reset_trace(),
- rpc:call(Node,?MODULE,start_tracer,[]),
+ true = is_pid(rpc:call(Node,?MODULE,start_tracer,[])),
Receiver = spawn(Node,?MODULE,one_time_receiver,[]),
%% This node does not support arbitrary labels, so it must fail with a
@@ -389,7 +392,7 @@ do_compatible_labels(Rel) ->
Mdir = filename:dirname(Dir),
true = rpc:call(Node,code,add_patha,[Mdir]),
seq_trace:reset_trace(),
- rpc:call(Node,?MODULE,start_tracer,[]),
+ true = is_pid(rpc:call(Node,?MODULE,start_tracer,[])),
Receiver = spawn(Node,?MODULE,one_time_receiver,[]),
%% This node does not support arbitrary labels, but small integers should