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