Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / sync_task_manager_unittest.cc
blobcf01a067f3d03f5ff916f189bab95b609a6b6e35
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/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
15 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
16 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
17 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
18 #include "storage/common/fileapi/file_system_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 #define MAKE_PATH(path) \
22 base::FilePath(storage::VirtualPath::GetNormalizedFilePath( \
23 base::FilePath(FILE_PATH_LITERAL(path))))
25 namespace sync_file_system {
26 namespace drive_backend {
28 namespace {
30 void DumbTask(SyncStatusCode status,
31 const SyncStatusCallback& callback) {
32 base::MessageLoop::current()->PostTask(
33 FROM_HERE, base::Bind(callback, status));
36 void IncrementAndAssign(int expected_before_counter,
37 int* counter,
38 SyncStatusCode* status_out,
39 SyncStatusCode status) {
40 EXPECT_EQ(expected_before_counter, *counter);
41 ++(*counter);
42 *status_out = status;
45 template <typename T>
46 void IncrementAndAssignWithOwnedPointer(T* object,
47 int* counter,
48 SyncStatusCode* status_out,
49 SyncStatusCode status) {
50 ++(*counter);
51 *status_out = status;
54 class TaskManagerClient
55 : public SyncTaskManager::Client,
56 public base::SupportsWeakPtr<TaskManagerClient> {
57 public:
58 explicit TaskManagerClient(int64 maximum_background_task)
59 : maybe_schedule_next_task_count_(0),
60 task_scheduled_count_(0),
61 idle_task_scheduled_count_(0),
62 last_operation_status_(SYNC_STATUS_OK) {
63 task_manager_.reset(new SyncTaskManager(
64 AsWeakPtr(), maximum_background_task,
65 base::ThreadTaskRunnerHandle::Get(),
66 nullptr /* worker_pool */));
67 task_manager_->Initialize(SYNC_STATUS_OK);
68 base::MessageLoop::current()->RunUntilIdle();
69 maybe_schedule_next_task_count_ = 0;
71 ~TaskManagerClient() override {}
73 // DriveFileSyncManager::Client overrides.
74 void MaybeScheduleNextTask() override { ++maybe_schedule_next_task_count_; }
75 void NotifyLastOperationStatus(SyncStatusCode last_operation_status,
76 bool last_operation_used_network) override {
77 last_operation_status_ = last_operation_status;
80 void RecordTaskLog(scoped_ptr<TaskLogger::TaskLog>) override {}
82 void ScheduleTask(SyncStatusCode status_to_return,
83 const SyncStatusCallback& callback) {
84 task_manager_->ScheduleTask(
85 FROM_HERE,
86 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
87 status_to_return, false /* idle */),
88 SyncTaskManager::PRIORITY_MED,
89 callback);
92 void ScheduleTaskIfIdle(SyncStatusCode status_to_return) {
93 task_manager_->ScheduleTaskIfIdle(
94 FROM_HERE,
95 base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
96 status_to_return, true /* idle */),
97 SyncStatusCallback());
100 int maybe_schedule_next_task_count() const {
101 return maybe_schedule_next_task_count_;
103 int task_scheduled_count() const { return task_scheduled_count_; }
104 int idle_task_scheduled_count() const { return idle_task_scheduled_count_; }
105 SyncStatusCode last_operation_status() const {
106 return last_operation_status_;
109 private:
110 void DoTask(SyncStatusCode status_to_return,
111 bool is_idle_task,
112 const SyncStatusCallback& callback) {
113 ++task_scheduled_count_;
114 if (is_idle_task)
115 ++idle_task_scheduled_count_;
116 base::MessageLoop::current()->PostTask(
117 FROM_HERE, base::Bind(callback, status_to_return));
120 scoped_ptr<SyncTaskManager> task_manager_;
122 int maybe_schedule_next_task_count_;
123 int task_scheduled_count_;
124 int idle_task_scheduled_count_;
126 SyncStatusCode last_operation_status_;
128 DISALLOW_COPY_AND_ASSIGN(TaskManagerClient);
131 class MultihopSyncTask : public ExclusiveTask {
132 public:
133 MultihopSyncTask(bool* task_started,
134 bool* task_completed)
135 : task_started_(task_started),
136 task_completed_(task_completed),
137 weak_ptr_factory_(this) {
138 DCHECK(task_started_);
139 DCHECK(task_completed_);
142 ~MultihopSyncTask() override {}
144 void RunExclusive(const SyncStatusCallback& callback) override {
145 DCHECK(!*task_started_);
146 *task_started_ = true;
147 base::MessageLoop::current()->PostTask(
148 FROM_HERE, base::Bind(&MultihopSyncTask::CompleteTask,
149 weak_ptr_factory_.GetWeakPtr(), callback));
152 private:
153 void CompleteTask(const SyncStatusCallback& callback) {
154 DCHECK(*task_started_);
155 DCHECK(!*task_completed_);
156 *task_completed_ = true;
157 callback.Run(SYNC_STATUS_OK);
160 bool* task_started_;
161 bool* task_completed_;
162 base::WeakPtrFactory<MultihopSyncTask> weak_ptr_factory_;
164 DISALLOW_COPY_AND_ASSIGN(MultihopSyncTask);
167 class BackgroundTask : public SyncTask {
168 public:
169 struct Stats {
170 int64 running_background_task;
171 int64 finished_task;
172 int64 max_parallel_task;
174 Stats()
175 : running_background_task(0),
176 finished_task(0),
177 max_parallel_task(0) {}
180 BackgroundTask(const std::string& app_id,
181 const base::FilePath& path,
182 Stats* stats)
183 : app_id_(app_id),
184 path_(path),
185 stats_(stats),
186 weak_ptr_factory_(this) {
189 ~BackgroundTask() override {}
191 void RunPreflight(scoped_ptr<SyncTaskToken> token) override {
192 scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
193 task_blocker->app_id = app_id_;
194 task_blocker->paths.push_back(path_);
196 SyncTaskManager::UpdateTaskBlocker(
197 token.Pass(), task_blocker.Pass(),
198 base::Bind(&BackgroundTask::RunAsBackgroundTask,
199 weak_ptr_factory_.GetWeakPtr()));
202 private:
203 void RunAsBackgroundTask(scoped_ptr<SyncTaskToken> token) {
204 ++(stats_->running_background_task);
205 if (stats_->max_parallel_task < stats_->running_background_task)
206 stats_->max_parallel_task = stats_->running_background_task;
208 base::MessageLoop::current()->PostTask(
209 FROM_HERE,
210 base::Bind(&BackgroundTask::CompleteTask,
211 weak_ptr_factory_.GetWeakPtr(),
212 base::Passed(&token)));
215 void CompleteTask(scoped_ptr<SyncTaskToken> token) {
216 ++(stats_->finished_task);
217 --(stats_->running_background_task);
218 SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_OK);
221 std::string app_id_;
222 base::FilePath path_;
223 Stats* stats_;
225 base::WeakPtrFactory<BackgroundTask> weak_ptr_factory_;
227 DISALLOW_COPY_AND_ASSIGN(BackgroundTask);
230 class BlockerUpdateTestHelper : public SyncTask {
231 public:
232 typedef std::vector<std::string> Log;
234 BlockerUpdateTestHelper(const std::string& name,
235 const std::string& app_id,
236 const std::vector<std::string>& paths,
237 Log* log)
238 : name_(name),
239 app_id_(app_id),
240 paths_(paths.begin(), paths.end()),
241 log_(log),
242 weak_ptr_factory_(this) {
245 ~BlockerUpdateTestHelper() override {}
247 void RunPreflight(scoped_ptr<SyncTaskToken> token) override {
248 UpdateBlocker(token.Pass());
251 private:
252 void UpdateBlocker(scoped_ptr<SyncTaskToken> token) {
253 if (paths_.empty()) {
254 log_->push_back(name_ + ": finished");
255 SyncTaskManager::NotifyTaskDone(token.Pass(), SYNC_STATUS_OK);
256 return;
259 std::string updating_to = paths_.front();
260 paths_.pop_front();
262 log_->push_back(name_ + ": updating to " + updating_to);
264 scoped_ptr<TaskBlocker> task_blocker(new TaskBlocker);
265 task_blocker->app_id = app_id_;
266 task_blocker->paths.push_back(
267 base::FilePath(storage::VirtualPath::GetNormalizedFilePath(
268 base::FilePath::FromUTF8Unsafe(updating_to))));
270 SyncTaskManager::UpdateTaskBlocker(
271 token.Pass(), task_blocker.Pass(),
272 base::Bind(&BlockerUpdateTestHelper::UpdateBlockerSoon,
273 weak_ptr_factory_.GetWeakPtr(),
274 updating_to));
277 void UpdateBlockerSoon(const std::string& updated_to,
278 scoped_ptr<SyncTaskToken> token) {
279 log_->push_back(name_ + ": updated to " + updated_to);
280 base::MessageLoop::current()->PostTask(
281 FROM_HERE,
282 base::Bind(&BlockerUpdateTestHelper::UpdateBlocker,
283 weak_ptr_factory_.GetWeakPtr(), base::Passed(&token)));
286 std::string name_;
287 std::string app_id_;
288 std::deque<std::string> paths_;
289 Log* log_;
291 base::WeakPtrFactory<BlockerUpdateTestHelper> weak_ptr_factory_;
293 DISALLOW_COPY_AND_ASSIGN(BlockerUpdateTestHelper);
296 // Arbitrary non-default status values for testing.
297 const SyncStatusCode kStatus1 = static_cast<SyncStatusCode>(-1);
298 const SyncStatusCode kStatus2 = static_cast<SyncStatusCode>(-2);
299 const SyncStatusCode kStatus3 = static_cast<SyncStatusCode>(-3);
300 const SyncStatusCode kStatus4 = static_cast<SyncStatusCode>(-4);
301 const SyncStatusCode kStatus5 = static_cast<SyncStatusCode>(-5);
303 } // namespace
305 TEST(SyncTaskManagerTest, ScheduleTask) {
306 base::MessageLoop message_loop;
307 TaskManagerClient client(0 /* maximum_background_task */);
308 int callback_count = 0;
309 SyncStatusCode callback_status = SYNC_STATUS_OK;
311 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
312 &callback_count,
313 &callback_status));
314 message_loop.RunUntilIdle();
316 EXPECT_EQ(kStatus1, callback_status);
317 EXPECT_EQ(kStatus1, client.last_operation_status());
319 EXPECT_EQ(1, callback_count);
320 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
321 EXPECT_EQ(1, client.task_scheduled_count());
322 EXPECT_EQ(0, client.idle_task_scheduled_count());
325 TEST(SyncTaskManagerTest, ScheduleTwoTasks) {
326 base::MessageLoop message_loop;
327 TaskManagerClient client(0 /* maximum_background_task */);
328 int callback_count = 0;
329 SyncStatusCode callback_status = SYNC_STATUS_OK;
331 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
332 &callback_count,
333 &callback_status));
334 client.ScheduleTask(kStatus2, base::Bind(&IncrementAndAssign, 1,
335 &callback_count,
336 &callback_status));
337 message_loop.RunUntilIdle();
339 EXPECT_EQ(kStatus2, callback_status);
340 EXPECT_EQ(kStatus2, client.last_operation_status());
342 EXPECT_EQ(2, callback_count);
343 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
344 EXPECT_EQ(2, client.task_scheduled_count());
345 EXPECT_EQ(0, client.idle_task_scheduled_count());
348 TEST(SyncTaskManagerTest, ScheduleIdleTask) {
349 base::MessageLoop message_loop;
350 TaskManagerClient client(0 /* maximum_background_task */);
352 client.ScheduleTaskIfIdle(kStatus1);
353 message_loop.RunUntilIdle();
355 EXPECT_EQ(kStatus1, client.last_operation_status());
357 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
358 EXPECT_EQ(1, client.task_scheduled_count());
359 EXPECT_EQ(1, client.idle_task_scheduled_count());
362 TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) {
363 base::MessageLoop message_loop;
364 TaskManagerClient client(0 /* maximum_background_task */);
365 int callback_count = 0;
366 SyncStatusCode callback_status = SYNC_STATUS_OK;
368 client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
369 &callback_count,
370 &callback_status));
371 client.ScheduleTaskIfIdle(kStatus2);
372 message_loop.RunUntilIdle();
374 // Idle task must not have run.
375 EXPECT_EQ(kStatus1, callback_status);
376 EXPECT_EQ(kStatus1, client.last_operation_status());
378 EXPECT_EQ(1, callback_count);
379 EXPECT_EQ(1, client.maybe_schedule_next_task_count());
380 EXPECT_EQ(1, client.task_scheduled_count());
381 EXPECT_EQ(0, client.idle_task_scheduled_count());
384 TEST(SyncTaskManagerTest, ScheduleAndCancelSyncTask) {
385 base::MessageLoop message_loop;
387 int callback_count = 0;
388 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
390 bool task_started = false;
391 bool task_completed = false;
394 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
395 0 /* maximum_background_task */,
396 base::ThreadTaskRunnerHandle::Get(),
397 nullptr /* worker_pool */);
398 task_manager.Initialize(SYNC_STATUS_OK);
399 message_loop.RunUntilIdle();
400 task_manager.ScheduleSyncTask(
401 FROM_HERE,
402 scoped_ptr<SyncTask>(new MultihopSyncTask(
403 &task_started, &task_completed)),
404 SyncTaskManager::PRIORITY_MED,
405 base::Bind(&IncrementAndAssign, 0, &callback_count, &status));
407 message_loop.RunUntilIdle();
409 EXPECT_EQ(0, callback_count);
410 EXPECT_EQ(SYNC_STATUS_UNKNOWN, status);
411 EXPECT_TRUE(task_started);
412 EXPECT_FALSE(task_completed);
415 TEST(SyncTaskManagerTest, ScheduleTaskAtPriority) {
416 base::MessageLoop message_loop;
417 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
418 0 /* maximum_background_task */,
419 base::ThreadTaskRunnerHandle::Get(),
420 nullptr /* worker_pool */);
421 task_manager.Initialize(SYNC_STATUS_OK);
422 message_loop.RunUntilIdle();
424 int callback_count = 0;
425 SyncStatusCode callback_status1 = SYNC_STATUS_OK;
426 SyncStatusCode callback_status2 = SYNC_STATUS_OK;
427 SyncStatusCode callback_status3 = SYNC_STATUS_OK;
428 SyncStatusCode callback_status4 = SYNC_STATUS_OK;
429 SyncStatusCode callback_status5 = SYNC_STATUS_OK;
431 // This will run first even if its priority is low, since there're no
432 // pending tasks.
433 task_manager.ScheduleTask(
434 FROM_HERE,
435 base::Bind(&DumbTask, kStatus1),
436 SyncTaskManager::PRIORITY_LOW,
437 base::Bind(&IncrementAndAssign, 0, &callback_count, &callback_status1));
439 // This runs last (expected counter == 4).
440 task_manager.ScheduleTask(
441 FROM_HERE,
442 base::Bind(&DumbTask, kStatus2),
443 SyncTaskManager::PRIORITY_LOW,
444 base::Bind(&IncrementAndAssign, 4, &callback_count, &callback_status2));
446 // This runs second (expected counter == 1).
447 task_manager.ScheduleTask(
448 FROM_HERE,
449 base::Bind(&DumbTask, kStatus3),
450 SyncTaskManager::PRIORITY_HIGH,
451 base::Bind(&IncrementAndAssign, 1, &callback_count, &callback_status3));
453 // This runs fourth (expected counter == 3).
454 task_manager.ScheduleTask(
455 FROM_HERE,
456 base::Bind(&DumbTask, kStatus4),
457 SyncTaskManager::PRIORITY_MED,
458 base::Bind(&IncrementAndAssign, 3, &callback_count, &callback_status4));
460 // This runs third (expected counter == 2).
461 task_manager.ScheduleTask(
462 FROM_HERE,
463 base::Bind(&DumbTask, kStatus5),
464 SyncTaskManager::PRIORITY_HIGH,
465 base::Bind(&IncrementAndAssign, 2, &callback_count, &callback_status5));
467 message_loop.RunUntilIdle();
469 EXPECT_EQ(kStatus1, callback_status1);
470 EXPECT_EQ(kStatus2, callback_status2);
471 EXPECT_EQ(kStatus3, callback_status3);
472 EXPECT_EQ(kStatus4, callback_status4);
473 EXPECT_EQ(kStatus5, callback_status5);
474 EXPECT_EQ(5, callback_count);
477 TEST(SyncTaskManagerTest, BackgroundTask_Sequential) {
478 base::MessageLoop message_loop;
479 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
480 10 /* maximum_background_task */,
481 base::ThreadTaskRunnerHandle::Get(),
482 nullptr /* worker_pool */);
483 task_manager.Initialize(SYNC_STATUS_OK);
485 SyncStatusCode status = SYNC_STATUS_FAILED;
486 BackgroundTask::Stats stats;
487 task_manager.ScheduleSyncTask(
488 FROM_HERE,
489 scoped_ptr<SyncTask>(new BackgroundTask(
490 "app_id", MAKE_PATH("/hoge/fuga"),
491 &stats)),
492 SyncTaskManager::PRIORITY_MED,
493 CreateResultReceiver(&status));
495 task_manager.ScheduleSyncTask(
496 FROM_HERE,
497 scoped_ptr<SyncTask>(new BackgroundTask(
498 "app_id", MAKE_PATH("/hoge"),
499 &stats)),
500 SyncTaskManager::PRIORITY_MED,
501 CreateResultReceiver(&status));
503 task_manager.ScheduleSyncTask(
504 FROM_HERE,
505 scoped_ptr<SyncTask>(new BackgroundTask(
506 "app_id", MAKE_PATH("/hoge/fuga/piyo"),
507 &stats)),
508 SyncTaskManager::PRIORITY_MED,
509 CreateResultReceiver(&status));
511 message_loop.RunUntilIdle();
513 EXPECT_EQ(SYNC_STATUS_OK, status);
514 EXPECT_EQ(0, stats.running_background_task);
515 EXPECT_EQ(3, stats.finished_task);
516 EXPECT_EQ(1, stats.max_parallel_task);
519 TEST(SyncTaskManagerTest, BackgroundTask_Parallel) {
520 base::MessageLoop message_loop;
521 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
522 10 /* maximum_background_task */,
523 base::ThreadTaskRunnerHandle::Get(),
524 nullptr /* worker_pool */);
525 task_manager.Initialize(SYNC_STATUS_OK);
527 SyncStatusCode status = SYNC_STATUS_FAILED;
528 BackgroundTask::Stats stats;
529 task_manager.ScheduleSyncTask(
530 FROM_HERE,
531 scoped_ptr<SyncTask>(new BackgroundTask(
532 "app_id", MAKE_PATH("/hoge"),
533 &stats)),
534 SyncTaskManager::PRIORITY_MED,
535 CreateResultReceiver(&status));
537 task_manager.ScheduleSyncTask(
538 FROM_HERE,
539 scoped_ptr<SyncTask>(new BackgroundTask(
540 "app_id", MAKE_PATH("/fuga"),
541 &stats)),
542 SyncTaskManager::PRIORITY_MED,
543 CreateResultReceiver(&status));
545 task_manager.ScheduleSyncTask(
546 FROM_HERE,
547 scoped_ptr<SyncTask>(new BackgroundTask(
548 "app_id", MAKE_PATH("/piyo"),
549 &stats)),
550 SyncTaskManager::PRIORITY_MED,
551 CreateResultReceiver(&status));
553 message_loop.RunUntilIdle();
555 EXPECT_EQ(SYNC_STATUS_OK, status);
556 EXPECT_EQ(0, stats.running_background_task);
557 EXPECT_EQ(3, stats.finished_task);
558 EXPECT_EQ(3, stats.max_parallel_task);
561 TEST(SyncTaskManagerTest, BackgroundTask_Throttled) {
562 base::MessageLoop message_loop;
563 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
564 2 /* maximum_background_task */,
565 base::ThreadTaskRunnerHandle::Get(),
566 nullptr /* worker_pool */);
567 task_manager.Initialize(SYNC_STATUS_OK);
569 SyncStatusCode status = SYNC_STATUS_FAILED;
570 BackgroundTask::Stats stats;
571 task_manager.ScheduleSyncTask(
572 FROM_HERE,
573 scoped_ptr<SyncTask>(new BackgroundTask(
574 "app_id", MAKE_PATH("/hoge"),
575 &stats)),
576 SyncTaskManager::PRIORITY_MED,
577 CreateResultReceiver(&status));
579 task_manager.ScheduleSyncTask(
580 FROM_HERE,
581 scoped_ptr<SyncTask>(new BackgroundTask(
582 "app_id", MAKE_PATH("/fuga"),
583 &stats)),
584 SyncTaskManager::PRIORITY_MED,
585 CreateResultReceiver(&status));
587 task_manager.ScheduleSyncTask(
588 FROM_HERE,
589 scoped_ptr<SyncTask>(new BackgroundTask(
590 "app_id", MAKE_PATH("/piyo"),
591 &stats)),
592 SyncTaskManager::PRIORITY_MED,
593 CreateResultReceiver(&status));
595 message_loop.RunUntilIdle();
597 EXPECT_EQ(SYNC_STATUS_OK, status);
598 EXPECT_EQ(0, stats.running_background_task);
599 EXPECT_EQ(3, stats.finished_task);
600 EXPECT_EQ(2, stats.max_parallel_task);
603 TEST(SyncTaskManagerTest, UpdateTaskBlocker) {
604 base::MessageLoop message_loop;
605 SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
606 10 /* maximum_background_task */,
607 base::ThreadTaskRunnerHandle::Get(),
608 nullptr /* worker_pool */);
609 task_manager.Initialize(SYNC_STATUS_OK);
611 SyncStatusCode status1 = SYNC_STATUS_FAILED;
612 SyncStatusCode status2 = SYNC_STATUS_FAILED;
613 BlockerUpdateTestHelper::Log log;
616 std::vector<std::string> paths;
617 paths.push_back("/foo/bar");
618 paths.push_back("/foo");
619 paths.push_back("/hoge/fuga/piyo");
620 task_manager.ScheduleSyncTask(
621 FROM_HERE,
622 scoped_ptr<SyncTask>(new BlockerUpdateTestHelper(
623 "task1", "app_id", paths, &log)),
624 SyncTaskManager::PRIORITY_MED,
625 CreateResultReceiver(&status1));
629 std::vector<std::string> paths;
630 paths.push_back("/foo");
631 paths.push_back("/foo/bar");
632 paths.push_back("/hoge/fuga/piyo");
633 task_manager.ScheduleSyncTask(
634 FROM_HERE,
635 scoped_ptr<SyncTask>(new BlockerUpdateTestHelper(
636 "task2", "app_id", paths, &log)),
637 SyncTaskManager::PRIORITY_MED,
638 CreateResultReceiver(&status2));
641 message_loop.RunUntilIdle();
643 EXPECT_EQ(SYNC_STATUS_OK, status1);
644 EXPECT_EQ(SYNC_STATUS_OK, status2);
646 ASSERT_EQ(14u, log.size());
647 int i = 0;
649 // task1 takes "/foo/bar" first.
650 EXPECT_EQ("task1: updating to /foo/bar", log[i++]);
652 // task1 blocks task2. task2's update should not complete until task1 update.
653 EXPECT_EQ("task2: updating to /foo", log[i++]);
654 EXPECT_EQ("task1: updated to /foo/bar", log[i++]);
656 // task1 releases "/foo/bar" and tries to take "/foo". Then, pending task2
657 // takes "/foo" and blocks task1.
658 EXPECT_EQ("task1: updating to /foo", log[i++]);
659 EXPECT_EQ("task2: updated to /foo", log[i++]);
661 // task2 releases "/foo".
662 EXPECT_EQ("task2: updating to /foo/bar", log[i++]);
663 EXPECT_EQ("task1: updated to /foo", log[i++]);
665 // task1 releases "/foo".
666 EXPECT_EQ("task1: updating to /hoge/fuga/piyo", log[i++]);
667 EXPECT_EQ("task1: updated to /hoge/fuga/piyo", log[i++]);
668 EXPECT_EQ("task2: updated to /foo/bar", log[i++]);
670 EXPECT_EQ("task1: finished", log[i++]);
672 EXPECT_EQ("task2: updating to /hoge/fuga/piyo", log[i++]);
673 EXPECT_EQ("task2: updated to /hoge/fuga/piyo", log[i++]);
674 EXPECT_EQ("task2: finished", log[i++]);
677 } // namespace drive_backend
678 } // namespace sync_file_system