gcm_driver_desktop_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/gcm_driver/gcm_driver_desktop.h"
6
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"
34
35namespace gcm {
36
37namespace {
38
39const char kTestAccountID1[] = "user1@example.com";
40const char kTestAccountID2[] = "user2@example.com";
41const char kTestAppID1[] = "TestApp1";
42const char kTestAppID2[] = "TestApp2";
43const char kUserID1[] = "user1";
44
45class FakeGCMConnectionObserver : public GCMConnectionObserver {
46 public:
47  FakeGCMConnectionObserver();
48  virtual ~FakeGCMConnectionObserver();
49
50  // gcm::GCMConnectionObserver implementation:
51  virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE;
52  virtual void OnDisconnected() OVERRIDE;
53
54  bool connected() const { return connected_; }
55
56 private:
57  bool connected_;
58};
59
60FakeGCMConnectionObserver::FakeGCMConnectionObserver() : connected_(false) {
61}
62
63FakeGCMConnectionObserver::~FakeGCMConnectionObserver() {
64}
65
66void FakeGCMConnectionObserver::OnConnected(
67    const net::IPEndPoint& ip_endpoint) {
68  connected_ = true;
69}
70
71void FakeGCMConnectionObserver::OnDisconnected() {
72  connected_ = false;
73}
74
75void PumpCurrentLoop() {
76  base::MessageLoop::ScopedNestableTaskAllower
77      nestable_task_allower(base::MessageLoop::current());
78  base::RunLoop().RunUntilIdle();
79}
80
81void PumpUILoop() {
82  PumpCurrentLoop();
83}
84
85std::vector<std::string> ToSenderList(const std::string& sender_ids) {
86  std::vector<std::string> senders;
87  Tokenize(sender_ids, ",", &senders);
88  return senders;
89}
90
91}  // namespace
92
93class GCMDriverTest : public testing::Test {
94 public:
95  enum WaitToFinish {
96    DO_NOT_WAIT,
97    WAIT
98  };
99
100  GCMDriverTest();
101  virtual ~GCMDriverTest();
102
103  // testing::Test:
104  virtual void SetUp() OVERRIDE;
105  virtual void TearDown() OVERRIDE;
106
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();
111  }
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_;
118  }
119
120  void PumpIOLoop();
121
122  void ClearResults();
123
124  bool HasAppHandlers() const;
125  FakeGCMClient* GetGCMClient();
126
127  void CreateDriver(FakeGCMClient::StartMode gcm_client_start_mode);
128  void ShutdownDriver();
129  void AddAppHandlers();
130  void RemoveAppHandlers();
131
132  void SignIn(const std::string& account_id);
133  void SignOut();
134
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);
143
144  void WaitForAsyncOperation();
145
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);
151
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_;
161
162  base::Closure async_operation_completed_callback_;
163
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_;
169
170  DISALLOW_COPY_AND_ASSIGN(GCMDriverTest);
171};
172
173GCMDriverTest::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) {
180}
181
182GCMDriverTest::~GCMDriverTest() {
183}
184
185void GCMDriverTest::SetUp() {
186  GCMChannelStatusSyncer::RegisterPrefs(prefs_.registry());
187  io_thread_.Start();
188  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
189}
190
191void GCMDriverTest::TearDown() {
192  if (!driver_)
193    return;
194
195  ShutdownDriver();
196  driver_.reset();
197  PumpIOLoop();
198
199  io_thread_.Stop();
200}
201
202void 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();
209}
210
211void GCMDriverTest::ClearResults() {
212  registration_id_.clear();
213  registration_result_ = GCMClient::UNKNOWN_ERROR;
214
215  send_message_id_.clear();
216  send_result_ = GCMClient::UNKNOWN_ERROR;
217
218  unregistration_result_ = GCMClient::UNKNOWN_ERROR;
219}
220
221bool GCMDriverTest::HasAppHandlers() const {
222  return !driver_->app_handlers().empty();
223}
224
225FakeGCMClient* GCMDriverTest::GetGCMClient() {
226  return static_cast<FakeGCMClient*>(driver_->GetGCMClientForTesting());
227}
228
229void 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_));
246
247  gcm_app_handler_.reset(new FakeGCMAppHandler);
248  gcm_connection_observer_.reset(new FakeGCMConnectionObserver);
249
250  driver_->AddConnectionObserver(gcm_connection_observer_.get());
251}
252
253void GCMDriverTest::ShutdownDriver() {
254  if (gcm_connection_observer())
255    driver()->RemoveConnectionObserver(gcm_connection_observer());
256  driver()->Shutdown();
257}
258
259void GCMDriverTest::AddAppHandlers() {
260  driver_->AddAppHandler(kTestAppID1, gcm_app_handler_.get());
261  driver_->AddAppHandler(kTestAppID2, gcm_app_handler_.get());
262}
263
264void GCMDriverTest::RemoveAppHandlers() {
265  driver_->RemoveAppHandler(kTestAppID1);
266  driver_->RemoveAppHandler(kTestAppID2);
267}
268
269void GCMDriverTest::SignIn(const std::string& account_id) {
270  driver_->OnSignedIn();
271  PumpIOLoop();
272  PumpUILoop();
273}
274
275void GCMDriverTest::SignOut() {
276  driver_->Purge();
277  PumpIOLoop();
278  PumpUILoop();
279}
280
281void 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();
292}
293
294void 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();
307}
308
309void 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();
318}
319
320void GCMDriverTest::WaitForAsyncOperation() {
321  base::RunLoop run_loop;
322  async_operation_completed_callback_ = run_loop.QuitClosure();
323  run_loop.Run();
324}
325
326void 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();
332}
333
334void 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();
340}
341
342void GCMDriverTest::UnregisterCompleted(GCMClient::Result result) {
343  unregistration_result_ = result;
344  if (!async_operation_completed_callback_.is_null())
345    async_operation_completed_callback_.Run();
346}
347
348TEST_F(GCMDriverTest, Create) {
349  // Create GCMDriver first. GCM is not started.
350  CreateDriver(FakeGCMClient::NO_DELAY_START);
351  EXPECT_FALSE(driver()->IsStarted());
352
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());
358
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());
365}
366
367TEST_F(GCMDriverTest, CreateByFieldTrial) {
368  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled"));
369
370  // Create GCMDriver first. GCM is not started.
371  CreateDriver(FakeGCMClient::NO_DELAY_START);
372  EXPECT_FALSE(driver()->IsStarted());
373  EXPECT_FALSE(driver()->IsConnected());
374  EXPECT_FALSE(gcm_connection_observer()->connected());
375
376  // GCM will be started after app handler is added.
377  AddAppHandlers();
378  EXPECT_TRUE(driver()->IsStarted());
379  PumpIOLoop();
380  EXPECT_TRUE(driver()->IsConnected());
381  EXPECT_TRUE(gcm_connection_observer()->connected());
382}
383
384TEST_F(GCMDriverTest, Shutdown) {
385  CreateDriver(FakeGCMClient::NO_DELAY_START);
386  EXPECT_FALSE(HasAppHandlers());
387
388  AddAppHandlers();
389  EXPECT_TRUE(HasAppHandlers());
390
391  ShutdownDriver();
392  EXPECT_FALSE(HasAppHandlers());
393  EXPECT_FALSE(driver()->IsConnected());
394  EXPECT_FALSE(gcm_connection_observer()->connected());
395}
396
397TEST_F(GCMDriverTest, SignInAndSignOutOnGCMEnabled) {
398  // By default, GCM is enabled.
399  CreateDriver(FakeGCMClient::NO_DELAY_START);
400  AddAppHandlers();
401
402  // GCMClient should be started after sign-in.
403  SignIn(kTestAccountID1);
404  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
405
406  // GCMClient should be checked out after sign-out.
407  SignOut();
408  EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
409}
410
411TEST_F(GCMDriverTest, SignInAndSignOutOnGCMDisabled) {
412  // By default, GCM is enabled.
413  CreateDriver(FakeGCMClient::NO_DELAY_START);
414  AddAppHandlers();
415
416  // Disable GCM.
417  driver()->Disable();
418
419  // GCMClient should not be started after sign-in.
420  SignIn(kTestAccountID1);
421  EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status());
422
423  // Check-out should still be performed after sign-out.
424  SignOut();
425  EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
426}
427
428TEST_F(GCMDriverTest, SignOutAndThenSignIn) {
429  CreateDriver(FakeGCMClient::NO_DELAY_START);
430  AddAppHandlers();
431
432  // GCMClient should be started after sign-in.
433  SignIn(kTestAccountID1);
434  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
435
436  // GCMClient should be checked out after sign-out.
437  SignOut();
438  EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
439
440  // Sign-in with a different account.
441  SignIn(kTestAccountID2);
442
443  // GCMClient should be started again.
444  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
445}
446
447TEST_F(GCMDriverTest, DisableAndReenableGCM) {
448  CreateDriver(FakeGCMClient::NO_DELAY_START);
449  AddAppHandlers();
450  SignIn(kTestAccountID1);
451
452  // GCMClient should be started.
453  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
454
455  // Disables the GCM.
456  driver()->Disable();
457  PumpIOLoop();
458  PumpUILoop();
459
460  // GCMClient should be stopped.
461  EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
462
463  // Enables the GCM.
464  driver()->Enable();
465  PumpIOLoop();
466  PumpUILoop();
467
468  // GCMClient should be started.
469  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
470
471  // Disables the GCM.
472  driver()->Disable();
473  PumpIOLoop();
474  PumpUILoop();
475
476  // GCMClient should be stopped.
477  EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
478
479  // Sign out.
480  SignOut();
481
482  // GCMClient should be checked out.
483  EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status());
484}
485
486TEST_F(GCMDriverTest, StartOrStopGCMOnDemand) {
487  CreateDriver(FakeGCMClient::NO_DELAY_START);
488  SignIn(kTestAccountID1);
489
490  // GCMClient is not started.
491  EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status());
492
493  // GCMClient is started after an app handler has been added.
494  driver()->AddAppHandler(kTestAppID1, gcm_app_handler());
495  PumpIOLoop();
496  PumpUILoop();
497  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
498
499  // Add another app handler.
500  driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
501  PumpIOLoop();
502  PumpUILoop();
503  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
504
505  // GCMClient remains active after one app handler is gone.
506  driver()->RemoveAppHandler(kTestAppID1);
507  PumpIOLoop();
508  PumpUILoop();
509  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
510
511  // GCMClient should be stopped after the last app handler is gone.
512  driver()->RemoveAppHandler(kTestAppID2);
513  PumpIOLoop();
514  PumpUILoop();
515  EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status());
516
517  // GCMClient is restarted after an app handler has been added.
518  driver()->AddAppHandler(kTestAppID2, gcm_app_handler());
519  PumpIOLoop();
520  PumpUILoop();
521  EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status());
522}
523
524TEST_F(GCMDriverTest, RegisterFailed) {
525  std::vector<std::string> sender_ids;
526  sender_ids.push_back("sender1");
527
528  CreateDriver(FakeGCMClient::NO_DELAY_START);
529
530  // Registration fails when GCM is disabled.
531  driver()->Disable();
532  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
533  EXPECT_TRUE(registration_id().empty());
534  EXPECT_EQ(GCMClient::GCM_DISABLED, registration_result());
535
536  ClearResults();
537
538  // Registration fails when the sign-in does not occur.
539  driver()->Enable();
540  AddAppHandlers();
541  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
542  EXPECT_TRUE(registration_id().empty());
543  EXPECT_EQ(GCMClient::NOT_SIGNED_IN, registration_result());
544
545  ClearResults();
546
547  // Registration fails when the no app handler is added.
548  RemoveAppHandlers();
549  SignIn(kTestAccountID1);
550  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
551  EXPECT_TRUE(registration_id().empty());
552  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());
553}
554
555TEST_F(GCMDriverTest, UnregisterFailed) {
556  CreateDriver(FakeGCMClient::NO_DELAY_START);
557
558  // Unregistration fails when GCM is disabled.
559  driver()->Disable();
560  Unregister(kTestAppID1, GCMDriverTest::WAIT);
561  EXPECT_EQ(GCMClient::GCM_DISABLED, unregistration_result());
562
563  ClearResults();
564
565  // Unregistration fails when the sign-in does not occur.
566  driver()->Enable();
567  AddAppHandlers();
568  Unregister(kTestAppID1, GCMDriverTest::WAIT);
569  EXPECT_EQ(GCMClient::NOT_SIGNED_IN, unregistration_result());
570
571  ClearResults();
572
573  // Unregistration fails when the no app handler is added.
574  RemoveAppHandlers();
575  SignIn(kTestAccountID1);
576  Unregister(kTestAppID1, GCMDriverTest::WAIT);
577  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, unregistration_result());
578}
579
580TEST_F(GCMDriverTest, SendFailed) {
581  GCMClient::OutgoingMessage message;
582  message.id = "1";
583  message.data["key1"] = "value1";
584
585  CreateDriver(FakeGCMClient::NO_DELAY_START);
586
587  // Sending fails when GCM is disabled.
588  driver()->Disable();
589  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
590  EXPECT_TRUE(send_message_id().empty());
591  EXPECT_EQ(GCMClient::GCM_DISABLED, send_result());
592
593  ClearResults();
594
595  // Sending fails when the sign-in does not occur.
596  driver()->Enable();
597  AddAppHandlers();
598  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
599  EXPECT_TRUE(send_message_id().empty());
600  EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result());
601
602  ClearResults();
603
604  // Sending fails when the no app handler is added.
605  RemoveAppHandlers();
606  SignIn(kTestAccountID1);
607  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
608  EXPECT_TRUE(send_message_id().empty());
609  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());
610}
611
612TEST_F(GCMDriverTest, GCMClientNotReadyBeforeRegistration) {
613  // Make GCMClient not ready initially.
614  CreateDriver(FakeGCMClient::DELAY_START);
615  SignIn(kTestAccountID1);
616  AddAppHandlers();
617
618  // The registration is on hold until GCMClient is ready.
619  std::vector<std::string> sender_ids;
620  sender_ids.push_back("sender1");
621  Register(kTestAppID1,
622                     sender_ids,
623                     GCMDriverTest::DO_NOT_WAIT);
624  PumpIOLoop();
625  PumpUILoop();
626  EXPECT_TRUE(registration_id().empty());
627  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, registration_result());
628
629  // Register operation will be invoked after GCMClient becomes ready.
630  GetGCMClient()->PerformDelayedLoading();
631  WaitForAsyncOperation();
632  EXPECT_FALSE(registration_id().empty());
633  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
634}
635
636TEST_F(GCMDriverTest, GCMClientNotReadyBeforeSending) {
637  // Make GCMClient not ready initially.
638  CreateDriver(FakeGCMClient::DELAY_START);
639  SignIn(kTestAccountID1);
640  AddAppHandlers();
641
642  // The sending is on hold until GCMClient is ready.
643  GCMClient::OutgoingMessage message;
644  message.id = "1";
645  message.data["key1"] = "value1";
646  message.data["key2"] = "value2";
647  Send(kTestAppID1, kUserID1, message, GCMDriverTest::DO_NOT_WAIT);
648  PumpIOLoop();
649  PumpUILoop();
650
651  EXPECT_TRUE(send_message_id().empty());
652  EXPECT_EQ(GCMClient::UNKNOWN_ERROR, send_result());
653
654  // Send operation will be invoked after GCMClient becomes ready.
655  GetGCMClient()->PerformDelayedLoading();
656  WaitForAsyncOperation();
657  EXPECT_EQ(message.id, send_message_id());
658  EXPECT_EQ(GCMClient::SUCCESS, send_result());
659}
660
661// Tests a single instance of GCMDriver.
662class GCMDriverFunctionalTest : public GCMDriverTest {
663 public:
664  GCMDriverFunctionalTest();
665  virtual ~GCMDriverFunctionalTest();
666
667  // GCMDriverTest:
668  virtual void SetUp() OVERRIDE;
669
670 private:
671  DISALLOW_COPY_AND_ASSIGN(GCMDriverFunctionalTest);
672};
673
674GCMDriverFunctionalTest::GCMDriverFunctionalTest() {
675}
676
677GCMDriverFunctionalTest::~GCMDriverFunctionalTest() {
678}
679
680void GCMDriverFunctionalTest::SetUp() {
681  GCMDriverTest::SetUp();
682
683  CreateDriver(FakeGCMClient::NO_DELAY_START);
684  AddAppHandlers();
685  SignIn(kTestAccountID1);
686}
687
688TEST_F(GCMDriverFunctionalTest, Register) {
689  std::vector<std::string> sender_ids;
690  sender_ids.push_back("sender1");
691  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
692  const std::string expected_registration_id =
693      FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
694
695  EXPECT_EQ(expected_registration_id, registration_id());
696  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
697}
698
699TEST_F(GCMDriverFunctionalTest, RegisterError) {
700  std::vector<std::string> sender_ids;
701  sender_ids.push_back("sender1@error");
702  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
703
704  EXPECT_TRUE(registration_id().empty());
705  EXPECT_NE(GCMClient::SUCCESS, registration_result());
706}
707
708TEST_F(GCMDriverFunctionalTest, RegisterAgainWithSameSenderIDs) {
709  std::vector<std::string> sender_ids;
710  sender_ids.push_back("sender1");
711  sender_ids.push_back("sender2");
712  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
713  const std::string expected_registration_id =
714      FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
715
716  EXPECT_EQ(expected_registration_id, registration_id());
717  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
718
719  // Clears the results the would be set by the Register callback in preparation
720  // to call register 2nd time.
721  ClearResults();
722
723  // Calling register 2nd time with the same set of sender IDs but different
724  // ordering will get back the same registration ID.
725  std::vector<std::string> another_sender_ids;
726  another_sender_ids.push_back("sender2");
727  another_sender_ids.push_back("sender1");
728  Register(kTestAppID1, another_sender_ids, GCMDriverTest::WAIT);
729
730  EXPECT_EQ(expected_registration_id, registration_id());
731  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
732}
733
734TEST_F(GCMDriverFunctionalTest, RegisterAgainWithDifferentSenderIDs) {
735  std::vector<std::string> sender_ids;
736  sender_ids.push_back("sender1");
737  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
738  const std::string expected_registration_id =
739      FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
740
741  EXPECT_EQ(expected_registration_id, registration_id());
742  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
743
744  // Make sender IDs different.
745  sender_ids.push_back("sender2");
746  const std::string expected_registration_id2 =
747      FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids);
748
749  // Calling register 2nd time with the different sender IDs will get back a new
750  // registration ID.
751  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
752  EXPECT_EQ(expected_registration_id2, registration_id());
753  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
754}
755
756TEST_F(GCMDriverFunctionalTest, RegisterAfterSignOut) {
757  // This will trigger check-out.
758  SignOut();
759
760  std::vector<std::string> sender_ids;
761  sender_ids.push_back("sender1");
762  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
763
764  EXPECT_TRUE(registration_id().empty());
765  EXPECT_EQ(GCMClient::NOT_SIGNED_IN, registration_result());
766}
767
768TEST_F(GCMDriverFunctionalTest, UnregisterExplicitly) {
769  std::vector<std::string> sender_ids;
770  sender_ids.push_back("sender1");
771  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
772
773  EXPECT_FALSE(registration_id().empty());
774  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
775
776  Unregister(kTestAppID1, GCMDriverTest::WAIT);
777
778  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
779}
780
781TEST_F(GCMDriverFunctionalTest, UnregisterWhenAsyncOperationPending) {
782  std::vector<std::string> sender_ids;
783  sender_ids.push_back("sender1");
784  // First start registration without waiting for it to complete.
785  Register(kTestAppID1,
786                     sender_ids,
787                     GCMDriverTest::DO_NOT_WAIT);
788
789  // Test that unregistration fails with async operation pending when there is a
790  // registration already in progress.
791  Unregister(kTestAppID1, GCMDriverTest::WAIT);
792  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
793            unregistration_result());
794
795  // Complete the unregistration.
796  WaitForAsyncOperation();
797  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
798
799  // Start unregistration without waiting for it to complete. This time no async
800  // operation is pending.
801  Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);
802
803  // Test that unregistration fails with async operation pending when there is
804  // an unregistration already in progress.
805  Unregister(kTestAppID1, GCMDriverTest::WAIT);
806  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
807            unregistration_result());
808  ClearResults();
809
810  // Complete unregistration.
811  WaitForAsyncOperation();
812  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
813}
814
815TEST_F(GCMDriverFunctionalTest, RegisterWhenAsyncOperationPending) {
816  std::vector<std::string> sender_ids;
817  sender_ids.push_back("sender1");
818  // First start registration without waiting for it to complete.
819  Register(kTestAppID1,
820                     sender_ids,
821                     GCMDriverTest::DO_NOT_WAIT);
822
823  // Test that registration fails with async operation pending when there is a
824  // registration already in progress.
825  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
826  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
827            registration_result());
828  ClearResults();
829
830  // Complete the registration.
831  WaitForAsyncOperation();
832  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
833
834  // Start unregistration without waiting for it to complete. This time no async
835  // operation is pending.
836  Unregister(kTestAppID1, GCMDriverTest::DO_NOT_WAIT);
837
838  // Test that registration fails with async operation pending when there is an
839  // unregistration already in progress.
840  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
841  EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING,
842            registration_result());
843
844  // Complete the first unregistration expecting success.
845  WaitForAsyncOperation();
846  EXPECT_EQ(GCMClient::SUCCESS, unregistration_result());
847
848  // Test that it is ok to register again after unregistration.
849  Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
850  EXPECT_EQ(GCMClient::SUCCESS, registration_result());
851}
852
853TEST_F(GCMDriverFunctionalTest, Send) {
854  GCMClient::OutgoingMessage message;
855  message.id = "1@ack";
856  message.data["key1"] = "value1";
857  message.data["key2"] = "value2";
858  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
859
860  EXPECT_EQ(message.id, send_message_id());
861  EXPECT_EQ(GCMClient::SUCCESS, send_result());
862
863  gcm_app_handler()->WaitForNotification();
864  EXPECT_EQ(message.id, gcm_app_handler()->acked_message_id());
865  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
866}
867
868TEST_F(GCMDriverFunctionalTest, SendAfterSignOut) {
869  // This will trigger check-out.
870  SignOut();
871
872  GCMClient::OutgoingMessage message;
873  message.id = "1";
874  message.data["key1"] = "value1";
875  message.data["key2"] = "value2";
876  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
877
878  EXPECT_TRUE(send_message_id().empty());
879  EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result());
880}
881
882TEST_F(GCMDriverFunctionalTest, SendError) {
883  GCMClient::OutgoingMessage message;
884  // Embedding error in id will tell the mock to simulate the send error.
885  message.id = "1@error";
886  message.data["key1"] = "value1";
887  message.data["key2"] = "value2";
888  Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT);
889
890  EXPECT_EQ(message.id, send_message_id());
891  EXPECT_EQ(GCMClient::SUCCESS, send_result());
892
893  // Wait for the send error.
894  gcm_app_handler()->WaitForNotification();
895  EXPECT_EQ(FakeGCMAppHandler::SEND_ERROR_EVENT,
896            gcm_app_handler()->received_event());
897  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
898  EXPECT_EQ(message.id,
899            gcm_app_handler()->send_error_details().message_id);
900  EXPECT_NE(GCMClient::SUCCESS,
901            gcm_app_handler()->send_error_details().result);
902  EXPECT_EQ(message.data,
903            gcm_app_handler()->send_error_details().additional_data);
904}
905
906TEST_F(GCMDriverFunctionalTest, MessageReceived) {
907  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
908  GCMClient::IncomingMessage message;
909  message.data["key1"] = "value1";
910  message.data["key2"] = "value2";
911  message.sender_id = "sender";
912  GetGCMClient()->ReceiveMessage(kTestAppID1, message);
913  gcm_app_handler()->WaitForNotification();
914  EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
915            gcm_app_handler()->received_event());
916  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
917  EXPECT_EQ(message.data, gcm_app_handler()->message().data);
918  EXPECT_TRUE(gcm_app_handler()->message().collapse_key.empty());
919  EXPECT_EQ(message.sender_id, gcm_app_handler()->message().sender_id);
920}
921
922TEST_F(GCMDriverFunctionalTest, MessageWithCollapseKeyReceived) {
923  Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
924  GCMClient::IncomingMessage message;
925  message.data["key1"] = "value1";
926  message.collapse_key = "collapse_key_value";
927  message.sender_id = "sender";
928  GetGCMClient()->ReceiveMessage(kTestAppID1, message);
929  gcm_app_handler()->WaitForNotification();
930  EXPECT_EQ(FakeGCMAppHandler::MESSAGE_EVENT,
931            gcm_app_handler()->received_event());
932  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
933  EXPECT_EQ(message.data, gcm_app_handler()->message().data);
934  EXPECT_EQ(message.collapse_key,
935            gcm_app_handler()->message().collapse_key);
936}
937
938TEST_F(GCMDriverFunctionalTest, MessagesDeleted) {
939  GetGCMClient()->DeleteMessages(kTestAppID1);
940  gcm_app_handler()->WaitForNotification();
941  EXPECT_EQ(FakeGCMAppHandler::MESSAGES_DELETED_EVENT,
942            gcm_app_handler()->received_event());
943  EXPECT_EQ(kTestAppID1, gcm_app_handler()->app_id());
944}
945
946// Tests a single instance of GCMDriver.
947class GCMChannelStatusSyncerTest : public GCMDriverTest {
948 public:
949  GCMChannelStatusSyncerTest();
950  virtual ~GCMChannelStatusSyncerTest();
951
952  // testing::Test:
953  virtual void SetUp() OVERRIDE;
954
955  void CompleteGCMChannelStatusRequest(bool enabled, int poll_interval_seconds);
956  bool CompareDelaySeconds(bool expected_delay_seconds,
957                           bool actual_delay_seconds);
958
959  GCMChannelStatusSyncer* syncer() {
960    return driver()->gcm_channel_status_syncer_for_testing();
961  }
962
963 private:
964  net::TestURLFetcherFactory url_fetcher_factory_;
965
966  DISALLOW_COPY_AND_ASSIGN(GCMChannelStatusSyncerTest);
967};
968
969GCMChannelStatusSyncerTest::GCMChannelStatusSyncerTest() {
970}
971
972GCMChannelStatusSyncerTest::~GCMChannelStatusSyncerTest() {
973}
974
975void GCMChannelStatusSyncerTest::SetUp() {
976  GCMDriverTest::SetUp();
977
978  // Turn on all-user support.
979  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("GCM", "Enabled"));
980}
981
982void GCMChannelStatusSyncerTest::CompleteGCMChannelStatusRequest(
983    bool enabled, int poll_interval_seconds) {
984  gcm_proto::ExperimentStatusResponse response_proto;
985  response_proto.mutable_gcm_channel()->set_enabled(enabled);
986
987  if (poll_interval_seconds)
988    response_proto.set_poll_interval_seconds(poll_interval_seconds);
989
990  std::string response_string;
991  response_proto.SerializeToString(&response_string);
992
993  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
994  ASSERT_TRUE(fetcher);
995  fetcher->set_response_code(net::HTTP_OK);
996  fetcher->SetResponseString(response_string);
997  fetcher->delegate()->OnURLFetchComplete(fetcher);
998}
999
1000bool GCMChannelStatusSyncerTest::CompareDelaySeconds(
1001    bool expected_delay_seconds, bool actual_delay_seconds) {
1002  // Most of time, the actual delay should not be smaller than the expected
1003  // delay.
1004  if (actual_delay_seconds >= expected_delay_seconds)
1005    return true;
1006  // It is also OK that the actual delay is a bit smaller than the expected
1007  // delay in case that the test runs slowly.
1008  return expected_delay_seconds - actual_delay_seconds < 30;
1009}
1010
1011TEST_F(GCMChannelStatusSyncerTest, DisableAndEnable) {
1012  // Create GCMDriver first. GCM is not started.
1013  CreateDriver(FakeGCMClient::NO_DELAY_START);
1014  EXPECT_FALSE(driver()->IsStarted());
1015
1016  // By default, GCM is enabled.
1017  EXPECT_TRUE(driver()->gcm_enabled());
1018  EXPECT_TRUE(syncer()->gcm_enabled());
1019
1020  // Remove delay such that the request could be executed immediately.
1021  syncer()->set_delay_removed_for_testing(true);
1022
1023  // GCM will be started after app handler is added.
1024  AddAppHandlers();
1025  EXPECT_TRUE(driver()->IsStarted());
1026
1027  // GCM is still enabled at this point.
1028  EXPECT_TRUE(driver()->gcm_enabled());
1029  EXPECT_TRUE(syncer()->gcm_enabled());
1030
1031  // Wait until the GCM channel status request gets triggered.
1032  PumpUILoop();
1033
1034  // Complete the request that disables the GCM.
1035  CompleteGCMChannelStatusRequest(false, 0);
1036  EXPECT_FALSE(driver()->gcm_enabled());
1037  EXPECT_FALSE(syncer()->gcm_enabled());
1038  EXPECT_FALSE(driver()->IsStarted());
1039
1040  // Wait until next GCM channel status request gets triggered.
1041  PumpUILoop();
1042
1043  // Complete the request that enables the GCM.
1044  CompleteGCMChannelStatusRequest(true, 0);
1045  EXPECT_TRUE(driver()->gcm_enabled());
1046  EXPECT_TRUE(syncer()->gcm_enabled());
1047  EXPECT_TRUE(driver()->IsStarted());
1048}
1049
1050TEST_F(GCMChannelStatusSyncerTest, DisableAndRestart) {
1051  // Create GCMDriver first. GCM is not started.
1052  CreateDriver(FakeGCMClient::NO_DELAY_START);
1053  EXPECT_FALSE(driver()->IsStarted());
1054
1055  // By default, GCM is enabled.
1056  EXPECT_TRUE(driver()->gcm_enabled());
1057  EXPECT_TRUE(syncer()->gcm_enabled());
1058
1059  // Remove delay such that the request could be executed immediately.
1060  syncer()->set_delay_removed_for_testing(true);
1061
1062  // GCM will be started after app handler is added.
1063  AddAppHandlers();
1064  EXPECT_TRUE(driver()->IsStarted());
1065
1066  // GCM is still enabled at this point.
1067  EXPECT_TRUE(driver()->gcm_enabled());
1068  EXPECT_TRUE(syncer()->gcm_enabled());
1069
1070  // Wait until the GCM channel status request gets triggered.
1071  PumpUILoop();
1072
1073  // Complete the request that disables the GCM.
1074  CompleteGCMChannelStatusRequest(false, 0);
1075  EXPECT_FALSE(driver()->gcm_enabled());
1076  EXPECT_FALSE(syncer()->gcm_enabled());
1077  EXPECT_FALSE(driver()->IsStarted());
1078
1079  // Simulate browser start by recreating GCMDriver.
1080  ShutdownDriver();
1081  CreateDriver(FakeGCMClient::NO_DELAY_START);
1082
1083  // GCM is still disabled.
1084  EXPECT_FALSE(driver()->gcm_enabled());
1085  EXPECT_FALSE(syncer()->gcm_enabled());
1086  EXPECT_FALSE(driver()->IsStarted());
1087
1088  AddAppHandlers();
1089  EXPECT_FALSE(driver()->gcm_enabled());
1090  EXPECT_FALSE(syncer()->gcm_enabled());
1091  EXPECT_FALSE(driver()->IsStarted());
1092}
1093
1094TEST_F(GCMChannelStatusSyncerTest, FirstTimePolling) {
1095  // Start GCM.
1096  CreateDriver(FakeGCMClient::NO_DELAY_START);
1097  AddAppHandlers();
1098
1099  // The 1st request should be triggered shortly without jittering.
1100  EXPECT_EQ(GCMChannelStatusSyncer::first_time_delay_seconds(),
1101            syncer()->current_request_delay_interval().InSeconds());
1102}
1103
1104TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithDefaultInterval) {
1105  // Create GCMDriver first. GCM is not started.
1106  CreateDriver(FakeGCMClient::NO_DELAY_START);
1107
1108  // Remove delay such that the request could be executed immediately.
1109  syncer()->set_delay_removed_for_testing(true);
1110
1111  // Now GCM is started.
1112  AddAppHandlers();
1113
1114  // Wait until the GCM channel status request gets triggered.
1115  PumpUILoop();
1116
1117  // Keep delay such that we can find out the computed delay time.
1118  syncer()->set_delay_removed_for_testing(false);
1119
1120  // Complete the request. The default interval is intact.
1121  CompleteGCMChannelStatusRequest(true, 0);
1122
1123  // The next request should be scheduled at the expected default interval.
1124  int64 actual_delay_seconds =
1125      syncer()->current_request_delay_interval().InSeconds();
1126  int64 expected_delay_seconds =
1127      GCMChannelStatusRequest::default_poll_interval_seconds();
1128  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1129      << "expected delay: " << expected_delay_seconds
1130      << " actual delay: " << actual_delay_seconds;
1131
1132  // Simulate browser start by recreating GCMDriver.
1133  ShutdownDriver();
1134  CreateDriver(FakeGCMClient::NO_DELAY_START);
1135  AddAppHandlers();
1136
1137  // After start-up, the request should still be scheduled at the expected
1138  // default interval.
1139  actual_delay_seconds =
1140      syncer()->current_request_delay_interval().InSeconds();
1141  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1142      << "expected delay: " << expected_delay_seconds
1143      << " actual delay: " << actual_delay_seconds;
1144}
1145
1146TEST_F(GCMChannelStatusSyncerTest, SubsequentPollingWithUpdatedInterval) {
1147  // Create GCMDriver first. GCM is not started.
1148  CreateDriver(FakeGCMClient::NO_DELAY_START);
1149
1150  // Remove delay such that the request could be executed immediately.
1151  syncer()->set_delay_removed_for_testing(true);
1152
1153  // Now GCM is started.
1154  AddAppHandlers();
1155
1156  // Wait until the GCM channel status request gets triggered.
1157  PumpUILoop();
1158
1159  // Keep delay such that we can find out the computed delay time.
1160  syncer()->set_delay_removed_for_testing(false);
1161
1162  // Complete the request. The interval is being changed.
1163  int new_poll_interval_seconds =
1164      GCMChannelStatusRequest::default_poll_interval_seconds() * 2;
1165  CompleteGCMChannelStatusRequest(true, new_poll_interval_seconds);
1166
1167  // The next request should be scheduled at the expected updated interval.
1168  int64 actual_delay_seconds =
1169      syncer()->current_request_delay_interval().InSeconds();
1170  int64 expected_delay_seconds = new_poll_interval_seconds;
1171  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1172      << "expected delay: " << expected_delay_seconds
1173      << " actual delay: " << actual_delay_seconds;
1174
1175  // Simulate browser start by recreating GCMDriver.
1176  ShutdownDriver();
1177  CreateDriver(FakeGCMClient::NO_DELAY_START);
1178  AddAppHandlers();
1179
1180  // After start-up, the request should still be scheduled at the expected
1181  // updated interval.
1182  actual_delay_seconds =
1183      syncer()->current_request_delay_interval().InSeconds();
1184  EXPECT_TRUE(CompareDelaySeconds(expected_delay_seconds, actual_delay_seconds))
1185      << "expected delay: " << expected_delay_seconds
1186      << " actual delay: " << actual_delay_seconds;
1187}
1188
1189}  // namespace gcm
1190