Home | History | Annotate | Download | only in invalidation
      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/invalidation/sync_system_resources.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/callback.h"
     12 #include "base/message_loop/message_loop.h"
     13 
     14 #include "components/invalidation/push_client_channel.h"
     15 #include "components/invalidation/state_writer.h"
     16 #include "google/cacheinvalidation/include/types.h"
     17 #include "jingle/notifier/listener/fake_push_client.h"
     18 #include "testing/gmock/include/gmock/gmock.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace syncer {
     22 namespace {
     23 
     24 using ::testing::_;
     25 using ::testing::SaveArg;
     26 
     27 class MockStateWriter : public StateWriter {
     28  public:
     29   MOCK_METHOD1(WriteState, void(const std::string&));
     30 };
     31 
     32 class MockClosure {
     33  public:
     34   MOCK_CONST_METHOD0(Run, void(void));
     35   base::Closure* CreateClosure() {
     36     return new base::Closure(
     37         base::Bind(&MockClosure::Run, base::Unretained(this)));
     38   }
     39 };
     40 
     41 class MockStorageCallback {
     42  public:
     43   MOCK_CONST_METHOD1(Run, void(invalidation::Status));
     44   base::Callback<void(invalidation::Status)>* CreateCallback() {
     45     return new base::Callback<void(invalidation::Status)>(
     46         base::Bind(&MockStorageCallback::Run, base::Unretained(this)));
     47   }
     48 };
     49 
     50 class SyncSystemResourcesTest : public testing::Test {
     51  protected:
     52   SyncSystemResourcesTest()
     53       : push_client_channel_(
     54             scoped_ptr<notifier::PushClient>(new notifier::FakePushClient())),
     55         sync_system_resources_(&push_client_channel_, &mock_state_writer_) {}
     56 
     57   virtual ~SyncSystemResourcesTest() {}
     58 
     59   void ScheduleShouldNotRun() {
     60     {
     61       // Owned by ScheduleImmediately.
     62       MockClosure mock_closure;
     63       base::Closure* should_not_run = mock_closure.CreateClosure();
     64       EXPECT_CALL(mock_closure, Run()).Times(0);
     65       sync_system_resources_.internal_scheduler()->Schedule(
     66           invalidation::Scheduler::NoDelay(), should_not_run);
     67     }
     68     {
     69       // Owned by ScheduleOnListenerThread.
     70       MockClosure mock_closure;
     71       base::Closure* should_not_run = mock_closure.CreateClosure();
     72       EXPECT_CALL(mock_closure, Run()).Times(0);
     73       sync_system_resources_.listener_scheduler()->Schedule(
     74           invalidation::Scheduler::NoDelay(), should_not_run);
     75     }
     76     {
     77       // Owned by ScheduleWithDelay.
     78       MockClosure mock_closure;
     79       base::Closure* should_not_run = mock_closure.CreateClosure();
     80       EXPECT_CALL(mock_closure, Run()).Times(0);
     81       sync_system_resources_.internal_scheduler()->Schedule(
     82           invalidation::TimeDelta::FromSeconds(0), should_not_run);
     83     }
     84   }
     85 
     86   // Needed by |sync_system_resources_|.
     87   base::MessageLoop message_loop_;
     88   MockStateWriter mock_state_writer_;
     89   PushClientChannel push_client_channel_;
     90   SyncSystemResources sync_system_resources_;
     91 
     92  private:
     93   DISALLOW_COPY_AND_ASSIGN(SyncSystemResourcesTest);
     94 };
     95 
     96 // Make sure current_time() doesn't crash or leak.
     97 TEST_F(SyncSystemResourcesTest, CurrentTime) {
     98   invalidation::Time current_time =
     99       sync_system_resources_.internal_scheduler()->GetCurrentTime();
    100   DVLOG(1) << "current_time returned: " << current_time.ToInternalValue();
    101 }
    102 
    103 // Make sure Log() doesn't crash or leak.
    104 TEST_F(SyncSystemResourcesTest, Log) {
    105   sync_system_resources_.logger()->Log(SyncLogger::INFO_LEVEL,
    106                                          __FILE__, __LINE__, "%s %d",
    107                                          "test string", 5);
    108 }
    109 
    110 TEST_F(SyncSystemResourcesTest, ScheduleBeforeStart) {
    111   ScheduleShouldNotRun();
    112   sync_system_resources_.Start();
    113 }
    114 
    115 TEST_F(SyncSystemResourcesTest, ScheduleAfterStop) {
    116   sync_system_resources_.Start();
    117   sync_system_resources_.Stop();
    118   ScheduleShouldNotRun();
    119 }
    120 
    121 TEST_F(SyncSystemResourcesTest, ScheduleAndStop) {
    122   sync_system_resources_.Start();
    123   ScheduleShouldNotRun();
    124   sync_system_resources_.Stop();
    125 }
    126 
    127 TEST_F(SyncSystemResourcesTest, ScheduleAndDestroy) {
    128   sync_system_resources_.Start();
    129   ScheduleShouldNotRun();
    130 }
    131 
    132 TEST_F(SyncSystemResourcesTest, ScheduleImmediately) {
    133   sync_system_resources_.Start();
    134   MockClosure mock_closure;
    135   EXPECT_CALL(mock_closure, Run());
    136   sync_system_resources_.internal_scheduler()->Schedule(
    137       invalidation::Scheduler::NoDelay(), mock_closure.CreateClosure());
    138   message_loop_.RunUntilIdle();
    139 }
    140 
    141 TEST_F(SyncSystemResourcesTest, ScheduleOnListenerThread) {
    142   sync_system_resources_.Start();
    143   MockClosure mock_closure;
    144   EXPECT_CALL(mock_closure, Run());
    145   sync_system_resources_.listener_scheduler()->Schedule(
    146       invalidation::Scheduler::NoDelay(), mock_closure.CreateClosure());
    147   EXPECT_TRUE(
    148       sync_system_resources_.internal_scheduler()->IsRunningOnThread());
    149   message_loop_.RunUntilIdle();
    150 }
    151 
    152 TEST_F(SyncSystemResourcesTest, ScheduleWithZeroDelay) {
    153   sync_system_resources_.Start();
    154   MockClosure mock_closure;
    155   EXPECT_CALL(mock_closure, Run());
    156   sync_system_resources_.internal_scheduler()->Schedule(
    157       invalidation::TimeDelta::FromSeconds(0), mock_closure.CreateClosure());
    158   message_loop_.RunUntilIdle();
    159 }
    160 
    161 // TODO(akalin): Figure out how to test with a non-zero delay.
    162 
    163 TEST_F(SyncSystemResourcesTest, WriteState) {
    164   sync_system_resources_.Start();
    165   EXPECT_CALL(mock_state_writer_, WriteState(_));
    166   // Owned by WriteState.
    167   MockStorageCallback mock_storage_callback;
    168   invalidation::Status results(invalidation::Status::PERMANENT_FAILURE,
    169                                "fake-failure");
    170   EXPECT_CALL(mock_storage_callback, Run(_))
    171       .WillOnce(SaveArg<0>(&results));
    172   sync_system_resources_.storage()->WriteKey(
    173       std::string(), "state", mock_storage_callback.CreateCallback());
    174   message_loop_.RunUntilIdle();
    175   EXPECT_EQ(invalidation::Status(invalidation::Status::SUCCESS, std::string()),
    176             results);
    177 }
    178 
    179 class TestSyncNetworkChannel : public SyncNetworkChannel {
    180  public:
    181   TestSyncNetworkChannel() {}
    182   virtual ~TestSyncNetworkChannel() {}
    183 
    184   using SyncNetworkChannel::NotifyNetworkStatusChange;
    185   using SyncNetworkChannel::NotifyChannelStateChange;
    186   using SyncNetworkChannel::DeliverIncomingMessage;
    187 
    188   virtual void SendMessage(const std::string& message) OVERRIDE {
    189   }
    190 
    191   virtual void UpdateCredentials(const std::string& email,
    192       const std::string& token) OVERRIDE {
    193   }
    194 
    195   virtual int GetInvalidationClientType() OVERRIDE {
    196     return 0;
    197   }
    198 
    199   virtual void RequestDetailedStatus(
    200       base::Callback<void(const base::DictionaryValue&)> callback) OVERRIDE {
    201     base::DictionaryValue value;
    202     callback.Run(value);
    203   }
    204 };
    205 
    206 class SyncNetworkChannelTest
    207     : public testing::Test,
    208       public SyncNetworkChannel::Observer {
    209  protected:
    210   SyncNetworkChannelTest()
    211       : last_invalidator_state_(DEFAULT_INVALIDATION_ERROR),
    212         connected_(false) {
    213     network_channel_.AddObserver(this);
    214     network_channel_.AddNetworkStatusReceiver(
    215         invalidation::NewPermanentCallback(
    216             this, &SyncNetworkChannelTest::OnNetworkStatusChange));
    217   }
    218 
    219   virtual ~SyncNetworkChannelTest() {
    220     network_channel_.RemoveObserver(this);
    221   }
    222 
    223   virtual void OnNetworkChannelStateChanged(
    224       InvalidatorState invalidator_state) OVERRIDE {
    225     last_invalidator_state_ = invalidator_state;
    226   }
    227 
    228   void OnNetworkStatusChange(bool connected) {
    229     connected_ = connected;
    230   }
    231 
    232   TestSyncNetworkChannel network_channel_;
    233   InvalidatorState last_invalidator_state_;
    234   bool connected_;
    235 };
    236 
    237 // Simulate channel state change. It should propagate to observer.
    238 TEST_F(SyncNetworkChannelTest, ChannelStateChange) {
    239   EXPECT_EQ(DEFAULT_INVALIDATION_ERROR, last_invalidator_state_);
    240   network_channel_.NotifyChannelStateChange(INVALIDATIONS_ENABLED);
    241   EXPECT_EQ(INVALIDATIONS_ENABLED, last_invalidator_state_);
    242   network_channel_.NotifyChannelStateChange(INVALIDATION_CREDENTIALS_REJECTED);
    243   EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, last_invalidator_state_);
    244 }
    245 
    246 // Simulate network state change. It should propagate to cacheinvalidations.
    247 TEST_F(SyncNetworkChannelTest, NetworkStateChange) {
    248   EXPECT_FALSE(connected_);
    249   network_channel_.NotifyNetworkStatusChange(true);
    250   EXPECT_TRUE(connected_);
    251   network_channel_.NotifyNetworkStatusChange(false);
    252   EXPECT_FALSE(connected_);
    253 }
    254 
    255 }  // namespace
    256 }  // namespace syncer
    257