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"
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"
19 class SerialWorkerTest
: public testing::Test
{
21 // The class under test
22 class TestSerialWorker
: public SerialWorker
{
24 explicit TestSerialWorker(SerialWorkerTest
* t
)
26 void DoWork() override
{
30 void OnWorkFinished() override
{
32 test_
->OnWorkFinished();
35 ~TestSerialWorker() override
{}
36 SerialWorkerTest
* test_
;
42 { // Check that OnWork is executed serially.
43 base::AutoLock
lock(work_lock_
);
44 EXPECT_FALSE(work_running_
) << "DoRead is not called serially!";
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");
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
) {
79 ASSERT_EQ(breakpoint_
, b
);
85 work_allowed_(false, false),
86 work_called_(false, false),
87 work_running_(false) {
92 // Lets OnWork run and waits for it to complete. Can only return if OnWork is
93 // executed on a concurrent thread.
95 RunUntilBreak("OnWork");
96 work_allowed_
.Signal();
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.
109 // Check if OnWork is stalled.
110 EXPECT_FALSE(work_running_
) << "OnWork should be done by TearDown";
111 // Release it for cleanliness.
117 // Input value read on WorkerPool.
119 // Output value written on WorkerPool.
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.
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
) {
144 RunUntilBreak("OnWorkFinished");
146 EXPECT_TRUE(message_loop_
->IsIdleForTesting());
149 // Schedule two calls. OnWork checks if it is called serially.
152 // read is blocked, so this will have to induce re-work
156 RunUntilBreak("OnWorkFinished");
158 // No more tasks should remain.
159 EXPECT_TRUE(message_loop_
->IsIdleForTesting());