Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: base/sequence_checker_impl_unittest.cc

Issue 11550031: Implement SequenceChecker, which is a generalization of ThreadChecker (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "base/sequence_checker_impl.h"
6
7 #include <cstddef>
8
9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/location.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/threading/thread.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19
20 namespace {
21
22 // Implementation of SequencedTaskRunner that lets us control what
23 // RunsTasksOnCurrentThread() returns.
24 class FakeTaskRunner : public SequencedTaskRunner {
25 public:
26 FakeTaskRunner() : runs_tasks_on_current_thread_(false) {}
27
28 void SetRunsTasksOnCurrentThread(bool runs_tasks_on_current_thread) {
29 runs_tasks_on_current_thread_ = runs_tasks_on_current_thread;
30 }
31
32 // SequencedTaskRunner implementation.
33 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
34 const Closure& task,
35 TimeDelta delay) OVERRIDE {
36 ADD_FAILURE();
37 return false;
38 }
39
40 virtual bool PostNonNestableDelayedTask(
41 const tracked_objects::Location& from_here,
42 const Closure& task,
43 TimeDelta delay) OVERRIDE {
44 ADD_FAILURE();
45 return false;
46 }
47
48 virtual bool RunsTasksOnCurrentThread() const OVERRIDE {
49 return runs_tasks_on_current_thread_;
50 }
51
52 protected:
53 virtual ~FakeTaskRunner() {}
54
55 private:
56 bool runs_tasks_on_current_thread_;
57 };
58
59 class SequenceCheckerImplTest : public ::testing::Test {
60 };
61
62 // Create a SequenceCheckerImpl with a SequencedTaskRunner and make
63 // sure that CalledInSequence() returns what that SequencedTaskRunner
64 // returns for RunsTasksOnCurrentThread().
65 TEST_F(SequenceCheckerImplTest, CalledInSequenceNonNull) {
66 const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner(
67 new FakeTaskRunner());
68
69 const SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner);
70 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
71
72 fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(true);
73 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
74
75 fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(false);
76 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
77 }
78
79 void ExpectCalledInSequence(const tracked_objects::Location& location,
80 const SequenceCheckerImpl* sequence_checker_impl,
81 bool expected_value) {
82 EXPECT_EQ(expected_value, sequence_checker_impl->CalledInSequence())
83 << location.ToString();
84 }
85
86 // Create a SequenceCheckerImpl with no SequencedTaskRunner and make
87 // sure that CalledInSequence() behaves like
88 // ThreadChecker::CalledOnValidThread().
89 TEST_F(SequenceCheckerImplTest, CalledInSequenceNull) {
90 const SequenceCheckerImpl sequence_checker_impl(NULL);
91 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
92
93 {
94 Thread thread("thread 1");
95 ASSERT_TRUE(thread.Start());
96 thread.message_loop()->PostTask(
97 FROM_HERE, Bind(&ExpectCalledInSequence,
98 FROM_HERE,
99 Unretained(&sequence_checker_impl),
100 false));
Ryan Sleevi 2012/12/13 22:49:15 I didn't think it was safe for GTest to use ADD_FA
akalin 2012/12/18 22:12:19 ADD_FAILURE() seems to work from other threads. I
101 }
102 }
103
104 // Create a SequenceCheckerImpl with a SequencedTaskRunner and switch
105 // it to another one. CalledInSequence() should return what its
106 // underlying SequencedTaskRunner returns for
107 // RunsTasksOnCurrentThread().
108 TEST_F(SequenceCheckerImplTest, ChangeSequenceNonNull) {
109 const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner1(
110 new FakeTaskRunner());
111
112 const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner2(
113 new FakeTaskRunner());
114
115 SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner1);
116 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
117
118 fake_sequenced_task_runner2->SetRunsTasksOnCurrentThread(true);
119 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
120
121 sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner2);
122 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
123 }
124
125 // Create a SequenceCheckerImpl with a SequencedTaskRunner and switch
126 // it to a NULL one. CalledInSequence() should then behave like
127 // ThreadChecker::CalledOnValidThread().
128 TEST_F(SequenceCheckerImplTest, ChangeSequenceNull) {
129 const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner(
130 new FakeTaskRunner());
131
132 SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner);
133 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
134
135 sequence_checker_impl.ChangeSequence(NULL);
136 // Binds to current thread.
Ryan Sleevi 2012/12/13 22:49:15 Move this comment up a line?
akalin 2012/12/18 22:12:19 Actually, the comment is in the right place -- the
137 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
138 {
139 Thread thread("thread 1");
140 ASSERT_TRUE(thread.Start());
141 thread.message_loop()->PostTask(
142 FROM_HERE, Bind(&ExpectCalledInSequence,
143 FROM_HERE,
144 Unretained(&sequence_checker_impl),
145 false));
146 }
147
148 sequence_checker_impl.ChangeSequence(NULL);
149 // Binds to worker thread.
150 {
151 Thread thread("thread 2");
152 ASSERT_TRUE(thread.Start());
153 thread.message_loop()->PostTask(
154 FROM_HERE, Bind(&ExpectCalledInSequence,
155 FROM_HERE,
156 Unretained(&sequence_checker_impl),
157 true));
158 }
159 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
160 }
161
162 // Create a SequenceCheckerImpl with the current thread's task runner
163 // and switch it to other ones. CalledInSequence() should return true
164 // only when it's on the correct thread.
165 TEST_F(SequenceCheckerImplTest, MultipleThreads) {
166 MessageLoop loop;
167
168 SequenceCheckerImpl sequence_checker_impl(loop.message_loop_proxy());
169 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
170
171 {
172 Thread thread("thread 1");
173 ASSERT_TRUE(thread.Start());
174 thread.message_loop()->PostTask(
175 FROM_HERE, Bind(&ExpectCalledInSequence,
176 FROM_HERE,
177 Unretained(&sequence_checker_impl),
178 false));
179 thread.message_loop()->PostTask(
180 FROM_HERE, Bind(&SequenceCheckerImpl::ChangeSequence,
181 Unretained(&sequence_checker_impl),
182 thread.message_loop_proxy()));
183 thread.message_loop()->PostTask(
184 FROM_HERE, Bind(&ExpectCalledInSequence,
185 FROM_HERE,
186 Unretained(&sequence_checker_impl),
187 true));
188 }
189
190 EXPECT_FALSE(sequence_checker_impl.CalledInSequence());
191
192 sequence_checker_impl.ChangeSequence(loop.message_loop_proxy());
193 EXPECT_TRUE(sequence_checker_impl.CalledInSequence());
194
195 {
196 Thread thread("thread 2");
197 ASSERT_TRUE(thread.Start());
198 thread.message_loop()->PostTask(
199 FROM_HERE, Bind(&ExpectCalledInSequence,
200 FROM_HERE,
201 Unretained(&sequence_checker_impl),
202 false));
203 }
204 }
205
206 } // namespace
207
208 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698