// Copyright (c) 2011 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 "net/dns/serial_worker.h"

#include "base/bind.h"
#include "base/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class SerialWorkerTest : public testing::Test {
 public:
  // The class under test
  class TestSerialWorker : public SerialWorker {
   public:
    explicit TestSerialWorker(SerialWorkerTest* t)
      : test_(t) {}
    virtual void DoWork() override {
      ASSERT_TRUE(test_);
      test_->OnWork();
    }
    virtual void OnWorkFinished() override {
      ASSERT_TRUE(test_);
      test_->OnWorkFinished();
    }
   private:
    virtual ~TestSerialWorker() {}
    SerialWorkerTest* test_;
  };

  // Mocks

  void OnWork() {
    { // Check that OnWork is executed serially.
      base::AutoLock lock(work_lock_);
      EXPECT_FALSE(work_running_) << "DoRead is not called serially!";
      work_running_ = true;
    }
    BreakNow("OnWork");
    work_allowed_.Wait();
    // Calling from WorkerPool, but protected by work_allowed_/work_called_.
    output_value_ = input_value_;

    { // This lock might be destroyed after work_called_ is signalled.
      base::AutoLock lock(work_lock_);
      work_running_ = false;
    }
    work_called_.Signal();
  }

  void OnWorkFinished() {
    EXPECT_TRUE(message_loop_ == MessageLoop::current());
    EXPECT_EQ(output_value_, input_value_);
    BreakNow("OnWorkFinished");
  }

 protected:
  void BreakCallback(std::string breakpoint) {
    breakpoint_ = breakpoint;
    MessageLoop::current()->QuitNow();
  }

  void BreakNow(std::string b) {
    message_loop_->PostTask(FROM_HERE,
        base::Bind(&SerialWorkerTest::BreakCallback,
                   base::Unretained(this), b));
  }

  void RunUntilBreak(std::string b) {
    message_loop_->Run();
    ASSERT_EQ(breakpoint_, b);
  }

  SerialWorkerTest()
      : input_value_(0),
        output_value_(-1),
        work_allowed_(false, false),
        work_called_(false, false),
        work_running_(false) {
  }

  // Helpers for tests.

  // Lets OnWork run and waits for it to complete. Can only return if OnWork is
  // executed on a concurrent thread.
  void WaitForWork() {
    RunUntilBreak("OnWork");
    work_allowed_.Signal();
    work_called_.Wait();
  }

  // test::Test methods
  virtual void SetUp() override {
    message_loop_ = MessageLoop::current();
    worker_ = new TestSerialWorker(this);
  }

  virtual void TearDown() override {
    // Cancel the worker to catch if it makes a late DoWork call.
    worker_->Cancel();
    // Check if OnWork is stalled.
    EXPECT_FALSE(work_running_) << "OnWork should be done by TearDown";
    // Release it for cleanliness.
    if (work_running_) {
      WaitForWork();
    }
  }

  // Input value read on WorkerPool.
  int input_value_;
  // Output value written on WorkerPool.
  int output_value_;

  // read is called on WorkerPool so we need to synchronize with it.
  base::WaitableEvent work_allowed_;
  base::WaitableEvent work_called_;

  // Protected by read_lock_. Used to verify that read calls are serialized.
  bool work_running_;
  base::Lock work_lock_;

  // Loop for this thread.
  MessageLoop* message_loop_;

  // WatcherDelegate under test.
  scoped_refptr<TestSerialWorker> worker_;

  std::string breakpoint_;
};

TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
  for (int i = 0; i < 3; ++i) {
    ++input_value_;
    worker_->WorkNow();
    WaitForWork();
    RunUntilBreak("OnWorkFinished");

    message_loop_->AssertIdle();
  }

  // Schedule two calls. OnWork checks if it is called serially.
  ++input_value_;
  worker_->WorkNow();
  // read is blocked, so this will have to induce re-work
  worker_->WorkNow();
  WaitForWork();
  WaitForWork();
  RunUntilBreak("OnWorkFinished");

  // No more tasks should remain.
  message_loop_->AssertIdle();
}

}  // namespace

}  // namespace net

