xref: /aosp_15_r20/external/cronet/base/threading/thread_checker_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/sequence_token.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/test_simple_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/threading/simple_thread.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_local.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace base::internal {
22*6777b538SAndroid Build Coastguard Worker namespace {
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker // A thread that runs a callback.
25*6777b538SAndroid Build Coastguard Worker class RunCallbackThread : public SimpleThread {
26*6777b538SAndroid Build Coastguard Worker  public:
RunCallbackThread(OnceClosure callback)27*6777b538SAndroid Build Coastguard Worker   explicit RunCallbackThread(OnceClosure callback)
28*6777b538SAndroid Build Coastguard Worker       : SimpleThread("RunCallbackThread"), callback_(std::move(callback)) {}
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker   RunCallbackThread(const RunCallbackThread&) = delete;
31*6777b538SAndroid Build Coastguard Worker   RunCallbackThread& operator=(const RunCallbackThread&) = delete;
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker  private:
34*6777b538SAndroid Build Coastguard Worker   // SimpleThread:
Run()35*6777b538SAndroid Build Coastguard Worker   void Run() override { std::move(callback_).Run(); }
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker   OnceClosure callback_;
38*6777b538SAndroid Build Coastguard Worker };
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker // Runs a callback on a new thread synchronously.
RunCallbackOnNewThreadSynchronously(OnceClosure callback)41*6777b538SAndroid Build Coastguard Worker void RunCallbackOnNewThreadSynchronously(OnceClosure callback) {
42*6777b538SAndroid Build Coastguard Worker   RunCallbackThread run_callback_thread(std::move(callback));
43*6777b538SAndroid Build Coastguard Worker   run_callback_thread.Start();
44*6777b538SAndroid Build Coastguard Worker   run_callback_thread.Join();
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker 
ExpectCalledOnValidThread(ThreadCheckerImpl * thread_checker)47*6777b538SAndroid Build Coastguard Worker void ExpectCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
48*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(thread_checker);
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // This should bind |thread_checker| to the current thread if it wasn't
51*6777b538SAndroid Build Coastguard Worker   // already bound to a thread.
52*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_checker->CalledOnValidThread());
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // Since |thread_checker| is now bound to the current thread, another call to
55*6777b538SAndroid Build Coastguard Worker   // CalledOnValidThread() should return true.
56*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_checker->CalledOnValidThread());
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
ExpectNotCalledOnValidThread(ThreadCheckerImpl * thread_checker)59*6777b538SAndroid Build Coastguard Worker void ExpectNotCalledOnValidThread(ThreadCheckerImpl* thread_checker) {
60*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(thread_checker);
61*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(thread_checker->CalledOnValidThread());
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound(ThreadCheckerImpl * thread_checker,SequenceToken sequence_token)64*6777b538SAndroid Build Coastguard Worker void ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound(
65*6777b538SAndroid Build Coastguard Worker     ThreadCheckerImpl* thread_checker,
66*6777b538SAndroid Build Coastguard Worker     SequenceToken sequence_token) {
67*6777b538SAndroid Build Coastguard Worker   TaskScope task_scope(sequence_token, /* is_thread_bound=*/true);
68*6777b538SAndroid Build Coastguard Worker   ExpectNotCalledOnValidThread(thread_checker);
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker }  // namespace
72*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,AllowedSameThreadNoSequenceToken)73*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadNoSequenceToken) {
74*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
75*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_checker.CalledOnValidThread());
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,AllowedSameThreadAndSequenceDifferentThreadBoundTasks)78*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadAndSequenceDifferentThreadBoundTasks) {
79*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ThreadCheckerImpl> thread_checker;
80*6777b538SAndroid Build Coastguard Worker   const SequenceToken sequence_token = SequenceToken::Create();
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   {
83*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(sequence_token,
84*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/true);
85*6777b538SAndroid Build Coastguard Worker     thread_checker = std::make_unique<ThreadCheckerImpl>();
86*6777b538SAndroid Build Coastguard Worker   }
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   {
89*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(sequence_token,
90*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/true);
91*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(thread_checker->CalledOnValidThread());
92*6777b538SAndroid Build Coastguard Worker   }
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,AllowedSameThreadSequenceAndTaskNotThreadBound)95*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, AllowedSameThreadSequenceAndTaskNotThreadBound) {
96*6777b538SAndroid Build Coastguard Worker   TaskScope task_scope(SequenceToken::Create(),
97*6777b538SAndroid Build Coastguard Worker                        /* is_thread_bound=*/false);
98*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
99*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_checker.CalledOnValidThread());
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DisallowedSameThreadAndSequenceDifferentTasksNotThreadBound)102*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest,
103*6777b538SAndroid Build Coastguard Worker      DisallowedSameThreadAndSequenceDifferentTasksNotThreadBound) {
104*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ThreadCheckerImpl> thread_checker;
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   {
107*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(SequenceToken::Create(),
108*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/false);
109*6777b538SAndroid Build Coastguard Worker     thread_checker = std::make_unique<ThreadCheckerImpl>();
110*6777b538SAndroid Build Coastguard Worker   }
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   {
113*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(SequenceToken::Create(),
114*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/false);
115*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(thread_checker->CalledOnValidThread());
116*6777b538SAndroid Build Coastguard Worker   }
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DisallowedDifferentThreadsNoSequenceToken)119*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedDifferentThreadsNoSequenceToken) {
120*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
121*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
122*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectNotCalledOnValidThread, Unretained(&thread_checker)));
123*6777b538SAndroid Build Coastguard Worker }
124*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DisallowedDifferentThreadsSameSequence)125*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedDifferentThreadsSameSequence) {
126*6777b538SAndroid Build Coastguard Worker   SingleThreadTaskRunner::CurrentDefaultHandle
127*6777b538SAndroid Build Coastguard Worker       single_thread_task_runner_current_default_handle(
128*6777b538SAndroid Build Coastguard Worker           MakeRefCounted<TestSimpleTaskRunner>());
129*6777b538SAndroid Build Coastguard Worker   const SequenceToken sequence_token(SequenceToken::Create());
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   TaskScope task_scope(sequence_token,
132*6777b538SAndroid Build Coastguard Worker                        /* is_thread_bound=*/false);
133*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
134*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_checker.CalledOnValidThread());
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
137*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectNotCalledOnValidThreadWithSequenceTokenThreadBound,
138*6777b538SAndroid Build Coastguard Worker                Unretained(&thread_checker), sequence_token));
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DisallowedSameThreadDifferentSequence)141*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DisallowedSameThreadDifferentSequence) {
142*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ThreadCheckerImpl> thread_checker;
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker   SingleThreadTaskRunner::CurrentDefaultHandle
145*6777b538SAndroid Build Coastguard Worker       single_thread_task_runner_current_default_handle(
146*6777b538SAndroid Build Coastguard Worker           MakeRefCounted<TestSimpleTaskRunner>());
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   {
149*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(SequenceToken::Create(),
150*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/false);
151*6777b538SAndroid Build Coastguard Worker     thread_checker = std::make_unique<ThreadCheckerImpl>();
152*6777b538SAndroid Build Coastguard Worker   }
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   {
155*6777b538SAndroid Build Coastguard Worker     // Different SequenceToken.
156*6777b538SAndroid Build Coastguard Worker     TaskScope task_scope(SequenceToken::Create(),
157*6777b538SAndroid Build Coastguard Worker                          /* is_thread_bound=*/false);
158*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(thread_checker->CalledOnValidThread());
159*6777b538SAndroid Build Coastguard Worker   }
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   // No SequenceToken.
162*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(thread_checker->CalledOnValidThread());
163*6777b538SAndroid Build Coastguard Worker }
164*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DetachFromThread)165*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DetachFromThread) {
166*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
167*6777b538SAndroid Build Coastguard Worker   thread_checker.DetachFromThread();
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker   // Verify that CalledOnValidThread() returns true when called on a different
170*6777b538SAndroid Build Coastguard Worker   // thread after a call to DetachFromThread().
171*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
172*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(thread_checker.CalledOnValidThread());
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,DetachFromThreadWithSequenceToken)177*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, DetachFromThreadWithSequenceToken) {
178*6777b538SAndroid Build Coastguard Worker   SingleThreadTaskRunner::CurrentDefaultHandle
179*6777b538SAndroid Build Coastguard Worker       single_thread_task_runner_current_default_handle(
180*6777b538SAndroid Build Coastguard Worker           MakeRefCounted<TestSimpleTaskRunner>());
181*6777b538SAndroid Build Coastguard Worker   TaskScope task_scope(SequenceToken::Create(),
182*6777b538SAndroid Build Coastguard Worker                        /* is_thread_bound=*/false);
183*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl thread_checker;
184*6777b538SAndroid Build Coastguard Worker   thread_checker.DetachFromThread();
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   // Verify that CalledOnValidThread() returns true when called on a different
187*6777b538SAndroid Build Coastguard Worker   // thread after a call to DetachFromThread().
188*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
189*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&thread_checker)));
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(thread_checker.CalledOnValidThread());
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker // Owns a ThreadCheckerImpl and asserts that CalledOnValidThread() is valid
195*6777b538SAndroid Build Coastguard Worker // in ~ThreadCheckerOwner.
196*6777b538SAndroid Build Coastguard Worker class ThreadCheckerOwner {
197*6777b538SAndroid Build Coastguard Worker  public:
ThreadCheckerOwner(bool detach_from_thread)198*6777b538SAndroid Build Coastguard Worker   explicit ThreadCheckerOwner(bool detach_from_thread) {
199*6777b538SAndroid Build Coastguard Worker     if (detach_from_thread)
200*6777b538SAndroid Build Coastguard Worker       checker_.DetachFromThread();
201*6777b538SAndroid Build Coastguard Worker   }
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker   ThreadCheckerOwner(const ThreadCheckerOwner&) = delete;
204*6777b538SAndroid Build Coastguard Worker   ThreadCheckerOwner& operator=(const ThreadCheckerOwner&) = delete;
205*6777b538SAndroid Build Coastguard Worker 
~ThreadCheckerOwner()206*6777b538SAndroid Build Coastguard Worker   ~ThreadCheckerOwner() { EXPECT_TRUE(checker_.CalledOnValidThread()); }
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker  private:
209*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl checker_;
210*6777b538SAndroid Build Coastguard Worker };
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker // Verifies ThreadCheckerImpl::CalledOnValidThread() returns true if called
213*6777b538SAndroid Build Coastguard Worker // during thread destruction.
TEST(ThreadCheckerTest,CalledOnValidThreadFromThreadDestruction)214*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestruction) {
215*6777b538SAndroid Build Coastguard Worker   ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
216*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
217*6777b538SAndroid Build Coastguard Worker     thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(false));
218*6777b538SAndroid Build Coastguard Worker   }));
219*6777b538SAndroid Build Coastguard Worker }
220*6777b538SAndroid Build Coastguard Worker 
221*6777b538SAndroid Build Coastguard Worker // Variant of CalledOnValidThreadFromThreadDestruction that calls
222*6777b538SAndroid Build Coastguard Worker // ThreadCheckerImpl::DetachFromThread().
TEST(ThreadCheckerTest,CalledOnValidThreadFromThreadDestructionDetached)223*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, CalledOnValidThreadFromThreadDestructionDetached) {
224*6777b538SAndroid Build Coastguard Worker   ThreadLocalOwnedPointer<ThreadCheckerOwner> thread_local_owner;
225*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(BindLambdaForTesting([&]() {
226*6777b538SAndroid Build Coastguard Worker     thread_local_owner.Set(std::make_unique<ThreadCheckerOwner>(true));
227*6777b538SAndroid Build Coastguard Worker   }));
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,Move)230*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, Move) {
231*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl initial;
232*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(initial.CalledOnValidThread());
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl move_constructed(std::move(initial));
235*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(move_constructed.CalledOnValidThread());
236*6777b538SAndroid Build Coastguard Worker 
237*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl move_assigned;
238*6777b538SAndroid Build Coastguard Worker   move_assigned = std::move(move_constructed);
239*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(move_assigned.CalledOnValidThread());
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   // The two ThreadCheckerImpls moved from should be able to rebind to another
242*6777b538SAndroid Build Coastguard Worker   // thread.
243*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
244*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
245*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
246*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&move_constructed)));
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   // But the latest one shouldn't be able to run on another thread.
249*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
250*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(move_assigned.CalledOnValidThread());
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,MoveAssignIntoDetached)255*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveAssignIntoDetached) {
256*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl initial;
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl move_assigned;
259*6777b538SAndroid Build Coastguard Worker   move_assigned.DetachFromThread();
260*6777b538SAndroid Build Coastguard Worker   move_assigned = std::move(initial);
261*6777b538SAndroid Build Coastguard Worker 
262*6777b538SAndroid Build Coastguard Worker   // |initial| is detached after move.
263*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
264*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
265*6777b538SAndroid Build Coastguard Worker 
266*6777b538SAndroid Build Coastguard Worker   // |move_assigned| should be associated with the main thread.
267*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
268*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectNotCalledOnValidThread, Unretained(&move_assigned)));
269*6777b538SAndroid Build Coastguard Worker 
270*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(move_assigned.CalledOnValidThread());
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,MoveFromDetachedRebinds)273*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveFromDetachedRebinds) {
274*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl initial;
275*6777b538SAndroid Build Coastguard Worker   initial.DetachFromThread();
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl moved_into(std::move(initial));
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker   // |initial| is still detached after move.
280*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
281*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&initial)));
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   // |moved_into| is bound to the current thread as part of the move.
284*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
285*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectNotCalledOnValidThread, Unretained(&moved_into)));
286*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(moved_into.CalledOnValidThread());
287*6777b538SAndroid Build Coastguard Worker }
288*6777b538SAndroid Build Coastguard Worker 
TEST(ThreadCheckerTest,MoveOffThreadBanned)289*6777b538SAndroid Build Coastguard Worker TEST(ThreadCheckerTest, MoveOffThreadBanned) {
290*6777b538SAndroid Build Coastguard Worker   GTEST_FLAG_SET(death_test_style, "threadsafe");
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   ThreadCheckerImpl other_thread;
293*6777b538SAndroid Build Coastguard Worker   other_thread.DetachFromThread();
294*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
295*6777b538SAndroid Build Coastguard Worker       BindOnce(&ExpectCalledOnValidThread, Unretained(&other_thread)));
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker   EXPECT_DCHECK_DEATH(ThreadCheckerImpl main_thread(std::move(other_thread)));
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker namespace {
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker // This fixture is a helper for unit testing the thread checker macros as it is
303*6777b538SAndroid Build Coastguard Worker // not possible to inline ExpectDeathOnOtherThread() and
304*6777b538SAndroid Build Coastguard Worker // ExpectNoDeathOnOtherThreadAfterDetach() as lambdas since binding
305*6777b538SAndroid Build Coastguard Worker // |Unretained(&my_sequence_checker)| wouldn't compile on non-dcheck builds
306*6777b538SAndroid Build Coastguard Worker // where it won't be defined.
307*6777b538SAndroid Build Coastguard Worker class ThreadCheckerMacroTest : public testing::Test {
308*6777b538SAndroid Build Coastguard Worker  public:
309*6777b538SAndroid Build Coastguard Worker   ThreadCheckerMacroTest() = default;
310*6777b538SAndroid Build Coastguard Worker 
311*6777b538SAndroid Build Coastguard Worker   ThreadCheckerMacroTest(const ThreadCheckerMacroTest&) = delete;
312*6777b538SAndroid Build Coastguard Worker   ThreadCheckerMacroTest& operator=(const ThreadCheckerMacroTest&) = delete;
313*6777b538SAndroid Build Coastguard Worker 
ExpectDeathOnOtherThread()314*6777b538SAndroid Build Coastguard Worker   void ExpectDeathOnOtherThread() {
315*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
316*6777b538SAndroid Build Coastguard Worker     EXPECT_DCHECK_DEATH({ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); });
317*6777b538SAndroid Build Coastguard Worker #else
318*6777b538SAndroid Build Coastguard Worker     // Happily no-ops on non-dcheck builds.
319*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
320*6777b538SAndroid Build Coastguard Worker #endif
321*6777b538SAndroid Build Coastguard Worker   }
322*6777b538SAndroid Build Coastguard Worker 
ExpectNoDeathOnOtherThreadAfterDetach()323*6777b538SAndroid Build Coastguard Worker   void ExpectNoDeathOnOtherThreadAfterDetach() {
324*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
325*6777b538SAndroid Build Coastguard Worker   }
326*6777b538SAndroid Build Coastguard Worker 
327*6777b538SAndroid Build Coastguard Worker  protected:
328*6777b538SAndroid Build Coastguard Worker   THREAD_CHECKER(thread_checker_);
329*6777b538SAndroid Build Coastguard Worker };
330*6777b538SAndroid Build Coastguard Worker 
331*6777b538SAndroid Build Coastguard Worker }  // namespace
332*6777b538SAndroid Build Coastguard Worker 
TEST_F(ThreadCheckerMacroTest,Macros)333*6777b538SAndroid Build Coastguard Worker TEST_F(ThreadCheckerMacroTest, Macros) {
334*6777b538SAndroid Build Coastguard Worker   GTEST_FLAG_SET(death_test_style, "threadsafe");
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker   THREAD_CHECKER(my_thread_checker);
337*6777b538SAndroid Build Coastguard Worker 
338*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(BindOnce(
339*6777b538SAndroid Build Coastguard Worker       &ThreadCheckerMacroTest::ExpectDeathOnOtherThread, Unretained(this)));
340*6777b538SAndroid Build Coastguard Worker 
341*6777b538SAndroid Build Coastguard Worker   DETACH_FROM_THREAD(thread_checker_);
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker   RunCallbackOnNewThreadSynchronously(
344*6777b538SAndroid Build Coastguard Worker       BindOnce(&ThreadCheckerMacroTest::ExpectNoDeathOnOtherThreadAfterDetach,
345*6777b538SAndroid Build Coastguard Worker                Unretained(this)));
346*6777b538SAndroid Build Coastguard Worker }
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker }  // namespace base::internal
349