xref: /aosp_15_r20/external/webrtc/api/sequence_checker_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <utility>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include "api/function_view.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/event.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/platform_thread.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
21*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker using testing::HasSubstr;
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
27*d9f75844SAndroid Build Coastguard Worker namespace {
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker // This class is dead code, but its purpose is to make sure that
30*d9f75844SAndroid Build Coastguard Worker // SequenceChecker is compatible with the RTC_GUARDED_BY and RTC_RUN_ON
31*d9f75844SAndroid Build Coastguard Worker // attributes that are checked at compile-time.
32*d9f75844SAndroid Build Coastguard Worker class CompileTimeTestForGuardedBy {
33*d9f75844SAndroid Build Coastguard Worker  public:
CalledOnSequence()34*d9f75844SAndroid Build Coastguard Worker   int CalledOnSequence() RTC_RUN_ON(sequence_checker_) { return guarded_; }
35*d9f75844SAndroid Build Coastguard Worker 
CallMeFromSequence()36*d9f75844SAndroid Build Coastguard Worker   void CallMeFromSequence() {
37*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_RUN_ON(&sequence_checker_);
38*d9f75844SAndroid Build Coastguard Worker     guarded_ = 41;
39*d9f75844SAndroid Build Coastguard Worker   }
40*d9f75844SAndroid Build Coastguard Worker 
41*d9f75844SAndroid Build Coastguard Worker  private:
42*d9f75844SAndroid Build Coastguard Worker   int guarded_ RTC_GUARDED_BY(sequence_checker_);
43*d9f75844SAndroid Build Coastguard Worker   ::webrtc::SequenceChecker sequence_checker_;
44*d9f75844SAndroid Build Coastguard Worker };
45*d9f75844SAndroid Build Coastguard Worker 
RunOnDifferentThread(rtc::FunctionView<void ()> run)46*d9f75844SAndroid Build Coastguard Worker void RunOnDifferentThread(rtc::FunctionView<void()> run) {
47*d9f75844SAndroid Build Coastguard Worker   rtc::Event thread_has_run_event;
48*d9f75844SAndroid Build Coastguard Worker   rtc::PlatformThread::SpawnJoinable(
49*d9f75844SAndroid Build Coastguard Worker       [&] {
50*d9f75844SAndroid Build Coastguard Worker         run();
51*d9f75844SAndroid Build Coastguard Worker         thread_has_run_event.Set();
52*d9f75844SAndroid Build Coastguard Worker       },
53*d9f75844SAndroid Build Coastguard Worker       "thread");
54*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread_has_run_event.Wait(TimeDelta::Seconds(1)));
55*d9f75844SAndroid Build Coastguard Worker }
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker }  // namespace
58*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,CallsAllowedOnSameThread)59*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, CallsAllowedOnSameThread) {
60*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
61*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(sequence_checker.IsCurrent());
62*d9f75844SAndroid Build Coastguard Worker }
63*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,DestructorAllowedOnDifferentThread)64*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DestructorAllowedOnDifferentThread) {
65*d9f75844SAndroid Build Coastguard Worker   auto sequence_checker = std::make_unique<SequenceChecker>();
66*d9f75844SAndroid Build Coastguard Worker   RunOnDifferentThread([&] {
67*d9f75844SAndroid Build Coastguard Worker     // Verify that the destructor doesn't assert when called on a different
68*d9f75844SAndroid Build Coastguard Worker     // thread.
69*d9f75844SAndroid Build Coastguard Worker     sequence_checker.reset();
70*d9f75844SAndroid Build Coastguard Worker   });
71*d9f75844SAndroid Build Coastguard Worker }
72*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,Detach)73*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, Detach) {
74*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
75*d9f75844SAndroid Build Coastguard Worker   sequence_checker.Detach();
76*d9f75844SAndroid Build Coastguard Worker   RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,DetachFromThreadAndUseOnTaskQueue)79*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromThreadAndUseOnTaskQueue) {
80*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
81*d9f75844SAndroid Build Coastguard Worker   sequence_checker.Detach();
82*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue;
83*d9f75844SAndroid Build Coastguard Worker   queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
84*d9f75844SAndroid Build Coastguard Worker }
85*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,DetachFromTaskQueueAndUseOnThread)86*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) {
87*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue;
88*d9f75844SAndroid Build Coastguard Worker   queue.SendTask([] {
89*d9f75844SAndroid Build Coastguard Worker     SequenceChecker sequence_checker;
90*d9f75844SAndroid Build Coastguard Worker     sequence_checker.Detach();
91*d9f75844SAndroid Build Coastguard Worker     RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
92*d9f75844SAndroid Build Coastguard Worker   });
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,MethodNotAllowedOnDifferentThreadInDebug)95*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) {
96*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
97*d9f75844SAndroid Build Coastguard Worker   RunOnDifferentThread(
98*d9f75844SAndroid Build Coastguard Worker       [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
99*d9f75844SAndroid Build Coastguard Worker }
100*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,MethodNotAllowedOnDifferentTaskQueueInDebug)101*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) {
102*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
103*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue;
104*d9f75844SAndroid Build Coastguard Worker   queue.SendTask(
105*d9f75844SAndroid Build Coastguard Worker       [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
106*d9f75844SAndroid Build Coastguard Worker }
107*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,DetachFromTaskQueueInDebug)108*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
109*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
110*d9f75844SAndroid Build Coastguard Worker   sequence_checker.Detach();
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue1;
113*d9f75844SAndroid Build Coastguard Worker   queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker   // IsCurrent should return false in debug builds after moving to
116*d9f75844SAndroid Build Coastguard Worker   // another task queue.
117*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue2;
118*d9f75844SAndroid Build Coastguard Worker   queue2.SendTask(
119*d9f75844SAndroid Build Coastguard Worker       [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
120*d9f75844SAndroid Build Coastguard Worker }
121*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,ExpectationToString)122*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, ExpectationToString) {
123*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue1;
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   SequenceChecker sequence_checker;
126*d9f75844SAndroid Build Coastguard Worker   sequence_checker.Detach();
127*d9f75844SAndroid Build Coastguard Worker 
128*d9f75844SAndroid Build Coastguard Worker   rtc::Event blocker;
129*d9f75844SAndroid Build Coastguard Worker   queue1.PostTask([&blocker, &sequence_checker]() {
130*d9f75844SAndroid Build Coastguard Worker     (void)sequence_checker.IsCurrent();
131*d9f75844SAndroid Build Coastguard Worker     blocker.Set();
132*d9f75844SAndroid Build Coastguard Worker   });
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker   blocker.Wait(rtc::Event::kForever);
135*d9f75844SAndroid Build Coastguard Worker 
136*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
137*d9f75844SAndroid Build Coastguard Worker 
138*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(ExpectationToString(&sequence_checker),
139*d9f75844SAndroid Build Coastguard Worker               HasSubstr("# Expected: TQ:"));
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   // Test for the base class
142*d9f75844SAndroid Build Coastguard Worker   webrtc_sequence_checker_internal::SequenceCheckerImpl* sequence_checker_base =
143*d9f75844SAndroid Build Coastguard Worker       &sequence_checker;
144*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(ExpectationToString(sequence_checker_base),
145*d9f75844SAndroid Build Coastguard Worker               HasSubstr("# Expected: TQ:"));
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker #else
148*d9f75844SAndroid Build Coastguard Worker   GTEST_ASSERT_EQ(ExpectationToString(&sequence_checker), "");
149*d9f75844SAndroid Build Coastguard Worker #endif
150*d9f75844SAndroid Build Coastguard Worker }
151*d9f75844SAndroid Build Coastguard Worker 
152*d9f75844SAndroid Build Coastguard Worker class TestAnnotations {
153*d9f75844SAndroid Build Coastguard Worker  public:
TestAnnotations()154*d9f75844SAndroid Build Coastguard Worker   TestAnnotations() : test_var_(false) {}
155*d9f75844SAndroid Build Coastguard Worker 
ModifyTestVar()156*d9f75844SAndroid Build Coastguard Worker   void ModifyTestVar() {
157*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_RUN_ON(&checker_);
158*d9f75844SAndroid Build Coastguard Worker     test_var_ = true;
159*d9f75844SAndroid Build Coastguard Worker   }
160*d9f75844SAndroid Build Coastguard Worker 
161*d9f75844SAndroid Build Coastguard Worker  private:
162*d9f75844SAndroid Build Coastguard Worker   bool test_var_ RTC_GUARDED_BY(&checker_);
163*d9f75844SAndroid Build Coastguard Worker   SequenceChecker checker_;
164*d9f75844SAndroid Build Coastguard Worker };
165*d9f75844SAndroid Build Coastguard Worker 
TEST(SequenceCheckerTest,TestAnnotations)166*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, TestAnnotations) {
167*d9f75844SAndroid Build Coastguard Worker   TestAnnotations annotations;
168*d9f75844SAndroid Build Coastguard Worker   annotations.ModifyTestVar();
169*d9f75844SAndroid Build Coastguard Worker }
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
172*d9f75844SAndroid Build Coastguard Worker 
TestAnnotationsOnWrongQueue()173*d9f75844SAndroid Build Coastguard Worker void TestAnnotationsOnWrongQueue() {
174*d9f75844SAndroid Build Coastguard Worker   TestAnnotations annotations;
175*d9f75844SAndroid Build Coastguard Worker   TaskQueueForTest queue;
176*d9f75844SAndroid Build Coastguard Worker   queue.SendTask([&] { annotations.ModifyTestVar(); });
177*d9f75844SAndroid Build Coastguard Worker }
178*d9f75844SAndroid Build Coastguard Worker 
179*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
180*d9f75844SAndroid Build Coastguard Worker // Note: Ending the test suite name with 'DeathTest' is important as it causes
181*d9f75844SAndroid Build Coastguard Worker // gtest to order this test before any other non-death-tests, to avoid potential
182*d9f75844SAndroid Build Coastguard Worker // global process state pollution such as shared worker threads being started
183*d9f75844SAndroid Build Coastguard Worker // (e.g. a side effect of calling InitCocoaMultiThreading() on Mac causes one or
184*d9f75844SAndroid Build Coastguard Worker // two additional threads to be created).
TEST(SequenceCheckerDeathTest,TestAnnotationsOnWrongQueueDebug)185*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerDeathTest, TestAnnotationsOnWrongQueueDebug) {
186*d9f75844SAndroid Build Coastguard Worker   ASSERT_DEATH({ TestAnnotationsOnWrongQueue(); }, "");
187*d9f75844SAndroid Build Coastguard Worker }
188*d9f75844SAndroid Build Coastguard Worker #else
TEST(SequenceCheckerTest,TestAnnotationsOnWrongQueueRelease)189*d9f75844SAndroid Build Coastguard Worker TEST(SequenceCheckerTest, TestAnnotationsOnWrongQueueRelease) {
190*d9f75844SAndroid Build Coastguard Worker   TestAnnotationsOnWrongQueue();
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker #endif
193*d9f75844SAndroid Build Coastguard Worker #endif  // GTEST_HAS_DEATH_TEST
194*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
195