// Copyright 2014 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/cancelable_task_tracker.h"

#include <cstddef>
#include <tuple>

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

class CancelableTaskTrackerTest : public testing::Test {
 protected:
  ~CancelableTaskTrackerTest() override { RunLoop().RunUntilIdle(); }

  CancelableTaskTracker task_tracker_;

 private:
  // Needed by CancelableTaskTracker methods.
  test::TaskEnvironment task_environment_;
};

}  // namespace

// With the task tracker, post a task, a task with a reply, and get a
// new task id without canceling any of them.  The tasks and the reply
// should run and the "is canceled" callback should return false.
TEST_F(CancelableTaskTrackerTest, NoCancel) {
  Thread worker_thread("worker thread");
  ASSERT_TRUE(worker_thread.Start());

  std::ignore =
      task_tracker_.PostTask(worker_thread.task_runner().get(), FROM_HERE,
                             MakeExpectedRunClosure(FROM_HERE));

  std::ignore = task_tracker_.PostTaskAndReply(
      worker_thread.task_runner().get(), FROM_HERE,
      MakeExpectedRunClosure(FROM_HERE), MakeExpectedRunClosure(FROM_HERE));

  CancelableTaskTracker::IsCanceledCallback is_canceled;
  std::ignore = task_tracker_.NewTrackedTaskId(&is_canceled);

  worker_thread.Stop();

  RunLoop().RunUntilIdle();

  EXPECT_FALSE(is_canceled.Run());
}

// Post a task with the task tracker but cancel it before running the
// task runner.  The task should not run.
TEST_F(CancelableTaskTrackerTest, CancelPostedTask) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask(
      test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE));
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  EXPECT_EQ(1U, test_task_runner->NumPendingTasks());

  task_tracker_.TryCancel(task_id);

  test_task_runner->RunUntilIdle();
}

// Post a task with reply with the task tracker and cancel it before
// running the task runner.  Neither the task nor the reply should
// run.
TEST_F(CancelableTaskTrackerTest, CancelPostedTaskAndReply) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  CancelableTaskTracker::TaskId task_id =
      task_tracker_.PostTaskAndReply(test_task_runner.get(),
                                     FROM_HERE,
                                     MakeExpectedNotRunClosure(FROM_HERE),
                                     MakeExpectedNotRunClosure(FROM_HERE));
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  task_tracker_.TryCancel(task_id);

  test_task_runner->RunUntilIdle();
}

// Post a task with reply with the task tracker and cancel it after
// running the task runner but before running the current message
// loop.  The task should run but the reply should not.
TEST_F(CancelableTaskTrackerTest, CancelReply) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  CancelableTaskTracker::TaskId task_id =
      task_tracker_.PostTaskAndReply(test_task_runner.get(),
                                     FROM_HERE,
                                     MakeExpectedRunClosure(FROM_HERE),
                                     MakeExpectedNotRunClosure(FROM_HERE));
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  test_task_runner->RunUntilIdle();

  task_tracker_.TryCancel(task_id);
}

// Post a task with reply with the task tracker on a worker thread and
// cancel it before running the current message loop.  The task should
// run but the reply should not.
TEST_F(CancelableTaskTrackerTest, CancelReplyDifferentThread) {
  Thread worker_thread("worker thread");
  ASSERT_TRUE(worker_thread.Start());

  CancelableTaskTracker::TaskId task_id = task_tracker_.PostTaskAndReply(
      worker_thread.task_runner().get(), FROM_HERE, DoNothing(),
      MakeExpectedNotRunClosure(FROM_HERE));
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  task_tracker_.TryCancel(task_id);

  worker_thread.Stop();
}

void ExpectIsCanceled(
    const CancelableTaskTracker::IsCanceledCallback& is_canceled,
    bool expected_is_canceled) {
  EXPECT_EQ(expected_is_canceled, is_canceled.Run());
}

// Create a new task ID and check its status on a separate thread
// before and after canceling.  The is-canceled callback should be
// thread-safe (i.e., nothing should blow up).
TEST_F(CancelableTaskTrackerTest, NewTrackedTaskIdDifferentThread) {
  CancelableTaskTracker::IsCanceledCallback is_canceled;
  CancelableTaskTracker::TaskId task_id =
      task_tracker_.NewTrackedTaskId(&is_canceled);

  EXPECT_FALSE(is_canceled.Run());

  Thread other_thread("other thread");
  ASSERT_TRUE(other_thread.Start());
  other_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&ExpectIsCanceled, is_canceled, false));
  other_thread.Stop();

  task_tracker_.TryCancel(task_id);

  ASSERT_TRUE(other_thread.Start());
  other_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&ExpectIsCanceled, is_canceled, true));
  other_thread.Stop();
}

// With the task tracker, post a task, a task with a reply, get a new
// task id, and then cancel all of them.  None of the tasks nor the
// reply should run and the "is canceled" callback should return
// true.
TEST_F(CancelableTaskTrackerTest, CancelAll) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  std::ignore = task_tracker_.PostTask(test_task_runner.get(), FROM_HERE,
                                       MakeExpectedNotRunClosure(FROM_HERE));

  std::ignore = task_tracker_.PostTaskAndReply(
      test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE),
      MakeExpectedNotRunClosure(FROM_HERE));

  CancelableTaskTracker::IsCanceledCallback is_canceled;
  std::ignore = task_tracker_.NewTrackedTaskId(&is_canceled);

  task_tracker_.TryCancelAll();

  test_task_runner->RunUntilIdle();

  RunLoop().RunUntilIdle();

  EXPECT_TRUE(is_canceled.Run());
}

// With the task tracker, post a task, a task with a reply, get a new
// task id, and then cancel all of them.  None of the tasks nor the
// reply should run and the "is canceled" callback should return
// true.
TEST_F(CancelableTaskTrackerTest, DestructionCancelsAll) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  CancelableTaskTracker::IsCanceledCallback is_canceled;

  {
    // Create another task tracker with a smaller scope.
    CancelableTaskTracker task_tracker;

    std::ignore = task_tracker.PostTask(test_task_runner.get(), FROM_HERE,
                                        MakeExpectedNotRunClosure(FROM_HERE));

    std::ignore = task_tracker.PostTaskAndReply(
        test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE),
        MakeExpectedNotRunClosure(FROM_HERE));

    std::ignore = task_tracker_.NewTrackedTaskId(&is_canceled);
  }

  test_task_runner->RunUntilIdle();

  RunLoop().RunUntilIdle();

  EXPECT_FALSE(is_canceled.Run());
}

// Post a task and cancel it. HasTrackedTasks() should return false as soon as
// TryCancel() returns, otherwise we may have leaked per-task state.
TEST_F(CancelableTaskTrackerTest, HasTrackedTasksCancelById) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask(
      test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE));
  EXPECT_TRUE(task_tracker_.HasTrackedTasks());

  task_tracker_.TryCancel(task_id);
  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  test_task_runner->RunUntilIdle();
  RunLoop().RunUntilIdle();
}

// Post a task and then cancel all tasks. HasTrackedTasks() should return false
// as soon as TryCancelAll() is called.
TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPostCancelAll) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  std::ignore = task_tracker_.PostTask(test_task_runner.get(), FROM_HERE,
                                       MakeExpectedNotRunClosure(FROM_HERE));

  task_tracker_.TryCancelAll();

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  test_task_runner->RunUntilIdle();
  RunLoop().RunUntilIdle();
}

// Post a task with a reply and cancel it. HasTrackedTasks() should return false
// as soon as TryCancelAll() is called.
TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPostWithReplyCancelAll) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  std::ignore = task_tracker_.PostTaskAndReply(
      test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE),
      MakeExpectedNotRunClosure(FROM_HERE));

  task_tracker_.TryCancelAll();

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  test_task_runner->RunUntilIdle();
  RunLoop().RunUntilIdle();
}

// Create a new tracked task ID. HasTrackedTasks() should return false as soon
// as TryCancelAll() is called.
TEST_F(CancelableTaskTrackerTest, HasTrackedTasksIsCancelledCancelAll) {
  EXPECT_FALSE(task_tracker_.HasTrackedTasks());

  CancelableTaskTracker::IsCanceledCallback is_canceled;
  std::ignore = task_tracker_.NewTrackedTaskId(&is_canceled);

  task_tracker_.TryCancelAll();

  EXPECT_FALSE(task_tracker_.HasTrackedTasks());
}

// The death tests below make sure that calling task tracker member
// functions from a thread different from its owner thread DCHECKs in
// debug mode.

class CancelableTaskTrackerDeathTest : public CancelableTaskTrackerTest {
 protected:
  CancelableTaskTrackerDeathTest() {
    // The default style "fast" does not support multi-threaded tests.
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  }
};

// Runs |fn| with |task_tracker|, expecting it to crash in debug mode.
void MaybeRunDeadlyTaskTrackerMemberFunction(
    CancelableTaskTracker* task_tracker,
    OnceCallback<void(CancelableTaskTracker*)> fn) {
  EXPECT_DCHECK_DEATH(std::move(fn).Run(task_tracker));
}

void PostDoNothingTask(CancelableTaskTracker* task_tracker) {
  std::ignore = task_tracker->PostTask(
      scoped_refptr<TestSimpleTaskRunner>(new TestSimpleTaskRunner()).get(),
      FROM_HERE, DoNothing());
}

TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) {
  Thread bad_thread("bad thread");
  ASSERT_TRUE(bad_thread.Start());

  bad_thread.task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&MaybeRunDeadlyTaskTrackerMemberFunction,
               Unretained(&task_tracker_), BindOnce(&PostDoNothingTask)));
}

void TryCancel(CancelableTaskTracker::TaskId task_id,
               CancelableTaskTracker* task_tracker) {
  task_tracker->TryCancel(task_id);
}

TEST_F(CancelableTaskTrackerDeathTest, CancelOnDifferentThread) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  Thread bad_thread("bad thread");
  ASSERT_TRUE(bad_thread.Start());

  CancelableTaskTracker::TaskId task_id =
      task_tracker_.PostTask(test_task_runner.get(), FROM_HERE, DoNothing());
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  bad_thread.task_runner()->PostTask(
      FROM_HERE,
      BindOnce(&MaybeRunDeadlyTaskTrackerMemberFunction,
               Unretained(&task_tracker_), BindOnce(&TryCancel, task_id)));

  test_task_runner->RunUntilIdle();
}

TEST_F(CancelableTaskTrackerDeathTest, CancelAllOnDifferentThread) {
  scoped_refptr<TestSimpleTaskRunner> test_task_runner(
      new TestSimpleTaskRunner());

  Thread bad_thread("bad thread");
  ASSERT_TRUE(bad_thread.Start());

  CancelableTaskTracker::TaskId task_id =
      task_tracker_.PostTask(test_task_runner.get(), FROM_HERE, DoNothing());
  EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);

  bad_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&MaybeRunDeadlyTaskTrackerMemberFunction,
                          Unretained(&task_tracker_),
                          BindOnce(&CancelableTaskTracker::TryCancelAll)));

  test_task_runner->RunUntilIdle();
}

}  // namespace base
