Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / sync_task_manager_unittest.cc
blobbe9fb0cc9c5c2695d526836bc812ac5d3b78321d
1 // Copyright 2013 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 "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/sync_file_system/sync_task_manager.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace sync_file_system {
14 namespace {
16 void DumbTask(SyncStatusCode status,
17 const SyncStatusCallback& callback) {
18 base::MessageLoop::current()->PostTask(
19 FROM_HERE, base::Bind(callback, status));
22 void IncrementAndAssign(int expected_before_counter,
23 int* counter,
24 SyncStatusCode* status_out,
25 SyncStatusCode status) {
26 EXPECT_EQ(expected_before_counter, *counter);
27 ++(*counter);
28 *status_out = status;
31 template <typename T>
32 void IncrementAndAssignWithOwnedPointer(T* object,
33 int* counter,
34 SyncStatusCode* status_out,
35 SyncStatusCode status) {
36 ++(*counter);
37 *status_out = status;
40 class TaskManagerClient
41 : public SyncTaskManager::Client,
42 public base::SupportsWeakPtr<TaskManagerClient> {
43 public:
44 TaskManagerClient()
45 : maybe_schedule_next_task_count_(0),
46 task_scheduled_count_(0),
47 idle_task_scheduled_count_(0),
48 last_operation_status_(SYNC_STATUS_OK) {
49 task_manager_.reset(new SyncTaskManager(AsWeakPtr()));
50 task_manager_->Initialize(SYNC_STATUS_OK);
51 maybe_schedule_next_task_count_ = 0;
53 virtual ~TaskManagerClient() {}
55 // DriveFileSyncManager::Client overrides.
56 virtual void MaybeScheduleNextTask() OVERRIDE {
57 ++maybe_schedule_next_task_count_;
59 virtual void NotifyLastOperationStatus(
60 SyncStatusCode last_operation_status,
61 bool last_operation_used_network) OVERRIDE {
62 last_operation_status_ = last_operation_status;
65 void ScheduleTask(SyncStatusCode status_to_return,
66 const SyncStatusCallback& callback) {
67 task_manager_->ScheduleTask(
68 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
69 status_to_return, false /* idle */),
70 callback);
73 void ScheduleTaskIfIdle(SyncStatusCode status_to_return) {
74 task_manager_->ScheduleTaskIfIdle(
75 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
76 status_to_return, true /* idle */),
77 SyncStatusCallback());
80 int maybe_schedule_next_task_count() const {
81 return maybe_schedule_next_task_count_;
83 int task_scheduled_count() const { return task_scheduled_count_; }
84 int idle_task_scheduled_count() const { return idle_task_scheduled_count_; }
85 SyncStatusCode last_operation_status() const {
86 return last_operation_status_;
89 private:
90 void DoTask(SyncStatusCode status_to_return,
91 bool is_idle_task,
92 const SyncStatusCallback& callback) {
93 ++task_scheduled_count_;
94 if (is_idle_task)
95 ++idle_task_scheduled_count_;
96 base::MessageLoop::current()->PostTask(
97 FROM_HERE, base::Bind(callback, status_to_return));
100 scoped_ptr<SyncTaskManager> task_manager_;
102 int maybe_schedule_next_task_count_;
103 int task_scheduled_count_;
104 int idle_task_scheduled_count_;
106 SyncStatusCode last_operation_status_;
108 DISALLOW_COPY_AND_ASSIGN(TaskManagerClient);
111 class MultihopSyncTask : public SyncTask {
112 public:
113 MultihopSyncTask(bool* task_started,
114 bool* task_completed)
115 : task_started_(task_started),
116 task_completed_(task_completed),
117 weak_ptr_factory_(this) {
118 DCHECK(task_started_);
119 DCHECK(task_completed_);
122 virtual ~MultihopSyncTask() {}
124 virtual void Run(const SyncStatusCallback& callback) OVERRIDE {
125 DCHECK(!*task_started_);
126 *task_started_ = true;
127 base::MessageLoop::current()->PostTask(
128 FROM_HERE, base::Bind(&MultihopSyncTask::CompleteTask,
129 weak_ptr_factory_.GetWeakPtr(), callback));
132 private:
133 void CompleteTask(const SyncStatusCallback& callback) {
134 DCHECK(*task_started_);
135 DCHECK(!*task_completed_);
136 *task_completed_ = true;
137 callback.Run(SYNC_STATUS_OK);
140 bool* task_started_;
141 bool* task_completed_;
142 base::WeakPtrFactory<MultihopSyncTask> weak_ptr_factory_;
144 DISALLOW_COPY_AND_ASSIGN(MultihopSyncTask);
147 // Arbitrary non-default status values for testing.
148 const SyncStatusCode kStatus1 = static_cast<SyncStatusCode>(-1);
149 const SyncStatusCode kStatus2 = static_cast<SyncStatusCode>(-2);
150 const SyncStatusCode kStatus3 = static_cast<SyncStatusCode>(-3);
151 const SyncStatusCode kStatus4 = static_cast<SyncStatusCode>(-4);
152 const SyncStatusCode kStatus5 = static_cast<SyncStatusCode>(-5);
154 } // namespace
156 TEST(SyncTaskManagerTest, ScheduleTask) {
157 base::MessageLoop message_loop;
158 TaskManagerClient client;
159 int callback_count = 0;
160 SyncStatusCode callback_status = SYNC_STATUS_OK;
162 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
163 &callback_count,
164 &callback_status));
165 message_loop.RunUntilIdle();
167 EXPECT_EQ(kStatus1, callback_status);
168 EXPECT_EQ(kStatus1, client.last_operation_status());
170 EXPECT_EQ(1, callback_count);
171 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
172 EXPECT_EQ(1, client.task_scheduled_count());
173 EXPECT_EQ(0, client.idle_task_scheduled_count());
176 TEST(SyncTaskManagerTest, ScheduleTwoTasks) {
177 base::MessageLoop message_loop;
178 TaskManagerClient client;
179 int callback_count = 0;
180 SyncStatusCode callback_status = SYNC_STATUS_OK;
182 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
183 &callback_count,
184 &callback_status));
185 client.ScheduleTask(kStatus2, base::Bind(&IncrementAndAssign, 1,
186 &callback_count,
187 &callback_status));
188 message_loop.RunUntilIdle();
190 EXPECT_EQ(kStatus2, callback_status);
191 EXPECT_EQ(kStatus2, client.last_operation_status());
193 EXPECT_EQ(2, callback_count);
194 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
195 EXPECT_EQ(2, client.task_scheduled_count());
196 EXPECT_EQ(0, client.idle_task_scheduled_count());
199 TEST(SyncTaskManagerTest, ScheduleIdleTask) {
200 base::MessageLoop message_loop;
201 TaskManagerClient client;
203 client.ScheduleTaskIfIdle(kStatus1);
204 message_loop.RunUntilIdle();
206 EXPECT_EQ(kStatus1, client.last_operation_status());
208 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
209 EXPECT_EQ(1, client.task_scheduled_count());
210 EXPECT_EQ(1, client.idle_task_scheduled_count());
213 TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) {
214 base::MessageLoop message_loop;
215 TaskManagerClient client;
216 int callback_count = 0;
217 SyncStatusCode callback_status = SYNC_STATUS_OK;
219 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
220 &callback_count,
221 &callback_status));
222 client.ScheduleTaskIfIdle(kStatus2);
223 message_loop.RunUntilIdle();
225 // Idle task must not have run.
226 EXPECT_EQ(kStatus1, callback_status);
227 EXPECT_EQ(kStatus1, client.last_operation_status());
229 EXPECT_EQ(1, callback_count);
230 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
231 EXPECT_EQ(1, client.task_scheduled_count());
232 EXPECT_EQ(0, client.idle_task_scheduled_count());
235 TEST(SyncTaskManagerTest, ScheduleAndCancelSyncTask) {
236 base::MessageLoop message_loop;
238 int callback_count = 0;
239 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
241 bool task_started = false;
242 bool task_completed = false;
245 SyncTaskManager task_manager((base::WeakPtr<SyncTaskManager::Client>()));
246 task_manager.Initialize(SYNC_STATUS_OK);
247 task_manager.ScheduleSyncTask(
248 scoped_ptr<SyncTask>(new MultihopSyncTask(
249 &task_started, &task_completed)),
250 base::Bind(&IncrementAndAssign, 0, &callback_count, &status));
253 message_loop.RunUntilIdle();
254 EXPECT_EQ(0, callback_count);
255 EXPECT_EQ(SYNC_STATUS_UNKNOWN, status);
256 EXPECT_TRUE(task_started);
257 EXPECT_FALSE(task_completed);
260 TEST(SyncTaskManagerTest, ScheduleAndCancelTask) {
261 base::MessageLoop message_loop;
263 int callback_count = 0;
264 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
266 bool task_started = false;
267 bool task_completed = false;
270 SyncTaskManager task_manager((base::WeakPtr<SyncTaskManager::Client>()));
271 task_manager.Initialize(SYNC_STATUS_OK);
272 MultihopSyncTask* task = new MultihopSyncTask(
273 &task_started, &task_completed);
274 task_manager.ScheduleTask(
275 base::Bind(&MultihopSyncTask::Run, base::Unretained(task)),
276 base::Bind(&IncrementAndAssignWithOwnedPointer<MultihopSyncTask>,
277 base::Owned(task), &callback_count, &status));
280 message_loop.RunUntilIdle();
281 EXPECT_EQ(0, callback_count);
282 EXPECT_EQ(SYNC_STATUS_UNKNOWN, status);
283 EXPECT_TRUE(task_started);
284 EXPECT_FALSE(task_completed);
287 TEST(SyncTaskManagerTest, ScheduleTaskAtPriority) {
288 base::MessageLoop message_loop;
289 SyncTaskManager task_manager((base::WeakPtr<SyncTaskManager::Client>()));
290 task_manager.Initialize(SYNC_STATUS_OK);
292 int callback_count = 0;
293 SyncStatusCode callback_status1 = SYNC_STATUS_OK;
294 SyncStatusCode callback_status2 = SYNC_STATUS_OK;
295 SyncStatusCode callback_status3 = SYNC_STATUS_OK;
296 SyncStatusCode callback_status4 = SYNC_STATUS_OK;
297 SyncStatusCode callback_status5 = SYNC_STATUS_OK;
299 // This will run first even if its priority is low, since there're no
300 // pending tasks.
301 task_manager.ScheduleTaskAtPriority(
302 base::Bind(&DumbTask, kStatus1),
303 SyncTaskManager::PRIORITY_LOW,
304 base::Bind(&IncrementAndAssign, 0, &callback_count, &callback_status1));
306 // This runs last (expected counter == 4).
307 task_manager.ScheduleTaskAtPriority(
308 base::Bind(&DumbTask, kStatus2),
309 SyncTaskManager::PRIORITY_LOW,
310 base::Bind(&IncrementAndAssign, 4, &callback_count, &callback_status2));
312 // This runs second (expected counter == 1).
313 task_manager.ScheduleTaskAtPriority(
314 base::Bind(&DumbTask, kStatus3),
315 SyncTaskManager::PRIORITY_HIGH,
316 base::Bind(&IncrementAndAssign, 1, &callback_count, &callback_status3));
318 // This runs fourth (expected counter == 3).
319 task_manager.ScheduleTaskAtPriority(
320 base::Bind(&DumbTask, kStatus4),
321 SyncTaskManager::PRIORITY_MED,
322 base::Bind(&IncrementAndAssign, 3, &callback_count, &callback_status4));
324 // This runs third (expected counter == 2).
325 task_manager.ScheduleTaskAtPriority(
326 base::Bind(&DumbTask, kStatus5),
327 SyncTaskManager::PRIORITY_HIGH,
328 base::Bind(&IncrementAndAssign, 2, &callback_count, &callback_status5));
330 message_loop.RunUntilIdle();
332 EXPECT_EQ(kStatus1, callback_status1);
333 EXPECT_EQ(kStatus2, callback_status2);
334 EXPECT_EQ(kStatus3, callback_status3);
335 EXPECT_EQ(kStatus4, callback_status4);
336 EXPECT_EQ(kStatus5, callback_status5);
337 EXPECT_EQ(5, callback_count);
340 } // namespace sync_file_system