// Copyright 2018 The Chromium Authors
// 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_impl.h"

#include <stddef.h>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "base/auto_reset.h"
#include "base/cancelable_callback.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_pump_default.h"
#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/current_thread.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/sequence_manager/task_queue_impl.h"
#include "base/task/sequence_manager/task_queue_selector.h"
#include "base/task/sequence_manager/tasks.h"
#include "base/task/sequence_manager/test/mock_time_domain.h"
#include "base/task/sequence_manager/test/mock_time_message_pump.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.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/sequence_manager/work_queue.h"
#include "base/task/sequence_manager/work_queue_sets.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_features.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/null_task_runner.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "base/trace_event/base_tracing.h"
#include "base/tracing_buildflags.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"

#if BUILDFLAG(ENABLE_BASE_TRACING)
#include "base/test/trace_event_analyzer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#endif  // BUILDFLAG(ENABLE_BASE_TRACING)

using base::sequence_manager::EnqueueOrder;
using testing::_;
using testing::AnyNumber;
using testing::Contains;
using testing::ElementsAre;
using testing::ElementsAreArray;
using testing::HasSubstr;
using testing::Mock;
using testing::Not;
using testing::Return;
using testing::StrictMock;
using testing::UnorderedElementsAre;

namespace base {
namespace sequence_manager {
namespace internal {

class TestTaskQueue : public TaskQueue {
 public:
  TestTaskQueue(SequenceManager& sequence_manager, const TaskQueue::Spec& spec)
      : TaskQueue(sequence_manager.CreateTaskQueueImpl(spec), spec) {}

  using TaskQueue::GetTaskQueueImpl;

  WeakPtr<TestTaskQueue> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }

 private:
  ~TestTaskQueue() override = default;  // Ref-counted.

  // Used to ensure that task queue is deleted in tests.
  WeakPtrFactory<TestTaskQueue> weak_factory_{this};
};

namespace {

enum class RunnerType {
  kMockTaskRunner,
  kMessagePump,
};

enum class WakeUpType {
  kDefault,
  kAlign,
};

enum class TestQueuePriority : TaskQueue::QueuePriority {
  kControlPriority = 0,
  kHighestPriority = 1,
  kVeryHighPriority = 2,
  kHighPriority = 3,

  kNormalPriority = 4,
  kDefaultPriority = kNormalPriority,

  kLowPriority = 5,
  kBestEffortPriority = 6,
  kQueuePriorityCount = 7,
  kFirstQueuePriority = kControlPriority,
};

std::string ToString(RunnerType type) {
  switch (type) {
    case RunnerType::kMockTaskRunner:
      return "kMockTaskRunner";
    case RunnerType::kMessagePump:
      return "kMessagePump";
  }
}

std::string ToString(WakeUpType type) {
  switch (type) {
    case WakeUpType::kDefault:
      return "";
    case WakeUpType::kAlign:
      return "AlignedWakeUps";
  }
}

std::string GetTestNameSuffix(
    const testing::TestParamInfo<std::tuple<RunnerType, WakeUpType>>& info) {
  return StrCat({"With", ToString(std::get<0>(info.param)).substr(1),
                 ToString(std::get<1>(info.param))});
}

void PrintTo(const RunnerType type, std::ostream* os) {
  *os << ToString(type);
}

constexpr TimeDelta kLeeway = kDefaultLeeway;

using MockTask = MockCallback<base::RepeatingCallback<void()>>;

// This class abstracts the details of how the SequenceManager runs tasks.
// Subclasses will use a MockTaskRunner, a MessageLoop or a MockMessagePump. We
// can then have common tests for all the scenarios by just using this
// interface.
class Fixture {
 public:
  virtual ~Fixture() = default;
  virtual void AdvanceMockTickClock(TimeDelta delta) = 0;
  virtual const TickClock* mock_tick_clock() const = 0;
  virtual TimeTicks NextPendingTaskTime() const = 0;
  // Keeps advancing time as needed to run tasks up to the specified limit.
  virtual void FastForwardBy(TimeDelta delta) = 0;
  // Keeps advancing time as needed to run tasks until no more tasks are
  // available.
  virtual void FastForwardUntilNoTasksRemain() = 0;
  virtual void RunDoWorkOnce() = 0;
  virtual SequenceManagerForTest* sequence_manager() const = 0;
  virtual void DestroySequenceManager() = 0;
  virtual int GetNowTicksCallCount() = 0;
  virtual TimeTicks FromStartAligned(TimeDelta delta) const = 0;
};

class CallCountingTickClock : public TickClock {
 public:
  explicit CallCountingTickClock(RepeatingCallback<TimeTicks()> now_callback)
      : now_callback_(std::move(now_callback)) {}
  explicit CallCountingTickClock(TickClock* clock)
      : CallCountingTickClock(
            BindLambdaForTesting([clock]() { return clock->NowTicks(); })) {}

  ~CallCountingTickClock() override = default;

  TimeTicks NowTicks() const override {
    ++now_call_count_;
    return now_callback_.Run();
  }

  void Reset() { now_call_count_.store(0); }

  int now_call_count() const { return now_call_count_; }

 private:
  const RepeatingCallback<TimeTicks()> now_callback_;
  mutable std::atomic<int> now_call_count_{0};
};

class FixtureWithMockTaskRunner final : public Fixture {
 public:
  FixtureWithMockTaskRunner()
      : test_task_runner_(MakeRefCounted<TestMockTimeTaskRunner>(
            TestMockTimeTaskRunner::Type::kBoundToThread)),
        call_counting_clock_(BindRepeating(&TestMockTimeTaskRunner::NowTicks,
                                           test_task_runner_)),
        sequence_manager_(SequenceManagerForTest::Create(
            nullptr,
            SingleThreadTaskRunner::GetCurrentDefault(),
            mock_tick_clock(),
            SequenceManager::Settings::Builder()
                .SetMessagePumpType(MessagePumpType::DEFAULT)
                .SetRandomisedSamplingEnabled(false)
                .SetTickClock(mock_tick_clock())
                .SetPrioritySettings(SequenceManager::PrioritySettings(
                    TestQueuePriority::kQueuePriorityCount,
                    TestQueuePriority::kDefaultPriority))
                .Build())) {
    // A null clock triggers some assertions.
    AdvanceMockTickClock(Milliseconds(1));
    start_time_ = test_task_runner_->NowTicks();

    // The SequenceManager constructor calls Now() once for setting up
    // housekeeping.
    EXPECT_EQ(1, GetNowTicksCallCount());
    call_counting_clock_.Reset();
  }

  void AdvanceMockTickClock(TimeDelta delta) override {
    test_task_runner_->AdvanceMockTickClock(delta);
  }

  const TickClock* mock_tick_clock() const override {
    return &call_counting_clock_;
  }

  TimeTicks NextPendingTaskTime() const override {
    return test_task_runner_->NowTicks() +
           test_task_runner_->NextPendingTaskDelay();
  }

  void FastForwardBy(TimeDelta delta) override {
    test_task_runner_->FastForwardBy(delta);
  }

  void FastForwardUntilNoTasksRemain() override {
    test_task_runner_->FastForwardUntilNoTasksRemain();
  }

  void RunDoWorkOnce() override {
    EXPECT_EQ(test_task_runner_->GetPendingTaskCount(), 1u);
    // We should only run tasks already posted by that moment.
    RunLoop run_loop;
    test_task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure());
    // TestMockTimeTaskRunner will fast-forward mock clock if necessary.
    run_loop.Run();
  }

  scoped_refptr<TestMockTimeTaskRunner> test_task_runner() const {
    return test_task_runner_;
  }

  SequenceManagerForTest* sequence_manager() const override {
    return sequence_manager_.get();
  }

  void DestroySequenceManager() override { sequence_manager_.reset(); }

  int GetNowTicksCallCount() override {
    return call_counting_clock_.now_call_count();
  }

  TimeTicks FromStartAligned(TimeDelta delta) const override {
    return start_time_ + delta;
  }

 private:
  scoped_refptr<TestMockTimeTaskRunner> test_task_runner_;
  CallCountingTickClock call_counting_clock_;
  std::unique_ptr<SequenceManagerForTest> sequence_manager_;
  TimeTicks start_time_;
};

class FixtureWithMockMessagePump : public Fixture {
 public:
  explicit FixtureWithMockMessagePump(WakeUpType wake_up_type)
      : call_counting_clock_(&mock_clock_), wake_up_type_(wake_up_type) {
    if (wake_up_type_ == WakeUpType::kAlign)
      feature_list_.InitAndEnableFeature(kAlignWakeUps);
    else
      feature_list_.InitAndDisableFeature(kAlignWakeUps);
    // A null clock triggers some assertions.
    mock_clock_.Advance(Milliseconds(1));

    auto pump = std::make_unique<MockTimeMessagePump>(&mock_clock_);
    pump_ = pump.get();
    auto settings = SequenceManager::Settings::Builder()
                        .SetMessagePumpType(MessagePumpType::DEFAULT)
                        .SetRandomisedSamplingEnabled(false)
                        .SetTickClock(mock_tick_clock())
                        .SetPrioritySettings(SequenceManager::PrioritySettings(
                            TestQueuePriority::kQueuePriorityCount,
                            TestQueuePriority::kDefaultPriority))
                        .Build();
    auto thread_controller =
        std::make_unique<ThreadControllerWithMessagePumpImpl>(std::move(pump),
                                                              settings);
    ThreadControllerWithMessagePumpImpl::InitializeFeatures();
    sequence_manager_ = SequenceManagerForTest::Create(
        std::move(thread_controller), std::move(settings));
    sequence_manager_->SetDefaultTaskRunner(MakeRefCounted<NullTaskRunner>());
    start_time_ = mock_clock_.NowTicks();

    // The SequenceManager constructor calls Now() once for setting up
    // housekeeping.
    EXPECT_EQ(1, GetNowTicksCallCount());
    call_counting_clock_.Reset();
  }
  ~FixtureWithMockMessagePump() override {
    ThreadControllerWithMessagePumpImpl::ResetFeatures();
  }

  void AdvanceMockTickClock(TimeDelta delta) override {
    mock_clock_.Advance(delta);
  }

  const TickClock* mock_tick_clock() const override {
    return &call_counting_clock_;
  }

  TimeTicks NextPendingTaskTime() const override {
    return pump_->next_wake_up_time();
  }

  void FastForwardBy(TimeDelta delta) override {
    pump_->SetAllowTimeToAutoAdvanceUntil(mock_tick_clock()->NowTicks() +
                                          delta);
    pump_->SetStopWhenMessagePumpIsIdle(true);
    RunLoop().Run();
    pump_->SetStopWhenMessagePumpIsIdle(false);
  }

  void FastForwardUntilNoTasksRemain() override {
    pump_->SetAllowTimeToAutoAdvanceUntil(TimeTicks::Max());
    pump_->SetStopWhenMessagePumpIsIdle(true);
    RunLoop().Run();
    pump_->SetStopWhenMessagePumpIsIdle(false);
    pump_->SetAllowTimeToAutoAdvanceUntil(mock_tick_clock()->NowTicks());
  }

  void RunDoWorkOnce() override {
    pump_->SetQuitAfterDoWork(true);
    RunLoop().Run();
    pump_->SetQuitAfterDoWork(false);
  }

  SequenceManagerForTest* sequence_manager() const override {
    return sequence_manager_.get();
  }

  void DestroySequenceManager() override {
    pump_ = nullptr;
    sequence_manager_.reset();
  }

  int GetNowTicksCallCount() override {
    return call_counting_clock_.now_call_count();
  }

  TimeTicks FromStartAligned(TimeDelta delta) const override {
    if (wake_up_type_ == WakeUpType::kAlign) {
      return (start_time_ + delta).SnappedToNextTick(TimeTicks(), kLeeway);
    }
    return start_time_ + delta;
  }

 private:
  base::test::ScopedFeatureList feature_list_;
  SimpleTestTickClock mock_clock_;
  CallCountingTickClock call_counting_clock_;

  // Must outlive `pump_`.
  std::unique_ptr<SequenceManagerForTest> sequence_manager_;

  raw_ptr<MockTimeMessagePump> pump_ = nullptr;
  WakeUpType wake_up_type_;
  TimeTicks start_time_;
};

// Convenience wrapper around the fixtures so that we can use parametrized tests
// instead of templated ones. The latter would be more verbose as all method
// calls to the fixture would need to be like this->method()
class SequenceManagerTest
    : public testing::TestWithParam<std::tuple<RunnerType, WakeUpType>>,
      public Fixture {
 public:
  SequenceManagerTest() {
    switch (GetUnderlyingRunnerType()) {
      case RunnerType::kMockTaskRunner:
        fixture_ = std::make_unique<FixtureWithMockTaskRunner>();
        break;
      case RunnerType::kMessagePump:
        fixture_ =
            std::make_unique<FixtureWithMockMessagePump>(GetWakeUpType());
        break;
    }
  }

  scoped_refptr<TestTaskQueue> CreateTaskQueue(
      TaskQueue::Spec spec = TaskQueue::Spec(QueueName::TEST_TQ)) {
    return MakeRefCounted<TestTaskQueue>(*sequence_manager(), spec);
  }

  std::vector<scoped_refptr<TestTaskQueue>> CreateTaskQueues(
      size_t num_queues) {
    std::vector<scoped_refptr<TestTaskQueue>> queues;
    for (size_t i = 0; i < num_queues; i++)
      queues.push_back(CreateTaskQueue());
    return queues;
  }

  void RunUntilManagerIsIdle(RepeatingClosure per_run_time_callback) {
    for (;;) {
      // Advance time if we've run out of immediate work to do.
      if (!sequence_manager()->HasImmediateWork()) {
        LazyNow lazy_now(mock_tick_clock());
        auto wake_up = sequence_manager()->GetNextDelayedWakeUp();
        if (wake_up.has_value()) {
          AdvanceMockTickClock(wake_up->time - lazy_now.Now());
          per_run_time_callback.Run();
        } else {
          break;
        }
      }
      RunLoop().RunUntilIdle();
    }
  }

  debug::CrashKeyString* dummy_key() { return &dummy_key_; }

  void AdvanceMockTickClock(TimeDelta delta) override {
    fixture_->AdvanceMockTickClock(delta);
  }

  const TickClock* mock_tick_clock() const override {
    return fixture_->mock_tick_clock();
  }

  TimeTicks NextPendingTaskTime() const override {
    return fixture_->NextPendingTaskTime();
  }

  void FastForwardBy(TimeDelta delta) override {
    fixture_->FastForwardBy(delta);
  }

  void FastForwardUntilNoTasksRemain() override {
    fixture_->FastForwardUntilNoTasksRemain();
  }

  void RunDoWorkOnce() override { fixture_->RunDoWorkOnce(); }

  SequenceManagerForTest* sequence_manager() const override {
    return fixture_->sequence_manager();
  }

  void DestroySequenceManager() override { fixture_->DestroySequenceManager(); }

  int GetNowTicksCallCount() override {
    return fixture_->GetNowTicksCallCount();
  }

  RunnerType GetUnderlyingRunnerType() { return std::get<0>(GetParam()); }
  WakeUpType GetWakeUpType() { return std::get<1>(GetParam()); }

  TimeTicks FromStartAligned(TimeDelta delta) const override {
    return fixture_->FromStartAligned(delta);
  }

 private:
  debug::CrashKeyString dummy_key_{"dummy", debug::CrashKeySize::Size64};
  std::unique_ptr<Fixture> fixture_;
};

auto GetTestTypes() {
  return testing::Values(
      std::make_tuple(RunnerType::kMessagePump, WakeUpType::kDefault),
#if !BUILDFLAG(IS_WIN)
      std::make_tuple(RunnerType::kMessagePump, WakeUpType::kAlign),
#endif
      std::make_tuple(RunnerType::kMockTaskRunner, WakeUpType::kDefault));
}

INSTANTIATE_TEST_SUITE_P(All,
                         SequenceManagerTest,
                         GetTestTypes(),
                         GetTestNameSuffix);

void PostFromNestedRunloop(scoped_refptr<TestTaskQueue> runner,
                           std::vector<std::pair<OnceClosure, bool>>* tasks) {
  for (std::pair<OnceClosure, bool>& pair : *tasks) {
    if (pair.second) {
      runner->task_runner()->PostTask(FROM_HERE, std::move(pair.first));
    } else {
      runner->task_runner()->PostNonNestableTask(FROM_HERE,
                                                 std::move(pair.first));
    }
  }
  RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
}

void NopTask() {}

class TestCountUsesTimeSource : public TickClock {
 public:
  TestCountUsesTimeSource() = default;
  TestCountUsesTimeSource(const TestCountUsesTimeSource&) = delete;
  TestCountUsesTimeSource& operator=(const TestCountUsesTimeSource&) = delete;
  ~TestCountUsesTimeSource() override = default;

  TimeTicks NowTicks() const override {
    now_calls_count_++;
    // Don't return 0, as it triggers some assertions.
    return TimeTicks() + Seconds(1);
  }

  int now_calls_count() const { return now_calls_count_; }

 private:
  mutable int now_calls_count_ = 0;
};

class QueueTimeTaskObserver : public TaskObserver {
 public:
  void WillProcessTask(const PendingTask& pending_task,
                       bool was_blocked_or_low_priority) override {
    queue_times_.push_back(pending_task.queue_time);
  }
  void DidProcessTask(const PendingTask& pending_task) override {}
  std::vector<TimeTicks> queue_times() const { return queue_times_; }

 private:
  std::vector<TimeTicks> queue_times_;
};

class ScopedNoWakeUpsForCanceledTasks {
 public:
  ScopedNoWakeUpsForCanceledTasks()
      : scoped_feature_list_(kNoWakeUpsForCanceledTasks) {
    SequenceManagerImpl::ApplyNoWakeUpsForCanceledTasks();
  }

  ~ScopedNoWakeUpsForCanceledTasks() {
    SequenceManagerImpl::ResetNoWakeUpsForCanceledTasksForTesting();
  }

 private:
  test::ScopedFeatureList scoped_feature_list_;
};

}  // namespace

TEST_P(SequenceManagerTest, GetCorrectTaskRunnerForCurrentTask) {
  auto queue = CreateTaskQueue();

  queue->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        EXPECT_EQ(queue->task_runner(),
                  sequence_manager()->GetTaskRunnerForCurrentTask());
      }));

  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, NowNotCalledIfUnneeded) {
  sequence_manager()->SetWorkBatchSize(6);

  auto queues = CreateTaskQueues(3u);

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  RunLoop().RunUntilIdle();

  EXPECT_EQ(0, GetNowTicksCallCount());
}

TEST_P(SequenceManagerTest,
       NowCalledMinimumNumberOfTimesToComputeTaskDurations) {
  TestTaskTimeObserver time_observer;
  sequence_manager()->SetWorkBatchSize(6);
  sequence_manager()->AddTaskTimeObserver(&time_observer);

  auto queues = CreateTaskQueues(3u);

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  RunLoop().RunUntilIdle();
  // Now is called when we start work and then for each task when it's
  // completed. 1 + 6  = 7 calls.
  EXPECT_EQ(7, GetNowTicksCallCount());
}

TEST_P(SequenceManagerTest,
       NowCalledMinimumNumberOfTimesToComputeTaskDurationsDelayedFenceAllowed) {
  TestTaskTimeObserver time_observer;
  sequence_manager()->SetWorkBatchSize(6);
  sequence_manager()->AddTaskTimeObserver(&time_observer);

  std::vector<scoped_refptr<TestTaskQueue>> queues;
  for (size_t i = 0; i < 3; i++) {
    queues.push_back(CreateTaskQueue(
        TaskQueue::Spec(QueueName::TEST_TQ).SetDelayedFencesAllowed(true)));
  }

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  RunLoop().RunUntilIdle();
  // Now is called each time a task is queued, when first task is started
  // running, and when a task is completed. 1 + 6 * 2 = 13 calls.
  EXPECT_EQ(13, GetNowTicksCallCount());
}

void NullTask() {}

void TestTask(uint64_t value, std::vector<EnqueueOrder>* out_result) {
  out_result->push_back(EnqueueOrder::FromIntForTesting(value));
}

void DisableQueueTestTask(uint64_t value,
                          std::vector<EnqueueOrder>* out_result,
                          TaskQueue::QueueEnabledVoter* voter) {
  out_result->push_back(EnqueueOrder::FromIntForTesting(value));
  voter->SetVoteToEnable(false);
}

TEST_P(SequenceManagerTest, SingleQueuePosting) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
}

TEST_P(SequenceManagerTest, MultiQueuePosting) {
  auto queues = CreateTaskQueues(3u);

  std::vector<EnqueueOrder> run_order;
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 1, &run_order));
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 2, &run_order));
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 3, &run_order));
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 4, &run_order));
  queues[2]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 5, &run_order));
  queues[2]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 6, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u));
}

TEST_P(SequenceManagerTest, NonNestableTaskPosting) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostNonNestableTask(FROM_HERE,
                                            BindOnce(&TestTask, 1, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));
}

TEST_P(SequenceManagerTest, NonNestableTaskExecutesInExpectedOrder) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order));
  queue->task_runner()->PostNonNestableTask(FROM_HERE,
                                            BindOnce(&TestTask, 5, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u));
}

TEST_P(SequenceManagerTest, NonNestableTasksDoesntExecuteInNestedLoop) {
  // TestMockTimeTaskRunner doesn't support nested loops.
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop;
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 3, &run_order), false));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 4, &run_order), false));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 5, &run_order), true));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 6, &run_order), true));

  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostFromNestedRunloop, queue,
                          Unretained(&tasks_to_post_from_nested_loop)));

  RunLoop().RunUntilIdle();
  // Note we expect tasks 3 & 4 to run last because they're non-nestable.
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 5u, 6u, 3u, 4u));
}

TEST_P(SequenceManagerTest, NonNestableTasksShutdownQueue) {
  // TestMockTimeTaskRunner doesn't support nested loops.
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;

  std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop;
  tasks_to_post_from_nested_loop.emplace_back(
      BindOnce(&TestTask, 1, &run_order), false);
  tasks_to_post_from_nested_loop.emplace_back(
      BindOnce(&TestTask, 2, &run_order), true);
  tasks_to_post_from_nested_loop.emplace_back(
      BindLambdaForTesting([&queue]() { queue->ShutdownTaskQueue(); }), true);

  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostFromNestedRunloop, queue,
                          Unretained(&tasks_to_post_from_nested_loop)));

  RunLoop().RunUntilIdle();
  // We don't expect task 1 to run because the queue was shutdown.
  EXPECT_THAT(run_order, ElementsAre(2u));
}

TEST_P(SequenceManagerTest, NonNestableTaskQueueTimeShiftsToEndOfNestedLoop) {
  // TestMockTimeTaskRunner doesn't support nested loops.
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;

  auto queue = CreateTaskQueue();

  QueueTimeTaskObserver observer;
  sequence_manager()->AddTaskObserver(&observer);
  sequence_manager()->SetAddQueueTimeToTasks(true);

  RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);

  const TimeTicks start_time = mock_tick_clock()->NowTicks();

  constexpr auto kTimeSpentInNestedLoop = Seconds(1);
  constexpr auto kTimeInTaskAfterNestedLoop = Seconds(3);

  // 1) Run task 1
  // 2) Enter a nested loop
  // 3) Run task 3
  // 4) Advance time by 1 second
  // 5) Run task 5
  // 6) Exit nested loop
  // 7) Run task 7 (non-nestable)
  // 8) Advance time by 3 seconds (non-nestable)
  // 9) Run task 9 (non-nestable)
  // Steps 7-9 are expected to run last and have had their queue time adjusted
  // to 6 (task 8 shouldn't affect task 9's queue time).
  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   TestTask(2, &run_order);
                                   nested_run_loop.Run();
                                 }));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
  queue->task_runner()->PostNonNestableTask(FROM_HERE,
                                            BindOnce(&TestTask, 7, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   TestTask(4, &run_order);
                                   AdvanceMockTickClock(kTimeSpentInNestedLoop);
                                 }));
  queue->task_runner()->PostNonNestableTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        TestTask(8, &run_order);
        AdvanceMockTickClock(kTimeInTaskAfterNestedLoop);
      }));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order));
  queue->task_runner()->PostNonNestableTask(FROM_HERE,
                                            BindOnce(&TestTask, 9, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   TestTask(6, &run_order);
                                   nested_run_loop.Quit();
                                 }));

  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u));

  const TimeTicks expected_adjusted_queueing_time =
      start_time + kTimeSpentInNestedLoop;
  EXPECT_THAT(
      observer.queue_times(),
      ElementsAre(start_time, start_time, start_time, start_time, start_time,
                  start_time, expected_adjusted_queueing_time,
                  expected_adjusted_queueing_time,
                  expected_adjusted_queueing_time));

  sequence_manager()->RemoveTaskObserver(&observer);
}

namespace {

void InsertFenceAndPostTestTask(int id,
                                std::vector<EnqueueOrder>* run_order,
                                scoped_refptr<TestTaskQueue> task_queue,
                                SequenceManagerForTest* manager) {
  run_order->push_back(EnqueueOrder::FromIntForTesting(id));
  task_queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  task_queue->task_runner()->PostTask(FROM_HERE,
                                      BindOnce(&TestTask, id + 1, run_order));

  // Force reload of immediate work queue. In real life the same effect can be
  // achieved with cross-thread posting.
  manager->ReloadEmptyWorkQueues();
}

}  // namespace

TEST_P(SequenceManagerTest, TaskQueueDisabledFromNestedLoop) {
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  auto queue = CreateTaskQueue();
  std::vector<EnqueueOrder> run_order;

  std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop;

  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 1, &run_order), false));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&InsertFenceAndPostTestTask, 2, &run_order, queue,
                              sequence_manager()),
                     true));

  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostFromNestedRunloop, queue,
                          Unretained(&tasks_to_post_from_nested_loop)));
  RunLoop().RunUntilIdle();

  // Task 1 shouldn't run first due to it being non-nestable and queue gets
  // blocked after task 2. Task 1 runs after existing nested message loop
  // due to being posted before inserting a fence.
  // This test checks that breaks when nestable task is pushed into a redo
  // queue.
  EXPECT_THAT(run_order, ElementsAre(2u, 1u));

  queue->RemoveFence();
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(2u, 1u, 3u));
}

TEST_P(SequenceManagerTest,
       HasTaskToRunImmediatelyOrReadyDelayedTask_ImmediateTask) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Move the task into the |immediate_work_queue|.
  EXPECT_TRUE(queue->GetTaskQueueImpl()->immediate_work_queue()->Empty());
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(queue->GetTaskQueueImpl()->immediate_work_queue()->Empty());
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Run the task, making the queue empty.
  voter->SetVoteToEnable(true);
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest,
       HasTaskToRunImmediatelyOrReadyDelayedTask_DelayedTask) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay(Milliseconds(10));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  AdvanceMockTickClock(delay);
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Move the task into the |delayed_work_queue|.
  LazyNow lazy_now(mock_tick_clock());
  sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now);
  sequence_manager()->ScheduleWork();
  EXPECT_FALSE(queue->GetTaskQueueImpl()->delayed_work_queue()->Empty());
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Run the task, making the queue empty.
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(queue->GetTaskQueueImpl()->delayed_work_queue()->Empty());
}

TEST_P(SequenceManagerTest, DelayedTaskPosting) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay(Milliseconds(10));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  EXPECT_TRUE(run_order.empty());

  // The task doesn't run before the delay has completed.
  FastForwardBy(Milliseconds(9));
  EXPECT_TRUE(run_order.empty());

  // After the delay has completed, the task runs normally.
  FastForwardBy(Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest, DelayedTaskAtPosting) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  constexpr TimeDelta kDelay(Milliseconds(10));
  auto handle = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order),
      sequence_manager()->NowTicks() + kDelay,
      subtle::DelayPolicy::kFlexibleNoSooner);
  EXPECT_EQ(FromStartAligned(kDelay), NextPendingTaskTime());
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  EXPECT_TRUE(run_order.empty());

  // The task doesn't run before the delay has completed.
  FastForwardBy(kDelay - Milliseconds(1));
  EXPECT_TRUE(run_order.empty());

  // After the delay has completed, the task runs normally.
  FastForwardBy(Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest, DelayedTaskAtPosting_FlexiblePreferEarly) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time = sequence_manager()->NowTicks();
  std::vector<EnqueueOrder> run_order;
  constexpr TimeDelta kDelay(Milliseconds(20));
  auto handle = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order),
      sequence_manager()->NowTicks() + kDelay,
      subtle::DelayPolicy::kFlexiblePreferEarly);
  TimeTicks expected_run_time = start_time + kDelay;
  if (GetWakeUpType() == WakeUpType::kAlign) {
    expected_run_time =
        (start_time + kDelay - kLeeway).SnappedToNextTick(TimeTicks(), kLeeway);
  }
  EXPECT_EQ(expected_run_time, NextPendingTaskTime());
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  EXPECT_TRUE(run_order.empty());
  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ((WakeUp{start_time + kDelay, kLeeway, WakeUpResolution::kLow,
                    subtle::DelayPolicy::kFlexiblePreferEarly}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // The task doesn't run before the delay has completed.
  FastForwardBy(kDelay - kLeeway - Milliseconds(1));
  EXPECT_TRUE(run_order.empty());

  // After the delay has completed, the task runs normally.
  FastForwardBy(kLeeway + Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest, DelayedTaskAtPosting_MixedDelayPolicy) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time = sequence_manager()->NowTicks();
  std::vector<EnqueueOrder> run_order;
  auto handle1 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 2, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(8),
      subtle::DelayPolicy::kFlexibleNoSooner);
  auto handle2 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(10),
      subtle::DelayPolicy::kPrecise);
  EXPECT_EQ(start_time + Milliseconds(10), NextPendingTaskTime());
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  EXPECT_TRUE(run_order.empty());
  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ((WakeUp{start_time + Milliseconds(10), kLeeway,
                    WakeUpResolution::kLow, subtle::DelayPolicy::kPrecise}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // The task doesn't run before the delay has completed.
  FastForwardBy(Milliseconds(10) - Milliseconds(1));
  EXPECT_TRUE(run_order.empty());

  // After the delay has completed, the task runs normally.
  FastForwardBy(Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest, DelayedTaskAtPosting_Immediate) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  auto handle = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order), TimeTicks(),
      subtle::DelayPolicy::kFlexibleNoSooner);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->HasTaskToRunImmediately());
  EXPECT_TRUE(run_order.empty());

  // The task runs immediately.
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST(SequenceManagerTestWithMockTaskRunner,
     DelayedTaskExecutedInOneMessageLoopTask) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(10));
  RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, fixture.test_task_runner()->GetPendingTaskCount());
  fixture.FastForwardUntilNoTasksRemain();
  EXPECT_EQ(0u, fixture.test_task_runner()->GetPendingTaskCount());
}

TEST_P(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(10));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(8));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(5));

  EXPECT_EQ(FromStartAligned(Milliseconds(5)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(5));
  EXPECT_THAT(run_order, ElementsAre(3u));
  EXPECT_EQ(FromStartAligned(Milliseconds(8)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(3));
  EXPECT_THAT(run_order, ElementsAre(3u, 2u));
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(2));
  EXPECT_THAT(run_order, ElementsAre(3u, 2u, 1u));
}

TEST_P(SequenceManagerTest,
       DelayedTaskAtPosting_MultipleTasks_DescendingOrder) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  auto handle1 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(10),
      subtle::DelayPolicy::kFlexibleNoSooner);

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(8));

  auto handle2 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 3, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(5),
      subtle::DelayPolicy::kFlexibleNoSooner);

  EXPECT_EQ(FromStartAligned(Milliseconds(5)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(5));
  EXPECT_THAT(run_order, ElementsAre(3u));
  EXPECT_EQ(FromStartAligned(Milliseconds(8)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(3));
  EXPECT_THAT(run_order, ElementsAre(3u, 2u));
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(2));
  EXPECT_THAT(run_order, ElementsAre(3u, 2u, 1u));
}

TEST_P(SequenceManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(1));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(5));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(10));

  EXPECT_EQ(FromStartAligned(Milliseconds(1)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_EQ(FromStartAligned(Milliseconds(5)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(4));
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(5));
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
}

TEST_P(SequenceManagerTest, DelayedTaskAtPosting_MultipleTasks_AscendingOrder) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  auto handle1 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 1, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(1),
      subtle::DelayPolicy::kFlexibleNoSooner);

  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(5));

  auto handle2 = queue->task_runner()->PostCancelableDelayedTaskAt(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindOnce(&TestTask, 3, &run_order),
      sequence_manager()->NowTicks() + Milliseconds(10),
      subtle::DelayPolicy::kFlexibleNoSooner);

  EXPECT_EQ(FromStartAligned(Milliseconds(1)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(1));
  EXPECT_THAT(run_order, ElementsAre(1u));
  EXPECT_EQ(FromStartAligned(Milliseconds(5)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(4));
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());

  FastForwardBy(Milliseconds(5));
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
}

TEST(SequenceManagerTestWithMockTaskRunner,
     PostDelayedTask_SharesUnderlyingDelayedTasks) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay(Milliseconds(10));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), delay);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), delay);

  EXPECT_EQ(1u, fixture.test_task_runner()->GetPendingTaskCount());
}

TEST(SequenceManagerTestWithMockTaskRunner,
     CrossThreadTaskPostingToDisabledQueueDoesntScheduleWork) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  WaitableEvent done_event;
  Thread thread("TestThread");
  thread.Start();
  thread.task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   // Should not schedule a DoWork.
                                   queue->task_runner()->PostTask(
                                       FROM_HERE, BindOnce(&NopTask));
                                   done_event.Signal();
                                 }));
  done_event.Wait();
  thread.Stop();

  EXPECT_EQ(0u, fixture.test_task_runner()->GetPendingTaskCount());

  // But if the queue becomes re-enabled it does schedule work.
  voter->SetVoteToEnable(true);
  EXPECT_EQ(1u, fixture.test_task_runner()->GetPendingTaskCount());
}

TEST(SequenceManagerTestWithMockTaskRunner,
     CrossThreadTaskPostingToBlockedQueueDoesntScheduleWork) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  WaitableEvent done_event;
  Thread thread("TestThread");
  thread.Start();
  thread.task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   // Should not schedule a DoWork.
                                   queue->task_runner()->PostTask(
                                       FROM_HERE, BindOnce(&NopTask));
                                   done_event.Signal();
                                 }));
  done_event.Wait();
  thread.Stop();

  EXPECT_EQ(0u, fixture.test_task_runner()->GetPendingTaskCount());

  // But if the queue becomes unblocked it does schedule work.
  queue->RemoveFence();
  EXPECT_EQ(1u, fixture.test_task_runner()->GetPendingTaskCount());
}

namespace {

class TestObject {
 public:
  ~TestObject() { destructor_count__++; }

  void Run() { FAIL() << "TestObject::Run should not be called"; }

  static int destructor_count__;
};

int TestObject::destructor_count__ = 0;

}  // namespace

TEST_P(SequenceManagerTest, PendingDelayedTasksRemovedOnShutdown) {
  auto queue = CreateTaskQueue();

  TestObject::destructor_count__ = 0;

  TimeDelta delay(Milliseconds(10));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestObject::Run, Owned(new TestObject())), delay);
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&TestObject::Run, Owned(new TestObject())));

  DestroySequenceManager();

  EXPECT_EQ(2, TestObject::destructor_count__);
}

TEST_P(SequenceManagerTest, InsertAndRemoveFence) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  // Posting a task when pumping is disabled doesn't result in work getting
  // posted.
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, task.Get());
  EXPECT_CALL(task, Run).Times(0);
  RunLoop().RunUntilIdle();

  // However polling still works.
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // After removing the fence the task runs normally.
  queue->RemoveFence();
  EXPECT_CALL(task, Run);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, RemovingFenceForDisabledQueueDoesNotPostDoWork) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, task.Get());

  queue->RemoveFence();
  EXPECT_CALL(task, Run).Times(0);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, EnablingFencedQueueDoesNotPostDoWork) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, task.Get());
  voter->SetVoteToEnable(true);

  EXPECT_CALL(task, Run).Times(0);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, DenyRunning_BeforePosting) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  queue->task_runner()->PostTask(FROM_HERE, task.Get());

  EXPECT_CALL(task, Run).Times(0);
  RunLoop().RunUntilIdle();

  voter->SetVoteToEnable(true);
  EXPECT_CALL(task, Run);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, DenyRunning_AfterPosting) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  queue->task_runner()->PostTask(FROM_HERE, task.Get());
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  EXPECT_CALL(task, Run).Times(0);
  RunLoop().RunUntilIdle();

  voter->SetVoteToEnable(true);
  EXPECT_CALL(task, Run);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, DenyRunning_AfterRemovingFence) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(run_order.empty());

  queue->RemoveFence();
  voter->SetVoteToEnable(true);
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));
}

TEST_P(SequenceManagerTest, RemovingFenceWithDelayedTask) {
  TimeDelta kDelay = Milliseconds(10);
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;

  // Posting a delayed task when fenced will apply the delay, but won't cause
  // work to executed afterwards.
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  queue->task_runner()->PostDelayedTask(FROM_HERE, task.Get(), kDelay);

  // The task does not run even though it's delay is up.
  EXPECT_CALL(task, Run).Times(0);
  FastForwardBy(kDelay);

  // Removing the fence causes the task to run.
  queue->RemoveFence();
  EXPECT_CALL(task, Run);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, RemovingFenceWithMultipleDelayedTasks) {
  auto queue = CreateTaskQueue();
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  std::vector<EnqueueOrder> run_order;
  // Posting a delayed task when fenced will apply the delay, but won't cause
  // work to executed afterwards.
  TimeDelta delay1(Milliseconds(1));
  TimeDelta delay2(Milliseconds(10));
  TimeDelta delay3(Milliseconds(20));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay1);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), delay2);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), delay3);

  AdvanceMockTickClock(Milliseconds(15));
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(run_order.empty());

  // Removing the fence causes the ready tasks to run.
  queue->RemoveFence();
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
}

TEST_P(SequenceManagerTest, InsertFencePreventsDelayedTasksFromRunning) {
  auto queue = CreateTaskQueue();
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay(Milliseconds(10));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);

  FastForwardBy(Milliseconds(10));
  EXPECT_TRUE(run_order.empty());
}

TEST_P(SequenceManagerTest, MultipleFences) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  // Subsequent tasks should be blocked.
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order));
  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
}

TEST_P(SequenceManagerTest, InsertFenceThenImmediatlyRemoveDoesNotBlock) {
  auto queue = CreateTaskQueue();
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->RemoveFence();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
}

TEST_P(SequenceManagerTest, InsertFencePostThenRemoveDoesNotBlock) {
  auto queue = CreateTaskQueue();
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->RemoveFence();

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
}

TEST_P(SequenceManagerTest, MultipleFencesWithInitiallyEmptyQueue) {
  auto queue = CreateTaskQueue();
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));
}

TEST_P(SequenceManagerTest, BlockedByFence) {
  auto queue = CreateTaskQueue();
  EXPECT_FALSE(queue->BlockedByFence());

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  EXPECT_TRUE(queue->BlockedByFence());

  queue->RemoveFence();
  EXPECT_FALSE(queue->BlockedByFence());

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  EXPECT_FALSE(queue->BlockedByFence());

  RunLoop().RunUntilIdle();
  EXPECT_TRUE(queue->BlockedByFence());

  queue->RemoveFence();
  EXPECT_FALSE(queue->BlockedByFence());
}

TEST_P(SequenceManagerTest, BlockedByFence_BothTypesOfFence) {
  auto queue = CreateTaskQueue();

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  EXPECT_FALSE(queue->BlockedByFence());

  queue->InsertFence(TaskQueue::InsertFencePosition::kBeginningOfTime);
  EXPECT_TRUE(queue->BlockedByFence());
}

namespace {

void RecordTimeTask(std::vector<TimeTicks>* run_times, const TickClock* clock) {
  run_times->push_back(clock->NowTicks());
}

void RecordTimeAndQueueTask(
    std::vector<std::pair<scoped_refptr<TestTaskQueue>, TimeTicks>>* run_times,
    scoped_refptr<TestTaskQueue> task_queue,
    const TickClock* clock) {
  run_times->emplace_back(task_queue, clock->NowTicks());
}

}  // namespace

TEST_P(SequenceManagerTest, DelayedFence_DelayedTasks) {
  scoped_refptr<TestTaskQueue> queue = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ).SetDelayedFencesAllowed(true));

  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
      Milliseconds(100));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
      Milliseconds(200));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
      Milliseconds(300));

  queue->InsertFenceAt(mock_tick_clock()->NowTicks() + Milliseconds(250));
  EXPECT_FALSE(queue->HasActiveFence());

  FastForwardUntilNoTasksRemain();

  EXPECT_TRUE(queue->HasActiveFence());
  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(100)),
                                     FromStartAligned(Milliseconds(200))));
  run_times.clear();

  queue->RemoveFence();

  FastForwardUntilNoTasksRemain();

  EXPECT_FALSE(queue->HasActiveFence());
  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(300))));
}

TEST_P(SequenceManagerTest, DelayedFence_ImmediateTasks) {
  const auto kStartTime = mock_tick_clock()->NowTicks();
  scoped_refptr<TestTaskQueue> queue = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ).SetDelayedFencesAllowed(true));

  std::vector<TimeTicks> run_times;
  queue->InsertFenceAt(mock_tick_clock()->NowTicks() + Milliseconds(250));

  for (int i = 0; i < 5; ++i) {
    queue->task_runner()->PostTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()));
    FastForwardBy(Milliseconds(100));
    if (i < 2) {
      EXPECT_FALSE(queue->HasActiveFence());
    } else {
      EXPECT_TRUE(queue->HasActiveFence());
    }
  }

  EXPECT_THAT(run_times, ElementsAre(kStartTime, kStartTime + Milliseconds(100),
                                     kStartTime + Milliseconds(200)));
  run_times.clear();

  queue->RemoveFence();
  FastForwardUntilNoTasksRemain();

  EXPECT_THAT(run_times, ElementsAre(kStartTime + Milliseconds(500),
                                     kStartTime + Milliseconds(500)));
}

TEST_P(SequenceManagerTest, DelayedFence_RemovedFenceDoesNotActivate) {
  const auto kStartTime = mock_tick_clock()->NowTicks();
  scoped_refptr<TestTaskQueue> queue = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ).SetDelayedFencesAllowed(true));

  std::vector<TimeTicks> run_times;
  queue->InsertFenceAt(mock_tick_clock()->NowTicks() + Milliseconds(250));

  for (int i = 0; i < 3; ++i) {
    queue->task_runner()->PostTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()));
    EXPECT_FALSE(queue->HasActiveFence());
    FastForwardBy(Milliseconds(100));
  }

  EXPECT_TRUE(queue->HasActiveFence());
  queue->RemoveFence();

  for (int i = 0; i < 2; ++i) {
    queue->task_runner()->PostTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()));
    FastForwardBy(Milliseconds(100));
    EXPECT_FALSE(queue->HasActiveFence());
  }

  EXPECT_THAT(run_times, ElementsAre(kStartTime, kStartTime + Milliseconds(100),
                                     kStartTime + Milliseconds(200),
                                     kStartTime + Milliseconds(300),
                                     kStartTime + Milliseconds(400)));
}

TEST_P(SequenceManagerTest, DelayedFence_TakeIncomingImmediateQueue) {
  // This test checks that everything works correctly when a work queue
  // is swapped with an immediate incoming queue and a delayed fence
  // is activated, forcing a different queue to become active.
  const auto kStartTime = mock_tick_clock()->NowTicks();
  scoped_refptr<TestTaskQueue> queue1 = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ).SetDelayedFencesAllowed(true));
  scoped_refptr<TestTaskQueue> queue2 = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST2_TQ).SetDelayedFencesAllowed(true));

  std::vector<std::pair<scoped_refptr<TestTaskQueue>, TimeTicks>> run_times;

  // Fence ensures that the task posted after advancing time is blocked.
  queue1->InsertFenceAt(mock_tick_clock()->NowTicks() + Milliseconds(250));

  // This task should not be blocked and should run immediately after
  // advancing time at 301ms.
  queue1->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&RecordTimeAndQueueTask, &run_times, queue1, mock_tick_clock()));
  // Force reload of immediate work queue. In real life the same effect can be
  // achieved with cross-thread posting.
  sequence_manager()->ReloadEmptyWorkQueues();

  AdvanceMockTickClock(Milliseconds(300));

  // This task should be blocked.
  queue1->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&RecordTimeAndQueueTask, &run_times, queue1, mock_tick_clock()));
  // This task on a different runner should run as expected.
  queue2->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&RecordTimeAndQueueTask, &run_times, queue2, mock_tick_clock()));

  FastForwardUntilNoTasksRemain();

  EXPECT_THAT(
      run_times,
      ElementsAre(std::make_pair(queue1, kStartTime + Milliseconds(300)),
                  std::make_pair(queue2, kStartTime + Milliseconds(300))));
}

namespace {

void ReentrantTestTask(scoped_refptr<TestTaskQueue> runner,
                       int countdown,
                       std::vector<EnqueueOrder>* out_result) {
  out_result->push_back(EnqueueOrder::FromIntForTesting(countdown));
  if (--countdown) {
    runner->task_runner()->PostTask(
        FROM_HERE, BindOnce(&ReentrantTestTask, runner, countdown, out_result));
  }
}

}  // namespace

TEST_P(SequenceManagerTest, ReentrantPosting) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&ReentrantTestTask, queue, 3, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(3u, 2u, 1u));
}

namespace {

class RefCountedCallbackFactory {
 public:
  OnceCallback<void()> WrapCallback(OnceCallback<void()> cb) {
    return BindOnce(
        [](OnceCallback<void()> cb, WeakPtr<bool>) { std::move(cb).Run(); },
        std::move(cb), task_references_.GetWeakPtr());
  }

  bool HasReferences() const { return task_references_.HasWeakPtrs(); }

 private:
  bool dummy_;
  WeakPtrFactory<bool> task_references_{&dummy_};
};

}  // namespace

TEST_P(SequenceManagerTest, NoTasksAfterShutdown) {
  auto queue = CreateTaskQueue();
  StrictMock<MockTask> task;
  RefCountedCallbackFactory counter;

  EXPECT_CALL(task, Run).Times(0);
  queue->task_runner()->PostTask(FROM_HERE, counter.WrapCallback(task.Get()));
  DestroySequenceManager();
  queue->task_runner()->PostTask(FROM_HERE, counter.WrapCallback(task.Get()));

  if (GetUnderlyingRunnerType() != RunnerType::kMessagePump) {
    RunLoop().RunUntilIdle();
  }

  EXPECT_FALSE(counter.HasReferences());
}

void PostTaskToRunner(scoped_refptr<TestTaskQueue> runner,
                      std::vector<EnqueueOrder>* run_order) {
  runner->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, run_order));
}

TEST_P(SequenceManagerTest, PostFromThread) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  Thread thread("TestThread");
  thread.Start();
  thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostTaskToRunner, queue, &run_order));
  thread.Stop();

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));
}

void RePostingTestTask(scoped_refptr<TestTaskQueue> runner, int* run_count) {
  (*run_count)++;
  runner->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&RePostingTestTask, Unretained(runner.get()), run_count));
}

TEST_P(SequenceManagerTest, DoWorkCantPostItselfMultipleTimes) {
  auto queue = CreateTaskQueue();

  int run_count = 0;
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&RePostingTestTask, queue, &run_count));

  RunDoWorkOnce();
  EXPECT_EQ(1u, sequence_manager()->GetPendingTaskCountForTesting());
  EXPECT_EQ(1, run_count);
}

TEST_P(SequenceManagerTest, PostFromNestedRunloop) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop;
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&TestTask, 1, &run_order), true));

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 0, &run_order));
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostFromNestedRunloop, queue,
                          Unretained(&tasks_to_post_from_nested_loop)));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(0u, 2u, 1u));
}

TEST_P(SequenceManagerTest, WorkBatching) {
  auto queue = CreateTaskQueue();
  sequence_manager()->SetWorkBatchSize(2);

  std::vector<EnqueueOrder> run_order;
  for (int i = 0; i < 4; ++i) {
    queue->task_runner()->PostTask(FROM_HERE,
                                   BindOnce(&TestTask, i, &run_order));
  }

  // Running one task in the host message loop should cause two posted tasks
  // to get executed.
  RunDoWorkOnce();
  EXPECT_THAT(run_order, ElementsAre(0u, 1u));

  // The second task runs the remaining two posted tasks.
  RunDoWorkOnce();
  EXPECT_THAT(run_order, ElementsAre(0u, 1u, 2u, 3u));
}

namespace {

class MockTaskObserver : public TaskObserver {
 public:
  MOCK_METHOD1(DidProcessTask, void(const PendingTask& task));
  MOCK_METHOD2(WillProcessTask,
               void(const PendingTask& task, bool was_blocked_or_low_priority));
};

}  // namespace

TEST_P(SequenceManagerTest, TaskObserverAdding) {
  auto queue = CreateTaskQueue();
  MockTaskObserver observer;

  sequence_manager()->SetWorkBatchSize(2);
  sequence_manager()->AddTaskObserver(&observer);

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false))
      .Times(2);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(2);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, TaskObserverRemoving) {
  auto queue = CreateTaskQueue();
  MockTaskObserver observer;
  sequence_manager()->SetWorkBatchSize(2);
  sequence_manager()->AddTaskObserver(&observer);
  sequence_manager()->RemoveTaskObserver(&observer);

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));

  EXPECT_CALL(observer, WillProcessTask(_, _)).Times(0);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
  RunLoop().RunUntilIdle();
}

void RemoveObserverTask(SequenceManagerImpl* manager, TaskObserver* observer) {
  manager->RemoveTaskObserver(observer);
}

TEST_P(SequenceManagerTest, TaskObserverRemovingInsideTask) {
  auto queue = CreateTaskQueue();
  MockTaskObserver observer;
  sequence_manager()->SetWorkBatchSize(3);
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&RemoveObserverTask, sequence_manager(), &observer));

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false))
      .Times(1);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, QueueTaskObserverAdding) {
  auto queues = CreateTaskQueues(2);
  MockTaskObserver observer;

  sequence_manager()->SetWorkBatchSize(2);
  queues[0]->AddTaskObserver(&observer);

  std::vector<EnqueueOrder> run_order;
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 1, &run_order));
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 2, &run_order));

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false))
      .Times(1);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, QueueTaskObserverRemoving) {
  auto queue = CreateTaskQueue();
  MockTaskObserver observer;
  sequence_manager()->SetWorkBatchSize(2);
  queue->AddTaskObserver(&observer);
  queue->RemoveTaskObserver(&observer);

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false))
      .Times(0);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(0);

  RunLoop().RunUntilIdle();
}

void RemoveQueueObserverTask(scoped_refptr<TestTaskQueue> queue,
                             TaskObserver* observer) {
  queue->RemoveTaskObserver(observer);
}

TEST_P(SequenceManagerTest, QueueTaskObserverRemovingInsideTask) {
  auto queue = CreateTaskQueue();
  MockTaskObserver observer;
  queue->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&RemoveQueueObserverTask, queue, &observer));

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false))
      .Times(1);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, CancelHandleInsideTaskObserver) {
  class CancelingTaskObserver : public TaskObserver {
   public:
    DelayedTaskHandle handle;
    bool will_run_task_called = false;
    bool did_process_task_called = false;
    explicit CancelingTaskObserver(DelayedTaskHandle handle_in)
        : handle(std::move(handle_in)) {
      EXPECT_TRUE(handle.IsValid());
    }

    ~CancelingTaskObserver() override {
      EXPECT_FALSE(handle.IsValid());
      EXPECT_TRUE(will_run_task_called);
      EXPECT_TRUE(did_process_task_called);
    }

    void DidProcessTask(const PendingTask& task) override {
      did_process_task_called = true;
    }
    void WillProcessTask(const PendingTask& task,
                         bool was_blocked_or_low_priority) override {
      handle.CancelTask();
      will_run_task_called = true;
    }
  };

  auto queue = CreateTaskQueue();

  auto handle = queue->task_runner()->PostCancelableDelayedTask(
      subtle::PostDelayedTaskPassKeyForTesting(), FROM_HERE,
      BindLambdaForTesting([]() { FAIL(); }), base::TimeDelta());

  CancelingTaskObserver observer(std::move(handle));
  queue->AddTaskObserver(&observer);

  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, ThreadCheckAfterTermination) {
  auto queue = CreateTaskQueue();
  EXPECT_TRUE(queue->task_runner()->RunsTasksInCurrentSequence());
  DestroySequenceManager();
  EXPECT_TRUE(queue->task_runner()->RunsTasksInCurrentSequence());
}

TEST_P(SequenceManagerTest, GetNextDelayedWakeUp) {
  auto queues = CreateTaskQueues(2u);
  AdvanceMockTickClock(Microseconds(10000));
  LazyNow lazy_now_1(mock_tick_clock());

  // With no delayed tasks.
  EXPECT_FALSE(sequence_manager()->GetNextDelayedWakeUp());

  // With a non-delayed task.
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_FALSE(sequence_manager()->GetNextDelayedWakeUp());

  // With a delayed task.
  TimeDelta expected_delay = Milliseconds(50);
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            expected_delay);
  EXPECT_EQ(lazy_now_1.Now() + expected_delay,
            sequence_manager()->GetNextDelayedWakeUp()->time);

  // With another delayed task in the same queue with a longer delay.
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(100));
  EXPECT_EQ(lazy_now_1.Now() + expected_delay,
            sequence_manager()->GetNextDelayedWakeUp()->time);

  // With another delayed task in the same queue with a shorter delay.
  expected_delay = Milliseconds(20);
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            expected_delay);
  EXPECT_EQ(lazy_now_1.Now() + expected_delay,
            sequence_manager()->GetNextDelayedWakeUp()->time);

  // With another delayed task in a different queue with a shorter delay.
  expected_delay = Milliseconds(10);
  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            expected_delay);
  EXPECT_EQ(lazy_now_1.Now() + expected_delay,
            sequence_manager()->GetNextDelayedWakeUp()->time);
}

TEST_P(SequenceManagerTest, GetNextDelayedWakeUp_MultipleQueues) {
  auto queues = CreateTaskQueues(3u);

  TimeDelta delay1 = Milliseconds(50);
  TimeDelta delay2 = Milliseconds(5);
  TimeDelta delay3 = Milliseconds(10);
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            delay1);
  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            delay2);
  queues[2]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            delay3);
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(lazy_now.Now() + delay2,
            sequence_manager()->GetNextDelayedWakeUp()->time);
}

TEST(SequenceManagerWithTaskRunnerTest, DeleteSequenceManagerInsideATask) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));

  queue->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   fixture.DestroySequenceManager();
                                 }));

  // This should not crash, assuming DoWork detects the SequenceManager has
  // been deleted.
  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, GetAndClearSystemIsQuiescentBit) {
  auto queues = CreateTaskQueues(3u);

  scoped_refptr<TestTaskQueue> queue0 = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ).SetShouldMonitorQuiescence(true));
  scoped_refptr<TestTaskQueue> queue1 = CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST2_TQ).SetShouldMonitorQuiescence(true));
  scoped_refptr<TestTaskQueue> queue2 = CreateTaskQueue();

  EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit());

  queue0->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->GetAndClearSystemIsQuiescentBit());
  EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit());

  queue1->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->GetAndClearSystemIsQuiescentBit());
  EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit());

  queue2->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit());

  queue0->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queue1->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->GetAndClearSystemIsQuiescentBit());
  EXPECT_TRUE(sequence_manager()->GetAndClearSystemIsQuiescentBit());
}

TEST_P(SequenceManagerTest, HasTaskToRunImmediatelyOrReadyDelayedTask) {
  auto queue = CreateTaskQueue();

  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask));
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  RunLoop().RunUntilIdle();
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest,
       HasTaskToRunImmediatelyOrReadyDelayedTask_DelayedTasks) {
  auto queue = CreateTaskQueue();

  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(NullTask),
                                        Milliseconds(12));
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Move time forwards until just before the delayed task should run.
  AdvanceMockTickClock(Milliseconds(10));
  LazyNow lazy_now_1(mock_tick_clock());
  sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now_1);
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  // Force the delayed task onto the work queue.
  AdvanceMockTickClock(Milliseconds(2));
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  LazyNow lazy_now_2(mock_tick_clock());
  sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now_2);
  EXPECT_TRUE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());

  sequence_manager()->ScheduleWork();
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(queue->HasTaskToRunImmediatelyOrReadyDelayedTask());
}

TEST_P(SequenceManagerTest, ImmediateTasksAreNotStarvedByDelayedTasks) {
  auto queue = CreateTaskQueue();
  std::vector<EnqueueOrder> run_order;
  constexpr auto kDelay = Milliseconds(10);

  // By posting the immediate tasks from a delayed one we make sure that the
  // delayed tasks we post afterwards have a lower enqueue_order than the
  // immediate ones. Thus all the delayed ones would run before the immediate
  // ones if it weren't for the anti-starvation feature we are testing here.
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        for (int i = 0; i < 9; i++) {
          queue->task_runner()->PostTask(FROM_HERE,
                                         BindOnce(&TestTask, i, &run_order));
        }
      }),
      kDelay);

  for (int i = 10; i < 19; i++) {
    queue->task_runner()->PostDelayedTask(
        FROM_HERE, BindOnce(&TestTask, i, &run_order), kDelay);
  }

  FastForwardBy(Milliseconds(10));

  // Delayed tasks are not allowed to starve out immediate work which is why
  // some of the immediate tasks run out of order.
  uint64_t expected_run_order[] = {10, 11, 12, 0, 13, 14, 15, 1, 16,
                                   17, 18, 2,  3, 4,  5,  6,  7, 8};
  EXPECT_THAT(run_order, ElementsAreArray(expected_run_order));
}

TEST_P(SequenceManagerTest,
       DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay = Milliseconds(10);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);

  AdvanceMockTickClock(delay * 2);
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(2u, 3u, 1u));
}

TEST_P(SequenceManagerTest,
       DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) {
  auto queues = CreateTaskQueues(2u);

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay = Milliseconds(10);
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 2, &run_order));
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 3, &run_order));
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay);

  AdvanceMockTickClock(delay * 2);
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(2u, 3u, 1u));
}

TEST_P(SequenceManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
  auto queues = CreateTaskQueues(2u);

  std::vector<EnqueueOrder> run_order;
  TimeDelta delay1 = Milliseconds(10);
  TimeDelta delay2 = Milliseconds(5);
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), delay1);
  queues[1]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), delay2);

  AdvanceMockTickClock(delay1 * 2);
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(2u, 1u));
}

namespace {

void CheckIsNested(bool* is_nested) {
  *is_nested = RunLoop::IsNestedOnCurrentThread();
}

void PostAndQuitFromNestedRunloop(RunLoop* run_loop,
                                  scoped_refptr<TestTaskQueue> runner,
                                  bool* was_nested) {
  runner->task_runner()->PostTask(FROM_HERE, run_loop->QuitClosure());
  runner->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&CheckIsNested, was_nested));
  run_loop->Run();
}

}  // namespace

TEST_P(SequenceManagerTest, QuitWhileNested) {
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  // This test makes sure we don't continue running a work batch after a nested
  // run loop has been exited in the middle of the batch.
  auto queue = CreateTaskQueue();
  sequence_manager()->SetWorkBatchSize(2);

  bool was_nested = true;
  RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed);
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostAndQuitFromNestedRunloop, Unretained(&run_loop),
                          queue, Unretained(&was_nested)));

  RunLoop().RunUntilIdle();
  EXPECT_FALSE(was_nested);
}

namespace {

class SequenceNumberCapturingTaskObserver : public TaskObserver {
 public:
  // TaskObserver overrides.
  void WillProcessTask(const PendingTask& pending_task,
                       bool was_blocked_or_low_priority) override {}
  void DidProcessTask(const PendingTask& pending_task) override {
    sequence_numbers_.push_back(pending_task.sequence_num);
  }

  const std::vector<int>& sequence_numbers() const { return sequence_numbers_; }

 private:
  std::vector<int> sequence_numbers_;
};

}  // namespace

TEST_P(SequenceManagerTest, SequenceNumSetWhenTaskIsPosted) {
  auto queue = CreateTaskQueue();

  SequenceNumberCapturingTaskObserver observer;
  sequence_manager()->AddTaskObserver(&observer);

  // Register four tasks that will run in reverse order.
  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(30));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(20));
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(10));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order));

  FastForwardBy(Milliseconds(40));
  ASSERT_THAT(run_order, ElementsAre(4u, 3u, 2u, 1u));

  // The sequence numbers are a one-based monotonically incrememting counter
  // which should be set when the task is posted rather than when it's enqueued
  // onto the Incoming queue. This counter starts with 2.
  EXPECT_THAT(observer.sequence_numbers(), ElementsAre(5, 4, 3, 2));

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest, NewTaskQueues) {
  auto queue = CreateTaskQueue();

  scoped_refptr<TestTaskQueue> queue1 = CreateTaskQueue();
  scoped_refptr<TestTaskQueue> queue2 = CreateTaskQueue();
  scoped_refptr<TestTaskQueue> queue3 = CreateTaskQueue();

  ASSERT_NE(queue1, queue2);
  ASSERT_NE(queue1, queue3);
  ASSERT_NE(queue2, queue3);

  std::vector<EnqueueOrder> run_order;
  queue1->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 1, &run_order));
  queue2->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 2, &run_order));
  queue3->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 3, &run_order));
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));
}

TEST_P(SequenceManagerTest, ShutdownTaskQueue_TaskRunnersDetaching) {
  scoped_refptr<TestTaskQueue> queue = CreateTaskQueue();

  scoped_refptr<SingleThreadTaskRunner> runner1 = queue->task_runner();
  scoped_refptr<SingleThreadTaskRunner> runner2 = queue->CreateTaskRunner(1);

  std::vector<EnqueueOrder> run_order;
  EXPECT_TRUE(runner1->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)));
  EXPECT_TRUE(runner2->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)));
  queue->ShutdownTaskQueue();
  EXPECT_FALSE(
      runner1->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)));
  EXPECT_FALSE(
      runner2->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre());
}

TEST_P(SequenceManagerTest, ShutdownTaskQueue) {
  auto queue = CreateTaskQueue();

  scoped_refptr<TestTaskQueue> queue1 = CreateTaskQueue();
  scoped_refptr<TestTaskQueue> queue2 = CreateTaskQueue();
  scoped_refptr<TestTaskQueue> queue3 = CreateTaskQueue();

  ASSERT_NE(queue1, queue2);
  ASSERT_NE(queue1, queue3);
  ASSERT_NE(queue2, queue3);

  std::vector<EnqueueOrder> run_order;
  queue1->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 1, &run_order));
  queue2->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 2, &run_order));
  queue3->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&TestTask, 3, &run_order));
  queue2->ShutdownTaskQueue();
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(1u, 3u));
}

TEST_P(SequenceManagerTest, ShutdownTaskQueue_WithDelayedTasks) {
  auto queues = CreateTaskQueues(2u);

  // Register three delayed tasks
  std::vector<EnqueueOrder> run_order;
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(10));
  queues[1]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(20));
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(30));

  queues[1]->ShutdownTaskQueue();
  RunLoop().RunUntilIdle();

  FastForwardBy(Milliseconds(40));
  ASSERT_THAT(run_order, ElementsAre(1u, 3u));
}

namespace {
void ShutdownQueue(scoped_refptr<TestTaskQueue> queue) {
  queue->ShutdownTaskQueue();
}
}  // namespace

TEST_P(SequenceManagerTest, ShutdownTaskQueue_InTasks) {
  auto queues = CreateTaskQueues(3u);

  std::vector<EnqueueOrder> run_order;
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 1, &run_order));
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&ShutdownQueue, queues[1]));
  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&ShutdownQueue, queues[2]));
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 2, &run_order));
  queues[2]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 3, &run_order));

  RunLoop().RunUntilIdle();
  ASSERT_THAT(run_order, ElementsAre(1u));
}

namespace {

class MockObserver : public SequenceManager::Observer {
 public:
  MOCK_METHOD0(OnTriedToExecuteBlockedTask, void());
  MOCK_METHOD0(OnBeginNestedRunLoop, void());
  MOCK_METHOD0(OnExitNestedRunLoop, void());
};

}  // namespace

TEST_P(SequenceManagerTest, ShutdownTaskQueueInNestedLoop) {
  auto queue = CreateTaskQueue();

  // We retain a reference to the task queue even when the manager has deleted
  // its reference.
  scoped_refptr<TestTaskQueue> task_queue = CreateTaskQueue();

  std::vector<bool> log;
  std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop;

  // Inside a nested run loop, call task_queue->ShutdownTaskQueue, bookended
  // by calls to HasOneRefTask to make sure the manager doesn't release its
  // reference until the nested run loop exits.
  // NB: This first HasOneRefTask is a sanity check.
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&NopTask), true));
  tasks_to_post_from_nested_loop.push_back(std::make_pair(
      BindOnce(&TaskQueue::ShutdownTaskQueue, Unretained(task_queue.get())),
      true));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&NopTask), true));
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&PostFromNestedRunloop, queue,
                          Unretained(&tasks_to_post_from_nested_loop)));
  RunLoop().RunUntilIdle();

  // Just make sure that we don't crash.
}

TEST_P(SequenceManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time_ticks = sequence_manager()->NowTicks();
  std::unique_ptr<MockTimeDomain> domain_a =
      std::make_unique<MockTimeDomain>(start_time_ticks);
  std::unique_ptr<MockTimeDomain> domain_b =
      std::make_unique<MockTimeDomain>(start_time_ticks);

  sequence_manager()->SetTimeDomain(domain_a.get());
  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  sequence_manager()->ResetTimeDomain();
  sequence_manager()->SetTimeDomain(domain_b.get());

  RunLoop().RunUntilIdle();
  EXPECT_THAT(run_order, ElementsAre(1u));

  sequence_manager()->ResetTimeDomain();
  queue->ShutdownTaskQueue();
}

// Test that no wake up is scheduled for a delayed task in the future when a
// time domain is present.
TEST_P(SequenceManagerTest, TimeDomainDoesNotCauseWakeUp) {
  auto queue = CreateTaskQueue();

  std::unique_ptr<MockTimeDomain> domain =
      std::make_unique<MockTimeDomain>(sequence_manager()->NowTicks());
  sequence_manager()->SetTimeDomain(domain.get());

  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(10));
  LazyNow lazy_now1(domain.get());
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now1));
  EXPECT_EQ(TimeTicks::Max(), NextPendingTaskTime());

  domain->SetNowTicks(sequence_manager()->NowTicks() + Milliseconds(10));
  LazyNow lazy_now2(domain.get());
  EXPECT_EQ(WakeUp{}, sequence_manager()->GetPendingWakeUp(&lazy_now2));

  sequence_manager()->ResetTimeDomain();
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest,
       PostDelayedTasksReverseOrderAlternatingTimeDomains) {
  auto queue = CreateTaskQueue();

  std::vector<EnqueueOrder> run_order;

  std::unique_ptr<sequence_manager::MockTimeDomain> domain =
      std::make_unique<sequence_manager::MockTimeDomain>(
          mock_tick_clock()->NowTicks());

  sequence_manager()->SetTimeDomain(domain.get());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(400));

  sequence_manager()->ResetTimeDomain();
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(300));

  sequence_manager()->SetTimeDomain(domain.get());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(200));

  sequence_manager()->ResetTimeDomain();
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 4, &run_order), Milliseconds(100));

  FastForwardBy(Milliseconds(400));
  EXPECT_THAT(run_order, ElementsAre(4u, 3u, 2u, 1u));

  sequence_manager()->ResetTimeDomain();
  queue->ShutdownTaskQueue();
}

namespace {

class MockTaskQueueThrottler : public TaskQueue::Throttler {
 public:
  MockTaskQueueThrottler() = default;
  ~MockTaskQueueThrottler() = default;

  MOCK_METHOD1(OnWakeUp, void(LazyNow*));
  MOCK_METHOD0(OnHasImmediateTask, void());
  MOCK_METHOD1(GetNextAllowedWakeUp_DesiredWakeUpTime, void(TimeTicks));

  absl::optional<WakeUp> GetNextAllowedWakeUp(
      LazyNow* lazy_now,
      absl::optional<WakeUp> next_desired_wake_up,
      bool has_immediate_work) override {
    if (next_desired_wake_up)
      GetNextAllowedWakeUp_DesiredWakeUpTime(next_desired_wake_up->time);
    if (next_allowed_wake_up_)
      return next_allowed_wake_up_;
    return next_desired_wake_up;
  }

  void SetNextAllowedWakeUp(absl::optional<WakeUp> next_allowed_wake_up) {
    next_allowed_wake_up_ = next_allowed_wake_up;
  }

 private:
  absl::optional<WakeUp> next_allowed_wake_up_;
};

}  // namespace

TEST_P(SequenceManagerTest, TaskQueueThrottler_ImmediateTask) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  // OnHasImmediateTask should be called when a task is posted on an empty
  // queue.
  EXPECT_CALL(throttler, OnHasImmediateTask());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  sequence_manager()->ReloadEmptyWorkQueues();
  Mock::VerifyAndClearExpectations(&throttler);

  // But not subsequently.
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  sequence_manager()->ReloadEmptyWorkQueues();
  Mock::VerifyAndClearExpectations(&throttler);

  // Unless the immediate work queue is emptied.
  LazyNow lazy_now(mock_tick_clock());
  sequence_manager()->SelectNextTask(lazy_now);
  sequence_manager()->DidRunTask(lazy_now);
  sequence_manager()->SelectNextTask(lazy_now);
  sequence_manager()->DidRunTask(lazy_now);
  EXPECT_CALL(throttler, OnHasImmediateTask());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  sequence_manager()->ReloadEmptyWorkQueues();
  Mock::VerifyAndClearExpectations(&throttler);

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, TaskQueueThrottler_DelayedTask) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay10s(Seconds(10));
  TimeDelta delay100s(Seconds(100));
  TimeDelta delay1s(Seconds(1));

  // GetNextAllowedWakeUp should be called when a delayed task is posted on an
  // empty queue.
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay10s));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        delay10s);
  Mock::VerifyAndClearExpectations(&throttler);

  // GetNextAllowedWakeUp should be given the same delay when a longer delay
  // task is posted.
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay10s));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        delay100s);
  Mock::VerifyAndClearExpectations(&throttler);

  // GetNextAllowedWakeUp should be given the new delay when a task is posted
  // with a shorter delay.
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1s));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s);
  Mock::VerifyAndClearExpectations(&throttler);

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  Mock::VerifyAndClearExpectations(&throttler);

  // When a queue has been enabled, we may get a notification if the
  // TimeDomain's next scheduled wake-up has changed.
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1s));
  voter->SetVoteToEnable(true);
  Mock::VerifyAndClearExpectations(&throttler);

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, TaskQueueThrottler_OnWakeUp) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay(Seconds(1));

  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay);
  Mock::VerifyAndClearExpectations(&throttler);

  AdvanceMockTickClock(delay);

  // OnWakeUp should be called when the queue has a scheduler wake up.
  EXPECT_CALL(throttler, OnWakeUp(_));
  // Move the task into the |delayed_work_queue|.
  LazyNow lazy_now(mock_tick_clock());
  sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now);
  Mock::VerifyAndClearExpectations(&throttler);

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, TaskQueueThrottler_ResetThrottler) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay10s(Seconds(10));
  TimeDelta delay1s(Seconds(1));

  EXPECT_FALSE(queue->GetNextDesiredWakeUp());

  // GetNextAllowedWakeUp should be called when a delayed task is posted on an
  // empty queue.
  throttler.SetNextAllowedWakeUp(
      base::sequence_manager::WakeUp{start_time + delay10s});
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1s));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s);
  Mock::VerifyAndClearExpectations(&throttler);
  // Expect throttled wake up.
  LazyNow lazy_now(mock_tick_clock());
  WakeUp expected_wake_up{start_time + delay10s};
  EXPECT_EQ(expected_wake_up, sequence_manager()->GetPendingWakeUp(&lazy_now));

  queue->ResetThrottler();
  // Next wake up should be back to normal.
  EXPECT_EQ((WakeUp{start_time + delay1s, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, TaskQueueThrottler_DelayedTaskMultipleQueues) {
  StrictMock<MockTaskQueueThrottler> throttler0;
  StrictMock<MockTaskQueueThrottler> throttler1;
  auto queues = CreateTaskQueues(2u);
  queues[0]->SetThrottler(&throttler0);
  queues[1]->SetThrottler(&throttler1);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay1s(Seconds(1));
  TimeDelta delay10s(Seconds(10));

  EXPECT_CALL(throttler0,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1s))
      .Times(1);
  EXPECT_CALL(throttler1,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay10s))
      .Times(1);
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            delay1s);
  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            delay10s);
  testing::Mock::VerifyAndClearExpectations(&throttler0);
  testing::Mock::VerifyAndClearExpectations(&throttler1);

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter0 =
      queues[0]->CreateQueueEnabledVoter();
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter1 =
      queues[1]->CreateQueueEnabledVoter();

  // Disabling a queue should not trigger a notification.
  voter0->SetVoteToEnable(false);
  Mock::VerifyAndClearExpectations(&throttler0);

  // But re-enabling it should should trigger an GetNextAllowedWakeUp
  // notification.
  EXPECT_CALL(throttler0,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1s));
  voter0->SetVoteToEnable(true);
  Mock::VerifyAndClearExpectations(&throttler0);

  // Disabling a queue should not trigger a notification.
  voter1->SetVoteToEnable(false);
  Mock::VerifyAndClearExpectations(&throttler0);

  // But re-enabling it should should trigger a notification.
  EXPECT_CALL(throttler1,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay10s));
  voter1->SetVoteToEnable(true);
  Mock::VerifyAndClearExpectations(&throttler1);

  // Tidy up.
  queues[0]->ShutdownTaskQueue();
  queues[1]->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, TaskQueueThrottler_DelayedWorkWhichCanRunNow) {
  // This test checks that when delayed work becomes available the notification
  // still fires. This usually happens when time advances and task becomes
  // available in the middle of the scheduling code. For this test we force
  // notification dispatching by calling UpdateWakeUp() explicitly.

  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeDelta delay1s(Seconds(1));

  // GetNextAllowedWakeUp should be called when a delayed task is posted on an
  // empty queue.
  EXPECT_CALL(throttler, GetNextAllowedWakeUp_DesiredWakeUpTime(_));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s);
  Mock::VerifyAndClearExpectations(&throttler);

  AdvanceMockTickClock(Seconds(10));

  EXPECT_CALL(throttler, GetNextAllowedWakeUp_DesiredWakeUpTime(_));
  LazyNow lazy_now(mock_tick_clock());
  queue->UpdateWakeUp(&lazy_now);
  Mock::VerifyAndClearExpectations(&throttler);

  // Tidy up.
  queue->ShutdownTaskQueue();
}

namespace {

class CancelableTask {
 public:
  explicit CancelableTask(const TickClock* clock) : clock_(clock) {}

  void RecordTimeTask(std::vector<TimeTicks>* run_times) {
    run_times->push_back(clock_->NowTicks());
  }

  template <typename... Args>
  void FailTask(Args...) {
    FAIL();
  }

  raw_ptr<const TickClock> clock_;
  WeakPtrFactory<CancelableTask> weak_factory_{this};
};

class DestructionCallback {
 public:
  explicit DestructionCallback(OnceCallback<void()> on_destroy)
      : on_destroy_(std::move(on_destroy)) {}
  ~DestructionCallback() {
    if (on_destroy_)
      std::move(on_destroy_).Run();
  }
  DestructionCallback(const DestructionCallback&) = delete;
  DestructionCallback& operator=(const DestructionCallback&) = delete;
  DestructionCallback(DestructionCallback&&) = default;

 private:
  OnceCallback<void()> on_destroy_;
};

}  // namespace

TEST_P(SequenceManagerTest, TaskQueueThrottler_SweepCanceledDelayedTasks) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay1(Seconds(5));
  TimeDelta delay2(Seconds(10));

  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay1))
      .Times(2);

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task1.weak_factory_.GetWeakPtr(), &run_times),
      delay1);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task2.weak_factory_.GetWeakPtr(), &run_times),
      delay2);

  task1.weak_factory_.InvalidateWeakPtrs();

  // Sweeping away canceled delayed tasks should trigger a notification.
  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay2))
      .Times(1);
  sequence_manager()->ReclaimMemory();
}

TEST_P(SequenceManagerTest, SweepLastTaskInQueue) {
  auto queue = CreateTaskQueue();
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::FailTask<>, task.weak_factory_.GetWeakPtr()),
      base::Seconds(1));

  // Make sure sweeping away the last task in the queue doesn't end up accessing
  // invalid iterators.
  task.weak_factory_.InvalidateWeakPtrs();
  sequence_manager()->ReclaimMemory();
}

TEST_P(SequenceManagerTest, CancelledTaskPostAnother_ReclaimMemory) {
  // This check ensures that a task whose destruction causes another task to be
  // posted as a side-effect doesn't cause us to access invalid iterators while
  // sweeping away cancelled tasks.
  auto queue = CreateTaskQueue();
  bool did_destroy = false;
  auto on_destroy = BindLambdaForTesting([&] {
    queue->task_runner()->PostDelayedTask(
        FROM_HERE, BindLambdaForTesting([] {}), base::Seconds(1));
    did_destroy = true;
  });

  DestructionCallback destruction_observer(std::move(on_destroy));
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::FailTask<DestructionCallback>,
               task.weak_factory_.GetWeakPtr(),
               std::move(destruction_observer)),
      base::Seconds(1));

  task.weak_factory_.InvalidateWeakPtrs();
  EXPECT_FALSE(did_destroy);
  sequence_manager()->ReclaimMemory();
  EXPECT_TRUE(did_destroy);
}

// Regression test to ensure that posting a new task from the destructor of a
// canceled task doesn't crash.
TEST_P(SequenceManagerTest,
       CancelledTaskPostAnother_MoveReadyDelayedTasksToWorkQueues) {
  // This check ensures that a task whose destruction causes another task to be
  // posted as a side-effect doesn't cause us to access invalid iterators while
  // sweeping away cancelled tasks.
  auto queue = CreateTaskQueue();
  bool did_destroy = false;
  auto on_destroy = BindLambdaForTesting([&] {
    queue->task_runner()->PostDelayedTask(
        FROM_HERE, BindLambdaForTesting([] {}), base::Seconds(1));
    did_destroy = true;
  });

  DestructionCallback destruction_observer(std::move(on_destroy));
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::FailTask<DestructionCallback>,
               task.weak_factory_.GetWeakPtr(),
               std::move(destruction_observer)),
      base::Seconds(1));

  AdvanceMockTickClock(base::Seconds(1));

  task.weak_factory_.InvalidateWeakPtrs();
  EXPECT_FALSE(did_destroy);
  LazyNow lazy_now(mock_tick_clock());
  sequence_manager()->MoveReadyDelayedTasksToWorkQueues(&lazy_now);
  EXPECT_TRUE(did_destroy);
}

TEST_P(SequenceManagerTest,
       CancelledTaskPostAnother_RemoveAllCanceledDelayedTasksFromFront) {
  ScopedNoWakeUpsForCanceledTasks scoped_no_wake_ups_for_canceled_tasks;

  // This check ensures that a task whose destruction causes another task to be
  // posted as a side-effect doesn't cause us to access invalid iterators while
  // removing canceled tasks from the front of the queues.
  auto queue = CreateTaskQueue();
  bool did_destroy = false;
  auto on_destroy = BindLambdaForTesting([&] {
    queue->task_runner()->PostDelayedTask(
        FROM_HERE, BindLambdaForTesting([] {}), base::Seconds(1));
    did_destroy = true;
  });

  DestructionCallback destruction_observer(std::move(on_destroy));
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::FailTask<DestructionCallback>,
               task.weak_factory_.GetWeakPtr(),
               std::move(destruction_observer)),
      base::Seconds(1));

  task.weak_factory_.InvalidateWeakPtrs();
  EXPECT_FALSE(did_destroy);
  LazyNow lazy_now(mock_tick_clock());
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);
  EXPECT_TRUE(did_destroy);
}

TEST_P(SequenceManagerTest, CancelledImmediateTaskShutsDownQueue) {
  // This check ensures that an immediate task whose destruction causes the
  // owning task queue to be shut down doesn't cause us to access freed memory.
  auto queue = CreateTaskQueue();
  bool did_shutdown = false;
  auto on_destroy = BindLambdaForTesting([&] {
    queue->ShutdownTaskQueue();
    did_shutdown = true;
  });

  DestructionCallback destruction_observer(std::move(on_destroy));
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostTask(
      FROM_HERE, BindOnce(&CancelableTask::FailTask<DestructionCallback>,
                          task.weak_factory_.GetWeakPtr(),
                          std::move(destruction_observer)));

  task.weak_factory_.InvalidateWeakPtrs();
  EXPECT_FALSE(did_shutdown);
  RunLoop().RunUntilIdle();
  EXPECT_TRUE(did_shutdown);
}

TEST_P(SequenceManagerTest, CancelledDelayedTaskShutsDownQueue) {
  // This check ensures that a delayed task whose destruction causes the owning
  // task queue to be shut down doesn't cause us to access freed memory.
  auto queue = CreateTaskQueue();
  bool did_shutdown = false;
  auto on_destroy = BindLambdaForTesting([&] {
    queue->ShutdownTaskQueue();
    did_shutdown = true;
  });

  DestructionCallback destruction_observer(std::move(on_destroy));
  CancelableTask task(mock_tick_clock());
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::FailTask<DestructionCallback>,
               task.weak_factory_.GetWeakPtr(),
               std::move(destruction_observer)),
      base::Seconds(1));

  task.weak_factory_.InvalidateWeakPtrs();
  EXPECT_FALSE(did_shutdown);
  sequence_manager()->ReclaimMemory();
  EXPECT_TRUE(did_shutdown);
}

namespace {

void ChromiumRunloopInspectionTask(
    scoped_refptr<TestMockTimeTaskRunner> test_task_runner) {
  // We don't expect more than 1 pending task at any time.
  EXPECT_GE(1u, test_task_runner->GetPendingTaskCount());
}

}  // namespace

TEST(SequenceManagerTestWithMockTaskRunner,
     NumberOfPendingTasksOnChromiumRunLoop) {
  FixtureWithMockTaskRunner fixture;
  auto queue = fixture.sequence_manager()->CreateTaskQueue(
      TaskQueue::Spec(QueueName::TEST_TQ));

  // NOTE because tasks posted to the chromiumrun loop are not cancellable, we
  // will end up with a lot more tasks posted if the delayed tasks were posted
  // in the reverse order.
  // TODO(alexclarke): Consider talking to the message pump directly.
  for (int i = 1; i < 100; i++) {
    queue->task_runner()->PostDelayedTask(
        FROM_HERE,
        BindOnce(&ChromiumRunloopInspectionTask, fixture.test_task_runner()),
        Milliseconds(i));
  }
  fixture.FastForwardUntilNoTasksRemain();
}

namespace {

class QuadraticTask {
 public:
  QuadraticTask(scoped_refptr<TaskRunner> task_runner,
                TimeDelta delay,
                Fixture* fixture)
      : count_(0),
        task_runner_(task_runner),
        delay_(delay),
        fixture_(fixture) {}

  void SetShouldExit(RepeatingCallback<bool()> should_exit) {
    should_exit_ = should_exit;
  }

  void Run() {
    if (should_exit_.Run())
      return;
    count_++;
    task_runner_->PostDelayedTask(
        FROM_HERE, BindOnce(&QuadraticTask::Run, Unretained(this)), delay_);
    task_runner_->PostDelayedTask(
        FROM_HERE, BindOnce(&QuadraticTask::Run, Unretained(this)), delay_);
    fixture_->AdvanceMockTickClock(Milliseconds(5));
  }

  int Count() const { return count_; }

 private:
  int count_;
  scoped_refptr<TaskRunner> task_runner_;
  TimeDelta delay_;
  raw_ptr<Fixture> fixture_;
  RepeatingCallback<bool()> should_exit_;
};

class LinearTask {
 public:
  LinearTask(scoped_refptr<TaskRunner> task_runner,
             TimeDelta delay,
             Fixture* fixture)
      : count_(0),
        task_runner_(task_runner),
        delay_(delay),
        fixture_(fixture) {}

  void SetShouldExit(RepeatingCallback<bool()> should_exit) {
    should_exit_ = should_exit;
  }

  void Run() {
    if (should_exit_.Run())
      return;
    count_++;
    task_runner_->PostDelayedTask(
        FROM_HERE, BindOnce(&LinearTask::Run, Unretained(this)), delay_);
    fixture_->AdvanceMockTickClock(Milliseconds(5));
  }

  int Count() const { return count_; }

 private:
  int count_;
  scoped_refptr<TaskRunner> task_runner_;
  TimeDelta delay_;
  raw_ptr<Fixture> fixture_;
  RepeatingCallback<bool()> should_exit_;
};

bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) {
  return quadratic_task->Count() == 1000 || linear_task->Count() == 1000;
}

}  // namespace

TEST_P(SequenceManagerTest,
       DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) {
  auto queue = CreateTaskQueue();

  QuadraticTask quadratic_delayed_task(queue->task_runner(), Milliseconds(10),
                                       this);
  LinearTask linear_immediate_task(queue->task_runner(), TimeDelta(), this);
  RepeatingCallback<bool()> should_exit = BindRepeating(
      ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
  quadratic_delayed_task.SetShouldExit(should_exit);
  linear_immediate_task.SetShouldExit(should_exit);

  quadratic_delayed_task.Run();
  linear_immediate_task.Run();

  FastForwardUntilNoTasksRemain();

  double ratio = static_cast<double>(linear_immediate_task.Count()) /
                 static_cast<double>(quadratic_delayed_task.Count());

  EXPECT_GT(ratio, 0.333);
  EXPECT_LT(ratio, 1.1);
}

TEST_P(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
  auto queue = CreateTaskQueue();

  QuadraticTask quadratic_immediate_task(queue->task_runner(), TimeDelta(),
                                         this);
  LinearTask linear_delayed_task(queue->task_runner(), Milliseconds(10), this);
  RepeatingCallback<bool()> should_exit = BindRepeating(
      &ShouldExit, &quadratic_immediate_task, &linear_delayed_task);

  quadratic_immediate_task.SetShouldExit(should_exit);
  linear_delayed_task.SetShouldExit(should_exit);

  quadratic_immediate_task.Run();
  linear_delayed_task.Run();

  FastForwardUntilNoTasksRemain();

  double ratio = static_cast<double>(linear_delayed_task.Count()) /
                 static_cast<double>(quadratic_immediate_task.Count());

  // This is by design, we want to enforce a strict ordering in task execution
  // where by delayed tasks can not skip ahead of non-delayed work.
  EXPECT_GT(ratio, 0.0);
  EXPECT_LT(ratio, 0.1);
}

TEST_P(SequenceManagerTest,
       DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) {
  auto queues = CreateTaskQueues(2u);

  QuadraticTask quadratic_delayed_task(queues[0]->task_runner(),
                                       Milliseconds(10), this);
  LinearTask linear_immediate_task(queues[1]->task_runner(), TimeDelta(), this);
  RepeatingCallback<bool()> should_exit = BindRepeating(
      ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
  quadratic_delayed_task.SetShouldExit(should_exit);
  linear_immediate_task.SetShouldExit(should_exit);

  quadratic_delayed_task.Run();
  linear_immediate_task.Run();

  FastForwardUntilNoTasksRemain();

  double ratio = static_cast<double>(linear_immediate_task.Count()) /
                 static_cast<double>(quadratic_delayed_task.Count());

  EXPECT_GT(ratio, 0.333);
  EXPECT_LT(ratio, 1.1);
}

TEST_P(SequenceManagerTest, ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
  auto queues = CreateTaskQueues(2u);

  QuadraticTask quadratic_immediate_task(queues[0]->task_runner(), TimeDelta(),
                                         this);
  LinearTask linear_delayed_task(queues[1]->task_runner(), Milliseconds(10),
                                 this);
  RepeatingCallback<bool()> should_exit = BindRepeating(
      &ShouldExit, &quadratic_immediate_task, &linear_delayed_task);

  quadratic_immediate_task.SetShouldExit(should_exit);
  linear_delayed_task.SetShouldExit(should_exit);

  quadratic_immediate_task.Run();
  linear_delayed_task.Run();

  FastForwardUntilNoTasksRemain();

  double ratio = static_cast<double>(linear_delayed_task.Count()) /
                 static_cast<double>(quadratic_immediate_task.Count());

  // This is by design, we want to enforce a strict ordering in task execution
  // where by delayed tasks can not skip ahead of non-delayed work.
  EXPECT_GT(ratio, 0.0);
  EXPECT_LT(ratio, 0.1);
}

TEST_P(SequenceManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) {
  auto queue = CreateTaskQueue();

  EXPECT_EQ(nullptr, sequence_manager()->currently_executing_task_queue());
}

namespace {
void CurrentlyExecutingTaskQueueTestTask(
    SequenceManagerImpl* sequence_manager,
    std::vector<internal::TaskQueueImpl*>* task_sources) {
  task_sources->push_back(sequence_manager->currently_executing_task_queue());
}
}  // namespace

TEST_P(SequenceManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) {
  auto queues = CreateTaskQueues(2u);

  TestTaskQueue* queue0 = queues[0].get();
  TestTaskQueue* queue1 = queues[1].get();

  std::vector<internal::TaskQueueImpl*> task_sources;
  queue0->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&CurrentlyExecutingTaskQueueTestTask,
                                           sequence_manager(), &task_sources));
  queue1->task_runner()->PostTask(FROM_HERE,
                                  BindOnce(&CurrentlyExecutingTaskQueueTestTask,
                                           sequence_manager(), &task_sources));
  RunLoop().RunUntilIdle();

  EXPECT_THAT(task_sources, ElementsAre(queue0->GetTaskQueueImpl(),
                                        queue1->GetTaskQueueImpl()));
  EXPECT_EQ(nullptr, sequence_manager()->currently_executing_task_queue());
}

namespace {
void RunloopCurrentlyExecutingTaskQueueTestTask(
    SequenceManagerImpl* sequence_manager,
    std::vector<internal::TaskQueueImpl*>* task_sources,
    std::vector<std::pair<OnceClosure, TestTaskQueue*>>* tasks) {
  task_sources->push_back(sequence_manager->currently_executing_task_queue());

  for (std::pair<OnceClosure, TestTaskQueue*>& pair : *tasks) {
    pair.second->task_runner()->PostTask(FROM_HERE, std::move(pair.first));
  }

  RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
  task_sources->push_back(sequence_manager->currently_executing_task_queue());
}
}  // namespace

TEST_P(SequenceManagerTest, CurrentlyExecutingTaskQueue_NestedLoop) {
  auto queues = CreateTaskQueues(3u);

  TestTaskQueue* queue0 = queues[0].get();
  TestTaskQueue* queue1 = queues[1].get();
  TestTaskQueue* queue2 = queues[2].get();

  std::vector<internal::TaskQueueImpl*> task_sources;
  std::vector<std::pair<OnceClosure, TestTaskQueue*>>
      tasks_to_post_from_nested_loop;
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&CurrentlyExecutingTaskQueueTestTask,
                              sequence_manager(), &task_sources),
                     queue1));
  tasks_to_post_from_nested_loop.push_back(
      std::make_pair(BindOnce(&CurrentlyExecutingTaskQueueTestTask,
                              sequence_manager(), &task_sources),
                     queue2));

  queue0->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&RunloopCurrentlyExecutingTaskQueueTestTask, sequence_manager(),
               &task_sources, &tasks_to_post_from_nested_loop));

  RunLoop().RunUntilIdle();
  EXPECT_THAT(task_sources, UnorderedElementsAre(queue0->GetTaskQueueImpl(),
                                                 queue1->GetTaskQueueImpl(),
                                                 queue2->GetTaskQueueImpl(),
                                                 queue0->GetTaskQueueImpl()));
  EXPECT_EQ(nullptr, sequence_manager()->currently_executing_task_queue());
}

TEST_P(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasks) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time = sequence_manager()->NowTicks();

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  CancelableTask task3(mock_tick_clock());
  CancelableTask task4(mock_tick_clock());
  TimeDelta delay1(Seconds(5));
  TimeDelta delay2(Seconds(10));
  TimeDelta delay3(Seconds(15));
  TimeDelta delay4(Seconds(30));
  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task1.weak_factory_.GetWeakPtr(), &run_times),
      delay1);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task2.weak_factory_.GetWeakPtr(), &run_times),
      delay2);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task3.weak_factory_.GetWeakPtr(), &run_times),
      delay3);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task4.weak_factory_.GetWeakPtr(), &run_times),
      delay4);

  task2.weak_factory_.InvalidateWeakPtrs();
  task3.weak_factory_.InvalidateWeakPtrs();

  std::set<TimeTicks> wake_up_times;

  RunUntilManagerIsIdle(BindRepeating(
      [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) {
        wake_up_times->insert(clock->NowTicks());
      },
      &wake_up_times, mock_tick_clock()));

  EXPECT_THAT(wake_up_times,
              ElementsAre(start_time + delay1, start_time + delay4));
  EXPECT_THAT(run_times, ElementsAre(start_time + delay1, start_time + delay4));
}

TEST_P(SequenceManagerTest, NoWakeUpsForCanceledDelayedTasksReversePostOrder) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time = sequence_manager()->NowTicks();

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  CancelableTask task3(mock_tick_clock());
  CancelableTask task4(mock_tick_clock());
  TimeDelta delay1(Seconds(5));
  TimeDelta delay2(Seconds(10));
  TimeDelta delay3(Seconds(15));
  TimeDelta delay4(Seconds(30));
  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task4.weak_factory_.GetWeakPtr(), &run_times),
      delay4);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task3.weak_factory_.GetWeakPtr(), &run_times),
      delay3);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task2.weak_factory_.GetWeakPtr(), &run_times),
      delay2);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task1.weak_factory_.GetWeakPtr(), &run_times),
      delay1);

  task2.weak_factory_.InvalidateWeakPtrs();
  task3.weak_factory_.InvalidateWeakPtrs();

  std::set<TimeTicks> wake_up_times;

  RunUntilManagerIsIdle(BindRepeating(
      [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) {
        wake_up_times->insert(clock->NowTicks());
      },
      &wake_up_times, mock_tick_clock()));

  EXPECT_THAT(wake_up_times,
              ElementsAre(start_time + delay1, start_time + delay4));
  EXPECT_THAT(run_times, ElementsAre(start_time + delay1, start_time + delay4));
}

TEST_P(SequenceManagerTest, TimeDomainWakeUpOnlyCancelledIfAllUsesCancelled) {
  auto queue = CreateTaskQueue();

  TimeTicks start_time = sequence_manager()->NowTicks();

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  CancelableTask task3(mock_tick_clock());
  CancelableTask task4(mock_tick_clock());
  TimeDelta delay1(Seconds(5));
  TimeDelta delay2(Seconds(10));
  TimeDelta delay3(Seconds(15));
  TimeDelta delay4(Seconds(30));
  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task1.weak_factory_.GetWeakPtr(), &run_times),
      delay1);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task2.weak_factory_.GetWeakPtr(), &run_times),
      delay2);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task3.weak_factory_.GetWeakPtr(), &run_times),
      delay3);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task4.weak_factory_.GetWeakPtr(), &run_times),
      delay4);

  // Post a non-canceled task with |delay3|. So we should still get a wake-up at
  // |delay3| even though we cancel |task3|.
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask, Unretained(&task3), &run_times),
      delay3);

  task2.weak_factory_.InvalidateWeakPtrs();
  task3.weak_factory_.InvalidateWeakPtrs();
  task1.weak_factory_.InvalidateWeakPtrs();

  std::set<TimeTicks> wake_up_times;

  RunUntilManagerIsIdle(BindRepeating(
      [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) {
        wake_up_times->insert(clock->NowTicks());
      },
      &wake_up_times, mock_tick_clock()));

  EXPECT_THAT(wake_up_times,
              ElementsAre(start_time + delay1, start_time + delay3,
                          start_time + delay4));

  EXPECT_THAT(run_times, ElementsAre(start_time + delay3, start_time + delay4));
}

TEST_P(SequenceManagerTest, SweepCanceledDelayedTasks) {
  auto queue = CreateTaskQueue();

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  CancelableTask task3(mock_tick_clock());
  CancelableTask task4(mock_tick_clock());
  TimeDelta delay1(Seconds(5));
  TimeDelta delay2(Seconds(10));
  TimeDelta delay3(Seconds(15));
  TimeDelta delay4(Seconds(30));
  std::vector<TimeTicks> run_times;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task1.weak_factory_.GetWeakPtr(), &run_times),
      delay1);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task2.weak_factory_.GetWeakPtr(), &run_times),
      delay2);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task3.weak_factory_.GetWeakPtr(), &run_times),
      delay3);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTask::RecordTimeTask,
               task4.weak_factory_.GetWeakPtr(), &run_times),
      delay4);

  EXPECT_EQ(4u, queue->GetNumberOfPendingTasks());
  task2.weak_factory_.InvalidateWeakPtrs();
  task3.weak_factory_.InvalidateWeakPtrs();
  EXPECT_EQ(4u, queue->GetNumberOfPendingTasks());

  sequence_manager()->ReclaimMemory();
  EXPECT_EQ(2u, queue->GetNumberOfPendingTasks());

  task1.weak_factory_.InvalidateWeakPtrs();
  task4.weak_factory_.InvalidateWeakPtrs();

  sequence_manager()->ReclaimMemory();
  EXPECT_EQ(0u, queue->GetNumberOfPendingTasks());
}

TEST_P(SequenceManagerTest, SweepCanceledDelayedTasks_ManyTasks) {
  auto queue = CreateTaskQueue();

  constexpr const int kNumTasks = 100;

  std::vector<std::unique_ptr<CancelableTask>> tasks(100);
  std::vector<TimeTicks> run_times;
  for (int i = 0; i < kNumTasks; i++) {
    tasks[i] = std::make_unique<CancelableTask>(mock_tick_clock());
    queue->task_runner()->PostDelayedTask(
        FROM_HERE,
        BindOnce(&CancelableTask::RecordTimeTask,
                 tasks[i]->weak_factory_.GetWeakPtr(), &run_times),
        Seconds(i + 1));
  }

  // Invalidate ever other timer.
  for (int i = 0; i < kNumTasks; i++) {
    if (i % 2)
      tasks[i]->weak_factory_.InvalidateWeakPtrs();
  }

  sequence_manager()->ReclaimMemory();
  EXPECT_EQ(50u, queue->GetNumberOfPendingTasks());

  // Make sure the priority queue still operates as expected.
  FastForwardUntilNoTasksRemain();
  ASSERT_EQ(50u, run_times.size());
  for (int i = 0; i < 50; i++) {
    TimeTicks expected_run_time = FromStartAligned(Seconds(2 * i + 1));
    EXPECT_EQ(run_times[i], expected_run_time);
  }
}

TEST_P(SequenceManagerTest, DelayedTasksNotSelected) {
  auto queue = CreateTaskQueue();
  constexpr TimeDelta kDelay(Milliseconds(10));
  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), kDelay);

  // No task should be ready to execute.
  EXPECT_FALSE(sequence_manager()->SelectNextTask(
      lazy_now, SequencedTaskSource::SelectTaskOption::kDefault));
  EXPECT_FALSE(sequence_manager()->SelectNextTask(
      lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  AdvanceMockTickClock(kDelay);
  LazyNow lazy_now2(mock_tick_clock());

  // Delayed task is ready to be executed. Consider it only if not in power
  // suspend state.
  EXPECT_FALSE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Execute the delayed task.
  EXPECT_TRUE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kDefault));
  sequence_manager()->DidRunTask(lazy_now2);
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, DelayedTasksNotSelectedWithImmediateTask) {
  auto queue = CreateTaskQueue();
  constexpr TimeDelta kDelay(Milliseconds(10));
  LazyNow lazy_now(mock_tick_clock());

  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Post an immediate task.
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), kDelay);

  EXPECT_EQ(WakeUp{}, sequence_manager()->GetPendingWakeUp(&lazy_now));
  EXPECT_EQ(
      WakeUp{},
      sequence_manager()->GetPendingWakeUp(
          &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  AdvanceMockTickClock(kDelay);
  LazyNow lazy_now2(mock_tick_clock());

  // An immediate task is present, even if we skip the delayed tasks.
  EXPECT_EQ(
      WakeUp{},
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Immediate task should be ready to execute, execute it.
  EXPECT_TRUE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  sequence_manager()->DidRunTask(lazy_now);

  // Delayed task is ready to be executed. Consider it only if not in power
  // suspend state. This test differs from
  // SequenceManagerTest.DelayedTasksNotSelected as it confirms that delayed
  // tasks are ignored even if they're already in the ready queue (per having
  // performed task selection already before running the immediate task above).
  EXPECT_FALSE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Execute the delayed task.
  EXPECT_TRUE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kDefault));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  sequence_manager()->DidRunTask(lazy_now2);

  // Tidy up.
  queue->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest,
       DelayedTasksNotSelectedWithImmediateTaskWithPriority) {
  auto queues = CreateTaskQueues(4u);
  queues[0]->SetQueuePriority(TestQueuePriority::kLowPriority);
  queues[1]->SetQueuePriority(TestQueuePriority::kNormalPriority);
  queues[2]->SetQueuePriority(TestQueuePriority::kHighPriority);
  queues[3]->SetQueuePriority(TestQueuePriority::kVeryHighPriority);

  // Post immediate tasks.
  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  // Post delayed tasks.
  constexpr TimeDelta kDelay(Milliseconds(10));
  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            kDelay);
  queues[3]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            kDelay);

  LazyNow lazy_now(mock_tick_clock());

  EXPECT_EQ(
      WakeUp{},
      sequence_manager()->GetPendingWakeUp(
          &lazy_now, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  AdvanceMockTickClock(kDelay);
  LazyNow lazy_now2(mock_tick_clock());

  EXPECT_EQ(
      WakeUp{},
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Immediate tasks should be ready to execute, execute them.
  EXPECT_TRUE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  sequence_manager()->DidRunTask(lazy_now2);
  EXPECT_TRUE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  sequence_manager()->DidRunTask(lazy_now2);

  // No immediate tasks can be executed anymore.
  EXPECT_FALSE(sequence_manager()->SelectNextTask(
      lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));
  EXPECT_EQ(
      absl::nullopt,
      sequence_manager()->GetPendingWakeUp(
          &lazy_now2, SequencedTaskSource::SelectTaskOption::kSkipDelayedTask));

  // Execute delayed tasks.
  EXPECT_TRUE(sequence_manager()->SelectNextTask(lazy_now2));
  sequence_manager()->DidRunTask(lazy_now2);
  EXPECT_TRUE(sequence_manager()->SelectNextTask(lazy_now2));
  sequence_manager()->DidRunTask(lazy_now2);

  // No delayed tasks can be executed anymore.
  EXPECT_FALSE(sequence_manager()->SelectNextTask(lazy_now2));
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now2));

  // Tidy up.
  queues[0]->ShutdownTaskQueue();
  queues[1]->ShutdownTaskQueue();
  queues[2]->ShutdownTaskQueue();
  queues[3]->ShutdownTaskQueue();
}

TEST_P(SequenceManagerTest, GetPendingWakeUp) {
  auto queues = CreateTaskQueues(2u);

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));

  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Seconds(10));

  EXPECT_EQ((WakeUp{lazy_now.Now() + Seconds(10), kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Seconds(15));

  EXPECT_EQ((WakeUp{lazy_now.Now() + Seconds(10), kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Seconds(5));

  EXPECT_EQ((WakeUp{lazy_now.Now() + Seconds(5), kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  EXPECT_EQ(WakeUp{}, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest, GetPendingWakeUp_Disabled) {
  auto queue = CreateTaskQueue();

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest, GetPendingWakeUp_Fence) {
  auto queue = CreateTaskQueue();

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest, GetPendingWakeUp_FenceUnblocking) {
  auto queue = CreateTaskQueue();

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(WakeUp{}, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest, GetPendingWakeUp_DelayedTaskReady) {
  auto queue = CreateTaskQueue();

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Seconds(1));

  AdvanceMockTickClock(Seconds(10));

  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ(WakeUp{}, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest, RemoveAllCanceledDelayedTasksFromFront) {
  ScopedNoWakeUpsForCanceledTasks scoped_no_wake_ups_for_canceled_tasks;

  auto queue = CreateTaskQueue();

  // Posts a cancelable task.
  CancelableOnceClosure cancelable_closure(base::BindOnce(&NopTask));
  constexpr TimeDelta kDelay = Seconds(1);
  queue->task_runner()->PostDelayedTask(FROM_HERE,
                                        cancelable_closure.callback(), kDelay);

  // Ensure it is picked to calculate the next task time.
  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Canceling the task is not sufficient to ensure it is not considered for the
  // next task time.
  cancelable_closure.Cancel();
  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Removing the canceled task means it can't be considered for the next task
  // time.
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

TEST_P(SequenceManagerTest,
       RemoveAllCanceledDelayedTasksFromFront_MultipleQueues) {
  ScopedNoWakeUpsForCanceledTasks scoped_no_wake_ups_for_canceled_tasks;

  auto queues = CreateTaskQueues(2u);

  // Post a task in each queue such that they would be executed in order
  // according to their delay.
  CancelableOnceClosure cancelable_closure_1(base::BindOnce(&NopTask));
  constexpr TimeDelta kDelay1 = Seconds(1);
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, cancelable_closure_1.callback(), kDelay1);

  CancelableOnceClosure cancelable_closure_2(base::BindOnce(&NopTask));
  constexpr TimeDelta kDelay2 = Seconds(2);
  queues[1]->task_runner()->PostDelayedTask(
      FROM_HERE, cancelable_closure_2.callback(), kDelay2);

  // The task from the first queue is picked to calculate the next task time.
  LazyNow lazy_now(mock_tick_clock());
  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay1, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Test that calling RemoveAllCanceledDelayedTasksFromFront() works (and does
  // nothing) when no task is canceled.
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);
  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay1, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Canceling the first task which comes from the first queue.
  cancelable_closure_1.Cancel();
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);

  // Now the only task remaining is the one from the second queue.
  EXPECT_EQ((WakeUp{lazy_now.Now() + kDelay2, kLeeway}),
            sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Cancel the remaining task.
  cancelable_closure_2.Cancel();
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);

  // No more valid tasks in any queues.
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));

  // Test that calling RemoveAllCanceledDelayedTasksFromFront() works (and does
  // nothing) when all queues are empty.
  sequence_manager()->RemoveAllCanceledDelayedTasksFromFront(&lazy_now);
  EXPECT_EQ(absl::nullopt, sequence_manager()->GetPendingWakeUp(&lazy_now));
}

namespace {
void MessageLoopTaskWithDelayedQuit(Fixture* fixture,
                                    scoped_refptr<TestTaskQueue> task_queue) {
  RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed);
  task_queue->task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
                                             Milliseconds(100));
  fixture->AdvanceMockTickClock(Milliseconds(200));
  run_loop.Run();
}
}  // namespace

TEST_P(SequenceManagerTest, DelayedTaskRunsInNestedMessageLoop) {
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  auto queue = CreateTaskQueue();
  RunLoop run_loop;
  queue->task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&MessageLoopTaskWithDelayedQuit, this, RetainedRef(queue)));
  run_loop.RunUntilIdle();
}

namespace {
void MessageLoopTaskWithImmediateQuit(OnceClosure non_nested_quit_closure,
                                      scoped_refptr<TestTaskQueue> task_queue) {
  RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed);
  // Needed because entering the nested run loop causes a DoWork to get
  // posted.
  task_queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  task_queue->task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
  run_loop.Run();
  std::move(non_nested_quit_closure).Run();
}
}  // namespace

TEST_P(SequenceManagerTest, DelayedNestedMessageLoopDoesntPreventTasksRunning) {
  if (GetUnderlyingRunnerType() == RunnerType::kMockTaskRunner)
    return;
  auto queue = CreateTaskQueue();
  RunLoop run_loop;
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&MessageLoopTaskWithImmediateQuit, run_loop.QuitClosure(),
               RetainedRef(queue)),
      Milliseconds(100));

  AdvanceMockTickClock(Milliseconds(200));
  run_loop.Run();
}

TEST_P(SequenceManagerTest, CouldTaskRun_DisableAndReenable) {
  auto queue = CreateTaskQueue();

  EnqueueOrder enqueue_order = sequence_manager()->GetNextSequenceNumber();
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  EXPECT_FALSE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  voter->SetVoteToEnable(true);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
}

TEST_P(SequenceManagerTest, CouldTaskRun_Fence) {
  auto queue = CreateTaskQueue();

  EnqueueOrder enqueue_order = sequence_manager()->GetNextSequenceNumber();
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  queue->InsertFence(TaskQueue::InsertFencePosition::kBeginningOfTime);
  EXPECT_FALSE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  queue->RemoveFence();
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
}

TEST_P(SequenceManagerTest, CouldTaskRun_FenceBeforeThenAfter) {
  auto queue = CreateTaskQueue();

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);

  EnqueueOrder enqueue_order = sequence_manager()->GetNextSequenceNumber();
  EXPECT_FALSE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));

  queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->CouldTaskRun(enqueue_order));
}

TEST_P(SequenceManagerTest, DelayedDoWorkNotPostedForDisabledQueue) {
  auto queue = CreateTaskQueue();

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(1));
  EXPECT_EQ(FromStartAligned(Milliseconds(1)), NextPendingTaskTime());

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  EXPECT_EQ(TimeTicks::Max(), NextPendingTaskTime());

  voter->SetVoteToEnable(true);
  EXPECT_EQ(FromStartAligned(Milliseconds(1)), NextPendingTaskTime());
}

TEST_P(SequenceManagerTest, DisablingQueuesChangesDelayTillNextDoWork) {
  auto queues = CreateTaskQueues(3u);
  queues[0]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(1));
  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(10));
  queues[2]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(100));

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter0 =
      queues[0]->CreateQueueEnabledVoter();
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter1 =
      queues[1]->CreateQueueEnabledVoter();
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter2 =
      queues[2]->CreateQueueEnabledVoter();

  EXPECT_EQ(FromStartAligned(Milliseconds(1)), NextPendingTaskTime());

  voter0->SetVoteToEnable(false);
  EXPECT_EQ(FromStartAligned(Milliseconds(10)), NextPendingTaskTime());

  voter1->SetVoteToEnable(false);
  EXPECT_EQ(FromStartAligned(Milliseconds(100)), NextPendingTaskTime());

  voter2->SetVoteToEnable(false);
  EXPECT_EQ(TimeTicks::Max(), NextPendingTaskTime());
}

TEST_P(SequenceManagerTest, GetNextDesiredWakeUp) {
  auto queue = CreateTaskQueue();

  EXPECT_EQ(absl::nullopt, queue->GetNextDesiredWakeUp());

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay1 = Milliseconds(10);
  TimeDelta delay2 = Milliseconds(2);

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1);
  EXPECT_EQ(start_time + delay1, queue->GetNextDesiredWakeUp()->time);

  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay2);
  EXPECT_EQ(start_time + delay2, queue->GetNextDesiredWakeUp()->time);

  // We don't have wake-ups scheduled for disabled queues.
  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);
  EXPECT_EQ(absl::nullopt, queue->GetNextDesiredWakeUp());

  voter->SetVoteToEnable(true);
  EXPECT_EQ(start_time + delay2, queue->GetNextDesiredWakeUp()->time);

  // Immediate tasks shouldn't make any difference.
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(start_time + delay2, queue->GetNextDesiredWakeUp()->time);

  // Neither should fences.
  queue->InsertFence(TaskQueue::InsertFencePosition::kBeginningOfTime);
  EXPECT_EQ(start_time + delay2, queue->GetNextDesiredWakeUp()->time);
}

TEST_P(SequenceManagerTest, SetTimeDomainForDisabledQueue) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  TimeTicks start_time = sequence_manager()->NowTicks();
  TimeDelta delay(Milliseconds(1));

  EXPECT_CALL(throttler,
              GetNextAllowedWakeUp_DesiredWakeUpTime(start_time + delay));
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay);
  Mock::VerifyAndClearExpectations(&throttler);

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  // We should not get a notification for a disabled queue.
  std::unique_ptr<MockTimeDomain> domain =
      std::make_unique<MockTimeDomain>(sequence_manager()->NowTicks());
  sequence_manager()->SetTimeDomain(domain.get());

  // Tidy up.
  queue->ShutdownTaskQueue();
  sequence_manager()->ResetTimeDomain();
}

namespace {
void SetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue,
                       int* start_counter,
                       int* complete_counter) {
  task_queue->GetTaskQueueImpl()->SetOnTaskStartedHandler(BindRepeating(
      [](int* counter, const Task& task,
         const TaskQueue::TaskTiming& task_timing) { ++(*counter); },
      start_counter));
  task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(BindRepeating(
      [](int* counter, const Task& task, TaskQueue::TaskTiming* task_timing,
         LazyNow* lazy_now) { ++(*counter); },
      complete_counter));
}

void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) {
  task_queue->GetTaskQueueImpl()->SetOnTaskStartedHandler(
      internal::TaskQueueImpl::OnTaskStartedHandler());
  task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(
      internal::TaskQueueImpl::OnTaskCompletedHandler());
}
}  // namespace

TEST_P(SequenceManagerTest, ProcessTasksWithoutTaskTimeObservers) {
  auto queue = CreateTaskQueue();
  int start_counter = 0;
  int complete_counter = 0;
  std::vector<EnqueueOrder> run_order;
  SetOnTaskHandlers(queue, &start_counter, &complete_counter);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 3);
  EXPECT_EQ(complete_counter, 3);
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u));

  UnsetOnTaskHandlers(queue);
  EXPECT_FALSE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 3);
  EXPECT_EQ(complete_counter, 3);
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u));
}

TEST_P(SequenceManagerTest, ProcessTasksWithTaskTimeObservers) {
  TestTaskTimeObserver test_task_time_observer;
  auto queue = CreateTaskQueue();
  int start_counter = 0;
  int complete_counter = 0;

  sequence_manager()->AddTaskTimeObserver(&test_task_time_observer);
  SetOnTaskHandlers(queue, &start_counter, &complete_counter);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  std::vector<EnqueueOrder> run_order;
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 2);
  EXPECT_EQ(complete_counter, 2);
  EXPECT_THAT(run_order, ElementsAre(1u, 2u));

  UnsetOnTaskHandlers(queue);
  EXPECT_FALSE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 2);
  EXPECT_EQ(complete_counter, 2);
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u));

  sequence_manager()->RemoveTaskTimeObserver(&test_task_time_observer);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 2);
  EXPECT_EQ(complete_counter, 2);
  EXPECT_FALSE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u));

  SetOnTaskHandlers(queue, &start_counter, &complete_counter);
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 7, &run_order));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&TestTask, 8, &run_order));

  RunLoop().RunUntilIdle();
  EXPECT_EQ(start_counter, 4);
  EXPECT_EQ(complete_counter, 4);
  EXPECT_TRUE(queue->GetTaskQueueImpl()->RequiresTaskTiming());
  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u));
  UnsetOnTaskHandlers(queue);
}

TEST_P(SequenceManagerTest, ObserverNotFiredAfterTaskQueueDestructed) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  // We don't expect the throttler to be notified if the TaskQueue gets
  // destructed.
  auto task_runner = queue->task_runner();
  queue = nullptr;
  task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));

  FastForwardUntilNoTasksRemain();
}

TEST_P(SequenceManagerTest,
       OnQueueNextWakeUpChangedNotFiredForDisabledQueuePostTask) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  // We don't expect the OnHasImmediateTask to be called if the TaskQueue gets
  // disabled.
  auto task_runner = queue->task_runner();
  task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));

  FastForwardUntilNoTasksRemain();
  // When |voter| goes out of scope the queue will become enabled and the
  // observer will fire. We're not interested in testing that however.
  Mock::VerifyAndClearExpectations(&throttler);
}

TEST_P(SequenceManagerTest,
       OnQueueNextWakeUpChangedNotFiredForCrossThreadDisabledQueuePostTask) {
  StrictMock<MockTaskQueueThrottler> throttler;
  auto queue = CreateTaskQueue();
  queue->SetThrottler(&throttler);

  std::unique_ptr<TaskQueue::QueueEnabledVoter> voter =
      queue->CreateQueueEnabledVoter();
  voter->SetVoteToEnable(false);

  // We don't expect OnHasImmediateTask to be called if the TaskQueue gets
  // blocked.
  auto task_runner = queue->task_runner();
  WaitableEvent done_event;
  Thread thread("TestThread");
  thread.Start();
  thread.task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                   // Should not fire the observer.
                                   task_runner->PostTask(FROM_HERE,
                                                         BindOnce(&NopTask));
                                   done_event.Signal();
                                 }));
  done_event.Wait();
  thread.Stop();

  FastForwardUntilNoTasksRemain();
  // When |voter| goes out of scope the queue will become enabled and the
  // observer will fire. We're not interested in testing that however.
  Mock::VerifyAndClearExpectations(&throttler);
}

TEST_P(SequenceManagerTest, GracefulShutdown) {
  std::vector<TimeTicks> run_times;
  scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
  WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr();

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  for (int i = 1; i <= 5; ++i) {
    main_tq->task_runner()->PostDelayedTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
        Milliseconds(i * 100));
  }
  FastForwardBy(Milliseconds(250));

  main_tq = nullptr;
  // Ensure that task queue went away.
  EXPECT_FALSE(main_tq_weak_ptr.get());

  FastForwardBy(Milliseconds(1));

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(1u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  FastForwardUntilNoTasksRemain();

  // Even with TaskQueue gone, tasks are executed.
  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(100)),
                                     FromStartAligned(Milliseconds(200)),
                                     FromStartAligned(Milliseconds(300)),
                                     FromStartAligned(Milliseconds(400)),
                                     FromStartAligned(Milliseconds(500))));

  EXPECT_EQ(0u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());
}

TEST_P(SequenceManagerTest, GracefulShutdown_ManagerDeletedInFlight) {
  std::vector<TimeTicks> run_times;
  scoped_refptr<TestTaskQueue> control_tq = CreateTaskQueue();
  std::vector<scoped_refptr<TestTaskQueue>> main_tqs;
  std::vector<WeakPtr<TestTaskQueue>> main_tq_weak_ptrs;

  // There might be a race condition - async task queues should be unregistered
  // first. Increase the number of task queues to surely detect that.
  // The problem is that pointers are compared in a set and generally for
  // a small number of allocations value of the pointers increases
  // monotonically. 100 is large enough to force allocations from different
  // pages.
  const int N = 100;
  for (int i = 0; i < N; ++i) {
    scoped_refptr<TestTaskQueue> tq = CreateTaskQueue();
    main_tq_weak_ptrs.push_back(tq->GetWeakPtr());
    main_tqs.push_back(std::move(tq));
  }

  for (int i = 1; i <= 5; ++i) {
    main_tqs[0]->task_runner()->PostDelayedTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
        Milliseconds(i * 100));
  }
  FastForwardBy(Milliseconds(250));

  main_tqs.clear();
  // Ensure that task queues went away.
  for (int i = 0; i < N; ++i) {
    EXPECT_FALSE(main_tq_weak_ptrs[i].get());
  }

  // No leaks should occur when TQM was destroyed before processing
  // shutdown task and TaskQueueImpl should be safely deleted on a correct
  // thread.
  DestroySequenceManager();

  if (GetUnderlyingRunnerType() != RunnerType::kMessagePump) {
    FastForwardUntilNoTasksRemain();
  }

  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(100)),
                                     FromStartAligned(Milliseconds(200))));
}

TEST_P(SequenceManagerTest,
       GracefulShutdown_ManagerDeletedWithQueuesToShutdown) {
  std::vector<TimeTicks> run_times;
  scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
  WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr();
  RefCountedCallbackFactory counter;

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  for (int i = 1; i <= 5; ++i) {
    main_tq->task_runner()->PostDelayedTask(
        FROM_HERE,
        counter.WrapCallback(
            BindOnce(&RecordTimeTask, &run_times, mock_tick_clock())),
        Milliseconds(i * 100));
  }
  FastForwardBy(Milliseconds(250));

  main_tq = nullptr;
  // Ensure that task queue went away.
  EXPECT_FALSE(main_tq_weak_ptr.get());

  FastForwardBy(Milliseconds(1));

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(1u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  // Ensure that all queues-to-gracefully-shutdown are properly unregistered.
  DestroySequenceManager();

  if (GetUnderlyingRunnerType() != RunnerType::kMessagePump) {
    FastForwardUntilNoTasksRemain();
  }

  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(100)),
                                     FromStartAligned(Milliseconds(200))));
  EXPECT_FALSE(counter.HasReferences());
}

TEST(SequenceManagerBasicTest, DefaultTaskRunnerSupport) {
  auto base_sequence_manager =
      sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
          MessagePump::Create(MessagePumpType::DEFAULT));
  auto queue = base_sequence_manager->CreateTaskQueue(
      sequence_manager::TaskQueue::Spec(QueueName::DEFAULT_TQ));
  base_sequence_manager->SetDefaultTaskRunner(queue->task_runner());

  scoped_refptr<SingleThreadTaskRunner> original_task_runner =
      SingleThreadTaskRunner::GetCurrentDefault();
  scoped_refptr<SingleThreadTaskRunner> custom_task_runner =
      MakeRefCounted<TestSimpleTaskRunner>();
  {
    std::unique_ptr<SequenceManager> manager =
        CreateSequenceManagerOnCurrentThread(SequenceManager::Settings());

    manager->SetDefaultTaskRunner(custom_task_runner);
    DCHECK_EQ(custom_task_runner, SingleThreadTaskRunner::GetCurrentDefault());
  }
  DCHECK_EQ(original_task_runner, SingleThreadTaskRunner::GetCurrentDefault());
}

TEST_P(SequenceManagerTest, CanceledTasksInQueueCantMakeOtherTasksSkipAhead) {
  auto queues = CreateTaskQueues(2u);

  CancelableTask task1(mock_tick_clock());
  CancelableTask task2(mock_tick_clock());
  std::vector<TimeTicks> run_times;

  queues[0]->task_runner()->PostTask(
      FROM_HERE, BindOnce(&CancelableTask::RecordTimeTask,
                          task1.weak_factory_.GetWeakPtr(), &run_times));
  queues[0]->task_runner()->PostTask(
      FROM_HERE, BindOnce(&CancelableTask::RecordTimeTask,
                          task2.weak_factory_.GetWeakPtr(), &run_times));

  std::vector<EnqueueOrder> run_order;
  queues[1]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 1, &run_order));

  queues[0]->task_runner()->PostTask(FROM_HERE,
                                     BindOnce(&TestTask, 2, &run_order));

  task1.weak_factory_.InvalidateWeakPtrs();
  task2.weak_factory_.InvalidateWeakPtrs();
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(1u, 2u));
}

TEST_P(SequenceManagerTest, TaskRunnerDeletedOnAnotherThread) {
  std::vector<TimeTicks> run_times;
  scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
  scoped_refptr<TaskRunner> task_runner =
      main_tq->CreateTaskRunner(kTaskTypeNone);

  int start_counter = 0;
  int complete_counter = 0;
  SetOnTaskHandlers(main_tq, &start_counter, &complete_counter);

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  for (int i = 1; i <= 5; ++i) {
    task_runner->PostDelayedTask(
        FROM_HERE, BindOnce(&RecordTimeTask, &run_times, mock_tick_clock()),
        Milliseconds(i * 100));
  }

  // TODO(altimin): do not do this after switching to weak pointer-based
  // task handlers.
  UnsetOnTaskHandlers(main_tq);

  // Make |task_runner| the only reference to |main_tq|.
  main_tq = nullptr;

  WaitableEvent task_queue_deleted(WaitableEvent::ResetPolicy::MANUAL,
                                   WaitableEvent::InitialState::NOT_SIGNALED);
  std::unique_ptr<Thread> thread = std::make_unique<Thread>("test thread");
  thread->StartAndWaitForTesting();

  thread->task_runner()->PostTask(
      FROM_HERE, BindOnce(
                     [](scoped_refptr<TaskRunner> task_runner,
                        WaitableEvent* task_queue_deleted) {
                       task_runner = nullptr;
                       task_queue_deleted->Signal();
                     },
                     std::move(task_runner), &task_queue_deleted));
  task_queue_deleted.Wait();

  EXPECT_EQ(1u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(1u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  FastForwardUntilNoTasksRemain();

  // Even with TaskQueue gone, tasks are executed.
  EXPECT_THAT(run_times, ElementsAre(FromStartAligned(Milliseconds(100)),
                                     FromStartAligned(Milliseconds(200)),
                                     FromStartAligned(Milliseconds(300)),
                                     FromStartAligned(Milliseconds(400)),
                                     FromStartAligned(Milliseconds(500))));

  EXPECT_EQ(0u, sequence_manager()->ActiveQueuesCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToShutdownCount());
  EXPECT_EQ(0u, sequence_manager()->QueuesToDeleteCount());

  thread->Stop();
}

namespace {

class RunOnDestructionHelper {
 public:
  explicit RunOnDestructionHelper(base::OnceClosure task)
      : task_(std::move(task)) {}

  ~RunOnDestructionHelper() { std::move(task_).Run(); }

 private:
  base::OnceClosure task_;
};

base::OnceClosure RunOnDestruction(base::OnceClosure task) {
  return base::BindOnce(
      [](std::unique_ptr<RunOnDestructionHelper>) {},
      std::make_unique<RunOnDestructionHelper>(std::move(task)));
}

base::OnceClosure PostOnDestruction(scoped_refptr<TestTaskQueue> task_queue,
                                    base::OnceClosure task) {
  return RunOnDestruction(base::BindOnce(
      [](base::OnceClosure task, scoped_refptr<TestTaskQueue> task_queue) {
        task_queue->task_runner()->PostTask(FROM_HERE, std::move(task));
      },
      std::move(task), task_queue));
}

}  // namespace

TEST_P(SequenceManagerTest, TaskQueueUsedInTaskDestructorAfterShutdown) {
  // This test checks that when a task is posted to a shutdown queue and
  // destroyed, it can try to post a task to the same queue without deadlocks.
  scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();

  WaitableEvent test_executed(WaitableEvent::ResetPolicy::MANUAL,
                              WaitableEvent::InitialState::NOT_SIGNALED);
  std::unique_ptr<Thread> thread = std::make_unique<Thread>("test thread");
  thread->StartAndWaitForTesting();

  DestroySequenceManager();

  thread->task_runner()->PostTask(
      FROM_HERE, BindOnce(
                     [](scoped_refptr<TestTaskQueue> task_queue,
                        WaitableEvent* test_executed) {
                       task_queue->task_runner()->PostTask(
                           FROM_HERE, PostOnDestruction(
                                          task_queue, base::BindOnce([]() {})));
                       test_executed->Signal();
                     },
                     main_tq, &test_executed));
  test_executed.Wait();
}

TEST_P(SequenceManagerTest, TaskQueueTaskRunnerDetach) {
  scoped_refptr<TestTaskQueue> queue1 = CreateTaskQueue();
  EXPECT_TRUE(queue1->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask)));
  queue1->ShutdownTaskQueue();
  EXPECT_FALSE(queue1->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask)));

  // Create without a sequence manager.
  std::unique_ptr<TaskQueueImpl> queue2 = std::make_unique<TaskQueueImpl>(
      nullptr, nullptr, TaskQueue::Spec(QueueName::TEST_TQ));
  scoped_refptr<SingleThreadTaskRunner> task_runner2 =
      queue2->CreateTaskRunner(0);
  EXPECT_FALSE(task_runner2->PostTask(FROM_HERE, BindOnce(&NopTask)));

  // Tidy up.
  queue2->UnregisterTaskQueue();
}

TEST_P(SequenceManagerTest, DestructorPostChainDuringShutdown) {
  // Checks that a chain of closures which post other closures on destruction do
  // thing on shutdown.
  scoped_refptr<TestTaskQueue> task_queue = CreateTaskQueue();
  bool run = false;
  task_queue->task_runner()->PostTask(
      FROM_HERE,
      PostOnDestruction(
          task_queue,
          PostOnDestruction(task_queue,
                            RunOnDestruction(base::BindOnce(
                                [](bool* run) { *run = true; }, &run)))));

  DestroySequenceManager();

  EXPECT_TRUE(run);
}

TEST_P(SequenceManagerTest, DestructorPostsViaTaskRunnerHandleDuringShutdown) {
  scoped_refptr<TestTaskQueue> task_queue = CreateTaskQueue();
  bool run = false;
  task_queue->task_runner()->PostTask(
      FROM_HERE, RunOnDestruction(BindLambdaForTesting([&]() {
        SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(&NopTask));
        run = true;
      })));

  // Should not DCHECK when SingleThreadTaskRunner::GetCurrentDefault() is
  // invoked.
  DestroySequenceManager();
  EXPECT_TRUE(run);
}

TEST_P(SequenceManagerTest, CreateUnboundSequenceManagerWhichIsNeverBound) {
  // This should not crash.
  CreateUnboundSequenceManager();
}

TEST_P(SequenceManagerTest, HasPendingHighResolutionTasks) {
  auto queue = CreateTaskQueue();
  bool supports_high_res = false;
#if BUILDFLAG(IS_WIN)
  supports_high_res = true;
#endif

  // Only the third task needs high resolution timing.
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(100));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(10));
  EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
            supports_high_res);

  // Running immediate tasks doesn't affect pending high resolution tasks.
  RunLoop().RunUntilIdle();
  EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
            supports_high_res);

  // Advancing to just before a pending low resolution task doesn't mean that we
  // have pending high resolution work.
  AdvanceMockTickClock(Milliseconds(99));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  AdvanceMockTickClock(Milliseconds(100));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
}

TEST_P(SequenceManagerTest, HasPendingHighResolutionTasksLowPriority) {
  auto queue = CreateTaskQueue();
  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  bool supports_high_res = false;
#if BUILDFLAG(IS_WIN)
  supports_high_res = true;
#endif

  // No task should be considered high resolution in a low priority queue.
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(100));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queue->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                        Milliseconds(10));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  // Increasing queue priority should enable high resolution timer.
  queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
  EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
            supports_high_res);
  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  // Running immediate tasks doesn't affect pending high resolution tasks.
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  // Advancing to just before a pending low resolution task doesn't mean that we
  // have pending high resolution work.
  AdvanceMockTickClock(Milliseconds(99));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  AdvanceMockTickClock(Milliseconds(100));
  RunLoop().RunUntilIdle();
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
}

TEST_P(SequenceManagerTest,
       HasPendingHighResolutionTasksLowAndNormalPriorityQueues) {
  auto queueLow = CreateTaskQueue();
  queueLow->SetQueuePriority(TestQueuePriority::kLowPriority);
  auto queueNormal = CreateTaskQueue();
  queueNormal->SetQueuePriority(TestQueuePriority::kNormalPriority);
  bool supports_high_res = false;
#if BUILDFLAG(IS_WIN)
  supports_high_res = true;
#endif

  // No task should be considered high resolution in a low priority queue.
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queueLow->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                           Milliseconds(10));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
  queueNormal->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                              Milliseconds(100));
  EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());

  // Increasing queue priority should enable high resolution timer.
  queueLow->SetQueuePriority(TestQueuePriority::kNormalPriority);
  EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
            supports_high_res);
}

namespace {

class PostTaskWhenDeleted;
void CallbackWithDestructor(std::unique_ptr<PostTaskWhenDeleted>);

class PostTaskWhenDeleted {
 public:
  PostTaskWhenDeleted(std::string name,
                      scoped_refptr<SingleThreadTaskRunner> task_runner,
                      size_t depth,
                      std::set<std::string>* tasks_alive,
                      std::vector<std::string>* tasks_deleted)
      : name_(name),
        task_runner_(std::move(task_runner)),
        depth_(depth),
        tasks_alive_(tasks_alive),
        tasks_deleted_(tasks_deleted) {
    tasks_alive_->insert(full_name());
  }

  ~PostTaskWhenDeleted() {
    DCHECK(tasks_alive_->find(full_name()) != tasks_alive_->end());
    tasks_alive_->erase(full_name());
    tasks_deleted_->push_back(full_name());

    if (depth_ > 0) {
      task_runner_->PostTask(
          FROM_HERE, base::BindOnce(&CallbackWithDestructor,
                                    std::make_unique<PostTaskWhenDeleted>(
                                        name_, task_runner_, depth_ - 1,
                                        tasks_alive_, tasks_deleted_)));
    }
  }

 private:
  std::string full_name() { return name_ + " " + NumberToString(depth_); }

  std::string name_;
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  int depth_;
  raw_ptr<std::set<std::string>> tasks_alive_;
  raw_ptr<std::vector<std::string>> tasks_deleted_;
};

void CallbackWithDestructor(std::unique_ptr<PostTaskWhenDeleted> object) {}

}  // namespace

TEST_P(SequenceManagerTest, DoesNotRecordQueueTimeIfSettingFalse) {
  auto queue = CreateTaskQueue();

  QueueTimeTaskObserver observer;
  sequence_manager()->AddTaskObserver(&observer);

  // We do not record task queue time when the setting is false.
  sequence_manager()->SetAddQueueTimeToTasks(false);
  AdvanceMockTickClock(Milliseconds(99));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_THAT(observer.queue_times(), ElementsAre(TimeTicks()));

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest, RecordsQueueTimeIfSettingTrue) {
  const auto kStartTime = mock_tick_clock()->NowTicks();
  auto queue = CreateTaskQueue();

  QueueTimeTaskObserver observer;
  sequence_manager()->AddTaskObserver(&observer);

  // We correctly record task queue time when the setting is true.
  sequence_manager()->SetAddQueueTimeToTasks(true);
  AdvanceMockTickClock(Milliseconds(99));
  queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  RunLoop().RunUntilIdle();
  EXPECT_THAT(observer.queue_times(),
              ElementsAre(kStartTime + Milliseconds(99)));

  sequence_manager()->RemoveTaskObserver(&observer);
}

namespace {

// Inject a test point for recording the destructor calls for OnceClosure
// objects sent to PostTask(). It is awkward usage since we are trying to hook
// the actual destruction, which is not a common operation.
class DestructionObserverProbe : public RefCounted<DestructionObserverProbe> {
 public:
  DestructionObserverProbe(bool* task_destroyed,
                           bool* destruction_observer_called)
      : task_destroyed_(task_destroyed),
        destruction_observer_called_(destruction_observer_called) {}
  virtual void Run() {
    // This task should never run.
    ADD_FAILURE();
  }

 private:
  friend class RefCounted<DestructionObserverProbe>;

  virtual ~DestructionObserverProbe() {
    EXPECT_FALSE(*destruction_observer_called_);
    *task_destroyed_ = true;
  }

  raw_ptr<bool> task_destroyed_;
  raw_ptr<bool> destruction_observer_called_;
};

class SMDestructionObserver : public CurrentThread::DestructionObserver {
 public:
  SMDestructionObserver(bool* task_destroyed, bool* destruction_observer_called)
      : task_destroyed_(task_destroyed),
        destruction_observer_called_(destruction_observer_called),
        task_destroyed_before_message_loop_(false) {}
  void WillDestroyCurrentMessageLoop() override {
    task_destroyed_before_message_loop_ = *task_destroyed_;
    *destruction_observer_called_ = true;
  }
  bool task_destroyed_before_message_loop() const {
    return task_destroyed_before_message_loop_;
  }

 private:
  raw_ptr<bool> task_destroyed_;
  raw_ptr<bool> destruction_observer_called_;
  bool task_destroyed_before_message_loop_;
};

}  // namespace

TEST_P(SequenceManagerTest, DestructionObserverTest) {
  auto queue = CreateTaskQueue();

  // Verify that the destruction observer gets called at the very end (after
  // all the pending tasks have been destroyed).
  const TimeDelta kDelay = Milliseconds(100);

  bool task_destroyed = false;
  bool destruction_observer_called = false;

  SMDestructionObserver observer(&task_destroyed, &destruction_observer_called);
  sequence_manager()->AddDestructionObserver(&observer);
  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&DestructionObserverProbe::Run,
               base::MakeRefCounted<DestructionObserverProbe>(
                   &task_destroyed, &destruction_observer_called)),
      kDelay);

  DestroySequenceManager();

  EXPECT_TRUE(observer.task_destroyed_before_message_loop());
  // The task should have been destroyed when we deleted the loop.
  EXPECT_TRUE(task_destroyed);
  EXPECT_TRUE(destruction_observer_called);
}

TEST_P(SequenceManagerTest, GetMessagePump) {
  switch (GetUnderlyingRunnerType()) {
    default:
      EXPECT_THAT(sequence_manager()->GetMessagePump(), testing::IsNull());
      break;
    case RunnerType::kMessagePump:
      EXPECT_THAT(sequence_manager()->GetMessagePump(), testing::NotNull());
      break;
  }
}

namespace {

class MockTimeDomain : public TimeDomain {
 public:
  MockTimeDomain() = default;
  MockTimeDomain(const MockTimeDomain&) = delete;
  MockTimeDomain& operator=(const MockTimeDomain&) = delete;
  ~MockTimeDomain() override = default;

  // TickClock:
  TimeTicks NowTicks() const override { return now_; }

  // TimeDomain:
  bool MaybeFastForwardToWakeUp(absl::optional<WakeUp> wakeup,
                                bool quit_when_idle_requested) override {
    return MaybeFastForwardToWakeUp(quit_when_idle_requested);
  }

  MOCK_METHOD1(MaybeFastForwardToWakeUp, bool(bool quit_when_idle_requested));

  const char* GetName() const override { return "Test"; }

 private:
  TimeTicks now_;
};

}  // namespace

TEST_P(SequenceManagerTest, OnSystemIdleTimeDomainNotification) {
  if (GetUnderlyingRunnerType() != RunnerType::kMessagePump)
    return;

  auto queue = CreateTaskQueue();

  // If we call OnSystemIdle, we expect registered TimeDomains to receive a call
  // to MaybeFastForwardToWakeUp.  If no run loop has requested quit on idle,
  // the parameter passed in should be false.
  StrictMock<MockTimeDomain> mock_time_domain;
  sequence_manager()->SetTimeDomain(&mock_time_domain);
  EXPECT_CALL(mock_time_domain, MaybeFastForwardToWakeUp(false))
      .WillOnce(Return(false));
  sequence_manager()->OnSystemIdle();
  sequence_manager()->ResetTimeDomain();
  Mock::VerifyAndClearExpectations(&mock_time_domain);

  // However if RunUntilIdle is called it should be true.
  queue->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        StrictMock<MockTimeDomain> mock_time_domain;
        EXPECT_CALL(mock_time_domain, MaybeFastForwardToWakeUp(true))
            .WillOnce(Return(false));
        sequence_manager()->SetTimeDomain(&mock_time_domain);
        sequence_manager()->OnSystemIdle();
        sequence_manager()->ResetTimeDomain();
      }));

  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, CreateTaskQueue) {
  scoped_refptr<TaskQueue> task_queue =
      sequence_manager()->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
  EXPECT_THAT(task_queue.get(), testing::NotNull());

  task_queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(1u, sequence_manager()->GetPendingTaskCountForTesting());
}

TEST_P(SequenceManagerTest, GetPendingTaskCountForTesting) {
  auto queues = CreateTaskQueues(3u);

  EXPECT_EQ(0u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(1u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(2u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(3u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[1]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(4u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[2]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
  EXPECT_EQ(5u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[1]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(10));
  EXPECT_EQ(6u, sequence_manager()->GetPendingTaskCountForTesting());

  queues[2]->task_runner()->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                                            Milliseconds(20));
  EXPECT_EQ(7u, sequence_manager()->GetPendingTaskCountForTesting());

  RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, sequence_manager()->GetPendingTaskCountForTesting());

  AdvanceMockTickClock(Milliseconds(10));
  RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, sequence_manager()->GetPendingTaskCountForTesting());

  AdvanceMockTickClock(Milliseconds(10));
  RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, sequence_manager()->GetPendingTaskCountForTesting());
}

TEST_P(SequenceManagerTest, PostDelayedTaskFromOtherThread) {
  scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue();
  scoped_refptr<TaskRunner> task_runner =
      main_tq->CreateTaskRunner(kTaskTypeNone);
  sequence_manager()->SetAddQueueTimeToTasks(true);

  Thread thread("test thread");
  thread.StartAndWaitForTesting();

  WaitableEvent task_posted(WaitableEvent::ResetPolicy::MANUAL,
                            WaitableEvent::InitialState::NOT_SIGNALED);
  thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(
                     [](scoped_refptr<TaskRunner> task_runner,
                        WaitableEvent* task_posted) {
                       task_runner->PostDelayedTask(FROM_HERE,
                                                    BindOnce(&NopTask),
                                                    base::Milliseconds(10));
                       task_posted->Signal();
                     },
                     std::move(task_runner), &task_posted));
  task_posted.Wait();
  FastForwardUntilNoTasksRemain();
  RunLoop().RunUntilIdle();
  thread.Stop();
}

namespace {

void PostTaskA(scoped_refptr<TaskRunner> task_runner) {
  task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));
  task_runner->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                               base::Milliseconds(10));
}

void PostTaskB(scoped_refptr<TaskRunner> task_runner) {
  task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));
  task_runner->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                               base::Milliseconds(20));
}

void PostTaskC(scoped_refptr<TaskRunner> task_runner) {
  task_runner->PostTask(FROM_HERE, BindOnce(&NopTask));
  task_runner->PostDelayedTask(FROM_HERE, BindOnce(&NopTask),
                               base::Milliseconds(30));
}

}  // namespace

TEST_P(SequenceManagerTest, DescribeAllPendingTasks) {
  auto queues = CreateTaskQueues(3u);

  PostTaskA(queues[0]->task_runner());
  PostTaskB(queues[1]->task_runner());
  PostTaskC(queues[2]->task_runner());

  std::string description = sequence_manager()->DescribeAllPendingTasks();
  EXPECT_THAT(description, HasSubstr("PostTaskA@"));
  EXPECT_THAT(description, HasSubstr("PostTaskB@"));
  EXPECT_THAT(description, HasSubstr("PostTaskC@"));
}

TEST_P(SequenceManagerTest, TaskPriortyInterleaving) {
  auto queues = CreateTaskQueues(
      static_cast<size_t>(TestQueuePriority::kQueuePriorityCount));

  for (uint8_t priority = 0;
       priority < static_cast<uint8_t>(TestQueuePriority::kQueuePriorityCount);
       priority++) {
    if (priority != static_cast<uint8_t>(TestQueuePriority::kNormalPriority)) {
      queues[priority]->SetQueuePriority(
          static_cast<TaskQueue::QueuePriority>(priority));
    }
  }

  std::string order;
  for (int i = 0; i < 60; i++) {
    for (uint8_t priority = 0;
         priority <
         static_cast<uint8_t>(TestQueuePriority::kQueuePriorityCount);
         priority++) {
      queues[priority]->task_runner()->PostTask(
          FROM_HERE,
          base::BindOnce([](std::string* str, char c) { str->push_back(c); },
                         &order, '0' + priority));
    }
  }

  RunLoop().RunUntilIdle();

  EXPECT_EQ(order,
            "000000000000000000000000000000000000000000000000000000000000"
            "111111111111111111111111111111111111111111111111111111111111"
            "222222222222222222222222222222222222222222222222222222222222"
            "333333333333333333333333333333333333333333333333333333333333"
            "444444444444444444444444444444444444444444444444444444444444"
            "555555555555555555555555555555555555555555555555555555555555"
            "666666666666666666666666666666666666666666666666666666666666");
}

namespace {

class CancelableTaskWithDestructionObserver {
 public:
  CancelableTaskWithDestructionObserver() {}

  void Task(std::unique_ptr<ScopedClosureRunner> destruction_observer) {
    destruction_observer_ = std::move(destruction_observer);
  }

  std::unique_ptr<ScopedClosureRunner> destruction_observer_;
  WeakPtrFactory<CancelableTaskWithDestructionObserver> weak_factory_{this};
};

}  // namespace

TEST_P(SequenceManagerTest, PeriodicHousekeeping) {
  auto queue = CreateTaskQueue();

  // Post a task that will trigger housekeeping.
  queue->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&NopTask),
      SequenceManagerImpl::kReclaimMemoryInterval);

  // Posts some tasks set to run long in the future and then cancel some of
  // them.
  bool task1_deleted = false;
  bool task2_deleted = false;
  bool task3_deleted = false;
  CancelableTaskWithDestructionObserver task1;
  CancelableTaskWithDestructionObserver task2;
  CancelableTaskWithDestructionObserver task3;

  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTaskWithDestructionObserver::Task,
               task1.weak_factory_.GetWeakPtr(),
               std::make_unique<ScopedClosureRunner>(
                   BindLambdaForTesting([&]() { task1_deleted = true; }))),
      Hours(1));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTaskWithDestructionObserver::Task,
               task2.weak_factory_.GetWeakPtr(),
               std::make_unique<ScopedClosureRunner>(
                   BindLambdaForTesting([&]() { task2_deleted = true; }))),
      Hours(2));

  queue->task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(&CancelableTaskWithDestructionObserver::Task,
               task3.weak_factory_.GetWeakPtr(),
               std::make_unique<ScopedClosureRunner>(
                   BindLambdaForTesting([&]() { task3_deleted = true; }))),
      Hours(3));

  task2.weak_factory_.InvalidateWeakPtrs();
  task3.weak_factory_.InvalidateWeakPtrs();

  EXPECT_FALSE(task1_deleted);
  EXPECT_FALSE(task2_deleted);
  EXPECT_FALSE(task3_deleted);

  // This should trigger housekeeping which will sweep away the canceled tasks.
  FastForwardBy(SequenceManagerImpl::kReclaimMemoryInterval);

  EXPECT_FALSE(task1_deleted);
  EXPECT_TRUE(task2_deleted);
  EXPECT_TRUE(task3_deleted);

  // Tidy up.
  FastForwardUntilNoTasksRemain();
}

namespace {

class MockCrashKeyImplementation : public debug::CrashKeyImplementation {
 public:
  MOCK_METHOD2(Allocate,
               debug::CrashKeyString*(const char name[], debug::CrashKeySize));
  MOCK_METHOD2(Set, void(debug::CrashKeyString*, StringPiece));
  MOCK_METHOD1(Clear, void(debug::CrashKeyString*));
  MOCK_METHOD1(OutputCrashKeysToStream, void(std::ostream&));
};

}  // namespace

TEST_P(SequenceManagerTest, CrashKeys) {
  testing::InSequence sequence;
  auto queue = CreateTaskQueue();
  auto runner = queue->CreateTaskRunner(kTaskTypeNone);
  auto crash_key_impl = std::make_unique<MockCrashKeyImplementation>();
  RunLoop run_loop;

  MockCrashKeyImplementation* mock_impl = crash_key_impl.get();
  debug::SetCrashKeyImplementation(std::move(crash_key_impl));

  // Parent task.
  auto parent_location = FROM_HERE;
  auto expected_stack1 = StringPrintf(
      "0x%zX 0x0",
      reinterpret_cast<uintptr_t>(parent_location.program_counter()));
  EXPECT_CALL(*mock_impl, Allocate(_, _)).WillRepeatedly(Return(dummy_key()));
  EXPECT_CALL(*mock_impl, Set(_, testing::Eq(expected_stack1)));

  // Child task.
  auto location = FROM_HERE;
  auto expected_stack2 = StringPrintf(
      "0x%zX 0x%zX", reinterpret_cast<uintptr_t>(location.program_counter()),
      reinterpret_cast<uintptr_t>(parent_location.program_counter()));
  EXPECT_CALL(*mock_impl, Set(_, testing::Eq(expected_stack2)));

  sequence_manager()->EnableCrashKeys("test-async-stack");

  // Run a task that posts another task to establish an asynchronous call stack.
  runner->PostTask(parent_location, BindLambdaForTesting([&]() {
                     runner->PostTask(location, run_loop.QuitClosure());
                   }));
  run_loop.Run();

  debug::SetCrashKeyImplementation(nullptr);
}

TEST_P(SequenceManagerTest, CrossQueueTaskPostingWhenQueueDeleted) {
  MockTask task;
  auto queue_1 = CreateTaskQueue();
  auto queue_2 = CreateTaskQueue();

  EXPECT_CALL(task, Run).Times(1);

  queue_1->task_runner()->PostDelayedTask(
      FROM_HERE, PostOnDestruction(queue_2, task.Get()), Minutes(1));

  queue_1->ShutdownTaskQueue();

  FastForwardUntilNoTasksRemain();
}

TEST_P(SequenceManagerTest, UnregisterTaskQueueTriggersScheduleWork) {
  constexpr auto kDelay = Minutes(1);
  auto queue_1 = CreateTaskQueue();
  auto queue_2 = CreateTaskQueue();

  MockTask task;
  EXPECT_CALL(task, Run).Times(1);

  queue_1->task_runner()->PostDelayedTask(FROM_HERE, task.Get(), kDelay);
  queue_2->task_runner()->PostDelayedTask(FROM_HERE, task.Get(), kDelay * 2);

  AdvanceMockTickClock(kDelay * 2);

  // Wakeup time needs to be adjusted to kDelay * 2 when the queue is
  // unregistered from the TimeDomain
  queue_1->ShutdownTaskQueue();

  RunLoop().RunUntilIdle();
}

TEST_P(SequenceManagerTest, ReclaimMemoryRemovesCorrectQueueFromSet) {
  auto queue1 = CreateTaskQueue();
  auto queue2 = CreateTaskQueue();
  auto queue3 = CreateTaskQueue();
  auto queue4 = CreateTaskQueue();

  std::vector<int> order;

  CancelableRepeatingClosure cancelable_closure1(
      BindLambdaForTesting([&]() { order.push_back(10); }));
  CancelableRepeatingClosure cancelable_closure2(
      BindLambdaForTesting([&]() { order.push_back(11); }));
  queue1->task_runner()->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
                                    order.push_back(1);
                                    cancelable_closure1.Cancel();
                                    cancelable_closure2.Cancel();
                                    // This should remove |queue4| from the work
                                    // queue set,
                                    sequence_manager()->ReclaimMemory();
                                  }));
  queue2->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() { order.push_back(2); }));
  queue3->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() { order.push_back(3); }));
  queue4->task_runner()->PostTask(FROM_HERE, cancelable_closure1.callback());
  queue4->task_runner()->PostTask(FROM_HERE, cancelable_closure2.callback());

  RunLoop().RunUntilIdle();

  // Make sure ReclaimMemory didn't prevent the task from |queue2| from running.
  EXPECT_THAT(order, ElementsAre(1, 2, 3));
}

namespace {

class TaskObserverExpectingNoDelayedRunTime : public TaskObserver {
 public:
  TaskObserverExpectingNoDelayedRunTime() = default;
  ~TaskObserverExpectingNoDelayedRunTime() override = default;

  int num_will_process_task() const { return num_will_process_task_; }
  int num_did_process_task() const { return num_did_process_task_; }

 private:
  void WillProcessTask(const base::PendingTask& pending_task,
                       bool was_blocked_or_low_priority) override {
    EXPECT_TRUE(pending_task.delayed_run_time.is_null());
    ++num_will_process_task_;
  }
  void DidProcessTask(const base::PendingTask& pending_task) override {
    EXPECT_TRUE(pending_task.delayed_run_time.is_null());
    ++num_did_process_task_;
  }

  int num_will_process_task_ = 0;
  int num_did_process_task_ = 0;
};

}  // namespace

// The |delayed_run_time| must not be set for immediate tasks as that prevents
// external observers from correctly identifying delayed tasks.
// https://crbug.com/1029137
TEST_P(SequenceManagerTest, NoDelayedRunTimeForImmediateTask) {
  TaskObserverExpectingNoDelayedRunTime task_observer;
  sequence_manager()->SetAddQueueTimeToTasks(true);
  sequence_manager()->AddTaskObserver(&task_observer);
  auto queue = CreateTaskQueue();

  base::RunLoop run_loop;
  queue->task_runner()->PostTask(
      FROM_HERE, BindLambdaForTesting([&]() { run_loop.Quit(); }));
  run_loop.Run();

  EXPECT_EQ(1, task_observer.num_will_process_task());
  EXPECT_EQ(1, task_observer.num_did_process_task());

  sequence_manager()->RemoveTaskObserver(&task_observer);
}

TEST_P(SequenceManagerTest, TaskObserverBlockedOrLowPriority_QueueDisabled) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->SetQueueEnabled(false);
  queue->GetTaskQueueImpl()->SetQueueEnabled(true);

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_FenceBeginningOfTime) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->InsertFence(
      TaskQueue::InsertFencePosition::kBeginningOfTime);
  queue->GetTaskQueueImpl()->RemoveFence();

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_PostedBeforeFenceNow) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->GetTaskQueueImpl()->RemoveFence();

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_PostedAfterFenceNow) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->GetTaskQueueImpl()->InsertFence(TaskQueue::InsertFencePosition::kNow);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->RemoveFence();

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_LowerPriorityWhileQueued) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  queue->SetQueuePriority(TestQueuePriority::kNormalPriority);

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_LowPriorityWhenQueueing) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->SetQueuePriority(TestQueuePriority::kNormalPriority);

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_LowPriorityWhenRunning) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->SetQueuePriority(TestQueuePriority::kLowPriority);

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest,
       TaskObserverBlockedOrLowPriority_TaskObserverUnblockedWithBacklog) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->InsertFence(
      TaskQueue::InsertFencePosition::kBeginningOfTime);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->RemoveFence();
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
  // Post a task while the queue is kNormalPriority and unblocked, but has a
  // backlog of tasks that were blocked.
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true))
      .Times(3);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(4);
  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
  RunLoop().RunUntilIdle();
  testing::Mock::VerifyAndClear(&observer);

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest, TaskObserverBlockedOrLowPriority_Mix) {
  auto queue = CreateTaskQueue();
  testing::StrictMock<MockTaskObserver> observer;
  sequence_manager()->AddTaskObserver(&observer);

  queue->SetQueuePriority(TestQueuePriority::kLowPriority);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->InsertFence(
      TaskQueue::InsertFencePosition::kBeginningOfTime);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  queue->GetTaskQueueImpl()->RemoveFence();
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());

  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/true))
      .Times(3);
  EXPECT_CALL(observer, DidProcessTask(_)).Times(3);
  RunLoop().RunUntilIdle();
  testing::Mock::VerifyAndClear(&observer);

  queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
  queue->task_runner()->PostTask(FROM_HERE, DoNothing());
  EXPECT_CALL(observer,
              WillProcessTask(_, /*was_blocked_or_low_priority=*/false));
  EXPECT_CALL(observer, DidProcessTask(_));
  RunLoop().RunUntilIdle();

  sequence_manager()->RemoveTaskObserver(&observer);
}

TEST_P(SequenceManagerTest, DelayedTaskOrderFromMultipleQueues) {
  // Regression test for crbug.com/1249857. The 4th task posted below should run
  // 4th despite being in queues[0].
  std::vector<EnqueueOrder> run_order;
  auto queues = CreateTaskQueues(3u);

  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 1, &run_order), Milliseconds(9));
  queues[1]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 2, &run_order), Milliseconds(10));
  queues[2]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 3, &run_order), Milliseconds(10));
  queues[0]->task_runner()->PostDelayedTask(
      FROM_HERE, BindOnce(&TestTask, 4, &run_order), Milliseconds(100));

  // All delayed tasks are now ready, but none have run.
  AdvanceMockTickClock(Milliseconds(100));
  RunLoop().RunUntilIdle();

  EXPECT_THAT(run_order, ElementsAre(1u, 2u, 3u, 4u));
}

TEST_P(SequenceManagerTest, OnTaskPostedCallbacks) {
  int counter1 = 0;
  int counter2 = 0;

  auto queue = CreateTaskQueue();

  std::unique_ptr<TaskQueue::OnTaskPostedCallbackHandle> handle1 =
      queue->AddOnTaskPostedHandler(BindRepeating(
          [](int* counter, const Task& task) { ++(*counter); }, &counter1));

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask));
  EXPECT_EQ(1, counter1);
  EXPECT_EQ(0, counter2);

  std::unique_ptr<TaskQueue::OnTaskPostedCallbackHandle> handle2 =
      queue->AddOnTaskPostedHandler(BindRepeating(
          [](int* counter, const Task& task) { ++(*counter); }, &counter2));

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask));
  EXPECT_EQ(2, counter1);
  EXPECT_EQ(1, counter2);

  handle1.reset();

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask));
  EXPECT_EQ(2, counter1);
  EXPECT_EQ(2, counter2);

  handle2.reset();

  queue->task_runner()->PostTask(FROM_HERE, BindOnce(NullTask));
  EXPECT_EQ(2, counter1);
  EXPECT_EQ(2, counter2);
}

TEST(
    SequenceManagerTest,
    CanAccessSingleThreadTaskRunnerCurrentDefaultHandleHandleDuringSequenceLocalStorageSlotDestruction) {
  auto sequence_manager =
      sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
          MessagePump::Create(MessagePumpType::DEFAULT));
  auto queue = sequence_manager->CreateTaskQueue(
      sequence_manager::TaskQueue::Spec(QueueName::DEFAULT_TQ));
  sequence_manager->SetDefaultTaskRunner(queue->task_runner());

  scoped_refptr<SingleThreadTaskRunner> expected_task_runner =
      SingleThreadTaskRunner::GetCurrentDefault();

  StrictMock<MockCallback<base::OnceCallback<void()>>> cb;
  EXPECT_CALL(cb, Run).WillOnce(testing::Invoke([expected_task_runner]() {
    EXPECT_EQ(SingleThreadTaskRunner::GetCurrentDefault(),
              expected_task_runner);
  }));

  static base::SequenceLocalStorageSlot<std::unique_ptr<DestructionCallback>>
      storage_slot;
  storage_slot.GetOrCreateValue() =
      std::make_unique<DestructionCallback>(cb.Get());

  queue.reset();
  sequence_manager.reset();
}

}  // namespace internal
}  // namespace sequence_manager
}  // namespace base
