// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"

#include <stdint.h>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
#include "storage/common/fileapi/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"

#define MAKE_PATH(path)                                       \
  base::FilePath(storage::VirtualPath::GetNormalizedFilePath( \
      base::FilePath(FILE_PATH_LITERAL(path))))

namespace sync_file_system {
namespace drive_backend {

namespace {

void DumbTask(SyncStatusCode status,
              const SyncStatusCallback& callback) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(callback, status));
}

void IncrementAndAssign(int expected_before_counter,
                        int* counter,
                        SyncStatusCode* status_out,
                        SyncStatusCode status) {
  EXPECT_EQ(expected_before_counter, *counter);
  ++(*counter);
  *status_out = status;
}

class TaskManagerClient
    : public SyncTaskManager::Client,
      public base::SupportsWeakPtr<TaskManagerClient> {
 public:
  explicit TaskManagerClient(int64_t maximum_background_task)
      : maybe_schedule_next_task_count_(0),
        task_scheduled_count_(0),
        idle_task_scheduled_count_(0),
        last_operation_status_(SYNC_STATUS_OK) {
    task_manager_.reset(
        new SyncTaskManager(AsWeakPtr(), maximum_background_task,
                            base::ThreadTaskRunnerHandle::Get()));
    task_manager_->Initialize(SYNC_STATUS_OK);
    base::RunLoop().RunUntilIdle();
    maybe_schedule_next_task_count_ = 0;
  }
  ~TaskManagerClient() override {}

  // DriveFileSyncManager::Client overrides.
  void MaybeScheduleNextTask() override { ++maybe_schedule_next_task_count_; }
  void NotifyLastOperationStatus(SyncStatusCode last_operation_status,
                                 bool last_operation_used_network) override {
    last_operation_status_ = last_operation_status;
  }

  void RecordTaskLog(std::unique_ptr<TaskLogger::TaskLog>) override {}

  void ScheduleTask(SyncStatusCode status_to_return,
                    const SyncStatusCallback& callback) {
    task_manager_->ScheduleTask(
        FROM_HERE,
        base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
                   status_to_return, false /* idle */),
        SyncTaskManager::PRIORITY_MED,
        callback);
  }

  void ScheduleTaskIfIdle(SyncStatusCode status_to_return) {
    task_manager_->ScheduleTaskIfIdle(
        FROM_HERE,
        base::Bind(&TaskManagerClient::DoTask, AsWeakPtr(),
                   status_to_return, true /* idle */),
        SyncStatusCallback());
  }

  int maybe_schedule_next_task_count() const {
    return maybe_schedule_next_task_count_;
  }
  int task_scheduled_count() const { return task_scheduled_count_; }
  int idle_task_scheduled_count() const { return idle_task_scheduled_count_; }
  SyncStatusCode last_operation_status() const {
    return last_operation_status_;
  }

 private:
  void DoTask(SyncStatusCode status_to_return,
              bool is_idle_task,
              const SyncStatusCallback& callback) {
    ++task_scheduled_count_;
    if (is_idle_task)
      ++idle_task_scheduled_count_;
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(callback, status_to_return));
  }

  std::unique_ptr<SyncTaskManager> task_manager_;

  int maybe_schedule_next_task_count_;
  int task_scheduled_count_;
  int idle_task_scheduled_count_;

  SyncStatusCode last_operation_status_;

  DISALLOW_COPY_AND_ASSIGN(TaskManagerClient);
};

class MultihopSyncTask : public ExclusiveTask {
 public:
  MultihopSyncTask(bool* task_started,
                   bool* task_completed)
      : task_started_(task_started),
        task_completed_(task_completed),
        weak_ptr_factory_(this) {
    DCHECK(task_started_);
    DCHECK(task_completed_);
  }

  ~MultihopSyncTask() override {}

  void RunExclusive(const SyncStatusCallback& callback) override {
    DCHECK(!*task_started_);
    *task_started_ = true;
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&MultihopSyncTask::CompleteTask,
                                  weak_ptr_factory_.GetWeakPtr(), callback));
  }

 private:
  void CompleteTask(const SyncStatusCallback& callback) {
    DCHECK(*task_started_);
    DCHECK(!*task_completed_);
    *task_completed_ = true;
    callback.Run(SYNC_STATUS_OK);
  }

  bool* task_started_;
  bool* task_completed_;
  base::WeakPtrFactory<MultihopSyncTask> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(MultihopSyncTask);
};

class BackgroundTask : public SyncTask {
 public:
  struct Stats {
    int64_t running_background_task;
    int64_t finished_task;
    int64_t max_parallel_task;

    Stats()
        : running_background_task(0),
          finished_task(0),
          max_parallel_task(0) {}
  };

  BackgroundTask(const std::string& app_id,
                 const base::FilePath& path,
                 Stats* stats)
      : app_id_(app_id),
        path_(path),
        stats_(stats),
        weak_ptr_factory_(this) {
  }

  ~BackgroundTask() override {}

  void RunPreflight(std::unique_ptr<SyncTaskToken> token) override {
    std::unique_ptr<TaskBlocker> task_blocker(new TaskBlocker);
    task_blocker->app_id = app_id_;
    task_blocker->paths.push_back(path_);

    SyncTaskManager::UpdateTaskBlocker(
        std::move(token), std::move(task_blocker),
        base::Bind(&BackgroundTask::RunAsBackgroundTask,
                   weak_ptr_factory_.GetWeakPtr()));
  }

 private:
  void RunAsBackgroundTask(std::unique_ptr<SyncTaskToken> token) {
    ++(stats_->running_background_task);
    if (stats_->max_parallel_task < stats_->running_background_task)
      stats_->max_parallel_task = stats_->running_background_task;

    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&BackgroundTask::CompleteTask,
                       weak_ptr_factory_.GetWeakPtr(), std::move(token)));
  }

  void CompleteTask(std::unique_ptr<SyncTaskToken> token) {
    ++(stats_->finished_task);
    --(stats_->running_background_task);
    SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_OK);
  }

  std::string app_id_;
  base::FilePath path_;
  Stats* stats_;

  base::WeakPtrFactory<BackgroundTask> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundTask);
};

class BlockerUpdateTestHelper : public SyncTask {
 public:
  typedef std::vector<std::string> Log;

  BlockerUpdateTestHelper(const std::string& name,
                          const std::string& app_id,
                          const std::vector<std::string>& paths,
                          Log* log)
      : name_(name),
        app_id_(app_id),
        paths_(paths.begin(), paths.end()),
        log_(log),
        weak_ptr_factory_(this) {
  }

  ~BlockerUpdateTestHelper() override {}

  void RunPreflight(std::unique_ptr<SyncTaskToken> token) override {
    UpdateBlocker(std::move(token));
  }

 private:
  void UpdateBlocker(std::unique_ptr<SyncTaskToken> token) {
    if (paths_.empty()) {
      log_->push_back(name_ + ": finished");
      SyncTaskManager::NotifyTaskDone(std::move(token), SYNC_STATUS_OK);
      return;
    }

    std::string updating_to = paths_.front();
    paths_.pop_front();

    log_->push_back(name_ + ": updating to " + updating_to);

    std::unique_ptr<TaskBlocker> task_blocker(new TaskBlocker);
    task_blocker->app_id = app_id_;
    task_blocker->paths.push_back(
        base::FilePath(storage::VirtualPath::GetNormalizedFilePath(
            base::FilePath::FromUTF8Unsafe(updating_to))));

    SyncTaskManager::UpdateTaskBlocker(
        std::move(token), std::move(task_blocker),
        base::Bind(&BlockerUpdateTestHelper::UpdateBlockerSoon,
                   weak_ptr_factory_.GetWeakPtr(), updating_to));
  }

  void UpdateBlockerSoon(const std::string& updated_to,
                         std::unique_ptr<SyncTaskToken> token) {
    log_->push_back(name_ + ": updated to " + updated_to);
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&BlockerUpdateTestHelper::UpdateBlocker,
                       weak_ptr_factory_.GetWeakPtr(), std::move(token)));
  }

  std::string name_;
  std::string app_id_;
  base::circular_deque<std::string> paths_;
  Log* log_;

  base::WeakPtrFactory<BlockerUpdateTestHelper> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(BlockerUpdateTestHelper);
};

// Arbitrary non-default status values for testing.
const SyncStatusCode kStatus1 = static_cast<SyncStatusCode>(-1);
const SyncStatusCode kStatus2 = static_cast<SyncStatusCode>(-2);
const SyncStatusCode kStatus3 = static_cast<SyncStatusCode>(-3);
const SyncStatusCode kStatus4 = static_cast<SyncStatusCode>(-4);
const SyncStatusCode kStatus5 = static_cast<SyncStatusCode>(-5);

}  // namespace

TEST(SyncTaskManagerTest, ScheduleTask) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  TaskManagerClient client(0 /* maximum_background_task */);
  int callback_count = 0;
  SyncStatusCode callback_status = SYNC_STATUS_OK;

  client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
                                           &callback_count,
                                           &callback_status));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kStatus1, callback_status);
  EXPECT_EQ(kStatus1, client.last_operation_status());

  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(1, client.maybe_schedule_next_task_count());
  EXPECT_EQ(1, client.task_scheduled_count());
  EXPECT_EQ(0, client.idle_task_scheduled_count());
}

TEST(SyncTaskManagerTest, ScheduleTwoTasks) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  TaskManagerClient client(0 /* maximum_background_task */);
  int callback_count = 0;
  SyncStatusCode callback_status = SYNC_STATUS_OK;

  client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
                                           &callback_count,
                                           &callback_status));
  client.ScheduleTask(kStatus2, base::Bind(&IncrementAndAssign, 1,
                                           &callback_count,
                                           &callback_status));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kStatus2, callback_status);
  EXPECT_EQ(kStatus2, client.last_operation_status());

  EXPECT_EQ(2, callback_count);
  EXPECT_EQ(1, client.maybe_schedule_next_task_count());
  EXPECT_EQ(2, client.task_scheduled_count());
  EXPECT_EQ(0, client.idle_task_scheduled_count());
}

TEST(SyncTaskManagerTest, ScheduleIdleTask) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  TaskManagerClient client(0 /* maximum_background_task */);

  client.ScheduleTaskIfIdle(kStatus1);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kStatus1, client.last_operation_status());

  EXPECT_EQ(1, client.maybe_schedule_next_task_count());
  EXPECT_EQ(1, client.task_scheduled_count());
  EXPECT_EQ(1, client.idle_task_scheduled_count());
}

TEST(SyncTaskManagerTest, ScheduleIdleTaskWhileNotIdle) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  TaskManagerClient client(0 /* maximum_background_task */);
  int callback_count = 0;
  SyncStatusCode callback_status = SYNC_STATUS_OK;

  client.ScheduleTask(kStatus1, base::Bind(&IncrementAndAssign, 0,
                                           &callback_count,
                                           &callback_status));
  client.ScheduleTaskIfIdle(kStatus2);
  base::RunLoop().RunUntilIdle();

  // Idle task must not have run.
  EXPECT_EQ(kStatus1, callback_status);
  EXPECT_EQ(kStatus1, client.last_operation_status());

  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(1, client.maybe_schedule_next_task_count());
  EXPECT_EQ(1, client.task_scheduled_count());
  EXPECT_EQ(0, client.idle_task_scheduled_count());
}

TEST(SyncTaskManagerTest, ScheduleAndCancelSyncTask) {
  base::test::ScopedTaskEnvironment scoped_task_environment;

  int callback_count = 0;
  SyncStatusCode status = SYNC_STATUS_UNKNOWN;

  bool task_started = false;
  bool task_completed = false;

  {
    SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                                 0 /* maximum_background_task */,
                                 base::ThreadTaskRunnerHandle::Get());
    task_manager.Initialize(SYNC_STATUS_OK);
    base::RunLoop().RunUntilIdle();
    task_manager.ScheduleSyncTask(
        FROM_HERE, std::unique_ptr<SyncTask>(
                       new MultihopSyncTask(&task_started, &task_completed)),
        SyncTaskManager::PRIORITY_MED,
        base::Bind(&IncrementAndAssign, 0, &callback_count, &status));
  }
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, callback_count);
  EXPECT_EQ(SYNC_STATUS_UNKNOWN, status);
  EXPECT_TRUE(task_started);
  EXPECT_FALSE(task_completed);
}

TEST(SyncTaskManagerTest, ScheduleTaskAtPriority) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                               0 /* maximum_background_task */,
                               base::ThreadTaskRunnerHandle::Get());
  task_manager.Initialize(SYNC_STATUS_OK);
  base::RunLoop().RunUntilIdle();

  int callback_count = 0;
  SyncStatusCode callback_status1 = SYNC_STATUS_OK;
  SyncStatusCode callback_status2 = SYNC_STATUS_OK;
  SyncStatusCode callback_status3 = SYNC_STATUS_OK;
  SyncStatusCode callback_status4 = SYNC_STATUS_OK;
  SyncStatusCode callback_status5 = SYNC_STATUS_OK;

  // This will run first even if its priority is low, since there're no
  // pending tasks.
  task_manager.ScheduleTask(
      FROM_HERE,
      base::Bind(&DumbTask, kStatus1),
      SyncTaskManager::PRIORITY_LOW,
      base::Bind(&IncrementAndAssign, 0, &callback_count, &callback_status1));

  // This runs last (expected counter == 4).
  task_manager.ScheduleTask(
      FROM_HERE,
      base::Bind(&DumbTask, kStatus2),
      SyncTaskManager::PRIORITY_LOW,
      base::Bind(&IncrementAndAssign, 4, &callback_count, &callback_status2));

  // This runs second (expected counter == 1).
  task_manager.ScheduleTask(
      FROM_HERE,
      base::Bind(&DumbTask, kStatus3),
      SyncTaskManager::PRIORITY_HIGH,
      base::Bind(&IncrementAndAssign, 1, &callback_count, &callback_status3));

  // This runs fourth (expected counter == 3).
  task_manager.ScheduleTask(
      FROM_HERE,
      base::Bind(&DumbTask, kStatus4),
      SyncTaskManager::PRIORITY_MED,
      base::Bind(&IncrementAndAssign, 3, &callback_count, &callback_status4));

  // This runs third (expected counter == 2).
  task_manager.ScheduleTask(
      FROM_HERE,
      base::Bind(&DumbTask, kStatus5),
      SyncTaskManager::PRIORITY_HIGH,
      base::Bind(&IncrementAndAssign, 2, &callback_count, &callback_status5));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kStatus1, callback_status1);
  EXPECT_EQ(kStatus2, callback_status2);
  EXPECT_EQ(kStatus3, callback_status3);
  EXPECT_EQ(kStatus4, callback_status4);
  EXPECT_EQ(kStatus5, callback_status5);
  EXPECT_EQ(5, callback_count);
}

TEST(SyncTaskManagerTest, BackgroundTask_Sequential) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                               10 /* maximum_background_task */,
                               base::ThreadTaskRunnerHandle::Get());
  task_manager.Initialize(SYNC_STATUS_OK);

  SyncStatusCode status = SYNC_STATUS_FAILED;
  BackgroundTask::Stats stats;
  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(new BackgroundTask(
                     "app_id", MAKE_PATH("/hoge/fuga"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/hoge"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(new BackgroundTask(
                     "app_id", MAKE_PATH("/hoge/fuga/piyo"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(SYNC_STATUS_OK, status);
  EXPECT_EQ(0, stats.running_background_task);
  EXPECT_EQ(3, stats.finished_task);
  EXPECT_EQ(1, stats.max_parallel_task);
}

TEST(SyncTaskManagerTest, BackgroundTask_Parallel) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                               10 /* maximum_background_task */,
                               base::ThreadTaskRunnerHandle::Get());
  task_manager.Initialize(SYNC_STATUS_OK);

  SyncStatusCode status = SYNC_STATUS_FAILED;
  BackgroundTask::Stats stats;
  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/hoge"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/fuga"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/piyo"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(SYNC_STATUS_OK, status);
  EXPECT_EQ(0, stats.running_background_task);
  EXPECT_EQ(3, stats.finished_task);
  EXPECT_EQ(3, stats.max_parallel_task);
}

TEST(SyncTaskManagerTest, BackgroundTask_Throttled) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                               2 /* maximum_background_task */,
                               base::ThreadTaskRunnerHandle::Get());
  task_manager.Initialize(SYNC_STATUS_OK);

  SyncStatusCode status = SYNC_STATUS_FAILED;
  BackgroundTask::Stats stats;
  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/hoge"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/fuga"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  task_manager.ScheduleSyncTask(
      FROM_HERE, std::unique_ptr<SyncTask>(
                     new BackgroundTask("app_id", MAKE_PATH("/piyo"), &stats)),
      SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(SYNC_STATUS_OK, status);
  EXPECT_EQ(0, stats.running_background_task);
  EXPECT_EQ(3, stats.finished_task);
  EXPECT_EQ(2, stats.max_parallel_task);
}

TEST(SyncTaskManagerTest, UpdateTaskBlocker) {
  base::test::ScopedTaskEnvironment scoped_task_environment;
  SyncTaskManager task_manager(base::WeakPtr<SyncTaskManager::Client>(),
                               10 /* maximum_background_task */,
                               base::ThreadTaskRunnerHandle::Get());
  task_manager.Initialize(SYNC_STATUS_OK);

  SyncStatusCode status1 = SYNC_STATUS_FAILED;
  SyncStatusCode status2 = SYNC_STATUS_FAILED;
  BlockerUpdateTestHelper::Log log;

  {
    std::vector<std::string> paths;
    paths.push_back("/foo/bar");
    paths.push_back("/foo");
    paths.push_back("/hoge/fuga/piyo");
    task_manager.ScheduleSyncTask(
        FROM_HERE, std::unique_ptr<SyncTask>(new BlockerUpdateTestHelper(
                       "task1", "app_id", paths, &log)),
        SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status1));
  }

  {
    std::vector<std::string> paths;
    paths.push_back("/foo");
    paths.push_back("/foo/bar");
    paths.push_back("/hoge/fuga/piyo");
    task_manager.ScheduleSyncTask(
        FROM_HERE, std::unique_ptr<SyncTask>(new BlockerUpdateTestHelper(
                       "task2", "app_id", paths, &log)),
        SyncTaskManager::PRIORITY_MED, CreateResultReceiver(&status2));
  }

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(SYNC_STATUS_OK, status1);
  EXPECT_EQ(SYNC_STATUS_OK, status2);

  ASSERT_EQ(14u, log.size());
  int i = 0;

  // task1 takes "/foo/bar" first.
  EXPECT_EQ("task1: updating to /foo/bar", log[i++]);

  // task1 blocks task2. task2's update should not complete until task1 update.
  EXPECT_EQ("task2: updating to /foo", log[i++]);
  EXPECT_EQ("task1: updated to /foo/bar", log[i++]);

  // task1 releases "/foo/bar" and tries to take "/foo". Then, pending task2
  // takes "/foo" and blocks task1.
  EXPECT_EQ("task1: updating to /foo", log[i++]);
  EXPECT_EQ("task2: updated to /foo", log[i++]);

  // task2 releases "/foo".
  EXPECT_EQ("task2: updating to /foo/bar", log[i++]);
  EXPECT_EQ("task1: updated to /foo", log[i++]);

  // task1 releases "/foo".
  EXPECT_EQ("task1: updating to /hoge/fuga/piyo", log[i++]);
  EXPECT_EQ("task1: updated to /hoge/fuga/piyo", log[i++]);
  EXPECT_EQ("task2: updated to /foo/bar", log[i++]);

  EXPECT_EQ("task1: finished", log[i++]);

  EXPECT_EQ("task2: updating to /hoge/fuga/piyo", log[i++]);
  EXPECT_EQ("task2: updated to /hoge/fuga/piyo", log[i++]);
  EXPECT_EQ("task2: finished", log[i++]);
}

}  // namespace drive_backend
}  // namespace sync_file_system
