// Copyright (c) 2012 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/threading/thread_checker.h"

#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_token.h"
#include "base/test/bind_test_util.h"
#include "base/test/gtest_util.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

// A thread that runs a callback.
class RunCallbackThread : public SimpleThread {
 public:
  explicit RunCallbackThread(OnceClosure callback)
      : SimpleThread("RunCallbackThread"), callback_(std::move(callback)) {}

 private:
  // SimpleThread:
  void Run() override { std::move(callback_).Run(); }

  OnceClosure callback_;

  DISALLOW_COPY_AND_ASSIGN(RunCallbackThread);
};

// Runs a callback on a new thread synchronously.
void RunCallbackOnNewThreadSynchronously(OnceClosure callback) {
  RunCallbackThread run_callback_thread(std::move(callback));
  run_callback_thread.Start();
  run_callback_thread.Join();
}

void ExpectCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
  ASSERT_TRUE(thread_checker);

  // This should bind |thread_checker| to the current thread if it wasn't
  // already bound to a thread.
  EXPECT_TRUE(thread_checker->CalledOnValidThread());

  // Since |thread_checker| is now bound to the current thread, another call to
  // CalledOnValidThread() should return true.
  EXPECT_TRUE(thread_checker->CalledOnValidThread());
}

void ExpectNotCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
  ASSERT_TRUE(thread_checker);
  EXPECT_FALSE(thread_checker->CalledOnValidThread());
}

void ExpectNotCalledOnValidThreadWithSequenceTokenAndThreadTaskRunnerHandle(
    ThreadCheckerImpl* thread_checker,
    SequenceToken sequence_token) {
  ThreadTaskRunnerHandle thread_task_runner_handle(
      MakeRefCounted<TestSimpleTaskRunner>());
  ScopedSetSequenceTokenForCurrentThread
      scoped_set_sequence_token_for_current_thread(sequence_token);
  ExpectNotCalledOnValidThread(thread_checker);
}

}  // namespace

TEST(ThreadCheckerTest, AllowedSameThreadNoSequenceToken) {
  ThreadCheckerImpl thread_checker;
  EXPECT_TRUE(thread_checker.CalledOnValidThread());
}

TEST(ThreadCheckerTest,
     AllowedSameThreadAndSequenceDifferentTasksWithThreadTaskRunnerHandle) {
  ThreadTaskRunnerHandle thread_task_runner_handle(
      MakeRefCounted<TestSimpleTaskRunner>());

  std::unique_ptr<ThreadCheckerImpl> thread_checker;
  const SequenceToken sequence_token = SequenceToken::Create();

  {
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(sequence_token);
    thread_checker.reset(new ThreadCheckerImpl);
  }

  {
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(sequence_token);
    EXPECT_TRUE(thread_checker->CalledOnValidThread());
  }
}

TEST(ThreadCheckerTest,
     AllowedSameThreadSequenceAndTaskNoThreadTaskRunnerHandle) {
  ScopedSetSequenceTokenForCurrentThread
      scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
  ThreadCheckerImpl thread_checker;
  EXPECT_TRUE(thread_checker.CalledOnValidThread());
}

TEST(ThreadCheckerTest,
     DisallowedSameThreadAndSequenceDifferentTasksNoThreadTaskRunnerHandle) {
  std::unique_ptr<ThreadCheckerImpl> thread_checker;

  {
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
    thread_checker.reset(new ThreadCheckerImpl);
  }

  {
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
    EXPECT_FALSE(thread_checker->CalledOnValidThread());
  }
}

TEST(ThreadCheckerTest, DisallowedDifferentThreadsNoSequenceToken) {
  ThreadCheckerImpl thread_checker;
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectNotCalledOnValidThread, Unretained(&thread_checker)));
}

TEST(ThreadCheckerTest, DisallowedDifferentThreadsSameSequence) {
  ThreadTaskRunnerHandle thread_task_runner_handle(
      MakeRefCounted<TestSimpleTaskRunner>());
  const SequenceToken sequence_token(SequenceToken::Create());

  ScopedSetSequenceTokenForCurrentThread
      scoped_set_sequence_token_for_current_thread(sequence_token);
  ThreadCheckerImpl thread_checker;
  EXPECT_TRUE(thread_checker.CalledOnValidThread());

  RunCallbackOnNewThreadSynchronously(BindOnce(
      &ExpectNotCalledOnValidThreadWithSequenceTokenAndThreadTaskRunnerHandle,
      Unretained(&thread_checker), sequence_token));
}

TEST(ThreadCheckerTest, DisallowedSameThreadDifferentSequence) {
  std::unique_ptr<ThreadCheckerImpl> thread_checker;

  ThreadTaskRunnerHandle thread_task_runner_handle(
      MakeRefCounted<TestSimpleTaskRunner>());

  {
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
    thread_checker.reset(new ThreadCheckerImpl);
  }

  {
    // Different SequenceToken.
    ScopedSetSequenceTokenForCurrentThread
        scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
    EXPECT_FALSE(thread_checker->CalledOnValidThread());
  }

  // No SequenceToken.
  EXPECT_FALSE(thread_checker->CalledOnValidThread());
}

TEST(ThreadCheckerTest, DetachFromThread) {
  ThreadCheckerImpl thread_checker;
  thread_checker.DetachFromThread();

  // Verify that CalledOnValidThread() returns true when called on a different
  // thread after a call to DetachFromThread().
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));

  EXPECT_FALSE(thread_checker.CalledOnValidThread());
}

TEST(ThreadCheckerTest, DetachFromThreadWithSequenceToken) {
  ThreadTaskRunnerHandle thread_task_runner_handle(
      MakeRefCounted<TestSimpleTaskRunner>());
  ScopedSetSequenceTokenForCurrentThread
      scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
  ThreadCheckerImpl thread_checker;
  thread_checker.DetachFromThread();

  // Verify that CalledOnValidThread() returns true when called on a different
  // thread after a call to DetachFromThread().
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));

  EXPECT_FALSE(thread_checker.CalledOnValidThread());
}

// Owns a ThreadCheckerImpl and asserts that CalledOnValidThread() is valid
// in ~ThreadCheckerOwner.
class ThreadCheckerOwner {
 public:
  explicit ThreadCheckerOwner(bool detach_from_thread) {
    if (detach_from_thread)
      checker_.DetachFromThread();
  }
  ~ThreadCheckerOwner() { EXPECT_TRUE(checker_.CalledOnValidThread()); }

 private:
  ThreadCheckerImpl checker_;

  DISALLOW_COPY_AND_ASSIGN(ThreadCheckerOwner);
};

// Verifies ThreadCheckerImpl::CalledOnValidThread() returns true if called
// during thread destruction.
TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestruction) {
  ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
  RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
    thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(false));
  }));
}

// Variant of CalledOnValidThreadFromThreadDestruction that calls
// ThreadCheckerImpl::DetachFromThread().
TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestructionDetached) {
  ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
  RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
    thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(true));
  }));
}

TEST(ThreadCheckerTest, Move) {
  ThreadCheckerImpl initial;
  EXPECT_TRUE(initial.CalledOnValidThread());

  ThreadCheckerImpl move_constructed(std::move(initial));
  EXPECT_TRUE(move_constructed.CalledOnValidThread());

  ThreadCheckerImpl move_assigned;
  move_assigned = std::move(move_constructed);
  EXPECT_TRUE(move_assigned.CalledOnValidThread());

  // The two ThreadCheckerImpls moved from should be able to rebind to another
  // thread.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&move_constructed)));

  // But the latest one shouldn't be able to run on another thread.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));

  EXPECT_TRUE(move_assigned.CalledOnValidThread());
}

TEST(ThreadCheckerTest, MoveAssignIntoDetached) {
  ThreadCheckerImpl initial;

  ThreadCheckerImpl move_assigned;
  move_assigned.DetachFromThread();
  move_assigned = std::move(initial);

  // |initial| is detached after move.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));

  // |move_assigned| should be associated with the main thread.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));

  EXPECT_TRUE(move_assigned.CalledOnValidThread());
}

TEST(ThreadCheckerTest, MoveFromDetachedRebinds) {
  ThreadCheckerImpl initial;
  initial.DetachFromThread();

  ThreadCheckerImpl moved_into(std::move(initial));

  // |initial| is still detached after move.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));

  // |moved_into| is bound to the current thread as part of the move.
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectNotCalledOnValidThread, Unretained(&moved_into)));
  EXPECT_TRUE(moved_into.CalledOnValidThread());
}

TEST(ThreadCheckerTest, MoveOffThreadBanned) {
  testing::GTEST_FLAG(death_test_style) = "threadsafe";

  ThreadCheckerImpl other_thread;
  other_thread.DetachFromThread();
  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ExpectCalledOnValidThread, Unretained(&other_thread)));

  EXPECT_DCHECK_DEATH(ThreadCheckerImpl main_thread(std::move(other_thread)));
}

namespace {

// This fixture is a helper for unit testing the thread checker macros as it is
// not possible to inline ExpectDeathOnOtherThread() and
// ExpectNoDeathOnOtherThreadAfterDetach() as lambdas since binding
// |Unretained(&my_sequence_checker)| wouldn't compile on non-dcheck builds
// where it won't be defined.
class ThreadCheckerMacroTest : public testing::Test {
 public:
  ThreadCheckerMacroTest() = default;

  void ExpectDeathOnOtherThread() {
#if DCHECK_IS_ON()
    EXPECT_DCHECK_DEATH({ DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_); });
#else
    // Happily no-ops on non-dcheck builds.
    DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_);
#endif
  }

  void ExpectNoDeathOnOtherThreadAfterDetach() {
    DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_);
    DCHECK_CALLED_ON_VALID_THREAD(my_thread_checker_)
        << "Make sure it compiles when DCHECK is off";
  }

 protected:
  THREAD_CHECKER(my_thread_checker_);

 private:
  DISALLOW_COPY_AND_ASSIGN(ThreadCheckerMacroTest);
};

}  // namespace

TEST_F(ThreadCheckerMacroTest, Macros) {
  testing::GTEST_FLAG(death_test_style) = "threadsafe";

  THREAD_CHECKER(my_thread_checker);

  RunCallbackOnNewThreadSynchronously(BindOnce(
      &ThreadCheckerMacroTest::ExpectDeathOnOtherThread, Unretained(this)));

  DETACH_FROM_THREAD(my_thread_checker_);

  RunCallbackOnNewThreadSynchronously(
      BindOnce(&ThreadCheckerMacroTest::ExpectNoDeathOnOtherThreadAfterDetach,
               Unretained(this)));
}

}  // namespace base
