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
,
43 const uint64 kDeviceAndroidId
= 54321;
44 const uint64 kDeviceSecurityToken
= 12345;
45 const int64 kSettingsCheckinInterval
= 16 * 60 * 60;
46 const char kAppId
[] = "app_id";
47 const char kSender
[] = "project_id";
48 const char kSender2
[] = "project_id2";
49 const char kSender3
[] = "project_id3";
50 const char kRegistrationResponsePrefix
[] = "token=";
51 const char kUnregistrationResponsePrefix
[] = "deleted=";
53 // Helper for building arbitrary data messages.
54 MCSMessage
BuildDownstreamMessage(
55 const std::string
& project_id
,
56 const std::string
& app_id
,
57 const std::map
<std::string
, std::string
>& data
) {
58 mcs_proto::DataMessageStanza data_message
;
59 data_message
.set_from(project_id
);
60 data_message
.set_category(app_id
);
61 for (std::map
<std::string
, std::string
>::const_iterator iter
= data
.begin();
64 mcs_proto::AppData
* app_data
= data_message
.add_app_data();
65 app_data
->set_key(iter
->first
);
66 app_data
->set_value(iter
->second
);
68 return MCSMessage(kDataMessageStanzaTag
, data_message
);
71 class FakeMCSClient
: public MCSClient
{
73 FakeMCSClient(base::Clock
* clock
,
74 ConnectionFactory
* connection_factory
,
76 GCMStatsRecorder
* recorder
);
77 virtual ~FakeMCSClient();
78 virtual void Login(uint64 android_id
, uint64 security_token
) OVERRIDE
;
79 virtual void SendMessage(const MCSMessage
& message
) OVERRIDE
;
81 uint64
last_android_id() const { return last_android_id_
; }
82 uint64
last_security_token() const { return last_security_token_
; }
83 uint8
last_message_tag() const { return last_message_tag_
; }
84 const mcs_proto::DataMessageStanza
& last_data_message_stanza() const {
85 return last_data_message_stanza_
;
89 uint64 last_android_id_
;
90 uint64 last_security_token_
;
91 uint8 last_message_tag_
;
92 mcs_proto::DataMessageStanza last_data_message_stanza_
;
95 FakeMCSClient::FakeMCSClient(base::Clock
* clock
,
96 ConnectionFactory
* connection_factory
,
98 GCMStatsRecorder
* recorder
)
99 : MCSClient("", clock
, connection_factory
, gcm_store
, recorder
),
100 last_android_id_(0u),
101 last_security_token_(0u),
102 last_message_tag_(kNumProtoTypes
) {
105 FakeMCSClient::~FakeMCSClient() {
108 void FakeMCSClient::Login(uint64 android_id
, uint64 security_token
) {
109 last_android_id_
= android_id
;
110 last_security_token_
= security_token
;
113 void FakeMCSClient::SendMessage(const MCSMessage
& message
) {
114 last_message_tag_
= message
.tag();
115 if (last_message_tag_
== kDataMessageStanzaTag
) {
116 last_data_message_stanza_
.CopyFrom(
117 reinterpret_cast<const mcs_proto::DataMessageStanza
&>(
118 message
.GetProtobuf()));
122 class AutoAdvancingTestClock
: public base::Clock
{
124 explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta
);
125 virtual ~AutoAdvancingTestClock();
127 virtual base::Time
Now() OVERRIDE
;
128 void Advance(TimeDelta delta
);
129 int call_count() const { return call_count_
; }
133 base::TimeDelta auto_increment_time_delta_
;
136 DISALLOW_COPY_AND_ASSIGN(AutoAdvancingTestClock
);
139 AutoAdvancingTestClock::AutoAdvancingTestClock(
140 base::TimeDelta auto_increment_time_delta
)
141 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta
) {
144 AutoAdvancingTestClock::~AutoAdvancingTestClock() {
147 base::Time
AutoAdvancingTestClock::Now() {
149 now_
+= auto_increment_time_delta_
;
153 void AutoAdvancingTestClock::Advance(base::TimeDelta delta
) {
157 class FakeGCMInternalsBuilder
: public GCMInternalsBuilder
{
159 FakeGCMInternalsBuilder(base::TimeDelta clock_step
);
160 virtual ~FakeGCMInternalsBuilder();
162 virtual scoped_ptr
<base::Clock
> BuildClock() OVERRIDE
;
163 virtual scoped_ptr
<MCSClient
> BuildMCSClient(
164 const std::string
& version
,
166 ConnectionFactory
* connection_factory
,
168 GCMStatsRecorder
* recorder
) OVERRIDE
;
169 virtual scoped_ptr
<ConnectionFactory
> BuildConnectionFactory(
170 const std::vector
<GURL
>& endpoints
,
171 const net::BackoffEntry::Policy
& backoff_policy
,
172 const scoped_refptr
<net::HttpNetworkSession
>& gcm_network_session
,
173 const scoped_refptr
<net::HttpNetworkSession
>& http_network_session
,
174 net::NetLog
* net_log
,
175 GCMStatsRecorder
* recorder
) OVERRIDE
;
178 base::TimeDelta clock_step_
;
181 FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step
)
182 : clock_step_(clock_step
) {
185 FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}
187 scoped_ptr
<base::Clock
> FakeGCMInternalsBuilder::BuildClock() {
188 return make_scoped_ptr
<base::Clock
>(new AutoAdvancingTestClock(clock_step_
));
191 scoped_ptr
<MCSClient
> FakeGCMInternalsBuilder::BuildMCSClient(
192 const std::string
& version
,
194 ConnectionFactory
* connection_factory
,
196 GCMStatsRecorder
* recorder
) {
197 return make_scoped_ptr
<MCSClient
>(new FakeMCSClient(clock
,
203 scoped_ptr
<ConnectionFactory
> FakeGCMInternalsBuilder::BuildConnectionFactory(
204 const std::vector
<GURL
>& endpoints
,
205 const net::BackoffEntry::Policy
& backoff_policy
,
206 const scoped_refptr
<net::HttpNetworkSession
>& gcm_network_session
,
207 const scoped_refptr
<net::HttpNetworkSession
>& http_network_session
,
208 net::NetLog
* net_log
,
209 GCMStatsRecorder
* recorder
) {
210 return make_scoped_ptr
<ConnectionFactory
>(new FakeConnectionFactory());
215 class GCMClientImplTest
: public testing::Test
,
216 public GCMClient::Delegate
{
219 virtual ~GCMClientImplTest();
221 virtual void SetUp() OVERRIDE
;
223 void BuildGCMClient(base::TimeDelta clock_step
);
224 void InitializeGCMClient();
225 void StartGCMClient();
226 void ReceiveMessageFromMCS(const MCSMessage
& message
);
227 void ReceiveOnMessageSentToMCS(
228 const std::string
& app_id
,
229 const std::string
& message_id
,
230 const MCSClient::MessageSendStatus status
);
231 void CompleteCheckin(uint64 android_id
,
232 uint64 security_token
,
233 const std::string
& digest
,
234 const std::map
<std::string
, std::string
>& settings
);
235 void CompleteRegistration(const std::string
& registration_id
);
236 void CompleteUnregistration(const std::string
& app_id
);
238 bool ExistsRegistration(const std::string
& app_id
) const;
239 void AddRegistration(const std::string
& app_id
,
240 const std::vector
<std::string
>& sender_ids
,
241 const std::string
& registration_id
);
243 // GCMClient::Delegate overrides (for verification).
244 virtual void OnRegisterFinished(const std::string
& app_id
,
245 const std::string
& registration_id
,
246 GCMClient::Result result
) OVERRIDE
;
247 virtual void OnUnregisterFinished(const std::string
& app_id
,
248 GCMClient::Result result
) OVERRIDE
;
249 virtual void OnSendFinished(const std::string
& app_id
,
250 const std::string
& message_id
,
251 GCMClient::Result result
) OVERRIDE
{}
252 virtual void OnMessageReceived(const std::string
& registration_id
,
253 const GCMClient::IncomingMessage
& message
)
255 virtual void OnMessagesDeleted(const std::string
& app_id
) OVERRIDE
;
256 virtual void OnMessageSendError(
257 const std::string
& app_id
,
258 const gcm::GCMClient::SendErrorDetails
& send_error_details
) OVERRIDE
;
259 virtual void OnSendAcknowledged(const std::string
& app_id
,
260 const std::string
& message_id
) OVERRIDE
;
261 virtual void OnGCMReady() OVERRIDE
;
262 virtual void OnActivityRecorded() OVERRIDE
{}
263 virtual void OnConnected(const net::IPEndPoint
& ip_endpoint
) OVERRIDE
{}
264 virtual void OnDisconnected() OVERRIDE
{}
266 GCMClientImpl
* gcm_client() const { return gcm_client_
.get(); }
267 FakeMCSClient
* mcs_client() const {
268 return reinterpret_cast<FakeMCSClient
*>(gcm_client_
->mcs_client_
.get());
270 ConnectionFactory
* connection_factory() const {
271 return gcm_client_
->connection_factory_
.get();
274 const GCMClientImpl::CheckinInfo
& device_checkin_info() const {
275 return gcm_client_
->device_checkin_info_
;
278 void reset_last_event() {
280 last_app_id_
.clear();
281 last_registration_id_
.clear();
282 last_message_id_
.clear();
283 last_result_
= GCMClient::UNKNOWN_ERROR
;
286 LastEvent
last_event() const { return last_event_
; }
287 const std::string
& last_app_id() const { return last_app_id_
; }
288 const std::string
& last_registration_id() const {
289 return last_registration_id_
;
291 const std::string
& last_message_id() const { return last_message_id_
; }
292 GCMClient::Result
last_result() const { return last_result_
; }
293 const GCMClient::IncomingMessage
& last_message() const {
294 return last_message_
;
296 const GCMClient::SendErrorDetails
& last_error_details() const {
297 return last_error_details_
;
300 const GServicesSettings
& gservices_settings() const {
301 return gcm_client_
->gservices_settings_
;
308 void PumpLoopUntilIdle();
310 void InitializeLoop();
311 bool CreateUniqueTempDir();
312 AutoAdvancingTestClock
* clock() const {
313 return reinterpret_cast<AutoAdvancingTestClock
*>(gcm_client_
->clock_
.get());
317 // Variables used for verification.
318 LastEvent last_event_
;
319 std::string last_app_id_
;
320 std::string last_registration_id_
;
321 std::string last_message_id_
;
322 GCMClient::Result last_result_
;
323 GCMClient::IncomingMessage last_message_
;
324 GCMClient::SendErrorDetails last_error_details_
;
326 scoped_ptr
<GCMClientImpl
> gcm_client_
;
328 base::MessageLoop message_loop_
;
329 scoped_ptr
<base::RunLoop
> run_loop_
;
330 net::TestURLFetcherFactory url_fetcher_factory_
;
332 // Injected to GCM client:
333 base::ScopedTempDir temp_directory_
;
334 scoped_refptr
<net::TestURLRequestContextGetter
> url_request_context_getter_
;
337 GCMClientImplTest::GCMClientImplTest()
339 last_result_(GCMClient::UNKNOWN_ERROR
),
340 url_request_context_getter_(new net::TestURLRequestContextGetter(
341 message_loop_
.message_loop_proxy())) {
344 GCMClientImplTest::~GCMClientImplTest() {}
346 void GCMClientImplTest::SetUp() {
347 testing::Test::SetUp();
348 ASSERT_TRUE(CreateUniqueTempDir());
350 BuildGCMClient(base::TimeDelta());
351 InitializeGCMClient();
353 CompleteCheckin(kDeviceAndroidId
,
354 kDeviceSecurityToken
,
356 std::map
<std::string
, std::string
>());
359 void GCMClientImplTest::PumpLoop() {
361 run_loop_
.reset(new base::RunLoop());
364 void GCMClientImplTest::PumpLoopUntilIdle() {
365 run_loop_
->RunUntilIdle();
366 run_loop_
.reset(new base::RunLoop());
369 void GCMClientImplTest::QuitLoop() {
370 if (run_loop_
&& run_loop_
->running())
374 void GCMClientImplTest::InitializeLoop() {
375 run_loop_
.reset(new base::RunLoop
);
378 bool GCMClientImplTest::CreateUniqueTempDir() {
379 return temp_directory_
.CreateUniqueTempDir();
382 void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step
) {
383 gcm_client_
.reset(new GCMClientImpl(make_scoped_ptr
<GCMInternalsBuilder
>(
384 new FakeGCMInternalsBuilder(clock_step
))));
387 void GCMClientImplTest::CompleteCheckin(
389 uint64 security_token
,
390 const std::string
& digest
,
391 const std::map
<std::string
, std::string
>& settings
) {
392 checkin_proto::AndroidCheckinResponse response
;
393 response
.set_stats_ok(true);
394 response
.set_android_id(android_id
);
395 response
.set_security_token(security_token
);
397 // For testing G-services settings.
398 if (!digest
.empty()) {
399 response
.set_digest(digest
);
400 for (std::map
<std::string
, std::string
>::const_iterator it
=
402 it
!= settings
.end();
404 checkin_proto::GservicesSetting
* setting
= response
.add_setting();
405 setting
->set_name(it
->first
);
406 setting
->set_value(it
->second
);
408 response
.set_settings_diff(false);
411 std::string response_string
;
412 response
.SerializeToString(&response_string
);
414 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
415 ASSERT_TRUE(fetcher
);
416 fetcher
->set_response_code(net::HTTP_OK
);
417 fetcher
->SetResponseString(response_string
);
418 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
419 url_fetcher_factory_
.RemoveFetcherFromMap(0);
422 void GCMClientImplTest::CompleteRegistration(
423 const std::string
& registration_id
) {
424 std::string
response(kRegistrationResponsePrefix
);
425 response
.append(registration_id
);
426 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
427 ASSERT_TRUE(fetcher
);
428 fetcher
->set_response_code(net::HTTP_OK
);
429 fetcher
->SetResponseString(response
);
430 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
431 url_fetcher_factory_
.RemoveFetcherFromMap(0);
434 void GCMClientImplTest::CompleteUnregistration(
435 const std::string
& app_id
) {
436 std::string
response(kUnregistrationResponsePrefix
);
437 response
.append(app_id
);
438 net::TestURLFetcher
* fetcher
= url_fetcher_factory_
.GetFetcherByID(0);
439 ASSERT_TRUE(fetcher
);
440 fetcher
->set_response_code(net::HTTP_OK
);
441 fetcher
->SetResponseString(response
);
442 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
443 url_fetcher_factory_
.RemoveFetcherFromMap(0);
446 bool GCMClientImplTest::ExistsRegistration(const std::string
& app_id
) const {
447 return gcm_client_
->registrations_
.count(app_id
) > 0;
450 void GCMClientImplTest::AddRegistration(
451 const std::string
& app_id
,
452 const std::vector
<std::string
>& sender_ids
,
453 const std::string
& registration_id
) {
454 linked_ptr
<RegistrationInfo
> registration(new RegistrationInfo
);
455 registration
->sender_ids
= sender_ids
;
456 registration
->registration_id
= registration_id
;
457 gcm_client_
->registrations_
[app_id
] = registration
;
460 void GCMClientImplTest::InitializeGCMClient() {
461 clock()->Advance(base::TimeDelta::FromMilliseconds(1));
463 // Actual initialization.
464 GCMClient::ChromeBuildInfo chrome_build_info
;
465 gcm_client_
->Initialize(chrome_build_info
,
466 temp_directory_
.path(),
467 message_loop_
.message_loop_proxy(),
468 url_request_context_getter_
,
469 make_scoped_ptr
<Encryptor
>(new FakeEncryptor
),
473 void GCMClientImplTest::StartGCMClient() {
474 // Start loading and check-in.
475 gcm_client_
->Start();
480 void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage
& message
) {
481 gcm_client_
->recorder_
.RecordConnectionInitiated(std::string());
482 gcm_client_
->recorder_
.RecordConnectionSuccess();
483 gcm_client_
->OnMessageReceivedFromMCS(message
);
486 void GCMClientImplTest::ReceiveOnMessageSentToMCS(
487 const std::string
& app_id
,
488 const std::string
& message_id
,
489 const MCSClient::MessageSendStatus status
) {
490 gcm_client_
->OnMessageSentToMCS(0LL, app_id
, message_id
, status
);
493 void GCMClientImplTest::OnGCMReady() {
494 last_event_
= LOADING_COMPLETED
;
498 void GCMClientImplTest::OnMessageReceived(
499 const std::string
& registration_id
,
500 const GCMClient::IncomingMessage
& message
) {
501 last_event_
= MESSAGE_RECEIVED
;
502 last_app_id_
= registration_id
;
503 last_message_
= message
;
507 void GCMClientImplTest::OnRegisterFinished(const std::string
& app_id
,
508 const std::string
& registration_id
,
509 GCMClient::Result result
) {
510 last_event_
= REGISTRATION_COMPLETED
;
511 last_app_id_
= app_id
;
512 last_registration_id_
= registration_id
;
513 last_result_
= result
;
516 void GCMClientImplTest::OnUnregisterFinished(const std::string
& app_id
,
517 GCMClient::Result result
) {
518 last_event_
= UNREGISTRATION_COMPLETED
;
519 last_app_id_
= app_id
;
520 last_result_
= result
;
523 void GCMClientImplTest::OnMessagesDeleted(const std::string
& app_id
) {
524 last_event_
= MESSAGES_DELETED
;
525 last_app_id_
= app_id
;
528 void GCMClientImplTest::OnMessageSendError(
529 const std::string
& app_id
,
530 const gcm::GCMClient::SendErrorDetails
& send_error_details
) {
531 last_event_
= MESSAGE_SEND_ERROR
;
532 last_app_id_
= app_id
;
533 last_error_details_
= send_error_details
;
536 void GCMClientImplTest::OnSendAcknowledged(const std::string
& app_id
,
537 const std::string
& message_id
) {
538 last_event_
= MESSAGE_SEND_ACK
;
539 last_app_id_
= app_id
;
540 last_message_id_
= message_id
;
543 int64
GCMClientImplTest::CurrentTime() {
544 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond
;
547 TEST_F(GCMClientImplTest
, LoadingCompleted
) {
548 EXPECT_EQ(LOADING_COMPLETED
, last_event());
549 EXPECT_EQ(kDeviceAndroidId
, mcs_client()->last_android_id());
550 EXPECT_EQ(kDeviceSecurityToken
, mcs_client()->last_security_token());
552 // Checking freshly loaded CheckinInfo.
553 EXPECT_EQ(kDeviceAndroidId
, device_checkin_info().android_id
);
554 EXPECT_EQ(kDeviceSecurityToken
, device_checkin_info().secret
);
555 EXPECT_TRUE(device_checkin_info().last_checkin_accounts
.empty());
556 EXPECT_TRUE(device_checkin_info().accounts_set
);
557 EXPECT_TRUE(device_checkin_info().account_tokens
.empty());
560 TEST_F(GCMClientImplTest
, CheckOut
) {
561 EXPECT_TRUE(mcs_client());
562 EXPECT_TRUE(connection_factory());
563 gcm_client()->CheckOut();
564 EXPECT_FALSE(mcs_client());
565 EXPECT_FALSE(connection_factory());
568 TEST_F(GCMClientImplTest
, RegisterApp
) {
569 EXPECT_FALSE(ExistsRegistration(kAppId
));
571 std::vector
<std::string
> senders
;
572 senders
.push_back("sender");
573 gcm_client()->Register(kAppId
, senders
);
574 CompleteRegistration("reg_id");
576 EXPECT_EQ(REGISTRATION_COMPLETED
, last_event());
577 EXPECT_EQ(kAppId
, last_app_id());
578 EXPECT_EQ("reg_id", last_registration_id());
579 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
580 EXPECT_TRUE(ExistsRegistration(kAppId
));
583 TEST_F(GCMClientImplTest
, DISABLED_RegisterAppFromCache
) {
584 EXPECT_FALSE(ExistsRegistration(kAppId
));
586 std::vector
<std::string
> senders
;
587 senders
.push_back("sender");
588 gcm_client()->Register(kAppId
, senders
);
589 CompleteRegistration("reg_id");
590 EXPECT_TRUE(ExistsRegistration(kAppId
));
592 EXPECT_EQ(kAppId
, last_app_id());
593 EXPECT_EQ("reg_id", last_registration_id());
594 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
595 EXPECT_EQ(REGISTRATION_COMPLETED
, last_event());
597 // Recreate GCMClient in order to load from the persistent store.
598 BuildGCMClient(base::TimeDelta());
599 InitializeGCMClient();
602 EXPECT_TRUE(ExistsRegistration(kAppId
));
605 TEST_F(GCMClientImplTest
, UnregisterApp
) {
606 EXPECT_FALSE(ExistsRegistration(kAppId
));
608 std::vector
<std::string
> senders
;
609 senders
.push_back("sender");
610 gcm_client()->Register(kAppId
, senders
);
611 CompleteRegistration("reg_id");
612 EXPECT_TRUE(ExistsRegistration(kAppId
));
614 gcm_client()->Unregister(kAppId
);
615 CompleteUnregistration(kAppId
);
617 EXPECT_EQ(UNREGISTRATION_COMPLETED
, last_event());
618 EXPECT_EQ(kAppId
, last_app_id());
619 EXPECT_EQ(GCMClient::SUCCESS
, last_result());
620 EXPECT_FALSE(ExistsRegistration(kAppId
));
623 TEST_F(GCMClientImplTest
, DispatchDownstreamMessage
) {
624 // Register to receive messages from kSender and kSender2 only.
625 std::vector
<std::string
> senders
;
626 senders
.push_back(kSender
);
627 senders
.push_back(kSender2
);
628 AddRegistration(kAppId
, senders
, "reg_id");
630 std::map
<std::string
, std::string
> expected_data
;
631 expected_data
["message_type"] = "gcm";
632 expected_data
["key"] = "value";
633 expected_data
["key2"] = "value2";
635 // Message for kSender will be received.
636 MCSMessage
message(BuildDownstreamMessage(kSender
, kAppId
, expected_data
));
637 EXPECT_TRUE(message
.IsValid());
638 ReceiveMessageFromMCS(message
);
640 expected_data
.erase(expected_data
.find("message_type"));
641 EXPECT_EQ(MESSAGE_RECEIVED
, last_event());
642 EXPECT_EQ(kAppId
, last_app_id());
643 EXPECT_EQ(expected_data
.size(), last_message().data
.size());
644 EXPECT_EQ(expected_data
, last_message().data
);
645 EXPECT_EQ(kSender
, last_message().sender_id
);
649 // Message for kSender2 will be received.
650 MCSMessage
message2(BuildDownstreamMessage(kSender2
, kAppId
, expected_data
));
651 EXPECT_TRUE(message2
.IsValid());
652 ReceiveMessageFromMCS(message2
);
654 EXPECT_EQ(MESSAGE_RECEIVED
, last_event());
655 EXPECT_EQ(kAppId
, last_app_id());
656 EXPECT_EQ(expected_data
.size(), last_message().data
.size());
657 EXPECT_EQ(expected_data
, last_message().data
);
658 EXPECT_EQ(kSender2
, last_message().sender_id
);
662 // Message from kSender3 will be dropped.
663 MCSMessage
message3(BuildDownstreamMessage(kSender3
, kAppId
, expected_data
));
664 EXPECT_TRUE(message3
.IsValid());
665 ReceiveMessageFromMCS(message3
);
667 EXPECT_NE(MESSAGE_RECEIVED
, last_event());
668 EXPECT_NE(kAppId
, last_app_id());
671 TEST_F(GCMClientImplTest
, DispatchDownstreamMessageSendError
) {
672 std::map
<std::string
, std::string
> expected_data
;
673 expected_data
["message_type"] = "send_error";
674 expected_data
["google.message_id"] = "007";
675 expected_data
["error_details"] = "some details";
676 MCSMessage
message(BuildDownstreamMessage(
677 kSender
, kAppId
, expected_data
));
678 EXPECT_TRUE(message
.IsValid());
679 ReceiveMessageFromMCS(message
);
681 EXPECT_EQ(MESSAGE_SEND_ERROR
, last_event());
682 EXPECT_EQ(kAppId
, last_app_id());
683 EXPECT_EQ("007", last_error_details().message_id
);
684 EXPECT_EQ(1UL, last_error_details().additional_data
.size());
685 GCMClient::MessageData::const_iterator iter
=
686 last_error_details().additional_data
.find("error_details");
687 EXPECT_TRUE(iter
!= last_error_details().additional_data
.end());
688 EXPECT_EQ("some details", iter
->second
);
691 TEST_F(GCMClientImplTest
, DispatchDownstreamMessgaesDeleted
) {
692 std::map
<std::string
, std::string
> expected_data
;
693 expected_data
["message_type"] = "deleted_messages";
694 MCSMessage
message(BuildDownstreamMessage(
695 kSender
, kAppId
, expected_data
));
696 EXPECT_TRUE(message
.IsValid());
697 ReceiveMessageFromMCS(message
);
699 EXPECT_EQ(MESSAGES_DELETED
, last_event());
700 EXPECT_EQ(kAppId
, last_app_id());
703 TEST_F(GCMClientImplTest
, SendMessage
) {
704 GCMClient::OutgoingMessage message
;
706 message
.time_to_live
= 500;
707 message
.data
["key"] = "value";
708 gcm_client()->Send(kAppId
, kSender
, message
);
710 EXPECT_EQ(kDataMessageStanzaTag
, mcs_client()->last_message_tag());
711 EXPECT_EQ(kAppId
, mcs_client()->last_data_message_stanza().category());
712 EXPECT_EQ(kSender
, mcs_client()->last_data_message_stanza().to());
713 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
714 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
715 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
716 EXPECT_EQ("gcm@chrome.com", mcs_client()->last_data_message_stanza().from());
717 EXPECT_EQ(kSender
, mcs_client()->last_data_message_stanza().to());
718 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
720 mcs_client()->last_data_message_stanza().app_data(0).value());
723 TEST_F(GCMClientImplTest
, SendMessageAcknowledged
) {
724 ReceiveOnMessageSentToMCS(kAppId
, "007", MCSClient::SENT
);
725 EXPECT_EQ(MESSAGE_SEND_ACK
, last_event());
726 EXPECT_EQ(kAppId
, last_app_id());
727 EXPECT_EQ("007", last_message_id());
730 class GCMClientImplCheckinTest
: public GCMClientImplTest
{
732 GCMClientImplCheckinTest();
733 virtual ~GCMClientImplCheckinTest();
735 virtual void SetUp() OVERRIDE
;
738 GCMClientImplCheckinTest::GCMClientImplCheckinTest() {
741 GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {
744 void GCMClientImplCheckinTest::SetUp() {
745 testing::Test::SetUp();
746 // Creating unique temp directory that will be used by GCMStore shared between
747 // GCM Client and G-services settings.
748 ASSERT_TRUE(CreateUniqueTempDir());
750 // Time will be advancing one hour every time it is checked.
751 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
));
752 InitializeGCMClient();
756 TEST_F(GCMClientImplCheckinTest
, GServicesSettingsAfterInitialCheckin
) {
757 std::map
<std::string
, std::string
> settings
;
758 settings
["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval
);
759 settings
["checkin_url"] = "http://alternative.url/checkin";
760 settings
["gcm_hostname"] = "alternative.gcm.host";
761 settings
["gcm_secure_port"] = "7777";
762 settings
["gcm_registration_url"] = "http://alternative.url/registration";
763 CompleteCheckin(kDeviceAndroidId
,
764 kDeviceSecurityToken
,
765 GServicesSettings::CalculateDigest(settings
),
767 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
),
768 gservices_settings().GetCheckinInterval());
769 EXPECT_EQ(GURL("http://alternative.url/checkin"),
770 gservices_settings().GetCheckinURL());
771 EXPECT_EQ(GURL("http://alternative.url/registration"),
772 gservices_settings().GetRegistrationURL());
773 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
774 gservices_settings().GetMCSMainEndpoint());
775 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
776 gservices_settings().GetMCSFallbackEndpoint());
779 // This test only checks that periodic checkin happens.
780 TEST_F(GCMClientImplCheckinTest
, PeriodicCheckin
) {
781 std::map
<std::string
, std::string
> settings
;
782 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
783 settings
["checkin_url"] = "http://alternative.url/checkin";
784 settings
["gcm_hostname"] = "alternative.gcm.host";
785 settings
["gcm_secure_port"] = "7777";
786 settings
["gcm_registration_url"] = "http://alternative.url/registration";
787 CompleteCheckin(kDeviceAndroidId
,
788 kDeviceSecurityToken
,
789 GServicesSettings::CalculateDigest(settings
),
792 EXPECT_EQ(2, clock()->call_count());
795 CompleteCheckin(kDeviceAndroidId
,
796 kDeviceSecurityToken
,
797 GServicesSettings::CalculateDigest(settings
),
801 TEST_F(GCMClientImplCheckinTest
, LoadGSettingsFromStore
) {
802 std::map
<std::string
, std::string
> settings
;
803 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
804 settings
["checkin_url"] = "http://alternative.url/checkin";
805 settings
["gcm_hostname"] = "alternative.gcm.host";
806 settings
["gcm_secure_port"] = "7777";
807 settings
["gcm_registration_url"] = "http://alternative.url/registration";
808 CompleteCheckin(kDeviceAndroidId
,
809 kDeviceSecurityToken
,
810 GServicesSettings::CalculateDigest(settings
),
813 BuildGCMClient(base::TimeDelta());
814 InitializeGCMClient();
817 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval
),
818 gservices_settings().GetCheckinInterval());
819 EXPECT_EQ(GURL("http://alternative.url/checkin"),
820 gservices_settings().GetCheckinURL());
821 EXPECT_EQ(GURL("http://alternative.url/registration"),
822 gservices_settings().GetRegistrationURL());
823 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
824 gservices_settings().GetMCSMainEndpoint());
825 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
826 gservices_settings().GetMCSFallbackEndpoint());
829 // This test only checks that periodic checkin happens.
830 TEST_F(GCMClientImplCheckinTest
, CheckinWithAccounts
) {
831 std::map
<std::string
, std::string
> settings
;
832 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
833 settings
["checkin_url"] = "http://alternative.url/checkin";
834 settings
["gcm_hostname"] = "alternative.gcm.host";
835 settings
["gcm_secure_port"] = "7777";
836 settings
["gcm_registration_url"] = "http://alternative.url/registration";
837 CompleteCheckin(kDeviceAndroidId
,
838 kDeviceSecurityToken
,
839 GServicesSettings::CalculateDigest(settings
),
842 std::map
<std::string
, std::string
> account_tokens
;
843 account_tokens
["test_user1@gmail.com"] = "token1";
844 account_tokens
["test_user2@gmail.com"] = "token2";
845 gcm_client()->SetAccountsForCheckin(account_tokens
);
847 EXPECT_TRUE(device_checkin_info().last_checkin_accounts
.empty());
848 EXPECT_TRUE(device_checkin_info().accounts_set
);
849 EXPECT_EQ(account_tokens
, device_checkin_info().account_tokens
);
852 CompleteCheckin(kDeviceAndroidId
,
853 kDeviceSecurityToken
,
854 GServicesSettings::CalculateDigest(settings
),
857 std::set
<std::string
> accounts
;
858 accounts
.insert("test_user1@gmail.com");
859 accounts
.insert("test_user2@gmail.com");
860 EXPECT_EQ(accounts
, device_checkin_info().last_checkin_accounts
);
861 EXPECT_TRUE(device_checkin_info().accounts_set
);
862 EXPECT_EQ(account_tokens
, device_checkin_info().account_tokens
);
865 // This test only checks that periodic checkin happens.
866 TEST_F(GCMClientImplCheckinTest
, CheckinWhenAccountRemoved
) {
867 std::map
<std::string
, std::string
> settings
;
868 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
869 settings
["checkin_url"] = "http://alternative.url/checkin";
870 settings
["gcm_hostname"] = "alternative.gcm.host";
871 settings
["gcm_secure_port"] = "7777";
872 settings
["gcm_registration_url"] = "http://alternative.url/registration";
873 CompleteCheckin(kDeviceAndroidId
,
874 kDeviceSecurityToken
,
875 GServicesSettings::CalculateDigest(settings
),
878 std::map
<std::string
, std::string
> account_tokens
;
879 account_tokens
["test_user1@gmail.com"] = "token1";
880 account_tokens
["test_user2@gmail.com"] = "token2";
881 gcm_client()->SetAccountsForCheckin(account_tokens
);
883 CompleteCheckin(kDeviceAndroidId
,
884 kDeviceSecurityToken
,
885 GServicesSettings::CalculateDigest(settings
),
888 EXPECT_EQ(2UL, device_checkin_info().last_checkin_accounts
.size());
889 EXPECT_TRUE(device_checkin_info().accounts_set
);
890 EXPECT_EQ(account_tokens
, device_checkin_info().account_tokens
);
892 account_tokens
.erase(account_tokens
.find("test_user2@gmail.com"));
893 gcm_client()->SetAccountsForCheckin(account_tokens
);
896 CompleteCheckin(kDeviceAndroidId
,
897 kDeviceSecurityToken
,
898 GServicesSettings::CalculateDigest(settings
),
901 std::set
<std::string
> accounts
;
902 accounts
.insert("test_user1@gmail.com");
903 EXPECT_EQ(accounts
, device_checkin_info().last_checkin_accounts
);
904 EXPECT_TRUE(device_checkin_info().accounts_set
);
905 EXPECT_EQ(account_tokens
, device_checkin_info().account_tokens
);
908 // This test only checks that periodic checkin happens.
909 TEST_F(GCMClientImplCheckinTest
, CheckinWhenAccountReplaced
) {
910 std::map
<std::string
, std::string
> settings
;
911 settings
["checkin_interval"] = base::IntToString(kSettingsCheckinInterval
);
912 settings
["checkin_url"] = "http://alternative.url/checkin";
913 settings
["gcm_hostname"] = "alternative.gcm.host";
914 settings
["gcm_secure_port"] = "7777";
915 settings
["gcm_registration_url"] = "http://alternative.url/registration";
916 CompleteCheckin(kDeviceAndroidId
,
917 kDeviceSecurityToken
,
918 GServicesSettings::CalculateDigest(settings
),
921 std::map
<std::string
, std::string
> account_tokens
;
922 account_tokens
["test_user1@gmail.com"] = "token1";
923 gcm_client()->SetAccountsForCheckin(account_tokens
);
926 CompleteCheckin(kDeviceAndroidId
,
927 kDeviceSecurityToken
,
928 GServicesSettings::CalculateDigest(settings
),
931 std::set
<std::string
> accounts
;
932 accounts
.insert("test_user1@gmail.com");
933 EXPECT_EQ(accounts
, device_checkin_info().last_checkin_accounts
);
935 // This should trigger another checkin, because the list of accounts is
937 account_tokens
.erase(account_tokens
.find("test_user1@gmail.com"));
938 account_tokens
["test_user2@gmail.com"] = "token2";
939 gcm_client()->SetAccountsForCheckin(account_tokens
);
942 CompleteCheckin(kDeviceAndroidId
,
943 kDeviceSecurityToken
,
944 GServicesSettings::CalculateDigest(settings
),
948 accounts
.insert("test_user2@gmail.com");
949 EXPECT_EQ(accounts
, device_checkin_info().last_checkin_accounts
);
950 EXPECT_TRUE(device_checkin_info().accounts_set
);
951 EXPECT_EQ(account_tokens
, device_checkin_info().account_tokens
);
954 class GCMClientImplStartAndStopTest
: public GCMClientImplTest
{
956 GCMClientImplStartAndStopTest();
957 virtual ~GCMClientImplStartAndStopTest();
959 virtual void SetUp() OVERRIDE
;
962 GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() {
965 GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() {
968 void GCMClientImplStartAndStopTest::SetUp() {
969 testing::Test::SetUp();
970 ASSERT_TRUE(CreateUniqueTempDir());
972 BuildGCMClient(base::TimeDelta());
973 InitializeGCMClient();
976 TEST_F(GCMClientImplStartAndStopTest
, StartStopAndRestart
) {
977 // Start the GCM and wait until it is ready.
978 gcm_client()->Start();
982 gcm_client()->Stop();
986 gcm_client()->Start();
990 TEST_F(GCMClientImplStartAndStopTest
, StartAndStopImmediately
) {
991 // Start the GCM and then stop it immediately.
992 gcm_client()->Start();
993 gcm_client()->Stop();
998 TEST_F(GCMClientImplStartAndStopTest
, StartStopAndRestartImmediately
) {
999 // Start the GCM and then stop and restart it immediately.
1000 gcm_client()->Start();
1001 gcm_client()->Stop();
1002 gcm_client()->Start();
1004 PumpLoopUntilIdle();