xref: /aosp_15_r20/external/cronet/base/threading/thread_restrictions_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/threading/thread_restrictions.h"
6 
7 #include <utility>
8 
9 #include "base/compiler_specific.h"
10 #include "base/dcheck_is_on.h"
11 #include "base/debug/stack_trace.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/test/gtest_util.h"
15 #include "build/build_config.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace base {
19 
20 namespace {
21 
22 class ThreadRestrictionsTest : public testing::Test {
23  public:
24   ThreadRestrictionsTest() = default;
25 
26   ThreadRestrictionsTest(const ThreadRestrictionsTest&) = delete;
27   ThreadRestrictionsTest& operator=(const ThreadRestrictionsTest&) = delete;
28 
~ThreadRestrictionsTest()29   ~ThreadRestrictionsTest() override {
30     internal::ResetThreadRestrictionsForTesting();
31   }
32 };
33 
34 }  // namespace
35 
TEST_F(ThreadRestrictionsTest,BlockingAllowedByDefault)36 TEST_F(ThreadRestrictionsTest, BlockingAllowedByDefault) {
37   internal::AssertBlockingAllowed();
38 }
39 
TEST_F(ThreadRestrictionsTest,ScopedDisallowBlocking)40 TEST_F(ThreadRestrictionsTest, ScopedDisallowBlocking) {
41   {
42     ScopedDisallowBlocking scoped_disallow_blocking;
43     EXPECT_DCHECK_DEATH({ internal::AssertBlockingAllowed(); });
44   }
45   internal::AssertBlockingAllowed();
46 }
47 
TEST_F(ThreadRestrictionsTest,ScopedAllowBlocking)48 TEST_F(ThreadRestrictionsTest, ScopedAllowBlocking) {
49   ScopedDisallowBlocking scoped_disallow_blocking;
50   {
51     ScopedAllowBlocking scoped_allow_blocking;
52     internal::AssertBlockingAllowed();
53   }
54   EXPECT_DCHECK_DEATH({ internal::AssertBlockingAllowed(); });
55 }
56 
TEST_F(ThreadRestrictionsTest,ScopedAllowBlockingForTesting)57 TEST_F(ThreadRestrictionsTest, ScopedAllowBlockingForTesting) {
58   ScopedDisallowBlocking scoped_disallow_blocking;
59   {
60     ScopedAllowBlockingForTesting scoped_allow_blocking_for_testing;
61     internal::AssertBlockingAllowed();
62   }
63   EXPECT_DCHECK_DEATH({ internal::AssertBlockingAllowed(); });
64 }
65 
TEST_F(ThreadRestrictionsTest,BaseSyncPrimitivesAllowedByDefault)66 TEST_F(ThreadRestrictionsTest, BaseSyncPrimitivesAllowedByDefault) {
67   internal::AssertBaseSyncPrimitivesAllowed();
68 }
69 
TEST_F(ThreadRestrictionsTest,DisallowBaseSyncPrimitives)70 TEST_F(ThreadRestrictionsTest, DisallowBaseSyncPrimitives) {
71   DisallowBaseSyncPrimitives();
72   EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
73 }
74 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitives)75 TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitives) {
76   DisallowBaseSyncPrimitives();
77   ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives;
78   internal::AssertBaseSyncPrimitivesAllowed();
79 }
80 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesResetsState)81 TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesResetsState) {
82   DisallowBaseSyncPrimitives();
83   { ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives; }
84   EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
85 }
86 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed)87 TEST_F(ThreadRestrictionsTest,
88        ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed) {
89   ScopedDisallowBlocking scoped_disallow_blocking;
90   DisallowBaseSyncPrimitives();
91 
92   // This should DCHECK because blocking is not allowed in this scope
93   // and OutsideBlockingScope is not passed to the constructor.
94   EXPECT_DCHECK_DEATH(
95       { ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives; });
96 }
97 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesOutsideBlockingScope)98 TEST_F(ThreadRestrictionsTest,
99        ScopedAllowBaseSyncPrimitivesOutsideBlockingScope) {
100   ScopedDisallowBlocking scoped_disallow_blocking;
101   DisallowBaseSyncPrimitives();
102   ScopedAllowBaseSyncPrimitivesOutsideBlockingScope
103       scoped_allow_base_sync_primitives;
104   internal::AssertBaseSyncPrimitivesAllowed();
105 }
106 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState)107 TEST_F(ThreadRestrictionsTest,
108        ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState) {
109   DisallowBaseSyncPrimitives();
110   {
111     ScopedAllowBaseSyncPrimitivesOutsideBlockingScope
112         scoped_allow_base_sync_primitives;
113   }
114   EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
115 }
116 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesForTesting)117 TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesForTesting) {
118   DisallowBaseSyncPrimitives();
119   ScopedAllowBaseSyncPrimitivesForTesting
120       scoped_allow_base_sync_primitives_for_testing;
121   internal::AssertBaseSyncPrimitivesAllowed();
122 }
123 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesForTestingResetsState)124 TEST_F(ThreadRestrictionsTest,
125        ScopedAllowBaseSyncPrimitivesForTestingResetsState) {
126   DisallowBaseSyncPrimitives();
127   {
128     ScopedAllowBaseSyncPrimitivesForTesting
129         scoped_allow_base_sync_primitives_for_testing;
130   }
131   EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
132 }
133 
TEST_F(ThreadRestrictionsTest,ScopedAllowBaseSyncPrimitivesForTestingWithBlockingDisallowed)134 TEST_F(ThreadRestrictionsTest,
135        ScopedAllowBaseSyncPrimitivesForTestingWithBlockingDisallowed) {
136   ScopedDisallowBlocking scoped_disallow_blocking;
137   DisallowBaseSyncPrimitives();
138   // This should not DCHECK.
139   ScopedAllowBaseSyncPrimitivesForTesting
140       scoped_allow_base_sync_primitives_for_testing;
141 }
142 
TEST_F(ThreadRestrictionsTest,ScopedDisallowBaseSyncPrimitives)143 TEST_F(ThreadRestrictionsTest, ScopedDisallowBaseSyncPrimitives) {
144   {
145     ScopedDisallowBaseSyncPrimitives disallow_sync_primitives;
146     EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
147   }
148   internal::AssertBaseSyncPrimitivesAllowed();
149 }
150 
TEST_F(ThreadRestrictionsTest,SingletonAllowedByDefault)151 TEST_F(ThreadRestrictionsTest, SingletonAllowedByDefault) {
152   internal::AssertSingletonAllowed();
153 }
154 
TEST_F(ThreadRestrictionsTest,DisallowSingleton)155 TEST_F(ThreadRestrictionsTest, DisallowSingleton) {
156   DisallowSingleton();
157   EXPECT_DCHECK_DEATH({ internal::AssertSingletonAllowed(); });
158 }
159 
TEST_F(ThreadRestrictionsTest,ScopedDisallowSingleton)160 TEST_F(ThreadRestrictionsTest, ScopedDisallowSingleton) {
161   {
162     ScopedDisallowSingleton disallow_sync_primitives;
163     EXPECT_DCHECK_DEATH({ internal::AssertSingletonAllowed(); });
164   }
165   internal::AssertSingletonAllowed();
166 }
167 
TEST_F(ThreadRestrictionsTest,LongCPUWorkAllowedByDefault)168 TEST_F(ThreadRestrictionsTest, LongCPUWorkAllowedByDefault) {
169   AssertLongCPUWorkAllowed();
170 }
171 
TEST_F(ThreadRestrictionsTest,DisallowUnresponsiveTasks)172 TEST_F(ThreadRestrictionsTest, DisallowUnresponsiveTasks) {
173   DisallowUnresponsiveTasks();
174   EXPECT_DCHECK_DEATH(internal::AssertBlockingAllowed());
175   EXPECT_DCHECK_DEATH(internal::AssertBaseSyncPrimitivesAllowed());
176   EXPECT_DCHECK_DEATH(AssertLongCPUWorkAllowed());
177 }
178 
179 // thread_restriction_checks_and_has_death_tests
180 #if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_ANDROID) && DCHECK_IS_ON() && \
181     defined(GTEST_HAS_DEATH_TEST)
182 
TEST_F(ThreadRestrictionsTest,BlockingCheckEmitsStack)183 TEST_F(ThreadRestrictionsTest, BlockingCheckEmitsStack) {
184   debug::OverrideStackTraceOutputForTesting enable_stacks_in_death_tests(
185       debug::OverrideStackTraceOutputForTesting::Mode::kForceOutput);
186   ScopedDisallowBlocking scoped_disallow_blocking;
187   // The above ScopedDisallowBlocking should be on the blame list for who set
188   // the ban.
189   EXPECT_DEATH({ internal::AssertBlockingAllowed(); },
190                EXPENSIVE_DCHECKS_ARE_ON() &&
191                        debug::StackTrace::WillSymbolizeToStreamForTesting()
192                    ? "ScopedDisallowBlocking"
193                    : "");
194   // And the stack should mention this test body as source.
195   EXPECT_DEATH({ internal::AssertBlockingAllowed(); },
196                EXPENSIVE_DCHECKS_ARE_ON() &&
197                        debug::StackTrace::WillSymbolizeToStreamForTesting()
198                    ? "BlockingCheckEmitsStack"
199                    : "");
200 }
201 
202 class TestCustomDisallow {
203  public:
TestCustomDisallow()204   NOINLINE TestCustomDisallow() { DisallowBlocking(); }
~TestCustomDisallow()205   NOINLINE ~TestCustomDisallow() { PermanentThreadAllowance::AllowBlocking(); }
206 };
207 
TEST_F(ThreadRestrictionsTest,NestedAllowRestoresPreviousStack)208 TEST_F(ThreadRestrictionsTest, NestedAllowRestoresPreviousStack) {
209   debug::OverrideStackTraceOutputForTesting enable_stacks_in_death_tests(
210       debug::OverrideStackTraceOutputForTesting::Mode::kForceOutput);
211   TestCustomDisallow custom_disallow;
212   {
213     ScopedAllowBlocking scoped_allow;
214     internal::AssertBlockingAllowed();
215   }
216   // TestCustomDisallow should be back on the blame list (as opposed to
217   // ~ScopedAllowBlocking which is the last one to have changed the state but is
218   // no longer relevant).
219   EXPECT_DEATH({ internal::AssertBlockingAllowed(); },
220                EXPENSIVE_DCHECKS_ARE_ON() &&
221                        debug::StackTrace::WillSymbolizeToStreamForTesting()
222                    ? "TestCustomDisallow"
223                    : "");
224   // And the stack should mention this test body as source.
225   EXPECT_DEATH({ internal::AssertBlockingAllowed(); },
226                EXPENSIVE_DCHECKS_ARE_ON() &&
227                        debug::StackTrace::WillSymbolizeToStreamForTesting()
228                    ? "NestedAllowRestoresPreviousStack"
229                    : "");
230 }
231 
232 #endif  // thread_restriction_checks_and_has_death_tests
233 
234 }  // namespace base
235