1 // Copyright 2017 The Chromium Authors. All rights reserved.
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/scoped_blocking_call.h"
6
7 #include <memory>
8
9 #include "base/macros.h"
10 #include "base/test/gtest_util.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace base {
15
16 namespace {
17
18 class MockBlockingObserver : public internal::BlockingObserver {
19 public:
20 MockBlockingObserver() = default;
21
22 MOCK_METHOD1(BlockingStarted, void(BlockingType));
23 MOCK_METHOD0(BlockingTypeUpgraded, void());
24 MOCK_METHOD0(BlockingEnded, void());
25
26 private:
27 DISALLOW_COPY_AND_ASSIGN(MockBlockingObserver);
28 };
29
30 class ScopedBlockingCallTest : public testing::Test {
31 protected:
ScopedBlockingCallTest()32 ScopedBlockingCallTest() {
33 internal::SetBlockingObserverForCurrentThread(&observer_);
34 }
35
~ScopedBlockingCallTest()36 ~ScopedBlockingCallTest() override {
37 internal::ClearBlockingObserverForTesting();
38 }
39
40 testing::StrictMock<MockBlockingObserver> observer_;
41
42 private:
43 DISALLOW_COPY_AND_ASSIGN(ScopedBlockingCallTest);
44 };
45
46 } // namespace
47
TEST_F(ScopedBlockingCallTest,MayBlock)48 TEST_F(ScopedBlockingCallTest, MayBlock) {
49 EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK));
50 ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
51 testing::Mock::VerifyAndClear(&observer_);
52 EXPECT_CALL(observer_, BlockingEnded());
53 }
54
TEST_F(ScopedBlockingCallTest,WillBlock)55 TEST_F(ScopedBlockingCallTest, WillBlock) {
56 EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK));
57 ScopedBlockingCall scoped_blocking_call(BlockingType::WILL_BLOCK);
58 testing::Mock::VerifyAndClear(&observer_);
59 EXPECT_CALL(observer_, BlockingEnded());
60 }
61
TEST_F(ScopedBlockingCallTest,MayBlockWillBlock)62 TEST_F(ScopedBlockingCallTest, MayBlockWillBlock) {
63 EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK));
64 ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK);
65 testing::Mock::VerifyAndClear(&observer_);
66
67 {
68 EXPECT_CALL(observer_, BlockingTypeUpgraded());
69 ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK);
70 testing::Mock::VerifyAndClear(&observer_);
71 }
72
73 EXPECT_CALL(observer_, BlockingEnded());
74 }
75
TEST_F(ScopedBlockingCallTest,WillBlockMayBlock)76 TEST_F(ScopedBlockingCallTest, WillBlockMayBlock) {
77 EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK));
78 ScopedBlockingCall scoped_blocking_call_a(BlockingType::WILL_BLOCK);
79 testing::Mock::VerifyAndClear(&observer_);
80
81 { ScopedBlockingCall scoped_blocking_call_b(BlockingType::MAY_BLOCK); }
82
83 EXPECT_CALL(observer_, BlockingEnded());
84 }
85
TEST_F(ScopedBlockingCallTest,MayBlockMayBlock)86 TEST_F(ScopedBlockingCallTest, MayBlockMayBlock) {
87 EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK));
88 ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK);
89 testing::Mock::VerifyAndClear(&observer_);
90
91 { ScopedBlockingCall scoped_blocking_call_b(BlockingType::MAY_BLOCK); }
92
93 EXPECT_CALL(observer_, BlockingEnded());
94 }
95
TEST_F(ScopedBlockingCallTest,WillBlockWillBlock)96 TEST_F(ScopedBlockingCallTest, WillBlockWillBlock) {
97 EXPECT_CALL(observer_, BlockingStarted(BlockingType::WILL_BLOCK));
98 ScopedBlockingCall scoped_blocking_call_a(BlockingType::WILL_BLOCK);
99 testing::Mock::VerifyAndClear(&observer_);
100
101 { ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK); }
102
103 EXPECT_CALL(observer_, BlockingEnded());
104 }
105
TEST_F(ScopedBlockingCallTest,MayBlockWillBlockTwice)106 TEST_F(ScopedBlockingCallTest, MayBlockWillBlockTwice) {
107 EXPECT_CALL(observer_, BlockingStarted(BlockingType::MAY_BLOCK));
108 ScopedBlockingCall scoped_blocking_call_a(BlockingType::MAY_BLOCK);
109 testing::Mock::VerifyAndClear(&observer_);
110
111 {
112 EXPECT_CALL(observer_, BlockingTypeUpgraded());
113 ScopedBlockingCall scoped_blocking_call_b(BlockingType::WILL_BLOCK);
114 testing::Mock::VerifyAndClear(&observer_);
115
116 {
117 ScopedBlockingCall scoped_blocking_call_c(BlockingType::MAY_BLOCK);
118 ScopedBlockingCall scoped_blocking_call_d(BlockingType::WILL_BLOCK);
119 }
120 }
121
122 EXPECT_CALL(observer_, BlockingEnded());
123 }
124
TEST(ScopedBlockingCallDestructionOrderTest,InvalidDestructionOrder)125 TEST(ScopedBlockingCallDestructionOrderTest, InvalidDestructionOrder) {
126 auto scoped_blocking_call_a =
127 std::make_unique<ScopedBlockingCall>(BlockingType::WILL_BLOCK);
128 auto scoped_blocking_call_b =
129 std::make_unique<ScopedBlockingCall>(BlockingType::WILL_BLOCK);
130
131 EXPECT_DCHECK_DEATH({ scoped_blocking_call_a.reset(); });
132 }
133
134 } // namespace base
135