| 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 |