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.
8 #include "base/basictypes.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
{
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
,
40 SyncStatusCode
* status_out
,
41 SyncStatusCode status
) {
42 EXPECT_EQ(expected_before_counter
, *counter
);
48 void IncrementAndAssignWithOwnedPointer(T
* object
,
50 SyncStatusCode
* status_out
,
51 SyncStatusCode status
) {
56 class TaskManagerClient
57 : public SyncTaskManager::Client
,
58 public base::SupportsWeakPtr
<TaskManagerClient
> {
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(
88 base::Bind(&TaskManagerClient::DoTask
, AsWeakPtr(),
89 status_to_return
, false /* idle */),
90 SyncTaskManager::PRIORITY_MED
,
94 void ScheduleTaskIfIdle(SyncStatusCode status_to_return
) {
95 task_manager_
->ScheduleTaskIfIdle(
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_
;
112 void DoTask(SyncStatusCode status_to_return
,
114 const SyncStatusCallback
& callback
) {
115 ++task_scheduled_count_
;
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
{
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
));
155 void CompleteTask(const SyncStatusCallback
& callback
) {
156 DCHECK(*task_started_
);
157 DCHECK(!*task_completed_
);
158 *task_completed_
= true;
159 callback
.Run(SYNC_STATUS_OK
);
163 bool* task_completed_
;
164 base::WeakPtrFactory
<MultihopSyncTask
> weak_ptr_factory_
;
166 DISALLOW_COPY_AND_ASSIGN(MultihopSyncTask
);
169 class BackgroundTask
: public SyncTask
{
172 int64 running_background_task
;
174 int64 max_parallel_task
;
177 : running_background_task(0),
179 max_parallel_task(0) {}
182 BackgroundTask(const std::string
& app_id
,
183 const base::FilePath
& path
,
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()));
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(
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
);
223 base::FilePath path_
;
226 base::WeakPtrFactory
<BackgroundTask
> weak_ptr_factory_
;
228 DISALLOW_COPY_AND_ASSIGN(BackgroundTask
);
231 class BlockerUpdateTestHelper
: public SyncTask
{
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
,
241 paths_(paths
.begin(), paths
.end()),
243 weak_ptr_factory_(this) {
246 ~BlockerUpdateTestHelper() override
{}
248 void RunPreflight(scoped_ptr
<SyncTaskToken
> token
) override
{
249 UpdateBlocker(token
.Pass());
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
);
260 std::string updating_to
= paths_
.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(),
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(
283 base::Bind(&BlockerUpdateTestHelper::UpdateBlocker
,
284 weak_ptr_factory_
.GetWeakPtr(), base::Passed(&token
)));
289 std::deque
<std::string
> paths_
;
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);
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,
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,
335 client
.ScheduleTask(kStatus2
, base::Bind(&IncrementAndAssign
, 1,
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,
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(
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
434 task_manager
.ScheduleTask(
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(
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(
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(
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(
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(
490 scoped_ptr
<SyncTask
>(new BackgroundTask(
491 "app_id", MAKE_PATH("/hoge/fuga"),
493 SyncTaskManager::PRIORITY_MED
,
494 CreateResultReceiver(&status
));
496 task_manager
.ScheduleSyncTask(
498 scoped_ptr
<SyncTask
>(new BackgroundTask(
499 "app_id", MAKE_PATH("/hoge"),
501 SyncTaskManager::PRIORITY_MED
,
502 CreateResultReceiver(&status
));
504 task_manager
.ScheduleSyncTask(
506 scoped_ptr
<SyncTask
>(new BackgroundTask(
507 "app_id", MAKE_PATH("/hoge/fuga/piyo"),
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(
532 scoped_ptr
<SyncTask
>(new BackgroundTask(
533 "app_id", MAKE_PATH("/hoge"),
535 SyncTaskManager::PRIORITY_MED
,
536 CreateResultReceiver(&status
));
538 task_manager
.ScheduleSyncTask(
540 scoped_ptr
<SyncTask
>(new BackgroundTask(
541 "app_id", MAKE_PATH("/fuga"),
543 SyncTaskManager::PRIORITY_MED
,
544 CreateResultReceiver(&status
));
546 task_manager
.ScheduleSyncTask(
548 scoped_ptr
<SyncTask
>(new BackgroundTask(
549 "app_id", MAKE_PATH("/piyo"),
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(
574 scoped_ptr
<SyncTask
>(new BackgroundTask(
575 "app_id", MAKE_PATH("/hoge"),
577 SyncTaskManager::PRIORITY_MED
,
578 CreateResultReceiver(&status
));
580 task_manager
.ScheduleSyncTask(
582 scoped_ptr
<SyncTask
>(new BackgroundTask(
583 "app_id", MAKE_PATH("/fuga"),
585 SyncTaskManager::PRIORITY_MED
,
586 CreateResultReceiver(&status
));
588 task_manager
.ScheduleSyncTask(
590 scoped_ptr
<SyncTask
>(new BackgroundTask(
591 "app_id", MAKE_PATH("/piyo"),
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(
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(
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());
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