OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/sequence_checker.h" | |
6 | |
7 #include <stddef.h> | 5 #include <stddef.h> |
8 | 6 |
9 #include <memory> | 7 #include <memory> |
10 #include <utility> | 8 #include <string> |
11 | 9 |
12 #include "base/bind.h" | 10 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
14 #include "base/location.h" | 12 #include "base/callback_forward.h" |
15 #include "base/logging.h" | |
16 #include "base/macros.h" | 13 #include "base/macros.h" |
17 #include "base/memory/ref_counted.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/sequence_checker_impl.h" | |
16 #include "base/sequence_token.h" | |
18 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
19 #include "base/test/sequenced_worker_pool_owner.h" | 18 #include "base/test/sequenced_worker_pool_owner.h" |
20 #include "base/threading/thread.h" | 19 #include "base/threading/simple_thread.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
22 | 21 |
23 // Duplicated from base/sequence_checker.h so that we can be good citizens | |
24 // there and undef the macro. | |
25 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) | |
26 #define ENABLE_SEQUENCE_CHECKER 1 | |
27 #else | |
28 #define ENABLE_SEQUENCE_CHECKER 0 | |
29 #endif | |
30 | |
31 namespace base { | 22 namespace base { |
32 | 23 |
33 namespace { | 24 namespace { |
34 | 25 |
35 const size_t kNumWorkerThreads = 3; | 26 constexpr size_t kNumWorkerThreads = 3; |
36 | 27 |
37 // Simple class to exercise the basics of SequenceChecker. | 28 // Runs a callback on another thread. |
38 // DoStuff should verify that it's called on a valid sequenced thread. | 29 class RunCallbackThread : public SimpleThread { |
39 // SequenceCheckedObject can be destroyed on any thread (like WeakPtr). | |
40 class SequenceCheckedObject { | |
41 public: | 30 public: |
42 SequenceCheckedObject() {} | 31 explicit RunCallbackThread(const Closure& callback) |
43 ~SequenceCheckedObject() {} | 32 : SimpleThread("RunCallbackThread"), callback_(callback) { |
44 | 33 Start(); |
45 // Verifies that it was called on the same thread as the constructor. | 34 Join(); |
46 void DoStuff() { | |
47 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | |
48 } | |
49 | |
50 void DetachFromSequence() { | |
51 sequence_checker_.DetachFromSequence(); | |
52 } | 35 } |
53 | 36 |
54 private: | 37 private: |
55 SequenceChecker sequence_checker_; | 38 // SimpleThread: |
56 | 39 void Run() override { callback_.Run(); } |
57 DISALLOW_COPY_AND_ASSIGN(SequenceCheckedObject); | 40 |
41 const Closure callback_; | |
42 | |
43 DISALLOW_COPY_AND_ASSIGN(RunCallbackThread); | |
58 }; | 44 }; |
59 | 45 |
60 class SequenceCheckerTest : public testing::Test { | 46 class SequenceCheckerTest : public testing::Test { |
61 public: | |
62 SequenceCheckerTest() : other_thread_("sequence_checker_test_other_thread") {} | |
63 | |
64 void SetUp() override { | |
65 other_thread_.Start(); | |
66 ResetPool(); | |
67 } | |
68 | |
69 void TearDown() override { | |
70 other_thread_.Stop(); | |
71 } | |
72 | |
73 protected: | 47 protected: |
74 base::Thread* other_thread() { return &other_thread_; } | 48 SequenceCheckerTest() : pool_owner_(kNumWorkerThreads, "test") {} |
75 | 49 |
76 const scoped_refptr<SequencedWorkerPool>& pool() { | 50 void PostToSequencedWorkerPool(const Closure& callback, |
77 return pool_owner_->pool(); | 51 const std::string& token_name) { |
78 } | 52 pool_owner_.pool()->PostNamedSequencedWorkerTask(token_name, FROM_HERE, |
79 | 53 callback); |
80 void PostDoStuffToWorkerPool(SequenceCheckedObject* sequence_checked_object, | 54 } |
81 const std::string& token_name) { | 55 |
82 pool()->PostNamedSequencedWorkerTask( | 56 void FlushSequencedWorkerPoolForTesting() { |
83 token_name, | 57 pool_owner_.pool()->FlushForTesting(); |
84 FROM_HERE, | 58 } |
85 base::Bind(&SequenceCheckedObject::DoStuff, | |
86 base::Unretained(sequence_checked_object))); | |
87 } | |
88 | |
89 void PostDoStuffToOtherThread( | |
90 SequenceCheckedObject* sequence_checked_object) { | |
91 other_thread()->task_runner()->PostTask( | |
92 FROM_HERE, base::Bind(&SequenceCheckedObject::DoStuff, | |
93 base::Unretained(sequence_checked_object))); | |
94 } | |
95 | |
96 void PostDeleteToOtherThread( | |
97 std::unique_ptr<SequenceCheckedObject> sequence_checked_object) { | |
98 other_thread()->message_loop()->task_runner()->DeleteSoon( | |
99 FROM_HERE, sequence_checked_object.release()); | |
100 } | |
101 | |
102 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut | |
103 // down, and creates a new instance. | |
104 void ResetPool() { | |
105 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); | |
106 } | |
107 | |
108 void MethodOnDifferentThreadDeathTest(); | |
109 void DetachThenCallFromDifferentThreadDeathTest(); | |
110 void DifferentSequenceTokensDeathTest(); | |
111 void WorkerPoolAndSimpleThreadDeathTest(); | |
112 void TwoDifferentWorkerPoolsDeathTest(); | |
113 | 59 |
114 private: | 60 private: |
115 MessageLoop message_loop_; // Needed by SequencedWorkerPool to function. | 61 MessageLoop message_loop_; // Needed by SequencedWorkerPool to function. |
116 base::Thread other_thread_; | 62 SequencedWorkerPoolOwner pool_owner_; |
117 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 63 |
64 DISALLOW_COPY_AND_ASSIGN(SequenceCheckerTest); | |
118 }; | 65 }; |
119 | 66 |
120 TEST_F(SequenceCheckerTest, CallsAllowedOnSameThread) { | 67 void ExpectCalledOnValidSequencedThread(SequenceCheckerImpl* sequence_checker) { |
121 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 68 ASSERT_TRUE(sequence_checker); |
122 new SequenceCheckedObject); | 69 |
123 | 70 // This should bind |sequence_checker| to the current sequence if it wasn't |
124 // Verify that DoStuff doesn't assert. | 71 // already bound to a sequence. |
125 sequence_checked_object->DoStuff(); | 72 EXPECT_TRUE(sequence_checker->CalledOnValidSequencedThread()); |
126 | 73 |
127 // Verify that the destructor doesn't assert. | 74 // Since |sequence_checker| is now bound to the current sequence, another call |
128 sequence_checked_object.reset(); | 75 // to CalledOnValidSequencedThread() should return true. |
129 } | 76 EXPECT_TRUE(sequence_checker->CalledOnValidSequencedThread()); |
130 | 77 } |
131 TEST_F(SequenceCheckerTest, DestructorAllowedOnDifferentThread) { | 78 |
132 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 79 void ExpectCalledOnValidSequencedThreadWithSequenceToken( |
133 new SequenceCheckedObject); | 80 SequenceCheckerImpl* sequence_checker, |
134 | 81 internal::SequenceToken sequence_token) { |
135 // Verify the destructor doesn't assert when called on a different thread. | 82 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
136 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 83 sequence_token); |
137 other_thread()->Stop(); | 84 ExpectCalledOnValidSequencedThread(sequence_checker); |
85 } | |
86 | |
87 void ExpectNotCalledOnValidSequencedThread( | |
88 SequenceCheckerImpl* sequence_checker) { | |
89 ASSERT_TRUE(sequence_checker); | |
90 EXPECT_FALSE(sequence_checker->CalledOnValidSequencedThread()); | |
91 } | |
92 | |
93 } // namespace | |
94 | |
95 TEST_F(SequenceCheckerTest, CallsAllowedOnSameThreadNoSequenceToken) { | |
96 SequenceCheckerImpl sequence_checker; | |
97 EXPECT_TRUE(sequence_checker.CalledOnValidSequencedThread()); | |
98 } | |
99 | |
100 TEST_F(SequenceCheckerTest, CallsAllowedOnSameThreadSameSequenceToken) { | |
101 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( | |
102 internal::SequenceToken::Create()); | |
gab
2016/07/21 21:14:24
internal::SequenceToken::Create() will become inva
fdoray
2016/07/25 13:24:28
ScopedSetCurrentSequenceToken copies the argument
gab
2016/07/25 14:09:31
Ah, good point :-).
| |
103 SequenceCheckerImpl sequence_checker; | |
104 EXPECT_TRUE(sequence_checker.CalledOnValidSequencedThread()); | |
105 } | |
106 | |
107 TEST_F(SequenceCheckerTest, CallsDisallowedOnDifferentThreadsNoSequenceToken) { | |
108 SequenceCheckerImpl sequence_checker; | |
109 RunCallbackThread thread(Bind(&ExpectNotCalledOnValidSequencedThread, | |
110 Unretained(&sequence_checker))); | |
111 } | |
112 | |
113 TEST_F(SequenceCheckerTest, CallsAllowedOnDifferentThreadsSameSequenceToken) { | |
114 const internal::SequenceToken sequence_token( | |
115 internal::SequenceToken::Create()); | |
116 | |
117 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( | |
118 sequence_token); | |
119 SequenceCheckerImpl sequence_checker; | |
120 | |
gab
2016/07/21 21:14:24
Also EXPECT_TRUE(sequence_checker.CalledOnValidSeq
fdoray
2016/07/25 13:24:28
Done.
| |
121 RunCallbackThread thread( | |
122 Bind(&ExpectCalledOnValidSequencedThreadWithSequenceToken, | |
123 Unretained(&sequence_checker), sequence_token)); | |
124 } | |
125 | |
126 TEST_F(SequenceCheckerTest, CallsDisallowedOnSameThreadDifferentSequenceToken) { | |
127 std::unique_ptr<SequenceCheckerImpl> sequence_checker; | |
128 | |
129 { | |
130 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( | |
131 internal::SequenceToken::Create()); | |
132 sequence_checker.reset(new SequenceCheckerImpl); | |
133 } | |
134 | |
135 { | |
136 // Different SequenceToken. | |
137 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( | |
138 internal::SequenceToken::Create()); | |
139 EXPECT_FALSE(sequence_checker->CalledOnValidSequencedThread()); | |
140 } | |
141 | |
142 // No SequenceToken. | |
143 EXPECT_FALSE(sequence_checker->CalledOnValidSequencedThread()); | |
138 } | 144 } |
139 | 145 |
140 TEST_F(SequenceCheckerTest, DetachFromSequence) { | 146 TEST_F(SequenceCheckerTest, DetachFromSequence) { |
141 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 147 std::unique_ptr<SequenceCheckerImpl> sequence_checker; |
142 new SequenceCheckedObject); | 148 |
143 | 149 { |
144 // Verify that DoStuff doesn't assert when called on a different thread after | 150 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
145 // a call to DetachFromSequence. | 151 internal::SequenceToken::Create()); |
146 sequence_checked_object->DetachFromSequence(); | 152 sequence_checker.reset(new SequenceCheckerImpl); |
147 | 153 } |
148 PostDoStuffToOtherThread(sequence_checked_object.get()); | 154 |
149 other_thread()->Stop(); | 155 sequence_checker->DetachFromSequence(); |
150 } | 156 |
151 | 157 { |
152 TEST_F(SequenceCheckerTest, SameSequenceTokenValid) { | 158 // Verify that CalledOnValidSequencedThread() returns true when called with |
153 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 159 // a different sequence token after a call to DetachFromSequence(). |
154 new SequenceCheckedObject); | 160 internal::ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
155 | 161 internal::SequenceToken::Create()); |
156 sequence_checked_object->DetachFromSequence(); | 162 EXPECT_TRUE(sequence_checker->CalledOnValidSequencedThread()); |
157 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 163 } |
158 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 164 } |
159 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 165 |
160 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 166 TEST_F(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) { |
161 pool()->FlushForTesting(); | 167 SequenceCheckerImpl sequence_checker; |
162 | 168 sequence_checker.DetachFromSequence(); |
163 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 169 |
164 other_thread()->Stop(); | 170 // Verify that CalledOnValidSequencedThread() returns true when called on a |
165 } | 171 // different thread after a call to DetachFromSequence(). |
166 | 172 RunCallbackThread thread( |
167 TEST_F(SequenceCheckerTest, DetachSequenceTokenValid) { | 173 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker))); |
168 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 174 |
169 new SequenceCheckedObject); | 175 EXPECT_FALSE(sequence_checker.CalledOnValidSequencedThread()); |
170 | 176 } |
171 sequence_checked_object->DetachFromSequence(); | 177 |
172 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 178 TEST_F(SequenceCheckerTest, SequencedWorkerPool_SameSequenceTokenValid) { |
173 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 179 SequenceCheckerImpl sequence_checker; |
174 pool()->FlushForTesting(); | 180 sequence_checker.DetachFromSequence(); |
175 | 181 |
176 sequence_checked_object->DetachFromSequence(); | 182 PostToSequencedWorkerPool( |
177 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 183 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
178 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 184 "A"); |
179 pool()->FlushForTesting(); | 185 PostToSequencedWorkerPool( |
180 | 186 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
181 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 187 "A"); |
182 other_thread()->Stop(); | 188 PostToSequencedWorkerPool( |
183 } | 189 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
184 | 190 "A"); |
185 #if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER | 191 PostToSequencedWorkerPool( |
186 | 192 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
187 void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() { | 193 "A"); |
188 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 194 FlushSequencedWorkerPoolForTesting(); |
189 new SequenceCheckedObject); | 195 } |
190 | 196 |
191 // DoStuff should assert in debug builds only when called on a | 197 TEST_F(SequenceCheckerTest, SequencedWorkerPool_DetachSequenceTokenValid) { |
192 // different thread. | 198 SequenceCheckerImpl sequence_checker; |
193 PostDoStuffToOtherThread(sequence_checked_object.get()); | 199 sequence_checker.DetachFromSequence(); |
194 other_thread()->Stop(); | 200 |
195 } | 201 PostToSequencedWorkerPool( |
196 | 202 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
197 #if ENABLE_SEQUENCE_CHECKER | 203 "A"); |
198 TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) { | 204 PostToSequencedWorkerPool( |
199 // The default style "fast" does not support multi-threaded tests. | 205 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
200 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 206 "A"); |
201 ASSERT_DEATH({ | 207 FlushSequencedWorkerPoolForTesting(); |
202 MethodOnDifferentThreadDeathTest(); | 208 |
203 }, ""); | 209 sequence_checker.DetachFromSequence(); |
204 } | 210 |
205 #else | 211 PostToSequencedWorkerPool( |
206 TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) { | 212 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
207 MethodOnDifferentThreadDeathTest(); | 213 "B"); |
208 } | 214 PostToSequencedWorkerPool( |
209 #endif // ENABLE_SEQUENCE_CHECKER | 215 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
210 | 216 "B"); |
211 void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() { | 217 FlushSequencedWorkerPoolForTesting(); |
212 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 218 } |
213 new SequenceCheckedObject); | 219 |
214 | 220 TEST_F(SequenceCheckerTest, |
215 // DoStuff doesn't assert when called on a different thread | 221 SequencedWorkerPool_DifferentSequenceTokensInvalid) { |
216 // after a call to DetachFromSequence. | 222 SequenceCheckerImpl sequence_checker; |
217 sequence_checked_object->DetachFromSequence(); | 223 sequence_checker.DetachFromSequence(); |
218 PostDoStuffToOtherThread(sequence_checked_object.get()); | 224 |
219 other_thread()->Stop(); | 225 PostToSequencedWorkerPool( |
220 | 226 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
221 // DoStuff should assert in debug builds only after moving to | 227 "A"); |
222 // another thread. | 228 PostToSequencedWorkerPool( |
223 sequence_checked_object->DoStuff(); | 229 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
224 } | 230 "A"); |
225 | 231 FlushSequencedWorkerPoolForTesting(); |
226 #if ENABLE_SEQUENCE_CHECKER | 232 |
227 TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) { | 233 PostToSequencedWorkerPool(Bind(&ExpectNotCalledOnValidSequencedThread, |
228 // The default style "fast" does not support multi-threaded tests. | 234 Unretained(&sequence_checker)), |
229 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 235 "B"); |
230 ASSERT_DEATH({ | 236 PostToSequencedWorkerPool(Bind(&ExpectNotCalledOnValidSequencedThread, |
231 DetachThenCallFromDifferentThreadDeathTest(); | 237 Unretained(&sequence_checker)), |
232 }, ""); | 238 "B"); |
233 } | 239 FlushSequencedWorkerPoolForTesting(); |
234 #else | 240 } |
235 TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) { | 241 |
236 DetachThenCallFromDifferentThreadDeathTest(); | 242 TEST_F(SequenceCheckerTest, |
237 } | 243 SequencedWorkerPool_WorkerPoolAndSimpleThreadInvalid) { |
238 #endif // ENABLE_SEQUENCE_CHECKER | 244 SequenceCheckerImpl sequence_checker; |
239 | 245 sequence_checker.DetachFromSequence(); |
240 void SequenceCheckerTest::DifferentSequenceTokensDeathTest() { | 246 |
241 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 247 PostToSequencedWorkerPool( |
242 new SequenceCheckedObject); | 248 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
243 | 249 "A"); |
244 sequence_checked_object->DetachFromSequence(); | 250 PostToSequencedWorkerPool( |
245 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 251 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
246 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 252 "A"); |
247 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 253 FlushSequencedWorkerPoolForTesting(); |
248 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 254 |
249 pool()->FlushForTesting(); | 255 EXPECT_FALSE(sequence_checker.CalledOnValidSequencedThread()); |
250 | 256 } |
251 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 257 |
252 other_thread()->Stop(); | 258 TEST_F(SequenceCheckerTest, |
253 } | 259 SequencedWorkerPool_TwoDifferentWorkerPoolsInvalid) { |
254 | 260 SequenceCheckerImpl sequence_checker; |
255 #if ENABLE_SEQUENCE_CHECKER | 261 sequence_checker.DetachFromSequence(); |
256 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) { | 262 |
257 // The default style "fast" does not support multi-threaded tests. | 263 PostToSequencedWorkerPool( |
258 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 264 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
259 ASSERT_DEATH({ | 265 "A"); |
260 DifferentSequenceTokensDeathTest(); | 266 PostToSequencedWorkerPool( |
261 }, ""); | 267 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
262 } | 268 "A"); |
263 #else | 269 FlushSequencedWorkerPoolForTesting(); |
264 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInRelease) { | |
265 DifferentSequenceTokensDeathTest(); | |
266 } | |
267 #endif // ENABLE_SEQUENCE_CHECKER | |
268 | |
269 void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() { | |
270 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | |
271 new SequenceCheckedObject); | |
272 | |
273 sequence_checked_object->DetachFromSequence(); | |
274 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | |
275 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | |
276 pool()->FlushForTesting(); | |
277 | |
278 PostDoStuffToOtherThread(sequence_checked_object.get()); | |
279 other_thread()->Stop(); | |
280 } | |
281 | |
282 #if ENABLE_SEQUENCE_CHECKER | |
283 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) { | |
284 // The default style "fast" does not support multi-threaded tests. | |
285 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | |
286 ASSERT_DEATH({ | |
287 WorkerPoolAndSimpleThreadDeathTest(); | |
288 }, ""); | |
289 } | |
290 #else | |
291 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInRelease) { | |
292 WorkerPoolAndSimpleThreadDeathTest(); | |
293 } | |
294 #endif // ENABLE_SEQUENCE_CHECKER | |
295 | |
296 void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() { | |
297 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | |
298 new SequenceCheckedObject); | |
299 | |
300 sequence_checked_object->DetachFromSequence(); | |
301 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | |
302 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | |
303 pool()->FlushForTesting(); | |
304 | 270 |
305 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); | 271 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); |
306 second_pool_owner.pool()->PostNamedSequencedWorkerTask( | 272 second_pool_owner.pool()->PostNamedSequencedWorkerTask( |
307 "A", | 273 "A", FROM_HERE, base::Bind(&ExpectNotCalledOnValidSequencedThread, |
308 FROM_HERE, | 274 base::Unretained(&sequence_checker))); |
309 base::Bind(&SequenceCheckedObject::DoStuff, | |
310 base::Unretained(sequence_checked_object.get()))); | |
311 second_pool_owner.pool()->FlushForTesting(); | 275 second_pool_owner.pool()->FlushForTesting(); |
312 } | 276 } |
313 | 277 |
314 #if ENABLE_SEQUENCE_CHECKER | |
315 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) { | |
316 // The default style "fast" does not support multi-threaded tests. | |
317 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | |
318 ASSERT_DEATH({ | |
319 TwoDifferentWorkerPoolsDeathTest(); | |
320 }, ""); | |
321 } | |
322 #else | |
323 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInRelease) { | |
324 TwoDifferentWorkerPoolsDeathTest(); | |
325 } | |
326 #endif // ENABLE_SEQUENCE_CHECKER | |
327 | |
328 #endif // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER | |
329 | |
330 } // namespace | |
331 | |
332 } // namespace base | 278 } // namespace base |
333 | |
334 // Just in case we ever get lumped together with other compilation units. | |
335 #undef ENABLE_SEQUENCE_CHECKER | |
OLD | NEW |