[SyncFS] Use nullptr instead of NULL
[chromium-blink-merge.git] / chrome / browser / sync_file_system / sync_process_runner_unittest.cc
blobeeded442b3bbe68d197d4ba0b66cdfa86ad12c7d
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 "chrome/browser/sync_file_system/sync_process_runner.h"
7 #include <queue>
9 #include "base/memory/scoped_ptr.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace sync_file_system {
14 namespace {
16 class FakeClient : public SyncProcessRunner::Client {
17 public:
18 FakeClient() : service_state_(SYNC_SERVICE_RUNNING) {}
19 virtual ~FakeClient() {}
21 virtual SyncServiceState GetSyncServiceState() OVERRIDE {
22 return service_state_;
25 virtual SyncFileSystemService* GetSyncService() OVERRIDE {
26 return nullptr;
29 void set_service_state(SyncServiceState service_state) {
30 service_state_ = service_state;
33 private:
34 SyncServiceState service_state_;
36 DISALLOW_COPY_AND_ASSIGN(FakeClient);
39 class FakeTimerHelper : public SyncProcessRunner::TimerHelper {
40 public:
41 FakeTimerHelper() {}
42 virtual ~FakeTimerHelper() {}
44 virtual bool IsRunning() OVERRIDE {
45 return !timer_task_.is_null();
48 virtual void Start(const tracked_objects::Location& from_here,
49 const base::TimeDelta& delay,
50 const base::Closure& closure) OVERRIDE {
51 scheduled_time_ = current_time_ + delay;
52 timer_task_ = closure;
55 virtual base::TimeTicks Now() const OVERRIDE {
56 return current_time_;
59 void SetCurrentTime(const base::TimeTicks& current_time) {
60 current_time_ = current_time;
61 if (current_time_ < scheduled_time_ || timer_task_.is_null())
62 return;
64 base::Closure task = timer_task_;
65 timer_task_.Reset();
66 task.Run();
69 void AdvanceToScheduledTime() {
70 SetCurrentTime(scheduled_time_);
73 int64 GetCurrentDelay() {
74 EXPECT_FALSE(timer_task_.is_null());
75 return (scheduled_time_ - current_time_).InMilliseconds();
78 private:
79 base::TimeTicks current_time_;
80 base::TimeTicks scheduled_time_;
81 base::Closure timer_task_;
83 DISALLOW_COPY_AND_ASSIGN(FakeTimerHelper);
86 class FakeSyncProcessRunner : public SyncProcessRunner {
87 public:
88 FakeSyncProcessRunner(SyncProcessRunner::Client* client,
89 scoped_ptr<TimerHelper> timer_helper,
90 size_t max_parallel_task)
91 : SyncProcessRunner("FakeSyncProcess",
92 client, timer_helper.Pass(),
93 max_parallel_task),
94 max_parallel_task_(max_parallel_task) {
97 virtual void StartSync(const SyncStatusCallback& callback) OVERRIDE {
98 EXPECT_LT(running_tasks_.size(), max_parallel_task_);
99 running_tasks_.push(callback);
102 virtual ~FakeSyncProcessRunner() {
105 void UpdateChanges(int num_changes) {
106 OnChangesUpdated(num_changes);
109 void CompleteTask(SyncStatusCode status) {
110 ASSERT_FALSE(running_tasks_.empty());
111 SyncStatusCallback task = running_tasks_.front();
112 running_tasks_.pop();
113 task.Run(status);
116 bool HasRunningTask() const {
117 return !running_tasks_.empty();
120 private:
121 size_t max_parallel_task_;
122 std::queue<SyncStatusCallback> running_tasks_;
124 DISALLOW_COPY_AND_ASSIGN(FakeSyncProcessRunner);
127 } // namespace
129 TEST(SyncProcessRunnerTest, SingleTaskBasicTest) {
130 FakeClient fake_client;
131 FakeTimerHelper* fake_timer = new FakeTimerHelper();
132 FakeSyncProcessRunner fake_runner(
133 &fake_client,
134 scoped_ptr<SyncProcessRunner::TimerHelper>(fake_timer),
135 1 /* max_parallel_task */);
137 base::TimeTicks base_time = base::TimeTicks::Now();
138 fake_timer->SetCurrentTime(base_time);
140 // SyncProcessRunner is expected not to run a task initially.
141 EXPECT_FALSE(fake_timer->IsRunning());
143 // As soon as SyncProcessRunner gets a new update, it should start running
144 // the timer to run a synchronization task.
145 fake_runner.UpdateChanges(100);
146 EXPECT_TRUE(fake_timer->IsRunning());
147 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
148 fake_timer->GetCurrentDelay());
150 // When the time has come, the timer should fire the scheduled task.
151 fake_timer->AdvanceToScheduledTime();
152 EXPECT_FALSE(fake_timer->IsRunning());
153 EXPECT_TRUE(fake_runner.HasRunningTask());
155 // Successful completion of the task fires next synchronization task.
156 fake_runner.CompleteTask(SYNC_STATUS_OK);
157 EXPECT_TRUE(fake_timer->IsRunning());
158 EXPECT_FALSE(fake_runner.HasRunningTask());
159 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
160 fake_timer->GetCurrentDelay());
162 // Turn |service_state| to TEMPORARY_UNAVAILABLE and let the task fail.
163 // |fake_runner| should schedule following tasks with longer delay.
164 fake_timer->AdvanceToScheduledTime();
165 fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE);
166 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
167 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds,
168 fake_timer->GetCurrentDelay());
170 // Repeated failure makes the task delay back off.
171 fake_timer->AdvanceToScheduledTime();
172 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
173 EXPECT_EQ(2 * SyncProcessRunner::kSyncDelaySlowInMilliseconds,
174 fake_timer->GetCurrentDelay());
176 // After |service_state| gets back to normal state, SyncProcessRunner should
177 // restart rapid task invocation.
178 fake_client.set_service_state(SYNC_SERVICE_RUNNING);
179 fake_timer->AdvanceToScheduledTime();
180 fake_runner.CompleteTask(SYNC_STATUS_OK);
181 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
182 fake_timer->GetCurrentDelay());
184 // There's no item to sync anymore, SyncProcessRunner should schedules the
185 // next with the longest delay.
186 fake_runner.UpdateChanges(0);
187 fake_timer->AdvanceToScheduledTime();
188 fake_runner.CompleteTask(SYNC_STATUS_OK);
189 EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds,
190 fake_timer->GetCurrentDelay());
192 // Schedule the next with the longest delay if the client is persistently
193 // unavailable.
194 fake_client.set_service_state(SYNC_SERVICE_AUTHENTICATION_REQUIRED);
195 fake_runner.UpdateChanges(100);
196 EXPECT_EQ(SyncProcessRunner::kSyncDelayMaxInMilliseconds,
197 fake_timer->GetCurrentDelay());
200 TEST(SyncProcessRunnerTest, MultiTaskBasicTest) {
201 FakeClient fake_client;
202 FakeTimerHelper* fake_timer = new FakeTimerHelper();
203 FakeSyncProcessRunner fake_runner(
204 &fake_client,
205 scoped_ptr<SyncProcessRunner::TimerHelper>(fake_timer),
206 2 /* max_parallel_task */);
208 base::TimeTicks base_time = base::TimeTicks::Now();
209 fake_timer->SetCurrentTime(base_time);
211 EXPECT_FALSE(fake_timer->IsRunning());
213 fake_runner.UpdateChanges(100);
214 EXPECT_TRUE(fake_timer->IsRunning());
215 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
216 fake_timer->GetCurrentDelay());
218 // Even after a task starts running, SyncProcessRunner should schedule next
219 // task until the number of running task reachs the limit.
220 fake_timer->AdvanceToScheduledTime();
221 EXPECT_TRUE(fake_timer->IsRunning());
222 EXPECT_TRUE(fake_runner.HasRunningTask());
223 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
224 fake_timer->GetCurrentDelay());
226 // After the second task starts running, SyncProcessRunner should stop
227 // scheduling a task.
228 fake_timer->AdvanceToScheduledTime();
229 EXPECT_FALSE(fake_timer->IsRunning());
230 EXPECT_TRUE(fake_runner.HasRunningTask());
232 fake_runner.CompleteTask(SYNC_STATUS_OK);
233 EXPECT_TRUE(fake_timer->IsRunning());
234 EXPECT_TRUE(fake_runner.HasRunningTask());
235 fake_runner.CompleteTask(SYNC_STATUS_OK);
236 EXPECT_TRUE(fake_timer->IsRunning());
237 EXPECT_FALSE(fake_runner.HasRunningTask());
239 // Turn |service_state| to TEMPORARY_UNAVAILABLE and let the task fail.
240 // |fake_runner| should schedule following tasks with longer delay.
241 fake_timer->AdvanceToScheduledTime();
242 fake_timer->AdvanceToScheduledTime();
243 fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE);
244 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
245 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds,
246 fake_timer->GetCurrentDelay());
248 // Consecutive error reports shouldn't extend delay immediately.
249 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
250 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds,
251 fake_timer->GetCurrentDelay());
253 // The next task will run after throttle period is over.
254 // And its failure should extend the throttle period by twice.
255 fake_timer->AdvanceToScheduledTime();
256 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds,
257 fake_timer->GetCurrentDelay());
258 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
259 EXPECT_EQ(2 * SyncProcessRunner::kSyncDelaySlowInMilliseconds,
260 fake_timer->GetCurrentDelay());
262 // Next successful task should clear the throttling.
263 fake_timer->AdvanceToScheduledTime();
264 fake_client.set_service_state(SYNC_SERVICE_RUNNING);
265 fake_runner.CompleteTask(SYNC_STATUS_OK);
266 EXPECT_EQ(SyncProcessRunner::kSyncDelayFastInMilliseconds,
267 fake_timer->GetCurrentDelay());
269 // Then, following failing task should not extend throttling period.
270 fake_timer->AdvanceToScheduledTime();
271 fake_client.set_service_state(SYNC_SERVICE_TEMPORARY_UNAVAILABLE);
272 fake_runner.CompleteTask(SYNC_STATUS_FAILED);
273 EXPECT_EQ(SyncProcessRunner::kSyncDelaySlowInMilliseconds,
274 fake_timer->GetCurrentDelay());
277 } // namespace sync_file_system