aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-07-18 14:35:45 +0200
committerMicael Karlberg <[email protected]>2019-07-18 14:35:45 +0200
commit138a6b122934dfd63571afda0f45bf8126c541b6 (patch)
tree2b65ee6f93c18502ad49cf244e947511baa11ecd /erts
parent12155cba0b8b8dc3853d78e948a917c92a84174e (diff)
parent16d4820c063c0b88c8114dc8958905765ab82fc8 (diff)
downloadotp-138a6b122934dfd63571afda0f45bf8126c541b6.tar.gz
otp-138a6b122934dfd63571afda0f45bf8126c541b6.tar.bz2
otp-138a6b122934dfd63571afda0f45bf8126c541b6.zip
Merge branch 'bmk/erts/esock/20190718/socket_option_keepalive/OTP-15904' into bmk/erts/esock/20190717/socket_options/OTP-15904
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/test/socket_SUITE.erl137
1 files changed, 135 insertions, 2 deletions
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index 313408aa36..babf3a0c45 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -128,6 +128,7 @@
api_opt_sock_debug/1,
api_opt_sock_domain/1,
api_opt_sock_dontroute/1,
+ api_opt_sock_keepalive/1,
api_opt_ip_add_drop_membership/1,
%% *** API Operation Timeout ***
@@ -793,7 +794,8 @@ api_options_socket_cases() ->
api_opt_sock_broadcast,
api_opt_sock_debug,
api_opt_sock_domain,
- api_opt_sock_dontroute
+ api_opt_sock_dontroute,
+ api_opt_sock_keepalive
].
api_options_ip_cases() ->
@@ -9551,7 +9553,7 @@ api_opt_sock_debug() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Tests the socket option domain.
-%% This is a read only option. Also not available on oll platforms.
+%% This is a read only option. Also not available on all platforms.
api_opt_sock_domain(suite) ->
[];
@@ -9794,6 +9796,134 @@ api_opt_sock_dontroute() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Tests the socket option keepalive.
+%% This is bit tricky to test, partly because we have no control over
+%% the underlying TCP timeouts. So, for now, we just test that we can
+%% change the value.
+
+api_opt_sock_keepalive(suite) ->
+ [];
+api_opt_sock_keepalive(doc) ->
+ [];
+api_opt_sock_keepalive(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_opt_sock_keepalive,
+ fun() -> has_support_sock_keepalive() end,
+ fun() -> api_opt_sock_keepalive() end).
+
+
+api_opt_sock_keepalive() ->
+ Opt = keepalive,
+ Set = fun(S, Val) when is_boolean(Val) ->
+ socket:setopt(S, socket, Opt, Val)
+ end,
+ Get = fun(S) ->
+ socket:getopt(S, socket, Opt)
+ end,
+
+ TesterSeq =
+ [
+ #{desc => "which local address",
+ cmd => fun(#{domain := Domain} = State) ->
+ case ?LIB:which_local_host_info(Domain) of
+ {ok, #{name := Name,
+ addr := Addr,
+ broadaddr := BAddr}} ->
+ ?SEV_IPRINT("local host info: "
+ "~n Name: ~p"
+ "~n Addr: ~p"
+ "~n Broadcast Addr: ~p",
+ [Name, Addr, BAddr]),
+ LSA = #{family => Domain,
+ addr => Addr},
+ BSA = #{family => Domain,
+ addr => BAddr},
+ {ok, State#{lsa => LSA,
+ bsa => BSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end},
+
+ #{desc => "create TCP 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 => "Get current value",
+ cmd => fun(#{sock := Sock} = State) ->
+ case Get(Sock) of
+ {ok, Val} when is_boolean(Val) ->
+ ?SEV_IPRINT("Success: ~p", [Val]),
+ {ok, State#{keepalive => Val}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Try change the value",
+ cmd => fun(#{sock := Sock, keepalive := Current} = State) ->
+ New = not Current,
+ ?SEV_IPRINT("Try change value from ~p to ~p",
+ [Current, New]),
+ case Set(Sock, New) of
+ ok ->
+ ?SEV_IPRINT("Expected Success"),
+ {ok, State#{keepalive => New}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected Failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+ #{desc => "Verify (new) current value",
+ cmd => fun(#{sock := Sock, keepalive := Val} = _State) ->
+ case Get(Sock) of
+ {ok, Val} ->
+ ?SEV_IPRINT("Expected Success (~p)", [Val]),
+ ok;
+ {ok, OtherVal} ->
+ ?SEV_IPRINT("Unexpected Success: ~p",
+ [OtherVal]),
+ {error, {unexpected_success_value,
+ Val, OtherVal}};
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("Unexpected failure: ~p",
+ [Reason]),
+ ERROR
+ end
+ end},
+
+ %% *** Termination ***
+ #{desc => "close UDP socket",
+ cmd => fun(#{sock := Sock} = State0) ->
+ socket:close(Sock),
+ State1 = maps:remove(sock, State0),
+ {ok, State1}
+ end},
+
+ %% *** We are done ***
+ ?SEV_FINISH_NORMAL
+ ],
+
+ Domain = inet,
+
+ i("start tester evaluator"),
+ InitState = #{domain => Domain},
+ Tester = ?SEV_START("tester", TesterSeq, InitState),
+
+ i("await evaluator(s)"),
+ ok = ?SEV_AWAIT_FINISH([Tester]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
%% Tests that the add_mambership and drop_membership ip options work.
%% We create one server and two clients. The server only send messages,
%% the clients only receives messages.
@@ -28553,6 +28683,9 @@ has_support_sock_domain() ->
has_support_sock_dontroute() ->
has_support_socket_option_sock(dontroute).
+has_support_sock_keepalive() ->
+ has_support_socket_option_sock(keepalive).
+
has_support_ip_add_membership() ->
has_support_socket_option_ip(add_membership).