| OLD | NEW |
| (Empty) |
| 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 "google_apis/gcm/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 | |
| 28 namespace gcm { | |
| 29 | |
| 30 namespace { | |
| 31 | |
| 32 enum LastEvent { | |
| 33 NONE, | |
| 34 LOADING_COMPLETED, | |
| 35 REGISTRATION_COMPLETED, | |
| 36 UNREGISTRATION_COMPLETED, | |
| 37 MESSAGE_SEND_ERROR, | |
| 38 MESSAGE_RECEIVED, | |
| 39 MESSAGES_DELETED, | |
| 40 }; | |
| 41 | |
| 42 const uint64 kDeviceAndroidId = 54321; | |
| 43 const uint64 kDeviceSecurityToken = 12345; | |
| 44 const int64 kSettingsCheckinInterval = 16 * 60 * 60; | |
| 45 const char kAppId[] = "app_id"; | |
| 46 const char kSender[] = "project_id"; | |
| 47 const char kSender2[] = "project_id2"; | |
| 48 const char kSender3[] = "project_id3"; | |
| 49 const char kRegistrationResponsePrefix[] = "token="; | |
| 50 const char kUnregistrationResponsePrefix[] = "deleted="; | |
| 51 | |
| 52 // Helper for building arbitrary data messages. | |
| 53 MCSMessage 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 | |
| 70 class 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 | |
| 94 FakeMCSClient::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 | |
| 104 FakeMCSClient::~FakeMCSClient() { | |
| 105 } | |
| 106 | |
| 107 void FakeMCSClient::Login(uint64 android_id, uint64 security_token) { | |
| 108 last_android_id_ = android_id; | |
| 109 last_security_token_ = security_token; | |
| 110 } | |
| 111 | |
| 112 void 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 | |
| 121 class 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 | |
| 138 AutoAdvancingTestClock::AutoAdvancingTestClock( | |
| 139 base::TimeDelta auto_increment_time_delta) | |
| 140 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta) { | |
| 141 } | |
| 142 | |
| 143 AutoAdvancingTestClock::~AutoAdvancingTestClock() { | |
| 144 } | |
| 145 | |
| 146 base::Time AutoAdvancingTestClock::Now() { | |
| 147 call_count_++; | |
| 148 now_ += auto_increment_time_delta_; | |
| 149 return now_; | |
| 150 } | |
| 151 | |
| 152 void AutoAdvancingTestClock::Advance(base::TimeDelta delta) { | |
| 153 now_ += delta; | |
| 154 } | |
| 155 | |
| 156 class 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 | |
| 179 FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step) | |
| 180 : clock_step_(clock_step) { | |
| 181 } | |
| 182 | |
| 183 FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {} | |
| 184 | |
| 185 scoped_ptr<base::Clock> FakeGCMInternalsBuilder::BuildClock() { | |
| 186 return make_scoped_ptr<base::Clock>(new AutoAdvancingTestClock(clock_step_)); | |
| 187 } | |
| 188 | |
| 189 scoped_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 | |
| 201 scoped_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 | |
| 212 class 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 ReceiveMessageFromMCS(const MCSMessage& message); | |
| 223 void CompleteCheckin(uint64 android_id, | |
| 224 uint64 security_token, | |
| 225 const std::string& digest, | |
| 226 const std::map<std::string, std::string>& settings); | |
| 227 void CompleteRegistration(const std::string& registration_id); | |
| 228 void CompleteUnregistration(const std::string& app_id); | |
| 229 | |
| 230 bool ExistsRegistration(const std::string& app_id) const; | |
| 231 void AddRegistration(const std::string& app_id, | |
| 232 const std::vector<std::string>& sender_ids, | |
| 233 const std::string& registration_id); | |
| 234 | |
| 235 // GCMClient::Delegate overrides (for verification). | |
| 236 virtual void OnRegisterFinished(const std::string& app_id, | |
| 237 const std::string& registration_id, | |
| 238 GCMClient::Result result) OVERRIDE; | |
| 239 virtual void OnUnregisterFinished(const std::string& app_id, | |
| 240 GCMClient::Result result) OVERRIDE; | |
| 241 virtual void OnSendFinished(const std::string& app_id, | |
| 242 const std::string& message_id, | |
| 243 GCMClient::Result result) OVERRIDE {} | |
| 244 virtual void OnMessageReceived(const std::string& registration_id, | |
| 245 const GCMClient::IncomingMessage& message) | |
| 246 OVERRIDE; | |
| 247 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; | |
| 248 virtual void OnMessageSendError( | |
| 249 const std::string& app_id, | |
| 250 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE; | |
| 251 virtual void OnGCMReady() OVERRIDE; | |
| 252 virtual void OnActivityRecorded() OVERRIDE {} | |
| 253 | |
| 254 GCMClientImpl* gcm_client() const { return gcm_client_.get(); } | |
| 255 FakeMCSClient* mcs_client() const { | |
| 256 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get()); | |
| 257 } | |
| 258 ConnectionFactory* connection_factory() const { | |
| 259 return gcm_client_->connection_factory_.get(); | |
| 260 } | |
| 261 | |
| 262 void reset_last_event() { | |
| 263 last_event_ = NONE; | |
| 264 last_app_id_.clear(); | |
| 265 last_registration_id_.clear(); | |
| 266 last_message_id_.clear(); | |
| 267 last_result_ = GCMClient::UNKNOWN_ERROR; | |
| 268 } | |
| 269 | |
| 270 LastEvent last_event() const { return last_event_; } | |
| 271 const std::string& last_app_id() const { return last_app_id_; } | |
| 272 const std::string& last_registration_id() const { | |
| 273 return last_registration_id_; | |
| 274 } | |
| 275 const std::string& last_message_id() const { return last_message_id_; } | |
| 276 GCMClient::Result last_result() const { return last_result_; } | |
| 277 const GCMClient::IncomingMessage& last_message() const { | |
| 278 return last_message_; | |
| 279 } | |
| 280 const GCMClient::SendErrorDetails& last_error_details() const { | |
| 281 return last_error_details_; | |
| 282 } | |
| 283 | |
| 284 const GServicesSettings& gservices_settings() const { | |
| 285 return gcm_client_->gservices_settings_; | |
| 286 } | |
| 287 | |
| 288 int64 CurrentTime(); | |
| 289 | |
| 290 // Tooling. | |
| 291 void PumpLoop(); | |
| 292 void PumpLoopUntilIdle(); | |
| 293 void QuitLoop(); | |
| 294 void InitializeLoop(); | |
| 295 bool CreateUniqueTempDir(); | |
| 296 AutoAdvancingTestClock* clock() const { | |
| 297 return reinterpret_cast<AutoAdvancingTestClock*>(gcm_client_->clock_.get()); | |
| 298 } | |
| 299 | |
| 300 private: | |
| 301 // Variables used for verification. | |
| 302 LastEvent last_event_; | |
| 303 std::string last_app_id_; | |
| 304 std::string last_registration_id_; | |
| 305 std::string last_message_id_; | |
| 306 GCMClient::Result last_result_; | |
| 307 GCMClient::IncomingMessage last_message_; | |
| 308 GCMClient::SendErrorDetails last_error_details_; | |
| 309 | |
| 310 scoped_ptr<GCMClientImpl> gcm_client_; | |
| 311 | |
| 312 base::MessageLoop message_loop_; | |
| 313 scoped_ptr<base::RunLoop> run_loop_; | |
| 314 net::TestURLFetcherFactory url_fetcher_factory_; | |
| 315 | |
| 316 // Injected to GCM client: | |
| 317 base::ScopedTempDir temp_directory_; | |
| 318 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; | |
| 319 }; | |
| 320 | |
| 321 GCMClientImplTest::GCMClientImplTest() | |
| 322 : last_event_(NONE), | |
| 323 last_result_(GCMClient::UNKNOWN_ERROR), | |
| 324 url_request_context_getter_(new net::TestURLRequestContextGetter( | |
| 325 message_loop_.message_loop_proxy())) { | |
| 326 } | |
| 327 | |
| 328 GCMClientImplTest::~GCMClientImplTest() {} | |
| 329 | |
| 330 void GCMClientImplTest::SetUp() { | |
| 331 testing::Test::SetUp(); | |
| 332 ASSERT_TRUE(CreateUniqueTempDir()); | |
| 333 InitializeLoop(); | |
| 334 BuildGCMClient(base::TimeDelta()); | |
| 335 InitializeGCMClient(); | |
| 336 CompleteCheckin(kDeviceAndroidId, | |
| 337 kDeviceSecurityToken, | |
| 338 std::string(), | |
| 339 std::map<std::string, std::string>()); | |
| 340 } | |
| 341 | |
| 342 void GCMClientImplTest::PumpLoop() { | |
| 343 run_loop_->Run(); | |
| 344 run_loop_.reset(new base::RunLoop()); | |
| 345 } | |
| 346 | |
| 347 void GCMClientImplTest::PumpLoopUntilIdle() { | |
| 348 run_loop_->RunUntilIdle(); | |
| 349 run_loop_.reset(new base::RunLoop()); | |
| 350 } | |
| 351 | |
| 352 void GCMClientImplTest::QuitLoop() { | |
| 353 if (run_loop_ && run_loop_->running()) | |
| 354 run_loop_->Quit(); | |
| 355 } | |
| 356 | |
| 357 void GCMClientImplTest::InitializeLoop() { | |
| 358 run_loop_.reset(new base::RunLoop); | |
| 359 } | |
| 360 | |
| 361 bool GCMClientImplTest::CreateUniqueTempDir() { | |
| 362 return temp_directory_.CreateUniqueTempDir(); | |
| 363 } | |
| 364 | |
| 365 void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step) { | |
| 366 gcm_client_.reset(new GCMClientImpl(make_scoped_ptr<GCMInternalsBuilder>( | |
| 367 new FakeGCMInternalsBuilder(clock_step)))); | |
| 368 } | |
| 369 | |
| 370 void GCMClientImplTest::CompleteCheckin( | |
| 371 uint64 android_id, | |
| 372 uint64 security_token, | |
| 373 const std::string& digest, | |
| 374 const std::map<std::string, std::string>& settings) { | |
| 375 checkin_proto::AndroidCheckinResponse response; | |
| 376 response.set_stats_ok(true); | |
| 377 response.set_android_id(android_id); | |
| 378 response.set_security_token(security_token); | |
| 379 | |
| 380 // For testing G-services settings. | |
| 381 if (!digest.empty()) { | |
| 382 response.set_digest(digest); | |
| 383 for (std::map<std::string, std::string>::const_iterator it = | |
| 384 settings.begin(); | |
| 385 it != settings.end(); | |
| 386 ++it) { | |
| 387 checkin_proto::GservicesSetting* setting = response.add_setting(); | |
| 388 setting->set_name(it->first); | |
| 389 setting->set_value(it->second); | |
| 390 } | |
| 391 response.set_settings_diff(false); | |
| 392 } | |
| 393 | |
| 394 std::string response_string; | |
| 395 response.SerializeToString(&response_string); | |
| 396 | |
| 397 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); | |
| 398 ASSERT_TRUE(fetcher); | |
| 399 fetcher->set_response_code(net::HTTP_OK); | |
| 400 fetcher->SetResponseString(response_string); | |
| 401 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 402 url_fetcher_factory_.RemoveFetcherFromMap(0); | |
| 403 } | |
| 404 | |
| 405 void GCMClientImplTest::CompleteRegistration( | |
| 406 const std::string& registration_id) { | |
| 407 std::string response(kRegistrationResponsePrefix); | |
| 408 response.append(registration_id); | |
| 409 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); | |
| 410 ASSERT_TRUE(fetcher); | |
| 411 fetcher->set_response_code(net::HTTP_OK); | |
| 412 fetcher->SetResponseString(response); | |
| 413 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 414 url_fetcher_factory_.RemoveFetcherFromMap(0); | |
| 415 } | |
| 416 | |
| 417 void GCMClientImplTest::CompleteUnregistration( | |
| 418 const std::string& app_id) { | |
| 419 std::string response(kUnregistrationResponsePrefix); | |
| 420 response.append(app_id); | |
| 421 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); | |
| 422 ASSERT_TRUE(fetcher); | |
| 423 fetcher->set_response_code(net::HTTP_OK); | |
| 424 fetcher->SetResponseString(response); | |
| 425 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 426 url_fetcher_factory_.RemoveFetcherFromMap(0); | |
| 427 } | |
| 428 | |
| 429 bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const { | |
| 430 return gcm_client_->registrations_.count(app_id) > 0; | |
| 431 } | |
| 432 | |
| 433 void GCMClientImplTest::AddRegistration( | |
| 434 const std::string& app_id, | |
| 435 const std::vector<std::string>& sender_ids, | |
| 436 const std::string& registration_id) { | |
| 437 linked_ptr<RegistrationInfo> registration(new RegistrationInfo); | |
| 438 registration->sender_ids = sender_ids; | |
| 439 registration->registration_id = registration_id; | |
| 440 gcm_client_->registrations_[app_id] = registration; | |
| 441 } | |
| 442 | |
| 443 void GCMClientImplTest::InitializeGCMClient() { | |
| 444 clock()->Advance(base::TimeDelta::FromMilliseconds(1)); | |
| 445 | |
| 446 // Actual initialization. | |
| 447 GCMClient::ChromeBuildInfo chrome_build_info; | |
| 448 gcm_client_->Initialize(chrome_build_info, | |
| 449 temp_directory_.path(), | |
| 450 std::vector<std::string>(), | |
| 451 message_loop_.message_loop_proxy(), | |
| 452 url_request_context_getter_, | |
| 453 make_scoped_ptr<Encryptor>(new FakeEncryptor), | |
| 454 this); | |
| 455 | |
| 456 // Start loading and check-in. | |
| 457 gcm_client_->Start(); | |
| 458 | |
| 459 PumpLoopUntilIdle(); | |
| 460 } | |
| 461 | |
| 462 void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) { | |
| 463 gcm_client_->OnMessageReceivedFromMCS(message); | |
| 464 } | |
| 465 | |
| 466 void GCMClientImplTest::OnGCMReady() { | |
| 467 last_event_ = LOADING_COMPLETED; | |
| 468 QuitLoop(); | |
| 469 } | |
| 470 | |
| 471 void GCMClientImplTest::OnMessageReceived( | |
| 472 const std::string& registration_id, | |
| 473 const GCMClient::IncomingMessage& message) { | |
| 474 last_event_ = MESSAGE_RECEIVED; | |
| 475 last_app_id_ = registration_id; | |
| 476 last_message_ = message; | |
| 477 QuitLoop(); | |
| 478 } | |
| 479 | |
| 480 void GCMClientImplTest::OnRegisterFinished(const std::string& app_id, | |
| 481 const std::string& registration_id, | |
| 482 GCMClient::Result result) { | |
| 483 last_event_ = REGISTRATION_COMPLETED; | |
| 484 last_app_id_ = app_id; | |
| 485 last_registration_id_ = registration_id; | |
| 486 last_result_ = result; | |
| 487 } | |
| 488 | |
| 489 void GCMClientImplTest::OnUnregisterFinished(const std::string& app_id, | |
| 490 GCMClient::Result result) { | |
| 491 last_event_ = UNREGISTRATION_COMPLETED; | |
| 492 last_app_id_ = app_id; | |
| 493 last_result_ = result; | |
| 494 } | |
| 495 | |
| 496 void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) { | |
| 497 last_event_ = MESSAGES_DELETED; | |
| 498 last_app_id_ = app_id; | |
| 499 } | |
| 500 | |
| 501 void GCMClientImplTest::OnMessageSendError( | |
| 502 const std::string& app_id, | |
| 503 const gcm::GCMClient::SendErrorDetails& send_error_details) { | |
| 504 last_event_ = MESSAGE_SEND_ERROR; | |
| 505 last_app_id_ = app_id; | |
| 506 last_error_details_ = send_error_details; | |
| 507 } | |
| 508 | |
| 509 int64 GCMClientImplTest::CurrentTime() { | |
| 510 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond; | |
| 511 } | |
| 512 | |
| 513 TEST_F(GCMClientImplTest, LoadingCompleted) { | |
| 514 EXPECT_EQ(LOADING_COMPLETED, last_event()); | |
| 515 EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id()); | |
| 516 EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token()); | |
| 517 } | |
| 518 | |
| 519 TEST_F(GCMClientImplTest, CheckOut) { | |
| 520 EXPECT_TRUE(mcs_client()); | |
| 521 EXPECT_TRUE(connection_factory()); | |
| 522 gcm_client()->CheckOut(); | |
| 523 EXPECT_FALSE(mcs_client()); | |
| 524 EXPECT_FALSE(connection_factory()); | |
| 525 } | |
| 526 | |
| 527 TEST_F(GCMClientImplTest, RegisterApp) { | |
| 528 EXPECT_FALSE(ExistsRegistration(kAppId)); | |
| 529 | |
| 530 std::vector<std::string> senders; | |
| 531 senders.push_back("sender"); | |
| 532 gcm_client()->Register(kAppId, senders); | |
| 533 CompleteRegistration("reg_id"); | |
| 534 | |
| 535 EXPECT_EQ(REGISTRATION_COMPLETED, last_event()); | |
| 536 EXPECT_EQ(kAppId, last_app_id()); | |
| 537 EXPECT_EQ("reg_id", last_registration_id()); | |
| 538 EXPECT_EQ(GCMClient::SUCCESS, last_result()); | |
| 539 EXPECT_TRUE(ExistsRegistration(kAppId)); | |
| 540 } | |
| 541 | |
| 542 TEST_F(GCMClientImplTest, DISABLED_RegisterAppFromCache) { | |
| 543 EXPECT_FALSE(ExistsRegistration(kAppId)); | |
| 544 | |
| 545 std::vector<std::string> senders; | |
| 546 senders.push_back("sender"); | |
| 547 gcm_client()->Register(kAppId, senders); | |
| 548 CompleteRegistration("reg_id"); | |
| 549 EXPECT_TRUE(ExistsRegistration(kAppId)); | |
| 550 | |
| 551 EXPECT_EQ(kAppId, last_app_id()); | |
| 552 EXPECT_EQ("reg_id", last_registration_id()); | |
| 553 EXPECT_EQ(GCMClient::SUCCESS, last_result()); | |
| 554 EXPECT_EQ(REGISTRATION_COMPLETED, last_event()); | |
| 555 | |
| 556 // Recreate GCMClient in order to load from the persistent store. | |
| 557 BuildGCMClient(base::TimeDelta()); | |
| 558 InitializeGCMClient(); | |
| 559 | |
| 560 EXPECT_TRUE(ExistsRegistration(kAppId)); | |
| 561 } | |
| 562 | |
| 563 TEST_F(GCMClientImplTest, UnregisterApp) { | |
| 564 EXPECT_FALSE(ExistsRegistration(kAppId)); | |
| 565 | |
| 566 std::vector<std::string> senders; | |
| 567 senders.push_back("sender"); | |
| 568 gcm_client()->Register(kAppId, senders); | |
| 569 CompleteRegistration("reg_id"); | |
| 570 EXPECT_TRUE(ExistsRegistration(kAppId)); | |
| 571 | |
| 572 gcm_client()->Unregister(kAppId); | |
| 573 CompleteUnregistration(kAppId); | |
| 574 | |
| 575 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event()); | |
| 576 EXPECT_EQ(kAppId, last_app_id()); | |
| 577 EXPECT_EQ(GCMClient::SUCCESS, last_result()); | |
| 578 EXPECT_FALSE(ExistsRegistration(kAppId)); | |
| 579 } | |
| 580 | |
| 581 TEST_F(GCMClientImplTest, DispatchDownstreamMessage) { | |
| 582 // Register to receive messages from kSender and kSender2 only. | |
| 583 std::vector<std::string> senders; | |
| 584 senders.push_back(kSender); | |
| 585 senders.push_back(kSender2); | |
| 586 AddRegistration(kAppId, senders, "reg_id"); | |
| 587 | |
| 588 std::map<std::string, std::string> expected_data; | |
| 589 expected_data["message_type"] = "gcm"; | |
| 590 expected_data["key"] = "value"; | |
| 591 expected_data["key2"] = "value2"; | |
| 592 | |
| 593 // Message for kSender will be received. | |
| 594 MCSMessage message(BuildDownstreamMessage(kSender, kAppId, expected_data)); | |
| 595 EXPECT_TRUE(message.IsValid()); | |
| 596 ReceiveMessageFromMCS(message); | |
| 597 | |
| 598 expected_data.erase(expected_data.find("message_type")); | |
| 599 EXPECT_EQ(MESSAGE_RECEIVED, last_event()); | |
| 600 EXPECT_EQ(kAppId, last_app_id()); | |
| 601 EXPECT_EQ(expected_data.size(), last_message().data.size()); | |
| 602 EXPECT_EQ(expected_data, last_message().data); | |
| 603 EXPECT_EQ(kSender, last_message().sender_id); | |
| 604 | |
| 605 reset_last_event(); | |
| 606 | |
| 607 // Message for kSender2 will be received. | |
| 608 MCSMessage message2(BuildDownstreamMessage(kSender2, kAppId, expected_data)); | |
| 609 EXPECT_TRUE(message2.IsValid()); | |
| 610 ReceiveMessageFromMCS(message2); | |
| 611 | |
| 612 EXPECT_EQ(MESSAGE_RECEIVED, last_event()); | |
| 613 EXPECT_EQ(kAppId, last_app_id()); | |
| 614 EXPECT_EQ(expected_data.size(), last_message().data.size()); | |
| 615 EXPECT_EQ(expected_data, last_message().data); | |
| 616 EXPECT_EQ(kSender2, last_message().sender_id); | |
| 617 | |
| 618 reset_last_event(); | |
| 619 | |
| 620 // Message from kSender3 will be dropped. | |
| 621 MCSMessage message3(BuildDownstreamMessage(kSender3, kAppId, expected_data)); | |
| 622 EXPECT_TRUE(message3.IsValid()); | |
| 623 ReceiveMessageFromMCS(message3); | |
| 624 | |
| 625 EXPECT_NE(MESSAGE_RECEIVED, last_event()); | |
| 626 EXPECT_NE(kAppId, last_app_id()); | |
| 627 } | |
| 628 | |
| 629 TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) { | |
| 630 std::map<std::string, std::string> expected_data; | |
| 631 expected_data["message_type"] = "send_error"; | |
| 632 expected_data["google.message_id"] = "007"; | |
| 633 expected_data["error_details"] = "some details"; | |
| 634 MCSMessage message(BuildDownstreamMessage( | |
| 635 kSender, kAppId, expected_data)); | |
| 636 EXPECT_TRUE(message.IsValid()); | |
| 637 ReceiveMessageFromMCS(message); | |
| 638 | |
| 639 EXPECT_EQ(MESSAGE_SEND_ERROR, last_event()); | |
| 640 EXPECT_EQ(kAppId, last_app_id()); | |
| 641 EXPECT_EQ("007", last_error_details().message_id); | |
| 642 EXPECT_EQ(1UL, last_error_details().additional_data.size()); | |
| 643 GCMClient::MessageData::const_iterator iter = | |
| 644 last_error_details().additional_data.find("error_details"); | |
| 645 EXPECT_TRUE(iter != last_error_details().additional_data.end()); | |
| 646 EXPECT_EQ("some details", iter->second); | |
| 647 } | |
| 648 | |
| 649 TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) { | |
| 650 std::map<std::string, std::string> expected_data; | |
| 651 expected_data["message_type"] = "deleted_messages"; | |
| 652 MCSMessage message(BuildDownstreamMessage( | |
| 653 kSender, kAppId, expected_data)); | |
| 654 EXPECT_TRUE(message.IsValid()); | |
| 655 ReceiveMessageFromMCS(message); | |
| 656 | |
| 657 EXPECT_EQ(MESSAGES_DELETED, last_event()); | |
| 658 EXPECT_EQ(kAppId, last_app_id()); | |
| 659 } | |
| 660 | |
| 661 TEST_F(GCMClientImplTest, SendMessage) { | |
| 662 mcs_proto::DataMessageStanza stanza; | |
| 663 stanza.set_ttl(500); | |
| 664 | |
| 665 GCMClient::OutgoingMessage message; | |
| 666 message.id = "007"; | |
| 667 message.time_to_live = 500; | |
| 668 message.data["key"] = "value"; | |
| 669 gcm_client()->Send(kAppId, kSender, message); | |
| 670 | |
| 671 EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag()); | |
| 672 EXPECT_EQ(kAppId, mcs_client()->last_data_message_stanza().category()); | |
| 673 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); | |
| 674 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl()); | |
| 675 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent()); | |
| 676 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id()); | |
| 677 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from()); | |
| 678 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to()); | |
| 679 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key()); | |
| 680 EXPECT_EQ("value", | |
| 681 mcs_client()->last_data_message_stanza().app_data(0).value()); | |
| 682 } | |
| 683 | |
| 684 class GCMClientImplCheckinTest : public GCMClientImplTest { | |
| 685 public: | |
| 686 GCMClientImplCheckinTest(); | |
| 687 virtual ~GCMClientImplCheckinTest(); | |
| 688 | |
| 689 virtual void SetUp() OVERRIDE; | |
| 690 }; | |
| 691 | |
| 692 GCMClientImplCheckinTest::GCMClientImplCheckinTest() { | |
| 693 } | |
| 694 | |
| 695 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() { | |
| 696 } | |
| 697 | |
| 698 void GCMClientImplCheckinTest::SetUp() { | |
| 699 testing::Test::SetUp(); | |
| 700 // Creating unique temp directory that will be used by GCMStore shared between | |
| 701 // GCM Client and G-services settings. | |
| 702 ASSERT_TRUE(CreateUniqueTempDir()); | |
| 703 InitializeLoop(); | |
| 704 // Time will be advancing one hour every time it is checked. | |
| 705 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval)); | |
| 706 InitializeGCMClient(); | |
| 707 } | |
| 708 | |
| 709 TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) { | |
| 710 std::map<std::string, std::string> settings; | |
| 711 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval); | |
| 712 settings["checkin_url"] = "http://alternative.url/checkin"; | |
| 713 settings["gcm_hostname"] = "alternative.gcm.host"; | |
| 714 settings["gcm_secure_port"] = "7777"; | |
| 715 settings["gcm_registration_url"] = "http://alternative.url/registration"; | |
| 716 CompleteCheckin(kDeviceAndroidId, | |
| 717 kDeviceSecurityToken, | |
| 718 GServicesSettings::CalculateDigest(settings), | |
| 719 settings); | |
| 720 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval), | |
| 721 gservices_settings().GetCheckinInterval()); | |
| 722 EXPECT_EQ(GURL("http://alternative.url/checkin"), | |
| 723 gservices_settings().GetCheckinURL()); | |
| 724 EXPECT_EQ(GURL("http://alternative.url/registration"), | |
| 725 gservices_settings().GetRegistrationURL()); | |
| 726 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"), | |
| 727 gservices_settings().GetMCSMainEndpoint()); | |
| 728 EXPECT_EQ(GURL("https://alternative.gcm.host:443"), | |
| 729 gservices_settings().GetMCSFallbackEndpoint()); | |
| 730 } | |
| 731 | |
| 732 // This test only checks that periodic checkin happens. | |
| 733 TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) { | |
| 734 std::map<std::string, std::string> settings; | |
| 735 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval); | |
| 736 settings["checkin_url"] = "http://alternative.url/checkin"; | |
| 737 settings["gcm_hostname"] = "alternative.gcm.host"; | |
| 738 settings["gcm_secure_port"] = "7777"; | |
| 739 settings["gcm_registration_url"] = "http://alternative.url/registration"; | |
| 740 CompleteCheckin(kDeviceAndroidId, | |
| 741 kDeviceSecurityToken, | |
| 742 GServicesSettings::CalculateDigest(settings), | |
| 743 settings); | |
| 744 EXPECT_EQ(2, clock()->call_count()); | |
| 745 | |
| 746 PumpLoopUntilIdle(); | |
| 747 CompleteCheckin(kDeviceAndroidId, | |
| 748 kDeviceSecurityToken, | |
| 749 GServicesSettings::CalculateDigest(settings), | |
| 750 settings); | |
| 751 } | |
| 752 | |
| 753 TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) { | |
| 754 std::map<std::string, std::string> settings; | |
| 755 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval); | |
| 756 settings["checkin_url"] = "http://alternative.url/checkin"; | |
| 757 settings["gcm_hostname"] = "alternative.gcm.host"; | |
| 758 settings["gcm_secure_port"] = "7777"; | |
| 759 settings["gcm_registration_url"] = "http://alternative.url/registration"; | |
| 760 CompleteCheckin(kDeviceAndroidId, | |
| 761 kDeviceSecurityToken, | |
| 762 GServicesSettings::CalculateDigest(settings), | |
| 763 settings); | |
| 764 | |
| 765 BuildGCMClient(base::TimeDelta()); | |
| 766 InitializeGCMClient(); | |
| 767 | |
| 768 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval), | |
| 769 gservices_settings().GetCheckinInterval()); | |
| 770 EXPECT_EQ(GURL("http://alternative.url/checkin"), | |
| 771 gservices_settings().GetCheckinURL()); | |
| 772 EXPECT_EQ(GURL("http://alternative.url/registration"), | |
| 773 gservices_settings().GetRegistrationURL()); | |
| 774 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"), | |
| 775 gservices_settings().GetMCSMainEndpoint()); | |
| 776 EXPECT_EQ(GURL("https://alternative.gcm.host:443"), | |
| 777 gservices_settings().GetMCSFallbackEndpoint()); | |
| 778 } | |
| 779 | |
| 780 } // namespace gcm | |
| OLD | NEW |