Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: google_apis/gcm/engine/connection_factory_impl_unittest.cc

Issue 213693002: [GCM] Add support for canary connection attempts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refactor tests Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "google_apis/gcm/engine/connection_factory_impl.h" 5 #include "google_apis/gcm/engine/connection_factory_impl.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/test/simple_test_tick_clock.h" 11 #include "base/test/simple_test_tick_clock.h"
12 #include "google_apis/gcm/base/mcs_util.h"
13 #include "google_apis/gcm/engine/fake_connection_handler.h"
12 #include "net/base/backoff_entry.h" 14 #include "net/base/backoff_entry.h"
13 #include "net/http/http_network_session.h" 15 #include "net/http/http_network_session.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 17
16 class Policy; 18 class Policy;
17 19
18 namespace gcm { 20 namespace gcm {
19 namespace { 21 namespace {
20 22
21 const char kMCSEndpoint[] = "http://my.server"; 23 const char kMCSEndpoint[] = "http://my.server";
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 double CalculateBackoff(int num_attempts) { 65 double CalculateBackoff(int num_attempts) {
64 double delay = kBackoffDelayMs; 66 double delay = kBackoffDelayMs;
65 for (int i = 1; i < num_attempts; ++i) { 67 for (int i = 1; i < num_attempts; ++i) {
66 delay += kBackoffDelayMs * pow(static_cast<double>(kBackoffMultiplier), 68 delay += kBackoffDelayMs * pow(static_cast<double>(kBackoffMultiplier),
67 i - 1); 69 i - 1);
68 } 70 }
69 DVLOG(1) << "Expected backoff " << delay << " milliseconds."; 71 DVLOG(1) << "Expected backoff " << delay << " milliseconds.";
70 return delay; 72 return delay;
71 } 73 }
72 74
73 // Helper methods that should never actually be called due to real connections
74 // being stubbed out.
75 void ReadContinuation( 75 void ReadContinuation(
76 scoped_ptr<google::protobuf::MessageLite> message) { 76 scoped_ptr<google::protobuf::MessageLite> message) {
77 ADD_FAILURE();
78 } 77 }
79 78
80 void WriteContinuation() { 79 void WriteContinuation() {
81 ADD_FAILURE();
82 } 80 }
83 81
84 class TestBackoffEntry : public net::BackoffEntry { 82 class TestBackoffEntry : public net::BackoffEntry {
85 public: 83 public:
86 explicit TestBackoffEntry(base::SimpleTestTickClock* tick_clock); 84 explicit TestBackoffEntry(base::SimpleTestTickClock* tick_clock);
87 virtual ~TestBackoffEntry(); 85 virtual ~TestBackoffEntry();
88 86
89 virtual base::TimeTicks ImplGetTimeNow() const OVERRIDE; 87 virtual base::TimeTicks ImplGetTimeNow() const OVERRIDE;
90 88
91 private: 89 private:
(...skipping 11 matching lines...) Expand all
103 return tick_clock_->NowTicks(); 101 return tick_clock_->NowTicks();
104 } 102 }
105 103
106 // A connection factory that stubs out network requests and overrides the 104 // A connection factory that stubs out network requests and overrides the
107 // backoff policy. 105 // backoff policy.
108 class TestConnectionFactoryImpl : public ConnectionFactoryImpl { 106 class TestConnectionFactoryImpl : public ConnectionFactoryImpl {
109 public: 107 public:
110 TestConnectionFactoryImpl(const base::Closure& finished_callback); 108 TestConnectionFactoryImpl(const base::Closure& finished_callback);
111 virtual ~TestConnectionFactoryImpl(); 109 virtual ~TestConnectionFactoryImpl();
112 110
111 void InitializeFactory();
112
113 // Overridden stubs. 113 // Overridden stubs.
114 virtual void ConnectImpl() OVERRIDE; 114 virtual void ConnectImpl() OVERRIDE;
115 virtual void InitHandler() OVERRIDE; 115 virtual void InitHandler() OVERRIDE;
116 virtual scoped_ptr<net::BackoffEntry> CreateBackoffEntry( 116 virtual scoped_ptr<net::BackoffEntry> CreateBackoffEntry(
117 const net::BackoffEntry::Policy* const policy) OVERRIDE; 117 const net::BackoffEntry::Policy* const policy) OVERRIDE;
118 virtual scoped_ptr<ConnectionHandler> CreateConnectionHandler(
119 base::TimeDelta read_timeout,
120 const ConnectionHandler::ProtoReceivedCallback& read_callback,
121 const ConnectionHandler::ProtoSentCallback& write_callback,
122 const ConnectionHandler::ConnectionChangedCallback& connection_callback)
123 OVERRIDE;
118 virtual base::TimeTicks NowTicks() OVERRIDE; 124 virtual base::TimeTicks NowTicks() OVERRIDE;
119 125
120 // Helpers for verifying connection attempts are made. Connection results 126 // Helpers for verifying connection attempts are made. Connection results
121 // must be consumed. 127 // must be consumed.
122 void SetConnectResult(int connect_result); 128 void SetConnectResult(int connect_result);
123 void SetMultipleConnectResults(int connect_result, int num_expected_attempts); 129 void SetMultipleConnectResults(int connect_result, int num_expected_attempts);
124 130
125 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; } 131 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; }
126 132
127 private: 133 private:
128 // Clock for controlling delay. 134 // Clock for controlling delay.
129 base::SimpleTestTickClock tick_clock_; 135 base::SimpleTestTickClock tick_clock_;
130 // The result to return on the next connect attempt. 136 // The result to return on the next connect attempt.
131 int connect_result_; 137 int connect_result_;
132 // The number of expected connection attempts; 138 // The number of expected connection attempts;
133 int num_expected_attempts_; 139 int num_expected_attempts_;
134 // Whether all expected connection attempts have been fulfilled since an 140 // Whether all expected connection attempts have been fulfilled since an
135 // expectation was last set. 141 // expectation was last set.
136 bool connections_fulfilled_; 142 bool connections_fulfilled_;
137 // Callback to invoke when all connection attempts have been made. 143 // Callback to invoke when all connection attempts have been made.
138 base::Closure finished_callback_; 144 base::Closure finished_callback_;
145 // The current fake connection handler..
146 FakeConnectionHandler* fake_handler_;
139 }; 147 };
140 148
141 TestConnectionFactoryImpl::TestConnectionFactoryImpl( 149 TestConnectionFactoryImpl::TestConnectionFactoryImpl(
142 const base::Closure& finished_callback) 150 const base::Closure& finished_callback)
143 : ConnectionFactoryImpl(BuildEndpoints(), 151 : ConnectionFactoryImpl(BuildEndpoints(),
144 net::BackoffEntry::Policy(), 152 net::BackoffEntry::Policy(),
145 NULL, 153 NULL,
146 NULL), 154 NULL),
147 connect_result_(net::ERR_UNEXPECTED), 155 connect_result_(net::ERR_UNEXPECTED),
148 num_expected_attempts_(0), 156 num_expected_attempts_(0),
149 connections_fulfilled_(true), 157 connections_fulfilled_(true),
150 finished_callback_(finished_callback) { 158 finished_callback_(finished_callback),
159 fake_handler_(NULL) {
151 // Set a non-null time. 160 // Set a non-null time.
152 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); 161 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
153 } 162 }
154 163
155 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() { 164 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() {
156 EXPECT_EQ(0, num_expected_attempts_); 165 EXPECT_EQ(0, num_expected_attempts_);
157 } 166 }
158 167
159 void TestConnectionFactoryImpl::ConnectImpl() { 168 void TestConnectionFactoryImpl::ConnectImpl() {
160 ASSERT_GT(num_expected_attempts_, 0); 169 ASSERT_GT(num_expected_attempts_, 0);
161 170 scoped_ptr<mcs_proto::LoginRequest> request(BuildLoginRequest(0, 0, ""));
171 GetConnectionHandler()->Init(*request, NULL);
162 OnConnectDone(connect_result_); 172 OnConnectDone(connect_result_);
163 if (!NextRetryAttempt().is_null()) { 173 if (!NextRetryAttempt().is_null()) {
164 // Advance the time to the next retry time. 174 // Advance the time to the next retry time.
165 base::TimeDelta time_till_retry = 175 base::TimeDelta time_till_retry =
166 NextRetryAttempt() - tick_clock_.NowTicks(); 176 NextRetryAttempt() - tick_clock_.NowTicks();
167 tick_clock_.Advance(time_till_retry); 177 tick_clock_.Advance(time_till_retry);
168 } 178 }
169 --num_expected_attempts_; 179 --num_expected_attempts_;
170 if (num_expected_attempts_ == 0) { 180 if (num_expected_attempts_ == 0) {
171 connect_result_ = net::ERR_UNEXPECTED; 181 connect_result_ = net::ERR_UNEXPECTED;
172 connections_fulfilled_ = true; 182 connections_fulfilled_ = true;
173 finished_callback_.Run(); 183 finished_callback_.Run();
174 } 184 }
175 } 185 }
176 186
177 void TestConnectionFactoryImpl::InitHandler() { 187 void TestConnectionFactoryImpl::InitHandler() {
178 EXPECT_NE(connect_result_, net::ERR_UNEXPECTED); 188 EXPECT_NE(connect_result_, net::ERR_UNEXPECTED);
179 ConnectionHandlerCallback(net::OK); 189 ConnectionHandlerCallback(net::OK);
180 } 190 }
181 191
182 scoped_ptr<net::BackoffEntry> TestConnectionFactoryImpl::CreateBackoffEntry( 192 scoped_ptr<net::BackoffEntry> TestConnectionFactoryImpl::CreateBackoffEntry(
183 const net::BackoffEntry::Policy* const policy) { 193 const net::BackoffEntry::Policy* const policy) {
184 return scoped_ptr<net::BackoffEntry>(new TestBackoffEntry(&tick_clock_)); 194 return scoped_ptr<net::BackoffEntry>(new TestBackoffEntry(&tick_clock_));
185 } 195 }
186 196
197 scoped_ptr<ConnectionHandler>
198 TestConnectionFactoryImpl::CreateConnectionHandler(
199 base::TimeDelta read_timeout,
200 const ConnectionHandler::ProtoReceivedCallback& read_callback,
201 const ConnectionHandler::ProtoSentCallback& write_callback,
202 const ConnectionHandler::ConnectionChangedCallback& connection_callback) {
203 fake_handler_ = new FakeConnectionHandler(
204 base::Bind(&ReadContinuation),
205 base::Bind(&WriteContinuation));
206 return make_scoped_ptr<ConnectionHandler>(fake_handler_);
207 }
208
187 base::TimeTicks TestConnectionFactoryImpl::NowTicks() { 209 base::TimeTicks TestConnectionFactoryImpl::NowTicks() {
188 return tick_clock_.NowTicks(); 210 return tick_clock_.NowTicks();
189 } 211 }
190 212
191 void TestConnectionFactoryImpl::SetConnectResult(int connect_result) { 213 void TestConnectionFactoryImpl::SetConnectResult(int connect_result) {
192 DCHECK_NE(connect_result, net::ERR_UNEXPECTED); 214 DCHECK_NE(connect_result, net::ERR_UNEXPECTED);
193 ASSERT_EQ(0, num_expected_attempts_); 215 ASSERT_EQ(0, num_expected_attempts_);
194 connections_fulfilled_ = false; 216 connections_fulfilled_ = false;
195 connect_result_ = connect_result; 217 connect_result_ = connect_result;
196 num_expected_attempts_ = 1; 218 num_expected_attempts_ = 1;
219 fake_handler_->ExpectOutgoingMessage(
220 MCSMessage(kLoginRequestTag,
221 BuildLoginRequest(0, 0, "").PassAs<
222 const google::protobuf::MessageLite>()));
197 } 223 }
198 224
199 void TestConnectionFactoryImpl::SetMultipleConnectResults( 225 void TestConnectionFactoryImpl::SetMultipleConnectResults(
200 int connect_result, 226 int connect_result,
201 int num_expected_attempts) { 227 int num_expected_attempts) {
202 DCHECK_NE(connect_result, net::ERR_UNEXPECTED); 228 DCHECK_NE(connect_result, net::ERR_UNEXPECTED);
203 DCHECK_GT(num_expected_attempts, 0); 229 DCHECK_GT(num_expected_attempts, 0);
204 ASSERT_EQ(0, num_expected_attempts_); 230 ASSERT_EQ(0, num_expected_attempts_);
205 connections_fulfilled_ = false; 231 connections_fulfilled_ = false;
206 connect_result_ = connect_result; 232 connect_result_ = connect_result;
207 num_expected_attempts_ = num_expected_attempts; 233 num_expected_attempts_ = num_expected_attempts;
234 for (int i = 0 ; i < num_expected_attempts; ++i) {
235 fake_handler_->ExpectOutgoingMessage(
236 MCSMessage(kLoginRequestTag,
237 BuildLoginRequest(0, 0, "").PassAs<
238 const google::protobuf::MessageLite>()));
239 }
208 } 240 }
209 241
210 class ConnectionFactoryImplTest : public testing::Test { 242 class ConnectionFactoryImplTest : public testing::Test {
211 public: 243 public:
212 ConnectionFactoryImplTest(); 244 ConnectionFactoryImplTest();
213 virtual ~ConnectionFactoryImplTest(); 245 virtual ~ConnectionFactoryImplTest();
214 246
215 TestConnectionFactoryImpl* factory() { return &factory_; } 247 TestConnectionFactoryImpl* factory() { return &factory_; }
216 248
217 void WaitForConnections(); 249 void WaitForConnections();
218 250
219 private: 251 private:
220 void ConnectionsComplete(); 252 void ConnectionsComplete();
221 253
222 TestConnectionFactoryImpl factory_; 254 TestConnectionFactoryImpl factory_;
223 base::MessageLoop message_loop_; 255 base::MessageLoop message_loop_;
224 scoped_ptr<base::RunLoop> run_loop_; 256 scoped_ptr<base::RunLoop> run_loop_;
225 }; 257 };
226 258
227 ConnectionFactoryImplTest::ConnectionFactoryImplTest() 259 ConnectionFactoryImplTest::ConnectionFactoryImplTest()
228 : factory_(base::Bind(&ConnectionFactoryImplTest::ConnectionsComplete, 260 : factory_(base::Bind(&ConnectionFactoryImplTest::ConnectionsComplete,
229 base::Unretained(this))), 261 base::Unretained(this))),
230 run_loop_(new base::RunLoop()) {} 262 run_loop_(new base::RunLoop()) {
263 factory()->Initialize(
264 ConnectionFactory::BuildLoginRequestCallback(),
265 ConnectionHandler::ProtoReceivedCallback(),
266 ConnectionHandler::ProtoSentCallback());
267 }
231 ConnectionFactoryImplTest::~ConnectionFactoryImplTest() {} 268 ConnectionFactoryImplTest::~ConnectionFactoryImplTest() {}
232 269
233 void ConnectionFactoryImplTest::WaitForConnections() { 270 void ConnectionFactoryImplTest::WaitForConnections() {
234 run_loop_->Run(); 271 run_loop_->Run();
235 run_loop_.reset(new base::RunLoop()); 272 run_loop_.reset(new base::RunLoop());
236 } 273 }
237 274
238 void ConnectionFactoryImplTest::ConnectionsComplete() { 275 void ConnectionFactoryImplTest::ConnectionsComplete() {
239 if (!run_loop_) 276 if (!run_loop_)
240 return; 277 return;
241 run_loop_->Quit(); 278 run_loop_->Quit();
242 } 279 }
243 280
244 // Verify building a connection handler works. 281 // Verify building a connection handler works.
245 TEST_F(ConnectionFactoryImplTest, Initialize) { 282 TEST_F(ConnectionFactoryImplTest, Initialize) {
246 EXPECT_FALSE(factory()->IsEndpointReachable());
247 factory()->Initialize(
248 ConnectionFactory::BuildLoginRequestCallback(),
249 base::Bind(&ReadContinuation),
250 base::Bind(&WriteContinuation));
251 ConnectionHandler* handler = factory()->GetConnectionHandler(); 283 ConnectionHandler* handler = factory()->GetConnectionHandler();
252 ASSERT_TRUE(handler); 284 ASSERT_TRUE(handler);
253 EXPECT_FALSE(factory()->IsEndpointReachable()); 285 EXPECT_FALSE(factory()->IsEndpointReachable());
254 } 286 }
255 287
256 // An initial successful connection should not result in backoff. 288 // An initial successful connection should not result in backoff.
257 TEST_F(ConnectionFactoryImplTest, ConnectSuccess) { 289 TEST_F(ConnectionFactoryImplTest, ConnectSuccess) {
258 factory()->Initialize(
259 ConnectionFactory::BuildLoginRequestCallback(),
260 ConnectionHandler::ProtoReceivedCallback(),
261 ConnectionHandler::ProtoSentCallback());
262 factory()->SetConnectResult(net::OK); 290 factory()->SetConnectResult(net::OK);
263 factory()->Connect(); 291 factory()->Connect();
264 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 292 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
265 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[0]); 293 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[0]);
294 EXPECT_TRUE(factory()->IsEndpointReachable());
266 } 295 }
267 296
268 // A connection failure should result in backoff, and attempting the fallback 297 // A connection failure should result in backoff, and attempting the fallback
269 // endpoint next. 298 // endpoint next.
270 TEST_F(ConnectionFactoryImplTest, ConnectFail) { 299 TEST_F(ConnectionFactoryImplTest, ConnectFail) {
271 factory()->Initialize(
272 ConnectionFactory::BuildLoginRequestCallback(),
273 ConnectionHandler::ProtoReceivedCallback(),
274 ConnectionHandler::ProtoSentCallback());
275 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); 300 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
276 factory()->Connect(); 301 factory()->Connect();
277 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); 302 EXPECT_FALSE(factory()->NextRetryAttempt().is_null());
278 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[1]); 303 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[1]);
304 EXPECT_FALSE(factory()->IsEndpointReachable());
279 } 305 }
280 306
281 // A connection success after a failure should reset backoff. 307 // A connection success after a failure should reset backoff.
282 TEST_F(ConnectionFactoryImplTest, FailThenSucceed) { 308 TEST_F(ConnectionFactoryImplTest, FailThenSucceed) {
283 factory()->Initialize(
284 ConnectionFactory::BuildLoginRequestCallback(),
285 ConnectionHandler::ProtoReceivedCallback(),
286 ConnectionHandler::ProtoSentCallback());
287 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); 309 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
288 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); 310 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks();
289 factory()->Connect(); 311 factory()->Connect();
290 WaitForConnections(); 312 WaitForConnections();
313 EXPECT_FALSE(factory()->IsEndpointReachable());
291 base::TimeTicks retry_time = factory()->NextRetryAttempt(); 314 base::TimeTicks retry_time = factory()->NextRetryAttempt();
292 EXPECT_FALSE(retry_time.is_null()); 315 EXPECT_FALSE(retry_time.is_null());
293 EXPECT_GE((retry_time - connect_time).InMilliseconds(), CalculateBackoff(1)); 316 EXPECT_GE((retry_time - connect_time).InMilliseconds(), CalculateBackoff(1));
294 factory()->SetConnectResult(net::OK); 317 factory()->SetConnectResult(net::OK);
295 WaitForConnections(); 318 WaitForConnections();
296 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 319 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
320 EXPECT_TRUE(factory()->IsEndpointReachable());
297 } 321 }
298 322
299 // Multiple connection failures should retry with an exponentially increasing 323 // Multiple connection failures should retry with an exponentially increasing
300 // backoff, then reset on success. 324 // backoff, then reset on success.
301 TEST_F(ConnectionFactoryImplTest, MultipleFailuresThenSucceed) { 325 TEST_F(ConnectionFactoryImplTest, MultipleFailuresThenSucceed) {
302 factory()->Initialize(
303 ConnectionFactory::BuildLoginRequestCallback(),
304 ConnectionHandler::ProtoReceivedCallback(),
305 ConnectionHandler::ProtoSentCallback());
306 326
307 const int kNumAttempts = 5; 327 const int kNumAttempts = 5;
308 factory()->SetMultipleConnectResults(net::ERR_CONNECTION_FAILED, 328 factory()->SetMultipleConnectResults(net::ERR_CONNECTION_FAILED,
309 kNumAttempts); 329 kNumAttempts);
310 330
311 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); 331 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks();
312 factory()->Connect(); 332 factory()->Connect();
313 WaitForConnections(); 333 WaitForConnections();
334 EXPECT_FALSE(factory()->IsEndpointReachable());
314 base::TimeTicks retry_time = factory()->NextRetryAttempt(); 335 base::TimeTicks retry_time = factory()->NextRetryAttempt();
315 EXPECT_FALSE(retry_time.is_null()); 336 EXPECT_FALSE(retry_time.is_null());
316 EXPECT_GE((retry_time - connect_time).InMilliseconds(), 337 EXPECT_GE((retry_time - connect_time).InMilliseconds(),
317 CalculateBackoff(kNumAttempts)); 338 CalculateBackoff(kNumAttempts));
318 339
319 factory()->SetConnectResult(net::OK); 340 factory()->SetConnectResult(net::OK);
320 WaitForConnections(); 341 WaitForConnections();
321 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 342 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
343 EXPECT_TRUE(factory()->IsEndpointReachable());
322 } 344 }
323 345
324 // IP events should reset backoff. 346 // IP events should trigger canary connections.
325 TEST_F(ConnectionFactoryImplTest, FailThenIPEvent) { 347 TEST_F(ConnectionFactoryImplTest, FailThenIPEvent) {
326 factory()->Initialize(
327 ConnectionFactory::BuildLoginRequestCallback(),
328 ConnectionHandler::ProtoReceivedCallback(),
329 ConnectionHandler::ProtoSentCallback());
330 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); 348 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
331 factory()->Connect(); 349 factory()->Connect();
332 WaitForConnections(); 350 WaitForConnections();
333 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); 351 base::TimeTicks initial_backoff = factory()->NextRetryAttempt();
352 EXPECT_FALSE(initial_backoff.is_null());
334 353
354 factory()->SetConnectResult(net::ERR_FAILED);
335 factory()->OnIPAddressChanged(); 355 factory()->OnIPAddressChanged();
336 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 356 WaitForConnections();
357
358 // Backoff should increase.
359 base::TimeTicks next_backoff = factory()->NextRetryAttempt();
360 EXPECT_GT(next_backoff, initial_backoff);
361 EXPECT_FALSE(factory()->IsEndpointReachable());
337 } 362 }
338 363
339 // Connection type events should reset backoff. 364 // Connection type events should trigger canary connections.
340 TEST_F(ConnectionFactoryImplTest, FailThenConnectionTypeEvent) { 365 TEST_F(ConnectionFactoryImplTest, FailThenConnectionTypeEvent) {
341 factory()->Initialize(
342 ConnectionFactory::BuildLoginRequestCallback(),
343 ConnectionHandler::ProtoReceivedCallback(),
344 ConnectionHandler::ProtoSentCallback());
345 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); 366 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
346 factory()->Connect(); 367 factory()->Connect();
347 WaitForConnections(); 368 WaitForConnections();
348 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); 369 base::TimeTicks initial_backoff = factory()->NextRetryAttempt();
370 EXPECT_FALSE(initial_backoff.is_null());
349 371
372 factory()->SetConnectResult(net::ERR_FAILED);
350 factory()->OnConnectionTypeChanged( 373 factory()->OnConnectionTypeChanged(
351 net::NetworkChangeNotifier::CONNECTION_WIFI); 374 net::NetworkChangeNotifier::CONNECTION_WIFI);
352 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 375 WaitForConnections();
376
377 // Backoff should increase.
378 base::TimeTicks next_backoff = factory()->NextRetryAttempt();
379 EXPECT_GT(next_backoff, initial_backoff);
380 EXPECT_FALSE(factory()->IsEndpointReachable());
381 }
382
383 // Verify that we reconnect even if a canary succeeded then disconnected while
384 // a backoff was pending.
385 TEST_F(ConnectionFactoryImplTest, CanarySucceedsThenDisconnects) {
386 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
387 factory()->Connect();
388 WaitForConnections();
389 base::TimeTicks initial_backoff = factory()->NextRetryAttempt();
390 EXPECT_FALSE(initial_backoff.is_null());
391
392 factory()->SetConnectResult(net::OK);
393 factory()->OnConnectionTypeChanged(
394 net::NetworkChangeNotifier::CONNECTION_WIFI);
395 WaitForConnections();
396 EXPECT_TRUE(factory()->IsEndpointReachable());
397
398 factory()->SetConnectResult(net::OK);
399 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
400 EXPECT_FALSE(factory()->IsEndpointReachable());
401 WaitForConnections();
402 EXPECT_TRUE(factory()->IsEndpointReachable());
353 } 403 }
354 404
355 // Fail after successful connection via signal reset. 405 // Fail after successful connection via signal reset.
356 TEST_F(ConnectionFactoryImplTest, FailViaSignalReset) { 406 TEST_F(ConnectionFactoryImplTest, FailViaSignalReset) {
357 factory()->Initialize(
358 ConnectionFactory::BuildLoginRequestCallback(),
359 ConnectionHandler::ProtoReceivedCallback(),
360 ConnectionHandler::ProtoSentCallback());
361 factory()->SetConnectResult(net::OK); 407 factory()->SetConnectResult(net::OK);
362 factory()->Connect(); 408 factory()->Connect();
363 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 409 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
364 410
365 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); 411 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
366 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); 412 EXPECT_FALSE(factory()->NextRetryAttempt().is_null());
367 EXPECT_FALSE(factory()->GetConnectionHandler()->CanSendMessage()); 413 EXPECT_FALSE(factory()->IsEndpointReachable());
368 } 414 }
369 415
370 TEST_F(ConnectionFactoryImplTest, IgnoreResetWhileConnecting) { 416 TEST_F(ConnectionFactoryImplTest, IgnoreResetWhileConnecting) {
371 factory()->Initialize(
372 ConnectionFactory::BuildLoginRequestCallback(),
373 ConnectionHandler::ProtoReceivedCallback(),
374 ConnectionHandler::ProtoSentCallback());
375 factory()->SetConnectResult(net::OK); 417 factory()->SetConnectResult(net::OK);
376 factory()->Connect(); 418 factory()->Connect();
377 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 419 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
378 420
379 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); 421 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
380 base::TimeTicks retry_time = factory()->NextRetryAttempt(); 422 base::TimeTicks retry_time = factory()->NextRetryAttempt();
381 EXPECT_FALSE(retry_time.is_null()); 423 EXPECT_FALSE(retry_time.is_null());
424 EXPECT_FALSE(factory()->IsEndpointReachable());
382 425
383 const int kNumAttempts = 5; 426 const int kNumAttempts = 5;
384 for (int i = 0; i < kNumAttempts; ++i) 427 for (int i = 0; i < kNumAttempts; ++i)
385 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); 428 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
386 EXPECT_EQ(retry_time, factory()->NextRetryAttempt()); 429 EXPECT_EQ(retry_time, factory()->NextRetryAttempt());
430 EXPECT_FALSE(factory()->IsEndpointReachable());
387 } 431 }
388 432
389 // Go into backoff due to connection failure. On successful connection, receive 433 // Go into backoff due to connection failure. On successful connection, receive
390 // a signal reset. The original backoff should be restored and extended, rather 434 // a signal reset. The original backoff should be restored and extended, rather
391 // than a new backoff starting from scratch. 435 // than a new backoff starting from scratch.
392 TEST_F(ConnectionFactoryImplTest, SignalResetRestoresBackoff) { 436 TEST_F(ConnectionFactoryImplTest, SignalResetRestoresBackoff) {
393 factory()->Initialize(
394 ConnectionFactory::BuildLoginRequestCallback(),
395 ConnectionHandler::ProtoReceivedCallback(),
396 ConnectionHandler::ProtoSentCallback());
397 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); 437 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED);
398 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); 438 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks();
399 factory()->Connect(); 439 factory()->Connect();
400 WaitForConnections(); 440 WaitForConnections();
401 base::TimeTicks retry_time = factory()->NextRetryAttempt(); 441 base::TimeTicks retry_time = factory()->NextRetryAttempt();
402 EXPECT_FALSE(retry_time.is_null()); 442 EXPECT_FALSE(retry_time.is_null());
403 443
404 factory()->SetConnectResult(net::OK); 444 factory()->SetConnectResult(net::OK);
405 connect_time = factory()->tick_clock()->NowTicks(); 445 connect_time = factory()->tick_clock()->NowTicks();
406 WaitForConnections(); 446 WaitForConnections();
407 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 447 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
408 448
409 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); 449 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
410 EXPECT_FALSE(factory()->GetConnectionHandler()->CanSendMessage()); 450 EXPECT_FALSE(factory()->IsEndpointReachable());
411 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); 451 EXPECT_NE(retry_time, factory()->NextRetryAttempt());
412 retry_time = factory()->NextRetryAttempt(); 452 retry_time = factory()->NextRetryAttempt();
413 EXPECT_FALSE(retry_time.is_null()); 453 EXPECT_FALSE(retry_time.is_null());
414 EXPECT_GE((retry_time - connect_time).InMilliseconds(), 454 EXPECT_GE((retry_time - connect_time).InMilliseconds(),
415 CalculateBackoff(2)); 455 CalculateBackoff(2));
416 456
417 factory()->SetConnectResult(net::OK); 457 factory()->SetConnectResult(net::OK);
418 connect_time = factory()->tick_clock()->NowTicks(); 458 connect_time = factory()->tick_clock()->NowTicks();
419 factory()->tick_clock()->Advance( 459 factory()->tick_clock()->Advance(
420 factory()->NextRetryAttempt() - connect_time); 460 factory()->NextRetryAttempt() - connect_time);
421 WaitForConnections(); 461 WaitForConnections();
422 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); 462 EXPECT_TRUE(factory()->NextRetryAttempt().is_null());
463 EXPECT_TRUE(factory()->IsEndpointReachable());
423 464
424 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); 465 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE);
425 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); 466 EXPECT_NE(retry_time, factory()->NextRetryAttempt());
426 retry_time = factory()->NextRetryAttempt(); 467 retry_time = factory()->NextRetryAttempt();
427 EXPECT_FALSE(retry_time.is_null()); 468 EXPECT_FALSE(retry_time.is_null());
428 EXPECT_GE((retry_time - connect_time).InMilliseconds(), 469 EXPECT_GE((retry_time - connect_time).InMilliseconds(),
429 CalculateBackoff(3)); 470 CalculateBackoff(3));
471 EXPECT_FALSE(factory()->IsEndpointReachable());
430 } 472 }
431 473
432 } // namespace 474 } // namespace
433 } // namespace gcm 475 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698