// Copyright 2015 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 "base/task/sequence_manager/sequence_manager.h"

#include <stddef.h>
#include <memory>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_default.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/condition_variable.h"
#include "base/task/post_task.h"
#include "base/task/sequence_manager/task_queue_impl.h"
#include "base/task/sequence_manager/test/mock_time_domain.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/sequence_manager/test/test_task_queue.h"
#include "base/task/sequence_manager/test/test_task_time_observer.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/task/task_scheduler/task_scheduler_impl.h"
#include "base/task/task_traits.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"

namespace base {
namespace sequence_manager {
namespace {
const int kNumTasks = 1000000;
}

// To reduce noise related to the OS timer, we use a mock time domain to
// fast forward the timers.
class PerfTestTimeDomain : public MockTimeDomain {
 public:
  PerfTestTimeDomain() : MockTimeDomain(TimeTicks::Now()) {}
  ~PerfTestTimeDomain() override = default;

  Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override {
    Optional<TimeTicks> run_time = NextScheduledRunTime();
    if (!run_time)
      return nullopt;
    SetNowTicks(*run_time);
    // Makes SequenceManager to continue immediately.
    return TimeDelta();
  }

  void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) override {
    // De-dupe DoWorks.
    if (NumberOfScheduledWakeUps() == 1u)
      RequestDoWork();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(PerfTestTimeDomain);
};

enum class PerfTestType : int {
  kUseSequenceManagerWithMessageLoop = 0,
  kUseSequenceManagerWithMessagePump = 1,
  kUseSequenceManagerWithUIMessageLoop = 2,
  kUseSequenceManagerWithUIMessagePump = 3,
  kUseSequenceManagerWithIOMessageLoop = 4,
  kUseSequenceManagerWithIOMessagePump = 5,
  kUseMessageLoop = 6,
  kUseUIMessageLoop = 7,
  kUseIOMessageLoop = 8,
  kUseSingleThreadInWorkerPool = 9,
};

// Customization point for SequenceManagerPerfTest which allows us to test
// various implementations.
class PerfTestDelegate {
 public:
  virtual ~PerfTestDelegate() = default;

  virtual const char* GetName() const = 0;

  virtual bool VirtualTimeIsSupported() const = 0;

  virtual bool MultipleQueuesSupported() const = 0;

  virtual scoped_refptr<TaskRunner> CreateTaskRunner() = 0;

  virtual void WaitUntilDone() = 0;

  virtual void SignalDone() = 0;
};

class BaseSequenceManagerPerfTestDelegate : public PerfTestDelegate {
 public:
  BaseSequenceManagerPerfTestDelegate() {}

  ~BaseSequenceManagerPerfTestDelegate() override = default;

  bool VirtualTimeIsSupported() const override { return true; }

  bool MultipleQueuesSupported() const override { return true; }

  scoped_refptr<TaskRunner> CreateTaskRunner() override {
    scoped_refptr<TestTaskQueue> task_queue =
        manager_->CreateTaskQueue<TestTaskQueue>(
            TaskQueue::Spec("test").SetTimeDomain(time_domain_.get()));
    owned_task_queues_.push_back(task_queue);
    return task_queue->task_runner();
  }

  void WaitUntilDone() override {
    run_loop_.reset(new RunLoop());
    run_loop_->Run();
  }

  void SignalDone() override { run_loop_->Quit(); }

  SequenceManager* GetManager() const { return manager_.get(); }

  void SetSequenceManager(std::unique_ptr<SequenceManager> manager) {
    manager_ = std::move(manager);
    time_domain_ = std::make_unique<PerfTestTimeDomain>();
    manager_->RegisterTimeDomain(time_domain_.get());
  }

  void ShutDown() {
    owned_task_queues_.clear();
    manager_->UnregisterTimeDomain(time_domain_.get());
    manager_.reset();
  }

 private:
  std::unique_ptr<SequenceManager> manager_;
  std::unique_ptr<TimeDomain> time_domain_;
  std::unique_ptr<RunLoop> run_loop_;
  std::vector<scoped_refptr<TestTaskQueue>> owned_task_queues_;
};

template <class MessageLoopType>
class SequenceManagerWithMessageLoopPerfTestDelegate
    : public BaseSequenceManagerPerfTestDelegate {
 public:
  explicit SequenceManagerWithMessageLoopPerfTestDelegate(const char* name)
      : name_(name), message_loop_(new MessageLoopType()) {
    SetSequenceManager(SequenceManagerForTest::Create(
        message_loop_->GetMessageLoopBase(), message_loop_->task_runner(),
        DefaultTickClock::GetInstance()));
  }

  ~SequenceManagerWithMessageLoopPerfTestDelegate() override { ShutDown(); }

  const char* GetName() const override { return name_; }

 private:
  const char* const name_;
  std::unique_ptr<MessageLoop> message_loop_;
};

class SequenceManagerWithMessagePumpPerfTestDelegate
    : public BaseSequenceManagerPerfTestDelegate {
 public:
  SequenceManagerWithMessagePumpPerfTestDelegate(const char* name,
                                                 MessageLoop::Type type)
      : name_(name) {
    SetSequenceManager(SequenceManagerForTest::Create(
        std::make_unique<internal::ThreadControllerWithMessagePumpImpl>(
            MessageLoop ::CreateMessagePumpForType(type),
            DefaultTickClock::GetInstance())));

    // ThreadControllerWithMessagePumpImpl doesn't provide a default task
    // runner.
    scoped_refptr<TaskQueue> default_task_queue =
        GetManager()->template CreateTaskQueue<TestTaskQueue>(
            TaskQueue::Spec("default"));
    GetManager()->SetDefaultTaskRunner(default_task_queue->task_runner());
  }

  ~SequenceManagerWithMessagePumpPerfTestDelegate() override { ShutDown(); }

  const char* GetName() const override { return name_; }

 private:
  const char* const name_;
};

class MessageLoopPerfTestDelegate : public PerfTestDelegate {
 public:
  MessageLoopPerfTestDelegate(const char* name,
                              std::unique_ptr<MessageLoop> message_loop)
      : name_(name), message_loop_(std::move(message_loop)) {}

  ~MessageLoopPerfTestDelegate() override = default;

  const char* GetName() const override { return name_; }

  bool VirtualTimeIsSupported() const override { return false; }

  bool MultipleQueuesSupported() const override { return false; }

  scoped_refptr<TaskRunner> CreateTaskRunner() override {
    return message_loop_->task_runner();
  }

  void WaitUntilDone() override {
    run_loop_.reset(new RunLoop());
    run_loop_->Run();
  }

  void SignalDone() override { run_loop_->Quit(); }

 private:
  const char* const name_;
  std::unique_ptr<MessageLoop> message_loop_;
  std::unique_ptr<RunLoop> run_loop_;
};

class SingleThreadInWorkerPoolPerfTestDelegate : public PerfTestDelegate {
 public:
  SingleThreadInWorkerPoolPerfTestDelegate() : done_cond_(&done_lock_) {
    TaskScheduler::SetInstance(
        std::make_unique<::base::internal::TaskSchedulerImpl>("Test"));
    TaskScheduler::GetInstance()->StartWithDefaultParams();
  }

  ~SingleThreadInWorkerPoolPerfTestDelegate() override {
    TaskScheduler::GetInstance()->JoinForTesting();
    TaskScheduler::SetInstance(nullptr);
  }

  const char* GetName() const override {
    return " single thread in WorkerPool ";
  }

  bool VirtualTimeIsSupported() const override { return false; }

  bool MultipleQueuesSupported() const override { return false; }

  scoped_refptr<TaskRunner> CreateTaskRunner() override {
    return CreateSingleThreadTaskRunnerWithTraits(
        {TaskPriority::USER_BLOCKING});
  }

  void WaitUntilDone() override {
    AutoLock auto_lock(done_lock_);
    done_cond_.Wait();
  }

  void SignalDone() override {
    AutoLock auto_lock(done_lock_);
    done_cond_.Signal();
  }

 private:
  Lock done_lock_;
  ConditionVariable done_cond_;
};

class TestCase {
 public:
  // |delegate| is assumed to outlive TestCase.
  explicit TestCase(PerfTestDelegate* delegate) : delegate_(delegate) {}

  virtual ~TestCase() = default;

  virtual void Start() = 0;

 protected:
  PerfTestDelegate* const delegate_;  // NOT OWNED
};

class TaskSource {
 public:
  virtual ~TaskSource() = default;

  virtual void Start() = 0;
};

class SameThreadTaskSource : public TaskSource {
 public:
  SameThreadTaskSource(std::vector<scoped_refptr<TaskRunner>> task_runners,
                       size_t num_tasks)
      : num_queues_(task_runners.size()),
        num_tasks_(num_tasks),
        task_closure_(
            BindRepeating(&SameThreadTaskSource::TestTask, Unretained(this))),
        task_runners_(std::move(task_runners)) {}

  void Start() override {
    num_tasks_in_flight_ = 1;
    num_tasks_to_post_ = num_tasks_;
    num_tasks_to_run_ = num_tasks_;
    TestTask();
  }

 protected:
  virtual void PostTask(unsigned int queue) = 0;

  virtual void SignalDone() = 0;

  void TestTask() {
    if (--num_tasks_to_run_ == 0) {
      SignalDone();
      return;
    }

    num_tasks_in_flight_--;
    // NOTE there are only up to max_tasks_in_flight_ pending delayed tasks at
    // any one time.  Thanks to the lower_num_tasks_to_post going to zero if
    // there are a lot of tasks in flight, the total number of task in flight at
    // any one time is very variable.
    unsigned int lower_num_tasks_to_post =
        num_tasks_in_flight_ < (max_tasks_in_flight_ / 2) ? 1 : 0;
    unsigned int max_tasks_to_post =
        num_tasks_to_post_ % 2 ? lower_num_tasks_to_post : 10;
    for (unsigned int i = 0;
         i < max_tasks_to_post && num_tasks_in_flight_ < max_tasks_in_flight_ &&
         num_tasks_to_post_ > 0;
         i++) {
      // Choose a queue weighted towards queue 0.
      unsigned int queue = num_tasks_to_post_ % (num_queues_ + 1);
      if (queue == num_queues_) {
        queue = 0;
      }
      PostTask(queue);
      num_tasks_in_flight_++;
      num_tasks_to_post_--;
    }
  }

  const size_t num_queues_;
  const size_t num_tasks_;
  const RepeatingClosure task_closure_;
  const std::vector<scoped_refptr<TaskRunner>> task_runners_;
  const unsigned int max_tasks_in_flight_ = 200;
  unsigned int num_tasks_in_flight_;
  unsigned int num_tasks_to_post_;
  unsigned int num_tasks_to_run_;
};

class CrossThreadTaskSource : public TaskSource {
 public:
  CrossThreadTaskSource(std::vector<scoped_refptr<TaskRunner>> task_runners,
                        size_t num_tasks)
      : num_queues_(task_runners.size()),
        num_tasks_(num_tasks),
        task_closure_(
            BindRepeating(&CrossThreadTaskSource::TestTask, Unretained(this))),
        task_runners_(std::move(task_runners)) {}

  void Start() override {
    num_tasks_in_flight_ = 0;
    num_tasks_to_run_ = num_tasks_;

    for (size_t i = 0; i < num_tasks_; i++) {
      while (num_tasks_in_flight_.load(std::memory_order_acquire) >
             max_tasks_in_flight_) {
        PlatformThread::YieldCurrentThread();
      }
      // Choose a queue weighted towards queue 0.
      unsigned int queue = i % (num_queues_ + 1);
      if (queue == num_queues_) {
        queue = 0;
      }
      PostTask(queue);
      num_tasks_in_flight_++;
    }
  }

 protected:
  virtual void PostTask(unsigned int queue) = 0;

  // Will be called on the main thread.
  virtual void SignalDone() = 0;

  void TestTask() {
    if (num_tasks_to_run_.fetch_sub(1) == 1) {
      SignalDone();
      return;
    }
    num_tasks_in_flight_--;
  }

  const size_t num_queues_;
  const size_t num_tasks_;
  const RepeatingClosure task_closure_;
  const std::vector<scoped_refptr<TaskRunner>> task_runners_;
  const unsigned int max_tasks_in_flight_ = 200;
  std::atomic<unsigned int> num_tasks_in_flight_;
  std::atomic<unsigned int> num_tasks_to_run_;
};

class SingleThreadImmediateTestCase : public TestCase {
 public:
  SingleThreadImmediateTestCase(
      PerfTestDelegate* delegate,
      std::vector<scoped_refptr<TaskRunner>> task_runners)
      : TestCase(delegate),
        task_source_(std::make_unique<SingleThreadImmediateTaskSource>(
            delegate,
            std::move(task_runners),
            kNumTasks)) {}

  void Start() override { task_source_->Start(); }

 private:
  class SingleThreadImmediateTaskSource : public SameThreadTaskSource {
   public:
    SingleThreadImmediateTaskSource(
        PerfTestDelegate* delegate,
        std::vector<scoped_refptr<TaskRunner>> task_runners,
        size_t num_tasks)
        : SameThreadTaskSource(std::move(task_runners), num_tasks),
          delegate_(delegate) {}

    ~SingleThreadImmediateTaskSource() override = default;

    void PostTask(unsigned int queue) override {
      task_runners_[queue]->PostTask(FROM_HERE, task_closure_);
    }

    void SignalDone() override { delegate_->SignalDone(); }

    PerfTestDelegate* delegate_;  // NOT OWNED.
  };

  const std::unique_ptr<TaskSource> task_source_;
};

class SingleThreadDelayedTestCase : public TestCase {
 public:
  SingleThreadDelayedTestCase(
      PerfTestDelegate* delegate,
      std::vector<scoped_refptr<TaskRunner>> task_runners)
      : TestCase(delegate),
        task_source_(std::make_unique<SingleThreadDelayedTaskSource>(
            delegate,
            std::move(task_runners),
            kNumTasks)) {}

  void Start() override { task_source_->Start(); }

 private:
  class SingleThreadDelayedTaskSource : public SameThreadTaskSource {
   public:
    explicit SingleThreadDelayedTaskSource(
        PerfTestDelegate* delegate,
        std::vector<scoped_refptr<TaskRunner>> task_runners,
        size_t num_tasks)
        : SameThreadTaskSource(std::move(task_runners), num_tasks),
          delegate_(delegate) {}

    ~SingleThreadDelayedTaskSource() override = default;

    void PostTask(unsigned int queue) override {
      unsigned int delay =
          num_tasks_to_post_ % 2 ? 1 : (10 + num_tasks_to_post_ % 10);
      task_runners_[queue]->PostDelayedTask(FROM_HERE, task_closure_,
                                            TimeDelta::FromMilliseconds(delay));
    }

    void SignalDone() override { delegate_->SignalDone(); }

    PerfTestDelegate* delegate_;  // NOT OWNED.
  };

  const std::unique_ptr<TaskSource> task_source_;
};

class TwoThreadTestCase : public TestCase {
 public:
  TwoThreadTestCase(PerfTestDelegate* delegate,
                    std::vector<scoped_refptr<TaskRunner>> task_runners)
      : TestCase(delegate),
        task_runners_(std::move(task_runners)),
        num_tasks_(kNumTasks),
        auxiliary_thread_("auxillary thread") {
    auxiliary_thread_.Start();
  }

  ~TwoThreadTestCase() override { auxiliary_thread_.Stop(); }

 protected:
  void Start() override {
    done_count_ = 0;
    same_thread_task_source_ =
        std::make_unique<SingleThreadImmediateTaskSource>(this, task_runners_,
                                                          num_tasks_ / 2);
    cross_thread_task_scorce_ =
        std::make_unique<CrossThreadImmediateTaskSource>(this, task_runners_,
                                                         num_tasks_ / 2);

    auxiliary_thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&CrossThreadImmediateTaskSource::Start,
                                  Unretained(cross_thread_task_scorce_.get())));
    same_thread_task_source_->Start();
  }

  class SingleThreadImmediateTaskSource : public SameThreadTaskSource {
   public:
    SingleThreadImmediateTaskSource(
        TwoThreadTestCase* two_thread_test_case,
        std::vector<scoped_refptr<TaskRunner>> task_runners,
        size_t num_tasks)
        : SameThreadTaskSource(std::move(task_runners), num_tasks),
          two_thread_test_case_(two_thread_test_case) {}

    ~SingleThreadImmediateTaskSource() override = default;

    void PostTask(unsigned int queue) override {
      task_runners_[queue]->PostTask(FROM_HERE, task_closure_);
    }

    // Will be called on the main thread.
    void SignalDone() override { two_thread_test_case_->SignalDone(); }

    TwoThreadTestCase* two_thread_test_case_;  // NOT OWNED.
  };

  class CrossThreadImmediateTaskSource : public CrossThreadTaskSource {
   public:
    CrossThreadImmediateTaskSource(
        TwoThreadTestCase* two_thread_test_case,
        std::vector<scoped_refptr<TaskRunner>> task_runners,
        size_t num_tasks)
        : CrossThreadTaskSource(std::move(task_runners), num_tasks),
          two_thread_test_case_(two_thread_test_case) {}

    ~CrossThreadImmediateTaskSource() override = default;

    void PostTask(unsigned int queue) override {
      task_runners_[queue]->PostTask(FROM_HERE, task_closure_);
    }

    // Will be called on the main thread.
    void SignalDone() override { two_thread_test_case_->SignalDone(); }

    TwoThreadTestCase* two_thread_test_case_;  // NOT OWNED.
  };

  void SignalDone() {
    if (++done_count_ == 2)
      delegate_->SignalDone();
  }

 private:
  const std::vector<scoped_refptr<TaskRunner>> task_runners_;
  const size_t num_tasks_;
  Thread auxiliary_thread_;
  std::unique_ptr<SingleThreadImmediateTaskSource> same_thread_task_source_;
  std::unique_ptr<CrossThreadImmediateTaskSource> cross_thread_task_scorce_;
  int done_count_ = 0;
};

class SequenceManagerPerfTest : public testing::TestWithParam<PerfTestType> {
 public:
  void SetUp() override {
    delegate_ = CreateDelegate();
  }

  void TearDown() override { delegate_.reset(); }

  std::unique_ptr<PerfTestDelegate> CreateDelegate() {
    switch (GetParam()) {
      case PerfTestType::kUseSequenceManagerWithMessageLoop:
        return std::make_unique<
            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoop>>(
            " SequenceManager with MessageLoop ");

      case PerfTestType::kUseSequenceManagerWithMessagePump:
        return std::make_unique<SequenceManagerWithMessagePumpPerfTestDelegate>(
            " SequenceManager with MessagePumpDefault ",
            MessageLoop::TYPE_DEFAULT);

      case PerfTestType::kUseSequenceManagerWithUIMessageLoop:
        return std::make_unique<
            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoopForUI>>(
            " SequenceManager with MessageLoopForUI ");

      case PerfTestType::kUseSequenceManagerWithUIMessagePump:
        return std::make_unique<SequenceManagerWithMessagePumpPerfTestDelegate>(
            " SequenceManager with MessagePumpForUI ", MessageLoop::TYPE_UI);

      case PerfTestType::kUseSequenceManagerWithIOMessageLoop:
        return std::make_unique<
            SequenceManagerWithMessageLoopPerfTestDelegate<MessageLoopForIO>>(
            " SequenceManager with MessageLoopForIO ");

      case PerfTestType::kUseSequenceManagerWithIOMessagePump:
        return std::make_unique<SequenceManagerWithMessagePumpPerfTestDelegate>(
            " SequenceManager with MessagePumpForIO ", MessageLoop::TYPE_IO);

      case PerfTestType::kUseMessageLoop:
        return std::make_unique<MessageLoopPerfTestDelegate>(
            " MessageLoop ", std::make_unique<MessageLoop>());

      case PerfTestType::kUseUIMessageLoop:
        return std::make_unique<MessageLoopPerfTestDelegate>(
            " MessageLoopForUI ", std::make_unique<MessageLoopForUI>());

      case PerfTestType::kUseIOMessageLoop:
        return std::make_unique<MessageLoopPerfTestDelegate>(
            " MessageLoopForIO ", std::make_unique<MessageLoopForIO>());

      case PerfTestType::kUseSingleThreadInWorkerPool:
        return std::make_unique<SingleThreadInWorkerPoolPerfTestDelegate>();

      default:
        NOTREACHED();
        return nullptr;
    }
  }

  bool ShouldMeasureQueueScaling() const {
    // To limit test run time, we only measure multiple queues specific sequence
    // manager configurations.
    return delegate_->MultipleQueuesSupported() &&
           GetParam() == PerfTestType::kUseSequenceManagerWithUIMessagePump;
  }

  std::vector<scoped_refptr<TaskRunner>> CreateTaskRunners(int num) {
    std::vector<scoped_refptr<TaskRunner>> task_runners;
    for (int i = 0; i < num; i++) {
      task_runners.push_back(delegate_->CreateTaskRunner());
    }
    return task_runners;
  }

  void Benchmark(const std::string& trace, TestCase* TestCase) {
    TimeTicks start = TimeTicks::Now();
    TimeTicks now;
    TestCase->Start();
    delegate_->WaitUntilDone();
    now = TimeTicks::Now();

    perf_test::PrintResult(
        "task", "", trace + delegate_->GetName(),
        (now - start).InMicroseconds() / static_cast<double>(kNumTasks),
        "us/task", true);
    LOG(ERROR) << "task " << trace << delegate_->GetName()
               << ((now - start).InMicroseconds() /
                   static_cast<double>(kNumTasks))
               << " us/task";
  }

  std::unique_ptr<PerfTestDelegate> delegate_;
};

INSTANTIATE_TEST_CASE_P(
    ,
    SequenceManagerPerfTest,
    testing::Values(PerfTestType::kUseSequenceManagerWithMessageLoop,
                    PerfTestType::kUseSequenceManagerWithMessagePump,
                    PerfTestType::kUseSequenceManagerWithUIMessageLoop,
                    PerfTestType::kUseSequenceManagerWithUIMessagePump,
                    PerfTestType::kUseSequenceManagerWithIOMessageLoop,
                    PerfTestType::kUseSequenceManagerWithIOMessagePump,
                    PerfTestType::kUseMessageLoop,
                    PerfTestType::kUseUIMessageLoop,
                    PerfTestType::kUseIOMessageLoop,
                    PerfTestType::kUseSingleThreadInWorkerPool));

TEST_P(SequenceManagerPerfTest, PostDelayedTasks_OneQueue) {
  if (!delegate_->VirtualTimeIsSupported()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadDelayedTestCase task_source(delegate_.get(),
                                          CreateTaskRunners(1));
  Benchmark("post delayed tasks with one queue", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostDelayedTasks_FourQueues) {
  if (!delegate_->VirtualTimeIsSupported() || !ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadDelayedTestCase task_source(delegate_.get(),
                                          CreateTaskRunners(4));
  Benchmark("post delayed tasks with four queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostDelayedTasks_EightQueues) {
  if (!delegate_->VirtualTimeIsSupported() || !ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadDelayedTestCase task_source(delegate_.get(),
                                          CreateTaskRunners(8));
  Benchmark("post delayed tasks with eight queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostDelayedTasks_ThirtyTwoQueues) {
  if (!delegate_->VirtualTimeIsSupported() || !ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadDelayedTestCase task_source(delegate_.get(),
                                          CreateTaskRunners(32));
  Benchmark("post delayed tasks with thirty two queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasks_OneQueue) {
  SingleThreadImmediateTestCase task_source(delegate_.get(),
                                            CreateTaskRunners(1));
  Benchmark("post immediate tasks with one queue", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasks_FourQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadImmediateTestCase task_source(delegate_.get(),
                                            CreateTaskRunners(4));
  Benchmark("post immediate tasks with four queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasks_EightQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadImmediateTestCase task_source(delegate_.get(),
                                            CreateTaskRunners(8));
  Benchmark("post immediate tasks with eight queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasks_ThirtyTwoQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  SingleThreadImmediateTestCase task_source(delegate_.get(),
                                            CreateTaskRunners(32));
  Benchmark("post immediate tasks with thirty two queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasksFromTwoThreads_OneQueue) {
  TwoThreadTestCase task_source(delegate_.get(), CreateTaskRunners(1));
  Benchmark("post immediate tasks with one queue", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasksFromTwoThreads_FourQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  TwoThreadTestCase task_source(delegate_.get(), CreateTaskRunners(4));
  Benchmark("post immediate tasks with four queues", &task_source);
}

TEST_P(SequenceManagerPerfTest, PostImmediateTasksFromTwoThreads_EightQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  TwoThreadTestCase task_source(delegate_.get(), CreateTaskRunners(8));
  Benchmark("post immediate tasks with eight queues", &task_source);
}

TEST_P(SequenceManagerPerfTest,
       PostImmediateTasksFromTwoThreads_ThirtyTwoQueues) {
  if (!ShouldMeasureQueueScaling()) {
    LOG(INFO) << "Unsupported";
    return;
  }

  TwoThreadTestCase task_source(delegate_.get(), CreateTaskRunners(32));
  Benchmark("post immediate tasks with thirty two queues", &task_source);
}

// TODO(alexclarke): Add additional tests with different mixes of non-delayed vs
// delayed tasks.

}  // namespace sequence_manager
}  // namespace base
