Add GCMChannelStatusSyncer to schedule requests and enable/disable GCM
[chromium-blink-merge.git] / components / gcm_driver / gcm_driver_desktop_unittest.cc
blob8a2576815587f822eb473a99e2fd407434fb11a1
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_driver_desktop.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/location.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/metrics/field_trial.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_util.h"
18 #include "base/test/test_simple_task_runner.h"
19 #include "base/threading/thread.h"
20 #include "components/gcm_driver/fake_gcm_app_handler.h"
21 #include "components/gcm_driver/fake_gcm_client.h"
22 #include "components/gcm_driver/fake_gcm_client_factory.h"
23 #include "components/gcm_driver/gcm_app_handler.h"
24 #include "components/gcm_driver/gcm_channel_status_request.h"
25 #include "components/gcm_driver/gcm_channel_status_syncer.h"
26 #include "components/gcm_driver/gcm_client_factory.h"
27 #include "components/gcm_driver/gcm_connection_observer.h"
28 #include "components/gcm_driver/proto/gcm_channel_status.pb.h"
29 #include "net/url_request/test_url_fetcher_factory.h"
30 #include "net/url_request/url_fetcher_delegate.h"
31 #include "net/url_request/url_request_context_getter.h"
32 #include "net/url_request/url_request_test_util.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 namespace gcm {
37 namespace {
39 const char kTestAccountID1[] = "user1@example.com";
40 const char kTestAccountID2[] = "user2@example.com";
41 const char kTestAppID1[] = "TestApp1";
42 const char kTestAppID2[] = "TestApp2";
43 const char kUserID1[] = "user1";
45 class FakeGCMConnectionObserver : public GCMConnectionObserver {
46 public:
47 FakeGCMConnectionObserver();
48 virtual ~FakeGCMConnectionObserver();
50 // gcm::GCMConnectionObserver implementation:
51 virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE;
52 virtual void OnDisconnected() OVERRIDE;
54 bool connected() const { return connected_; }
56 private:
57 bool connected_;
60 FakeGCMConnectionObserver::FakeGCMConnectionObserver() : connected_(false) {
63 FakeGCMConnectionObserver::~FakeGCMConnectionObserver() {
66 void FakeGCMConnectionObserver::OnConnected(
67 const net::IPEndPoint& ip_endpoint) {
68 connected_ = true;
71 void FakeGCMConnectionObserver::OnDisconnected() {
72 connected_ = false;
75 void PumpCurrentLoop() {
76 base::MessageLoop::ScopedNestableTaskAllower
77 nestable_task_allower(base::MessageLoop::current());
78 base::RunLoop().RunUntilIdle();
81 void PumpUILoop() {
82 PumpCurrentLoop();
85 std::vector<std::string> ToSenderList(const std::string& sender_ids) {
86 std::vector<std::string> senders;
87 Tokenize(sender_ids, ",", &senders);
88 return senders;
91 } // namespace
93 class GCMDriverTest : public testing::Test {
94 public:
95 enum WaitToFinish {
96 DO_NOT_WAIT,
97 WAIT
100 GCMDriverTest();
101 virtual ~GCMDriverTest();
103 // testing::Test:
104 virtual void SetUp() OVERRIDE;
105 virtual void TearDown() OVERRIDE;
107 GCMDriverDesktop* driver() { return driver_.get(); }
108 FakeGCMAppHandler* gcm_app_handler() { return gcm_app_handler_.get(); }
109 FakeGCMConnectionObserver* gcm_connection_observer() {
110 return gcm_connection_observer_.get();
112 const std::string& registration_id() const { return registration_id_; }
113 GCMClient::Result registration_result() const { return registration_result_; }
114 const std::string& send_message_id() const { return send_message_id_; }
115 GCMClient::Result send_result() const { return send_result_; }
116 GCMClient::Result unregistration_result() const {
117 return unregistration_result_;
120 void PumpIOLoop();
122 void ClearResults();
124 bool HasAppHandlers() const;
125 FakeGCMClient* GetGCMClient();
127 void CreateDriver(FakeGCMClient::StartMode gcm_client_start_mode);
128 void ShutdownDriver();
129 void AddAppHandlers();
130 void RemoveAppHandlers();
132 void SignIn(const std::string& account_id);
133 void SignOut();
135 void Register(const std::string& app_id,
136 const std::vector<std::string>& sender_ids,
137 WaitToFinish wait_to_finish);
138 void Send(const std::string& app_id,
139 const std::string& receiver_id,
140 const GCMClient::OutgoingMessage& message,
141 WaitToFinish wait_to_finish);
142 void Unregister(const std::string& app_id, WaitToFinish wait_to_finish);
144 void WaitForAsyncOperation();
146 private:
147 void RegisterCompleted(const std::string& registration_id,
148 GCMClient::Result result);
149 void SendCompleted(const std::string& message_id, GCMClient::Result result);
150 void UnregisterCompleted(GCMClient::Result result);
152 base::ScopedTempDir temp_dir_;
153 TestingPrefServiceSimple prefs_;
154 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
155 base::MessageLoopForUI message_loop_;
156 base::Thread io_thread_;
157 base::FieldTrialList field_trial_list_;
158 scoped_ptr<GCMDriverDesktop> driver_;
159 scoped_ptr<FakeGCMAppHandler> gcm_app_handler_;
160 scoped_ptr<FakeGCMConnectionObserver> gcm_connection_observer_;
162 base::Closure async_operation_completed_callback_;
164 std::string registration_id_;
165 GCMClient::Result registration_result_;
166 std::string send_message_id_;
167 GCMClient::Result send_result_;
168 GCMClient::Result unregistration_result_;
170 DISALLOW_COPY_AND_ASSIGN(GCMDriverTest);
173 GCMDriverTest::GCMDriverTest()
174 : task_runner_(new base::TestSimpleTaskRunner()),
175 io_thread_("IOThread"),
176 field_trial_list_(NULL),
177 registration_result_(GCMClient::UNKNOWN_ERROR),
178 send_result_(GCMClient::UNKNOWN_ERROR),
179 unregistration_result_(GCMClient::UNKNOWN_ERROR) {
182 GCMDriverTest::~GCMDriverTest() {
185 void GCMDriverTest::SetUp() {
186 GCMChannelStatusSyncer::RegisterPrefs(prefs_.registry());
187 io_thread_.Start();
188 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
191 void GCMDriverTest::TearDown() {
192 if (!driver_)
193 return;
195 ShutdownDriver();
196 driver_.reset();
197 PumpIOLoop();
199 io_thread_.Stop();
202 void GCMDriverTest::PumpIOLoop() {
203 base::RunLoop run_loop;
204 io_thread_.message_loop_proxy()->PostTaskAndReply(
205 FROM_HERE,
206 base::Bind(&PumpCurrentLoop),
207 run_loop.QuitClosure());
208 run_loop.Run();
211 void GCMDriverTest::ClearResults() {
212 registration_id_.clear();
213 registration_result_ = GCMClient::UNKNOWN_ERROR;
215 send_message_id_.clear();
216 send_result_ = GCMClient::UNKNOWN_ERROR;
218 unregistration_result_ = GCMClient::UNKNOWN_ERROR;
221 bool GCMDriverTest::HasAppHandlers() const {
222 return !driver_->app_handlers().empty();
225 FakeGCMClient* GCMDriverTest::GetGCMClient() {
226 return static_cast<FakeGCMClient*>(driver_->GetGCMClientForTesting());
229 void GCMDriverTest::CreateDriver(
230 FakeGCMClient::StartMode gcm_client_start_mode) {
231 scoped_refptr<net::URLRequestContextGetter> request_context =
232 new net::TestURLRequestContextGetter(io_thread_.message_loop_proxy());
233 // TODO(johnme): Need equivalent test coverage of GCMDriverAndroid.
234 driver_.reset(new GCMDriverDesktop(
235 scoped_ptr<GCMClientFactory>(new FakeGCMClientFactory(
236 gcm_client_start_mode,
237 base::MessageLoopProxy::current(),
238 io_thread_.message_loop_proxy())).Pass(),
239 GCMClient::ChromeBuildInfo(),
240 &prefs_,
241 temp_dir_.path(),
242 request_context,
243 base::MessageLoopProxy::current(),
244 io_thread_.message_loop_proxy(),
245 task_runner_));
247 gcm_app_handler_.reset(new FakeGCMAppHandler);
248 gcm_connection_observer_.reset(new FakeGCMConnectionObserver);
250 driver_->AddConnectionObserver(gcm_connection_observer_.get());
253 void GCMDriverTest::ShutdownDriver() {
254 if (gcm_connection_observer())
255 driver()->RemoveConnectionObserver(gcm_connection_observer());
256 driver()->Shutdown();
259 void GCMDriverTest::AddAppHandlers() {
260 driver_->AddAppHandler(kTestAppID1, gcm_app_handler_.get());
261 driver_->AddAppHandler(kTestAppID2, gcm_app_handler_.get());
264 void GCMDriverTest::RemoveAppHandlers() {
265 driver_->RemoveAppHandler(kTestAppID1);
266 driver_->RemoveAppHandler(kTestAppID2);
269 void GCMDriverTest::SignIn(const std::string& account_id) {
270 driver_->OnSignedIn();
271 PumpIOLoop();
272 PumpUILoop();
275 void GCMDriverTest::SignOut() {
276 driver_->OnSignedOut();
277 PumpIOLoop();
278 PumpUILoop();
281 void GCMDriverTest::Register(const std::string& app_id,
282 const std::vector<std::string>& sender_ids,
283 WaitToFinish wait_to_finish) {
284 base::RunLoop run_loop;
285 async_operation_completed_callback_ = run_loop.QuitClosure();
286 driver_->Register(app_id,
287 sender_ids,
288 base::Bind(&GCMDriverTest::RegisterCompleted,
289 base::Unretained(this)));
290 if (wait_to_finish == WAIT)
291 run_loop.Run();
294 void GCMDriverTest::Send(const std::string& app_id,
295 const std::string& receiver_id,
296 const GCMClient::OutgoingMessage& message,
297 WaitToFinish wait_to_finish) {
298 base::RunLoop run_loop;
299 async_operation_completed_callback_ = run_loop.QuitClosure();
300 driver_->Send(app_id,
301 receiver_id,
302 message,
303 base::Bind(&GCMDriverTest::SendCompleted,
304 base::Unretained(this)));
305 if (wait_to_finish == WAIT)
306 run_loop.Run();
309 void GCMDriverTest::Unregister(const std::string& app_id,
310 WaitToFinish wait_to_finish) {
311 base::RunLoop run_loop;
312 async_operation_completed_callback_ = run_loop.QuitClosure();
313 driver_->Unregister(app_id,
314 base::Bind(&GCMDriverTest::UnregisterCompleted,
315 base::Unretained(this)));
316 if (wait_to_finish == WAIT)
317 run_loop.Run();
320 void GCMDriverTest::WaitForAsyncOperation() {
321 base::RunLoop run_loop;
322 async_operation_completed_callback_ = run_loop.QuitClosure();
323 run_loop.Run();
326 void GCMDriverTest::RegisterCompleted(const std::string& registration_id,
327 GCMClient::Result result) {
328 registration_id_ = registration_id;
329 registration_result_ = result;
330 if (!async_operation_completed_callback_.is_null())
331 async_operation_completed_callback_.Run();
334 void GCMDriverTest::SendCompleted(const std::string& message_id,
335 GCMClient::Result result) {
336 send_message_id_ = message_id;
337 send_result_ = result;
338 if (!async_operation_completed_callback_.is_null())
339 async_operation_completed_callback_.Run();
342 void GCMDriverTest::UnregisterCompleted(GCMClient::Result result) {
343 unregistration_result_ = result;
344 if (!async_operation_completed_callback_.is_null())
345 async_operation_completed_callback_.Run();
348 TEST_F(GCMDriverTest, Create) {
349 // Create GCMDriver first. GCM is not started.
350 CreateDriver(FakeGCMClient::NO_DELAY_START);
351 EXPECT_FALSE(driver()->IsStarted());
353 // Sign in. GCM is still not started.
354 SignIn(kTestAccountID1);
355 EXPECT_FALSE(driver()->IsStarted());
356 EXPECT_FALSE(driver()->IsConnected());
357 EXPECT_FALSE(gcm_connection_observer()->connected());
359 // GCM will be started only after both sign-in and app handler being added.
360 AddAppHandlers();
361 EXPECT_TRUE(driver()->IsStarted());
362 PumpIOLoop();
363 EXPECT_TRUE(driver()->IsConnected());
364 EXPECT_TRUE(gcm_connection_observer()->connected());
367 TEST_F(GCMDriverTest, CreateByFieldTrial) {
368 // Turn on the signal to drop sign-in enforcement.
369 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled"));
371 // Create GCMDriver first. GCM is not started.
372 CreateDriver(FakeGCMClient::NO_DELAY_START);
373 EXPECT_FALSE(driver()->IsStarted());
374 EXPECT_FALSE(driver()->IsConnected());
375 EXPECT_FALSE(gcm_connection_observer()->connected());
377 // GCM will be started after app handler is added.
378 AddAppHandlers();
379 EXPECT_TRUE(driver()->IsStarted());
380 PumpIOLoop();
381 EXPECT_TRUE(driver()->IsConnected());
382 EXPECT_TRUE(gcm_connection_observer()->connected());
384 // Sign-in will not affect GCM state.
385 SignIn(kTestAccountID1);
386 PumpIOLoop();
387 EXPECT_TRUE(driver()->IsStarted());
388 EXPECT_TRUE(driver()->IsConnected());
390 // Sign-out will not affect GCM state.
391 SignOut();
392 PumpIOLoop();
393 EXPECT_TRUE(driver()->IsStarted());
394 EXPECT_TRUE(driver()->IsConnected());
397 TEST_F(GCMDriverTest, Shutdown) {
398 CreateDriver(FakeGCMClient::NO_DELAY_START);
399 EXPECT_FALSE(HasAppHandlers());
401 AddAppHandlers();
402 EXPECT_TRUE(HasAppHandlers());
404 ShutdownDriver();
405 EXPECT_FALSE(HasAppHandlers());
406 EXPECT_FALSE(driver()->IsConnected());
407 EXPECT_FALSE(gcm_connection_observer()->connected());
410 TEST_F(GCMDriverTest, SignInAndSignOutOnGCMEnabled) {
411 // By default, GCM is enabled.
412 CreateDriver(FakeGCMClient::NO_DELAY_START);
413 AddAppHandlers();
415 // GCMClient should be started after sign-in.
416 SignIn(kTestAccountID1);
417 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
419 // GCMClient should be checked out after sign-out.
420 SignOut();
421 EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
424 TEST_F(GCMDriverTest, SignInAndSignOutOnGCMDisabled) {
425 // By default, GCM is enabled.
426 CreateDriver(FakeGCMClient::NO_DELAY_START);
427 AddAppHandlers();
429 // Disable GCM.
430 driver()->Disable();
432 // GCMClient should not be started after sign-in.
433 SignIn(kTestAccountID1);
434 EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status());
436 // Check-out should still be performed after sign-out.
437 SignOut();
438 EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
441 TEST_F(GCMDriverTest, SignOutAndThenSignIn) {
442 CreateDriver(FakeGCMClient::NO_DELAY_START);
443 AddAppHandlers();
445 // GCMClient should be started after sign-in.
446 SignIn(kTestAccountID1);
447 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
449 // GCMClient should be checked out after sign-out.
450 SignOut();
451 EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
453 // Sign-in with a different account.
454 SignIn(kTestAccountID2);
456 // GCMClient should be started again.
457 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
460 TEST_F(GCMDriverTest, DisableAndReenableGCM) {
461 CreateDriver(FakeGCMClient::NO_DELAY_START);
462 AddAppHandlers();
463 SignIn(kTestAccountID1);
465 // GCMClient should be started.
466 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
468 // Disables the GCM.
469 driver()->Disable();
470 PumpIOLoop();
471 PumpUILoop();
473 // GCMClient should be stopped.
474 EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
476 // Enables the GCM.
477 driver()->Enable();
478 PumpIOLoop();
479 PumpUILoop();
481 // GCMClient should be started.
482 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
484 // Disables the GCM.
485 driver()->Disable();
486 PumpIOLoop();
487 PumpUILoop();
489 // GCMClient should be stopped.
490 EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
492 // Sign out.
493 SignOut();
495 // GCMClient should be checked out.
496 EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
499 TEST_F(GCMDriverTest, StartOrStopGCMOnDemand) {
500 CreateDriver(FakeGCMClient::NO_DELAY_START);
501 SignIn(kTestAccountID1);
503 // GCMClient is not started.
504 EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status());
506 // GCMClient is started after an app handler has been added.
507 driver()->AddAppHandler(kTestAppID1, gcm_app_handler());
508 PumpIOLoop();
509 PumpUILoop();
510 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
512 // Add another app handler.
513 driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
514 PumpIOLoop();
515 PumpUILoop();
516 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
518 // GCMClient remains active after one app handler is gone.
519 driver()->RemoveAppHandler(kTestAppID1);
520 PumpIOLoop();
521 PumpUILoop();
522 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
524 // GCMClient should be stopped after the last app handler is gone.
525 driver()->RemoveAppHandler(kTestAppID2);
526 PumpIOLoop();
527 PumpUILoop();
528 EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
530 // GCMClient is restarted after an app handler has been added.
531 driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
532 PumpIOLoop();
533 PumpUILoop();
534 EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
537 TEST_F(GCMDriverTest, RegisterFailed) {
538 std::vector<std::string> sender_ids;
539 sender_ids.push_back("sender1");
541 CreateDriver(FakeGCMClient::NO_DELAY_START);
543 // Registration fails when GCM is disabled.
544 driver()->Disable();
545 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
546 EXPECT_TRUE(registration_id().empty());
547 EXPECT_EQ(GCMClient::GCM_DISABLED, registration_result());
549 ClearResults();
551 // Registration fails when the sign-in does not occur.
552 driver()->Enable();
553 AddAppHandlers();
554 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
555 EXPECT_TRUE(registration_id().empty());
556 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, registration_result());
558 ClearResults();
560 // Registration fails when the no app handler is added.
561 RemoveAppHandlers();
562 SignIn(kTestAccountID1);
563 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
564 EXPECT_TRUE(registration_id().empty());
565 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());
568 TEST_F(GCMDriverTest, UnregisterFailed) {
569 CreateDriver(FakeGCMClient::NO_DELAY_START);
571 // Unregistration fails when GCM is disabled.
572 driver()->Disable();
573 Unregister(kTestAppID1, GCMDriverTest::WAIT);
574 EXPECT_EQ(GCMClient::GCM_DISABLED, unregistration_result());
576 ClearResults();
578 // Unregistration fails when the sign-in does not occur.
579 driver()->Enable();
580 AddAppHandlers();
581 Unregister(kTestAppID1, GCMDriverTest::WAIT);
582 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, unregistration_result());
584 ClearResults();
586 // Unregistration fails when the no app handler is added.
587 RemoveAppHandlers();
588 SignIn(kTestAccountID1);
589 Unregister(kTestAppID1, GCMDriverTest::WAIT);
590 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, unregistration_result());
593 TEST_F(GCMDriverTest, SendFailed) {
594 GCMClient::OutgoingMessage message;
595 message.id = "1";
596 message.data["key1"] = "value1";
598 CreateDriver(FakeGCMClient::NO_DELAY_START);
600 // Sending fails when GCM is disabled.
601 driver()->Disable();
602 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
603 EXPECT_TRUE(send_message_id().empty());
604 EXPECT_EQ(GCMClient::GCM_DISABLED, send_result());
606 ClearResults();
608 // Sending fails when the sign-in does not occur.
609 driver()->Enable();
610 AddAppHandlers();
611 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
612 EXPECT_TRUE(send_message_id().empty());
613 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result());
615 ClearResults();
617 // Sending fails when the no app handler is added.
618 RemoveAppHandlers();
619 SignIn(kTestAccountID1);
620 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
621 EXPECT_TRUE(send_message_id().empty());
622 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());
625 TEST_F(GCMDriverTest, GCMClientNotReadyBeforeRegistration) {
626 // Make GCMClient not ready initially.
627 CreateDriver(FakeGCMClient::DELAY_START);
628 SignIn(kTestAccountID1);
629 AddAppHandlers();
631 // The registration is on hold until GCMClient is ready.
632 std::vector<std::string> sender_ids;
633 sender_ids.push_back("sender1");
634 Register(kTestAppID1,
635 sender_ids,
636 GCMDriverTest::DO_NOT_WAIT);
637 PumpIOLoop();
638 PumpUILoop();
639 EXPECT_TRUE(registration_id().empty());
640 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());
642 // Register operation will be invoked after GCMClient becomes ready.
643 GetGCMClient()->PerformDelayedLoading();
644 WaitForAsyncOperation();
645 EXPECT_FALSE(registration_id().empty());
646 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
649 TEST_F(GCMDriverTest, GCMClientNotReadyBeforeSending) {
650 // Make GCMClient not ready initially.
651 CreateDriver(FakeGCMClient::DELAY_START);
652 SignIn(kTestAccountID1);
653 AddAppHandlers();
655 // The sending is on hold until GCMClient is ready.
656 GCMClient::OutgoingMessage message;
657 message.id = "1";
658 message.data["key1"] = "value1";
659 message.data["key2"] = "value2";
660 Send(kTestAppID1, kUserID1, message, GCMDriverTest::DO_NOT_WAIT);
661 PumpIOLoop();
662 PumpUILoop();
664 EXPECT_TRUE(send_message_id().empty());
665 EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());
667 // Send operation will be invoked after GCMClient becomes ready.
668 GetGCMClient()->PerformDelayedLoading();
669 WaitForAsyncOperation();
670 EXPECT_EQ(message.id, send_message_id());
671 EXPECT_EQ(GCMClient::SUCCESS, send_result());
674 // Tests a single instance of GCMDriver.
675 class GCMDriverFunctionalTest : public GCMDriverTest {
676 public:
677 GCMDriverFunctionalTest();
678 virtual ~GCMDriverFunctionalTest();
680 // GCMDriverTest:
681 virtual void SetUp() OVERRIDE;
683 private:
684 DISALLOW_COPY_AND_ASSIGN(GCMDriverFunctionalTest);
687 GCMDriverFunctionalTest::GCMDriverFunctionalTest() {
690 GCMDriverFunctionalTest::~GCMDriverFunctionalTest() {
693 void GCMDriverFunctionalTest::SetUp() {
694 GCMDriverTest::SetUp();
696 CreateDriver(FakeGCMClient::NO_DELAY_START);
697 AddAppHandlers();
698 SignIn(kTestAccountID1);
701 TEST_F(GCMDriverFunctionalTest, Register) {
702 std::vector<std::string> sender_ids;
703 sender_ids.push_back("sender1");
704 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
705 const std::string expected_registration_id =
706 FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
708 EXPECT_EQ(expected_registration_id, registration_id());
709 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
712 TEST_F(GCMDriverFunctionalTest, RegisterError) {
713 std::vector<std::string> sender_ids;
714 sender_ids.push_back("sender1@error");
715 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
717 EXPECT_TRUE(registration_id().empty());
718 EXPECT_NE(GCMClient::SUCCESS, registration_result());
721 TEST_F(GCMDriverFunctionalTest, RegisterAgainWithSameSenderIDs) {
722 std::vector<std::string> sender_ids;
723 sender_ids.push_back("sender1");
724 sender_ids.push_back("sender2");
725 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
726 const std::string expected_registration_id =
727 FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
729 EXPECT_EQ(expected_registration_id, registration_id());
730 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
732 // Clears the results the would be set by the Register callback in preparation
733 // to call register 2nd time.
734 ClearResults();
736 // Calling register 2nd time with the same set of sender IDs but different
737 // ordering will get back the same registration ID.
738 std::vector<std::string> another_sender_ids;
739 another_sender_ids.push_back("sender2");
740 another_sender_ids.push_back("sender1");
741 Register(kTestAppID1, another_sender_ids, GCMDriverTest::WAIT);
743 EXPECT_EQ(expected_registration_id, registration_id());
744 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
747 TEST_F(GCMDriverFunctionalTest, RegisterAgainWithDifferentSenderIDs) {
748 std::vector<std::string> sender_ids;
749 sender_ids.push_back("sender1");
750 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
751 const std::string expected_registration_id =
752 FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
754 EXPECT_EQ(expected_registration_id, registration_id());
755 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
757 // Make sender IDs different.
758 sender_ids.push_back("sender2");
759 const std::string expected_registration_id2 =
760 FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
762 // Calling register 2nd time with the different sender IDs will get back a new
763 // registration ID.
764 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
765 EXPECT_EQ(expected_registration_id2, registration_id());
766 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
769 TEST_F(GCMDriverFunctionalTest, RegisterAfterSignOut) {
770 // This will trigger check-out.
771 SignOut();
773 std::vector<std::string> sender_ids;
774 sender_ids.push_back("sender1");
775 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
777 EXPECT_TRUE(registration_id().empty());
778 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, registration_result());
781 TEST_F(GCMDriverFunctionalTest, UnregisterExplicitly) {
782 std::vector<std::string> sender_ids;
783 sender_ids.push_back("sender1");
784 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
786 EXPECT_FALSE(registration_id().empty());
787 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
789 Unregister(kTestAppID1, GCMDriverTest::WAIT);
791 EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
794 TEST_F(GCMDriverFunctionalTest, UnregisterWhenAsyncOperationPending) {
795 std::vector<std::string> sender_ids;
796 sender_ids.push_back("sender1");
797 // First start registration without waiting for it to complete.
798 Register(kTestAppID1,
799 sender_ids,
800 GCMDriverTest::DO_NOT_WAIT);
802 // Test that unregistration fails with async operation pending when there is a
803 // registration already in progress.
804 Unregister(kTestAppID1, GCMDriverTest::WAIT);
805 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
806 unregistration_result());
808 // Complete the unregistration.
809 WaitForAsyncOperation();
810 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
812 // Start unregistration without waiting for it to complete. This time no async
813 // operation is pending.
814 Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);
816 // Test that unregistration fails with async operation pending when there is
817 // an unregistration already in progress.
818 Unregister(kTestAppID1, GCMDriverTest::WAIT);
819 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
820 unregistration_result());
821 ClearResults();
823 // Complete unregistration.
824 WaitForAsyncOperation();
825 EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
828 TEST_F(GCMDriverFunctionalTest, RegisterWhenAsyncOperationPending) {
829 std::vector<std::string> sender_ids;
830 sender_ids.push_back("sender1");
831 // First start registration without waiting for it to complete.
832 Register(kTestAppID1,
833 sender_ids,
834 GCMDriverTest::DO_NOT_WAIT);
836 // Test that registration fails with async operation pending when there is a
837 // registration already in progress.
838 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
839 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
840 registration_result());
841 ClearResults();
843 // Complete the registration.
844 WaitForAsyncOperation();
845 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
847 // Start unregistration without waiting for it to complete. This time no async
848 // operation is pending.
849 Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);
851 // Test that registration fails with async operation pending when there is an
852 // unregistration already in progress.
853 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
854 EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
855 registration_result());
857 // Complete the first unregistration expecting success.
858 WaitForAsyncOperation();
859 EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
861 // Test that it is ok to register again after unregistration.
862 Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
863 EXPECT_EQ(GCMClient::SUCCESS, registration_result());
866 TEST_F(GCMDriverFunctionalTest, Send) {
867 GCMClient::OutgoingMessage message;
868 message.id = "1@ack";
869 message.data["key1"] = "value1";
870 message.data["key2"] = "value2";
871 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
873 EXPECT_EQ(message.id, send_message_id());
874 EXPECT_EQ(GCMClient::SUCCESS, send_result());
876 gcm_app_handler()->WaitForNotification();
877 EXPECT_EQ(message.id, gcm_app_handler()->acked_message_id());
878 EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
881 TEST_F(GCMDriverFunctionalTest, SendAfterSignOut) {
882 // This will trigger check-out.
883 SignOut();
885 GCMClient::OutgoingMessage message;
886 message.id = "1";
887 message.data["key1"] = "value1";
888 message.data["key2"] = "value2";
889 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
891 EXPECT_TRUE(send_message_id().empty());
892 EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result());
895 TEST_F(GCMDriverFunctionalTest, SendError) {
896 GCMClient::OutgoingMessage message;
897 // Embedding error in id will tell the mock to simulate the send error.
898 message.id = "1@error";
899 message.data["key1"] = "value1";
900 message.data["key2"] = "value2";
901 Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
903 EXPECT_EQ(message.id, send_message_id());
904 EXPECT_EQ(GCMClient::SUCCESS, send_result());
906 // Wait for the send error.
907 gcm_app_handler()->WaitForNotification();
908 EXPECT_EQ(FakeGCMAppHandler::SEND_ERROR_EVENT,
909 gcm_app_handler()->received_event());
910 EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
911 EXPECT_EQ(message.id,
912 gcm_app_handler()->send_error_details().message_id);
913 EXPECT_NE(GCMClient::SUCCESS,
914 gcm_app_handler()->send_error_details().result);
915 EXPECT_EQ(message.data,
916 gcm_app_handler()->send_error_details().additional_data);
919 TEST_F(GCMDriverFunctionalTest, MessageReceived) {
920 Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
921 GCMClient::IncomingMessage message;
922 message.data["key1"] = "value1";
923 message.data["key2"] = "value2";
924 message.sender_id = "sender";
925 GetGCMClient()->ReceiveMessage(kTestAppID1, message);
926 gcm_app_handler()->WaitForNotification();
927 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
928 gcm_app_handler()->received_event());
929 EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
930 EXPECT_EQ(message.data, gcm_app_handler()->message().data);
931 EXPECT_TRUE(gcm_app_handler()->message().collapse_key.empty());
932 EXPECT_EQ(message.sender_id, gcm_app_handler()->message().sender_id);
935 TEST_F(GCMDriverFunctionalTest, MessageWithCollapseKeyReceived) {
936 Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
937 GCMClient::IncomingMessage message;
938 message.data["key1"] = "value1";
939 message.collapse_key = "collapse_key_value";
940 message.sender_id = "sender";
941 GetGCMClient()->ReceiveMessage(kTestAppID1, message);
942 gcm_app_handler()->WaitForNotification();
943 EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
944 gcm_app_handler()->received_event());
945 EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
946 EXPECT_EQ(message.data, gcm_app_handler()->message().data);
947 EXPECT_EQ(message.collapse_key,
948 gcm_app_handler()->message().collapse_key);
951 TEST_F(GCMDriverFunctionalTest, MessagesDeleted) {
952 GetGCMClient()->DeleteMessages(kTestAppID1);
953 gcm_app_handler()->WaitForNotification();
954 EXPECT_EQ(FakeGCMAppHandler::MESSAGES_DELETED_EVENT,
955 gcm_app_handler()->received_event());
956 EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
959 // Tests a single instance of GCMDriver.
960 class GCMChannelStatusSyncerTest : public GCMDriverTest {
961 public:
962 GCMChannelStatusSyncerTest();
963 virtual ~GCMChannelStatusSyncerTest();
965 // testing::Test:
966 virtual void SetUp() OVERRIDE;
968 void CompleteGCMChannelStatusRequest(bool enabled, int poll_interval_seconds);
969 bool CompareDelaySeconds(bool expected_delay_seconds,
970 bool actual_delay_seconds);
972 GCMChannelStatusSyncer* syncer() {
973 return driver()->gcm_channel_status_syncer_for_testing();
976 private:
977 net::TestURLFetcherFactory url_fetcher_factory_;
979 DISALLOW_COPY_AND_ASSIGN(GCMChannelStatusSyncerTest);
982 GCMChannelStatusSyncerTest::GCMChannelStatusSyncerTest() {
985 GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() {
988 void GCMChannelStatusSyncerTest::SetUp() {
989 GCMDriverTest::SetUp();
991 // Turn on all-user support.
992 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled"));
995 void GCMChannelStatusSyncerTest::CompleteGCMChannelStatusRequest(
996 bool enabled, int poll_interval_seconds) {
997 gcm_proto::ExperimentStatusResponse response_proto;
998 response_proto.mutable_gcm_channel()->set_enabled(enabled);
1000 if (poll_interval_seconds)
1001 response_proto.set_poll_interval_seconds(poll_interval_seconds);
1003 std::string response_string;
1004 response_proto.SerializeToString(&response_string);
1006 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
1007 ASSERT_TRUE(fetcher);
1008 fetcher->set_response_code(net::HTTP_OK);
1009 fetcher->SetResponseString(response_string);
1010 fetcher->delegate()->OnURLFetchComplete(fetcher);
1013 bool GCMChannelStatusSyncerTest::CompareDelaySeconds(
1014 bool expected_delay_seconds, bool actual_delay_seconds) {
1015 // Most of time, the actual delay should not be smaller than the expected
1016 // delay.
1017 if (actual_delay_seconds >= expected_delay_seconds)
1018 return true;
1019 // It is also OK that the actual delay is a bit smaller than the expected
1020 // delay in case that the test runs slowly.
1021 return expected_delay_seconds - actual_delay_seconds < 30;
1024 TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) {
1025 // Create GCMDriver first. GCM is not started.
1026 CreateDriver(FakeGCMClient::NO_DELAY_START);
1027 EXPECT_FALSE(driver()->IsStarted());
1029 // By default, GCM is enabled.
1030 EXPECT_TRUE(driver()->gcm_enabled());
1031 EXPECT_TRUE(syncer()->gcm_enabled());
1033 // Remove delay such that the request could be executed immediately.
1034 syncer()->set_delay_removed_for_testing(true);
1036 // GCM will be started after app handler is added.
1037 AddAppHandlers();
1038 EXPECT_TRUE(driver()->IsStarted());
1040 // GCM is still enabled at this point.
1041 EXPECT_TRUE(driver()->gcm_enabled());
1042 EXPECT_TRUE(syncer()->gcm_enabled());
1044 // Wait until the GCM channel status request gets triggered.
1045 PumpUILoop();
1047 // Complete the request that disables the GCM.
1048 CompleteGCMChannelStatusRequest(false, 0);
1049 EXPECT_FALSE(driver()->gcm_enabled());
1050 EXPECT_FALSE(syncer()->gcm_enabled());
1051 EXPECT_FALSE(driver()->IsStarted());
1053 // Wait until next GCM channel status request gets triggered.
1054 PumpUILoop();
1056 // Complete the request that enables the GCM.
1057 CompleteGCMChannelStatusRequest(true, 0);
1058 EXPECT_TRUE(driver()->gcm_enabled());
1059 EXPECT_TRUE(syncer()->gcm_enabled());
1060 EXPECT_TRUE(driver()->IsStarted());
1063 TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) {
1064 // Create GCMDriver first. GCM is not started.
1065 CreateDriver(FakeGCMClient::NO_DELAY_START);
1066 EXPECT_FALSE(driver()->IsStarted());
1068 // By default, GCM is enabled.
1069 EXPECT_TRUE(driver()->gcm_enabled());
1070 EXPECT_TRUE(syncer()->gcm_enabled());
1072 // Remove delay such that the request could be executed immediately.
1073 syncer()->set_delay_removed_for_testing(true);
1075 // GCM will be started after app handler is added.
1076 AddAppHandlers();
1077 EXPECT_TRUE(driver()->IsStarted());
1079 // GCM is still enabled at this point.
1080 EXPECT_TRUE(driver()->gcm_enabled());
1081 EXPECT_TRUE(syncer()->gcm_enabled());
1083 // Wait until the GCM channel status request gets triggered.
1084 PumpUILoop();
1086 // Complete the request that disables the GCM.
1087 CompleteGCMChannelStatusRequest(false, 0);
1088 EXPECT_FALSE(driver()->gcm_enabled());
1089 EXPECT_FALSE(syncer()->gcm_enabled());
1090 EXPECT_FALSE(driver()->IsStarted());
1092 // Simulate browser start by recreating GCMDriver.
1093 ShutdownDriver();
1094 CreateDriver(FakeGCMClient::NO_DELAY_START);
1096 // GCM is still disabled.
1097 EXPECT_FALSE(driver()->gcm_enabled());
1098 EXPECT_FALSE(syncer()->gcm_enabled());
1099 EXPECT_FALSE(driver()->IsStarted());
1101 AddAppHandlers();
1102 EXPECT_FALSE(driver()->gcm_enabled());
1103 EXPECT_FALSE(syncer()->gcm_enabled());
1104 EXPECT_FALSE(driver()->IsStarted());
1107 TEST_F(GCMChannelStatusSyncerTest, FirstTimePolling) {
1108 // Start GCM.
1109 CreateDriver(FakeGCMClient::NO_DELAY_START);
1110 AddAppHandlers();
1112 // The 1st request should be triggered shortly without jittering.
1113 EXPECT_EQ(GCMChannelStatusSyncer::first_time_delay_seconds(),
1114 syncer()->current_request_delay_interval().InSeconds());
1117 TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithDefaultInterval) {
1118 // Create GCMDriver first. GCM is not started.
1119 CreateDriver(FakeGCMClient::NO_DELAY_START);
1121 // Remove delay such that the request could be executed immediately.
1122 syncer()->set_delay_removed_for_testing(true);
1124 // Now GCM is started.
1125 AddAppHandlers();
1127 // Wait until the GCM channel status request gets triggered.
1128 PumpUILoop();
1130 // Keep delay such that we can find out the computed delay time.
1131 syncer()->set_delay_removed_for_testing(false);
1133 // Complete the request. The default interval is intact.
1134 CompleteGCMChannelStatusRequest(true, 0);
1136 // The next request should be scheduled at the expected default interval.
1137 int64 actual_delay_seconds =
1138 syncer()->current_request_delay_interval().InSeconds();
1139 int64 expected_delay_seconds =
1140 GCMChannelStatusRequest::default_poll_interval_seconds();
1141 EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1142 << "expected delay: " << expected_delay_seconds
1143 << " actual delay: " << actual_delay_seconds;
1145 // Simulate browser start by recreating GCMDriver.
1146 ShutdownDriver();
1147 CreateDriver(FakeGCMClient::NO_DELAY_START);
1148 AddAppHandlers();
1150 // After start-up, the request should still be scheduled at the expected
1151 // default interval.
1152 actual_delay_seconds =
1153 syncer()->current_request_delay_interval().InSeconds();
1154 EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1155 << "expected delay: " << expected_delay_seconds
1156 << " actual delay: " << actual_delay_seconds;
1159 TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithUpdatedInterval) {
1160 // Create GCMDriver first. GCM is not started.
1161 CreateDriver(FakeGCMClient::NO_DELAY_START);
1163 // Remove delay such that the request could be executed immediately.
1164 syncer()->set_delay_removed_for_testing(true);
1166 // Now GCM is started.
1167 AddAppHandlers();
1169 // Wait until the GCM channel status request gets triggered.
1170 PumpUILoop();
1172 // Keep delay such that we can find out the computed delay time.
1173 syncer()->set_delay_removed_for_testing(false);
1175 // Complete the request. The interval is being changed.
1176 int new_poll_interval_seconds =
1177 GCMChannelStatusRequest::default_poll_interval_seconds() * 2;
1178 CompleteGCMChannelStatusRequest(true, new_poll_interval_seconds);
1180 // The next request should be scheduled at the expected updated interval.
1181 int64 actual_delay_seconds =
1182 syncer()->current_request_delay_interval().InSeconds();
1183 int64 expected_delay_seconds = new_poll_interval_seconds;
1184 EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1185 << "expected delay: " << expected_delay_seconds
1186 << " actual delay: " << actual_delay_seconds;
1188 // Simulate browser start by recreating GCMDriver.
1189 ShutdownDriver();
1190 CreateDriver(FakeGCMClient::NO_DELAY_START);
1191 AddAppHandlers();
1193 // After start-up, the request should still be scheduled at the expected
1194 // updated interval.
1195 actual_delay_seconds =
1196 syncer()->current_request_delay_interval().InSeconds();
1197 EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1198 << "expected delay: " << expected_delay_seconds
1199 << " actual delay: " << actual_delay_seconds;
1202 } // namespace gcm