From 9e62e908c02988a4d3d8615f61100b9ed6fa7e6c Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Sat, 11 May 2019 13:38:09 +0200 Subject: [esock] Finalize handling of Unix Domain Socket Corrected various issues and added missing stuff. Default protocol is now indicated with the atom 'default' instead of the atom 'null'. Also let the underlying OS decide what protocol is actually the default protocol. OTP-15822 --- erts/emulator/nifs/common/socket_int.h | 1 + erts/emulator/nifs/common/socket_nif.c | 59 ++++++++++++++++++++++-- erts/emulator/test/socket_SUITE.erl | 46 +++++++++++++++++- erts/preloaded/ebin/socket.beam | Bin 70248 -> 70640 bytes erts/preloaded/src/socket.erl | 82 +++++++++++++++++++++------------ 5 files changed, 152 insertions(+), 36 deletions(-) diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h index 38c28a6de5..d6977be5aa 100644 --- a/erts/emulator/nifs/common/socket_int.h +++ b/erts/emulator/nifs/common/socket_int.h @@ -139,6 +139,7 @@ typedef unsigned int BOOLEAN_T; GLOBAL_ATOM_DEF(ctrunc); \ GLOBAL_ATOM_DEF(data); \ GLOBAL_ATOM_DEF(debug); \ + GLOBAL_ATOM_DEF(default); \ GLOBAL_ATOM_DEF(default_send_params); \ GLOBAL_ATOM_DEF(delayed_ack_time); \ GLOBAL_ATOM_DEF(dgram); \ diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index e71c786d3e..7484694cdb 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -528,6 +528,7 @@ typedef union { #define SOCKET_TYPE_SEQPACKET 5 /* protocol */ +#define SOCKET_PROTOCOL_DEFAULT 0 #define SOCKET_PROTOCOL_IP 1 #define SOCKET_PROTOCOL_TCP 2 #define SOCKET_PROTOCOL_UDP 3 @@ -1000,6 +1001,8 @@ static ERL_NIF_TERM nopen(ErlNifEnv* env, int type, int protocol, char* netns); +static BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto); + static ERL_NIF_TERM nbind(ErlNifEnv* env, ESockDescriptor* descP, ESockAddress* sockAddrP, @@ -2644,6 +2647,7 @@ static char str_exsend[] = "exsend"; // failed send GLOBAL_ATOM_DECL(ctrunc); \ GLOBAL_ATOM_DECL(data); \ GLOBAL_ATOM_DECL(debug); \ + GLOBAL_ATOM_DECL(default); \ GLOBAL_ATOM_DECL(default_send_params); \ GLOBAL_ATOM_DECL(delayed_ack_time); \ GLOBAL_ATOM_DECL(dgram); \ @@ -4421,6 +4425,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env, * yet, we must use the global debug flag. */ #if !defined(__WIN32__) + static ERL_NIF_TERM nopen(ErlNifEnv* env, int domain, int type, int protocol, @@ -4428,7 +4433,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, { ESockDescriptor* descP; ERL_NIF_TERM res; - int save_errno = 0; + int proto = protocol, save_errno = 0; SOCKET sock; HANDLE event; #ifdef HAVE_SETNS @@ -4448,11 +4453,24 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, return esock_make_error_errno(env, save_errno); #endif - if ((sock = sock_open(domain, type, protocol)) == INVALID_SOCKET) + if ((sock = sock_open(domain, type, proto)) == INVALID_SOCKET) return esock_make_error_errno(env, sock_errno()); SGDBG( ("SOCKET", "nopen -> open success: %d\r\n", sock) ); + + /* NOTE that if the protocol = 0 (default) and the domain is not + * local (AF_LOCAL) we need to explicitly get the protocol here! + */ + + if ((proto != 0) && (domain != AF_LOCAL)) + if (!nopen_which_protocol(sock, &proto)) { + save_errno = sock_errno(); + while ((sock_close(sock) == INVALID_SOCKET) && (sock_errno() == EINTR)); + return esock_make_error_errno(env, save_errno); + } + + #ifdef HAVE_SETNS if ((netns != NULL) && !restore_network_namespace(current_ns, sock, &save_errno)) @@ -4484,7 +4502,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, descP->state = SOCKET_STATE_OPEN; descP->domain = domain; descP->type = type; - descP->protocol = protocol; + descP->protocol = proto; /* Does this apply to other types? Such as RAW? * Also, is this really correct? Should we not wait for bind? @@ -4521,6 +4539,26 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, return esock_make_ok2(env, res); } + + +static +BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto) +{ + int val; + SOCKOPTLEN_T valSz = sizeof(val); + int res; + + res = sock_getopt(sock, SOL_SOCKET, SO_PROTOCOL, &val, &valSz); + + if (res != 0) { + return FALSE; + } else { + *proto = val; + return TRUE; + } +} + + #endif // if !defined(__WIN32__) @@ -10895,7 +10933,11 @@ ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env, switch (val) { case IPPROTO_IP: - result = esock_make_ok2(env, esock_atom_ip); + if (descP->domain == AF_LOCAL) { + result = esock_make_ok2(env, esock_atom_default); + } else { + result = esock_make_ok2(env, esock_atom_ip); + } break; case IPPROTO_TCP: @@ -11467,7 +11509,10 @@ ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env, } else { switch (val) { case IPPROTO_IP: - result = esock_make_ok2(env, esock_atom_ip); + if (descP->domain == AF_LOCAL) + result = esock_make_ok2(env, esock_atom_default); + else + result = esock_make_ok2(env, esock_atom_ip); break; case IPPROTO_TCP: @@ -17039,6 +17084,10 @@ BOOLEAN_T eproto2proto(ErlNifEnv* env, } switch (ep) { + case SOCKET_PROTOCOL_DEFAULT: + *proto = 0; // default - note that _IP also has the value 0... + break; + case SOCKET_PROTOCOL_IP: *proto = IPPROTO_IP; break; diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index e3545ccbf9..74a6e2ecde 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -70,6 +70,8 @@ %% *** API Basic *** api_b_open_and_close_udp4/1, api_b_open_and_close_tcp4/1, + api_b_open_and_close_udpL/1, + api_b_open_and_close_tcpL/1, api_b_sendto_and_recvfrom_udp4/1, api_b_sendmsg_and_recvmsg_udp4/1, api_b_send_and_recv_tcp4/1, @@ -588,6 +590,8 @@ api_basic_cases() -> [ api_b_open_and_close_udp4, api_b_open_and_close_tcp4, + api_b_open_and_close_udpL, + api_b_open_and_close_tcpL, api_b_sendto_and_recvfrom_udp4, api_b_sendmsg_and_recvmsg_udp4, api_b_send_and_recv_tcp4, @@ -1508,6 +1512,44 @@ api_b_open_and_close_tcp4(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically open (create) and close an Unix Domain dgram (UDP) socket. +%% With some extra checks... +api_b_open_and_close_udpL(suite) -> + []; +api_b_open_and_close_udpL(doc) -> + []; +api_b_open_and_close_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_b_open_and_close_udpL, + fun() -> + InitState = #{domain => local, + type => dgram, + protocol => default}, + ok = api_b_open_and_close(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically open (create) and close an Unix Domain stream (TCP) socket. +%% With some extra checks... +api_b_open_and_close_tcpL(suite) -> + []; +api_b_open_and_close_tcpL(doc) -> + []; +api_b_open_and_close_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_b_open_and_close_tcpL, + fun() -> + InitState = #{domain => local, + type => stream, + protocol => default}, + ok = api_b_open_and_close(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% api_b_open_and_close(InitState) -> @@ -1665,11 +1707,11 @@ api_b_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) -> end, Recv = fun(Sock) -> %% We have some issues on old darwing... - socket:setopt(Sock, otp, debug, true), + %% socket:setopt(Sock, otp, debug, true), case socket:recvmsg(Sock) of {ok, #{addr := Source, iov := [Data]}} -> - socket:setopt(Sock, otp, debug, false), + %% socket:setopt(Sock, otp, debug, false), {ok, {Source, Data}}; {error, _} = ERROR -> ERROR diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index 27efe10f38..6aa043972c 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 126db66cdd..cdbc79204e 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -602,12 +602,13 @@ %% -define(SOCKET_TYPE_RDM, 4). -define(SOCKET_TYPE_SEQPACKET, 5). --define(SOCKET_PROTOCOL_IP, 1). --define(SOCKET_PROTOCOL_TCP, 2). --define(SOCKET_PROTOCOL_UDP, 3). --define(SOCKET_PROTOCOL_SCTP, 4). --define(SOCKET_PROTOCOL_ICMP, 5). --define(SOCKET_PROTOCOL_IGMP, 6). +-define(SOCKET_PROTOCOL_DEFAULT, 0). +-define(SOCKET_PROTOCOL_IP, 1). +-define(SOCKET_PROTOCOL_TCP, 2). +-define(SOCKET_PROTOCOL_UDP, 3). +-define(SOCKET_PROTOCOL_SCTP, 4). +-define(SOCKET_PROTOCOL_ICMP, 5). +-define(SOCKET_PROTOCOL_IGMP, 6). -define(SOCKET_LISTEN_BACKLOG_DEFAULT, 5). @@ -1006,12 +1007,18 @@ supports(_Key1, _Key2, _Key3) -> Reason :: term(). open(Domain, Type) -> - open(Domain, Type, null). + open(Domain, Type, default). -spec open(Domain, Type, Protocol) -> {ok, Socket} | {error, Reason} when + Domain :: local, + Type :: stream | dgram, + Protocol :: default, + Socket :: socket(), + Reason :: term(); + (Domain, Type, Protocol) -> {ok, Socket} | {error, Reason} when Domain :: domain(), Type :: type(), - Protocol :: null | protocol(), + Protocol :: default | protocol(), Socket :: socket(), Reason :: term(). @@ -1019,17 +1026,23 @@ open(Domain, Type, Protocol) -> open(Domain, Type, Protocol, #{}). -spec open(Domain, Type, Protocol, Extra) -> {ok, Socket} | {error, Reason} when + Domain :: local, + Type :: stream | dgram, + Protocol :: default, + Extra :: map(), + Socket :: socket(), + Reason :: term(); + (Domain, Type, Protocol, Extra) -> {ok, Socket} | {error, Reason} when Domain :: domain(), Type :: type(), - Protocol :: null | protocol(), + Protocol :: default | protocol(), Extra :: map(), Socket :: socket(), Reason :: term(). -open(Domain, Type, Protocol0, Extra) when is_map(Extra) -> +open(Domain, Type, Protocol, Extra) when is_map(Extra) -> try begin - Protocol = default_protocol(Protocol0, Type), EDomain = enc_domain(Domain), EType = enc_type(Domain, Type), EProtocol = enc_protocol(Type, Protocol), @@ -1052,15 +1065,6 @@ open(Domain, Type, Protocol0, Extra) when is_map(Extra) -> {error, Reason} end. -%% Note that this is just a convenience function for when the protocol was -%% not specified. If its actually specified, then that will be selected. -%% Also, this only works for the some of the type's (stream, dgram and -%% seqpacket). -default_protocol(null, stream) -> tcp; -default_protocol(null, dgram) -> udp; -default_protocol(null, seqpacket) -> sctp; -default_protocol(null, Type) -> throw({error, {no_default_protocol, Type}}); -default_protocol(Protocol, _) -> Protocol. %% =========================================================================== @@ -2355,7 +2359,7 @@ peername(#socket{ref = SockRef}) -> enc_domain(local) -> ?SOCKET_DOMAIN_LOCAL; enc_domain(inet) -> ?SOCKET_DOMAIN_INET; enc_domain(inet6) -> ?SOCKET_DOMAIN_INET6; -enc_domain(Domain) -> throw({error, {invalid_domain, Domain}}). +enc_domain(Domain) -> invalid_domain(Domain). -spec enc_type(Domain, Type) -> non_neg_integer() when Domain :: domain(), @@ -2366,22 +2370,23 @@ enc_type(_, stream) -> ?SOCKET_TYPE_STREAM; enc_type(_, dgram) -> ?SOCKET_TYPE_DGRAM; enc_type(_, raw) -> ?SOCKET_TYPE_RAW; enc_type(_, seqpacket) -> ?SOCKET_TYPE_SEQPACKET; -enc_type(_, Type) -> throw({error, {invalid_type, Type}}). +enc_type(_, Type) -> invalid_type(Type). -spec enc_protocol(Type, Protocol) -> non_neg_integer() | {raw, non_neg_integer()} when Type :: type(), Protocol :: protocol(). -enc_protocol(dgram, ip) -> ?SOCKET_PROTOCOL_IP; -enc_protocol(stream, tcp) -> ?SOCKET_PROTOCOL_TCP; -enc_protocol(dgram, udp) -> ?SOCKET_PROTOCOL_UDP; -enc_protocol(seqpacket, sctp) -> ?SOCKET_PROTOCOL_SCTP; -enc_protocol(raw, icmp) -> ?SOCKET_PROTOCOL_ICMP; -enc_protocol(raw, igmp) -> ?SOCKET_PROTOCOL_IGMP; +enc_protocol(_, default) -> ?SOCKET_PROTOCOL_DEFAULT; +enc_protocol(dgram, ip) -> ?SOCKET_PROTOCOL_IP; +enc_protocol(stream, tcp) -> ?SOCKET_PROTOCOL_TCP; +enc_protocol(dgram, udp) -> ?SOCKET_PROTOCOL_UDP; +enc_protocol(seqpacket, sctp) -> ?SOCKET_PROTOCOL_SCTP; +enc_protocol(raw, icmp) -> ?SOCKET_PROTOCOL_ICMP; +enc_protocol(raw, igmp) -> ?SOCKET_PROTOCOL_IGMP; enc_protocol(raw, {raw, P} = RAW) when is_integer(P) -> RAW; enc_protocol(Type, Proto) -> - throw({error, {invalid_protocol, {Type, Proto}}}). + invalid_protocol(Type, Proto). -spec enc_send_flags(Flags) -> non_neg_integer() when @@ -3510,6 +3515,25 @@ tdiff(T1, T2) -> %% %% =========================================================================== +-spec invalid_domain(Domain) -> no_return() when + Domain :: term(). + +invalid_domain(Domain) -> + error({invalid_domain, Domain}). + +-spec invalid_type(Type) -> no_return() when + Type :: term(). + +invalid_type(Type) -> + error({invalid_type, Type}). + +-spec invalid_protocol(Type, Proto) -> no_return() when + Type :: term(), + Proto :: term(). + +invalid_protocol(Type, Proto) -> + error({invalid_protocol, {Type, Proto}}). + -spec not_supported(What) -> no_return() when What :: term(). -- cgit v1.2.3 From 39e137878aa5d1f745cf3c343429fe9de47ed1be Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 12:55:03 +0200 Subject: [esock|test] Add plain (stream) send and recv test case for local Add a plain send and recv test case for a unix domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 224 +++++++++++++++++++++++------------- 1 file changed, 146 insertions(+), 78 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 74a6e2ecde..639dfcd14d 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -75,6 +75,7 @@ api_b_sendto_and_recvfrom_udp4/1, api_b_sendmsg_and_recvmsg_udp4/1, api_b_send_and_recv_tcp4/1, + api_b_send_and_recv_tcpL/1, api_b_sendmsg_and_recvmsg_tcp4/1, %% *** API Options *** @@ -595,6 +596,7 @@ api_basic_cases() -> api_b_sendto_and_recvfrom_udp4, api_b_sendmsg_and_recvmsg_udp4, api_b_send_and_recv_tcp4, + api_b_send_and_recv_tcpL, api_b_sendmsg_and_recvmsg_tcp4 ]. @@ -1523,6 +1525,7 @@ api_b_open_and_close_udpL(doc) -> api_b_open_and_close_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_open_and_close_udpL, + fun() -> supports_unix_domain_socket() end, fun() -> InitState = #{domain => local, type => dgram, @@ -1542,6 +1545,7 @@ api_b_open_and_close_tcpL(doc) -> api_b_open_and_close_tcpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_open_and_close_tcpL, + fun() -> supports_unix_domain_socket() end, fun() -> InitState = #{domain => local, type => stream, @@ -1731,8 +1735,7 @@ api_b_send_and_recv_udp(InitState) -> [ #{desc => "local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "open src socket", @@ -1838,6 +1841,36 @@ api_b_send_and_recv_tcp4(_Config) when is_list(_Config) -> socket:recv(Sock) end, InitState = #{domain => inet, + type => stream, + proto => tcp, + send => Send, + recv => Recv}, + ok = api_b_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically send and receive using the "common" functions (send and recv) +%% on an IPv4 TCP (stream) socket. +api_b_send_and_recv_tcpL(suite) -> + []; +api_b_send_and_recv_tcpL(doc) -> + []; +api_b_send_and_recv_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_b_send_and_recv_tcpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + Send = fun(Sock, Data) -> + socket:send(Sock, Data) + end, + Recv = fun(Sock) -> + socket:recv(Sock) + end, + InitState = #{domain => local, + type => stream, + proto => default, send => Send, recv => Recv}, ok = api_b_send_and_recv_tcp(InitState) @@ -1870,6 +1903,8 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> end end, InitState = #{domain => inet, + type => stream, + proto => tcp, send => Send, recv => Recv}, ok = api_b_send_and_recv_tcp(InitState) @@ -1897,13 +1932,14 @@ api_b_send_and_recv_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, + type := Type, + proto := Proto} = State) -> + case socket:open(Domain, Type, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -1911,9 +1947,19 @@ api_b_send_and_recv_tcp(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, lsa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + lsa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, lsa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> + ?SEV_IPRINT("bound to port: ~w", [Port]), {ok, State#{lport => Port}}; {error, _} = ERROR -> ERROR @@ -1924,7 +1970,12 @@ api_b_send_and_recv_tcp(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, lsa := #{path := Path}}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Path), + ok; + (#{tester := Tester, lport := Port}) -> + %% This is actually not used for unix domain socket ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, @@ -1988,7 +2039,20 @@ api_b_send_and_recv_tcp(InitState) -> end end}, #{desc => "close connection socket", - cmd => fun(#{csock := Sock}) -> + cmd => fun(#{domain := local, + csock := Sock, + lsa := #{path := Path}}) -> + ok = socket:close(Sock), + case os:cmd("unlink " ++ Path) of + "" -> + ok; + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + ok + end, + ok; + (#{csock := Sock}) -> socket:close(Sock) end}, #{desc => "close listen socket", @@ -2004,7 +2068,10 @@ api_b_send_and_recv_tcp(InitState) -> [ %% *** Wait for start order *** #{desc => "await start (from tester)", - cmd => fun(State) -> + cmd => fun(#{domain := local} = State) -> + {Tester, Path} = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, server_path => Path}}; + (State) -> {Tester, Port} = ?SEV_AWAIT_START(), {ok, State#{tester => Tester, server_port => Port}} end}, @@ -2016,16 +2083,21 @@ api_b_send_and_recv_tcp(InitState) -> %% *** The init part *** #{desc => "which server (local) address", - cmd => fun(#{domain := Domain, server_port := Port} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, - SSA = LSA#{port => Port}, + cmd => fun(#{domain := local = Domain, + server_path := Path} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = #{family => Domain, path => Path}, + {ok, State#{local_sa => LSA, server_sa => SSA}}; + (#{domain := Domain, server_port := Port} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = LSA#{port => Port}, {ok, State#{local_sa => LSA, server_sa => SSA}} end}, #{desc => "create socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, + type := Type, + proto := Proto} = State) -> + case socket:open(Domain, Type, Proto) of {ok, Sock} -> {ok, State#{sock => Sock}}; {error, _} = ERROR -> @@ -2096,7 +2168,20 @@ api_b_send_and_recv_tcp(InitState) -> end end}, #{desc => "close socket", - cmd => fun(#{sock := Sock}) -> + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}}) -> + ok = socket:close(Sock), + case os:cmd("unlink " ++ Path) of + "" -> + ok; + Result -> + ?SEV_IPRINT("unlink result:" + "~n ~s", [Result]), + ok + end, + ok; + (#{sock := Sock} = S) -> socket:close(Sock) end}, @@ -2572,8 +2657,7 @@ api_opt_simple_otp_rcvbuf_option() -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -2818,8 +2902,7 @@ api_opt_simple_otp_rcvbuf_option() -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create socket", @@ -3573,8 +3656,7 @@ api_to_connect_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -3645,8 +3727,7 @@ api_to_connect_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create node", @@ -3796,8 +3877,7 @@ api_to_connect_tcp(InitState) -> end}, #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "order server start", @@ -3948,9 +4028,7 @@ api_toc_tcp_client_await_terminate(Parent) -> end. api_to_connect_tcp_await_timeout(To, ServerSA, Domain, ConLimit) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), NewSock = fun() -> S = case socket:open(Domain, stream, tcp) of {ok, Sock} -> @@ -4062,8 +4140,7 @@ api_to_accept_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "create (listen) socket", @@ -4187,8 +4264,7 @@ api_to_maccept_tcp(InitState) -> end}, #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "create (listen) socket", @@ -4705,8 +4781,7 @@ api_to_receive_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -4824,10 +4899,8 @@ api_to_receive_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain, server_port := Port} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, - SSA = LSA#{port => Port}, + LSA = which_local_socket_addr(Domain), + SSA = LSA#{port => Port}, {ok, State#{local_sa => LSA, server_sa => SSA}} end}, #{desc => "create socket", @@ -5043,8 +5116,7 @@ api_to_receive_udp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "create socket", @@ -5486,8 +5558,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create (listen) socket", @@ -5709,8 +5780,7 @@ sc_lc_receive_response_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create socket", @@ -6097,8 +6167,7 @@ sc_lc_receive_response_udp(InitState) -> %% *** Init part *** #{desc => "local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "open socket", @@ -6606,8 +6675,7 @@ sc_lc_acceptor_response_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{lsa => LSA}} end}, #{desc => "create (listen) socket", @@ -7046,8 +7114,7 @@ sc_rc_receive_response_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -7756,9 +7823,7 @@ sc_rc_tcp_client_create(Domain) -> sc_rc_tcp_client_bind(Sock, Domain) -> i("sc_rc_tcp_client_bind -> entry"), - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -7994,8 +8059,7 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> i("get local address for ~p", [Domain]), - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -8590,9 +8654,7 @@ sc_rs_tcp_client_create(Domain) -> sc_rs_tcp_client_bind(Sock, Domain) -> i("sc_rs_tcp_client_bind -> entry"), - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -8865,8 +8927,7 @@ traffic_send_and_recv_chunks_tcp(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -9750,9 +9811,7 @@ traffic_snr_tcp_client_create(Domain) -> traffic_snr_tcp_client_bind(Sock, Domain) -> i("traffic_snr_tcp_client_bind -> entry"), - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -10423,8 +10482,7 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -11151,9 +11209,7 @@ tpp_tcp_client_sock_open(Domain, BufInit) -> end. tpp_tcp_client_sock_bind(Sock, Domain) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -11342,8 +11398,7 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> %% *** Init part *** #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, addr => LAddr}, + LSA = which_local_socket_addr(Domain), {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", @@ -12049,9 +12104,7 @@ tpp_udp_sock_open(Domain, BufInit) -> end. tpp_udp_sock_bind(Sock, Domain) -> - LAddr = which_local_addr(Domain), - LSA = #{family => Domain, - addr => LAddr}, + LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -17941,13 +17994,19 @@ local_host() -> end. +which_local_socket_addr(local = Domain) -> + #{family => Domain, + path => ?LIB:f("/tmp/socket_~w", [erlang:unique_integer()])}; + %% This gets the local address (not 127.0...) %% We should really implement this using the (new) net module, %% but until that gets the necessary functionality... -which_local_addr(Domain) -> +which_local_socket_addr(Domain) -> case inet:getifaddrs() of {ok, IFL} -> - which_addr(Domain, IFL); + Addr = which_addr(Domain, IFL), + #{family => Domain, + addr => Addr}; {error, Reason} -> ?FAIL({inet, getifaddrs, Reason}) end. @@ -17983,6 +18042,15 @@ which_addr2(Domain, [_|IFO]) -> %% Here are all the *general* test vase condition functions. +supports_unix_domain_socket() -> + case os:type() of + {win32, _} -> + {skip, "Not supported"}; + _ -> + ok + end. + + %% The idea is that this function shall test if the test host has %% support for IPv6. If not, there is no point in running IPv6 tests. %% Currently we just skip. -- cgit v1.2.3 From 80e72ee3ddf73119618277c05df724b01ffdf18a Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 13:07:55 +0200 Subject: [esock|test] Add (stream) sendmsg and recvmsg test case for local Add a sendmsg and recvmsg test case for a unix domain (stream) socket. Found and fixed a bug for the return value for the address field for family 'local' (encoded as 'inet'). OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 2 +- erts/emulator/nifs/common/socket_util.c | 2 +- erts/emulator/test/socket_SUITE.erl | 41 +++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 7484694cdb..d8203f3b91 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -15180,7 +15180,7 @@ char* encode_msghdr(ErlNifEnv* env, "\r\n read: %d" "\r\n", read) ); - /* The address is not used if we are connected, + /* The address is not used if we are connected (unless family is 'local'), * so check (length = 0) before we try to encodel */ if (msgHdrP->msg_namelen != 0) { diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c index a61cfc75ef..4ba48afcfa 100644 --- a/erts/emulator/nifs/common/socket_util.c +++ b/erts/emulator/nifs/common/socket_util.c @@ -1656,7 +1656,7 @@ char* make_sockaddr_un(ErlNifEnv* env, ERL_NIF_TERM* sa) { ERL_NIF_TERM keys[] = {esock_atom_family, esock_atom_path}; - ERL_NIF_TERM vals[] = {esock_atom_inet, path}; + ERL_NIF_TERM vals[] = {esock_atom_local, path}; unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM); unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM); diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 639dfcd14d..d4e0d104e3 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -77,6 +77,7 @@ api_b_send_and_recv_tcp4/1, api_b_send_and_recv_tcpL/1, api_b_sendmsg_and_recvmsg_tcp4/1, + api_b_sendmsg_and_recvmsg_tcpL/1, %% *** API Options *** api_opt_simple_otp_options/1, @@ -597,7 +598,8 @@ api_basic_cases() -> api_b_sendmsg_and_recvmsg_udp4, api_b_send_and_recv_tcp4, api_b_send_and_recv_tcpL, - api_b_sendmsg_and_recvmsg_tcp4 + api_b_sendmsg_and_recvmsg_tcp4, + api_b_sendmsg_and_recvmsg_tcpL ]. api_options_cases() -> @@ -1911,6 +1913,41 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically send and receive using the msg functions (sendmsg and recvmsg) +%% on an IPv4 TCP (stream) socket. +api_b_sendmsg_and_recvmsg_tcpL(suite) -> + []; +api_b_sendmsg_and_recvmsg_tcpL(doc) -> + []; +api_b_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_b_sendmsg_and_recvmsg_tcpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + Send = fun(Sock, Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) + end, + Recv = fun(Sock) -> + case socket:recvmsg(Sock) of + {ok, #{addr := #{family := local}, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => local, + type => stream, + proto => default, + send => Send, + recv => Recv}, + ok = api_b_send_and_recv_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% api_b_send_and_recv_tcp(InitState) -> @@ -2181,7 +2218,7 @@ api_b_send_and_recv_tcp(InitState) -> ok end, ok; - (#{sock := Sock} = S) -> + (#{sock := Sock} = _S) -> socket:close(Sock) end}, -- cgit v1.2.3 From b6f949e3e95fd7a908aad64a9f03e7a4e2711286 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 14:31:03 +0200 Subject: [esock|test] Add (dgram) sendto and recvfrom test case for local Add a sendto and recvfrom test case for a unix domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 110 ++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 24 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index d4e0d104e3..a548d81467 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -73,6 +73,7 @@ api_b_open_and_close_udpL/1, api_b_open_and_close_tcpL/1, api_b_sendto_and_recvfrom_udp4/1, + api_b_sendto_and_recvfrom_udpL/1, api_b_sendmsg_and_recvmsg_udp4/1, api_b_send_and_recv_tcp4/1, api_b_send_and_recv_tcpL/1, @@ -595,6 +596,7 @@ api_basic_cases() -> api_b_open_and_close_udpL, api_b_open_and_close_tcpL, api_b_sendto_and_recvfrom_udp4, + api_b_sendto_and_recvfrom_udpL, api_b_sendmsg_and_recvmsg_udp4, api_b_send_and_recv_tcp4, api_b_send_and_recv_tcpL, @@ -1681,6 +1683,34 @@ api_b_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) -> socket:recvfrom(Sock) end, InitState = #{domain => inet, + proto => udp, + send => Send, + recv => Recv}, + ok = api_b_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically send and receive on an IPv4 UDP (dgram) socket using +%% sendto and recvfrom.. +api_b_sendto_and_recvfrom_udpL(suite) -> + []; +api_b_sendto_and_recvfrom_udpL(doc) -> + []; +api_b_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_b_sendto_and_recvfrom_udpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + Send = fun(Sock, Data, Dest) -> + socket:sendto(Sock, Data, Dest) + end, + Recv = fun(Sock) -> + socket:recvfrom(Sock) + end, + InitState = #{domain => local, + proto => default, send => Send, recv => Recv}, ok = api_b_send_and_recv_udp(InitState) @@ -1724,6 +1754,7 @@ api_b_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) -> end end, InitState = #{domain => inet, + proto => udp, send => Send, recv => Recv}, ok = api_b_send_and_recv_udp(InitState) @@ -1736,41 +1767,52 @@ api_b_send_and_recv_udp(InitState) -> Seq = [ #{desc => "local address", - cmd => fun(#{domain := Domain} = State) -> + cmd => fun(#{domain := local = Domain} = State) -> + LSASrc = which_local_socket_addr(Domain), + LSADst = which_local_socket_addr(Domain), + {ok, State#{lsa_src => LSASrc, + lsa_dst => LSADst}}; + (#{domain := Domain} = State) -> LSA = which_local_socket_addr(Domain), - {ok, State#{lsa => LSA}} + {ok, State#{lsa_src => LSA, + lsa_dst => LSA}} end}, + #{desc => "open src socket", - cmd => fun(#{domain := Domain} = State) -> - Sock = sock_open(Domain, dgram, udp), - SASrc = sock_sockname(Sock), - {ok, State#{sock_src => Sock, sa_src => SASrc}} + cmd => fun(#{domain := Domain, + proto := Proto} = State) -> + Sock = sock_open(Domain, dgram, Proto), + {ok, State#{sock_src => Sock}} end}, #{desc => "bind src", - cmd => fun(#{sock_src := Sock, lsa := LSA}) -> + cmd => fun(#{sock_src := Sock, lsa_src := LSA}) -> sock_bind(Sock, LSA), ok end}, #{desc => "sockname src socket", cmd => fun(#{sock_src := Sock} = State) -> SASrc = sock_sockname(Sock), - %% ei("src sockaddr: ~p", [SASrc]), + ?SEV_IPRINT("src sockaddr: " + "~n ~p", [SASrc]), {ok, State#{sa_src => SASrc}} end}, + #{desc => "open dst socket", - cmd => fun(#{domain := Domain} = State) -> - Sock = sock_open(Domain, dgram, udp), + cmd => fun(#{domain := Domain, + proto := Proto} = State) -> + Sock = sock_open(Domain, dgram, Proto), {ok, State#{sock_dst => Sock}} end}, #{desc => "bind dst", - cmd => fun(#{sock_dst := Sock, lsa := LSA}) -> + cmd => fun(#{sock_dst := Sock, lsa_dst := LSA}) -> sock_bind(Sock, LSA), ok end}, #{desc => "sockname dst socket", cmd => fun(#{sock_dst := Sock} = State) -> SADst = sock_sockname(Sock), - %% ei("dst sockaddr: ~p", [SADst]), + ?SEV_IPRINT("dst sockaddr: " + "~n ~p", [SADst]), {ok, State#{sa_dst => SADst}} end}, #{desc => "send req (to dst)", @@ -1808,11 +1850,37 @@ api_b_send_and_recv_udp(InitState) -> end end}, #{desc => "close src socket", - cmd => fun(#{sock_src := Sock}) -> + cmd => fun(#{domain := local, + sock_src := Sock, + lsa_src := #{path := Path}}) -> + ok = socket:close(Sock), + case os:cmd("unlink " ++ Path) of + "" -> + ok; + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + ok + end, + ok; + (#{sock_src := Sock}) -> ok = socket:close(Sock) end}, #{desc => "close dst socket", - cmd => fun(#{sock_dst := Sock}) -> + cmd => fun(#{domain := local, + sock_dst := Sock, + lsa_dst := #{path := Path}}) -> + ok = socket:close(Sock), + case os:cmd("unlink " ++ Path) of + "" -> + ok; + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + ok + end, + ok; + (#{sock_dst := Sock}) -> ok = socket:close(Sock) end}, @@ -1843,7 +1911,6 @@ api_b_send_and_recv_tcp4(_Config) when is_list(_Config) -> socket:recv(Sock) end, InitState = #{domain => inet, - type => stream, proto => tcp, send => Send, recv => Recv}, @@ -1854,7 +1921,7 @@ api_b_send_and_recv_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically send and receive using the "common" functions (send and recv) -%% on an IPv4 TCP (stream) socket. +%% on an Unix Domain (stream) socket (TCP). api_b_send_and_recv_tcpL(suite) -> []; api_b_send_and_recv_tcpL(doc) -> @@ -1871,7 +1938,6 @@ api_b_send_and_recv_tcpL(_Config) when is_list(_Config) -> socket:recv(Sock) end, InitState = #{domain => local, - type => stream, proto => default, send => Send, recv => Recv}, @@ -1905,7 +1971,6 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> end end, InitState = #{domain => inet, - type => stream, proto => tcp, send => Send, recv => Recv}, @@ -1916,7 +1981,7 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically send and receive using the msg functions (sendmsg and recvmsg) -%% on an IPv4 TCP (stream) socket. +%% on an Unix Domain (stream) socket (TCP). api_b_sendmsg_and_recvmsg_tcpL(suite) -> []; api_b_sendmsg_and_recvmsg_tcpL(doc) -> @@ -1940,7 +2005,6 @@ api_b_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> end end, InitState = #{domain => local, - type => stream, proto => default, send => Send, recv => Recv}, @@ -1974,9 +2038,8 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "create listen socket", cmd => fun(#{domain := Domain, - type := Type, proto := Proto} = State) -> - case socket:open(Domain, Type, Proto) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -2132,9 +2195,8 @@ api_b_send_and_recv_tcp(InitState) -> end}, #{desc => "create socket", cmd => fun(#{domain := Domain, - type := Type, proto := Proto} = State) -> - case socket:open(Domain, Type, Proto) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{sock => Sock}}; {error, _} = ERROR -> -- cgit v1.2.3 From 04d84bbf6af32c475c2477217b87259eff264dca Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 14:35:30 +0200 Subject: [esock|test] Add (dgram) sendmsg and recvmsg test case for local Add a sendmsg and recvmsg test case for a unix domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 49 ++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index a548d81467..a7add0bd0d 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -75,6 +75,7 @@ api_b_sendto_and_recvfrom_udp4/1, api_b_sendto_and_recvfrom_udpL/1, api_b_sendmsg_and_recvmsg_udp4/1, + api_b_sendmsg_and_recvmsg_udpL/1, api_b_send_and_recv_tcp4/1, api_b_send_and_recv_tcpL/1, api_b_sendmsg_and_recvmsg_tcp4/1, @@ -598,6 +599,7 @@ api_basic_cases() -> api_b_sendto_and_recvfrom_udp4, api_b_sendto_and_recvfrom_udpL, api_b_sendmsg_and_recvmsg_udp4, + api_b_sendmsg_and_recvmsg_udpL, api_b_send_and_recv_tcp4, api_b_send_and_recv_tcpL, api_b_sendmsg_and_recvmsg_tcp4, @@ -1693,7 +1695,7 @@ api_b_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically send and receive on an IPv4 UDP (dgram) socket using -%% sendto and recvfrom.. +%% sendto and recvfrom. api_b_sendto_and_recvfrom_udpL(suite) -> []; api_b_sendto_and_recvfrom_udpL(doc) -> @@ -1761,6 +1763,51 @@ api_b_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically send and receive on an IPv4 UDP (dgram) socket +%% using sendmsg and recvmsg. +api_b_sendmsg_and_recvmsg_udpL(suite) -> + []; +api_b_sendmsg_and_recvmsg_udpL(doc) -> + []; +api_b_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_b_sendmsg_and_recvmsg_udpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + Send = fun(Sock, Data, Dest) -> + %% We need tests for this, + %% but this is not the place it. + %% CMsgHdr = #{level => ip, + %% type => tos, + %% data => reliability}, + %% CMsgHdrs = [CMsgHdr], + MsgHdr = #{addr => Dest, + %% ctrl => CMsgHdrs, + iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) + end, + Recv = fun(Sock) -> + %% We have some issues on old darwing... + %% socket:setopt(Sock, otp, debug, true), + case socket:recvmsg(Sock) of + {ok, #{addr := Source, + iov := [Data]}} -> + %% socket:setopt(Sock, otp, debug, false), + {ok, {Source, Data}}; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => local, + proto => default, + send => Send, + recv => Recv}, + ok = api_b_send_and_recv_udp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% api_b_send_and_recv_udp(InitState) -> -- cgit v1.2.3 From 0820ab3a939ba69e44c9ca24df92a78fb1f2550b Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 14:45:55 +0200 Subject: [esock|test] Add controlling process test case for local Add controlling process exit test case for Unix Domain (stream and dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 51 +++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index a7add0bd0d..6df64720a6 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -113,8 +113,10 @@ %% *** Socket Closure *** sc_cpe_socket_cleanup_tcp4/1, sc_cpe_socket_cleanup_tcp6/1, + sc_cpe_socket_cleanup_tcpL/1, sc_cpe_socket_cleanup_udp4/1, sc_cpe_socket_cleanup_udp6/1, + sc_cpe_socket_cleanup_udpL/1, sc_lc_recv_response_tcp4/1, sc_lc_recv_response_tcp6/1, @@ -650,13 +652,15 @@ socket_closure_cases() -> ]. %% These cases are all about socket cleanup after the controlling process -%% exits *without* calling socket:close/1. +%% exits *without* explicitly calling socket:close/1. sc_cp_exit_cases() -> [ sc_cpe_socket_cleanup_tcp4, sc_cpe_socket_cleanup_tcp6, + sc_cpe_socket_cleanup_tcpL, sc_cpe_socket_cleanup_udp4, - sc_cpe_socket_cleanup_udp6 + sc_cpe_socket_cleanup_udp6, + sc_cpe_socket_cleanup_udpL ]. %% These cases tests what happens when the socket is closed locally. @@ -5461,6 +5465,27 @@ sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sockets are cleaned up +%% ("removed") when the controlling process terminates (without explicitly +%% calling the close function). For a Unix Domain (stream) socket (TCP). + +sc_cpe_socket_cleanup_tcpL(suite) -> + []; +sc_cpe_socket_cleanup_tcpL(doc) -> + []; +sc_cpe_socket_cleanup_tcpL(_Config) when is_list(_Config) -> + tc_try(sc_cpe_socket_cleanup_tcpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + ?TT(?SECS(5)), + InitState = #{domain => local, + type => stream, + protocol => default}, + ok = sc_cpe_socket_cleanup(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sockets are cleaned up %% ("removed") when the controlling process terminates (without explicitly @@ -5503,6 +5528,28 @@ sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sockets are cleaned up +%% ("removed") when the controlling process terminates (without explicitly +%% calling the close function). For a Unix Domain (dgram) socket (UDP). + +sc_cpe_socket_cleanup_udpL(suite) -> + []; +sc_cpe_socket_cleanup_udpL(doc) -> + []; +sc_cpe_socket_cleanup_udpL(_Config) when is_list(_Config) -> + tc_try(sc_cpe_socket_cleanup_udpL, + fun() -> supports_unix_domain_socket() end, + fun() -> + ?TT(?SECS(5)), + InitState = #{domain => local, + type => dgram, + protocol => default}, + ok = sc_cpe_socket_cleanup(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sc_cpe_socket_cleanup(InitState) -> -- cgit v1.2.3 From b73f63138bb4ea8c92148cb09f8569f9dcf63e9a Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 18:11:05 +0200 Subject: [esock|test] Add local close (plain) recv test case for local Add local close recv response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 189 ++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 53 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 6df64720a6..12481d7043 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -120,6 +120,7 @@ sc_lc_recv_response_tcp4/1, sc_lc_recv_response_tcp6/1, + sc_lc_recv_response_tcpL/1, sc_lc_recvfrom_response_udp4/1, sc_lc_recvfrom_response_udp6/1, sc_lc_recvmsg_response_tcp4/1, @@ -668,6 +669,7 @@ sc_lc_cases() -> [ sc_lc_recv_response_tcp4, sc_lc_recv_response_tcp6, + sc_lc_recv_response_tcpL, sc_lc_recvfrom_response_udp4, sc_lc_recvfrom_response_udp6, @@ -1535,7 +1537,7 @@ api_b_open_and_close_udpL(doc) -> api_b_open_and_close_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_open_and_close_udpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> InitState = #{domain => local, type => dgram, @@ -1555,7 +1557,7 @@ api_b_open_and_close_tcpL(doc) -> api_b_open_and_close_tcpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_open_and_close_tcpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> InitState = #{domain => local, type => stream, @@ -1707,7 +1709,7 @@ api_b_sendto_and_recvfrom_udpL(doc) -> api_b_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_sendto_and_recvfrom_udpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> Send = fun(Sock, Data, Dest) -> socket:sendto(Sock, Data, Dest) @@ -1778,7 +1780,7 @@ api_b_sendmsg_and_recvmsg_udpL(doc) -> api_b_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_sendmsg_and_recvmsg_udpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> Send = fun(Sock, Data, Dest) -> %% We need tests for this, @@ -1980,7 +1982,7 @@ api_b_send_and_recv_tcpL(doc) -> api_b_send_and_recv_tcpL(_Config) when is_list(_Config) -> ?TT(?SECS(10)), tc_try(api_b_send_and_recv_tcpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> Send = fun(Sock, Data) -> socket:send(Sock, Data) @@ -2040,7 +2042,7 @@ api_b_sendmsg_and_recvmsg_tcpL(doc) -> api_b_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> ?TT(?SECS(10)), tc_try(api_b_sendmsg_and_recvmsg_tcpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> Send = fun(Sock, Data) -> MsgHdr = #{iov => [Data]}, @@ -3709,11 +3711,11 @@ api_to_connect_tcp4(suite) -> api_to_connect_tcp4(doc) -> []; api_to_connect_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), Cond = fun() -> api_to_connect_cond() end, tc_try(api_to_connect_tcp4, Cond, fun() -> - ?TT(?SECS(10)), InitState = #{domain => inet, backlog => 1, timeout => 5000, @@ -3766,10 +3768,10 @@ api_to_connect_tcp6(suite) -> api_to_connect_tcp6(doc) -> []; api_to_connect_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_connect_tcp6, fun() -> has_support_ipv6(), api_to_connect_cond() end, fun() -> - ?TT(?SECS(10)), InitState = #{domain => inet6, backlog => 1, timeout => 5000, @@ -4256,9 +4258,9 @@ api_to_accept_tcp4(suite) -> api_to_accept_tcp4(doc) -> []; api_to_accept_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_accept_tcp4, fun() -> - ?TT(?SECS(10)), InitState = #{domain => inet, timeout => 5000}, ok = api_to_accept_tcp(InitState) end). @@ -4273,10 +4275,10 @@ api_to_accept_tcp6(suite) -> api_to_accept_tcp6(doc) -> []; api_to_accept_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_accept_tcp4, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), InitState = #{domain => inet6, timeout => 5000}, ok = api_to_accept_tcp(InitState) end). @@ -4870,9 +4872,9 @@ api_to_recv_tcp4(suite) -> api_to_recv_tcp4(doc) -> []; api_to_recv_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recv_tcp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recv(Sock, 0, To) end, InitState = #{domain => inet, recv => Recv, @@ -4890,12 +4892,12 @@ api_to_recv_tcp6(suite) -> api_to_recv_tcp6(doc) -> []; api_to_recv_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recv_tcp6, fun() -> has_support_ipv6() end, fun() -> case socket:supports(ipv6) of true -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recv(Sock, 0, To) end, @@ -5226,9 +5228,9 @@ api_to_recvfrom_udp4(suite) -> api_to_recvfrom_udp4(doc) -> []; api_to_recvfrom_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvfrom_udp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end, InitState = #{domain => inet, recv => Recv, @@ -5246,10 +5248,10 @@ api_to_recvfrom_udp6(suite) -> api_to_recvfrom_udp6(doc) -> []; api_to_recvfrom_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvfrom_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end, InitState = #{domain => inet6, recv => Recv, @@ -5342,9 +5344,9 @@ api_to_recvmsg_udp4(suite) -> api_to_recvmsg_udp4(doc) -> []; api_to_recvmsg_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvmsg_udp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, InitState = #{domain => inet, recv => Recv, @@ -5362,10 +5364,10 @@ api_to_recvmsg_udp6(suite) -> api_to_recvmsg_udp6(doc) -> []; api_to_recvmsg_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvmsg_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, InitState = #{domain => inet6, recv => Recv, @@ -5383,9 +5385,9 @@ api_to_recvmsg_tcp4(suite) -> api_to_recvmsg_tcp4(doc) -> []; api_to_recvmsg_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvmsg_tcp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, InitState = #{domain => inet, recv => Recv, @@ -5403,10 +5405,10 @@ api_to_recvmsg_tcp6(suite) -> api_to_recvmsg_tcp6(doc) -> []; api_to_recvmsg_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(api_to_recvmsg_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, InitState = #{domain => inet6, recv => Recv, @@ -5434,9 +5436,9 @@ sc_cpe_socket_cleanup_tcp4(suite) -> sc_cpe_socket_cleanup_tcp4(doc) -> []; sc_cpe_socket_cleanup_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_tcp4, fun() -> - ?TT(?SECS(5)), InitState = #{domain => inet, type => stream, protocol => tcp}, @@ -5454,10 +5456,10 @@ sc_cpe_socket_cleanup_tcp6(suite) -> sc_cpe_socket_cleanup_tcp6(doc) -> []; sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(5)), InitState = #{domain => inet6, type => stream, protocol => tcp}, @@ -5475,10 +5477,10 @@ sc_cpe_socket_cleanup_tcpL(suite) -> sc_cpe_socket_cleanup_tcpL(doc) -> []; sc_cpe_socket_cleanup_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_tcpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(5)), InitState = #{domain => local, type => stream, protocol => default}, @@ -5496,9 +5498,9 @@ sc_cpe_socket_cleanup_udp4(suite) -> sc_cpe_socket_cleanup_udp4(doc) -> []; sc_cpe_socket_cleanup_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_udp4, fun() -> - ?TT(?SECS(5)), InitState = #{domain => inet, type => dgram, protocol => udp}, @@ -5517,10 +5519,10 @@ sc_cpe_socket_cleanup_udp6(suite) -> sc_cpe_socket_cleanup_udp6(doc) -> []; sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(5)), InitState = #{domain => inet6, type => dgram, protocol => udp}, @@ -5538,10 +5540,10 @@ sc_cpe_socket_cleanup_udpL(suite) -> sc_cpe_socket_cleanup_udpL(doc) -> []; sc_cpe_socket_cleanup_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), tc_try(sc_cpe_socket_cleanup_udpL, - fun() -> supports_unix_domain_socket() end, + fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(5)), InitState = #{domain => local, type => dgram, protocol => default}, @@ -5693,12 +5695,11 @@ sc_lc_recv_response_tcp4(suite) -> sc_lc_recv_response_tcp4(doc) -> []; sc_lc_recv_response_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_lc_recv_response_tcp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet, - type => stream, protocol => tcp, recv => Recv}, ok = sc_lc_receive_response_tcp(InitState) @@ -5715,19 +5716,40 @@ sc_lc_recv_response_tcp6(suite) -> sc_lc_recv_response_tcp6(doc) -> []; sc_lc_recv_response_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_lc_recv_response_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet6, - type => stream, protocol => tcp, recv => Recv}, ok = sc_lc_receive_response_tcp(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_recv_response_tcpL(suite) -> + []; +sc_lc_recv_response_tcpL(doc) -> + []; +sc_lc_recv_response_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_lc_recv_response_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock) -> socket:recv(Sock) end, + InitState = #{domain => local, + protocol => default, + recv => Recv}, + ok = sc_lc_receive_response_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sc_lc_receive_response_tcp(InitState) -> @@ -5752,13 +5774,12 @@ sc_lc_receive_response_tcp(InitState) -> #{desc => "which local address", cmd => fun(#{domain := Domain} = State) -> LSA = which_local_socket_addr(Domain), - {ok, State#{local_sa => LSA}} + {ok, State#{lsa => LSA}} end}, #{desc => "create (listen) socket", cmd => fun(#{domain := Domain, - type := Type, protocol := Proto} = State) -> - case socket:open(Domain, Type, Proto) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -5766,9 +5787,22 @@ sc_lc_receive_response_tcp(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + lsa := LSA} = _State) -> + ?SEV_IPRINT("bind to LSA: " + "~n ~p", [LSA]), + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, + lsa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> + ?SEV_IPRINT("bound to port: ~w", [Port]), {ok, State#{lport => Port}}; {error, _} = ERROR -> ERROR @@ -5779,7 +5813,12 @@ sc_lc_receive_response_tcp(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, + lsa := #{path := Path}}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Path), + ok; + (#{tester := Tester, lport := Port}) -> ?SEV_ANNOUNCE_READY(Tester, init, Port), ok end}, @@ -5800,7 +5839,8 @@ sc_lc_receive_response_tcp(InitState) -> cmd => fun(#{lsock := LSock} = State) -> case socket:accept(LSock) of {ok, Sock} -> - ?SEV_IPRINT("connection accepted"), + ?SEV_IPRINT("connection accepted: " + "~n ~p", [socket:sockname(Sock)]), {ok, State#{csock => Sock}}; {error, _} = ERROR -> ERROR @@ -5831,9 +5871,8 @@ sc_lc_receive_response_tcp(InitState) -> ?SEV_AWAIT_CONTINUE(Tester, tester, close), ok end}, - #{desc => "close the connection socket", + #{desc => "close connection socket", cmd => fun(#{csock := Sock} = State) -> - %% ok = socket:setopt(Sock, otp, debug, true), case socket:close(Sock) of ok -> {ok, maps:remove(csock, State)}; @@ -5857,8 +5896,24 @@ sc_lc_receive_response_tcp(InitState) -> ERROR end end}, - #{desc => "close socket", - cmd => fun(#{lsock := Sock} = State) -> + #{desc => "close listen socket", + cmd => fun(#{domain := local, + lsock := Sock, + lsa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(lsa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + State2 = maps:remove(lsock, State1), + State3 = maps:remove(lport, State2), + {ok, State3}; + (#{lsock := Sock} = State) -> case socket:close(Sock) of ok -> State1 = maps:remove(lsock, State), @@ -5978,9 +6033,8 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "create socket", cmd => fun(#{domain := Domain, - type := Type, protocol := Proto} = State) -> - case socket:open(Domain, Type, Proto) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{sock => Sock}}; {error, _} = ERROR -> @@ -5989,6 +6043,8 @@ sc_lc_receive_response_tcp(InitState) -> end}, #{desc => "bind socket to local address", cmd => fun(#{sock := Sock, local_sa := LSA} = _State) -> + ?SEV_IPRINT("bind to LSA: " + "~n ~p", [LSA]), case socket:bind(Sock, LSA) of {ok, _} -> ok; @@ -6004,7 +6060,20 @@ sc_lc_receive_response_tcp(InitState) -> %% The actual test #{desc => "await continue (connect)", - cmd => fun(#{tester := Tester, local_sa := LSA} = State) -> + cmd => fun(#{domain := local = Domain, + tester := Tester, + local_sa := LSA} = State) -> + case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of + {ok, ServerPath} -> + ?SEV_IPRINT("Server Path: " + "~n ~s", [ServerPath]), + ServerSA = #{family => Domain, + path => ServerPath}, + {ok, State#{server_sa => ServerSA}}; + {error, _} = ERROR -> + ERROR + end; + (#{tester := Tester, local_sa := LSA} = State) -> case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of {ok, Port} -> ServerSA = LSA#{port => Port}, @@ -6034,7 +6103,21 @@ sc_lc_receive_response_tcp(InitState) -> end end}, #{desc => "close socket", - cmd => fun(#{sock := Sock} = State) -> + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}} = State) -> + sock_close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(local_sa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + {ok, maps:remove(sock, State)}; + (#{sock := Sock} = State) -> sock_close(Sock), {ok, maps:remove(sock, State)} end}, @@ -6081,8 +6164,8 @@ sc_lc_receive_response_tcp(InitState) -> #{desc => "await acceptor ready (init)", cmd => fun(#{acceptor := Pid} = State) -> case ?SEV_AWAIT_READY(Pid, acceptor, init) of - {ok, Port} -> - {ok, State#{lport => Port}}; + {ok, PortOrPath} -> + {ok, State#{server_info => PortOrPath}}; {error, _} = ERROR -> ERROR end @@ -6139,8 +6222,8 @@ sc_lc_receive_response_tcp(InitState) -> end}, ?SEV_SLEEP(?SECS(1)), #{desc => "order client to continue (connect)", - cmd => fun(#{client := Pid, lport := Port} = _State) -> - ?SEV_ANNOUNCE_CONTINUE(Pid, connect, Port), + cmd => fun(#{client := Pid, server_info := Info} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Pid, connect, Info), ok end}, #{desc => "await acceptor ready (accept)", @@ -6307,9 +6390,9 @@ sc_lc_recvfrom_response_udp4(suite) -> sc_lc_recvfrom_response_udp4(doc) -> []; sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), 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, @@ -6329,10 +6412,10 @@ sc_lc_recvfrom_response_udp6(suite) -> sc_lc_recvfrom_response_udp6(doc) -> []; sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_lc_recvfrom_response_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(30)), Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end, InitState = #{domain => inet6, recv => Recv}, @@ -6726,9 +6809,9 @@ sc_lc_recvmsg_response_tcp4(suite) -> sc_lc_recvmsg_response_tcp4(doc) -> []; sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_lc_recvmsg_response_tcp4, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet, type => stream, @@ -6748,10 +6831,10 @@ sc_lc_recvmsg_response_tcp6(suite) -> sc_lc_recvmsg_response_tcp6(doc) -> []; sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_recvmsg_response_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet6, type => stream, @@ -18235,7 +18318,7 @@ which_addr2(Domain, [_|IFO]) -> %% Here are all the *general* test vase condition functions. -supports_unix_domain_socket() -> +has_support_unix_domain_socket() -> case os:type() of {win32, _} -> {skip, "Not supported"}; -- cgit v1.2.3 From 1b64482fb7900101de032fe319524ff1d6fd1b0f Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 18:19:19 +0200 Subject: [esock|test] Add local close recvmsg test case for local (stream) Add local close recvmsg response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 12481d7043..becb50fc18 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -125,6 +125,7 @@ sc_lc_recvfrom_response_udp6/1, sc_lc_recvmsg_response_tcp4/1, sc_lc_recvmsg_response_tcp6/1, + sc_lc_recvmsg_response_tcpL/1, sc_lc_recvmsg_response_udp4/1, sc_lc_recvmsg_response_udp6/1, sc_lc_acceptor_response_tcp4/1, @@ -676,6 +677,7 @@ sc_lc_cases() -> sc_lc_recvmsg_response_tcp4, sc_lc_recvmsg_response_tcp6, + sc_lc_recvmsg_response_tcpL, sc_lc_recvmsg_response_udp4, sc_lc_recvmsg_response_udp6, @@ -5731,7 +5733,7 @@ sc_lc_recv_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 recv function. -%% Socket is IPv6. +%% Socket is Unix Domain (stream) socket. sc_lc_recv_response_tcpL(suite) -> []; @@ -6814,7 +6816,6 @@ sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) -> fun() -> Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet, - type => stream, protocol => tcp, recv => Recv}, ok = sc_lc_receive_response_tcp(InitState) @@ -6837,13 +6838,34 @@ sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) -> fun() -> Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet6, - type => stream, protocol => tcp, recv => Recv}, ok = sc_lc_receive_response_tcp(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 Unix Domain (stream) socket. + +sc_lc_recvmsg_response_tcpL(suite) -> + []; +sc_lc_recvmsg_response_tcpL(doc) -> + []; +sc_lc_recvmsg_response_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_recvmsg_response_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock) -> socket:recvmsg(Sock) end, + InitState = #{domain => local, + protocol => default, + recv => Recv}, + ok = sc_lc_receive_response_tcp(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. -- cgit v1.2.3 From 3a5a0c972ef5843d6de226c39484ec0d3692462d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 18:46:30 +0200 Subject: [esock|test] Add local close recvfrom test case for local (dgram) Add local close recvfrom response test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 77 ++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index becb50fc18..1a8243db38 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -123,6 +123,7 @@ sc_lc_recv_response_tcpL/1, sc_lc_recvfrom_response_udp4/1, sc_lc_recvfrom_response_udp6/1, + sc_lc_recvfrom_response_udpL/1, sc_lc_recvmsg_response_tcp4/1, sc_lc_recvmsg_response_tcp6/1, sc_lc_recvmsg_response_tcpL/1, @@ -674,6 +675,7 @@ sc_lc_cases() -> sc_lc_recvfrom_response_udp4, sc_lc_recvfrom_response_udp6, + sc_lc_recvfrom_response_udpL, sc_lc_recvmsg_response_tcp4, sc_lc_recvmsg_response_tcp6, @@ -6062,9 +6064,8 @@ sc_lc_receive_response_tcp(InitState) -> %% The actual test #{desc => "await continue (connect)", - cmd => fun(#{domain := local = Domain, - tester := Tester, - local_sa := LSA} = State) -> + cmd => fun(#{domain := local = Domain, + tester := Tester} = State) -> case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of {ok, ServerPath} -> ?SEV_IPRINT("Server Path: " @@ -6118,7 +6119,7 @@ sc_lc_receive_response_tcp(InitState) -> "~n ~s", [Result]), State end, - {ok, maps:remove(sock, State)}; + {ok, maps:remove(sock, State1)}; (#{sock := Sock} = State) -> sock_close(Sock), {ok, maps:remove(sock, State)} @@ -6397,7 +6398,6 @@ sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) -> fun() -> 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) @@ -6419,8 +6419,31 @@ sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) -> fun() -> has_support_ipv6() end, fun() -> Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end, - InitState = #{domain => inet6, - recv => Recv}, + InitState = #{domain => inet6, + 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 Unix Domainm (dgram) socket. + +sc_lc_recvfrom_response_udpL(suite) -> + []; +sc_lc_recvfrom_response_udpL(doc) -> + []; +sc_lc_recvfrom_response_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(sc_lc_recvfrom_response_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end, + InitState = #{domain => local, + protocol => default, + recv => Recv}, ok = sc_lc_receive_response_udp(InitState) end). @@ -6449,8 +6472,8 @@ sc_lc_receive_response_udp(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "open socket", - cmd => fun(#{domain := Domain} = State) -> - Sock = sock_open(Domain, dgram, udp), + cmd => fun(#{domain := Domain, protocol := Proto} = State) -> + Sock = sock_open(Domain, dgram, Proto), SA = sock_sockname(Sock), {ok, State#{sock => Sock, sa => SA}} end}, @@ -6496,7 +6519,21 @@ sc_lc_receive_response_udp(InitState) -> ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close) end}, #{desc => "close socket", - cmd => fun(#{sock := Sock} = State) -> + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(local_sa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + {ok, maps:remove(sock, State1)}; + (#{sock := Sock} = State) -> case socket:close(Sock) of ok -> {ok, maps:remove(sock, State)}; @@ -6789,9 +6826,9 @@ sc_lc_receive_response_udp(InitState) -> 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}, + sec_server1 => SecServer1#ev.pid, + sec_server2 => SecServer2#ev.pid, + sec_server3 => SecServer3#ev.pid}, Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator"), @@ -6880,8 +6917,9 @@ sc_lc_recvmsg_response_udp4(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, - InitState = #{domain => inet, - recv => Recv}, + InitState = #{domain => inet, + protocol => udp, + recv => Recv}, ok = sc_lc_receive_response_udp(InitState) end). @@ -6901,8 +6939,9 @@ sc_lc_recvmsg_response_udp6(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(10)), Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, - InitState = #{domain => inet6, - recv => Recv}, + InitState = #{domain => inet6, + protocol => udp, + recv => Recv}, ok = sc_lc_receive_response_udp(InitState) end). @@ -18199,7 +18238,9 @@ sock_bind(Sock, SockAddr) -> {ok, Port} -> Port; {error, Reason} -> - i("sock_bind -> error: ~p", [Reason]), + i("sock_bind -> error: " + "~n SockAddr: ~p" + "~n Reason: ~p", [SockAddr, Reason]), ?FAIL({bind, Reason}) catch C:E:S -> -- cgit v1.2.3 From b82fc1300ac999a56556ba75d8c28271bd10c1f2 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 18:50:44 +0200 Subject: [esock|test] Add local close recvmsg test case for local (dgram) Add local close recvmsg response test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 1a8243db38..b8c3620224 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -129,6 +129,7 @@ sc_lc_recvmsg_response_tcpL/1, sc_lc_recvmsg_response_udp4/1, sc_lc_recvmsg_response_udp6/1, + sc_lc_recvmsg_response_udpL/1, sc_lc_acceptor_response_tcp4/1, sc_lc_acceptor_response_tcp6/1, @@ -682,6 +683,7 @@ sc_lc_cases() -> sc_lc_recvmsg_response_tcpL, sc_lc_recvmsg_response_udp4, sc_lc_recvmsg_response_udp6, + sc_lc_recvmsg_response_udpL, sc_lc_acceptor_response_tcp4, sc_lc_acceptor_response_tcp6 @@ -6947,6 +6949,29 @@ sc_lc_recvmsg_response_udp6(_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 Unix Domain (dgram) socket. + +sc_lc_recvmsg_response_udpL(suite) -> + []; +sc_lc_recvmsg_response_udpL(doc) -> + []; +sc_lc_recvmsg_response_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_recvmsg_response_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end, + InitState = #{domain => local, + protocol => default, + 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 accept function. -- cgit v1.2.3 From f6d27ca5147a9dcea8f027dc89e289afc41a6de9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 13 May 2019 19:00:49 +0200 Subject: [esock|test] Add local close accept test case for local (stream) Add local close accept response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 65 +++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index b8c3620224..fda2669df0 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -132,6 +132,7 @@ sc_lc_recvmsg_response_udpL/1, sc_lc_acceptor_response_tcp4/1, sc_lc_acceptor_response_tcp6/1, + sc_lc_acceptor_response_tcpL/1, sc_rc_recv_response_tcp4/1, sc_rc_recv_response_tcp6/1, @@ -686,7 +687,8 @@ sc_lc_cases() -> sc_lc_recvmsg_response_udpL, sc_lc_acceptor_response_tcp4, - sc_lc_acceptor_response_tcp6 + sc_lc_acceptor_response_tcp6, + sc_lc_acceptor_response_tcpL ]. %% These cases tests what happens when the socket is closed remotely. @@ -6984,11 +6986,10 @@ sc_lc_acceptor_response_tcp4(suite) -> sc_lc_acceptor_response_tcp4(doc) -> []; sc_lc_acceptor_response_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_lc_acceptor_response_tcp4, fun() -> - ?TT(?SECS(10)), InitState = #{domain => inet, - type => stream, protocol => tcp}, ok = sc_lc_acceptor_response_tcp(InitState) end). @@ -7006,17 +7007,38 @@ sc_lc_acceptor_response_tcp6(suite) -> sc_lc_acceptor_response_tcp6(doc) -> []; sc_lc_acceptor_response_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), tc_try(sc_lc_acceptor_response_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), - InitState = #{domain => inet, - type => stream, + InitState = #{domain => inet6, protocol => tcp}, ok = sc_lc_acceptor_response_tcp(InitState) end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test what happens when a socket is +%% locally closed while the process is calling the accept function. +%% We test what happens with a non-controlling_process also, since we +%% git the setup anyway. +%% Socket is Unix Domain (stream) socket. + +sc_lc_acceptor_response_tcpL(suite) -> + []; +sc_lc_acceptor_response_tcpL(doc) -> + []; +sc_lc_acceptor_response_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_lc_acceptor_response_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + protocol => default}, + ok = sc_lc_acceptor_response_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sc_lc_acceptor_response_tcp(InitState) -> @@ -7042,9 +7064,8 @@ sc_lc_acceptor_response_tcp(InitState) -> end}, #{desc => "create (listen) socket", cmd => fun(#{domain := Domain, - type := Type, protocol := Proto} = State) -> - case socket:open(Domain, Type, Proto) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{sock => Sock}}; {error, _} = ERROR -> @@ -7081,8 +7102,8 @@ sc_lc_acceptor_response_tcp(InitState) -> end end}, #{desc => "await connection", - cmd => fun(#{sock := Sock, timeout := Timeout} = _State) -> - case socket:accept(Sock, Timeout) of + cmd => fun(#{sock := LSock, timeout := Timeout} = _State) -> + case socket:accept(LSock, Timeout) of {error, timeout} -> ok; {ok, Sock} -> @@ -7103,7 +7124,25 @@ sc_lc_acceptor_response_tcp(InitState) -> ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close) end}, #{desc => "close socket", - cmd => fun(#{sock := Sock} = State) -> + cmd => fun(#{domain := local, + sock := Sock, + lsa := #{path := Path}} = State) -> + case socket:close(Sock) of + ok -> + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(lsa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + {ok, maps:remove(sock, State1)}; + {error, _} = ERROR -> + ERROR + end; + (#{sock := Sock} = State) -> case socket:close(Sock) of ok -> {ok, maps:remove(sock, State)}; @@ -7418,9 +7457,9 @@ sc_rc_recv_response_tcp4(suite) -> sc_rc_recv_response_tcp4(doc) -> []; sc_rc_recv_response_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_rc_recv_response_tcp4, fun() -> - ?TT(?SECS(30)), Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet, type => stream, @@ -7440,10 +7479,10 @@ sc_rc_recv_response_tcp6(suite) -> sc_rc_recv_response_tcp6(doc) -> []; sc_rc_recv_response_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_rc_recv_response_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet6, type => stream, -- cgit v1.2.3 From f3c463d73daabeeef99fbfb8ea7efd9e994b60aa Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 11:51:55 +0200 Subject: [esock|test] Add remote close (plain) recv test case for local (stream) Add remote close recv response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 94 +++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 14 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index fda2669df0..12f74c60d3 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -136,6 +136,7 @@ sc_rc_recv_response_tcp4/1, sc_rc_recv_response_tcp6/1, + sc_rc_recv_response_tcpL/1, sc_rc_recvmsg_response_tcp4/1, sc_rc_recvmsg_response_tcp6/1, @@ -696,6 +697,7 @@ sc_rc_cases() -> [ sc_rc_recv_response_tcp4, sc_rc_recv_response_tcp6, + sc_rc_recv_response_tcpL, sc_rc_recvmsg_response_tcp4, sc_rc_recvmsg_response_tcp6 @@ -7462,7 +7464,6 @@ sc_rc_recv_response_tcp4(_Config) when is_list(_Config) -> fun() -> Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet, - type => stream, protocol => tcp, recv => Recv}, ok = sc_rc_receive_response_tcp(InitState) @@ -7485,13 +7486,34 @@ sc_rc_recv_response_tcp6(_Config) when is_list(_Config) -> fun() -> Recv = fun(Sock) -> socket:recv(Sock) end, InitState = #{domain => inet6, - type => stream, protocol => tcp, recv => Recv}, ok = sc_rc_receive_response_tcp(InitState) end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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 Unix Domain (stream) socket. + +sc_rc_recv_response_tcpL(suite) -> + []; +sc_rc_recv_response_tcpL(doc) -> + []; +sc_rc_recv_response_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(sc_rc_recv_response_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock) -> socket:recv(Sock) end, + InitState = #{domain => local, + protocol => default, + recv => Recv}, + ok = sc_rc_receive_response_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sc_rc_receive_response_tcp(InitState) -> @@ -7519,8 +7541,8 @@ sc_rc_receive_response_tcp(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, protocol := Proto} = State) -> + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -7528,7 +7550,17 @@ sc_rc_receive_response_tcp(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + lsa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, + local_sa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> {ok, State#{lport => Port}}; @@ -7541,7 +7573,15 @@ sc_rc_receive_response_tcp(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, + local_sa := LSA}) -> + %% Actually we only need to send the path, + %% but to keep it simple, we send the "same" + %% as for non-local. + ?SEV_ANNOUNCE_READY(Tester, init, LSA), + ok; + (#{tester := Tester, local_sa := LSA, lport := Port}) -> ServerSA = LSA#{port => Port}, ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok @@ -7723,7 +7763,25 @@ sc_rc_receive_response_tcp(InitState) -> {ok, State2} end}, #{desc => "close listen socket", - cmd => fun(#{lsock := LSock} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + lsa := #{path := Path}} = State) -> + case socket:close(LSock) of + ok -> + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(lsa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + {ok, maps:remove(lsock, State1)}; + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock} = State) -> case socket:close(LSock) of ok -> {ok, maps:remove(lsock, State)}; @@ -7780,8 +7838,10 @@ sc_rc_receive_response_tcp(InitState) -> ok end}, #{desc => "order remote client to start", - cmd => fun(#{rclient := Client, server_sa := ServerSA}) -> - ?SEV_ANNOUNCE_START(Client, ServerSA), + cmd => fun(#{rclient := Client, + server_sa := ServerSA, + protocol := Proto}) -> + ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}), ok end}, #{desc => "await remote client ready", @@ -8182,9 +8242,9 @@ sc_rc_tcp_client_start(Node) -> sc_rc_tcp_client(Parent) -> sc_rc_tcp_client_init(Parent), - ServerSA = sc_rc_tcp_client_await_start(Parent), + {ServerSA, Proto} = sc_rc_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), - Sock = sc_rc_tcp_client_create(Domain), + Sock = sc_rc_tcp_client_create(Domain, Proto), sc_rc_tcp_client_bind(Sock, Domain), sc_rc_tcp_client_announce_ready(Parent, init), sc_rc_tcp_client_await_continue(Parent, connect), @@ -8207,9 +8267,9 @@ sc_rc_tcp_client_await_start(Parent) -> i("sc_rc_tcp_client_await_start -> entry"), ?SEV_AWAIT_START(Parent). -sc_rc_tcp_client_create(Domain) -> +sc_rc_tcp_client_create(Domain, Proto) -> i("sc_rc_tcp_client_create -> entry"), - case socket:open(Domain, stream, tcp) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> case socket:getopt(Sock, otp, fd) of {ok, FD} -> @@ -18397,9 +18457,15 @@ local_host() -> end. +%% The point of this is to "ensure" that paths from different test runs +%% don't clash. +mk_unique_path() -> + [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), + ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:unique_integer()]). + which_local_socket_addr(local = Domain) -> #{family => Domain, - path => ?LIB:f("/tmp/socket_~w", [erlang:unique_integer()])}; + path => mk_unique_path()}; %% This gets the local address (not 127.0...) %% We should really implement this using the (new) net module, -- cgit v1.2.3 From a056e11b9539ce88b77913579b5b0cd5c49bdd38 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 11:59:47 +0200 Subject: [esock|test] Add remote close recvmsg test case for local (stream) Add remote close recvmsg response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 12f74c60d3..387cc55fa1 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -139,6 +139,7 @@ sc_rc_recv_response_tcpL/1, sc_rc_recvmsg_response_tcp4/1, sc_rc_recvmsg_response_tcp6/1, + sc_rc_recvmsg_response_tcpL/1, sc_rs_recv_send_shutdown_receive_tcp4/1, sc_rs_recv_send_shutdown_receive_tcp6/1, @@ -700,7 +701,8 @@ sc_rc_cases() -> sc_rc_recv_response_tcpL, sc_rc_recvmsg_response_tcp4, - sc_rc_recvmsg_response_tcp6 + sc_rc_recvmsg_response_tcp6, + sc_rc_recvmsg_response_tcpL ]. %% These cases tests what happens when the socket is shutdown/closed remotely @@ -8395,12 +8397,11 @@ sc_rc_recvmsg_response_tcp4(suite) -> sc_rc_recvmsg_response_tcp4(doc) -> []; sc_rc_recvmsg_response_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_rc_recvmsg_response_tcp4, fun() -> - ?TT(?SECS(30)), Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet, - type => stream, protocol => tcp, recv => Recv}, ok = sc_rc_receive_response_tcp(InitState) @@ -8417,19 +8418,40 @@ sc_rc_recvmsg_response_tcp6(suite) -> sc_rc_recvmsg_response_tcp6(doc) -> []; sc_rc_recvmsg_response_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_rc_recvmsg_response_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(10)), Recv = fun(Sock) -> socket:recvmsg(Sock) end, InitState = #{domain => inet6, - type => stream, protocol => tcp, recv => Recv}, ok = sc_rc_receive_response_tcp(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 Unix Domain (stream) socket. + +sc_rc_recvmsg_response_tcpL(suite) -> + []; +sc_rc_recvmsg_response_tcpL(doc) -> + []; +sc_rc_recvmsg_response_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(sc_rc_recvmsg_response_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + Recv = fun(Sock) -> socket:recvmsg(Sock) end, + InitState = #{domain => local, + protocol => default, + recv => Recv}, + ok = sc_rc_receive_response_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test what happens when a socket is %% remotely closed while the process is calling the recv function. -- cgit v1.2.3 From f62837f233cf83b05531138a7328c5026f424600 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 12:30:06 +0200 Subject: [esock|test] Add remote shutdown (plain) recv test case for local (stream) Add remote shutdown(write) recv response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 99 ++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 23 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 387cc55fa1..9349b661fc 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -143,6 +143,7 @@ sc_rs_recv_send_shutdown_receive_tcp4/1, sc_rs_recv_send_shutdown_receive_tcp6/1, + sc_rs_recv_send_shutdown_receive_tcpL/1, sc_rs_recvmsg_send_shutdown_receive_tcp4/1, sc_rs_recvmsg_send_shutdown_receive_tcp6/1, @@ -711,6 +712,7 @@ sc_rs_cases() -> [ sc_rs_recv_send_shutdown_receive_tcp4, sc_rs_recv_send_shutdown_receive_tcp6, + sc_rs_recv_send_shutdown_receive_tcpL, sc_rs_recvmsg_send_shutdown_receive_tcp4, sc_rs_recvmsg_send_shutdown_receive_tcp6 @@ -8462,6 +8464,7 @@ sc_rc_recvmsg_response_tcpL(_Config) when is_list(_Config) -> %% To minimize the chance of "weirdness", we should really have test cases %% where the two sides of the connection is on different machines. But for %% now, we will make do with different VMs on the same host. +%% This would of course not work for Unix Domain sockets. %% sc_rs_recv_send_shutdown_receive_tcp4(suite) -> @@ -8469,9 +8472,9 @@ sc_rs_recv_send_shutdown_receive_tcp4(suite) -> sc_rs_recv_send_shutdown_receive_tcp4(doc) -> []; sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(sc_rs_recv_send_shutdown_receive_tcp4, fun() -> - ?TT(?SECS(30)), MsgData = ?DATA, Recv = fun(Sock) -> socket:recv(Sock) @@ -8480,6 +8483,7 @@ sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) -> socket:send(Sock, Data) end, InitState = #{domain => inet, + proto => tcp, recv => Recv, send => Send, data => MsgData}, @@ -8511,6 +8515,39 @@ sc_rs_recv_send_shutdown_receive_tcp6(_Config) when is_list(_Config) -> socket:send(Sock, Data) end, InitState = #{domain => inet6, + proto => tcp, + recv => Recv, + send => Send, + data => MsgData}, + ok = sc_rs_send_shutdown_receive_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test what happens when a socket is +%% remotely closed while the process is calling the recv function. +%% The remote client sends data, then shutdown(write) and then the +%% reader attempts a recv. +%% Socket is Unix Domain (stream) socket. + +sc_rs_recv_send_shutdown_receive_tcpL(suite) -> + []; +sc_rs_recv_send_shutdown_receive_tcpL(doc) -> + []; +sc_rs_recv_send_shutdown_receive_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_rs_recv_send_shutdown_receive_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + MsgData = ?DATA, + Recv = fun(Sock) -> + socket:recv(Sock) + end, + Send = fun(Sock, Data) -> + socket:send(Sock, Data) + end, + InitState = #{domain => local, + proto => default, recv => Recv, send => Send, data => MsgData}, @@ -8546,8 +8583,8 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -8555,9 +8592,19 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + local_sa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, local_sa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> + ?SEV_IPRINT("bound to port: ~w", [Port]), {ok, State#{lport => Port}}; {error, _} = ERROR -> ERROR @@ -8568,7 +8615,11 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, local_sa := LSA}) -> + ?SEV_ANNOUNCE_READY(Tester, init, LSA), + ok; + (#{tester := Tester, local_sa := LSA, lport := Port}) -> ServerSA = LSA#{port => Port}, ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok @@ -8737,8 +8788,10 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> ok end}, #{desc => "order remote client to start", - cmd => fun(#{rclient := Client, server_sa := ServerSA}) -> - ?SEV_ANNOUNCE_START(Client, ServerSA), + cmd => fun(#{rclient := Client, + proto := Proto, + server_sa := ServerSA}) -> + ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}), ok end}, #{desc => "await remote client ready", @@ -9068,12 +9121,14 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> i("start server evaluator"), ServerInitState = #{domain => maps:get(domain, InitState), + proto => maps:get(proto, InitState), recv => maps:get(recv, InitState)}, Server = ?SEV_START("server", ServerSeq, ServerInitState), i("start client evaluator"), ClientInitState = #{host => local_host(), domain => maps:get(domain, InitState), + proto => maps:get(proto, InitState), send => maps:get(send, InitState)}, Client = ?SEV_START("client", ClientSeq, ClientInitState), @@ -9095,9 +9150,9 @@ sc_rs_tcp_client_start(Node, Send) -> sc_rs_tcp_client(Parent, Send) -> sc_rs_tcp_client_init(Parent), - ServerSA = sc_rs_tcp_client_await_start(Parent), + {ServerSA, Proto} = sc_rs_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), - Sock = sc_rs_tcp_client_create(Domain), + Sock = sc_rs_tcp_client_create(Domain, Proto), sc_rs_tcp_client_bind(Sock, Domain), sc_rs_tcp_client_announce_ready(Parent, init), sc_rs_tcp_client_await_continue(Parent, connect), @@ -9126,9 +9181,9 @@ sc_rs_tcp_client_await_start(Parent) -> i("sc_rs_tcp_client_await_start -> entry"), ?SEV_AWAIT_START(Parent). -sc_rs_tcp_client_create(Domain) -> +sc_rs_tcp_client_create(Domain, Proto) -> i("sc_rs_tcp_client_create -> entry"), - case socket:open(Domain, stream, tcp) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> Sock; {error, Reason} -> @@ -9298,12 +9353,11 @@ sc_rs_recvmsg_send_shutdown_receive_tcp4(_Config) when is_list(_Config) -> MsgHdr = #{iov => [Data]}, socket:sendmsg(Sock, MsgHdr) end, - InitState = #{domain => inet, - type => stream, - protocol => tcp, - recv => Recv, - send => Send, - data => MsgData}, + InitState = #{domain => inet, + proto => tcp, + recv => Recv, + send => Send, + data => MsgData}, ok = sc_rs_send_shutdown_receive_tcp(InitState) end). @@ -9338,12 +9392,11 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) -> MsgHdr = #{iov => [Data]}, socket:sendmsg(Sock, MsgHdr) end, - InitState = #{domain => inet6, - type => stream, - protocol => tcp, - recv => Recv, - send => Send, - data => MsgData}, + InitState = #{domain => inet6, + proto => tcp, + recv => Recv, + send => Send, + data => MsgData}, ok = sc_rs_send_shutdown_receive_tcp(InitState) end). -- cgit v1.2.3 From 5520d83c2677a2dc83c4b15994363d2ddd3b317f Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 12:53:38 +0200 Subject: [esock|test] Add remote shutdown recvmsg test case for local (stream) Add remote shutdown(write) recvmsg response test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 9349b661fc..9fe6016367 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -146,6 +146,7 @@ sc_rs_recv_send_shutdown_receive_tcpL/1, sc_rs_recvmsg_send_shutdown_receive_tcp4/1, sc_rs_recvmsg_send_shutdown_receive_tcp6/1, + sc_rs_recvmsg_send_shutdown_receive_tcpL/1, %% *** Traffic *** traffic_send_and_recv_chunks_tcp4/1, @@ -715,7 +716,8 @@ sc_rs_cases() -> sc_rs_recv_send_shutdown_receive_tcpL, sc_rs_recvmsg_send_shutdown_receive_tcp4, - sc_rs_recvmsg_send_shutdown_receive_tcp6 + sc_rs_recvmsg_send_shutdown_receive_tcp6, + sc_rs_recvmsg_send_shutdown_receive_tcpL ]. @@ -9389,8 +9391,8 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) -> end end, Send = fun(Sock, Data) when is_binary(Data) -> - MsgHdr = #{iov => [Data]}, - socket:sendmsg(Sock, MsgHdr) + MsgHdr = #{iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) end, InitState = #{domain => inet6, proto => tcp, @@ -9401,6 +9403,47 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) -> end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test what happens when a socket is +%% remotely closed while the process is calling the recvmsg function. +%% The remote client sends data, then shutdown(write) and then the +%% reader attempts a recv. +%% Socket is UNix Domain (stream) socket. + +sc_rs_recvmsg_send_shutdown_receive_tcpL(suite) -> + []; +sc_rs_recvmsg_send_shutdown_receive_tcpL(doc) -> + []; +sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(sc_rs_recvmsg_send_shutdown_receive_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + {ok, CWD} = file:get_cwd(), + ?SEV_IPRINT("CWD: ~s", [CWD]), + MsgData = ?DATA, + Recv = fun(Sock) -> + case socket:recvmsg(Sock) of + {ok, #{addr := #{family := local}, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end + end, + Send = fun(Sock, Data) when is_binary(Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) + end, + InitState = #{domain => local, + proto => default, + recv => Recv, + send => Send, + data => MsgData}, + ok = sc_rs_send_shutdown_receive_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the send and recv functions %% behave as expected when sending and/or reading chunks. @@ -18536,7 +18579,8 @@ local_host() -> %% don't clash. mk_unique_path() -> [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), - ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:unique_integer()]). + %% ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:unique_integer()]). + ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:system_time(nanosecond)]). which_local_socket_addr(local = Domain) -> #{family => Domain, -- cgit v1.2.3 From d68540b85cad7c42434f861c2cf624380c392d85 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 13:43:51 +0200 Subject: [esock|test] Add simple plain send and recv test case for local (stream) Add simple (plain) send and recv chunks test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 73 ++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 9fe6016367..339f6161df 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -151,6 +151,7 @@ %% *** Traffic *** traffic_send_and_recv_chunks_tcp4/1, traffic_send_and_recv_chunks_tcp6/1, + traffic_send_and_recv_chunks_tcpL/1, traffic_ping_pong_small_send_and_recv_tcp4/1, traffic_ping_pong_small_send_and_recv_tcp6/1, @@ -725,6 +726,7 @@ traffic_cases() -> [ traffic_send_and_recv_chunks_tcp4, traffic_send_and_recv_chunks_tcp6, + traffic_send_and_recv_chunks_tcpL, traffic_ping_pong_small_send_and_recv_tcp4, traffic_ping_pong_small_send_and_recv_tcp6, @@ -9456,10 +9458,11 @@ traffic_send_and_recv_chunks_tcp4(suite) -> traffic_send_and_recv_chunks_tcp4(doc) -> []; traffic_send_and_recv_chunks_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(traffic_send_and_recv_chunks_tcp4, fun() -> - ?TT(?SECS(30)), - InitState = #{domain => inet}, + InitState = #{domain => inet, + proto => tcp}, ok = traffic_send_and_recv_chunks_tcp(InitState) end). @@ -9477,11 +9480,34 @@ traffic_send_and_recv_chunks_tcp6(suite) -> traffic_send_and_recv_chunks_tcp6(doc) -> []; traffic_send_and_recv_chunks_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), tc_try(traffic_send_and_recv_chunks_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(30)), - InitState = #{domain => inet6}, + InitState = #{domain => inet6, + proto => tcp}, + ok = traffic_send_and_recv_chunks_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the send and recv functions +%% behave as expected when sending and/or reading chunks. +%% First send data in one "big" chunk, and read it in "small" chunks. +%% Second, send in a bunch of "small" chunks, and read in one "big" chunk. +%% Socket is UNix Domain (Stream) socket. + +traffic_send_and_recv_chunks_tcpL(suite) -> + []; +traffic_send_and_recv_chunks_tcpL(doc) -> + []; +traffic_send_and_recv_chunks_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(traffic_send_and_recv_chunks_tcp6, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default}, ok = traffic_send_and_recv_chunks_tcp(InitState) end). @@ -9510,8 +9536,8 @@ traffic_send_and_recv_chunks_tcp(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -9519,7 +9545,17 @@ traffic_send_and_recv_chunks_tcp(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + local_sa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, + local_sa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> {ok, State#{lport => Port}}; @@ -9532,7 +9568,14 @@ traffic_send_and_recv_chunks_tcp(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, + local_sa := LSA}) -> + ?SEV_ANNOUNCE_READY(Tester, init, LSA), + ok; + (#{tester := Tester, + local_sa := LSA, + lport := Port}) -> ServerSA = LSA#{port => Port}, ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok @@ -9780,8 +9823,10 @@ traffic_send_and_recv_chunks_tcp(InitState) -> ok end}, #{desc => "order remote client to start", - cmd => fun(#{rclient := Client, server_sa := ServerSA}) -> - ?SEV_ANNOUNCE_START(Client, ServerSA), + cmd => fun(#{rclient := Client, + server_sa := ServerSA, + proto := Proto}) -> + ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}), ok end}, #{desc => "await remote client ready", @@ -10369,9 +10414,9 @@ traffic_snr_tcp_client_init(Parent) -> put(sname, "rclient"), ?SEV_IPRINT("init"), _MRef = erlang:monitor(process, Parent), - ServerSA = traffic_snr_tcp_client_await_start(Parent), + {ServerSA, Proto} = traffic_snr_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), - Sock = traffic_snr_tcp_client_create(Domain), + Sock = traffic_snr_tcp_client_create(Domain, Proto), traffic_snr_tcp_client_bind(Sock, Domain), {Sock, ServerSA}. @@ -10379,9 +10424,9 @@ traffic_snr_tcp_client_await_start(Parent) -> i("traffic_snr_tcp_client_await_start -> entry"), ?SEV_AWAIT_START(Parent). -traffic_snr_tcp_client_create(Domain) -> +traffic_snr_tcp_client_create(Domain, Proto) -> i("traffic_snr_tcp_client_create -> entry"), - case socket:open(Domain, stream, tcp) of + case socket:open(Domain, stream, Proto) of {ok, Sock} -> Sock; {error, Reason} -> -- cgit v1.2.3 From 81a00a1174a73e42ee34ef63812be2392b3bc53e Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 15:42:21 +0200 Subject: [esock|test] Add plain send/recv small ping-pong test case for local Add a (plain) send and recv small ping-pong test case for Unix Domain (stream) socket. Also fixed minor bug in setopt for level 'otp' and option rcvbuf. Could not be changed if unix domain (stream) socket (local). OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 487 +++++++++++++++++++++++++++--------- erts/preloaded/ebin/socket.beam | Bin 70640 -> 70628 bytes erts/preloaded/src/socket.erl | 2 +- 3 files changed, 363 insertions(+), 126 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 339f6161df..1462cd2b00 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -155,6 +155,7 @@ traffic_ping_pong_small_send_and_recv_tcp4/1, traffic_ping_pong_small_send_and_recv_tcp6/1, + traffic_ping_pong_small_send_and_recv_tcpL/1, traffic_ping_pong_medium_send_and_recv_tcp4/1, traffic_ping_pong_medium_send_and_recv_tcp6/1, traffic_ping_pong_large_send_and_recv_tcp4/1, @@ -730,6 +731,7 @@ traffic_cases() -> traffic_ping_pong_small_send_and_recv_tcp4, traffic_ping_pong_small_send_and_recv_tcp6, + traffic_ping_pong_small_send_and_recv_tcpL, traffic_ping_pong_medium_send_and_recv_tcp4, traffic_ping_pong_medium_send_and_recv_tcp6, traffic_ping_pong_large_send_and_recv_tcp4, @@ -1923,36 +1925,48 @@ api_b_send_and_recv_udp(InitState) -> #{desc => "close src socket", cmd => fun(#{domain := local, sock_src := Sock, - lsa_src := #{path := Path}}) -> + lsa_src := #{path := Path}} = State) -> ok = socket:close(Sock), - case os:cmd("unlink " ++ Path) of - "" -> - ok; - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - ok + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(lsa_src, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State end, - ok; - (#{sock_src := Sock}) -> - ok = socket:close(Sock) + {ok, maps:remove(sock_src, State1)}; + (#{sock_src := Sock} = State) -> + ok = socket:close(Sock), + {ok, maps:remove(sock_src, State)} end}, #{desc => "close dst socket", cmd => fun(#{domain := local, sock_dst := Sock, - lsa_dst := #{path := Path}}) -> + lsa_dst := #{path := Path}} = State) -> ok = socket:close(Sock), - case os:cmd("unlink " ++ Path) of - "" -> - ok; - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - ok + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(lsa_dst, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State end, - ok; - (#{sock_dst := Sock}) -> - ok = socket:close(Sock) + {ok, maps:remove(sock_dst, State1)}; + (#{sock_dst := Sock} = State) -> + ok = socket:close(Sock), + {ok, maps:remove(sock_dst, State)} end}, %% *** We are done *** @@ -2210,25 +2224,36 @@ api_b_send_and_recv_tcp(InitState) -> end end}, #{desc => "close connection socket", - cmd => fun(#{domain := local, - csock := Sock, - lsa := #{path := Path}}) -> + cmd => fun(#{csock := Sock} = State) -> ok = socket:close(Sock), - case os:cmd("unlink " ++ Path) of - "" -> - ok; - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - ok - end, - ok; - (#{csock := Sock}) -> - socket:close(Sock) + {ok, maps:remove(csock, State)} end}, #{desc => "close listen socket", - cmd => fun(#{lsock := Sock}) -> - socket:close(Sock) + cmd => fun(#{domain := local, + lsock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(local_sa, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State + end, + {ok, maps:remove(lsock, State1)}; + (#{lsock := LSock} = State) -> + case socket:close(LSock) of + ok -> + {ok, maps:remove(lsock, State)}; + {error, _} = ERROR -> + ERROR + end end}, %% *** We are done *** @@ -2340,19 +2365,25 @@ api_b_send_and_recv_tcp(InitState) -> #{desc => "close socket", cmd => fun(#{domain := local, sock := Sock, - local_sa := #{path := Path}}) -> + local_sa := #{path := Path}} = State) -> ok = socket:close(Sock), - case os:cmd("unlink " ++ Path) of - "" -> - ok; - Result -> - ?SEV_IPRINT("unlink result:" - "~n ~s", [Result]), - ok - end, - ok; - (#{sock := Sock} = _S) -> - socket:close(Sock) + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(local_sa, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State + end, + {ok, maps:remove(sock, State1)}; + (#{sock := Sock} = State) -> + ok = socket:close(Sock), + {ok, maps:remove(sock, State)} end}, %% *** We are done *** @@ -5922,11 +5953,15 @@ sc_lc_receive_response_tcp(InitState) -> State1 = case os:cmd("unlink " ++ Path) of "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), maps:remove(lsa, State); - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - State + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State end, State2 = maps:remove(lsock, State1), State3 = maps:remove(lport, State2), @@ -6127,11 +6162,15 @@ sc_lc_receive_response_tcp(InitState) -> State1 = case os:cmd("unlink " ++ Path) of "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), maps:remove(local_sa, State); - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - State + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State end, {ok, maps:remove(sock, State1)}; (#{sock := Sock} = State) -> @@ -6540,10 +6579,14 @@ sc_lc_receive_response_udp(InitState) -> State1 = case os:cmd("unlink " ++ Path) of "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), maps:remove(local_sa, State); Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), State end, {ok, maps:remove(sock, State1)}; @@ -7142,10 +7185,14 @@ sc_lc_acceptor_response_tcp(InitState) -> State1 = case os:cmd("unlink " ++ Path) of "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), maps:remove(lsa, State); Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), State end, {ok, maps:remove(sock, State1)}; @@ -7779,10 +7826,14 @@ sc_rc_receive_response_tcp(InitState) -> State1 = case os:cmd("unlink " ++ Path) of "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), maps:remove(lsa, State); Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), State end, {ok, maps:remove(lsock, State1)}; @@ -8253,13 +8304,13 @@ sc_rc_tcp_client(Parent) -> {ServerSA, Proto} = sc_rc_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), Sock = sc_rc_tcp_client_create(Domain, Proto), - sc_rc_tcp_client_bind(Sock, Domain), + Path = sc_rc_tcp_client_bind(Sock, Domain), sc_rc_tcp_client_announce_ready(Parent, init), sc_rc_tcp_client_await_continue(Parent, connect), sc_rc_tcp_client_connect(Sock, ServerSA), sc_rc_tcp_client_announce_ready(Parent, connect), sc_rc_tcp_client_await_continue(Parent, close), - sc_rc_tcp_client_close(Sock), + sc_rc_tcp_client_close(Sock, Path), sc_rc_tcp_client_announce_ready(Parent, close), Reason = sc_rc_tcp_client_await_terminate(Parent), ?SEV_IPRINT("terminate"), @@ -8295,7 +8346,14 @@ sc_rc_tcp_client_bind(Sock, Domain) -> LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> - ok; + case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + Path; + {ok, _} -> + undefined; + {error, Reason1} -> + exit({sockname, Reason1}) + end; {error, Reason} -> exit({bind, Reason}) end. @@ -8317,13 +8375,17 @@ sc_rc_tcp_client_connect(Sock, ServerSA) -> exit({connect, Reason}) end. -sc_rc_tcp_client_close(Sock) -> +sc_rc_tcp_client_close(Sock, Path) -> i("sc_rc_tcp_client_close -> entry"), case socket:close(Sock) of ok -> + unlink_socket(Path), ok; {error, Reason} -> - exit({close, Reason}) + ?SEV_EPRINT("failed closing: " + "~n Reason: ~p", [Reason]), + unlink_socket(Path), + {error, {close, Reason}} end. sc_rc_tcp_client_await_terminate(Parent) -> @@ -8734,7 +8796,25 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> {ok, State2} end}, #{desc => "close listen socket", - cmd => fun(#{lsock := LSock} = State) -> + cmd => fun(#{domain := local, + lsock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(local_sa, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State + end, + {ok, maps:remove(lsock, State1)}; + (#{lsock := LSock} = State) -> case socket:close(LSock) of ok -> {ok, maps:remove(lsock, State)}; @@ -9157,7 +9237,7 @@ sc_rs_tcp_client(Parent, Send) -> {ServerSA, Proto} = sc_rs_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), Sock = sc_rs_tcp_client_create(Domain, Proto), - sc_rs_tcp_client_bind(Sock, Domain), + Path = sc_rs_tcp_client_bind(Sock, Domain), sc_rs_tcp_client_announce_ready(Parent, init), sc_rs_tcp_client_await_continue(Parent, connect), sc_rs_tcp_client_connect(Sock, ServerSA), @@ -9169,7 +9249,7 @@ sc_rs_tcp_client(Parent, Send) -> sc_rs_tcp_client_shutdown(Sock), sc_rs_tcp_client_announce_ready(Parent, shutdown), sc_rs_tcp_client_await_continue(Parent, close), - sc_rs_tcp_client_close(Sock), + sc_rs_tcp_client_close(Sock, Path), sc_rs_tcp_client_announce_ready(Parent, close), Reason = sc_rs_tcp_client_await_terminate(Parent), ?SEV_IPRINT("terminate"), @@ -9199,7 +9279,14 @@ sc_rs_tcp_client_bind(Sock, Domain) -> LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> - ok; + case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + Path; + {ok, _} -> + undefined; + {error, Reason1} -> + exit({sockname, Reason1}) + end; {error, Reason} -> exit({bind, Reason}) end. @@ -9246,13 +9333,17 @@ sc_rs_tcp_client_shutdown(Sock) -> exit({shutdown, Reason}) end. -sc_rs_tcp_client_close(Sock) -> +sc_rs_tcp_client_close(Sock, Path) -> i("sc_rs_tcp_client_close -> entry"), case socket:close(Sock) of ok -> + unlink_socket(Path), ok; {error, Reason} -> - exit({close, Reason}) + ?SEV_EPRINT("failed closing: " + "~n Reason: ~p", [Reason]), + unlink_socket(Path), + {error, {close, Reason}} end. sc_rs_tcp_client_await_terminate(Parent) -> @@ -9770,9 +9861,23 @@ traffic_send_and_recv_chunks_tcp(InitState) -> {ok, maps:remove(csock, State)} end}, #{desc => "close listen socket", - cmd => fun(#{lsock := Sock} = State) -> + cmd => fun(#{domain := local, + lsock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + maps:remove(local_sa, State); + Result -> + ?SEV_IPRINT("unlink result: " + "~n ~s", [Result]), + State + end, + {ok, maps:remove(lsock, State1)}; + (#{lsock := Sock} = State) -> (catch socket:close(Sock)), - {ok, maps:remove(lsock, State)} + {ok, maps:remove(lsock, State)} end}, %% *** We are done *** @@ -10381,14 +10486,14 @@ traffic_snr_tcp_client_start(Node) -> erlang:spawn(Node, Fun). traffic_snr_tcp_client(Parent) -> - {Sock, ServerSA} = traffic_snr_tcp_client_init(Parent), + {Sock, ServerSA, Path} = traffic_snr_tcp_client_init(Parent), traffic_snr_tcp_client_announce_ready(Parent, init), traffic_snr_tcp_client_await_continue(Parent, connect), traffic_snr_tcp_client_connect(Sock, ServerSA), traffic_snr_tcp_client_announce_ready(Parent, connect), traffic_snr_tcp_client_send_loop(Parent, Sock), Reason = traffic_snr_tcp_client_await_terminate(Parent), - traffic_snr_tcp_client_close(Sock), + traffic_snr_tcp_client_close(Sock, Path), exit(Reason). @@ -10417,8 +10522,8 @@ traffic_snr_tcp_client_init(Parent) -> {ServerSA, Proto} = traffic_snr_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), Sock = traffic_snr_tcp_client_create(Domain, Proto), - traffic_snr_tcp_client_bind(Sock, Domain), - {Sock, ServerSA}. + Path = traffic_snr_tcp_client_bind(Sock, Domain), + {Sock, ServerSA, Path}. traffic_snr_tcp_client_await_start(Parent) -> i("traffic_snr_tcp_client_await_start -> entry"), @@ -10438,7 +10543,14 @@ traffic_snr_tcp_client_bind(Sock, Domain) -> LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> - ok; + case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + Path; + {ok, _} -> + undefined; + {error, Reason1} -> + exit({sockname, Reason1}) + end; {error, Reason} -> exit({bind, Reason}) end. @@ -10459,13 +10571,17 @@ traffic_snr_tcp_client_connect(Sock, ServerSA) -> exit({connect, Reason}) end. -traffic_snr_tcp_client_close(Sock) -> +traffic_snr_tcp_client_close(Sock, Path) -> i("traffic_snr_tcp_client_close -> entry"), case socket:close(Sock) of ok -> + unlink_socket(Path), ok; {error, Reason} -> - exit({close, Reason}) + ?SEV_EPRINT("failed closing: " + "~n Reason: ~p", [Reason]), + unlink_socket(Path), + {error, {close, Reason}} end. traffic_snr_tcp_client_await_terminate(Parent) -> @@ -10493,12 +10609,13 @@ traffic_ping_pong_small_send_and_recv_tcp4(suite) -> traffic_ping_pong_small_send_and_recv_tcp4(doc) -> []; traffic_ping_pong_small_send_and_recv_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), Msg = l2b(?TPP_SMALL), Num = ?TPP_SMALL_NUM, tc_try(traffic_ping_pong_small_send_and_recv_tcp4, fun() -> - ?TT(?SECS(15)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10520,13 +10637,42 @@ traffic_ping_pong_small_send_and_recv_tcp6(suite) -> traffic_ping_pong_small_send_and_recv_tcp6(doc) -> []; traffic_ping_pong_small_send_and_recv_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), Msg = l2b(?TPP_SMALL), Num = ?TPP_SMALL_NUM, tc_try(traffic_ping_pong_small_send_and_recv_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(15)), InitState = #{domain => inet6, + proto => tcp, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the send and recv functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'small' message test case, for Unix Domain (stream) socket. + +traffic_ping_pong_small_send_and_recv_tcpL(suite) -> + []; +traffic_ping_pong_small_send_and_recv_tcpL(doc) -> + []; +traffic_ping_pong_small_send_and_recv_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + Msg = l2b(?TPP_SMALL), + Num = ?TPP_SMALL_NUM, + tc_try(traffic_ping_pong_small_send_and_recv_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10553,6 +10699,7 @@ traffic_ping_pong_medium_send_and_recv_tcp4(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(30)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10580,6 +10727,7 @@ traffic_ping_pong_medium_send_and_recv_tcp6(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(30)), InitState = #{domain => inet6, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10607,6 +10755,7 @@ traffic_ping_pong_large_send_and_recv_tcp4(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(45)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10634,6 +10783,7 @@ traffic_ping_pong_large_send_and_recv_tcp6(_Config) when is_list(_Config) -> fun() -> ?TT(?SECS(45)), InitState = #{domain => inet6, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_send_and_recv_tcp(InitState) @@ -10661,6 +10811,7 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(45)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) @@ -10687,6 +10838,7 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) fun() -> ?TT(?SECS(45)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) @@ -10714,6 +10866,7 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(45)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) @@ -10741,6 +10894,7 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) fun() -> ?TT(?SECS(45)), InitState = #{domain => inet6, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) @@ -10768,6 +10922,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(20)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10795,6 +10950,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) fun() -> ?TT(?SECS(20)), InitState = #{domain => inet6, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10821,6 +10977,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(30)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10847,7 +11004,8 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) fun() -> has_support_ipv6() end, fun() -> ?TT(?SECS(20)), - InitState = #{domain => ine6, + InitState = #{domain => inet6, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10874,6 +11032,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(30)), InitState = #{domain => inet, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10901,6 +11060,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) fun() -> ?TT(?SECS(30)), InitState = #{domain => inet6, + proto => tcp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) @@ -10928,6 +11088,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(60)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) @@ -10955,6 +11116,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) fun() -> ?TT(?SECS(30)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) @@ -10981,6 +11143,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) fun() -> ?TT(?SECS(30)), InitState = #{domain => inet, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) @@ -11007,7 +11170,8 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) fun() -> has_support_ipv6() end, fun() -> ?TT(?SECS(20)), - InitState = #{domain => ine6, + InitState = #{domain => inet6, + proto => udp, msg => Msg, num => Num}, ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) @@ -11027,14 +11191,19 @@ traffic_ping_pong_send_and_recv_tcp(InitState) -> }, traffic_ping_pong_send_and_receive_tcp(InitState2). -traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) -> - Send = fun(Sock, Data) when is_binary(Data) -> - MsgHdr = #{iov => [Data]}, - socket:sendmsg(Sock, MsgHdr); - (Sock, Data) when is_list(Data) -> %% We assume iovec... - MsgHdr = #{iov => Data}, - socket:sendmsg(Sock, MsgHdr) +traffic_ping_pong_sendmsg_and_recvmsg_tcp(#{domain := local} = InitState) -> + Recv = fun(Sock, Sz) -> + case socket:recvmsg(Sock, Sz, 0) of + {ok, #{addr := #{family := local}, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end end, + InitState2 = InitState#{recv => Recv}, % Receive function + traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState2); +traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) -> Recv = fun(Sock, Sz) -> case socket:recvmsg(Sock, Sz, 0) of {ok, #{addr := undefined, @@ -11044,9 +11213,18 @@ traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) -> ERROR end end, - InitState2 = InitState#{send => Send, % Send function - recv => Recv % Receive function - }, + InitState2 = InitState#{recv => Recv}, % Receive function + traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState2). + +traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState) -> + Send = fun(Sock, Data) when is_binary(Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(Sock, MsgHdr); + (Sock, Data) when is_list(Data) -> %% We assume iovec... + MsgHdr = #{iov => Data}, + socket:sendmsg(Sock, MsgHdr) + end, + InitState2 = InitState#{send => Send}, % Send function traffic_ping_pong_send_and_receive_tcp(InitState2). @@ -11110,8 +11288,8 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, stream, tcp) of + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, stream, Proto) of {ok, Sock} -> {ok, State#{lsock => Sock}}; {error, _} = ERROR -> @@ -11119,9 +11297,19 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{lsock := LSock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + lsock := LSock, + lsa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, local_sa := LSA} = State) -> case socket:bind(LSock, LSA) of {ok, Port} -> + ?SEV_IPRINT("bound to port: ~w", [Port]), {ok, State#{lport => Port}}; {error, _} = ERROR -> ERROR @@ -11136,7 +11324,11 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> socket:listen(LSock) end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, local_sa := LSA}) -> + ?SEV_ANNOUNCE_READY(Tester, init, LSA), + ok; + (#{tester := Tester, local_sa := LSA, lport := Port}) -> ServerSA = LSA#{port => Port}, ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok @@ -11247,9 +11439,27 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> {ok, State1} end}, #{desc => "close listen socket", - cmd => fun(#{lsock := Sock} = State) -> + cmd => fun(#{domain := local, + lsock := Sock, + local_sa := #{path := Path}} = State) -> + (catch socket:close(Sock)), + State1 = + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + maps:remove(local_sa, State); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + State + end, + {ok, maps:remove(lsock, State1)}; + (#{lsock := Sock} = State) -> (catch socket:close(Sock)), - {ok, maps:remove(lsock, State)} + {ok, maps:remove(lsock, State)} end}, %% *** We are done *** @@ -11301,12 +11511,14 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> end}, #{desc => "order remote client to start", cmd => fun(#{rclient := RClient, + proto := Proto, server_sa := ServerSA, buf_init := BufInit, send := Send, recv := Recv}) -> ?SEV_ANNOUNCE_START(RClient, - {ServerSA, BufInit, Send, Recv}), + {ServerSA, Proto, BufInit, + Send, Recv}), ok end}, #{desc => "await remote client ready", @@ -11607,6 +11819,7 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> i("start server evaluator"), ServerInitState = #{domain => maps:get(domain, InitState), + proto => maps:get(proto, InitState), recv => maps:get(recv, InitState), send => maps:get(send, InitState), buf_init => maps:get(buf_init, InitState)}, @@ -11700,14 +11913,6 @@ tpp_tcp_handler_msg_exchange_loop(Sock, Send, Recv, N, Sent, Received, Start) -> ?SEV_EPRINT("send (~w): ~p", [N, SReason]), exit({send, SReason, N}) end; - %% {error, timeout} -> - %% ?SEV_IPRINT("timeout(~w) - try again", [N]), - %% case Send(Sock, list_to_binary("ping")) of - %% ok -> - %% exit({'ping-send', ok, N}); - %% {error, Reason} -> - %% exit({'ping-send', Reason, N}) - %% end; {error, closed} -> ?SEV_IPRINT("closed - we are done: ~w, ~w, ~w", [N, Sent, Received]), Stop = ?LIB:timestamp(), @@ -11726,10 +11931,10 @@ tpp_tcp_client_create(Node) -> tpp_tcp_client(Parent) -> tpp_tcp_client_init(Parent), - {ServerSA, BufInit, Send, Recv} = tpp_tcp_client_await_start(Parent), + {ServerSA, Proto, BufInit, Send, Recv} = tpp_tcp_client_await_start(Parent), Domain = maps:get(family, ServerSA), - Sock = tpp_tcp_client_sock_open(Domain, BufInit), - tpp_tcp_client_sock_bind(Sock, Domain), + Sock = tpp_tcp_client_sock_open(Domain, Proto, BufInit), + Path = tpp_tcp_client_sock_bind(Sock, Domain), tpp_tcp_client_announce_ready(Parent, init), tpp_tcp_client_await_continue(Parent, connect), tpp_tcp_client_sock_connect(Sock, ServerSA), @@ -11738,7 +11943,7 @@ tpp_tcp_client(Parent) -> Result = tpp_tcp_client_msg_exchange(Sock, Send, Recv, InitMsg, Num), tpp_tcp_client_announce_ready(Parent, send, Result), Reason = tpp_tcp_client_await_terminate(Parent), - tpp_tcp_client_sock_close(Sock), + tpp_tcp_client_sock_close(Sock, Path), ?SEV_IPRINT("terminating"), exit(Reason). @@ -11778,8 +11983,10 @@ tpp_tcp_client_await_terminate(Parent) -> ?SEV_IPRINT("await terminate"), case ?SEV_AWAIT_TERMINATE(Parent, parent) of ok -> - ok; + ?SEV_IPRINT("termination received: normal"), + normal; {error, Reason} -> + ?SEV_IPRINT("termination received: ~w", [Reason]), Reason end. @@ -11823,8 +12030,8 @@ tpp_tcp_client_msg_exchange_loop(Sock, Send, Recv, Data, exit({send, SReason, N}) end. -tpp_tcp_client_sock_open(Domain, BufInit) -> - case socket:open(Domain, stream, tcp) of +tpp_tcp_client_sock_open(Domain, Proto, BufInit) -> + case socket:open(Domain, stream, Proto) of {ok, Sock} -> ok = BufInit(Sock), Sock; @@ -11836,9 +12043,16 @@ tpp_tcp_client_sock_bind(Sock, Domain) -> LSA = which_local_socket_addr(Domain), case socket:bind(Sock, LSA) of {ok, _} -> - ok; - {error, Reason} -> - exit({bind, Reason}) + case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + Path; + {ok, _} -> + undefined; + {error, Reason1} -> + exit({sockname, Reason1}) + end; + {error, Reason2} -> + exit({bind, Reason2}) end. tpp_tcp_client_sock_connect(Sock, ServerSA) -> @@ -11849,14 +12063,37 @@ tpp_tcp_client_sock_connect(Sock, ServerSA) -> exit({connect, Reason}) end. -tpp_tcp_client_sock_close(Sock) -> +tpp_tcp_client_sock_close(Sock, Path) -> case socket:close(Sock) of ok -> + unlink_socket(Path), ok; {error, Reason} -> - exit({close, Reason}) + ?SEV_EPRINT("failed closing: " + "~n Reason: ~p", [Reason]), + unlink_socket(Path), + {error, {close, Reason}} end. +unlink_socket(Path) when is_list(Path) -> + ?SEV_IPRINT("try unlink path: " + "~n ~s", [Path]), + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + ok; + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", [Path, Result]), + ok + end; +unlink_socket(_) -> + ok. + + + -define(TPP_REQUEST, 1). -define(TPP_REPLY, 2). diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index 6aa043972c..198dd08036 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index cdbc79204e..9fc73a11de 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -2537,7 +2537,7 @@ enc_setopt_value(otp, rcvbuf, V, _, _, _) when is_integer(V) andalso (V > 0) -> V; %% N: Number of reads (when specifying length = 0) %% V: Size of the "read" buffer -enc_setopt_value(otp, rcvbuf, {N, BufSz} = V, _, stream = _T, tcp = _P) +enc_setopt_value(otp, rcvbuf, {N, BufSz} = V, _, stream = _T, _P) when (is_integer(N) andalso (N > 0)) andalso (is_integer(BufSz) andalso (BufSz > 0)) -> V; -- cgit v1.2.3 From 3826ecc00141947c84fa1a3a5514d513d69bc764 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 15:50:07 +0200 Subject: [esock|test] Add plain send/recv medium ping-pong test case for local Add a (plain) send and recv medium ping-pong test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 1462cd2b00..321b5105be 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -158,6 +158,7 @@ traffic_ping_pong_small_send_and_recv_tcpL/1, traffic_ping_pong_medium_send_and_recv_tcp4/1, traffic_ping_pong_medium_send_and_recv_tcp6/1, + traffic_ping_pong_medium_send_and_recv_tcpL/1, traffic_ping_pong_large_send_and_recv_tcp4/1, traffic_ping_pong_large_send_and_recv_tcp6/1, @@ -734,6 +735,7 @@ traffic_cases() -> traffic_ping_pong_small_send_and_recv_tcpL, traffic_ping_pong_medium_send_and_recv_tcp4, traffic_ping_pong_medium_send_and_recv_tcp6, + traffic_ping_pong_medium_send_and_recv_tcpL, traffic_ping_pong_large_send_and_recv_tcp4, traffic_ping_pong_large_send_and_recv_tcp6, @@ -10735,6 +10737,35 @@ traffic_ping_pong_medium_send_and_recv_tcp6(_Config) when is_list(_Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the send and recv functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'medium' message test case, for Unix Domain (stream) socket. + +traffic_ping_pong_medium_send_and_recv_tcpL(suite) -> + []; +traffic_ping_pong_medium_send_and_recv_tcpL(doc) -> + []; +traffic_ping_pong_medium_send_and_recv_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + Msg = l2b(?TPP_MEDIUM), + Num = ?TPP_MEDIUM_NUM, + tc_try(traffic_ping_pong_medium_send_and_recv_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_send_and_recv_tcp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the send and recv functions %% by repeatedly sending a meassage between two entities. @@ -10749,11 +10780,11 @@ traffic_ping_pong_large_send_and_recv_tcp4(suite) -> traffic_ping_pong_large_send_and_recv_tcp4(doc) -> []; traffic_ping_pong_large_send_and_recv_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(45)), Msg = l2b(?TPP_LARGE), Num = ?TPP_LARGE_NUM, tc_try(traffic_ping_pong_large_send_and_recv_tcp4, fun() -> - ?TT(?SECS(45)), InitState = #{domain => inet, proto => tcp, msg => Msg, -- cgit v1.2.3 From d4fe0d19fe3a5a9e32310216fa284698e52d783d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 15:57:29 +0200 Subject: [esock|test] Add plain send/recv large ping-pong test case for local Add a (plain) send and recv large ping-pong test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 321b5105be..f0b9fcc604 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -161,6 +161,7 @@ traffic_ping_pong_medium_send_and_recv_tcpL/1, traffic_ping_pong_large_send_and_recv_tcp4/1, traffic_ping_pong_large_send_and_recv_tcp6/1, + traffic_ping_pong_large_send_and_recv_tcpL/1, traffic_ping_pong_small_sendto_and_recvfrom_udp4/1, traffic_ping_pong_small_sendto_and_recvfrom_udp6/1, @@ -738,6 +739,7 @@ traffic_cases() -> traffic_ping_pong_medium_send_and_recv_tcpL, traffic_ping_pong_large_send_and_recv_tcp4, traffic_ping_pong_large_send_and_recv_tcp6, + traffic_ping_pong_large_send_and_recv_tcpL, traffic_ping_pong_small_sendto_and_recvfrom_udp4, traffic_ping_pong_small_sendto_and_recvfrom_udp6, @@ -10822,6 +10824,35 @@ traffic_ping_pong_large_send_and_recv_tcp6(_Config) when is_list(_Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the send and recv functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'large' message test case, for UNix Domain (stream) socket. + +traffic_ping_pong_large_send_and_recv_tcpL(suite) -> + []; +traffic_ping_pong_large_send_and_recv_tcpL(doc) -> + []; +traffic_ping_pong_large_send_and_recv_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(45)), + Msg = l2b(?TPP_LARGE), + Num = ?TPP_LARGE_NUM, + tc_try(traffic_ping_pong_large_send_and_recv_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_send_and_recv_tcp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendto and recvfrom %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 9d55597478cc80e07bdc2bf4faf6f0685d494296 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 16:32:03 +0200 Subject: [esock|test] Add sendto/recvfrom small ping-pong test case for local Add a sendto and recvfrom small ping-pong test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 99 +++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 15 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index f0b9fcc604..930af72f53 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -165,6 +165,7 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp4/1, traffic_ping_pong_small_sendto_and_recvfrom_udp6/1, + traffic_ping_pong_small_sendto_and_recvfrom_udpL/1, traffic_ping_pong_medium_sendto_and_recvfrom_udp4/1, traffic_ping_pong_medium_sendto_and_recvfrom_udp6/1, @@ -743,6 +744,7 @@ traffic_cases() -> traffic_ping_pong_small_sendto_and_recvfrom_udp4, traffic_ping_pong_small_sendto_and_recvfrom_udp6, + traffic_ping_pong_small_sendto_and_recvfrom_udpL, traffic_ping_pong_medium_sendto_and_recvfrom_udp4, traffic_ping_pong_medium_sendto_and_recvfrom_udp6, @@ -10894,12 +10896,13 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(suite) -> traffic_ping_pong_small_sendto_and_recvfrom_udp6(doc) -> []; traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(45)), Msg = l2b(?TPP_SMALL), Num = ?TPP_SMALL_NUM, tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udp6, + fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(45)), - InitState = #{domain => inet, + InitState = #{domain => inet6, proto => udp, msg => Msg, num => Num}, @@ -10908,6 +10911,35 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendto and recvfrom +%% functions by repeatedly sending a meassage between two entities. +%% The same basic test case is used for two different message sizes; +%% small (8 bytes) and medium (8K). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'small' message test case, for Unix Domain (dgram) socket. + +traffic_ping_pong_small_sendto_and_recvfrom_udpL(suite) -> + []; +traffic_ping_pong_small_sendto_and_recvfrom_udpL(doc) -> + []; +traffic_ping_pong_small_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(45)), + Msg = l2b(?TPP_SMALL), + Num = ?TPP_SMALL_NUM, + tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendto and recvfrom %% functions by repeatedly sending a meassage between two entities. @@ -12325,8 +12357,8 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> {ok, State#{local_sa => LSA}} end}, #{desc => "create listen socket", - cmd => fun(#{domain := Domain} = State) -> - case socket:open(Domain, dgram, udp) of + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, dgram, Proto) of {ok, Sock} -> {ok, State#{sock => Sock}}; {error, _} = ERROR -> @@ -12334,7 +12366,15 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> end end}, #{desc => "bind to local address", - cmd => fun(#{sock := Sock, local_sa := LSA} = State) -> + cmd => fun(#{domain := local, + sock := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _} -> + ok; + {error, _} = ERROR -> + ERROR + end; + (#{sock := Sock, local_sa := LSA} = State) -> case socket:bind(Sock, LSA) of {ok, Port} -> {ok, State#{port => Port}}; @@ -12377,7 +12417,11 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> end end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, local_sa := LSA, port := Port}) -> + cmd => fun(#{domain := local, + tester := Tester, local_sa := LSA}) -> + ?SEV_ANNOUNCE_READY(Tester, init, LSA), + ok; + (#{tester := Tester, local_sa := LSA, port := Port}) -> ServerSA = LSA#{port => Port}, ?SEV_ANNOUNCE_READY(Tester, init, ServerSA), ok @@ -12416,6 +12460,24 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> ERROR end end}, + #{desc => "(maybe) unlink socket", + cmd => fun(#{domain := local, + local_sa := #{path := Path}} = State) -> + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + {ok, maps:remove(local_sa, State)}; + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", + [Path, Result]), + ok + end; + (_) -> + ok + end}, #{desc => "announce ready (close)", cmd => fun(#{tester := Tester} = _State) -> ?SEV_ANNOUNCE_READY(Tester, close), @@ -12512,11 +12574,13 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> #{desc => "order remote handler to start", cmd => fun(#{handler := Handler, server_sa := ServerSA, + proto := Proto, buf_init := BufInit, send := Send, recv := Recv}) -> ?SEV_ANNOUNCE_START(Handler, - {ServerSA, BufInit, Send, Recv}), + {ServerSA, Proto, BufInit, + Send, Recv}), ok end}, #{desc => "await (remote) handler ready", @@ -12761,6 +12825,7 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> i("start server evaluator"), ServerInitState = #{domain => maps:get(domain, InitState), + proto => maps:get(proto, InitState), recv => maps:get(recv, InitState), send => maps:get(send, InitState), buf_init => maps:get(buf_init, InitState)}, @@ -12861,12 +12926,12 @@ tpp_udp_client_handler_create(Node) -> tpp_udp_client_handler(Parent) -> tpp_udp_client_handler_init(Parent), ?SEV_IPRINT("await start command"), - {ServerSA, BufInit, Send, Recv} = tpp_udp_handler_await_start(Parent), + {ServerSA, Proto, BufInit, Send, Recv} = tpp_udp_handler_await_start(Parent), ?SEV_IPRINT("start command with" "~n ServerSA: ~p", [ServerSA]), Domain = maps:get(family, ServerSA), - Sock = tpp_udp_sock_open(Domain, BufInit), - tpp_udp_sock_bind(Sock, Domain), + Sock = tpp_udp_sock_open(Domain, Proto, BufInit), + Path = tpp_udp_sock_bind(Sock, Domain), ?SEV_IPRINT("announce ready", []), tpp_udp_handler_announce_ready(Parent, init), {InitMsg, Num} = tpp_udp_handler_await_continue(Parent, send), @@ -12879,7 +12944,7 @@ tpp_udp_client_handler(Parent) -> ?SEV_IPRINT("await terminate"), Reason = tpp_udp_handler_await_terminate(Parent), ?SEV_IPRINT("terminate with ~p", [Reason]), - tpp_udp_sock_close(Sock), + tpp_udp_sock_close(Sock, Path), ?SEV_IPRINT("terminating"), exit(Reason). @@ -13017,8 +13082,8 @@ tpp_udp_handler_await_terminate(Parent) -> end. -tpp_udp_sock_open(Domain, BufInit) -> - case socket:open(Domain, dgram, udp) of +tpp_udp_sock_open(Domain, Proto, BufInit) -> + case socket:open(Domain, dgram, Proto) of {ok, Sock} -> ok = BufInit(Sock), Sock; @@ -13035,12 +13100,16 @@ tpp_udp_sock_bind(Sock, Domain) -> exit({bind, Reason}) end. -tpp_udp_sock_close(Sock) -> +tpp_udp_sock_close(Sock, Path) -> case socket:close(Sock) of ok -> + unlink_socket(Path), ok; {error, Reason} -> - exit({close, Reason}) + ?SEV_EPRINT("Failed closing socket: " + "~n ~p", [Reason]), + unlink_socket(Path), + {error, {close, Reason}} end. -- cgit v1.2.3 From ac924068cb527f366622fc99adce35fc13851293 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 16:42:35 +0200 Subject: [esock|test] Add sendto/recvfrom medium ping-pong test case for local Add a sendto and recvfrom medium ping-pong test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 930af72f53..bca1f0023b 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -168,6 +168,7 @@ traffic_ping_pong_small_sendto_and_recvfrom_udpL/1, traffic_ping_pong_medium_sendto_and_recvfrom_udp4/1, traffic_ping_pong_medium_sendto_and_recvfrom_udp6/1, + traffic_ping_pong_medium_sendto_and_recvfrom_udpL/1, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6/1, @@ -747,6 +748,7 @@ traffic_cases() -> traffic_ping_pong_small_sendto_and_recvfrom_udpL, traffic_ping_pong_medium_sendto_and_recvfrom_udp4, traffic_ping_pong_medium_sendto_and_recvfrom_udp6, + traffic_ping_pong_medium_sendto_and_recvfrom_udpL, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6, @@ -10996,6 +10998,35 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendto and recvfrom +%% functions by repeatedly sending a meassage between two entities. +%% The same basic test case is used for two different message sizes; +%% small (8 bytes) and medium (8K). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'medium' message test case, for Unix Domain (dgram) socket. + +traffic_ping_pong_medium_sendto_and_recvfrom_udpL(suite) -> + []; +traffic_ping_pong_medium_sendto_and_recvfrom_udpL(doc) -> + []; +traffic_ping_pong_medium_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_MEDIUM), + Num = ?TPP_MEDIUM_NUM, + tc_try(traffic_ping_pong_medium_sendto_and_recvfrom_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(45)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendmsg and recvmsg %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 5e74b050e544d9da92b797266cbfb0acdba30291 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 16:57:13 +0200 Subject: [esock|test] Add sendmsg/recvmsg small ping-pong test case for local (stream) Add a sendmsg and recvmsg small ping-pong test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index bca1f0023b..c5dd5270f3 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -172,6 +172,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6/1, + traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6/1, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4/1, @@ -752,6 +753,7 @@ traffic_cases() -> traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6, + traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4, @@ -11082,6 +11084,34 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendmsg and recvmsg functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'small' message test case, for Unix Domain (stream) socket. + +traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(suite) -> + []; +traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(doc) -> + []; +traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_SMALL), + Num = ?TPP_SMALL_NUM, + tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(20)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendmsg and recvmsg %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 885fc0ed3e39d978edc380857e21a7b9e556a594 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 17:03:47 +0200 Subject: [esock|test] Add sendmsg/recvmsg medium ping-pong test case for local (stream) Add a sendmsg and recvmsg medium ping-pong test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index c5dd5270f3..031c9c6ba5 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -175,6 +175,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6/1, + traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL/1, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6/1, @@ -756,6 +757,7 @@ traffic_cases() -> traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6, + traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6, @@ -11167,6 +11169,34 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendmsg and recvmsg functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'medium' message test case, for Unix Domain (stream) socket. + +traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(suite) -> + []; +traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(doc) -> + []; +traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_MEDIUM), + Num = ?TPP_MEDIUM_NUM, + tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(20)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendmsg and recvmsg %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 0c0566e88953f35f844439b5f86e7e7d330559cb Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 17:16:13 +0200 Subject: [esock|test] Add sendmsg/recvmsg large ping-pong test case for local (stream) Add a sendmsg and recvmsg large ping-pong test case for Unix Domain (stream) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 031c9c6ba5..b2159af5af 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -178,6 +178,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL/1, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4/1, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6/1, + traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL/1, traffic_ping_pong_small_sendmsg_and_recvmsg_udp4/1, traffic_ping_pong_small_sendmsg_and_recvmsg_udp6/1, @@ -760,6 +761,7 @@ traffic_cases() -> traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6, + traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL, traffic_ping_pong_small_sendmsg_and_recvmsg_udp4, traffic_ping_pong_small_sendmsg_and_recvmsg_udp6, @@ -11253,6 +11255,35 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendmsg and recvmsg functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes), medium (8K) and large (8M). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'large' message test case, for Unix Domain (stream) socket. + +traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(suite) -> + []; +traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(doc) -> + []; +traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_LARGE), + Num = ?TPP_LARGE_NUM, + tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(30)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendmsg and recvmsg %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 0d551df1a44c3497d5d2ccf32a5d85ec06d9d088 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 17:26:54 +0200 Subject: [esock|test] Add sendmsg/recvmsg small ping-pong test case for local (dgram) Add a sendmsg and recvmsg small ping-pong test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index b2159af5af..d08833017c 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -182,6 +182,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp4/1, traffic_ping_pong_small_sendmsg_and_recvmsg_udp6/1, + traffic_ping_pong_small_sendmsg_and_recvmsg_udpL/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6/1, @@ -765,6 +766,7 @@ traffic_cases() -> traffic_ping_pong_small_sendmsg_and_recvmsg_udp4, traffic_ping_pong_small_sendmsg_and_recvmsg_udp6, + traffic_ping_pong_small_sendmsg_and_recvmsg_udpL, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6 ]. @@ -11331,7 +11333,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) fun() -> has_support_ipv6() end, fun() -> ?TT(?SECS(30)), - InitState = #{domain => inet, + InitState = #{domain => inet6, proto => udp, msg => Msg, num => Num}, @@ -11339,6 +11341,34 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) end). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendmsg and recvmsg functions +%% by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes) and medium (8K). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'small' message test case, for Unix Domain (dgram) socket. + +traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(suite) -> + []; +traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(doc) -> + []; +traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_SMALL), + Num = ?TPP_SMALL_NUM, + tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(30)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) + end). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendmsg and recvmsg %% functions by repeatedly sending a meassage between two entities. -- cgit v1.2.3 From 1c3d45e92e34864e6e2d8042f3a79a3513c7b240 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 17:35:23 +0200 Subject: [esock|test] Add sendmsg/recvmsg medium ping-pong test case for local (dgram) Add a sendmsg and recvmsg small ping-pong test case for Unix Domain (dgram) socket. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index d08833017c..a60012f86c 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -185,6 +185,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udpL/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4/1, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6/1, + traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL/1, %% *** Time Test *** %% Server: transport = gen_tcp, active = false @@ -768,7 +769,8 @@ traffic_cases() -> traffic_ping_pong_small_sendmsg_and_recvmsg_udp6, traffic_ping_pong_small_sendmsg_and_recvmsg_udpL, traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4, - traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6 + traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6, + traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL ]. @@ -11425,6 +11427,35 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to test that the sendmsg and recvmsg +%% functions by repeatedly sending a meassage between two entities. +%% The same basic test case is used for three different message sizes; +%% small (8 bytes) and medium (8K). +%% The message is sent from A to B and then back again. This is +%% repeated a set number of times (more times the small the message). +%% This is the 'medium' message test case, for Unix Domain (dgram) socket. + +traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(suite) -> + []; +traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(doc) -> + []; +traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) -> + Msg = l2b(?TPP_MEDIUM), + Num = ?TPP_MEDIUM_NUM, + tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + ?TT(?SECS(20)), + InitState = #{domain => local, + proto => default, + msg => Msg, + num => Num}, + ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Ping-Pong for TCP -- cgit v1.2.3 From fe0bd092d56260e0a8d874076182717244834d14 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 18:59:56 +0200 Subject: [esock|test] Preliminary Domain = local update for ttest OTP-15822 --- .../emulator/test/socket_test_ttest_tcp_socket.erl | 59 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/erts/emulator/test/socket_test_ttest_tcp_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_socket.erl index 0ae2412e4c..6a54d70d58 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_socket.erl @@ -24,7 +24,7 @@ accept/1, accept/2, active/2, close/1, - connect/2, connect/3, + connect/1, connect/2, connect/3, controlling_process/2, listen/0, listen/1, listen/2, port/1, @@ -36,6 +36,8 @@ ]). +-define(LIB, socket_test_lib). + -define(READER_RECV_TIMEOUT, 1000). -define(DATA_MSG(Sock, Method, Data), @@ -100,30 +102,56 @@ close(#{sock := Sock, reader := Pid}) -> socket:close(Sock). %% Create a socket and connect it to a peer -connect(Addr, Port) -> - connect(Addr, Port, #{method => plain}). - -connect(Addr, Port, #{method := Method} = Opts) -> +connect(ServerPath) when is_list(ServerPath) -> + Domain = local, + ServerSA = #{family => Domain, path => ServerPath}, + Opts = #{domain => Domain, + proto => default, + method => plain}, + do_connect(ServerSA, Opts). + +connect(Addr, Port) when is_tuple(Addr) andalso is_integer(Port) -> + Domain = inet, + ServerSA = #{family => Domain, + addr => Addr, + port => Port}, + Opts = #{domain => Domain, + proto => tcp, + method => plain}, + do_connect(ServerSA, Opts); +connect(ServerPath, + #{domain := local = Domain, proto := default} = Opts) + when is_list(ServerPath) -> + ServerSA = #{family => Domain, path => ServerPath}, + do_connect(ServerSA, Opts). + +connect(Addr, Port, #{domain := Domain, proto := tcp} = Opts) -> + ServerSA = #{family => Domain, + addr => Addr, + port => Port}, + do_connect(ServerSA, Opts). + +do_connect(ServerSA, #{domain := Domain, + proto := Proto, + method := Method} = Opts) -> try begin Sock = - case socket:open(inet, stream, tcp) of + case socket:open(Domain, stream, Proto) of {ok, S} -> S; {error, OReason} -> throw({error, {open, OReason}}) end, - case socket:bind(Sock, any) of + LocalSA = which_sa(Domain), + case socket:bind(Sock, LocalSA) of {ok, _} -> ok; {error, BReason} -> (catch socket:close(Sock)), throw({error, {bind, BReason}}) end, - SA = #{family => inet, - addr => Addr, - port => Port}, - case socket:connect(Sock, SA) of + case socket:connect(Sock, ServerSA) of ok -> ok; {error, CReason} -> @@ -140,6 +168,15 @@ connect(Addr, Port, #{method := Method} = Opts) -> ERROR end. +which_sa(local = Domain) -> + #{family => Domain, + path => mk_unique_path()}; +which_sa(_) -> + any. + +mk_unique_path() -> + [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), + ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]). maybe_start_stats_timer(#{stats_to := Pid, stats_interval := T}, -- cgit v1.2.3 From 6e08c4d74ba926827f644c2214675dc96d44423a Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 14 May 2019 19:24:18 +0200 Subject: [esock|test] Improved the path "unlink" Wrapped unlinking of path (for Unix Domain sockets) in a utility function. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 442 ++++++++++++++++-------------------- 1 file changed, 190 insertions(+), 252 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index a60012f86c..1842ca3330 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -536,71 +536,75 @@ use_group(Group, Env, Default) -> groups() -> - [{api, [], api_cases()}, - {api_basic, [], api_basic_cases()}, - {api_options, [], api_options_cases()}, - {api_op_with_timeout, [], api_op_with_timeout_cases()}, - {socket_closure, [], socket_closure_cases()}, - {sc_ctrl_proc_exit, [], sc_cp_exit_cases()}, - {sc_local_close, [], sc_lc_cases()}, - {sc_remote_close, [], sc_rc_cases()}, - {sc_remote_shutdown, [], sc_rs_cases()}, - {traffic, [], traffic_cases()}, - {ttest, [], ttest_cases()}, - {ttest_sgenf, [], ttest_sgenf_cases()}, - {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()}, - {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()}, - {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()}, - {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()}, - {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()}, - {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()}, - {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()}, - {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()}, - {ttest_sgeno, [], ttest_sgeno_cases()}, - {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()}, - {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()}, - {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()}, - {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()}, - {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()}, - {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()}, - {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()}, - {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()}, - {ttest_sgent, [], ttest_sgent_cases()}, - {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()}, - {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()}, - {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()}, - {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()}, - {ttest_sgent_csock, [], ttest_sgent_csock_cases()}, - {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()}, - {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()}, - {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()}, - {ttest_ssockf, [], ttest_ssockf_cases()}, - {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()}, - {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()}, - {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()}, - {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()}, - {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()}, - {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()}, - {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()}, - {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()}, - {ttest_ssocko, [], ttest_ssocko_cases()}, - {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()}, - {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()}, - {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()}, - {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()}, - {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()}, - {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()}, - {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()}, - {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()}, - {ttest_ssockt, [], ttest_ssockt_cases()}, - {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()}, - {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()}, - {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()}, - {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()}, - {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()}, - {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()}, - {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()}, - {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()} + [{api, [], api_cases()}, + {api_basic, [], api_basic_cases()}, + {api_options, [], api_options_cases()}, + {api_op_with_timeout, [], api_op_with_timeout_cases()}, + {socket_closure, [], socket_closure_cases()}, + {sc_ctrl_proc_exit, [], sc_cp_exit_cases()}, + {sc_local_close, [], sc_lc_cases()}, + {sc_remote_close, [], sc_rc_cases()}, + {sc_remote_shutdown, [], sc_rs_cases()}, + {traffic, [], traffic_cases()}, + {traffic_chunks, [], traffic_chunks_cases()}, + {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()}, + {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()}, + {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()}, + {ttest, [], ttest_cases()}, + {ttest_sgenf, [], ttest_sgenf_cases()}, + {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()}, + {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()}, + {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()}, + {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()}, + {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()}, + {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()}, + {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()}, + {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()}, + {ttest_sgeno, [], ttest_sgeno_cases()}, + {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()}, + {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()}, + {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()}, + {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()}, + {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()}, + {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()}, + {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()}, + {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()}, + {ttest_sgent, [], ttest_sgent_cases()}, + {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()}, + {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()}, + {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()}, + {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()}, + {ttest_sgent_csock, [], ttest_sgent_csock_cases()}, + {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()}, + {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()}, + {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()}, + {ttest_ssockf, [], ttest_ssockf_cases()}, + {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()}, + {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()}, + {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()}, + {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()}, + {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()}, + {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()}, + {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()}, + {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()}, + {ttest_ssocko, [], ttest_ssocko_cases()}, + {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()}, + {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()}, + {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()}, + {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()}, + {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()}, + {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()}, + {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()}, + {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()}, + {ttest_ssockt, [], ttest_ssockt_cases()}, + {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()}, + {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()}, + {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()}, + {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()}, + {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()}, + {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()}, + {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()}, + {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()} %% {tickets, [], ticket_cases()} ]. @@ -733,11 +737,22 @@ sc_rs_cases() -> traffic_cases() -> + [ + {group, traffic_chunks}, + {group, traffic_pp_send_recv}, + {group, traffic_pp_sendto_recvfrom}, + {group, traffic_pp_sendmsg_recvmsg} + ]. + +traffic_chunks_cases() -> [ traffic_send_and_recv_chunks_tcp4, traffic_send_and_recv_chunks_tcp6, - traffic_send_and_recv_chunks_tcpL, + traffic_send_and_recv_chunks_tcpL + ]. +traffic_pp_send_recv_cases() -> + [ traffic_ping_pong_small_send_and_recv_tcp4, traffic_ping_pong_small_send_and_recv_tcp6, traffic_ping_pong_small_send_and_recv_tcpL, @@ -746,15 +761,21 @@ traffic_cases() -> traffic_ping_pong_medium_send_and_recv_tcpL, traffic_ping_pong_large_send_and_recv_tcp4, traffic_ping_pong_large_send_and_recv_tcp6, - traffic_ping_pong_large_send_and_recv_tcpL, + traffic_ping_pong_large_send_and_recv_tcpL + ]. +traffic_pp_sendto_recvfrom_cases() -> + [ traffic_ping_pong_small_sendto_and_recvfrom_udp4, traffic_ping_pong_small_sendto_and_recvfrom_udp6, traffic_ping_pong_small_sendto_and_recvfrom_udpL, traffic_ping_pong_medium_sendto_and_recvfrom_udp4, traffic_ping_pong_medium_sendto_and_recvfrom_udp6, - traffic_ping_pong_medium_sendto_and_recvfrom_udpL, + traffic_ping_pong_medium_sendto_and_recvfrom_udpL + ]. +traffic_pp_sendmsg_recvmsg_cases() -> + [ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4, traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6, traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL, @@ -772,8 +793,7 @@ traffic_cases() -> traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6, traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL ]. - - + ttest_cases() -> [ %% Server: transport = gen_tcp, active = false @@ -1946,18 +1966,9 @@ api_b_send_and_recv_udp(InitState) -> lsa_src := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(lsa_src, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> maps:remove(lsa_src, State) end, + fun() -> State end), {ok, maps:remove(sock_src, State1)}; (#{sock_src := Sock} = State) -> ok = socket:close(Sock), @@ -1969,18 +1980,9 @@ api_b_send_and_recv_udp(InitState) -> lsa_dst := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(lsa_dst, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> maps:remove(lsa_dst, State) end, + fun() -> State end), {ok, maps:remove(sock_dst, State1)}; (#{sock_dst := Sock} = State) -> ok = socket:close(Sock), @@ -2252,18 +2254,11 @@ api_b_send_and_recv_tcp(InitState) -> local_sa := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(lsock, State1)}; (#{lsock := LSock} = State) -> case socket:close(LSock) of @@ -2386,18 +2381,11 @@ api_b_send_and_recv_tcp(InitState) -> local_sa := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(sock, State1)}; (#{sock := Sock} = State) -> ok = socket:close(Sock), @@ -5969,18 +5957,9 @@ sc_lc_receive_response_tcp(InitState) -> lsa := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(lsa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() ->maps:remove(lsa, State) end, + fun() -> State end), State2 = maps:remove(lsock, State1), State3 = maps:remove(lport, State2), {ok, State3}; @@ -6178,18 +6157,11 @@ sc_lc_receive_response_tcp(InitState) -> local_sa := #{path := Path}} = State) -> sock_close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(sock, State1)}; (#{sock := Sock} = State) -> sock_close(Sock), @@ -6595,18 +6567,11 @@ sc_lc_receive_response_udp(InitState) -> local_sa := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(sock, State1)}; (#{sock := Sock} = State) -> case socket:close(Sock) of @@ -7201,20 +7166,16 @@ sc_lc_acceptor_response_tcp(InitState) -> case socket:close(Sock) of ok -> State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(lsa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(lsa, State) + end, + fun() -> + State + end), {ok, maps:remove(sock, State1)}; {error, _} = ERROR -> + unlink_path(Path), ERROR end; (#{sock := Sock} = State) -> @@ -7842,20 +7803,16 @@ sc_rc_receive_response_tcp(InitState) -> case socket:close(LSock) of ok -> State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(lsa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(lsa, State) + end, + fun() -> + State + end), {ok, maps:remove(lsock, State1)}; {error, _} = ERROR -> + unlink_path(Path), ERROR end; (#{lsock := LSock} = State) -> @@ -8397,12 +8354,12 @@ sc_rc_tcp_client_close(Sock, Path) -> i("sc_rc_tcp_client_close -> entry"), case socket:close(Sock) of ok -> - unlink_socket(Path), + unlink_path(Path), ok; {error, Reason} -> ?SEV_EPRINT("failed closing: " "~n Reason: ~p", [Reason]), - unlink_socket(Path), + unlink_path(Path), {error, {close, Reason}} end. @@ -8817,20 +8774,13 @@ sc_rs_send_shutdown_receive_tcp(InitState) -> cmd => fun(#{domain := local, lsock := Sock, local_sa := #{path := Path}} = State) -> - ok = socket:close(Sock), + socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(lsock, State1)}; (#{lsock := LSock} = State) -> case socket:close(LSock) of @@ -9355,12 +9305,12 @@ sc_rs_tcp_client_close(Sock, Path) -> i("sc_rs_tcp_client_close -> entry"), case socket:close(Sock) of ok -> - unlink_socket(Path), + unlink_path(Path), ok; {error, Reason} -> ?SEV_EPRINT("failed closing: " "~n Reason: ~p", [Reason]), - unlink_socket(Path), + unlink_path(Path), {error, {close, Reason}} end. @@ -9884,14 +9834,11 @@ traffic_send_and_recv_chunks_tcp(InitState) -> local_sa := #{path := Path}} = State) -> ok = socket:close(Sock), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - maps:remove(local_sa, State); - Result -> - ?SEV_IPRINT("unlink result: " - "~n ~s", [Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(lsock, State1)}; (#{lsock := Sock} = State) -> (catch socket:close(Sock)), @@ -10593,12 +10540,12 @@ traffic_snr_tcp_client_close(Sock, Path) -> i("traffic_snr_tcp_client_close -> entry"), case socket:close(Sock) of ok -> - unlink_socket(Path), + unlink_path(Path), ok; {error, Reason} -> ?SEV_EPRINT("failed closing: " "~n Reason: ~p", [Reason]), - unlink_socket(Path), + unlink_path(Path), {error, {close, Reason}} end. @@ -11721,18 +11668,11 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) -> local_sa := #{path := Path}} = State) -> (catch socket:close(Sock)), State1 = - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - maps:remove(local_sa, State); - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - State - end, + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), {ok, maps:remove(lsock, State1)}; (#{lsock := Sock} = State) -> (catch socket:close(Sock)), @@ -12343,32 +12283,15 @@ tpp_tcp_client_sock_connect(Sock, ServerSA) -> tpp_tcp_client_sock_close(Sock, Path) -> case socket:close(Sock) of ok -> - unlink_socket(Path), + unlink_path(Path), ok; {error, Reason} -> ?SEV_EPRINT("failed closing: " "~n Reason: ~p", [Reason]), - unlink_socket(Path), + unlink_path(Path), {error, {close, Reason}} end. -unlink_socket(Path) when is_list(Path) -> - ?SEV_IPRINT("try unlink path: " - "~n ~s", [Path]), - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - ok; - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", [Path, Result]), - ok - end; -unlink_socket(_) -> - ok. - -define(TPP_REQUEST, 1). @@ -12646,18 +12569,13 @@ traffic_ping_pong_send_and_receive_udp2(InitState) -> #{desc => "(maybe) unlink socket", cmd => fun(#{domain := local, local_sa := #{path := Path}} = State) -> - case os:cmd("unlink " ++ Path) of - "" -> - ?SEV_IPRINT("path unlinked: " - "~n Path: ~s", [Path]), - {ok, maps:remove(local_sa, State)}; - Result -> - ?SEV_EPRINT("unlink maybe failed: " - "~n Path: ~s" - "~n Res: ~s", - [Path, Result]), - ok - end; + unlink_path(Path, + fun() -> + {ok, maps:remove(local_sa, State)} + end, + fun() -> + ok + end); (_) -> ok end}, @@ -13286,12 +13204,12 @@ tpp_udp_sock_bind(Sock, Domain) -> tpp_udp_sock_close(Sock, Path) -> case socket:close(Sock) of ok -> - unlink_socket(Path), + unlink_path(Path), ok; {error, Reason} -> ?SEV_EPRINT("Failed closing socket: " "~n ~p", [Reason]), - unlink_socket(Path), + unlink_path(Path), {error, {close, Reason}} end. @@ -19175,8 +19093,7 @@ local_host() -> %% don't clash. mk_unique_path() -> [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), - %% ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:unique_integer()]). - ?LIB:f("/tmp/socket_~s_~w", [NodeName, erlang:system_time(nanosecond)]). + ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]). which_local_socket_addr(local = Domain) -> #{family => Domain, @@ -19220,6 +19137,27 @@ which_addr2(Domain, [_|IFO]) -> +unlink_path(Path) -> + unlink_path(Path, fun() -> ok end, fun() -> ok end). + +unlink_path(Path, Success, Failure) when is_list(Path) andalso + is_function(Success, 0) andalso + is_function(Failure, 0) -> + ?SEV_IPRINT("try unlink path: " + "~n ~s", [Path]), + case os:cmd("unlink " ++ Path) of + "" -> + ?SEV_IPRINT("path unlinked: " + "~n Path: ~s", [Path]), + Success(); + Result -> + ?SEV_EPRINT("unlink maybe failed: " + "~n Path: ~s" + "~n Res: ~s", [Path, Result]), + Failure() + end; +unlink_path(_, _, _) -> + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From d1f053ada333595d07ee3d837bf0071e651c7dc9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 14:21:21 +0200 Subject: [esock|test] Made the first ttest case (ssf/csf/s) work for local (stream) Add the first *working* ttest test case for Unix Domain (stream) socket: Server: socket with active = false Client: socket with active = false Message Size: small OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 139 +++++++++++++++++---- .../emulator/test/socket_test_ttest_tcp_client.erl | 96 +++++++------- erts/emulator/test/socket_test_ttest_tcp_gen.erl | 11 +- .../emulator/test/socket_test_ttest_tcp_server.erl | 36 ++++-- .../emulator/test/socket_test_ttest_tcp_socket.erl | 104 ++++++++++----- 5 files changed, 270 insertions(+), 116 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 1842ca3330..fd7581f664 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -353,6 +353,7 @@ %% Client: transport = socket(tcp) ttest_ssockf_csockf_small_tcp4/1, ttest_ssockf_csockf_small_tcp6/1, + ttest_ssockf_csockf_small_tcpL/1, ttest_ssockf_csockf_medium_tcp4/1, ttest_ssockf_csockf_medium_tcp6/1, ttest_ssockf_csockf_large_tcp4/1, @@ -1199,6 +1200,7 @@ ttest_ssockf_csockf_cases() -> [ ttest_ssockf_csockf_small_tcp4, ttest_ssockf_csockf_small_tcp6, + ttest_ssockf_csockf_small_tcpL, ttest_ssockf_csockf_medium_tcp4, ttest_ssockf_csockf_medium_tcp6, @@ -16287,6 +16289,30 @@ ttest_ssockf_csockf_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = false +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockf_csockf_small_tcpL(suite) -> + []; +ttest_ssockf_csockf_small_tcpL(doc) -> + []; +ttest_ssockf_csockf_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csockf_small_tcpL, + Runtime, + local, + sock, false, + sock, false, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18460,7 +18486,8 @@ ttest_tcp(TC, tc_try(TC, fun() -> if - (Domain =/= inet) -> has_support_ipv6(); + (Domain =:= local) -> has_support_unix_domain_socket(); + (Domain =:= inet6) -> has_support_ipv6(); true -> ok end end, @@ -18514,11 +18541,25 @@ ttest_tcp(InitState) -> ok end}, #{desc => "start ttest (remote) server", - cmd => fun(#{mod := Mod, + cmd => fun(#{domain := local = Domain, + mod := Mod, + active := Active, + node := Node} = State) -> + case ttest_tcp_server_start(Node, + Domain, Mod, Active) of + {ok, {{Pid, _}, Path}} -> + {ok, State#{rserver => Pid, + path => Path}}; + {error, _} = ERROR -> + ERROR + end; + (#{domain := Domain, + mod := Mod, active := Active, node := Node} = State) -> - case ttest_tcp_server_start(Node, Mod, Active) of - {ok, {{Pid, _MRef}, {Addr, Port}}} -> + case ttest_tcp_server_start(Node, + Domain, Mod, Active) of + {ok, {{Pid, _}, {Addr, Port}}} -> {ok, State#{rserver => Pid, addr => Addr, port => Port}}; @@ -18527,7 +18568,12 @@ ttest_tcp(InitState) -> end end}, #{desc => "announce ready (init)", - cmd => fun(#{tester := Tester, + cmd => fun(#{domain := local, + tester := Tester, + path := Path}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Path), + ok; + (#{tester := Tester, addr := Addr, port := Port}) -> ?SEV_ANNOUNCE_READY(Tester, init, {Addr, Port}), @@ -18582,8 +18628,14 @@ ttest_tcp(InitState) -> [ %% *** Wait for start order part *** #{desc => "await start", - cmd => fun(State) -> - {Tester, {ServerAddr, ServerPort}} = ?SEV_AWAIT_START(), + cmd => fun(#{domain := local} = State) -> + {Tester, ServerPath} = + ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, + server_path => ServerPath}}; + (State) -> + {Tester, {ServerAddr, ServerPort}} = + ?SEV_AWAIT_START(), {ok, State#{tester => Tester, server_addr => ServerAddr, server_port => ServerPort}} @@ -18624,7 +18676,32 @@ ttest_tcp(InitState) -> ok end}, #{desc => "start ttest (remote) client", - cmd => fun(#{node := Node, + cmd => fun(#{domain := local = Domain, + node := Node, + mod := Mod, + active := Active, + msg_id := MsgID, + max_outstanding := MaxOutstanding, + runtime := RunTime, + server_path := Path} = State) -> + Self = self(), + Notify = + fun(Result) -> + ?SEV_ANNOUNCE_READY(Self, ttest, Result) + end, + case ttest_tcp_client_start(Node, Notify, + Domain, Mod, + Path, + Active, + MsgID, MaxOutstanding, + RunTime) of + {ok, {Pid, _MRef}} -> + {ok, State#{rclient => Pid}}; + {error, _} = ERROR -> + ERROR + end; + (#{domain := Domain, + node := Node, mod := Mod, active := Active, msg_id := MsgID, @@ -18638,8 +18715,9 @@ ttest_tcp(InitState) -> ?SEV_ANNOUNCE_READY(Self, ttest, Result) end, case ttest_tcp_client_start(Node, Notify, - Mod, Active, - Addr, Port, + Domain, Mod, + {Addr, Port}, + Active, MsgID, MaxOutstanding, RunTime) of {ok, {Pid, _MRef}} -> @@ -18651,8 +18729,6 @@ ttest_tcp(InitState) -> #{desc => "await ttest ready", cmd => fun(#{tester := Tester, rclient := RClient} = State) -> - %% TTestResult = ?SEV_AWAIT_READY(RClient, rclient, ttest, - %% [{tester, Tester}]), case ?SEV_AWAIT_READY(RClient, rclient, ttest, [{tester, Tester}]) of {ok, Result} -> @@ -18723,8 +18799,13 @@ ttest_tcp(InitState) -> ok end}, #{desc => "await server ready (init)", - cmd => fun(#{server := Pid} = State) -> - {ok, {Addr, Port}} = ?SEV_AWAIT_READY(Pid, server, init), + cmd => fun(#{domain := local, + server := Pid} = State) -> + {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init), + {ok, State#{server_path => Path}}; + (#{server := Pid} = State) -> + {ok, {Addr, Port}} = + ?SEV_AWAIT_READY(Pid, server, init), {ok, State#{server_addr => Addr, server_port => Port}} end}, @@ -18732,7 +18813,12 @@ ttest_tcp(InitState) -> %% Start the client #{desc => "order client start", - cmd => fun(#{client := Pid, + cmd => fun(#{domain := local, + client := Pid, + server_path := Path} = _State) -> + ?SEV_ANNOUNCE_START(Pid, Path), + ok; + (#{client := Pid, server_addr := Addr, server_port := Port} = _State) -> ?SEV_ANNOUNCE_START(Pid, {Addr, Port}), @@ -18871,7 +18957,8 @@ ttest_tcp(InitState) -> Client = ?SEV_START("client", ClientSeq, ClientInitState), i("start 'tester' evaluator"), - TesterInitState = #{server => Server#ev.pid, + TesterInitState = #{domain => maps:get(domain, InitState), + server => Server#ev.pid, client => Client#ev.pid}, Tester = ?SEV_START("tester", TesterSeq, TesterInitState), @@ -18880,12 +18967,12 @@ ttest_tcp(InitState) -> -ttest_tcp_server_start(Node, gen, Active) -> +ttest_tcp_server_start(Node, _Domain, gen, Active) -> Transport = socket_test_ttest_tcp_gen, socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active); -ttest_tcp_server_start(Node, sock, Active) -> +ttest_tcp_server_start(Node, Domain, sock, Active) -> TransportMod = socket_test_ttest_tcp_socket, - Transport = {TransportMod, #{method => plain}}, + Transport = {TransportMod, #{domain => Domain, method => plain}}, socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active). ttest_tcp_server_stop(Pid) -> @@ -18893,26 +18980,26 @@ ttest_tcp_server_stop(Pid) -> ttest_tcp_client_start(Node, Notify, - gen, - Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> + _Domain, gen, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> Transport = socket_test_ttest_tcp_gen, socket_test_ttest_tcp_client:start_monitor(Node, Notify, Transport, + ServerInfo, Active, - Addr, Port, MsgID, MaxOutstanding, RunTime); ttest_tcp_client_start(Node, Notify, - sock, - Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> + Domain, sock, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> TransportMod = socket_test_ttest_tcp_socket, - Transport = {TransportMod, #{method => plain}}, + Transport = {TransportMod, #{domain => Domain, method => plain}}, socket_test_ttest_tcp_client:start_monitor(Node, Notify, Transport, + ServerInfo, Active, - Addr, Port, MsgID, MaxOutstanding, RunTime). diff --git a/erts/emulator/test/socket_test_ttest_tcp_client.erl b/erts/emulator/test/socket_test_ttest_tcp_client.erl index 5efa3fe491..b5c5300fd0 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_client.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_client.erl @@ -42,16 +42,16 @@ -export([ %% These are for the test suite - start_monitor/6, start_monitor/7, start_monitor/9, + start_monitor/5, start_monitor/6, start_monitor/8, %% These are for starting in a shell when run "manually" - start/4, start/5, start/7, start/8, + start/3, start/4, start/6, start/7, stop/1 ]). %% Internal exports -export([ - do_start/10 + do_start/9 ]). -include_lib("kernel/include/inet.hrl"). @@ -80,25 +80,25 @@ %% ========================================================================== -start_monitor(Node, Notify, Transport, Active, Addr, Port) -> - start_monitor(Node, Notify, Transport, Active, Addr, Port, ?MSG_ID_DEFAULT). +start_monitor(Node, Notify, Transport, ServerInfo, Active) -> + start_monitor(Node, Notify, Transport, ServerInfo, Active, ?MSG_ID_DEFAULT). -start_monitor(Node, Notify, Transport, Active, Addr, Port, 1 = MsgID) -> - start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID, +start_monitor(Node, Notify, Transport, ServerInfo, Active, 1 = MsgID) -> + start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_1, ?RUNTIME_DEFAULT); -start_monitor(Node, Notify, Transport, Active, Addr, Port, 2 = MsgID) -> - start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID, +start_monitor(Node, Notify, Transport, ServerInfo, Active, 2 = MsgID) -> + start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_2, ?RUNTIME_DEFAULT); -start_monitor(Node, Notify, Transport, Active, Addr, Port, 3 = MsgID) -> - start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID, +start_monitor(Node, Notify, Transport, ServerInfo, Active, 3 = MsgID) -> + start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_3, ?RUNTIME_DEFAULT). -start_monitor(Node, Notify, Transport, Active, Addr, Port, +start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) when (Node =/= node()) -> Args = [false, self(), Notify, - Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime], + Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime], case rpc:call(Node, ?MODULE, do_start, Args) of {badrpc, _} = Reason -> {error, Reason}; @@ -108,11 +108,11 @@ start_monitor(Node, Notify, Transport, Active, Addr, Port, {error, _} = ERROR -> ERROR end; -start_monitor(_, Notify, Transport, Active, Addr, Port, +start_monitor(_, Notify, Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> case do_start(false, self(), Notify, - Transport, Active, Addr, Port, + Transport, Active, ServerInfo, MsgID, MaxOutstanding, RunTime) of {ok, Pid} -> MRef = erlang:monitor(process, Pid), @@ -122,50 +122,48 @@ start_monitor(_, Notify, Transport, Active, Addr, Port, end. -start(Transport, Active, Addr, Port) -> - start(Transport, Active, Addr, Port, ?MSG_ID_DEFAULT). +start(Transport, ServerInfo, Active) -> + start(Transport, ServerInfo, Active, ?MSG_ID_DEFAULT). -start(Transport, Active, Addr, Port, 1 = MsgID) -> +start(Transport, ServerInfo, Active, 1 = MsgID) -> start(false, - Transport, Active, Addr, Port, MsgID, + Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_1, ?RUNTIME_DEFAULT); -start(Transport, Active, Addr, Port, 2 = MsgID) -> +start(Transport, ServerInfo, Active, 2 = MsgID) -> start(false, - Transport, Active, Addr, Port, MsgID, + Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_2, ?RUNTIME_DEFAULT); -start(Transport, Active, Addr, Port, 3 = MsgID) -> +start(Transport, ServerInfo, Active, 3 = MsgID) -> start(false, - Transport, Active, Addr, Port, MsgID, + Transport, ServerInfo, Active, MsgID, ?MAX_OUTSTANDING_DEFAULT_3, ?RUNTIME_DEFAULT). -start(Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> start(false, - Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime). + Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime). -start(Quiet, Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(Quiet, Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> Notify = fun(R) -> present_results(R) end, do_start(Quiet, self(), Notify, - Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime). + Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime). -spec do_start(Quiet, Parent, Notify, Transport, + ServerInfo, Active, - Addr, - Port, MsgID, MaxOutstanding, RunTime) -> {ok, Pid} | {error, Reason} when - Quiet :: pid(), + Quiet :: boolean(), Parent :: pid(), Notify :: function(), Transport :: atom() | tuple(), + ServerInfo :: {inet:ip_address(), inet:port_number()} | string(), Active :: active(), - Addr :: inet:ip_address(), - Port :: inet:port_number(), MsgID :: msg_id(), MaxOutstanding :: max_outstanding(), RunTime :: runtime(), @@ -174,14 +172,13 @@ start(Quiet, Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> do_start(Quiet, Parent, Notify, - Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) + Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) when is_boolean(Quiet) andalso is_pid(Parent) andalso is_function(Notify) andalso (is_atom(Transport) orelse is_tuple(Transport)) andalso (is_boolean(Active) orelse (Active =:= once)) andalso - is_tuple(Addr) andalso - (is_integer(Port) andalso (Port > 0)) andalso + (is_tuple(ServerInfo) orelse is_list(ServerInfo)) andalso (is_integer(MsgID) andalso (MsgID >= 1) andalso (MsgID =< 3)) andalso (is_integer(MaxOutstanding) andalso (MaxOutstanding > 0)) andalso (is_integer(RunTime) andalso (RunTime > 0)) -> @@ -191,7 +188,7 @@ do_start(Quiet, Starter, Parent, Notify, - Transport, Active, Addr, Port, + Transport, Active, ServerInfo, MsgID, MaxOutstanding, RunTime) end, {Pid, MRef} = spawn_monitor(Init), @@ -217,25 +214,30 @@ stop(Pid) when is_pid(Pid) -> init(Quiet, Starter, Parent, Notify, - Transport, Active, Addr, Port, + Transport, Active, ServerInfo, MsgID, MaxOutstanding, RunTime) -> if not Quiet -> ?I("init with" "~n Transport: ~p" "~n Active: ~p" - "~n Addr: ~s" - "~n Port: ~p" + "~n ServerInfo: ~s" "~n Msg ID: ~p (=> 16 + ~w bytes)" "~n Max Outstanding: ~p" "~n (Suggested) Run Time: ~p ms", - [Transport, Active, inet:ntoa(Addr), Port, + [Transport, Active, + case ServerInfo of + {Addr, Port} -> + ?F("Addr: ~s, Port: ~w", [inet:ntoa(Addr), Port]); + Path -> + Path + end, MsgID, size(which_msg_data(MsgID)), MaxOutstanding, RunTime]); true -> ok end, {Mod, Connect} = process_transport(Transport), - case Connect(Addr, Port) of + case Connect(ServerInfo) of {ok, Sock} -> if not Quiet -> ?I("connected"); true -> ok @@ -269,9 +271,15 @@ init(Quiet, end. process_transport(Mod) when is_atom(Mod) -> - {Mod, fun(A, P) -> Mod:connect(A, P) end}; -process_transport({Mod, Opts}) -> - {Mod, fun(A, P) -> Mod:connect(A, P, Opts) end}. + %% In this case we assume it to be a plain tcp socket + {Mod, fun({A, P}) -> Mod:connect(A, P) end}; +process_transport({Mod, #{domain := Domain} = Opts}) -> + Connect = + case Domain of + local -> fun(Path) -> Mod:connect(Path, Opts) end; + _ -> fun({A, P}) -> Mod:connect(A, P, Opts) end + end, + {Mod, Connect}. which_msg_data(1) -> ?MSG_DATA1; diff --git a/erts/emulator/test/socket_test_ttest_tcp_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_gen.erl index 604408c489..16e7ccf66b 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_gen.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% Copyright Ericsson AB 2018-2019. 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. @@ -24,7 +24,7 @@ accept/1, accept/2, active/2, close/1, - connect/2, + connect/2, connect/3, controlling_process/2, listen/0, listen/1, peername/1, @@ -80,6 +80,13 @@ close(Sock) -> connect(Addr, Port) -> Opts = [binary, {packet, raw}, {active, false}, {buffer, 32*1024}], + do_connect(Addr, Port, Opts). + +connect(Addr, Port, #{domain := Domain}) -> + Opts = [Domain, binary, {packet, raw}, {active, false}, {buffer, 32*1024}], + do_connect(Addr, Port, Opts). + +do_connect(Addr, Port, Opts) -> case gen_tcp:connect(Addr, Port, Opts) of {ok, Sock} -> {ok, Sock}; diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl index e8d626e3d8..974f964c36 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% Copyright Ericsson AB 2018-2019. 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. @@ -96,8 +96,9 @@ do_start(Parent, Transport, Active) (is_atom(Transport) orelse is_tuple(Transport)) andalso (is_boolean(Active) orelse (Active =:= once)) -> Starter = self(), - ServerInit = fun() -> put(sname, "server"), - server_init(Starter, Parent, Transport, Active) + ServerInit = fun() -> + put(sname, "server"), + server_init(Starter, Parent, Transport, Active) end, {Pid, MRef} = spawn_monitor(ServerInit), receive @@ -126,13 +127,24 @@ server_init(Starter, Parent, Transport, Active) -> case Listen(0) of {ok, LSock} -> case Mod:port(LSock) of - {ok, Port} -> - Addr = which_addr(), % This is just for convenience - ?I("listening on:" - "~n Addr: ~p (~s)" - "~n Port: ~w" - "~n", [Addr, inet:ntoa(Addr), Port]), - Starter ! {?MODULE, self(), {ok, {Addr, Port}}}, + {ok, PortOrPath} -> + Result = + if + is_integer(PortOrPath) -> + %% This is just for convenience + Addr = which_addr(), + ?I("listening on:" + "~n Addr: ~p (~s)" + "~n Port: ~w" + "~n", [Addr, inet:ntoa(Addr), PortOrPath]), + {Addr, PortOrPath}; + is_list(PortOrPath) -> + ?I("listening on:" + "~n Path: ~s" + "~n", [PortOrPath]), + PortOrPath + end, + Starter ! {?MODULE, self(), {ok, Result}}, server_loop(#{parent => Parent, mod => Mod, active => Active, @@ -208,7 +220,9 @@ format_peername({Addr, Port}) -> ?F("~s (~s:~w)", [N, inet:ntoa(Addr), Port]); {error, _} -> ?F("~p, ~p", [Addr, Port]) - end. + end; +format_peername(Path) when is_list(Path) -> + Path. maybe_start_stats_timer(#{active := Active, stats_interval := Time}, Handler) when (Active =/= false) andalso (is_integer(Time) andalso (Time > 0)) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_socket.erl index 6a54d70d58..8df1cdfad3 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_socket.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% Copyright Ericsson AB 2018-2019. 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. @@ -99,41 +99,60 @@ active(#{reader := Pid}, NewActive) close(#{sock := Sock, reader := Pid}) -> Pid ! {?MODULE, stop}, - socket:close(Sock). + Unlink = case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + fun() -> os:cmd("unlink " ++ Path), ok end; + _ -> + fun() -> ok end + end, + Res = socket:close(Sock), + Unlink(), + Res. %% Create a socket and connect it to a peer connect(ServerPath) when is_list(ServerPath) -> Domain = local, + LocalSA = #{family => Domain, + path => mk_unique_path()}, ServerSA = #{family => Domain, path => ServerPath}, Opts = #{domain => Domain, proto => default, method => plain}, - do_connect(ServerSA, Opts). + Cleanup = fun() -> os:cmd("unlink " ++ ServerPath), ok end, + do_connect(LocalSA, ServerSA, Cleanup, Opts). connect(Addr, Port) when is_tuple(Addr) andalso is_integer(Port) -> Domain = inet, + LocalSA = any, ServerSA = #{family => Domain, addr => Addr, port => Port}, Opts = #{domain => Domain, proto => tcp, method => plain}, - do_connect(ServerSA, Opts); + Cleanup = fun() -> ok end, + do_connect(LocalSA, ServerSA, Cleanup, Opts); connect(ServerPath, - #{domain := local = Domain, proto := default} = Opts) + #{domain := local = Domain} = Opts) when is_list(ServerPath) -> - ServerSA = #{family => Domain, path => ServerPath}, - do_connect(ServerSA, Opts). + LocalSA = #{family => Domain, + path => mk_unique_path()}, + ServerSA = #{family => Domain, + path => ServerPath}, + Cleanup = fun() -> os:cmd("unlink " ++ ServerPath), ok end, + do_connect(LocalSA, ServerSA, Cleanup, Opts#{proto => default}). -connect(Addr, Port, #{domain := Domain, proto := tcp} = Opts) -> +connect(Addr, Port, #{domain := Domain} = Opts) -> + LocalSA = any, ServerSA = #{family => Domain, addr => Addr, port => Port}, - do_connect(ServerSA, Opts). + Cleanup = fun() -> ok end, + do_connect(LocalSA, ServerSA, Cleanup, Opts#{proto => tcp}). -do_connect(ServerSA, #{domain := Domain, - proto := Proto, - method := Method} = Opts) -> +do_connect(LocalSA, ServerSA, Cleanup, #{domain := Domain, + proto := Proto, + method := Method} = Opts) -> try begin Sock = @@ -143,12 +162,12 @@ do_connect(ServerSA, #{domain := Domain, {error, OReason} -> throw({error, {open, OReason}}) end, - LocalSA = which_sa(Domain), case socket:bind(Sock, LocalSA) of {ok, _} -> ok; {error, BReason} -> (catch socket:close(Sock)), + Cleanup(), throw({error, {bind, BReason}}) end, case socket:connect(Sock, ServerSA) of @@ -156,6 +175,7 @@ do_connect(ServerSA, #{domain := Domain, ok; {error, CReason} -> (catch socket:close(Sock)), + Cleanup(), throw({error, {connect, CReason}}) end, Self = self(), @@ -168,12 +188,6 @@ do_connect(ServerSA, #{domain := Domain, ERROR end. -which_sa(local = Domain) -> - #{family => Domain, - path => mk_unique_path()}; -which_sa(_) -> - any. - mk_unique_path() -> [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]). @@ -200,37 +214,57 @@ controlling_process(#{sock := Sock, reader := Pid}, NewPid) -> %% Create a listen socket listen() -> - listen(0, #{method => plain}). - -listen(Port) -> - listen(Port, #{method => plain}). -listen(Port, #{method := Method} = Opts) - when (is_integer(Port) andalso (Port >= 0)) andalso - ((Method =:= plain) orelse (Method =:= msg)) -> + listen(0). + +listen(Port) when is_integer(Port) -> + listen(Port, #{domain => inet, method => plain}); +listen(Path) when is_list(Path) -> + listen(Path, #{domain => local, method => plain}). + +listen(0, #{domain := local} = Opts) -> + listen(mk_unique_path(), Opts); +listen(Path, #{domain := local = Domain} = Opts) + when is_list(Path) andalso (Path =/= []) -> + SA = #{family => Domain, + path => Path}, + Cleanup = fun() -> os:cmd("unlink " ++ Path), ok end, + do_listen(SA, Cleanup, Opts#{proto => default}); +listen(Port, #{domain := Domain} = Opts) + when is_integer(Port) andalso (Port >= 0) -> + %% Bind fills in the rest + SA = #{family => Domain, + port => Port}, + Cleanup = fun() -> ok end, + do_listen(SA, Cleanup, Opts#{proto => tcp}). + +do_listen(SA, + Cleanup, + #{domain := Domain, proto := Proto, method := Method} = Opts) + when (Method =:= plain) orelse (Method =:= msg) -> try begin - Sock = case socket:open(inet, stream, tcp) of + Sock = case socket:open(Domain, stream, Proto) of {ok, S} -> S; {error, OReason} -> throw({error, {open, OReason}}) end, - SA = #{family => inet, - port => Port}, case socket:bind(Sock, SA) of {ok, _} -> ok; {error, BReason} -> (catch socket:close(Sock)), + Cleanup(), throw({error, {bind, BReason}}) end, case socket:listen(Sock) of ok -> - ok; - {error, LReason} -> + ok; + {error, LReason} -> (catch socket:close(Sock)), - throw({error, {listen, LReason}}) - end, + Cleanup(), + throw({error, {listen, LReason}}) + end, {ok, #{sock => Sock, opts => Opts}} end catch @@ -241,6 +275,8 @@ listen(Port, #{method := Method} = Opts) port(#{sock := Sock}) -> case socket:sockname(Sock) of + {ok, #{family := local, path := Path}} -> + {ok, Path}; {ok, #{port := Port}} -> {ok, Port}; {error, _} = ERROR -> @@ -250,6 +286,8 @@ port(#{sock := Sock}) -> peername(#{sock := Sock}) -> case socket:peername(Sock) of + {ok, #{family := local, path := Path}} -> + {ok, Path}; {ok, #{addr := Addr, port := Port}} -> {ok, {Addr, Port}}; {error, _} = ERROR -> -- cgit v1.2.3 From 663a0735a1f18f1ea8e482946a98cf09f3424271 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 14:29:27 +0200 Subject: [esock|test] Add ttest case (ssf/csf/m) work for local (stream) Add ttest test case for Unix Domain (stream) socket: Server: socket with active = false Client: socket with active = false Message Size: medium OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index fd7581f664..8424f0c97b 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -356,6 +356,7 @@ ttest_ssockf_csockf_small_tcpL/1, ttest_ssockf_csockf_medium_tcp4/1, ttest_ssockf_csockf_medium_tcp6/1, + ttest_ssockf_csockf_medium_tcpL/1, ttest_ssockf_csockf_large_tcp4/1, ttest_ssockf_csockf_large_tcp6/1, @@ -1204,6 +1205,7 @@ ttest_ssockf_csockf_cases() -> ttest_ssockf_csockf_medium_tcp4, ttest_ssockf_csockf_medium_tcp6, + ttest_ssockf_csockf_medium_tcpL, ttest_ssockf_csockf_large_tcp4, ttest_ssockf_csockf_large_tcp6 @@ -16361,6 +16363,30 @@ ttest_ssockf_csockf_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = false +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockf_csockf_medium_tcpL(suite) -> + []; +ttest_ssockf_csockf_medium_tcpL(doc) -> + []; +ttest_ssockf_csockf_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csockf_medium_tcpL, + Runtime, + local, + sock, false, + sock, false, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From d6ffa270a5ab6cb1967d51a00108d2b4d8bca47f Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 14:54:59 +0200 Subject: [esock|test] Add ttest case (ssf/csf/l) work for local (stream) Add ttest test case for Unix Domain (stream) socket: Server: socket with active = false Client: socket with active = false Message Size: large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 8424f0c97b..d727a7996c 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -359,6 +359,7 @@ ttest_ssockf_csockf_medium_tcpL/1, ttest_ssockf_csockf_large_tcp4/1, ttest_ssockf_csockf_large_tcp6/1, + ttest_ssockf_csockf_large_tcpL/1, ttest_ssockf_csocko_small_tcp4/1, ttest_ssockf_csocko_small_tcp6/1, @@ -1208,7 +1209,8 @@ ttest_ssockf_csockf_cases() -> ttest_ssockf_csockf_medium_tcpL, ttest_ssockf_csockf_large_tcp4, - ttest_ssockf_csockf_large_tcp6 + ttest_ssockf_csockf_large_tcp6, + ttest_ssockf_csockf_large_tcpL ]. %% Server: transport = socket(tcp), active = false @@ -16435,6 +16437,30 @@ ttest_ssockf_csockf_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = false +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockf_csockf_large_tcpL(suite) -> + []; +ttest_ssockf_csockf_large_tcpL(doc) -> + []; +ttest_ssockf_csockf_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csockf_large_tcpL, + Runtime, + local, + sock, false, + sock, false, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From 04ce3ab360b97d3683d4692e0e354a9767106881 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 15:12:23 +0200 Subject: [esock] SO_PROTOCOL does not exist on darwin (18.2.0) The flag SO_PROTOCOL does not exist on darwin 18.2.0 (atleast). So, creating a socket with domain =/= local using the default protocol does not work in this case. OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index d8203f3b91..a62914d730 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -660,6 +660,9 @@ typedef union { #define SOCKET_SUPPORTS_SCTP 0x0002 #define SOCKET_SUPPORTS_IPV6 0x0003 +#define ESOCK_WHICH_PROTO_ERROR -1 +#define ESOCK_WHICH_PROTO_UNSUP -2 + /* =================================================================== * @@ -4465,9 +4468,16 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, if ((proto != 0) && (domain != AF_LOCAL)) if (!nopen_which_protocol(sock, &proto)) { - save_errno = sock_errno(); - while ((sock_close(sock) == INVALID_SOCKET) && (sock_errno() == EINTR)); - return esock_make_error_errno(env, save_errno); + if (proto == ESOCK_WHICH_PROTO_ERROR) { + save_errno = sock_errno(); + while ((sock_close(sock) == INVALID_SOCKET) && + (sock_errno() == EINTR)); + return esock_make_error_errno(env, save_errno); + } else { + while ((sock_close(sock) == INVALID_SOCKET) && + (sock_errno() == EINTR)); + return esock_make_error(env, esock_atom_eafnosupport); + } } @@ -4544,6 +4554,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, static BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto) { +#if defined(SO_PROTOCOL) int val; SOCKOPTLEN_T valSz = sizeof(val); int res; @@ -4551,11 +4562,16 @@ BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto) res = sock_getopt(sock, SOL_SOCKET, SO_PROTOCOL, &val, &valSz); if (res != 0) { + *proto = ESOCK_WHICH_PROTO_ERROR; return FALSE; } else { *proto = val; return TRUE; } +#else + *proto = ESOCK_WHICH_PROTO_UNSUP; + return FALSE; +#endif } @@ -16303,8 +16319,6 @@ char* encode_cmsghdr_data_ipv6(ErlNifEnv* env, size_t dataLen, ERL_NIF_TERM* eCMsgHdrData) { - char* xres; - switch (type) { #if defined(IPV6_PKTINFO) case IPV6_PKTINFO: @@ -16312,6 +16326,7 @@ char* encode_cmsghdr_data_ipv6(ErlNifEnv* env, struct in6_pktinfo* pktInfoP = (struct in6_pktinfo*) dataP; ERL_NIF_TERM ifIndex = MKI(env, pktInfoP->ipi6_ifindex); ERL_NIF_TERM addr; + char* xres; if ((xres = esock_encode_ip6_address(env, &pktInfoP->ipi6_addr, -- cgit v1.2.3 From 6dac2f046233b75d6a4a52ddd71d9d5583de55ff Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 15:19:37 +0200 Subject: [esock|test] Add ttest case(s) (ssf/cso/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = false Client: socket with active = once Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index d727a7996c..53248111da 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -363,10 +363,13 @@ ttest_ssockf_csocko_small_tcp4/1, ttest_ssockf_csocko_small_tcp6/1, + ttest_ssockf_csocko_small_tcpL/1, ttest_ssockf_csocko_medium_tcp4/1, ttest_ssockf_csocko_medium_tcp6/1, + ttest_ssockf_csocko_medium_tcpL/1, ttest_ssockf_csocko_large_tcp4/1, ttest_ssockf_csocko_large_tcp6/1, + ttest_ssockf_csocko_large_tcpL/1, ttest_ssockf_csockt_small_tcp4/1, ttest_ssockf_csockt_small_tcp6/1, @@ -1219,12 +1222,15 @@ ttest_ssockf_csocko_cases() -> [ ttest_ssockf_csocko_small_tcp4, ttest_ssockf_csocko_small_tcp6, + ttest_ssockf_csocko_small_tcpL, ttest_ssockf_csocko_medium_tcp4, ttest_ssockf_csocko_medium_tcp6, + ttest_ssockf_csocko_medium_tcpL, ttest_ssockf_csocko_large_tcp4, - ttest_ssockf_csocko_large_tcp6 + ttest_ssockf_csocko_large_tcp6, + ttest_ssockf_csocko_large_tcpL ]. %% Server: transport = socket(tcp), active = false @@ -16509,6 +16515,30 @@ ttest_ssockf_csocko_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = once +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockf_csocko_small_tcpL(suite) -> + []; +ttest_ssockf_csocko_small_tcpL(doc) -> + []; +ttest_ssockf_csocko_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csocko_small_tcpL, + Runtime, + local, + sock, false, + sock, once, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -16557,6 +16587,30 @@ ttest_ssockf_csocko_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = once +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockf_csocko_medium_tcpL(suite) -> + []; +ttest_ssockf_csocko_medium_tcpL(doc) -> + []; +ttest_ssockf_csocko_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csocko_medium_tcpL, + Runtime, + local, + sock, false, + sock, once, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -16605,6 +16659,30 @@ ttest_ssockf_csocko_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = once +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockf_csocko_large_tcpL(suite) -> + []; +ttest_ssockf_csocko_large_tcpL(doc) -> + []; +ttest_ssockf_csocko_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csocko_large_tcpL, + Runtime, + local, + sock, false, + sock, once, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From 8653744f2406a9ec07d0ad29c8cd809c5523d9da Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 15:31:31 +0200 Subject: [esock|test] Add ttest case(s) (ssf/cst/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = false Client: socket with active = true Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 53248111da..63df6cd9c9 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -373,10 +373,13 @@ ttest_ssockf_csockt_small_tcp4/1, ttest_ssockf_csockt_small_tcp6/1, + ttest_ssockf_csockt_small_tcpL/1, ttest_ssockf_csockt_medium_tcp4/1, ttest_ssockf_csockt_medium_tcp6/1, + ttest_ssockf_csockt_medium_tcpL/1, ttest_ssockf_csockt_large_tcp4/1, ttest_ssockf_csockt_large_tcp6/1, + ttest_ssockf_csockt_large_tcpL/1, %% Server: transport = socket(tcp), active = once %% Client: transport = gen_tcp @@ -1239,12 +1242,15 @@ ttest_ssockf_csockt_cases() -> [ ttest_ssockf_csockt_small_tcp4, ttest_ssockf_csockt_small_tcp6, + ttest_ssockf_csockt_small_tcpL, ttest_ssockf_csockt_medium_tcp4, ttest_ssockf_csockt_medium_tcp6, + ttest_ssockf_csockt_medium_tcpL, ttest_ssockf_csockt_large_tcp4, - ttest_ssockf_csockt_large_tcp6 + ttest_ssockf_csockt_large_tcp6, + ttest_ssockf_csockt_large_tcpL ]. %% Server: transport = socket(tcp), active = once @@ -16731,6 +16737,30 @@ ttest_ssockf_csockt_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = true +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockf_csockt_small_tcpL(suite) -> + []; +ttest_ssockf_csockt_small_tcpL(doc) -> + []; +ttest_ssockf_csockt_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csocko_small_tcpL, + Runtime, + local, + sock, false, + sock, true, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -16779,6 +16809,30 @@ ttest_ssockf_csockt_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = true +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockf_csockt_medium_tcpL(suite) -> + []; +ttest_ssockf_csockt_medium_tcpL(doc) -> + []; +ttest_ssockf_csockt_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csockt_medium_tcpL, + Runtime, + local, + sock, false, + sock, true, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -16827,6 +16881,30 @@ ttest_ssockf_csockt_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = false +%% Client: Transport = socket(tcp), Active = true +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockf_csockt_large_tcpL(suite) -> + []; +ttest_ssockf_csockt_large_tcpL(doc) -> + []; +ttest_ssockf_csockt_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockf_csockt_large_tcpL, + Runtime, + local, + sock, false, + sock, true, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From fe87c100b821aab7d447320997f7417a2cdc2cd0 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 15:45:58 +0200 Subject: [esock|test] Add ttest case(s) (sso/csf/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = once Client: socket with active = false Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 63df6cd9c9..456e4fed56 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -408,10 +408,13 @@ %% Client: transport = socket(tcp) ttest_ssocko_csockf_small_tcp4/1, ttest_ssocko_csockf_small_tcp6/1, + ttest_ssocko_csockf_small_tcpL/1, ttest_ssocko_csockf_medium_tcp4/1, + ttest_ssocko_csockf_medium_tcpL/1, ttest_ssocko_csockf_medium_tcp6/1, ttest_ssocko_csockf_large_tcp4/1, ttest_ssocko_csockf_large_tcp6/1, + ttest_ssocko_csockf_large_tcpL/1, ttest_ssocko_csocko_small_tcp4/1, ttest_ssocko_csocko_small_tcp6/1, @@ -1326,12 +1329,15 @@ ttest_ssocko_csockf_cases() -> [ ttest_ssocko_csockf_small_tcp4, ttest_ssocko_csockf_small_tcp6, + ttest_ssocko_csockf_small_tcpL, ttest_ssocko_csockf_medium_tcp4, ttest_ssocko_csockf_medium_tcp6, + ttest_ssocko_csockf_medium_tcpL, ttest_ssocko_csockf_large_tcp4, - ttest_ssocko_csockf_large_tcp6 + ttest_ssocko_csockf_large_tcp6, + ttest_ssocko_csockf_large_tcpL ]. %% Server: transport = socket(tcp), active = once @@ -17385,6 +17391,30 @@ ttest_ssocko_csockf_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = false +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssocko_csockf_small_tcpL(suite) -> + []; +ttest_ssocko_csockf_small_tcpL(doc) -> + []; +ttest_ssocko_csockf_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csockf_small_tcpL, + Runtime, + local, + sock, once, + sock, false, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17433,6 +17463,30 @@ ttest_ssocko_csockf_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = false +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssocko_csockf_medium_tcpL(suite) -> + []; +ttest_ssocko_csockf_medium_tcpL(doc) -> + []; +ttest_ssocko_csockf_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csockf_medium_tcpL, + Runtime, + local, + sock, once, + sock, false, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17481,6 +17535,30 @@ ttest_ssocko_csockf_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = false +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssocko_csockf_large_tcpL(suite) -> + []; +ttest_ssocko_csockf_large_tcpL(doc) -> + []; +ttest_ssocko_csockf_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csockf_large_tcpL, + Runtime, + local, + sock, once, + sock, false, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From f749ed10398e8dd5e466aac8c8d40f2e426f7942 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:11:18 +0200 Subject: [esock|test] Add ttest case(s) (sso/cso/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = once Client: socket with active = once Message Size: small, medium and large Also added server path cleanup when closing. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 +++++++++++++++++++++- .../emulator/test/socket_test_ttest_tcp_server.erl | 10 +++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 456e4fed56..7b3de1de9a 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -418,10 +418,13 @@ ttest_ssocko_csocko_small_tcp4/1, ttest_ssocko_csocko_small_tcp6/1, + ttest_ssocko_csocko_small_tcpL/1, ttest_ssocko_csocko_medium_tcp4/1, ttest_ssocko_csocko_medium_tcp6/1, + ttest_ssocko_csocko_medium_tcpL/1, ttest_ssocko_csocko_large_tcp4/1, ttest_ssocko_csocko_large_tcp6/1, + ttest_ssocko_csocko_large_tcpL/1, ttest_ssocko_csockt_small_tcp4/1, ttest_ssocko_csockt_small_tcp6/1, @@ -1346,12 +1349,15 @@ ttest_ssocko_csocko_cases() -> [ ttest_ssocko_csocko_small_tcp4, ttest_ssocko_csocko_small_tcp6, + ttest_ssocko_csocko_small_tcpL, ttest_ssocko_csocko_medium_tcp4, ttest_ssocko_csocko_medium_tcp6, + ttest_ssocko_csocko_medium_tcpL, ttest_ssocko_csocko_large_tcp4, - ttest_ssocko_csocko_large_tcp6 + ttest_ssocko_csocko_large_tcp6, + ttest_ssocko_csocko_large_tcpL ]. %% Server: transport = socket(tcp), active = once @@ -17607,6 +17613,30 @@ ttest_ssocko_csocko_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = once +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssocko_csocko_small_tcpL(suite) -> + []; +ttest_ssocko_csocko_small_tcpL(doc) -> + []; +ttest_ssocko_csocko_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csocko_small_tcpL, + Runtime, + local, + sock, once, + sock, once, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17655,6 +17685,30 @@ ttest_ssocko_csocko_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = once +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssocko_csocko_medium_tcpL(suite) -> + []; +ttest_ssocko_csocko_medium_tcpL(doc) -> + []; +ttest_ssocko_csocko_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csocko_medium_tcpL, + Runtime, + local, + sock, once, + sock, once, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17703,6 +17757,30 @@ ttest_ssocko_csocko_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = once +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssocko_csocko_large_tcpL(suite) -> + []; +ttest_ssocko_csocko_large_tcpL(doc) -> + []; +ttest_ssocko_csocko_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csocko_large_tcpL, + Runtime, + local, + sock, once, + sock, once, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl index 974f964c36..acb940e9cd 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl @@ -149,6 +149,7 @@ server_init(Starter, Parent, Transport, Active) -> mod => Mod, active => Active, lsock => LSock, + port_or_path => PortOrPath, handlers => [], stats_interval => StatsInterval, %% Accumulation @@ -205,15 +206,22 @@ server_accept(#{mod := Mod, {error, CPReason} -> (catch Mod:close(Sock)), (catch Mod:close(LSock)), + maybe_unlink(maps:get(port_or_path, State)), exit({controlling_process, CPReason}) end; {error, timeout} -> State; {error, AReason} -> (catch Mod:close(LSock)), + maybe_unlink(maps:get(port_or_path, State)), exit({accept, AReason}) end. +maybe_unlink(Path) when is_list(Path) -> + os:cmd("unlink " ++ Path); +maybe_unlink(_) -> + ok. + format_peername({Addr, Port}) -> case inet:gethostbyaddr(Addr) of {ok, #hostent{h_name = N}} -> @@ -247,6 +255,8 @@ server_handle_message(#{parent := Parent, handlers := H} = State) -> {?MODULE, Ref, Parent, stop} -> reply(Parent, Ref, ok), lists:foreach(fun(P) -> handler_stop(P) end, H), + (catch socket:close(maps:get(lsock, State))), + maybe_unlink(maps:get(port_or_path, State)), exit(normal); {'DOWN', _MRef, process, Pid, Reason} -> -- cgit v1.2.3 From 69c1314373293bbb91fae74de312183e17af7d44 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:20:15 +0200 Subject: [esock|test] Add ttest case(s) (sso/cst/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = once Client: socket with active = true Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 7b3de1de9a..be42df0467 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -428,10 +428,13 @@ ttest_ssocko_csockt_small_tcp4/1, ttest_ssocko_csockt_small_tcp6/1, + ttest_ssocko_csockt_small_tcpL/1, ttest_ssocko_csockt_medium_tcp4/1, ttest_ssocko_csockt_medium_tcp6/1, + ttest_ssocko_csockt_medium_tcpL/1, ttest_ssocko_csockt_large_tcp4/1, ttest_ssocko_csockt_large_tcp6/1, + ttest_ssocko_csockt_large_tcpL/1, %% Server: transport = socket(tcp), active = true %% Client: transport = gen_tcp @@ -1366,12 +1369,15 @@ ttest_ssocko_csockt_cases() -> [ ttest_ssocko_csockt_small_tcp4, ttest_ssocko_csockt_small_tcp6, + ttest_ssocko_csockt_small_tcpL, ttest_ssocko_csockt_medium_tcp4, ttest_ssocko_csockt_medium_tcp6, + ttest_ssocko_csockt_medium_tcpL, ttest_ssocko_csockt_large_tcp4, - ttest_ssocko_csockt_large_tcp6 + ttest_ssocko_csockt_large_tcp6, + ttest_ssocko_csockt_large_tcpL ]. %% Server: transport = socket(tcp), active = true @@ -17829,6 +17835,30 @@ ttest_ssocko_csockt_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = true +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssocko_csockt_small_tcpL(suite) -> + []; +ttest_ssocko_csockt_small_tcpL(doc) -> + []; +ttest_ssocko_csockt_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csocko_small_tcpL, + Runtime, + local, + sock, once, + sock, true, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17877,6 +17907,30 @@ ttest_ssocko_csockt_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = true +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssocko_csockt_medium_tcpL(suite) -> + []; +ttest_ssocko_csockt_medium_tcpL(doc) -> + []; +ttest_ssocko_csockt_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csockt_medium_tcpL, + Runtime, + local, + sock, once, + sock, true, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -17925,6 +17979,30 @@ ttest_ssocko_csockt_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = once +%% Client: Transport = socket(tcp), Active = true +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssocko_csockt_large_tcpL(suite) -> + []; +ttest_ssocko_csockt_large_tcpL(doc) -> + []; +ttest_ssocko_csockt_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssocko_csockt_large_tcpL, + Runtime, + local, + sock, once, + sock, true, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From 83e559258fb873b48f14e74ba7f6297390a63799 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:29:47 +0200 Subject: [esock|test] Add ttest case(s) (sst/csf/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = true Client: socket with active = false Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index be42df0467..fd7ca7d249 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -463,10 +463,13 @@ %% Client: transport = socket(tcp) ttest_ssockt_csockf_small_tcp4/1, ttest_ssockt_csockf_small_tcp6/1, + ttest_ssockt_csockf_small_tcpL/1, ttest_ssockt_csockf_medium_tcp4/1, ttest_ssockt_csockf_medium_tcp6/1, + ttest_ssockt_csockf_medium_tcpL/1, ttest_ssockt_csockf_large_tcp4/1, ttest_ssockt_csockf_large_tcp6/1, + ttest_ssockt_csockf_large_tcpL/1, ttest_ssockt_csocko_small_tcp4/1, ttest_ssockt_csocko_small_tcp6/1, @@ -1453,12 +1456,15 @@ ttest_ssockt_csockf_cases() -> [ ttest_ssockt_csockf_small_tcp4, ttest_ssockt_csockf_small_tcp6, + ttest_ssockt_csockf_small_tcpL, ttest_ssockt_csockf_medium_tcp4, ttest_ssockt_csockf_medium_tcp6, + ttest_ssockt_csockf_medium_tcpL, ttest_ssockt_csockf_large_tcp4, - ttest_ssockt_csockf_large_tcp6 + ttest_ssockt_csockf_large_tcp6, + ttest_ssockt_csockf_large_tcpL ]. %% Server: transport = socket(tcp), active = true @@ -18483,6 +18489,30 @@ ttest_ssockt_csockf_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = false +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockt_csockf_small_tcpL(suite) -> + []; +ttest_ssockt_csockf_small_tcpL(doc) -> + []; +ttest_ssockt_csockf_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csockf_small_tcpL, + Runtime, + local, + sock, true, + sock, false, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18531,6 +18561,30 @@ ttest_ssockt_csockf_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = false +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockt_csockf_medium_tcpL(suite) -> + []; +ttest_ssockt_csockf_medium_tcpL(doc) -> + []; +ttest_ssockt_csockf_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csockf_medium_tcpL, + Runtime, + local, + sock, true, + sock, false, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18579,6 +18633,30 @@ ttest_ssockt_csockf_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = false +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockt_csockf_large_tcpL(suite) -> + []; +ttest_ssockt_csockf_large_tcpL(doc) -> + []; +ttest_ssockt_csockf_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csockf_large_tcpL, + Runtime, + local, + sock, true, + sock, false, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From cc4688dd9fdb00df099fc47608c486f9e24e1461 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:36:32 +0200 Subject: [esock|test] Add ttest case(s) (sst/cso/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = true Client: socket with active = once Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index fd7ca7d249..5fded7893b 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -473,10 +473,13 @@ ttest_ssockt_csocko_small_tcp4/1, ttest_ssockt_csocko_small_tcp6/1, + ttest_ssockt_csocko_small_tcpL/1, ttest_ssockt_csocko_medium_tcp4/1, ttest_ssockt_csocko_medium_tcp6/1, + ttest_ssockt_csocko_medium_tcpL/1, ttest_ssockt_csocko_large_tcp4/1, ttest_ssockt_csocko_large_tcp6/1, + ttest_ssockt_csocko_large_tcpL/1, ttest_ssockt_csockt_small_tcp4/1, ttest_ssockt_csockt_small_tcp6/1, @@ -1473,12 +1476,15 @@ ttest_ssockt_csocko_cases() -> [ ttest_ssockt_csocko_small_tcp4, ttest_ssockt_csocko_small_tcp6, + ttest_ssockt_csocko_small_tcpL, ttest_ssockt_csocko_medium_tcp4, ttest_ssockt_csocko_medium_tcp6, + ttest_ssockt_csocko_medium_tcpL, ttest_ssockt_csocko_large_tcp4, - ttest_ssockt_csocko_large_tcp6 + ttest_ssockt_csocko_large_tcp6, + ttest_ssockt_csocko_large_tcpL ]. %% Server: transport = socket(tcp), active = true @@ -18705,6 +18711,30 @@ ttest_ssockt_csocko_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = once +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockt_csocko_small_tcpL(suite) -> + []; +ttest_ssockt_csocko_small_tcpL(doc) -> + []; +ttest_ssockt_csocko_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csocko_small_tcpL, + Runtime, + local, + sock, true, + sock, once, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18753,6 +18783,30 @@ ttest_ssockt_csocko_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = once +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockt_csocko_medium_tcpL(suite) -> + []; +ttest_ssockt_csocko_medium_tcpL(doc) -> + []; +ttest_ssockt_csocko_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csocko_medium_tcpL, + Runtime, + local, + sock, true, + sock, once, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18801,6 +18855,30 @@ ttest_ssockt_csocko_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = once +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockt_csocko_large_tcpL(suite) -> + []; +ttest_ssockt_csocko_large_tcpL(doc) -> + []; +ttest_ssockt_csocko_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csocko_large_tcpL, + Runtime, + local, + sock, true, + sock, once, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. -- cgit v1.2.3 From 1ce67e5a832aa90eced2de63c7f3efa155ee1718 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:42:57 +0200 Subject: [esock|test] Add ttest case(s) (sst/cst/s,m,l) work for local (stream) Add ttest test case(s) for Unix Domain (stream) socket: Server: socket with active = true Client: socket with active = true Message Size: small, medium and large OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 82 ++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 5fded7893b..337a34c0d2 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -483,10 +483,13 @@ ttest_ssockt_csockt_small_tcp4/1, ttest_ssockt_csockt_small_tcp6/1, + ttest_ssockt_csockt_small_tcpL/1, ttest_ssockt_csockt_medium_tcp4/1, ttest_ssockt_csockt_medium_tcp6/1, + ttest_ssockt_csockt_medium_tcpL/1, ttest_ssockt_csockt_large_tcp4/1, - ttest_ssockt_csockt_large_tcp6/1 + ttest_ssockt_csockt_large_tcp6/1, + ttest_ssockt_csockt_large_tcpL/1 %% Tickets ]). @@ -1493,12 +1496,15 @@ ttest_ssockt_csockt_cases() -> [ ttest_ssockt_csockt_small_tcp4, ttest_ssockt_csockt_small_tcp6, + ttest_ssockt_csockt_small_tcpL, ttest_ssockt_csockt_medium_tcp4, ttest_ssockt_csockt_medium_tcp6, + ttest_ssockt_csockt_medium_tcpL, ttest_ssockt_csockt_large_tcp4, - ttest_ssockt_csockt_large_tcp6 + ttest_ssockt_csockt_large_tcp6, + ttest_ssockt_csockt_large_tcpL ]. %% ticket_cases() -> @@ -18927,6 +18933,30 @@ ttest_ssockt_csockt_small_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = true +%% Message Size: small (=1) +%% Domain: local +%% + +ttest_ssockt_csockt_small_tcpL(suite) -> + []; +ttest_ssockt_csockt_small_tcpL(doc) -> + []; +ttest_ssockt_csockt_small_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csocko_small_tcpL, + Runtime, + local, + sock, true, + sock, true, + 1, 200). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -18975,6 +19005,30 @@ ttest_ssockt_csockt_medium_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = true +%% Message Size: medium (=2) +%% Domain: local +%% + +ttest_ssockt_csockt_medium_tcpL(suite) -> + []; +ttest_ssockt_csockt_medium_tcpL(doc) -> + []; +ttest_ssockt_csockt_medium_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csockt_medium_tcpL, + Runtime, + local, + sock, true, + sock, true, + 2, 20). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case uses the time test (ttest) utility to implement a %% ping-pong like test case. @@ -19023,6 +19077,30 @@ ttest_ssockt_csockt_large_tcp6(Config) when is_list(Config) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case uses the time test (ttest) utility to implement a +%% ping-pong like test case. +%% Server: Transport = socket(tcp), Active = true +%% Client: Transport = socket(tcp), Active = true +%% Message Size: large (=3) +%% Domain: local +%% + +ttest_ssockt_csockt_large_tcpL(suite) -> + []; +ttest_ssockt_csockt_large_tcpL(doc) -> + []; +ttest_ssockt_csockt_large_tcpL(Config) when is_list(Config) -> + Runtime = which_ttest_runtime(Config), + ttest_tcp(ttest_ssockt_csockt_large_tcpL, + Runtime, + local, + sock, true, + sock, true, + 3, 2). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% which_ttest_runtime(Config) when is_list(Config) -> -- cgit v1.2.3 From 8ade89da0715e3b99e300429d10dca43aeac1f9d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 16:59:05 +0200 Subject: [esock] Update the supports functions to also display local The socket:supports/0,1 now also displays local (Unix Domain Socket). OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 36 +++++++++++++++++++++++++++------ erts/preloaded/ebin/socket.beam | Bin 70628 -> 70764 bytes erts/preloaded/src/socket.erl | 10 +++++++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index a62914d730..c1c72e525f 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -659,6 +659,7 @@ typedef union { #define SOCKET_SUPPORTS_OPTIONS 0x0001 #define SOCKET_SUPPORTS_SCTP 0x0002 #define SOCKET_SUPPORTS_IPV6 0x0003 +#define SOCKET_SUPPORTS_LOCAL 0x0004 #define ESOCK_WHICH_PROTO_ERROR -1 #define ESOCK_WHICH_PROTO_UNSUP -2 @@ -998,6 +999,7 @@ static ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env); static ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env); static ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env); static ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env); +static ERL_NIF_TERM nsupports_local(ErlNifEnv* env); static ERL_NIF_TERM nopen(ErlNifEnv* env, int domain, @@ -3053,6 +3055,9 @@ ERL_NIF_TERM nif_info(ErlNifEnv* env, * {tcp, [{Opt, boolean()}]}, * {udp, [{Opt, boolean()}]}, * {sctp, [{Opt, boolean()}]}] + * sctp boolean() + * ipv6 boolean() + * local boolean() */ static @@ -3080,13 +3085,10 @@ ERL_NIF_TERM nif_supports(ErlNifEnv* env, -/* nopen - create an endpoint for communication - * - * Assumes the input has been validated. +/* nsupports - what features do we support * - * Normally we want debugging on (individual) sockets to be controlled - * by the sockets own debug flag. But since we don't even have a socket - * yet, we must use the global debug flag. + * This is to prove information about what features actually + * work on the current platform. */ #if !defined(__WIN32__) static @@ -3109,6 +3111,10 @@ ERL_NIF_TERM nsupports(ErlNifEnv* env, int key) result = nsupports_ipv6(env); break; + case SOCKET_SUPPORTS_LOCAL: + result = nsupports_local(env); + break; + default: result = esock_atom_false; break; @@ -4331,6 +4337,24 @@ ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env) +#if !defined(__WIN32__) +static +ERL_NIF_TERM nsupports_local(ErlNifEnv* env) +{ + ERL_NIF_TERM supports; + +#if defined(AF_LOCAL) + supports = esock_atom_true; +#else + supports = esock_atom_false; +#endif + + return supports; +} +#endif + + + /* ---------------------------------------------------------------------- * nif_open * diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index 198dd08036..266adbd6f1 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 9fc73a11de..03107d22b1 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -821,6 +821,7 @@ -define(SOCKET_SUPPORTS_OPTIONS, 16#0001). -define(SOCKET_SUPPORTS_SCTP, 16#0002). -define(SOCKET_SUPPORTS_IPV6, 16#0003). +-define(SOCKET_SUPPORTS_LOCAL, 16#0004). %% =========================================================================== @@ -876,18 +877,21 @@ info() -> -spec supports() -> [{options, supports_options()} | {sctp, boolean()} | - {ipv6, boolean()}]. + {ipv6, boolean()} | + {local, boolean()}]. supports() -> [{options, supports(options)}, {sctp, supports(sctp)}, - {ipv6, supports(ipv6)}]. + {ipv6, supports(ipv6)}, + {local, supports(local)}]. -dialyzer({nowarn_function, supports/1}). -spec supports(options) -> supports_options(); (sctp) -> boolean(); (ipv6) -> boolean(); + (local) -> boolean(); (Key1) -> false when Key1 :: term(). @@ -897,6 +901,8 @@ supports(sctp) -> nif_supports(?SOCKET_SUPPORTS_SCTP); supports(ipv6) -> nif_supports(?SOCKET_SUPPORTS_IPV6); +supports(local) -> + nif_supports(?SOCKET_SUPPORTS_LOCAL); supports(_Key1) -> false. -- cgit v1.2.3 From 3ec5549972b672b0d177fb1eeb89addf184c13ef Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 15 May 2019 17:49:05 +0200 Subject: [esock] Fixed 'typing' of type timeval on darwin --- erts/emulator/nifs/common/socket_util.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c index 4ba48afcfa..2740cb51ef 100644 --- a/erts/emulator/nifs/common/socket_util.c +++ b/erts/emulator/nifs/common/socket_util.c @@ -986,9 +986,27 @@ char* esock_decode_timeval(ErlNifEnv* env, if (!GET_LONG(env, eSec, &timeP->tv_sec)) return ESOCK_STR_EINVAL; +#if (SIZEOF_INT == 4) + { + int usec; + if (!GET_INT(env, eUSec, &usec)) + return ESOCK_STR_EINVAL; + timeP->tv_usec = (typeof(timeP->tv_usec)) usec; + } +#elif (SIZEOF_LONG == 4) + { + long usec; + if (!GET_LONG(env, eUSec, &usec)) + return ESOCK_STR_EINVAL; + timeP->tv_usec = (typeof(timeP->tv_usec)) usec; + } +#else + /* Ok, we give up... */ if (!GET_LONG(env, eUSec, &timeP->tv_usec)) return ESOCK_STR_EINVAL; +#endif + return NULL; } -- cgit v1.2.3 From 5345f3d6fcb78acbe65803109f035cc979ad2199 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 17 May 2019 12:04:48 +0200 Subject: [esock] Fixed check domain local and specs Fixed the spec's for function open/3,4. Also, corrected the test for retreiving resulting protocol when performing open with proto = 0 (default) and domain is not local. Local may not be defined on all platforms. OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 8 ++++++-- erts/preloaded/ebin/socket.beam | Bin 70764 -> 70456 bytes erts/preloaded/src/socket.erl | 13 ------------- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index c1c72e525f..340111f76c 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -4490,7 +4490,11 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, * local (AF_LOCAL) we need to explicitly get the protocol here! */ - if ((proto != 0) && (domain != AF_LOCAL)) + if ((proto == 0) +#if defined(AF_LOCAL) + && (domain != AF_LOCAL) +#endif + ) if (!nopen_which_protocol(sock, &proto)) { if (proto == ESOCK_WHICH_PROTO_ERROR) { save_errno = sock_errno(); @@ -4501,7 +4505,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, while ((sock_close(sock) == INVALID_SOCKET) && (sock_errno() == EINTR)); return esock_make_error(env, esock_atom_eafnosupport); - } + } } diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index 266adbd6f1..e37aa81b7c 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 03107d22b1..0f0d8f7a02 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -1016,12 +1016,6 @@ open(Domain, Type) -> open(Domain, Type, default). -spec open(Domain, Type, Protocol) -> {ok, Socket} | {error, Reason} when - Domain :: local, - Type :: stream | dgram, - Protocol :: default, - Socket :: socket(), - Reason :: term(); - (Domain, Type, Protocol) -> {ok, Socket} | {error, Reason} when Domain :: domain(), Type :: type(), Protocol :: default | protocol(), @@ -1032,13 +1026,6 @@ open(Domain, Type, Protocol) -> open(Domain, Type, Protocol, #{}). -spec open(Domain, Type, Protocol, Extra) -> {ok, Socket} | {error, Reason} when - Domain :: local, - Type :: stream | dgram, - Protocol :: default, - Extra :: map(), - Socket :: socket(), - Reason :: term(); - (Domain, Type, Protocol, Extra) -> {ok, Socket} | {error, Reason} when Domain :: domain(), Type :: type(), Protocol :: default | protocol(), -- cgit v1.2.3 From 3e2c3eec258b1ea13affe91db0451f3737983306 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 17 May 2019 12:12:02 +0200 Subject: [esock|doc] Updated accoring to handling of Unix Domain socket Updated documentation with regard to Unix Domain sockets. OTP-15822 --- erts/doc/src/socket.xml | 21 +++++++++++++-------- erts/doc/src/socket_usage.xml | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index 343b61d4aa..9b34bf1df1 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -373,19 +373,24 @@ Create an endpoint for communication. -

Creates an endpoint (socket) for communication.

-

For some types there is a default protocol, which will - be used if no protocol is specified:

+

Creates an endpoint (socket) for communication.

- -

stream: tcp

-

dgram: udp

-

seqpacket: sctp

-
+

For some types there is a default protocol, + indicated by default, which it may be + possible to specify. + And for Domain = local, if a protocol is pecified, + it must be default.

The Extra argument is intended for "obscure" options. Currently the only supported option is netns, which is only supported on the linux platform.

+ + +

It may not be possible to specify the default protocol (except + when Domain = local). We need to be able to retreive + the resulting protocol, which is not possble on all + platforms.

+
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml index e0f006e618..4b3872d7e3 100644 --- a/erts/doc/src/socket_usage.xml +++ b/erts/doc/src/socket_usage.xml @@ -205,7 +205,7 @@ protocol() no yes - none + Not on (some) Darwin (for instance) rcvbuf -- cgit v1.2.3 From 12e99364db99e336d5382510241f47e40e0db9af Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 17 May 2019 16:43:30 +0200 Subject: [esock|test] On some platforms recvmsg does *not* return address On some platforms, e.g. FreeBSD, recvmsg does *not* return address for a Unix Domain (stream) socket. Unlike, for instance, on Linux. OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 4 ++-- erts/emulator/test/socket_SUITE.erl | 36 +++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 340111f76c..2562399fd0 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -15224,8 +15224,8 @@ char* encode_msghdr(ErlNifEnv* env, "\r\n read: %d" "\r\n", read) ); - /* The address is not used if we are connected (unless family is 'local'), - * so check (length = 0) before we try to encodel + /* The address is not used if we are connected (unless, maybe, + * family is 'local'), so check (length = 0) before we try to encodel */ if (msgHdrP->msg_namelen != 0) { if ((xres = esock_encode_sockaddr(env, diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 337a34c0d2..b420acd57c 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -2156,10 +2156,25 @@ api_b_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) -> end, Recv = fun(Sock) -> case socket:recvmsg(Sock) of + %% On some platforms, the address + %% is *not* provided (e.g. FreeBSD) + {ok, #{addr := undefined, + iov := [Data]}} -> + {ok, Data}; + %% On some platforms, the address + %% *is* provided (e.g. linux) {ok, #{addr := #{family := local}, iov := [Data]}} -> + socket:setopt(Sock, + otp, + debug, + false), {ok, Data}; {error, _} = ERROR -> + socket:setopt(Sock, + otp, + debug, + false), ERROR end end, @@ -9539,6 +9554,13 @@ sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) -> MsgData = ?DATA, Recv = fun(Sock) -> case socket:recvmsg(Sock) of + %% On some platforms, the address + %% is *not* provided (e.g. FreeBSD) + {ok, #{addr := undefined, + iov := [Data]}} -> + {ok, Data}; + %% On some platforms, the address + %% *is* provided (e.g. linux) {ok, #{addr := #{family := local}, iov := [Data]}} -> {ok, Data}; @@ -11472,6 +11494,13 @@ traffic_ping_pong_send_and_recv_tcp(InitState) -> traffic_ping_pong_sendmsg_and_recvmsg_tcp(#{domain := local} = InitState) -> Recv = fun(Sock, Sz) -> case socket:recvmsg(Sock, Sz, 0) of + %% On some platforms, the address + %% is *not* provided (e.g. FreeBSD) + {ok, #{addr := undefined, + iov := [Data]}} -> + {ok, Data}; + %% On some platforms, the address + %% *is* provided (e.g. linux) {ok, #{addr := #{family := local}, iov := [Data]}} -> {ok, Data}; @@ -19932,7 +19961,12 @@ has_support_unix_domain_socket() -> {win32, _} -> {skip, "Not supported"}; _ -> - ok + case socket:supports(local) of + true -> + ok; + false -> + {skip, "Not supported"} + end end. -- cgit v1.2.3 From b10770cbac5bd761270d6b1ec8ace99bd17ed707 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 17 May 2019 17:26:30 +0200 Subject: [esock|test] Skip Unix Domain stream test case on Open Indiana On OpenIndiana Hipster on a Unix Domain stream socket it may be possible to set a *large* recv buffer size, that will actually not work. So, to avoid issues, simply skip the traffic_ping_pong_large_send_and_recv_tcpL on that platform. OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index b420acd57c..9f0afcfca6 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -10879,7 +10879,10 @@ traffic_ping_pong_large_send_and_recv_tcpL(_Config) when is_list(_Config) -> Msg = l2b(?TPP_LARGE), Num = ?TPP_LARGE_NUM, tc_try(traffic_ping_pong_large_send_and_recv_tcpL, - fun() -> has_support_unix_domain_socket() end, + fun() -> + has_support_unix_domain_socket(), + traffic_ping_pong_large_host_cond() + end, fun() -> InitState = #{domain => local, proto => default, @@ -10888,6 +10891,15 @@ traffic_ping_pong_large_send_and_recv_tcpL(_Config) when is_list(_Config) -> ok = traffic_ping_pong_send_and_recv_tcp(InitState) end). +%% This test case is a bit extreme and fails on some hosts +%% (e.g. OpenIndiana Hipster), so exclude them. +traffic_ping_pong_large_host_cond() -> + traffic_ping_pong_large_host_cond(os:type(), os:version()). + +traffic_ping_pong_large_host_cond({unix, sunos}, _) -> + skip("TC does not work on platform"); +traffic_ping_pong_large_host_cond(_, _) -> + ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From fa4c61fe7eb34e6fdb2b1c77e6252a76577cb465 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 17 May 2019 17:36:26 +0200 Subject: [esock|test] Fixed host cond test Incorrect host condition test for linux (the api timeout connect test cases). OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 9f0afcfca6..bc359ddf70 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -3855,7 +3855,9 @@ api_to_connect_cond() -> %% So, just to simplify, we require atleast 4.15 api_to_connect_cond({unix, linux}, {Maj, Min, _Rev}) -> if - ((Maj >= 4) andalso (Min >= 15)) -> + (Maj > 4) -> + ok; + ((Maj =:= 4) andalso (Min >= 15)) -> ok; true -> skip("TC does not work") -- cgit v1.2.3 From da690a3c9857413943ab8534e27ab9a2ff54a4cb Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 20 May 2019 12:11:24 +0200 Subject: [esock|test] Try even harder to make unique path Some (Unix Domain socket) test cases fails because the path (supposedly) already existed on a (admittedly old) gento VM. So, we try enen harder to ensure that the path is unique... OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 51 ++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index bc359ddf70..0970739a19 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -1951,8 +1951,14 @@ api_b_send_and_recv_udp(InitState) -> end}, #{desc => "bind src", cmd => fun(#{sock_src := Sock, lsa_src := LSA}) -> - sock_bind(Sock, LSA), - ok + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ?SEV_IPRINT("src bound"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("src bind failed: ~p", [Reason]), + ERROR + end end}, #{desc => "sockname src socket", cmd => fun(#{sock_src := Sock} = State) -> @@ -1970,8 +1976,14 @@ api_b_send_and_recv_udp(InitState) -> end}, #{desc => "bind dst", cmd => fun(#{sock_dst := Sock, lsa_dst := LSA}) -> - sock_bind(Sock, LSA), - ok + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ?SEV_IPRINT("src bound"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("src bind failed: ~p", [Reason]), + ERROR + end end}, #{desc => "sockname dst socket", cmd => fun(#{sock_dst := Sock} = State) -> @@ -6593,8 +6605,14 @@ sc_lc_receive_response_udp(InitState) -> end}, #{desc => "bind socket", cmd => fun(#{sock := Sock, local_sa := LSA}) -> - sock_bind(Sock, LSA), - ok + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ?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}) -> @@ -19899,8 +19917,27 @@ local_host() -> %% don't clash. mk_unique_path() -> [NodeName | _] = string:tokens(atom_to_list(node()), [$@]), - ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]). + Path = ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]), + ensure_unique_path(Path). + +ensure_unique_path(Path) -> + case file:read_file_info(Path) of + {ok, _} -> % Ouch, append a unique ID and try again + ensure_unique_path(Path, 1); + {error, _} -> % We assume this means it does not exist yet... + Path + end. +ensure_unique_path(Path, ID) -> + NewPath = ?LIB:f("~s_~w", [Path, ID]), + case file:read_file_info(NewPath) of + {ok, _} -> % Ouch, this also existed, increment and try again + ensure_unique_path(Path, ID + 1); + {error, _} -> % We assume this means it does not exist yet... + NewPath + end. + + which_local_socket_addr(local = Domain) -> #{family => Domain, path => mk_unique_path()}; -- cgit v1.2.3 From 2eb1dd7b5ee49401aae3c8db185cd3bf659ea0ab Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 20 May 2019 14:38:56 +0200 Subject: [esock] Make sure AF_LOCAL exist before using Add if-def for AF_LOCAL before using the flag. OTP-15822 --- erts/emulator/nifs/common/socket_nif.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 2562399fd0..25bc712949 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -10977,11 +10977,15 @@ ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env, switch (val) { case IPPROTO_IP: +#if defined(AF_LOCAL) if (descP->domain == AF_LOCAL) { result = esock_make_ok2(env, esock_atom_default); } else { result = esock_make_ok2(env, esock_atom_ip); } +#else + result = esock_make_ok2(env, esock_atom_ip); +#endif break; case IPPROTO_TCP: @@ -11553,10 +11557,14 @@ ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env, } else { switch (val) { case IPPROTO_IP: +#if defined(AF_LOCAL) if (descP->domain == AF_LOCAL) result = esock_make_ok2(env, esock_atom_default); else result = esock_make_ok2(env, esock_atom_ip); +#else + result = esock_make_ok2(env, esock_atom_ip); +#endif break; case IPPROTO_TCP: -- cgit v1.2.3 From 9ccec09217aa3d721501a0634b205d9d87cab914 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 21 May 2019 15:18:31 +0200 Subject: [esock|test] Skip some test cases on old linux(s) OTP-15822 --- erts/emulator/test/socket_SUITE.erl | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 0970739a19..85f2e47812 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -1821,7 +1821,10 @@ api_b_sendto_and_recvfrom_udpL(doc) -> api_b_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_sendto_and_recvfrom_udpL, - fun() -> has_support_unix_domain_socket() end, + fun() -> + has_support_unix_domain_socket(), + unix_domain_socket_host_cond() + end, fun() -> Send = fun(Sock, Data, Dest) -> socket:sendto(Sock, Data, Dest) @@ -1892,7 +1895,10 @@ api_b_sendmsg_and_recvmsg_udpL(doc) -> api_b_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) -> ?TT(?SECS(5)), tc_try(api_b_sendmsg_and_recvmsg_udpL, - fun() -> has_support_unix_domain_socket() end, + fun() -> + has_support_unix_domain_socket(), + unix_domain_socket_host_cond() + end, fun() -> Send = fun(Sock, Data, Dest) -> %% We need tests for this, @@ -19813,21 +19819,6 @@ sock_open(Domain, Type, Proto) -> end. -sock_bind(Sock, SockAddr) -> - try socket:bind(Sock, SockAddr) of - {ok, Port} -> - Port; - {error, Reason} -> - i("sock_bind -> error: " - "~n SockAddr: ~p" - "~n Reason: ~p", [SockAddr, Reason]), - ?FAIL({bind, Reason}) - catch - C:E:S -> - i("sock_bind -> failed: ~p, ~p, ~p", [C, E, S]), - ?FAIL({bind, C, E, S}) - end. - sock_connect(Sock, SockAddr) -> try socket:connect(Sock, SockAddr) of ok -> @@ -20007,16 +19998,24 @@ unlink_path(_, _, _) -> %% Here are all the *general* test vase condition functions. +unix_domain_socket_host_cond() -> + unix_domain_socket_host_cond(os:type(), os:version()). + +unix_domain_socket_host_cond({unix, linux}, {M, _, _}) when (M < 3) -> + skip("TC may not work on this version"); +unix_domain_socket_host_cond(_, _) -> + ok. + has_support_unix_domain_socket() -> case os:type() of {win32, _} -> - {skip, "Not supported"}; + skip("Not supported"); _ -> case socket:supports(local) of true -> ok; false -> - {skip, "Not supported"} + skip("Not supported") end end. -- cgit v1.2.3 From 56cad32ecdfa36ea7a4cddac1579eb1e414ec0fe Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2019 14:19:30 +0200 Subject: [esock|ttest] Updated the ttest command line tool Updated the ttest command line tool to the new API. OTP-15822 --- erts/emulator/test/esock_ttest/esock-ttest | 10 ++-- .../test/socket_test_ttest_tcp_client_gen.erl | 18 +++---- .../test/socket_test_ttest_tcp_client_socket.erl | 60 +++++++++++++++++----- erts/emulator/test/socket_test_ttest_tcp_gen.erl | 10 ++-- .../emulator/test/socket_test_ttest_tcp_server.erl | 36 ++++++------- .../test/socket_test_ttest_tcp_server_gen.erl | 16 +++--- .../test/socket_test_ttest_tcp_server_socket.erl | 19 +++---- 7 files changed, 99 insertions(+), 70 deletions(-) diff --git a/erts/emulator/test/esock_ttest/esock-ttest b/erts/emulator/test/esock_ttest/esock-ttest index f0d363ab30..c48201da7c 100755 --- a/erts/emulator/test/esock_ttest/esock-ttest +++ b/erts/emulator/test/esock_ttest/esock-ttest @@ -266,7 +266,7 @@ exec(#{role := server, exec(#{role := server, active := Active, transport := {sock, Method}}) -> - case socket_test_ttest_tcp_server_socket:start(Method, Active) of + case socket_test_ttest_tcp_server_socket:start(Method, inet, Active) of {ok, {Pid, _}} -> MRef = erlang:monitor(process, Pid), receive @@ -283,15 +283,15 @@ exec(#{role := client, server := undefined}) -> usage("Mandatory option 'server' not provided"); exec(#{role := client, - server := {Addr, Port}, + server := {_Addr, _Port} = ServerInfo, active := Active, transport := gen, msg_id := MsgID, max_outstanding := MaxOutstanding, runtime := RunTime}) -> case socket_test_ttest_tcp_client_gen:start(true, + ServerInfo, Active, - Addr, Port, MsgID, MaxOutstanding, RunTime) of {ok, Pid} -> @@ -306,7 +306,7 @@ exec(#{role := client, error end; exec(#{role := client, - server := {Addr, Port}, + server := {_Addr, _Port} = ServerInfo, active := Active, transport := {sock, Method}, msg_id := MsgID, @@ -314,8 +314,8 @@ exec(#{role := client, runtime := RunTime}) -> case socket_test_ttest_tcp_client_socket:start(true, Method, + ServerInfo, Active, - Addr, Port, MsgID, MaxOutstanding, RunTime) of {ok, Pid} -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl index 0ec2e908d7..65a3a94d38 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl @@ -21,28 +21,28 @@ -module(socket_test_ttest_tcp_client_gen). -export([ - start/3, start/4, start/6, start/7, + start/2, start/3, start/5, start/6, stop/1 ]). -define(TRANSPORT_MOD, socket_test_ttest_tcp_gen). -start(Active, Addr, Port) -> - socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, Active, Addr, Port). +start(ServerInfo, Active) -> + socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, ServerInfo, Active). -start(Active, Addr, Port, MsgID) -> - socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, Active, Addr, Port, MsgID). +start(ServerInfo, Active, MsgID) -> + socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, ServerInfo, Active, MsgID). -start(Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> socket_test_ttest_tcp_client:start(false, ?TRANSPORT_MOD, - Active, Addr, Port, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). -start(Quiet, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(Quiet, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> socket_test_ttest_tcp_client:start(Quiet, ?TRANSPORT_MOD, - Active, Addr, Port, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). stop(Pid) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl index acf2556793..5b2a494ba0 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl @@ -21,30 +21,64 @@ -module(socket_test_ttest_tcp_client_socket). -export([ - start/4, start/5, start/7, start/8, + start/3, start/4, start/6, start/7, stop/1 ]). -define(TRANSPORT_MOD, socket_test_ttest_tcp_socket). --define(MOD(M), {?TRANSPORT_MOD, #{method => Method}}). +-define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D, method => M}}). -start(Method, Active, Addr, Port) -> - socket_test_ttest_tcp_client:start_monitor(?MOD(Method), Active, Addr, Port). +start(Method, ServerInfo = {Addr, _}, Active) + when is_tuple(Addr) andalso (size(Addr) =:= 4) -> + Domain = inet, + socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Method), + ServerInfo, Active); +start(Method, ServerInfo = {Addr, _}, Active) + when is_tuple(Addr) andalso (size(Addr) =:= 8) -> + Domain = inet6, + socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Method), + ServerInfo, Active). -start(Method, Active, Addr, Port, MsgID) -> - socket_test_ttest_tcp_client:start(?MOD(Method), - Active, Addr, Port, MsgID). +start(Method, ServerInfo = {Addr, _}, Active, MsgID) + when is_tuple(Addr) andalso (size(Addr) =:= 4) -> + %% This is just a simplification + Domain = inet, + socket_test_ttest_tcp_client:start(?MOD(Domain, Method), + ServerInfo, Active, MsgID); +start(Method, ServerInfo = {Addr, _}, Active, MsgID) + when is_tuple(Addr) andalso (size(Addr) =:= 8) -> + Domain = inet6, + socket_test_ttest_tcp_client:start(?MOD(Domain, Method), + ServerInfo, Active, MsgID). -start(Method, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime) + when is_tuple(Addr) andalso (size(Addr) =:= 4) -> + Domain = inet, socket_test_ttest_tcp_client:start(false, - ?MOD(Method), - Active, Addr, Port, + ?MOD(Domain, Method), + ServerInfo, Active, + MsgID, MaxOutstanding, RunTime); +start(Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime) + when is_tuple(Addr) andalso (size(Addr) =:= 8) -> + Domain = inet6, + socket_test_ttest_tcp_client:start(false, + ?MOD(Domain, Method), + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). -start(Quiet, Method, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) -> +start(Quiet, Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime) + when is_tuple(Addr) andalso (size(Addr) =:= 4) -> + Domain = inet, + socket_test_ttest_tcp_client:start(Quiet, + ?MOD(Domain, Method), + ServerInfo, Active, + MsgID, MaxOutstanding, RunTime); +start(Quiet, Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime) + when is_tuple(Addr) andalso (size(Addr) =:= 8) -> + Domain = inet6, socket_test_ttest_tcp_client:start(Quiet, - ?MOD(Method), - Active, Addr, Port, + ?MOD(Domain, Method), + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). stop(Pid) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_gen.erl index 16e7ccf66b..05b250e3d9 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_gen.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_gen.erl @@ -26,7 +26,7 @@ close/1, connect/2, connect/3, controlling_process/2, - listen/0, listen/1, + listen/0, listen/1, listen/2, peername/1, port/1, recv/2, recv/3, @@ -102,8 +102,12 @@ controlling_process(Sock, NewPid) -> listen() -> listen(0). -listen(Port) when is_integer(Port) andalso (Port >= 0) -> - Opts = [binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false}, +listen(Port) -> + listen(Port, #{domain => inet}). + +listen(Port, #{domain := Domain}) when is_integer(Port) andalso (Port >= 0) -> + Opts = [Domain, + binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false}, {buffer, 32*1024}], case gen_tcp:listen(Port, Opts) of {ok, Sock} -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl index acb940e9cd..cceaf0d0fc 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl @@ -296,28 +296,26 @@ server_handle_handler_down(Pid, AccMCnt2 = AccMCnt + MCnt, AccBCnt2 = AccBCnt + BCnt, AccHCnt2 = AccHCnt + 1, - ?I("handler ~p (~w) done => accumulated results: " - "~n Run Time: ~s ms" + MsgCount2Str = + fun(RT, ART, MC, AMC) when (RT > 0) -> + ?F("~w => ~w (~w) msgs / ms", [MC, MC div RT, AMC div ART]); + (_, _, MC, AMC) -> + ?F("~w (~w)", [MC, AMC]) + end, + ByteCount2Str = + fun(RT, ART, BC, ABC) when (RT > 0) -> + ?F("~w => ~w (~w) bytes / ms", [BC, BC div RT, ABC div ART]); + (_, _, BC, ABC) -> + ?F("~w", [BC, ABC]) + end, + ?I("handler ~p (~w) done: " + "~n Run Time: ~s" "~n Message Count: ~s" "~n Byte Count: ~s", [Pid, AccHCnt2, - ?FORMAT_TIME(AccRunTime2), - if (AccRunTime2 > 0) -> - ?F("~w => ~w (~w) msgs / ms", - [AccMCnt2, - AccMCnt2 div AccRunTime2, - (AccMCnt2 div AccHCnt2) div AccRunTime2]); - true -> - ?F("~w", [AccMCnt2]) - end, - if (AccRunTime2 > 0) -> - ?F("~w => ~w (~w) bytes / ms", - [AccBCnt2, - AccBCnt2 div AccRunTime2, - (AccBCnt2 div AccHCnt2) div AccRunTime2]); - true -> - ?F("~w", [AccBCnt2]) - end]), + ?FORMAT_TIME(RunTime), + MsgCount2Str(RunTime, AccRunTime2, MCnt, AccMCnt2), + ByteCount2Str(RunTime, AccRunTime2, BCnt, AccBCnt2)]), State#{runtime => AccRunTime2, mcnt => AccMCnt2, bcnt => AccBCnt2, diff --git a/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl index b1b31f5158..fdf40f1369 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% Copyright Ericsson AB 2018-2019. 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. @@ -21,20 +21,18 @@ -module(socket_test_ttest_tcp_server_gen). -export([ - start/1, + start/1, start/2, stop/1 ]). -define(TRANSPORT_MOD, socket_test_ttest_tcp_gen). +-define(MOD(D), {?TRANSPORT_MOD, #{domain => D}}). start(Active) -> - socket_test_ttest_tcp_server:start(?TRANSPORT_MOD, Active). - %% {ok, {Pid, AddrPort}} -> - %% MRef = erlang:monitor(process, Pid), - %% {ok, {Pid, MRef, AddrPort}}; - %% {error, _} = ERROR -> - %% ERROR - %% end. + start(inet, Active). + +start(Domain, Active) -> + socket_test_ttest_tcp_server:start(?MOD(Domain), Active). stop(Pid) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl index b7ea1e8e93..d1de230637 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2018-2018. All Rights Reserved. +%% Copyright Ericsson AB 2018-2019. 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. @@ -21,23 +21,18 @@ -module(socket_test_ttest_tcp_server_socket). -export([ - start/2, + start/3, stop/1 ]). -define(TRANSPORT_MOD, socket_test_ttest_tcp_socket). -%% -define(MOD(M), {?TRANSPORT_MOD, #{method => M, +%% -define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D, +%% method => M, %% stats_interval => 10000}}). --define(MOD(M), {?TRANSPORT_MOD, #{method => M}}). +-define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D, method => M}}). -start(Method, Active) -> - socket_test_ttest_tcp_server:start(?MOD(Method), Active). - %% {ok, {Pid, AddrPort}} -> - %% MRef = erlang:monitor(process, Pid), - %% {ok, {Pid, MRef, AddrPort}}; - %% {error, _} = ERROR -> - %% ERROR - %% end. +start(Method, Domain, Active) -> + socket_test_ttest_tcp_server:start(?MOD(Domain, Method), Active). stop(Pid) -> socket_test_ttest_tcp_server:stop(Pid). -- cgit v1.2.3 From 0eb29c0eebd4e58f294005dbe355e270208756d9 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 23 May 2019 15:14:29 +0200 Subject: [esock|ttest] Make it possible use local for ttest Make Unix Domain (stream) socket work with the ttest command line tool (for esock server and client). OTP-15822 --- erts/emulator/test/esock_ttest/esock-ttest | 100 ++++++++++++--------- erts/emulator/test/esock_ttest/esock-ttest-client | 63 +++++++------ .../test/socket_test_ttest_tcp_client_socket.erl | 25 ++++++ .../emulator/test/socket_test_ttest_tcp_server.erl | 15 ++-- .../emulator/test/socket_test_ttest_tcp_socket.erl | 28 +++--- 5 files changed, 141 insertions(+), 90 deletions(-) diff --git a/erts/emulator/test/esock_ttest/esock-ttest b/erts/emulator/test/esock_ttest/esock-ttest index c48201da7c..cf1d9cd9ab 100755 --- a/erts/emulator/test/esock_ttest/esock-ttest +++ b/erts/emulator/test/esock_ttest/esock-ttest @@ -50,43 +50,47 @@ usage() -> "~n units (server or client)." "~n" "~n options: " - "~n --help Display this info and exit. " - "~n --server [server-options] Start a server. " - "~n There are no mandatory server options." - "~n --client client-options Start a client" - "~n Some client options are mandatory and" - "~n others optional." - "~n --active boolean() | once." - "~n Valid for both client and server." - "~n Defaults to: false" - "~n --transport Which transport to use: gen|sock[:plain|msg]" - "~n gen: gen_tcp" - "~n sock: socket" - "~n plain: recv/send (default)" - "~n msg: recvmsg/sendmsg" - "~n Defaults to: sock:plain" - "~n --scon : Address and port of the server." - "~n The address part is in the standard form:" - "~n \"a.b.c.d\"." - "~n Only valid for client." - "~n Mandatory." - "~n --msg-id <1|2|3> Choose which message to use during the test." - "~n Basically: " - "~n 1: small" - "~n 2: medium" - "~n 3: large" - "~n Defaults to: 1" - "~n --max-outstanding How many messages to send before waiting for" - "~n a reply." - "~n Valid only for client." - "~n Defaults to: " - "~n MsgID 1: 100" - "~n MsgID 2: 10" - "~n MsgID 3: 1" - "~n --runtime