blob: 1bbc1cb3220cf2c8301cdb70e98787c724a6e4b7 [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>
Ben Chan22f1fbc2014-10-17 14:18:07 -07008
9#include <memory>
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070010#include <string>
11#include <vector>
12
13#include <base/bind.h>
14#include <base/callback.h>
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070015#include <base/cancelable_callback.h>
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070016#include <base/memory/scoped_vector.h>
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070017#include <gtest/gtest.h>
18
19#include "shill/mock_async_connection.h"
20#include "shill/mock_connection.h"
21#include "shill/mock_control.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070022#include "shill/mock_device_info.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070023#include "shill/mock_dns_client.h"
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070024#include "shill/mock_dns_client_factory.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070025#include "shill/mock_event_dispatcher.h"
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070026#include "shill/mock_ip_address_store.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070027#include "shill/mock_socket_info_reader.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070028#include "shill/net/mock_sockets.h"
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070029
30using base::Bind;
31using base::Callback;
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070032using base::Closure;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070033using base::Unretained;
34using std::string;
35using std::vector;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070036using ::testing::AtLeast;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070037using ::testing::DoAll;
38using ::testing::Gt;
39using ::testing::Invoke;
40using ::testing::Mock;
41using ::testing::NiceMock;
42using ::testing::Return;
43using ::testing::ReturnRef;
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -070044using ::testing::SaveArg;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070045using ::testing::Sequence;
46using ::testing::SetArgumentPointee;
47using ::testing::StrictMock;
48using ::testing::Test;
49using ::testing::_;
50
51namespace shill {
52
53namespace {
54const char kInterfaceName[] = "int0";
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070055const char kIPAddress_8_8_8_8[] = "8.8.8.8";
56const char kProxyIPAddressRemote[] = "74.125.224.84";
57const char kProxyIPAddressLocal[] = "192.23.34.1";
58const char kProxyIPv6AddressLocal[] = "::ffff:192.23.34.1";
59const char kProxyURLRemote[] = "http://www.google.com";
60const int kProxyFD = 100;
Alex Vakulenko8a532292014-06-16 17:18:44 -070061const int16_t kProxyPortLocal = 5540;
62const int16_t kProxyPortRemote = 80;
Alex Vakulenko8a532292014-06-16 17:18:44 -070063} // namespace
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070064
65MATCHER_P(IsSameIPAddress, ip_addr, "") {
66 return arg.Equals(ip_addr);
67}
68
69class ConnectionHealthCheckerTest : public Test {
70 public:
71 ConnectionHealthCheckerTest()
72 : interface_name_(kInterfaceName),
Ben Chancc225ef2014-09-30 13:26:51 -070073 device_info_(&control_, &dispatcher_, nullptr, nullptr),
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -070074 connection_(new NiceMock<MockConnection>(&device_info_)),
Ben Chancc225ef2014-09-30 13:26:51 -070075 socket_(nullptr) {}
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070076
77 // Invokes
Paul Stewart3b30ca52015-06-16 13:13:10 -070078 int GetSockName(int fd, struct sockaddr* addr_out, socklen_t* sockaddr_size) {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070079 struct sockaddr_in addr;
80 EXPECT_EQ(kProxyFD, fd);
81 EXPECT_LE(sizeof(sockaddr_in), *sockaddr_size);
82 addr.sin_family = AF_INET;
83 inet_pton(AF_INET, kProxyIPAddressLocal, &addr.sin_addr);
84 addr.sin_port = htons(kProxyPortLocal);
85 memcpy(addr_out, &addr, sizeof(addr));
86 *sockaddr_size = sizeof(sockaddr_in);
87 return 0;
88 }
89
Paul Stewart3b30ca52015-06-16 13:13:10 -070090 int GetSockNameReturnsIPv6(int fd, struct sockaddr* addr_out,
91 socklen_t* sockaddr_size) {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -070092 struct sockaddr_in6 addr;
93 EXPECT_EQ(kProxyFD, fd);
94 EXPECT_LE(sizeof(sockaddr_in6), *sockaddr_size);
95 addr.sin6_family = AF_INET6;
96 inet_pton(AF_INET6, kProxyIPv6AddressLocal, &addr.sin6_addr);
97 addr.sin6_port = htons(kProxyPortLocal);
98 memcpy(addr_out, &addr, sizeof(addr));
99 *sockaddr_size = sizeof(sockaddr_in6);
100 return 0;
101 }
102
103 void InvokeOnConnectionComplete(bool success, int sock_fd) {
104 health_checker_->OnConnectionComplete(success, sock_fd);
105 }
106
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700107 void InvokeGetDNSResultFailure() {
108 Error error(Error::kOperationFailed, "");
109 IPAddress address(IPAddress::kFamilyUnknown);
110 health_checker_->GetDNSResult(error, address);
111 }
112
Paul Stewart3b30ca52015-06-16 13:13:10 -0700113 void InvokeGetDNSResultSuccess(const IPAddress& address) {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700114 Error error;
115 health_checker_->GetDNSResult(error, address);
116 }
117
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700118 protected:
119 void SetUp() {
120 EXPECT_CALL(*connection_.get(), interface_name())
121 .WillRepeatedly(ReturnRef(interface_name_));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700122 ON_CALL(*connection_.get(), dns_servers())
123 .WillByDefault(ReturnRef(dns_servers_));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700124 // ConnectionHealthChecker constructor should add some IPs
125 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(AtLeast(1));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700126 health_checker_.reset(
127 new ConnectionHealthChecker(
128 connection_,
129 &dispatcher_,
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700130 &remote_ips_,
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700131 Bind(&ConnectionHealthCheckerTest::ResultCallbackTarget,
132 Unretained(this))));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700133 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700134 socket_ = new StrictMock<MockSockets>();
135 tcp_connection_ = new StrictMock<MockAsyncConnection>();
136 socket_info_reader_ = new StrictMock<MockSocketInfoReader>();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700137 // Passes ownership for all of these.
138 health_checker_->socket_.reset(socket_);
139 health_checker_->tcp_connection_.reset(tcp_connection_);
140 health_checker_->socket_info_reader_.reset(socket_info_reader_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700141 health_checker_->dns_client_factory_ = MockDNSClientFactory::GetInstance();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700142 }
143
144 void TearDown() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700145 ExpectStop();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700146 }
147
148 // Accessors for private data in ConnectionHealthChecker.
Paul Stewart3b30ca52015-06-16 13:13:10 -0700149 const Sockets* socket() {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700150 return health_checker_->socket_.get();
151 }
Paul Stewart3b30ca52015-06-16 13:13:10 -0700152 const AsyncConnection* tcp_connection() {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700153 return health_checker_->tcp_connection_.get();
154 }
Paul Stewart3b30ca52015-06-16 13:13:10 -0700155 ScopedVector<DNSClient>& dns_clients() {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700156 return health_checker_->dns_clients_;
157 }
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700158 int NumDNSQueries() {
159 return ConnectionHealthChecker::kNumDNSQueries;
160 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700161 int MaxFailedConnectionAttempts() {
162 return ConnectionHealthChecker::kMaxFailedConnectionAttempts;
163 }
164 int MaxSentDataPollingAttempts() {
165 return ConnectionHealthChecker::kMaxSentDataPollingAttempts;
166 }
167 int MinCongestedQueueAttempts() {
168 return ConnectionHealthChecker::kMinCongestedQueueAttempts;
169 }
170 int MinSuccessfulSendAttempts() {
171 return ConnectionHealthChecker::kMinSuccessfulSendAttempts;
172 }
Prathmesh Prabhu81404c62013-05-08 17:04:28 -0700173 void SetTCPStateUpdateWaitMilliseconds(int new_wait) {
174 health_checker_->tcp_state_update_wait_milliseconds_ = new_wait;
175 }
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700176
177 // Mock Callbacks
178 MOCK_METHOD1(ResultCallbackTarget,
179 void(ConnectionHealthChecker::Result result));
180
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700181 // Helper methods
Paul Stewart3b30ca52015-06-16 13:13:10 -0700182 IPAddress StringToIPv4Address(const string& address_string) {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700183 IPAddress ip_address(IPAddress::kFamilyIPv4);
184 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
185 return ip_address;
186 }
187 // Naming: CreateSocketInfo
188 // + (Proxy/Other) : TCP connection for proxy socket / some other
189 // socket.
190 // + arg1: Pass in any SocketInfo::ConnectionState you want.
191 // + arg2: Pass in any value of transmit_queue_value you want.
192 SocketInfo CreateSocketInfoOther() {
193 return SocketInfo(
194 SocketInfo::kConnectionStateUnknown,
195 StringToIPv4Address(kIPAddress_8_8_8_8),
196 0,
197 StringToIPv4Address(kProxyIPAddressRemote),
198 kProxyPortRemote,
199 0,
200 0,
201 SocketInfo::kTimerStateUnknown);
202 }
203 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state) {
204 return SocketInfo(
205 state,
206 StringToIPv4Address(kProxyIPAddressLocal),
207 kProxyPortLocal,
208 StringToIPv4Address(kProxyIPAddressRemote),
209 kProxyPortRemote,
210 0,
211 0,
212 SocketInfo::kTimerStateUnknown);
213 }
214 SocketInfo CreateSocketInfoProxy(SocketInfo::ConnectionState state,
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700215 SocketInfo::TimerState timer_state,
Ben Chan7fab8972014-08-10 17:14:46 -0700216 uint64_t transmit_queue_value) {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700217 return SocketInfo(
218 state,
219 StringToIPv4Address(kProxyIPAddressLocal),
220 kProxyPortLocal,
221 StringToIPv4Address(kProxyIPAddressRemote),
222 kProxyPortRemote,
223 transmit_queue_value,
224 0,
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700225 timer_state);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700226 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700227
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700228
229 // Expectations
230 void ExpectReset() {
231 EXPECT_EQ(connection_.get(), health_checker_->connection_.get());
232 EXPECT_EQ(&dispatcher_, health_checker_->dispatcher_);
233 EXPECT_EQ(socket_, health_checker_->socket_.get());
Ben Chancc225ef2014-09-30 13:26:51 -0700234 EXPECT_FALSE(socket_ == nullptr);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700235 EXPECT_EQ(socket_info_reader_, health_checker_->socket_info_reader_.get());
Ben Chancc225ef2014-09-30 13:26:51 -0700236 EXPECT_FALSE(socket_info_reader_ == nullptr);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700237 EXPECT_FALSE(health_checker_->connection_complete_callback_.is_null());
238 EXPECT_EQ(tcp_connection_, health_checker_->tcp_connection_.get());
Ben Chancc225ef2014-09-30 13:26:51 -0700239 EXPECT_FALSE(tcp_connection_ == nullptr);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700240 EXPECT_FALSE(health_checker_->health_check_in_progress_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700241 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700242
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700243 // Setup ConnectionHealthChecker::GetSocketInfo to return sock_info.
244 // This only works if GetSocketInfo is called with kProxyFD.
245 // If no matching sock_info is provided (Does not belong to proxy socket),
246 // GetSocketInfo will (correctly) return false.
247 void ExpectGetSocketInfoReturns(SocketInfo sock_info) {
248 vector<SocketInfo> info_list;
249 info_list.push_back(sock_info);
250 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
251 .InSequence(seq_)
252 .WillOnce(Invoke(this,
253 &ConnectionHealthCheckerTest::GetSockName));
254 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
255 .InSequence(seq_)
256 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
257 Return(true)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700258 }
259 void ExpectSuccessfulStart() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700260 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
261 EXPECT_CALL(remote_ips_, GetRandomIP())
262 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700263 EXPECT_CALL(
264 *tcp_connection_,
265 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
266 kProxyPortRemote))
267 .InSequence(seq_)
268 .WillOnce(Return(true));
269 }
270 void ExpectRetry() {
271 EXPECT_CALL(*socket_, Close(kProxyFD))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700272 .InSequence(seq_);
273 EXPECT_CALL(
274 *tcp_connection_,
275 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
276 kProxyPortRemote))
277 .InSequence(seq_)
278 .WillOnce(Return(true));
279 }
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700280 void ExpectStop() {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700281 if (tcp_connection_)
282 EXPECT_CALL(*tcp_connection_, Stop())
283 .InSequence(seq_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700284 }
285 void ExpectCleanUp() {
286 EXPECT_CALL(*socket_, Close(kProxyFD))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700287 .InSequence(seq_);
288 EXPECT_CALL(*tcp_connection_, Stop())
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700289 .InSequence(seq_);
290 }
291
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700292 void VerifyAndClearAllExpectations() {
293 Mock::VerifyAndClearExpectations(this);
294 Mock::VerifyAndClearExpectations(tcp_connection_);
295 Mock::VerifyAndClearExpectations(socket_);
296 Mock::VerifyAndClearExpectations(socket_info_reader_);
297 }
298
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700299 // Needed for other mocks, but not for the tests directly.
300 const string interface_name_;
301 NiceMock<MockControl> control_;
302 NiceMock<MockDeviceInfo> device_info_;
303 vector<string> dns_servers_;
304
Ben Chane2ee5e02014-09-19 19:29:42 -0700305 scoped_refptr<NiceMock<MockConnection>> connection_;
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700306 EventDispatcher dispatcher_;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700307 MockIPAddressStore remote_ips_;
Paul Stewart3b30ca52015-06-16 13:13:10 -0700308 StrictMock<MockSockets>* socket_;
309 StrictMock<MockSocketInfoReader>* socket_info_reader_;
310 StrictMock<MockAsyncConnection>* tcp_connection_;
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700311 // Expectations in the Expect* functions are put in this sequence.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700312 // This allows us to chain calls to Expect* functions.
313 Sequence seq_;
314
Ben Chan22f1fbc2014-10-17 14:18:07 -0700315 std::unique_ptr<ConnectionHealthChecker> health_checker_;
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700316};
317
318TEST_F(ConnectionHealthCheckerTest, Constructor) {
319 ExpectReset();
320}
321
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700322TEST_F(ConnectionHealthCheckerTest, SetConnection) {
Ben Chane2ee5e02014-09-19 19:29:42 -0700323 scoped_refptr<NiceMock<MockConnection>> new_connection =
324 new NiceMock<MockConnection>(&device_info_);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700325 // If a health check was in progress when SetConnection is called, verify
326 // that it restarts with the new connection.
327 ExpectSuccessfulStart();
328 health_checker_->Start();
329 VerifyAndClearAllExpectations();
Paul Stewart41a071e2013-04-26 07:56:04 -0700330
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700331 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(true));
332 EXPECT_CALL(*new_connection.get(), interface_name())
333 .WillRepeatedly(ReturnRef(interface_name_));
334 EXPECT_CALL(*this,
335 ResultCallbackTarget(ConnectionHealthChecker::kResultUnknown));
336 health_checker_->SetConnection(new_connection);
337 EXPECT_NE(tcp_connection_, health_checker_->tcp_connection());
338 EXPECT_EQ(new_connection.get(), health_checker_->connection());
Paul Stewart41a071e2013-04-26 07:56:04 -0700339
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700340 // health_checker_ has reset tcp_connection_ to a new object.
341 // Since it owned tcp_connection_, the object has been destroyed.
Ben Chancc225ef2014-09-30 13:26:51 -0700342 tcp_connection_ = nullptr;
Paul Stewart41a071e2013-04-26 07:56:04 -0700343}
344
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700345TEST_F(ConnectionHealthCheckerTest, GarbageCollectDNSClients) {
346 dns_clients().clear();
347 health_checker_->GarbageCollectDNSClients();
348 EXPECT_TRUE(dns_clients().empty());
349
350 for (int i = 0; i < 3; ++i) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700351 MockDNSClient* dns_client = new MockDNSClient();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700352 EXPECT_CALL(*dns_client, IsActive())
353 .WillOnce(Return(true))
354 .WillOnce(Return(true))
355 .WillOnce(Return(false));
356 // Takes ownership.
357 dns_clients().push_back(dns_client);
358 }
359 for (int i = 0; i < 2; ++i) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700360 MockDNSClient* dns_client = new MockDNSClient();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700361 EXPECT_CALL(*dns_client, IsActive())
362 .WillOnce(Return(false));
363 // Takes ownership.
364 dns_clients().push_back(dns_client);
365 }
366
367 EXPECT_EQ(5, dns_clients().size());
368 health_checker_->GarbageCollectDNSClients();
369 EXPECT_EQ(3, dns_clients().size());
370 health_checker_->GarbageCollectDNSClients();
371 EXPECT_EQ(3, dns_clients().size());
372 health_checker_->GarbageCollectDNSClients();
373 EXPECT_TRUE(dns_clients().empty());
374}
375
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700376TEST_F(ConnectionHealthCheckerTest, AddRemoteURL) {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700377 HTTPURL url;
378 url.ParseFromString(kProxyURLRemote);
379 string host = url.host();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700380 IPAddress remote_ip = StringToIPv4Address(kProxyIPAddressRemote);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700381 IPAddress remote_ip_2 = StringToIPv4Address(kIPAddress_8_8_8_8);
382
Paul Stewart3b30ca52015-06-16 13:13:10 -0700383 MockDNSClientFactory* dns_client_factory
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700384 = MockDNSClientFactory::GetInstance();
Paul Stewart3b30ca52015-06-16 13:13:10 -0700385 vector<MockDNSClient*> dns_client_buffer;
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700386
387 // All DNS queries fail.
388 for (int i = 0; i < NumDNSQueries(); ++i) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700389 MockDNSClient* dns_client = new MockDNSClient();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700390 EXPECT_CALL(*dns_client, Start(host, _))
391 .WillOnce(Return(false));
392 dns_client_buffer.push_back(dns_client);
393 }
394 // Will pass ownership of dns_clients elements.
395 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700396 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700397 .InSequence(seq_)
398 .WillOnce(Return(dns_client_buffer[i]));
399 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700400 EXPECT_CALL(remote_ips_, AddUnique(_)).Times(0);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700401 health_checker_->AddRemoteURL(kProxyURLRemote);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700402 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700403 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700404 dns_client_buffer.clear();
405 dns_clients().clear();
406
407 // All but one DNS queries fail, 1 succeeds.
408 for (int i = 0; i < NumDNSQueries(); ++i) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700409 MockDNSClient* dns_client = new MockDNSClient();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700410 EXPECT_CALL(*dns_client, Start(host, _))
411 .WillOnce(Return(true));
412 dns_client_buffer.push_back(dns_client);
413 }
414 // Will pass ownership of dns_clients elements.
415 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700416 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700417 .InSequence(seq_)
418 .WillOnce(Return(dns_client_buffer[i]));
419 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700420 EXPECT_CALL(remote_ips_, AddUnique(_));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700421 health_checker_->AddRemoteURL(kProxyURLRemote);
Alex Vakulenko8a532292014-06-16 17:18:44 -0700422 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700423 InvokeGetDNSResultFailure();
424 }
425 InvokeGetDNSResultSuccess(remote_ip);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700426 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700427 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700428 dns_client_buffer.clear();
429 dns_clients().clear();
430
431 // Only 2 distinct IP addresses are returned.
432 for (int i = 0; i < NumDNSQueries(); ++i) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700433 MockDNSClient* dns_client = new MockDNSClient();
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700434 EXPECT_CALL(*dns_client, Start(host, _))
435 .WillOnce(Return(true));
436 dns_client_buffer.push_back(dns_client);
437 }
438 // Will pass ownership of dns_clients elements.
439 for (int i = 0; i < NumDNSQueries(); ++i) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700440 EXPECT_CALL(*dns_client_factory, CreateDNSClient(_, _, _, _, _, _))
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700441 .InSequence(seq_)
442 .WillOnce(Return(dns_client_buffer[i]));
443 }
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700444 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip))).Times(4);
445 EXPECT_CALL(remote_ips_, AddUnique(IsSameIPAddress(remote_ip_2)));
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700446 health_checker_->AddRemoteURL(kProxyURLRemote);
447 for (int i = 0; i < NumDNSQueries() - 1; ++i) {
448 InvokeGetDNSResultSuccess(remote_ip);
449 }
450 InvokeGetDNSResultSuccess(remote_ip_2);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700451 Mock::VerifyAndClearExpectations(dns_client_factory);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700452 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700453 dns_client_buffer.clear();
454 dns_clients().clear();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700455}
456
457TEST_F(ConnectionHealthCheckerTest, GetSocketInfo) {
458 SocketInfo sock_info;
459 vector<SocketInfo> info_list;
460
461 // GetSockName fails.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700462 EXPECT_CALL(*socket_, GetSockName(_, _, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700463 .WillOnce(Return(-1));
464 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
465 Mock::VerifyAndClearExpectations(socket_);
466
467 // GetSockName returns IPv6.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700468 EXPECT_CALL(*socket_, GetSockName(_, _, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700469 .WillOnce(
470 Invoke(this,
471 &ConnectionHealthCheckerTest::GetSockNameReturnsIPv6));
472 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
473 Mock::VerifyAndClearExpectations(socket_);
474
475 // LoadTcpSocketInfo fails.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700476 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
477 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
478 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
479 .WillOnce(Return(false));
480 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
481 Mock::VerifyAndClearExpectations(socket_);
482 Mock::VerifyAndClearExpectations(socket_info_reader_);
483
484 // LoadTcpSocketInfo returns empty list.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700485 info_list.clear();
486 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
487 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
488 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
489 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
490 Return(true)));
491 EXPECT_FALSE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
492 Mock::VerifyAndClearExpectations(socket_);
493 Mock::VerifyAndClearExpectations(socket_info_reader_);
494
495 // LoadTcpSocketInfo returns a list without our socket.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700496 info_list.clear();
497 info_list.push_back(CreateSocketInfoOther());
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 with only our socket.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700508 info_list.clear();
509 info_list.push_back(
510 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
511 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
512 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
513 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
514 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
515 Return(true)));
516 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
517 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
518 .IsSameSocketAs(sock_info));
519 Mock::VerifyAndClearExpectations(socket_);
520 Mock::VerifyAndClearExpectations(socket_info_reader_);
521
522 // LoadTcpSocketInfo returns a list with two sockets, including ours.
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700523 info_list.clear();
524 info_list.push_back(CreateSocketInfoOther());
525 info_list.push_back(
526 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
527 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
528 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
529 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
530 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
531 Return(true)));
532 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
533 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
534 .IsSameSocketAs(sock_info));
535 Mock::VerifyAndClearExpectations(socket_);
536 Mock::VerifyAndClearExpectations(socket_info_reader_);
537
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700538 info_list.clear();
539 info_list.push_back(
540 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
541 info_list.push_back(CreateSocketInfoOther());
542 EXPECT_CALL(*socket_, GetSockName(kProxyFD, _, _))
543 .WillOnce(Invoke(this, &ConnectionHealthCheckerTest::GetSockName));
544 EXPECT_CALL(*socket_info_reader_, LoadTcpSocketInfo(_))
545 .WillOnce(DoAll(SetArgumentPointee<0>(info_list),
546 Return(true)));
547 EXPECT_TRUE(health_checker_->GetSocketInfo(kProxyFD, &sock_info));
548 EXPECT_TRUE(CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown)
549 .IsSameSocketAs(sock_info));
550 Mock::VerifyAndClearExpectations(socket_);
551 Mock::VerifyAndClearExpectations(socket_info_reader_);
552}
553
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700554TEST_F(ConnectionHealthCheckerTest, NextHealthCheckSample) {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700555 IPAddress ip = StringToIPv4Address(kProxyIPAddressRemote);
556 ON_CALL(remote_ips_, GetRandomIP())
557 .WillByDefault(Return(ip));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700558
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700559 health_checker_->set_num_connection_failures(MaxFailedConnectionAttempts());
560 ExpectStop();
561 EXPECT_CALL(
562 *this,
563 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
564 health_checker_->NextHealthCheckSample();
565 dispatcher_.DispatchPendingEvents();
566 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700567
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700568 health_checker_->set_num_congested_queue_detected(
569 MinCongestedQueueAttempts());
570 ExpectStop();
571 EXPECT_CALL(
572 *this,
573 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
574 health_checker_->NextHealthCheckSample();
575 dispatcher_.DispatchPendingEvents();
576 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700577
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700578 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts());
579 ExpectStop();
580 EXPECT_CALL(
581 *this,
582 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
583 health_checker_->NextHealthCheckSample();
584 dispatcher_.DispatchPendingEvents();
585 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700586
Alex Vakulenko8a532292014-06-16 17:18:44 -0700587 EXPECT_CALL(*tcp_connection_, Start(_, _)).WillOnce(Return(true));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700588 health_checker_->NextHealthCheckSample();
589 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700590
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700591 // This test assumes that there are at least 2 connection attempts left
592 // before ConnectionHealthChecker gives up.
Alex Vakulenko8a532292014-06-16 17:18:44 -0700593 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700594 .WillOnce(Return(false))
595 .WillOnce(Return(true));
Alex Vakulenko8a532292014-06-16 17:18:44 -0700596 int16_t num_connection_failures = health_checker_->num_connection_failures();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700597 health_checker_->NextHealthCheckSample();
598 EXPECT_EQ(num_connection_failures + 1,
599 health_checker_->num_connection_failures());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700600}
601
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700602TEST_F(ConnectionHealthCheckerTest, OnConnectionComplete) {
603 // Test that num_connection_attempts is incremented on failure when
604 // (1) Async Connection fails.
605 health_checker_->set_num_connection_failures(
606 MaxFailedConnectionAttempts() - 1);
607 ExpectStop();
608 EXPECT_CALL(
609 *this,
610 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
611 health_checker_->OnConnectionComplete(false, -1);
612 dispatcher_.DispatchPendingEvents();
613 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700614
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700615 // (2) The connection state is garbled up.
616 health_checker_->set_num_connection_failures(
617 MaxFailedConnectionAttempts() - 1);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700618 ExpectGetSocketInfoReturns(
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700619 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
620 EXPECT_CALL(*socket_, Close(kProxyFD));
621 ExpectStop();
622 EXPECT_CALL(
623 *this,
624 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
625 health_checker_->OnConnectionComplete(true, kProxyFD);
626 dispatcher_.DispatchPendingEvents();
627 VerifyAndClearAllExpectations();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700628
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700629 // (3) Send fails.
630 health_checker_->set_num_connection_failures(
631 MaxFailedConnectionAttempts() - 1);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700632 ExpectGetSocketInfoReturns(
633 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700634 EXPECT_CALL(*socket_, Send(kProxyFD, _, Gt(0), _)).WillOnce(Return(-1));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700635 EXPECT_CALL(*socket_, Close(kProxyFD));
636 ExpectStop();
637 EXPECT_CALL(
638 *this,
639 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
640 health_checker_->OnConnectionComplete(true, kProxyFD);
641 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700642}
643
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700644TEST_F(ConnectionHealthCheckerTest, VerifySentData) {
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700645 // (1) Test that num_connection_attempts is incremented when the connection
646 // state is garbled up.
647 health_checker_->set_num_connection_failures(
648 MaxFailedConnectionAttempts() - 1);
649 ExpectGetSocketInfoReturns(
650 CreateSocketInfoProxy(SocketInfo::kConnectionStateUnknown));
651 EXPECT_CALL(*socket_, Close(kProxyFD));
652 ExpectStop();
653 EXPECT_CALL(
654 *this,
655 ResultCallbackTarget(ConnectionHealthChecker::kResultConnectionFailure));
656 health_checker_->set_sock_fd(kProxyFD);
657 health_checker_->VerifySentData();
658 dispatcher_.DispatchPendingEvents();
659 VerifyAndClearAllExpectations();
660
661 // (2) Test that num_congested_queue_detected is incremented when all polling
662 // attempts have expired.
663 health_checker_->set_num_congested_queue_detected(
664 MinCongestedQueueAttempts() - 1);
665 health_checker_->set_num_tx_queue_polling_attempts(
666 MaxSentDataPollingAttempts());
667 health_checker_->set_old_transmit_queue_value(0);
668 ExpectGetSocketInfoReturns(
669 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
670 SocketInfo::kTimerStateRetransmitTimerPending,
671 1));
672 EXPECT_CALL(*socket_, Close(kProxyFD));
673 ExpectStop();
674 EXPECT_CALL(
675 *this,
676 ResultCallbackTarget(ConnectionHealthChecker::kResultCongestedTxQueue));
677 health_checker_->set_sock_fd(kProxyFD);
678 health_checker_->VerifySentData();
679 dispatcher_.DispatchPendingEvents();
680 VerifyAndClearAllExpectations();
681
682 // (3) Test that num_successful_sends is incremented if everything goes fine.
683 health_checker_->set_num_successful_sends(MinSuccessfulSendAttempts() - 1);
684 health_checker_->set_old_transmit_queue_value(0);
685 ExpectGetSocketInfoReturns(
686 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
687 SocketInfo::kTimerStateNoTimerPending,
688 0));
689 EXPECT_CALL(*socket_, Close(kProxyFD));
690 ExpectStop();
691 EXPECT_CALL(
692 *this,
693 ResultCallbackTarget(ConnectionHealthChecker::kResultSuccess));
694 health_checker_->set_sock_fd(kProxyFD);
695 health_checker_->VerifySentData();
696 dispatcher_.DispatchPendingEvents();
697 VerifyAndClearAllExpectations();
Prathmesh Prabhu81404c62013-05-08 17:04:28 -0700698
699 // (4) Test that VerifySentData correctly polls the tcpinfo twice.
700 // We want to immediately dispatch posted tasks.
701 SetTCPStateUpdateWaitMilliseconds(0);
702 health_checker_->set_num_congested_queue_detected(
703 MinCongestedQueueAttempts() - 1);
704 health_checker_->set_num_tx_queue_polling_attempts(
705 MaxSentDataPollingAttempts() - 1);
706 health_checker_->set_old_transmit_queue_value(0);
707 ExpectGetSocketInfoReturns(
708 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
709 SocketInfo::kTimerStateRetransmitTimerPending,
710 1));
711 ExpectGetSocketInfoReturns(
712 CreateSocketInfoProxy(SocketInfo::kConnectionStateEstablished,
713 SocketInfo::kTimerStateRetransmitTimerPending,
714 1));
715 EXPECT_CALL(*socket_, Close(kProxyFD));
716 ExpectStop();
717 EXPECT_CALL(
718 *this, ResultCallbackTarget(
719 ConnectionHealthChecker::kResultCongestedTxQueue))
720 .InSequence(seq_);
721 health_checker_->set_sock_fd(kProxyFD);
722 health_checker_->VerifySentData();
723 dispatcher_.DispatchPendingEvents();
724 dispatcher_.DispatchPendingEvents();
725 // Force an extra dispatch to make sure that VerifySentData did not poll an
726 // extra time. This dispatch should be a no-op.
727 dispatcher_.DispatchPendingEvents();
728 VerifyAndClearAllExpectations();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700729}
730
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700731// Flow: Start() -> Start()
732// Expectation: Only one AsyncConnection is setup
733TEST_F(ConnectionHealthCheckerTest, StartStartSkipsSecond) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700734 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700735 .WillOnce(Return(true));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700736 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
737 EXPECT_CALL(remote_ips_, GetRandomIP())
738 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700739 health_checker_->Start();
740 health_checker_->Start();
741}
742
743// Precondition: size(|remote_ips_|) > 0
744// Flow: Start() -> Stop() before ConnectionComplete()
745// Expectation: No call to |result_callback|
746TEST_F(ConnectionHealthCheckerTest, StartStopNoCallback) {
Alex Vakulenko8a532292014-06-16 17:18:44 -0700747 EXPECT_CALL(*tcp_connection_, Start(_, _))
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700748 .WillOnce(Return(true));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700749 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700750 EXPECT_CALL(*this, ResultCallbackTarget(_))
751 .Times(0);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700752 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
753 EXPECT_CALL(remote_ips_, GetRandomIP())
754 .WillOnce(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700755 health_checker_->Start();
756 health_checker_->Stop();
757}
758
759// Precondition: Empty remote_ips_
760// Flow: Start()
761// Expectation: call |result_callback| with kResultUnknown
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700762TEST_F(ConnectionHealthCheckerTest, StartImmediateFailure) {
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700763 EXPECT_CALL(remote_ips_, Empty()).WillOnce(Return(true));
764 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700765 EXPECT_CALL(*this, ResultCallbackTarget(
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700766 ConnectionHealthChecker::kResultUnknown));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700767 health_checker_->Start();
768 Mock::VerifyAndClearExpectations(this);
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700769 Mock::VerifyAndClearExpectations(&remote_ips_);
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700770 Mock::VerifyAndClearExpectations(tcp_connection_);
771
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700772 EXPECT_CALL(remote_ips_, Empty()).WillRepeatedly(Return(false));
773 EXPECT_CALL(remote_ips_, GetRandomIP())
774 .WillRepeatedly(Return(StringToIPv4Address(kProxyIPAddressRemote)));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700775 EXPECT_CALL(*tcp_connection_,
776 Start(IsSameIPAddress(StringToIPv4Address(kProxyIPAddressRemote)),
777 kProxyPortRemote))
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700778 .Times(MaxFailedConnectionAttempts())
Prathmesh Prabhu3e452f82013-04-10 16:31:44 -0700779 .WillRepeatedly(Return(false));
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700780 EXPECT_CALL(*tcp_connection_, Stop());
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700781 EXPECT_CALL(*this, ResultCallbackTarget(
Prathmesh Prabhuba99b592013-04-17 15:13:14 -0700782 ConnectionHealthChecker::kResultConnectionFailure));
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700783 health_checker_->Start();
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -0700784 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700785 Mock::VerifyAndClearExpectations(this);
786 Mock::VerifyAndClearExpectations(tcp_connection_);
787}
788
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700789} // namespace shill