This source file includes following definitions.
- DoWork
 
- OnWorkFinished
 
- OnWork
 
- OnWorkFinished
 
- BreakCallback
 
- BreakNow
 
- RunUntilBreak
 
- work_running_
 
- WaitForWork
 
- SetUp
 
- TearDown
 
- TEST_F
 
#include "net/dns/serial_worker.h"
#include "base/bind.h"
#include "base/message_loop/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:
  
  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_;
  };
  
  void OnWork() {
    { 
      base::AutoLock lock(work_lock_);
      EXPECT_FALSE(work_running_) << "DoRead is not called serially!";
      work_running_ = true;
    }
    BreakNow("OnWork");
    work_allowed_.Wait();
    
    output_value_ = input_value_;
    { 
      base::AutoLock lock(work_lock_);
      work_running_ = false;
    }
    work_called_.Signal();
  }
  void OnWorkFinished() {
    EXPECT_TRUE(message_loop_ == base::MessageLoop::current());
    EXPECT_EQ(output_value_, input_value_);
    BreakNow("OnWorkFinished");
  }
 protected:
  void BreakCallback(std::string breakpoint) {
    breakpoint_ = breakpoint;
    base::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) {
  }
  
  
  
  void WaitForWork() {
    RunUntilBreak("OnWork");
    work_allowed_.Signal();
    work_called_.Wait();
  }
  
  virtual void SetUp() OVERRIDE {
    message_loop_ = base::MessageLoop::current();
    worker_ = new TestSerialWorker(this);
  }
  virtual void TearDown() OVERRIDE {
    
    worker_->Cancel();
    
    EXPECT_FALSE(work_running_) << "OnWork should be done by TearDown";
    
    if (work_running_) {
      WaitForWork();
    }
  }
  
  int input_value_;
  
  int output_value_;
  
  base::WaitableEvent work_allowed_;
  base::WaitableEvent work_called_;
  
  bool work_running_;
  base::Lock work_lock_;
  
  base::MessageLoop* message_loop_;
  
  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");
    EXPECT_TRUE(message_loop_->IsIdleForTesting());
  }
  
  ++input_value_;
  worker_->WorkNow();
  
  worker_->WorkNow();
  WaitForWork();
  WaitForWork();
  RunUntilBreak("OnWorkFinished");
  
  EXPECT_TRUE(message_loop_->IsIdleForTesting());
}
}  
}