1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // Testing utilities that extend gtest. 6 7 #ifndef NET_TEST_GTEST_UTIL_H_ 8 #define NET_TEST_GTEST_UTIL_H_ 9 10 #include <string> 11 12 #include "base/strings/string_piece.h" 13 #include "base/test/mock_log.h" 14 #include "net/base/net_errors.h" 15 #include "net/test/scoped_disable_exit_on_dfatal.h" 16 #include "testing/gmock/include/gmock/gmock-matchers.h" 17 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace net::test { 21 22 // A GMock matcher that checks whether the argument is the expected net::Error. 23 // On failure, the expected and actual net::Error names will be printed. 24 // Usage: EXPECT_THAT(foo(), IsError(net::ERR_INVALID_ARGUMENT)); 25 MATCHER_P(IsError, 26 expected, 27 std::string(negation ? "not " : "") + net::ErrorToString(expected)) { 28 if (arg <= 0) 29 *result_listener << net::ErrorToString(arg); 30 return arg == expected; 31 } 32 33 // Shorthand for IsError(net::OK). 34 // Usage: EXPECT_THAT(foo(), IsOk()); 35 MATCHER(IsOk, 36 std::string(negation ? "not " : "") + net::ErrorToString(net::OK)) { 37 if (arg <= 0) 38 *result_listener << net::ErrorToString(arg); 39 return arg == net::OK; 40 } 41 42 // A gMock matcher for base::StringPiece arguments. 43 // gMock's built-in HasSubstrMatcher does not work, 44 // because base::StringPiece cannot be implicitly converted to std::string. 45 class StringPieceHasSubstrMatcher { 46 public: StringPieceHasSubstrMatcher(const std::string & substring)47 explicit StringPieceHasSubstrMatcher(const std::string& substring) 48 : substring_(substring) {} 49 StringPieceHasSubstrMatcher(const StringPieceHasSubstrMatcher&) = default; 50 StringPieceHasSubstrMatcher& operator=(const StringPieceHasSubstrMatcher&) = 51 default; 52 MatchAndExplain(base::StringPiece s,::testing::MatchResultListener * listener)53 bool MatchAndExplain(base::StringPiece s, 54 ::testing::MatchResultListener* listener) const { 55 return s.find(substring_) != std::string::npos; 56 } 57 58 // Describe what this matcher matches. DescribeTo(std::ostream * os)59 void DescribeTo(std::ostream* os) const { 60 *os << "has substring " << substring_; 61 } 62 DescribeNegationTo(std::ostream * os)63 void DescribeNegationTo(std::ostream* os) const { 64 *os << "has no substring " << substring_; 65 } 66 67 private: 68 std::string substring_; 69 }; 70 71 // Internal implementation for the EXPECT_DFATAL and ASSERT_DFATAL 72 // macros. Do not use this directly. 73 #define GTEST_DFATAL_(statement, severity, matcher, fail) \ 74 do { \ 75 ::base::test::MockLog gtest_log; \ 76 ::net::test::ScopedDisableExitOnDFatal gtest_disable_exit; \ 77 using ::testing::_; \ 78 EXPECT_CALL(gtest_log, Log(_, _, _, _, _)) \ 79 .WillRepeatedly(::testing::Return(false)); \ 80 EXPECT_CALL(gtest_log, Log(::logging::LOG_##severity, _, _, _, matcher)) \ 81 .Times(::testing::AtLeast(1)) \ 82 .WillOnce(::testing::Return(false)); \ 83 gtest_log.StartCapturingLogs(); \ 84 { statement; } \ 85 gtest_log.StopCapturingLogs(); \ 86 if (!testing::Mock::VerifyAndClear(>est_log)) \ 87 fail(""); \ 88 } while (false) 89 90 // The EXPECT_DFATAL and ASSERT_DFATAL macros are lightweight 91 // alternatives to EXPECT_DEBUG_DEATH and ASSERT_DEBUG_DEATH. They 92 // are appropriate for testing that your code logs a message at the 93 // DFATAL level. 94 // 95 // Unlike EXPECT_DEBUG_DEATH and ASSERT_DEBUG_DEATH, these macros 96 // execute the given statement in the current process, not a forked 97 // one. This works because we disable exiting the program for 98 // LOG(DFATAL). This makes the tests run more quickly. 99 // 100 // The _WITH() variants allow one to specify any matcher for the 101 // DFATAL log message, whereas the other variants assume a regex. 102 103 #define EXPECT_DFATAL_WITH(statement, matcher) \ 104 GTEST_DFATAL_(statement, DFATAL, matcher, GTEST_NONFATAL_FAILURE_) 105 106 #define ASSERT_DFATAL_WITH(statement, matcher) \ 107 GTEST_DFATAL_(statement, DFATAL, matcher, GTEST_FATAL_FAILURE_) 108 109 #define EXPECT_DFATAL(statement, regex) \ 110 EXPECT_DFATAL_WITH(statement, ::testing::ContainsRegex(regex)) 111 112 #define ASSERT_DFATAL(statement, regex) \ 113 ASSERT_DFATAL_WITH(statement, ::testing::ContainsRegex(regex)) 114 115 // The EXPECT_DEBUG_DFATAL and ASSERT_DEBUG_DFATAL macros are similar to 116 // EXPECT_DFATAL and ASSERT_DFATAL. Use them in conjunction with DLOG(DFATAL) 117 // or similar macros that produce no-op in opt build and DFATAL in dbg build. 118 119 #ifndef NDEBUG 120 121 #define EXPECT_DEBUG_DFATAL(statement, regex) \ 122 EXPECT_DFATAL(statement, regex) 123 #define ASSERT_DEBUG_DFATAL(statement, regex) \ 124 ASSERT_DFATAL(statement, regex) 125 126 #else // NDEBUG 127 128 #define EXPECT_DEBUG_DFATAL(statement, regex) \ 129 do { \ 130 (void)(regex); \ 131 statement; \ 132 } while (false) 133 #define ASSERT_DEBUG_DFATAL(statement, regex) \ 134 do { \ 135 (void)(regex); \ 136 statement; \ 137 } while (false) 138 139 #endif // NDEBUG 140 141 // The EXPECT_DCHECK and ASSERT_DCHECK macros are similar to EXPECT_DFATAL and 142 // ASSERT_DFATAL. Use them in conjunction with DCHECK that produces no-op in opt 143 // build and LOG_DCHECK (FATAL) if DCHECK_IS_ON(). 144 145 #if DCHECK_IS_ON() 146 147 #define EXPECT_DCHECK(statement, regex) \ 148 GTEST_DFATAL_(statement, DCHECK, ::testing::ContainsRegex(regex), \ 149 GTEST_NONFATAL_FAILURE_) 150 #define ASSERT_DCHECK(statement, regex) \ 151 GTEST_DFATAL_(statement, DCHECK, ::testing::ContainsRegex(regex), \ 152 GTEST_FATAL_FAILURE_) 153 154 #else // DCHECK_IS_ON() 155 156 #define EXPECT_DCHECK(statement, regex) \ 157 do { \ 158 (void)(regex); \ 159 statement; \ 160 } while (false) 161 #define ASSERT_DCHECK(statement, regex) \ 162 do { \ 163 (void)(regex); \ 164 statement; \ 165 } while (false) 166 167 #endif // DCHECK_IS_ON() 168 169 } // namespace net::test 170 171 #endif // NET_TEST_GTEST_UTIL_H_ 172