aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-10-05 14:23:47 +0200
committerMicael Karlberg <[email protected]>2018-10-05 15:13:31 +0200
commitd4cedb9fa86db720cc247b9201d5c7e1e8aab461 (patch)
treeca8b96b27779cf439ab062102391ed624c34cfc4
parent8210ffc460a0bfab8b3007afe3e1141c1bb9dec6 (diff)
downloadotp-d4cedb9fa86db720cc247b9201d5c7e1e8aab461.tar.gz
otp-d4cedb9fa86db720cc247b9201d5c7e1e8aab461.tar.bz2
otp-d4cedb9fa86db720cc247b9201d5c7e1e8aab461.zip
[socket-nif|test] Two more test cases (tcp) reworked
Two (tcp) test cases where reworked using the command evaluator. OTP-14831
-rw-r--r--lib/kernel/test/socket_SUITE.erl288
1 files changed, 160 insertions, 128 deletions
diff --git a/lib/kernel/test/socket_SUITE.erl b/lib/kernel/test/socket_SUITE.erl
index ed5722f008..e50daaf367 100644
--- a/lib/kernel/test/socket_SUITE.erl
+++ b/lib/kernel/test/socket_SUITE.erl
@@ -71,6 +71,7 @@
%% -export([]).
+-type initial_evaluator_state() :: map().
-type evaluator_state() :: term().
-type command_fun() ::
fun((State :: evaluator_state()) -> ok) |
@@ -78,8 +79,7 @@
fun((State :: evaluator_state()) -> {error, term()}).
-type command() :: #{desc := string(),
- cmd := command_fun()
- }.
+ cmd := command_fun()}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -89,6 +89,8 @@
-define(FAIL(R), exit(R)).
+-define(SLEEP(T), receive after T -> ok end).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -366,19 +368,6 @@ api_b_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
api_b_send_and_recv_udp(InitState) ->
- %% SockSrc = sock_open(Domain, dgram, udp),
- %% LAddr = which_local_addr(Domain),
- %% LSA = #{family => Domain, addr => LAddr},
- %% sock_bind(SockSrc, LSA),
- %% SockDst = sock_open(Domain, dgram, udp),
- %% sock_bind(SockDst, LSA),
- %% Dst = sock_sockname(SockDst),
- %% ok = Send(SockSrc, ?BASIC_REQ, Dst),
- %% {ok, {Src, ?BASIC_REQ}} = Recv(SockDst),
- %% ok = Send(SockDst, ?BASIC_REP, Src),
- %% {ok, {Dst, ?BASIC_REP}} = Recv(SockSrc),
- %% socket:close(SockSrc),
- %% socket:close(SockDst),
Seq =
[
#{desc => "local address",
@@ -425,7 +414,7 @@ api_b_send_and_recv_udp(InitState) ->
ok = Send(Sock, ?BASIC_REQ, Dst)
end},
#{desc => "recv req (from src)",
- cmd => fun(#{sock_dst := Sock, sa_src := Src, recv := Recv} = State) ->
+ cmd => fun(#{sock_dst := Sock, sa_src := Src, recv := Recv}) ->
{ok, {Src, ?BASIC_REQ}} = Recv(Sock),
ok
end},
@@ -469,7 +458,10 @@ api_b_send_and_recv_tcp4(_Config) when is_list(_Config) ->
Recv = fun(Sock) ->
socket:recv(Sock)
end,
- ok = api_b_send_and_recv_tcp(inet, Send, Recv),
+ InitState = #{domain => inet,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_tcp(InitState),
tc_end().
@@ -496,119 +488,157 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) ->
ERROR
end
end,
- ok = api_b_send_and_recv_tcp(inet, Send, Recv),
+ InitState = #{domain => inet,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_tcp(InitState),
tc_end().
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-api_b_send_and_recv_tcp(Domain, Send, Recv) ->
+api_b_send_and_recv_tcp(InitState) ->
process_flag(trap_exit, true),
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
- Starter = self(),
- ServerFun = fun() ->
- put(sname, "server"),
- %% Create the listen socket
- ServerLSock =
- case socket:open(Domain, stream, tcp) of
- {ok, S1} ->
- S1;
- {error, ServerOR} ->
- ?FAIL({server, open, ServerOR})
- end,
- %% And bind it to the local address
- SP =
- case socket:bind(ServerLSock, LSA) of
- {ok, P} ->
- P;
- {error, ServerBR} ->
- ?FAIL({server, bind, ServerBR})
- end,
- %% Listen for connecting clients
- case socket:listen(ServerLSock) of
- ok ->
- ok;
- {error, ServerLR} ->
- ?FAIL({server, listen, ServerLR})
- end,
- %% We are ready
- Starter ! {self(), {ok, SP}},
- %% Accept connections
- ServerSock =
- case socket:accept(ServerLSock) of
- {ok, Sock} ->
- Sock;
- {error, ServerAR} ->
- ?FAIL({server, accept, ServerAR})
- end,
- %% Wait for a message
- case Recv(ServerSock) of
- {ok, ?BASIC_REQ} ->
- ok;
- {error, ServerRR} ->
- ?FAIL({server, recv, ServerRR})
- end,
- %% Send the reply
- case Send(ServerSock, ?BASIC_REP) of
- ok ->
- ok;
- {error, ServerSR} ->
- ?FAIL({server, send, ServerSR})
- end,
- %% Close the sockets
- socket:close(ServerSock),
- socket:close(ServerLSock),
- %% We are done
- exit(normal)
- end,
- Server = spawn_link(ServerFun),
- ServerPort =
- receive
- {Server, {ok, P}} ->
- P;
- {'EXIT', Server, ServerStartReason} ->
- ?FAIL({server, start, ServerStartReason})
- end,
- ClientSock =
- case socket:open(Domain, stream, tcp) of
- {ok, S2} ->
- S2;
- {error, ClientOR} ->
- ?FAIL({client, open, ClientOR})
- end,
- case socket:bind(ClientSock, LSA) of
- {ok, _} ->
- ok;
- {error, ClientBR} ->
- ?FAIL({client, bind, ClientBR})
- end,
- case socket:connect(ClientSock, LSA#{port => ServerPort}) of
- ok ->
- ok;
- {error, ClientCR} ->
- ?FAIL({client, connect, ClientCR})
- end,
- case Send(ClientSock, ?BASIC_REQ) of
- ok ->
- ok;
- {error, ClientSR} ->
- ?FAIL({client, send, ClientSR})
- end,
- case Recv(ClientSock) of
- {ok, ?BASIC_REP} ->
- ok;
- {ok, Msg} ->
- ?FAIL({client, recv, {unexpected, Msg}})
- end,
- receive
- {'EXIT', Server, normal} ->
- ok;
- {'EXIT', Server, ServerStopReason} ->
- ?FAIL({server, stop, ServerStopReason})
- end,
- socket:close(ClientSock),
- ok.
+ ServerSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ LAddr = which_local_addr(Domain),
+ LSA = #{family => Domain, addr => LAddr},
+ {ok, State#{lsa => LSA}}
+ end},
+ #{desc => "create listen socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{lsock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{lsock := LSock, lsa := LSA} = State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, Port} ->
+ {ok, State#{lport => Port}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "make listen socket",
+ cmd => fun(#{lsock := LSock}) ->
+ socket:listen(LSock)
+ end},
+ #{desc => "announce server port",
+ cmd => fun(#{parent := Parent, lport := Port}) ->
+ ei("announcing port to parent (~p)", [Parent]),
+ Parent ! {server_port, self(), Port},
+ ok
+ end},
+ #{desc => "await connection",
+ cmd => fun(#{lsock := LSock} = State) ->
+ case socket:accept(LSock) of
+ {ok, Sock} ->
+ ei("accepted: ~p", [Sock]),
+ {ok, State#{tsock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "await request",
+ cmd => fun(#{tsock := Sock, recv := Recv}) ->
+ case Recv(Sock) of
+ {ok, ?BASIC_REQ} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "send reply",
+ cmd => fun(#{tsock := Sock, send := Send}) ->
+ Send(Sock, ?BASIC_REP)
+ end},
+ #{desc => "sleep some",
+ cmd => fun(_) ->
+ ?SLEEP(1000),
+ ok
+ end},
+ #{desc => "close traffic socket",
+ cmd => fun(#{tsock := Sock}) ->
+ socket:close(Sock)
+ end},
+ #{desc => "close listen socket",
+ cmd => fun(#{lsock := Sock}) ->
+ socket:close(Sock)
+ end},
+ #{desc => "finish",
+ cmd => fun(_) ->
+ {ok, normal}
+ end}
+ ],
+
+ ClientSeq =
+ [
+ #{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},
+ {ok, State#{lsa => LSA, ssa => SSA}}
+ end},
+ #{desc => "create socket",
+ cmd => fun(#{domain := Domain} = State) ->
+ case socket:open(Domain, stream, tcp) of
+ {ok, Sock} ->
+ {ok, State#{sock => Sock}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "bind to local address",
+ cmd => fun(#{sock := Sock, lsa := LSA} = State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, Port} ->
+ {ok, State#{port => Port}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+ #{desc => "connect to server",
+ cmd => fun(#{sock := Sock, ssa := SSA}) ->
+ socket:connect(Sock, SSA)
+ end},
+ #{desc => "send request (to server)",
+ cmd => fun(#{sock := Sock, send := Send}) ->
+ Send(Sock, ?BASIC_REQ)
+ end},
+ #{desc => "recv reply (from server)",
+ cmd => fun(#{sock := Sock, recv := Recv}) ->
+ {ok, ?BASIC_REP} = Recv(Sock),
+ ok
+ end},
+ #{desc => "close socket",
+ cmd => fun(#{sock := Sock}) ->
+ socket:close(Sock)
+ end},
+ #{desc => "finish",
+ cmd => fun(_) ->
+ {ok, normal}
+ end}
+ ],
+
+ p("start server evaluator"),
+ Server = evaluator_start("server", ServerSeq, InitState),
+ p("await server (~p) port", [Server]),
+ SPort = receive
+ {server_port, Server, Port} ->
+ Port
+ end,
+ p("start client evaluator"),
+ Client = evaluator_start("client", ClientSeq, InitState#{server_port => SPort}),
+ p("await evaluator(s)"),
+ ok = await_evaluator_finish([Server, Client]).
@@ -1404,13 +1434,15 @@ which_addr2(Domain, [_|IFO]) ->
-spec evaluator_start(Name, Seq, Init) -> {Pid, MRef} when
Name :: string(),
Seq :: [command()],
- Init :: evaluator_state(),
+ Init :: initial_evaluator_state(),
Pid :: pid(),
MRef :: reference().
evaluator_start(Name, Seq, Init)
when is_list(Name) andalso is_list(Seq) andalso (Seq =/= []) ->
- erlang:spawn_monitor(fun() -> evaluator_init(Name, Seq, Init) end).
+ Init2 = Init#{parent => self()},
+ {Pid, _} = erlang:spawn_monitor(fun() -> evaluator_init(Name, Seq, Init2) end),
+ Pid.
evaluator_init(Name, Seq, Init) ->
put(sname, Name),
@@ -1449,7 +1481,7 @@ await_evaluator_finish([], Fails) ->
await_evaluator_finish(Evs, Fails) ->
receive
{'DOWN', _MRef, process, Pid, normal} ->
- case lists:keydelete(Pid, 1, Evs) of
+ case lists:delete(Pid, Evs) of
Evs ->
p("unknown process ~p died (normal)", [Pid]),
await_evaluator_finish(Evs, Fails);
@@ -1458,7 +1490,7 @@ await_evaluator_finish(Evs, Fails) ->
await_evaluator_finish(NewEvs, Fails)
end;
{'DOWN', _MRef, process, Pid, Reason} ->
- case lists:keydelete(Pid, 1, Evs) of
+ case lists:delete(Pid, Evs) of
Evs ->
p("unknown process ~p died: "
"~n ~p", [Pid, Reason]),