blob: 41fd77be63ff7f053f8a6901b677903f6b05d4c3 [file] [log] [blame]
tommycli@chromium.org623e16c2013-07-31 04:26:40 +09001// Copyright 2013 The Chromium Authors. All rights reserved.
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avia6a6a682015-12-27 07:15:14 +09005#include <stddef.h>
6
dchengcc8e4d82016-04-05 06:25:51 +09007#include <memory>
fdoray4bcf1082016-07-27 07:28:45 +09008#include <string>
danakj800d2ea2015-11-25 14:29:58 +09009
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090010#include "base/bind.h"
11#include "base/bind_helpers.h"
fdoray4bcf1082016-07-27 07:28:45 +090012#include "base/callback_forward.h"
avia6a6a682015-12-27 07:15:14 +090013#include "base/macros.h"
fdoray4bcf1082016-07-27 07:28:45 +090014#include "base/message_loop/message_loop.h"
15#include "base/sequence_checker_impl.h"
16#include "base/sequence_token.h"
skyostil97aefe12015-05-01 04:06:15 +090017#include "base/single_thread_task_runner.h"
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090018#include "base/test/sequenced_worker_pool_owner.h"
fdoray4bcf1082016-07-27 07:28:45 +090019#include "base/threading/simple_thread.h"
dewittj@chromium.orgfadd9342013-07-27 02:10:02 +090020#include "testing/gtest/include/gtest/gtest.h"
tommycli@chromium.org755085a2013-07-26 23:23:56 +090021
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090022namespace base {
23
24namespace {
25
fdoray4bcf1082016-07-27 07:28:45 +090026constexpr size_t kNumWorkerThreads = 3;
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090027
fdoray4bcf1082016-07-27 07:28:45 +090028// Runs a callback on another thread.
29class RunCallbackThread : public SimpleThread {
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090030 public:
fdoray4bcf1082016-07-27 07:28:45 +090031 explicit RunCallbackThread(const Closure& callback)
32 : SimpleThread("RunCallbackThread"), callback_(callback) {
33 Start();
34 Join();
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090035 }
36
37 private:
fdoray4bcf1082016-07-27 07:28:45 +090038 // SimpleThread:
39 void Run() override { callback_.Run(); }
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090040
fdoray4bcf1082016-07-27 07:28:45 +090041 const Closure callback_;
42
43 DISALLOW_COPY_AND_ASSIGN(RunCallbackThread);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090044};
45
46class SequenceCheckerTest : public testing::Test {
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090047 protected:
fdoray4bcf1082016-07-27 07:28:45 +090048 SequenceCheckerTest() : pool_owner_(kNumWorkerThreads, "test") {}
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090049
fdoray4bcf1082016-07-27 07:28:45 +090050 void PostToSequencedWorkerPool(const Closure& callback,
51 const std::string& token_name) {
52 pool_owner_.pool()->PostNamedSequencedWorkerTask(token_name, FROM_HERE,
53 callback);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090054 }
55
fdoray4bcf1082016-07-27 07:28:45 +090056 void FlushSequencedWorkerPoolForTesting() {
57 pool_owner_.pool()->FlushForTesting();
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090058 }
59
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090060 private:
61 MessageLoop message_loop_; // Needed by SequencedWorkerPool to function.
fdoray4bcf1082016-07-27 07:28:45 +090062 SequencedWorkerPoolOwner pool_owner_;
63
64 DISALLOW_COPY_AND_ASSIGN(SequenceCheckerTest);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090065};
66
fdoraye4a58272016-07-29 11:30:16 +090067void ExpectCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
fdoray4bcf1082016-07-27 07:28:45 +090068 ASSERT_TRUE(sequence_checker);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090069
fdoray4bcf1082016-07-27 07:28:45 +090070 // This should bind |sequence_checker| to the current sequence if it wasn't
71 // already bound to a sequence.
fdoraye4a58272016-07-29 11:30:16 +090072 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090073
fdoray4bcf1082016-07-27 07:28:45 +090074 // Since |sequence_checker| is now bound to the current sequence, another call
fdoraye4a58272016-07-29 11:30:16 +090075 // to CalledOnValidSequence() should return true.
76 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090077}
78
fdoraye4a58272016-07-29 11:30:16 +090079void ExpectCalledOnValidSequenceWithSequenceToken(
fdoray4bcf1082016-07-27 07:28:45 +090080 SequenceCheckerImpl* sequence_checker,
81 SequenceToken sequence_token) {
82 ScopedSetSequenceTokenForCurrentThread
83 scoped_set_sequence_token_for_current_thread(sequence_token);
fdoraye4a58272016-07-29 11:30:16 +090084 ExpectCalledOnValidSequence(sequence_checker);
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090085}
86
fdoraye4a58272016-07-29 11:30:16 +090087void ExpectNotCalledOnValidSequence(SequenceCheckerImpl* sequence_checker) {
fdoray4bcf1082016-07-27 07:28:45 +090088 ASSERT_TRUE(sequence_checker);
fdoraye4a58272016-07-29 11:30:16 +090089 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090090}
91
akalin@chromium.org4fb2deb2012-12-28 04:58:00 +090092} // namespace
93
fdoray4bcf1082016-07-27 07:28:45 +090094TEST_F(SequenceCheckerTest, CallsAllowedOnSameThreadNoSequenceToken) {
95 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +090096 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +090097}
tommycli@chromium.org623e16c2013-07-31 04:26:40 +090098
fdoray4bcf1082016-07-27 07:28:45 +090099TEST_F(SequenceCheckerTest, CallsAllowedOnSameThreadSameSequenceToken) {
100 ScopedSetSequenceTokenForCurrentThread
101 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
102 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +0900103 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900104}
105
106TEST_F(SequenceCheckerTest, CallsDisallowedOnDifferentThreadsNoSequenceToken) {
107 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +0900108 RunCallbackThread thread(
109 Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)));
fdoray4bcf1082016-07-27 07:28:45 +0900110}
111
112TEST_F(SequenceCheckerTest, CallsAllowedOnDifferentThreadsSameSequenceToken) {
113 const SequenceToken sequence_token(SequenceToken::Create());
114
115 ScopedSetSequenceTokenForCurrentThread
116 scoped_set_sequence_token_for_current_thread(sequence_token);
117 SequenceCheckerImpl sequence_checker;
fdoraye4a58272016-07-29 11:30:16 +0900118 EXPECT_TRUE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900119
fdoraye4a58272016-07-29 11:30:16 +0900120 RunCallbackThread thread(Bind(&ExpectCalledOnValidSequenceWithSequenceToken,
121 Unretained(&sequence_checker), sequence_token));
fdoray4bcf1082016-07-27 07:28:45 +0900122}
123
124TEST_F(SequenceCheckerTest, CallsDisallowedOnSameThreadDifferentSequenceToken) {
125 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
126
127 {
128 ScopedSetSequenceTokenForCurrentThread
129 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
130 sequence_checker.reset(new SequenceCheckerImpl);
131 }
132
133 {
134 // Different SequenceToken.
135 ScopedSetSequenceTokenForCurrentThread
136 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
fdoraye4a58272016-07-29 11:30:16 +0900137 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900138 }
139
140 // No SequenceToken.
fdoraye4a58272016-07-29 11:30:16 +0900141 EXPECT_FALSE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900142}
143
144TEST_F(SequenceCheckerTest, DetachFromSequence) {
145 std::unique_ptr<SequenceCheckerImpl> sequence_checker;
146
147 {
148 ScopedSetSequenceTokenForCurrentThread
149 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
150 sequence_checker.reset(new SequenceCheckerImpl);
151 }
152
153 sequence_checker->DetachFromSequence();
154
155 {
fdoraye4a58272016-07-29 11:30:16 +0900156 // Verify that CalledOnValidSequence() returns true when called with
fdoray4bcf1082016-07-27 07:28:45 +0900157 // a different sequence token after a call to DetachFromSequence().
158 ScopedSetSequenceTokenForCurrentThread
159 scoped_set_sequence_token_for_current_thread(SequenceToken::Create());
fdoraye4a58272016-07-29 11:30:16 +0900160 EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900161 }
162}
163
164TEST_F(SequenceCheckerTest, DetachFromSequenceNoSequenceToken) {
165 SequenceCheckerImpl sequence_checker;
166 sequence_checker.DetachFromSequence();
167
fdoraye4a58272016-07-29 11:30:16 +0900168 // Verify that CalledOnValidSequence() returns true when called on a
fdoray4bcf1082016-07-27 07:28:45 +0900169 // different thread after a call to DetachFromSequence().
170 RunCallbackThread thread(
fdoraye4a58272016-07-29 11:30:16 +0900171 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)));
fdoray4bcf1082016-07-27 07:28:45 +0900172
fdoraye4a58272016-07-29 11:30:16 +0900173 EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900174}
175
176TEST_F(SequenceCheckerTest, SequencedWorkerPool_SameSequenceTokenValid) {
177 SequenceCheckerImpl sequence_checker;
178 sequence_checker.DetachFromSequence();
179
180 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900181 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900182 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900183 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900184 FlushSequencedWorkerPoolForTesting();
185}
186
187TEST_F(SequenceCheckerTest, SequencedWorkerPool_DetachSequenceTokenValid) {
188 SequenceCheckerImpl sequence_checker;
189 sequence_checker.DetachFromSequence();
190
191 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900192 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900193 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900194 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900195 FlushSequencedWorkerPoolForTesting();
196
197 sequence_checker.DetachFromSequence();
198
199 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900200 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "B");
fdoray4bcf1082016-07-27 07:28:45 +0900201 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900202 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "B");
fdoray4bcf1082016-07-27 07:28:45 +0900203 FlushSequencedWorkerPoolForTesting();
204}
205
206TEST_F(SequenceCheckerTest,
207 SequencedWorkerPool_DifferentSequenceTokensInvalid) {
208 SequenceCheckerImpl sequence_checker;
209 sequence_checker.DetachFromSequence();
210
211 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900212 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900213 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900214 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900215 FlushSequencedWorkerPoolForTesting();
216
fdoraye4a58272016-07-29 11:30:16 +0900217 PostToSequencedWorkerPool(
218 Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)),
219 "B");
220 PostToSequencedWorkerPool(
221 Bind(&ExpectNotCalledOnValidSequence, Unretained(&sequence_checker)),
222 "B");
fdoray4bcf1082016-07-27 07:28:45 +0900223 FlushSequencedWorkerPoolForTesting();
224}
225
226TEST_F(SequenceCheckerTest,
227 SequencedWorkerPool_WorkerPoolAndSimpleThreadInvalid) {
228 SequenceCheckerImpl sequence_checker;
229 sequence_checker.DetachFromSequence();
230
231 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900232 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900233 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900234 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900235 FlushSequencedWorkerPoolForTesting();
236
fdoraye4a58272016-07-29 11:30:16 +0900237 EXPECT_FALSE(sequence_checker.CalledOnValidSequence());
fdoray4bcf1082016-07-27 07:28:45 +0900238}
239
240TEST_F(SequenceCheckerTest,
241 SequencedWorkerPool_TwoDifferentWorkerPoolsInvalid) {
242 SequenceCheckerImpl sequence_checker;
243 sequence_checker.DetachFromSequence();
244
245 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900246 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900247 PostToSequencedWorkerPool(
fdoraye4a58272016-07-29 11:30:16 +0900248 Bind(&ExpectCalledOnValidSequence, Unretained(&sequence_checker)), "A");
fdoray4bcf1082016-07-27 07:28:45 +0900249 FlushSequencedWorkerPoolForTesting();
250
251 SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2");
252 second_pool_owner.pool()->PostNamedSequencedWorkerTask(
tzik6bdbeb22017-04-12 00:00:44 +0900253 "A", FROM_HERE,
254 base::BindOnce(&ExpectNotCalledOnValidSequence,
255 base::Unretained(&sequence_checker)));
fdoray4bcf1082016-07-27 07:28:45 +0900256 second_pool_owner.pool()->FlushForTesting();
257}
258
259} // namespace base