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: 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 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 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 115 void InvokeOnConnectionComplete(bool success, int sock_fd) { 116 health_checker_->OnConnectionComplete(success, sock_fd); 117 } 118 119 void InvokeGetDNSResultFailure() { 120 Error error(Error::kOperationFailed, ""); 121 IPAddress address(IPAddress::kFamilyUnknown); 122 health_checker_->GetDNSResult(error, address); 123 } 124 125 void InvokeGetDNSResultSuccess(const IPAddress& address) { 126 Error error; 127 health_checker_->GetDNSResult(error, address); 128 } 129 130 protected: 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 156 void TearDown() { 157 ExpectStop(); 158 } 159 160 // Accessors for private data in ConnectionHealthChecker. 161 const Sockets* socket() { 162 return health_checker_->socket_.get(); 163 } 164 const AsyncConnection* tcp_connection() { 165 return health_checker_->tcp_connection_.get(); 166 } 167 ScopedVector<DNSClient>& dns_clients() { 168 return health_checker_->dns_clients_; 169 } 170 int NumDNSQueries() { 171 return ConnectionHealthChecker::kNumDNSQueries; 172 } 173 int MaxFailedConnectionAttempts() { 174 return ConnectionHealthChecker::kMaxFailedConnectionAttempts; 175 } 176 int MaxSentDataPollingAttempts() { 177 return ConnectionHealthChecker::kMaxSentDataPollingAttempts; 178 } 179 int MinCongestedQueueAttempts() { 180 return ConnectionHealthChecker::kMinCongestedQueueAttempts; 181 } 182 int MinSuccessfulSendAttempts() { 183 return ConnectionHealthChecker::kMinSuccessfulSendAttempts; 184 } 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 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. 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 } 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 } 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 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. 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 } 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 } 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 } 292 void ExpectStop() { 293 if (tcp_connection_) 294 EXPECT_CALL(*tcp_connection_, Stop()) 295 .InSequence(seq_); 296 } 297 void ExpectCleanUp() { 298 EXPECT_CALL(*socket_, Close(kProxyFD)) 299 .InSequence(seq_); 300 EXPECT_CALL(*tcp_connection_, Stop()) 301 .InSequence(seq_); 302 } 303 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 330 TEST_F(ConnectionHealthCheckerTest, Constructor) { 331 ExpectReset(); 332 } 333 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 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 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 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 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 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 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 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| 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 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