| 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 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 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 102 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 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 117 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 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 131 SequenceToken::Create()); |
| 132 sequence_checker.reset(new SequenceCheckerImpl); |
| 133 } |
| 134 |
| 135 { |
| 136 // Different SequenceToken. |
| 137 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 138 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 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 145 // a call to DetachFromSequence. | 151 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 ScopedSetCurrentSequenceToken scoped_set_current_sequence_token( |
| 155 | 161 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 |