summaryrefslogtreecommitdiff
path: root/lib/kernel/test/socket_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/test/socket_SUITE.erl')
-rw-r--r--lib/kernel/test/socket_SUITE.erl2311
1 files changed, 1718 insertions, 593 deletions
diff --git a/lib/kernel/test/socket_SUITE.erl b/lib/kernel/test/socket_SUITE.erl
index 673c905ddf..196af34521 100644
--- a/lib/kernel/test/socket_SUITE.erl
+++ b/lib/kernel/test/socket_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2022. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2023. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -67,6 +67,15 @@
%%
%% Run a specific test case:
%% ts:run(emulator, socket_SUITE, foo, [batch]).
+%%
+%% S = fun() -> ts:run(kernel, socket_SUITE, [batch]) end.
+%% S = fun() -> ct:run_test([{suite, socket_SUITE}]) end.
+%% G = fun(GROUP) -> ts:run(kernel, socket_SUITE, {group, GROUP}, [batch]) end.
+%% G = fun(GROUP) -> ct:run_test([{suite, socket_SUITE}, {group, GROUP}]) end.
+%% T = fun(TC) -> ts:run(kernel, socket_SUITE, TC, [batch]) end.
+%% T = fun(TC) -> ct:run_test([{suite, socket_SUITE}, {testcase, TC}]) end.
+
+
-module(socket_SUITE).
@@ -89,6 +98,10 @@
api_m_error_bind/1,
%% *** API Basic ***
+ api_b_simple_open_and_close_udp4/1,
+ api_b_simple_open_and_close_udp6/1,
+ api_b_simple_open_and_close_tcp4/1,
+ api_b_simple_open_and_close_tcp6/1,
api_b_open_and_info_udp4/1,
api_b_open_and_info_udp6/1,
api_b_open_and_info_tcp4/1,
@@ -731,8 +744,11 @@
-define(TPP_LARGE_NUM, 50).
-define(TPP_NUM(Config, Base), (Base) div lookup(kernel_factor, 1, Config)).
+-define(WINDOWS, {win32,nt}).
+
-define(TTEST_RUNTIME, ?SECS(1)).
-define(TTEST_MIN_FACTOR, 3).
+-define(TTEST_MIN_FACTOR_WIN, ?TTEST_MIN_FACTOR-1).
-define(TTEST_DEFAULT_SMALL_MAX_OUTSTANDING, 50).
-define(TTEST_DEFAULT_MEDIUM_MAX_OUTSTANDING,
?TTEST_MK_DEFAULT_MAX_OUTSTANDING(
@@ -918,6 +934,10 @@ api_misc_cases() ->
api_basic_cases() ->
[
+ api_b_simple_open_and_close_udp4,
+ api_b_simple_open_and_close_udp6,
+ api_b_simple_open_and_close_tcp4,
+ api_b_simple_open_and_close_tcp6,
api_b_open_and_info_udp4,
api_b_open_and_info_udp6,
api_b_open_and_info_tcp4,
@@ -1387,7 +1407,12 @@ traffic_pp_sendmsg_recvmsg_cases() ->
%% No point in running these cases unless the machine is
%% reasonably fast.
ttest_condition(Config) ->
+ OsType = os:type(),
case ?config(kernel_factor, Config) of
+ Factor when (OsType =:= ?WINDOWS) andalso
+ is_integer(Factor) andalso
+ (Factor =< ?TTEST_MIN_FACTOR_WIN) ->
+ ok;
Factor when is_integer(Factor) andalso (Factor =< ?TTEST_MIN_FACTOR) ->
ok;
Factor when is_integer(Factor) ->
@@ -2581,6 +2606,100 @@ api_m_error_bind(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically open (create) and then close.
+api_b_simple_open_and_close_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ InitState = #{domain => inet,
+ type => dgram,
+ protocol => udp},
+ ok = api_b_simple_open_and_close(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically open (create) and then close.
+api_b_simple_open_and_close_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(?FUNCTION_NAME,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ type => dgram,
+ protocol => udp},
+ ok = api_b_simple_open_and_close(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically open (create) and then close.
+api_b_simple_open_and_close_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ InitState = #{domain => inet,
+ type => stream,
+ protocol => tcp},
+ ok = api_b_simple_open_and_close(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically open (create) and then close.
+api_b_simple_open_and_close_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(?FUNCTION_NAME,
+ fun() -> has_support_ipv6() end,
+ fun() ->
+ InitState = #{domain => inet6,
+ type => stream,
+ protocol => tcp},
+ ok = api_b_simple_open_and_close(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+api_b_simple_open_and_close(InitState) ->
+ Seq =
+ [
+ #{desc => "open",
+ cmd => fun(#{domain := Domain,
+ type := Type,
+ protocol := Protocol} = State) ->
+ case socket:open(Domain, Type, Protocol) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ ?SEV_SLEEP(?SECS(1)),
+
+ #{desc => "close socket",
+ cmd => fun(#{sock := Sock} = _State) ->
+ socket:close(Sock)
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+ Evaluator = ?SEV_START("tester", Seq, InitState),
+ ok = ?SEV_AWAIT_FINISH([Evaluator]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Basically open (create) and info of an IPv4 UDP (dgram) socket.
%% With some extra checks...
api_b_open_and_info_udp4(_Config) when is_list(_Config) ->
@@ -3381,7 +3500,10 @@ api_b_send_and_recv_seqpL(_Config) when is_list(_Config) ->
api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
tc_try(api_b_sendmsg_and_recvmsg_tcp4,
- fun() -> has_support_ipv4() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
Send = fun(Sock, Data) ->
Msg = #{iov => [Data]},
@@ -4530,6 +4652,12 @@ api_b_sendmsg_iov_stream(Domain) ->
DataTooLarge = erlang:iolist_to_binary(IOVTooLarge),
{ok, Sa} = socket:open(Domain, stream),
try
+ case os:type() of
+ {win32,nt} ->
+ ok = socket:bind(Sa, which_local_socket_addr(Domain));
+ _ ->
+ ok
+ end,
{ok, Sb} = socket:open(Domain, stream),
try
ok = socket:bind(Sb, which_local_socket_addr(Domain)),
@@ -4550,6 +4678,9 @@ api_b_sendmsg_iov_stream(Domain) ->
{ok, DataTooLarge} =
socket:recv(Sa, byte_size(DataTooLarge)),
ok
+ catch
+ error:notsup = Reason:_ ->
+ exit({skip, Reason})
after
socket:close(Sc)
end
@@ -4560,6 +4691,7 @@ api_b_sendmsg_iov_stream(Domain) ->
socket:close(Sa)
end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
@@ -6586,7 +6718,7 @@ api_a_connect_tcpD(Domain, Nowait) ->
connect => Connect,
send => Send,
recv => Recv,
- connect_sref => Nowait},
+ connect_ref => Nowait},
api_a_connect_tcp(InitState).
@@ -6777,41 +6909,67 @@ api_a_connect_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, async_connect)
end},
#{desc => "connect (async) to server",
- cmd => fun(#{sock := Sock,
- server_sa := SSA,
- connect := Connect,
- connect_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ server_sa := SSA,
+ connect := Connect,
+ connect_ref := SR} = State) ->
case Connect(Sock, SSA) of
ok ->
?SEV_IPRINT("ok -> "
"unexpected success => SKIP",
[]),
{skip, unexpected_success};
+
{select, {select_info, ST, SelectRef}}
when SR =:= nowait ->
?SEV_IPRINT("select nowait ->"
"~n tag: ~p"
"~n ref: ~p",
[ST, SelectRef]),
- {ok, State#{connect_stag => ST,
- connect_sref => SelectRef}};
+ {ok, State#{asynch_tag => select,
+ connect_tag => ST,
+ connect_ref => SelectRef}};
{select, {select_info, ST, SR}}
when is_reference(SR) ->
?SEV_IPRINT("select ref ->"
"~n tag: ~p"
"~n ref: ~p", [ST, SR]),
- {ok, State#{connect_stag => ST}};
+ {ok, State#{asynch_tag => select,
+ connect_tag => ST}};
+
+ {completion,
+ {completion_info, CT, CompletionRef}}
+ when SR =:= nowait ->
+ ?SEV_IPRINT("completion nowait ->"
+ "~n tag: ~p"
+ "~n ref: ~p",
+ [CT, CompletionRef]),
+ {ok, State#{asynch_tag => completion,
+ connect_tag => CT,
+ connect_ref => CompletionRef}};
+ {completion,
+ {completion_info, CT, CR}}
+ when is_reference(CR) ->
+ ?SEV_IPRINT("completion ref ->"
+ "~n tag: ~p"
+ "~n ref: ~p", [CT, CR]),
+ {ok, State#{asynch_tag => completion,
+ connect_tag => CT}};
+
{error, _} = ERROR ->
ERROR
end
end},
- #{desc => "announce ready (connect select)",
+ #{desc => "announce ready (connect select|completion)",
cmd => fun(#{tester := Tester}) ->
?SEV_ANNOUNCE_READY(Tester, connect_select),
ok
end},
- #{desc => "await select message",
- cmd => fun(#{sock := Sock, connect_sref := Ref}) ->
+ #{desc => "await select|completion message",
+ cmd => fun(#{sock := Sock,
+ asynch_tag := select,
+ connect_tag := connect,
+ connect_ref := Ref}) ->
receive
{'$socket', Sock, select, Ref} ->
?SEV_IPRINT("select message ->"
@@ -6822,15 +6980,35 @@ api_a_connect_tcp(InitState) ->
"~n message queue: ~p",
[mq()]),
{error, timeout}
+ end;
+ (#{sock := Sock,
+ asynch_tag := completion,
+ connect_tag := connect,
+ connect_ref := Ref}) ->
+ receive
+ {'$socket', Sock, completion, {Ref, ok = Res}} ->
+ ?SEV_IPRINT("completion message ->"
+ "~n ref: ~p"
+ "~n res: ~p", [Ref, Res]),
+ ok
+ after 5000 ->
+ ?SEV_EPRINT("timeout: "
+ "~n message queue: ~p",
+ [mq()]),
+ {error, timeout}
end
end},
- #{desc => "announce ready (select)",
+ #{desc => "announce ready (select|completion)",
cmd => fun(#{tester := Tester}) ->
?SEV_ANNOUNCE_READY(Tester, select),
ok
end},
- #{desc => "connect (async) to server",
- cmd => fun(#{sock := Sock, server_sa := SSA, connect := Connect}) ->
+ #{desc => "(maybe) connect (async) to server",
+ cmd => fun(#{sock := Sock,
+ server_sa := SSA,
+ asynch_tag := select,
+ connect_tag := connect,
+ connect := Connect}) ->
case Connect(Sock, SSA) of
ok ->
ok;
@@ -6838,7 +7016,13 @@ api_a_connect_tcp(InitState) ->
{error, {unexpected_select, SelectInfo}};
{error, _} = ERROR ->
ERROR
- end
+ end;
+ (#{sock := _Sock,
+ server_sa := _SSA,
+ asynch_tag := completion,
+ connect_tag := connect,
+ connect := _Connect}) ->
+ ok
end},
#{desc => "announce ready (connect)",
cmd => fun(#{tester := Tester}) ->
@@ -7080,7 +7264,7 @@ api_a_connect_tcp(InitState) ->
api_a_sendto_and_recvfrom_udp4(Config) when is_list(Config) ->
?TT(?SECS(5)),
Nowait = nowait(Config),
- tc_try(api_a_sendto_and_recvfrom_udp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Send = fun(Sock, Data, Dest) ->
@@ -7089,10 +7273,10 @@ api_a_sendto_and_recvfrom_udp4(Config) when is_list(Config) ->
Recv = fun(Sock) ->
socket:recvfrom(Sock, 0, Nowait)
end,
- InitState = #{domain => inet,
- send => Send,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ send => Send,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_send_and_recv_udp(InitState)
end).
@@ -7109,7 +7293,7 @@ api_a_sendto_and_recvfrom_udp4(Config) when is_list(Config) ->
api_a_sendto_and_recvfrom_udp6(Config) when is_list(Config) ->
?TT(?SECS(5)),
Nowait = nowait(Config),
- tc_try(api_a_sendto_and_recvfrom_udp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Send = fun(Sock, Data, Dest) ->
@@ -7118,10 +7302,10 @@ api_a_sendto_and_recvfrom_udp6(Config) when is_list(Config) ->
Recv = fun(Sock) ->
socket:recvfrom(Sock, 0, Nowait)
end,
- InitState = #{domain => inet6,
- send => Send,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_send_and_recv_udp(InitState)
end).
@@ -7156,14 +7340,16 @@ api_a_sendmsg_and_recvmsg_udp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- send => Send,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ send => Send,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_send_and_recv_udp(InitState)
end).
@@ -7198,14 +7384,16 @@ api_a_sendmsg_and_recvmsg_udp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- send => Send,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ send => Send,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_send_and_recv_udp(InitState)
end).
@@ -7266,25 +7454,45 @@ api_a_send_and_recv_udp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
#{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
{select, {select_info, Tag, RecvRef}}
- when SR =:= nowait ->
+ when Ref =:= nowait ->
?SEV_IPRINT("expected select nowait: "
"~n Tag: ~p"
"~n Ref: ~p", [Tag, RecvRef]),
- {ok, State#{recv_stag => Tag,
- recv_sref => RecvRef}};
- {select, {select_info, Tag, SR}}
- when is_reference(SR) ->
+ {ok, State#{async_tag => select,
+ recv_tag => Tag,
+ recv_ref => RecvRef}};
+ {select, {select_info, Tag, Ref}}
+ when is_reference(Ref) ->
?SEV_IPRINT("expected select ref: "
"~n Tag: ~p"
- "~n Ref: ~p", [Tag, SR]),
- {ok, State#{recv_stag => Tag}};
+ "~n Ref: ~p", [Tag, Ref]),
+ {ok, State#{async_tag => select,
+ recv_tag => Tag}};
+
+ {completion, {completion_info, Tag, RecvRef}}
+ when Ref =:= nowait ->
+ ?SEV_IPRINT("expected select nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, RecvRef]),
+ {ok, State#{async_tag => completion,
+ recv_tag => Tag,
+ recv_ref => RecvRef}};
+ {completion, {completion_info, Tag, Ref}}
+ when is_reference(Ref) ->
+ ?SEV_IPRINT("expected completion ref: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, Ref]),
+ {ok, State#{async_tag => completion,
+ recv_tag => Tag}};
+
{ok, X} ->
- {error, {unexpected_succes, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -7294,29 +7502,74 @@ api_a_send_and_recv_udp(InitState) ->
?SEV_ANNOUNCE_READY(Tester, recv_select),
ok
end},
- #{desc => "await select message",
- cmd => fun(#{sock := Sock, recv_sref := RecvRef}) ->
+ #{desc => "await select|completion message",
+ cmd => fun(#{async_tag := select,
+ sock := Sock,
+ recv_ref := RecvRef}) ->
receive
{'$socket', Sock, select, RecvRef} ->
ok
after 5000 ->
- ?SEV_EPRINT("message queue: ~p", [mq()]),
+ ?SEV_EPRINT("timeout when: "
+ "~n Socket Info: ~p"
+ "~n Message Queue: ~p",
+ [socket:info(Sock), mq()]),
+ {error, timeout}
+ end;
+ (#{async_tag := completion,
+ sock := Sock,
+ recv_ref := RecvRef} = State) ->
+ receive
+ %% Recvfrom
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, {Src, ?BASIC_REQ}}}} ->
+ {ok, State#{req_src => Src}};
+ %% Recvmsg
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, #{addr := Src,
+ iov := [?BASIC_REQ]}}}} ->
+ {ok, State#{req_src => Src}};
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, Unexpected}}} ->
+ ?SEV_EPRINT("Unexpected success result: "
+ "~n ~p", [Unexpected]),
+ {error, {unexpected_success_result,
+ Unexpected}};
+ {'$socket', Sock, completion,
+ {RecvRef, {error, Reason} = ERROR}} ->
+ ?SEV_EPRINT("completion with error: "
+ "~n ~p", [Reason]),
+ ERROR
+ after 5000 ->
+ ?SEV_EPRINT("timeout when: "
+ "~n Socket Info: ~p"
+ "~n Message Queue: ~p",
+ [socket:info(Sock), mq()]),
{error, timeout}
end
end},
#{desc => "announce ready (select)",
cmd => fun(#{tester := Tester}) ->
+ %% We are actually done *if* this was
+ %% a completion event, but to make the
+ %% test case simple...
?SEV_ANNOUNCE_READY(Tester, select),
ok
end},
- #{desc => "now read the data (request)",
- cmd => fun(#{sock := Sock, recv := Recv} = State) ->
+ #{desc => "now read the data (request), for select",
+ cmd => fun(#{async_tag := select,
+ sock := Sock,
+ recv := Recv} = State) ->
case Recv(Sock) of
{ok, {Src, ?BASIC_REQ}} ->
{ok, State#{req_src => Src}};
{error, _} = ERROR ->
ERROR
- end
+ end;
+ (#{async_tag := completion} = _State) ->
+ %% We are already done!
+ ?SEV_IPRINT("Already done!"),
+ ok
end},
#{desc => "announce ready (recv request)",
cmd => fun(#{tester := Tester}) ->
@@ -7344,10 +7597,11 @@ api_a_send_and_recv_udp(InitState) ->
case ?SEV_AWAIT_TERMINATE(Tester, tester) of
ok ->
State2 = maps:remove(tester, State),
- State3 = maps:remove(recv_stag, State2),
- State4 = maps:remove(recv_sref, State3),
- State5 = maps:remove(req_src, State4),
- {ok, State5};
+ State3 = maps:remove(async_tag, State2),
+ State4 = maps:remove(recv_tag, State3),
+ State5 = maps:remove(recv_ref, State4),
+ State6 = maps:remove(req_src, State5),
+ {ok, State6};
{error, _} = ERROR ->
ERROR
end
@@ -7387,8 +7641,7 @@ api_a_send_and_recv_udp(InitState) ->
#{desc => "open socket",
cmd => fun(#{domain := Domain} = State) ->
Sock = sock_open(Domain, dgram, udp),
- SA = sock_sockname(Sock),
- {ok, State#{sock => Sock, sa => SA}}
+ {ok, State#{sock => Sock}}
end},
#{desc => "bind socket (to local address)",
cmd => fun(#{sock := Sock, lsa := LSA}) ->
@@ -7399,6 +7652,11 @@ api_a_send_and_recv_udp(InitState) ->
ERROR
end
end},
+ #{desc => "sockname",
+ cmd => fun(#{sock := Sock} = State) ->
+ SA = sock_sockname(Sock),
+ {ok, State#{sa => SA}}
+ end},
#{desc => "announce ready (init)",
cmd => fun(#{tester := Tester}) ->
?SEV_ANNOUNCE_READY(Tester, init),
@@ -7424,17 +7682,28 @@ api_a_send_and_recv_udp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
#{desc => "try recv reply (with nowait)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
{select, {select_info, Tag, RecvRef}}
- when SR =:= nowait ->
- {ok, State#{recv_stag => Tag,
- recv_sref => RecvRef}};
- {select, {select_info, Tag, SR}}
- when is_reference(SR) ->
- {ok, State#{recv_stag => Tag}};
+ when Ref =:= nowait ->
+ {ok, State#{async_tag => select,
+ recv_tag => Tag,
+ recv_ref => RecvRef}};
+ {select, {select_info, Tag, Ref}}
+ when is_reference(Ref) ->
+ {ok, State#{async_tag => select,
+ recv_tag => Tag}};
+ {completion, {completion_info, Tag, RecvRef}}
+ when Ref =:= nowait ->
+ {ok, State#{async_tag => completion,
+ recv_tag => Tag,
+ recv_ref => RecvRef}};
+ {completion, {completion_info, Tag, Ref}}
+ when is_reference(Ref) ->
+ {ok, State#{async_tag => completion,
+ recv_tag => Tag}};
{ok, X} ->
{error, {unexpected_select_info, X}};
{error, _} = ERROR ->
@@ -7447,10 +7716,20 @@ api_a_send_and_recv_udp(InitState) ->
ok
end},
#{desc => "await select message",
- cmd => fun(#{sock := Sock, recv_sref := RecvRef}) ->
+ cmd => fun(#{async_tag := select,
+ sock := Sock,
+ recv_ref := RecvRef}) ->
receive
{'$socket', Sock, select, RecvRef} ->
ok
+ end;
+ (#{async_tag := completion,
+ sock := Sock,
+ recv_ref := RecvRef}) ->
+ receive
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, _}}} ->
+ ok
end
end},
#{desc => "announce ready (select)",
@@ -7459,13 +7738,18 @@ api_a_send_and_recv_udp(InitState) ->
ok
end},
#{desc => "now read the data (reply)",
- cmd => fun(#{sock := Sock, recv := Recv}) ->
+ cmd => fun(#{async_tag := select,
+ sock := Sock,
+ recv := Recv}) ->
case Recv(Sock) of
{ok, {_Src, ?BASIC_REP}} ->
ok;
{error, _} = ERROR ->
ERROR
- end
+ end;
+ (#{async_tag := completion}) ->
+ ?SEV_IPRINT("Already read!"),
+ ok
end},
#{desc => "announce ready (recv reply)",
cmd => fun(#{tester := Tester}) ->
@@ -7479,9 +7763,10 @@ api_a_send_and_recv_udp(InitState) ->
case ?SEV_AWAIT_TERMINATE(Tester, tester) of
ok ->
State2 = maps:remove(tester, State),
- State3 = maps:remove(recv_stag, State2),
- State4 = maps:remove(recv_sref, State3),
- {ok, State4};
+ State3 = maps:remove(async_tag, State2),
+ State4 = maps:remove(recv_tag, State3),
+ State5 = maps:remove(recv_ref, State4),
+ {ok, State5};
{error, _} = ERROR ->
ERROR
end
@@ -7716,7 +8001,10 @@ api_a_sendmsg_and_recvmsg_tcp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
tc_try(api_a_sendmsg_and_recvmsg_tcp4,
- fun() -> has_support_ipv4() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
Send = fun(Sock, Data) ->
Msg = #{iov => [Data]},
@@ -7842,20 +8130,40 @@ api_a_send_and_recv_tcp(Config, InitState) ->
case socket:accept(LSock, Nowait) of
{select, {select_info, Tag, Ref}}
when Nowait =:= nowait ->
- ?SEV_IPRINT("accept select nowait: "
+ ?SEV_IPRINT("select accept message: "
"~n Tag: ~p"
"~n Ref: ~p", [Tag, Ref]),
- {ok, State#{accept_stag => Tag,
+ {ok, State#{sorc => select,
+ accept_stag => Tag,
accept_sref => Ref}};
{select, {select_info, Tag, Nowait}}
when is_reference(Nowait) ->
- ?SEV_IPRINT("accept select ref: "
+ ?SEV_IPRINT("select accept result: "
"~n Tag: ~p"
"~n Ref: ~p", [Tag, Nowait]),
- {ok, State#{accept_stag => Tag,
+ {ok, State#{sorc => select,
+ accept_stag => Tag,
accept_sref => Nowait}};
+
+ {completion, {completion_info, Tag, Ref}}
+ when Nowait =:= nowait ->
+ ?SEV_IPRINT("completion accept result: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, Ref]),
+ {ok, State#{sorc => completion,
+ accept_stag => Tag,
+ accept_sref => Ref}};
+ {completion, {completion_info, Tag, Nowait}}
+ when is_reference(Nowait) ->
+ ?SEV_IPRINT("completion accept result: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, Nowait]),
+ {ok, State#{sorc => completion,
+ accept_stag => Tag,
+ accept_sref => Nowait}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
{error, _} = ERROR ->
ERROR
end
@@ -7865,11 +8173,25 @@ api_a_send_and_recv_tcp(Config, InitState) ->
?SEV_ANNOUNCE_READY(Tester, accept_select),
ok
end},
- #{desc => "await select message",
- cmd => fun(#{lsock := Sock, accept_sref := Ref}) ->
+ #{desc => "await select|completion message",
+ cmd => fun(#{lsock := Sock, accept_sref := Ref} = State) ->
receive
{'$socket', Sock, select, Ref} ->
- ok
+ ?SEV_IPRINT("select message: "
+ "ready for accept"),
+ ok;
+ {'$socket', Sock, completion,
+ {Ref, {ok, CSock}}} ->
+ ?SEV_IPRINT("completion message: accepted: "
+ "~n CSock: ~p", [Sock]),
+ {ok, State#{csock => CSock}}
+ after 5000 ->
+ ?SEV_EPRINT("select|completion message timeout:"
+ "~n Sock: ~p"
+ "~n Ref: ~p"
+ "~n Message Queue: ~p",
+ [Sock, Ref, mq()]),
+ {error, timeout}
end
end},
#{desc => "announce ready (select)",
@@ -7877,8 +8199,9 @@ api_a_send_and_recv_tcp(Config, InitState) ->
?SEV_ANNOUNCE_READY(Tester, select),
ok
end},
- #{desc => "await connection (again)",
- cmd => fun(#{lsock := LSock} = State) ->
+ #{desc => "try accept (again)",
+ cmd => fun(#{lsock := LSock, sorc := select} = State) ->
+ ?SEV_IPRINT("try accept again"),
case socket:accept(LSock, nowait) of
{ok, Sock} ->
?SEV_IPRINT("accepted: "
@@ -7886,7 +8209,10 @@ api_a_send_and_recv_tcp(Config, InitState) ->
{ok, State#{csock => Sock}};
{error, _} = ERROR ->
ERROR
- end
+ end;
+ (#{sorc := completion})->
+ ?SEV_IPRINT("already accepted"),
+ ok
end},
#{desc => "announce ready (accept)",
cmd => fun(#{tester := Tester}) ->
@@ -7899,8 +8225,8 @@ api_a_send_and_recv_tcp(Config, InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv_req)
end},
#{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{csock := Sock,
- recv := Recv,
+ cmd => fun(#{csock := Sock,
+ recv := Recv,
recv_sref := SR} = State) ->
case Recv(Sock) of
{select, {select_info, Tag, Ref}}
@@ -7916,8 +8242,23 @@ api_a_send_and_recv_tcp(Config, InitState) ->
"~n Tag: ~p"
"~n Ref: ~p", [Tag, SR]),
{ok, State#{recv_stag => Tag}};
+
+ {completion, {completion_info, Tag, Ref}}
+ when SR =:= nowait ->
+ ?SEV_IPRINT("recv completion nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, Ref]),
+ {ok, State#{recv_stag => Tag,
+ recv_sref => Ref}};
+ {completion, {completion_info, Tag, SR}}
+ when is_reference(SR) ->
+ ?SEV_IPRINT("recv completion ref: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, SR]),
+ {ok, State#{recv_stag => Tag}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
{error, _} = ERROR ->
ERROR
end
@@ -7927,11 +8268,20 @@ api_a_send_and_recv_tcp(Config, InitState) ->
?SEV_ANNOUNCE_READY(Tester, recv_select),
ok
end},
- #{desc => "await select message",
+ #{desc => "await select|completion message",
cmd => fun(#{csock := Sock, recv_sref := RecvRef}) ->
receive
{'$socket', Sock, select, RecvRef} ->
- ok
+ ok;
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, ?BASIC_REQ}}} ->
+ ?SEV_IPRINT("received expected data"),
+ ok;
+ {'$socket', Sock, completion,
+ {RecvRef, {error, Reason} = ERROR}} ->
+ ?SEV_EPRINT("received unexpected error: "
+ "~n ~p", [Reason]),
+ ERROR
end
end},
#{desc => "announce ready (select)",
@@ -7940,13 +8290,19 @@ api_a_send_and_recv_tcp(Config, InitState) ->
ok
end},
#{desc => "now read the data (request)",
- cmd => fun(#{csock := Sock, recv := Recv} = _State) ->
+ cmd => fun(#{sorc := select,
+ csock := Sock,
+ recv := Recv} = _State) ->
case Recv(Sock) of
{ok, ?BASIC_REQ} ->
+ ?SEV_IPRINT("read expected data"),
ok;
{error, _} = ERROR ->
ERROR
- end
+ end;
+ (#{sorc := completion}) ->
+ ?SEV_IPRINT("already received"),
+ ok
end},
#{desc => "announce ready (recv request)",
cmd => fun(#{tester := Tester}) ->
@@ -8066,7 +8422,7 @@ api_a_send_and_recv_tcp(Config, InitState) ->
ok
end},
- #{desc => "try recv reply (with nowait, expect select)",
+ #{desc => "try recv reply (with nowait, expect select|completion)",
cmd => fun(#{sock := Sock,
recv := Recv,
recv_sref := SR} = State) ->
@@ -8076,16 +8432,35 @@ api_a_send_and_recv_tcp(Config, InitState) ->
?SEV_IPRINT("recv select nowait: "
"~n Tag: ~p"
"~n Ref: ~p", [Tag, Ref]),
- {ok, State#{recv_stag => Tag,
+ {ok, State#{sorc => select,
+ recv_stag => Tag,
recv_sref => Ref}};
{select, {select_info, Tag, SR}}
when is_reference(SR) ->
?SEV_IPRINT("recv select ref: "
"~n Tag: ~p"
"~n Ref: ~p", [Tag, SR]),
- {ok, State#{recv_stag => Tag}};
+ {ok, State#{sorc => select,
+ recv_stag => Tag}};
+
+ {completion, {completion_info, Tag, Ref}}
+ when SR =:= nowait ->
+ ?SEV_IPRINT("recv completion nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, Ref]),
+ {ok, State#{sorc => completion,
+ recv_stag => Tag,
+ recv_sref => Ref}};
+ {completion, {completion_info, Tag, SR}}
+ when is_reference(SR) ->
+ ?SEV_IPRINT("recv completion ref: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [Tag, SR]),
+ {ok, State#{sorc => completion,
+ recv_stag => Tag}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
{error, _} = ERROR ->
ERROR
end
@@ -8099,6 +8474,10 @@ api_a_send_and_recv_tcp(Config, InitState) ->
cmd => fun(#{sock := Sock, recv_sref := RecvRef}) ->
receive
{'$socket', Sock, select, RecvRef} ->
+ ok;
+ {'$socket', Sock, completion,
+ {RecvRef, {ok, ?BASIC_REP}}} ->
+ ?SEV_IPRINT("received expected reply"),
ok
end
end},
@@ -8108,8 +8487,13 @@ api_a_send_and_recv_tcp(Config, InitState) ->
ok
end},
#{desc => "now read the data (reply)",
- cmd => fun(#{sock := Sock, recv := Recv}) ->
+ cmd => fun(#{sorc := select, sock := Sock, recv := Recv}) ->
{ok, ?BASIC_REP} = Recv(Sock),
+ ?SEV_IPRINT("[select] received expected reply"),
+ ok;
+ (#{sorc := completion}) ->
+ ?SEV_IPRINT("[completion] "
+ "expected reply already received"),
ok
end},
#{desc => "announce ready (recv reply)",
@@ -8311,7 +8695,7 @@ api_a_send_and_recv_tcp(Config, InitState) ->
api_a_recvfrom_cancel_udp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvfrom_cancel_udp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Recv = fun(Sock) ->
@@ -8320,13 +8704,15 @@ api_a_recvfrom_cancel_udp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_udp(InitState)
end).
@@ -8340,7 +8726,7 @@ api_a_recvfrom_cancel_udp4(Config) when is_list(Config) ->
api_a_recvfrom_cancel_udp6(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvfrom_cancel_udp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Recv = fun(Sock) ->
@@ -8349,13 +8735,15 @@ api_a_recvfrom_cancel_udp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_udp(InitState)
end).
@@ -8369,7 +8757,7 @@ api_a_recvfrom_cancel_udp6(Config) when is_list(Config) ->
api_a_recvmsg_cancel_udp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvmsg_cancel_udp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Recv = fun(Sock) ->
@@ -8378,13 +8766,15 @@ api_a_recvmsg_cancel_udp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_udp(InitState)
end).
@@ -8398,7 +8788,7 @@ api_a_recvmsg_cancel_udp4(Config) when is_list(Config) ->
api_a_recvmsg_cancel_udp6(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvmsg_cancel_udp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Recv = fun(Sock) ->
@@ -8407,13 +8797,15 @@ api_a_recvmsg_cancel_udp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_udp(InitState)
end).
@@ -8473,19 +8865,28 @@ api_a_recv_cancel_udp(InitState) ->
cmd => fun(#{tester := Tester} = _State) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
- #{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ #{desc => "try recv request (with nowait, expect select|completion)",
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, SelectInfo} when SR =:= nowait ->
- {ok, State#{recv_select_info => SelectInfo}};
+ {select, SI} when Ref =:= nowait ->
+ {ok, State#{recv_select_info => SI}};
{select,
- {select_info, _Tag, SR} = SelectInfo}
- when is_reference(SR) ->
- {ok, State#{recv_select_info => SelectInfo}};
+ {select_info, _Tag, Ref} = SI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_select_info => SI}};
+
+ {completion, CI} when Ref =:= nowait ->
+ {ok, State#{recv_completion_info => CI}};
+ {completion,
+ {completion_info, _Tag, Ref} = CI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -8495,11 +8896,15 @@ api_a_recv_cancel_udp(InitState) ->
?SEV_ANNOUNCE_READY(Tester, recv_select),
ok
end},
- #{desc => "await select message (without success)",
+ #{desc => "wait for select message - without success",
cmd => fun(#{sock := Sock}) ->
receive
{'$socket', Sock, select, Ref} ->
- {error, {unexpected_select, Ref}}
+ {error, {unexpected_select, Ref}};
+
+ {'$socket', Sock, completion, C} ->
+ {error, {unexpected_completion, C}}
+
after 5000 ->
ok
end
@@ -8514,9 +8919,12 @@ api_a_recv_cancel_udp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, cancel)
end},
#{desc => "cancel",
- cmd => fun(#{sock := Sock, recv_select_info := SelectInfo}) ->
- ok = socket:cancel(Sock, SelectInfo)
+ cmd => fun(#{sock := Sock, recv_select_info := SI}) ->
+ ok = socket:cancel(Sock, SI);
+ (#{sock := Sock, recv_completion_info := CI}) ->
+ ok = socket:cancel(Sock, CI)
end},
+
#{desc => "announce ready (cancel)",
cmd => fun(#{tester := Tester}) ->
?SEV_ANNOUNCE_READY(Tester, cancel),
@@ -8528,11 +8936,10 @@ api_a_recv_cancel_udp(InitState) ->
cmd => fun(#{tester := Tester} = State) ->
case ?SEV_AWAIT_TERMINATE(Tester, tester) of
ok ->
- State2 = maps:remove(tester, State),
- State3 = maps:remove(recv_stag, State2),
- State4 = maps:remove(recv_sref, State3),
- State5 = maps:remove(req_src, State4),
- {ok, State5};
+ State2 = maps:remove(tester, State),
+ State3 = maps:remove(recv_ref, State2),
+ State4 = maps:remove(req_src, State3),
+ {ok, State4};
{error, _} = ERROR ->
ERROR
end
@@ -8638,7 +9045,7 @@ api_a_recv_cancel_udp(InitState) ->
api_a_accept_cancel_tcp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_accept_cancel_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Accept = fun(Sock) ->
@@ -8647,13 +9054,15 @@ api_a_accept_cancel_tcp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- accept => Accept,
- accept_sref => Nowait},
+ InitState = #{domain => inet,
+ accept => Accept,
+ accept_ref => Nowait},
ok = api_a_accept_cancel_tcp(InitState)
end).
@@ -8668,7 +9077,7 @@ api_a_accept_cancel_tcp4(Config) when is_list(Config) ->
api_a_accept_cancel_tcp6(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_accept_cancel_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Accept = fun(Sock) ->
@@ -8677,13 +9086,15 @@ api_a_accept_cancel_tcp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- accept => Accept,
- accept_sref => Nowait},
+ InitState = #{domain => inet6,
+ accept => Accept,
+ accept_ref => Nowait},
ok = api_a_accept_cancel_tcp(InitState)
end).
@@ -8749,28 +9160,39 @@ api_a_accept_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, accept)
end},
#{desc => "await connection (nowait)",
- cmd => fun(#{lsock := LSock,
- accept := Accept,
- accept_sref := SR} = State) ->
+ cmd => fun(#{lsock := LSock,
+ accept := Accept,
+ accept_ref := Ref} = State) ->
case Accept(LSock) of
- {select, {select_info, T, R} = SelectInfo}
- when SR =:= nowait ->
+ {select, {select_info, T, R} = SI}
+ when Ref =:= nowait ->
?SEV_IPRINT("accept select nowait: "
"~n T: ~p"
"~n R: ~p", [T, R]),
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
- {select, {select_info, T, SR} = SelectInfo}
- when is_reference(SR) ->
+ {ok, State#{accept_select_info => SI}};
+ {select, {select_info, T, Ref} = SI}
+ when is_reference(Ref) ->
?SEV_IPRINT("accept select ref: "
"~n T: ~p"
- "~n R: ~p", [T, SR]),
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
+ "~n R: ~p", [T, Ref]),
+ {ok, State#{accept_select_info => SI}};
+
+ {completion, {completion_info, T, R} = CI}
+ when Ref =:= nowait ->
+ ?SEV_IPRINT("accept completion nowait: "
+ "~n T: ~p"
+ "~n R: ~p", [T, R]),
+ {ok, State#{accept_completion_info => CI}};
+ {completion, {completion_info, T, Ref} = CI}
+ when is_reference(Ref) ->
+ ?SEV_IPRINT("accept completion ref: "
+ "~n T: ~p"
+ "~n R: ~p", [T, Ref]),
+ {ok, State#{accept_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -8784,7 +9206,11 @@ api_a_accept_cancel_tcp(InitState) ->
cmd => fun(#{lsock := Sock}) ->
receive
{'$socket', Sock, select, Ref} ->
- {error, {unexpected_select, Ref}}
+ {error, {unexpected_select, Ref}};
+
+ {'$socket', Sock, completion, C} ->
+ {error, {unexpected_completion, C}}
+
after 5000 ->
ok
end
@@ -8799,8 +9225,12 @@ api_a_accept_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, cancel)
end},
#{desc => "cancel",
- cmd => fun(#{lsock := Sock, accept_select_info := SelectInfo}) ->
- ok = socket:cancel(Sock, SelectInfo)
+ cmd => fun(#{lsock := Sock,
+ accept_select_info := SelectInfo}) ->
+ ok = socket:cancel(Sock, SelectInfo);
+ (#{lsock := Sock,
+ accept_completion_info := CompletionInfo}) ->
+ ok = socket:cancel(Sock, CompletionInfo)
end},
#{desc => "announce ready (cancel)",
cmd => fun(#{tester := Tester}) ->
@@ -8911,15 +9341,15 @@ api_a_accept_cancel_tcp(InitState) ->
api_a_recv_cancel_tcp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recv_cancel_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Recv = fun(Sock) ->
socket:recv(Sock, 0, Nowait)
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_tcp(InitState)
end).
@@ -8933,15 +9363,15 @@ api_a_recv_cancel_tcp4(Config) when is_list(Config) ->
api_a_recv_cancel_tcp6(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recv_cancel_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Recv = fun(Sock) ->
socket:recv(Sock, 0, Nowait)
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_tcp(InitState)
end).
@@ -8955,15 +9385,18 @@ api_a_recv_cancel_tcp6(Config) when is_list(Config) ->
api_a_recvmsg_cancel_tcp4(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvmsg_cancel_tcp4,
- fun() -> has_support_ipv4() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
Recv = fun(Sock) ->
socket:recvmsg(Sock, Nowait)
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_tcp(InitState)
end).
@@ -8977,15 +9410,18 @@ api_a_recvmsg_cancel_tcp4(Config) when is_list(Config) ->
api_a_recvmsg_cancel_tcp6(Config) when is_list(Config) ->
?TT(?SECS(10)),
Nowait = nowait(Config),
- tc_try(api_a_recvmsg_cancel_tcp6,
- fun() -> has_support_ipv6() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
Recv = fun(Sock) ->
socket:recvmsg(Sock, Nowait)
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_recv_cancel_tcp(InitState)
end).
@@ -9068,27 +9504,43 @@ api_a_recv_cancel_tcp(InitState) ->
cmd => fun(#{tester := Tester} = _State) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
- #{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{csock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+
+ #{desc => "try recv request (with nowait, expect select|completion)",
+ cmd => fun(#{csock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, {select_info, T, R} = SelectInfo}
- when SR =:= nowait ->
+ {select, {select_info, T, R} = SI}
+ when Ref =:= nowait ->
?SEV_IPRINT("recv select nowait: "
"~n Tag: ~p"
"~n Ref: ~p", [T, R]),
- {ok,
- State#{recv_select_info => SelectInfo}};
- {select, {select_info, T, SR} = SelectInfo}
- when is_reference(SR) ->
+ {ok, State#{recv_select_info => SI}};
+ {select, {select_info, T, Ref} = SI}
+ when is_reference(Ref) ->
?SEV_IPRINT("recv select ref: "
"~n Tag: ~p"
- "~n Ref: ~p", [T, SR]),
- {ok,
- State#{recv_select_info => SelectInfo}};
+ "~n Ref: ~p", [T, Ref]),
+ {ok, State#{recv_select_info => SI}};
+
+ {completion,
+ {completion_info, T, R} = CI}
+ when Ref =:= nowait ->
+ ?SEV_IPRINT("recv completion nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [T, R]),
+ {ok, State#{recv_completion_info => CI}};
+ {completion,
+ {completion_info, T, Ref} = CI}
+ when is_reference(Ref) ->
+ ?SEV_IPRINT("recv completion ref: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [T, Ref]),
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -9102,7 +9554,11 @@ api_a_recv_cancel_tcp(InitState) ->
cmd => fun(#{csock := Sock}) ->
receive
{'$socket', Sock, select, Ref} ->
- {error, {unexpected_select, Ref}}
+ {error, {unexpected_select, Ref}};
+
+ {'$socket', Sock, completion, C} ->
+ {error, {unexpected_completion, C}}
+
after 5000 ->
ok
end
@@ -9117,8 +9573,11 @@ api_a_recv_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, cancel)
end},
#{desc => "cancel",
- cmd => fun(#{csock := Sock, recv_select_info := SelectInfo}) ->
- ok = socket:cancel(Sock, SelectInfo)
+ cmd => fun(#{csock := Sock, recv_select_info := SI}) ->
+ ok = socket:cancel(Sock, SI);
+
+ (#{csock := Sock, recv_completion_info := CI}) ->
+ ok = socket:cancel(Sock, CI)
end},
#{desc => "announce ready (cancel)",
cmd => fun(#{tester := Tester}) ->
@@ -9372,13 +9831,15 @@ api_a_mrecvfrom_cancel_udp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_udp(InitState)
end).
@@ -9402,13 +9863,15 @@ api_a_mrecvfrom_cancel_udp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_udp(InitState)
end).
@@ -9432,13 +9895,15 @@ api_a_mrecvmsg_cancel_udp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_udp(InitState)
end).
@@ -9462,13 +9927,15 @@ api_a_mrecvmsg_cancel_udp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_udp(InitState)
end).
@@ -9528,21 +9995,27 @@ api_a_mrecv_cancel_udp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
#{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, SelectInfo}
- when SR =:= nowait ->
- {ok,
- State#{recv_select_info => SelectInfo}};
- {select,
- {select_info, _Tag, SR} = SelectInfo}
- when is_reference(SR) ->
- {ok,
- State#{recv_select_info => SelectInfo}};
+ {select, SI}
+ when Ref =:= nowait ->
+ {ok, State#{recv_select_info => SI}};
+ {select, {select_info, _Tag, Ref} = SI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_select_info => SI}};
+
+ {completion, CI}
+ when Ref =:= nowait ->
+ {ok, State#{recv_completion_info => CI}};
+ {completion, {completion_info, _Tag, Ref} = CI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -9554,7 +10027,8 @@ api_a_mrecv_cancel_udp(InitState) ->
end},
#{desc => "await abort message",
cmd => fun(#{sock := Sock,
- recv_select_info := {select_info, _, Ref}} = State) ->
+ recv_select_info := {select_info, _, Ref}} =
+ State) ->
receive
{'$socket', Sock, select, Ref} ->
{error, {unexpected_select, Ref}};
@@ -9563,6 +10037,18 @@ api_a_mrecv_cancel_udp(InitState) ->
after 5000 ->
?SEV_EPRINT("message queue: ~p", [mq()]),
{error, timeout}
+ end;
+ (#{sock := Sock,
+ recv_completion_info := {completion_info, _, Ref}} =
+ State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, CS}} ->
+ {error, {unexpected_completion, CS}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(sock, State)}
+ after 5000 ->
+ ?SEV_EPRINT("message queue: ~p", [mq()]),
+ {error, timeout}
end
end},
#{desc => "announce ready (abort)",
@@ -9576,11 +10062,9 @@ api_a_mrecv_cancel_udp(InitState) ->
cmd => fun(#{tester := Tester} = State) ->
case ?SEV_AWAIT_TERMINATE(Tester, tester) of
ok ->
- State2 = maps:remove(tester, State),
- State3 = maps:remove(recv_stag, State2),
- State4 = maps:remove(recv_sref, State3),
- State5 = maps:remove(req_src, State4),
- {ok, State5};
+ State2 = maps:remove(tester, State),
+ State3 = maps:remove(recv_ref, State2),
+ {ok, State3};
{error, _} = ERROR ->
ERROR
end
@@ -9616,20 +10100,27 @@ api_a_mrecv_cancel_udp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
#{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, SelectInfo} when SR =:= nowait ->
- {ok,
- State#{recv_select_info => SelectInfo}};
+ {select, SI} when Ref =:= nowait ->
+ {ok, State#{recv_select_info => SI}};
{select,
- {select_info, _Tag, SR} = SelectInfo}
- when is_reference(SR) ->
- {ok,
- State#{recv_select_info => SelectInfo}};
+ {select_info, _Tag, Ref} = SI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_select_info => SI}};
+
+ {completion, CI} when Ref =:= nowait ->
+ {ok, State#{recv_completion_info => CI}};
+ {completion,
+ {completion_info, _Tag, Ref} = CI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -9650,6 +10141,19 @@ api_a_mrecv_cancel_udp(InitState) ->
after 5000 ->
?SEV_EPRINT("message queue: ~p", [mq()]),
{error, timeout}
+ end;
+
+ (#{sock := Sock,
+ recv_completion_info := {completion_info, _, Ref}} =
+ State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, CS}} ->
+ {error, {unexpected_completion, CS}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(sock, State)}
+ after 5000 ->
+ ?SEV_EPRINT("message queue: ~p", [mq()]),
+ {error, timeout}
end
end},
#{desc => "announce ready (abort)",
@@ -9665,9 +10169,10 @@ api_a_mrecv_cancel_udp(InitState) ->
ok ->
?SEV_IPRINT("terminating"),
State1 = maps:remove(recv_select_info, State),
- State2 = maps:remove(tester, State1),
- State3 = maps:remove(sock, State2),
- {ok, State3};
+ State2 = maps:remove(recv_completion_info, State1),
+ State3 = maps:remove(tester, State2),
+ State4 = maps:remove(sock, State3),
+ {ok, State4};
{error, _} = ERROR ->
ERROR
end
@@ -9879,13 +10384,15 @@ api_a_maccept_cancel_tcp4(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet,
- accept => Accept,
- accept_sref => Nowait},
+ InitState = #{domain => inet,
+ accept => Accept,
+ accept_ref => Nowait},
ok = api_a_maccept_cancel_tcp(InitState)
end).
@@ -9910,13 +10417,15 @@ api_a_maccept_cancel_tcp6(Config) when is_list(Config) ->
OK;
{select, _} = SELECT ->
SELECT;
+ {completion, _} = COMPLETION ->
+ COMPLETION;
{error, _} = ERROR ->
ERROR
end
end,
- InitState = #{domain => inet6,
- accept => Accept,
- accept_sref => Nowait},
+ InitState = #{domain => inet6,
+ accept => Accept,
+ accept_ref => Nowait},
ok = api_a_maccept_cancel_tcp(InitState)
end).
@@ -9982,28 +10491,39 @@ api_a_maccept_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, accept)
end},
#{desc => "await connection (nowait)",
- cmd => fun(#{lsock := LSock,
- accept := Accept,
- accept_sref := SR} = State) ->
+ cmd => fun(#{lsock := LSock,
+ accept := Accept,
+ accept_ref := Ref} = State) ->
case Accept(LSock) of
- {select, {select_info, T, R} = SelectInfo}
- when SR =:= nowait ->
+ {select, {select_info, T, R} = SI}
+ when Ref =:= nowait ->
?SEV_IPRINT("accept select nowait: "
"~n T: ~p"
"~n R: ~p", [T, R]),
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
- {select, {select_info, T, SR} = SelectInfo}
- when is_reference(SR) ->
+ {ok, State#{accept_select_info => SI}};
+ {select, {select_info, T, Ref} = SI}
+ when is_reference(Ref) ->
?SEV_IPRINT("accept select ref: "
"~n T: ~p"
- "~n R: ~p", [T, SR]),
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
+ "~n R: ~p", [T, Ref]),
+ {ok, State#{accept_select_info => SI}};
+
+ {completion, {completion_info, T, R} = CI}
+ when Ref =:= nowait ->
+ ?SEV_IPRINT("accept completion nowait: "
+ "~n T: ~p"
+ "~n R: ~p", [T, R]),
+ {ok, State#{accept_completion_info => CI}};
+ {completion, {completion_info, T, Ref} = CI}
+ when is_reference(Ref) ->
+ ?SEV_IPRINT("accept completion ref: "
+ "~n T: ~p"
+ "~n R: ~p", [T, Ref]),
+ {ok, State#{accept_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -10022,7 +10542,26 @@ api_a_maccept_cancel_tcp(InitState) ->
{'$socket', Sock, abort, {Ref, closed}} ->
{ok, maps:remove(lsock, State)}
after 5000 ->
- ?SEV_EPRINT("message queue: ~p", [mq()]),
+ ?SEV_EPRINT("timeout when: "
+ "~n Sock: ~p"
+ "~n Ref: ~p"
+ "~n message queue: ~p",
+ [Sock, Ref, mq()]),
+ {error, timeout}
+ end;
+ (#{lsock := Sock,
+ accept_completion_info := {completion_info, _, Ref}} = State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, _} = C} ->
+ {error, {unexpected_completion, C}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(lsock, State)}
+ after 5000 ->
+ ?SEV_EPRINT("timeout when: "
+ "~n Sock: ~p"
+ "~n Ref: ~p"
+ "~n message queue: ~p",
+ [Sock, Ref, mq()]),
{error, timeout}
end
end},
@@ -10073,22 +10612,25 @@ api_a_maccept_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, accept)
end},
#{desc => "try accept request (with nowait, expect select)",
- cmd => fun(#{lsock := Sock,
- accept := Accept,
- accept_sref := SR} = State) ->
+ cmd => fun(#{lsock := Sock,
+ accept := Accept,
+ accept_ref := Ref} = State) ->
case Accept(Sock) of
- {select, SelectInfo} when SR =:= nowait ->
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
- {select,
- {select_info, _Tag, SR} = SelectInfo}
- when is_reference(SR) ->
- {ok,
- State#{accept_select_info =>
- SelectInfo}};
+ {select, SI} when Ref =:= nowait ->
+ {ok, State#{accept_select_info => SI}};
+ {select, {select_info, _Tag, Ref} = SI}
+ when is_reference(Ref) ->
+ {ok, State#{accept_select_info => SI}};
+
+ {completion, CI} when Ref =:= nowait ->
+ {ok, State#{accept_completion_info => CI}};
+ {completion, {completion_info, _Tag, Ref} = CI}
+ when is_reference(Ref) ->
+ {ok, State#{accept_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -10107,7 +10649,26 @@ api_a_maccept_cancel_tcp(InitState) ->
{'$socket', Sock, abort, {Ref, closed}} ->
{ok, maps:remove(sock, State)}
after 5000 ->
- ?SEV_EPRINT("message queue: ~p", [mq()]),
+ ?SEV_EPRINT("timeout when: "
+ "~n Sock: ~p"
+ "~n Ref: ~p"
+ "~n message queue: ~p",
+ [Sock, Ref, mq()]),
+ {error, timeout}
+ end;
+ (#{lsock := Sock,
+ accept_completion_info := {completion_info, _, Ref}} = State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, _} = C} ->
+ {error, {unexpected_completion, C}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(sock, State)}
+ after 5000 ->
+ ?SEV_EPRINT("timeout when: "
+ "~n Sock: ~p"
+ "~n Ref: ~p"
+ "~n message queue: ~p",
+ [Sock, Ref, mq()]),
{error, timeout}
end
end},
@@ -10125,8 +10686,9 @@ api_a_maccept_cancel_tcp(InitState) ->
?SEV_IPRINT("terminating"),
State1 = maps:remove(tester, State),
State2 = maps:remove(accept_select_info, State1),
- State3 = maps:remove(lsock, State2),
- {ok, State3};
+ State3 = maps:remove(accept_completion_info, State2),
+ State4 = maps:remove(lsock, State3),
+ {ok, State4};
{error, _} = ERROR ->
ERROR
end
@@ -10322,15 +10884,15 @@ api_a_maccept_cancel_tcp(InitState) ->
api_a_mrecv_cancel_tcp4(Config) when is_list(Config) ->
?TT(?SECS(20)),
Nowait = nowait(Config),
- tc_try(api_a_mrecv_cancel_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Recv = fun(Sock) ->
socket:recv(Sock, 0, Nowait)
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_tcp(InitState)
end).
@@ -10345,15 +10907,15 @@ api_a_mrecv_cancel_tcp4(Config) when is_list(Config) ->
api_a_mrecv_cancel_tcp6(Config) when is_list(Config) ->
?TT(?SECS(20)),
Nowait = nowait(Config),
- tc_try(api_a_mrecv_cancel_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Recv = fun(Sock) ->
socket:recv(Sock, 0, Nowait)
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_tcp(InitState)
end).
@@ -10368,15 +10930,18 @@ api_a_mrecv_cancel_tcp6(Config) when is_list(Config) ->
api_a_mrecvmsg_cancel_tcp4(Config) when is_list(Config) ->
?TT(?SECS(20)),
Nowait = nowait(Config),
- tc_try(api_a_mrecvmsg_cancel_tcp4,
- fun() -> has_support_ipv4() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
Recv = fun(Sock) ->
socket:recvmsg(Sock, Nowait)
end,
- InitState = #{domain => inet,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_tcp(InitState)
end).
@@ -10391,15 +10956,18 @@ api_a_mrecvmsg_cancel_tcp4(Config) when is_list(Config) ->
api_a_mrecvmsg_cancel_tcp6(Config) when is_list(Config) ->
?TT(?SECS(20)),
Nowait = nowait(Config),
- tc_try(api_a_mrecvmsg_cancel_tcp6,
- fun() -> has_support_ipv6() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
Recv = fun(Sock) ->
socket:recvmsg(Sock, Nowait)
end,
- InitState = #{domain => inet6,
- recv => Recv,
- recv_sref => Nowait},
+ InitState = #{domain => inet6,
+ recv => Recv,
+ recv_ref => Nowait},
ok = api_a_mrecv_cancel_tcp(InitState)
end).
@@ -10482,25 +11050,40 @@ api_a_mrecv_cancel_tcp(InitState) ->
cmd => fun(#{tester := Tester} = _State) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
- #{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{csock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ #{desc => "try recv request (with nowait, expect select|completion)",
+ cmd => fun(#{csock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, {select_info, T, R} = SelectInfo}
- when SR =:= nowait ->
+ {select, {select_info, T, R} = SI}
+ when Ref =:= nowait ->
?SEV_IPRINT("recv select nowait: "
"~n Tag: ~p"
"~n Ref: ~p", [T, R]),
- {ok, State#{recv_select_info => SelectInfo}};
- {select, {select_info, T, SR} = SelectInfo}
- when is_reference(SR) ->
+ {ok, State#{recv_select_info => SI}};
+ {select, {select_info, T, Ref} = SI}
+ when is_reference(Ref) ->
?SEV_IPRINT("recv select nowait: "
"~n Tag: ~p"
- "~n Ref: ~p", [T, SR]),
- {ok, State#{recv_select_info => SelectInfo}};
+ "~n Ref: ~p", [T, Ref]),
+ {ok, State#{recv_select_info => SI}};
+
+ {completion, {completion_info, T, R} = CI}
+ when Ref =:= nowait ->
+ ?SEV_IPRINT("recv completion nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [T, R]),
+ {ok, State#{recv_completion_info => CI}};
+ {completion, {completion_info, T, Ref} = CI}
+ when is_reference(Ref) ->
+ ?SEV_IPRINT("recv completion nowait: "
+ "~n Tag: ~p"
+ "~n Ref: ~p", [T, Ref]),
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -10510,7 +11093,7 @@ api_a_mrecv_cancel_tcp(InitState) ->
?SEV_ANNOUNCE_READY(Tester, recv_select),
ok
end},
- #{desc => "await select message",
+ #{desc => "await select|completion message",
cmd => fun(#{csock := Sock,
recv_select_info := {select_info, _, Ref}} = State) ->
receive
@@ -10520,6 +11103,16 @@ api_a_mrecv_cancel_tcp(InitState) ->
{ok, maps:remove(sock, State)}
after 5000 ->
ok
+ end;
+ (#{csock := Sock,
+ recv_completion_info := {completion_info, _, Ref}} = State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, _} = C} ->
+ {error, {unexpected_completion, C}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(sock, State)}
+ after 5000 ->
+ ok
end
end},
#{desc => "announce ready (abort)",
@@ -10572,20 +11165,25 @@ api_a_mrecv_cancel_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
end},
#{desc => "try recv request (with nowait, expect select)",
- cmd => fun(#{sock := Sock,
- recv := Recv,
- recv_sref := SR} = State) ->
+ cmd => fun(#{sock := Sock,
+ recv := Recv,
+ recv_ref := Ref} = State) ->
case Recv(Sock) of
- {select, SelectInfo} when SR =:= nowait ->
- {ok,
- State#{recv_select_info => SelectInfo}};
- {select,
- {select_info, _Tag, SR} = SelectInfo}
- when is_reference(SR) ->
- {ok,
- State#{recv_select_info => SelectInfo}};
+ {select, SI} when Ref =:= nowait ->
+ {ok, State#{recv_select_info => SI}};
+ {select, {select_info, _Tag, Ref} = SI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_select_info => SI}};
+
+ {completion, CI} when Ref =:= nowait ->
+ {ok, State#{recv_completion_info => CI}};
+ {completion, {completion_info, _Tag, Ref} = CI}
+ when is_reference(Ref) ->
+ {ok, State#{recv_completion_info => CI}};
+
{ok, X} ->
- {error, {unexpected_select_info, X}};
+ {error, {unexpected_success, X}};
+
{error, _} = ERROR ->
ERROR
end
@@ -10606,6 +11204,17 @@ api_a_mrecv_cancel_tcp(InitState) ->
after 5000 ->
?SEV_EPRINT("message queue: ~p", [mq()]),
{error, timeout}
+ end;
+ (#{sock := Sock,
+ recv_completion_info := {completion_info, _, Ref}} = State) ->
+ receive
+ {'$socket', Sock, completion, {Ref, _} = C} ->
+ {error, {unexpected_completion, C}};
+ {'$socket', Sock, abort, {Ref, closed}} ->
+ {ok, maps:remove(sock, State)}
+ after 5000 ->
+ ?SEV_EPRINT("message queue: ~p", [mq()]),
+ {error, timeout}
end
end},
#{desc => "announce ready (abort)",
@@ -10621,9 +11230,10 @@ api_a_mrecv_cancel_tcp(InitState) ->
ok ->
?SEV_IPRINT("terminating"),
State1 = maps:remove(recv_select_info, State),
- State2 = maps:remove(tester, State1),
- State3 = maps:remove(sock, State2),
- {ok, State3};
+ State2 = maps:remove(recv_completion_info, State1),
+ State3 = maps:remove(tester, State2),
+ State4 = maps:remove(sock, State3),
+ {ok, State4};
{error, _} = ERROR ->
ERROR
end
@@ -11417,8 +12027,10 @@ api_opt_simple_otp_meta_option() ->
%% protocol = tcp.
api_opt_simple_otp_rcvbuf_option(_Config) when is_list(_Config) ->
?TT(?SECS(15)),
- tc_try(api_opt_simple_otp_rcvbuf_option,
- fun() -> api_opt_simple_otp_rcvbuf_option() end).
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ api_opt_simple_otp_rcvbuf_option()
+ end).
api_opt_simple_otp_rcvbuf_option() ->
Get = fun(S) ->
@@ -11557,6 +12169,12 @@ api_opt_simple_otp_rcvbuf_option() ->
end},
#{desc => "attempt to recv",
cmd => fun(#{sock := Sock, msg_sz := MsgSz} = _State) ->
+ ?SEV_IPRINT("try recv ~w bytes when rcvbuf is ~s",
+ [MsgSz,
+ case Get(Sock) of
+ {ok, RcvBuf} -> f("~w", [RcvBuf]);
+ {error, _} -> "-"
+ end]),
case socket:recv(Sock) of
{ok, Data} when (size(Data) =:= MsgSz) ->
ok;
@@ -11614,6 +12232,10 @@ api_opt_simple_otp_rcvbuf_option() ->
cmd => fun(#{tester := Tester} = State) ->
case ?SEV_AWAIT_CONTINUE(Tester, tester, recv) of
{ok, {ExpSz, NewRcvBuf}} ->
+ ?SEV_IPRINT("set new rcvbuf:"
+ "~n New RcvBuf: ~p"
+ "~n Expect Size: ~p",
+ [ExpSz, NewRcvBuf]),
{ok, State#{msg_sz => ExpSz,
rcvbuf => NewRcvBuf}};
{error, _} = ERROR ->
@@ -11624,7 +12246,8 @@ api_opt_simple_otp_rcvbuf_option() ->
cmd => fun(#{sock := Sock, rcvbuf := NewRcvBuf} = _State) ->
case Set(Sock, NewRcvBuf) of
ok ->
- ?SEV_IPRINT("set new rcvbuf: ~p", [NewRcvBuf]),
+ ?SEV_IPRINT("set new rcvbuf: ~p",
+ [NewRcvBuf]),
ok;
{error, _} = ERROR ->
ERROR
@@ -11919,7 +12542,13 @@ api_opt_simple_otp_rcvbuf_option() ->
#{desc => "order server continue (recv 1)",
cmd => fun(#{server := Server, data := Data} = _State) ->
MsgSz = size(Data),
- NewRcvBuf = {2 + (MsgSz div 1024), 1024},
+ NewRcvBuf =
+ case os:type() of
+ {win32, nt} ->
+ (((2 * MsgSz) div 1024) + 1) * 1024;
+ _ ->
+ {2 + (MsgSz div 1024), 1024}
+ end,
?SEV_ANNOUNCE_CONTINUE(Server, recv, NewRcvBuf),
ok
end},
@@ -11956,7 +12585,13 @@ api_opt_simple_otp_rcvbuf_option() ->
#{desc => "order server continue (recv 2)",
cmd => fun(#{server := Server, data := Data} = _State) ->
MsgSz = size(Data),
- NewRcvBuf = {2 + (MsgSz div 2048), 2048},
+ NewRcvBuf =
+ case os:type() of
+ {win32, nt} ->
+ (((3 * MsgSz) div 1024) + 1) * 1024;
+ _ ->
+ {2 + (MsgSz div 2048), 2048}
+ end,
?SEV_ANNOUNCE_CONTINUE(Server, recv, NewRcvBuf),
ok
end},
@@ -11993,12 +12628,18 @@ api_opt_simple_otp_rcvbuf_option() ->
?SEV_SLEEP(?SECS(1)),
#{desc => "order server continue (recv 3)",
cmd => fun(#{server := Server, data := Data} = _State) ->
- MsgSz = size(Data),
- BufSz = 2048,
- N = MsgSz div BufSz - 1,
- NewRcvBuf = {N, BufSz},
+ MsgSz = size(Data),
+ BufSz = 2048,
+ N = MsgSz div BufSz - 1,
+ {ExpSz, NewRcvBuf} =
+ case os:type() of
+ {win32, nt} ->
+ {N*BufSz, N*BufSz};
+ _ ->
+ {N*BufSz, {N, BufSz}}
+ end,
?SEV_ANNOUNCE_CONTINUE(Server, recv,
- {N*BufSz, NewRcvBuf})
+ {ExpSz, NewRcvBuf})
end},
#{desc => "await client ready (send 3)",
cmd => fun(#{server := Server,
@@ -13233,6 +13874,11 @@ api_opt_sock_broadcast() ->
?SEV_IPRINT("Expected Success (bound): ~p",
[Port]),
{ok, State#{sa2 => BSA#{port => Port}}};
+ {error, eaddrnotavail = Reason} ->
+ ?SEV_IPRINT("~p => "
+ "SKIP subnet-directed broadcast test",
+ [Reason]),
+ {ok, State#{sa2 => skip}};
{error, Reason} = ERROR ->
?SEV_EPRINT("Unexpected Failure: ~p",
[Reason]),
@@ -13240,7 +13886,10 @@ api_opt_sock_broadcast() ->
end
end},
#{desc => "[socket 2] UDP socket sockname",
- cmd => fun(#{sock2 := Sock} = _State) ->
+ cmd => fun(#{sa2 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP subnet-directed broadcast test"),
+ ok;
+ (#{sock2 := Sock} = _State) ->
case socket:sockname(Sock) of
{ok, SA} ->
?SEV_IPRINT("SA: ~p", [SA]),
@@ -13346,7 +13995,7 @@ api_opt_sock_broadcast() ->
#{desc => "[socket 3] try send to limited broadcast address",
cmd => fun(#{sa1 := skip} = _State) ->
- ?SEV_IPRINT("SKIP limited broadcast test"),
+ ?SEV_IPRINT("SKIP limited broadcast test (send)"),
ok;
(#{sock3 := Sock,
sa1 := Dest} = _State) ->
@@ -13366,7 +14015,7 @@ api_opt_sock_broadcast() ->
end},
#{desc => "[socket 1] try recv",
cmd => fun(#{sa1 := skip} = _State) ->
- ?SEV_IPRINT("SKIP limited broadcast test"),
+ ?SEV_IPRINT("SKIP limited broadcast test (recv)"),
ok;
(#{sock1 := Sock} = State) ->
case socket:recvfrom(Sock, 0, 5000) of
@@ -13393,8 +14042,12 @@ api_opt_sock_broadcast() ->
?SEV_SLEEP(?SECS(1)),
- #{desc => "[socket 3] try send to subnet-directed broadcast address",
- cmd => fun(#{sock3 := Sock,
+ #{desc => "[socket 2] try send to subnet-directed broadcast address",
+ cmd => fun(#{sa2 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP subnet-directed broadcast test "
+ "(send)"),
+ ok;
+ (#{sock2 := Sock,
sa2 := Dest} = _State) ->
Data = list_to_binary("hejsan"),
?SEV_IPRINT("try send to broadcast address: "
@@ -13404,6 +14057,14 @@ api_opt_sock_broadcast() ->
?SEV_IPRINT("Expected Success: "
"broadcast message sent"),
ok;
+ {error, eaddrnotavail = Reason} ->
+ ?SEV_EPRINT("Unexpected Failure: ~p => SKIP",
+ [Reason]),
+ {skip, Reason};
+ {error, eacces = Reason} ->
+ ?SEV_EPRINT("Unexpected Failure: ~p => SKIP",
+ [Reason]),
+ {skip, Reason};
{error, Reason} = ERROR ->
?SEV_EPRINT("Unexpected Failure: ~p",
[Reason]),
@@ -13411,13 +14072,17 @@ api_opt_sock_broadcast() ->
end
end},
#{desc => "[socket 2] try recv",
- cmd => fun(#{sock2 := Sock, sa1 := SA1} = _State) ->
+ cmd => fun(#{sa2 := skip} = _State) ->
+ ?SEV_IPRINT("SKIP subnet-directed broadcast test "
+ "(recv)"),
+ ok;
+ (#{sock2 := Sock, sa2 := SA2} = _State) ->
case socket:recvfrom(Sock, 0, 5000) of
{ok, _} ->
?SEV_IPRINT("Expected Success: "
"received message"),
ok;
- {error, timeout = Reason} when (SA1 =:= skip) ->
+ {error, timeout = Reason} when (SA2 =:= skip) ->
?SEV_IPRINT("Unexpected Failure: ~p",
[Reason]),
{skip, "receive timeout"};
@@ -17136,7 +17801,11 @@ api_opt_sock_timeo(InitState) ->
api_opt_sock_rcvlowat_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
tc_try(api_opt_sock_rcvlowat_udp4,
- fun() -> has_support_ipv4(), has_support_sock_rcvlowat() end,
+ fun() ->
+ is_not_windows(), % einval on Windows
+ has_support_ipv4(),
+ has_support_sock_rcvlowat()
+ end,
fun() ->
ok = api_opt_sock_lowat_udp4(rcvlowat)
end).
@@ -17155,7 +17824,11 @@ api_opt_sock_rcvlowat_udp4(_Config) when is_list(_Config) ->
api_opt_sock_sndlowat_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
tc_try(api_opt_sock_sndlowat_udp4,
- fun() -> has_support_ipv4(), has_support_sock_sndlowat() end,
+ fun() ->
+ is_not_windows(), % einval on Windows
+ has_support_ipv4(),
+ has_support_sock_sndlowat()
+ end,
fun() ->
ok = api_opt_sock_lowat_udp4(sndlowat)
end).
@@ -18819,7 +19492,7 @@ which_local_host_ifname(Domain) ->
api_opt_ip_pktinfo_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
- tc_try(api_opt_ip_pktinfo_udp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4(), has_support_ip_pktinfo() end,
fun() ->
Set = fun(Sock, Value) ->
@@ -18830,16 +19503,16 @@ api_opt_ip_pktinfo_udp4(_Config) when is_list(_Config) ->
end,
Send = fun(Sock, Data, Dest, default) ->
Msg = #{addr => Dest,
- iov => [Data]},
+ iov => [Data]},
socket:sendmsg(Sock, Msg);
(Sock, Data, Dest, Info) ->
%% We do not support this at the moment!!!
CMsg = #{level => ip,
- type => pktinfo,
- data => Info},
+ type => pktinfo,
+ data => Info},
Msg = #{addr => Dest,
- ctrl => [CMsg],
- iov => [Data]},
+ ctrl => [CMsg],
+ iov => [Data]},
socket:sendmsg(Sock, Msg)
end,
Recv = fun(Sock) ->
@@ -18928,18 +19601,18 @@ api_opt_ip_pktinfo_udp(InitState) ->
"~n ~p", [SADst]),
{ok, State#{sa_dst => SADst}}
end},
- #{desc => "default pktinfo for dst socket",
+ #{desc => "get default pktinfo for dst socket",
cmd => fun(#{sock_dst := Sock, get := Get} = _State) ->
case Get(Sock) of
{ok, false = Value} ->
?SEV_IPRINT("dst recvttl: ~p", [Value]),
ok;
{ok, Unexpected} ->
- ?SEV_EPRINT("Unexpected src recvtos: ~p",
+ ?SEV_EPRINT("Unexpected src pktinfo: ~p",
[Unexpected]),
{error, {unexpected, Unexpected}};
{error, Reason} = ERROR ->
- ?SEV_EPRINT("Failed getting (default) timestamp:"
+ ?SEV_EPRINT("Failed getting (default) pktinfo:"
" ~p", [Reason]),
ERROR
end
@@ -19881,6 +20554,7 @@ api_opt_ip_recvtos_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
tc_try(api_opt_ip_recvtos_udp4,
fun() ->
+ is_not_windows(), % IP_TOS on windows
has_support_ipv4(),
has_support_ip_recvtos(),
has_support_ip_tos() % Used in the test
@@ -20250,10 +20924,15 @@ api_opt_ip_recvtos_udp(InitState) ->
%% Maybe we should send and receive from different VMs, until then
%% skip darwin and OpenBSD.
%%
+%% Windows:
+%% It seems like its possible to set and get the recvttl option,
+%% but not to use the ttl control message header when sending.
+%% The following is the list of types (for level ip) which are listed
+%% as supported: IP_ORIGINAL_ARRIVAL_IF, IP_PKTINFO and IP_ECN
api_opt_ip_recvttl_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
- tc_try(api_opt_ip_recvttl_udp4,
+ tc_try(?FUNCTION_NAME,
fun() ->
has_support_ipv4(),
has_support_ip_recvttl(),
@@ -20269,15 +20948,15 @@ api_opt_ip_recvttl_udp4(_Config) when is_list(_Config) ->
end,
Send = fun(Sock, Data, Dest, default) ->
Msg = #{addr => Dest,
- iov => [Data]},
+ iov => [Data]},
socket:sendmsg(Sock, Msg);
(Sock, Data, Dest, TTL) ->
CMsg = #{level => ip,
- type => ttl,
- value => TTL},
+ type => ttl,
+ value => TTL},
Msg = #{addr => Dest,
- ctrl => [CMsg],
- iov => [Data]},
+ ctrl => [CMsg],
+ iov => [Data]},
socket:sendmsg(Sock, Msg)
end,
Recv = fun(Sock) ->
@@ -20442,6 +21121,69 @@ api_opt_ip_recvttl_udp(InitState) ->
(catch socket:close(SSock)),
(catch socket:close(DSock)),
{skip, Reason};
+
+ {error,
+ {get_overlapped_result,
+ #{file := File,
+ function := Function,
+ line := Line,
+ raw_info := RawInfo,
+ info := invalid_parameter = Info}}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TTL: "
+ "~p => SKIP: "
+ "~n File: ~s"
+ "~n Function: ~s"
+ "~n Line: ~p"
+ "~n Raw Info: ~p",
+ [Info,
+ File, Function, Line,
+ RawInfo]),
+ (catch socket:close(SSock)),
+ (catch socket:close(DSock)),
+ {skip,
+ ?F("Cannot send with TTL: ~p", [Info])};
+ {error, {get_overlapped_result,
+ invalid_parameter = Info}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TTL: "
+ "~p => SKIP", [Info]),
+ (catch socket:close(SSock)),
+ (catch socket:close(DSock)),
+ {skip,
+ ?F("Cannot send with TTL: ~p", [Info])};
+
+ {error,
+ {completion_status,
+ #{file := File,
+ function := Function,
+ line := Line,
+ raw_info := RawInfo,
+ info := invalid_parameter = Info}}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TTL: "
+ "~p => SKIP: "
+ "~n File: ~s"
+ "~n Function: ~s"
+ "~n Line: ~p"
+ "~n Raw Info: ~p",
+ [Info,
+ File, Function, Line,
+ RawInfo]),
+ (catch socket:close(SSock)),
+ (catch socket:close(DSock)),
+ {skip,
+ ?F("Cannot send with TTL: ~p", [Info])};
+ {error, {completion_status,
+ invalid_parameter = Info}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TTL: "
+ "~p => SKIP", [Info]),
+ (catch socket:close(SSock)),
+ (catch socket:close(DSock)),
+ {skip,
+ ?F("Cannot send with TTL: ~p", [Info])};
+
{error, _Reason} = ERROR ->
ERROR
end
@@ -20636,8 +21378,12 @@ api_opt_ip_recvttl_udp(InitState) ->
api_opt_ip_tos_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
- tc_try(api_opt_ip_tos_udp4,
- fun() -> has_support_ipv4(), has_support_ip_tos() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(), % IP_TOS on windows
+ has_support_ipv4(),
+ has_support_ip_tos()
+ end,
fun() ->
Set = fun(Sock, Value) ->
socket:setopt(Sock, ip, tos, Value)
@@ -20992,16 +21738,33 @@ api_opt_recverr_udp(Config, InitState) ->
{select, SelectInfo} when RecvRef =:= nowait ->
?SEV_IPRINT("expected select nowait: "
"~n ~p", [SelectInfo]),
- {ok, State#{rselect => SelectInfo}};
+ {ok, State#{async_tag => select,
+ rselect => SelectInfo}};
{select,
{select_info, _Tag, RecvRef} = SelectInfo}
when is_reference(RecvRef) ->
?SEV_IPRINT("expected select ref: "
"~n ~p", [SelectInfo]),
- {ok, State#{rselect => SelectInfo}};
+ {ok, State#{async_tag => select,
+ rselect => SelectInfo}};
+
+ {completion, CI} when RecvRef =:= nowait ->
+ ?SEV_IPRINT("expected completion nowait: "
+ "~n ~p", [CI]),
+ {ok, State#{asynch_tag => completion,
+ rcompletion => CI}};
+ {completion,
+ {completion_info, _Tag, RecvRef} = CI}
+ when is_reference(RecvRef) ->
+ ?SEV_IPRINT("expected completion ref: "
+ "~n ~p", [CI]),
+ {ok, State#{asynch_tag => completion,
+ rcompletion => CI}};
+
{ok, _} ->
?SEV_EPRINT("unexpected success"),
{error, unexpected_success};
+
{error, Reason} = ERROR ->
?SEV_EPRINT("unexpected error: ~p", [Reason]),
ERROR
@@ -21010,8 +21773,8 @@ api_opt_recverr_udp(Config, InitState) ->
#{desc => "try send to nowhere",
cmd => fun(#{domain := Domain,
- sock := Sock,
- send := Send} = State) ->
+ sock := Sock,
+ send := Send} = State) ->
SendRef = nowait(Config),
Dest = #{family => Domain,
addr => if
@@ -21024,18 +21787,40 @@ api_opt_recverr_udp(Config, InitState) ->
case Send(Sock, <<"ping">>, Dest, SendRef) of
ok ->
?SEV_IPRINT("sent"),
- ok;
+ {ok, State#{sent => true}};
+
{select, SelectInfo}
when SendRef =:= nowait ->
?SEV_IPRINT("expected select nowait: ~p",
[SelectInfo]),
- {ok, State#{sselect => SelectInfo}};
+ {ok, State#{sent => false,
+ asynch_tag => select,
+ sselect => SelectInfo}};
{select,
{select_info, _Tag, SendRef} = SelectInfo}
when is_reference(SendRef) ->
?SEV_IPRINT("expected select ref: ~p",
[SelectInfo]),
- {ok, State#{sselect => SelectInfo}};
+ {ok, State#{sent => false,
+ asynch_tag => select,
+ sselect => SelectInfo}};
+
+ {completion, CI}
+ when SendRef =:= nowait ->
+ ?SEV_IPRINT("expected completion nowait: ~p",
+ [CI]),
+ {ok, State#{sent => false,
+ asynch_tag => completion,
+ scompletion => CI}};
+ {completion,
+ {completion_info, _Tag, SendRef} = CI}
+ when is_reference(SendRef) ->
+ ?SEV_IPRINT("expected completion ref: ~p",
+ [CI]),
+ {ok, State#{sent => false,
+ asynch_tag => completion,
+ scompletion => CI}};
+
{error, Reason} = ERROR ->
?SEV_EPRINT("unexpected error: ~p",
[Reason]),
@@ -21043,22 +21828,55 @@ api_opt_recverr_udp(Config, InitState) ->
end
end},
- #{desc => "await receive select message",
- cmd => fun(#{sock := Sock,
- rselect := {select_info, _, Ref}} = _State) ->
+ #{desc => "await receive select|completion message",
+ cmd => fun(#{sent := false,
+ asynch_tag := select,
+ sock := Sock,
+ rselect := {select_info, _, Ref}} = _State) ->
receive
{'$socket', Sock, select, Ref} ->
- ?SEV_IPRINT("received expected (read) select message: "
+ ?SEV_IPRINT("received expected (read) "
+ "select message: "
"~n ~p", [Ref]),
ok
- end
+ end;
+ (#{sent := false,
+ asynch_tag := completion,
+ sock := Sock,
+ rcompletion := {completion_info, _, Ref}} = _State) ->
+ receive
+ {'$socket', Sock, completion,
+ {Ref, {error, econnrefused = Reason}}} ->
+ ?SEV_IPRINT("expected failure: ~p",
+ [Reason]),
+ ok;
+
+ {'$socket', Sock, completion,
+ {Ref, {ok, _}}} ->
+ ?SEV_EPRINT("unexpected success"),
+ {error, unexpected_success};
+ {'$socket', Sock, completion,
+ {Ref, {error, Reason} = ERROR}} ->
+ ?SEV_IPRINT("unexpected failure: ~p",
+ [Reason]),
+ ERROR
+
+ end;
+ (#{sent := true} = _State) ->
+ ?SEV_IPRINT("no action needed"),
+ ok
end},
#{desc => "try recv - expect econnrefused",
- cmd => fun(#{sock := Sock, recv := Recv} = _State) ->
+ cmd => fun(#{asynch_tag := completion} = _State) ->
+ ?SEV_IPRINT("already processed"),
+ ok;
+ (#{sock := Sock,
+ recv := Recv} = _State) ->
case Recv(Sock, infinity) of
{error, econnrefused = Reason} ->
- ?SEV_IPRINT("expected failure: ~p", [Reason]),
+ ?SEV_IPRINT("expected failure: ~p",
+ [Reason]),
ok;
{ok, _} ->
?SEV_EPRINT("unexpected success"),
@@ -21096,10 +21914,17 @@ api_opt_recverr_udp(Config, InitState) ->
{ok, {Addr, <<"ring">>}} ->
?SEV_IPRINT("receive expected"),
ok;
+
{select, SelectInfo} ->
?SEV_EPRINT("unexpected select: ~p",
[SelectInfo]),
{error, unexpected_success};
+
+ {completion, CompletionInfo} ->
+ ?SEV_EPRINT("unexpected completion: ~p",
+ [CompletionInfo]),
+ {error, unexpected_success};
+
{error, Reason} = ERROR ->
?SEV_EPRINT("unexpected error: ~p",
[Reason]),
@@ -21108,7 +21933,7 @@ api_opt_recverr_udp(Config, InitState) ->
end},
#{desc => "try recv error queue",
- cmd => fun(#{domain := Domain, sock := Sock}) ->
+ cmd => fun(#{domain := Domain, sock := Sock} = State) ->
%% Note that not all platforms that support
%% recverr, actually supports "encoding" the data
%% part, so we need to adjust for that.
@@ -21139,7 +21964,7 @@ api_opt_recverr_udp(Config, InitState) ->
}]} = Msg} ->
?SEV_IPRINT("expected error queue (decoded): "
"~n ~p", [Msg]),
- ok;
+ {ok, State#{asynch_tag => none}};
{ok, #{addr := #{family := Domain,
addr := _Addr},
flags := [errqueue],
@@ -21147,7 +21972,30 @@ api_opt_recverr_udp(Config, InitState) ->
value := [#{level := Level,
type := recverr}]} = _Msg} ->
?SEV_IPRINT("expected error queue"),
- ok;
+ {ok, State#{asynch_tag => none}};
+
+ {completion, CI} ->
+ ?SEV_IPRINT("completion: "
+ "~n ~p", [CI]),
+ {ok, State#{asynch_tag => completion,
+ completion => CI}};
+
+ {error, timeout = Reason} = ERROR ->
+ case os:type() of
+ {win32, nt} ->
+ ?SEV_IPRINT("failed reading "
+ "error queue: "
+ "~n ~p", [Reason]),
+ {skip,
+ "Test case does not "
+ "work on Windows"};
+ _ ->
+ ?SEV_EPRINT("failed reading "
+ "error queue: "
+ "~n ~p", [Reason]),
+ ERROR
+ end;
+
{error, Reason} = ERROR ->
?SEV_EPRINT("failed reading error queue: "
"~n ~p", [Reason]),
@@ -21155,6 +22003,29 @@ api_opt_recverr_udp(Config, InitState) ->
end
end},
+ #{desc => "await receive select message",
+ cmd => fun(#{asynch_tag := completion,
+ sock := Sock,
+ completion := {completion_info, _, Ref}} = _State) ->
+ receive
+ {'$socket', Sock, completion,
+ {Ref, {ok, Info}}} ->
+ ?SEV_EPRINT("expected success: "
+ "~n ~p", [Info]),
+ ok;
+
+ {'$socket', Sock, completion,
+ {Ref, {error, Reason} = ERROR}} ->
+ ?SEV_IPRINT("unexpected failure: ~p",
+ [Reason]),
+ ERROR
+
+ end;
+ (#{asynch_tag := none} = _State) ->
+ ?SEV_IPRINT("no action needed"),
+ ok
+ end},
+
#{desc => "close socket",
cmd => fun(#{sock := Sock} = State) ->
ok = socket:close(Sock),
@@ -21201,14 +22072,20 @@ api_opt_recverr_udp(Config, InitState) ->
api_opt_ip_mopts_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
- tc_try(api_opt_ip_mopts_udp4,
+ tc_try(?FUNCTION_NAME,
fun() ->
has_support_ipv4(),
- case is_any_options_supported(
- [{ip, pktinfo},
- {ip, recvorigdstaddr},
- {ip, recvtos},
- {ip, recvttl}]) of
+ Opts =
+ [{ip, pktinfo},
+ {ip, recvorigdstaddr}] ++
+ case os:type() of
+ {win32, nt} ->
+ [];
+ _ ->
+ [{ip, recvtos},
+ {ip, recvttl}]
+ end,
+ case is_any_options_supported(Opts) of
true ->
ok;
false ->
@@ -21244,42 +22121,49 @@ api_opt_ip_mopts_udp4(_Config) when is_list(_Config) ->
false ->
[]
end ++
- case socket:is_supported(options, ip, recvtos) of
- true ->
- %% It seems that sending any of the
- %% TOS or TTL values will fail on:
- %% FreeBSD
- %% Linux when
- %% version =< 3.12.60 (at least)
- %% Don't know when this starts working,
- %% but it works on:
- %% Ubunto 16.04.6 => 4.15.0-65
- %% SLES 12 SP2 => 4.4.120-92.70
- %% so don't!
- %%
- %% The latest we know it not to work was a
- %% SLES 12 (plain) at 3.12.50-52.54
- %%
- [{ip, recvtos, tos,
- case os:type() of
- {unix, freebsd} ->
- default;
- {unix, linux} ->
- case os:version() of
- Vsn when Vsn > {3,12,60} ->
- 42;
- _ ->
- default
- end;
- _ ->
- 42
- end}];
- false ->
- []
+ case os:type() of
+ {win32, nt} ->
+ [];
+ _ ->
+ case socket:is_supported(options, ip, recvtos) of
+ true ->
+ %% It seems that sending any of the
+ %% TOS or TTL values will fail on:
+ %% FreeBSD
+ %% Linux when
+ %% version =< 3.12.60 (at least)
+ %% Don't know when this starts
+ %% working, but it works on:
+ %% Ubunto 16.04.6 => 4.15.0-65
+ %% SLES 12 SP2 => 4.4.120-92.70
+ %% so don't!
+ %%
+ %% The latest we know it not to work
+ %% was a SLES 12 (plain) at 3.12.50-52.54
+ %%
+ [{ip, recvtos, tos,
+ case os:type() of
+ {unix, freebsd} ->
+ default;
+ {unix, linux} ->
+ case os:version() of
+ Vsn when Vsn > {3,12,60} ->
+ 42;
+ _ ->
+ default
+ end;
+ _ ->
+ 42
+ end}];
+ false ->
+ []
+ end
end ++
case os:type() of
{unix, darwin} ->
[];
+ {win32, nt} ->
+ [];
_ ->
case socket:is_supported(options, ip, recvttl) of
true ->
@@ -21314,21 +22198,22 @@ api_opt_ip_mopts_udp4(_Config) when is_list(_Config) ->
end,
Enable = fun(Sock, Level, Opt) ->
- ?SEV_IPRINT("try enable [~w] ~p", [Level, Opt]),
+ ?SEV_IPRINT("try enable [~w] ~p",
+ [Level, Opt]),
socket:setopt(Sock, Level, Opt, true)
end,
Send = fun(Sock, Data, Dest, []) ->
Msg = #{addr => Dest,
- iov => [Data]},
+ iov => [Data]},
socket:sendmsg(Sock, Msg);
(Sock, Data, Dest, Hdrs) when is_list(Hdrs) ->
CMsgs = [#{level => Level,
- type => Type,
- value => Val} ||
- {Level, Type, Val} <- Hdrs],
+ type => Type,
+ value => Val} ||
+ {Level, Type, Val} <- Hdrs],
Msg = #{addr => Dest,
- ctrl => CMsgs,
- iov => [Data]},
+ ctrl => CMsgs,
+ iov => [Data]},
socket:sendmsg(Sock, Msg)
end,
Recv = fun(Sock) ->
@@ -22592,7 +23477,68 @@ api_opt_ipv6_tclass_udp(InitState) ->
#{desc => "send req (to dst) (w explicit tc = 1)",
cmd => fun(#{sock_src := Sock, sa_dst := Dst, send := Send}) ->
- Send(Sock, ?BASIC_REQ, Dst, 1)
+ case Send(Sock, ?BASIC_REQ, Dst, 1) of
+ {error,
+ {get_overlapped_result,
+ #{file := File,
+ function := Function,
+ line := Line,
+ raw_info := RawInfo,
+ info := invalid_parameter = Info}}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TClass: "
+ "~p => SKIP: "
+ "~n File: ~s"
+ "~n Function: ~s"
+ "~n Line: ~p"
+ "~n Raw Info: ~p",
+ [Info,
+ File, Function, Line,
+ RawInfo]),
+ (catch socket:close(Sock)),
+ {skip,
+ ?F("Cannot send with TClass: ~p", [Info])};
+ {error, {get_overlapped_result,
+ invalid_parameter = Info}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TClass: "
+ "~p => SKIP", [Info]),
+ (catch socket:close(Sock)),
+ {skip,
+ ?F("Cannot send with TClass: ~p", [Info])};
+
+ {error,
+ {completion_status,
+ #{file := File,
+ function := Function,
+ line := Line,
+ raw_info := RawInfo,
+ info := invalid_parameter = Info}}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TClass: "
+ "~p => SKIP: "
+ "~n File: ~s"
+ "~n Function: ~s"
+ "~n Line: ~p"
+ "~n Raw Info: ~p",
+ [Info,
+ File, Function, Line,
+ RawInfo]),
+ (catch socket:close(Sock)),
+ {skip,
+ ?F("Cannot send with TClass: ~p", [Info])};
+ {error, {completion_status,
+ invalid_parameter = Info}} ->
+ %% IF we can't send it the test will not work
+ ?SEV_EPRINT("Cannot send TClass: "
+ "~p => SKIP", [Info]),
+ (catch socket:close(Sock)),
+ {skip,
+ ?F("Cannot send with TClass: ~p", [Info])};
+
+ Other ->
+ Other
+ end
end},
#{desc => "recv req (from src)",
cmd => fun(#{sock_dst := Sock, sa_src := Src, recv := Recv}) ->
@@ -22639,7 +23585,8 @@ api_opt_ipv6_tclass_udp(InitState) ->
value => "something"},
?BASIC_REQ, UnexpData]),
{error, {unexpected_data, UnexpData}};
- {error, _} = ERROR ->
+
+ {error, _} = ERROR ->
%% At the moment there is no way to get
%% status or state for the socket...
ERROR
@@ -22700,13 +23647,19 @@ api_opt_ipv6_mopts_udp6(_Config) when is_list(_Config) ->
tc_try(api_opt_ipv6_mopts_udp6,
fun() ->
has_support_ipv6(),
- case is_any_options_supported(
- [{ipv6, recvpktinfo},
- {ipv6, flowinfo},
- {ipv6, recvhoplimit},
- {ipv6, hoplimit},
- {ipv6, recvtclass},
- {ipv6, tclass}]) of
+ Opts =
+ [{ipv6, recvpktinfo},
+ {ipv6, flowinfo},
+ {ipv6, recvhoplimit},
+ {ipv6, hoplimit}] ++
+ case os:type() of
+ {win32, nt} ->
+ [];
+ _ ->
+ [{ipv6, recvtclass},
+ {ipv6, tclass}]
+ end,
+ case is_any_options_supported(Opts) of
true ->
ok;
false ->
@@ -22755,20 +23708,28 @@ api_opt_ipv6_mopts_udp6(_Config) when is_list(_Config) ->
[]
end
end ++
- case socket:is_supported(options, ipv6, recvtclass) of
- true ->
- [{ipv6, recvtclass, tclass, 42}];
- false ->
- case socket:is_supported(options, ipv6, tclass) of
- true ->
- [{ipv6, tclass, tclass, 42}];
- false ->
- []
- end
+ case os:type() of
+ {win32, nt} ->
+ [];
+ _ ->
+ case socket:is_supported(options,
+ ipv6, recvtclass) of
+ true ->
+ [{ipv6, recvtclass, tclass, 42}];
+ false ->
+ case socket:is_supported(options,
+ ipv6, tclass) of
+ true ->
+ [{ipv6, tclass, tclass, 42}];
+ false ->
+ []
+ end
+ end
end,
Enable = fun(Sock, Level, Opt) ->
- ?SEV_IPRINT("try enable [~w] ~p", [Level, Opt]),
+ ?SEV_IPRINT("try enable [~w] ~p",
+ [Level, Opt]),
socket:setopt(Sock, Level, Opt, true)
end,
Send = fun(Sock, Data, Dest, []) ->
@@ -22777,12 +23738,12 @@ api_opt_ipv6_mopts_udp6(_Config) when is_list(_Config) ->
socket:sendmsg(Sock, Msg);
(Sock, Data, Dest, Hdrs) when is_list(Hdrs) ->
CMsgs = [#{level => Level,
- type => Type,
- data => Val} ||
- {Level, Type, Val} <- Hdrs],
+ type => Type,
+ data => Val} ||
+ {Level, Type, Val} <- Hdrs],
Msg = #{addr => Dest,
- ctrl => CMsgs,
- iov => [Data]},
+ ctrl => CMsgs,
+ iov => [Data]},
socket:sendmsg(Sock, Msg)
end,
Recv = fun(Sock) ->
@@ -23293,8 +24254,11 @@ api_opt_tcp_cork_tcp(InitState) ->
api_opt_tcp_maxseg_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(5)),
- tc_try(api_opt_tcp_maxseg_tcp4,
- fun() -> has_support_ipv4(), has_support_tcp_maxseg() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ has_support_ipv4(),
+ has_support_tcp_maxseg()
+ end,
fun() ->
Set = fun(Sock, Value) when is_integer(Value) ->
socket:setopt(Sock, tcp, maxseg, Value)
@@ -23353,6 +24317,8 @@ api_opt_tcp_maxseg_tcp(InitState) ->
{ok, DefMaxSeg} ->
?SEV_IPRINT("maxseg default: ~p", [DefMaxSeg]),
{ok, State#{def_maxseg => DefMaxSeg}};
+ {error, enoprotoopt = Reason} ->
+ {skip, Reason};
{error, _} = ERROR ->
ERROR
end
@@ -31638,10 +32604,12 @@ sc_lc_receive_response_tcp(InitState) ->
sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_lc_recvfrom_response_udp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
- Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ Recv = fun(Sock, To) ->
+ socket:recvfrom(Sock, [], To)
+ end,
InitState = #{domain => inet,
protocol => udp,
recv => Recv},
@@ -31656,10 +32624,12 @@ sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) ->
sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_lc_recvfrom_response_udp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
- Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ Recv = fun(Sock, To) ->
+ socket:recvfrom(Sock, [], To)
+ end,
InitState = #{domain => inet6,
protocol => udp,
recv => Recv},
@@ -31674,7 +32644,7 @@ sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) ->
sc_lc_recvfrom_response_udpL(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_lc_recvfrom_response_udpL,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_unix_domain_socket() end,
fun() ->
Recv = fun(Sock, To) ->
@@ -31713,10 +32683,24 @@ sc_lc_receive_response_udp(InitState) ->
#{desc => "open socket",
cmd => fun(#{domain := Domain, protocol := Proto} = State) ->
Sock = sock_open(Domain, dgram, Proto),
- %% SA = sock_sockname(Sock),
+ {ok, State#{sock => Sock}}
+ end},
+ #{desc => "bind socket",
+ cmd => fun(#{sock := Sock, local_sa := LSA}) ->
+ case sock_bind(Sock, LSA) of
+ ok ->
+ ?SEV_IPRINT("src bound"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("src bind failed: ~p", [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "socket name",
+ cmd => fun(#{sock := Sock} = State) ->
case socket:sockname(Sock) of
{ok, SA} ->
- {ok, State#{sock => Sock, sa => SA}};
+ {ok, State#{sa => SA}};
{error, eafnosupport = Reason} ->
?SEV_IPRINT("Failed get socket name: "
"~n ~p", [Reason]),
@@ -31728,17 +32712,6 @@ sc_lc_receive_response_udp(InitState) ->
ERROR
end
end},
- #{desc => "bind socket",
- cmd => fun(#{sock := Sock, local_sa := LSA}) ->
- case sock_bind(Sock, LSA) of
- ok ->
- ?SEV_IPRINT("src bound"),
- ok;
- {error, Reason} = ERROR ->
- ?SEV_EPRINT("src bind failed: ~p", [Reason]),
- ERROR
- end
- end},
#{desc => "announce ready (init)",
cmd => fun(#{tester := Tester, sock := Sock}) ->
?SEV_ANNOUNCE_READY(Tester, init, Sock),
@@ -32099,8 +33072,11 @@ sc_lc_receive_response_udp(InitState) ->
sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
- tc_try(sc_lc_recvmsg_response_tcp4,
- fun() -> has_support_ipv4() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet,
@@ -32117,8 +33093,11 @@ sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) ->
sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
- tc_try(sc_recvmsg_response_tcp6,
- fun() -> has_support_ipv6() end,
+ tc_try(?FUNCTION_NAME,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet6,
@@ -32671,7 +33650,7 @@ sc_lc_acceptor_response_tcp(InitState) ->
sc_rc_recv_response_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_rc_recv_response_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
Recv = fun(Sock) -> socket:recv(Sock) end,
@@ -32689,7 +33668,7 @@ sc_rc_recv_response_tcp4(_Config) when is_list(_Config) ->
sc_rc_recv_response_tcp6(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_rc_recv_response_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
Recv = fun(Sock) -> socket:recv(Sock) end,
@@ -32707,7 +33686,7 @@ sc_rc_recv_response_tcp6(_Config) when is_list(_Config) ->
sc_rc_recv_response_tcpL(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_rc_recv_response_tcpL,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_unix_domain_socket() end,
fun() ->
Recv = fun(Sock) -> socket:recv(Sock) end,
@@ -32865,6 +33844,8 @@ sc_rc_receive_response_tcp(InitState) ->
?SEV_ANNOUNCE_READY(Tester, accept),
ok
end},
+
+
#{desc => "await continue (recv)",
cmd => fun(#{tester := Tester} = _State) ->
?SEV_AWAIT_CONTINUE(Tester, tester, recv)
@@ -32885,19 +33866,31 @@ sc_rc_receive_response_tcp(InitState) ->
ok
end},
#{desc => "await ready from handler 1 (recv)",
- cmd => fun(#{tester := Tester, handler1 := Pid} = _State) ->
- case ?SEV_AWAIT_READY(Pid, handler1, recv,
- [{tester, Tester}]) of
+ cmd => fun(#{tester := Tester,
+ handler1 := Pid1,
+ handler2 := Pid2,
+ handler3 := Pid3} = _State) ->
+ case ?SEV_AWAIT_READY(Pid1, handler1, recv,
+ [{tester, Tester},
+ {handler2, Pid2},
+ {handler3, Pid3}]) of
{ok, Result} ->
Result;
- {error, _} = ERROR ->
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: "
+ "~n ~p", [Reason]),
ERROR
end
end},
#{desc => "await ready from handler 2 (recv)",
- cmd => fun(#{tester := Tester, handler2 := Pid} = _State) ->
- case ?SEV_AWAIT_READY(Pid, handler2, recv,
- [{tester, Tester}]) of
+ cmd => fun(#{tester := Tester,
+ handler1 := Pid1,
+ handler2 := Pid2,
+ handler3 := Pid3} = _State) ->
+ case ?SEV_AWAIT_READY(Pid2, handler2, recv,
+ [{tester, Tester},
+ {handler1, Pid1},
+ {handler3, Pid3}]) of
{ok, Result} ->
Result;
{error, _} = ERROR ->
@@ -32905,9 +33898,14 @@ sc_rc_receive_response_tcp(InitState) ->
end
end},
#{desc => "await ready from handler 3 (recv)",
- cmd => fun(#{tester := Tester, handler3 := Pid} = _State) ->
- case ?SEV_AWAIT_READY(Pid, handler3, recv,
- [{tester, Tester}]) of
+ cmd => fun(#{tester := Tester,
+ handler1 := Pid1,
+ handler2 := Pid2,
+ handler3 := Pid3} = _State) ->
+ case ?SEV_AWAIT_READY(Pid3, handler3, recv,
+ [{tester, Tester},
+ {handler1, Pid1},
+ {handler2, Pid2}]) of
{ok, Result} ->
Result;
{error, _} = ERROR ->
@@ -33464,8 +34462,8 @@ sc_rc_receive_response_tcp(InitState) ->
i("await evaluator"),
ok = ?SEV_AWAIT_FINISH([Server,
- Client1, Client2, Client3,
- Tester]).
+ Client1, Client2, Client3,
+ Tester]).
sc_rc_tcp_client_start(Node) ->
@@ -33608,14 +34606,20 @@ sc_rc_tcp_handler_recv(Recv, Sock) ->
try Recv(Sock) of
{error, closed} ->
ok;
- {ok, _} ->
- ?SEV_IPRINT("unexpected success"),
+ {ok, Data} ->
+ ?SEV_IPRINT("unexpected success: "
+ "~n (Unexp) Data: ~p"
+ "~n Socket Info: ~p", [Data, socket:info(Sock)]),
{error, unexpected_success};
{error, Reason} = ERROR ->
?SEV_IPRINT("receive error: "
"~n ~p", [Reason]),
ERROR
catch
+ error:notsup = Error:Stack ->
+ ?SEV_IPRINT("receive ~w error: skip"
+ "~n Stack: ~p", [Error, Stack]),
+ exit({skip, Error});
C:E:S ->
?SEV_IPRINT("receive failure: "
"~n Class: ~p"
@@ -33699,7 +34703,7 @@ sc_rc_recvmsg_response_tcpL(_Config) when is_list(_Config) ->
sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(30)),
- tc_try(sc_rs_recv_send_shutdown_receive_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
MsgData = ?DATA,
@@ -33726,7 +34730,7 @@ sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
%% Socket is IPv6.
sc_rs_recv_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
- tc_try(sc_rs_recv_send_shutdown_receive_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
?TT(?SECS(10)),
@@ -33755,7 +34759,7 @@ sc_rs_recv_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
sc_rs_recv_send_shutdown_receive_tcpL(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
- tc_try(sc_rs_recv_send_shutdown_receive_tcpL,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_unix_domain_socket() end,
fun() ->
MsgData = ?DATA,
@@ -34480,11 +35484,14 @@ sc_rs_tcp_client_connect(Sock, ServerSA) ->
sc_rs_tcp_client_send(Sock, Send, Data) ->
i("sc_rs_tcp_client_send -> entry"),
- case Send(Sock, Data) of
+ try Send(Sock, Data) of
ok ->
ok;
{error, Reason} ->
exit({send, Reason})
+ catch
+ error : notsup = Reason : _ ->
+ exit({skip, Reason})
end.
sc_rs_tcp_client_shutdown(Sock) ->
@@ -34568,6 +35575,8 @@ sc_rs_tcp_handler_recv(Recv, Sock, First) ->
"~n ~p", [Reason]),
ERROR
catch
+ error : notsup = Reason : _ ->
+ exit({skip, Reason});
C:E:S ->
?SEV_IPRINT("receive failure: "
"~n Class: ~p"
@@ -34590,7 +35599,7 @@ sc_rs_tcp_handler_announce_ready(Parent, Slogan, Result) ->
%% Socket is IPv4.
sc_rs_recvmsg_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
- tc_try(sc_rs_recvmsg_send_shutdown_receive_tcp4,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
?TT(?SECS(30)),
@@ -34626,7 +35635,7 @@ sc_rs_recvmsg_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
%% Socket is IPv6.
sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
- tc_try(sc_rs_recvmsg_send_shutdown_receive_tcp6,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
?TT(?SECS(10)),
@@ -34663,7 +35672,7 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) ->
?TT(?SECS(10)),
- tc_try(sc_rs_recvmsg_send_shutdown_receive_tcpL,
+ tc_try(?FUNCTION_NAME,
fun() -> has_support_unix_domain_socket() end,
fun() ->
{ok, CWD} = file:get_cwd(),
@@ -35587,7 +36596,10 @@ traffic_send_and_recv_counters_tcpL(_Config) when is_list(_Config) ->
traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) ->
?TT(?SECS(15)),
tc_try(traffic_sendmsg_and_recvmsg_counters_tcp4,
- fun() -> has_support_ipv4() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
InitState = #{domain => inet,
proto => tcp,
@@ -35616,7 +36628,10 @@ traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) ->
traffic_sendmsg_and_recvmsg_counters_tcp6(_Config) when is_list(_Config) ->
?TT(?SECS(15)),
tc_try(traffic_sendmsg_and_recvmsg_counters_tcp6,
- fun() -> has_support_ipv6() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
InitState = #{domain => inet6,
proto => tcp,
@@ -39199,7 +40214,10 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4(Config) when is_list(Config) ->
Msg = l2b(?TPP_SMALL),
Num = ?TPP_NUM(Config, ?TPP_SMALL_NUM),
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4,
- fun() -> has_support_ipv4() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
?TT(?SECS(20)),
InitState = #{domain => inet,
@@ -39223,7 +40241,10 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(Config) when is_list(Config) ->
Msg = l2b(?TPP_SMALL),
Num = ?TPP_NUM(Config, ?TPP_SMALL_NUM),
tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6,
- fun() -> has_support_ipv6() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
?TT(?SECS(20)),
InitState = #{domain => inet6,
@@ -39271,7 +40292,10 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4(Config) when is_list(Config) -
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_NUM(Config, ?TPP_MEDIUM_NUM),
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4,
- fun() -> has_support_ipv4() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4()
+ end,
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet,
@@ -39295,7 +40319,10 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(Config) when is_list(Config) -
Msg = l2b(?TPP_MEDIUM),
Num = ?TPP_NUM(Config, ?TPP_MEDIUM_NUM),
tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6,
- fun() -> has_support_ipv6() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv6()
+ end,
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet6,
@@ -39343,7 +40370,11 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4(Config) when is_list(Config) ->
Msg = l2b(?TPP_LARGE),
Num = ?TPP_NUM(Config, ?TPP_LARGE_NUM),
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4,
- fun() -> has_support_ipv4(), traffic_ping_pong_large_sendmsg_and_recvmsg_cond() end,
+ fun() ->
+ is_not_windows(),
+ has_support_ipv4(),
+ traffic_ping_pong_large_sendmsg_and_recvmsg_cond()
+ end,
fun() ->
?TT(?SECS(60)),
InitState = #{domain => inet,
@@ -39378,6 +40409,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(Config) when is_list(Config) ->
Num = ?TPP_NUM(Config, ?TPP_LARGE_NUM),
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6,
fun() ->
+ is_not_windows(),
has_support_ipv6(),
traffic_ping_pong_large_sendmsg_and_recvmsg_cond()
end,
@@ -39661,7 +40693,12 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) ->
true ->
ok
end,
- ok = socket:setopt(Sock, otp, rcvbuf, {12, 1024})
+ case os:type() of
+ {win32, nt} ->
+ ok = socket:setopt(Sock, otp, rcvbuf, 12*1024);
+ _ ->
+ ok = socket:setopt(Sock, otp, rcvbuf, {12, 1024})
+ end
end,
traffic_ping_pong_send_and_receive_tcp2(InitState#{buf_init => Fun}).
@@ -40178,36 +41215,63 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
{CSent, CReceived, _, CStart, CStop} = CRes,
STime = tdiff(SStart, SStop),
CTime = tdiff(CStart, CStop),
- %% Note that the sizes we are counting is only
- %% the "data" part of the messages. There is also
- %% fixed header for each message, which of course
- %% is small for the large messages, but comparatively
- %% big for the small messages!
- ?SEV_IPRINT("Results: ~w messages exchanged"
- "~n Server: ~w msec"
- "~n ~.2f msec/message (roundtrip)"
- "~n ~.2f messages/msec (roundtrip)"
- "~n ~w bytes/msec sent"
- "~n ~w bytes/msec received"
- "~n Client: ~w msec"
- "~n ~.2f msec/message (roundtrip)"
- "~n ~.2f messages/msec (roundtrip)"
- "~n ~w bytes/msec sent"
- "~n ~w bytes/msec received",
+ ?SEV_IPRINT("process result data:"
+ "~n Num: ~p"
+ "~n Server Sent: ~p"
+ "~n Server Recv: ~p"
+ "~n Server Start: ~p"
+ "~n Server Stop: ~p"
+ "~n Server Time: ~p"
+ "~n Client Sent: ~p"
+ "~n Client Recv: ~p"
+ "~n Client Start: ~p"
+ "~n Client Stop: ~p"
+ "~n Client Time: ~p",
[Num,
+ SSent, SReceived, SStart, SStop,
STime,
- STime / Num,
- Num / STime,
- SSent div STime,
- SReceived div STime,
- CTime,
- CTime / Num,
- Num / CTime,
- CSent div CTime,
- CReceived div CTime]),
- State1 = maps:remove(server_result, State),
- State2 = maps:remove(client_result, State1),
- {ok, State2}
+ CSent, CReceived, CStart, CStop,
+ CTime]),
+ if
+ (STime =:= 0) orelse
+ (CTime =:= 0) ->
+ {skip,
+ ?F("Invalid exec time(s): ~w , ~w",
+ [STime, CTime])};
+ true ->
+ %% Note that the sizes we are counting is
+ %% only the "data" part of the messages.
+ %% There is also fixed header for each
+ %% message, which of course is small for
+ %% the large messages, but comparatively
+ %% big for the small messages!
+ ?SEV_IPRINT(
+ "Results: ~w messages exchanged"
+ "~n Server: ~w msec"
+ "~n ~.2f msec/message (roundtrip)"
+ "~n ~.2f messages/msec (roundtrip)"
+ "~n ~w bytes/msec sent"
+ "~n ~w bytes/msec received"
+ "~n Client: ~w msec"
+ "~n ~.2f msec/message (roundtrip)"
+ "~n ~.2f messages/msec (roundtrip)"
+ "~n ~w bytes/msec sent"
+ "~n ~w bytes/msec received",
+ [Num,
+ STime,
+ STime / Num,
+ Num / STime,
+ SSent div STime,
+ SReceived div STime,
+ CTime,
+ CTime / Num,
+ Num / CTime,
+ CSent div CTime,
+ CReceived div CTime]),
+ State1 = maps:remove(server_result, State),
+ State2 = maps:remove(client_result, State1),
+ {ok, State2}
+ end
end},
%% Terminations
@@ -40582,14 +41646,6 @@ tpp_tcp_send_msg(Sock, Send, Msg, AccSz) when is_binary(Msg) ->
%% size_of_iovec([B|IOVec], Sz) ->
%% size_of_iovec(IOVec, Sz+size(B)).
-mq() ->
- mq(self()).
-
-mq(Pid) when is_pid(Pid) ->
- Tag = messages,
- {Tag, Msgs} = process_info(Pid, Tag),
- Msgs.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -41098,25 +42154,33 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
num := Num} = State) ->
{CSent, CReceived, CStart, CStop} = CRes,
CTime = tdiff(CStart, CStop),
- %% Note that the sizes we are counting is only
- %% the "data" part of the messages. There is also
- %% fixed header for each message, which of course
- %% is small for the large messages, but comparatively
- %% big for the small messages!
- ?SEV_IPRINT("Results: ~w messages exchanged"
- "~n Client: ~w msec"
- "~n ~.2f msec/message (roundtrip)"
- "~n ~.2f messages/msec (roundtrip)"
- "~n ~w bytes/msec sent"
- "~n ~w bytes/msec received",
- [Num,
- CTime,
- CTime / Num,
- Num / CTime,
- CSent div CTime,
- CReceived div CTime]),
- State1 = maps:remove(client_result, State),
- {ok, State1}
+ if
+ (CTime =:= 0) ->
+ {skip,
+ ?F("Invalid exec time: ~w ", [CTime])};
+ true ->
+ %% Note that the sizes we are counting is
+ %% only the "data" part of the messages.
+ %% There is also fixed header for each
+ %% message, which of course is small for
+ %% the large messages, but comparatively
+ %% big for the small messages!
+ ?SEV_IPRINT(
+ "Results: ~w messages exchanged"
+ "~n Client: ~w msec"
+ "~n ~.2f msec/message (roundtrip)"
+ "~n ~.2f messages/msec (roundtrip)"
+ "~n ~w bytes/msec sent"
+ "~n ~w bytes/msec received",
+ [Num,
+ CTime,
+ CTime / Num,
+ Num / CTime,
+ CSent div CTime,
+ CReceived div CTime]),
+ State1 = maps:remove(client_result, State),
+ {ok, State1}
+ end
end},
%% Terminations
@@ -47877,7 +48941,7 @@ otp16359_maccept_tcp(InitState) ->
%% This test case is to verify that we do not leak monitors.
otp18240_accept_mon_leak_tcp4(Config) when is_list(Config) ->
- ?TT(?SECS(10)),
+ ?TT(?SECS(30)),
tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv4() end,
fun() ->
@@ -47892,7 +48956,7 @@ otp18240_accept_mon_leak_tcp4(Config) when is_list(Config) ->
%% This test case is to verify that we do not leak monitors.
otp18240_accept_mon_leak_tcp6(Config) when is_list(Config) ->
- ?TT(?SECS(10)),
+ ?TT(?SECS(30)),
tc_try(?FUNCTION_NAME,
fun() -> has_support_ipv6() end,
fun() ->
@@ -47918,34 +48982,54 @@ otp18240_accept_tcp(#{domain := Domain,
otp18240_await_acceptor(Pid, Mon) ->
receive
- {'DOWN', Mon, process, Pid, Info} ->
- i("acceptor terminated: "
- "~n ~p", [Info])
+ {'DOWN', Mon, process, Pid, ok} ->
+ i("acceptor successfully terminated"),
+ ok;
+ {'DOWN', Mon, process, Pid, {skip, _} = SKIP} ->
+ i("acceptor successfully terminated"),
+ exit(SKIP);
+ {'DOWN', Mon, process, Pid, Info} ->
+ i("acceptor unexpected termination: "
+ "~n ~p", [Info]),
+ exit({unexpected_result, Info})
after 5000 ->
- i("acceptor info"
+ i("acceptor process (~p) info"
"~n Refs: ~p"
"~n Info: ~p",
- [monitored_by(Pid), erlang:process_info(Pid)]),
+ [Pid, monitored_by(Pid), erlang:process_info(Pid)]),
otp18240_await_acceptor(Pid, Mon)
end.
otp18240_acceptor(Parent, Domain, Proto, NumSocks) ->
i("[acceptor] begin with: "
+ "~n Parent: ~p"
"~n Domain: ~p"
- "~n Protocol: ~p", [Domain, Proto]),
+ "~n Protocol: ~p", [Parent, Domain, Proto]),
MonitoredBy0 = monitored_by(),
- {ok, LSock} = socket:open(Domain, stream, Proto,
- #{use_registry => false}),
- ok = socket:bind(LSock, #{family => Domain, port => 0, addr => any}),
+ ?SLEEP(?SECS(5)),
+ Addr = case ?LIB:which_local_host_info(Domain) of
+ {ok, #{addr := A}} ->
+ A;
+ {error, Reason} ->
+ exit({skip, Reason})
+ end,
+ {ok, LSock} = socket:open(Domain, stream, Proto,
+ #{use_registry => false}),
+ ok = socket:bind(LSock, #{family => Domain, addr => Addr, port => 0}),
ok = socket:listen(LSock, NumSocks),
+ ?SLEEP(?SECS(5)),
MonitoredBy1 = monitored_by(),
- [LSockMon] = MonitoredBy1 -- MonitoredBy0,
i("[acceptor]: listen socket created"
- "~n Montored By before listen socket: ~p"
- "~n Montored By after listen socket: ~p"
- "~n Listen Socket Monitor: ~p"
- "~n Listen Socket info: ~p",
- [MonitoredBy0, MonitoredBy1, LSockMon, socket:info(LSock)]),
+ "~n 'Montored By' before listen socket: ~p"
+ "~n 'Montored By' after listen socket: ~p",
+ [MonitoredBy0, MonitoredBy1]),
+
+ [LSockMon] = MonitoredBy1 -- MonitoredBy0,
+
+ i("[acceptor]: "
+ "~n Listen Socket Monitor: ~p"
+ "~n Listen Socket info: ~p",
+ [LSockMon, socket:info(LSock)]),
{ok, #{port := Port}} = socket:sockname(LSock),
@@ -47953,7 +49037,7 @@ otp18240_acceptor(Parent, Domain, Proto, NumSocks) ->
_Clients = [spawn_link(fun() ->
otp18240_client(CID,
Domain, Proto,
- Port)
+ Addr, Port)
end) || CID <- lists:seq(1, NumSocks)],
i("[acceptor] accept ~w connections", [NumSocks]),
@@ -47987,26 +49071,49 @@ otp18240_acceptor(Parent, Domain, Proto, NumSocks) ->
end.
-otp18240_client(ID, Domain, Proto, PortNo) ->
+otp18240_client(ID, Domain, Proto, Addr, PortNo) ->
i("[connector ~w] try create connector socket", [ID]),
{ok, Sock} = socket:open(Domain, stream, Proto, #{use_registry => false}),
- ok = socket:bind(Sock, #{family => Domain, port => 0, addr => any}),
+ ok = socket:bind(Sock, #{family => Domain, addr => Addr, port => 0}),
%% ok = socket:setopt(Sock, otp, debug, true),
i("[connector ~w] try connect", [ID]),
- ok = socket:connect(Sock, #{family => Domain, addr => any, port => PortNo}),
- i("[connector ~w] connected - now try recv", [ID]),
- case socket:recv(Sock) of
- {ok, Data} ->
- i("[connector ~w] received unexpected data: "
- "~n ~p", [ID, Data]),
- (catch socket:close(Sock)),
- exit('unexpected data');
- {error, closed} ->
- i("[connector ~w] expected socket close", [ID]);
- {error, Reason} ->
- i("[connector ~w] unexpected error when reading: "
- "~n ~p", [ID, Reason]),
- (catch socket:close(Sock))
+ case socket:connect(Sock,
+ #{family => Domain, addr => Addr, port => PortNo}) of
+ ok ->
+ i("[connector ~w] connected - now try recv", [ID]),
+ case socket:recv(Sock) of
+ {ok, Data} ->
+ i("[connector ~w] received unexpected data: "
+ "~n ~p", [ID, Data]),
+ (catch socket:close(Sock)),
+ exit('unexpected data');
+ {error, closed} ->
+ i("[connector ~w] expected socket close", [ID]);
+ {error, Reason} ->
+ i("[connector ~w] unexpected error when reading: "
+ "~n ~p", [ID, Reason]),
+ (catch socket:close(Sock))
+ end;
+ {error, {completion_status, #{info := invalid_netname = R} = Reason}} ->
+ i("[connector ~w] failed connecting: "
+ "~n ~p", [ID, Reason]),
+ (catch socket:close(Sock)),
+ exit({skip, R});
+ {error, {completion_status, invalid_netname = Reason}} ->
+ i("[connector ~w] failed connecting: "
+ "~n ~p", [ID, Reason]),
+ (catch socket:close(Sock)),
+ exit({skip, Reason});
+ {error, enetunreach = Reason} ->
+ i("[connector ~w] failed connecting: "
+ "~n ~p", [ID, Reason]),
+ (catch socket:close(Sock)),
+ exit({skip, Reason});
+
+ {error, Reason} ->
+ i("[connector ~w] failed connecting: "
+ "~n ~p", [ID, Reason]),
+ (catch socket:close(Sock))
end,
i("[connector ~w] done", [ID]),
ok.
@@ -48477,11 +49584,19 @@ is_not_netbsd() ->
is_not_darwin() ->
is_not_platform(darwin, "Darwin").
+is_not_windows() ->
+ case os:type() of
+ {win32, nt} ->
+ skip("This does not work on Windows");
+ _ ->
+ ok
+ end.
+
is_not_platform(Platform, PlatformStr)
when is_atom(Platform) andalso is_list(PlatformStr) ->
case os:type() of
- {unix, Platform} ->
- skip("This does not work on " ++ PlatformStr);
+ {unix, Platform} ->
+ skip("This does not work on " ++ PlatformStr);
_ ->
ok
end.
@@ -48859,6 +49974,16 @@ start_node(Name, Timeout) when is_integer(Timeout) andalso (Timeout > 0) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mq() ->
+ mq(self()).
+
+mq(Pid) when is_pid(Pid) ->
+ {messages, MQ} = process_info(Pid, messages),
+ MQ.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
nowait(Config) ->
case lists:member({select_handle, true}, Config) of
true ->