Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / sync_task_manager_unittest.cc
blob9bb3ee05954b989c899f91bf62bfe020d8d7cc48
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 <deque>
6 #include <string>
8 #include "base/basictypes.h"
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
17 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
18 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
19 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
20 #include "storage/common/fileapi/file_system_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 #define MAKE_PATH(path) \
24 base::FilePath(storage::VirtualPath::GetNormalizedFilePath( \
25 base::FilePath(FILE_PATH_LITERAL(path))))
27 namespace sync_file_system {
28 namespace drive_backend {
30 namespace {
32 void DumbTask(SyncStatusCode status,
33 const SyncStatusCallback& callback) {
34 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
35 base::Bind(callback, status));
38 void IncrementAndAssign(int expected_before_counter,
39 int* counter,
40 SyncStatusCode* status_out,
41 SyncStatusCode status) {
42 EXPECT_EQ(expected_before_counter, *counter);
43 ++(*counter);
44 *status_out = status;
47 template <typename T>
48 void IncrementAndAssignWithOwnedPointer(T* object,
49 int* counter,
50 SyncStatusCode* status_out,
51 SyncStatusCode status) {
52 ++(*counter);
53 *status_out = status;
56 class TaskManagerClient
57 : public SyncTaskManager::Client,
58 public base::SupportsWeakPtr<TaskManagerClient> {
59 public:
60 explicit TaskManagerClient(int64 maximum_background_task)
61 : maybe_schedule_next_task_count_(0),
62 task_scheduled_count_(0),
63 idle_task_scheduled_count_(0),
64 last_operation_status_(SYNC_STATUS_OK) {
65 task_manager_.reset(new SyncTaskManager(
66 AsWeakPtr(), maximum_background_task,
67 base::ThreadTaskRunnerHandle::Get(),
68 nullptr /* worker_pool */));
69 task_manager_->Initialize(SYNC_STATUS_OK);
70 base::MessageLoop::current()->RunUntilIdle();
71 maybe_schedule_next_task_count_ = 0;
73 ~TaskManagerClient() override {}
75 // DriveFileSyncManager::Client overrides.
76 void MaybeScheduleNextTask() override { ++maybe_schedule_next_task_count_; }
77 void NotifyLastOperationStatus(SyncStatusCode last_operation_status,
78 bool last_operation_used_network) override {
79 last_operation_status_ = last_operation_status;
82 void RecordTaskLog(scoped_ptr<TaskLogger::TaskLog>) override {}
84 void ScheduleTask(SyncStatusCode status_to_return,
85 const SyncStatusCallback& callback) {
86 task_manager_->ScheduleTask(
87 FROM_HERE,
88 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
89 status_to_return, false /* idle */),
90 SyncTaskManager::PRIORITY_MED,
91 callback);
94 void ScheduleTaskIfIdle(SyncStatusCode status_to_return) {
95 task_manager_->ScheduleTaskIfIdle(
96 FROM_HERE,
97 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
98 status_to_return, true /* idle */),
99 SyncStatusCallback());
102 int maybe_schedule_next_task_count() const {
103 return maybe_schedule_next_task_count_;
105 int task_scheduled_count() const { return task_scheduled_count_; }
106 int idle_task_scheduled_count() const { return idle_task_scheduled_count_; }
107 SyncStatusCode last_operation_status() const {
108 return last_operation_status_;
111 private:
112 void DoTask(SyncStatusCode status_to_return,
113 bool is_idle_task,
114 const SyncStatusCallback& callback) {
115 ++task_scheduled_count_;
116 if (is_idle_task)
117 ++idle_task_scheduled_count_;
118 base::ThreadTaskRunnerHandle::Get()->PostTask(
119 FROM_HERE, base::Bind(callback, status_to_return));
122 scoped_ptr<SyncTaskManager> task_manager_;
124 int maybe_schedule_next_task_count_;
125 int task_scheduled_count_;
126 int idle_task_scheduled_count_;
128 SyncStatusCode last_operation_status_;
130 DISALLOW_COPY_AND_ASSIGN(TaskManagerClient);
133 class MultihopSyncTask : public ExclusiveTask {
134 public:
135 MultihopSyncTask(bool* task_started,
136 bool* task_completed)
137 : task_started_(task_started),
138 task_completed_(task_completed),
139 weak_ptr_factory_(this) {
140 DCHECK(task_started_);
141 DCHECK(task_completed_);
144 ~MultihopSyncTask() override {}
146 void RunExclusive(const SyncStatusCallback& callback) override {
147 DCHECK(!*task_started_);
148 *task_started_ = true;
149 base::ThreadTaskRunnerHandle::Get()->PostTask(
150 FROM_HERE, base::Bind(&MultihopSyncTask::CompleteTask,
151 weak_ptr_factory_.GetWeakPtr(), callback));
154 private:
155 void CompleteTask(const SyncStatusCallback& callback) {
156 DCHECK(*task_started_);
157 DCHECK(!*task_completed_);
158 *task_completed_ = true;
159 callback.Run(SYNC_STATUS_OK);
162 bool* task_started_;
163 bool* task_completed_;
164 base::WeakPtrFactory<MultihopSyncTask> weak_ptr_factory_;
166 DISALLOW_COPY_AND_ASSIGN(MultihopSyncTask);
169 class BackgroundTask : public SyncTask {
170 public:
171 struct Stats {
172 int64 running_background_task;
173 int64 finished_task;
174 int64 max_parallel_task;
176 Stats()
177 : running_background_task(0),
178 finished_task(0),
179 max_parallel_task(0) {}
182 BackgroundTask(const std::string& app_id,
183 const base::FilePath& path,
184 Stats* stats)
185 : app_id_(app_id),
186 path_(path),
187 stats_(stats),
188 weak_ptr_factory_(this) {
191 ~BackgroundTask() override {}
193 void RunPreflight(scoped_ptr<SyncTaskToken> token) override {
194 scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
195 task_blocker->app_id = app_id_;
196 task_blocker->paths.push_back(path_);
198 SyncTaskManager::UpdateTaskBlocker(
199 token.Pass(), task_blocker.Pass(),
200 base::Bind(&BackgroundTask::RunAsBackgroundTask,
201 weak_ptr_factory_.GetWeakPtr()));
204 private:
205 void RunAsBackgroundTask(scoped_ptr<SyncTaskToken> token) {
206 ++(stats_->running_background_task);
207 if (stats_->max_parallel_task < stats_->running_background_task)
208 stats_->max_parallel_task = stats_->running_background_task;
210 base::ThreadTaskRunnerHandle::Get()->PostTask(
211 FROM_HERE,
212 base::Bind(&BackgroundTask::CompleteTask,
213 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token)));
216 void CompleteTask(scoped_ptr<SyncTaskToken> token) {
217 ++(stats_->finished_task);
218 --(stats_->running_background_task);
219 SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_OK);
222 std::string app_id_;
223 base::FilePath path_;
224 Stats* stats_;
226 base::WeakPtrFactory<BackgroundTask> weak_ptr_factory_;
228 DISALLOW_COPY_AND_ASSIGN(BackgroundTask);
231 class BlockerUpdateTestHelper : public SyncTask {
232 public:
233 typedef std::vector<std::string> Log;
235 BlockerUpdateTestHelper(const std::string& name,
236 const std::string& app_id,
237 const std::vector<std::string>& paths,
238 Log* log)
239 : name_(name),
240 app_id_(app_id),
241 paths_(paths.begin(), paths.end()),
242 log_(log),
243 weak_ptr_factory_(this) {
246 ~BlockerUpdateTestHelper() override {}
248 void RunPreflight(scoped_ptr<SyncTaskToken> token) override {
249 UpdateBlocker(token.Pass());
252 private:
253 void UpdateBlocker(scoped_ptr<SyncTaskToken> token) {
254 if (paths_.empty()) {
255 log_->push_back(name_ + ": finished");
256 SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_OK);
257 return;
260 std::string updating_to = paths_.front();
261 paths_.pop_front();
263 log_->push_back(name_ + ": updating to " + updating_to);
265 scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
266 task_blocker->app_id = app_id_;
267 task_blocker->paths.push_back(
268 base::FilePath(storage::VirtualPath::GetNormalizedFilePath(
269 base::FilePath::FromUTF8Unsafe(updating_to))));
271 SyncTaskManager::UpdateTaskBlocker(
272 token.Pass(), task_blocker.Pass(),
273 base::Bind(&BlockerUpdateTestHelper::UpdateBlockerSoon,
274 weak_ptr_factory_.GetWeakPtr(),
275 updating_to));
278 void UpdateBlockerSoon(const std::string& updated_to,
279 scoped_ptr<SyncTaskToken> token) {
280 log_->push_back(name_ + ": updated to " + updated_to);
281 base::ThreadTaskRunnerHandle::Get()->PostTask(
282 FROM_HERE,
283 base::Bind(&BlockerUpdateTestHelper::UpdateBlocker,
284 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token)));
287 std::string name_;
288 std::string app_id_;
289 std::deque<std::string> paths_;
290 Log* log_;
292 base::WeakPtrFactory<BlockerUpdateTestHelper> weak_ptr_factory_;
294 DISALLOW_COPY_AND_ASSIGN(BlockerUpdateTestHelper);
297 // Arbitrary non-default status values for testing.
298 const SyncStatusCode kStatus1 = static_cast<SyncStatusCode>(-1);
299 const SyncStatusCode kStatus2 = static_cast<SyncStatusCode>(-2);
300 const SyncStatusCode kStatus3 = static_cast<SyncStatusCode>(-3);
301 const SyncStatusCode kStatus4 = static_cast<SyncStatusCode>(-4);
302 const SyncStatusCode kStatus5 = static_cast<SyncStatusCode>(-5);
304 } // namespace
306 TEST(SyncTaskManagerTest, ScheduleTask) {
307 base::MessageLoop message_loop;
308 TaskManagerClient client(0 /* maximum_background_task */);
309 int callback_count = 0;
310 SyncStatusCode callback_status = SYNC_STATUS_OK;
312 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
313 &callback_count,
314 &callback_status));
315 message_loop.RunUntilIdle();
317 EXPECT_EQ(kStatus1, callback_status);
318 EXPECT_EQ(kStatus1, client.last_operation_status());
320 EXPECT_EQ(1, callback_count);
321 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
322 EXPECT_EQ(1, client.task_scheduled_count());
323 EXPECT_EQ(0, client.idle_task_scheduled_count());
326 TEST(SyncTaskManagerTest, ScheduleTwoTasks) {
327 base::MessageLoop message_loop;
328 TaskManagerClient client(0 /* maximum_background_task */);
329 int callback_count = 0;
330 SyncStatusCode callback_status = SYNC_STATUS_OK;
332 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
333 &callback_count,
334 &callback_status));
335 client.ScheduleTask(kStatus2, base::Bind(&IncrementAndAssign, 1,
336 &callback_count,
337 &callback_status));
338 message_loop.RunUntilIdle();
340 EXPECT_EQ(kStatus2, callback_status);
341 EXPECT_EQ(kStatus2, client.last_operation_status());
343 EXPECT_EQ(2, callback_count);
344 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
345 EXPECT_EQ(2, client.task_scheduled_count());
346 EXPECT_EQ(0, client.idle_task_scheduled_count());
349 TEST(SyncTaskManagerTest, ScheduleIdleTask) {
350 base::MessageLoop message_loop;
351 TaskManagerClient client(0 /* maximum_background_task */);
353 client.ScheduleTaskIfIdle(kStatus1);
354 message_loop.RunUntilIdle();
356 EXPECT_EQ(kStatus1, client.last_operation_status());
358 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
359 EXPECT_EQ(1, client.task_scheduled_count());
360 EXPECT_EQ(1, client.idle_task_scheduled_count());
363 TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) {
364 base::MessageLoop message_loop;
365 TaskManagerClient client(0 /* maximum_background_task */);
366 int callback_count = 0;
367 SyncStatusCode callback_status = SYNC_STATUS_OK;
369 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
370 &callback_count,
371 &callback_status));
372 client.ScheduleTaskIfIdle(kStatus2);
373 message_loop.RunUntilIdle();
375 // Idle task must not have run.
376 EXPECT_EQ(kStatus1, callback_status);
377 EXPECT_EQ(kStatus1, client.last_operation_status());
379 EXPECT_EQ(1, callback_count);
380 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
381 EXPECT_EQ(1, client.task_scheduled_count());
382 EXPECT_EQ(0, client.idle_task_scheduled_count());
385 TEST(SyncTaskManagerTest, ScheduleAndCancelSyncTask) {
386 base::MessageLoop message_loop;
388 int callback_count = 0;
389 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
391 bool task_started = false;
392 bool task_completed = false;
395 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
396 0 /* maximum_background_task */,
397 base::ThreadTaskRunnerHandle::Get(),
398 nullptr /* worker_pool */);
399 task_manager.Initialize(SYNC_STATUS_OK);
400 message_loop.RunUntilIdle();
401 task_manager.ScheduleSyncTask(
402 FROM_HERE,
403 scoped_ptr<SyncTask>(new MultihopSyncTask(
404 &task_started, &task_completed)),
405 SyncTaskManager::PRIORITY_MED,
406 base::Bind(&IncrementAndAssign, 0, &callback_count, &status));
408 message_loop.RunUntilIdle();
410 EXPECT_EQ(0, callback_count);
411 EXPECT_EQ(SYNC_STATUS_UNKNOWN, status);
412 EXPECT_TRUE(task_started);
413 EXPECT_FALSE(task_completed);
416 TEST(SyncTaskManagerTest, ScheduleTaskAtPriority) {
417 base::MessageLoop message_loop;
418 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
419 0 /* maximum_background_task */,
420 base::ThreadTaskRunnerHandle::Get(),
421 nullptr /* worker_pool */);
422 task_manager.Initialize(SYNC_STATUS_OK);
423 message_loop.RunUntilIdle();
425 int callback_count = 0;
426 SyncStatusCode callback_status1 = SYNC_STATUS_OK;
427 SyncStatusCode callback_status2 = SYNC_STATUS_OK;
428 SyncStatusCode callback_status3 = SYNC_STATUS_OK;
429 SyncStatusCode callback_status4 = SYNC_STATUS_OK;
430 SyncStatusCode callback_status5 = SYNC_STATUS_OK;
432 // This will run first even if its priority is low, since there're no
433 // pending tasks.
434 task_manager.ScheduleTask(
435 FROM_HERE,
436 base::Bind(&DumbTask, kStatus1),
437 SyncTaskManager::PRIORITY_LOW,
438 base::Bind(&IncrementAndAssign, 0, &callback_count, &callback_status1));
440 // This runs last (expected counter == 4).
441 task_manager.ScheduleTask(
442 FROM_HERE,
443 base::Bind(&DumbTask, kStatus2),
444 SyncTaskManager::PRIORITY_LOW,
445 base::Bind(&IncrementAndAssign, 4, &callback_count, &callback_status2));
447 // This runs second (expected counter == 1).
448 task_manager.ScheduleTask(
449 FROM_HERE,
450 base::Bind(&DumbTask, kStatus3),
451 SyncTaskManager::PRIORITY_HIGH,
452 base::Bind(&IncrementAndAssign, 1, &callback_count, &callback_status3));
454 // This runs fourth (expected counter == 3).
455 task_manager.ScheduleTask(
456 FROM_HERE,
457 base::Bind(&DumbTask, kStatus4),
458 SyncTaskManager::PRIORITY_MED,
459 base::Bind(&IncrementAndAssign, 3, &callback_count, &callback_status4));
461 // This runs third (expected counter == 2).
462 task_manager.ScheduleTask(
463 FROM_HERE,
464 base::Bind(&DumbTask, kStatus5),
465 SyncTaskManager::PRIORITY_HIGH,
466 base::Bind(&IncrementAndAssign, 2, &callback_count, &callback_status5));
468 message_loop.RunUntilIdle();
470 EXPECT_EQ(kStatus1, callback_status1);
471 EXPECT_EQ(kStatus2, callback_status2);
472 EXPECT_EQ(kStatus3, callback_status3);
473 EXPECT_EQ(kStatus4, callback_status4);
474 EXPECT_EQ(kStatus5, callback_status5);
475 EXPECT_EQ(5, callback_count);
478 TEST(SyncTaskManagerTest, BackgroundTask_Sequential) {
479 base::MessageLoop message_loop;
480 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
481 10 /* maximum_background_task */,
482 base::ThreadTaskRunnerHandle::Get(),
483 nullptr /* worker_pool */);
484 task_manager.Initialize(SYNC_STATUS_OK);
486 SyncStatusCode status = SYNC_STATUS_FAILED;
487 BackgroundTask::Stats stats;
488 task_manager.ScheduleSyncTask(
489 FROM_HERE,
490 scoped_ptr<SyncTask>(new BackgroundTask(
491 "app_id", MAKE_PATH("/hoge/fuga"),
492 &stats)),
493 SyncTaskManager::PRIORITY_MED,
494 CreateResultReceiver(&status));
496 task_manager.ScheduleSyncTask(
497 FROM_HERE,
498 scoped_ptr<SyncTask>(new BackgroundTask(
499 "app_id", MAKE_PATH("/hoge"),
500 &stats)),
501 SyncTaskManager::PRIORITY_MED,
502 CreateResultReceiver(&status));
504 task_manager.ScheduleSyncTask(
505 FROM_HERE,
506 scoped_ptr<SyncTask>(new BackgroundTask(
507 "app_id", MAKE_PATH("/hoge/fuga/piyo"),
508 &stats)),
509 SyncTaskManager::PRIORITY_MED,
510 CreateResultReceiver(&status));
512 message_loop.RunUntilIdle();
514 EXPECT_EQ(SYNC_STATUS_OK, status);
515 EXPECT_EQ(0, stats.running_background_task);
516 EXPECT_EQ(3, stats.finished_task);
517 EXPECT_EQ(1, stats.max_parallel_task);
520 TEST(SyncTaskManagerTest, BackgroundTask_Parallel) {
521 base::MessageLoop message_loop;
522 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
523 10 /* maximum_background_task */,
524 base::ThreadTaskRunnerHandle::Get(),
525 nullptr /* worker_pool */);
526 task_manager.Initialize(SYNC_STATUS_OK);
528 SyncStatusCode status = SYNC_STATUS_FAILED;
529 BackgroundTask::Stats stats;
530 task_manager.ScheduleSyncTask(
531 FROM_HERE,
532 scoped_ptr<SyncTask>(new BackgroundTask(
533 "app_id", MAKE_PATH("/hoge"),
534 &stats)),
535 SyncTaskManager::PRIORITY_MED,
536 CreateResultReceiver(&status));
538 task_manager.ScheduleSyncTask(
539 FROM_HERE,
540 scoped_ptr<SyncTask>(new BackgroundTask(
541 "app_id", MAKE_PATH("/fuga"),
542 &stats)),
543 SyncTaskManager::PRIORITY_MED,
544 CreateResultReceiver(&status));
546 task_manager.ScheduleSyncTask(
547 FROM_HERE,
548 scoped_ptr<SyncTask>(new BackgroundTask(
549 "app_id", MAKE_PATH("/piyo"),
550 &stats)),
551 SyncTaskManager::PRIORITY_MED,
552 CreateResultReceiver(&status));
554 message_loop.RunUntilIdle();
556 EXPECT_EQ(SYNC_STATUS_OK, status);
557 EXPECT_EQ(0, stats.running_background_task);
558 EXPECT_EQ(3, stats.finished_task);
559 EXPECT_EQ(3, stats.max_parallel_task);
562 TEST(SyncTaskManagerTest, BackgroundTask_Throttled) {
563 base::MessageLoop message_loop;
564 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
565 2 /* maximum_background_task */,
566 base::ThreadTaskRunnerHandle::Get(),
567 nullptr /* worker_pool */);
568 task_manager.Initialize(SYNC_STATUS_OK);
570 SyncStatusCode status = SYNC_STATUS_FAILED;
571 BackgroundTask::Stats stats;
572 task_manager.ScheduleSyncTask(
573 FROM_HERE,
574 scoped_ptr<SyncTask>(new BackgroundTask(
575 "app_id", MAKE_PATH("/hoge"),
576 &stats)),
577 SyncTaskManager::PRIORITY_MED,
578 CreateResultReceiver(&status));
580 task_manager.ScheduleSyncTask(
581 FROM_HERE,
582 scoped_ptr<SyncTask>(new BackgroundTask(
583 "app_id", MAKE_PATH("/fuga"),
584 &stats)),
585 SyncTaskManager::PRIORITY_MED,
586 CreateResultReceiver(&status));
588 task_manager.ScheduleSyncTask(
589 FROM_HERE,
590 scoped_ptr<SyncTask>(new BackgroundTask(
591 "app_id", MAKE_PATH("/piyo"),
592 &stats)),
593 SyncTaskManager::PRIORITY_MED,
594 CreateResultReceiver(&status));
596 message_loop.RunUntilIdle();
598 EXPECT_EQ(SYNC_STATUS_OK, status);
599 EXPECT_EQ(0, stats.running_background_task);
600 EXPECT_EQ(3, stats.finished_task);
601 EXPECT_EQ(2, stats.max_parallel_task);
604 TEST(SyncTaskManagerTest, UpdateTaskBlocker) {
605 base::MessageLoop message_loop;
606 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
607 10 /* maximum_background_task */,
608 base::ThreadTaskRunnerHandle::Get(),
609 nullptr /* worker_pool */);
610 task_manager.Initialize(SYNC_STATUS_OK);
612 SyncStatusCode status1 = SYNC_STATUS_FAILED;
613 SyncStatusCode status2 = SYNC_STATUS_FAILED;
614 BlockerUpdateTestHelper::Log log;
617 std::vector<std::string> paths;
618 paths.push_back("/foo/bar");
619 paths.push_back("/foo");
620 paths.push_back("/hoge/fuga/piyo");
621 task_manager.ScheduleSyncTask(
622 FROM_HERE,
623 scoped_ptr<SyncTask>(new BlockerUpdateTestHelper(
624 "task1", "app_id", paths, &log)),
625 SyncTaskManager::PRIORITY_MED,
626 CreateResultReceiver(&status1));
630 std::vector<std::string> paths;
631 paths.push_back("/foo");
632 paths.push_back("/foo/bar");
633 paths.push_back("/hoge/fuga/piyo");
634 task_manager.ScheduleSyncTask(
635 FROM_HERE,
636 scoped_ptr<SyncTask>(new BlockerUpdateTestHelper(
637 "task2", "app_id", paths, &log)),
638 SyncTaskManager::PRIORITY_MED,
639 CreateResultReceiver(&status2));
642 message_loop.RunUntilIdle();
644 EXPECT_EQ(SYNC_STATUS_OK, status1);
645 EXPECT_EQ(SYNC_STATUS_OK, status2);
647 ASSERT_EQ(14u, log.size());
648 int i = 0;
650 // task1 takes "/foo/bar" first.
651 EXPECT_EQ("task1: updating to /foo/bar", log[i++]);
653 // task1 blocks task2. task2's update should not complete until task1 update.
654 EXPECT_EQ("task2: updating to /foo", log[i++]);
655 EXPECT_EQ("task1: updated to /foo/bar", log[i++]);
657 // task1 releases "/foo/bar" and tries to take "/foo". Then, pending task2
658 // takes "/foo" and blocks task1.
659 EXPECT_EQ("task1: updating to /foo", log[i++]);
660 EXPECT_EQ("task2: updated to /foo", log[i++]);
662 // task2 releases "/foo".
663 EXPECT_EQ("task2: updating to /foo/bar", log[i++]);
664 EXPECT_EQ("task1: updated to /foo", log[i++]);
666 // task1 releases "/foo".
667 EXPECT_EQ("task1: updating to /hoge/fuga/piyo", log[i++]);
668 EXPECT_EQ("task1: updated to /hoge/fuga/piyo", log[i++]);
669 EXPECT_EQ("task2: updated to /foo/bar", log[i++]);
671 EXPECT_EQ("task1: finished", log[i++]);
673 EXPECT_EQ("task2: updating to /hoge/fuga/piyo", log[i++]);
674 EXPECT_EQ("task2: updated to /hoge/fuga/piyo", log[i++]);
675 EXPECT_EQ("task2: finished", log[i++]);
678 } // namespace drive_backend
679 } // namespace sync_file_system