// 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