• 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 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 #include "absl/base/attributes.h"
19 #include "absl/base/log_severity.h"
20 #include "absl/log/log.h"
21 #include "absl/log/scoped_mock_log.h"
22 
23 namespace {
24 using ::testing::_;
25 using ::testing::Eq;
26 
27 namespace not_absl {
28 
29 class Dummy {
30  public:
Dummy()31   Dummy() {}
32 
33  private:
34   Dummy(const Dummy&) = delete;
35   Dummy& operator=(const Dummy&) = delete;
36 };
37 
38 // This line tests that local definitions of INFO, WARNING, ERROR, and
39 // etc don't shadow the global ones used by the logging macros.  If
40 // they do, the LOG() calls in the tests won't compile, catching the
41 // bug.
42 const Dummy INFO, WARNING, ERROR, FATAL, NUM_SEVERITIES;
43 
44 // These makes sure that the uses of same-named types in the
45 // implementation of the logging macros are fully qualified.
46 class string {};
47 class vector {};
48 class LogMessage {};
49 class LogMessageFatal {};
50 class LogMessageQuietlyFatal {};
51 class LogMessageVoidify {};
52 class LogSink {};
53 class NullStream {};
54 class NullStreamFatal {};
55 
56 }  // namespace not_absl
57 
58 using namespace not_absl;  // NOLINT
59 
60 // Tests for LOG(LEVEL(()).
61 
TEST(LogHygieneTest,WorksForQualifiedSeverity)62 TEST(LogHygieneTest, WorksForQualifiedSeverity) {
63   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
64 
65   ::testing::InSequence seq;
66   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "To INFO"));
67   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "To WARNING"));
68   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "To ERROR"));
69 
70   test_sink.StartCapturingLogs();
71   // Note that LOG(LEVEL()) expects the severity as a run-time
72   // expression (as opposed to a compile-time constant).  Hence we
73   // test that :: is allowed before INFO, etc.
74   LOG(LEVEL(absl::LogSeverity::kInfo)) << "To INFO";
75   LOG(LEVEL(absl::LogSeverity::kWarning)) << "To WARNING";
76   LOG(LEVEL(absl::LogSeverity::kError)) << "To ERROR";
77 }
78 
TEST(LogHygieneTest,WorksWithAlternativeINFOSymbol)79 TEST(LogHygieneTest, WorksWithAlternativeINFOSymbol) {
80   const double INFO ABSL_ATTRIBUTE_UNUSED = 7.77;
81   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
82 
83   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"));
84 
85   test_sink.StartCapturingLogs();
86   LOG(INFO) << "Hello world";
87 }
88 
TEST(LogHygieneTest,WorksWithAlternativeWARNINGSymbol)89 TEST(LogHygieneTest, WorksWithAlternativeWARNINGSymbol) {
90   const double WARNING ABSL_ATTRIBUTE_UNUSED = 7.77;
91   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
92 
93   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "Hello world"));
94 
95   test_sink.StartCapturingLogs();
96   LOG(WARNING) << "Hello world";
97 }
98 
TEST(LogHygieneTest,WorksWithAlternativeERRORSymbol)99 TEST(LogHygieneTest, WorksWithAlternativeERRORSymbol) {
100   const double ERROR ABSL_ATTRIBUTE_UNUSED = 7.77;
101   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
102 
103   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
104 
105   test_sink.StartCapturingLogs();
106   LOG(ERROR) << "Hello world";
107 }
108 
TEST(LogHygieneTest,WorksWithAlternativeLEVELSymbol)109 TEST(LogHygieneTest, WorksWithAlternativeLEVELSymbol) {
110   const double LEVEL ABSL_ATTRIBUTE_UNUSED = 7.77;
111   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
112 
113   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
114 
115   test_sink.StartCapturingLogs();
116   LOG(LEVEL(absl::LogSeverity::kError)) << "Hello world";
117 }
118 
119 #define INFO Bogus
120 #ifdef NDEBUG
121 constexpr bool IsOptimized = false;
122 #else
123 constexpr bool IsOptimized = true;
124 #endif
125 
TEST(LogHygieneTest,WorksWithINFODefined)126 TEST(LogHygieneTest, WorksWithINFODefined) {
127   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
128 
129   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
130       .Times(2 + (IsOptimized ? 2 : 0));
131 
132   test_sink.StartCapturingLogs();
133   LOG(INFO) << "Hello world";
134   LOG_IF(INFO, true) << "Hello world";
135 
136   DLOG(INFO) << "Hello world";
137   DLOG_IF(INFO, true) << "Hello world";
138 }
139 
140 #undef INFO
141 
142 #define _INFO Bogus
TEST(LogHygieneTest,WorksWithUnderscoreINFODefined)143 TEST(LogHygieneTest, WorksWithUnderscoreINFODefined) {
144   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
145 
146   EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
147       .Times(2 + (IsOptimized ? 2 : 0));
148 
149   test_sink.StartCapturingLogs();
150   LOG(INFO) << "Hello world";
151   LOG_IF(INFO, true) << "Hello world";
152 
153   DLOG(INFO) << "Hello world";
154   DLOG_IF(INFO, true) << "Hello world";
155 }
156 #undef _INFO
157 
TEST(LogHygieneTest,ExpressionEvaluationInLEVELSeverity)158 TEST(LogHygieneTest, ExpressionEvaluationInLEVELSeverity) {
159   auto i = static_cast<int>(absl::LogSeverity::kInfo);
160   LOG(LEVEL(++i)) << "hello world";  // NOLINT
161   EXPECT_THAT(i, Eq(static_cast<int>(absl::LogSeverity::kInfo) + 1));
162 }
163 
TEST(LogHygieneTest,ExpressionEvaluationInStreamedMessage)164 TEST(LogHygieneTest, ExpressionEvaluationInStreamedMessage) {
165   int i = 0;
166   LOG(INFO) << ++i;
167   EXPECT_THAT(i, 1);
168   LOG_IF(INFO, false) << ++i;
169   EXPECT_THAT(i, 1);
170 }
171 
172 // Tests that macros are usable in unbraced switch statements.
173 // -----------------------------------------------------------
174 
175 class UnbracedSwitchCompileTest {
Log()176   static void Log() {
177     switch (0) {
178       case 0:
179         LOG(INFO);
180         break;
181       default:
182         break;
183     }
184   }
185 };
186 
187 }  // namespace
188