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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> |
9 | 10 |
10 #include "base/bind.h" | 11 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
13 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
18 #include "base/test/simple_test_clock.h" | 19 #include "base/test/simple_test_clock.h" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 scoped_ptr<mcs_proto::LoginRequest> login_request = | 245 scoped_ptr<mcs_proto::LoginRequest> login_request = |
245 BuildLoginRequest(kAndroidId, kSecurityToken, ""); | 246 BuildLoginRequest(kAndroidId, kSecurityToken, ""); |
246 for (size_t i = 0; i < acknowledged_ids.size(); ++i) | 247 for (size_t i = 0; i < acknowledged_ids.size(); ++i) |
247 login_request->add_received_persistent_id(acknowledged_ids[i]); | 248 login_request->add_received_persistent_id(acknowledged_ids[i]); |
248 if (heartbeat_interval_ms) { | 249 if (heartbeat_interval_ms) { |
249 mcs_proto::Setting* setting = login_request->add_setting(); | 250 mcs_proto::Setting* setting = login_request->add_setting(); |
250 setting->set_name("hbping"); | 251 setting->set_name("hbping"); |
251 setting->set_value(base::IntToString(heartbeat_interval_ms)); | 252 setting->set_value(base::IntToString(heartbeat_interval_ms)); |
252 } | 253 } |
253 GetFakeHandler()->ExpectOutgoingMessage( | 254 GetFakeHandler()->ExpectOutgoingMessage( |
254 MCSMessage(kLoginRequestTag, login_request.Pass())); | 255 MCSMessage(kLoginRequestTag, std::move(login_request))); |
255 } | 256 } |
256 | 257 |
257 void MCSClientTest::StoreCredentials() { | 258 void MCSClientTest::StoreCredentials() { |
258 gcm_store_->SetDeviceCredentials( | 259 gcm_store_->SetDeviceCredentials( |
259 kAndroidId, kSecurityToken, | 260 kAndroidId, kSecurityToken, |
260 base::Bind(&MCSClientTest::SetDeviceCredentialsCallback, | 261 base::Bind(&MCSClientTest::SetDeviceCredentialsCallback, |
261 base::Unretained(this))); | 262 base::Unretained(this))); |
262 run_loop_->Run(); | 263 run_loop_->Run(); |
263 run_loop_.reset(new base::RunLoop()); | 264 run_loop_.reset(new base::RunLoop()); |
264 } | 265 } |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 423 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
423 GetFakeHandler()->set_fail_send(false); | 424 GetFakeHandler()->set_fail_send(false); |
424 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); | 425 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); |
425 connection_factory()->Connect(); | 426 connection_factory()->Connect(); |
426 WaitForMCSEvent(); // Wait for the login to finish. | 427 WaitForMCSEvent(); // Wait for the login to finish. |
427 PumpLoop(); // Wait for the send to happen. | 428 PumpLoop(); // Wait for the send to happen. |
428 | 429 |
429 // Receive the ack. | 430 // Receive the ack. |
430 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 431 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
431 ack->set_last_stream_id_received(2); | 432 ack->set_last_stream_id_received(2); |
432 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 433 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, std::move(ack))); |
433 WaitForMCSEvent(); | 434 WaitForMCSEvent(); |
434 | 435 |
435 EXPECT_EQ(MCSClient::SENT, message_send_status()); | 436 EXPECT_EQ(MCSClient::SENT, message_send_status()); |
436 EXPECT_EQ("X", sent_message_id()); | 437 EXPECT_EQ("X", sent_message_id()); |
437 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 438 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
438 } | 439 } |
439 | 440 |
440 // Send a message with RMQ support without receiving an acknowledgement. On | 441 // Send a message with RMQ support without receiving an acknowledgement. On |
441 // restart the message should be resent. | 442 // restart the message should be resent. |
442 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { | 443 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 "", 0, IMMEDIATE_ACK_NO)); | 485 "", 0, IMMEDIATE_ACK_NO)); |
485 GetFakeHandler()->ExpectOutgoingMessage(message); | 486 GetFakeHandler()->ExpectOutgoingMessage(message); |
486 mcs_client()->SendMessage(message); | 487 mcs_client()->SendMessage(message); |
487 PumpLoop(); | 488 PumpLoop(); |
488 } | 489 } |
489 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 490 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
490 | 491 |
491 // Receive the ack. | 492 // Receive the ack. |
492 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 493 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
493 ack->set_last_stream_id_received(kMessageBatchSize + 1); | 494 ack->set_last_stream_id_received(kMessageBatchSize + 1); |
494 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 495 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, std::move(ack))); |
495 WaitForMCSEvent(); | 496 WaitForMCSEvent(); |
496 | 497 |
497 // Reconnect and ensure no messages are resent. | 498 // Reconnect and ensure no messages are resent. |
498 StoreCredentials(); | 499 StoreCredentials(); |
499 BuildMCSClient(); | 500 BuildMCSClient(); |
500 InitializeClient(); | 501 InitializeClient(); |
501 LoginClient(std::vector<std::string>()); | 502 LoginClient(std::vector<std::string>()); |
502 PumpLoop(); | 503 PumpLoop(); |
503 } | 504 } |
504 | 505 |
(...skipping 17 matching lines...) Expand all Loading... |
522 } | 523 } |
523 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 524 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
524 | 525 |
525 // Rebuild the client, and receive an acknowledgment for the messages as | 526 // Rebuild the client, and receive an acknowledgment for the messages as |
526 // part of the login response. | 527 // part of the login response. |
527 StoreCredentials(); | 528 StoreCredentials(); |
528 BuildMCSClient(); | 529 BuildMCSClient(); |
529 InitializeClient(); | 530 InitializeClient(); |
530 LoginClient(std::vector<std::string>()); | 531 LoginClient(std::vector<std::string>()); |
531 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list)); | 532 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(id_list)); |
532 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 533 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, std::move(ack))); |
533 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 534 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
534 } | 535 } |
535 | 536 |
536 // Send messages with RMQ support. On restart, receive a SelectiveAck with | 537 // Send messages with RMQ support. On restart, receive a SelectiveAck with |
537 // the login response that only acks some messages. The unacked messages should | 538 // the login response that only acks some messages. The unacked messages should |
538 // be resent. | 539 // be resent. |
539 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { | 540 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { |
540 BuildMCSClient(); | 541 BuildMCSClient(); |
541 InitializeClient(); | 542 InitializeClient(); |
542 LoginClient(std::vector<std::string>()); | 543 LoginClient(std::vector<std::string>()); |
(...skipping 25 matching lines...) Expand all Loading... |
568 remaining_ids.insert(remaining_ids.end(), | 569 remaining_ids.insert(remaining_ids.end(), |
569 id_list.begin() + kMessageBatchSize / 2, | 570 id_list.begin() + kMessageBatchSize / 2, |
570 id_list.end()); | 571 id_list.end()); |
571 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { | 572 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { |
572 MCSMessage message(BuildDataMessage( | 573 MCSMessage message(BuildDataMessage( |
573 "from", "category", remaining_ids[i - 1], 2, remaining_ids[i - 1], | 574 "from", "category", remaining_ids[i - 1], 2, remaining_ids[i - 1], |
574 kTTLValue, 1, 0, "", 0, IMMEDIATE_ACK_NO)); | 575 kTTLValue, 1, 0, "", 0, IMMEDIATE_ACK_NO)); |
575 GetFakeHandler()->ExpectOutgoingMessage(message); | 576 GetFakeHandler()->ExpectOutgoingMessage(message); |
576 } | 577 } |
577 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); | 578 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); |
578 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 579 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, std::move(ack))); |
579 WaitForMCSEvent(); | 580 WaitForMCSEvent(); |
580 PumpLoop(); | 581 PumpLoop(); |
581 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 582 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
582 } | 583 } |
583 | 584 |
584 // Handle a selective ack that only acks some messages. The remaining unacked | 585 // Handle a selective ack that only acks some messages. The remaining unacked |
585 // messages should be resent. On restart, those same unacked messages should be | 586 // messages should be resent. On restart, those same unacked messages should be |
586 // resent, and any pending acks for incoming messages should also be resent. | 587 // resent, and any pending acks for incoming messages should also be resent. |
587 TEST_F(MCSClientTest, SelectiveAckMidStream) { | 588 TEST_F(MCSClientTest, SelectiveAckMidStream) { |
588 BuildMCSClient(); | 589 BuildMCSClient(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 // Simulate the last message being dropped by having the server selectively | 632 // Simulate the last message being dropped by having the server selectively |
632 // ack client message "1". | 633 // ack client message "1". |
633 // Client message "2" should be resent, acking server stream id 4 (selective | 634 // Client message "2" should be resent, acking server stream id 4 (selective |
634 // ack). | 635 // ack). |
635 MCSMessage cMessage3(BuildDataMessage("from", "category", "Y", 4, "2", | 636 MCSMessage cMessage3(BuildDataMessage("from", "category", "Y", 4, "2", |
636 kTTLValue, 1, 0, "", 0, | 637 kTTLValue, 1, 0, "", 0, |
637 IMMEDIATE_ACK_NO)); | 638 IMMEDIATE_ACK_NO)); |
638 GetFakeHandler()->ExpectOutgoingMessage(cMessage3); | 639 GetFakeHandler()->ExpectOutgoingMessage(cMessage3); |
639 std::vector<std::string> acked_ids(1, "1"); | 640 std::vector<std::string> acked_ids(1, "1"); |
640 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); | 641 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); |
641 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 642 GetFakeHandler()->ReceiveMessage(MCSMessage(kIqStanzaTag, std::move(ack))); |
642 WaitForMCSEvent(); | 643 WaitForMCSEvent(); |
643 PumpLoop(); | 644 PumpLoop(); |
644 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 645 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
645 | 646 |
646 // Rebuild the client without any further acks from server. Note that this | 647 // Rebuild the client without any further acks from server. Note that this |
647 // resets the stream ids. | 648 // resets the stream ids. |
648 // Sever message "s2" should be acked as part of login. | 649 // Sever message "s2" should be acked as part of login. |
649 // Client message "2" should be resent. | 650 // Client message "2" should be resent. |
650 StoreCredentials(); | 651 StoreCredentials(); |
651 BuildMCSClient(); | 652 BuildMCSClient(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 // Receive the ack limit in messages, which should trigger an automatic | 719 // Receive the ack limit in messages, which should trigger an automatic |
719 // stream ack. Receive a heartbeat to confirm the ack. | 720 // stream ack. Receive a heartbeat to confirm the ack. |
720 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { | 721 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { |
721 BuildMCSClient(); | 722 BuildMCSClient(); |
722 InitializeClient(); | 723 InitializeClient(); |
723 LoginClient(std::vector<std::string>()); | 724 LoginClient(std::vector<std::string>()); |
724 | 725 |
725 // The stream ack. | 726 // The stream ack. |
726 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 727 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
727 ack->set_last_stream_id_received(kAckLimitSize + 1); | 728 ack->set_last_stream_id_received(kAckLimitSize + 1); |
728 GetFakeHandler()->ExpectOutgoingMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 729 GetFakeHandler()->ExpectOutgoingMessage( |
| 730 MCSMessage(kIqStanzaTag, std::move(ack))); |
729 | 731 |
730 // Receive some messages. | 732 // Receive some messages. |
731 std::vector<std::string> id_list; | 733 std::vector<std::string> id_list; |
732 for (int i = 1; i <= kAckLimitSize; ++i) { | 734 for (int i = 1; i <= kAckLimitSize; ++i) { |
733 id_list.push_back(base::IntToString(i)); | 735 id_list.push_back(base::IntToString(i)); |
734 MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, | 736 MCSMessage message(BuildDataMessage("from", "category", id_list.back(), 1, |
735 id_list.back(), kTTLValue, 1, 0, "", 0, | 737 id_list.back(), kTTLValue, 1, 0, "", 0, |
736 IMMEDIATE_ACK_NO)); | 738 IMMEDIATE_ACK_NO)); |
737 GetFakeHandler()->ReceiveMessage(message); | 739 GetFakeHandler()->ReceiveMessage(message); |
738 WaitForMCSEvent(); | 740 WaitForMCSEvent(); |
739 PumpLoop(); | 741 PumpLoop(); |
740 } | 742 } |
741 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 743 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
742 | 744 |
743 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). | 745 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). |
744 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( | 746 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( |
745 new mcs_proto::HeartbeatPing()); | 747 new mcs_proto::HeartbeatPing()); |
746 heartbeat->set_last_stream_id_received(2); | 748 heartbeat->set_last_stream_id_received(2); |
747 | 749 |
748 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack( | 750 scoped_ptr<mcs_proto::HeartbeatAck> heartbeat_ack( |
749 new mcs_proto::HeartbeatAck()); | 751 new mcs_proto::HeartbeatAck()); |
750 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2); | 752 heartbeat_ack->set_last_stream_id_received(kAckLimitSize + 2); |
751 GetFakeHandler()->ExpectOutgoingMessage( | 753 GetFakeHandler()->ExpectOutgoingMessage( |
752 MCSMessage(kHeartbeatAckTag, heartbeat_ack.Pass())); | 754 MCSMessage(kHeartbeatAckTag, std::move(heartbeat_ack))); |
753 | 755 |
754 GetFakeHandler()->ReceiveMessage( | 756 GetFakeHandler()->ReceiveMessage( |
755 MCSMessage(kHeartbeatPingTag, heartbeat.Pass())); | 757 MCSMessage(kHeartbeatPingTag, std::move(heartbeat))); |
756 PumpLoop(); | 758 PumpLoop(); |
757 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 759 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
758 | 760 |
759 // Rebuild the client. Nothing should be sent on login. | 761 // Rebuild the client. Nothing should be sent on login. |
760 StoreCredentials(); | 762 StoreCredentials(); |
761 BuildMCSClient(); | 763 BuildMCSClient(); |
762 InitializeClient(); | 764 InitializeClient(); |
763 LoginClient(std::vector<std::string>()); | 765 LoginClient(std::vector<std::string>()); |
764 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 766 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
765 } | 767 } |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 // Receive a message with immediate ack request, which should trigger an | 1149 // Receive a message with immediate ack request, which should trigger an |
1148 // automatic stream ack. | 1150 // automatic stream ack. |
1149 TEST_F(MCSClientTest, AckWhenImmediateAckRequested) { | 1151 TEST_F(MCSClientTest, AckWhenImmediateAckRequested) { |
1150 BuildMCSClient(); | 1152 BuildMCSClient(); |
1151 InitializeClient(); | 1153 InitializeClient(); |
1152 LoginClient(std::vector<std::string>()); | 1154 LoginClient(std::vector<std::string>()); |
1153 | 1155 |
1154 // The stream ack. | 1156 // The stream ack. |
1155 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 1157 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
1156 ack->set_last_stream_id_received(kAckLimitSize - 1); | 1158 ack->set_last_stream_id_received(kAckLimitSize - 1); |
1157 GetFakeHandler()->ExpectOutgoingMessage(MCSMessage(kIqStanzaTag, ack.Pass())); | 1159 GetFakeHandler()->ExpectOutgoingMessage( |
| 1160 MCSMessage(kIqStanzaTag, std::move(ack))); |
1158 | 1161 |
1159 // Receive some messages. | 1162 // Receive some messages. |
1160 for (int i = 1; i < kAckLimitSize - 2; ++i) { | 1163 for (int i = 1; i < kAckLimitSize - 2; ++i) { |
1161 std::string id(base::IntToString(i)); | 1164 std::string id(base::IntToString(i)); |
1162 MCSMessage message(BuildDataMessage("from", "category", id, 1, id, | 1165 MCSMessage message(BuildDataMessage("from", "category", id, 1, id, |
1163 kTTLValue, 1, 0, "", 0, | 1166 kTTLValue, 1, 0, "", 0, |
1164 IMMEDIATE_ACK_NO)); | 1167 IMMEDIATE_ACK_NO)); |
1165 GetFakeHandler()->ReceiveMessage(message); | 1168 GetFakeHandler()->ReceiveMessage(message); |
1166 WaitForMCSEvent(); | 1169 WaitForMCSEvent(); |
1167 PumpLoop(); | 1170 PumpLoop(); |
1168 } | 1171 } |
1169 // This message expects immediate ACK, which means it will happen before the | 1172 // This message expects immediate ACK, which means it will happen before the |
1170 // ACK limit size is reached. All of the preceding messages will be acked at | 1173 // ACK limit size is reached. All of the preceding messages will be acked at |
1171 // the same time. | 1174 // the same time. |
1172 std::string ack_id(base::IntToString(kAckLimitSize - 1)); | 1175 std::string ack_id(base::IntToString(kAckLimitSize - 1)); |
1173 MCSMessage message(BuildDataMessage("from", "category", ack_id, 1, ack_id, | 1176 MCSMessage message(BuildDataMessage("from", "category", ack_id, 1, ack_id, |
1174 kTTLValue, 1, 0, "", 0, | 1177 kTTLValue, 1, 0, "", 0, |
1175 IMMEDIATE_ACK_YES)); | 1178 IMMEDIATE_ACK_YES)); |
1176 GetFakeHandler()->ReceiveMessage(message); | 1179 GetFakeHandler()->ReceiveMessage(message); |
1177 WaitForMCSEvent(); | 1180 WaitForMCSEvent(); |
1178 PumpLoop(); | 1181 PumpLoop(); |
1179 | 1182 |
1180 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 1183 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
1181 } | 1184 } |
1182 | 1185 |
1183 } // namespace | 1186 } // namespace |
1184 | 1187 |
1185 } // namespace gcm | 1188 } // namespace gcm |
OLD | NEW |