1 /*
2  * Copyright (c) 2016, 2021, Oracle and/or its affiliates.
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
23  * 02110-1301  USA
24  */
25 
26 #include <gtest/gtest.h>
27 #include <gmock/gmock.h>
28 #include "mock/ngs_general.h"
29 
30 #include "io/xpl_listener_tcp.h"
31 
32 
33 namespace xpl {
34 
35 namespace tests {
36 
37 using namespace ::testing;
38 
39 const std::string ADDRESS = "0.1.2.3";
40 const std::string ALL_INTERFACES_4 = "0.0.0.0";
41 const std::string ALL_INTERFACES_6 = "::";
42 const uint16 PORT = 3030;
43 const std::string PORT_STRING = "3030";
44 const uint32 PORT_TIMEOUT = 123;
45 const uint32 BACKLOG = 122;
46 const my_socket SOCKET_OK = 10;
47 const int POSIX_OK = 0;
48 const int POSIX_FAILURE = -1;
49 
50 MATCHER(EqInvalidSocket, "") {
51   return INVALID_SOCKET == mysql_socket_getfd(arg);
52 }
53 
54 MATCHER_P(EqCastToCStr, expected, "") {
55   std::string force_string = expected;
56   return force_string == (char*)arg;
57 }
58 
59 
60 class Listener_tcp_testsuite : public Test {
61 public:
SetUp()62   void SetUp() {
63     KEY_socket_x_tcpip = 1;
64 
65     m_mock_factory = ngs::make_shared<StrictMock<ngs::test::Mock_factory> >();
66     m_mock_socket = ngs::make_shared<StrictMock<ngs::test::Mock_socket> >();
67     m_mock_system = ngs::make_shared<StrictMock<ngs::test::Mock_system> >();
68     m_mock_socket_invalid = ngs::make_shared<StrictMock<ngs::test::Mock_socket> >();
69 
70     ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
71   }
72 
assert_verify_and_reinitailize_rules()73   void assert_verify_and_reinitailize_rules() {
74     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_factory.get()));
75     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_socket_invalid.get()));
76     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_socket.get()));
77     ASSERT_TRUE(Mock::VerifyAndClearExpectations(m_mock_system.get()));
78 
79     EXPECT_CALL(*m_mock_factory, create_system_interface()).WillRepeatedly(Return(m_mock_system));
80     EXPECT_CALL(*m_mock_factory, create_socket(EqInvalidSocket())).WillRepeatedly(Return(m_mock_socket_invalid));
81     EXPECT_CALL(*m_mock_socket_invalid, get_socket_fd()).WillRepeatedly(Return(INVALID_SOCKET));
82     EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillRepeatedly(Return(SOCKET_OK));
83   }
84 
make_sut(const std::string & interface,const uint32 port=PORT,const uint32 port_timeout=PORT_TIMEOUT)85   void make_sut(const std::string &interface, const uint32 port = PORT, const uint32 port_timeout = PORT_TIMEOUT) {
86     m_resulting_bind_address = interface;
87     sut = ngs::make_shared<Listener_tcp>(
88         m_mock_factory,
89         ngs::ref(m_resulting_bind_address),
90         port,
91         port_timeout,
92         ngs::ref(m_mock_socket_events),
93         BACKLOG);
94   }
95 
expect_create_socket(addrinfo & ai,const std::string & interface,const int family,const int result=SOCKET_OK)96   void expect_create_socket(
97       addrinfo &ai,
98       const std::string &interface,
99       const int family,
100       const int result = SOCKET_OK) {
101 
102     make_sut(interface,
103              PORT,
104              PORT_TIMEOUT);
105 
106     EXPECT_CALL(*m_mock_system, getaddrinfo(
107         StrEq(interface),
108         StrEq(PORT_STRING),
109         _,
110         _)).WillOnce(DoAll(SetArgPointee<3>(&ai),Return(POSIX_OK)));
111 
112     EXPECT_CALL(*m_mock_socket, get_socket_fd())
113       .WillOnce(Return(result));
114     EXPECT_CALL(*m_mock_factory, create_socket(KEY_socket_x_tcpip, family, SOCK_STREAM, 0))
115       .WillOnce(Return(m_mock_socket));
116 
117     #ifdef IPV6_V6ONLY
118     EXPECT_CALL(*m_mock_socket, set_socket_opt(IPPROTO_IPV6, IPV6_V6ONLY, _, sizeof(int)))
119       .WillRepeatedly(Return(POSIX_OK));
120     #endif
121   }
122 
expect_listen_socket(ngs::shared_ptr<ngs::test::Mock_socket> mock_socket,addrinfo & ai,const bool socket_events_listen=true)123   void expect_listen_socket(
124       ngs::shared_ptr<ngs::test::Mock_socket> mock_socket,
125       addrinfo &ai,
126       const bool socket_events_listen = true) {
127     EXPECT_CALL(*mock_socket, set_socket_thread_owner());
128     EXPECT_CALL(*mock_socket, bind(ai.ai_addr, ai.ai_addrlen))
129       .WillOnce(Return(POSIX_OK));
130     EXPECT_CALL(*mock_socket, listen(BACKLOG))
131       .WillOnce(Return(POSIX_OK));
132     ngs::Socket_interface::Shared_ptr socket_ptr = mock_socket;
133     EXPECT_CALL(m_mock_socket_events, listen(socket_ptr, _))
134       .WillOnce(Return(socket_events_listen));
135   }
136 
137 
get_ai_ipv6()138   struct addrinfo get_ai_ipv6()
139   {
140     struct addrinfo result;
141     static struct sockaddr_in6 in6;
142 
143     in6.sin6_family = result.ai_family = AF_INET6;
144     result.ai_socktype = 0;
145     result.ai_protocol = 0;
146     result.ai_addrlen = sizeof(in6);
147     result.ai_addr = (sockaddr*)&in6;
148     result.ai_next = NULL;
149 
150     return result;
151   }
152 
get_ai_ipv4()153   struct addrinfo get_ai_ipv4()
154   {
155     struct addrinfo result;
156     static struct sockaddr_in in4;
157 
158     in4.sin_family = result.ai_family = AF_INET;
159     result.ai_socktype = 0;
160     result.ai_protocol = 0;
161     result.ai_addrlen = sizeof(in4);
162     result.ai_addr = (sockaddr*)&in4;
163     result.ai_next = NULL;
164 
165     return result;
166   }
167   std::string m_resulting_bind_address;
168 
169   ngs::shared_ptr<ngs::test::Mock_socket> m_mock_socket;
170   ngs::shared_ptr<ngs::test::Mock_socket> m_mock_socket_invalid;
171   ngs::shared_ptr<ngs::test::Mock_system> m_mock_system;
172   StrictMock<ngs::test::Mock_socket_events> m_mock_socket_events;
173   ngs::shared_ptr<ngs::test::Mock_factory> m_mock_factory;
174 
175   ngs::shared_ptr<Listener_tcp> sut;
176 };
177 
TEST_F(Listener_tcp_testsuite,setup_listener_does_nothing_when_resolve_failes)178 TEST_F(Listener_tcp_testsuite, setup_listener_does_nothing_when_resolve_failes) {
179   make_sut(ADDRESS);
180 
181   EXPECT_CALL(*m_mock_system, getaddrinfo(
182       StrEq(ADDRESS),
183       StrEq(PORT_STRING),
184       _,
185       _)).WillOnce(Return(POSIX_FAILURE));
186 
187   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
188   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
189 }
190 
TEST_F(Listener_tcp_testsuite,setup_listener_does_resolved_IP6_and_IP4_localhost_when_asterisk_and_IP6_supported)191 TEST_F(Listener_tcp_testsuite, setup_listener_does_resolved_IP6_and_IP4_localhost_when_asterisk_and_IP6_supported) {
192   make_sut("*");
193 
194   EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillOnce(Return(SOCKET_OK));
195   EXPECT_CALL(*m_mock_factory, create_socket(PSI_NOT_INSTRUMENTED, AF_INET6, SOCK_STREAM, 0))
196     .WillOnce(Return(m_mock_socket));
197 
198   EXPECT_CALL(*m_mock_system, getaddrinfo(
199       StrEq(ALL_INTERFACES_6),
200       StrEq(PORT_STRING),
201       _,
202       _)).WillOnce(Return(POSIX_FAILURE));
203 
204   EXPECT_CALL(*m_mock_system, getaddrinfo(
205       StrEq(ALL_INTERFACES_4),
206       StrEq(PORT_STRING),
207       _,
208       _)).WillOnce(Return(POSIX_FAILURE));
209 
210   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
211   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
212 }
213 
TEST_F(Listener_tcp_testsuite,setup_listener_does_resolved_IP4_localhost_when_asterisk_and_IP6_not_supported)214 TEST_F(Listener_tcp_testsuite, setup_listener_does_resolved_IP4_localhost_when_asterisk_and_IP6_not_supported) {
215   make_sut("*");
216 
217   EXPECT_CALL(*m_mock_socket, get_socket_fd()).WillOnce(Return(INVALID_SOCKET));
218   EXPECT_CALL(*m_mock_factory, create_socket(PSI_NOT_INSTRUMENTED, AF_INET6, SOCK_STREAM, 0))
219     .WillOnce(Return(m_mock_socket));
220 
221   EXPECT_CALL(*m_mock_system, getaddrinfo(
222       StrEq(ALL_INTERFACES_4),
223       StrEq(PORT_STRING),
224       _,
225       _)).WillOnce(Return(POSIX_FAILURE));
226 
227   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
228   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
229 }
230 
231 struct TimeOutAndExpectedRetries
232 {
TimeOutAndExpectedRetriesxpl::tests::TimeOutAndExpectedRetries233   TimeOutAndExpectedRetries(const uint32 timeout, const uint32 expected_retries)
234   : m_timeout(timeout),
235     m_expected_retries(expected_retries){
236   }
237 
238   uint32 m_timeout;
239   uint32 m_expected_retries;
240 };
241 
242 class Listener_tcp_retry_testsuite: public Listener_tcp_testsuite, public WithParamInterface<TimeOutAndExpectedRetries> {};
243 
TEST_P(Listener_tcp_retry_testsuite,setup_listener_retry_socket_allocation_when_it_is_in_use)244 TEST_P(Listener_tcp_retry_testsuite, setup_listener_retry_socket_allocation_when_it_is_in_use) {
245   addrinfo ai = get_ai_ipv6();
246 
247   make_sut(ALL_INTERFACES_6, PORT, GetParam().m_timeout);
248 
249   EXPECT_CALL(*m_mock_system, getaddrinfo(
250       StrEq(ALL_INTERFACES_6),
251       StrEq(PORT_STRING),
252       _,
253       _)).WillOnce(DoAll(SetArgPointee<3>(&ai),Return(POSIX_OK)));
254 
255   const int n = GetParam().m_expected_retries;
256 
257   EXPECT_CALL(*m_mock_socket, get_socket_fd())
258     .Times(n).WillRepeatedly(Return(INVALID_SOCKET));
259   EXPECT_CALL(*m_mock_factory, create_socket(KEY_socket_x_tcpip, AF_INET6, SOCK_STREAM, 0))
260     .Times(n).WillRepeatedly(Return(m_mock_socket));
261   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_,_))
262     .Times(n);
263   EXPECT_CALL(*m_mock_system, get_socket_errno())
264     .Times(n).WillRepeatedly(Return(SOCKET_EADDRINUSE));
265   EXPECT_CALL(*m_mock_system, sleep(Gt(0)))
266     .Times(n);
267 
268   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
269 
270   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
271   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
272 }
273 
274 INSTANTIATE_TEST_CASE_P(Instantiation_tcp_retry_when_already_in_use, Listener_tcp_retry_testsuite,
275                         Values(TimeOutAndExpectedRetries(0, 1),
276                                TimeOutAndExpectedRetries(1, 2),
277                                TimeOutAndExpectedRetries(5, 3),
278                                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(
286       ai,
287       ALL_INTERFACES_6,
288       AF_INET6,
289       SOCKET_OK);
290 
291   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
292     .WillOnce(Return(POSIX_OK));
293   EXPECT_CALL(*m_mock_socket, set_socket_thread_owner());
294 
295   EXPECT_CALL(*m_mock_socket, bind(ai.ai_addr, ai.ai_addrlen))
296     .WillOnce(Return(POSIX_FAILURE));
297   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_,_));
298   EXPECT_CALL(*m_mock_system, get_socket_errno())
299     .WillRepeatedly(Return(SOCKET_ETIMEDOUT));
300 
301   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
302 
303   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
304   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
305 }
306 
TEST_F(Listener_tcp_testsuite,setup_listener_listen_failure)307 TEST_F(Listener_tcp_testsuite, setup_listener_listen_failure) {
308   addrinfo ai = get_ai_ipv6();
309 
310   expect_create_socket(
311       ai,
312       ALL_INTERFACES_6,
313       AF_INET6,
314       SOCKET_OK);
315 
316   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
317     .WillOnce(Return(POSIX_OK));
318   EXPECT_CALL(*m_mock_socket, set_socket_thread_owner());
319   EXPECT_CALL(*m_mock_socket, bind(ai.ai_addr, ai.ai_addrlen))
320     .WillOnce(Return(POSIX_OK));
321 
322   EXPECT_CALL(*m_mock_socket, listen(BACKLOG))
323     .WillOnce(Return(POSIX_FAILURE));
324   EXPECT_CALL(*m_mock_system, get_socket_error_and_message(_,_));
325   EXPECT_CALL(*m_mock_system, get_socket_errno())
326     .WillRepeatedly(Return(SOCKET_ETIMEDOUT));
327 
328   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
329 
330   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
331   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
332 }
333 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv6_success)334 TEST_F(Listener_tcp_testsuite, setup_listener_ipv6_success) {
335   addrinfo ai = get_ai_ipv6();
336 
337   expect_create_socket(
338       ai,
339       ALL_INTERFACES_6,
340       AF_INET6,
341       SOCKET_OK);
342 
343   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
344     .WillOnce(Return(POSIX_OK));
345 
346   expect_listen_socket(m_mock_socket, ai);
347 
348   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
349 
350   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
351   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
352 
353   // SUT destructor
354   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
355   EXPECT_CALL(*m_mock_socket, close());
356 }
357 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_success)358 TEST_F(Listener_tcp_testsuite, setup_listener_ipv4_success) {
359   addrinfo ai = get_ai_ipv4();
360 
361   expect_create_socket(
362       ai,
363       ALL_INTERFACES_4,
364       AF_INET,
365       SOCKET_OK);
366 
367   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
368     .WillOnce(Return(POSIX_OK));
369 
370   expect_listen_socket(m_mock_socket, ai);
371 
372   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
373 
374   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
375   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
376 
377   // SUT destructor
378   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
379   EXPECT_CALL(*m_mock_socket, close());
380 }
381 
TEST_F(Listener_tcp_testsuite,setup_listener_failure_when_socket_event_registry_failed)382 TEST_F(Listener_tcp_testsuite, setup_listener_failure_when_socket_event_registry_failed) {
383   addrinfo ai = get_ai_ipv4();
384 
385   expect_create_socket(
386       ai,
387       ALL_INTERFACES_4,
388       AF_INET,
389       SOCKET_OK);
390 
391   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
392     .WillOnce(Return(POSIX_OK));
393 
394   const bool socket_event_listen_failed = false;
395   expect_listen_socket(m_mock_socket, ai, socket_event_listen_failed);
396 
397   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
398 
399   ASSERT_FALSE(sut->setup_listener(ngs::Listener_interface::On_connection()));
400   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_initializing));
401 
402   // SUT destructor
403   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
404 }
405 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip4)406 TEST_F(Listener_tcp_testsuite, setup_listener_ipv4_and_ip6_addresses_successful_is_ip4) {
407   addrinfo ai4 = get_ai_ipv4();
408   addrinfo ai6 = get_ai_ipv6();
409 
410   ai4.ai_next = &ai6;
411 
412   expect_create_socket(
413       ai4,
414       ALL_INTERFACES_4,
415       AF_INET,
416       SOCKET_OK);
417 
418   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
419     .WillOnce(Return(POSIX_OK));
420 
421   expect_listen_socket(m_mock_socket, ai4);
422 
423   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
424 
425   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
426   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
427 
428   // SUT destructor
429   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
430   EXPECT_CALL(*m_mock_socket, close());
431 }
432 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip4_beacause_it_is_always_first_to_try)433 TEST_F(Listener_tcp_testsuite, setup_listener_ipv4_and_ip6_addresses_successful_is_ip4_beacause_it_is_always_first_to_try) {
434   addrinfo ai4 = get_ai_ipv4();
435   addrinfo ai6 = get_ai_ipv6();
436 
437   ai4.ai_next = &ai6;
438 
439   expect_create_socket(
440       ai4,
441       ALL_INTERFACES_6,
442       AF_INET,
443       SOCKET_OK);
444 
445   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
446     .WillOnce(Return(POSIX_OK));
447 
448   expect_listen_socket(m_mock_socket, ai4);
449 
450   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
451 
452   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
453   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
454 
455   // SUT destructor
456   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
457   EXPECT_CALL(*m_mock_socket, close());
458 }
459 
TEST_F(Listener_tcp_testsuite,setup_listener_ipv4_and_ip6_addresses_successful_is_ip6_at_retry)460 TEST_F(Listener_tcp_testsuite, setup_listener_ipv4_and_ip6_addresses_successful_is_ip6_at_retry) {
461   addrinfo ai4 = get_ai_ipv4();
462   addrinfo ai6 = get_ai_ipv6();
463 
464   ai4.ai_next = &ai6;
465 
466   expect_create_socket(
467       ai4,
468       ALL_INTERFACES_6,
469       AF_INET,
470       INVALID_SOCKET);
471 
472   ngs::shared_ptr<ngs::test::Mock_socket> mock_socket_ipv6(
473       new StrictMock<ngs::test::Mock_socket>());
474   EXPECT_CALL(*mock_socket_ipv6, get_socket_fd())
475     .WillOnce(Return(SOCKET_OK));
476   EXPECT_CALL(*m_mock_factory, create_socket(KEY_socket_x_tcpip, AF_INET6, SOCK_STREAM, 0))
477     .WillOnce(Return(mock_socket_ipv6));
478 
479   #ifdef IPV6_V6ONLY
480   EXPECT_CALL(*mock_socket_ipv6, set_socket_opt(IPPROTO_IPV6, IPV6_V6ONLY, _, sizeof(int)))
481     .WillRepeatedly(Return(POSIX_OK));
482   #endif
483 
484   EXPECT_CALL(*mock_socket_ipv6, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
485     .WillOnce(Return(POSIX_OK));
486 
487   expect_listen_socket(mock_socket_ipv6, ai6);
488 
489   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai4));
490 
491   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
492   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
493 
494   // SUT destructor
495   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
496   EXPECT_CALL(*mock_socket_ipv6, close());
497 }
498 
TEST_F(Listener_tcp_testsuite,setup_listener_success_evean_socket_opt_fails)499 TEST_F(Listener_tcp_testsuite, setup_listener_success_evean_socket_opt_fails) {
500   addrinfo ai = get_ai_ipv6();
501 
502   expect_create_socket(
503       ai,
504       ALL_INTERFACES_6,
505       AF_INET6,
506       SOCKET_OK);
507 
508   EXPECT_CALL(*m_mock_socket, set_socket_opt(SOL_SOCKET, SO_REUSEADDR, _, sizeof(int)))
509     .WillOnce(Return(POSIX_FAILURE));
510   EXPECT_CALL(*m_mock_system, get_socket_errno());
511 
512   expect_listen_socket(m_mock_socket, ai);
513 
514   EXPECT_CALL(*m_mock_system, freeaddrinfo(&ai));
515 
516   ASSERT_TRUE(sut->setup_listener(ngs::Listener_interface::On_connection()));
517   ASSERT_TRUE(sut->get_state().is(ngs::State_listener_prepared));
518 
519   // SUT destructor
520   ASSERT_NO_FATAL_FAILURE(assert_verify_and_reinitailize_rules());
521   EXPECT_CALL(*m_mock_socket, close());
522 }
523 
TEST_F(Listener_tcp_testsuite,is_handled_by_socket_event_always_true)524 TEST_F(Listener_tcp_testsuite, is_handled_by_socket_event_always_true) {
525   make_sut(ALL_INTERFACES_6);
526 
527   ASSERT_TRUE(sut->is_handled_by_socket_event());
528 }
529 
TEST_F(Listener_tcp_testsuite,get_name_and_configuration)530 TEST_F(Listener_tcp_testsuite, get_name_and_configuration) {
531   make_sut(ALL_INTERFACES_6, 2222);
532 
533   ASSERT_STREQ("TCP (bind-address:'::', port:2222)", sut->get_name_and_configuration().c_str());
534 }
535 
TEST_F(Listener_tcp_testsuite,close_listener_does_nothing_when_socket_not_started)536 TEST_F(Listener_tcp_testsuite, close_listener_does_nothing_when_socket_not_started) {
537   make_sut(ALL_INTERFACES_6);
538 
539   sut->close_listener();
540 
541   //After stopping, start must not work !
542   sut->setup_listener(ngs::Listener_interface::On_connection());
543 }
544 
TEST_F(Listener_tcp_testsuite,loop_does_nothing_always)545 TEST_F(Listener_tcp_testsuite, loop_does_nothing_always) {
546   make_sut(ALL_INTERFACES_6);
547 
548   sut->loop();
549 }
550 
551 } // namespace tests
552 
553 } // namespace xpl
554