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/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"
35 REGISTRATION_COMPLETED
,
36 UNREGISTRATION_COMPLETED
,
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=";
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();
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
);
67 return MCSMessage(kDataMessageStanzaTag
, data_message
);
70 class FakeMCSClient
: public MCSClient
{
72 FakeMCSClient(base::Clock
* clock
,
73 ConnectionFactory
* connection_factory
,
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
;
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_
;
88 uint64 last_android_id_
;
89 uint64 last_security_token_
;
90 uint8 last_message_tag_
;
91 mcs_proto::DataMessageStanza last_data_message_stanza_
;
94 FakeMCSClient::FakeMCSClient(base::Clock
* clock
,
95 ConnectionFactory
* connection_factory
,
97 GCMStatsRecorder
* recorder
)
98 : MCSClient("", clock
, connection_factory
, gcm_store
, recorder
),
100 last_security_token_(0u),
101 last_message_tag_(kNumProtoTypes
) {
104 FakeMCSClient::~FakeMCSClient() {
107 void FakeMCSClient::Login(uint64 android_id
, uint64 security_token
) {
108 last_android_id_
= android_id
;
109 last_security_token_
= security_token
;
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()));
121 class AutoAdvancingTestClock
: public base::Clock
{
123 explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta
);
124 virtual ~AutoAdvancingTestClock();
126 virtual base::Time
Now() OVERRIDE
;
127 void Advance(TimeDelta delta
);
128 int call_count() const { return call_count_
; }
132 base::TimeDelta auto_increment_time_delta_
;
135 DISALLOW_COPY_AND_ASSIGN(AutoAdvancingTestClock
);
138 AutoAdvancingTestClock::AutoAdvancingTestClock(
139 base::TimeDelta auto_increment_time_delta
)
140 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta
) {
143 AutoAdvancingTestClock::~AutoAdvancingTestClock() {
146 base::Time
AutoAdvancingTestClock::Now() {
148 now_
+= auto_increment_time_delta_
;
152 void AutoAdvancingTestClock::Advance(base::TimeDelta delta
) {
156 class FakeGCMInternalsBuilder
: public GCMInternalsBuilder
{
158 FakeGCMInternalsBuilder(base::TimeDelta clock_step
);
159 virtual ~FakeGCMInternalsBuilder();
161 virtual scoped_ptr
<base::Clock
> BuildClock() OVERRIDE
;
162 virtual scoped_ptr
<MCSClient
> BuildMCSClient(
163 const std::string
& version
,
165 ConnectionFactory
* connection_factory
,
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
;
176 base::TimeDelta clock_step_
;
179 FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step
)
180 : clock_step_(clock_step
) {
183 FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}
185 scoped_ptr
<base::Clock
> FakeGCMInternalsBuilder::BuildClock() {
186 return make_scoped_ptr
<base::Clock
>(new AutoAdvancingTestClock(clock_step_
));
189 scoped_ptr
<MCSClient
> FakeGCMInternalsBuilder::BuildMCSClient(
190 const std::string
& version
,
192 ConnectionFactory
* connection_factory
,
194 GCMStatsRecorder
* recorder
) {
195 return make_scoped_ptr
<MCSClient
>(new FakeMCSClient(clock
,
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());
212 class GCMClientImplTest
: public testing::Test
,
213 public GCMClient::Delegate
{
216 virtual ~GCMClientImplTest();
218 virtual void SetUp() OVERRIDE
;
220 void BuildGCMClient(base::TimeDelta clock_step
);
221 void InitializeGCMClient();
222 void StartGCMClient();
223 void ReceiveMessageFromMCS(const MCSMessage
& message
);
224 void CompleteCheckin(uint64 android_id
,
225 uint64 security_token
,
226 const std::string
& digest
,
227 const std::map
<std::string
, std::string
>& settings
);
228 void CompleteRegistration(const std::string
& registration_id
);
229 void CompleteUnregistration(const std::string
& app_id
);
231 bool ExistsRegistration(const std::string
& app_id
) const;
232 void AddRegistration(const std::string
& app_id
,
233 const std::vector
<std::string
>& sender_ids
,
234 const std::string
& registration_id
);
236 // GCMClient::Delegate overrides (for verification).
237 virtual void OnRegisterFinished(const std::string
& app_id
,
238 const std::string
& registration_id
,
239 GCMClient::Result result
) OVERRIDE
;
240 virtual void OnUnregisterFinished(const std::string
& app_id
,
241 GCMClient::Result result
) OVERRIDE
;
242 virtual void OnSendFinished(const std::string
& app_id
,
243 const std::string
& message_id
,
244 GCMClient::Result result
) OVERRIDE
{}
245 virtual void OnMessageReceived(const std::string
& registration_id
,
246 const GCMClient::IncomingMessage
& message
)
248 virtual void OnMessagesDeleted(const std::string
& app_id
) OVERRIDE
;
249 virtual void OnMessageSendError(
250 const std::string
& app_id
,
251 const gcm::GCMClient::SendErrorDetails
& send_error_details
) OVERRIDE
;
252 virtual void OnGCMReady() OVERRIDE
;
253 virtual void OnActivityRecorded() OVERRIDE
{}
254 virtual void OnConnected(const net::IPEndPoint
& ip_endpoint
) OVERRIDE
{}
255 virtual void OnDisconnected() OVERRIDE
{}
257 GCMClientImpl
* gcm_client() const { return gcm_client_
.get(); }
258 FakeMCSClient
* mcs_client() const {
259 return reinterpret_cast<FakeMCSClient
*>(gcm_client_
->mcs_client_
.get());
261 ConnectionFactory
* connection_factory() const {
262 return gcm_client_
->connection_factory_
.get();
265 void reset_last_event() {
267 last_app_id_
.clear();
268 last_registration_id_
.clear();
269 last_message_id_
.clear();
270 last_result_
= GCMClient::UNKNOWN_ERROR
;
273 LastEvent
last_event() const { return last_event_
; }
274 const std::string
& last_app_id() const { return last_app_id_
; }
275 const std::string
& last_registration_id() const {
276 return last_registration_id_
;
278 const std::string
& last_message_id() const { return last_message_id_
; }
279 GCMClient::Result
last_result() const { return last_result_
; }
280 const GCMClient::IncomingMessage
& last_message() const {
281 return last_message_
;
283 const GCMClient::SendErrorDetails
& last_error_details() const {
284 return last_error_details_
;
287 const GServicesSettings
& gservices_settings() const {
288 return gcm_client_
->gservices_settings_
;
295 void PumpLoopUntilIdle();
297 void InitializeLoop();
298 bool CreateUniqueTempDir();
299 AutoAdvancingTestClock
* clock() const {
300 return reinterpret_cast<AutoAdvancingTestClock
*>(gcm_client_
->clock_
.get());
304 // Variables used for verification.
305 LastEvent last_event_
;
306 std::string last_app_id_
;
307 std::string last_registration_id_
;
308 std::string last_message_id_
;
309 GCMClient::Result last_result_
;
310 GCMClient::IncomingMessage last_message_
;
311 GCMClient::SendErrorDetails last_error_details_
;
313 scoped_ptr
<GCMClientImpl
> gcm_client_
;
315 base::MessageLoop message_loop_
;
316 scoped_ptr
<base::RunLoop
> run_loop_
;
317 net::TestURLFetcherFactory url_fetcher_factory_
;
319 // Injected to GCM client:
320 base::ScopedTempDir temp_directory_
;
321 scoped_refptr
<net::TestURLRequestContextGetter
> url_request_context_getter_
;
324 GCMClientImplTest::GCMClientImplTest()
326 last_result_(GCMClient::UNKNOWN_ERROR
),
327 url_request_context_getter_(new net::TestURLRequestContextGetter(
328 message_loop_
.message_loop_proxy())) {
331 GCMClientImplTest::~GCMClientImplTest() {}
333 void GCMClientImplTest::SetUp() {
334 testing::Test::SetUp();
335 ASSERT_TRUE(CreateUniqueTempDir());
337 BuildGCMClient(base::TimeDelta());
338 InitializeGCMClient();
340 CompleteCheckin(kDeviceAndroidId
,
341 kDeviceSecurityToken
,
343 std::map
<std::string
, std::string
>());
346 void GCMClientImplTest::PumpLoop() {
348 run_loop_
.reset(new base::RunLoop());
351 void GCMClientImplTest::PumpLoopUntilIdle() {
352 run_loop_
->RunUntilIdle();
353 run_loop_
.reset(new base::RunLoop());
356 void GCMClientImplTest::QuitLoop() {
357 if (run_loop_
&& run_loop_
->running())
361 void GCMClientImplTest::InitializeLoop() {
362 run_loop_
.reset(new base::RunLoop
);
365 bool GCMClientImplTest::CreateUniqueTempDir() {
366 return temp_directory_
.CreateUniqueTempDir();
369 void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step
) {
370 gcm_client_
.reset(new GCMClientImpl(make_scoped_ptr
<GCMInternalsBuilder
>(
371 new FakeGCMInternalsBuilder(clock_step
))));
374 void GCMClientImplTest::CompleteCheckin(
376 uint64 security_token
,
377 const std::string
& digest
,
378 const std::map
<std::string
, std::string
>& settings
) {
379 checkin_proto::AndroidCheckinResponse response
;
380 response
.set_stats_ok(true);
381 response
.set_android_id(android_id
);
382 response
.set_security_token(security_token
);
384 // For testing G-services settings.
385 if (!digest
.empty()) {
386 response
.set_digest(digest
);
387 for (std::map
<std::string
, std::string
>::const_iterator it
=
389 it
!= settings
.end();
391 checkin_proto::GservicesSetting
* setting
= response
.add_setting();
392 setting
->set_name(it
->first
);
393 setting
->set_value(it
->second
);
395 response
.set_settings_diff(false);
398 std::string response_string
;
399 response
.SerializeToString(&response_string
);
401 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
402 ASSERT_TRUE(fetcher
);
403 fetcher
->set_response_code(net::HTTP_OK
);
404 fetcher
->SetResponseString(response_string
);
405 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
406 url_fetcher_factory_
.RemoveFetcherFromMap(0);
409 void GCMClientImplTest::CompleteRegistration(
410 const std::string
& registration_id
) {
411 std::string
response(kRegistrationResponsePrefix
);
412 response
.append(registration_id
);
413 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
414 ASSERT_TRUE(fetcher
);
415 fetcher
->set_response_code(net::HTTP_OK
);
416 fetcher
->SetResponseString(response
);
417 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
418 url_fetcher_factory_
.RemoveFetcherFromMap(0);
421 void GCMClientImplTest::CompleteUnregistration(
422 const std::string
& app_id
) {
423 std::string
response(kUnregistrationResponsePrefix
);
424 response
.append(app_id
);
425 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
426 ASSERT_TRUE(fetcher
);
427 fetcher
->set_response_code(net::HTTP_OK
);
428 fetcher
->SetResponseString(response
);
429 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
430 url_fetcher_factory_
.RemoveFetcherFromMap(0);
433 bool GCMClientImplTest::ExistsRegistration(const std::string
& app_id
) const {
434 return gcm_client_
->registrations_
.count(app_id
) > 0;
437 void GCMClientImplTest::AddRegistration(
438 const std::string
& app_id
,
439 const std::vector
<std::string
>& sender_ids
,
440 const std::string
& registration_id
) {
441 linked_ptr
<RegistrationInfo
> registration(new RegistrationInfo
);
442 registration
->sender_ids
= sender_ids
;
443 registration
->registration_id
= registration_id
;
444 gcm_client_
->registrations_
[app_id
] = registration
;
447 void GCMClientImplTest::InitializeGCMClient() {
448 clock()->Advance(base::TimeDelta::FromMilliseconds(1));
450 // Actual initialization.
451 GCMClient::ChromeBuildInfo chrome_build_info
;
452 gcm_client_
->Initialize(chrome_build_info
,
453 temp_directory_
.path(),
454 message_loop_
.message_loop_proxy(),
455 url_request_context_getter_
,
456 make_scoped_ptr
<Encryptor
>(new FakeEncryptor
),
460 void GCMClientImplTest::StartGCMClient() {
461 // Start loading and check-in.
462 gcm_client_
->Start();
467 void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage
& message
) {
468 gcm_client_
->OnMessageReceivedFromMCS(message
);
471 void GCMClientImplTest::OnGCMReady() {
472 last_event_
= LOADING_COMPLETED
;
476 void GCMClientImplTest::OnMessageReceived(
477 const std::string
& registration_id
,
478 const GCMClient::IncomingMessage
& message
) {
479 last_event_
= MESSAGE_RECEIVED
;
480 last_app_id_
= registration_id
;
481 last_message_
= message
;
485 void GCMClientImplTest::OnRegisterFinished(const std::string
& app_id
,
486 const std::string
& registration_id
,
487 GCMClient::Result result
) {
488 last_event_
= REGISTRATION_COMPLETED
;
489 last_app_id_
= app_id
;
490 last_registration_id_
= registration_id
;
491 last_result_
= result
;
494 void GCMClientImplTest::OnUnregisterFinished(const std::string
& app_id
,
495 GCMClient::Result result
) {
496 last_event_
= UNREGISTRATION_COMPLETED
;
497 last_app_id_
= app_id
;
498 last_result_
= result
;
501 void GCMClientImplTest::OnMessagesDeleted(const std::string
& app_id
) {
502 last_event_
= MESSAGES_DELETED
;
503 last_app_id_
= app_id
;
506 void GCMClientImplTest::OnMessageSendError(
507 const std::string
& app_id
,
508 const gcm::GCMClient::SendErrorDetails
& send_error_details
) {
509 last_event_
= MESSAGE_SEND_ERROR
;
510 last_app_id_
= app_id
;
511 last_error_details_
= send_error_details
;
514 int64
GCMClientImplTest::CurrentTime() {
515 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond
;
518 TEST_F(GCMClientImplTest
, LoadingCompleted
) {
519 EXPECT_EQ(LOADING_COMPLETED
, last_event());
520 EXPECT_EQ(kDeviceAndroidId
, mcs_client()->last_android_id());
521 EXPECT_EQ(kDeviceSecurityToken
, mcs_client()->last_security_token());
524 TEST_F(GCMClientImplTest
, CheckOut
) {
525 EXPECT_TRUE(mcs_client());
526 EXPECT_TRUE(connection_factory());
527 gcm_client()->CheckOut();
528 EXPECT_FALSE(mcs_client());
529 EXPECT_FALSE(connection_factory());
532 TEST_F(GCMClientImplTest
, RegisterApp
) {
533 EXPECT_FALSE(ExistsRegistration(kAppId
));
535 std::vector
<std::string
> senders
;
536 senders
.push_back("sender");
537 gcm_client()->Register(kAppId
, senders
);
538 CompleteRegistration("reg_id");
540 EXPECT_EQ(REGISTRATION_COMPLETED
, last_event());
541 EXPECT_EQ(kAppId
, last_app_id());
542 EXPECT_EQ("reg_id", last_registration_id());
543 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
544 EXPECT_TRUE(ExistsRegistration(kAppId
));
547 TEST_F(GCMClientImplTest
, DISABLED_RegisterAppFromCache
) {
548 EXPECT_FALSE(ExistsRegistration(kAppId
));
550 std::vector
<std::string
> senders
;
551 senders
.push_back("sender");
552 gcm_client()->Register(kAppId
, senders
);
553 CompleteRegistration("reg_id");
554 EXPECT_TRUE(ExistsRegistration(kAppId
));
556 EXPECT_EQ(kAppId
, last_app_id());
557 EXPECT_EQ("reg_id", last_registration_id());
558 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
559 EXPECT_EQ(REGISTRATION_COMPLETED
, last_event());
561 // Recreate GCMClient in order to load from the persistent store.
562 BuildGCMClient(base::TimeDelta());
563 InitializeGCMClient();
566 EXPECT_TRUE(ExistsRegistration(kAppId
));
569 TEST_F(GCMClientImplTest
, UnregisterApp
) {
570 EXPECT_FALSE(ExistsRegistration(kAppId
));
572 std::vector
<std::string
> senders
;
573 senders
.push_back("sender");
574 gcm_client()->Register(kAppId
, senders
);
575 CompleteRegistration("reg_id");
576 EXPECT_TRUE(ExistsRegistration(kAppId
));
578 gcm_client()->Unregister(kAppId
);
579 CompleteUnregistration(kAppId
);
581 EXPECT_EQ(UNREGISTRATION_COMPLETED
, last_event());
582 EXPECT_EQ(kAppId
, last_app_id());
583 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
584 EXPECT_FALSE(ExistsRegistration(kAppId
));
587 TEST_F(GCMClientImplTest
, DispatchDownstreamMessage
) {
588 // Register to receive messages from kSender and kSender2 only.
589 std::vector
<std::string
> senders
;
590 senders
.push_back(kSender
);
591 senders
.push_back(kSender2
);
592 AddRegistration(kAppId
, senders
, "reg_id");
594 std::map
<std::string
, std::string
> expected_data
;
595 expected_data
["message_type"] = "gcm";
596 expected_data
["key"] = "value";
597 expected_data
["key2"] = "value2";
599 // Message for kSender will be received.
600 MCSMessage
message(BuildDownstreamMessage(kSender
, kAppId
, expected_data
));
601 EXPECT_TRUE(message
.IsValid());
602 ReceiveMessageFromMCS(message
);
604 expected_data
.erase(expected_data
.find("message_type"));
605 EXPECT_EQ(MESSAGE_RECEIVED
, last_event());
606 EXPECT_EQ(kAppId
, last_app_id());
607 EXPECT_EQ(expected_data
.size(), last_message().data
.size());
608 EXPECT_EQ(expected_data
, last_message().data
);
609 EXPECT_EQ(kSender
, last_message().sender_id
);
613 // Message for kSender2 will be received.
614 MCSMessage
message2(BuildDownstreamMessage(kSender2
, kAppId
, expected_data
));
615 EXPECT_TRUE(message2
.IsValid());
616 ReceiveMessageFromMCS(message2
);
618 EXPECT_EQ(MESSAGE_RECEIVED
, last_event());
619 EXPECT_EQ(kAppId
, last_app_id());
620 EXPECT_EQ(expected_data
.size(), last_message().data
.size());
621 EXPECT_EQ(expected_data
, last_message().data
);
622 EXPECT_EQ(kSender2
, last_message().sender_id
);
626 // Message from kSender3 will be dropped.
627 MCSMessage
message3(BuildDownstreamMessage(kSender3
, kAppId
, expected_data
));
628 EXPECT_TRUE(message3
.IsValid());
629 ReceiveMessageFromMCS(message3
);
631 EXPECT_NE(MESSAGE_RECEIVED
, last_event());
632 EXPECT_NE(kAppId
, last_app_id());
635 TEST_F(GCMClientImplTest
, DispatchDownstreamMessageSendError
) {
636 std::map
<std::string
, std::string
> expected_data
;
637 expected_data
["message_type"] = "send_error";
638 expected_data
["google.message_id"] = "007";
639 expected_data
["error_details"] = "some details";
640 MCSMessage
message(BuildDownstreamMessage(
641 kSender
, kAppId
, expected_data
));
642 EXPECT_TRUE(message
.IsValid());
643 ReceiveMessageFromMCS(message
);
645 EXPECT_EQ(MESSAGE_SEND_ERROR
, last_event());
646 EXPECT_EQ(kAppId
, last_app_id());
647 EXPECT_EQ("007", last_error_details().message_id
);
648 EXPECT_EQ(1UL, last_error_details().additional_data
.size());
649 GCMClient::MessageData::const_iterator iter
=
650 last_error_details().additional_data
.find("error_details");
651 EXPECT_TRUE(iter
!= last_error_details().additional_data
.end());
652 EXPECT_EQ("some details", iter
->second
);
655 TEST_F(GCMClientImplTest
, DispatchDownstreamMessgaesDeleted
) {
656 std::map
<std::string
, std::string
> expected_data
;
657 expected_data
["message_type"] = "deleted_messages";
658 MCSMessage
message(BuildDownstreamMessage(
659 kSender
, kAppId
, expected_data
));
660 EXPECT_TRUE(message
.IsValid());
661 ReceiveMessageFromMCS(message
);
663 EXPECT_EQ(MESSAGES_DELETED
, last_event());
664 EXPECT_EQ(kAppId
, last_app_id());
667 TEST_F(GCMClientImplTest
, SendMessage
) {
668 mcs_proto::DataMessageStanza stanza
;
671 GCMClient::OutgoingMessage message
;
673 message
.time_to_live
= 500;
674 message
.data
["key"] = "value";
675 gcm_client()->Send(kAppId
, kSender
, message
);
677 EXPECT_EQ(kDataMessageStanzaTag
, mcs_client()->last_message_tag());
678 EXPECT_EQ(kAppId
, mcs_client()->last_data_message_stanza().category());
679 EXPECT_EQ(kSender
, mcs_client()->last_data_message_stanza().to());
680 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
681 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
682 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
683 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
684 EXPECT_EQ(kSender
, mcs_client()->last_data_message_stanza().to());
685 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
687 mcs_client()->last_data_message_stanza().app_data(0).value());
690 class GCMClientImplCheckinTest
: public GCMClientImplTest
{
692 GCMClientImplCheckinTest();
693 virtual ~GCMClientImplCheckinTest();
695 virtual void SetUp() OVERRIDE
;
698 GCMClientImplCheckinTest::GCMClientImplCheckinTest() {
701 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {
704 void GCMClientImplCheckinTest::SetUp() {
705 testing::Test::SetUp();
706 // Creating unique temp directory that will be used by GCMStore shared between
707 // GCM Client and G-services settings.
708 ASSERT_TRUE(CreateUniqueTempDir());
710 // Time will be advancing one hour every time it is checked.
711 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
));
712 InitializeGCMClient();
716 TEST_F(GCMClientImplCheckinTest
, GServicesSettingsAfterInitialCheckin
) {
717 std::map
<std::string
, std::string
> settings
;
718 settings
["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval
);
719 settings
["checkin_url"] = "http://alternative.url/checkin";
720 settings
["gcm_hostname"] = "alternative.gcm.host";
721 settings
["gcm_secure_port"] = "7777";
722 settings
["gcm_registration_url"] = "http://alternative.url/registration";
723 CompleteCheckin(kDeviceAndroidId
,
724 kDeviceSecurityToken
,
725 GServicesSettings::CalculateDigest(settings
),
727 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
),
728 gservices_settings().GetCheckinInterval());
729 EXPECT_EQ(GURL("http://alternative.url/checkin"),
730 gservices_settings().GetCheckinURL());
731 EXPECT_EQ(GURL("http://alternative.url/registration"),
732 gservices_settings().GetRegistrationURL());
733 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
734 gservices_settings().GetMCSMainEndpoint());
735 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
736 gservices_settings().GetMCSFallbackEndpoint());
739 // This test only checks that periodic checkin happens.
740 TEST_F(GCMClientImplCheckinTest
, PeriodicCheckin
) {
741 std::map
<std::string
, std::string
> settings
;
742 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
743 settings
["checkin_url"] = "http://alternative.url/checkin";
744 settings
["gcm_hostname"] = "alternative.gcm.host";
745 settings
["gcm_secure_port"] = "7777";
746 settings
["gcm_registration_url"] = "http://alternative.url/registration";
747 CompleteCheckin(kDeviceAndroidId
,
748 kDeviceSecurityToken
,
749 GServicesSettings::CalculateDigest(settings
),
751 EXPECT_EQ(2, clock()->call_count());
754 CompleteCheckin(kDeviceAndroidId
,
755 kDeviceSecurityToken
,
756 GServicesSettings::CalculateDigest(settings
),
760 TEST_F(GCMClientImplCheckinTest
, LoadGSettingsFromStore
) {
761 std::map
<std::string
, std::string
> settings
;
762 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
763 settings
["checkin_url"] = "http://alternative.url/checkin";
764 settings
["gcm_hostname"] = "alternative.gcm.host";
765 settings
["gcm_secure_port"] = "7777";
766 settings
["gcm_registration_url"] = "http://alternative.url/registration";
767 CompleteCheckin(kDeviceAndroidId
,
768 kDeviceSecurityToken
,
769 GServicesSettings::CalculateDigest(settings
),
772 BuildGCMClient(base::TimeDelta());
773 InitializeGCMClient();
776 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
),
777 gservices_settings().GetCheckinInterval());
778 EXPECT_EQ(GURL("http://alternative.url/checkin"),
779 gservices_settings().GetCheckinURL());
780 EXPECT_EQ(GURL("http://alternative.url/registration"),
781 gservices_settings().GetRegistrationURL());
782 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
783 gservices_settings().GetMCSMainEndpoint());
784 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
785 gservices_settings().GetMCSFallbackEndpoint());
788 class GCMClientImplStartAndStopTest
: public GCMClientImplTest
{
790 GCMClientImplStartAndStopTest();
791 virtual ~GCMClientImplStartAndStopTest();
793 virtual void SetUp() OVERRIDE
;
796 GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() {
799 GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() {
802 void GCMClientImplStartAndStopTest::SetUp() {
803 testing::Test::SetUp();
804 ASSERT_TRUE(CreateUniqueTempDir());
806 BuildGCMClient(base::TimeDelta());
807 InitializeGCMClient();
810 TEST_F(GCMClientImplStartAndStopTest
, StartStopAndRestart
) {
811 // Start the GCM and wait until it is ready.
812 gcm_client()->Start();
816 gcm_client()->Stop();
820 gcm_client()->Start();
824 TEST_F(GCMClientImplStartAndStopTest
, StartAndStopImmediately
) {
825 // Start the GCM and then stop it immediately.
826 gcm_client()->Start();
827 gcm_client()->Stop();
832 TEST_F(GCMClientImplStartAndStopTest
, StartStopAndRestartImmediately
) {
833 // Start the GCM and then stop and restart it immediately.
834 gcm_client()->Start();
835 gcm_client()->Stop();
836 gcm_client()->Start();