| 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 |