blob: e0619425f7542804b0c4604aba51603f619ef3b8 [file] [log] [blame]
jeffbailey@chromium.orgeff8f002011-04-03 06:13:21 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
akalin@chromium.orga88579b2010-10-02 08:02:36 +09002// 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/basictypes.h"
pkastingee4b1122014-11-21 10:37:22 +09006#include "base/compiler_specific.h"
akalin@chromium.orga88579b2010-10-02 08:02:36 +09007#include "base/logging.h"
8
9#include "testing/gmock/include/gmock/gmock.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace logging {
13
14namespace {
15
16using ::testing::Return;
17
akalin@chromium.org25cef532010-11-02 04:49:22 +090018// Needs to be global since log assert handlers can't maintain state.
19int log_sink_call_count = 0;
20
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +090021#if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
akalin@chromium.org25cef532010-11-02 04:49:22 +090022void LogSink(const std::string& str) {
23 ++log_sink_call_count;
24}
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +090025#endif
akalin@chromium.org25cef532010-11-02 04:49:22 +090026
akalin@chromium.orga88579b2010-10-02 08:02:36 +090027// Class to make sure any manipulations we do to the min log level are
28// contained (i.e., do not affect other unit tests).
akalin@chromium.org25cef532010-11-02 04:49:22 +090029class LogStateSaver {
akalin@chromium.orga88579b2010-10-02 08:02:36 +090030 public:
akalin@chromium.org25cef532010-11-02 04:49:22 +090031 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {}
akalin@chromium.orga88579b2010-10-02 08:02:36 +090032
akalin@chromium.org25cef532010-11-02 04:49:22 +090033 ~LogStateSaver() {
34 SetMinLogLevel(old_min_log_level_);
35 SetLogAssertHandler(NULL);
akalin@chromium.org25cef532010-11-02 04:49:22 +090036 log_sink_call_count = 0;
37 }
akalin@chromium.orga88579b2010-10-02 08:02:36 +090038
39 private:
40 int old_min_log_level_;
41
akalin@chromium.org25cef532010-11-02 04:49:22 +090042 DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
akalin@chromium.orga88579b2010-10-02 08:02:36 +090043};
44
45class LoggingTest : public testing::Test {
46 private:
akalin@chromium.org25cef532010-11-02 04:49:22 +090047 LogStateSaver log_state_saver_;
akalin@chromium.orga88579b2010-10-02 08:02:36 +090048};
49
50class MockLogSource {
51 public:
52 MOCK_METHOD0(Log, const char*());
53};
54
55TEST_F(LoggingTest, BasicLogging) {
56 MockLogSource mock_log_source;
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090057 EXPECT_CALL(mock_log_source, Log()).Times(DEBUG_MODE ? 16 : 8).
akalin@chromium.orga88579b2010-10-02 08:02:36 +090058 WillRepeatedly(Return("log message"));
59
60 SetMinLogLevel(LOG_INFO);
61
62 EXPECT_TRUE(LOG_IS_ON(INFO));
jeffbailey@chromium.orgeff8f002011-04-03 06:13:21 +090063 // As of g++-4.5, the first argument to EXPECT_EQ cannot be a
64 // constant expression.
65 const bool kIsDebugMode = (DEBUG_MODE != 0);
mostynb@opera.com7b2ca622013-04-12 16:31:15 +090066 EXPECT_TRUE(kIsDebugMode == DLOG_IS_ON(INFO));
akalin@chromium.orga88579b2010-10-02 08:02:36 +090067 EXPECT_TRUE(VLOG_IS_ON(0));
68
69 LOG(INFO) << mock_log_source.Log();
70 LOG_IF(INFO, true) << mock_log_source.Log();
71 PLOG(INFO) << mock_log_source.Log();
72 PLOG_IF(INFO, true) << mock_log_source.Log();
73 VLOG(0) << mock_log_source.Log();
74 VLOG_IF(0, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090075 VPLOG(0) << mock_log_source.Log();
76 VPLOG_IF(0, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +090077
78 DLOG(INFO) << mock_log_source.Log();
79 DLOG_IF(INFO, true) << mock_log_source.Log();
80 DPLOG(INFO) << mock_log_source.Log();
81 DPLOG_IF(INFO, true) << mock_log_source.Log();
82 DVLOG(0) << mock_log_source.Log();
83 DVLOG_IF(0, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +090084 DVPLOG(0) << mock_log_source.Log();
85 DVPLOG_IF(0, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +090086}
87
akalin@chromium.org434c5b62010-11-03 14:30:14 +090088TEST_F(LoggingTest, LogIsOn) {
89#if defined(NDEBUG)
90 const bool kDfatalIsFatal = false;
91#else // defined(NDEBUG)
92 const bool kDfatalIsFatal = true;
93#endif // defined(NDEBUG)
94
95 SetMinLogLevel(LOG_INFO);
96 EXPECT_TRUE(LOG_IS_ON(INFO));
97 EXPECT_TRUE(LOG_IS_ON(WARNING));
98 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +090099 EXPECT_TRUE(LOG_IS_ON(FATAL));
100 EXPECT_TRUE(LOG_IS_ON(DFATAL));
101
102 SetMinLogLevel(LOG_WARNING);
103 EXPECT_FALSE(LOG_IS_ON(INFO));
104 EXPECT_TRUE(LOG_IS_ON(WARNING));
105 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900106 EXPECT_TRUE(LOG_IS_ON(FATAL));
107 EXPECT_TRUE(LOG_IS_ON(DFATAL));
108
109 SetMinLogLevel(LOG_ERROR);
110 EXPECT_FALSE(LOG_IS_ON(INFO));
111 EXPECT_FALSE(LOG_IS_ON(WARNING));
112 EXPECT_TRUE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900113 EXPECT_TRUE(LOG_IS_ON(FATAL));
114 EXPECT_TRUE(LOG_IS_ON(DFATAL));
115
viettrungluu@chromium.org96925ac2014-06-17 21:04:23 +0900116 // LOG_IS_ON(FATAL) should always be true.
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900117 SetMinLogLevel(LOG_FATAL + 1);
118 EXPECT_FALSE(LOG_IS_ON(INFO));
119 EXPECT_FALSE(LOG_IS_ON(WARNING));
120 EXPECT_FALSE(LOG_IS_ON(ERROR));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900121 EXPECT_TRUE(LOG_IS_ON(FATAL));
mostynb@opera.com7b2ca622013-04-12 16:31:15 +0900122 EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900123}
124
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900125TEST_F(LoggingTest, LoggingIsLazy) {
126 MockLogSource mock_log_source;
127 EXPECT_CALL(mock_log_source, Log()).Times(0);
128
129 SetMinLogLevel(LOG_WARNING);
130
131 EXPECT_FALSE(LOG_IS_ON(INFO));
132 EXPECT_FALSE(DLOG_IS_ON(INFO));
133 EXPECT_FALSE(VLOG_IS_ON(1));
134
135 LOG(INFO) << mock_log_source.Log();
136 LOG_IF(INFO, false) << mock_log_source.Log();
137 PLOG(INFO) << mock_log_source.Log();
138 PLOG_IF(INFO, false) << mock_log_source.Log();
139 VLOG(1) << mock_log_source.Log();
140 VLOG_IF(1, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +0900141 VPLOG(1) << mock_log_source.Log();
142 VPLOG_IF(1, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900143
144 DLOG(INFO) << mock_log_source.Log();
145 DLOG_IF(INFO, true) << mock_log_source.Log();
146 DPLOG(INFO) << mock_log_source.Log();
147 DPLOG_IF(INFO, true) << mock_log_source.Log();
148 DVLOG(1) << mock_log_source.Log();
149 DVLOG_IF(1, true) << mock_log_source.Log();
vitalybuka@chromium.orge8717362014-04-23 10:11:01 +0900150 DVPLOG(1) << mock_log_source.Log();
151 DVPLOG_IF(1, true) << mock_log_source.Log();
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900152}
153
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900154// Official builds have CHECKs directly call BreakDebugger.
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900155#if !defined(OFFICIAL_BUILD)
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900156
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900157TEST_F(LoggingTest, CheckStreamsAreLazy) {
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900158 MockLogSource mock_log_source, uncalled_mock_log_source;
159 EXPECT_CALL(mock_log_source, Log()).Times(8).
160 WillRepeatedly(Return("check message"));
161 EXPECT_CALL(uncalled_mock_log_source, Log()).Times(0);
162
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900163 SetLogAssertHandler(&LogSink);
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900164
165 CHECK(mock_log_source.Log()) << uncalled_mock_log_source.Log();
166 PCHECK(!mock_log_source.Log()) << mock_log_source.Log();
167 CHECK_EQ(mock_log_source.Log(), mock_log_source.Log())
168 << uncalled_mock_log_source.Log();
169 CHECK_NE(mock_log_source.Log(), mock_log_source.Log())
170 << mock_log_source.Log();
171}
172
akalin@chromium.org1fcfcd42011-12-16 15:01:23 +0900173#endif
174
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900175TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
176#if !defined(NDEBUG)
177 int debug_only_variable = 1;
178#endif
179 // These should avoid emitting references to |debug_only_variable|
180 // in release mode.
181 DLOG_IF(INFO, debug_only_variable) << "test";
182 DLOG_ASSERT(debug_only_variable) << "test";
183 DPLOG_IF(INFO, debug_only_variable) << "test";
184 DVLOG_IF(1, debug_only_variable) << "test";
185}
186
akalin@chromium.org434c5b62010-11-03 14:30:14 +0900187TEST_F(LoggingTest, DcheckStreamsAreLazy) {
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900188 MockLogSource mock_log_source;
189 EXPECT_CALL(mock_log_source, Log()).Times(0);
danakj9a89f242015-01-09 08:35:58 +0900190#if DCHECK_IS_ON()
wangxianzhu@chromium.org1eea1402014-03-15 03:39:53 +0900191 DCHECK(true) << mock_log_source.Log();
192 DCHECK_EQ(0, 0) << mock_log_source.Log();
193#else
194 DCHECK(mock_log_source.Log()) << mock_log_source.Log();
195 DPCHECK(mock_log_source.Log()) << mock_log_source.Log();
196 DCHECK_EQ(0, 0) << mock_log_source.Log();
197 DCHECK_EQ(mock_log_source.Log(), static_cast<const char*>(NULL))
198 << mock_log_source.Log();
199#endif
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900200}
201
akalin@chromium.org25cef532010-11-02 04:49:22 +0900202TEST_F(LoggingTest, Dcheck) {
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900203#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
204 // Release build.
danakj9a89f242015-01-09 08:35:58 +0900205 EXPECT_FALSE(DCHECK_IS_ON());
akalin@chromium.org25cef532010-11-02 04:49:22 +0900206 EXPECT_FALSE(DLOG_IS_ON(DCHECK));
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900207#elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON)
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900208 // Release build with real DCHECKS.
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900209 SetLogAssertHandler(&LogSink);
danakj9a89f242015-01-09 08:35:58 +0900210 EXPECT_TRUE(DCHECK_IS_ON());
nsylvain@chromium.org675aad32011-09-21 05:59:01 +0900211 EXPECT_FALSE(DLOG_IS_ON(DCHECK));
akalin@chromium.org25cef532010-11-02 04:49:22 +0900212#else
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900213 // Debug build.
akalin@chromium.orgfaed5f82011-01-11 10:03:36 +0900214 SetLogAssertHandler(&LogSink);
danakj9a89f242015-01-09 08:35:58 +0900215 EXPECT_TRUE(DCHECK_IS_ON());
akalin@chromium.org25cef532010-11-02 04:49:22 +0900216 EXPECT_TRUE(DLOG_IS_ON(DCHECK));
wangxianzhu@chromium.org75a5cd92014-03-11 03:23:38 +0900217#endif
akalin@chromium.org25cef532010-11-02 04:49:22 +0900218
219 EXPECT_EQ(0, log_sink_call_count);
220 DCHECK(false);
danakj9a89f242015-01-09 08:35:58 +0900221 EXPECT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900222 DPCHECK(false);
danakj9a89f242015-01-09 08:35:58 +0900223 EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900224 DCHECK_EQ(0, 1);
danakj9a89f242015-01-09 08:35:58 +0900225 EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count);
akalin@chromium.org25cef532010-11-02 04:49:22 +0900226}
227
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900228TEST_F(LoggingTest, DcheckReleaseBehavior) {
229 int some_variable = 1;
230 // These should still reference |some_variable| so we don't get
231 // unused variable warnings.
232 DCHECK(some_variable) << "test";
233 DPCHECK(some_variable) << "test";
234 DCHECK_EQ(some_variable, 1) << "test";
235}
236
erikwrightb02505e2015-07-23 05:05:52 +0900237TEST_F(LoggingTest, DCheckEqStatements) {
238 bool reached = false;
239 if (false)
240 DCHECK_EQ(false, true); // Unreached.
241 else
242 DCHECK_EQ(true, reached = true); // Reached, passed.
243 ASSERT_EQ(DCHECK_IS_ON() ? true : false, reached);
244
245 if (false)
246 DCHECK_EQ(false, true); // Unreached.
247}
248
249TEST_F(LoggingTest, CheckEqStatements) {
250 bool reached = false;
251 if (false)
252 CHECK_EQ(false, true); // Unreached.
253 else
254 CHECK_EQ(true, reached = true); // Reached, passed.
255 ASSERT_TRUE(reached);
256
257 if (false)
258 CHECK_EQ(false, true); // Unreached.
259}
260
jyasskin@chromium.orgf01cfba2014-07-09 08:03:06 +0900261// Test that defining an operator<< for a type in a namespace doesn't prevent
262// other code in that namespace from calling the operator<<(ostream, wstring)
263// defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
264// found by ADL, since defining another operator<< prevents name lookup from
265// looking in the global namespace.
266namespace nested_test {
267 class Streamable {};
pkastingd36037a2014-10-17 08:49:24 +0900268 ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out,
269 const Streamable&) {
jyasskin@chromium.orgf01cfba2014-07-09 08:03:06 +0900270 return out << "Streamable";
271 }
272 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) {
273 std::wstring wstr = L"Hello World";
274 std::ostringstream ostr;
275 ostr << wstr;
276 EXPECT_EQ("Hello World", ostr.str());
277 }
278} // namespace nested_test
279
akalin@chromium.orga88579b2010-10-02 08:02:36 +0900280} // namespace
281
282} // namespace logging