1: %%============================================================================== 2: %% Copyright 2012 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: 17: -module(tcp_listener_SUITE). 18: -compile([export_all, nowarn_export_all]). 19: 20: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]). 21: 22: %%-------------------------------------------------------------------- 23: %% Suite configuration 24: %%-------------------------------------------------------------------- 25: 26: all() -> 27: [s2s_inet_sockname_returns_error, 28: service_inet_sockname_returns_error]. 29: 30: suite() -> 31: require_rpc_nodes([mim]). 32: 33: %%-------------------------------------------------------------------- 34: %% Init & teardown 35: %%-------------------------------------------------------------------- 36: 37: init_per_suite(Config) -> 38: setup_meck(), 39: Config. 40: 41: end_per_suite(_Config) -> 42: teardown_meck(). 43: 44: setup_meck() -> 45: {Mod, Code} = rpc(mim(), dynamic_compile, from_string, [tcp_listener_helper_code()]), 46: rpc(mim(), code, load_binary, [Mod, "tcp_listener_helper.erl", Code]), 47: ok = rpc(mim(), meck, new, [mongoose_tcp_listener, [passthrough, no_link]]), 48: ok = rpc(mim(), tcp_listener_helper, setup_meck, []). 49: 50: teardown_meck() -> 51: rpc(mim(), meck, unload, []). 52: 53: tcp_listener_helper_code() -> 54: "-module(tcp_listener_helper).\n" 55: "-compile([export_all, nowarn_export_all]).\n" 56: "setup_meck() ->\n" 57: " meck:expect(mongoose_tcp_listener, read_connection_details, fun read_connection_details/2).\n\n" 58: "read_connection_details(Socket, Opts) ->\n" 59: " persistent_term:put(tcp_listener_helper_info, {Socket, self()}),\n" 60: " gen_tcp:close(Socket),\n" 61: " Result = meck:passthrough([Socket, Opts]),\n" 62: " persistent_term:put(tcp_listener_helper_result, Result),\n" 63: " Result.\n". 64: 65: %%-------------------------------------------------------------------- 66: %% Test cases 67: %%-------------------------------------------------------------------- 68: 69: s2s_inet_sockname_returns_error(_Config) -> 70: inet_sockname_returns_error(incoming_s2s_port). 71: 72: service_inet_sockname_returns_error(_Config) -> 73: inet_sockname_returns_error(service_port). 74: 75: %% Checks that the listener does not crash if inet:sockname/1 call returns an error 76: inet_sockname_returns_error(PortName) -> 77: Port = ct:get_config({hosts, mim, PortName}), 78: {ok, ClientSocket} = gen_tcp:connect(localhost, Port, []), 79: receive {tcp_closed, ClientSocket} -> gen_tcp:close(ClientSocket) 80: after 5000 -> ct:fail("Socket was not closed by the server") 81: end, 82: {_ServerSocket, Pid} = rpc(mim(), persistent_term, get, [tcp_listener_helper_info]), 83: %% The listener process is still alive 84: [_|_] = rpc:pinfo(Pid), 85: {error, einval} = rpc(mim(), persistent_term, get, [tcp_listener_helper_result]), 86: ok.