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 3// found in the LICENSE file. 4 5#include "components/gcm_driver/gcm_client_impl.h" 6 7#include "base/command_line.h" 8#include "base/files/scoped_temp_dir.h" 9#include "base/message_loop/message_loop.h" 10#include "base/run_loop.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/time/clock.h" 13#include "google_apis/gcm/base/fake_encryptor.h" 14#include "google_apis/gcm/base/mcs_message.h" 15#include "google_apis/gcm/base/mcs_util.h" 16#include "google_apis/gcm/engine/fake_connection_factory.h" 17#include "google_apis/gcm/engine/fake_connection_handler.h" 18#include "google_apis/gcm/engine/gservices_settings.h" 19#include "google_apis/gcm/monitoring/gcm_stats_recorder.h" 20#include "google_apis/gcm/protocol/android_checkin.pb.h" 21#include "google_apis/gcm/protocol/checkin.pb.h" 22#include "google_apis/gcm/protocol/mcs.pb.h" 23#include "net/url_request/test_url_fetcher_factory.h" 24#include "net/url_request/url_fetcher_delegate.h" 25#include "net/url_request/url_request_test_util.h" 26#include "testing/gtest/include/gtest/gtest.h" 27 28namespace gcm { 29 30namespace { 31 32enum LastEvent { 33 NONE, 34 LOADING_COMPLETED, 35 REGISTRATION_COMPLETED, 36 UNREGISTRATION_COMPLETED, 37 MESSAGE_SEND_ERROR, 38 MESSAGE_RECEIVED, 39 MESSAGES_DELETED, 40}; 41 42const uint64 kDeviceAndroidId = 54321; 43const uint64 kDeviceSecurityToken = 12345; 44const int64 kSettingsCheckinInterval = 16 * 60 * 60; 45const char kAppId[] = "app_id"; 46const char kSender[] = "project_id"; 47const char kSender2[] = "project_id2"; 48const char kSender3[] = "project_id3"; 49const char kRegistrationResponsePrefix[] = "token="; 50const char kUnregistrationResponsePrefix[] = "deleted="; 51 52// Helper for building arbitrary data messages. 53MCSMessage BuildDownstreamMessage( 54 const std::string& project_id, 55 const std::string& app_id, 56 const std::map<std::string, std::string>& data) { 57 mcs_proto::DataMessageStanza data_message; 58 data_message.set_from(project_id); 59 data_message.set_category(app_id); 60 for (std::map<std::string, std::string>::const_iterator iter = data.begin(); 61 iter != data.end(); 62 ++iter) { 63 mcs_proto::AppData* app_data = data_message.add_app_data(); 64 app_data->set_key(iter->first); 65 app_data->set_value(iter->second); 66 } 67 return MCSMessage(kDataMessageStanzaTag, data_message); 68} 69 70class FakeMCSClient : public MCSClient { 71 public: 72 FakeMCSClient(base::Clock* clock, 73 ConnectionFactory* connection_factory, 74 GCMStore* gcm_store, 75 GCMStatsRecorder* recorder); 76 virtual ~FakeMCSClient(); 77 virtual void Login(uint64 android_id, uint64 security_token) OVERRIDE; 78 virtual void SendMessage(const MCSMessage& message) OVERRIDE; 79 80 uint64 last_android_id() const { return last_android_id_; } 81 uint64 last_security_token() const { return last_security_token_; } 82 uint8 last_message_tag() const { return last_message_tag_; } 83 const mcs_proto::DataMessageStanza& last_data_message_stanza() const { 84 return last_data_message_stanza_; 85 } 86 87 private: 88 uint64 last_android_id_; 89 uint64 last_security_token_; 90 uint8 last_message_tag_; 91 mcs_proto::DataMessageStanza last_data_message_stanza_; 92}; 93 94FakeMCSClient::FakeMCSClient(base::Clock* clock, 95 ConnectionFactory* connection_factory, 96 GCMStore* gcm_store, 97 GCMStatsRecorder* recorder) 98 : MCSClient("", clock, connection_factory, gcm_store, recorder), 99 last_android_id_(0u), 100 last_security_token_(0u), 101 last_message_tag_(kNumProtoTypes) { 102} 103 104FakeMCSClient::~FakeMCSClient() { 105} 106 107void FakeMCSClient::Login(uint64 android_id, uint64 security_token) { 108 last_android_id_ = android_id; 109 last_security_token_ = security_token; 110} 111 112void FakeMCSClient::SendMessage(const MCSMessage& message) { 113 last_message_tag_ = message.tag(); 114 if (last_message_tag_ == kDataMessageStanzaTag) { 115 last_data_message_stanza_.CopyFrom( 116 reinterpret_cast<const mcs_proto::DataMessageStanza&>( 117 message.GetProtobuf())); 118 } 119} 120 121class AutoAdvancingTestClock : public base::Clock { 122 public: 123 explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta); 124 virtual ~AutoAdvancingTestClock(); 125 126 virtual base::Time Now() OVERRIDE; 127 void Advance(TimeDelta delta); 128 int call_count() const { return call_count_; } 129 130 private: 131 int call_count_; 132 base::TimeDelta auto_increment_time_delta_; 133 base::Time now_; 134 135 DISALLOW_COPY_AND_ASSIGN(AutoAdvancingTestClock); 136}; 137 138AutoAdvancingTestClock::AutoAdvancingTestClock( 139 base::TimeDelta auto_increment_time_delta) 140 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta) { 141} 142 143AutoAdvancingTestClock::~AutoAdvancingTestClock() { 144} 145 146base::Time AutoAdvancingTestClock::Now() { 147 call_count_++; 148 now_ += auto_increment_time_delta_; 149 return now_; 150} 151 152void AutoAdvancingTestClock::Advance(base::TimeDelta delta) { 153 now_ += delta; 154} 155 156class FakeGCMInternalsBuilder : public GCMInternalsBuilder { 157 public: 158 FakeGCMInternalsBuilder(base::TimeDelta clock_step); 159 virtual ~FakeGCMInternalsBuilder(); 160 161 virtual scoped_ptr<base::Clock> BuildClock() OVERRIDE; 162 virtual scoped_ptr<MCSClient> BuildMCSClient( 163 const std::string& version, 164 base::Clock* clock, 165 ConnectionFactory* connection_factory, 166 GCMStore* gcm_store, 167 GCMStatsRecorder* recorder) OVERRIDE; 168 virtual scoped_ptr<ConnectionFactory> BuildConnectionFactory( 169 const std::vector<GURL>& endpoints, 170 const net::BackoffEntry::Policy& backoff_policy, 171 scoped_refptr<net::HttpNetworkSession> network_session, 172 net::NetLog* net_log, 173 GCMStatsRecorder* recorder) OVERRIDE; 174 175 private: 176 base::TimeDelta clock_step_; 177}; 178 179FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step) 180 : clock_step_(clock_step) { 181} 182 183FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {} 184 185scoped_ptr<base::Clock> FakeGCMInternalsBuilder::BuildClock() { 186 return make_scoped_ptr<base::Clock>(new AutoAdvancingTestClock(clock_step_)); 187} 188 189scoped_ptr<MCSClient> FakeGCMInternalsBuilder::BuildMCSClient( 190 const std::string& version, 191 base::Clock* clock, 192 ConnectionFactory* connection_factory, 193 GCMStore* gcm_store, 194 GCMStatsRecorder* recorder) { 195 return make_scoped_ptr<MCSClient>(new FakeMCSClient(clock, 196 connection_factory, 197 gcm_store, 198 recorder)); 199} 200 201scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory( 202 const std::vector<GURL>& endpoints, 203 const net::BackoffEntry::Policy& backoff_policy, 204 scoped_refptr<net::HttpNetworkSession> network_session, 205 net::NetLog* net_log, 206 GCMStatsRecorder* recorder) { 207 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory()); 208} 209 210} // namespace 211 212class GCMClientImplTest : public testing::Test, 213 public GCMClient::Delegate { 214 public: 215 GCMClientImplTest(); 216 virtual ~GCMClientImplTest(); 217 218 virtual void SetUp() OVERRIDE; 219 220 void BuildGCMClient(base::TimeDelta clock_step); 221 void InitializeGCMClient(); 222 void StartGCMClient(); 223 void ReceiveMessageFromMCS(const MCSMessage& message); 224 void CompleteCheckin(uint64 android_id, 225 uint64 security_token, 226 const std::string& digest, 227 const std::map<std::string, std::string>& settings); 228 void CompleteRegistration(const std::string& registration_id); 229 void CompleteUnregistration(const std::string& app_id); 230 231 bool ExistsRegistration(const std::string& app_id) const; 232 void AddRegistration(const std::string& app_id, 233 const std::vector<std::string>& sender_ids, 234 const std::string& registration_id); 235 236 // GCMClient::Delegate overrides (for verification). 237 virtual void OnRegisterFinished(const std::string& app_id, 238 const std::string& registration_id, 239 GCMClient::Result result) OVERRIDE; 240 virtual void OnUnregisterFinished(const std::string& app_id, 241 GCMClient::Result result) OVERRIDE; 242 virtual void OnSendFinished(const std::string& app_id, 243 const std::string& message_id, 244 GCMClient::Result result) OVERRIDE {} 245 virtual void OnMessageReceived(const std::string& registration_id, 246 const GCMClient::IncomingMessage& message) 247 OVERRIDE; 248 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; 249 virtual void OnMessageSendError( 250 const std::string& app_id, 251 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE; 252 virtual void OnGCMReady() OVERRIDE; 253 virtual void OnActivityRecorded() OVERRIDE {} 254 virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE {} 255 virtual void OnDisconnected() OVERRIDE {} 256 257 GCMClientImpl* gcm_client() const { return gcm_client_.get(); } 258 FakeMCSClient* mcs_client() const { 259 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get()); 260 } 261 ConnectionFactory* connection_factory() const { 262 return gcm_client_->connection_factory_.get(); 263 } 264 265 void reset_last_event() { 266 last_event_ = NONE; 267 last_app_id_.clear(); 268 last_registration_id_.clear(); 269 last_message_id_.clear(); 270 last_result_ = GCMClient::UNKNOWN_ERROR; 271 } 272 273 LastEvent last_event() const { return last_event_; } 274 const std::string& last_app_id() const { return last_app_id_; } 275 const std::string& last_registration_id() const { 276 return last_registration_id_; 277 } 278 const std::string& last_message_id() const { return last_message_id_; } 279 GCMClient::Result last_result() const { return last_result_; } 280 const GCMClient::IncomingMessage& last_message() const { 281 return last_message_; 282 } 283 const GCMClient::SendErrorDetails& last_error_details() const { 284 return last_error_details_; 285 } 286 287 const GServicesSettings& gservices_settings() const { 288 return gcm_client_->gservices_settings_; 289 } 290 291 int64 CurrentTime(); 292 293 // Tooling. 294 void PumpLoop(); 295 void PumpLoopUntilIdle(); 296 void QuitLoop(); 297 void InitializeLoop(); 298 bool CreateUniqueTempDir(); 299 AutoAdvancingTestClock* clock() const { 300 return reinterpret_cast<AutoAdvancingTestClock*>(gcm_client_->clock_.get()); 301 } 302 303 private: 304 // Variables used for verification. 305 LastEvent last_event_; 306 std::string last_app_id_; 307 std::string last_registration_id_; 308 std::string last_message_id_; 309 GCMClient::Result last_result_; 310 GCMClient::IncomingMessage last_message_; 311 GCMClient::SendErrorDetails last_error_details_; 312 313 scoped_ptr<GCMClientImpl> gcm_client_; 314 315 base::MessageLoop message_loop_; 316 scoped_ptr<base::RunLoop> run_loop_; 317 net::TestURLFetcherFactory url_fetcher_factory_; 318 319 // Injected to GCM client: 320 base::ScopedTempDir temp_directory_; 321 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 322}; 323 324GCMClientImplTest::GCMClientImplTest() 325 : last_event_(NONE), 326 last_result_(GCMClient::UNKNOWN_ERROR), 327 url_request_context_getter_(new net::TestURLRequestContextGetter( 328 message_loop_.message_loop_proxy())) { 329} 330 331GCMClientImplTest::~GCMClientImplTest() {} 332 333void GCMClientImplTest::SetUp() { 334 testing::Test::SetUp(); 335 ASSERT_TRUE(CreateUniqueTempDir()); 336 InitializeLoop(); 337 BuildGCMClient(base::TimeDelta()); 338 InitializeGCMClient(); 339 StartGCMClient(); 340 CompleteCheckin(kDeviceAndroidId, 341 kDeviceSecurityToken, 342 std::string(), 343 std::map<std::string, std::string>()); 344} 345 346void GCMClientImplTest::PumpLoop() { 347 run_loop_->Run(); 348 run_loop_.reset(new base::RunLoop()); 349} 350 351void GCMClientImplTest::PumpLoopUntilIdle() { 352 run_loop_->RunUntilIdle(); 353 run_loop_.reset(new base::RunLoop()); 354} 355 356void GCMClientImplTest::QuitLoop() { 357 if (run_loop_ && run_loop_->running()) 358 run_loop_->Quit(); 359} 360 361void GCMClientImplTest::InitializeLoop() { 362 run_loop_.reset(new base::RunLoop); 363} 364 365bool GCMClientImplTest::CreateUniqueTempDir() { 366 return temp_directory_.CreateUniqueTempDir(); 367} 368 369void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step) { 370 gcm_client_.reset(new GCMClientImpl(make_scoped_ptr<GCMInternalsBuilder>( 371 new FakeGCMInternalsBuilder(clock_step)))); 372} 373 374void GCMClientImplTest::CompleteCheckin( 375 uint64 android_id, 376 uint64 security_token, 377 const std::string& digest, 378 const std::map<std::string, std::string>& settings) { 379 checkin_proto::AndroidCheckinResponse response; 380 response.set_stats_ok(true); 381 response.set_android_id(android_id); 382 response.set_security_token(security_token); 383 384 // For testing G-services settings. 385 if (!digest.empty()) { 386 response.set_digest(digest); 387 for (std::map<std::string, std::string>::const_iterator it = 388 settings.begin(); 389 it != settings.end(); 390 ++it) { 391 checkin_proto::GservicesSetting* setting = response.add_setting(); 392 setting->set_name(it->first); 393 setting->set_value(it->second); 394 } 395 response.set_settings_diff(false); 396 } 397 398 std::string response_string; 399 response.SerializeToString(&response_string); 400 401 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 402 ASSERT_TRUE(fetcher); 403 fetcher->set_response_code(net::HTTP_OK); 404 fetcher->SetResponseString(response_string); 405 fetcher->delegate()->OnURLFetchComplete(fetcher); 406 url_fetcher_factory_.RemoveFetcherFromMap(0); 407} 408 409void GCMClientImplTest::CompleteRegistration( 410 const std::string& registration_id) { 411 std::string response(kRegistrationResponsePrefix); 412 response.append(registration_id); 413 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 414 ASSERT_TRUE(fetcher); 415 fetcher->set_response_code(net::HTTP_OK); 416 fetcher->SetResponseString(response); 417 fetcher->delegate()->OnURLFetchComplete(fetcher); 418 url_fetcher_factory_.RemoveFetcherFromMap(0); 419} 420 421void GCMClientImplTest::CompleteUnregistration( 422 const std::string& app_id) { 423 std::string response(kUnregistrationResponsePrefix); 424 response.append(app_id); 425 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 426 ASSERT_TRUE(fetcher); 427 fetcher->set_response_code(net::HTTP_OK); 428 fetcher->SetResponseString(response); 429 fetcher->delegate()->OnURLFetchComplete(fetcher); 430 url_fetcher_factory_.RemoveFetcherFromMap(0); 431} 432 433bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const { 434 return gcm_client_->registrations_.count(app_id) > 0; 435} 436 437void GCMClientImplTest::AddRegistration( 438 const std::string& app_id, 439 const std::vector<std::string>& sender_ids, 440 const std::string& registration_id) { 441 linked_ptr<RegistrationInfo> registration(new RegistrationInfo); 442 registration->sender_ids = sender_ids; 443 registration->registration_id = registration_id; 444 gcm_client_->registrations_[app_id] = registration; 445} 446 447void GCMClientImplTest::InitializeGCMClient() { 448 clock()->Advance(base::TimeDelta::FromMilliseconds(1)); 449 450 // Actual initialization. 451 GCMClient::ChromeBuildInfo chrome_build_info; 452 gcm_client_->Initialize(chrome_build_info, 453 temp_directory_.path(), 454 message_loop_.message_loop_proxy(), 455 url_request_context_getter_, 456 make_scoped_ptr<Encryptor>(new FakeEncryptor), 457 this); 458} 459 460void GCMClientImplTest::StartGCMClient() { 461 // Start loading and check-in. 462 gcm_client_->Start(); 463 464 PumpLoopUntilIdle(); 465} 466 467void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) { 468 gcm_client_->OnMessageReceivedFromMCS(message); 469} 470 471void GCMClientImplTest::OnGCMReady() { 472 last_event_ = LOADING_COMPLETED; 473 QuitLoop(); 474} 475 476void GCMClientImplTest::OnMessageReceived( 477 const std::string& registration_id, 478 const GCMClient::IncomingMessage& message) { 479 last_event_ = MESSAGE_RECEIVED; 480 last_app_id_ = registration_id; 481 last_message_ = message; 482 QuitLoop(); 483} 484 485void GCMClientImplTest::OnRegisterFinished(const std::string& app_id, 486 const std::string& registration_id, 487 GCMClient::Result result) { 488 last_event_ = REGISTRATION_COMPLETED; 489 last_app_id_ = app_id; 490 last_registration_id_ = registration_id; 491 last_result_ = result; 492} 493 494void GCMClientImplTest::OnUnregisterFinished(const std::string& app_id, 495 GCMClient::Result result) { 496 last_event_ = UNREGISTRATION_COMPLETED; 497 last_app_id_ = app_id; 498 last_result_ = result; 499} 500 501void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) { 502 last_event_ = MESSAGES_DELETED; 503 last_app_id_ = app_id; 504} 505 506void GCMClientImplTest::OnMessageSendError( 507 const std::string& app_id, 508 const gcm::GCMClient::SendErrorDetails& send_error_details) { 509 last_event_ = MESSAGE_SEND_ERROR; 510 last_app_id_ = app_id; 511 last_error_details_ = send_error_details; 512} 513 514int64 GCMClientImplTest::CurrentTime() { 515 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond; 516} 517 518TEST_F(GCMClientImplTest, LoadingCompleted) { 519 EXPECT_EQ(LOADING_COMPLETED, last_event()); 520 EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id()); 521 EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token()); 522} 523 524TEST_F(GCMClientImplTest, CheckOut) { 525 EXPECT_TRUE(mcs_client()); 526 EXPECT_TRUE(connection_factory()); 527 gcm_client()->CheckOut(); 528 EXPECT_FALSE(mcs_client()); 529 EXPECT_FALSE(connection_factory()); 530} 531 532TEST_F(GCMClientImplTest, RegisterApp) { 533 EXPECT_FALSE(ExistsRegistration(kAppId)); 534 535 std::vector<std::string> senders; 536 senders.push_back("sender"); 537 gcm_client()->Register(kAppId, senders); 538 CompleteRegistration("reg_id"); 539 540 EXPECT_EQ(REGISTRATION_COMPLETED, last_event()); 541 EXPECT_EQ(kAppId, last_app_id()); 542 EXPECT_EQ("reg_id", last_registration_id()); 543 EXPECT_EQ(GCMClient::SUCCESS, last_result()); 544 EXPECT_TRUE(ExistsRegistration(kAppId)); 545} 546 547TEST_F(GCMClientImplTest, DISABLED_RegisterAppFromCache) { 548 EXPECT_FALSE(ExistsRegistration(kAppId)); 549 550 std::vector<std::string> senders; 551 senders.push_back("sender"); 552 gcm_client()->Register(kAppId, senders); 553 CompleteRegistration("reg_id"); 554 EXPECT_TRUE(ExistsRegistration(kAppId)); 555 556 EXPECT_EQ(kAppId, last_app_id()); 557 EXPECT_EQ("reg_id", last_registration_id()); 558 EXPECT_EQ(GCMClient::SUCCESS, last_result()); 559 EXPECT_EQ(REGISTRATION_COMPLETED, last_event()); 560 561 // Recreate GCMClient in order to load from the persistent store. 562 BuildGCMClient(base::TimeDelta()); 563 InitializeGCMClient(); 564 StartGCMClient(); 565 566 EXPECT_TRUE(ExistsRegistration(kAppId)); 567} 568 569TEST_F(GCMClientImplTest, UnregisterApp) { 570 EXPECT_FALSE(ExistsRegistration(kAppId)); 571 572 std::vector<std::string> senders; 573 senders.push_back("sender"); 574 gcm_client()->Register(kAppId, senders); 575 CompleteRegistration("reg_id"); 576 EXPECT_TRUE(ExistsRegistration(kAppId)); 577 578 gcm_client()->Unregister(kAppId); 579 CompleteUnregistration(kAppId); 580 581 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event()); 582 EXPECT_EQ(kAppId, last_app_id()); 583 EXPECT_EQ(GCMClient::SUCCESS, last_result()); 584 EXPECT_FALSE(ExistsRegistration(kAppId)); 585} 586 587TEST_F(GCMClientImplTest, DispatchDownstreamMessage) { 588 // Register to receive messages from kSender and kSender2 only. 589 std::vector<std::string> senders; 590 senders.push_back(kSender); 591 senders.push_back(kSender2); 592 AddRegistration(kAppId, senders, "reg_id"); 593 594 std::map<std::string, std::string> expected_data; 595 expected_data["message_type"] = "gcm"; 596 expected_data["key"] = "value"; 597 expected_data["key2"] = "value2"; 598 599 // Message for kSender will be received. 600 MCSMessage message(BuildDownstreamMessage(kSender, kAppId, expected_data)); 601 EXPECT_TRUE(message.IsValid()); 602 ReceiveMessageFromMCS(message); 603 604 expected_data.erase(expected_data.find("message_type")); 605 EXPECT_EQ(MESSAGE_RECEIVED, last_event()); 606 EXPECT_EQ(kAppId, last_app_id()); 607 EXPECT_EQ(expected_data.size(), last_message().data.size()); 608 EXPECT_EQ(expected_data, last_message().data); 609 EXPECT_EQ(kSender, last_message().sender_id); 610 611 reset_last_event(); 612 613 // Message for kSender2 will be received. 614 MCSMessage message2(BuildDownstreamMessage(kSender2, kAppId, expected_data)); 615 EXPECT_TRUE(message2.IsValid()); 616 ReceiveMessageFromMCS(message2); 617 618 EXPECT_EQ(MESSAGE_RECEIVED, last_event()); 619 EXPECT_EQ(kAppId, last_app_id()); 620 EXPECT_EQ(expected_data.size(), last_message().data.size()); 621 EXPECT_EQ(expected_data, last_message().data); 622 EXPECT_EQ(kSender2, last_message().sender_id); 623 624 reset_last_event(); 625 626 // Message from kSender3 will be dropped. 627 MCSMessage message3(BuildDownstreamMessage(kSender3, kAppId, expected_data)); 628 EXPECT_TRUE(message3.IsValid()); 629 ReceiveMessageFromMCS(message3); 630 631 EXPECT_NE(MESSAGE_RECEIVED, last_event()); 632 EXPECT_NE(kAppId, last_app_id()); 633} 634 635TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) { 636 std::map<std::string, std::string> expected_data; 637 expected_data["message_type"] = "send_error"; 638 expected_data["google.message_id"] = "007"; 639 expected_data["error_details"] = "some details"; 640 MCSMessage message(BuildDownstreamMessage( 641 kSender, kAppId, expected_data)); 642 EXPECT_TRUE(message.IsValid()); 643 ReceiveMessageFromMCS(message); 644 645 EXPECT_EQ(MESSAGE_SEND_ERROR, last_event()); 646 EXPECT_EQ(kAppId, last_app_id()); 647 EXPECT_EQ("007", last_error_details().message_id); 648 EXPECT_EQ(1UL, last_error_details().additional_data.size()); 649 GCMClient::MessageData::const_iterator iter = 650 last_error_details().additional_data.find("error_details"); 651 EXPECT_TRUE(iter != last_error_details().additional_data.end()); 652 EXPECT_EQ("some details", iter->second); 653} 654 655TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) { 656 std::map<std::string, std::string> expected_data; 657 expected_data["message_type"] = "deleted_messages"; 658 MCSMessage message(BuildDownstreamMessage( 659 kSender, kAppId, expected_data)); 660 EXPECT_TRUE(message.IsValid()); 661 ReceiveMessageFromMCS(message); 662 663 EXPECT_EQ(MESSAGES_DELETED, last_event()); 664 EXPECT_EQ(kAppId, last_app_id()); 665} 666 667TEST_F(GCMClientImplTest, SendMessage) { 668 mcs_proto::DataMessageStanza stanza; 669 stanza.set_ttl(500); 670 671 GCMClient::OutgoingMessage message; 672 message.id = "007"; 673 message.time_to_live = 500; 674 message.data["key"] = "value"; 675 gcm_client()->Send(kAppId, kSender, message); 676 677 EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag()); 678 EXPECT_EQ(kAppId, mcs_client()->last_data_message_stanza().category()); 679 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); 680 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl()); 681 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent()); 682 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id()); 683 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from()); 684 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); 685 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key()); 686 EXPECT_EQ("value", 687 mcs_client()->last_data_message_stanza().app_data(0).value()); 688} 689 690class GCMClientImplCheckinTest : public GCMClientImplTest { 691 public: 692 GCMClientImplCheckinTest(); 693 virtual ~GCMClientImplCheckinTest(); 694 695 virtual void SetUp() OVERRIDE; 696}; 697 698GCMClientImplCheckinTest::GCMClientImplCheckinTest() { 699} 700 701GCMClientImplCheckinTest::~GCMClientImplCheckinTest() { 702} 703 704void GCMClientImplCheckinTest::SetUp() { 705 testing::Test::SetUp(); 706 // Creating unique temp directory that will be used by GCMStore shared between 707 // GCM Client and G-services settings. 708 ASSERT_TRUE(CreateUniqueTempDir()); 709 InitializeLoop(); 710 // Time will be advancing one hour every time it is checked. 711 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval)); 712 InitializeGCMClient(); 713 StartGCMClient(); 714} 715 716TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) { 717 std::map<std::string, std::string> settings; 718 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval); 719 settings["checkin_url"] = "http://alternative.url/checkin"; 720 settings["gcm_hostname"] = "alternative.gcm.host"; 721 settings["gcm_secure_port"] = "7777"; 722 settings["gcm_registration_url"] = "http://alternative.url/registration"; 723 CompleteCheckin(kDeviceAndroidId, 724 kDeviceSecurityToken, 725 GServicesSettings::CalculateDigest(settings), 726 settings); 727 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval), 728 gservices_settings().GetCheckinInterval()); 729 EXPECT_EQ(GURL("http://alternative.url/checkin"), 730 gservices_settings().GetCheckinURL()); 731 EXPECT_EQ(GURL("http://alternative.url/registration"), 732 gservices_settings().GetRegistrationURL()); 733 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"), 734 gservices_settings().GetMCSMainEndpoint()); 735 EXPECT_EQ(GURL("https://alternative.gcm.host:443"), 736 gservices_settings().GetMCSFallbackEndpoint()); 737} 738 739// This test only checks that periodic checkin happens. 740TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) { 741 std::map<std::string, std::string> settings; 742 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval); 743 settings["checkin_url"] = "http://alternative.url/checkin"; 744 settings["gcm_hostname"] = "alternative.gcm.host"; 745 settings["gcm_secure_port"] = "7777"; 746 settings["gcm_registration_url"] = "http://alternative.url/registration"; 747 CompleteCheckin(kDeviceAndroidId, 748 kDeviceSecurityToken, 749 GServicesSettings::CalculateDigest(settings), 750 settings); 751 EXPECT_EQ(2, clock()->call_count()); 752 753 PumpLoopUntilIdle(); 754 CompleteCheckin(kDeviceAndroidId, 755 kDeviceSecurityToken, 756 GServicesSettings::CalculateDigest(settings), 757 settings); 758} 759 760TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) { 761 std::map<std::string, std::string> settings; 762 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval); 763 settings["checkin_url"] = "http://alternative.url/checkin"; 764 settings["gcm_hostname"] = "alternative.gcm.host"; 765 settings["gcm_secure_port"] = "7777"; 766 settings["gcm_registration_url"] = "http://alternative.url/registration"; 767 CompleteCheckin(kDeviceAndroidId, 768 kDeviceSecurityToken, 769 GServicesSettings::CalculateDigest(settings), 770 settings); 771 772 BuildGCMClient(base::TimeDelta()); 773 InitializeGCMClient(); 774 StartGCMClient(); 775 776 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval), 777 gservices_settings().GetCheckinInterval()); 778 EXPECT_EQ(GURL("http://alternative.url/checkin"), 779 gservices_settings().GetCheckinURL()); 780 EXPECT_EQ(GURL("http://alternative.url/registration"), 781 gservices_settings().GetRegistrationURL()); 782 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"), 783 gservices_settings().GetMCSMainEndpoint()); 784 EXPECT_EQ(GURL("https://alternative.gcm.host:443"), 785 gservices_settings().GetMCSFallbackEndpoint()); 786} 787 788class GCMClientImplStartAndStopTest : public GCMClientImplTest { 789public: 790 GCMClientImplStartAndStopTest(); 791 virtual ~GCMClientImplStartAndStopTest(); 792 793 virtual void SetUp() OVERRIDE; 794}; 795 796GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() { 797} 798 799GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() { 800} 801 802void GCMClientImplStartAndStopTest::SetUp() { 803 testing::Test::SetUp(); 804 ASSERT_TRUE(CreateUniqueTempDir()); 805 InitializeLoop(); 806 BuildGCMClient(base::TimeDelta()); 807 InitializeGCMClient(); 808} 809 810TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestart) { 811 // Start the GCM and wait until it is ready. 812 gcm_client()->Start(); 813 PumpLoopUntilIdle(); 814 815 // Stop the GCM. 816 gcm_client()->Stop(); 817 PumpLoopUntilIdle(); 818 819 // Restart the GCM. 820 gcm_client()->Start(); 821 PumpLoopUntilIdle(); 822} 823 824TEST_F(GCMClientImplStartAndStopTest, StartAndStopImmediately) { 825 // Start the GCM and then stop it immediately. 826 gcm_client()->Start(); 827 gcm_client()->Stop(); 828 829 PumpLoopUntilIdle(); 830} 831 832TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestartImmediately) { 833 // Start the GCM and then stop and restart it immediately. 834 gcm_client()->Start(); 835 gcm_client()->Stop(); 836 gcm_client()->Start(); 837 838 PumpLoopUntilIdle(); 839} 840 841} // namespace gcm 842