aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/socket_SUITE.erl198
-rw-r--r--erts/emulator/test/socket_test_evaluator.erl10
-rw-r--r--erts/emulator/test/socket_test_lib.erl10
-rw-r--r--erts/emulator/test/socket_test_logger.erl99
5 files changed, 208 insertions, 110 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 09bfe6f104..300270a10e 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -33,6 +33,7 @@ SOCKET_MODULES = \
socket_server \
socket_client \
socket_test_lib \
+ socket_test_logger \
socket_test_evaluator \
socket_test_ttest_lib \
socket_test_ttest_tcp_gen \
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index 779cc80ad6..57f562f24d 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -149,6 +149,7 @@
-define(TT(T), ct:timetrap(T)).
-define(LIB, socket_test_lib).
+-define(LOGGER, socket_test_logger).
-define(TPP_SMALL, lists:seq(1, 8)).
-define(TPP_MEDIUM, lists:flatten(lists:duplicate(1024, ?TPP_SMALL))).
@@ -335,15 +336,19 @@ traffic_cases() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init_per_suite(Config) ->
+ ?LOGGER:start(),
Config.
end_per_suite(_) ->
+ ?LOGGER:stop(),
ok.
init_per_testcase(_TC, Config) ->
+ ?LOGGER:start(),
Config.
end_per_testcase(_TC, Config) ->
+ ?LOGGER:stop(),
Config.
@@ -1798,6 +1803,10 @@ api_to_connect_tcp(InitState) ->
[{tester, Tester}]) of
{ok, ok = _Result} ->
{ok, maps:remove(connect_limit, State)};
+ {ok, {error, {connect_limit_reached,R,L}}} ->
+ {skip,
+ ?LIB:f("Connect limit reached ~w: ~w",
+ [L, R])};
{ok, Result} ->
Result;
{error, _} = ERROR ->
@@ -1968,25 +1977,25 @@ api_to_connect_tcp(InitState) ->
api_toc_tcp_client_start(Node) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> api_toc_tcp_client(Self, GL) end,
+ Fun = fun() -> api_toc_tcp_client(Self) end,
erlang:spawn(Node, Fun).
-api_toc_tcp_client(Parent, GL) ->
- api_toc_tcp_client_init(Parent, GL),
+api_toc_tcp_client(Parent) ->
+ api_toc_tcp_client_init(Parent),
ServerSA = api_toc_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
api_toc_tcp_client_announce_ready(Parent, init),
{To, ConLimit} = api_toc_tcp_client_await_continue(Parent, connect),
Result = api_to_connect_tcp_await_timeout(To, ServerSA, Domain, ConLimit),
+ ?SEV_IPRINT("result: ~p", [Result]),
api_toc_tcp_client_announce_ready(Parent, connect, Result),
Reason = api_toc_tcp_client_await_terminate(Parent),
exit(Reason).
-api_toc_tcp_client_init(Parent, GL) ->
+api_toc_tcp_client_init(Parent) ->
+ put(sname, "rclient"),
%% i("api_toc_tcp_client_init -> entry"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ok.
api_toc_tcp_client_await_start(Parent) ->
@@ -3710,7 +3719,8 @@ sc_lc_receive_response_tcp(InitState) ->
?SEV_FINISH_NORMAL
],
- %% The point of this is to perform the recv for which we are testing the reponse
+ %% The point of this is to perform the recv for which
+ %% we are testing the reponse.
HandlerSeq =
[
%% *** Wait for start order part ***
@@ -3758,7 +3768,8 @@ sc_lc_receive_response_tcp(InitState) ->
?SEV_EPRINT("Unexpected data received"),
{error, unexpected_success};
{error, closed} ->
- ?SEV_IPRINT("received expected 'closed' result"),
+ ?SEV_IPRINT("received expected 'closed' "
+ "result"),
State1 = maps:remove(sock, State),
{ok, State1};
{error, Reason} = ERROR ->
@@ -5806,13 +5817,12 @@ sc_rc_receive_response_tcp(InitState) ->
sc_rc_tcp_client_start(Node) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> sc_rc_tcp_client(Self, GL) end,
+ Fun = fun() -> sc_rc_tcp_client(Self) end,
erlang:spawn(Node, Fun).
-sc_rc_tcp_client(Parent, GL) ->
- sc_rc_tcp_client_init(Parent, GL),
+sc_rc_tcp_client(Parent) ->
+ sc_rc_tcp_client_init(Parent),
ServerSA = sc_rc_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
Sock = sc_rc_tcp_client_create(Domain),
@@ -5825,12 +5835,13 @@ sc_rc_tcp_client(Parent, GL) ->
sc_rc_tcp_client_close(Sock),
sc_rc_tcp_client_announce_ready(Parent, close),
Reason = sc_rc_tcp_client_await_terminate(Parent),
+ ?SEV_IPRINT("terminate"),
exit(Reason).
-sc_rc_tcp_client_init(Parent, GL) ->
- i("sc_rc_tcp_client_init -> entry"),
+sc_rc_tcp_client_init(Parent) ->
+ put(sname, "rclient"),
+ ?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ok.
sc_rc_tcp_client_await_start(Parent) ->
@@ -6633,13 +6644,12 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
sc_rs_tcp_client_start(Node, Send) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> sc_rs_tcp_client(Self, Send, GL) end,
+ Fun = fun() -> sc_rs_tcp_client(Self, Send) end,
erlang:spawn(Node, Fun).
-sc_rs_tcp_client(Parent, Send, GL) ->
- sc_rs_tcp_client_init(Parent, GL),
+sc_rs_tcp_client(Parent, Send) ->
+ sc_rs_tcp_client_init(Parent),
ServerSA = sc_rs_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
Sock = sc_rs_tcp_client_create(Domain),
@@ -6658,12 +6668,13 @@ sc_rs_tcp_client(Parent, Send, GL) ->
sc_rs_tcp_client_close(Sock),
sc_rs_tcp_client_announce_ready(Parent, close),
Reason = sc_rs_tcp_client_await_terminate(Parent),
+ ?SEV_IPRINT("terminate"),
exit(Reason).
-sc_rs_tcp_client_init(Parent, GL) ->
- i("sc_rs_tcp_client_init -> entry"),
+sc_rs_tcp_client_init(Parent) ->
+ put(sname, "rclient"),
+ ?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ok.
sc_rs_tcp_client_await_start(Parent) ->
@@ -7782,12 +7793,11 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
traffic_snr_tcp_client_start(Node) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> traffic_snr_tcp_client(Self, GL) end,
+ Fun = fun() -> traffic_snr_tcp_client(Self) end,
erlang:spawn(Node, Fun).
-traffic_snr_tcp_client(Parent, GL) ->
- {Sock, ServerSA} = traffic_snr_tcp_client_init(Parent, GL),
+traffic_snr_tcp_client(Parent) ->
+ {Sock, ServerSA} = 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),
@@ -7816,10 +7826,10 @@ traffic_snr_tcp_client_send_loop(Parent, Sock) ->
exit({await_continue, Reason})
end.
-traffic_snr_tcp_client_init(Parent, GL) ->
- i("traffic_snr_tcp_client_init -> entry"),
+traffic_snr_tcp_client_init(Parent) ->
+ put(sname, "rclient"),
+ ?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ServerSA = traffic_snr_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
Sock = traffic_snr_tcp_client_create(Domain),
@@ -8146,8 +8156,9 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp6(_Config) when is_list(_Config)
Num = ?TPP_MEDIUM_NUM,
tc_try(traffic_ping_pong_medium_sendto_and_recvfrom_udp6,
fun() ->
+ not_yet_implemented(),
?TT(?SECS(45)),
- InitState = #{domain => inet,
+ InitState = #{domain => inet6,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
@@ -8201,7 +8212,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
fun() ->
not_yet_implemented(),
?TT(?SECS(20)),
- InitState = #{domain => inet,
+ InitState = #{domain => inet6,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -8471,6 +8482,9 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) ->
true ->
ok
end,
+
+
+
ok = socket:setopt(Sock, otp, rcvbuf, 8*1024)
end,
traffic_ping_pong_send_and_receive_tcp2(InitState#{buf_init => Fun}).
@@ -9109,12 +9123,11 @@ tpp_tcp_handler_msg_exchange_loop(Sock, Send, Recv, N, Sent, Received, Start) ->
tpp_tcp_client_create(Node) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> tpp_tcp_client(Self, GL) end,
+ Fun = fun() -> tpp_tcp_client(Self) end,
erlang:spawn(Node, Fun).
-tpp_tcp_client(Parent, GL) ->
- tpp_tcp_client_init(Parent, GL),
+tpp_tcp_client(Parent) ->
+ tpp_tcp_client_init(Parent),
{ServerSA, BufInit, Send, Recv} = tpp_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
Sock = tpp_tcp_client_sock_open(Domain, BufInit),
@@ -9131,11 +9144,10 @@ tpp_tcp_client(Parent, GL) ->
?SEV_IPRINT("terminating"),
exit(Reason).
-tpp_tcp_client_init(Parent, GL) ->
+tpp_tcp_client_init(Parent) ->
put(sname, "rclient"),
?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ok.
tpp_tcp_client_await_start(Parent) ->
@@ -9362,20 +9374,23 @@ traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState) ->
traffic_ping_pong_send_and_receive_udp(#{msg := Msg} = InitState) ->
Fun = fun(Sock) ->
{ok, RcvSz} = socket:getopt(Sock, socket, rcvbuf),
- if (RcvSz < size(Msg)) ->
+ if (RcvSz =< (8+size(Msg))) ->
+ i("adjust socket rcvbuf buffer size"),
ok = socket:setopt(Sock, socket, rcvbuf, 1024+size(Msg));
true ->
ok
end,
{ok, SndSz} = socket:getopt(Sock, socket, sndbuf),
- if (SndSz < size(Msg)) ->
+ if (SndSz =< (8+size(Msg))) ->
+ i("adjust socket sndbuf buffer size"),
ok = socket:setopt(Sock, socket, sndbuf, 1024+size(Msg));
true ->
ok
end,
{ok, OtpRcvBuf} = socket:getopt(Sock, otp, rcvbuf),
if
- (OtpRcvBuf < size(Msg)) ->
+ (OtpRcvBuf =< (8+size(Msg))) ->
+ i("adjust otp rcvbuf buffer size"),
ok = socket:setopt(Sock, otp, rcvbuf, 1024+size(Msg));
true ->
ok
@@ -9837,6 +9852,7 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
?SEV_FINISH_NORMAL
],
+
i("start server evaluator"),
ServerInitState = #{domain => maps:get(domain, InitState),
recv => maps:get(recv, InitState),
@@ -9884,7 +9900,8 @@ tpp_udp_server_handler_init(Parent) ->
ok.
tpp_udp_server_handler_msg_exchange(Sock, Send, Recv) ->
- tpp_udp_server_handler_msg_exchange_loop(Sock, Send, Recv, 0, 0, 0, undefined).
+ tpp_udp_server_handler_msg_exchange_loop(Sock, Send, Recv,
+ 0, 0, 0, undefined).
tpp_udp_server_handler_msg_exchange_loop(Sock, Send, Recv,
N, Sent, Received, Start) ->
@@ -9920,7 +9937,8 @@ tpp_udp_server_handler_msg_exchange_loop(Sock, Send, Recv,
%% exit({'ping-send', Reason, N})
%% end;
{error, closed} ->
- ?SEV_IPRINT("closed - we are done: ~w, ~w, ~w", [N, Sent, Received]),
+ ?SEV_IPRINT("closed - we are done: ~w, ~w, ~w",
+ [N, Sent, Received]),
Stop = ?LIB:timestamp(),
{N, Sent, Received, Start, Stop};
{error, RReason} ->
@@ -9933,36 +9951,45 @@ tpp_udp_server_handler_msg_exchange_loop(Sock, Send, Recv,
tpp_udp_client_handler_create(Node) ->
Self = self(),
- GL = group_leader(),
- Fun = fun() -> tpp_udp_client_handler(Self, GL) end,
+ Fun = fun() -> put(sname, "chandler"), tpp_udp_client_handler(Self) end,
erlang:spawn(Node, Fun).
-tpp_udp_client_handler(Parent, GL) ->
- tpp_udp_client_handler_init(Parent, GL),
+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),
+ ?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),
+ ?SEV_IPRINT("announce ready", []),
tpp_udp_handler_announce_ready(Parent, init),
{InitMsg, Num} = tpp_udp_handler_await_continue(Parent, send),
+ ?SEV_IPRINT("received continue with"
+ "~n Num: ~p", [Num]),
Result = tpp_udp_client_handler_msg_exchange(Sock, ServerSA,
Send, Recv, InitMsg, Num),
+ ?SEV_IPRINT("ready"),
tpp_udp_handler_announce_ready(Parent, send, Result),
+ ?SEV_IPRINT("await terminate"),
Reason = tpp_udp_handler_await_terminate(Parent),
+ ?SEV_IPRINT("terminate with ~p", [Reason]),
tpp_udp_sock_close(Sock),
?SEV_IPRINT("terminating"),
exit(Reason).
-tpp_udp_client_handler_init(Parent, GL) ->
+tpp_udp_client_handler_init(Parent) ->
put(sname, "chandler"),
?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- group_leader(self(), GL),
ok.
-tpp_udp_client_handler_msg_exchange(Sock, ServerSA, Send, Recv, InitMsg, Num) ->
+tpp_udp_client_handler_msg_exchange(Sock, ServerSA,
+ Send, Recv, InitMsg, Num) ->
Start = ?LIB:timestamp(),
- tpp_udp_client_handler_msg_exchange_loop(Sock, ServerSA, Send, Recv, InitMsg,
+ tpp_udp_client_handler_msg_exchange_loop(Sock, ServerSA,
+ Send, Recv, InitMsg,
Num, 0, 0, 0, Start).
tpp_udp_client_handler_msg_exchange_loop(_Sock, _Dest, _Send, _Recv, _Msg,
@@ -9970,16 +9997,14 @@ tpp_udp_client_handler_msg_exchange_loop(_Sock, _Dest, _Send, _Recv, _Msg,
Start) ->
Stop = ?LIB:timestamp(),
{Sent, Received, Start, Stop};
-tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data,
+tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data,
Num, N, Sent, Received, Start) ->
- %% d("tpp_udp_client_handler_msg_exchange_loop(~w,~w) try send", [Num,N]),
case tpp_udp_send_req(Sock, Send, Data, Dest) of
{ok, SendSz} ->
- %% d("tpp_tcp_client_msg_exchange_loop(~w,~w) sent - "
- %% "now try recv", [Num,N]),
case tpp_udp_recv_rep(Sock, Recv) of
{ok, NewData, RecvSz, Dest} ->
- tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv,
+ tpp_udp_client_handler_msg_exchange_loop(Sock, Dest,
+ Send, Recv,
NewData, Num, N+1,
Sent+SendSz,
Received+RecvSz,
@@ -10009,55 +10034,17 @@ tpp_udp_recv(Sock, Recv, Tag) ->
%% "~n Source: ~p"
%% "~n Tag: ~p"
%% "~n Sz: ~p"
- %% "~n size(Data): ~p", [Source, Tag, Sz, size(Data)]),
+ %% "~n size(Data): ~p",
+ %% [Source, Tag, Sz, size(Data)]),
{ok, Data, size(Msg), Source};
- {ok, {Source, <<Tag:32/integer, Sz:32/integer, Data/binary>> = Msg}} ->
- %% ?SEV_IPRINT("tpp_udp_recv -> got part: "
- %% "~n Source: ~p"
- %% "~n Tag: ~p"
- %% "~n Sz: ~p"
- %% "~n size(Data): ~p", [Source, Tag, Sz, size(Data)]),
- Remains = Sz - size(Data),
- tpp_tcp_recv(Sock, Source, Recv, Tag, Remains, size(Msg), [Data]);
+ {ok, {_Source, <<Tag:32/integer, Sz:32/integer, Data/binary>>}} ->
+ {error, {invalid_msg, Sz, size(Data)}};
{ok, {_, <<Tag:32/integer, _/binary>>}} ->
{error, {invalid_msg_tag, Tag}};
{error, _} = ERROR ->
ERROR
end.
-%% We match against Source since we only communicate with one peer
-tpp_tcp_recv(Sock, Source, Recv, Tag, Remaining, AccSz, Acc) ->
- %% ?SEV_IPRINT("tpp_tcp_recv -> entry with"
- %% "~n Tag: ~p"
- %% "~n Remaining: ~p"
- %% "~n AccSz: ~p"
- %% "~n RcvBuf: ~p"
- %% "~n SndBuf: ~p",
- %% [Tag, Remaining, AccSz,
- %% socket:getopt(Sock, socket, rcvbuf),
- %% socket:getopt(Sock, socket, sndbuf)]),
- case Recv(Sock, Remaining) of
- {ok, {Source, Data}} when (Remaining =:= size(Data)) ->
- %% ?SEV_IPRINT("tpp_udp_recv -> got rest: "
- %% "~n Source: ~p"
- %% "~n size(Data): ~p", [Source, size(Data)]),
- %% We got the rest
- TotSz = AccSz + size(Data),
- {ok,
- erlang:iolist_to_binary(lists:reverse([Data | Acc])),
- TotSz, Source};
- {ok, {Source, Data}} when (Remaining > size(Data)) ->
- %% ?SEV_IPRINT("tpp_udp_recv -> got part of rest: "
- %% "~n Source: ~p"
- %% "~n size(Data): ~p", [Source, size(Data)]),
- tpp_tcp_recv(Sock, Source, Recv, Tag,
- Remaining - size(Data), AccSz + size(Data),
- [Data | Acc]);
- {error, _} = ERROR ->
- ERROR
- end.
-
-
tpp_udp_send_req(Sock, Send, Data, Dest) ->
tpp_udp_send(Sock, Send, ?TPP_REQUEST, Data, Dest).
@@ -10070,15 +10057,6 @@ tpp_udp_send(Sock, Send, Tag, Data, Dest) ->
tpp_udp_send_msg(Sock, Send, Msg, Dest, 0).
tpp_udp_send_msg(Sock, Send, Msg, Dest, AccSz) when is_binary(Msg) ->
- %% d("tpp_udp_send_msg -> entry with"
- %% "~n size(Msg): ~p"
- %% "~n Dest: ~p"
- %% "~n AccSz: ~p"
- %% "~n RcvBuf: ~p"
- %% "~n SndBuf: ~p",
- %% [size(Msg), Dest, AccSz,
- %% socket:getopt(Sock, socket, rcvbuf),
- %% socket:getopt(Sock, socket, sndbuf)]),
case Send(Sock, Msg, Dest) of
ok ->
{ok, AccSz+size(Msg)};
@@ -10162,6 +10140,14 @@ start_node(Host, NodeName) ->
UniqueNodeName = f("~w_~w", [NodeName, erlang:system_time(millisecond)]),
case do_start_node(Host, UniqueNodeName) of
{ok, _} = OK ->
+ global:sync(),
+ %% i("Node ~p started: "
+ %% "~n Nodes: ~p"
+ %% "~n Logger: ~p"
+ %% "~n Global Names: ~p",
+ %% [NodeName, nodes(),
+ %% global:whereis_name(socket_test_logger),
+ %% global:registered_names()]),
OK;
{error, Reason, _} ->
{error, Reason}
diff --git a/erts/emulator/test/socket_test_evaluator.erl b/erts/emulator/test/socket_test_evaluator.erl
index e8755a9512..48fb6a027e 100644
--- a/erts/emulator/test/socket_test_evaluator.erl
+++ b/erts/emulator/test/socket_test_evaluator.erl
@@ -76,6 +76,7 @@
%% ============================================================================
-define(LIB, socket_test_lib).
+-define(LOGGER, socket_test_logger).
-define(EXTRA_NOTHING, '$nothing').
-define(ANNOUNCEMENT_START, '$start').
@@ -122,6 +123,8 @@ loop(ID, [#{desc := Desc,
loop(ID + 1, Cmds, State);
{ok, NewState} ->
loop(ID + 1, Cmds, NewState);
+ {skip, Reason} ->
+ exit({skip, Reason});
{error, Reason} ->
eprint("command ~w failed: "
"~n Reason: ~p", [ID, Reason]),
@@ -160,6 +163,8 @@ await_finish(Evs, Fails) ->
iprint("unknown process ~p died (normal)", [Pid]),
await_finish(Evs, Fails)
end;
+ {'DOWN', _MRef, process, Pid, {skip, Reason}} ->
+ ?LIB:skip(Reason);
{'DOWN', _MRef, process, Pid, Reason} ->
case lists:keysearch(Pid, #ev.pid, Evs) of
{value, #ev{name = Name}} ->
@@ -486,6 +491,5 @@ print(Prefix, F, A) ->
SName ->
f("[~s][~p]", [SName, self()])
end,
- FStr = f("[~s]~s ~s" ++ F, [?LIB:formated_timestamp(), IDStr, Prefix | A]),
- io:format(user, FStr ++ "~n", []),
- io:format(FStr, []).
+ ?LOGGER:format("[~s]~s ~s" ++ F,
+ [?LIB:formated_timestamp(), IDStr, Prefix | A]).
diff --git a/erts/emulator/test/socket_test_lib.erl b/erts/emulator/test/socket_test_lib.erl
index c36cc4fbfa..f55f338ef9 100644
--- a/erts/emulator/test/socket_test_lib.erl
+++ b/erts/emulator/test/socket_test_lib.erl
@@ -27,13 +27,15 @@
formated_timestamp/0,
format_timestamp/1,
+ %% String and format
+ f/2,
+
%% Skipping
not_yet_implemented/0,
skip/1
]).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
timestamp() ->
@@ -62,6 +64,12 @@ format_timestamp({_N1, _N2, _N3} = TS) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+f(F, A) ->
+ lists:flatten(io_lib:format(F, A)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
not_yet_implemented() ->
skip("not yet implemented").
diff --git a/erts/emulator/test/socket_test_logger.erl b/erts/emulator/test/socket_test_logger.erl
new file mode 100644
index 0000000000..5996bbe855
--- /dev/null
+++ b/erts/emulator/test/socket_test_logger.erl
@@ -0,0 +1,99 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2018-2018. 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.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(socket_test_logger).
+
+-export([
+ start/0,
+ stop/0,
+ format/2
+ ]).
+
+
+-define(LIB, socket_test_lib).
+-define(LOGGER, ?MODULE).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+start() ->
+ case global:whereis_name(?LOGGER) of
+ Pid when is_pid(Pid) ->
+ ok;
+ undefined ->
+ Self = self(),
+ Pid = spawn_link(fun() -> init(Self) end),
+ yes = global:register_name(?LOGGER, Pid),
+ ok
+ end.
+
+
+stop() ->
+ case global:whereis_name(?LOGGER) of
+ undefined ->
+ ok;
+ Pid when is_pid(Pid) ->
+ global:unregister_name(?LOGGER),
+ Pid ! {?LOGGER, '$logger', stop},
+ ok
+ end.
+
+
+format(F, []) ->
+ do_format(F);
+format(F, A) ->
+ do_format(?LIB:f(F, A)).
+
+do_format(Msg) ->
+ case global:whereis_name(?LOGGER) of
+ undefined ->
+ ok;
+ Pid when is_pid(Pid) ->
+ Pid ! {?MODULE, '$logger', {msg, Msg}},
+ ok
+ end.
+
+init(Parent) ->
+ put(sname, "logger"),
+ print("[~s][logger] starting~n", [?LIB:formated_timestamp()]),
+ loop(#{parent => Parent}).
+
+loop(#{parent := Parent} = State) ->
+ receive
+ {'EXIT', Parent, _} ->
+ print("[~s][logger] parent exit~n", [?LIB:formated_timestamp()]),
+ exit(normal);
+
+ {?MODULE, '$logger', stop} ->
+ print("[~s][logger] stopping~n", [?LIB:formated_timestamp()]),
+ exit(normal);
+
+ {?MODULE, '$logger', {msg, Msg}} ->
+ print(Msg),
+ loop(State)
+ end.
+
+
+print(F, A) ->
+ print(?LIB:f(F, A)).
+
+print(Str) ->
+ io:format(user, Str ++ "~n", []),
+ io:format(Str, []).