diff options
author | Micael Karlberg <[email protected]> | 2019-07-18 12:34:34 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2019-07-18 12:44:05 +0200 |
commit | 319465f1b4b7a518a27a9f5170de528b8566b3f9 (patch) | |
tree | 1824ba6b5142a408a3608d44cafdf99f5eeedbba /erts/emulator/test | |
parent | a4e00d2bb479b84e01ec26afe8303d21e6eb29fb (diff) | |
download | otp-319465f1b4b7a518a27a9f5170de528b8566b3f9.tar.gz otp-319465f1b4b7a518a27a9f5170de528b8566b3f9.tar.bz2 otp-319465f1b4b7a518a27a9f5170de528b8566b3f9.zip |
[esock|test] Add test case for socket option 'dontroute'
OTP-15905
Diffstat (limited to 'erts/emulator/test')
-rw-r--r-- | erts/emulator/test/socket_SUITE.erl | 135 |
1 files changed, 133 insertions, 2 deletions
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index fd3206f2ef..759d3ba58f 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -126,6 +126,7 @@ api_opt_sock_bindtodevice/1, api_opt_sock_broadcast/1, api_opt_sock_debug/1, + api_opt_sock_dontroute/1, api_opt_ip_add_drop_membership/1, %% *** API Operation Timeout *** @@ -789,7 +790,8 @@ api_options_socket_cases() -> api_opt_sock_acceptfilter, api_opt_sock_bindtodevice, api_opt_sock_broadcast, - api_opt_sock_debug + api_opt_sock_debug, + api_opt_sock_dontroute ]. api_options_ip_cases() -> @@ -9511,7 +9513,7 @@ api_opt_sock_debug() -> end end}, #{desc => "Get current (new) debug value", - cmd => fun(#{sock := Sock, debug := Debug} = State) -> + cmd => fun(#{sock := Sock, debug := Debug} = _State) -> case Get(Sock) of {ok, Debug} when is_integer(Debug) -> ?SEV_IPRINT("Success: ~p", [Debug]), @@ -9548,6 +9550,132 @@ api_opt_sock_debug() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Tests the socket option dontroute. +%% The man page has the following to say: +%% "Don't send via a gateway, send only to directly connected hosts. +%% The same effect can be achieved by setting the MSG_DONTROUTE +%% flag on a socket send(2) operation." +%% Since its "kind of" difficult to check if it actually takes an +%% effect (you would need a gateway for that), we only test if we +%% can set and get the value. Better then nothing. + +api_opt_sock_dontroute(suite) -> + []; +api_opt_sock_dontroute(doc) -> + []; +api_opt_sock_dontroute(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_dontroute, + fun() -> has_support_sock_dontroute() end, + fun() -> api_opt_sock_dontroute() end). + + +api_opt_sock_dontroute() -> + Opt = dontroute, + 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 UDP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) 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#{dontroute => Val}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Try change value", + cmd => fun(#{sock := Sock, dontroute := Current} = State) -> + New = not Current, + ?SEV_IPRINT("Change from ~p to ~p", [Current, New]), + case Set(Sock, New) of + ok -> + ?SEV_IPRINT("Expected Success"), + {ok, State#{dontroute => New}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Verify changed value", + cmd => fun(#{sock := Sock, dontroute := Val} = _State) -> + case Get(Sock) of + {ok, Val} -> + ?SEV_IPRINT("Expected Success"), + ok; + {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. @@ -28301,6 +28429,9 @@ has_support_sock_broadcast() -> has_support_sock_debug() -> has_support_socket_option_sock(debug). +has_support_sock_dontroute() -> + has_support_socket_option_sock(dontroute). + has_support_ip_add_membership() -> has_support_socket_option_ip(add_membership). |