// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/connection_health_checker.h"

#include <arpa/inet.h>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/memory/scoped_ptr.h>
#include <base/memory/scoped_vector.h>
#include <gtest/gtest.h>

#include "shill/mock_async_connection.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_dns_client.h"
#include "shill/mock_dns_client_factory.h"
#include "shill/mock_device_info.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_ip_address_store.h"
#include "shill/mock_sockets.h"
#include "shill/mock_socket_info_reader.h"

using base::Bind;
using base::Callback;
using base::Closure;
using base::Unretained;
using std::string;
using std::vector;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Gt;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::Sequence;
using ::testing::SetArgumentPointee;
using ::testing::StrictMock;
using ::testing::Test;
using ::testing::_;

namespace shill {

namespace {
const char kInterfaceName[] = "int0";
const char kIPAddress_0_0_0_0[] = "0.0.0.0";
const char kIPAddress_8_8_8_8[] = "8.8.8.8";
const char kProxyIPAddressRemote[] = "74.125.224.84";
const char kProxyIPAddressLocal[] = "192.23.34.1";
const char kProxyIPv6AddressLocal[] = "::ffff:192.23.34.1";
const char kProxyURLRemote[] = "http://www.google.com";
const int kProxyFD = 100;
const short kProxyPortLocal = 5540;
const short kProxyPortRemote = 80;
const int kSocketError = 3000;
}  // namespace {}

MATCHER_P(IsSameIPAddress, ip_addr, "") {
  return arg.Equals(ip_addr);
}

class ConnectionHealthCheckerTest : public Test {
 public:
  ConnectionHealthCheckerTest()
      : interface_name_(kInterfaceName),
        device_info_(&control_, &dispatcher_,
                     reinterpret_cast<Metrics*>(NULL),
                     reinterpret_cast<Manager*>(NULL)),
        connection_(new NiceMock<MockConnection>(&device_info_)),
        socket_(NULL) {}

  // Invokes
  int GetSockName(int fd, struct sockaddr *addr_out, socklen_t *sockaddr_size) {
    struct sockaddr_in addr;
    EXPECT_EQ(kProxyFD, fd);
    EXPECT_LE(sizeof(sockaddr_in), *sockaddr_size);
    addr.sin_family = AF_INET;
    inet_pton(AF_INET, kProxyIPAddressLocal, &addr.sin_addr);
    addr.sin_port = htons(kProxyPortLocal);
    memcpy(addr_out, &addr, sizeof(addr));
    *sockaddr_size = sizeof(sockaddr_in);
    return 0;
  }

  int GetSockNameReturnsIPv6(int fd, struct sockaddr *addr_out,
                             socklen_t *sockaddr_size) {
    struct sockaddr_in6 addr;
    EXPECT_EQ(kProxyFD, fd);
    EXPECT_LE(sizeof(sockaddr_in6), *sockaddr_size);
    addr.sin6_family = AF_INET6;
    inet_pton(AF_INET6, kProxyIPv6AddressLocal, &addr.sin6_addr);
    addr.sin6_port = htons(kProxyPortLocal);
    memcpy(addr_out, &addr, sizeof(addr));
    *sockaddr_size = sizeof(sockaddr_in6);
    return 0;
  }

  void InvokeOnConnectionComplete(bool success, int sock_fd) {
    health_checker_->OnConnectionComplete(success, sock_fd);
  }

  void InvokeGetDNSResultFailure() {
    Error error(Error::kOperationFailed, "");
    IPAddress address(IPAddress::kFamilyUnknown);
    health_checker_->GetDNSResult(error, address);
  }

  void InvokeGetDNSResultSuccess(const IPAddress &address) {
    Error error;
    health_checker_->GetDNSResult(error, address);
  }

 protected:
  void SetUp() {
    EXPECT_CALL(*connection_.get(), interface_name())
        .WillRepeatedly(ReturnRef(interface_name_));
    ON_CALL(*connection_.get(), dns_servers())
        .WillByDefault(ReturnRef(dns_servers_));
    // ConnectionHealthChecker constructor should add some IPs
    EXPECT_CALL(remote_ips_, AddUnique(_)).Times(AtLeast(1));
    health_checker_.reset(
        new ConnectionHealthChecker(
             connection_,
             &dispatcher_,
             &remote_ips_,
             Bind(&ConnectionHealthCheckerTest::ResultCallbackTarget,
                  Unretained(this))));
    Mock::VerifyAndClearExpectations(&remote_ips_);
    socket_ = new StrictMock<MockSockets>();
    tcp_connection_ = new StrictMock<MockAsyncConnection>();
    socket_info_reader_ = new StrictMock<MockSocketInfoReader>();
    // Passes ownership for all of these.
    health_checker_->socket_.reset(socket_);
    health_checker_->tcp_connection_.reset(tcp_connection_);
    health_checker_->socket_info_reader_.reset(socket_info_reader_);
    health_checker_->dns_client_factory_ = MockDNSClientFactory::GetInstance();
  }

  void TearDown() {
    ExpectStop();
  }

  // Accessors for private data in ConnectionHealthChecker.
  const Sockets *socket() {
    return health_checker_->socket_.get();
  }
  const AsyncConnection *tcp_connection() {
    return health_checker_->tcp_connection_.get();
  }
  ScopedVector<DNSClient> &dns_clients() {
    return health_checker_->dns_clients_;
  }
  int NumDNSQueries() {
    return ConnectionHealthChecker::kNumDNSQueries;
  }
  int MaxFailedConnectionAttempts() {
    return ConnectionHealthChecker::kMaxFailedConnectionAttempts;
  }
  int MaxSentDataPollingAttempts() {
    return ConnectionHealthChecker::kMaxSentDataPollingAttempts;
  }
  int MinCongestedQueueAttempts() {
    return ConnectionHealthChecker::kMinCongestedQueueAttempts;
  }
  int MinSuccessfulSendAttempts() {
    return ConnectionHealthChecker::kMinSuccessfulSendAttempts;
  }
  void SetTCPStateUpdateWaitMilliseconds(int new_wait) {
    health_checker_->tcp_state_update_wait_milliseconds_ = new_wait;
  }

  // Mock Callbacks
  MOCK_METHOD1(ResultCallbackTarget,
               void(ConnectionHealthChecker::Result result));

  // Helper methods
  IPAddress StringToIPv4Address(const string &address_string) {
    IPAddress ip_address(IPAddress::kFamilyIPv4);
    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
    return ip_address;
  }
  // Naming: CreateSocketInfo
  //         + (Proxy/Other) : TCP connection for proxy socket / some other
  //         socket.
  //         + arg1: Pass in any SocketInfo::ConnectionState you want.
  //         + arg2: Pass in any value of transmit_queue_value you want.
  SocketInfo CreateSocketInfoOther() {
    return SocketInfo(
        SocketInfo::kConnectionStateUnknown,
        StringToIPv4Address(kIPAddress_8_8_8_8),
        0,
        StringToIPv4Address(kProxyIPAddressRemote),
        kProxyPortRemote,
        0,
        0,
        SocketInfo::kTimerStateUnknown);
  }
  SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state) {
    return SocketInfo(
        state,
        StringToIPv4Address(kProxyIPAddressLocal),
        kProxyPortLocal,
        StringToIPv4Address(kProxyIPAddressRemote),
        kProxyPortRemote,
        0,
        0,
        SocketInfo::kTimerStateUnknown);
  }
  SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state,
                                   SocketInfo::TimerState timer_state,
                                   uint64 transmit_queue_value) {
    return SocketInfo(
        state,
        StringToIPv4Address(kProxyIPAddressLocal),
        kProxyPortLocal,
        StringToIPv4Address(kProxyIPAddressRemote),
        kProxyPortRemote,
        transmit_queue_value,
        0,
        timer_state);
  }


  // Expectations
  void ExpectReset() {
    EXPECT_EQ(connection_.get(), health_checker_->connection_.get());
    EXPECT_EQ(&dispatcher_, health_checker_->dispatcher_);
    EXPECT_EQ(socket_, health_checker_->socket_.get());
    EXPECT_FALSE(socket_ == NULL);
    EXPECT_EQ(socket_info_reader_, health_checker_->socket_info_reader_.get());
    EXPECT_FALSE(socket_info_reader_ == NULL);
    EXPECT_FALSE(health_checker_->connection_complete_callback_.is_null());
    EXPECT_EQ(tcp_connection_, health_checker_->tcp_connection_.get());
    EXPECT_FALSE(tcp_connection_ == NULL);
    EXPECT_FALSE(health_checker_->health_check_in_progress_);
  }

  // Setup ConnectionHealthChecker::GetSocketInfo to return sock_info.
  // This only works if GetSocketInfo is called with kProxyFD.
  // If no matching sock_info is provided (Does not belong to proxy socket),
  // GetSocketInfo will (correctly) return false.
  void ExpectGetSocketInfoReturns(SocketInfo sock_info) {
    vector<SocketInfo> info_list;
    info_list.push_back(sock_info);
    EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
        .InSequence(seq_)
        .WillOnce(Invoke(this,
                         &ConnectionHealthCheckerTest::GetSockName));
    EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
        .InSequence(seq_)
        .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                        Return(true)));

  }
  void ExpectSuccessfulStart() {
    EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
    EXPECT_CALL(remote_ips_, GetRandomIP())
        .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
    EXPECT_CALL(
        *tcp_connection_,
        Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
              kProxyPortRemote))
        .InSequence(seq_)
        .WillOnce(Return(true));
  }
  void ExpectRetry() {
    EXPECT_CALL(*socket_, Close(kProxyFD))
        .InSequence(seq_);
    EXPECT_CALL(
        *tcp_connection_,
        Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
              kProxyPortRemote))
        .InSequence(seq_)
        .WillOnce(Return(true));
  }
  void ExpectStop() {
    if (tcp_connection_)
      EXPECT_CALL(*tcp_connection_, Stop())
          .InSequence(seq_);
  }
  void ExpectCleanUp() {
    EXPECT_CALL(*socket_, Close(kProxyFD))
        .InSequence(seq_);
    EXPECT_CALL(*tcp_connection_, Stop())
        .InSequence(seq_);
  }

  void VerifyAndClearAllExpectations() {
    Mock::VerifyAndClearExpectations(this);
    Mock::VerifyAndClearExpectations(tcp_connection_);
    Mock::VerifyAndClearExpectations(socket_);
    Mock::VerifyAndClearExpectations(socket_info_reader_);
  }

  // Needed for other mocks, but not for the tests directly.
  const string interface_name_;
  NiceMock<MockControl> control_;
  NiceMock<MockDeviceInfo> device_info_;
  vector<string> dns_servers_;

  scoped_refptr<NiceMock<MockConnection> > connection_;
  EventDispatcher dispatcher_;
  MockIPAddressStore remote_ips_;
  StrictMock<MockSockets> *socket_;
  StrictMock<MockSocketInfoReader> *socket_info_reader_;
  StrictMock<MockAsyncConnection> *tcp_connection_;
  // Expectations in the Expect* functions are put in this sequence.
  // This allows us to chain calls to Expect* functions.
  Sequence seq_;

  scoped_ptr<ConnectionHealthChecker> health_checker_;
};

TEST_F(ConnectionHealthCheckerTest, Constructor) {
  ExpectReset();
}

TEST_F(ConnectionHealthCheckerTest, SetConnection) {
  scoped_refptr<NiceMock<MockConnection> > new_connection
      = new NiceMock<MockConnection>(&device_info_);
  // If a health check was in progress when SetConnection is called, verify
  // that it restarts with the new connection.
  ExpectSuccessfulStart();
  health_checker_->Start();
  VerifyAndClearAllExpectations();

  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(true));
  EXPECT_CALL(*new_connection.get(), interface_name())
      .WillRepeatedly(ReturnRef(interface_name_));
  EXPECT_CALL(*this,
              ResultCallbackTarget(ConnectionHealthChecker::kResultUnknown));
  health_checker_->SetConnection(new_connection);
  EXPECT_NE(tcp_connection_, health_checker_->tcp_connection());
  EXPECT_EQ(new_connection.get(), health_checker_->connection());

  // health_checker_ has reset tcp_connection_ to a new object.
  // Since it owned tcp_connection_, the object has been destroyed.
  tcp_connection_ = NULL;
}

TEST_F(ConnectionHealthCheckerTest, GarbageCollectDNSClients) {
  dns_clients().clear();
  health_checker_->GarbageCollectDNSClients();
  EXPECT_TRUE(dns_clients().empty());

  for (int i = 0; i < 3; ++i) {
    MockDNSClient *dns_client = new MockDNSClient();
    EXPECT_CALL(*dns_client, IsActive())
        .WillOnce(Return(true))
        .WillOnce(Return(true))
        .WillOnce(Return(false));
    // Takes ownership.
    dns_clients().push_back(dns_client);
  }
  for (int i = 0; i < 2; ++i) {
    MockDNSClient *dns_client = new MockDNSClient();
    EXPECT_CALL(*dns_client, IsActive())
        .WillOnce(Return(false));
    // Takes ownership.
    dns_clients().push_back(dns_client);
  }

  EXPECT_EQ(5, dns_clients().size());
  health_checker_->GarbageCollectDNSClients();
  EXPECT_EQ(3, dns_clients().size());
  health_checker_->GarbageCollectDNSClients();
  EXPECT_EQ(3, dns_clients().size());
  health_checker_->GarbageCollectDNSClients();
  EXPECT_TRUE(dns_clients().empty());
}

TEST_F(ConnectionHealthCheckerTest, AddRemoteURL) {
  HTTPURL url;
  url.ParseFromString(kProxyURLRemote);
  string host = url.host();
  IPAddress remote_ip = StringToIPv4Address(kProxyIPAddressRemote);
  IPAddress remote_ip_2 = StringToIPv4Address(kIPAddress_8_8_8_8);

  MockDNSClientFactory *dns_client_factory
      = MockDNSClientFactory::GetInstance();
  vector<MockDNSClient *> dns_client_buffer;

  // All DNS queries fail.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    MockDNSClient *dns_client = new MockDNSClient();
    EXPECT_CALL(*dns_client, Start(host, _))
        .WillOnce(Return(false));
    dns_client_buffer.push_back(dns_client);
  }
  // Will pass ownership of dns_clients elements.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_,_,_,_,_,_))
        .InSequence(seq_)
        .WillOnce(Return(dns_client_buffer[i]));
  }
  EXPECT_CALL(remote_ips_, AddUnique(_)).Times(0);
  health_checker_->AddRemoteURL(kProxyURLRemote);
  Mock::VerifyAndClearExpectations(dns_client_factory);
  Mock::VerifyAndClearExpectations(&remote_ips_);
  dns_client_buffer.clear();
  dns_clients().clear();

  // All but one DNS queries fail, 1 succeeds.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    MockDNSClient *dns_client = new MockDNSClient();
    EXPECT_CALL(*dns_client, Start(host, _))
        .WillOnce(Return(true));
    dns_client_buffer.push_back(dns_client);
  }
  // Will pass ownership of dns_clients elements.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_,_,_,_,_,_))
        .InSequence(seq_)
        .WillOnce(Return(dns_client_buffer[i]));
  }
  EXPECT_CALL(remote_ips_, AddUnique(_));
  health_checker_->AddRemoteURL(kProxyURLRemote);
  for(int i = 0; i < NumDNSQueries() - 1; ++i) {
    InvokeGetDNSResultFailure();
  }
  InvokeGetDNSResultSuccess(remote_ip);
  Mock::VerifyAndClearExpectations(dns_client_factory);
  Mock::VerifyAndClearExpectations(&remote_ips_);
  dns_client_buffer.clear();
  dns_clients().clear();

  // Only 2 distinct IP addresses are returned.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    MockDNSClient *dns_client = new MockDNSClient();
    EXPECT_CALL(*dns_client, Start(host, _))
        .WillOnce(Return(true));
    dns_client_buffer.push_back(dns_client);
  }
  // Will pass ownership of dns_clients elements.
  for (int i = 0; i < NumDNSQueries(); ++i) {
    EXPECT_CALL(*dns_client_factory, CreateDNSClient(_,_,_,_,_,_))
        .InSequence(seq_)
        .WillOnce(Return(dns_client_buffer[i]));
  }
  EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip))).Times(4);
  EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip_2)));
  health_checker_->AddRemoteURL(kProxyURLRemote);
  for (int i = 0; i < NumDNSQueries() - 1; ++i) {
    InvokeGetDNSResultSuccess(remote_ip);
  }
  InvokeGetDNSResultSuccess(remote_ip_2);
  Mock::VerifyAndClearExpectations(dns_client_factory);
  Mock::VerifyAndClearExpectations(&remote_ips_);
  dns_client_buffer.clear();
  dns_clients().clear();
}

TEST_F(ConnectionHealthCheckerTest, GetSocketInfo) {
  SocketInfo sock_info;
  vector<SocketInfo> info_list;

  // GetSockName fails.
  EXPECT_CALL(*socket_, GetSockName(_,_,_))
      .WillOnce(Return(-1));
  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  Mock::VerifyAndClearExpectations(socket_);

  // GetSockName returns IPv6.
  EXPECT_CALL(*socket_, GetSockName(_,_,_))
      .WillOnce(
          Invoke(this,
                 &ConnectionHealthCheckerTest::GetSockNameReturnsIPv6));
  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  Mock::VerifyAndClearExpectations(socket_);

  // LoadTcpSocketInfo fails.
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
    .WillOnce(Return(false));
  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);

  // LoadTcpSocketInfo returns empty list.
  info_list.clear();
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                      Return(true)));
  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);

  // LoadTcpSocketInfo returns a list without our socket.
  info_list.clear();
  info_list.push_back(CreateSocketInfoOther());
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                      Return(true)));
  EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);

  // LoadTcpSocketInfo returns a list with only our socket.
  info_list.clear();
  info_list.push_back(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                      Return(true)));
  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
                  .IsSameSocketAs(sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);

  // LoadTcpSocketInfo returns a list with two sockets, including ours.
  info_list.clear();
  info_list.push_back(CreateSocketInfoOther());
  info_list.push_back(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                      Return(true)));
  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
                  .IsSameSocketAs(sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);

  info_list.clear();
  info_list.push_back(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
  info_list.push_back(CreateSocketInfoOther());
  EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
      .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
  EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
                      Return(true)));
  EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
  EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
                  .IsSameSocketAs(sock_info));
  Mock::VerifyAndClearExpectations(socket_);
  Mock::VerifyAndClearExpectations(socket_info_reader_);
}

TEST_F(ConnectionHealthCheckerTest, NextHealthCheckSample) {
  IPAddress ip = StringToIPv4Address(kProxyIPAddressRemote);
  ON_CALL(remote_ips_, GetRandomIP())
      .WillByDefault(Return(ip));

  health_checker_->set_num_connection_failures(MaxFailedConnectionAttempts());
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->NextHealthCheckSample();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  health_checker_->set_num_congested_queue_detected(
      MinCongestedQueueAttempts());
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
  health_checker_->NextHealthCheckSample();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts());
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
  health_checker_->NextHealthCheckSample();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  EXPECT_CALL(*tcp_connection_, Start(_,_)).WillOnce(Return(true));
  health_checker_->NextHealthCheckSample();
  VerifyAndClearAllExpectations();

  // This test assumes that there are at least 2 connection attempts left
  // before ConnectionHealthChecker gives up.
  EXPECT_CALL(*tcp_connection_, Start(_,_))
    .WillOnce(Return(false))
    .WillOnce(Return(true));
  short num_connection_failures = health_checker_->num_connection_failures();
  health_checker_->NextHealthCheckSample();
  EXPECT_EQ(num_connection_failures + 1,
            health_checker_->num_connection_failures());
}

TEST_F(ConnectionHealthCheckerTest, OnConnectionComplete) {
  // Test that num_connection_attempts is incremented on failure when
  // (1) Async Connection fails.
  health_checker_->set_num_connection_failures(
      MaxFailedConnectionAttempts() - 1);
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->OnConnectionComplete(false, -1);
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  // (2) The connection state is garbled up.
  health_checker_->set_num_connection_failures(
      MaxFailedConnectionAttempts() - 1);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->OnConnectionComplete(true, kProxyFD);
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  // (3) Send fails.
  health_checker_->set_num_connection_failures(
      MaxFailedConnectionAttempts() - 1);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished));
  EXPECT_CALL(*socket_, Send(kProxyFD, _, Gt(0), _)).WillOnce(Return(-1));
  EXPECT_CALL(*socket_, Error()).WillOnce(Return(kSocketError));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->OnConnectionComplete(true, kProxyFD);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(ConnectionHealthCheckerTest, VerifySentData) {
  // (1) Test that num_connection_attempts is incremented when the connection
  // state is garbled up.
  health_checker_->set_num_connection_failures(
      MaxFailedConnectionAttempts() - 1);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->set_sock_fd(kProxyFD);
  health_checker_->VerifySentData();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  // (2) Test that num_congested_queue_detected is incremented when all polling
  // attempts have expired.
  health_checker_->set_num_congested_queue_detected(
      MinCongestedQueueAttempts() - 1);
  health_checker_->set_num_tx_queue_polling_attempts(
      MaxSentDataPollingAttempts());
  health_checker_->set_old_transmit_queue_value(0);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
                            SocketInfo::kTimerStateRetransmitTimerPending,
                            1));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
  health_checker_->set_sock_fd(kProxyFD);
  health_checker_->VerifySentData();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  // (3) Test that num_successful_sends is incremented if everything goes fine.
  health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts() - 1);
  health_checker_->set_old_transmit_queue_value(0);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
                            SocketInfo::kTimerStateNoTimerPending,
                            0));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this,
      ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
  health_checker_->set_sock_fd(kProxyFD);
  health_checker_->VerifySentData();
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();

  // (4) Test that VerifySentData correctly polls the tcpinfo twice.
  // We want to immediately dispatch posted tasks.
  SetTCPStateUpdateWaitMilliseconds(0);
  health_checker_->set_num_congested_queue_detected(
      MinCongestedQueueAttempts() - 1);
  health_checker_->set_num_tx_queue_polling_attempts(
      MaxSentDataPollingAttempts() - 1);
  health_checker_->set_old_transmit_queue_value(0);
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
                            SocketInfo::kTimerStateRetransmitTimerPending,
                            1));
  ExpectGetSocketInfoReturns(
      CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
                            SocketInfo::kTimerStateRetransmitTimerPending,
                            1));
  EXPECT_CALL(*socket_, Close(kProxyFD));
  ExpectStop();
  EXPECT_CALL(
      *this, ResultCallbackTarget(
          ConnectionHealthChecker::kResultCongestedTxQueue))
      .InSequence(seq_);
  health_checker_->set_sock_fd(kProxyFD);
  health_checker_->VerifySentData();
  dispatcher_.DispatchPendingEvents();
  dispatcher_.DispatchPendingEvents();
  // Force an extra dispatch to make sure that VerifySentData did not poll an
  // extra time. This dispatch should be a no-op.
  dispatcher_.DispatchPendingEvents();
  VerifyAndClearAllExpectations();
}

// Flow: Start() -> Start()
// Expectation: Only one AsyncConnection is setup
TEST_F(ConnectionHealthCheckerTest, StartStartSkipsSecond) {
  EXPECT_CALL(*tcp_connection_, Start(_,_))
      .WillOnce(Return(true));
  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
  EXPECT_CALL(remote_ips_, GetRandomIP())
      .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
  health_checker_->Start();
  health_checker_->Start();
}

// Precondition: size(|remote_ips_|) > 0
// Flow: Start() -> Stop() before ConnectionComplete()
// Expectation: No call to |result_callback|
TEST_F(ConnectionHealthCheckerTest, StartStopNoCallback) {
  EXPECT_CALL(*tcp_connection_, Start(_,_))
      .WillOnce(Return(true));
  EXPECT_CALL(*tcp_connection_, Stop());
  EXPECT_CALL(*this, ResultCallbackTarget(_))
      .Times(0);
  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
  EXPECT_CALL(remote_ips_, GetRandomIP())
      .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
  health_checker_->Start();
  health_checker_->Stop();
}

// Precondition: Empty remote_ips_
// Flow: Start()
// Expectation: call |result_callback| with kResultUnknown
TEST_F(ConnectionHealthCheckerTest, StartImmediateFailure) {
  EXPECT_CALL(remote_ips_, Empty()).WillOnce(Return(true));
  EXPECT_CALL(*tcp_connection_, Stop());
  EXPECT_CALL(*this, ResultCallbackTarget(
                           ConnectionHealthChecker::kResultUnknown));
  health_checker_->Start();
  Mock::VerifyAndClearExpectations(this);
  Mock::VerifyAndClearExpectations(&remote_ips_);
  Mock::VerifyAndClearExpectations(tcp_connection_);

  EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
  EXPECT_CALL(remote_ips_, GetRandomIP())
      .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
  EXPECT_CALL(*tcp_connection_,
              Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
                    kProxyPortRemote))
      .Times(MaxFailedConnectionAttempts())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*tcp_connection_, Stop());
  EXPECT_CALL(*this, ResultCallbackTarget(
                           ConnectionHealthChecker::kResultConnectionFailure));
  health_checker_->Start();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(this);
  Mock::VerifyAndClearExpectations(tcp_connection_);
}

}  // namespace shill
