OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/mcs_client.h" | 5 #include "google_apis/gcm/engine/mcs_client.h" |
6 | 6 |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 const int kTTLValue = 5 * 60; // 5 minutes. | 36 const int kTTLValue = 5 * 60; // 5 minutes. |
37 | 37 |
38 // Helper for building arbitrary data messages. | 38 // Helper for building arbitrary data messages. |
39 MCSMessage BuildDataMessage(const std::string& from, | 39 MCSMessage BuildDataMessage(const std::string& from, |
40 const std::string& category, | 40 const std::string& category, |
41 const std::string& message_id, | 41 const std::string& message_id, |
42 int last_stream_id_received, | 42 int last_stream_id_received, |
43 const std::string& persistent_id, | 43 const std::string& persistent_id, |
44 int ttl, | 44 int ttl, |
45 uint64 sent, | 45 uint64 sent, |
46 int queued) { | 46 int queued, |
| 47 const std::string& token, |
| 48 const uint64& user_id) { |
47 mcs_proto::DataMessageStanza data_message; | 49 mcs_proto::DataMessageStanza data_message; |
48 data_message.set_id(message_id); | 50 data_message.set_id(message_id); |
49 data_message.set_from(from); | 51 data_message.set_from(from); |
50 data_message.set_category(category); | 52 data_message.set_category(category); |
51 data_message.set_last_stream_id_received(last_stream_id_received); | 53 data_message.set_last_stream_id_received(last_stream_id_received); |
52 if (!persistent_id.empty()) | 54 if (!persistent_id.empty()) |
53 data_message.set_persistent_id(persistent_id); | 55 data_message.set_persistent_id(persistent_id); |
54 data_message.set_ttl(ttl); | 56 data_message.set_ttl(ttl); |
55 data_message.set_sent(sent); | 57 data_message.set_sent(sent); |
56 data_message.set_queued(queued); | 58 data_message.set_queued(queued); |
| 59 data_message.set_token(token); |
| 60 data_message.set_device_user_id(user_id); |
57 return MCSMessage(kDataMessageStanzaTag, data_message); | 61 return MCSMessage(kDataMessageStanzaTag, data_message); |
58 } | 62 } |
59 | 63 |
60 // MCSClient with overriden exposed persistent id logic. | 64 // MCSClient with overriden exposed persistent id logic. |
61 class TestMCSClient : public MCSClient { | 65 class TestMCSClient : public MCSClient { |
62 public: | 66 public: |
63 TestMCSClient(base::Clock* clock, | 67 TestMCSClient(base::Clock* clock, |
64 ConnectionFactory* connection_factory, | 68 ConnectionFactory* connection_factory, |
65 GCMStore* gcm_store) | 69 GCMStore* gcm_store) |
66 : MCSClient(clock, connection_factory, gcm_store), | 70 : MCSClient(clock, connection_factory, gcm_store), |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 EXPECT_FALSE(connection_factory()->IsEndpointReachable()); | 283 EXPECT_FALSE(connection_factory()->IsEndpointReachable()); |
280 EXPECT_FALSE(init_success()); | 284 EXPECT_FALSE(init_success()); |
281 EXPECT_FALSE(received_message()); | 285 EXPECT_FALSE(received_message()); |
282 } | 286 } |
283 | 287 |
284 // Send a message without RMQ support. | 288 // Send a message without RMQ support. |
285 TEST_F(MCSClientTest, SendMessageNoRMQ) { | 289 TEST_F(MCSClientTest, SendMessageNoRMQ) { |
286 BuildMCSClient(); | 290 BuildMCSClient(); |
287 InitializeClient(); | 291 InitializeClient(); |
288 LoginClient(std::vector<std::string>()); | 292 LoginClient(std::vector<std::string>()); |
289 MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0)); | 293 MCSMessage message( |
| 294 BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); |
290 GetFakeHandler()->ExpectOutgoingMessage(message); | 295 GetFakeHandler()->ExpectOutgoingMessage(message); |
291 mcs_client()->SendMessage(message); | 296 mcs_client()->SendMessage(message); |
292 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 297 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
293 } | 298 } |
294 | 299 |
295 // Send a message without RMQ support while disconnected. Message send should | 300 // Send a message without RMQ support while disconnected. Message send should |
296 // fail immediately, invoking callback. | 301 // fail immediately, invoking callback. |
297 TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) { | 302 TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) { |
298 BuildMCSClient(); | 303 BuildMCSClient(); |
299 InitializeClient(); | 304 InitializeClient(); |
300 | 305 |
301 EXPECT_TRUE(sent_message_id().empty()); | 306 EXPECT_TRUE(sent_message_id().empty()); |
302 MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0)); | 307 MCSMessage message( |
| 308 BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); |
303 mcs_client()->SendMessage(message); | 309 mcs_client()->SendMessage(message); |
304 | 310 |
305 // Message sent callback should be invoked, but no message should actually | 311 // Message sent callback should be invoked, but no message should actually |
306 // be sent. | 312 // be sent. |
307 EXPECT_EQ("X", sent_message_id()); | 313 EXPECT_EQ("X", sent_message_id()); |
308 EXPECT_EQ(MCSClient::NO_CONNECTION_ON_ZERO_TTL, message_send_status()); | 314 EXPECT_EQ(MCSClient::NO_CONNECTION_ON_ZERO_TTL, message_send_status()); |
309 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 315 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
310 } | 316 } |
311 | 317 |
312 // Send a message with RMQ support. | 318 // Send a message with RMQ support. |
313 TEST_F(MCSClientTest, SendMessageRMQ) { | 319 TEST_F(MCSClientTest, SendMessageRMQ) { |
314 BuildMCSClient(); | 320 BuildMCSClient(); |
315 InitializeClient(); | 321 InitializeClient(); |
316 LoginClient(std::vector<std::string>()); | 322 LoginClient(std::vector<std::string>()); |
317 MCSMessage message( | 323 MCSMessage message(BuildDataMessage( |
318 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 324 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
319 GetFakeHandler()->ExpectOutgoingMessage(message); | 325 GetFakeHandler()->ExpectOutgoingMessage(message); |
320 mcs_client()->SendMessage(message); | 326 mcs_client()->SendMessage(message); |
321 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 327 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
322 } | 328 } |
323 | 329 |
324 // Send a message with RMQ support while disconnected. On reconnect, the message | 330 // Send a message with RMQ support while disconnected. On reconnect, the message |
325 // should be resent. | 331 // should be resent. |
326 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { | 332 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { |
327 BuildMCSClient(); | 333 BuildMCSClient(); |
328 InitializeClient(); | 334 InitializeClient(); |
329 LoginClient(std::vector<std::string>()); | 335 LoginClient(std::vector<std::string>()); |
330 GetFakeHandler()->set_fail_send(true); | 336 GetFakeHandler()->set_fail_send(true); |
331 MCSMessage message( | 337 MCSMessage message(BuildDataMessage( |
332 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 338 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
333 | 339 |
334 // The initial (failed) send. | 340 // The initial (failed) send. |
335 GetFakeHandler()->ExpectOutgoingMessage(message); | 341 GetFakeHandler()->ExpectOutgoingMessage(message); |
336 // The login request. | 342 // The login request. |
337 GetFakeHandler()->ExpectOutgoingMessage( | 343 GetFakeHandler()->ExpectOutgoingMessage( |
338 MCSMessage( | 344 MCSMessage( |
339 kLoginRequestTag, | 345 kLoginRequestTag, |
340 BuildLoginRequest(kAndroidId, kSecurityToken). | 346 BuildLoginRequest(kAndroidId, kSecurityToken). |
341 PassAs<const google::protobuf::MessageLite>())); | 347 PassAs<const google::protobuf::MessageLite>())); |
342 // The second (re)send. | 348 // The second (re)send. |
343 MCSMessage message2(BuildDataMessage("from", | 349 MCSMessage message2(BuildDataMessage( |
344 "category", | 350 "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); |
345 "X", | |
346 1, | |
347 "1", | |
348 kTTLValue, | |
349 1, | |
350 kTTLValue - 1)); | |
351 GetFakeHandler()->ExpectOutgoingMessage(message2); | 351 GetFakeHandler()->ExpectOutgoingMessage(message2); |
352 mcs_client()->SendMessage(message); | 352 mcs_client()->SendMessage(message); |
353 PumpLoop(); // Wait for the queuing to happen. | 353 PumpLoop(); // Wait for the queuing to happen. |
354 EXPECT_EQ(MCSClient::QUEUED, message_send_status()); | 354 EXPECT_EQ(MCSClient::QUEUED, message_send_status()); |
355 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 355 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
356 GetFakeHandler()->set_fail_send(false); | 356 GetFakeHandler()->set_fail_send(false); |
357 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); | 357 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); |
358 connection_factory()->Connect(); | 358 connection_factory()->Connect(); |
359 WaitForMCSEvent(); // Wait for the login to finish. | 359 WaitForMCSEvent(); // Wait for the login to finish. |
360 PumpLoop(); // Wait for the send to happen. | 360 PumpLoop(); // Wait for the send to happen. |
361 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 361 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
362 } | 362 } |
363 | 363 |
364 // Send a message with RMQ support without receiving an acknowledgement. On | 364 // Send a message with RMQ support without receiving an acknowledgement. On |
365 // restart the message should be resent. | 365 // restart the message should be resent. |
366 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { | 366 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { |
367 BuildMCSClient(); | 367 BuildMCSClient(); |
368 InitializeClient(); | 368 InitializeClient(); |
369 LoginClient(std::vector<std::string>()); | 369 LoginClient(std::vector<std::string>()); |
370 GetFakeHandler()->set_fail_send(true); | 370 GetFakeHandler()->set_fail_send(true); |
371 MCSMessage message( | 371 MCSMessage message(BuildDataMessage( |
372 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 372 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
373 | 373 |
374 // The initial (failed) send. | 374 // The initial (failed) send. |
375 GetFakeHandler()->ExpectOutgoingMessage(message); | 375 GetFakeHandler()->ExpectOutgoingMessage(message); |
376 GetFakeHandler()->set_fail_send(false); | 376 GetFakeHandler()->set_fail_send(false); |
377 mcs_client()->SendMessage(message); | 377 mcs_client()->SendMessage(message); |
378 PumpLoop(); | 378 PumpLoop(); |
379 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 379 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
380 | 380 |
381 // Rebuild the client, which should resend the old message. | 381 // Rebuild the client, which should resend the old message. |
382 StoreCredentials(); | 382 StoreCredentials(); |
383 BuildMCSClient(); | 383 BuildMCSClient(); |
384 InitializeClient(); | 384 InitializeClient(); |
385 | 385 |
386 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); | 386 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); |
387 MCSMessage message2(BuildDataMessage("from", | 387 MCSMessage message2(BuildDataMessage( |
388 "category", | 388 "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); |
389 "X", | |
390 1, | |
391 "1", | |
392 kTTLValue, | |
393 1, | |
394 kTTLValue - 1)); | |
395 LoginClient(std::vector<std::string>()); | 389 LoginClient(std::vector<std::string>()); |
396 GetFakeHandler()->ExpectOutgoingMessage(message2); | 390 GetFakeHandler()->ExpectOutgoingMessage(message2); |
397 PumpLoop(); | 391 PumpLoop(); |
398 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 392 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
399 } | 393 } |
400 | 394 |
401 // Send messages with RMQ support, followed by receiving a stream ack. On | 395 // Send messages with RMQ support, followed by receiving a stream ack. On |
402 // restart nothing should be recent. | 396 // restart nothing should be recent. |
403 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { | 397 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { |
404 BuildMCSClient(); | 398 BuildMCSClient(); |
405 InitializeClient(); | 399 InitializeClient(); |
406 LoginClient(std::vector<std::string>()); | 400 LoginClient(std::vector<std::string>()); |
407 | 401 |
408 // Send some messages. | 402 // Send some messages. |
409 for (int i = 1; i <= kMessageBatchSize; ++i) { | 403 for (int i = 1; i <= kMessageBatchSize; ++i) { |
410 MCSMessage message( | 404 MCSMessage message(BuildDataMessage("from", |
411 BuildDataMessage("from", | 405 "category", |
412 "category", | 406 "X", |
413 "X", | 407 1, |
414 1, | 408 base::IntToString(i), |
415 base::IntToString(i), | 409 kTTLValue, |
416 kTTLValue, | 410 1, |
417 1, | 411 0, |
418 0)); | 412 "", |
| 413 0)); |
419 GetFakeHandler()->ExpectOutgoingMessage(message); | 414 GetFakeHandler()->ExpectOutgoingMessage(message); |
420 mcs_client()->SendMessage(message); | 415 mcs_client()->SendMessage(message); |
421 PumpLoop(); | 416 PumpLoop(); |
422 } | 417 } |
423 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 418 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
424 | 419 |
425 // Receive the ack. | 420 // Receive the ack. |
426 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 421 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
427 ack->set_last_stream_id_received(kMessageBatchSize + 1); | 422 ack->set_last_stream_id_received(kMessageBatchSize + 1); |
428 GetFakeHandler()->ReceiveMessage( | 423 GetFakeHandler()->ReceiveMessage( |
(...skipping 13 matching lines...) Expand all Loading... |
442 // the login response. No messages should be resent. | 437 // the login response. No messages should be resent. |
443 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { | 438 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { |
444 BuildMCSClient(); | 439 BuildMCSClient(); |
445 InitializeClient(); | 440 InitializeClient(); |
446 LoginClient(std::vector<std::string>()); | 441 LoginClient(std::vector<std::string>()); |
447 | 442 |
448 // Send some messages. | 443 // Send some messages. |
449 std::vector<std::string> id_list; | 444 std::vector<std::string> id_list; |
450 for (int i = 1; i <= kMessageBatchSize; ++i) { | 445 for (int i = 1; i <= kMessageBatchSize; ++i) { |
451 id_list.push_back(base::IntToString(i)); | 446 id_list.push_back(base::IntToString(i)); |
452 MCSMessage message( | 447 MCSMessage message(BuildDataMessage("from", |
453 BuildDataMessage("from", | 448 "category", |
454 "category", | 449 id_list.back(), |
455 id_list.back(), | 450 1, |
456 1, | 451 id_list.back(), |
457 id_list.back(), | 452 kTTLValue, |
458 kTTLValue, | 453 1, |
459 1, | 454 0, |
460 0)); | 455 "", |
| 456 0)); |
461 GetFakeHandler()->ExpectOutgoingMessage(message); | 457 GetFakeHandler()->ExpectOutgoingMessage(message); |
462 mcs_client()->SendMessage(message); | 458 mcs_client()->SendMessage(message); |
463 PumpLoop(); | 459 PumpLoop(); |
464 } | 460 } |
465 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 461 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
466 | 462 |
467 // Rebuild the client, and receive an acknowledgment for the messages as | 463 // Rebuild the client, and receive an acknowledgment for the messages as |
468 // part of the login response. | 464 // part of the login response. |
469 StoreCredentials(); | 465 StoreCredentials(); |
470 BuildMCSClient(); | 466 BuildMCSClient(); |
(...skipping 11 matching lines...) Expand all Loading... |
482 // be resent. | 478 // be resent. |
483 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { | 479 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { |
484 BuildMCSClient(); | 480 BuildMCSClient(); |
485 InitializeClient(); | 481 InitializeClient(); |
486 LoginClient(std::vector<std::string>()); | 482 LoginClient(std::vector<std::string>()); |
487 | 483 |
488 // Send some messages. | 484 // Send some messages. |
489 std::vector<std::string> id_list; | 485 std::vector<std::string> id_list; |
490 for (int i = 1; i <= kMessageBatchSize; ++i) { | 486 for (int i = 1; i <= kMessageBatchSize; ++i) { |
491 id_list.push_back(base::IntToString(i)); | 487 id_list.push_back(base::IntToString(i)); |
492 MCSMessage message( | 488 MCSMessage message(BuildDataMessage("from", |
493 BuildDataMessage("from", | 489 "category", |
494 "category", | 490 id_list.back(), |
495 id_list.back(), | 491 1, |
496 1, | 492 id_list.back(), |
497 id_list.back(), | 493 kTTLValue, |
498 kTTLValue, | 494 1, |
499 1, | 495 0, |
500 0)); | 496 "", |
| 497 0)); |
501 GetFakeHandler()->ExpectOutgoingMessage(message); | 498 GetFakeHandler()->ExpectOutgoingMessage(message); |
502 mcs_client()->SendMessage(message); | 499 mcs_client()->SendMessage(message); |
503 PumpLoop(); | 500 PumpLoop(); |
504 } | 501 } |
505 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 502 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
506 | 503 |
507 // Rebuild the client, and receive an acknowledgment for the messages as | 504 // Rebuild the client, and receive an acknowledgment for the messages as |
508 // part of the login response. | 505 // part of the login response. |
509 StoreCredentials(); | 506 StoreCredentials(); |
510 BuildMCSClient(); | 507 BuildMCSClient(); |
511 InitializeClient(); | 508 InitializeClient(); |
512 LoginClient(std::vector<std::string>()); | 509 LoginClient(std::vector<std::string>()); |
513 | 510 |
514 std::vector<std::string> acked_ids, remaining_ids; | 511 std::vector<std::string> acked_ids, remaining_ids; |
515 acked_ids.insert(acked_ids.end(), | 512 acked_ids.insert(acked_ids.end(), |
516 id_list.begin(), | 513 id_list.begin(), |
517 id_list.begin() + kMessageBatchSize / 2); | 514 id_list.begin() + kMessageBatchSize / 2); |
518 remaining_ids.insert(remaining_ids.end(), | 515 remaining_ids.insert(remaining_ids.end(), |
519 id_list.begin() + kMessageBatchSize / 2, | 516 id_list.begin() + kMessageBatchSize / 2, |
520 id_list.end()); | 517 id_list.end()); |
521 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { | 518 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { |
522 MCSMessage message( | 519 MCSMessage message(BuildDataMessage("from", |
523 BuildDataMessage("from", | 520 "category", |
524 "category", | 521 remaining_ids[i - 1], |
525 remaining_ids[i - 1], | 522 2, |
526 2, | 523 remaining_ids[i - 1], |
527 remaining_ids[i - 1], | 524 kTTLValue, |
528 kTTLValue, | 525 1, |
529 1, 0)); | 526 0, |
| 527 "", |
| 528 0)); |
530 GetFakeHandler()->ExpectOutgoingMessage(message); | 529 GetFakeHandler()->ExpectOutgoingMessage(message); |
531 } | 530 } |
532 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); | 531 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); |
533 GetFakeHandler()->ReceiveMessage( | 532 GetFakeHandler()->ReceiveMessage( |
534 MCSMessage(kIqStanzaTag, | 533 MCSMessage(kIqStanzaTag, |
535 ack.PassAs<const google::protobuf::MessageLite>())); | 534 ack.PassAs<const google::protobuf::MessageLite>())); |
536 WaitForMCSEvent(); | 535 WaitForMCSEvent(); |
537 PumpLoop(); | 536 PumpLoop(); |
538 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 537 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
539 } | 538 } |
540 | 539 |
541 // Receive some messages. On restart, the login request should contain the | 540 // Receive some messages. On restart, the login request should contain the |
542 // appropriate acknowledged ids. | 541 // appropriate acknowledged ids. |
543 TEST_F(MCSClientTest, AckOnLogin) { | 542 TEST_F(MCSClientTest, AckOnLogin) { |
544 BuildMCSClient(); | 543 BuildMCSClient(); |
545 InitializeClient(); | 544 InitializeClient(); |
546 LoginClient(std::vector<std::string>()); | 545 LoginClient(std::vector<std::string>()); |
547 | 546 |
548 // Receive some messages. | 547 // Receive some messages. |
549 std::vector<std::string> id_list; | 548 std::vector<std::string> id_list; |
550 for (int i = 1; i <= kMessageBatchSize; ++i) { | 549 for (int i = 1; i <= kMessageBatchSize; ++i) { |
551 id_list.push_back(base::IntToString(i)); | 550 id_list.push_back(base::IntToString(i)); |
552 MCSMessage message( | 551 MCSMessage message(BuildDataMessage( |
553 BuildDataMessage("from", | 552 "from", "category", "X", 1, id_list.back(), kTTLValue, 1, 0, "", 0)); |
554 "category", | |
555 "X", | |
556 1, | |
557 id_list.back(), | |
558 kTTLValue, | |
559 1, | |
560 0)); | |
561 GetFakeHandler()->ReceiveMessage(message); | 553 GetFakeHandler()->ReceiveMessage(message); |
562 WaitForMCSEvent(); | 554 WaitForMCSEvent(); |
563 PumpLoop(); | 555 PumpLoop(); |
564 } | 556 } |
565 | 557 |
566 // Restart the client. | 558 // Restart the client. |
567 StoreCredentials(); | 559 StoreCredentials(); |
568 BuildMCSClient(); | 560 BuildMCSClient(); |
569 InitializeClient(); | 561 InitializeClient(); |
570 LoginClient(id_list); | 562 LoginClient(id_list); |
571 } | 563 } |
572 | 564 |
573 // Receive some messages. On the next send, the outgoing message should contain | 565 // Receive some messages. On the next send, the outgoing message should contain |
574 // the appropriate last stream id received field to ack the received messages. | 566 // the appropriate last stream id received field to ack the received messages. |
575 TEST_F(MCSClientTest, AckOnSend) { | 567 TEST_F(MCSClientTest, AckOnSend) { |
576 BuildMCSClient(); | 568 BuildMCSClient(); |
577 InitializeClient(); | 569 InitializeClient(); |
578 LoginClient(std::vector<std::string>()); | 570 LoginClient(std::vector<std::string>()); |
579 | 571 |
580 // Receive some messages. | 572 // Receive some messages. |
581 std::vector<std::string> id_list; | 573 std::vector<std::string> id_list; |
582 for (int i = 1; i <= kMessageBatchSize; ++i) { | 574 for (int i = 1; i <= kMessageBatchSize; ++i) { |
583 id_list.push_back(base::IntToString(i)); | 575 id_list.push_back(base::IntToString(i)); |
584 MCSMessage message( | 576 MCSMessage message(BuildDataMessage("from", |
585 BuildDataMessage("from", | 577 "category", |
586 "category", | 578 id_list.back(), |
587 id_list.back(), | 579 1, |
588 1, | 580 id_list.back(), |
589 id_list.back(), | 581 kTTLValue, |
590 kTTLValue, | 582 1, |
591 1, | 583 0, |
592 0)); | 584 "", |
| 585 0)); |
593 GetFakeHandler()->ReceiveMessage(message); | 586 GetFakeHandler()->ReceiveMessage(message); |
594 PumpLoop(); | 587 PumpLoop(); |
595 } | 588 } |
596 | 589 |
597 // Trigger a message send, which should acknowledge via stream ack. | 590 // Trigger a message send, which should acknowledge via stream ack. |
598 MCSMessage message( | 591 MCSMessage message(BuildDataMessage("from", |
599 BuildDataMessage("from", | 592 "category", |
600 "category", | 593 "X", |
601 "X", | 594 kMessageBatchSize + 1, |
602 kMessageBatchSize + 1, | 595 "1", |
603 "1", | 596 kTTLValue, |
604 kTTLValue, | 597 1, |
605 1, 0)); | 598 0, |
| 599 "", |
| 600 0)); |
606 GetFakeHandler()->ExpectOutgoingMessage(message); | 601 GetFakeHandler()->ExpectOutgoingMessage(message); |
607 mcs_client()->SendMessage(message); | 602 mcs_client()->SendMessage(message); |
608 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 603 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
609 } | 604 } |
610 | 605 |
611 // Receive the ack limit in messages, which should trigger an automatic | 606 // Receive the ack limit in messages, which should trigger an automatic |
612 // stream ack. Receive a heartbeat to confirm the ack. | 607 // stream ack. Receive a heartbeat to confirm the ack. |
613 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { | 608 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { |
614 BuildMCSClient(); | 609 BuildMCSClient(); |
615 InitializeClient(); | 610 InitializeClient(); |
616 LoginClient(std::vector<std::string>()); | 611 LoginClient(std::vector<std::string>()); |
617 | 612 |
618 // The stream ack. | 613 // The stream ack. |
619 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 614 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
620 ack->set_last_stream_id_received(kAckLimitSize + 1); | 615 ack->set_last_stream_id_received(kAckLimitSize + 1); |
621 GetFakeHandler()->ExpectOutgoingMessage( | 616 GetFakeHandler()->ExpectOutgoingMessage( |
622 MCSMessage(kIqStanzaTag, | 617 MCSMessage(kIqStanzaTag, |
623 ack.PassAs<const google::protobuf::MessageLite>())); | 618 ack.PassAs<const google::protobuf::MessageLite>())); |
624 | 619 |
625 // Receive some messages. | 620 // Receive some messages. |
626 std::vector<std::string> id_list; | 621 std::vector<std::string> id_list; |
627 for (int i = 1; i <= kAckLimitSize; ++i) { | 622 for (int i = 1; i <= kAckLimitSize; ++i) { |
628 id_list.push_back(base::IntToString(i)); | 623 id_list.push_back(base::IntToString(i)); |
629 MCSMessage message( | 624 MCSMessage message(BuildDataMessage("from", |
630 BuildDataMessage("from", | 625 "category", |
631 "category", | 626 id_list.back(), |
632 id_list.back(), | 627 1, |
633 1, | 628 id_list.back(), |
634 id_list.back(), | 629 kTTLValue, |
635 kTTLValue, | 630 1, |
636 1, | 631 0, |
637 0)); | 632 "", |
| 633 0)); |
638 GetFakeHandler()->ReceiveMessage(message); | 634 GetFakeHandler()->ReceiveMessage(message); |
639 WaitForMCSEvent(); | 635 WaitForMCSEvent(); |
640 PumpLoop(); | 636 PumpLoop(); |
641 } | 637 } |
642 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 638 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
643 | 639 |
644 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). | 640 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). |
645 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( | 641 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( |
646 new mcs_proto::HeartbeatPing()); | 642 new mcs_proto::HeartbeatPing()); |
647 heartbeat->set_last_stream_id_received(2); | 643 heartbeat->set_last_stream_id_received(2); |
(...skipping 18 matching lines...) Expand all Loading... |
666 LoginClient(std::vector<std::string>()); | 662 LoginClient(std::vector<std::string>()); |
667 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 663 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
668 } | 664 } |
669 | 665 |
670 // If a message's TTL has expired by the time it reaches the front of the send | 666 // If a message's TTL has expired by the time it reaches the front of the send |
671 // queue, it should be dropped. | 667 // queue, it should be dropped. |
672 TEST_F(MCSClientTest, ExpiredTTLOnSend) { | 668 TEST_F(MCSClientTest, ExpiredTTLOnSend) { |
673 BuildMCSClient(); | 669 BuildMCSClient(); |
674 InitializeClient(); | 670 InitializeClient(); |
675 LoginClient(std::vector<std::string>()); | 671 LoginClient(std::vector<std::string>()); |
676 MCSMessage message( | 672 MCSMessage message(BuildDataMessage( |
677 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 673 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
678 | 674 |
679 // Advance time to after the TTL. | 675 // Advance time to after the TTL. |
680 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); | 676 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); |
681 EXPECT_TRUE(sent_message_id().empty()); | 677 EXPECT_TRUE(sent_message_id().empty()); |
682 mcs_client()->SendMessage(message); | 678 mcs_client()->SendMessage(message); |
683 | 679 |
684 // No messages should be sent, but the callback should still be invoked. | 680 // No messages should be sent, but the callback should still be invoked. |
685 EXPECT_EQ("X", sent_message_id()); | 681 EXPECT_EQ("X", sent_message_id()); |
686 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); | 682 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); |
687 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 683 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
688 } | 684 } |
689 | 685 |
690 TEST_F(MCSClientTest, ExpiredTTLOnRestart) { | 686 TEST_F(MCSClientTest, ExpiredTTLOnRestart) { |
691 BuildMCSClient(); | 687 BuildMCSClient(); |
692 InitializeClient(); | 688 InitializeClient(); |
693 LoginClient(std::vector<std::string>()); | 689 LoginClient(std::vector<std::string>()); |
694 GetFakeHandler()->set_fail_send(true); | 690 GetFakeHandler()->set_fail_send(true); |
695 MCSMessage message( | 691 MCSMessage message(BuildDataMessage( |
696 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 692 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
697 | 693 |
698 // The initial (failed) send. | 694 // The initial (failed) send. |
699 GetFakeHandler()->ExpectOutgoingMessage(message); | 695 GetFakeHandler()->ExpectOutgoingMessage(message); |
700 GetFakeHandler()->set_fail_send(false); | 696 GetFakeHandler()->set_fail_send(false); |
701 mcs_client()->SendMessage(message); | 697 mcs_client()->SendMessage(message); |
702 PumpLoop(); | 698 PumpLoop(); |
703 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 699 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
704 | 700 |
705 // Move the clock forward and rebuild the client, which should fail the | 701 // Move the clock forward and rebuild the client, which should fail the |
706 // message send on restart. | 702 // message send on restart. |
707 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); | 703 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); |
708 StoreCredentials(); | 704 StoreCredentials(); |
709 BuildMCSClient(); | 705 BuildMCSClient(); |
710 InitializeClient(); | 706 InitializeClient(); |
711 LoginClient(std::vector<std::string>()); | 707 LoginClient(std::vector<std::string>()); |
712 PumpLoop(); | 708 PumpLoop(); |
713 EXPECT_EQ("X", sent_message_id()); | 709 EXPECT_EQ("X", sent_message_id()); |
714 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); | 710 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); |
715 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 711 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
716 } | 712 } |
717 | 713 |
| 714 // Sending two messages with the same collapse key and same app id while |
| 715 // disconnected should only send the latter of the two on reconnection. |
| 716 TEST_F(MCSClientTest, CollapseKeysSameApp) { |
| 717 BuildMCSClient(); |
| 718 InitializeClient(); |
| 719 MCSMessage message(BuildDataMessage( |
| 720 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 721 mcs_client()->SendMessage(message); |
| 722 |
| 723 MCSMessage message2(BuildDataMessage( |
| 724 "from", "app", "message id 2", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 725 mcs_client()->SendMessage(message2); |
| 726 |
| 727 LoginClient(std::vector<std::string>()); |
| 728 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 729 PumpLoop(); |
| 730 } |
| 731 |
| 732 // Sending two messages with the same collapse key and different app id while |
| 733 // disconnected should not perform any collapsing. |
| 734 TEST_F(MCSClientTest, CollapseKeysDifferentApp) { |
| 735 BuildMCSClient(); |
| 736 InitializeClient(); |
| 737 MCSMessage message(BuildDataMessage( |
| 738 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 739 mcs_client()->SendMessage(message); |
| 740 |
| 741 MCSMessage message2(BuildDataMessage("from", |
| 742 "app 2", |
| 743 "message id 2", |
| 744 1, |
| 745 "2", |
| 746 kTTLValue, |
| 747 1, |
| 748 0, |
| 749 "token", |
| 750 0)); |
| 751 mcs_client()->SendMessage(message2); |
| 752 |
| 753 LoginClient(std::vector<std::string>()); |
| 754 GetFakeHandler()->ExpectOutgoingMessage(message); |
| 755 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 756 PumpLoop(); |
| 757 } |
| 758 |
| 759 // Sending two messages with the same collapse key and app id, but different |
| 760 // user, while disconnected, should not perform any collapsing. |
| 761 TEST_F(MCSClientTest, CollapseKeysDifferentUser) { |
| 762 BuildMCSClient(); |
| 763 InitializeClient(); |
| 764 MCSMessage message(BuildDataMessage( |
| 765 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 766 mcs_client()->SendMessage(message); |
| 767 |
| 768 MCSMessage message2(BuildDataMessage("from", |
| 769 "app", |
| 770 "message id 2", |
| 771 1, |
| 772 "2", |
| 773 kTTLValue, |
| 774 1, |
| 775 0, |
| 776 "token", |
| 777 1)); |
| 778 mcs_client()->SendMessage(message2); |
| 779 |
| 780 LoginClient(std::vector<std::string>()); |
| 781 GetFakeHandler()->ExpectOutgoingMessage(message); |
| 782 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 783 PumpLoop(); |
| 784 } |
| 785 |
718 } // namespace | 786 } // namespace |
719 | 787 |
720 } // namespace gcm | 788 } // namespace gcm |
OLD | NEW |