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 |