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/message_loop/message_loop.h"
9 #include "base/synchronization/lock.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "testing/gtest/include/gtest/gtest.h"
17 class SerialWorkerTest
: public testing::Test
{
19 // The class under test
20 class TestSerialWorker
: public SerialWorker
{
22 explicit TestSerialWorker(SerialWorkerTest
* t
)
24 void DoWork() override
{
28 void OnWorkFinished() override
{
30 test_
->OnWorkFinished();
33 ~TestSerialWorker() override
{}
34 SerialWorkerTest
* test_
;
40 { // Check that OnWork is executed serially.
41 base::AutoLock
lock(work_lock_
);
42 EXPECT_FALSE(work_running_
) << "DoRead is not called serially!";
47 // Calling from WorkerPool, but protected by work_allowed_/work_called_.
48 output_value_
= input_value_
;
50 { // This lock might be destroyed after work_called_ is signalled.
51 base::AutoLock
lock(work_lock_
);
52 work_running_
= false;
54 work_called_
.Signal();
57 void OnWorkFinished() {
58 EXPECT_TRUE(message_loop_
== base::MessageLoop::current());
59 EXPECT_EQ(output_value_
, input_value_
);
60 BreakNow("OnWorkFinished");
64 void BreakCallback(std::string breakpoint
) {
65 breakpoint_
= breakpoint
;
66 base::MessageLoop::current()->QuitNow();
69 void BreakNow(std::string b
) {
70 message_loop_
->PostTask(FROM_HERE
,
71 base::Bind(&SerialWorkerTest::BreakCallback
,
72 base::Unretained(this), b
));
75 void RunUntilBreak(std::string b
) {
77 ASSERT_EQ(breakpoint_
, b
);
83 work_allowed_(false, false),
84 work_called_(false, false),
85 work_running_(false) {
90 // Lets OnWork run and waits for it to complete. Can only return if OnWork is
91 // executed on a concurrent thread.
93 RunUntilBreak("OnWork");
94 work_allowed_
.Signal();
99 void SetUp() override
{
100 message_loop_
= base::MessageLoop::current();
101 worker_
= new TestSerialWorker(this);
104 void TearDown() override
{
105 // Cancel the worker to catch if it makes a late DoWork call.
107 // Check if OnWork is stalled.
108 EXPECT_FALSE(work_running_
) << "OnWork should be done by TearDown";
109 // Release it for cleanliness.
115 // Input value read on WorkerPool.
117 // Output value written on WorkerPool.
120 // read is called on WorkerPool so we need to synchronize with it.
121 base::WaitableEvent work_allowed_
;
122 base::WaitableEvent work_called_
;
124 // Protected by read_lock_. Used to verify that read calls are serialized.
126 base::Lock work_lock_
;
128 // Loop for this thread.
129 base::MessageLoop
* message_loop_
;
131 // WatcherDelegate under test.
132 scoped_refptr
<TestSerialWorker
> worker_
;
134 std::string breakpoint_
;
137 TEST_F(SerialWorkerTest
, ExecuteAndSerializeReads
) {
138 for (int i
= 0; i
< 3; ++i
) {
142 RunUntilBreak("OnWorkFinished");
144 EXPECT_TRUE(message_loop_
->IsIdleForTesting());
147 // Schedule two calls. OnWork checks if it is called serially.
150 // read is blocked, so this will have to induce re-work
154 RunUntilBreak("OnWorkFinished");
156 // No more tasks should remain.
157 EXPECT_TRUE(message_loop_
->IsIdleForTesting());