diff options
Diffstat (limited to 'base/threading/scoped_blocking_call_unittest.cc')
-rw-r--r-- | base/threading/scoped_blocking_call_unittest.cc | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/base/threading/scoped_blocking_call_unittest.cc b/base/threading/scoped_blocking_call_unittest.cc new file mode 100644 index 0000000000..5e030f3518 --- /dev/null +++ b/base/threading/scoped_blocking_call_unittest.cc @@ -0,0 +1,134 @@ +// 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/scoped_blocking_call.h" + +#include <memory> + +#include "base/macros.h" +#include "base/test/gtest_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +namespace { + +class MockBlockingObserver : public internal::BlockingObserver { + public: + MockBlockingObserver() = default; + + MOCK_METHOD1(BlockingStarted, void(BlockingType)); + MOCK_METHOD0(BlockingTypeUpgraded, void()); + MOCK_METHOD0(BlockingEnded, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockBlockingObserver); +}; + +class ScopedBlockingCallTest : public testing::Test { + protected: + ScopedBlockingCallTest() { + internal::SetBlockingObserverForCurrentThread(&observer_); + } + + ~ScopedBlockingCallTest() override { + internal::ClearBlockingObserverForTesting(); + } + + testing::StrictMock<MockBlockingObserver> observer_; + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedBlockingCallTest); +}; + +} // namespace + +TEST_F(ScopedBlockingCallTest, MayBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK)); + ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, WillBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK)); + ScopedBlockingCall scoped_blocking_call(BlockingType::WILL_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, MayBlockWillBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK)); + ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { + EXPECT_CALL(observer_, BlockingTypeUpgraded()); + ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + } + + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, WillBlockMayBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK)); + ScopedBlockingCall scoped_blocking_call_a(BlockingType::WILL_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { ScopedBlockingCall scoped_blocking_call_b(BlockingType::MAY_BLOCK); } + + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, MayBlockMayBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK)); + ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { ScopedBlockingCall scoped_blocking_call_b(BlockingType::MAY_BLOCK); } + + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, WillBlockWillBlock) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK)); + ScopedBlockingCall scoped_blocking_call_a(BlockingType::WILL_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK); } + + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST_F(ScopedBlockingCallTest, MayBlockWillBlockTwice) { + EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK)); + ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { + EXPECT_CALL(observer_, BlockingTypeUpgraded()); + ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK); + testing::Mock::VerifyAndClear(&observer_); + + { + ScopedBlockingCall scoped_blocking_call_c(BlockingType::MAY_BLOCK); + ScopedBlockingCall scoped_blocking_call_d(BlockingType::WILL_BLOCK); + } + } + + EXPECT_CALL(observer_, BlockingEnded()); +} + +TEST(ScopedBlockingCallDestructionOrderTest, InvalidDestructionOrder) { + auto scoped_blocking_call_a = + std::make_unique<ScopedBlockingCall>(BlockingType::WILL_BLOCK); + auto scoped_blocking_call_b = + std::make_unique<ScopedBlockingCall>(BlockingType::WILL_BLOCK); + + EXPECT_DCHECK_DEATH({ scoped_blocking_call_a.reset(); }); +} + +} // namespace base |