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

#include "base/run_loop.h"

#include <functional>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind_test_util.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker_impl.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

void QuitWhenIdleTask(RunLoop* run_loop, int* counter) {
  run_loop->QuitWhenIdle();
  ++(*counter);
}

void RunNestedLoopTask(int* counter) {
  RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);

  // This task should quit |nested_run_loop| but not the main RunLoop.
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&nested_run_loop),
                          Unretained(counter)));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), TimeDelta::FromDays(1));

  nested_run_loop.Run();

  ++(*counter);
}

// A simple SingleThreadTaskRunner that just queues undelayed tasks (and ignores
// delayed tasks). Tasks can then be processed one by one by ProcessTask() which
// will return true if it processed a task and false otherwise.
class SimpleSingleThreadTaskRunner : public SingleThreadTaskRunner {
 public:
  SimpleSingleThreadTaskRunner() = default;

  bool PostDelayedTask(const Location& from_here,
                       OnceClosure task,
                       base::TimeDelta delay) override {
    if (delay > base::TimeDelta())
      return false;
    AutoLock auto_lock(tasks_lock_);
    pending_tasks_.push(std::move(task));
    return true;
  }

  bool PostNonNestableDelayedTask(const Location& from_here,
                                  OnceClosure task,
                                  base::TimeDelta delay) override {
    return PostDelayedTask(from_here, std::move(task), delay);
  }

  bool RunsTasksInCurrentSequence() const override {
    return origin_thread_checker_.CalledOnValidThread();
  }

  bool ProcessSingleTask() {
    OnceClosure task;
    {
      AutoLock auto_lock(tasks_lock_);
      if (pending_tasks_.empty())
        return false;
      task = std::move(pending_tasks_.front());
      pending_tasks_.pop();
    }
    // It's important to Run() after pop() and outside the lock as |task| may
    // run a nested loop which will re-enter ProcessSingleTask().
    std::move(task).Run();
    return true;
  }

 private:
  ~SimpleSingleThreadTaskRunner() override = default;

  Lock tasks_lock_;
  base::queue<OnceClosure> pending_tasks_;

  // RunLoop relies on RunsTasksInCurrentSequence() signal. Use a
  // ThreadCheckerImpl to be able to reliably provide that signal even in
  // non-dcheck builds.
  ThreadCheckerImpl origin_thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(SimpleSingleThreadTaskRunner);
};

// The basis of all TestDelegates, allows safely injecting a OnceClosure to be
// run in the next idle phase of this delegate's Run() implementation. This can
// be used to have code run on a thread that is otherwise livelocked in an idle
// phase (sometimes a simple PostTask() won't do it -- e.g. when processing
// application tasks is disallowed).
class InjectableTestDelegate : public RunLoop::Delegate {
 public:
  void InjectClosureOnDelegate(OnceClosure closure) {
    AutoLock auto_lock(closure_lock_);
    closure_ = std::move(closure);
  }

  bool RunInjectedClosure() {
    AutoLock auto_lock(closure_lock_);
    if (closure_.is_null())
      return false;
    std::move(closure_).Run();
    return true;
  }

 private:
  Lock closure_lock_;
  OnceClosure closure_;
};

// A simple test RunLoop::Delegate to exercise Runloop logic independent of any
// other base constructs. BindToCurrentThread() must be called before this
// TestBoundDelegate is operational.
class TestBoundDelegate final : public InjectableTestDelegate {
 public:
  TestBoundDelegate() = default;

  // Makes this TestBoundDelegate become the RunLoop::Delegate and
  // ThreadTaskRunnerHandle for this thread.
  void BindToCurrentThread() {
    thread_task_runner_handle_ =
        std::make_unique<ThreadTaskRunnerHandle>(simple_task_runner_);
    RunLoop::RegisterDelegateForCurrentThread(this);
  }

 private:
  void Run(bool application_tasks_allowed, TimeDelta timeout) override {
    if (nested_run_allowing_tasks_incoming_) {
      EXPECT_TRUE(RunLoop::IsNestedOnCurrentThread());
      EXPECT_TRUE(application_tasks_allowed);
    } else if (RunLoop::IsNestedOnCurrentThread()) {
      EXPECT_FALSE(application_tasks_allowed);
    }
    nested_run_allowing_tasks_incoming_ = false;

    while (!should_quit_) {
      if (application_tasks_allowed && simple_task_runner_->ProcessSingleTask())
        continue;

      if (ShouldQuitWhenIdle())
        break;

      if (RunInjectedClosure())
        continue;

      PlatformThread::YieldCurrentThread();
    }
    should_quit_ = false;
  }

  void Quit() override { should_quit_ = true; }

  void EnsureWorkScheduled() override {
    nested_run_allowing_tasks_incoming_ = true;
  }

  // True if the next invocation of Run() is expected to be from a
  // kNestableTasksAllowed RunLoop.
  bool nested_run_allowing_tasks_incoming_ = false;

  scoped_refptr<SimpleSingleThreadTaskRunner> simple_task_runner_ =
      MakeRefCounted<SimpleSingleThreadTaskRunner>();

  std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;

  bool should_quit_ = false;
};

enum class RunLoopTestType {
  // Runs all RunLoopTests under a ScopedTaskEnvironment to make sure real world
  // scenarios work.
  kRealEnvironment,

  // Runs all RunLoopTests under a test RunLoop::Delegate to make sure the
  // delegate interface fully works standalone.
  kTestDelegate,
};

// The task environment for the RunLoopTest of a given type. A separate class
// so it can be instantiated on the stack in the RunLoopTest fixture.
class RunLoopTestEnvironment {
 public:
  RunLoopTestEnvironment(RunLoopTestType type) {
    switch (type) {
      case RunLoopTestType::kRealEnvironment: {
        task_environment_ = std::make_unique<test::ScopedTaskEnvironment>();
        break;
      }
      case RunLoopTestType::kTestDelegate: {
        auto test_delegate = std::make_unique<TestBoundDelegate>();
        test_delegate->BindToCurrentThread();
        test_delegate_ = std::move(test_delegate);
        break;
      }
    }
  }

 private:
  // Instantiates one or the other based on the RunLoopTestType.
  std::unique_ptr<test::ScopedTaskEnvironment> task_environment_;
  std::unique_ptr<InjectableTestDelegate> test_delegate_;
};

class RunLoopTest : public testing::TestWithParam<RunLoopTestType> {
 protected:
  RunLoopTest() : test_environment_(GetParam()) {}

  RunLoopTestEnvironment test_environment_;
  RunLoop run_loop_;

 private:
  DISALLOW_COPY_AND_ASSIGN(RunLoopTest);
};

}  // namespace

TEST_P(RunLoopTest, QuitWhenIdle) {
  int counter = 0;
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_),
                          Unretained(&counter)));
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), TimeDelta::FromDays(1));

  run_loop_.Run();
  EXPECT_EQ(1, counter);
}

TEST_P(RunLoopTest, QuitWhenIdleNestedLoop) {
  int counter = 0;
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, BindOnce(&RunNestedLoopTask, Unretained(&counter)));
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, BindOnce(&QuitWhenIdleTask, Unretained(&run_loop_),
                          Unretained(&counter)));
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), TimeDelta::FromDays(1));

  run_loop_.Run();
  EXPECT_EQ(3, counter);
}

TEST_P(RunLoopTest, QuitWhenIdleClosure) {
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          run_loop_.QuitWhenIdleClosure());
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE), TimeDelta::FromDays(1));

  run_loop_.Run();
}

TEST_P(RunLoopTest, RunWithTimeout) {
  // SimpleSingleThreadTaskRunner doesn't support delayed tasks.
  if (GetParam() == RunLoopTestType::kTestDelegate)
    return;

  bool task1_run = false;
  bool task2_run = false;
  bool task3_run = false;
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task1_run = true; }),
      TimeDelta::FromMilliseconds(10));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task2_run = true; }),
      TimeDelta::FromMilliseconds(20));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task3_run = true; }),
      TimeDelta::FromSeconds(10));

  run_loop_.RunWithTimeout(TimeDelta::FromMilliseconds(20));
  EXPECT_TRUE(task1_run);
  EXPECT_TRUE(task2_run);
  EXPECT_FALSE(task3_run);
}

TEST_P(RunLoopTest, NestedRunWithTimeout) {
  // SimpleSingleThreadTaskRunner doesn't support delayed tasks.
  if (GetParam() == RunLoopTestType::kTestDelegate)
    return;

  bool task1_run = false;
  bool task2_run = false;
  bool task3_run = false;
  bool task4_run = false;
  bool task5_run = false;
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task1_run = true; }),
      TimeDelta::FromMilliseconds(10));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        task2_run = true;
        EXPECT_FALSE(task3_run);
        RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);
        nested_run_loop.RunWithTimeout(TimeDelta::FromMilliseconds(20));
        EXPECT_TRUE(task3_run);
        EXPECT_TRUE(task4_run);
      }),
      TimeDelta::FromMilliseconds(20));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task3_run = true; }),
      TimeDelta::FromMilliseconds(30));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task4_run = true; }),
      TimeDelta::FromMilliseconds(40));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task5_run = true; }),
      TimeDelta::FromSeconds(10));

  run_loop_.RunWithTimeout(TimeDelta::FromMilliseconds(40));
  EXPECT_TRUE(task1_run);
  EXPECT_TRUE(task2_run);
  EXPECT_TRUE(task3_run);
  EXPECT_TRUE(task4_run);
  EXPECT_FALSE(task5_run);
}

TEST_P(RunLoopTest, NestedRunWithTimeoutWhereInnerLoopHasALongerTimeout) {
  // SimpleSingleThreadTaskRunner doesn't support delayed tasks.
  if (GetParam() == RunLoopTestType::kTestDelegate)
    return;

  bool task1_run = false;
  bool task2_run = false;
  bool task3_run = false;
  bool task4_run = false;
  bool task5_run = false;
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task1_run = true; }),
      TimeDelta::FromMilliseconds(10));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() {
        task2_run = true;
        EXPECT_FALSE(task3_run);
        RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);
        nested_run_loop.RunWithTimeout(TimeDelta::FromMilliseconds(50));
        EXPECT_TRUE(task3_run);
        EXPECT_TRUE(task4_run);
      }),
      TimeDelta::FromMilliseconds(20));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task3_run = true; }),
      TimeDelta::FromMilliseconds(30));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task4_run = true; }),
      TimeDelta::FromMilliseconds(40));

  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, BindLambdaForTesting([&]() { task5_run = true; }),
      TimeDelta::FromMilliseconds(50));

  run_loop_.RunWithTimeout(TimeDelta::FromMilliseconds(40));
  EXPECT_TRUE(task1_run);
  EXPECT_TRUE(task2_run);
  EXPECT_TRUE(task3_run);
  EXPECT_TRUE(task4_run);
  EXPECT_TRUE(task5_run);
}

// Verify that the QuitWhenIdleClosure() can run after the RunLoop has been
// deleted. It should have no effect.
TEST_P(RunLoopTest, QuitWhenIdleClosureAfterRunLoopScope) {
  Closure quit_when_idle_closure;
  {
    RunLoop run_loop;
    quit_when_idle_closure = run_loop.QuitWhenIdleClosure();
    run_loop.RunUntilIdle();
  }
  quit_when_idle_closure.Run();
}

// Verify that Quit can be executed from another sequence.
TEST_P(RunLoopTest, QuitFromOtherSequence) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  // Always expected to run before asynchronous Quit() kicks in.
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  WaitableEvent loop_was_quit(WaitableEvent::ResetPolicy::MANUAL,
                              WaitableEvent::InitialState::NOT_SIGNALED);
  other_sequence->PostTask(
      FROM_HERE, base::BindOnce([](RunLoop* run_loop) { run_loop->Quit(); },
                                Unretained(&run_loop_)));
  other_sequence->PostTask(
      FROM_HERE,
      base::BindOnce(&WaitableEvent::Signal, base::Unretained(&loop_was_quit)));

  // Anything that's posted after the Quit closure was posted back to this
  // sequence shouldn't get a chance to run.
  loop_was_quit.Wait();
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedNotRunClosure(FROM_HERE));

  run_loop_.Run();
}

// Verify that QuitClosure can be executed from another sequence.
TEST_P(RunLoopTest, QuitFromOtherSequenceWithClosure) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  // Always expected to run before asynchronous Quit() kicks in.
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  WaitableEvent loop_was_quit(WaitableEvent::ResetPolicy::MANUAL,
                              WaitableEvent::InitialState::NOT_SIGNALED);
  other_sequence->PostTask(FROM_HERE, run_loop_.QuitClosure());
  other_sequence->PostTask(
      FROM_HERE,
      base::BindOnce(&WaitableEvent::Signal, base::Unretained(&loop_was_quit)));

  // Anything that's posted after the Quit closure was posted back to this
  // sequence shouldn't get a chance to run.
  loop_was_quit.Wait();
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedNotRunClosure(FROM_HERE));

  run_loop_.Run();
}

// Verify that Quit can be executed from another sequence even when the
// Quit is racing with Run() -- i.e. forgo the WaitableEvent used above.
TEST_P(RunLoopTest, QuitFromOtherSequenceRacy) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  // Always expected to run before asynchronous Quit() kicks in.
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  other_sequence->PostTask(FROM_HERE, run_loop_.QuitClosure());

  run_loop_.Run();
}

// Verify that QuitClosure can be executed from another sequence even when the
// Quit is racing with Run() -- i.e. forgo the WaitableEvent used above.
TEST_P(RunLoopTest, QuitFromOtherSequenceRacyWithClosure) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  // Always expected to run before asynchronous Quit() kicks in.
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  other_sequence->PostTask(FROM_HERE, run_loop_.QuitClosure());

  run_loop_.Run();
}

// Verify that QuitWhenIdle can be executed from another sequence.
TEST_P(RunLoopTest, QuitWhenIdleFromOtherSequence) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  other_sequence->PostTask(
      FROM_HERE,
      base::BindOnce([](RunLoop* run_loop) { run_loop->QuitWhenIdle(); },
                     Unretained(&run_loop_)));

  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  run_loop_.Run();

  // Regardless of the outcome of the race this thread shouldn't have been idle
  // until both tasks posted to this sequence have run.
}

// Verify that QuitWhenIdleClosure can be executed from another sequence.
TEST_P(RunLoopTest, QuitWhenIdleFromOtherSequenceWithClosure) {
  Thread other_thread("test");
  other_thread.Start();
  scoped_refptr<SequencedTaskRunner> other_sequence =
      other_thread.task_runner();

  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  other_sequence->PostTask(FROM_HERE, run_loop_.QuitWhenIdleClosure());

  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                          MakeExpectedRunClosure(FROM_HERE));

  run_loop_.Run();

  // Regardless of the outcome of the race this thread shouldn't have been idle
  // until the both tasks posted to this sequence have run.
}

TEST_P(RunLoopTest, IsRunningOnCurrentThread) {
  EXPECT_FALSE(RunLoop::IsRunningOnCurrentThread());
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      BindOnce([]() { EXPECT_TRUE(RunLoop::IsRunningOnCurrentThread()); }));
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop_.QuitClosure());
  run_loop_.Run();
}

TEST_P(RunLoopTest, IsNestedOnCurrentThread) {
  EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());

  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, BindOnce([]() {
        EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());

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

        ThreadTaskRunnerHandle::Get()->PostTask(
            FROM_HERE, BindOnce([]() {
              EXPECT_TRUE(RunLoop::IsNestedOnCurrentThread());
            }));
        ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                nested_run_loop.QuitClosure());

        EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
        nested_run_loop.Run();
        EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
      }));

  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop_.QuitClosure());
  run_loop_.Run();
}

namespace {

class MockNestingObserver : public RunLoop::NestingObserver {
 public:
  MockNestingObserver() = default;

  // RunLoop::NestingObserver:
  MOCK_METHOD0(OnBeginNestedRunLoop, void());
  MOCK_METHOD0(OnExitNestedRunLoop, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockNestingObserver);
};

class MockTask {
 public:
  MockTask() = default;
  MOCK_METHOD0(Task, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockTask);
};

}  // namespace

TEST_P(RunLoopTest, NestingObservers) {
  testing::StrictMock<MockNestingObserver> nesting_observer;
  testing::StrictMock<MockTask> mock_task_a;
  testing::StrictMock<MockTask> mock_task_b;

  RunLoop::AddNestingObserverOnCurrentThread(&nesting_observer);

  const RepeatingClosure run_nested_loop = BindRepeating([]() {
    RunLoop nested_run_loop(RunLoop::Type::kNestableTasksAllowed);
    ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                            nested_run_loop.QuitClosure());
    nested_run_loop.Run();
  });

  // Generate a stack of nested RunLoops. OnBeginNestedRunLoop() is expected
  // when beginning each nesting depth and OnExitNestedRunLoop() is expected
  // when exiting each nesting depth. Each one of these tasks is ahead of the
  // QuitClosures as those are only posted at the end of the queue when
  // |run_nested_loop| is executed.
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_nested_loop);
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&MockTask::Task, base::Unretained(&mock_task_a)));
  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_nested_loop);
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&MockTask::Task, base::Unretained(&mock_task_b)));

  {
    testing::InSequence in_sequence;
    EXPECT_CALL(nesting_observer, OnBeginNestedRunLoop());
    EXPECT_CALL(mock_task_a, Task());
    EXPECT_CALL(nesting_observer, OnBeginNestedRunLoop());
    EXPECT_CALL(mock_task_b, Task());
    EXPECT_CALL(nesting_observer, OnExitNestedRunLoop()).Times(2);
  }
  run_loop_.RunUntilIdle();

  RunLoop::RemoveNestingObserverOnCurrentThread(&nesting_observer);
}

TEST_P(RunLoopTest, DisallowRunningForTesting) {
  RunLoop::ScopedDisallowRunningForTesting disallow_running;
  EXPECT_DCHECK_DEATH({ run_loop_.RunUntilIdle(); });
}

TEST_P(RunLoopTest, ExpiredDisallowRunningForTesting) {
  { RunLoop::ScopedDisallowRunningForTesting disallow_running; }
  // Running should be fine after |disallow_running| goes out of scope.
  run_loop_.RunUntilIdle();
}

INSTANTIATE_TEST_SUITE_P(Real,
                         RunLoopTest,
                         testing::Values(RunLoopTestType::kRealEnvironment));
INSTANTIATE_TEST_SUITE_P(Mock,
                         RunLoopTest,
                         testing::Values(RunLoopTestType::kTestDelegate));

TEST(ScopedRunTimeoutForTestTest, TimesOut) {
  test::ScopedTaskEnvironment task_environment;
  RunLoop run_loop;

  static constexpr auto kArbitraryTimeout =
      base::TimeDelta::FromMilliseconds(10);
  RunLoop::ScopedRunTimeoutForTest run_timeout(
      kArbitraryTimeout, MakeExpectedRunAtLeastOnceClosure(FROM_HERE));

  // Since the delayed task will be posted only after the message pump starts
  // running, the ScopedRunTimeoutForTest will already have started to elapse,
  // so if Run() exits at the correct time then our delayed task will not run.
  SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&SequencedTaskRunner::PostDelayedTask),
                     SequencedTaskRunnerHandle::Get(), FROM_HERE,
                     MakeExpectedNotRunClosure(FROM_HERE), kArbitraryTimeout));

  // This task should get to run before Run() times-out.
  SequencedTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedRunClosure(FROM_HERE), kArbitraryTimeout);

  run_loop.Run();
}

TEST(ScopedRunTimeoutForTestTest, RunTasksUntilTimeout) {
  test::ScopedTaskEnvironment task_environment;
  RunLoop run_loop;

  static constexpr auto kArbitraryTimeout =
      base::TimeDelta::FromMilliseconds(10);
  RunLoop::ScopedRunTimeoutForTest run_timeout(
      kArbitraryTimeout, MakeExpectedRunAtLeastOnceClosure(FROM_HERE));

  // Posting a task with the same delay as our timeout, immediately before
  // calling Run(), means it should get to run. Since this uses QuitWhenIdle(),
  // the Run() timeout callback should also get to run.
  SequencedTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, MakeExpectedRunClosure(FROM_HERE), kArbitraryTimeout);

  run_loop.Run();
}

TEST(RunLoopDeathTest, MustRegisterBeforeInstantiating) {
  TestBoundDelegate unbound_test_delegate_;
  // RunLoop::RunLoop() should CHECK fetching the ThreadTaskRunnerHandle.
  EXPECT_DEATH_IF_SUPPORTED({ RunLoop(); }, "");
}

TEST(RunLoopDelegateTest, NestableTasksDontRunInDefaultNestedLoops) {
  TestBoundDelegate test_delegate;
  test_delegate.BindToCurrentThread();

  base::Thread other_thread("test");
  other_thread.Start();

  RunLoop main_loop;
  // A nested run loop which isn't kNestableTasksAllowed.
  RunLoop nested_run_loop(RunLoop::Type::kDefault);

  bool nested_run_loop_ended = false;

  // The first task on the main loop will result in a nested run loop. Since
  // it's not kNestableTasksAllowed, no further task should be processed until
  // it's quit.
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      BindOnce([](RunLoop* nested_run_loop) { nested_run_loop->Run(); },
               Unretained(&nested_run_loop)));

  // Post a task that will fail if it runs inside the nested run loop.
  ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      BindOnce(
          [](const bool& nested_run_loop_ended,
             OnceClosure continuation_callback) {
            EXPECT_TRUE(nested_run_loop_ended);
            EXPECT_FALSE(RunLoop::IsNestedOnCurrentThread());
            std::move(continuation_callback).Run();
          },
          std::cref(nested_run_loop_ended), main_loop.QuitClosure()));

  // Post a task flipping the boolean bit for extra verification right before
  // quitting |nested_run_loop|.
  other_thread.task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(
          [](bool* nested_run_loop_ended) {
            EXPECT_FALSE(*nested_run_loop_ended);
            *nested_run_loop_ended = true;
          },
          Unretained(&nested_run_loop_ended)),
      TestTimeouts::tiny_timeout());
  // Post an async delayed task to exit the run loop when idle. This confirms
  // that (1) the test task only ran in the main loop after the nested loop
  // exited and (2) the nested run loop actually considers itself idle while
  // spinning. Note: The quit closure needs to be injected directly on the
  // delegate as invoking QuitWhenIdle() off-thread results in a thread bounce
  // which will not processed because of the very logic under test (nestable
  // tasks don't run in |nested_run_loop|).
  other_thread.task_runner()->PostDelayedTask(
      FROM_HERE,
      BindOnce(
          [](TestBoundDelegate* test_delegate, OnceClosure injected_closure) {
            test_delegate->InjectClosureOnDelegate(std::move(injected_closure));
          },
          Unretained(&test_delegate), nested_run_loop.QuitWhenIdleClosure()),
      TestTimeouts::tiny_timeout());

  main_loop.Run();
}

}  // namespace base
