blob: 8e30e28cf6ffdf091ce44d2007a98b13ef06dd10 [file] [log] [blame]
[email protected]76d7f722011-10-10 17:22:411// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/dns/serial_worker.h"
6
[email protected]221c035c2011-11-30 06:37:407#include "base/bind.h"
[email protected]5ee20982013-07-17 21:51:188#include "base/message_loop/message_loop.h"
[email protected]76d7f722011-10-10 17:22:419#include "base/synchronization/lock.h"
10#include "base/synchronization/waitable_event.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace net {
14
15namespace {
16
17class SerialWorkerTest : public testing::Test {
18 public:
19 // The class under test
20 class TestSerialWorker : public SerialWorker {
21 public:
22 explicit TestSerialWorker(SerialWorkerTest* t)
23 : test_(t) {}
dchengb03027d2014-10-21 12:00:2024 void DoWork() override {
[email protected]76d7f722011-10-10 17:22:4125 ASSERT_TRUE(test_);
26 test_->OnWork();
27 }
dchengb03027d2014-10-21 12:00:2028 void OnWorkFinished() override {
[email protected]76d7f722011-10-10 17:22:4129 ASSERT_TRUE(test_);
30 test_->OnWorkFinished();
31 }
32 private:
dchengb03027d2014-10-21 12:00:2033 ~TestSerialWorker() override {}
[email protected]76d7f722011-10-10 17:22:4134 SerialWorkerTest* test_;
35 };
36
37 // Mocks
38
39 void OnWork() {
40 { // Check that OnWork is executed serially.
41 base::AutoLock lock(work_lock_);
42 EXPECT_FALSE(work_running_) << "DoRead is not called serially!";
43 work_running_ = true;
44 }
45 BreakNow("OnWork");
46 work_allowed_.Wait();
47 // Calling from WorkerPool, but protected by work_allowed_/work_called_.
48 output_value_ = input_value_;
49
50 { // This lock might be destroyed after work_called_ is signalled.
51 base::AutoLock lock(work_lock_);
52 work_running_ = false;
53 }
54 work_called_.Signal();
55 }
56
57 void OnWorkFinished() {
[email protected]2da659e2013-05-23 20:51:3458 EXPECT_TRUE(message_loop_ == base::MessageLoop::current());
[email protected]76d7f722011-10-10 17:22:4159 EXPECT_EQ(output_value_, input_value_);
60 BreakNow("OnWorkFinished");
61 }
62
63 protected:
[email protected]221c035c2011-11-30 06:37:4064 void BreakCallback(std::string breakpoint) {
65 breakpoint_ = breakpoint;
[email protected]2da659e2013-05-23 20:51:3466 base::MessageLoop::current()->QuitNow();
[email protected]221c035c2011-11-30 06:37:4067 }
[email protected]76d7f722011-10-10 17:22:4168
69 void BreakNow(std::string b) {
[email protected]221c035c2011-11-30 06:37:4070 message_loop_->PostTask(FROM_HERE,
71 base::Bind(&SerialWorkerTest::BreakCallback,
72 base::Unretained(this), b));
[email protected]76d7f722011-10-10 17:22:4173 }
74
75 void RunUntilBreak(std::string b) {
76 message_loop_->Run();
77 ASSERT_EQ(breakpoint_, b);
78 }
79
80 SerialWorkerTest()
81 : input_value_(0),
82 output_value_(-1),
83 work_allowed_(false, false),
84 work_called_(false, false),
85 work_running_(false) {
86 }
87
88 // Helpers for tests.
89
90 // Lets OnWork run and waits for it to complete. Can only return if OnWork is
91 // executed on a concurrent thread.
92 void WaitForWork() {
93 RunUntilBreak("OnWork");
94 work_allowed_.Signal();
95 work_called_.Wait();
96 }
97
98 // test::Test methods
mostynbba063d6032014-10-09 11:01:1399 virtual void SetUp() override {
[email protected]2da659e2013-05-23 20:51:34100 message_loop_ = base::MessageLoop::current();
[email protected]76d7f722011-10-10 17:22:41101 worker_ = new TestSerialWorker(this);
102 }
103
mostynbba063d6032014-10-09 11:01:13104 virtual void TearDown() override {
[email protected]76d7f722011-10-10 17:22:41105 // Cancel the worker to catch if it makes a late DoWork call.
106 worker_->Cancel();
107 // Check if OnWork is stalled.
108 EXPECT_FALSE(work_running_) << "OnWork should be done by TearDown";
109 // Release it for cleanliness.
110 if (work_running_) {
111 WaitForWork();
112 }
113 }
114
115 // Input value read on WorkerPool.
116 int input_value_;
117 // Output value written on WorkerPool.
118 int output_value_;
119
120 // read is called on WorkerPool so we need to synchronize with it.
121 base::WaitableEvent work_allowed_;
122 base::WaitableEvent work_called_;
123
124 // Protected by read_lock_. Used to verify that read calls are serialized.
125 bool work_running_;
126 base::Lock work_lock_;
127
128 // Loop for this thread.
[email protected]2da659e2013-05-23 20:51:34129 base::MessageLoop* message_loop_;
[email protected]76d7f722011-10-10 17:22:41130
131 // WatcherDelegate under test.
132 scoped_refptr<TestSerialWorker> worker_;
133
134 std::string breakpoint_;
135};
136
137TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
138 for (int i = 0; i < 3; ++i) {
139 ++input_value_;
140 worker_->WorkNow();
141 WaitForWork();
142 RunUntilBreak("OnWorkFinished");
143
[email protected]54aa4f12013-07-22 22:24:13144 EXPECT_TRUE(message_loop_->IsIdleForTesting());
[email protected]76d7f722011-10-10 17:22:41145 }
146
147 // Schedule two calls. OnWork checks if it is called serially.
148 ++input_value_;
149 worker_->WorkNow();
150 // read is blocked, so this will have to induce re-work
151 worker_->WorkNow();
152 WaitForWork();
153 WaitForWork();
154 RunUntilBreak("OnWorkFinished");
155
156 // No more tasks should remain.
[email protected]54aa4f12013-07-22 22:24:13157 EXPECT_TRUE(message_loop_->IsIdleForTesting());
[email protected]76d7f722011-10-10 17:22:41158}
159
160} // namespace
161
162} // namespace net
163