| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/run_loop.h" | 5 #include "base/run_loop.h" |
| 6 #include "base/strings/string_util.h" | 6 #include "base/strings/string_util.h" |
| 7 #include "google_apis/gaia/google_service_auth_error.h" | 7 #include "google_apis/gaia/google_service_auth_error.h" |
| 8 #include "net/url_request/test_url_fetcher_factory.h" | 8 #include "net/url_request/test_url_fetcher_factory.h" |
| 9 #include "net/url_request/url_request_test_util.h" | 9 #include "net/url_request/url_request_test_util.h" |
| 10 #include "sync/notifier/gcm_network_channel.h" | 10 #include "sync/notifier/gcm_network_channel.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 private: | 111 private: |
| 112 GCMNetworkChannelTest* test_; | 112 GCMNetworkChannelTest* test_; |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 class GCMNetworkChannelTest | 115 class GCMNetworkChannelTest |
| 116 : public ::testing::Test, | 116 : public ::testing::Test, |
| 117 public SyncNetworkChannel::Observer { | 117 public SyncNetworkChannel::Observer { |
| 118 public: | 118 public: |
| 119 GCMNetworkChannelTest() | 119 GCMNetworkChannelTest() |
| 120 : delegate_(NULL), | 120 : delegate_(NULL), |
| 121 url_fetchers_created_count_(0) { | 121 url_fetchers_created_count_(0), |
| 122 } | 122 last_invalidator_state_(TRANSIENT_INVALIDATION_ERROR) {} |
| 123 | 123 |
| 124 virtual ~GCMNetworkChannelTest() { | 124 virtual ~GCMNetworkChannelTest() { |
| 125 } | 125 } |
| 126 | 126 |
| 127 virtual void SetUp() { | 127 virtual void SetUp() { |
| 128 request_context_getter_ = new net::TestURLRequestContextGetter( | 128 request_context_getter_ = new net::TestURLRequestContextGetter( |
| 129 base::MessageLoopProxy::current()); | 129 base::MessageLoopProxy::current()); |
| 130 // Ownership of delegate goes to GCNMentworkChannel but test needs pointer | 130 // Ownership of delegate goes to GCNMentworkChannel but test needs pointer |
| 131 // to it. | 131 // to it. |
| 132 delegate_ = new TestGCMNetworkChannelDelegate(); | 132 delegate_ = new TestGCMNetworkChannelDelegate(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 157 GCMNetworkChannel::Base64EncodeURLSafe(input, output); | 157 GCMNetworkChannel::Base64EncodeURLSafe(input, output); |
| 158 } | 158 } |
| 159 | 159 |
| 160 static bool Base64DecodeURLSafe(const std::string& input, | 160 static bool Base64DecodeURLSafe(const std::string& input, |
| 161 std::string* output) { | 161 std::string* output) { |
| 162 return GCMNetworkChannel::Base64DecodeURLSafe(input, output); | 162 return GCMNetworkChannel::Base64DecodeURLSafe(input, output); |
| 163 } | 163 } |
| 164 | 164 |
| 165 virtual void OnNetworkChannelStateChanged( | 165 virtual void OnNetworkChannelStateChanged( |
| 166 InvalidatorState invalidator_state) OVERRIDE { | 166 InvalidatorState invalidator_state) OVERRIDE { |
| 167 last_invalidator_state_ = invalidator_state; |
| 167 } | 168 } |
| 168 | 169 |
| 169 void OnIncomingMessage(std::string incoming_message) { | 170 void OnIncomingMessage(std::string incoming_message) { |
| 170 } | 171 } |
| 171 | 172 |
| 172 GCMNetworkChannel* network_channel() { | 173 GCMNetworkChannel* network_channel() { |
| 173 return gcm_network_channel_.get(); | 174 return gcm_network_channel_.get(); |
| 174 } | 175 } |
| 175 | 176 |
| 176 TestGCMNetworkChannelDelegate* delegate() { | 177 TestGCMNetworkChannelDelegate* delegate() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 197 } | 198 } |
| 198 | 199 |
| 199 void set_last_echo_token(const std::string& echo_token) { | 200 void set_last_echo_token(const std::string& echo_token) { |
| 200 last_echo_token_ = echo_token; | 201 last_echo_token_ = echo_token; |
| 201 } | 202 } |
| 202 | 203 |
| 203 const std::string& get_last_echo_token() { | 204 const std::string& get_last_echo_token() { |
| 204 return last_echo_token_; | 205 return last_echo_token_; |
| 205 } | 206 } |
| 206 | 207 |
| 208 InvalidatorState get_last_invalidator_state() { |
| 209 return last_invalidator_state_; |
| 210 } |
| 211 |
| 207 void RunLoopUntilIdle() { | 212 void RunLoopUntilIdle() { |
| 208 base::RunLoop run_loop; | 213 base::RunLoop run_loop; |
| 209 run_loop.RunUntilIdle(); | 214 run_loop.RunUntilIdle(); |
| 210 } | 215 } |
| 211 | 216 |
| 212 private: | 217 private: |
| 213 base::MessageLoop message_loop_; | 218 base::MessageLoop message_loop_; |
| 214 TestGCMNetworkChannelDelegate* delegate_; | 219 TestGCMNetworkChannelDelegate* delegate_; |
| 215 scoped_ptr<GCMNetworkChannel> gcm_network_channel_; | 220 scoped_ptr<GCMNetworkChannel> gcm_network_channel_; |
| 216 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; | 221 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; |
| 217 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; | 222 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; |
| 218 int url_fetchers_created_count_; | 223 int url_fetchers_created_count_; |
| 219 std::string last_echo_token_; | 224 std::string last_echo_token_; |
| 225 InvalidatorState last_invalidator_state_; |
| 220 }; | 226 }; |
| 221 | 227 |
| 222 void TestNetworkChannelURLFetcher::AddExtraRequestHeader( | 228 void TestNetworkChannelURLFetcher::AddExtraRequestHeader( |
| 223 const std::string& header_line) { | 229 const std::string& header_line) { |
| 224 net::FakeURLFetcher::AddExtraRequestHeader(header_line); | 230 net::FakeURLFetcher::AddExtraRequestHeader(header_line); |
| 225 std::string header_name("echo-token: "); | 231 std::string header_name("echo-token: "); |
| 226 std::string echo_token; | 232 std::string echo_token; |
| 227 if (StartsWithASCII(header_line, header_name, false)) { | 233 if (StartsWithASCII(header_line, header_name, false)) { |
| 228 echo_token = header_line; | 234 echo_token = header_line; |
| 229 ReplaceFirstSubstringAfterOffset( | 235 ReplaceFirstSubstringAfterOffset( |
| 230 &echo_token, 0, header_name, std::string()); | 236 &echo_token, 0, header_name, std::string()); |
| 231 test_->set_last_echo_token(echo_token); | 237 test_->set_last_echo_token(echo_token); |
| 232 } | 238 } |
| 233 } | 239 } |
| 234 | 240 |
| 235 TEST_F(GCMNetworkChannelTest, HappyCase) { | 241 TEST_F(GCMNetworkChannelTest, HappyCase) { |
| 242 EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, get_last_invalidator_state()); |
| 236 EXPECT_FALSE(delegate()->message_callback.is_null()); | 243 EXPECT_FALSE(delegate()->message_callback.is_null()); |
| 237 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), | 244 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 238 std::string(), | 245 std::string(), |
| 239 net::HTTP_OK, | 246 net::HTTP_NO_CONTENT, |
| 240 net::URLRequestStatus::SUCCESS); | 247 net::URLRequestStatus::SUCCESS); |
| 241 | 248 |
| 242 // After construction GCMNetworkChannel should have called Register. | 249 // After construction GCMNetworkChannel should have called Register. |
| 243 EXPECT_FALSE(delegate()->register_callback.is_null()); | 250 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 244 // Return valid registration id. | 251 // Return valid registration id. |
| 245 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); | 252 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 246 | 253 |
| 247 network_channel()->SendMessage("abra.cadabra"); | 254 network_channel()->SendMessage("abra.cadabra"); |
| 248 // SendMessage should have triggered RequestToken. No HTTP request should be | 255 // SendMessage should have triggered RequestToken. No HTTP request should be |
| 249 // started yet. | 256 // started yet. |
| 250 EXPECT_FALSE(delegate()->request_token_callback.is_null()); | 257 EXPECT_FALSE(delegate()->request_token_callback.is_null()); |
| 251 EXPECT_EQ(url_fetchers_created_count(), 0); | 258 EXPECT_EQ(url_fetchers_created_count(), 0); |
| 252 // Return valid access token. This should trigger HTTP request. | 259 // Return valid access token. This should trigger HTTP request. |
| 253 delegate()->request_token_callback.Run( | 260 delegate()->request_token_callback.Run( |
| 254 GoogleServiceAuthError::AuthErrorNone(), "access.token"); | 261 GoogleServiceAuthError::AuthErrorNone(), "access.token"); |
| 255 RunLoopUntilIdle(); | 262 RunLoopUntilIdle(); |
| 256 EXPECT_EQ(url_fetchers_created_count(), 1); | 263 EXPECT_EQ(url_fetchers_created_count(), 1); |
| 257 | 264 |
| 258 // Return another access token. Message should be cleared by now and shouldn't | 265 // Return another access token. Message should be cleared by now and shouldn't |
| 259 // be sent. | 266 // be sent. |
| 260 delegate()->request_token_callback.Run( | 267 delegate()->request_token_callback.Run( |
| 261 GoogleServiceAuthError::AuthErrorNone(), "access.token2"); | 268 GoogleServiceAuthError::AuthErrorNone(), "access.token2"); |
| 262 RunLoopUntilIdle(); | 269 RunLoopUntilIdle(); |
| 263 EXPECT_EQ(url_fetchers_created_count(), 1); | 270 EXPECT_EQ(url_fetchers_created_count(), 1); |
| 271 EXPECT_EQ(INVALIDATIONS_ENABLED, get_last_invalidator_state()); |
| 264 } | 272 } |
| 265 | 273 |
| 266 TEST_F(GCMNetworkChannelTest, FailedRegister) { | 274 TEST_F(GCMNetworkChannelTest, FailedRegister) { |
| 267 // After construction GCMNetworkChannel should have called Register. | 275 // After construction GCMNetworkChannel should have called Register. |
| 268 EXPECT_FALSE(delegate()->register_callback.is_null()); | 276 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 269 EXPECT_EQ(1, delegate()->register_call_count_); | 277 EXPECT_EQ(1, delegate()->register_call_count_); |
| 270 // Return transient error from Register call. | 278 // Return transient error from Register call. |
| 271 delegate()->register_callback.Run("", gcm::GCMClient::NETWORK_ERROR); | 279 delegate()->register_callback.Run("", gcm::GCMClient::NETWORK_ERROR); |
| 272 RunLoopUntilIdle(); | 280 RunLoopUntilIdle(); |
| 273 // GcmNetworkChannel should have scheduled Register retry. | 281 // GcmNetworkChannel should have scheduled Register retry. |
| 274 EXPECT_EQ(2, delegate()->register_call_count_); | 282 EXPECT_EQ(2, delegate()->register_call_count_); |
| 275 // Return persistent error from Register call. | 283 // Return persistent error from Register call. |
| 276 delegate()->register_callback.Run("", gcm::GCMClient::NOT_SIGNED_IN); | 284 delegate()->register_callback.Run("", gcm::GCMClient::NOT_SIGNED_IN); |
| 277 RunLoopUntilIdle(); | 285 RunLoopUntilIdle(); |
| 278 // GcmNetworkChannel should give up trying. | 286 // GcmNetworkChannel should give up trying. |
| 279 EXPECT_EQ(2, delegate()->register_call_count_); | 287 EXPECT_EQ(2, delegate()->register_call_count_); |
| 280 | 288 |
| 281 network_channel()->SendMessage("abra.cadabra"); | 289 network_channel()->SendMessage("abra.cadabra"); |
| 282 // SendMessage shouldn't trigger RequestToken. | 290 // SendMessage shouldn't trigger RequestToken. |
| 283 EXPECT_TRUE(delegate()->request_token_callback.is_null()); | 291 EXPECT_TRUE(delegate()->request_token_callback.is_null()); |
| 284 EXPECT_EQ(0, url_fetchers_created_count()); | 292 EXPECT_EQ(0, url_fetchers_created_count()); |
| 285 } | 293 } |
| 286 | 294 |
| 287 TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) { | 295 TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) { |
| 288 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), | 296 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 289 "", | 297 "", |
| 290 net::HTTP_OK, | 298 net::HTTP_NO_CONTENT, |
| 291 net::URLRequestStatus::SUCCESS); | 299 net::URLRequestStatus::SUCCESS); |
| 292 | 300 |
| 293 // After construction GCMNetworkChannel should have called Register. | 301 // After construction GCMNetworkChannel should have called Register. |
| 294 EXPECT_FALSE(delegate()->register_callback.is_null()); | 302 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 295 | 303 |
| 296 network_channel()->SendMessage("abra.cadabra"); | 304 network_channel()->SendMessage("abra.cadabra"); |
| 297 // SendMessage shouldn't trigger RequestToken. | 305 // SendMessage shouldn't trigger RequestToken. |
| 298 EXPECT_TRUE(delegate()->request_token_callback.is_null()); | 306 EXPECT_TRUE(delegate()->request_token_callback.is_null()); |
| 299 EXPECT_EQ(url_fetchers_created_count(), 0); | 307 EXPECT_EQ(url_fetchers_created_count(), 0); |
| 300 | 308 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 EXPECT_EQ(input, plain); | 412 EXPECT_EQ(input, plain); |
| 405 } | 413 } |
| 406 // Presence of '-', '_'. | 414 // Presence of '-', '_'. |
| 407 input = "\xfb\xff"; | 415 input = "\xfb\xff"; |
| 408 Base64EncodeURLSafe(input, &base64); | 416 Base64EncodeURLSafe(input, &base64); |
| 409 EXPECT_EQ("-_8", base64); | 417 EXPECT_EQ("-_8", base64); |
| 410 EXPECT_TRUE(Base64DecodeURLSafe(base64, &plain)); | 418 EXPECT_TRUE(Base64DecodeURLSafe(base64, &plain)); |
| 411 EXPECT_EQ(input, plain); | 419 EXPECT_EQ(input, plain); |
| 412 } | 420 } |
| 413 | 421 |
| 422 TEST_F(GCMNetworkChannelTest, TransientError) { |
| 423 EXPECT_FALSE(delegate()->message_callback.is_null()); |
| 424 // POST will fail. |
| 425 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 426 std::string(), |
| 427 net::HTTP_SERVICE_UNAVAILABLE, |
| 428 net::URLRequestStatus::SUCCESS); |
| 429 |
| 430 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 431 |
| 432 network_channel()->SendMessage("abra.cadabra"); |
| 433 EXPECT_FALSE(delegate()->request_token_callback.is_null()); |
| 434 delegate()->request_token_callback.Run( |
| 435 GoogleServiceAuthError::AuthErrorNone(), "access.token"); |
| 436 RunLoopUntilIdle(); |
| 437 EXPECT_EQ(url_fetchers_created_count(), 1); |
| 438 // Failing HTTP POST should cause TRANSIENT_INVALIDATION_ERROR. |
| 439 EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, get_last_invalidator_state()); |
| 440 // Network change to CONNECTION_NONE shouldn't affect invalidator state. |
| 441 network_channel()->OnNetworkChanged( |
| 442 net::NetworkChangeNotifier::CONNECTION_NONE); |
| 443 EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, get_last_invalidator_state()); |
| 444 // Network change to something else should trigger retry. |
| 445 network_channel()->OnNetworkChanged( |
| 446 net::NetworkChangeNotifier::CONNECTION_WIFI); |
| 447 EXPECT_EQ(INVALIDATIONS_ENABLED, get_last_invalidator_state()); |
| 448 network_channel()->OnNetworkChanged( |
| 449 net::NetworkChangeNotifier::CONNECTION_NONE); |
| 450 EXPECT_EQ(INVALIDATIONS_ENABLED, get_last_invalidator_state()); |
| 451 } |
| 452 |
| 414 #if !defined(ANDROID) | 453 #if !defined(ANDROID) |
| 415 TEST_F(GCMNetworkChannelTest, EchoToken) { | 454 TEST_F(GCMNetworkChannelTest, EchoToken) { |
| 416 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), | 455 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 417 std::string(), | 456 std::string(), |
| 418 net::HTTP_OK, | 457 net::HTTP_OK, |
| 419 net::URLRequestStatus::SUCCESS); | 458 net::URLRequestStatus::SUCCESS); |
| 420 // After construction GCMNetworkChannel should have called Register. | 459 // After construction GCMNetworkChannel should have called Register. |
| 421 // Return valid registration id. | 460 // Return valid registration id. |
| 422 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); | 461 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 423 | 462 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 448 delegate()->request_token_callback.Run( | 487 delegate()->request_token_callback.Run( |
| 449 GoogleServiceAuthError::AuthErrorNone(), "access.token"); | 488 GoogleServiceAuthError::AuthErrorNone(), "access.token"); |
| 450 RunLoopUntilIdle(); | 489 RunLoopUntilIdle(); |
| 451 EXPECT_EQ(url_fetchers_created_count(), 3); | 490 EXPECT_EQ(url_fetchers_created_count(), 3); |
| 452 // Echo_token should be from second message. | 491 // Echo_token should be from second message. |
| 453 EXPECT_EQ("echo.token", get_last_echo_token()); | 492 EXPECT_EQ("echo.token", get_last_echo_token()); |
| 454 } | 493 } |
| 455 #endif | 494 #endif |
| 456 | 495 |
| 457 } // namespace syncer | 496 } // namespace syncer |
| OLD | NEW |