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