1 /*
2  * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License, version 2.0,
6  * as published by the Free Software Foundation.
7  *
8  * This program is also distributed with certain software (including
9  * but not limited to OpenSSL) that is licensed under separate terms,
10  * as designated in a particular file or component or in included license
11  * documentation.  The authors of MySQL hereby grant you an additional
12  * permission to link the program and your derivative works with the
13  * separately licensed software that they have included with MySQL.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License, version 2.0, for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23  */
24 
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27 #include <stddef.h>
28 #ifndef _WIN32
29 #include <netdb.h>
30 #endif
31 
32 #include <cstdint>
33 
34 #include "my_io.h"  // NOLINT(build/include_subdir)
35 #include "plugin/x/src/io/xpl_listener_tcp.h"
36 #include "unittest/gunit/xplugin/xpl/mock/ngs_general.h"
37 
38 namespace xpl {
39 namespace test {
40 
41 using namespace ::testing;  // NOLINT(build/namespaces)
42 
43 const char *const ADDRESS = "0.1.2.3";
44 const char *const ALL_INTERFACES_4 = "0.0.0.0";
45 const char *const ALL_INTERFACES_6 = "::";
46 const uint16_t PORT = 3030;
47 const char *const PORT_STRING = "3030";
48 const uint32_t PORT_TIMEOUT = 123;
49 const uint32_t BACKLOG = 122;
50 const my_socket SOCKET_OK = 10;
51 const int POSIX_OK = 0;
52 const int POSIX_FAILURE = -1;
53 
54 MATCHER(EqInvalidSocket, "") {
55   return INVALID_SOCKET == mysql_socket_getfd(arg);
56 }
57 
58 MATCHER_P(EqCastToCStr, expected, "") {
59   std::string force_string = expected;
60   return force_string == static_cast<char *>(arg);
61 }
62 
63 class Listener_tcp_testsuite : public Test {
64  public:
SetUp()65   void SetUp() {
66     KEY_socket_x_tcpip = 1;
67 
68     m_mock_factory = std::make_shared<StrictMock<Mock_factory>>();
69     m_mock_socket = std::make_shared<StrictMock<Mock_socket>>();
70     m_mock_system = std::make_shared<StrictMock<Mock_system>>();
71     m_mock_socket_invalid = std::make_shared<StrictMock<Mock_socket>>();
72 
73     ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
74   }
75 
assert_verify_and_reinitailize_rules()76   void assert_verify_and_reinitailize_rules() {
77     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_factory.get()));
78     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_socket_invalid.get()));
79     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_socket.get()));
80     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_system.get()));
81 
82     EXPECT_CALL(*m_mock_factory, create_system_interface())
83         .WillRepeatedly(Return(m_mock_system));
84     EXPECT_CALL(*m_mock_factory, create_socket(EqInvalidSocket()))
85         .WillRepeatedly(Return(m_mock_socket_invalid));
86     EXPECT_CALL(*m_mock_socket_invalid, get_socket_fd())
87         .WillRepeatedly(Return(INVALID_SOCKET));
88     EXPECT_CALL(*m_mock_socket, get_socket_fd())
89         .WillRepeatedly(Return(SOCKET_OK));
90     ON_CALL(*m_mock_system, get_socket_error_and_message(_, _))
91         .WillByDefault(DoAll(SetArgPointee<0>(0), SetArgPointee<1>("")));
92   }
93 
make_sut(const std::string & interface,const uint32_t port=PORT,const uint32_t port_timeout=PORT_TIMEOUT)94   void make_sut(const std::string &interface, const uint32_t port = PORT,
95                 const uint32_t port_timeout = PORT_TIMEOUT) {
96     m_resulting_bind_address = interface;
97     sut = std::make_shared<Listener_tcp>(
98         m_mock_factory, std::ref(m_resulting_bind_address), "", port,
99         port_timeout, std::ref(m_mock_socket_events), BACKLOG);
100   }
101 
expect_create_socket(addrinfo & ai,const std::string & interface,const int family,const int64_t result=SOCKET_OK)102   void expect_create_socket(addrinfo &ai, const std::string &interface,
103                             const int family,
104                             const int64_t result = SOCKET_OK) {
105     make_sut(interface, PORT, PORT_TIMEOUT);
106 
107     EXPECT_CALL(*m_mock_system,
108                 getaddrinfo(StrEq(interface), StrEq(PORT_STRING), _, _))
109         .WillOnce(DoAll(SetArgPointee<3>(&ai), Return(POSIX_OK)));
110 
111     EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillOnce(Return(result));
112     EXPECT_CALL(*m_mock_factory,
113                 create_socket(KEY_socket_x_tcpip, family, SOCK_STREAM, 0))
114         .WillOnce(Return(m_mock_socket));
115 
116 #ifdef IPV6_V6ONLY
117     EXPECT_CALL(*m_mock_socket,
118                 set_socket_opt(IPPROTO_IPV6, IPV6_V6ONLY, _, sizeof(int)))
119         .WillRepeatedly(Return(POSIX_OK));
120 #endif
121   }
122 
expect_listen_socket(std::shared_ptr<Mock_socket> mock_socket,addrinfo & ai,const bool socket_events_listen=true)123   void expect_listen_socket(std::shared_ptr<Mock_socket> mock_socket,
124                             addrinfo &ai,
125                             const bool socket_events_listen = true) {
126     EXPECT_CALL(*mock_socket, set_socket_thread_owner());
127     EXPECT_CALL(*mock_socket,
128                 bind(ai.ai_addr, static_cast<socklen_t>(ai.ai_addrlen)))
129         .WillOnce(Return(POSIX_OK));
130     EXPECT_CALL(*mock_socket, listen(BACKLOG)).WillOnce(Return(POSIX_OK));
131     std::shared_ptr<iface::Socket> socket_ptr = mock_socket;
132     EXPECT_CALL(m_mock_socket_events, listen(socket_ptr, _))
133         .WillOnce(Return(socket_events_listen));
134   }
135 
get_ai_ipv6()136   struct addrinfo get_ai_ipv6() {
137     struct addrinfo result;
138     static struct sockaddr_in6 in6;
139 
140     in6.sin6_family = result.ai_family = AF_INET6;
141     result.ai_socktype = 0;
142     result.ai_protocol = 0;
143     result.ai_addrlen = sizeof(in6);
144     result.ai_addr = reinterpret_cast<sockaddr *>(&in6);
145     result.ai_next = nullptr;
146 
147     return result;
148   }
149 
get_ai_ipv4()150   struct addrinfo get_ai_ipv4() {
151     struct addrinfo result;
152     static struct sockaddr_in in4;
153 
154     in4.sin_family = result.ai_family = AF_INET;
155     result.ai_socktype = 0;
156     result.ai_protocol = 0;
157     result.ai_addrlen = sizeof(in4);
158     result.ai_addr = reinterpret_cast<sockaddr *>(&in4);
159     result.ai_next = nullptr;
160 
161     return result;
162   }
163   std::string m_resulting_bind_address;
164 
165   std::shared_ptr<Mock_socket> m_mock_socket;
166   std::shared_ptr<Mock_socket> m_mock_socket_invalid;
167   std::shared_ptr<Mock_system> m_mock_system;
168   StrictMock<Mock_socket_events> m_mock_socket_events;
169   std::shared_ptr<Mock_factory> m_mock_factory;
170 
171   std::shared_ptr<Listener_tcp> sut;
172 };
173 
TEST_F(Listener_tcp_testsuite,setup_listener_does_nothing_when_resolve_failes)174 TEST_F(Listener_tcp_testsuite,
175        setup_listener_does_nothing_when_resolve_failes) {
176   make_sut(ADDRESS);
177 
178   EXPECT_CALL(*m_mock_system,
179               getaddrinfo(StrEq(ADDRESS), StrEq(PORT_STRING), _, _))
180       .WillOnce(Return(POSIX_FAILURE));
181 
182   ASSERT_FALSE(sut->setup_listener(nullptr));
183   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
184 }
185 
TEST_F(Listener_tcp_testsuite,setup_listener_does_resolved_IP6_and_IP4_localhost_when_asterisk_and_IP6_supported)186 TEST_F(
187     Listener_tcp_testsuite,
188     setup_listener_does_resolved_IP6_and_IP4_localhost_when_asterisk_and_IP6_supported) {  // NOLINT(whitespace/line_length)
189   make_sut("*");
190 
191   EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillOnce(Return(SOCKET_OK));
192   EXPECT_CALL(*m_mock_factory,
193               create_socket(static_cast<PSI_socket_key>(PSI_NOT_INSTRUMENTED),
194                             AF_INET6, SOCK_STREAM, 0))
195       .WillOnce(Return(m_mock_socket));
196 
197   EXPECT_CALL(*m_mock_system,
198               getaddrinfo(StrEq(ALL_INTERFACES_6), StrEq(PORT_STRING), _, _))
199       .WillOnce(Return(POSIX_FAILURE));
200 
201   EXPECT_CALL(*m_mock_system,
202               getaddrinfo(StrEq(ALL_INTERFACES_4), StrEq(PORT_STRING), _, _))
203       .WillOnce(Return(POSIX_FAILURE));
204 
205   ASSERT_FALSE(sut->setup_listener(nullptr));
206   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
207 }
208 
TEST_F(Listener_tcp_testsuite,setup_listener_does_resolved_IP4_localhost_when_asterisk_and_IP6_not_supported)209 TEST_F(
210     Listener_tcp_testsuite,
211     setup_listener_does_resolved_IP4_localhost_when_asterisk_and_IP6_not_supported) {  // NOLINT(whitespace/line_length)
212   make_sut("*");
213 
214   EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillOnce(Return(INVALID_SOCKET));
215   EXPECT_CALL(*m_mock_factory,
216               create_socket(static_cast<PSI_socket_key>(PSI_NOT_INSTRUMENTED),
217                             AF_INET6, SOCK_STREAM, 0))
218       .WillOnce(Return(m_mock_socket));
219 
220   EXPECT_CALL(*m_mock_system,
221               getaddrinfo(StrEq(ALL_INTERFACES_4), StrEq(PORT_STRING), _, _))
222       .WillOnce(Return(POSIX_FAILURE));
223 
224   ASSERT_FALSE(sut->setup_listener(nullptr));
225   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
226 }
227 
228 struct TimeOutAndExpectedRetries {
TimeOutAndExpectedRetriesxpl::test::TimeOutAndExpectedRetries229   TimeOutAndExpectedRetries(const uint32_t timeout,
230                             const uint32_t expected_retries)
231       : m_timeout(timeout), m_expected_retries(expected_retries) {}
232 
233   uint32_t m_timeout;
234   uint32_t m_expected_retries;
235 };
236 
237 class Listener_tcp_retry_testsuite
238     : public Listener_tcp_testsuite,
239       public WithParamInterface<TimeOutAndExpectedRetries> {};
240 
TEST_P(Listener_tcp_retry_testsuite,setup_listener_retry_socket_allocation_when_it_is_in_use)241 TEST_P(Listener_tcp_retry_testsuite,
242        setup_listener_retry_socket_allocation_when_it_is_in_use) {
243   addrinfo ai = get_ai_ipv6();
244 
245   make_sut(ALL_INTERFACES_6, PORT, GetParam().m_timeout);
246 
247   EXPECT_CALL(*m_mock_system,
248               getaddrinfo(StrEq(ALL_INTERFACES_6), StrEq(PORT_STRING), _, _))
249       .WillOnce(DoAll(SetArgPointee<3>(&ai), Return(POSIX_OK)));
250 
251   const int n = GetParam().m_expected_retries;
252 
253   ON_CALL(*m_mock_system, get_socket_error_and_message(_, _))
254       .WillByDefault(DoAll(SetArgPointee<0>(0), SetArgPointee<1>("")));
255 
256   EXPECT_CALL(*m_mock_socket, get_socket_fd())
257       .Times(n)
258       .WillRepeatedly(Return(INVALID_SOCKET));
259   EXPECT_CALL(*m_mock_factory,
260               create_socket(KEY_socket_x_tcpip, AF_INET6, SOCK_STREAM, 0))
261       .Times(n)
262       .WillRepeatedly(Return(m_mock_socket));
263   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_, _)).Times(n);
264   EXPECT_CALL(*m_mock_system, get_socket_errno())
265       .Times(n)
266       .WillRepeatedly(Return(SOCKET_EADDRINUSE));
267   EXPECT_CALL(*m_mock_system, sleep(Gt(0u))).Times(n);
268 
269   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
270 
271   ASSERT_FALSE(sut->setup_listener(nullptr));
272   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
273 }
274 
275 INSTANTIATE_TEST_CASE_P(
276     Instantiation_tcp_retry_when_already_in_use, Listener_tcp_retry_testsuite,
277     Values(TimeOutAndExpectedRetries(0, 1), TimeOutAndExpectedRetries(1, 2),
278            TimeOutAndExpectedRetries(5, 3), TimeOutAndExpectedRetries(6, 3),
279            TimeOutAndExpectedRetries(7, 4),
280            TimeOutAndExpectedRetries(PORT_TIMEOUT, 10)));  // 123, 10
281 
TEST_F(Listener_tcp_testsuite,setup_listener_bind_failure)282 TEST_F(Listener_tcp_testsuite, setup_listener_bind_failure) {
283   addrinfo ai = get_ai_ipv6();
284 
285   expect_create_socket(ai, ALL_INTERFACES_6, AF_INET6, SOCKET_OK);
286 
287   EXPECT_CALL(*m_mock_socket,
288               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
289       .WillOnce(Return(POSIX_OK));
290   EXPECT_CALL(*m_mock_socket, set_socket_thread_owner());
291 
292   EXPECT_CALL(*m_mock_socket, bind(ai.ai_addr, ai.ai_addrlen))
293       .WillOnce(Return(POSIX_FAILURE));
294   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_, _));
295   EXPECT_CALL(*m_mock_system, get_socket_errno())
296       .WillRepeatedly(Return(SOCKET_ETIMEDOUT));
297 
298   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
299 
300   ASSERT_FALSE(sut->setup_listener(nullptr));
301   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
302 }
303 
TEST_F(Listener_tcp_testsuite,setup_listener_listen_failure)304 TEST_F(Listener_tcp_testsuite, setup_listener_listen_failure) {
305   addrinfo ai = get_ai_ipv6();
306 
307   expect_create_socket(ai, ALL_INTERFACES_6, AF_INET6, SOCKET_OK);
308 
309   EXPECT_CALL(*m_mock_socket,
310               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _,
311                              static_cast<socklen_t>(sizeof(int))))
312       .WillOnce(Return(POSIX_OK));
313   EXPECT_CALL(*m_mock_socket, set_socket_thread_owner());
314   EXPECT_CALL(*m_mock_socket, bind(ai.ai_addr, ai.ai_addrlen))
315       .WillOnce(Return(POSIX_OK));
316 
317   EXPECT_CALL(*m_mock_socket, listen(BACKLOG)).WillOnce(Return(POSIX_FAILURE));
318   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_, _));
319   EXPECT_CALL(*m_mock_system, get_socket_errno())
320       .WillRepeatedly(Return(SOCKET_ETIMEDOUT));
321 
322   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
323 
324   ASSERT_FALSE(sut->setup_listener(nullptr));
325   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
326 }
327 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv6_success)328 TEST_F(Listener_tcp_testsuite, setup_listener_ipv6_success) {
329   addrinfo ai = get_ai_ipv6();
330 
331   expect_create_socket(ai, ALL_INTERFACES_6, AF_INET6, SOCKET_OK);
332 
333   EXPECT_CALL(*m_mock_socket,
334               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
335       .WillOnce(Return(POSIX_OK));
336 
337   expect_listen_socket(m_mock_socket, ai);
338 
339   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
340 
341   ASSERT_TRUE(sut->setup_listener(nullptr));
342   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
343 
344   // SUT destructor
345   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
346   EXPECT_CALL(*m_mock_socket, close());
347 }
348 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_success)349 TEST_F(Listener_tcp_testsuite, setup_listener_ipv4_success) {
350   addrinfo ai = get_ai_ipv4();
351 
352   expect_create_socket(ai, ALL_INTERFACES_4, AF_INET, SOCKET_OK);
353 
354   EXPECT_CALL(*m_mock_socket,
355               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
356       .WillOnce(Return(POSIX_OK));
357 
358   expect_listen_socket(m_mock_socket, ai);
359 
360   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
361 
362   ASSERT_TRUE(sut->setup_listener(nullptr));
363   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
364 
365   // SUT destructor
366   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
367   EXPECT_CALL(*m_mock_socket, close());
368 }
369 
TEST_F(Listener_tcp_testsuite,setup_listener_failure_when_socket_event_registry_failed)370 TEST_F(Listener_tcp_testsuite,
371        setup_listener_failure_when_socket_event_registry_failed) {
372   addrinfo ai = get_ai_ipv4();
373 
374   expect_create_socket(ai, ALL_INTERFACES_4, AF_INET, SOCKET_OK);
375 
376   EXPECT_CALL(*m_mock_socket,
377               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
378       .WillOnce(Return(POSIX_OK));
379 
380   const bool socket_event_listen_failed = false;
381   expect_listen_socket(m_mock_socket, ai, socket_event_listen_failed);
382 
383   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
384 
385   ASSERT_FALSE(sut->setup_listener(nullptr));
386   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_stopped));
387 
388   // SUT destructor
389   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
390 }
391 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip4)392 TEST_F(Listener_tcp_testsuite,
393        setup_listener_ipv4_and_ip6_addresses_successful_is_ip4) {
394   addrinfo ai4 = get_ai_ipv4();
395   addrinfo ai6 = get_ai_ipv6();
396 
397   ai4.ai_next = &ai6;
398 
399   expect_create_socket(ai4, ALL_INTERFACES_4, AF_INET, SOCKET_OK);
400 
401   EXPECT_CALL(*m_mock_socket,
402               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
403       .WillOnce(Return(POSIX_OK));
404 
405   expect_listen_socket(m_mock_socket, ai4);
406 
407   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
408 
409   ASSERT_TRUE(sut->setup_listener(nullptr));
410   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
411 
412   // SUT destructor
413   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
414   EXPECT_CALL(*m_mock_socket, close());
415 }
416 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip4_beacause_it_is_always_first_to_try)417 TEST_F(
418     Listener_tcp_testsuite,
419     setup_listener_ipv4_and_ip6_addresses_successful_is_ip4_beacause_it_is_always_first_to_try) {  // NOLINT(whitespace/line_length)
420   addrinfo ai4 = get_ai_ipv4();
421   addrinfo ai6 = get_ai_ipv6();
422 
423   ai4.ai_next = &ai6;
424 
425   expect_create_socket(ai4, ALL_INTERFACES_6, AF_INET, SOCKET_OK);
426 
427   EXPECT_CALL(*m_mock_socket,
428               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
429       .WillOnce(Return(POSIX_OK));
430 
431   expect_listen_socket(m_mock_socket, ai4);
432 
433   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
434 
435   ASSERT_TRUE(sut->setup_listener(nullptr));
436   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
437 
438   // SUT destructor
439   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
440   EXPECT_CALL(*m_mock_socket, close());
441 }
442 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip6_at_retry)443 TEST_F(Listener_tcp_testsuite,
444        setup_listener_ipv4_and_ip6_addresses_successful_is_ip6_at_retry) {
445   addrinfo ai4 = get_ai_ipv4();
446   addrinfo ai6 = get_ai_ipv6();
447 
448   ai4.ai_next = &ai6;
449 
450   expect_create_socket(ai4, ALL_INTERFACES_6, AF_INET, INVALID_SOCKET);
451 
452   std::shared_ptr<Mock_socket> mock_socket_ipv6(new StrictMock<Mock_socket>());
453   EXPECT_CALL(*mock_socket_ipv6, get_socket_fd()).WillOnce(Return(SOCKET_OK));
454   EXPECT_CALL(*m_mock_factory,
455               create_socket(KEY_socket_x_tcpip, AF_INET6, SOCK_STREAM, 0))
456       .WillOnce(Return(mock_socket_ipv6));
457 
458 #ifdef IPV6_V6ONLY
459   EXPECT_CALL(*mock_socket_ipv6,
460               set_socket_opt(IPPROTO_IPV6, IPV6_V6ONLY, _, sizeof(int)))
461       .WillRepeatedly(Return(POSIX_OK));
462 #endif
463 
464   EXPECT_CALL(*mock_socket_ipv6,
465               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
466       .WillOnce(Return(POSIX_OK));
467 
468   expect_listen_socket(mock_socket_ipv6, ai6);
469 
470   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
471 
472   ASSERT_TRUE(sut->setup_listener(nullptr));
473   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
474 
475   // SUT destructor
476   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
477   EXPECT_CALL(*mock_socket_ipv6, close());
478 }
479 
TEST_F(Listener_tcp_testsuite,setup_listener_success_evean_socket_opt_fails)480 TEST_F(Listener_tcp_testsuite, setup_listener_success_evean_socket_opt_fails) {
481   addrinfo ai = get_ai_ipv6();
482 
483   expect_create_socket(ai, ALL_INTERFACES_6, AF_INET6, SOCKET_OK);
484 
485   EXPECT_CALL(*m_mock_socket,
486               set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
487       .WillOnce(Return(POSIX_FAILURE));
488   EXPECT_CALL(*m_mock_system, get_socket_errno());
489 
490   expect_listen_socket(m_mock_socket, ai);
491 
492   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
493 
494   ASSERT_TRUE(sut->setup_listener(nullptr));
495   ASSERT_TRUE(sut->get_state().is(iface::Listener::State::k_prepared));
496 
497   // SUT destructor
498   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
499   EXPECT_CALL(*m_mock_socket, close());
500 }
501 
TEST_F(Listener_tcp_testsuite,close_listener_does_nothing_when_socket_not_started)502 TEST_F(Listener_tcp_testsuite,
503        close_listener_does_nothing_when_socket_not_started) {
504   make_sut(ALL_INTERFACES_6);
505 
506   sut->close_listener();
507 
508   // After stopping, start must not work !
509   sut->setup_listener(nullptr);
510 }
511 
TEST_F(Listener_tcp_testsuite,loop_does_nothing_always)512 TEST_F(Listener_tcp_testsuite, loop_does_nothing_always) {
513   make_sut(ALL_INTERFACES_6);
514 
515   sut->loop();
516 }
517 
518 }  // namespace test
519 }  // namespace xpl
520