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
3 // found in the LICENSE file.
5 #include "base/sequence_checker.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/callback_forward.h"
15 #include "base/macros.h"
16 #include "base/sequence_token.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/test/gtest_util.h"
19 #include "base/threading/simple_thread.h"
20 #include "testing/gtest/include/gtest/gtest.h"
26 // Runs a callback on another thread.
27 class RunCallbackThread : public SimpleThread {
29 explicit RunCallbackThread(const Closure& callback)
30 : SimpleThread("RunCallbackThread"), callback_(callback) {
37 void Run() override { callback_.Run(); }
39 const Closure callback_;
41 DISALLOW_COPY_AND_ASSIGN(RunCallbackThread);
44 void ExpectCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
45 ASSERT_TRUE(sequence_checker);
47 // This should bind |sequence_checker| to the current sequence if it wasn't
48 // already bound to a sequence.
49 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
51 // Since |sequence_checker| is now bound to the current sequence, another call
52 // to CalledOnValidSequence() should return true.
53 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
56 void ExpectCalledOnValidSequenceWithSequenceToken(
57 SequenceCheckerImpl* sequence_checker,
58 SequenceToken sequence_token) {
59 ScopedSetSequenceTokenForCurrentThread
60 scoped_set_sequence_token_for_current_thread(sequence_token);
61 ExpectCalledOnValidSequence(sequence_checker);
64 void ExpectNotCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
65 ASSERT_TRUE(sequence_checker);
66 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
71 TEST(SequenceCheckerTest, CallsAllowedOnSameThreadNoSequenceToken) {
72 SequenceCheckerImpl sequence_checker;
73 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
76 TEST(SequenceCheckerTest, CallsAllowedOnSameThreadSameSequenceToken) {
77 ScopedSetSequenceTokenForCurrentThread
78 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
79 SequenceCheckerImpl sequence_checker;
80 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
83 TEST(SequenceCheckerTest, CallsDisallowedOnDifferentThreadsNoSequenceToken) {
84 SequenceCheckerImpl sequence_checker;
85 RunCallbackThread thread(
86 Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)));
89 TEST(SequenceCheckerTest, CallsAllowedOnDifferentThreadsSameSequenceToken) {
90 const SequenceToken sequence_token(SequenceToken::Create());
92 ScopedSetSequenceTokenForCurrentThread
93 scoped_set_sequence_token_for_current_thread(sequence_token);
94 SequenceCheckerImpl sequence_checker;
95 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
97 RunCallbackThread thread(Bind(&ExpectCalledOnValidSequenceWithSequenceToken,
98 Unretained(&sequence_checker), sequence_token));
101 TEST(SequenceCheckerTest, CallsDisallowedOnSameThreadDifferentSequenceToken) {
102 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
105 ScopedSetSequenceTokenForCurrentThread
106 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
107 sequence_checker.reset(new SequenceCheckerImpl);
111 // Different SequenceToken.
112 ScopedSetSequenceTokenForCurrentThread
113 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
114 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
118 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
121 TEST(SequenceCheckerTest, DetachFromSequence) {
122 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
125 ScopedSetSequenceTokenForCurrentThread
126 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
127 sequence_checker.reset(new SequenceCheckerImpl);
130 sequence_checker->DetachFromSequence();
133 // Verify that CalledOnValidSequence() returns true when called with
134 // a different sequence token after a call to DetachFromSequence().
135 ScopedSetSequenceTokenForCurrentThread
136 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
137 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
141 TEST(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) {
142 SequenceCheckerImpl sequence_checker;
143 sequence_checker.DetachFromSequence();
145 // Verify that CalledOnValidSequence() returns true when called on a
146 // different thread after a call to DetachFromSequence().
147 RunCallbackThread thread(
148 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)));
150 EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
153 TEST(SequenceCheckerMacroTest, Macros) {
154 auto scope = std::make_unique<ScopedSetSequenceTokenForCurrentThread>(
155 SequenceToken::Create());
156 SEQUENCE_CHECKER(my_sequence_checker);
158 // Don't expect a DCHECK death when a SequenceChecker is used on the right
160 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
165 // Expect DCHECK death when used on a different sequence.
166 EXPECT_DCHECK_DEATH({
167 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
170 // Happily no-ops on non-dcheck builds.
171 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";
174 DETACH_FROM_SEQUENCE(my_sequence_checker);
176 // Don't expect a DCHECK death when a SequenceChecker is used for the first
177 // time after having been detached.
178 DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker) << "Error message.";