summaryrefslogtreecommitdiff
path: root/base/threading/scoped_blocking_call_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'base/threading/scoped_blocking_call_unittest.cc')
-rw-r--r--base/threading/scoped_blocking_call_unittest.cc134
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