aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-05-15 14:21:21 +0200
committerMicael Karlberg <[email protected]>2019-05-29 13:47:40 +0200
commitd1f053ada333595d07ee3d837bf0071e651c7dc9 (patch)
tree93f30a4f490f8827bb484c6cfa2fda6efbe2fb1a /erts/emulator/test
parent6e08c4d74ba926827f644c2214675dc96d44423a (diff)
downloadotp-d1f053ada333595d07ee3d837bf0071e651c7dc9.tar.gz
otp-d1f053ada333595d07ee3d837bf0071e651c7dc9.tar.bz2
otp-d1f053ada333595d07ee3d837bf0071e651c7dc9.zip
[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
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/socket_SUITE.erl139
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client.erl96
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_gen.erl11
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_server.erl36
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_socket.erl104
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,
@@ -16292,6 +16294,30 @@ ttest_ssockf_csockf_small_tcp6(Config) when is_list(Config) ->
%% 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.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -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 ->