| 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 base::TimeTicks NowTicks() override; | 125 base::TimeTicks NowTicks() override; |
| 126 | 126 |
| 127 // Helpers for verifying connection attempts are made. Connection results | 127 // Helpers for verifying connection attempts are made. Connection results |
| 128 // must be consumed. | 128 // must be consumed. |
| 129 void SetConnectResult(int connect_result); | 129 void SetConnectResult(int connect_result); |
| 130 void SetMultipleConnectResults(int connect_result, int num_expected_attempts); | 130 void SetMultipleConnectResults(int connect_result, int num_expected_attempts); |
| 131 | 131 |
| 132 // Force a login handshake to be delayed. | 132 // Force a login handshake to be delayed. |
| 133 void SetDelayLogin(bool delay_login); | 133 void SetDelayLogin(bool delay_login); |
| 134 | 134 |
| 135 // Simulate a socket error. |
| 136 void SetSocketError(); |
| 137 |
| 135 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; } | 138 base::SimpleTestTickClock* tick_clock() { return &tick_clock_; } |
| 136 | 139 |
| 137 private: | 140 private: |
| 138 // Clock for controlling delay. | 141 // Clock for controlling delay. |
| 139 base::SimpleTestTickClock tick_clock_; | 142 base::SimpleTestTickClock tick_clock_; |
| 140 // The result to return on the next connect attempt. | 143 // The result to return on the next connect attempt. |
| 141 int connect_result_; | 144 int connect_result_; |
| 142 // The number of expected connection attempts; | 145 // The number of expected connection attempts; |
| 143 int num_expected_attempts_; | 146 int num_expected_attempts_; |
| 144 // Whether all expected connection attempts have been fulfilled since an | 147 // Whether all expected connection attempts have been fulfilled since an |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 // Set a non-null time. | 180 // Set a non-null time. |
| 178 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | 181 tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| 179 } | 182 } |
| 180 | 183 |
| 181 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() { | 184 TestConnectionFactoryImpl::~TestConnectionFactoryImpl() { |
| 182 EXPECT_EQ(0, num_expected_attempts_); | 185 EXPECT_EQ(0, num_expected_attempts_); |
| 183 } | 186 } |
| 184 | 187 |
| 185 void TestConnectionFactoryImpl::ConnectImpl() { | 188 void TestConnectionFactoryImpl::ConnectImpl() { |
| 186 ASSERT_GT(num_expected_attempts_, 0); | 189 ASSERT_GT(num_expected_attempts_, 0); |
| 190 ASSERT_FALSE(GetConnectionHandler()->CanSendMessage()); |
| 187 scoped_ptr<mcs_proto::LoginRequest> request(BuildLoginRequest(0, 0, "")); | 191 scoped_ptr<mcs_proto::LoginRequest> request(BuildLoginRequest(0, 0, "")); |
| 188 GetConnectionHandler()->Init(*request, NULL); | 192 GetConnectionHandler()->Init(*request, NULL); |
| 189 OnConnectDone(connect_result_); | 193 OnConnectDone(connect_result_); |
| 190 if (!NextRetryAttempt().is_null()) { | 194 if (!NextRetryAttempt().is_null()) { |
| 191 // Advance the time to the next retry time. | 195 // Advance the time to the next retry time. |
| 192 base::TimeDelta time_till_retry = | 196 base::TimeDelta time_till_retry = |
| 193 NextRetryAttempt() - tick_clock_.NowTicks(); | 197 NextRetryAttempt() - tick_clock_.NowTicks(); |
| 194 tick_clock_.Advance(time_till_retry); | 198 tick_clock_.Advance(time_till_retry); |
| 195 } | 199 } |
| 196 --num_expected_attempts_; | 200 --num_expected_attempts_; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 fake_handler_->ExpectOutgoingMessage( | 252 fake_handler_->ExpectOutgoingMessage( |
| 249 MCSMessage(kLoginRequestTag, BuildLoginRequest(0, 0, ""))); | 253 MCSMessage(kLoginRequestTag, BuildLoginRequest(0, 0, ""))); |
| 250 } | 254 } |
| 251 } | 255 } |
| 252 | 256 |
| 253 void TestConnectionFactoryImpl::SetDelayLogin(bool delay_login) { | 257 void TestConnectionFactoryImpl::SetDelayLogin(bool delay_login) { |
| 254 delay_login_ = delay_login; | 258 delay_login_ = delay_login; |
| 255 fake_handler_->set_fail_login(delay_login_); | 259 fake_handler_->set_fail_login(delay_login_); |
| 256 } | 260 } |
| 257 | 261 |
| 262 void TestConnectionFactoryImpl::SetSocketError() { |
| 263 fake_handler_->set_had_error(true); |
| 264 } |
| 265 |
| 258 } // namespace | 266 } // namespace |
| 259 | 267 |
| 260 class ConnectionFactoryImplTest | 268 class ConnectionFactoryImplTest |
| 261 : public testing::Test, | 269 : public testing::Test, |
| 262 public ConnectionFactory::ConnectionListener { | 270 public ConnectionFactory::ConnectionListener { |
| 263 public: | 271 public: |
| 264 ConnectionFactoryImplTest(); | 272 ConnectionFactoryImplTest(); |
| 265 ~ConnectionFactoryImplTest() override; | 273 ~ConnectionFactoryImplTest() override; |
| 266 | 274 |
| 267 TestConnectionFactoryImpl* factory() { return &factory_; } | 275 TestConnectionFactoryImpl* factory() { return &factory_; } |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 // Receiving a network change event before the initial connection should have | 562 // Receiving a network change event before the initial connection should have |
| 555 // no effect. | 563 // no effect. |
| 556 TEST_F(ConnectionFactoryImplTest, NetworkChangeBeforeFirstConnection) { | 564 TEST_F(ConnectionFactoryImplTest, NetworkChangeBeforeFirstConnection) { |
| 557 factory()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_4G); | 565 factory()->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_4G); |
| 558 factory()->SetConnectResult(net::OK); | 566 factory()->SetConnectResult(net::OK); |
| 559 factory()->Connect(); | 567 factory()->Connect(); |
| 560 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); | 568 EXPECT_TRUE(factory()->NextRetryAttempt().is_null()); |
| 561 EXPECT_TRUE(factory()->IsEndpointReachable()); | 569 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 562 } | 570 } |
| 563 | 571 |
| 572 // Test that if the client attempts to reconnect while a connection is already |
| 573 // open, we don't crash. |
| 574 TEST_F(ConnectionFactoryImplTest, ConnectionResetRace) { |
| 575 // Initial successful connection. |
| 576 factory()->SetConnectResult(net::OK); |
| 577 factory()->Connect(); |
| 578 WaitForConnections(); |
| 579 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 580 |
| 581 // Trigger a connection error under the hood. |
| 582 factory()->SetSocketError(); |
| 583 EXPECT_FALSE(factory()->IsEndpointReachable()); |
| 584 |
| 585 // Now trigger force a re-connection. |
| 586 factory()->SetConnectResult(net::OK); |
| 587 factory()->Connect(); |
| 588 WaitForConnections(); |
| 589 |
| 590 // Re-connection should succeed. |
| 591 EXPECT_TRUE(factory()->IsEndpointReachable()); |
| 592 } |
| 593 |
| 564 } // namespace gcm | 594 } // namespace gcm |
| OLD | NEW |