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 SequenceToken sequence_token) { |
135 // Verify the destructor doesn't assert when called on a different thread. | 82 ScopedSetSequenceTokenForCurrentThread |
136 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 83 scoped_set_sequence_token_for_current_thread(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 ScopedSetSequenceTokenForCurrentThread |
| 102 scoped_set_sequence_token_for_current_thread(SequenceToken::Create()); |
| 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 SequenceToken sequence_token(SequenceToken::Create()); |
| 115 |
| 116 ScopedSetSequenceTokenForCurrentThread |
| 117 scoped_set_sequence_token_for_current_thread(sequence_token); |
| 118 SequenceCheckerImpl sequence_checker; |
| 119 EXPECT_TRUE(sequence_checker.CalledOnValidSequencedThread()); |
| 120 |
| 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 ScopedSetSequenceTokenForCurrentThread |
| 131 scoped_set_sequence_token_for_current_thread(SequenceToken::Create()); |
| 132 sequence_checker.reset(new SequenceCheckerImpl); |
| 133 } |
| 134 |
| 135 { |
| 136 // Different SequenceToken. |
| 137 ScopedSetSequenceTokenForCurrentThread |
| 138 scoped_set_sequence_token_for_current_thread(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 ScopedSetSequenceTokenForCurrentThread |
145 // a call to DetachFromSequence. | 151 scoped_set_sequence_token_for_current_thread(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 ScopedSetSequenceTokenForCurrentThread |
155 | 161 scoped_set_sequence_token_for_current_thread(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 FlushSequencedWorkerPoolForTesting(); |
183 } | 189 } |
184 | 190 |
185 #if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER | 191 TEST_F(SequenceCheckerTest, SequencedWorkerPool_DetachSequenceTokenValid) { |
186 | 192 SequenceCheckerImpl sequence_checker; |
187 void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() { | 193 sequence_checker.DetachFromSequence(); |
188 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 194 |
189 new SequenceCheckedObject); | 195 PostToSequencedWorkerPool( |
190 | 196 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
191 // DoStuff should assert in debug builds only when called on a | 197 "A"); |
192 // different thread. | 198 PostToSequencedWorkerPool( |
193 PostDoStuffToOtherThread(sequence_checked_object.get()); | 199 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
194 other_thread()->Stop(); | 200 "A"); |
195 } | 201 FlushSequencedWorkerPoolForTesting(); |
196 | 202 |
197 #if ENABLE_SEQUENCE_CHECKER | 203 sequence_checker.DetachFromSequence(); |
198 TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) { | 204 |
199 // The default style "fast" does not support multi-threaded tests. | 205 PostToSequencedWorkerPool( |
200 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 206 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
201 ASSERT_DEATH({ | 207 "B"); |
202 MethodOnDifferentThreadDeathTest(); | 208 PostToSequencedWorkerPool( |
203 }, ""); | 209 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
204 } | 210 "B"); |
205 #else | 211 FlushSequencedWorkerPoolForTesting(); |
206 TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) { | 212 } |
207 MethodOnDifferentThreadDeathTest(); | 213 |
208 } | 214 TEST_F(SequenceCheckerTest, |
209 #endif // ENABLE_SEQUENCE_CHECKER | 215 SequencedWorkerPool_DifferentSequenceTokensInvalid) { |
210 | 216 SequenceCheckerImpl sequence_checker; |
211 void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() { | 217 sequence_checker.DetachFromSequence(); |
212 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 218 |
213 new SequenceCheckedObject); | 219 PostToSequencedWorkerPool( |
214 | 220 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
215 // DoStuff doesn't assert when called on a different thread | 221 "A"); |
216 // after a call to DetachFromSequence. | 222 PostToSequencedWorkerPool( |
217 sequence_checked_object->DetachFromSequence(); | 223 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
218 PostDoStuffToOtherThread(sequence_checked_object.get()); | 224 "A"); |
219 other_thread()->Stop(); | 225 FlushSequencedWorkerPoolForTesting(); |
220 | 226 |
221 // DoStuff should assert in debug builds only after moving to | 227 PostToSequencedWorkerPool(Bind(&ExpectNotCalledOnValidSequencedThread, |
222 // another thread. | 228 Unretained(&sequence_checker)), |
223 sequence_checked_object->DoStuff(); | 229 "B"); |
224 } | 230 PostToSequencedWorkerPool(Bind(&ExpectNotCalledOnValidSequencedThread, |
225 | 231 Unretained(&sequence_checker)), |
226 #if ENABLE_SEQUENCE_CHECKER | 232 "B"); |
227 TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) { | 233 FlushSequencedWorkerPoolForTesting(); |
228 // The default style "fast" does not support multi-threaded tests. | 234 } |
229 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 235 |
230 ASSERT_DEATH({ | 236 TEST_F(SequenceCheckerTest, |
231 DetachThenCallFromDifferentThreadDeathTest(); | 237 SequencedWorkerPool_WorkerPoolAndSimpleThreadInvalid) { |
232 }, ""); | 238 SequenceCheckerImpl sequence_checker; |
233 } | 239 sequence_checker.DetachFromSequence(); |
234 #else | 240 |
235 TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) { | 241 PostToSequencedWorkerPool( |
236 DetachThenCallFromDifferentThreadDeathTest(); | 242 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
237 } | 243 "A"); |
238 #endif // ENABLE_SEQUENCE_CHECKER | 244 PostToSequencedWorkerPool( |
239 | 245 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
240 void SequenceCheckerTest::DifferentSequenceTokensDeathTest() { | 246 "A"); |
241 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 247 FlushSequencedWorkerPoolForTesting(); |
242 new SequenceCheckedObject); | 248 |
243 | 249 EXPECT_FALSE(sequence_checker.CalledOnValidSequencedThread()); |
244 sequence_checked_object->DetachFromSequence(); | 250 } |
245 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 251 |
246 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 252 TEST_F(SequenceCheckerTest, |
247 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 253 SequencedWorkerPool_TwoDifferentWorkerPoolsInvalid) { |
248 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 254 SequenceCheckerImpl sequence_checker; |
249 pool()->FlushForTesting(); | 255 sequence_checker.DetachFromSequence(); |
250 | 256 |
251 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 257 PostToSequencedWorkerPool( |
252 other_thread()->Stop(); | 258 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
253 } | 259 "A"); |
254 | 260 PostToSequencedWorkerPool( |
255 #if ENABLE_SEQUENCE_CHECKER | 261 Bind(&ExpectCalledOnValidSequencedThread, Unretained(&sequence_checker)), |
256 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) { | 262 "A"); |
257 // The default style "fast" does not support multi-threaded tests. | 263 FlushSequencedWorkerPoolForTesting(); |
258 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | |
259 ASSERT_DEATH({ | |
260 DifferentSequenceTokensDeathTest(); | |
261 }, ""); | |
262 } | |
263 #else | |
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 | 264 |
305 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); | 265 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); |
306 second_pool_owner.pool()->PostNamedSequencedWorkerTask( | 266 second_pool_owner.pool()->PostNamedSequencedWorkerTask( |
307 "A", | 267 "A", FROM_HERE, base::Bind(&ExpectNotCalledOnValidSequencedThread, |
308 FROM_HERE, | 268 base::Unretained(&sequence_checker))); |
309 base::Bind(&SequenceCheckedObject::DoStuff, | |
310 base::Unretained(sequence_checked_object.get()))); | |
311 second_pool_owner.pool()->FlushForTesting(); | 269 second_pool_owner.pool()->FlushForTesting(); |
312 } | 270 } |
313 | 271 |
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 | 272 } // namespace base |
333 | |
334 // Just in case we ever get lumped together with other compilation units. | |
335 #undef ENABLE_SEQUENCE_CHECKER | |
OLD | NEW |