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