// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/threading/thread_restrictions.h" #include <utility> #include "base/bind.h" #include "base/callback.h" #include "base/macros.h" #include "base/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { namespace { class ThreadRestrictionsTest : public testing::Test { public: ThreadRestrictionsTest() = default; ~ThreadRestrictionsTest() override { internal::ResetThreadRestrictionsForTesting(); } private: DISALLOW_COPY_AND_ASSIGN(ThreadRestrictionsTest); }; } // namespace TEST_F(ThreadRestrictionsTest, BlockingAllowedByDefault) { AssertBlockingAllowed(); } TEST_F(ThreadRestrictionsTest, ScopedDisallowBlocking) { { ScopedDisallowBlocking scoped_disallow_blocking; EXPECT_DCHECK_DEATH({ AssertBlockingAllowed(); }); } AssertBlockingAllowed(); } TEST_F(ThreadRestrictionsTest, ScopedAllowBlocking) { ScopedDisallowBlocking scoped_disallow_blocking; { ScopedAllowBlocking scoped_allow_blocking; AssertBlockingAllowed(); } EXPECT_DCHECK_DEATH({ AssertBlockingAllowed(); }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBlockingForTesting) { ScopedDisallowBlocking scoped_disallow_blocking; { ScopedAllowBlockingForTesting scoped_allow_blocking_for_testing; AssertBlockingAllowed(); } EXPECT_DCHECK_DEATH({ AssertBlockingAllowed(); }); } TEST_F(ThreadRestrictionsTest, BaseSyncPrimitivesAllowedByDefault) {} TEST_F(ThreadRestrictionsTest, DisallowBaseSyncPrimitives) { DisallowBaseSyncPrimitives(); EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitives) { DisallowBaseSyncPrimitives(); ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives; internal::AssertBaseSyncPrimitivesAllowed(); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesResetsState) { DisallowBaseSyncPrimitives(); { ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives; } EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesWithBlockingDisallowed) { ScopedDisallowBlocking scoped_disallow_blocking; DisallowBaseSyncPrimitives(); // This should DCHECK because blocking is not allowed in this scope // and OutsideBlockingScope is not passed to the constructor. EXPECT_DCHECK_DEATH( { ScopedAllowBaseSyncPrimitives scoped_allow_base_sync_primitives; }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesOutsideBlockingScope) { ScopedDisallowBlocking scoped_disallow_blocking; DisallowBaseSyncPrimitives(); ScopedAllowBaseSyncPrimitivesOutsideBlockingScope scoped_allow_base_sync_primitives; internal::AssertBaseSyncPrimitivesAllowed(); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesOutsideBlockingScopeResetsState) { DisallowBaseSyncPrimitives(); { ScopedAllowBaseSyncPrimitivesOutsideBlockingScope scoped_allow_base_sync_primitives; } EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesForTesting) { DisallowBaseSyncPrimitives(); ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_base_sync_primitives_for_testing; internal::AssertBaseSyncPrimitivesAllowed(); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesForTestingResetsState) { DisallowBaseSyncPrimitives(); { ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_base_sync_primitives_for_testing; } EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); }); } TEST_F(ThreadRestrictionsTest, ScopedAllowBaseSyncPrimitivesForTestingWithBlockingDisallowed) { ScopedDisallowBlocking scoped_disallow_blocking; DisallowBaseSyncPrimitives(); // This should not DCHECK. ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_base_sync_primitives_for_testing; } } // namespace base