Allow RunShellCommand to work even with very large commands
[chromium-blink-merge.git] / components / gcm_driver / gcm_client_impl_unittest.cc
blob273c99f783317971ec598140fed1b09cb9702f1c
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.
5 #include "components/gcm_driver/gcm_client_impl.h"
7 #include "base/command_line.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/time/clock.h"
14 #include "base/timer/timer.h"
15 #include "google_apis/gcm/base/fake_encryptor.h"
16 #include "google_apis/gcm/base/mcs_message.h"
17 #include "google_apis/gcm/base/mcs_util.h"
18 #include "google_apis/gcm/engine/fake_connection_factory.h"
19 #include "google_apis/gcm/engine/fake_connection_handler.h"
20 #include "google_apis/gcm/engine/gservices_settings.h"
21 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
22 #include "google_apis/gcm/protocol/android_checkin.pb.h"
23 #include "google_apis/gcm/protocol/checkin.pb.h"
24 #include "google_apis/gcm/protocol/mcs.pb.h"
25 #include "net/url_request/test_url_fetcher_factory.h"
26 #include "net/url_request/url_fetcher_delegate.h"
27 #include "net/url_request/url_request_test_util.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 namespace gcm {
32 namespace {
34 enum LastEvent {
35 NONE,
36 LOADING_COMPLETED,
37 REGISTRATION_COMPLETED,
38 UNREGISTRATION_COMPLETED,
39 MESSAGE_SEND_ERROR,
40 MESSAGE_SEND_ACK,
41 MESSAGE_RECEIVED,
42 MESSAGES_DELETED,
45 const uint64 kDeviceAndroidId = 54321;
46 const uint64 kDeviceSecurityToken = 12345;
47 const int64 kSettingsCheckinInterval = 16 * 60 * 60;
48 const char kAppId[] = "app_id";
49 const char kSender[] = "project_id";
50 const char kSender2[] = "project_id2";
51 const char kSender3[] = "project_id3";
52 const char kRegistrationResponsePrefix[] = "token=";
53 const char kUnregistrationResponsePrefix[] = "deleted=";
55 // Helper for building arbitrary data messages.
56 MCSMessage BuildDownstreamMessage(
57 const std::string& project_id,
58 const std::string& app_id,
59 const std::map<std::string, std::string>& data) {
60 mcs_proto::DataMessageStanza data_message;
61 data_message.set_from(project_id);
62 data_message.set_category(app_id);
63 for (std::map<std::string, std::string>::const_iterator iter = data.begin();
64 iter != data.end();
65 ++iter) {
66 mcs_proto::AppData* app_data = data_message.add_app_data();
67 app_data->set_key(iter->first);
68 app_data->set_value(iter->second);
70 return MCSMessage(kDataMessageStanzaTag, data_message);
73 GCMClient::AccountTokenInfo MakeAccountToken(const std::string& email,
74 const std::string& token) {
75 GCMClient::AccountTokenInfo account_token;
76 account_token.email = email;
77 account_token.access_token = token;
78 return account_token;
81 std::map<std::string, std::string> MakeEmailToTokenMap(
82 const std::vector<GCMClient::AccountTokenInfo>& account_tokens) {
83 std::map<std::string, std::string> email_token_map;
84 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator iter =
85 account_tokens.begin(); iter != account_tokens.end(); ++iter) {
86 email_token_map[iter->email] = iter->access_token;
88 return email_token_map;
91 class FakeMCSClient : public MCSClient {
92 public:
93 FakeMCSClient(base::Clock* clock,
94 ConnectionFactory* connection_factory,
95 GCMStore* gcm_store,
96 GCMStatsRecorder* recorder);
97 ~FakeMCSClient() override;
98 void Login(uint64 android_id, uint64 security_token) override;
99 void SendMessage(const MCSMessage& message) override;
101 uint64 last_android_id() const { return last_android_id_; }
102 uint64 last_security_token() const { return last_security_token_; }
103 uint8 last_message_tag() const { return last_message_tag_; }
104 const mcs_proto::DataMessageStanza& last_data_message_stanza() const {
105 return last_data_message_stanza_;
108 private:
109 uint64 last_android_id_;
110 uint64 last_security_token_;
111 uint8 last_message_tag_;
112 mcs_proto::DataMessageStanza last_data_message_stanza_;
115 FakeMCSClient::FakeMCSClient(base::Clock* clock,
116 ConnectionFactory* connection_factory,
117 GCMStore* gcm_store,
118 GCMStatsRecorder* recorder)
119 : MCSClient("", clock, connection_factory, gcm_store, recorder),
120 last_android_id_(0u),
121 last_security_token_(0u),
122 last_message_tag_(kNumProtoTypes) {
125 FakeMCSClient::~FakeMCSClient() {
128 void FakeMCSClient::Login(uint64 android_id, uint64 security_token) {
129 last_android_id_ = android_id;
130 last_security_token_ = security_token;
133 void FakeMCSClient::SendMessage(const MCSMessage& message) {
134 last_message_tag_ = message.tag();
135 if (last_message_tag_ == kDataMessageStanzaTag) {
136 last_data_message_stanza_.CopyFrom(
137 reinterpret_cast<const mcs_proto::DataMessageStanza&>(
138 message.GetProtobuf()));
142 class AutoAdvancingTestClock : public base::Clock {
143 public:
144 explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta);
145 ~AutoAdvancingTestClock() override;
147 base::Time Now() override;
148 void Advance(TimeDelta delta);
149 int call_count() const { return call_count_; }
151 private:
152 int call_count_;
153 base::TimeDelta auto_increment_time_delta_;
154 base::Time now_;
156 DISALLOW_COPY_AND_ASSIGN(AutoAdvancingTestClock);
159 AutoAdvancingTestClock::AutoAdvancingTestClock(
160 base::TimeDelta auto_increment_time_delta)
161 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta) {
164 AutoAdvancingTestClock::~AutoAdvancingTestClock() {
167 base::Time AutoAdvancingTestClock::Now() {
168 call_count_++;
169 now_ += auto_increment_time_delta_;
170 return now_;
173 void AutoAdvancingTestClock::Advance(base::TimeDelta delta) {
174 now_ += delta;
177 class FakeGCMInternalsBuilder : public GCMInternalsBuilder {
178 public:
179 FakeGCMInternalsBuilder(base::TimeDelta clock_step);
180 ~FakeGCMInternalsBuilder() override;
182 scoped_ptr<base::Clock> BuildClock() override;
183 scoped_ptr<MCSClient> BuildMCSClient(const std::string& version,
184 base::Clock* clock,
185 ConnectionFactory* connection_factory,
186 GCMStore* gcm_store,
187 GCMStatsRecorder* recorder) override;
188 scoped_ptr<ConnectionFactory> BuildConnectionFactory(
189 const std::vector<GURL>& endpoints,
190 const net::BackoffEntry::Policy& backoff_policy,
191 const scoped_refptr<net::HttpNetworkSession>& gcm_network_session,
192 const scoped_refptr<net::HttpNetworkSession>& http_network_session,
193 net::NetLog* net_log,
194 GCMStatsRecorder* recorder) override;
196 private:
197 base::TimeDelta clock_step_;
200 FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step)
201 : clock_step_(clock_step) {
204 FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}
206 scoped_ptr<base::Clock> FakeGCMInternalsBuilder::BuildClock() {
207 return make_scoped_ptr<base::Clock>(new AutoAdvancingTestClock(clock_step_));
210 scoped_ptr<MCSClient> FakeGCMInternalsBuilder::BuildMCSClient(
211 const std::string& version,
212 base::Clock* clock,
213 ConnectionFactory* connection_factory,
214 GCMStore* gcm_store,
215 GCMStatsRecorder* recorder) {
216 return make_scoped_ptr<MCSClient>(new FakeMCSClient(clock,
217 connection_factory,
218 gcm_store,
219 recorder));
222 scoped_ptr<ConnectionFactory> FakeGCMInternalsBuilder::BuildConnectionFactory(
223 const std::vector<GURL>& endpoints,
224 const net::BackoffEntry::Policy& backoff_policy,
225 const scoped_refptr<net::HttpNetworkSession>& gcm_network_session,
226 const scoped_refptr<net::HttpNetworkSession>& http_network_session,
227 net::NetLog* net_log,
228 GCMStatsRecorder* recorder) {
229 return make_scoped_ptr<ConnectionFactory>(new FakeConnectionFactory());
232 } // namespace
234 class GCMClientImplTest : public testing::Test,
235 public GCMClient::Delegate {
236 public:
237 GCMClientImplTest();
238 ~GCMClientImplTest() override;
240 void SetUp() override;
242 void SetUpUrlFetcherFactory();
244 void BuildGCMClient(base::TimeDelta clock_step);
245 void InitializeGCMClient();
246 void StartGCMClient();
247 void ReceiveMessageFromMCS(const MCSMessage& message);
248 void ReceiveOnMessageSentToMCS(
249 const std::string& app_id,
250 const std::string& message_id,
251 const MCSClient::MessageSendStatus status);
252 void CompleteCheckin(uint64 android_id,
253 uint64 security_token,
254 const std::string& digest,
255 const std::map<std::string, std::string>& settings);
256 void CompleteRegistration(const std::string& registration_id);
257 void CompleteUnregistration(const std::string& app_id);
258 void VerifyPendingRequestFetcherDeleted();
260 bool ExistsRegistration(const std::string& app_id) const;
261 void AddRegistration(const std::string& app_id,
262 const std::vector<std::string>& sender_ids,
263 const std::string& registration_id);
265 // GCMClient::Delegate overrides (for verification).
266 void OnRegisterFinished(const std::string& app_id,
267 const std::string& registration_id,
268 GCMClient::Result result) override;
269 void OnUnregisterFinished(const std::string& app_id,
270 GCMClient::Result result) override;
271 void OnSendFinished(const std::string& app_id,
272 const std::string& message_id,
273 GCMClient::Result result) override {}
274 void OnMessageReceived(const std::string& registration_id,
275 const GCMClient::IncomingMessage& message) override;
276 void OnMessagesDeleted(const std::string& app_id) override;
277 void OnMessageSendError(
278 const std::string& app_id,
279 const gcm::GCMClient::SendErrorDetails& send_error_details) override;
280 void OnSendAcknowledged(const std::string& app_id,
281 const std::string& message_id) override;
282 void OnGCMReady(const std::vector<AccountMapping>& account_mappings,
283 const base::Time& last_token_fetch_time) override;
284 void OnActivityRecorded() override {}
285 void OnConnected(const net::IPEndPoint& ip_endpoint) override {}
286 void OnDisconnected() override {}
288 GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
289 FakeMCSClient* mcs_client() const {
290 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
292 ConnectionFactory* connection_factory() const {
293 return gcm_client_->connection_factory_.get();
296 const GCMClientImpl::CheckinInfo& device_checkin_info() const {
297 return gcm_client_->device_checkin_info_;
300 void reset_last_event() {
301 last_event_ = NONE;
302 last_app_id_.clear();
303 last_registration_id_.clear();
304 last_message_id_.clear();
305 last_result_ = GCMClient::UNKNOWN_ERROR;
306 last_account_mappings_.clear();
307 last_token_fetch_time_ = base::Time();
310 LastEvent last_event() const { return last_event_; }
311 const std::string& last_app_id() const { return last_app_id_; }
312 const std::string& last_registration_id() const {
313 return last_registration_id_;
315 const std::string& last_message_id() const { return last_message_id_; }
316 GCMClient::Result last_result() const { return last_result_; }
317 const GCMClient::IncomingMessage& last_message() const {
318 return last_message_;
320 const GCMClient::SendErrorDetails& last_error_details() const {
321 return last_error_details_;
323 const base::Time& last_token_fetch_time() const {
324 return last_token_fetch_time_;
326 const std::vector<AccountMapping>& last_account_mappings() {
327 return last_account_mappings_;
330 const GServicesSettings& gservices_settings() const {
331 return gcm_client_->gservices_settings_;
334 int64 CurrentTime();
336 // Tooling.
337 void PumpLoop();
338 void PumpLoopUntilIdle();
339 void QuitLoop();
340 void InitializeLoop();
341 bool CreateUniqueTempDir();
342 AutoAdvancingTestClock* clock() const {
343 return reinterpret_cast<AutoAdvancingTestClock*>(gcm_client_->clock_.get());
346 private:
347 // Variables used for verification.
348 LastEvent last_event_;
349 std::string last_app_id_;
350 std::string last_registration_id_;
351 std::string last_message_id_;
352 GCMClient::Result last_result_;
353 GCMClient::IncomingMessage last_message_;
354 GCMClient::SendErrorDetails last_error_details_;
355 base::Time last_token_fetch_time_;
356 std::vector<AccountMapping> last_account_mappings_;
358 scoped_ptr<GCMClientImpl> gcm_client_;
360 base::MessageLoop message_loop_;
361 scoped_ptr<base::RunLoop> run_loop_;
362 net::TestURLFetcherFactory url_fetcher_factory_;
364 // Injected to GCM client:
365 base::ScopedTempDir temp_directory_;
366 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
369 GCMClientImplTest::GCMClientImplTest()
370 : last_event_(NONE),
371 last_result_(GCMClient::UNKNOWN_ERROR),
372 url_request_context_getter_(new net::TestURLRequestContextGetter(
373 message_loop_.message_loop_proxy())) {
376 GCMClientImplTest::~GCMClientImplTest() {}
378 void GCMClientImplTest::SetUp() {
379 testing::Test::SetUp();
380 ASSERT_TRUE(CreateUniqueTempDir());
381 InitializeLoop();
382 BuildGCMClient(base::TimeDelta());
383 InitializeGCMClient();
384 StartGCMClient();
385 SetUpUrlFetcherFactory();
386 CompleteCheckin(kDeviceAndroidId,
387 kDeviceSecurityToken,
388 std::string(),
389 std::map<std::string, std::string>());
392 void GCMClientImplTest::SetUpUrlFetcherFactory() {
393 url_fetcher_factory_.set_remove_fetcher_on_delete(true);
396 void GCMClientImplTest::PumpLoop() {
397 run_loop_->Run();
398 run_loop_.reset(new base::RunLoop());
401 void GCMClientImplTest::PumpLoopUntilIdle() {
402 run_loop_->RunUntilIdle();
403 run_loop_.reset(new base::RunLoop());
406 void GCMClientImplTest::QuitLoop() {
407 if (run_loop_ && run_loop_->running())
408 run_loop_->Quit();
411 void GCMClientImplTest::InitializeLoop() {
412 run_loop_.reset(new base::RunLoop);
415 bool GCMClientImplTest::CreateUniqueTempDir() {
416 return temp_directory_.CreateUniqueTempDir();
419 void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step) {
420 gcm_client_.reset(new GCMClientImpl(make_scoped_ptr<GCMInternalsBuilder>(
421 new FakeGCMInternalsBuilder(clock_step))));
424 void GCMClientImplTest::CompleteCheckin(
425 uint64 android_id,
426 uint64 security_token,
427 const std::string& digest,
428 const std::map<std::string, std::string>& settings) {
429 checkin_proto::AndroidCheckinResponse response;
430 response.set_stats_ok(true);
431 response.set_android_id(android_id);
432 response.set_security_token(security_token);
434 // For testing G-services settings.
435 if (!digest.empty()) {
436 response.set_digest(digest);
437 for (std::map<std::string, std::string>::const_iterator it =
438 settings.begin();
439 it != settings.end();
440 ++it) {
441 checkin_proto::GservicesSetting* setting = response.add_setting();
442 setting->set_name(it->first);
443 setting->set_value(it->second);
445 response.set_settings_diff(false);
448 std::string response_string;
449 response.SerializeToString(&response_string);
451 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
452 ASSERT_TRUE(fetcher);
453 fetcher->set_response_code(net::HTTP_OK);
454 fetcher->SetResponseString(response_string);
455 fetcher->delegate()->OnURLFetchComplete(fetcher);
458 void GCMClientImplTest::CompleteRegistration(
459 const std::string& registration_id) {
460 std::string response(kRegistrationResponsePrefix);
461 response.append(registration_id);
462 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
463 ASSERT_TRUE(fetcher);
464 fetcher->set_response_code(net::HTTP_OK);
465 fetcher->SetResponseString(response);
466 fetcher->delegate()->OnURLFetchComplete(fetcher);
469 void GCMClientImplTest::CompleteUnregistration(
470 const std::string& app_id) {
471 std::string response(kUnregistrationResponsePrefix);
472 response.append(app_id);
473 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
474 ASSERT_TRUE(fetcher);
475 fetcher->set_response_code(net::HTTP_OK);
476 fetcher->SetResponseString(response);
477 fetcher->delegate()->OnURLFetchComplete(fetcher);
480 void GCMClientImplTest::VerifyPendingRequestFetcherDeleted() {
481 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
482 EXPECT_FALSE(fetcher);
485 bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const {
486 return gcm_client_->registrations_.count(app_id) > 0;
489 void GCMClientImplTest::AddRegistration(
490 const std::string& app_id,
491 const std::vector<std::string>& sender_ids,
492 const std::string& registration_id) {
493 linked_ptr<RegistrationInfo> registration(new RegistrationInfo);
494 registration->sender_ids = sender_ids;
495 registration->registration_id = registration_id;
496 gcm_client_->registrations_[app_id] = registration;
499 void GCMClientImplTest::InitializeGCMClient() {
500 clock()->Advance(base::TimeDelta::FromMilliseconds(1));
502 // Actual initialization.
503 GCMClient::ChromeBuildInfo chrome_build_info;
504 gcm_client_->Initialize(chrome_build_info,
505 temp_directory_.path(),
506 message_loop_.message_loop_proxy(),
507 url_request_context_getter_,
508 make_scoped_ptr<Encryptor>(new FakeEncryptor),
509 this);
512 void GCMClientImplTest::StartGCMClient() {
513 // Start loading and check-in.
514 gcm_client_->Start();
516 PumpLoopUntilIdle();
519 void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) {
520 gcm_client_->recorder_.RecordConnectionInitiated(std::string());
521 gcm_client_->recorder_.RecordConnectionSuccess();
522 gcm_client_->OnMessageReceivedFromMCS(message);
525 void GCMClientImplTest::ReceiveOnMessageSentToMCS(
526 const std::string& app_id,
527 const std::string& message_id,
528 const MCSClient::MessageSendStatus status) {
529 gcm_client_->OnMessageSentToMCS(0LL, app_id, message_id, status);
532 void GCMClientImplTest::OnGCMReady(
533 const std::vector<AccountMapping>& account_mappings,
534 const base::Time& last_token_fetch_time) {
535 last_event_ = LOADING_COMPLETED;
536 last_account_mappings_ = account_mappings;
537 last_token_fetch_time_ = last_token_fetch_time;
538 QuitLoop();
541 void GCMClientImplTest::OnMessageReceived(
542 const std::string& registration_id,
543 const GCMClient::IncomingMessage& message) {
544 last_event_ = MESSAGE_RECEIVED;
545 last_app_id_ = registration_id;
546 last_message_ = message;
547 QuitLoop();
550 void GCMClientImplTest::OnRegisterFinished(const std::string& app_id,
551 const std::string& registration_id,
552 GCMClient::Result result) {
553 last_event_ = REGISTRATION_COMPLETED;
554 last_app_id_ = app_id;
555 last_registration_id_ = registration_id;
556 last_result_ = result;
559 void GCMClientImplTest::OnUnregisterFinished(const std::string& app_id,
560 GCMClient::Result result) {
561 last_event_ = UNREGISTRATION_COMPLETED;
562 last_app_id_ = app_id;
563 last_result_ = result;
566 void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) {
567 last_event_ = MESSAGES_DELETED;
568 last_app_id_ = app_id;
571 void GCMClientImplTest::OnMessageSendError(
572 const std::string& app_id,
573 const gcm::GCMClient::SendErrorDetails& send_error_details) {
574 last_event_ = MESSAGE_SEND_ERROR;
575 last_app_id_ = app_id;
576 last_error_details_ = send_error_details;
579 void GCMClientImplTest::OnSendAcknowledged(const std::string& app_id,
580 const std::string& message_id) {
581 last_event_ = MESSAGE_SEND_ACK;
582 last_app_id_ = app_id;
583 last_message_id_ = message_id;
586 int64 GCMClientImplTest::CurrentTime() {
587 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond;
590 TEST_F(GCMClientImplTest, LoadingCompleted) {
591 EXPECT_EQ(LOADING_COMPLETED, last_event());
592 EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id());
593 EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token());
595 // Checking freshly loaded CheckinInfo.
596 EXPECT_EQ(kDeviceAndroidId, device_checkin_info().android_id);
597 EXPECT_EQ(kDeviceSecurityToken, device_checkin_info().secret);
598 EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
599 EXPECT_TRUE(device_checkin_info().accounts_set);
600 EXPECT_TRUE(device_checkin_info().account_tokens.empty());
603 TEST_F(GCMClientImplTest, CheckOut) {
604 EXPECT_TRUE(mcs_client());
605 EXPECT_TRUE(connection_factory());
606 gcm_client()->CheckOut();
607 EXPECT_FALSE(mcs_client());
608 EXPECT_FALSE(connection_factory());
611 TEST_F(GCMClientImplTest, RegisterApp) {
612 EXPECT_FALSE(ExistsRegistration(kAppId));
614 std::vector<std::string> senders;
615 senders.push_back("sender");
616 gcm_client()->Register(kAppId, senders);
617 CompleteRegistration("reg_id");
619 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
620 EXPECT_EQ(kAppId, last_app_id());
621 EXPECT_EQ("reg_id", last_registration_id());
622 EXPECT_EQ(GCMClient::SUCCESS, last_result());
623 EXPECT_TRUE(ExistsRegistration(kAppId));
626 TEST_F(GCMClientImplTest, DISABLED_RegisterAppFromCache) {
627 EXPECT_FALSE(ExistsRegistration(kAppId));
629 std::vector<std::string> senders;
630 senders.push_back("sender");
631 gcm_client()->Register(kAppId, senders);
632 CompleteRegistration("reg_id");
633 EXPECT_TRUE(ExistsRegistration(kAppId));
635 EXPECT_EQ(kAppId, last_app_id());
636 EXPECT_EQ("reg_id", last_registration_id());
637 EXPECT_EQ(GCMClient::SUCCESS, last_result());
638 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
640 // Recreate GCMClient in order to load from the persistent store.
641 BuildGCMClient(base::TimeDelta());
642 InitializeGCMClient();
643 StartGCMClient();
645 EXPECT_TRUE(ExistsRegistration(kAppId));
648 TEST_F(GCMClientImplTest, UnregisterApp) {
649 EXPECT_FALSE(ExistsRegistration(kAppId));
651 std::vector<std::string> senders;
652 senders.push_back("sender");
653 gcm_client()->Register(kAppId, senders);
654 CompleteRegistration("reg_id");
655 EXPECT_TRUE(ExistsRegistration(kAppId));
657 gcm_client()->Unregister(kAppId);
658 CompleteUnregistration(kAppId);
660 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
661 EXPECT_EQ(kAppId, last_app_id());
662 EXPECT_EQ(GCMClient::SUCCESS, last_result());
663 EXPECT_FALSE(ExistsRegistration(kAppId));
666 // Tests that stopping the GCMClient also deletes pending registration requests.
667 // This is tested by checking that url fetcher contained in the request was
668 // deleted.
669 TEST_F(GCMClientImplTest, DeletePendingRequestsWhenStopping) {
670 std::vector<std::string> senders;
671 senders.push_back("sender");
672 gcm_client()->Register(kAppId, senders);
674 gcm_client()->Stop();
675 VerifyPendingRequestFetcherDeleted();
678 TEST_F(GCMClientImplTest, DispatchDownstreamMessage) {
679 // Register to receive messages from kSender and kSender2 only.
680 std::vector<std::string> senders;
681 senders.push_back(kSender);
682 senders.push_back(kSender2);
683 AddRegistration(kAppId, senders, "reg_id");
685 std::map<std::string, std::string> expected_data;
686 expected_data["message_type"] = "gcm";
687 expected_data["key"] = "value";
688 expected_data["key2"] = "value2";
690 // Message for kSender will be received.
691 MCSMessage message(BuildDownstreamMessage(kSender, kAppId, expected_data));
692 EXPECT_TRUE(message.IsValid());
693 ReceiveMessageFromMCS(message);
695 expected_data.erase(expected_data.find("message_type"));
696 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
697 EXPECT_EQ(kAppId, last_app_id());
698 EXPECT_EQ(expected_data.size(), last_message().data.size());
699 EXPECT_EQ(expected_data, last_message().data);
700 EXPECT_EQ(kSender, last_message().sender_id);
702 reset_last_event();
704 // Message for kSender2 will be received.
705 MCSMessage message2(BuildDownstreamMessage(kSender2, kAppId, expected_data));
706 EXPECT_TRUE(message2.IsValid());
707 ReceiveMessageFromMCS(message2);
709 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
710 EXPECT_EQ(kAppId, last_app_id());
711 EXPECT_EQ(expected_data.size(), last_message().data.size());
712 EXPECT_EQ(expected_data, last_message().data);
713 EXPECT_EQ(kSender2, last_message().sender_id);
715 reset_last_event();
717 // Message from kSender3 will be dropped.
718 MCSMessage message3(BuildDownstreamMessage(kSender3, kAppId, expected_data));
719 EXPECT_TRUE(message3.IsValid());
720 ReceiveMessageFromMCS(message3);
722 EXPECT_NE(MESSAGE_RECEIVED, last_event());
723 EXPECT_NE(kAppId, last_app_id());
726 TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) {
727 std::map<std::string, std::string> expected_data;
728 expected_data["message_type"] = "send_error";
729 expected_data["google.message_id"] = "007";
730 expected_data["error_details"] = "some details";
731 MCSMessage message(BuildDownstreamMessage(
732 kSender, kAppId, expected_data));
733 EXPECT_TRUE(message.IsValid());
734 ReceiveMessageFromMCS(message);
736 EXPECT_EQ(MESSAGE_SEND_ERROR, last_event());
737 EXPECT_EQ(kAppId, last_app_id());
738 EXPECT_EQ("007", last_error_details().message_id);
739 EXPECT_EQ(1UL, last_error_details().additional_data.size());
740 GCMClient::MessageData::const_iterator iter =
741 last_error_details().additional_data.find("error_details");
742 EXPECT_TRUE(iter != last_error_details().additional_data.end());
743 EXPECT_EQ("some details", iter->second);
746 TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) {
747 std::map<std::string, std::string> expected_data;
748 expected_data["message_type"] = "deleted_messages";
749 MCSMessage message(BuildDownstreamMessage(
750 kSender, kAppId, expected_data));
751 EXPECT_TRUE(message.IsValid());
752 ReceiveMessageFromMCS(message);
754 EXPECT_EQ(MESSAGES_DELETED, last_event());
755 EXPECT_EQ(kAppId, last_app_id());
758 TEST_F(GCMClientImplTest, SendMessage) {
759 GCMClient::OutgoingMessage message;
760 message.id = "007";
761 message.time_to_live = 500;
762 message.data["key"] = "value";
763 gcm_client()->Send(kAppId, kSender, message);
765 EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag());
766 EXPECT_EQ(kAppId, mcs_client()->last_data_message_stanza().category());
767 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
768 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
769 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
770 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
771 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
772 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
773 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
774 EXPECT_EQ("value",
775 mcs_client()->last_data_message_stanza().app_data(0).value());
778 TEST_F(GCMClientImplTest, SendMessageAcknowledged) {
779 ReceiveOnMessageSentToMCS(kAppId, "007", MCSClient::SENT);
780 EXPECT_EQ(MESSAGE_SEND_ACK, last_event());
781 EXPECT_EQ(kAppId, last_app_id());
782 EXPECT_EQ("007", last_message_id());
785 class GCMClientImplCheckinTest : public GCMClientImplTest {
786 public:
787 GCMClientImplCheckinTest();
788 ~GCMClientImplCheckinTest() override;
790 void SetUp() override;
793 GCMClientImplCheckinTest::GCMClientImplCheckinTest() {
796 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {
799 void GCMClientImplCheckinTest::SetUp() {
800 testing::Test::SetUp();
801 // Creating unique temp directory that will be used by GCMStore shared between
802 // GCM Client and G-services settings.
803 ASSERT_TRUE(CreateUniqueTempDir());
804 InitializeLoop();
805 // Time will be advancing one hour every time it is checked.
806 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval));
807 InitializeGCMClient();
808 StartGCMClient();
811 TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) {
812 std::map<std::string, std::string> settings;
813 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
814 settings["checkin_url"] = "http://alternative.url/checkin";
815 settings["gcm_hostname"] = "alternative.gcm.host";
816 settings["gcm_secure_port"] = "7777";
817 settings["gcm_registration_url"] = "http://alternative.url/registration";
818 CompleteCheckin(kDeviceAndroidId,
819 kDeviceSecurityToken,
820 GServicesSettings::CalculateDigest(settings),
821 settings);
822 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
823 gservices_settings().GetCheckinInterval());
824 EXPECT_EQ(GURL("http://alternative.url/checkin"),
825 gservices_settings().GetCheckinURL());
826 EXPECT_EQ(GURL("http://alternative.url/registration"),
827 gservices_settings().GetRegistrationURL());
828 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
829 gservices_settings().GetMCSMainEndpoint());
830 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
831 gservices_settings().GetMCSFallbackEndpoint());
834 // This test only checks that periodic checkin happens.
835 TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) {
836 std::map<std::string, std::string> settings;
837 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
838 settings["checkin_url"] = "http://alternative.url/checkin";
839 settings["gcm_hostname"] = "alternative.gcm.host";
840 settings["gcm_secure_port"] = "7777";
841 settings["gcm_registration_url"] = "http://alternative.url/registration";
842 CompleteCheckin(kDeviceAndroidId,
843 kDeviceSecurityToken,
844 GServicesSettings::CalculateDigest(settings),
845 settings);
847 EXPECT_EQ(2, clock()->call_count());
849 PumpLoopUntilIdle();
850 CompleteCheckin(kDeviceAndroidId,
851 kDeviceSecurityToken,
852 GServicesSettings::CalculateDigest(settings),
853 settings);
856 TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) {
857 std::map<std::string, std::string> settings;
858 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
859 settings["checkin_url"] = "http://alternative.url/checkin";
860 settings["gcm_hostname"] = "alternative.gcm.host";
861 settings["gcm_secure_port"] = "7777";
862 settings["gcm_registration_url"] = "http://alternative.url/registration";
863 CompleteCheckin(kDeviceAndroidId,
864 kDeviceSecurityToken,
865 GServicesSettings::CalculateDigest(settings),
866 settings);
868 BuildGCMClient(base::TimeDelta());
869 InitializeGCMClient();
870 StartGCMClient();
872 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
873 gservices_settings().GetCheckinInterval());
874 EXPECT_EQ(GURL("http://alternative.url/checkin"),
875 gservices_settings().GetCheckinURL());
876 EXPECT_EQ(GURL("http://alternative.url/registration"),
877 gservices_settings().GetRegistrationURL());
878 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
879 gservices_settings().GetMCSMainEndpoint());
880 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
881 gservices_settings().GetMCSFallbackEndpoint());
884 // This test only checks that periodic checkin happens.
885 TEST_F(GCMClientImplCheckinTest, CheckinWithAccounts) {
886 std::map<std::string, std::string> settings;
887 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
888 settings["checkin_url"] = "http://alternative.url/checkin";
889 settings["gcm_hostname"] = "alternative.gcm.host";
890 settings["gcm_secure_port"] = "7777";
891 settings["gcm_registration_url"] = "http://alternative.url/registration";
892 CompleteCheckin(kDeviceAndroidId,
893 kDeviceSecurityToken,
894 GServicesSettings::CalculateDigest(settings),
895 settings);
897 std::vector<GCMClient::AccountTokenInfo> account_tokens;
898 account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
899 account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
900 gcm_client()->SetAccountTokens(account_tokens);
902 EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
903 EXPECT_TRUE(device_checkin_info().accounts_set);
904 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
905 device_checkin_info().account_tokens);
907 PumpLoopUntilIdle();
908 CompleteCheckin(kDeviceAndroidId,
909 kDeviceSecurityToken,
910 GServicesSettings::CalculateDigest(settings),
911 settings);
913 std::set<std::string> accounts;
914 accounts.insert("test_user1@gmail.com");
915 accounts.insert("test_user2@gmail.com");
916 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
917 EXPECT_TRUE(device_checkin_info().accounts_set);
918 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
919 device_checkin_info().account_tokens);
922 // This test only checks that periodic checkin happens.
923 TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountRemoved) {
924 std::map<std::string, std::string> settings;
925 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
926 settings["checkin_url"] = "http://alternative.url/checkin";
927 settings["gcm_hostname"] = "alternative.gcm.host";
928 settings["gcm_secure_port"] = "7777";
929 settings["gcm_registration_url"] = "http://alternative.url/registration";
930 CompleteCheckin(kDeviceAndroidId,
931 kDeviceSecurityToken,
932 GServicesSettings::CalculateDigest(settings),
933 settings);
935 std::vector<GCMClient::AccountTokenInfo> account_tokens;
936 account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
937 account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
938 gcm_client()->SetAccountTokens(account_tokens);
939 PumpLoopUntilIdle();
940 CompleteCheckin(kDeviceAndroidId,
941 kDeviceSecurityToken,
942 GServicesSettings::CalculateDigest(settings),
943 settings);
945 EXPECT_EQ(2UL, device_checkin_info().last_checkin_accounts.size());
946 EXPECT_TRUE(device_checkin_info().accounts_set);
947 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
948 device_checkin_info().account_tokens);
950 account_tokens.erase(account_tokens.begin() + 1);
951 gcm_client()->SetAccountTokens(account_tokens);
953 PumpLoopUntilIdle();
954 CompleteCheckin(kDeviceAndroidId,
955 kDeviceSecurityToken,
956 GServicesSettings::CalculateDigest(settings),
957 settings);
959 std::set<std::string> accounts;
960 accounts.insert("test_user1@gmail.com");
961 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
962 EXPECT_TRUE(device_checkin_info().accounts_set);
963 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
964 device_checkin_info().account_tokens);
967 // This test only checks that periodic checkin happens.
968 TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountReplaced) {
969 std::map<std::string, std::string> settings;
970 settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
971 settings["checkin_url"] = "http://alternative.url/checkin";
972 settings["gcm_hostname"] = "alternative.gcm.host";
973 settings["gcm_secure_port"] = "7777";
974 settings["gcm_registration_url"] = "http://alternative.url/registration";
975 CompleteCheckin(kDeviceAndroidId,
976 kDeviceSecurityToken,
977 GServicesSettings::CalculateDigest(settings),
978 settings);
980 std::vector<GCMClient::AccountTokenInfo> account_tokens;
981 account_tokens.push_back(MakeAccountToken("test_user1@gmail.com", "token1"));
982 gcm_client()->SetAccountTokens(account_tokens);
984 PumpLoopUntilIdle();
985 CompleteCheckin(kDeviceAndroidId,
986 kDeviceSecurityToken,
987 GServicesSettings::CalculateDigest(settings),
988 settings);
990 std::set<std::string> accounts;
991 accounts.insert("test_user1@gmail.com");
992 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
994 // This should trigger another checkin, because the list of accounts is
995 // different.
996 account_tokens.clear();
997 account_tokens.push_back(MakeAccountToken("test_user2@gmail.com", "token2"));
998 gcm_client()->SetAccountTokens(account_tokens);
1000 PumpLoopUntilIdle();
1001 CompleteCheckin(kDeviceAndroidId,
1002 kDeviceSecurityToken,
1003 GServicesSettings::CalculateDigest(settings),
1004 settings);
1006 accounts.clear();
1007 accounts.insert("test_user2@gmail.com");
1008 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
1009 EXPECT_TRUE(device_checkin_info().accounts_set);
1010 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1011 device_checkin_info().account_tokens);
1014 class GCMClientImplStartAndStopTest : public GCMClientImplTest {
1015 public:
1016 GCMClientImplStartAndStopTest();
1017 ~GCMClientImplStartAndStopTest() override;
1019 void SetUp() override;
1021 void DefaultCompleteCheckin();
1024 GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() {
1027 GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() {
1030 void GCMClientImplStartAndStopTest::SetUp() {
1031 testing::Test::SetUp();
1032 ASSERT_TRUE(CreateUniqueTempDir());
1033 InitializeLoop();
1034 BuildGCMClient(base::TimeDelta());
1035 InitializeGCMClient();
1038 void GCMClientImplStartAndStopTest::DefaultCompleteCheckin() {
1039 SetUpUrlFetcherFactory();
1040 CompleteCheckin(kDeviceAndroidId,
1041 kDeviceSecurityToken,
1042 std::string(),
1043 std::map<std::string, std::string>());
1044 PumpLoopUntilIdle();
1047 TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestart) {
1048 // Start the GCM and wait until it is ready.
1049 gcm_client()->Start();
1050 PumpLoopUntilIdle();
1052 // Stop the GCM.
1053 gcm_client()->Stop();
1054 PumpLoopUntilIdle();
1056 // Restart the GCM.
1057 gcm_client()->Start();
1058 PumpLoopUntilIdle();
1061 TEST_F(GCMClientImplStartAndStopTest, StartAndStopImmediately) {
1062 // Start the GCM and then stop it immediately.
1063 gcm_client()->Start();
1064 gcm_client()->Stop();
1066 PumpLoopUntilIdle();
1069 TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestartImmediately) {
1070 // Start the GCM and then stop and restart it immediately.
1071 gcm_client()->Start();
1072 gcm_client()->Stop();
1073 gcm_client()->Start();
1075 PumpLoopUntilIdle();
1078 // Test for known account mappings and last token fetching time being passed
1079 // to OnGCMReady.
1080 TEST_F(GCMClientImplStartAndStopTest, OnGCMReadyAccountsAndTokenFetchingTime) {
1081 // Start the GCM and wait until it is ready.
1082 gcm_client()->Start();
1083 PumpLoopUntilIdle();
1084 DefaultCompleteCheckin();
1086 base::Time expected_time = base::Time::Now();
1087 gcm_client()->SetLastTokenFetchTime(expected_time);
1088 AccountMapping expected_mapping;
1089 expected_mapping.account_id = "accId";
1090 expected_mapping.email = "email@gmail.com";
1091 expected_mapping.status = AccountMapping::MAPPED;
1092 expected_mapping.status_change_timestamp = expected_time;
1093 gcm_client()->UpdateAccountMapping(expected_mapping);
1094 PumpLoopUntilIdle();
1096 // Stop the GCM.
1097 gcm_client()->Stop();
1098 PumpLoopUntilIdle();
1100 // Restart the GCM.
1101 gcm_client()->Start();
1102 PumpLoopUntilIdle();
1104 EXPECT_EQ(LOADING_COMPLETED, last_event());
1105 EXPECT_EQ(expected_time, last_token_fetch_time());
1106 ASSERT_EQ(1UL, last_account_mappings().size());
1107 const AccountMapping& actual_mapping = last_account_mappings()[0];
1108 EXPECT_EQ(expected_mapping.account_id, actual_mapping.account_id);
1109 EXPECT_EQ(expected_mapping.email, actual_mapping.email);
1110 EXPECT_EQ(expected_mapping.status, actual_mapping.status);
1111 EXPECT_EQ(expected_mapping.status_change_timestamp,
1112 actual_mapping.status_change_timestamp);
1115 } // namespace gcm