1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
1740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/connection_health_checker.h"
1840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
1940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <arpa/inet.h>
2022f1fbc11b69ee41af8370ec38f1b90577db6c3cBen Chan
2122f1fbc11b69ee41af8370ec38f1b90577db6c3cBen Chan#include <memory>
2240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <string>
2340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <vector>
2440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
2540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <base/bind.h>
2640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <base/callback.h>
27ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu#include <base/cancelable_callback.h>
283e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu#include <base/memory/scoped_vector.h>
2940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include <gtest/gtest.h>
3040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
3140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/mock_async_connection.h"
3240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/mock_connection.h"
3340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/mock_control.h"
34a41ab517725d036b63420f8445550246f8f50b99Alex Vakulenko#include "shill/mock_device_info.h"
3540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/mock_dns_client.h"
363e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu#include "shill/mock_dns_client_factory.h"
37ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu#include "shill/mock_ip_address_store.h"
3840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu#include "shill/mock_socket_info_reader.h"
398d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
40a92b0a0438803ebb3432d7b42672fbb7fb6bccf4Peter Qiu#include "shill/test_event_dispatcher.h"
4140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
4240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing base::Bind;
4340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing base::Callback;
44ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhuusing base::Closure;
4540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing base::Unretained;
4640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing std::string;
4740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing std::vector;
48ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhuusing ::testing::AtLeast;
4940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::DoAll;
5040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Gt;
5140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Invoke;
5240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Mock;
5340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::NiceMock;
5440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Return;
5540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::ReturnRef;
56ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhuusing ::testing::SaveArg;
5740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Sequence;
5840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::SetArgumentPointee;
5940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::StrictMock;
6040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::Test;
6140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuusing ::testing::_;
6240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
6340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhunamespace shill {
6440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
6540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhunamespace {
6640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kInterfaceName[] = "int0";
6740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kIPAddress_8_8_8_8[] = "8.8.8.8";
6840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kProxyIPAddressRemote[] = "74.125.224.84";
6940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kProxyIPAddressLocal[] = "192.23.34.1";
7040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kProxyIPv6AddressLocal[] = "::ffff:192.23.34.1";
7140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst char kProxyURLRemote[] = "http://www.google.com";
7240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuconst int kProxyFD = 100;
738a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenkoconst int16_t kProxyPortLocal = 5540;
748a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenkoconst int16_t kProxyPortRemote = 80;
758a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko}  // namespace
7640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
7740daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuMATCHER_P(IsSameIPAddress, ip_addr, "") {
7840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  return arg.Equals(ip_addr);
7940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
8040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
8140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhuclass ConnectionHealthCheckerTest : public Test {
8240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu public:
8340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ConnectionHealthCheckerTest()
8440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      : interface_name_(kInterfaceName),
85cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        device_info_(&control_, &dispatcher_, nullptr, nullptr),
863e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        connection_(new NiceMock<MockConnection>(&device_info_)),
87cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        socket_(nullptr) {}
8840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
8940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Invokes
903b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  int GetSockName(int fd, struct sockaddr* addr_out, socklen_t* sockaddr_size) {
9140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    struct sockaddr_in addr;
9240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(kProxyFD, fd);
9340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_LE(sizeof(sockaddr_in), *sockaddr_size);
9440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    addr.sin_family = AF_INET;
9540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    inet_pton(AF_INET, kProxyIPAddressLocal, &addr.sin_addr);
9640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    addr.sin_port = htons(kProxyPortLocal);
9740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    memcpy(addr_out, &addr, sizeof(addr));
9840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    *sockaddr_size = sizeof(sockaddr_in);
9940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return 0;
10040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
10140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
1023b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  int GetSockNameReturnsIPv6(int fd, struct sockaddr* addr_out,
1033b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                             socklen_t* sockaddr_size) {
10440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    struct sockaddr_in6 addr;
10540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(kProxyFD, fd);
10640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_LE(sizeof(sockaddr_in6), *sockaddr_size);
10740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    addr.sin6_family = AF_INET6;
10840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    inet_pton(AF_INET6, kProxyIPv6AddressLocal, &addr.sin6_addr);
10940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    addr.sin6_port = htons(kProxyPortLocal);
11040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    memcpy(addr_out, &addr, sizeof(addr));
11140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    *sockaddr_size = sizeof(sockaddr_in6);
11240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return 0;
11340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
11440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
11540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void InvokeOnConnectionComplete(bool success, int sock_fd) {
11640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    health_checker_->OnConnectionComplete(success, sock_fd);
11740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
11840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
1193e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  void InvokeGetDNSResultFailure() {
1203e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    Error error(Error::kOperationFailed, "");
1213e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    IPAddress address(IPAddress::kFamilyUnknown);
1223e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    health_checker_->GetDNSResult(error, address);
1233e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
1243e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
1253b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void InvokeGetDNSResultSuccess(const IPAddress& address) {
1263e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    Error error;
1273e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    health_checker_->GetDNSResult(error, address);
1283e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
1293e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
13040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu protected:
13140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void SetUp() {
13240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*connection_.get(), interface_name())
13340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .WillRepeatedly(ReturnRef(interface_name_));
1343e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    ON_CALL(*connection_.get(), dns_servers())
1353e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillByDefault(ReturnRef(dns_servers_));
136ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    // ConnectionHealthChecker constructor should add some IPs
137ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    EXPECT_CALL(remote_ips_, AddUnique(_)).Times(AtLeast(1));
13840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    health_checker_.reset(
13940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        new ConnectionHealthChecker(
14040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu             connection_,
14140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu             &dispatcher_,
142ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu             &remote_ips_,
14340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu             Bind(&ConnectionHealthCheckerTest::ResultCallbackTarget,
14440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                  Unretained(this))));
145ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    Mock::VerifyAndClearExpectations(&remote_ips_);
14640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    socket_ = new StrictMock<MockSockets>();
14740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    tcp_connection_ = new StrictMock<MockAsyncConnection>();
14840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    socket_info_reader_ = new StrictMock<MockSocketInfoReader>();
14940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    // Passes ownership for all of these.
15040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    health_checker_->socket_.reset(socket_);
15140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    health_checker_->tcp_connection_.reset(tcp_connection_);
15240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    health_checker_->socket_info_reader_.reset(socket_info_reader_);
1533e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    health_checker_->dns_client_factory_ = MockDNSClientFactory::GetInstance();
15440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
15540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
15640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void TearDown() {
157ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    ExpectStop();
15840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
15940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
16040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Accessors for private data in ConnectionHealthChecker.
1613b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const Sockets* socket() {
16240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return health_checker_->socket_.get();
16340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
1643b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const AsyncConnection* tcp_connection() {
1653e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    return health_checker_->tcp_connection_.get();
1663e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
1673b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  ScopedVector<DNSClient>& dns_clients() {
1683e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    return health_checker_->dns_clients_;
1693e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
1703e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  int NumDNSQueries() {
1713e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    return ConnectionHealthChecker::kNumDNSQueries;
1723e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
173ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  int MaxFailedConnectionAttempts() {
174ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    return ConnectionHealthChecker::kMaxFailedConnectionAttempts;
175ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  }
176ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  int MaxSentDataPollingAttempts() {
177ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    return ConnectionHealthChecker::kMaxSentDataPollingAttempts;
178ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  }
179ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  int MinCongestedQueueAttempts() {
180ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    return ConnectionHealthChecker::kMinCongestedQueueAttempts;
181ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  }
182ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  int MinSuccessfulSendAttempts() {
183ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    return ConnectionHealthChecker::kMinSuccessfulSendAttempts;
184ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  }
18581404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  void SetTCPStateUpdateWaitMilliseconds(int new_wait) {
18681404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu    health_checker_->tcp_state_update_wait_milliseconds_ = new_wait;
18781404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  }
18840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
18940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Mock Callbacks
19040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  MOCK_METHOD1(ResultCallbackTarget,
19140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu               void(ConnectionHealthChecker::Result result));
19240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
19340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Helper methods
1943b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  IPAddress StringToIPv4Address(const string& address_string) {
19540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    IPAddress ip_address(IPAddress::kFamilyIPv4);
19640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
19740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return ip_address;
19840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
19940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Naming: CreateSocketInfo
20040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  //         + (Proxy/Other) : TCP connection for proxy socket / some other
20140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  //         socket.
20240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  //         + arg1: Pass in any SocketInfo::ConnectionState you want.
20340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  //         + arg2: Pass in any value of transmit_queue_value you want.
20440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  SocketInfo CreateSocketInfoOther() {
20540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return SocketInfo(
20640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        SocketInfo::kConnectionStateUnknown,
20740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kIPAddress_8_8_8_8),
20840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
20940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kProxyIPAddressRemote),
21040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        kProxyPortRemote,
21140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
21240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
21340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        SocketInfo::kTimerStateUnknown);
21440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
21540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state) {
21640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return SocketInfo(
21740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        state,
21840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kProxyIPAddressLocal),
21940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        kProxyPortLocal,
22040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kProxyIPAddressRemote),
22140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        kProxyPortRemote,
22240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
22340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
22440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        SocketInfo::kTimerStateUnknown);
22540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
22640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state,
227ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu                                   SocketInfo::TimerState timer_state,
2287fab89734d88724a288e96a9996b15548c5294c7Ben Chan                                   uint64_t transmit_queue_value) {
22940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    return SocketInfo(
23040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        state,
23140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kProxyIPAddressLocal),
23240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        kProxyPortLocal,
23340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        StringToIPv4Address(kProxyIPAddressRemote),
23440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        kProxyPortRemote,
23540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        transmit_queue_value,
23640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        0,
237ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu        timer_state);
23840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
23940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
240ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu
24140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Expectations
24240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void ExpectReset() {
24340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(connection_.get(), health_checker_->connection_.get());
24440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(&dispatcher_, health_checker_->dispatcher_);
24540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(socket_, health_checker_->socket_.get());
246cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    EXPECT_FALSE(socket_ == nullptr);
24740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(socket_info_reader_, health_checker_->socket_info_reader_.get());
248cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    EXPECT_FALSE(socket_info_reader_ == nullptr);
24940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_FALSE(health_checker_->connection_complete_callback_.is_null());
25040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_EQ(tcp_connection_, health_checker_->tcp_connection_.get());
251cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    EXPECT_FALSE(tcp_connection_ == nullptr);
25240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_FALSE(health_checker_->health_check_in_progress_);
25340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
254ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu
25540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Setup ConnectionHealthChecker::GetSocketInfo to return sock_info.
25640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // This only works if GetSocketInfo is called with kProxyFD.
25740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // If no matching sock_info is provided (Does not belong to proxy socket),
25840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // GetSocketInfo will (correctly) return false.
25940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void ExpectGetSocketInfoReturns(SocketInfo sock_info) {
26040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    vector<SocketInfo> info_list;
26140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    info_list.push_back(sock_info);
26240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
26340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_)
26440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .WillOnce(Invoke(this,
26540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                         &ConnectionHealthCheckerTest::GetSockName));
26640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
26740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_)
26840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
26940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                        Return(true)));
27040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
27140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void ExpectSuccessfulStart() {
272ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
273ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    EXPECT_CALL(remote_ips_, GetRandomIP())
274ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu        .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
27540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(
27640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        *tcp_connection_,
27740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
27840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu              kProxyPortRemote))
27940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_)
28040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .WillOnce(Return(true));
28140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
28240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void ExpectRetry() {
28340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*socket_, Close(kProxyFD))
28440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_);
28540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(
28640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        *tcp_connection_,
28740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
28840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu              kProxyPortRemote))
28940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_)
29040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .WillOnce(Return(true));
29140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
292ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  void ExpectStop() {
293ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu    if (tcp_connection_)
294ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      EXPECT_CALL(*tcp_connection_, Stop())
295ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu          .InSequence(seq_);
29640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
29740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  void ExpectCleanUp() {
29840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*socket_, Close(kProxyFD))
29940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_);
30040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    EXPECT_CALL(*tcp_connection_, Stop())
30140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu        .InSequence(seq_);
30240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  }
30340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
304ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  void VerifyAndClearAllExpectations() {
305ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    Mock::VerifyAndClearExpectations(this);
306ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    Mock::VerifyAndClearExpectations(tcp_connection_);
307ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    Mock::VerifyAndClearExpectations(socket_);
308ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    Mock::VerifyAndClearExpectations(socket_info_reader_);
309ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  }
310ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu
31140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // Needed for other mocks, but not for the tests directly.
31240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  const string interface_name_;
31340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  NiceMock<MockControl> control_;
31440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  NiceMock<MockDeviceInfo> device_info_;
31540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  vector<string> dns_servers_;
31640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
317e2ee5e009081a392fb31596c1d0cfb30bc7bad6eBen Chan  scoped_refptr<NiceMock<MockConnection>> connection_;
318a92b0a0438803ebb3432d7b42672fbb7fb6bccf4Peter Qiu  EventDispatcherForTest dispatcher_;
319ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  MockIPAddressStore remote_ips_;
3203b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  StrictMock<MockSockets>* socket_;
3213b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  StrictMock<MockSocketInfoReader>* socket_info_reader_;
3223b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  StrictMock<MockAsyncConnection>* tcp_connection_;
3233e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // Expectations in the Expect* functions are put in this sequence.
32440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // This allows us to chain calls to Expect* functions.
32540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Sequence seq_;
32640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
32722f1fbc11b69ee41af8370ec38f1b90577db6c3cBen Chan  std::unique_ptr<ConnectionHealthChecker> health_checker_;
32840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu};
32940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
33040daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, Constructor) {
33140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectReset();
33240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
33340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
334ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, SetConnection) {
335e2ee5e009081a392fb31596c1d0cfb30bc7bad6eBen Chan  scoped_refptr<NiceMock<MockConnection>> new_connection =
336e2ee5e009081a392fb31596c1d0cfb30bc7bad6eBen Chan      new NiceMock<MockConnection>(&device_info_);
337ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  // If a health check was in progress when SetConnection is called, verify
338ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  // that it restarts with the new connection.
339ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  ExpectSuccessfulStart();
340ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  health_checker_->Start();
341ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  VerifyAndClearAllExpectations();
34241a071e432b09ab1945f5c9ae74c998726142810Paul Stewart
343ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(true));
344ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(*new_connection.get(), interface_name())
345ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      .WillRepeatedly(ReturnRef(interface_name_));
346ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(*this,
347ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu              ResultCallbackTarget(ConnectionHealthChecker::kResultUnknown));
348ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  health_checker_->SetConnection(new_connection);
349ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_NE(tcp_connection_, health_checker_->tcp_connection());
350ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_EQ(new_connection.get(), health_checker_->connection());
351ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu
352ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  // health_checker_ has reset tcp_connection_ to a new object.
353ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  // Since it owned tcp_connection_, the object has been destroyed.
354cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  tcp_connection_ = nullptr;
35541a071e432b09ab1945f5c9ae74c998726142810Paul Stewart}
35641a071e432b09ab1945f5c9ae74c998726142810Paul Stewart
3573e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, GarbageCollectDNSClients) {
3583e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_clients().clear();
3593e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  health_checker_->GarbageCollectDNSClients();
3603e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  EXPECT_TRUE(dns_clients().empty());
3613e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
3623e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < 3; ++i) {
3633b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MockDNSClient* dns_client = new MockDNSClient();
3643e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    EXPECT_CALL(*dns_client, IsActive())
3653e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(true))
3663e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(true))
3673e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(false));
3683e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    // Takes ownership.
3693e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    dns_clients().push_back(dns_client);
3703e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
3713e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < 2; ++i) {
3723b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MockDNSClient* dns_client = new MockDNSClient();
3733e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    EXPECT_CALL(*dns_client, IsActive())
3743e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(false));
3753e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    // Takes ownership.
3763e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    dns_clients().push_back(dns_client);
3773e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
37840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
3793e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  EXPECT_EQ(5, dns_clients().size());
3803e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  health_checker_->GarbageCollectDNSClients();
3813e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  EXPECT_EQ(3, dns_clients().size());
3823e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  health_checker_->GarbageCollectDNSClients();
3833e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  EXPECT_EQ(3, dns_clients().size());
3843e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  health_checker_->GarbageCollectDNSClients();
3853e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  EXPECT_TRUE(dns_clients().empty());
3863e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu}
38740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
3883e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, AddRemoteURL) {
3893e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  HTTPURL url;
3903e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  url.ParseFromString(kProxyURLRemote);
3913e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  string host = url.host();
3923e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  IPAddress remote_ip = StringToIPv4Address(kProxyIPAddressRemote);
3933e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  IPAddress remote_ip_2 = StringToIPv4Address(kIPAddress_8_8_8_8);
3943e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
3953b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockDNSClientFactory* dns_client_factory
3963e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu      = MockDNSClientFactory::GetInstance();
3973b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  vector<MockDNSClient*> dns_client_buffer;
3983e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
3993e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // All DNS queries fail.
4003e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4013b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MockDNSClient* dns_client = new MockDNSClient();
4023e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    EXPECT_CALL(*dns_client, Start(host, _))
4033e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(false));
4043e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    dns_client_buffer.push_back(dns_client);
4053e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
4063e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // Will pass ownership of dns_clients elements.
4073e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4088a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
4093e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .InSequence(seq_)
4103e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(dns_client_buffer[i]));
4113e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
412ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, AddUnique(_)).Times(0);
41340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->AddRemoteURL(kProxyURLRemote);
4143e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  Mock::VerifyAndClearExpectations(dns_client_factory);
415ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  Mock::VerifyAndClearExpectations(&remote_ips_);
4163e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_client_buffer.clear();
4173e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_clients().clear();
4183e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
4193e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // All but one DNS queries fail, 1 succeeds.
4203e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4213b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MockDNSClient* dns_client = new MockDNSClient();
4223e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    EXPECT_CALL(*dns_client, Start(host, _))
4233e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(true));
4243e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    dns_client_buffer.push_back(dns_client);
4253e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
4263e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // Will pass ownership of dns_clients elements.
4273e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4288a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
4293e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .InSequence(seq_)
4303e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(dns_client_buffer[i]));
4313e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
432ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, AddUnique(_));
43340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->AddRemoteURL(kProxyURLRemote);
4348a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  for (int i = 0; i < NumDNSQueries() - 1; ++i) {
4353e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    InvokeGetDNSResultFailure();
4363e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
4373e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  InvokeGetDNSResultSuccess(remote_ip);
4383e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  Mock::VerifyAndClearExpectations(dns_client_factory);
439ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  Mock::VerifyAndClearExpectations(&remote_ips_);
4403e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_client_buffer.clear();
4413e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_clients().clear();
4423e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu
4433e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // Only 2 distinct IP addresses are returned.
4443e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4453b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    MockDNSClient* dns_client = new MockDNSClient();
4463e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    EXPECT_CALL(*dns_client, Start(host, _))
4473e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(true));
4483e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    dns_client_buffer.push_back(dns_client);
4493e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
4503e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  // Will pass ownership of dns_clients elements.
4513e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries(); ++i) {
4528a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
4533e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .InSequence(seq_)
4543e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu        .WillOnce(Return(dns_client_buffer[i]));
4553e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
456ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip))).Times(4);
457ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip_2)));
4583e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  health_checker_->AddRemoteURL(kProxyURLRemote);
4593e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  for (int i = 0; i < NumDNSQueries() - 1; ++i) {
4603e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu    InvokeGetDNSResultSuccess(remote_ip);
4613e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  }
4623e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  InvokeGetDNSResultSuccess(remote_ip_2);
4633e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  Mock::VerifyAndClearExpectations(dns_client_factory);
464ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  Mock::VerifyAndClearExpectations(&remote_ips_);
4653e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_client_buffer.clear();
4663e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu  dns_clients().clear();
46740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
46840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
46940daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, GetSocketInfo) {
47040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  SocketInfo sock_info;
47140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  vector<SocketInfo> info_list;
47240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
47340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // GetSockName fails.
4748a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*socket_, GetSockName(_, _, _))
47540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Return(-1));
47640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
47740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
47840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
47940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // GetSockName returns IPv6.
4808a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*socket_, GetSockName(_, _, _))
48140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(
48240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu          Invoke(this,
48340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                 &ConnectionHealthCheckerTest::GetSockNameReturnsIPv6));
48440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
48540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
48640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
48740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // LoadTcpSocketInfo fails.
48840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
48940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
49040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
49140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu    .WillOnce(Return(false));
49240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
49340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
49440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
49540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
49640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // LoadTcpSocketInfo returns empty list.
49740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.clear();
49840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
49940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
50040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
50140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
50240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                      Return(true)));
50340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
50440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
50540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
50640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
50740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // LoadTcpSocketInfo returns a list without our socket.
50840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.clear();
50940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(CreateSocketInfoOther());
51040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
51140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
51240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
51340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
51440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                      Return(true)));
51540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
51640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
51740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
51840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
51940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // LoadTcpSocketInfo returns a list with only our socket.
52040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.clear();
52140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(
52240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
52340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
52440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
52540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
52640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
52740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                      Return(true)));
52840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
52940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
53040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                  .IsSameSocketAs(sock_info));
53140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
53240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
53340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
53440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  // LoadTcpSocketInfo returns a list with two sockets, including ours.
53540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.clear();
53640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(CreateSocketInfoOther());
53740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(
53840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
53940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
54040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
54140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
54240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
54340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                      Return(true)));
54440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
54540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
54640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                  .IsSameSocketAs(sock_info));
54740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
54840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
54940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
55040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.clear();
55140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(
55240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
55340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  info_list.push_back(CreateSocketInfoOther());
55440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
55540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
55640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
55740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
55840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                      Return(true)));
55940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
56040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
56140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                  .IsSameSocketAs(sock_info));
56240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_);
56340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(socket_info_reader_);
56440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
56540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
566ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, NextHealthCheckSample) {
567ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  IPAddress ip = StringToIPv4Address(kProxyIPAddressRemote);
568ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  ON_CALL(remote_ips_, GetRandomIP())
569ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      .WillByDefault(Return(ip));
57040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
571ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_connection_failures(MaxFailedConnectionAttempts());
572ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
573ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
574ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
575ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
576ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->NextHealthCheckSample();
577ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
578ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
57940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
580ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_congested_queue_detected(
581ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MinCongestedQueueAttempts());
582ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
583ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
584ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
585ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
586ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->NextHealthCheckSample();
587ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
588ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
58940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
590ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts());
591ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
592ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
593ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
594ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
595ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->NextHealthCheckSample();
596ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
597ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
59840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
5998a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*tcp_connection_, Start(_, _)).WillOnce(Return(true));
600ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->NextHealthCheckSample();
601ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
60240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
603ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // This test assumes that there are at least 2 connection attempts left
604ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // before ConnectionHealthChecker gives up.
6058a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*tcp_connection_, Start(_, _))
606ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    .WillOnce(Return(false))
607ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu    .WillOnce(Return(true));
6088a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  int16_t num_connection_failures = health_checker_->num_connection_failures();
609ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->NextHealthCheckSample();
610ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_EQ(num_connection_failures + 1,
611ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu            health_checker_->num_connection_failures());
61240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
61340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
614ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, OnConnectionComplete) {
615ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // Test that num_connection_attempts is incremented on failure when
616ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (1) Async Connection fails.
617ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_connection_failures(
618ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MaxFailedConnectionAttempts() - 1);
619ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
620ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
621ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
622ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
623ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->OnConnectionComplete(false, -1);
624ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
625ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
62640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
627ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (2) The connection state is garbled up.
628ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_connection_failures(
629ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MaxFailedConnectionAttempts() - 1);
63040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectGetSocketInfoReturns(
631ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
632ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
633ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
634ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
635ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
636ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
637ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->OnConnectionComplete(true, kProxyFD);
638ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
639ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
64040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
641ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (3) Send fails.
642ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_connection_failures(
643ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MaxFailedConnectionAttempts() - 1);
64440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectGetSocketInfoReturns(
64540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished));
646ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Send(kProxyFD, _, Gt(0), _)).WillOnce(Return(-1));
647ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
648ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
649ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
650ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
651ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
652ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->OnConnectionComplete(true, kProxyFD);
653ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
654ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu}
65540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
656ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, VerifySentData) {
657ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (1) Test that num_connection_attempts is incremented when the connection
658ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // state is garbled up.
659ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_connection_failures(
660ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MaxFailedConnectionAttempts() - 1);
66140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectGetSocketInfoReturns(
662ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
663ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
664ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
665ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
666ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
667ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
668ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_sock_fd(kProxyFD);
669ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->VerifySentData();
670ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
671ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
67240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
673ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (2) Test that num_congested_queue_detected is incremented when all polling
674ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // attempts have expired.
675ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_congested_queue_detected(
676ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MinCongestedQueueAttempts() - 1);
677ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_tx_queue_polling_attempts(
678ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      MaxSentDataPollingAttempts());
679ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_old_transmit_queue_value(0);
68040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectGetSocketInfoReturns(
681ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
682ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu                            SocketInfo::kTimerStateRetransmitTimerPending,
683ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu                            1));
684ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
685ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
686ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
687ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
688ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
689ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_sock_fd(kProxyFD);
690ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->VerifySentData();
691ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
692ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
69340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
694ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  // (3) Test that num_successful_sends is incremented if everything goes fine.
695ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts() - 1);
696ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_old_transmit_queue_value(0);
69740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  ExpectGetSocketInfoReturns(
698ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
699ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu                            SocketInfo::kTimerStateNoTimerPending,
700ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu                            0));
701ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
702ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  ExpectStop();
703ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  EXPECT_CALL(
704ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      *this,
705ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
706ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->set_sock_fd(kProxyFD);
707ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  health_checker_->VerifySentData();
708ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
709ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  VerifyAndClearAllExpectations();
71081404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu
71181404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  // (4) Test that VerifySentData correctly polls the tcpinfo twice.
71281404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  // We want to immediately dispatch posted tasks.
71381404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  SetTCPStateUpdateWaitMilliseconds(0);
71481404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  health_checker_->set_num_congested_queue_detected(
71581404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      MinCongestedQueueAttempts() - 1);
71681404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  health_checker_->set_num_tx_queue_polling_attempts(
71781404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      MaxSentDataPollingAttempts() - 1);
71881404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  health_checker_->set_old_transmit_queue_value(0);
71981404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  ExpectGetSocketInfoReturns(
72081404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
72181404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu                            SocketInfo::kTimerStateRetransmitTimerPending,
72281404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu                            1));
72381404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  ExpectGetSocketInfoReturns(
72481404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
72581404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu                            SocketInfo::kTimerStateRetransmitTimerPending,
72681404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu                            1));
72781404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  EXPECT_CALL(*socket_, Close(kProxyFD));
72881404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  ExpectStop();
72981404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  EXPECT_CALL(
73081404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      *this, ResultCallbackTarget(
73181404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu          ConnectionHealthChecker::kResultCongestedTxQueue))
73281404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu      .InSequence(seq_);
73381404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  health_checker_->set_sock_fd(kProxyFD);
73481404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  health_checker_->VerifySentData();
73581404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  dispatcher_.DispatchPendingEvents();
73681404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  dispatcher_.DispatchPendingEvents();
73781404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  // Force an extra dispatch to make sure that VerifySentData did not poll an
73881404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  // extra time. This dispatch should be a no-op.
73981404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  dispatcher_.DispatchPendingEvents();
74081404c674c82f0ac2c958715b451b84521148b7ePrathmesh Prabhu  VerifyAndClearAllExpectations();
74140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
74240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
74340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Flow: Start() -> Start()
74440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Expectation: Only one AsyncConnection is setup
74540daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, StartStartSkipsSecond) {
7468a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*tcp_connection_, Start(_, _))
74740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Return(true));
748ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
749ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, GetRandomIP())
750ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
75140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Start();
75240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Start();
75340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
75440daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
75540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Precondition: size(|remote_ips_|) > 0
75640daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Flow: Start() -> Stop() before ConnectionComplete()
75740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Expectation: No call to |result_callback|
75840daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, StartStopNoCallback) {
7598a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  EXPECT_CALL(*tcp_connection_, Start(_, _))
76040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .WillOnce(Return(true));
761ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(*tcp_connection_, Stop());
76240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*this, ResultCallbackTarget(_))
76340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu      .Times(0);
764ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
765ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, GetRandomIP())
766ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
76740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Start();
76840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Stop();
76940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
77040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
77140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Precondition: Empty remote_ips_
77240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Flow: Start()
77340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu// Expectation: call |result_callback| with kResultUnknown
77440daa01c4c8d772889d9c4167dee312869152174Prathmesh PrabhuTEST_F(ConnectionHealthCheckerTest, StartImmediateFailure) {
775ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, Empty()).WillOnce(Return(true));
776ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(*tcp_connection_, Stop());
77740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*this, ResultCallbackTarget(
778ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu                           ConnectionHealthChecker::kResultUnknown));
77940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Start();
78040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(this);
781ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  Mock::VerifyAndClearExpectations(&remote_ips_);
78240daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(tcp_connection_);
78340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
784ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
785ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(remote_ips_, GetRandomIP())
786ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu      .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
78740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*tcp_connection_,
78840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu              Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
78940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu                    kProxyPortRemote))
790ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu      .Times(MaxFailedConnectionAttempts())
7913e452f8c41b7983f1068a4b7229998c7e7de4334Prathmesh Prabhu      .WillRepeatedly(Return(false));
792ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu  EXPECT_CALL(*tcp_connection_, Stop());
79340daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  EXPECT_CALL(*this, ResultCallbackTarget(
794ba99b598d3f399a41e57f49dccac5f988e653126Prathmesh Prabhu                           ConnectionHealthChecker::kResultConnectionFailure));
79540daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  health_checker_->Start();
796ade9b9a914efaeac3b2f4d4888ffdfb3e76b76f6Prathmesh Prabhu  dispatcher_.DispatchPendingEvents();
79740daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(this);
79840daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu  Mock::VerifyAndClearExpectations(tcp_connection_);
79940daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}
80040daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu
80140daa01c4c8d772889d9c4167dee312869152174Prathmesh Prabhu}  // namespace shill
802