| 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 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 // A connection factory that stubs out network requests and overrides the | 83 // A connection factory that stubs out network requests and overrides the |
| 84 // backoff policy. | 84 // backoff policy. |
| 85 class TestConnectionFactoryImpl : public ConnectionFactoryImpl { | 85 class TestConnectionFactoryImpl : public ConnectionFactoryImpl { |
| 86 public: | 86 public: |
| 87 TestConnectionFactoryImpl(const base::Closure& finished_callback); | 87 TestConnectionFactoryImpl(const base::Closure& finished_callback); |
| 88 ~TestConnectionFactoryImpl() override; | 88 ~TestConnectionFactoryImpl() override; |
| 89 | 89 |
| 90 void InitializeFactory(); | 90 void InitializeFactory(); |
| 91 | 91 |
| 92 // Overridden stubs. | 92 // Overridden stubs. |
| 93 void ConnectImpl() override; | 93 void StartConnection() override; |
| 94 void InitHandler() override; | 94 void InitHandler() override; |
| 95 std::unique_ptr<net::BackoffEntry> CreateBackoffEntry( | 95 std::unique_ptr<net::BackoffEntry> CreateBackoffEntry( |
| 96 const net::BackoffEntry::Policy* const policy) override; | 96 const net::BackoffEntry::Policy* const policy) override; |
| 97 std::unique_ptr<ConnectionHandler> CreateConnectionHandler( | 97 std::unique_ptr<ConnectionHandler> CreateConnectionHandler( |
| 98 base::TimeDelta read_timeout, | 98 base::TimeDelta read_timeout, |
| 99 const ConnectionHandler::ProtoReceivedCallback& read_callback, | 99 const ConnectionHandler::ProtoReceivedCallback& read_callback, |
| 100 const ConnectionHandler::ProtoSentCallback& write_callback, | 100 const ConnectionHandler::ProtoSentCallback& write_callback, |
| 101 const ConnectionHandler::ConnectionChangedCallback& connection_callback) | 101 const ConnectionHandler::ConnectionChangedCallback& connection_callback) |
| 102 override; | 102 override; |
| 103 base::TimeTicks NowTicks() override; | 103 base::TimeTicks NowTicks() override; |
| 104 | 104 |
| 105 // Helpers for verifying connection attempts are made. Connection results | 105 // Helpers for verifying connection attempts are made. Connection results |
| 106 // must be consumed. | 106 // must be consumed. |
| 107 void SetConnectResult(int connect_result); | 107 void SetConnectResult(int connect_result); |
| 108 void SetMultipleConnectResults(int connect_result, int num_expected_attempts); | 108 void SetMultipleConnectResults(int connect_result, int num_expected_attempts); |
| 109 | 109 |
| 110 // Force a login handshake to be delayed. | 110 // Force a login handshake to be delayed. |
| 111 void SetDelayLogin(bool delay_login); | 111 void SetDelayLogin(bool delay_login); |
| 112 | 112 |
| 113 // Simulate a socket error. | 113 // Simulate a socket error. |
| 114 void SetSocketError(); | 114 void SetSocketError(); |
| 115 | 115 |
| 116 // Get the client events recorded by the factory. |
| 117 const google::protobuf::RepeatedPtrField<mcs_proto::ClientEvent>* |
| 118 GetClientEventsForTest() { |
| 119 return &client_events_; |
| 120 } |
| 121 |
| 116 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; } | 122 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; } |
| 117 | 123 |
| 118 private: | 124 private: |
| 119 // Clock for controlling delay. | 125 // Clock for controlling delay. |
| 120 base::SimpleTestTickClock tick_clock_; | 126 base::SimpleTestTickClock tick_clock_; |
| 121 // The result to return on the next connect attempt. | 127 // The result to return on the next connect attempt. |
| 122 int connect_result_; | 128 int connect_result_; |
| 123 // The number of expected connection attempts; | 129 // The number of expected connection attempts; |
| 124 int num_expected_attempts_; | 130 int num_expected_attempts_; |
| 125 // Whether all expected connection attempts have been fulfilled since an | 131 // Whether all expected connection attempts have been fulfilled since an |
| (...skipping 30 matching lines...) Expand all Loading... |
| 156 base::Bind(&WriteContinuation))), | 162 base::Bind(&WriteContinuation))), |
| 157 fake_handler_(scoped_handler_.get()) { | 163 fake_handler_(scoped_handler_.get()) { |
| 158 // Set a non-null time. | 164 // Set a non-null time. |
| 159 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | 165 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| 160 } | 166 } |
| 161 | 167 |
| 162 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() { | 168 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() { |
| 163 EXPECT_EQ(0, num_expected_attempts_); | 169 EXPECT_EQ(0, num_expected_attempts_); |
| 164 } | 170 } |
| 165 | 171 |
| 166 void TestConnectionFactoryImpl::ConnectImpl() { | 172 void TestConnectionFactoryImpl::StartConnection() { |
| 167 ASSERT_GT(num_expected_attempts_, 0); | 173 ASSERT_GT(num_expected_attempts_, 0); |
| 168 ASSERT_FALSE(GetConnectionHandler()->CanSendMessage()); | 174 ASSERT_FALSE(GetConnectionHandler()->CanSendMessage()); |
| 169 std::unique_ptr<mcs_proto::LoginRequest> request(BuildLoginRequest(0, 0, "")); | 175 std::unique_ptr<mcs_proto::LoginRequest> request(BuildLoginRequest(0, 0, "")); |
| 170 GetConnectionHandler()->Init(*request, NULL); | 176 GetConnectionHandler()->Init(*request, NULL); |
| 171 OnConnectDone(connect_result_); | 177 OnConnectDone(connect_result_); |
| 172 if (!NextRetryAttempt().is_null()) { | 178 if (!NextRetryAttempt().is_null()) { |
| 173 // Advance the time to the next retry time. | 179 // Advance the time to the next retry time. |
| 174 base::TimeDelta time_till_retry = | 180 base::TimeDelta time_till_retry = |
| 175 NextRetryAttempt() - tick_clock_.NowTicks(); | 181 NextRetryAttempt() - tick_clock_.NowTicks(); |
| 176 tick_clock_.Advance(time_till_retry); | 182 tick_clock_.Advance(time_till_retry); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); | 367 base::TimeTicks connect_time = factory()->tick_clock()->NowTicks(); |
| 362 factory()->Connect(); | 368 factory()->Connect(); |
| 363 WaitForConnections(); | 369 WaitForConnections(); |
| 364 EXPECT_FALSE(factory()->IsEndpointReachable()); | 370 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 365 EXPECT_FALSE(connected_server().is_valid()); | 371 EXPECT_FALSE(connected_server().is_valid()); |
| 366 base::TimeTicks retry_time = factory()->NextRetryAttempt(); | 372 base::TimeTicks retry_time = factory()->NextRetryAttempt(); |
| 367 EXPECT_FALSE(retry_time.is_null()); | 373 EXPECT_FALSE(retry_time.is_null()); |
| 368 EXPECT_GE((retry_time - connect_time).InMilliseconds(), | 374 EXPECT_GE((retry_time - connect_time).InMilliseconds(), |
| 369 CalculateBackoff(kNumAttempts)); | 375 CalculateBackoff(kNumAttempts)); |
| 370 | 376 |
| 377 // There should be one failed client event for each failed connection, but the |
| 378 // most recent failure won't be added until the next connect attempt. |
| 379 const auto* client_events = factory()->GetClientEventsForTest(); |
| 380 ASSERT_EQ(kNumAttempts - 1, client_events->size()); |
| 381 |
| 382 for (const auto client_event : *client_events) { |
| 383 EXPECT_EQ(mcs_proto::ClientEvent::FAILED_CONNECTION, client_event.type()); |
| 384 EXPECT_EQ(net::ERR_CONNECTION_FAILED, client_event.error_code()); |
| 385 } |
| 386 |
| 371 factory()->SetConnectResult(net::OK); | 387 factory()->SetConnectResult(net::OK); |
| 372 WaitForConnections(); | 388 WaitForConnections(); |
| 373 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 389 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
| 374 EXPECT_TRUE(factory()->IsEndpointReachable()); | 390 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 375 EXPECT_TRUE(connected_server().is_valid()); | 391 EXPECT_TRUE(connected_server().is_valid()); |
| 392 |
| 393 // Old client events should have been reset after the successful connection. |
| 394 client_events = factory()->GetClientEventsForTest(); |
| 395 ASSERT_EQ(0, client_events->size()); |
| 376 } | 396 } |
| 377 | 397 |
| 378 // Network change events should trigger canary connections. | 398 // Network change events should trigger canary connections. |
| 379 TEST_F(ConnectionFactoryImplTest, FailThenNetworkChangeEvent) { | 399 TEST_F(ConnectionFactoryImplTest, FailThenNetworkChangeEvent) { |
| 380 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); | 400 factory()->SetConnectResult(net::ERR_CONNECTION_FAILED); |
| 381 factory()->Connect(); | 401 factory()->Connect(); |
| 382 WaitForConnections(); | 402 WaitForConnections(); |
| 383 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); | 403 base::TimeTicks initial_backoff = factory()->NextRetryAttempt(); |
| 384 EXPECT_FALSE(initial_backoff.is_null()); | 404 EXPECT_FALSE(initial_backoff.is_null()); |
| 385 | 405 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 | 582 |
| 563 // Now trigger force a re-connection. | 583 // Now trigger force a re-connection. |
| 564 factory()->SetConnectResult(net::OK); | 584 factory()->SetConnectResult(net::OK); |
| 565 factory()->Connect(); | 585 factory()->Connect(); |
| 566 WaitForConnections(); | 586 WaitForConnections(); |
| 567 | 587 |
| 568 // Re-connection should succeed. | 588 // Re-connection should succeed. |
| 569 EXPECT_TRUE(factory()->IsEndpointReachable()); | 589 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 570 } | 590 } |
| 571 | 591 |
| 592 TEST_F(ConnectionFactoryImplTest, MultipleFailuresWrapClientEvents) { |
| 593 const int kNumAttempts = 50; |
| 594 factory()->SetMultipleConnectResults(net::ERR_CONNECTION_FAILED, |
| 595 kNumAttempts); |
| 596 |
| 597 factory()->Connect(); |
| 598 WaitForConnections(); |
| 599 |
| 600 // There should be one failed client event for each failed connection, but |
| 601 // there is a maximum cap of kMaxClientEvents, which is 30. |
| 602 const auto* client_events = factory()->GetClientEventsForTest(); |
| 603 ASSERT_EQ(30, client_events->size()); |
| 604 |
| 605 for (const auto client_event : *client_events) { |
| 606 EXPECT_EQ(mcs_proto::ClientEvent::FAILED_CONNECTION, client_event.type()); |
| 607 EXPECT_EQ(net::ERR_CONNECTION_FAILED, client_event.error_code()); |
| 608 } |
| 609 |
| 610 factory()->SetConnectResult(net::OK); |
| 611 WaitForConnections(); |
| 612 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 613 EXPECT_TRUE(connected_server().is_valid()); |
| 614 |
| 615 // Old client events should have been reset after the successful connection. |
| 616 client_events = factory()->GetClientEventsForTest(); |
| 617 ASSERT_EQ(0, client_events->size()); |
| 618 } |
| 619 |
| 572 } // namespace gcm | 620 } // namespace gcm |
| OLD | NEW |