// Copyright 2013 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/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/sequence_checker.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

// Duplicated from base/sequence_checker.h so that we can be good citizens
// there and undef the macro.
#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
#define ENABLE_SEQUENCE_CHECKER 1
#else
#define ENABLE_SEQUENCE_CHECKER 0
#endif

namespace base {

namespace {

const size_t kNumWorkerThreads = 3;

// Simple class to exercise the basics of SequenceChecker.
// DoStuff should verify that it's called on a valid sequenced thread.
// SequenceCheckedObject can be destroyed on any thread (like WeakPtr).
class SequenceCheckedObject {
 public:
  SequenceCheckedObject() {}
  ~SequenceCheckedObject() {}

  // Verifies that it was called on the same thread as the constructor.
  void DoStuff() {
    DCHECK(sequence_checker_.CalledOnValidSequencedThread());
  }

  void DetachFromSequence() {
    sequence_checker_.DetachFromSequence();
  }

 private:
  SequenceChecker sequence_checker_;

  DISALLOW_COPY_AND_ASSIGN(SequenceCheckedObject);
};

class SequenceCheckerTest : public testing::Test {
 public:
  SequenceCheckerTest() : other_thread_("sequence_checker_test_other_thread") {}

  virtual ~SequenceCheckerTest() {}

  virtual void SetUp() OVERRIDE {
    other_thread_.Start();
    ResetPool();
  }

  virtual void TearDown() OVERRIDE {
    other_thread_.Stop();
    pool()->Shutdown();
  }

 protected:
  base::Thread* other_thread() { return &other_thread_; }

  const scoped_refptr<SequencedWorkerPool>& pool() {
    return pool_owner_->pool();
  }

  void PostDoStuffToWorkerPool(SequenceCheckedObject* sequence_checked_object,
                               const std::string& token_name) {
    pool()->PostNamedSequencedWorkerTask(
        token_name,
        FROM_HERE,
        base::Bind(&SequenceCheckedObject::DoStuff,
                   base::Unretained(sequence_checked_object)));
  }

  void PostDoStuffToOtherThread(
      SequenceCheckedObject* sequence_checked_object) {
    other_thread()->message_loop()->PostTask(
        FROM_HERE,
        base::Bind(&SequenceCheckedObject::DoStuff,
                   base::Unretained(sequence_checked_object)));
  }

  void PostDeleteToOtherThread(
      scoped_ptr<SequenceCheckedObject> sequence_checked_object) {
    other_thread()->message_loop()->DeleteSoon(
        FROM_HERE,
        sequence_checked_object.release());
  }

  // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
  // down, and creates a new instance.
  void ResetPool() {
    pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test"));
  }

  void MethodOnDifferentThreadDeathTest();
  void DetachThenCallFromDifferentThreadDeathTest();
  void DifferentSequenceTokensDeathTest();
  void WorkerPoolAndSimpleThreadDeathTest();
  void TwoDifferentWorkerPoolsDeathTest();

 private:
  MessageLoop message_loop_;  // Needed by SequencedWorkerPool to function.
  base::Thread other_thread_;
  scoped_ptr<SequencedWorkerPoolOwner> pool_owner_;
};

TEST_F(SequenceCheckerTest, CallsAllowedOnSameThread) {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  // Verify that DoStuff doesn't assert.
  sequence_checked_object->DoStuff();

  // Verify that the destructor doesn't assert.
  sequence_checked_object.reset();
}

TEST_F(SequenceCheckerTest, DestructorAllowedOnDifferentThread) {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  // Verify the destructor doesn't assert when called on a different thread.
  PostDeleteToOtherThread(sequence_checked_object.Pass());
  other_thread()->Stop();
}

TEST_F(SequenceCheckerTest, DetachFromSequence) {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  // Verify that DoStuff doesn't assert when called on a different thread after
  // a call to DetachFromSequence.
  sequence_checked_object->DetachFromSequence();

  PostDoStuffToOtherThread(sequence_checked_object.get());
  other_thread()->Stop();
}

TEST_F(SequenceCheckerTest, SameSequenceTokenValid) {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  pool()->FlushForTesting();

  PostDeleteToOtherThread(sequence_checked_object.Pass());
  other_thread()->Stop();
}

TEST_F(SequenceCheckerTest, DetachSequenceTokenValid) {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  pool()->FlushForTesting();

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
  pool()->FlushForTesting();

  PostDeleteToOtherThread(sequence_checked_object.Pass());
  other_thread()->Stop();
}

#if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER

void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  // DoStuff should assert in debug builds only when called on a
  // different thread.
  PostDoStuffToOtherThread(sequence_checked_object.get());
  other_thread()->Stop();
}

#if ENABLE_SEQUENCE_CHECKER
TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) {
  // The default style "fast" does not support multi-threaded tests.
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_DEATH({
    MethodOnDifferentThreadDeathTest();
  }, "");
}
#else
TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) {
  MethodOnDifferentThreadDeathTest();
}
#endif  // ENABLE_SEQUENCE_CHECKER

void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  // DoStuff doesn't assert when called on a different thread
  // after a call to DetachFromSequence.
  sequence_checked_object->DetachFromSequence();
  PostDoStuffToOtherThread(sequence_checked_object.get());
  other_thread()->Stop();

  // DoStuff should assert in debug builds only after moving to
  // another thread.
  sequence_checked_object->DoStuff();
}

#if ENABLE_SEQUENCE_CHECKER
TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) {
  // The default style "fast" does not support multi-threaded tests.
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_DEATH({
    DetachThenCallFromDifferentThreadDeathTest();
  }, "");
}
#else
TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) {
  DetachThenCallFromDifferentThreadDeathTest();
}
#endif  // ENABLE_SEQUENCE_CHECKER

void SequenceCheckerTest::DifferentSequenceTokensDeathTest() {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "B");
  pool()->FlushForTesting();

  PostDeleteToOtherThread(sequence_checked_object.Pass());
  other_thread()->Stop();
}

#if ENABLE_SEQUENCE_CHECKER
TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) {
  // The default style "fast" does not support multi-threaded tests.
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_DEATH({
    DifferentSequenceTokensDeathTest();
  }, "");
}
#else
TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInRelease) {
  DifferentSequenceTokensDeathTest();
}
#endif  // ENABLE_SEQUENCE_CHECKER

void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  pool()->FlushForTesting();

  PostDoStuffToOtherThread(sequence_checked_object.get());
  other_thread()->Stop();
}

#if ENABLE_SEQUENCE_CHECKER
TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) {
  // The default style "fast" does not support multi-threaded tests.
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_DEATH({
    WorkerPoolAndSimpleThreadDeathTest();
  }, "");
}
#else
TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInRelease) {
  WorkerPoolAndSimpleThreadDeathTest();
}
#endif  // ENABLE_SEQUENCE_CHECKER

void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() {
  scoped_ptr<SequenceCheckedObject> sequence_checked_object(
      new SequenceCheckedObject);

  sequence_checked_object->DetachFromSequence();
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  PostDoStuffToWorkerPool(sequence_checked_object.get(), "A");
  pool()->FlushForTesting();

  SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2");
  second_pool_owner.pool()->PostNamedSequencedWorkerTask(
      "A",
      FROM_HERE,
      base::Bind(&SequenceCheckedObject::DoStuff,
                 base::Unretained(sequence_checked_object.get())));
  second_pool_owner.pool()->FlushForTesting();
  second_pool_owner.pool()->Shutdown();
}

#if ENABLE_SEQUENCE_CHECKER
TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) {
  // The default style "fast" does not support multi-threaded tests.
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_DEATH({
    TwoDifferentWorkerPoolsDeathTest();
  }, "");
}
#else
TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInRelease) {
  TwoDifferentWorkerPoolsDeathTest();
}
#endif  // ENABLE_SEQUENCE_CHECKER

#endif  // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER

}  // namespace

}  // namespace base

// Just in case we ever get lumped together with other compilation units.
#undef ENABLE_SEQUENCE_CHECKER
