1 //
2 // Copyright (C) 2013 The Android Open Source Project
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 #include "shill/connection_health_checker.h"
18
19 #include <arpa/inet.h>
20
21 #include <memory>
22 #include <string>
23 #include <vector>
24
25 #include <base/bind.h>
26 #include <base/callback.h>
27 #include <base/cancelable_callback.h>
28 #include <base/memory/scoped_vector.h>
29 #include <gtest/gtest.h>
30
31 #include "shill/mock_async_connection.h"
32 #include "shill/mock_connection.h"
33 #include "shill/mock_control.h"
34 #include "shill/mock_device_info.h"
35 #include "shill/mock_dns_client.h"
36 #include "shill/mock_dns_client_factory.h"
37 #include "shill/mock_ip_address_store.h"
38 #include "shill/mock_socket_info_reader.h"
39 #include "shill/net/mock_sockets.h"
40 #include "shill/test_event_dispatcher.h"
41
42 using base::Bind;
43 using base::Callback;
44 using base::Closure;
45 using base::Unretained;
46 using std::string;
47 using std::vector;
48 using ::testing::AtLeast;
49 using ::testing::DoAll;
50 using ::testing::Gt;
51 using ::testing::Invoke;
52 using ::testing::Mock;
53 using ::testing::NiceMock;
54 using ::testing::Return;
55 using ::testing::ReturnRef;
56 using ::testing::SaveArg;
57 using ::testing::Sequence;
58 using ::testing::SetArgumentPointee;
59 using ::testing::StrictMock;
60 using ::testing::Test;
61 using ::testing::_;
62
63 namespace shill {
64
65 namespace {
66 const char kInterfaceName[] = "int0";
67 const char kIPAddress_8_8_8_8[] = "8.8.8.8";
68 const char kProxyIPAddressRemote[] = "74.125.224.84";
69 const char kProxyIPAddressLocal[] = "192.23.34.1";
70 const char kProxyIPv6AddressLocal[] = "::ffff:192.23.34.1";
71 const char kProxyURLRemote[] = "http://www.google.com";
72 const int kProxyFD = 100;
73 const int16_t kProxyPortLocal = 5540;
74 const int16_t kProxyPortRemote = 80;
75 } // namespace
76
77 MATCHER_P(IsSameIPAddress, ip_addr, "") {
78 return arg.Equals(ip_addr);
79 }
80
81 class ConnectionHealthCheckerTest : public Test {
82 public:
ConnectionHealthCheckerTest()83 ConnectionHealthCheckerTest()
84 : interface_name_(kInterfaceName),
85 device_info_(&control_, &dispatcher_, nullptr, nullptr),
86 connection_(new NiceMock<MockConnection>(&device_info_)),
87 socket_(nullptr) {}
88
89 // Invokes
GetSockName(int fd,struct sockaddr * addr_out,socklen_t * sockaddr_size)90 int GetSockName(int fd, struct sockaddr* addr_out, socklen_t* sockaddr_size) {
91 struct sockaddr_in addr;
92 EXPECT_EQ(kProxyFD, fd);
93 EXPECT_LE(sizeof(sockaddr_in), *sockaddr_size);
94 addr.sin_family = AF_INET;
95 inet_pton(AF_INET, kProxyIPAddressLocal, &addr.sin_addr);
96 addr.sin_port = htons(kProxyPortLocal);
97 memcpy(addr_out, &addr, sizeof(addr));
98 *sockaddr_size = sizeof(sockaddr_in);
99 return 0;
100 }
101
GetSockNameReturnsIPv6(int fd,struct sockaddr * addr_out,socklen_t * sockaddr_size)102 int GetSockNameReturnsIPv6(int fd, struct sockaddr* addr_out,
103 socklen_t* sockaddr_size) {
104 struct sockaddr_in6 addr;
105 EXPECT_EQ(kProxyFD, fd);
106 EXPECT_LE(sizeof(sockaddr_in6), *sockaddr_size);
107 addr.sin6_family = AF_INET6;
108 inet_pton(AF_INET6, kProxyIPv6AddressLocal, &addr.sin6_addr);
109 addr.sin6_port = htons(kProxyPortLocal);
110 memcpy(addr_out, &addr, sizeof(addr));
111 *sockaddr_size = sizeof(sockaddr_in6);
112 return 0;
113 }
114
InvokeOnConnectionComplete(bool success,int sock_fd)115 void InvokeOnConnectionComplete(bool success, int sock_fd) {
116 health_checker_->OnConnectionComplete(success, sock_fd);
117 }
118
InvokeGetDNSResultFailure()119 void InvokeGetDNSResultFailure() {
120 Error error(Error::kOperationFailed, "");
121 IPAddress address(IPAddress::kFamilyUnknown);
122 health_checker_->GetDNSResult(error, address);
123 }
124
InvokeGetDNSResultSuccess(const IPAddress & address)125 void InvokeGetDNSResultSuccess(const IPAddress& address) {
126 Error error;
127 health_checker_->GetDNSResult(error, address);
128 }
129
130 protected:
SetUp()131 void SetUp() {
132 EXPECT_CALL(*connection_.get(), interface_name())
133 .WillRepeatedly(ReturnRef(interface_name_));
134 ON_CALL(*connection_.get(), dns_servers())
135 .WillByDefault(ReturnRef(dns_servers_));
136 // ConnectionHealthChecker constructor should add some IPs
137 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(AtLeast(1));
138 health_checker_.reset(
139 new ConnectionHealthChecker(
140 connection_,
141 &dispatcher_,
142 &remote_ips_,
143 Bind(&ConnectionHealthCheckerTest::ResultCallbackTarget,
144 Unretained(this))));
145 Mock::VerifyAndClearExpectations(&remote_ips_);
146 socket_ = new StrictMock<MockSockets>();
147 tcp_connection_ = new StrictMock<MockAsyncConnection>();
148 socket_info_reader_ = new StrictMock<MockSocketInfoReader>();
149 // Passes ownership for all of these.
150 health_checker_->socket_.reset(socket_);
151 health_checker_->tcp_connection_.reset(tcp_connection_);
152 health_checker_->socket_info_reader_.reset(socket_info_reader_);
153 health_checker_->dns_client_factory_ = MockDNSClientFactory::GetInstance();
154 }
155
TearDown()156 void TearDown() {
157 ExpectStop();
158 }
159
160 // Accessors for private data in ConnectionHealthChecker.
socket()161 const Sockets* socket() {
162 return health_checker_->socket_.get();
163 }
tcp_connection()164 const AsyncConnection* tcp_connection() {
165 return health_checker_->tcp_connection_.get();
166 }
dns_clients()167 ScopedVector<DNSClient>& dns_clients() {
168 return health_checker_->dns_clients_;
169 }
NumDNSQueries()170 int NumDNSQueries() {
171 return ConnectionHealthChecker::kNumDNSQueries;
172 }
MaxFailedConnectionAttempts()173 int MaxFailedConnectionAttempts() {
174 return ConnectionHealthChecker::kMaxFailedConnectionAttempts;
175 }
MaxSentDataPollingAttempts()176 int MaxSentDataPollingAttempts() {
177 return ConnectionHealthChecker::kMaxSentDataPollingAttempts;
178 }
MinCongestedQueueAttempts()179 int MinCongestedQueueAttempts() {
180 return ConnectionHealthChecker::kMinCongestedQueueAttempts;
181 }
MinSuccessfulSendAttempts()182 int MinSuccessfulSendAttempts() {
183 return ConnectionHealthChecker::kMinSuccessfulSendAttempts;
184 }
SetTCPStateUpdateWaitMilliseconds(int new_wait)185 void SetTCPStateUpdateWaitMilliseconds(int new_wait) {
186 health_checker_->tcp_state_update_wait_milliseconds_ = new_wait;
187 }
188
189 // Mock Callbacks
190 MOCK_METHOD1(ResultCallbackTarget,
191 void(ConnectionHealthChecker::Result result));
192
193 // Helper methods
StringToIPv4Address(const string & address_string)194 IPAddress StringToIPv4Address(const string& address_string) {
195 IPAddress ip_address(IPAddress::kFamilyIPv4);
196 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
197 return ip_address;
198 }
199 // Naming: CreateSocketInfo
200 // + (Proxy/Other) : TCP connection for proxy socket / some other
201 // socket.
202 // + arg1: Pass in any SocketInfo::ConnectionState you want.
203 // + arg2: Pass in any value of transmit_queue_value you want.
CreateSocketInfoOther()204 SocketInfo CreateSocketInfoOther() {
205 return SocketInfo(
206 SocketInfo::kConnectionStateUnknown,
207 StringToIPv4Address(kIPAddress_8_8_8_8),
208 0,
209 StringToIPv4Address(kProxyIPAddressRemote),
210 kProxyPortRemote,
211 0,
212 0,
213 SocketInfo::kTimerStateUnknown);
214 }
CreateSocketInfoProxy(SocketInfo::ConnectionState state)215 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state) {
216 return SocketInfo(
217 state,
218 StringToIPv4Address(kProxyIPAddressLocal),
219 kProxyPortLocal,
220 StringToIPv4Address(kProxyIPAddressRemote),
221 kProxyPortRemote,
222 0,
223 0,
224 SocketInfo::kTimerStateUnknown);
225 }
CreateSocketInfoProxy(SocketInfo::ConnectionState state,SocketInfo::TimerState timer_state,uint64_t transmit_queue_value)226 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state,
227 SocketInfo::TimerState timer_state,
228 uint64_t transmit_queue_value) {
229 return SocketInfo(
230 state,
231 StringToIPv4Address(kProxyIPAddressLocal),
232 kProxyPortLocal,
233 StringToIPv4Address(kProxyIPAddressRemote),
234 kProxyPortRemote,
235 transmit_queue_value,
236 0,
237 timer_state);
238 }
239
240
241 // Expectations
ExpectReset()242 void ExpectReset() {
243 EXPECT_EQ(connection_.get(), health_checker_->connection_.get());
244 EXPECT_EQ(&dispatcher_, health_checker_->dispatcher_);
245 EXPECT_EQ(socket_, health_checker_->socket_.get());
246 EXPECT_FALSE(socket_ == nullptr);
247 EXPECT_EQ(socket_info_reader_, health_checker_->socket_info_reader_.get());
248 EXPECT_FALSE(socket_info_reader_ == nullptr);
249 EXPECT_FALSE(health_checker_->connection_complete_callback_.is_null());
250 EXPECT_EQ(tcp_connection_, health_checker_->tcp_connection_.get());
251 EXPECT_FALSE(tcp_connection_ == nullptr);
252 EXPECT_FALSE(health_checker_->health_check_in_progress_);
253 }
254
255 // Setup ConnectionHealthChecker::GetSocketInfo to return sock_info.
256 // This only works if GetSocketInfo is called with kProxyFD.
257 // If no matching sock_info is provided (Does not belong to proxy socket),
258 // GetSocketInfo will (correctly) return false.
ExpectGetSocketInfoReturns(SocketInfo sock_info)259 void ExpectGetSocketInfoReturns(SocketInfo sock_info) {
260 vector<SocketInfo> info_list;
261 info_list.push_back(sock_info);
262 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
263 .InSequence(seq_)
264 .WillOnce(Invoke(this,
265 &ConnectionHealthCheckerTest::GetSockName));
266 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
267 .InSequence(seq_)
268 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
269 Return(true)));
270 }
ExpectSuccessfulStart()271 void ExpectSuccessfulStart() {
272 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
273 EXPECT_CALL(remote_ips_, GetRandomIP())
274 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
275 EXPECT_CALL(
276 *tcp_connection_,
277 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
278 kProxyPortRemote))
279 .InSequence(seq_)
280 .WillOnce(Return(true));
281 }
ExpectRetry()282 void ExpectRetry() {
283 EXPECT_CALL(*socket_, Close(kProxyFD))
284 .InSequence(seq_);
285 EXPECT_CALL(
286 *tcp_connection_,
287 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
288 kProxyPortRemote))
289 .InSequence(seq_)
290 .WillOnce(Return(true));
291 }
ExpectStop()292 void ExpectStop() {
293 if (tcp_connection_)
294 EXPECT_CALL(*tcp_connection_, Stop())
295 .InSequence(seq_);
296 }
ExpectCleanUp()297 void ExpectCleanUp() {
298 EXPECT_CALL(*socket_, Close(kProxyFD))
299 .InSequence(seq_);
300 EXPECT_CALL(*tcp_connection_, Stop())
301 .InSequence(seq_);
302 }
303
VerifyAndClearAllExpectations()304 void VerifyAndClearAllExpectations() {
305 Mock::VerifyAndClearExpectations(this);
306 Mock::VerifyAndClearExpectations(tcp_connection_);
307 Mock::VerifyAndClearExpectations(socket_);
308 Mock::VerifyAndClearExpectations(socket_info_reader_);
309 }
310
311 // Needed for other mocks, but not for the tests directly.
312 const string interface_name_;
313 NiceMock<MockControl> control_;
314 NiceMock<MockDeviceInfo> device_info_;
315 vector<string> dns_servers_;
316
317 scoped_refptr<NiceMock<MockConnection>> connection_;
318 EventDispatcherForTest dispatcher_;
319 MockIPAddressStore remote_ips_;
320 StrictMock<MockSockets>* socket_;
321 StrictMock<MockSocketInfoReader>* socket_info_reader_;
322 StrictMock<MockAsyncConnection>* tcp_connection_;
323 // Expectations in the Expect* functions are put in this sequence.
324 // This allows us to chain calls to Expect* functions.
325 Sequence seq_;
326
327 std::unique_ptr<ConnectionHealthChecker> health_checker_;
328 };
329
TEST_F(ConnectionHealthCheckerTest,Constructor)330 TEST_F(ConnectionHealthCheckerTest, Constructor) {
331 ExpectReset();
332 }
333
TEST_F(ConnectionHealthCheckerTest,SetConnection)334 TEST_F(ConnectionHealthCheckerTest, SetConnection) {
335 scoped_refptr<NiceMock<MockConnection>> new_connection =
336 new NiceMock<MockConnection>(&device_info_);
337 // If a health check was in progress when SetConnection is called, verify
338 // that it restarts with the new connection.
339 ExpectSuccessfulStart();
340 health_checker_->Start();
341 VerifyAndClearAllExpectations();
342
343 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(true));
344 EXPECT_CALL(*new_connection.get(), interface_name())
345 .WillRepeatedly(ReturnRef(interface_name_));
346 EXPECT_CALL(*this,
347 ResultCallbackTarget(ConnectionHealthChecker::kResultUnknown));
348 health_checker_->SetConnection(new_connection);
349 EXPECT_NE(tcp_connection_, health_checker_->tcp_connection());
350 EXPECT_EQ(new_connection.get(), health_checker_->connection());
351
352 // health_checker_ has reset tcp_connection_ to a new object.
353 // Since it owned tcp_connection_, the object has been destroyed.
354 tcp_connection_ = nullptr;
355 }
356
TEST_F(ConnectionHealthCheckerTest,GarbageCollectDNSClients)357 TEST_F(ConnectionHealthCheckerTest, GarbageCollectDNSClients) {
358 dns_clients().clear();
359 health_checker_->GarbageCollectDNSClients();
360 EXPECT_TRUE(dns_clients().empty());
361
362 for (int i = 0; i < 3; ++i) {
363 MockDNSClient* dns_client = new MockDNSClient();
364 EXPECT_CALL(*dns_client, IsActive())
365 .WillOnce(Return(true))
366 .WillOnce(Return(true))
367 .WillOnce(Return(false));
368 // Takes ownership.
369 dns_clients().push_back(dns_client);
370 }
371 for (int i = 0; i < 2; ++i) {
372 MockDNSClient* dns_client = new MockDNSClient();
373 EXPECT_CALL(*dns_client, IsActive())
374 .WillOnce(Return(false));
375 // Takes ownership.
376 dns_clients().push_back(dns_client);
377 }
378
379 EXPECT_EQ(5, dns_clients().size());
380 health_checker_->GarbageCollectDNSClients();
381 EXPECT_EQ(3, dns_clients().size());
382 health_checker_->GarbageCollectDNSClients();
383 EXPECT_EQ(3, dns_clients().size());
384 health_checker_->GarbageCollectDNSClients();
385 EXPECT_TRUE(dns_clients().empty());
386 }
387
TEST_F(ConnectionHealthCheckerTest,AddRemoteURL)388 TEST_F(ConnectionHealthCheckerTest, AddRemoteURL) {
389 HTTPURL url;
390 url.ParseFromString(kProxyURLRemote);
391 string host = url.host();
392 IPAddress remote_ip = StringToIPv4Address(kProxyIPAddressRemote);
393 IPAddress remote_ip_2 = StringToIPv4Address(kIPAddress_8_8_8_8);
394
395 MockDNSClientFactory* dns_client_factory
396 = MockDNSClientFactory::GetInstance();
397 vector<MockDNSClient*> dns_client_buffer;
398
399 // All DNS queries fail.
400 for (int i = 0; i < NumDNSQueries(); ++i) {
401 MockDNSClient* dns_client = new MockDNSClient();
402 EXPECT_CALL(*dns_client, Start(host, _))
403 .WillOnce(Return(false));
404 dns_client_buffer.push_back(dns_client);
405 }
406 // Will pass ownership of dns_clients elements.
407 for (int i = 0; i < NumDNSQueries(); ++i) {
408 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
409 .InSequence(seq_)
410 .WillOnce(Return(dns_client_buffer[i]));
411 }
412 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(0);
413 health_checker_->AddRemoteURL(kProxyURLRemote);
414 Mock::VerifyAndClearExpectations(dns_client_factory);
415 Mock::VerifyAndClearExpectations(&remote_ips_);
416 dns_client_buffer.clear();
417 dns_clients().clear();
418
419 // All but one DNS queries fail, 1 succeeds.
420 for (int i = 0; i < NumDNSQueries(); ++i) {
421 MockDNSClient* dns_client = new MockDNSClient();
422 EXPECT_CALL(*dns_client, Start(host, _))
423 .WillOnce(Return(true));
424 dns_client_buffer.push_back(dns_client);
425 }
426 // Will pass ownership of dns_clients elements.
427 for (int i = 0; i < NumDNSQueries(); ++i) {
428 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
429 .InSequence(seq_)
430 .WillOnce(Return(dns_client_buffer[i]));
431 }
432 EXPECT_CALL(remote_ips_, AddUnique(_));
433 health_checker_->AddRemoteURL(kProxyURLRemote);
434 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
435 InvokeGetDNSResultFailure();
436 }
437 InvokeGetDNSResultSuccess(remote_ip);
438 Mock::VerifyAndClearExpectations(dns_client_factory);
439 Mock::VerifyAndClearExpectations(&remote_ips_);
440 dns_client_buffer.clear();
441 dns_clients().clear();
442
443 // Only 2 distinct IP addresses are returned.
444 for (int i = 0; i < NumDNSQueries(); ++i) {
445 MockDNSClient* dns_client = new MockDNSClient();
446 EXPECT_CALL(*dns_client, Start(host, _))
447 .WillOnce(Return(true));
448 dns_client_buffer.push_back(dns_client);
449 }
450 // Will pass ownership of dns_clients elements.
451 for (int i = 0; i < NumDNSQueries(); ++i) {
452 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
453 .InSequence(seq_)
454 .WillOnce(Return(dns_client_buffer[i]));
455 }
456 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip))).Times(4);
457 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip_2)));
458 health_checker_->AddRemoteURL(kProxyURLRemote);
459 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
460 InvokeGetDNSResultSuccess(remote_ip);
461 }
462 InvokeGetDNSResultSuccess(remote_ip_2);
463 Mock::VerifyAndClearExpectations(dns_client_factory);
464 Mock::VerifyAndClearExpectations(&remote_ips_);
465 dns_client_buffer.clear();
466 dns_clients().clear();
467 }
468
TEST_F(ConnectionHealthCheckerTest,GetSocketInfo)469 TEST_F(ConnectionHealthCheckerTest, GetSocketInfo) {
470 SocketInfo sock_info;
471 vector<SocketInfo> info_list;
472
473 // GetSockName fails.
474 EXPECT_CALL(*socket_, GetSockName(_, _, _))
475 .WillOnce(Return(-1));
476 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
477 Mock::VerifyAndClearExpectations(socket_);
478
479 // GetSockName returns IPv6.
480 EXPECT_CALL(*socket_, GetSockName(_, _, _))
481 .WillOnce(
482 Invoke(this,
483 &ConnectionHealthCheckerTest::GetSockNameReturnsIPv6));
484 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
485 Mock::VerifyAndClearExpectations(socket_);
486
487 // LoadTcpSocketInfo fails.
488 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
489 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
490 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
491 .WillOnce(Return(false));
492 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
493 Mock::VerifyAndClearExpectations(socket_);
494 Mock::VerifyAndClearExpectations(socket_info_reader_);
495
496 // LoadTcpSocketInfo returns empty list.
497 info_list.clear();
498 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
499 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
500 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
501 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
502 Return(true)));
503 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
504 Mock::VerifyAndClearExpectations(socket_);
505 Mock::VerifyAndClearExpectations(socket_info_reader_);
506
507 // LoadTcpSocketInfo returns a list without our socket.
508 info_list.clear();
509 info_list.push_back(CreateSocketInfoOther());
510 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
511 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
512 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
513 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
514 Return(true)));
515 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
516 Mock::VerifyAndClearExpectations(socket_);
517 Mock::VerifyAndClearExpectations(socket_info_reader_);
518
519 // LoadTcpSocketInfo returns a list with only our socket.
520 info_list.clear();
521 info_list.push_back(
522 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
523 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
524 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
525 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
526 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
527 Return(true)));
528 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
529 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
530 .IsSameSocketAs(sock_info));
531 Mock::VerifyAndClearExpectations(socket_);
532 Mock::VerifyAndClearExpectations(socket_info_reader_);
533
534 // LoadTcpSocketInfo returns a list with two sockets, including ours.
535 info_list.clear();
536 info_list.push_back(CreateSocketInfoOther());
537 info_list.push_back(
538 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
539 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
540 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
541 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
542 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
543 Return(true)));
544 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
545 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
546 .IsSameSocketAs(sock_info));
547 Mock::VerifyAndClearExpectations(socket_);
548 Mock::VerifyAndClearExpectations(socket_info_reader_);
549
550 info_list.clear();
551 info_list.push_back(
552 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
553 info_list.push_back(CreateSocketInfoOther());
554 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
555 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
556 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
557 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
558 Return(true)));
559 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
560 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
561 .IsSameSocketAs(sock_info));
562 Mock::VerifyAndClearExpectations(socket_);
563 Mock::VerifyAndClearExpectations(socket_info_reader_);
564 }
565
TEST_F(ConnectionHealthCheckerTest,NextHealthCheckSample)566 TEST_F(ConnectionHealthCheckerTest, NextHealthCheckSample) {
567 IPAddress ip = StringToIPv4Address(kProxyIPAddressRemote);
568 ON_CALL(remote_ips_, GetRandomIP())
569 .WillByDefault(Return(ip));
570
571 health_checker_->set_num_connection_failures(MaxFailedConnectionAttempts());
572 ExpectStop();
573 EXPECT_CALL(
574 *this,
575 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
576 health_checker_->NextHealthCheckSample();
577 dispatcher_.DispatchPendingEvents();
578 VerifyAndClearAllExpectations();
579
580 health_checker_->set_num_congested_queue_detected(
581 MinCongestedQueueAttempts());
582 ExpectStop();
583 EXPECT_CALL(
584 *this,
585 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
586 health_checker_->NextHealthCheckSample();
587 dispatcher_.DispatchPendingEvents();
588 VerifyAndClearAllExpectations();
589
590 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts());
591 ExpectStop();
592 EXPECT_CALL(
593 *this,
594 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
595 health_checker_->NextHealthCheckSample();
596 dispatcher_.DispatchPendingEvents();
597 VerifyAndClearAllExpectations();
598
599 EXPECT_CALL(*tcp_connection_, Start(_, _)).WillOnce(Return(true));
600 health_checker_->NextHealthCheckSample();
601 VerifyAndClearAllExpectations();
602
603 // This test assumes that there are at least 2 connection attempts left
604 // before ConnectionHealthChecker gives up.
605 EXPECT_CALL(*tcp_connection_, Start(_, _))
606 .WillOnce(Return(false))
607 .WillOnce(Return(true));
608 int16_t num_connection_failures = health_checker_->num_connection_failures();
609 health_checker_->NextHealthCheckSample();
610 EXPECT_EQ(num_connection_failures + 1,
611 health_checker_->num_connection_failures());
612 }
613
TEST_F(ConnectionHealthCheckerTest,OnConnectionComplete)614 TEST_F(ConnectionHealthCheckerTest, OnConnectionComplete) {
615 // Test that num_connection_attempts is incremented on failure when
616 // (1) Async Connection fails.
617 health_checker_->set_num_connection_failures(
618 MaxFailedConnectionAttempts() - 1);
619 ExpectStop();
620 EXPECT_CALL(
621 *this,
622 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
623 health_checker_->OnConnectionComplete(false, -1);
624 dispatcher_.DispatchPendingEvents();
625 VerifyAndClearAllExpectations();
626
627 // (2) The connection state is garbled up.
628 health_checker_->set_num_connection_failures(
629 MaxFailedConnectionAttempts() - 1);
630 ExpectGetSocketInfoReturns(
631 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
632 EXPECT_CALL(*socket_, Close(kProxyFD));
633 ExpectStop();
634 EXPECT_CALL(
635 *this,
636 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
637 health_checker_->OnConnectionComplete(true, kProxyFD);
638 dispatcher_.DispatchPendingEvents();
639 VerifyAndClearAllExpectations();
640
641 // (3) Send fails.
642 health_checker_->set_num_connection_failures(
643 MaxFailedConnectionAttempts() - 1);
644 ExpectGetSocketInfoReturns(
645 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished));
646 EXPECT_CALL(*socket_, Send(kProxyFD, _, Gt(0), _)).WillOnce(Return(-1));
647 EXPECT_CALL(*socket_, Close(kProxyFD));
648 ExpectStop();
649 EXPECT_CALL(
650 *this,
651 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
652 health_checker_->OnConnectionComplete(true, kProxyFD);
653 dispatcher_.DispatchPendingEvents();
654 }
655
TEST_F(ConnectionHealthCheckerTest,VerifySentData)656 TEST_F(ConnectionHealthCheckerTest, VerifySentData) {
657 // (1) Test that num_connection_attempts is incremented when the connection
658 // state is garbled up.
659 health_checker_->set_num_connection_failures(
660 MaxFailedConnectionAttempts() - 1);
661 ExpectGetSocketInfoReturns(
662 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
663 EXPECT_CALL(*socket_, Close(kProxyFD));
664 ExpectStop();
665 EXPECT_CALL(
666 *this,
667 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
668 health_checker_->set_sock_fd(kProxyFD);
669 health_checker_->VerifySentData();
670 dispatcher_.DispatchPendingEvents();
671 VerifyAndClearAllExpectations();
672
673 // (2) Test that num_congested_queue_detected is incremented when all polling
674 // attempts have expired.
675 health_checker_->set_num_congested_queue_detected(
676 MinCongestedQueueAttempts() - 1);
677 health_checker_->set_num_tx_queue_polling_attempts(
678 MaxSentDataPollingAttempts());
679 health_checker_->set_old_transmit_queue_value(0);
680 ExpectGetSocketInfoReturns(
681 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
682 SocketInfo::kTimerStateRetransmitTimerPending,
683 1));
684 EXPECT_CALL(*socket_, Close(kProxyFD));
685 ExpectStop();
686 EXPECT_CALL(
687 *this,
688 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
689 health_checker_->set_sock_fd(kProxyFD);
690 health_checker_->VerifySentData();
691 dispatcher_.DispatchPendingEvents();
692 VerifyAndClearAllExpectations();
693
694 // (3) Test that num_successful_sends is incremented if everything goes fine.
695 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts() - 1);
696 health_checker_->set_old_transmit_queue_value(0);
697 ExpectGetSocketInfoReturns(
698 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
699 SocketInfo::kTimerStateNoTimerPending,
700 0));
701 EXPECT_CALL(*socket_, Close(kProxyFD));
702 ExpectStop();
703 EXPECT_CALL(
704 *this,
705 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
706 health_checker_->set_sock_fd(kProxyFD);
707 health_checker_->VerifySentData();
708 dispatcher_.DispatchPendingEvents();
709 VerifyAndClearAllExpectations();
710
711 // (4) Test that VerifySentData correctly polls the tcpinfo twice.
712 // We want to immediately dispatch posted tasks.
713 SetTCPStateUpdateWaitMilliseconds(0);
714 health_checker_->set_num_congested_queue_detected(
715 MinCongestedQueueAttempts() - 1);
716 health_checker_->set_num_tx_queue_polling_attempts(
717 MaxSentDataPollingAttempts() - 1);
718 health_checker_->set_old_transmit_queue_value(0);
719 ExpectGetSocketInfoReturns(
720 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
721 SocketInfo::kTimerStateRetransmitTimerPending,
722 1));
723 ExpectGetSocketInfoReturns(
724 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
725 SocketInfo::kTimerStateRetransmitTimerPending,
726 1));
727 EXPECT_CALL(*socket_, Close(kProxyFD));
728 ExpectStop();
729 EXPECT_CALL(
730 *this, ResultCallbackTarget(
731 ConnectionHealthChecker::kResultCongestedTxQueue))
732 .InSequence(seq_);
733 health_checker_->set_sock_fd(kProxyFD);
734 health_checker_->VerifySentData();
735 dispatcher_.DispatchPendingEvents();
736 dispatcher_.DispatchPendingEvents();
737 // Force an extra dispatch to make sure that VerifySentData did not poll an
738 // extra time. This dispatch should be a no-op.
739 dispatcher_.DispatchPendingEvents();
740 VerifyAndClearAllExpectations();
741 }
742
743 // Flow: Start() -> Start()
744 // Expectation: Only one AsyncConnection is setup
TEST_F(ConnectionHealthCheckerTest,StartStartSkipsSecond)745 TEST_F(ConnectionHealthCheckerTest, StartStartSkipsSecond) {
746 EXPECT_CALL(*tcp_connection_, Start(_, _))
747 .WillOnce(Return(true));
748 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
749 EXPECT_CALL(remote_ips_, GetRandomIP())
750 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
751 health_checker_->Start();
752 health_checker_->Start();
753 }
754
755 // Precondition: size(|remote_ips_|) > 0
756 // Flow: Start() -> Stop() before ConnectionComplete()
757 // Expectation: No call to |result_callback|
TEST_F(ConnectionHealthCheckerTest,StartStopNoCallback)758 TEST_F(ConnectionHealthCheckerTest, StartStopNoCallback) {
759 EXPECT_CALL(*tcp_connection_, Start(_, _))
760 .WillOnce(Return(true));
761 EXPECT_CALL(*tcp_connection_, Stop());
762 EXPECT_CALL(*this, ResultCallbackTarget(_))
763 .Times(0);
764 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
765 EXPECT_CALL(remote_ips_, GetRandomIP())
766 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
767 health_checker_->Start();
768 health_checker_->Stop();
769 }
770
771 // Precondition: Empty remote_ips_
772 // Flow: Start()
773 // Expectation: call |result_callback| with kResultUnknown
TEST_F(ConnectionHealthCheckerTest,StartImmediateFailure)774 TEST_F(ConnectionHealthCheckerTest, StartImmediateFailure) {
775 EXPECT_CALL(remote_ips_, Empty()).WillOnce(Return(true));
776 EXPECT_CALL(*tcp_connection_, Stop());
777 EXPECT_CALL(*this, ResultCallbackTarget(
778 ConnectionHealthChecker::kResultUnknown));
779 health_checker_->Start();
780 Mock::VerifyAndClearExpectations(this);
781 Mock::VerifyAndClearExpectations(&remote_ips_);
782 Mock::VerifyAndClearExpectations(tcp_connection_);
783
784 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
785 EXPECT_CALL(remote_ips_, GetRandomIP())
786 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
787 EXPECT_CALL(*tcp_connection_,
788 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
789 kProxyPortRemote))
790 .Times(MaxFailedConnectionAttempts())
791 .WillRepeatedly(Return(false));
792 EXPECT_CALL(*tcp_connection_, Stop());
793 EXPECT_CALL(*this, ResultCallbackTarget(
794 ConnectionHealthChecker::kResultConnectionFailure));
795 health_checker_->Start();
796 dispatcher_.DispatchPendingEvents();
797 Mock::VerifyAndClearExpectations(this);
798 Mock::VerifyAndClearExpectations(tcp_connection_);
799 }
800
801 } // namespace shill
802