• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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