• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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));
CreateClosure()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));
CreateCallback()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:
SyncSystemResourcesTest()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 
~SyncSystemResourcesTest()57   virtual ~SyncSystemResourcesTest() {}
58 
ScheduleShouldNotRun()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.
TEST_F(SyncSystemResourcesTest,CurrentTime)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.
TEST_F(SyncSystemResourcesTest,Log)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 
TEST_F(SyncSystemResourcesTest,ScheduleBeforeStart)110 TEST_F(SyncSystemResourcesTest, ScheduleBeforeStart) {
111   ScheduleShouldNotRun();
112   sync_system_resources_.Start();
113 }
114 
TEST_F(SyncSystemResourcesTest,ScheduleAfterStop)115 TEST_F(SyncSystemResourcesTest, ScheduleAfterStop) {
116   sync_system_resources_.Start();
117   sync_system_resources_.Stop();
118   ScheduleShouldNotRun();
119 }
120 
TEST_F(SyncSystemResourcesTest,ScheduleAndStop)121 TEST_F(SyncSystemResourcesTest, ScheduleAndStop) {
122   sync_system_resources_.Start();
123   ScheduleShouldNotRun();
124   sync_system_resources_.Stop();
125 }
126 
TEST_F(SyncSystemResourcesTest,ScheduleAndDestroy)127 TEST_F(SyncSystemResourcesTest, ScheduleAndDestroy) {
128   sync_system_resources_.Start();
129   ScheduleShouldNotRun();
130 }
131 
TEST_F(SyncSystemResourcesTest,ScheduleImmediately)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 
TEST_F(SyncSystemResourcesTest,ScheduleOnListenerThread)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 
TEST_F(SyncSystemResourcesTest,ScheduleWithZeroDelay)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 
TEST_F(SyncSystemResourcesTest,WriteState)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:
TestSyncNetworkChannel()181   TestSyncNetworkChannel() {}
~TestSyncNetworkChannel()182   virtual ~TestSyncNetworkChannel() {}
183 
184   using SyncNetworkChannel::NotifyNetworkStatusChange;
185   using SyncNetworkChannel::NotifyChannelStateChange;
186   using SyncNetworkChannel::DeliverIncomingMessage;
187 
SendMessage(const std::string & message)188   virtual void SendMessage(const std::string& message) OVERRIDE {
189   }
190 
UpdateCredentials(const std::string & email,const std::string & token)191   virtual void UpdateCredentials(const std::string& email,
192       const std::string& token) OVERRIDE {
193   }
194 
GetInvalidationClientType()195   virtual int GetInvalidationClientType() OVERRIDE {
196     return 0;
197   }
198 
RequestDetailedStatus(base::Callback<void (const base::DictionaryValue &)> callback)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:
SyncNetworkChannelTest()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 
~SyncNetworkChannelTest()219   virtual ~SyncNetworkChannelTest() {
220     network_channel_.RemoveObserver(this);
221   }
222 
OnNetworkChannelStateChanged(InvalidatorState invalidator_state)223   virtual void OnNetworkChannelStateChanged(
224       InvalidatorState invalidator_state) OVERRIDE {
225     last_invalidator_state_ = invalidator_state;
226   }
227 
OnNetworkStatusChange(bool connected)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.
TEST_F(SyncNetworkChannelTest,ChannelStateChange)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.
TEST_F(SyncNetworkChannelTest,NetworkStateChange)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