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" | 5 #include "base/sequence_checker.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/test/gtest_util.h" |
19 #include "base/test/sequenced_worker_pool_owner.h" | 20 #include "base/test/sequenced_worker_pool_owner.h" |
20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 // Duplicated from base/sequence_checker.h so that we can be good citizens | 24 // Duplicated from base/sequence_checker.h so that we can be good citizens |
24 // there and undef the macro. | 25 // there and undef the macro. |
25 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) | 26 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) |
26 #define ENABLE_SEQUENCE_CHECKER 1 | 27 #define ENABLE_SEQUENCE_CHECKER 1 |
27 #else | 28 #else |
28 #define ENABLE_SEQUENCE_CHECKER 0 | 29 #define ENABLE_SEQUENCE_CHECKER 0 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 176 |
176 sequence_checked_object->DetachFromSequence(); | 177 sequence_checked_object->DetachFromSequence(); |
177 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 178 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); |
178 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 179 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); |
179 pool()->FlushForTesting(); | 180 pool()->FlushForTesting(); |
180 | 181 |
181 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 182 PostDeleteToOtherThread(std::move(sequence_checked_object)); |
182 other_thread()->Stop(); | 183 other_thread()->Stop(); |
183 } | 184 } |
184 | 185 |
185 #if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER | |
186 | |
187 void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() { | 186 void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() { |
188 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 187 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( |
189 new SequenceCheckedObject); | 188 new SequenceCheckedObject); |
190 | 189 |
191 // DoStuff should assert in debug builds only when called on a | 190 // DoStuff should assert in debug builds only when called on a |
192 // different thread. | 191 // different thread. |
193 PostDoStuffToOtherThread(sequence_checked_object.get()); | 192 PostDoStuffToOtherThread(sequence_checked_object.get()); |
194 other_thread()->Stop(); | 193 other_thread()->Stop(); |
195 } | 194 } |
196 | 195 |
197 #if ENABLE_SEQUENCE_CHECKER | 196 #if ENABLE_SEQUENCE_CHECKER |
198 TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) { | 197 TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) { |
199 // The default style "fast" does not support multi-threaded tests. | 198 // The default style "fast" does not support multi-threaded tests. |
200 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 199 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
201 ASSERT_DEATH({ | 200 ASSERT_DCHECK_DEATH({ MethodOnDifferentThreadDeathTest(); }, ""); |
202 MethodOnDifferentThreadDeathTest(); | |
203 }, ""); | |
204 } | 201 } |
205 #else | 202 #else |
206 TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) { | 203 TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) { |
207 MethodOnDifferentThreadDeathTest(); | 204 MethodOnDifferentThreadDeathTest(); |
208 } | 205 } |
209 #endif // ENABLE_SEQUENCE_CHECKER | 206 #endif // ENABLE_SEQUENCE_CHECKER |
210 | 207 |
211 void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() { | 208 void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() { |
212 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 209 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( |
213 new SequenceCheckedObject); | 210 new SequenceCheckedObject); |
214 | 211 |
215 // DoStuff doesn't assert when called on a different thread | 212 // DoStuff doesn't assert when called on a different thread |
216 // after a call to DetachFromSequence. | 213 // after a call to DetachFromSequence. |
217 sequence_checked_object->DetachFromSequence(); | 214 sequence_checked_object->DetachFromSequence(); |
218 PostDoStuffToOtherThread(sequence_checked_object.get()); | 215 PostDoStuffToOtherThread(sequence_checked_object.get()); |
219 other_thread()->Stop(); | 216 other_thread()->Stop(); |
220 | 217 |
221 // DoStuff should assert in debug builds only after moving to | 218 // DoStuff should assert in debug builds only after moving to |
222 // another thread. | 219 // another thread. |
223 sequence_checked_object->DoStuff(); | 220 sequence_checked_object->DoStuff(); |
224 } | 221 } |
225 | 222 |
226 #if ENABLE_SEQUENCE_CHECKER | 223 #if ENABLE_SEQUENCE_CHECKER |
227 TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) { | 224 TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) { |
228 // The default style "fast" does not support multi-threaded tests. | 225 // The default style "fast" does not support multi-threaded tests. |
229 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 226 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
230 ASSERT_DEATH({ | 227 ASSERT_DCHECK_DEATH({ DetachThenCallFromDifferentThreadDeathTest(); }, ""); |
231 DetachThenCallFromDifferentThreadDeathTest(); | |
232 }, ""); | |
233 } | 228 } |
234 #else | 229 #else |
235 TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) { | 230 TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) { |
236 DetachThenCallFromDifferentThreadDeathTest(); | 231 DetachThenCallFromDifferentThreadDeathTest(); |
237 } | 232 } |
238 #endif // ENABLE_SEQUENCE_CHECKER | 233 #endif // ENABLE_SEQUENCE_CHECKER |
239 | 234 |
240 void SequenceCheckerTest::DifferentSequenceTokensDeathTest() { | 235 void SequenceCheckerTest::DifferentSequenceTokensDeathTest() { |
241 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 236 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( |
242 new SequenceCheckedObject); | 237 new SequenceCheckedObject); |
243 | 238 |
244 sequence_checked_object->DetachFromSequence(); | 239 sequence_checked_object->DetachFromSequence(); |
245 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 240 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
246 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 241 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
247 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 242 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); |
248 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); | 243 PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); |
249 pool()->FlushForTesting(); | 244 pool()->FlushForTesting(); |
250 | 245 |
251 PostDeleteToOtherThread(std::move(sequence_checked_object)); | 246 PostDeleteToOtherThread(std::move(sequence_checked_object)); |
252 other_thread()->Stop(); | 247 other_thread()->Stop(); |
253 } | 248 } |
254 | 249 |
255 #if ENABLE_SEQUENCE_CHECKER | 250 #if ENABLE_SEQUENCE_CHECKER |
256 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) { | 251 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) { |
257 // The default style "fast" does not support multi-threaded tests. | 252 // The default style "fast" does not support multi-threaded tests. |
258 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 253 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
259 ASSERT_DEATH({ | 254 ASSERT_DCHECK_DEATH({ DifferentSequenceTokensDeathTest(); }, ""); |
260 DifferentSequenceTokensDeathTest(); | |
261 }, ""); | |
262 } | 255 } |
263 #else | 256 #else |
264 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInRelease) { | 257 TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInRelease) { |
265 DifferentSequenceTokensDeathTest(); | 258 DifferentSequenceTokensDeathTest(); |
266 } | 259 } |
267 #endif // ENABLE_SEQUENCE_CHECKER | 260 #endif // ENABLE_SEQUENCE_CHECKER |
268 | 261 |
269 void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() { | 262 void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() { |
270 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 263 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( |
271 new SequenceCheckedObject); | 264 new SequenceCheckedObject); |
272 | 265 |
273 sequence_checked_object->DetachFromSequence(); | 266 sequence_checked_object->DetachFromSequence(); |
274 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 267 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
275 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 268 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
276 pool()->FlushForTesting(); | 269 pool()->FlushForTesting(); |
277 | 270 |
278 PostDoStuffToOtherThread(sequence_checked_object.get()); | 271 PostDoStuffToOtherThread(sequence_checked_object.get()); |
279 other_thread()->Stop(); | 272 other_thread()->Stop(); |
280 } | 273 } |
281 | 274 |
282 #if ENABLE_SEQUENCE_CHECKER | 275 #if ENABLE_SEQUENCE_CHECKER |
283 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) { | 276 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) { |
284 // The default style "fast" does not support multi-threaded tests. | 277 // The default style "fast" does not support multi-threaded tests. |
285 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 278 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
286 ASSERT_DEATH({ | 279 ASSERT_DCHECK_DEATH({ WorkerPoolAndSimpleThreadDeathTest(); }, ""); |
287 WorkerPoolAndSimpleThreadDeathTest(); | |
288 }, ""); | |
289 } | 280 } |
290 #else | 281 #else |
291 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInRelease) { | 282 TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInRelease) { |
292 WorkerPoolAndSimpleThreadDeathTest(); | 283 WorkerPoolAndSimpleThreadDeathTest(); |
293 } | 284 } |
294 #endif // ENABLE_SEQUENCE_CHECKER | 285 #endif // ENABLE_SEQUENCE_CHECKER |
295 | 286 |
296 void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() { | 287 void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() { |
297 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( | 288 std::unique_ptr<SequenceCheckedObject> sequence_checked_object( |
298 new SequenceCheckedObject); | 289 new SequenceCheckedObject); |
299 | 290 |
300 sequence_checked_object->DetachFromSequence(); | 291 sequence_checked_object->DetachFromSequence(); |
301 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 292 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
302 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); | 293 PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); |
303 pool()->FlushForTesting(); | 294 pool()->FlushForTesting(); |
304 | 295 |
305 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); | 296 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); |
306 second_pool_owner.pool()->PostNamedSequencedWorkerTask( | 297 second_pool_owner.pool()->PostNamedSequencedWorkerTask( |
307 "A", | 298 "A", |
308 FROM_HERE, | 299 FROM_HERE, |
309 base::Bind(&SequenceCheckedObject::DoStuff, | 300 base::Bind(&SequenceCheckedObject::DoStuff, |
310 base::Unretained(sequence_checked_object.get()))); | 301 base::Unretained(sequence_checked_object.get()))); |
311 second_pool_owner.pool()->FlushForTesting(); | 302 second_pool_owner.pool()->FlushForTesting(); |
312 } | 303 } |
313 | 304 |
314 #if ENABLE_SEQUENCE_CHECKER | 305 #if ENABLE_SEQUENCE_CHECKER |
315 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) { | 306 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) { |
316 // The default style "fast" does not support multi-threaded tests. | 307 // The default style "fast" does not support multi-threaded tests. |
317 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 308 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
318 ASSERT_DEATH({ | 309 ASSERT_DCHECK_DEATH({ TwoDifferentWorkerPoolsDeathTest(); }, ""); |
319 TwoDifferentWorkerPoolsDeathTest(); | |
320 }, ""); | |
321 } | 310 } |
322 #else | 311 #else |
323 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInRelease) { | 312 TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInRelease) { |
324 TwoDifferentWorkerPoolsDeathTest(); | 313 TwoDifferentWorkerPoolsDeathTest(); |
325 } | 314 } |
326 #endif // ENABLE_SEQUENCE_CHECKER | 315 #endif // ENABLE_SEQUENCE_CHECKER |
327 | 316 |
328 #endif // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER | |
329 | |
330 } // namespace | 317 } // namespace |
331 | 318 |
332 } // namespace base | 319 } // namespace base |
333 | 320 |
334 // Just in case we ever get lumped together with other compilation units. | 321 // Just in case we ever get lumped together with other compilation units. |
335 #undef ENABLE_SEQUENCE_CHECKER | 322 #undef ENABLE_SEQUENCE_CHECKER |
OLD | NEW |