OLD | NEW |
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" |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 BuildLoginRequest(0, 0, "").PassAs< | 247 BuildLoginRequest(0, 0, "").PassAs< |
248 const google::protobuf::MessageLite>())); | 248 const google::protobuf::MessageLite>())); |
249 } | 249 } |
250 } | 250 } |
251 | 251 |
252 void TestConnectionFactoryImpl::SetDelayLogin(bool delay_login) { | 252 void TestConnectionFactoryImpl::SetDelayLogin(bool delay_login) { |
253 delay_login_ = delay_login; | 253 delay_login_ = delay_login; |
254 fake_handler_->set_fail_login(delay_login_); | 254 fake_handler_->set_fail_login(delay_login_); |
255 } | 255 } |
256 | 256 |
257 class ConnectionFactoryImplTest : public testing::Test { | 257 } // namespace |
| 258 |
| 259 class ConnectionFactoryImplTest |
| 260 : public testing::Test, |
| 261 public ConnectionFactory::ConnectionListener { |
258 public: | 262 public: |
259 ConnectionFactoryImplTest(); | 263 ConnectionFactoryImplTest(); |
260 virtual ~ConnectionFactoryImplTest(); | 264 virtual ~ConnectionFactoryImplTest(); |
261 | 265 |
262 TestConnectionFactoryImpl* factory() { return &factory_; } | 266 TestConnectionFactoryImpl* factory() { return &factory_; } |
| 267 GURL& connected_server() { return connected_server_; } |
263 | 268 |
264 void WaitForConnections(); | 269 void WaitForConnections(); |
265 | 270 |
| 271 // ConnectionFactory::ConnectionListener |
| 272 virtual void OnConnected(const GURL& current_server, |
| 273 const net::IPEndPoint& ip_endpoint) OVERRIDE; |
| 274 virtual void OnDisconnected() OVERRIDE; |
| 275 |
266 private: | 276 private: |
267 void ConnectionsComplete(); | 277 void ConnectionsComplete(); |
268 | 278 |
269 TestConnectionFactoryImpl factory_; | 279 TestConnectionFactoryImpl factory_; |
270 base::MessageLoop message_loop_; | 280 base::MessageLoop message_loop_; |
271 scoped_ptr<base::RunLoop> run_loop_; | 281 scoped_ptr<base::RunLoop> run_loop_; |
| 282 |
| 283 GURL connected_server_; |
272 }; | 284 }; |
273 | 285 |
274 ConnectionFactoryImplTest::ConnectionFactoryImplTest() | 286 ConnectionFactoryImplTest::ConnectionFactoryImplTest() |
275 : factory_(base::Bind(&ConnectionFactoryImplTest::ConnectionsComplete, | 287 : factory_(base::Bind(&ConnectionFactoryImplTest::ConnectionsComplete, |
276 base::Unretained(this))), | 288 base::Unretained(this))), |
277 run_loop_(new base::RunLoop()) { | 289 run_loop_(new base::RunLoop()) { |
| 290 factory()->SetConnectionListener(this); |
278 factory()->Initialize( | 291 factory()->Initialize( |
279 ConnectionFactory::BuildLoginRequestCallback(), | 292 ConnectionFactory::BuildLoginRequestCallback(), |
280 ConnectionHandler::ProtoReceivedCallback(), | 293 ConnectionHandler::ProtoReceivedCallback(), |
281 ConnectionHandler::ProtoSentCallback()); | 294 ConnectionHandler::ProtoSentCallback()); |
282 } | 295 } |
283 ConnectionFactoryImplTest::~ConnectionFactoryImplTest() {} | 296 ConnectionFactoryImplTest::~ConnectionFactoryImplTest() {} |
284 | 297 |
285 void ConnectionFactoryImplTest::WaitForConnections() { | 298 void ConnectionFactoryImplTest::WaitForConnections() { |
286 run_loop_->Run(); | 299 run_loop_->Run(); |
287 run_loop_.reset(new base::RunLoop()); | 300 run_loop_.reset(new base::RunLoop()); |
288 } | 301 } |
289 | 302 |
290 void ConnectionFactoryImplTest::ConnectionsComplete() { | 303 void ConnectionFactoryImplTest::ConnectionsComplete() { |
291 if (!run_loop_) | 304 if (!run_loop_) |
292 return; | 305 return; |
293 run_loop_->Quit(); | 306 run_loop_->Quit(); |
294 } | 307 } |
295 | 308 |
| 309 void ConnectionFactoryImplTest::OnConnected( |
| 310 const GURL& current_server, |
| 311 const net::IPEndPoint& ip_endpoint) { |
| 312 connected_server_ = current_server; |
| 313 } |
| 314 |
| 315 void ConnectionFactoryImplTest::OnDisconnected() { |
| 316 connected_server_ = GURL(); |
| 317 } |
| 318 |
296 // Verify building a connection handler works. | 319 // Verify building a connection handler works. |
297 TEST_F(ConnectionFactoryImplTest, Initialize) { | 320 TEST_F(ConnectionFactoryImplTest, Initialize) { |
298 ConnectionHandler* handler = factory()->GetConnectionHandler(); | 321 ConnectionHandler* handler = factory()->GetConnectionHandler(); |
299 ASSERT_TRUE(handler); | 322 ASSERT_TRUE(handler); |
300 EXPECT_FALSE(factory()->IsEndpointReachable()); | 323 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 324 EXPECT_FALSE(connected_server().is_valid()); |
301 } | 325 } |
302 | 326 |
303 // An initial successful connection should not result in backoff. | 327 // An initial successful connection should not result in backoff. |
304 TEST_F(ConnectionFactoryImplTest, ConnectSuccess) { | 328 TEST_F(ConnectionFactoryImplTest, ConnectSuccess) { |
305 factory()->SetConnectResult(net::OK); | 329 factory()->SetConnectResult(net::OK); |
306 factory()->Connect(); | 330 factory()->Connect(); |
307 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 331 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
308 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[0]); | 332 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[0]); |
309 EXPECT_TRUE(factory()->IsEndpointReachable()); | 333 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 334 EXPECT_TRUE(connected_server().is_valid()); |
310 } | 335 } |
311 | 336 |
312 // A connection failure should result in backoff, and attempting the fallback | 337 // A connection failure should result in backoff, and attempting the fallback |
313 // endpoint next. | 338 // endpoint next. |
314 TEST_F(ConnectionFactoryImplTest, ConnectFail) { | 339 TEST_F(ConnectionFactoryImplTest, ConnectFail) { |
315 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); | 340 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); |
316 factory()->Connect(); | 341 factory()->Connect(); |
317 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); | 342 EXPECT_FALSE(factory()->NextRetryAttempt().is_null()); |
318 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[1]); | 343 EXPECT_EQ(factory()->GetCurrentEndpoint(), BuildEndpoints()[1]); |
319 EXPECT_FALSE(factory()->IsEndpointReachable()); | 344 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 345 EXPECT_FALSE(connected_server().is_valid()); |
320 } | 346 } |
321 | 347 |
322 // A connection success after a failure should reset backoff. | 348 // A connection success after a failure should reset backoff. |
323 TEST_F(ConnectionFactoryImplTest, FailThenSucceed) { | 349 TEST_F(ConnectionFactoryImplTest, FailThenSucceed) { |
324 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); | 350 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); |
325 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); | 351 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); |
326 factory()->Connect(); | 352 factory()->Connect(); |
327 WaitForConnections(); | 353 WaitForConnections(); |
328 EXPECT_FALSE(factory()->IsEndpointReachable()); | 354 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 355 EXPECT_FALSE(connected_server().is_valid()); |
329 base::TimeTicks retry_time = factory()->NextRetryAttempt(); | 356 base::TimeTicks retry_time = factory()->NextRetryAttempt(); |
330 EXPECT_FALSE(retry_time.is_null()); | 357 EXPECT_FALSE(retry_time.is_null()); |
331 EXPECT_GE((retry_time - connect_time).InMilliseconds(), CalculateBackoff(1)); | 358 EXPECT_GE((retry_time - connect_time).InMilliseconds(), CalculateBackoff(1)); |
332 factory()->SetConnectResult(net::OK); | 359 factory()->SetConnectResult(net::OK); |
333 WaitForConnections(); | 360 WaitForConnections(); |
334 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 361 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
335 EXPECT_TRUE(factory()->IsEndpointReachable()); | 362 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 363 EXPECT_TRUE(connected_server().is_valid()); |
336 } | 364 } |
337 | 365 |
338 // Multiple connection failures should retry with an exponentially increasing | 366 // Multiple connection failures should retry with an exponentially increasing |
339 // backoff, then reset on success. | 367 // backoff, then reset on success. |
340 TEST_F(ConnectionFactoryImplTest, MultipleFailuresThenSucceed) { | 368 TEST_F(ConnectionFactoryImplTest, MultipleFailuresThenSucceed) { |
341 const int kNumAttempts = 5; | 369 const int kNumAttempts = 5; |
342 factory()->SetMultipleConnectResults(net::ERR_CONNECTION_FAILED, | 370 factory()->SetMultipleConnectResults(net::ERR_CONNECTION_FAILED, |
343 kNumAttempts); | 371 kNumAttempts); |
344 | 372 |
345 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); | 373 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); |
346 factory()->Connect(); | 374 factory()->Connect(); |
347 WaitForConnections(); | 375 WaitForConnections(); |
348 EXPECT_FALSE(factory()->IsEndpointReachable()); | 376 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 377 EXPECT_FALSE(connected_server().is_valid()); |
349 base::TimeTicks retry_time = factory()->NextRetryAttempt(); | 378 base::TimeTicks retry_time = factory()->NextRetryAttempt(); |
350 EXPECT_FALSE(retry_time.is_null()); | 379 EXPECT_FALSE(retry_time.is_null()); |
351 EXPECT_GE((retry_time - connect_time).InMilliseconds(), | 380 EXPECT_GE((retry_time - connect_time).InMilliseconds(), |
352 CalculateBackoff(kNumAttempts)); | 381 CalculateBackoff(kNumAttempts)); |
353 | 382 |
354 factory()->SetConnectResult(net::OK); | 383 factory()->SetConnectResult(net::OK); |
355 WaitForConnections(); | 384 WaitForConnections(); |
356 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 385 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
357 EXPECT_TRUE(factory()->IsEndpointReachable()); | 386 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 387 EXPECT_TRUE(connected_server().is_valid()); |
358 } | 388 } |
359 | 389 |
360 // IP events should trigger canary connections. | 390 // IP events should trigger canary connections. |
361 TEST_F(ConnectionFactoryImplTest, FailThenIPEvent) { | 391 TEST_F(ConnectionFactoryImplTest, FailThenIPEvent) { |
362 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); | 392 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); |
363 factory()->Connect(); | 393 factory()->Connect(); |
364 WaitForConnections(); | 394 WaitForConnections(); |
365 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); | 395 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); |
366 EXPECT_FALSE(initial_backoff.is_null()); | 396 EXPECT_FALSE(initial_backoff.is_null()); |
367 | 397 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 factory()->Connect(); | 431 factory()->Connect(); |
402 WaitForConnections(); | 432 WaitForConnections(); |
403 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); | 433 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); |
404 EXPECT_FALSE(initial_backoff.is_null()); | 434 EXPECT_FALSE(initial_backoff.is_null()); |
405 | 435 |
406 factory()->SetConnectResult(net::OK); | 436 factory()->SetConnectResult(net::OK); |
407 factory()->OnConnectionTypeChanged( | 437 factory()->OnConnectionTypeChanged( |
408 net::NetworkChangeNotifier::CONNECTION_WIFI); | 438 net::NetworkChangeNotifier::CONNECTION_WIFI); |
409 WaitForConnections(); | 439 WaitForConnections(); |
410 EXPECT_TRUE(factory()->IsEndpointReachable()); | 440 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 441 EXPECT_TRUE(connected_server().is_valid()); |
411 | 442 |
412 factory()->SetConnectResult(net::OK); | 443 factory()->SetConnectResult(net::OK); |
413 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); | 444 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); |
414 EXPECT_FALSE(factory()->IsEndpointReachable()); | 445 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 446 EXPECT_FALSE(connected_server().is_valid()); |
415 WaitForConnections(); | 447 WaitForConnections(); |
416 EXPECT_TRUE(factory()->IsEndpointReachable()); | 448 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 449 EXPECT_TRUE(connected_server().is_valid()); |
417 } | 450 } |
418 | 451 |
419 // Verify that if a canary connects, but hasn't finished the handshake, a | 452 // Verify that if a canary connects, but hasn't finished the handshake, a |
420 // pending backoff attempt doesn't interrupt the connection. | 453 // pending backoff attempt doesn't interrupt the connection. |
421 TEST_F(ConnectionFactoryImplTest, CanarySucceedsRetryDuringLogin) { | 454 TEST_F(ConnectionFactoryImplTest, CanarySucceedsRetryDuringLogin) { |
422 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); | 455 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); |
423 factory()->Connect(); | 456 factory()->Connect(); |
424 WaitForConnections(); | 457 WaitForConnections(); |
425 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); | 458 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); |
426 EXPECT_FALSE(initial_backoff.is_null()); | 459 EXPECT_FALSE(initial_backoff.is_null()); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 base::TimeTicks retry_time = factory()->NextRetryAttempt(); | 512 base::TimeTicks retry_time = factory()->NextRetryAttempt(); |
480 EXPECT_FALSE(retry_time.is_null()); | 513 EXPECT_FALSE(retry_time.is_null()); |
481 | 514 |
482 factory()->SetConnectResult(net::OK); | 515 factory()->SetConnectResult(net::OK); |
483 connect_time = factory()->tick_clock()->NowTicks(); | 516 connect_time = factory()->tick_clock()->NowTicks(); |
484 WaitForConnections(); | 517 WaitForConnections(); |
485 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 518 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
486 | 519 |
487 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); | 520 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); |
488 EXPECT_FALSE(factory()->IsEndpointReachable()); | 521 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 522 EXPECT_FALSE(connected_server().is_valid()); |
489 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); | 523 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); |
490 retry_time = factory()->NextRetryAttempt(); | 524 retry_time = factory()->NextRetryAttempt(); |
491 EXPECT_FALSE(retry_time.is_null()); | 525 EXPECT_FALSE(retry_time.is_null()); |
492 EXPECT_GE((retry_time - connect_time).InMilliseconds(), | 526 EXPECT_GE((retry_time - connect_time).InMilliseconds(), |
493 CalculateBackoff(2)); | 527 CalculateBackoff(2)); |
494 | 528 |
495 factory()->SetConnectResult(net::OK); | 529 factory()->SetConnectResult(net::OK); |
496 connect_time = factory()->tick_clock()->NowTicks(); | 530 connect_time = factory()->tick_clock()->NowTicks(); |
497 factory()->tick_clock()->Advance( | 531 factory()->tick_clock()->Advance( |
498 factory()->NextRetryAttempt() - connect_time); | 532 factory()->NextRetryAttempt() - connect_time); |
499 WaitForConnections(); | 533 WaitForConnections(); |
500 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 534 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
501 EXPECT_TRUE(factory()->IsEndpointReachable()); | 535 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 536 EXPECT_TRUE(connected_server().is_valid()); |
502 | 537 |
503 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); | 538 factory()->SignalConnectionReset(ConnectionFactory::SOCKET_FAILURE); |
504 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); | 539 EXPECT_NE(retry_time, factory()->NextRetryAttempt()); |
505 retry_time = factory()->NextRetryAttempt(); | 540 retry_time = factory()->NextRetryAttempt(); |
506 EXPECT_FALSE(retry_time.is_null()); | 541 EXPECT_FALSE(retry_time.is_null()); |
507 EXPECT_GE((retry_time - connect_time).InMilliseconds(), | 542 EXPECT_GE((retry_time - connect_time).InMilliseconds(), |
508 CalculateBackoff(3)); | 543 CalculateBackoff(3)); |
509 EXPECT_FALSE(factory()->IsEndpointReachable()); | 544 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 545 EXPECT_FALSE(connected_server().is_valid()); |
510 } | 546 } |
511 | 547 |
512 } // namespace | |
513 } // namespace gcm | 548 } // namespace gcm |
OLD | NEW |