aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/socket_SUITE.erl
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-10-22 14:20:46 +0200
committerMicael Karlberg <[email protected]>2018-10-22 14:20:46 +0200
commite54fc6d2a4749f637f29e726de55102d37a9dbb1 (patch)
tree4be2202767c04c6d015aa1c52159c4c8f3bad857 /erts/emulator/test/socket_SUITE.erl
parentada0029d11c33cef2b2aabc9ef2902a98f574ffb (diff)
downloadotp-e54fc6d2a4749f637f29e726de55102d37a9dbb1.tar.gz
otp-e54fc6d2a4749f637f29e726de55102d37a9dbb1.tar.bz2
otp-e54fc6d2a4749f637f29e726de55102d37a9dbb1.zip
[socket-nif|test] Add test cases for UDP recvfrom and recvmsg
Add test cases for udp local socket close for UDP recvfrom and recvmsg. OTP-14831
Diffstat (limited to 'erts/emulator/test/socket_SUITE.erl')
-rw-r--r--erts/emulator/test/socket_SUITE.erl583
1 files changed, 575 insertions, 8 deletions
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index 0edcc3eb04..85b8fcce77 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -73,8 +73,12 @@
sc_cpe_socket_cleanup_udp6/1,
sc_lc_recv_response_tcp4/1,
sc_lc_recv_response_tcp6/1,
+ sc_lc_recvfrom_response_udp4/1,
+ sc_lc_recvfrom_response_udp6/1,
sc_lc_recvmsg_response_tcp4/1,
sc_lc_recvmsg_response_tcp6/1,
+ sc_lc_recvmsg_response_udp4/1,
+ sc_lc_recvmsg_response_udp6/1,
sc_lc_acceptor_response_tcp4/1,
sc_lc_acceptor_response_tcp6/1,
sc_rc_recv_response_tcp4/1,
@@ -217,8 +221,13 @@ sc_lc_cases() ->
sc_lc_recv_response_tcp4,
sc_lc_recv_response_tcp6,
+ sc_lc_recvfrom_response_udp4,
+ sc_lc_recvfrom_response_udp6,
+
sc_lc_recvmsg_response_tcp4,
sc_lc_recvmsg_response_tcp6,
+ sc_lc_recvmsg_response_udp4,
+ sc_lc_recvmsg_response_udp6,
sc_lc_acceptor_response_tcp4,
sc_lc_acceptor_response_tcp6
@@ -1238,24 +1247,22 @@ api_opt_simple_otp_controlling_process() ->
i("start tcp (stream) socket"),
ClientInitState1 = #{},
- #ev{pid = Pid1} = Client1 = evaluator_start("tcp-client",
- ClientSeq, ClientInitState1),
+ Client1 = evaluator_start("tcp-client", ClientSeq, ClientInitState1),
TesterInitState1 = #{domain => inet,
type => stream,
protocol => tcp,
- client => Pid1},
+ client => Client1#ev.pid},
Tester1 = evaluator_start("tcp-tester", TesterSeq, TesterInitState1),
i("await tcp evaluator"),
ok = await_evaluator_finish([Tester1, Client1]),
i("start udp (dgram) socket"),
ClientInitState2 = #{},
- #ev{pid = Pid2} = Client2 = evaluator_start("udp-client",
- ClientSeq, ClientInitState2),
+ Client2 = evaluator_start("udp-client", ClientSeq, ClientInitState2),
TesterInitState2 = #{domain => inet,
type => dgram,
protocol => udp,
- client => Pid2},
+ client => Client2#ev.pid},
Tester2 = evaluator_start("udp-tester", TesterSeq, TesterInitState2),
i("await udp evaluator"),
ok = await_evaluator_finish([Tester2, Client2]).
@@ -3605,7 +3612,7 @@ sc_lc_receive_response_tcp(InitState) ->
{'DOWN', _, process, Pid, Reason} ->
ee("Unexpected DOWN regarding cient ~p: "
"~n ~p", [Pid, Reason]),
- {error, {unexpected_exit, acceptor}};
+ {error, {unexpected_exit, client}};
{ready, Pid} ->
ok
end
@@ -3642,7 +3649,7 @@ sc_lc_receive_response_tcp(InitState) ->
{'DOWN', _, process, Pid, Reason} ->
ee("Unexpected DOWN regarding client ~p: "
"~n ~p", [Pid, Reason]),
- {error, {unexpected_exit, acceptor}};
+ {error, {unexpected_exit, client}};
{ready, Pid} ->
ok
end
@@ -3829,6 +3836,525 @@ sc_lc_receive_response_tcp(InitState) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test what happens when a socket is
+%% locally closed while a process is calling the recvfrom function.
+%% Socket is IPv4.
+%%
+
+sc_lc_recvfrom_response_udp4(suite) ->
+ [];
+sc_lc_recvfrom_response_udp4(doc) ->
+ [];
+sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) ->
+ tc_try(sc_lc_recvfrom_response_udp4,
+ fun() ->
+ ?TT(?SECS(30)),
+ Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ InitState = #{domain => inet,
+ type => dgram,
+ protocol => udp,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recv function.
+%% Socket is IPv6.
+
+sc_lc_recvfrom_response_udp6(suite) ->
+ [];
+sc_lc_recvfrom_response_udp6(doc) ->
+ [];
+sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) ->
+ tc_try(sc_lc_recvfrom_response_udp6,
+ fun() ->
+ not_yet_implemented(),
+ ?TT(?SECS(30)),
+ Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+sc_lc_receive_response_udp(InitState) ->
+ PrimServerSeq =
+ [
+ %% *** Init part ***
+ #{desc => "await start",
+ cmd => fun(State) ->
+ receive
+ {start, Tester} ->
+ {ok, State#{tester => Tester}}
+ end
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+ #{desc => "local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LAddr = which_local_addr(Domain),
+ LSA = #{family => Domain, addr => LAddr},
+ {ok, State#{lsa => LSA}}
+ end},
+ #{desc => "open socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ Sock = sock_open(Domain, dgram, udp),
+ SA = sock_sockname(Sock),
+ {ok, State#{sock => Sock, sa => SA}}
+ end},
+ #{desc => "bind socket",
+ cmd => fun(#{sock := Sock, lsa := LSA}) ->
+ sock_bind(Sock, LSA),
+ ok
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{tester := Tester, sock := Sock}) ->
+ Tester ! {ready, self(), Sock},
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (receive)",
+ cmd => fun(#{tester := Tester} = State) ->
+ receive
+ {'DOWN', _, process, Tester, Reason} ->
+ ee("Unexpected DOWN regarding tester ~p: "
+ "~n ~p", [Reason]),
+ {error, {unexpected_exit, tester}};
+ {continue, Tester, Timeout} ->
+ {ok, State#{timeout => Timeout}}
+ end
+ end},
+ #{desc => "receive with timeout",
+ cmd => fun(#{sock := Sock, recv := Recv, timeout := Timeout}) ->
+ case Recv(Sock, Timeout) of
+ {error, timeout} ->
+ ok;
+ {ok, _} ->
+ {error, unexpected_success};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "announce ready (timeout)",
+ cmd => fun(#{tester := Tester}) ->
+ Tester ! {ready, self()},
+ ok
+ end},
+ #{desc => "await continue (close)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ receive
+ {'DOWN', _, process, Tester, Reason} ->
+ ee("Unexpected DOWN regarding tester ~p: "
+ "~n ~p", [Reason]),
+ {error, {unexpected_exit, tester}};
+ {continue, Tester} ->
+ ok
+ end
+ end},
+ #{desc => "close socket",
+ cmd => fun(#{sock := Sock} = State) ->
+ case socket:close(Sock) of
+ ok ->
+ {ok, maps:remove(sock, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "announce ready (closed)",
+ cmd => fun(#{tester := Tester}) ->
+ Tester ! {ready, self()},
+ ok
+ end},
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ receive
+ {'DOWN', _, process, Tester, Reason} ->
+ ee("Unexpected DOWN regarding tester ~p: "
+ "~n ~p", [Reason]),
+ {error, {unexpected_exit, tester}};
+ {terminate, Tester} ->
+ {ok, maps:remove(tester, State)}
+ end
+ end},
+
+ %% *** We are done ***
+ #{desc => "finish",
+ cmd => fun(_) ->
+ {ok, normal}
+ end}
+ ],
+
+ SecServerSeq =
+ [
+ %% *** Init part ***
+ #{desc => "await start",
+ cmd => fun(State) ->
+ receive
+ {start, Tester, Sock} ->
+ {ok, State#{tester => Tester, sock => Sock}}
+ end
+ end},
+ #{desc => "monitor tester",
+ cmd => fun(#{tester := Tester} = _State) ->
+ _MRef = erlang:monitor(process, Tester),
+ ok
+ end},
+ #{desc => "announce ready (init)",
+ cmd => fun(#{tester := Tester}) ->
+ Tester ! {ready, self()},
+ ok
+ end},
+
+ %% The actual test
+ #{desc => "await continue (receive)",
+ cmd => fun(#{tester := Tester} = _State) ->
+ receive
+ {'DOWN', _, process, Tester, Reason} ->
+ ee("Unexpected DOWN regarding tester ~p: "
+ "~n ~p", [Reason]),
+ {error, {unexpected_exit, tester}};
+ {continue, Tester} ->
+ ok
+ end
+ end},
+ #{desc => "receive",
+ cmd => fun(#{sock := Sock, recv := Recv} = State) ->
+ %% ok = socket:setopt(Sock, otp, debug, true),
+ case Recv(Sock, infinity) of
+ {error, closed} ->
+ {ok, maps:remove(sock, State)};
+ {ok, _} ->
+ {error, unexpected_success};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "announce ready (closed)",
+ cmd => fun(#{tester := Tester}) ->
+ Tester ! {ready, self()},
+ ok
+ end},
+
+ %% Termination
+ #{desc => "await terminate (from tester)",
+ cmd => fun(#{tester := Tester} = State) ->
+ receive
+ {'DOWN', _, process, Tester, Reason} ->
+ ee("Unexpected DOWN regarding tester ~p: "
+ "~n ~p", [Reason]),
+ {error, {unexpected_exit, tester}};
+ {terminate, Tester} ->
+ {ok, maps:remove(tester, State)}
+ end
+ end},
+
+ %% *** We are done ***
+ #{desc => "finish",
+ cmd => fun(_) ->
+ {ok, normal}
+ end}
+ ],
+
+
+ TesterSeq =
+ [
+ %% *** Init part ***
+ #{desc => "monitor primary server",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+ #{desc => "monitor secondary server 1",
+ cmd => fun(#{sec_server1 := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+ #{desc => "monitor secondary server 2",
+ cmd => fun(#{sec_server2 := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+ #{desc => "monitor secondary server 3",
+ cmd => fun(#{sec_server3 := Pid} = _State) ->
+ _MRef = erlang:monitor(process, Pid),
+ ok
+ end},
+
+ %% Start the primary server
+ #{desc => "order 'primary server' start",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ Pid ! {start, self()},
+ ok
+ end},
+ #{desc => "await 'primary server' ready (init)",
+ cmd => fun(#{prim_server := Pid} = State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding prim-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, prim_server}};
+ {ready, Pid, Sock} ->
+ {ok, State#{sock => Sock}}
+ end
+ end},
+
+ %% Start the secondary server 1
+ #{desc => "order 'secondary server 1' start",
+ cmd => fun(#{sec_server1 := Pid, sock := Sock} = _State) ->
+ Pid ! {start, self(), Sock},
+ ok
+ end},
+ #{desc => "await 'secondary server 1' ready (init)",
+ cmd => fun(#{sec_server1 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server1}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+
+ %% Start the secondary server 2
+ #{desc => "order 'secondary server 2' start",
+ cmd => fun(#{sec_server2 := Pid, sock := Sock} = _State) ->
+ Pid ! {start, self(), Sock},
+ ok
+ end},
+ #{desc => "await 'secondary server 2' ready (init)",
+ cmd => fun(#{sec_server2 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server1}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+
+ %% Start the secondary server 3
+ #{desc => "order 'secondary server 3' start",
+ cmd => fun(#{sec_server3 := Pid, sock := Sock} = _State) ->
+ Pid ! {start, self(), Sock},
+ ok
+ end},
+ #{desc => "await 'secondary server 3' ready (init)",
+ cmd => fun(#{sec_server3 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server1}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+
+
+ %% The actual test
+ %% Make all the seondary servers continue, with an infinit recvfrom
+ %% and then the prim-server with a timed recvfrom.
+ %% After the prim server notifies us (about the timeout) we order it
+ %% to close the socket, which should cause the all the secondary
+ %% server to return with error-closed.
+
+ #{desc => "order 'secondary server 1' to continue",
+ cmd => fun(#{sec_server1 := Pid} = _State) ->
+ Pid ! {continue, self()},
+ ok
+ end},
+ #{desc => "sleep",
+ cmd => fun(_) ->
+ ?SLEEP(?SECS(1)),
+ ok
+ end},
+ #{desc => "order 'secondary server 2' to continue",
+ cmd => fun(#{sec_server2 := Pid} = _State) ->
+ Pid ! {continue, self()},
+ ok
+ end},
+ #{desc => "sleep",
+ cmd => fun(_) ->
+ ?SLEEP(?SECS(1)),
+ ok
+ end},
+ #{desc => "order 'secondary server 3' to continue",
+ cmd => fun(#{sec_server3 := Pid} = _State) ->
+ Pid ! {continue, self()},
+ ok
+ end},
+ #{desc => "sleep",
+ cmd => fun(_) ->
+ ?SLEEP(?SECS(1)),
+ ok
+ end},
+ #{desc => "order 'primary server' to continue (recvfrom)",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ Pid ! {continue, self(), ?SECS(5)},
+ ok
+ end},
+ #{desc => "await 'primary server' ready (timeout)",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding prim-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, prim_server}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+ #{desc => "order 'primary server' to continue (close)",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ Pid ! {continue, self()},
+ ok
+ end},
+ #{desc => "await 'primary server' ready (closed)",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding prim-server ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, prim_server}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+ #{desc => "await 'secondary server 1' ready (closed)",
+ cmd => fun(#{sec_server1 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server-1 ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server1}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+ #{desc => "await 'secondary server 2' ready (closed)",
+ cmd => fun(#{sec_server2 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server-2 ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server2}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+ #{desc => "await 'secondary server 3' ready (closed)",
+ cmd => fun(#{sec_server3 := Pid} = _State) ->
+ receive
+ {'DOWN', _, process, Pid, Reason} ->
+ ee("Unexpected DOWN regarding sec-server-3 ~p: "
+ "~n ~p", [Pid, Reason]),
+ {error, {unexpected_exit, sec_server3}};
+ {ready, Pid} ->
+ ok
+ end
+ end},
+
+
+ %% Terminations
+ #{desc => "order 'secondary server 3' to terminate",
+ cmd => fun(#{sec_server3 := Pid} = _State) ->
+ Pid ! {terminate, self()},
+ ok
+ end},
+ #{desc => "await 'secondary server 3' termination",
+ cmd => fun(#{sec_server3 := Pid} = State) ->
+ receive
+ {'DOWN', _, process, Pid, _} ->
+ {ok, maps:remove(sec_server3, State)}
+ end
+ end},
+ #{desc => "order 'secondary server 2' to terminate",
+ cmd => fun(#{sec_server2 := Pid} = _State) ->
+ Pid ! {terminate, self()},
+ ok
+ end},
+ #{desc => "await 'secondary server 2' termination",
+ cmd => fun(#{sec_server2 := Pid} = State) ->
+ receive
+ {'DOWN', _, process, Pid, _} ->
+ {ok, maps:remove(sec_server2, State)}
+ end
+ end},
+ #{desc => "order 'secondary server 1' to terminate",
+ cmd => fun(#{sec_server1 := Pid} = _State) ->
+ Pid ! {terminate, self()},
+ ok
+ end},
+ #{desc => "await 'secondary server 1' termination",
+ cmd => fun(#{sec_server1 := Pid} = State) ->
+ receive
+ {'DOWN', _, process, Pid, _} ->
+ {ok, maps:remove(sec_server1, State)}
+ end
+ end},
+ #{desc => "order 'primary server' to terminate",
+ cmd => fun(#{prim_server := Pid} = _State) ->
+ Pid ! {terminate, self()},
+ ok
+ end},
+ #{desc => "await 'primary server' termination",
+ cmd => fun(#{prim_server := Pid} = State) ->
+ receive
+ {'DOWN', _, process, Pid, _} ->
+ {ok, maps:remove(prim_server, State)}
+ end
+ end},
+
+
+ %% *** We are done ***
+ #{desc => "finish",
+ cmd => fun(_) ->
+ {ok, normal}
+ end}
+ ],
+
+
+ i("start 'primary server' evaluator"),
+ PrimSrvInitState = InitState,
+ PrimServer = evaluator_start("prim-server", PrimServerSeq, PrimSrvInitState),
+
+ i("start 'secondary server 1' evaluator"),
+ SecSrvInitState = #{recv => maps:get(recv, InitState)},
+ SecServer1 = evaluator_start("sec-server-1", SecServerSeq, SecSrvInitState),
+
+ i("start 'secondary server 2' evaluator"),
+ SecServer2 = evaluator_start("sec-server-2", SecServerSeq, SecSrvInitState),
+
+ i("start 'secondary server 3' evaluator"),
+ SecServer3 = evaluator_start("sec-server-3", SecServerSeq, SecSrvInitState),
+
+ i("start 'tester' evaluator"),
+ TesterInitState = #{prim_server => PrimServer#ev.pid,
+ sec_server1 => SecServer1#ev.pid,
+ sec_server2 => SecServer2#ev.pid,
+ sec_server3 => SecServer3#ev.pid},
+ Tester = evaluator_start("tester", TesterSeq, TesterInitState),
+
+ i("await evaluator"),
+ ok = await_evaluator_finish([PrimServer,
+ SecServer1, SecServer2, SecServer3,
+ Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
%% remotely closed while the process is calling the recv function.
%% Socket is IPv4.
@@ -3927,6 +4453,47 @@ sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recvmsg function.
+%% Socket is IPv4.
+
+sc_lc_recvmsg_response_udp4(suite) ->
+ [];
+sc_lc_recvmsg_response_udp4(doc) ->
+ [];
+sc_lc_recvmsg_response_udp4(_Config) when is_list(_Config) ->
+ tc_try(sc_lc_recvmsg_response_udp4,
+ fun() ->
+ ?TT(?SECS(10)),
+ Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
+ InitState = #{domain => inet,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recvmsg function.
+%% Socket is IPv6.
+
+sc_lc_recvmsg_response_udp6(suite) ->
+ [];
+sc_lc_recvmsg_response_udp6(doc) ->
+ [];
+sc_lc_recvmsg_response_udp6(_Config) when is_list(_Config) ->
+ tc_try(sc_recvmsg_response_udp6,
+ fun() ->
+ not_yet_implemented(),
+ ?TT(?SECS(10)),
+ Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
+ InitState = #{domain => inet6,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
%% remotely closed while the process is calling the recvmsg function.
%% Socket is IPv4.