• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2022 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 // The testcases in this file are expected to pass or be skipped with any value
17 // of ABSL_MIN_LOG_LEVEL
18 
19 #ifndef ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
20 #define ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
21 
22 // Verify that both sets of macros behave identically by parameterizing the
23 // entire test file.
24 #ifndef ABSL_TEST_LOG
25 #error ABSL_TEST_LOG must be defined for these tests to work.
26 #endif
27 
28 #include <cerrno>
29 #include <sstream>
30 #include <string>
31 
32 #include "gmock/gmock.h"
33 #include "gtest/gtest.h"
34 #include "absl/base/internal/sysinfo.h"
35 #include "absl/base/log_severity.h"
36 #include "absl/log/globals.h"
37 #include "absl/log/internal/test_actions.h"
38 #include "absl/log/internal/test_helpers.h"
39 #include "absl/log/internal/test_matchers.h"
40 #include "absl/log/log_entry.h"
41 #include "absl/log/scoped_mock_log.h"
42 
43 namespace absl_log_internal {
44 #if GTEST_HAS_DEATH_TEST
45 using ::absl::log_internal::DeathTestExpectedLogging;
46 using ::absl::log_internal::DeathTestUnexpectedLogging;
47 using ::absl::log_internal::DeathTestValidateExpectations;
48 using ::absl::log_internal::DiedOfFatal;
49 using ::absl::log_internal::DiedOfQFatal;
50 #endif
51 using ::absl::log_internal::LoggingEnabledAt;
52 using ::absl::log_internal::LogSeverity;
53 using ::absl::log_internal::Prefix;
54 using ::absl::log_internal::SourceBasename;
55 using ::absl::log_internal::SourceFilename;
56 using ::absl::log_internal::SourceLine;
57 using ::absl::log_internal::Stacktrace;
58 using ::absl::log_internal::TextMessage;
59 using ::absl::log_internal::ThreadID;
60 using ::absl::log_internal::TimestampInMatchWindow;
61 using ::absl::log_internal::Verbosity;
62 using ::testing::AnyNumber;
63 using ::testing::Eq;
64 using ::testing::IsEmpty;
65 using ::testing::IsTrue;
66 
67 class BasicLogTest : public testing::TestWithParam<absl::LogSeverityAtLeast> {};
68 
ThresholdName(testing::TestParamInfo<absl::LogSeverityAtLeast> severity)69 std::string ThresholdName(
70     testing::TestParamInfo<absl::LogSeverityAtLeast> severity) {
71   std::stringstream ostr;
72   ostr << severity.param;
73   return ostr.str().substr(
74       severity.param == absl::LogSeverityAtLeast::kInfinity ? 0 : 2);
75 }
76 
77 INSTANTIATE_TEST_SUITE_P(WithParam, BasicLogTest,
78                          testing::Values(absl::LogSeverityAtLeast::kInfo,
79                                          absl::LogSeverityAtLeast::kWarning,
80                                          absl::LogSeverityAtLeast::kError,
81                                          absl::LogSeverityAtLeast::kFatal,
82                                          absl::LogSeverityAtLeast::kInfinity),
83                          ThresholdName);
84 
TEST_P(BasicLogTest,Info)85 TEST_P(BasicLogTest, Info) {
86   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
87 
88   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
89 
90   const int log_line = __LINE__ + 1;
91   auto do_log = [] { ABSL_TEST_LOG(INFO) << "hello world"; };
92 
93   if (LoggingEnabledAt(absl::LogSeverity::kInfo)) {
94     EXPECT_CALL(
95         test_sink,
96         Send(AllOf(SourceFilename(Eq(__FILE__)),
97                    SourceBasename(Eq("log_basic_test_impl.h")),
98                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
99                    LogSeverity(Eq(absl::LogSeverity::kInfo)),
100                    TimestampInMatchWindow(),
101                    ThreadID(Eq(absl::base_internal::GetTID())),
102                    TextMessage(Eq("hello world")),
103                    Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
104                    ENCODED_MESSAGE(EqualsProto(R"pb(value {
105                                                       literal: "hello world"
106                                                     })pb")),
107                    Stacktrace(IsEmpty()))));
108   }
109 
110   test_sink.StartCapturingLogs();
111   do_log();
112 }
113 
TEST_P(BasicLogTest,Warning)114 TEST_P(BasicLogTest, Warning) {
115   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
116 
117   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
118 
119   const int log_line = __LINE__ + 1;
120   auto do_log = [] { ABSL_TEST_LOG(WARNING) << "hello world"; };
121 
122   if (LoggingEnabledAt(absl::LogSeverity::kWarning)) {
123     EXPECT_CALL(
124         test_sink,
125         Send(AllOf(SourceFilename(Eq(__FILE__)),
126                    SourceBasename(Eq("log_basic_test_impl.h")),
127                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
128                    LogSeverity(Eq(absl::LogSeverity::kWarning)),
129                    TimestampInMatchWindow(),
130                    ThreadID(Eq(absl::base_internal::GetTID())),
131                    TextMessage(Eq("hello world")),
132                    Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
133                    ENCODED_MESSAGE(EqualsProto(R"pb(value {
134                                                       literal: "hello world"
135                                                     })pb")),
136                    Stacktrace(IsEmpty()))));
137   }
138 
139   test_sink.StartCapturingLogs();
140   do_log();
141 }
142 
TEST_P(BasicLogTest,Error)143 TEST_P(BasicLogTest, Error) {
144   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
145 
146   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
147 
148   const int log_line = __LINE__ + 1;
149   auto do_log = [] { ABSL_TEST_LOG(ERROR) << "hello world"; };
150 
151   if (LoggingEnabledAt(absl::LogSeverity::kError)) {
152     EXPECT_CALL(
153         test_sink,
154         Send(AllOf(SourceFilename(Eq(__FILE__)),
155                    SourceBasename(Eq("log_basic_test_impl.h")),
156                    SourceLine(Eq(log_line)), Prefix(IsTrue()),
157                    LogSeverity(Eq(absl::LogSeverity::kError)),
158                    TimestampInMatchWindow(),
159                    ThreadID(Eq(absl::base_internal::GetTID())),
160                    TextMessage(Eq("hello world")),
161                    Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
162                    ENCODED_MESSAGE(EqualsProto(R"pb(value {
163                                                       literal: "hello world"
164                                                     })pb")),
165                    Stacktrace(IsEmpty()))));
166   }
167 
168   test_sink.StartCapturingLogs();
169   do_log();
170 }
171 
172 #if GTEST_HAS_DEATH_TEST
173 using BasicLogDeathTest = BasicLogTest;
174 
175 INSTANTIATE_TEST_SUITE_P(WithParam, BasicLogDeathTest,
176                          testing::Values(absl::LogSeverityAtLeast::kInfo,
177                                          absl::LogSeverityAtLeast::kFatal,
178                                          absl::LogSeverityAtLeast::kInfinity),
179                          ThresholdName);
180 
TEST_P(BasicLogDeathTest,Fatal)181 TEST_P(BasicLogDeathTest, Fatal) {
182   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
183 
184   const int log_line = __LINE__ + 1;
185   auto do_log = [] { ABSL_TEST_LOG(FATAL) << "hello world"; };
186 
187   EXPECT_EXIT(
188       {
189         absl::ScopedMockLog test_sink(
190             absl::MockLogDefault::kDisallowUnexpected);
191 
192         EXPECT_CALL(test_sink, Send)
193             .Times(AnyNumber())
194             .WillRepeatedly(DeathTestUnexpectedLogging());
195 
196         ::testing::InSequence s;
197 
198         // Note the logic in DeathTestValidateExpectations() caters for the case
199         // of logging being disabled at FATAL level.
200 
201         if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
202           // The first call without the stack trace.
203           EXPECT_CALL(
204               test_sink,
205               Send(AllOf(SourceFilename(Eq(__FILE__)),
206                          SourceBasename(Eq("log_basic_test_impl.h")),
207                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
208                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
209                          TimestampInMatchWindow(),
210                          ThreadID(Eq(absl::base_internal::GetTID())),
211                          TextMessage(Eq("hello world")),
212                          Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
213                          ENCODED_MESSAGE(EqualsProto(
214                              R"pb(value { literal: "hello world" })pb")),
215                          Stacktrace(IsEmpty()))))
216               .WillOnce(DeathTestExpectedLogging());
217 
218           // The second call with the stack trace.
219           EXPECT_CALL(
220               test_sink,
221               Send(AllOf(SourceFilename(Eq(__FILE__)),
222                          SourceBasename(Eq("log_basic_test_impl.h")),
223                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
224                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
225                          TimestampInMatchWindow(),
226                          ThreadID(Eq(absl::base_internal::GetTID())),
227                          TextMessage(Eq("hello world")),
228                          Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
229                          ENCODED_MESSAGE(EqualsProto(
230                              R"pb(value { literal: "hello world" })pb")),
231                          Stacktrace(Not(IsEmpty())))))
232               .WillOnce(DeathTestExpectedLogging());
233         }
234 
235         test_sink.StartCapturingLogs();
236         do_log();
237       },
238       DiedOfFatal, DeathTestValidateExpectations());
239 }
240 
TEST_P(BasicLogDeathTest,QFatal)241 TEST_P(BasicLogDeathTest, QFatal) {
242   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
243 
244   const int log_line = __LINE__ + 1;
245   auto do_log = [] { ABSL_TEST_LOG(QFATAL) << "hello world"; };
246 
247   EXPECT_EXIT(
248       {
249         absl::ScopedMockLog test_sink(
250             absl::MockLogDefault::kDisallowUnexpected);
251 
252         EXPECT_CALL(test_sink, Send)
253             .Times(AnyNumber())
254             .WillRepeatedly(DeathTestUnexpectedLogging());
255 
256         if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
257           EXPECT_CALL(
258               test_sink,
259               Send(AllOf(SourceFilename(Eq(__FILE__)),
260                          SourceBasename(Eq("log_basic_test_impl.h")),
261                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
262                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
263                          TimestampInMatchWindow(),
264                          ThreadID(Eq(absl::base_internal::GetTID())),
265                          TextMessage(Eq("hello world")),
266                          Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
267                          ENCODED_MESSAGE(EqualsProto(
268                              R"pb(value { literal: "hello world" })pb")),
269                          Stacktrace(IsEmpty()))))
270               .WillOnce(DeathTestExpectedLogging());
271         }
272 
273         test_sink.StartCapturingLogs();
274         do_log();
275       },
276       DiedOfQFatal, DeathTestValidateExpectations());
277 }
278 #endif
279 
TEST_P(BasicLogTest,Level)280 TEST_P(BasicLogTest, Level) {
281   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
282 
283   for (auto severity : {absl::LogSeverity::kInfo, absl::LogSeverity::kWarning,
284                         absl::LogSeverity::kError}) {
285     absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
286 
287     const int log_line = __LINE__ + 2;
288     auto do_log = [severity] {
289       ABSL_TEST_LOG(LEVEL(severity)) << "hello world";
290     };
291 
292     if (LoggingEnabledAt(severity)) {
293       EXPECT_CALL(
294           test_sink,
295           Send(AllOf(SourceFilename(Eq(__FILE__)),
296                      SourceBasename(Eq("log_basic_test_impl.h")),
297                      SourceLine(Eq(log_line)), Prefix(IsTrue()),
298                      LogSeverity(Eq(severity)), TimestampInMatchWindow(),
299                      ThreadID(Eq(absl::base_internal::GetTID())),
300                      TextMessage(Eq("hello world")),
301                      Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
302                      ENCODED_MESSAGE(EqualsProto(R"pb(value {
303                                                         literal: "hello world"
304                                                       })pb")),
305                      Stacktrace(IsEmpty()))));
306     }
307     test_sink.StartCapturingLogs();
308     do_log();
309   }
310 }
311 
312 #if GTEST_HAS_DEATH_TEST
TEST_P(BasicLogDeathTest,Level)313 TEST_P(BasicLogDeathTest, Level) {
314   // TODO(b/242568884): re-enable once bug is fixed.
315   // absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
316 
317   // Ensure that `severity` is not a compile-time constant to prove that
318   // `LOG(LEVEL(severity))` works regardless:
319   auto volatile severity = absl::LogSeverity::kFatal;
320 
321   const int log_line = __LINE__ + 1;
322   auto do_log = [severity] { ABSL_TEST_LOG(LEVEL(severity)) << "hello world"; };
323 
324   EXPECT_EXIT(
325       {
326         absl::ScopedMockLog test_sink(
327             absl::MockLogDefault::kDisallowUnexpected);
328 
329         EXPECT_CALL(test_sink, Send)
330             .Times(AnyNumber())
331             .WillRepeatedly(DeathTestUnexpectedLogging());
332 
333         ::testing::InSequence s;
334 
335         if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
336           EXPECT_CALL(
337               test_sink,
338               Send(AllOf(SourceFilename(Eq(__FILE__)),
339                          SourceBasename(Eq("log_basic_test_impl.h")),
340                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
341                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
342                          TimestampInMatchWindow(),
343                          ThreadID(Eq(absl::base_internal::GetTID())),
344                          TextMessage(Eq("hello world")),
345                          Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
346                          ENCODED_MESSAGE(EqualsProto(
347                              R"pb(value { literal: "hello world" })pb")),
348                          Stacktrace(IsEmpty()))))
349               .WillOnce(DeathTestExpectedLogging());
350 
351           EXPECT_CALL(
352               test_sink,
353               Send(AllOf(SourceFilename(Eq(__FILE__)),
354                          SourceBasename(Eq("log_basic_test_impl.h")),
355                          SourceLine(Eq(log_line)), Prefix(IsTrue()),
356                          LogSeverity(Eq(absl::LogSeverity::kFatal)),
357                          TimestampInMatchWindow(),
358                          ThreadID(Eq(absl::base_internal::GetTID())),
359                          TextMessage(Eq("hello world")),
360                          Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
361                          ENCODED_MESSAGE(EqualsProto(
362                              R"pb(value { literal: "hello world" })pb")),
363                          Stacktrace(Not(IsEmpty())))))
364               .WillOnce(DeathTestExpectedLogging());
365         }
366 
367         test_sink.StartCapturingLogs();
368         do_log();
369       },
370       DiedOfFatal, DeathTestValidateExpectations());
371 }
372 #endif
373 
TEST_P(BasicLogTest,LevelClampsNegativeValues)374 TEST_P(BasicLogTest, LevelClampsNegativeValues) {
375   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
376 
377   if (!LoggingEnabledAt(absl::LogSeverity::kInfo)) {
378     GTEST_SKIP() << "This test cases required INFO log to be enabled";
379     return;
380   }
381 
382   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
383 
384   EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kInfo))));
385 
386   test_sink.StartCapturingLogs();
387   ABSL_TEST_LOG(LEVEL(-1)) << "hello world";
388 }
389 
TEST_P(BasicLogTest,LevelClampsLargeValues)390 TEST_P(BasicLogTest, LevelClampsLargeValues) {
391   absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
392 
393   if (!LoggingEnabledAt(absl::LogSeverity::kError)) {
394     GTEST_SKIP() << "This test cases required ERROR log to be enabled";
395     return;
396   }
397 
398   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
399 
400   EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kError))));
401 
402   test_sink.StartCapturingLogs();
403   ABSL_TEST_LOG(LEVEL(static_cast<int>(absl::LogSeverity::kFatal) + 1))
404       << "hello world";
405 }
406 
TEST(ErrnoPreservationTest,InSeverityExpression)407 TEST(ErrnoPreservationTest, InSeverityExpression) {
408   errno = 77;
409   int saved_errno;
410   ABSL_TEST_LOG(LEVEL((saved_errno = errno, absl::LogSeverity::kInfo)));
411   EXPECT_THAT(saved_errno, Eq(77));
412 }
413 
TEST(ErrnoPreservationTest,InStreamedExpression)414 TEST(ErrnoPreservationTest, InStreamedExpression) {
415   if (!LoggingEnabledAt(absl::LogSeverity::kInfo)) {
416     GTEST_SKIP() << "This test cases required INFO log to be enabled";
417     return;
418   }
419 
420   errno = 77;
421   int saved_errno = 0;
422   ABSL_TEST_LOG(INFO) << (saved_errno = errno, "hello world");
423   EXPECT_THAT(saved_errno, Eq(77));
424 }
425 
TEST(ErrnoPreservationTest,AfterStatement)426 TEST(ErrnoPreservationTest, AfterStatement) {
427   errno = 77;
428   ABSL_TEST_LOG(INFO);
429   const int saved_errno = errno;
430   EXPECT_THAT(saved_errno, Eq(77));
431 }
432 
433 // Tests that using a variable/parameter in a logging statement suppresses
434 // unused-variable/parameter warnings.
435 // -----------------------------------------------------------------------
436 class UnusedVariableWarningCompileTest {
437   // These four don't prove anything unless `ABSL_MIN_LOG_LEVEL` is greater than
438   // `kInfo`.
LoggedVariable()439   static void LoggedVariable() {
440     const int x = 0;
441     ABSL_TEST_LOG(INFO) << x;
442   }
LoggedParameter(const int x)443   static void LoggedParameter(const int x) { ABSL_TEST_LOG(INFO) << x; }
SeverityVariable()444   static void SeverityVariable() {
445     const int x = 0;
446     ABSL_TEST_LOG(LEVEL(x)) << "hello world";
447   }
SeverityParameter(const int x)448   static void SeverityParameter(const int x) {
449     ABSL_TEST_LOG(LEVEL(x)) << "hello world";
450   }
451 };
452 
453 }  // namespace absl_log_internal
454 
455 #endif  // ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
456