Fix nullptr crash in OnEmbed
[chromium-blink-merge.git] / net / dns / serial_worker_unittest.cc
blobda8783064294f5e31ca405369e2c726aa2069801
1 // 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.
5 #include "net/dns/serial_worker.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/lock.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace net {
17 namespace {
19 class SerialWorkerTest : public testing::Test {
20 public:
21 // The class under test
22 class TestSerialWorker : public SerialWorker {
23 public:
24 explicit TestSerialWorker(SerialWorkerTest* t)
25 : test_(t) {}
26 void DoWork() override {
27 ASSERT_TRUE(test_);
28 test_->OnWork();
30 void OnWorkFinished() override {
31 ASSERT_TRUE(test_);
32 test_->OnWorkFinished();
34 private:
35 ~TestSerialWorker() override {}
36 SerialWorkerTest* test_;
39 // Mocks
41 void OnWork() {
42 { // Check that OnWork is executed serially.
43 base::AutoLock lock(work_lock_);
44 EXPECT_FALSE(work_running_) << "DoRead is not called serially!";
45 work_running_ = true;
47 BreakNow("OnWork");
48 work_allowed_.Wait();
49 // Calling from WorkerPool, but protected by work_allowed_/work_called_.
50 output_value_ = input_value_;
52 { // This lock might be destroyed after work_called_ is signalled.
53 base::AutoLock lock(work_lock_);
54 work_running_ = false;
56 work_called_.Signal();
59 void OnWorkFinished() {
60 EXPECT_TRUE(message_loop_ == base::MessageLoop::current());
61 EXPECT_EQ(output_value_, input_value_);
62 BreakNow("OnWorkFinished");
65 protected:
66 void BreakCallback(std::string breakpoint) {
67 breakpoint_ = breakpoint;
68 base::MessageLoop::current()->QuitNow();
71 void BreakNow(std::string b) {
72 message_loop_->task_runner()->PostTask(
73 FROM_HERE, base::Bind(&SerialWorkerTest::BreakCallback,
74 base::Unretained(this), b));
77 void RunUntilBreak(std::string b) {
78 message_loop_->Run();
79 ASSERT_EQ(breakpoint_, b);
82 SerialWorkerTest()
83 : input_value_(0),
84 output_value_(-1),
85 work_allowed_(false, false),
86 work_called_(false, false),
87 work_running_(false) {
90 // Helpers for tests.
92 // Lets OnWork run and waits for it to complete. Can only return if OnWork is
93 // executed on a concurrent thread.
94 void WaitForWork() {
95 RunUntilBreak("OnWork");
96 work_allowed_.Signal();
97 work_called_.Wait();
100 // test::Test methods
101 void SetUp() override {
102 message_loop_ = base::MessageLoop::current();
103 worker_ = new TestSerialWorker(this);
106 void TearDown() override {
107 // Cancel the worker to catch if it makes a late DoWork call.
108 worker_->Cancel();
109 // Check if OnWork is stalled.
110 EXPECT_FALSE(work_running_) << "OnWork should be done by TearDown";
111 // Release it for cleanliness.
112 if (work_running_) {
113 WaitForWork();
117 // Input value read on WorkerPool.
118 int input_value_;
119 // Output value written on WorkerPool.
120 int output_value_;
122 // read is called on WorkerPool so we need to synchronize with it.
123 base::WaitableEvent work_allowed_;
124 base::WaitableEvent work_called_;
126 // Protected by read_lock_. Used to verify that read calls are serialized.
127 bool work_running_;
128 base::Lock work_lock_;
130 // Loop for this thread.
131 base::MessageLoop* message_loop_;
133 // WatcherDelegate under test.
134 scoped_refptr<TestSerialWorker> worker_;
136 std::string breakpoint_;
139 TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
140 for (int i = 0; i < 3; ++i) {
141 ++input_value_;
142 worker_->WorkNow();
143 WaitForWork();
144 RunUntilBreak("OnWorkFinished");
146 EXPECT_TRUE(message_loop_->IsIdleForTesting());
149 // Schedule two calls. OnWork checks if it is called serially.
150 ++input_value_;
151 worker_->WorkNow();
152 // read is blocked, so this will have to induce re-work
153 worker_->WorkNow();
154 WaitForWork();
155 WaitForWork();
156 RunUntilBreak("OnWorkFinished");
158 // No more tasks should remain.
159 EXPECT_TRUE(message_loop_->IsIdleForTesting());
162 } // namespace
164 } // namespace net