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