blob: 6b9d0cfbc73fdc41126c03551c3608ffb70f4227 [file] [log] [blame]
Prathmesh Prabhu40daa012013-04-03 10:35:03 -07001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/connection_health_checker.h"
6
7#include <arpa/inet.h>
8#include <string>
9#include <vector>
10
11#include <base/bind.h>
12#include <base/callback.h>
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070013#include <base/cancelable_callback.h>
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070014#include <base/memory/scoped_ptr.h>
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070015#include <base/memory/scoped_vector.h>
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070016#include <gtest/gtest.h>
17
18#include "shill/mock_async_connection.h"
19#include "shill/mock_connection.h"
20#include "shill/mock_control.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070021#include "shill/mock_device_info.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070022#include "shill/mock_dns_client.h"
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070023#include "shill/mock_dns_client_factory.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070024#include "shill/mock_event_dispatcher.h"
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070025#include "shill/mock_ip_address_store.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070026#include "shill/mock_socket_info_reader.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070027#include "shill/mock_sockets.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070028
29using base::Bind;
30using base::Callback;
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070031using base::Closure;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070032using base::Unretained;
33using std::string;
34using std::vector;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070035using ::testing::AtLeast;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070036using ::testing::DoAll;
37using ::testing::Gt;
38using ::testing::Invoke;
39using ::testing::Mock;
40using ::testing::NiceMock;
41using ::testing::Return;
42using ::testing::ReturnRef;
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070043using ::testing::SaveArg;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070044using ::testing::Sequence;
45using ::testing::SetArgumentPointee;
46using ::testing::StrictMock;
47using ::testing::Test;
48using ::testing::_;
49
50namespace shill {
51
52namespace {
53const char kInterfaceName[] = "int0";
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070054const char kIPAddress_8_8_8_8[] = "8.8.8.8";
55const char kProxyIPAddressRemote[] = "74.125.224.84";
56const char kProxyIPAddressLocal[] = "192.23.34.1";
57const char kProxyIPv6AddressLocal[] = "::ffff:192.23.34.1";
58const char kProxyURLRemote[] = "http://www.google.com";
59const int kProxyFD = 100;
Alex Vakulenko8a532292014-06-16 17:18:44 -070060const int16_t kProxyPortLocal = 5540;
61const int16_t kProxyPortRemote = 80;
Alex Vakulenko8a532292014-06-16 17:18:44 -070062} // namespace
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070063
64MATCHER_P(IsSameIPAddress, ip_addr, "") {
65 return arg.Equals(ip_addr);
66}
67
68class ConnectionHealthCheckerTest : public Test {
69 public:
70 ConnectionHealthCheckerTest()
71 : interface_name_(kInterfaceName),
72 device_info_(&control_, &dispatcher_,
73 reinterpret_cast<Metrics*>(NULL),
74 reinterpret_cast<Manager*>(NULL)),
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070075 connection_(new NiceMock<MockConnection>(&device_info_)),
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070076 socket_(NULL) {}
77
78 // Invokes
79 int GetSockName(int fd, struct sockaddr *addr_out, socklen_t *sockaddr_size) {
80 struct sockaddr_in addr;
81 EXPECT_EQ(kProxyFD, fd);
82 EXPECT_LE(sizeof(sockaddr_in), *sockaddr_size);
83 addr.sin_family = AF_INET;
84 inet_pton(AF_INET, kProxyIPAddressLocal, &addr.sin_addr);
85 addr.sin_port = htons(kProxyPortLocal);
86 memcpy(addr_out, &addr, sizeof(addr));
87 *sockaddr_size = sizeof(sockaddr_in);
88 return 0;
89 }
90
91 int GetSockNameReturnsIPv6(int fd, struct sockaddr *addr_out,
92 socklen_t *sockaddr_size) {
93 struct sockaddr_in6 addr;
94 EXPECT_EQ(kProxyFD, fd);
95 EXPECT_LE(sizeof(sockaddr_in6), *sockaddr_size);
96 addr.sin6_family = AF_INET6;
97 inet_pton(AF_INET6, kProxyIPv6AddressLocal, &addr.sin6_addr);
98 addr.sin6_port = htons(kProxyPortLocal);
99 memcpy(addr_out, &addr, sizeof(addr));
100 *sockaddr_size = sizeof(sockaddr_in6);
101 return 0;
102 }
103
104 void InvokeOnConnectionComplete(bool success, int sock_fd) {
105 health_checker_->OnConnectionComplete(success, sock_fd);
106 }
107
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700108 void InvokeGetDNSResultFailure() {
109 Error error(Error::kOperationFailed, "");
110 IPAddress address(IPAddress::kFamilyUnknown);
111 health_checker_->GetDNSResult(error, address);
112 }
113
114 void InvokeGetDNSResultSuccess(const IPAddress &address) {
115 Error error;
116 health_checker_->GetDNSResult(error, address);
117 }
118
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700119 protected:
120 void SetUp() {
121 EXPECT_CALL(*connection_.get(), interface_name())
122 .WillRepeatedly(ReturnRef(interface_name_));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700123 ON_CALL(*connection_.get(), dns_servers())
124 .WillByDefault(ReturnRef(dns_servers_));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700125 // ConnectionHealthChecker constructor should add some IPs
126 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(AtLeast(1));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700127 health_checker_.reset(
128 new ConnectionHealthChecker(
129 connection_,
130 &dispatcher_,
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700131 &remote_ips_,
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700132 Bind(&ConnectionHealthCheckerTest::ResultCallbackTarget,
133 Unretained(this))));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700134 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700135 socket_ = new StrictMock<MockSockets>();
136 tcp_connection_ = new StrictMock<MockAsyncConnection>();
137 socket_info_reader_ = new StrictMock<MockSocketInfoReader>();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700138 // Passes ownership for all of these.
139 health_checker_->socket_.reset(socket_);
140 health_checker_->tcp_connection_.reset(tcp_connection_);
141 health_checker_->socket_info_reader_.reset(socket_info_reader_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700142 health_checker_->dns_client_factory_ = MockDNSClientFactory::GetInstance();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700143 }
144
145 void TearDown() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700146 ExpectStop();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700147 }
148
149 // Accessors for private data in ConnectionHealthChecker.
150 const Sockets *socket() {
151 return health_checker_->socket_.get();
152 }
153 const AsyncConnection *tcp_connection() {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700154 return health_checker_->tcp_connection_.get();
155 }
156 ScopedVector<DNSClient> &dns_clients() {
157 return health_checker_->dns_clients_;
158 }
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700159 int NumDNSQueries() {
160 return ConnectionHealthChecker::kNumDNSQueries;
161 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700162 int MaxFailedConnectionAttempts() {
163 return ConnectionHealthChecker::kMaxFailedConnectionAttempts;
164 }
165 int MaxSentDataPollingAttempts() {
166 return ConnectionHealthChecker::kMaxSentDataPollingAttempts;
167 }
168 int MinCongestedQueueAttempts() {
169 return ConnectionHealthChecker::kMinCongestedQueueAttempts;
170 }
171 int MinSuccessfulSendAttempts() {
172 return ConnectionHealthChecker::kMinSuccessfulSendAttempts;
173 }
Prathmesh Prabhu81404c62013-05-08 17:04:28 -0700174 void SetTCPStateUpdateWaitMilliseconds(int new_wait) {
175 health_checker_->tcp_state_update_wait_milliseconds_ = new_wait;
176 }
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700177
178 // Mock Callbacks
179 MOCK_METHOD1(ResultCallbackTarget,
180 void(ConnectionHealthChecker::Result result));
181
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700182 // Helper methods
183 IPAddress StringToIPv4Address(const string &address_string) {
184 IPAddress ip_address(IPAddress::kFamilyIPv4);
185 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
186 return ip_address;
187 }
188 // Naming: CreateSocketInfo
189 // + (Proxy/Other) : TCP connection for proxy socket / some other
190 // socket.
191 // + arg1: Pass in any SocketInfo::ConnectionState you want.
192 // + arg2: Pass in any value of transmit_queue_value you want.
193 SocketInfo CreateSocketInfoOther() {
194 return SocketInfo(
195 SocketInfo::kConnectionStateUnknown,
196 StringToIPv4Address(kIPAddress_8_8_8_8),
197 0,
198 StringToIPv4Address(kProxyIPAddressRemote),
199 kProxyPortRemote,
200 0,
201 0,
202 SocketInfo::kTimerStateUnknown);
203 }
204 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state) {
205 return SocketInfo(
206 state,
207 StringToIPv4Address(kProxyIPAddressLocal),
208 kProxyPortLocal,
209 StringToIPv4Address(kProxyIPAddressRemote),
210 kProxyPortRemote,
211 0,
212 0,
213 SocketInfo::kTimerStateUnknown);
214 }
215 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state,
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700216 SocketInfo::TimerState timer_state,
Ben Chan7fab8972014-08-10 17:14:46 -0700217 uint64_t transmit_queue_value) {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700218 return SocketInfo(
219 state,
220 StringToIPv4Address(kProxyIPAddressLocal),
221 kProxyPortLocal,
222 StringToIPv4Address(kProxyIPAddressRemote),
223 kProxyPortRemote,
224 transmit_queue_value,
225 0,
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700226 timer_state);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700227 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700228
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700229
230 // Expectations
231 void ExpectReset() {
232 EXPECT_EQ(connection_.get(), health_checker_->connection_.get());
233 EXPECT_EQ(&dispatcher_, health_checker_->dispatcher_);
234 EXPECT_EQ(socket_, health_checker_->socket_.get());
235 EXPECT_FALSE(socket_ == NULL);
236 EXPECT_EQ(socket_info_reader_, health_checker_->socket_info_reader_.get());
237 EXPECT_FALSE(socket_info_reader_ == NULL);
238 EXPECT_FALSE(health_checker_->connection_complete_callback_.is_null());
239 EXPECT_EQ(tcp_connection_, health_checker_->tcp_connection_.get());
240 EXPECT_FALSE(tcp_connection_ == NULL);
241 EXPECT_FALSE(health_checker_->health_check_in_progress_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700242 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700243
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700244 // Setup ConnectionHealthChecker::GetSocketInfo to return sock_info.
245 // This only works if GetSocketInfo is called with kProxyFD.
246 // If no matching sock_info is provided (Does not belong to proxy socket),
247 // GetSocketInfo will (correctly) return false.
248 void ExpectGetSocketInfoReturns(SocketInfo sock_info) {
249 vector<SocketInfo> info_list;
250 info_list.push_back(sock_info);
251 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
252 .InSequence(seq_)
253 .WillOnce(Invoke(this,
254 &ConnectionHealthCheckerTest::GetSockName));
255 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
256 .InSequence(seq_)
257 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
258 Return(true)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700259 }
260 void ExpectSuccessfulStart() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700261 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
262 EXPECT_CALL(remote_ips_, GetRandomIP())
263 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700264 EXPECT_CALL(
265 *tcp_connection_,
266 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
267 kProxyPortRemote))
268 .InSequence(seq_)
269 .WillOnce(Return(true));
270 }
271 void ExpectRetry() {
272 EXPECT_CALL(*socket_, Close(kProxyFD))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700273 .InSequence(seq_);
274 EXPECT_CALL(
275 *tcp_connection_,
276 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
277 kProxyPortRemote))
278 .InSequence(seq_)
279 .WillOnce(Return(true));
280 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700281 void ExpectStop() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700282 if (tcp_connection_)
283 EXPECT_CALL(*tcp_connection_, Stop())
284 .InSequence(seq_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700285 }
286 void ExpectCleanUp() {
287 EXPECT_CALL(*socket_, Close(kProxyFD))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700288 .InSequence(seq_);
289 EXPECT_CALL(*tcp_connection_, Stop())
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700290 .InSequence(seq_);
291 }
292
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700293 void VerifyAndClearAllExpectations() {
294 Mock::VerifyAndClearExpectations(this);
295 Mock::VerifyAndClearExpectations(tcp_connection_);
296 Mock::VerifyAndClearExpectations(socket_);
297 Mock::VerifyAndClearExpectations(socket_info_reader_);
298 }
299
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700300 // Needed for other mocks, but not for the tests directly.
301 const string interface_name_;
302 NiceMock<MockControl> control_;
303 NiceMock<MockDeviceInfo> device_info_;
304 vector<string> dns_servers_;
305
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700306 scoped_refptr<NiceMock<MockConnection> > connection_;
307 EventDispatcher dispatcher_;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700308 MockIPAddressStore remote_ips_;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700309 StrictMock<MockSockets> *socket_;
310 StrictMock<MockSocketInfoReader> *socket_info_reader_;
311 StrictMock<MockAsyncConnection> *tcp_connection_;
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700312 // Expectations in the Expect* functions are put in this sequence.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700313 // This allows us to chain calls to Expect* functions.
314 Sequence seq_;
315
316 scoped_ptr<ConnectionHealthChecker> health_checker_;
317};
318
319TEST_F(ConnectionHealthCheckerTest, Constructor) {
320 ExpectReset();
321}
322
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700323TEST_F(ConnectionHealthCheckerTest, SetConnection) {
324 scoped_refptr<NiceMock<MockConnection> > new_connection
325 = new NiceMock<MockConnection>(&device_info_);
326 // If a health check was in progress when SetConnection is called, verify
327 // that it restarts with the new connection.
328 ExpectSuccessfulStart();
329 health_checker_->Start();
330 VerifyAndClearAllExpectations();
Paul Stewart41a071e2013-04-26 07:56:04 -0700331
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700332 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(true));
333 EXPECT_CALL(*new_connection.get(), interface_name())
334 .WillRepeatedly(ReturnRef(interface_name_));
335 EXPECT_CALL(*this,
336 ResultCallbackTarget(ConnectionHealthChecker::kResultUnknown));
337 health_checker_->SetConnection(new_connection);
338 EXPECT_NE(tcp_connection_, health_checker_->tcp_connection());
339 EXPECT_EQ(new_connection.get(), health_checker_->connection());
Paul Stewart41a071e2013-04-26 07:56:04 -0700340
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700341 // health_checker_ has reset tcp_connection_ to a new object.
342 // Since it owned tcp_connection_, the object has been destroyed.
343 tcp_connection_ = NULL;
Paul Stewart41a071e2013-04-26 07:56:04 -0700344}
345
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700346TEST_F(ConnectionHealthCheckerTest, GarbageCollectDNSClients) {
347 dns_clients().clear();
348 health_checker_->GarbageCollectDNSClients();
349 EXPECT_TRUE(dns_clients().empty());
350
351 for (int i = 0; i < 3; ++i) {
352 MockDNSClient *dns_client = new MockDNSClient();
353 EXPECT_CALL(*dns_client, IsActive())
354 .WillOnce(Return(true))
355 .WillOnce(Return(true))
356 .WillOnce(Return(false));
357 // Takes ownership.
358 dns_clients().push_back(dns_client);
359 }
360 for (int i = 0; i < 2; ++i) {
361 MockDNSClient *dns_client = new MockDNSClient();
362 EXPECT_CALL(*dns_client, IsActive())
363 .WillOnce(Return(false));
364 // Takes ownership.
365 dns_clients().push_back(dns_client);
366 }
367
368 EXPECT_EQ(5, dns_clients().size());
369 health_checker_->GarbageCollectDNSClients();
370 EXPECT_EQ(3, dns_clients().size());
371 health_checker_->GarbageCollectDNSClients();
372 EXPECT_EQ(3, dns_clients().size());
373 health_checker_->GarbageCollectDNSClients();
374 EXPECT_TRUE(dns_clients().empty());
375}
376
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700377TEST_F(ConnectionHealthCheckerTest, AddRemoteURL) {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700378 HTTPURL url;
379 url.ParseFromString(kProxyURLRemote);
380 string host = url.host();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700381 IPAddress remote_ip = StringToIPv4Address(kProxyIPAddressRemote);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700382 IPAddress remote_ip_2 = StringToIPv4Address(kIPAddress_8_8_8_8);
383
384 MockDNSClientFactory *dns_client_factory
385 = MockDNSClientFactory::GetInstance();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700386 vector<MockDNSClient *> dns_client_buffer;
387
388 // All DNS queries fail.
389 for (int i = 0; i < NumDNSQueries(); ++i) {
390 MockDNSClient *dns_client = new MockDNSClient();
391 EXPECT_CALL(*dns_client, Start(host, _))
392 .WillOnce(Return(false));
393 dns_client_buffer.push_back(dns_client);
394 }
395 // Will pass ownership of dns_clients elements.
396 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700397 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700398 .InSequence(seq_)
399 .WillOnce(Return(dns_client_buffer[i]));
400 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700401 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(0);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700402 health_checker_->AddRemoteURL(kProxyURLRemote);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700403 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700404 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700405 dns_client_buffer.clear();
406 dns_clients().clear();
407
408 // All but one DNS queries fail, 1 succeeds.
409 for (int i = 0; i < NumDNSQueries(); ++i) {
410 MockDNSClient *dns_client = new MockDNSClient();
411 EXPECT_CALL(*dns_client, Start(host, _))
412 .WillOnce(Return(true));
413 dns_client_buffer.push_back(dns_client);
414 }
415 // Will pass ownership of dns_clients elements.
416 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700417 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700418 .InSequence(seq_)
419 .WillOnce(Return(dns_client_buffer[i]));
420 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700421 EXPECT_CALL(remote_ips_, AddUnique(_));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700422 health_checker_->AddRemoteURL(kProxyURLRemote);
Alex Vakulenko8a532292014-06-16 17:18:44 -0700423 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700424 InvokeGetDNSResultFailure();
425 }
426 InvokeGetDNSResultSuccess(remote_ip);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700427 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700428 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700429 dns_client_buffer.clear();
430 dns_clients().clear();
431
432 // Only 2 distinct IP addresses are returned.
433 for (int i = 0; i < NumDNSQueries(); ++i) {
434 MockDNSClient *dns_client = new MockDNSClient();
435 EXPECT_CALL(*dns_client, Start(host, _))
436 .WillOnce(Return(true));
437 dns_client_buffer.push_back(dns_client);
438 }
439 // Will pass ownership of dns_clients elements.
440 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700441 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700442 .InSequence(seq_)
443 .WillOnce(Return(dns_client_buffer[i]));
444 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700445 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip))).Times(4);
446 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip_2)));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700447 health_checker_->AddRemoteURL(kProxyURLRemote);
448 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
449 InvokeGetDNSResultSuccess(remote_ip);
450 }
451 InvokeGetDNSResultSuccess(remote_ip_2);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700452 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700453 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700454 dns_client_buffer.clear();
455 dns_clients().clear();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700456}
457
458TEST_F(ConnectionHealthCheckerTest, GetSocketInfo) {
459 SocketInfo sock_info;
460 vector<SocketInfo> info_list;
461
462 // GetSockName fails.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700463 EXPECT_CALL(*socket_, GetSockName(_, _, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700464 .WillOnce(Return(-1));
465 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
466 Mock::VerifyAndClearExpectations(socket_);
467
468 // GetSockName returns IPv6.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700469 EXPECT_CALL(*socket_, GetSockName(_, _, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700470 .WillOnce(
471 Invoke(this,
472 &ConnectionHealthCheckerTest::GetSockNameReturnsIPv6));
473 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
474 Mock::VerifyAndClearExpectations(socket_);
475
476 // LoadTcpSocketInfo fails.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700477 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
478 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
479 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
480 .WillOnce(Return(false));
481 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
482 Mock::VerifyAndClearExpectations(socket_);
483 Mock::VerifyAndClearExpectations(socket_info_reader_);
484
485 // LoadTcpSocketInfo returns empty list.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700486 info_list.clear();
487 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
488 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
489 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
490 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
491 Return(true)));
492 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
493 Mock::VerifyAndClearExpectations(socket_);
494 Mock::VerifyAndClearExpectations(socket_info_reader_);
495
496 // LoadTcpSocketInfo returns a list without our socket.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700497 info_list.clear();
498 info_list.push_back(CreateSocketInfoOther());
499 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
500 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
501 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
502 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
503 Return(true)));
504 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
505 Mock::VerifyAndClearExpectations(socket_);
506 Mock::VerifyAndClearExpectations(socket_info_reader_);
507
508 // LoadTcpSocketInfo returns a list with only our socket.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700509 info_list.clear();
510 info_list.push_back(
511 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
512 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
513 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
514 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
515 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
516 Return(true)));
517 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
518 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
519 .IsSameSocketAs(sock_info));
520 Mock::VerifyAndClearExpectations(socket_);
521 Mock::VerifyAndClearExpectations(socket_info_reader_);
522
523 // LoadTcpSocketInfo returns a list with two sockets, including ours.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700524 info_list.clear();
525 info_list.push_back(CreateSocketInfoOther());
526 info_list.push_back(
527 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
528 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
529 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
530 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
531 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
532 Return(true)));
533 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
534 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
535 .IsSameSocketAs(sock_info));
536 Mock::VerifyAndClearExpectations(socket_);
537 Mock::VerifyAndClearExpectations(socket_info_reader_);
538
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700539 info_list.clear();
540 info_list.push_back(
541 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
542 info_list.push_back(CreateSocketInfoOther());
543 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
544 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
545 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
546 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
547 Return(true)));
548 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
549 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
550 .IsSameSocketAs(sock_info));
551 Mock::VerifyAndClearExpectations(socket_);
552 Mock::VerifyAndClearExpectations(socket_info_reader_);
553}
554
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700555TEST_F(ConnectionHealthCheckerTest, NextHealthCheckSample) {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700556 IPAddress ip = StringToIPv4Address(kProxyIPAddressRemote);
557 ON_CALL(remote_ips_, GetRandomIP())
558 .WillByDefault(Return(ip));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700559
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700560 health_checker_->set_num_connection_failures(MaxFailedConnectionAttempts());
561 ExpectStop();
562 EXPECT_CALL(
563 *this,
564 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
565 health_checker_->NextHealthCheckSample();
566 dispatcher_.DispatchPendingEvents();
567 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700568
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700569 health_checker_->set_num_congested_queue_detected(
570 MinCongestedQueueAttempts());
571 ExpectStop();
572 EXPECT_CALL(
573 *this,
574 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
575 health_checker_->NextHealthCheckSample();
576 dispatcher_.DispatchPendingEvents();
577 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700578
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700579 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts());
580 ExpectStop();
581 EXPECT_CALL(
582 *this,
583 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
584 health_checker_->NextHealthCheckSample();
585 dispatcher_.DispatchPendingEvents();
586 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700587
Alex Vakulenko8a532292014-06-16 17:18:44 -0700588 EXPECT_CALL(*tcp_connection_, Start(_, _)).WillOnce(Return(true));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700589 health_checker_->NextHealthCheckSample();
590 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700591
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700592 // This test assumes that there are at least 2 connection attempts left
593 // before ConnectionHealthChecker gives up.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700594 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700595 .WillOnce(Return(false))
596 .WillOnce(Return(true));
Alex Vakulenko8a532292014-06-16 17:18:44 -0700597 int16_t num_connection_failures = health_checker_->num_connection_failures();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700598 health_checker_->NextHealthCheckSample();
599 EXPECT_EQ(num_connection_failures + 1,
600 health_checker_->num_connection_failures());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700601}
602
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700603TEST_F(ConnectionHealthCheckerTest, OnConnectionComplete) {
604 // Test that num_connection_attempts is incremented on failure when
605 // (1) Async Connection fails.
606 health_checker_->set_num_connection_failures(
607 MaxFailedConnectionAttempts() - 1);
608 ExpectStop();
609 EXPECT_CALL(
610 *this,
611 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
612 health_checker_->OnConnectionComplete(false, -1);
613 dispatcher_.DispatchPendingEvents();
614 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700615
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700616 // (2) The connection state is garbled up.
617 health_checker_->set_num_connection_failures(
618 MaxFailedConnectionAttempts() - 1);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700619 ExpectGetSocketInfoReturns(
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700620 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
621 EXPECT_CALL(*socket_, Close(kProxyFD));
622 ExpectStop();
623 EXPECT_CALL(
624 *this,
625 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
626 health_checker_->OnConnectionComplete(true, kProxyFD);
627 dispatcher_.DispatchPendingEvents();
628 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700629
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700630 // (3) Send fails.
631 health_checker_->set_num_connection_failures(
632 MaxFailedConnectionAttempts() - 1);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700633 ExpectGetSocketInfoReturns(
634 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700635 EXPECT_CALL(*socket_, Send(kProxyFD, _, Gt(0), _)).WillOnce(Return(-1));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700636 EXPECT_CALL(*socket_, Close(kProxyFD));
637 ExpectStop();
638 EXPECT_CALL(
639 *this,
640 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
641 health_checker_->OnConnectionComplete(true, kProxyFD);
642 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700643}
644
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700645TEST_F(ConnectionHealthCheckerTest, VerifySentData) {
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700646 // (1) Test that num_connection_attempts is incremented when the connection
647 // state is garbled up.
648 health_checker_->set_num_connection_failures(
649 MaxFailedConnectionAttempts() - 1);
650 ExpectGetSocketInfoReturns(
651 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
652 EXPECT_CALL(*socket_, Close(kProxyFD));
653 ExpectStop();
654 EXPECT_CALL(
655 *this,
656 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
657 health_checker_->set_sock_fd(kProxyFD);
658 health_checker_->VerifySentData();
659 dispatcher_.DispatchPendingEvents();
660 VerifyAndClearAllExpectations();
661
662 // (2) Test that num_congested_queue_detected is incremented when all polling
663 // attempts have expired.
664 health_checker_->set_num_congested_queue_detected(
665 MinCongestedQueueAttempts() - 1);
666 health_checker_->set_num_tx_queue_polling_attempts(
667 MaxSentDataPollingAttempts());
668 health_checker_->set_old_transmit_queue_value(0);
669 ExpectGetSocketInfoReturns(
670 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
671 SocketInfo::kTimerStateRetransmitTimerPending,
672 1));
673 EXPECT_CALL(*socket_, Close(kProxyFD));
674 ExpectStop();
675 EXPECT_CALL(
676 *this,
677 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
678 health_checker_->set_sock_fd(kProxyFD);
679 health_checker_->VerifySentData();
680 dispatcher_.DispatchPendingEvents();
681 VerifyAndClearAllExpectations();
682
683 // (3) Test that num_successful_sends is incremented if everything goes fine.
684 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts() - 1);
685 health_checker_->set_old_transmit_queue_value(0);
686 ExpectGetSocketInfoReturns(
687 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
688 SocketInfo::kTimerStateNoTimerPending,
689 0));
690 EXPECT_CALL(*socket_, Close(kProxyFD));
691 ExpectStop();
692 EXPECT_CALL(
693 *this,
694 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
695 health_checker_->set_sock_fd(kProxyFD);
696 health_checker_->VerifySentData();
697 dispatcher_.DispatchPendingEvents();
698 VerifyAndClearAllExpectations();
Prathmesh Prabhu81404c62013-05-08 17:04:28 -0700699
700 // (4) Test that VerifySentData correctly polls the tcpinfo twice.
701 // We want to immediately dispatch posted tasks.
702 SetTCPStateUpdateWaitMilliseconds(0);
703 health_checker_->set_num_congested_queue_detected(
704 MinCongestedQueueAttempts() - 1);
705 health_checker_->set_num_tx_queue_polling_attempts(
706 MaxSentDataPollingAttempts() - 1);
707 health_checker_->set_old_transmit_queue_value(0);
708 ExpectGetSocketInfoReturns(
709 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
710 SocketInfo::kTimerStateRetransmitTimerPending,
711 1));
712 ExpectGetSocketInfoReturns(
713 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
714 SocketInfo::kTimerStateRetransmitTimerPending,
715 1));
716 EXPECT_CALL(*socket_, Close(kProxyFD));
717 ExpectStop();
718 EXPECT_CALL(
719 *this, ResultCallbackTarget(
720 ConnectionHealthChecker::kResultCongestedTxQueue))
721 .InSequence(seq_);
722 health_checker_->set_sock_fd(kProxyFD);
723 health_checker_->VerifySentData();
724 dispatcher_.DispatchPendingEvents();
725 dispatcher_.DispatchPendingEvents();
726 // Force an extra dispatch to make sure that VerifySentData did not poll an
727 // extra time. This dispatch should be a no-op.
728 dispatcher_.DispatchPendingEvents();
729 VerifyAndClearAllExpectations();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700730}
731
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700732// Flow: Start() -> Start()
733// Expectation: Only one AsyncConnection is setup
734TEST_F(ConnectionHealthCheckerTest, StartStartSkipsSecond) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700735 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700736 .WillOnce(Return(true));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700737 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
738 EXPECT_CALL(remote_ips_, GetRandomIP())
739 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700740 health_checker_->Start();
741 health_checker_->Start();
742}
743
744// Precondition: size(|remote_ips_|) > 0
745// Flow: Start() -> Stop() before ConnectionComplete()
746// Expectation: No call to |result_callback|
747TEST_F(ConnectionHealthCheckerTest, StartStopNoCallback) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700748 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700749 .WillOnce(Return(true));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700750 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700751 EXPECT_CALL(*this, ResultCallbackTarget(_))
752 .Times(0);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700753 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
754 EXPECT_CALL(remote_ips_, GetRandomIP())
755 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700756 health_checker_->Start();
757 health_checker_->Stop();
758}
759
760// Precondition: Empty remote_ips_
761// Flow: Start()
762// Expectation: call |result_callback| with kResultUnknown
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700763TEST_F(ConnectionHealthCheckerTest, StartImmediateFailure) {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700764 EXPECT_CALL(remote_ips_, Empty()).WillOnce(Return(true));
765 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700766 EXPECT_CALL(*this, ResultCallbackTarget(
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700767 ConnectionHealthChecker::kResultUnknown));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700768 health_checker_->Start();
769 Mock::VerifyAndClearExpectations(this);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700770 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700771 Mock::VerifyAndClearExpectations(tcp_connection_);
772
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700773 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
774 EXPECT_CALL(remote_ips_, GetRandomIP())
775 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700776 EXPECT_CALL(*tcp_connection_,
777 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
778 kProxyPortRemote))
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700779 .Times(MaxFailedConnectionAttempts())
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700780 .WillRepeatedly(Return(false));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700781 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700782 EXPECT_CALL(*this, ResultCallbackTarget(
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700783 ConnectionHealthChecker::kResultConnectionFailure));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700784 health_checker_->Start();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700785 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700786 Mock::VerifyAndClearExpectations(this);
787 Mock::VerifyAndClearExpectations(tcp_connection_);
788}
789
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700790} // namespace shill