xref: /aosp_15_r20/external/abseil-cpp/absl/log/log_modifier_methods_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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 <errno.h>
17 
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 #include "absl/log/internal/test_actions.h"
21 #include "absl/log/internal/test_helpers.h"
22 #include "absl/log/internal/test_matchers.h"
23 #include "absl/log/log.h"
24 #include "absl/log/log_sink.h"
25 #include "absl/log/scoped_mock_log.h"
26 #include "absl/strings/match.h"
27 #include "absl/strings/string_view.h"
28 #include "absl/time/time.h"
29 
30 namespace {
31 #if GTEST_HAS_DEATH_TEST
32 using ::absl::log_internal::DeathTestExpectedLogging;
33 using ::absl::log_internal::DeathTestUnexpectedLogging;
34 using ::absl::log_internal::DeathTestValidateExpectations;
35 using ::absl::log_internal::DiedOfQFatal;
36 #endif
37 using ::absl::log_internal::LogSeverity;
38 using ::absl::log_internal::Prefix;
39 using ::absl::log_internal::SourceBasename;
40 using ::absl::log_internal::SourceFilename;
41 using ::absl::log_internal::SourceLine;
42 using ::absl::log_internal::Stacktrace;
43 using ::absl::log_internal::TextMessage;
44 using ::absl::log_internal::TextMessageWithPrefix;
45 using ::absl::log_internal::TextMessageWithPrefixAndNewline;
46 using ::absl::log_internal::TextPrefix;
47 using ::absl::log_internal::ThreadID;
48 using ::absl::log_internal::Timestamp;
49 using ::absl::log_internal::Verbosity;
50 
51 using ::testing::AllOf;
52 using ::testing::AnyNumber;
53 using ::testing::AnyOf;
54 using ::testing::Eq;
55 using ::testing::IsEmpty;
56 using ::testing::IsFalse;
57 using ::testing::Truly;
58 
TEST(TailCallsModifiesTest,AtLocationFileLine)59 TEST(TailCallsModifiesTest, AtLocationFileLine) {
60   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
61 
62   EXPECT_CALL(
63       test_sink,
64       Send(AllOf(
65           // The metadata should change:
66           SourceFilename(Eq("/my/very/very/very_long_source_file.cc")),
67           SourceBasename(Eq("very_long_source_file.cc")), SourceLine(Eq(777)),
68           // The logged line should change too, even though the prefix must
69           // grow to fit the new metadata.
70           TextMessageWithPrefix(Truly([](absl::string_view msg) {
71             return absl::EndsWith(msg,
72                                   " very_long_source_file.cc:777] hello world");
73           })))));
74 
75   test_sink.StartCapturingLogs();
76   LOG(INFO).AtLocation("/my/very/very/very_long_source_file.cc", 777)
77       << "hello world";
78 }
79 
TEST(TailCallsModifiesTest,NoPrefix)80 TEST(TailCallsModifiesTest, NoPrefix) {
81   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
82 
83   EXPECT_CALL(test_sink, Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()),
84                                     TextMessageWithPrefix(Eq("hello world")))));
85 
86   test_sink.StartCapturingLogs();
87   LOG(INFO).NoPrefix() << "hello world";
88 }
89 
TEST(TailCallsModifiesTest,NoPrefixNoMessageNoShirtNoShoesNoService)90 TEST(TailCallsModifiesTest, NoPrefixNoMessageNoShirtNoShoesNoService) {
91   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
92 
93   EXPECT_CALL(test_sink,
94               Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()),
95                          TextMessageWithPrefix(IsEmpty()),
96                          TextMessageWithPrefixAndNewline(Eq("\n")))));
97   test_sink.StartCapturingLogs();
98   LOG(INFO).NoPrefix();
99 }
100 
TEST(TailCallsModifiesTest,WithVerbosity)101 TEST(TailCallsModifiesTest, WithVerbosity) {
102   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
103 
104   EXPECT_CALL(test_sink, Send(Verbosity(Eq(2))));
105 
106   test_sink.StartCapturingLogs();
107   LOG(INFO).WithVerbosity(2) << "hello world";
108 }
109 
TEST(TailCallsModifiesTest,WithVerbosityNoVerbosity)110 TEST(TailCallsModifiesTest, WithVerbosityNoVerbosity) {
111   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
112 
113   EXPECT_CALL(test_sink,
114               Send(Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel))));
115 
116   test_sink.StartCapturingLogs();
117   LOG(INFO).WithVerbosity(2).WithVerbosity(absl::LogEntry::kNoVerbosityLevel)
118       << "hello world";
119 }
120 
TEST(TailCallsModifiesTest,WithTimestamp)121 TEST(TailCallsModifiesTest, WithTimestamp) {
122   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
123 
124   EXPECT_CALL(test_sink, Send(Timestamp(Eq(absl::UnixEpoch()))));
125 
126   test_sink.StartCapturingLogs();
127   LOG(INFO).WithTimestamp(absl::UnixEpoch()) << "hello world";
128 }
129 
TEST(TailCallsModifiesTest,WithThreadID)130 TEST(TailCallsModifiesTest, WithThreadID) {
131   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
132 
133   EXPECT_CALL(test_sink,
134               Send(AllOf(ThreadID(Eq(absl::LogEntry::tid_t{1234})))));
135 
136   test_sink.StartCapturingLogs();
137   LOG(INFO).WithThreadID(1234) << "hello world";
138 }
139 
TEST(TailCallsModifiesTest,WithMetadataFrom)140 TEST(TailCallsModifiesTest, WithMetadataFrom) {
141   class ForwardingLogSink : public absl::LogSink {
142    public:
143     void Send(const absl::LogEntry &entry) override {
144       LOG(LEVEL(entry.log_severity())).WithMetadataFrom(entry)
145           << "forwarded: " << entry.text_message();
146     }
147   } forwarding_sink;
148 
149   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
150 
151   EXPECT_CALL(
152       test_sink,
153       Send(AllOf(SourceFilename(Eq("fake/file")), SourceBasename(Eq("file")),
154                  SourceLine(Eq(123)), Prefix(IsFalse()),
155                  LogSeverity(Eq(absl::LogSeverity::kWarning)),
156                  Timestamp(Eq(absl::UnixEpoch())),
157                  ThreadID(Eq(absl::LogEntry::tid_t{456})),
158                  TextMessage(Eq("forwarded: hello world")), Verbosity(Eq(7)),
159                  ENCODED_MESSAGE(MatchesEvent(
160                      Eq("fake/file"), Eq(123), Eq(absl::UnixEpoch()),
161                      Eq(logging::proto::WARNING), Eq(456),
162                      ElementsAre(EqualsProto(R"pb(literal: "forwarded: ")pb"),
163                                  EqualsProto(R"pb(str: "hello world")pb")))))));
164 
165   test_sink.StartCapturingLogs();
166   LOG(WARNING)
167           .AtLocation("fake/file", 123)
168           .NoPrefix()
169           .WithTimestamp(absl::UnixEpoch())
170           .WithThreadID(456)
171           .WithVerbosity(7)
172           .ToSinkOnly(&forwarding_sink)
173       << "hello world";
174 }
175 
TEST(TailCallsModifiesTest,WithPerror)176 TEST(TailCallsModifiesTest, WithPerror) {
177   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
178 
179   EXPECT_CALL(
180       test_sink,
181       Send(AllOf(TextMessage(AnyOf(Eq("hello world: Bad file number [9]"),
182                                    Eq("hello world: Bad file descriptor [9]"),
183                                    Eq("hello world: Bad file descriptor [8]"))),
184                  ENCODED_MESSAGE(HasValues(ElementsAre(
185                      EqualsProto(R"pb(literal: "hello world")pb"),
186                      EqualsProto(R"pb(literal: ": ")pb"),
187                      AnyOf(EqualsProto(R"pb(str: "Bad file number")pb"),
188                            EqualsProto(R"pb(str: "Bad file descriptor")pb")),
189                      EqualsProto(R"pb(literal: " [")pb"),
190                      AnyOf(EqualsProto(R"pb(str: "8")pb"),
191                            EqualsProto(R"pb(str: "9")pb")),
192                      EqualsProto(R"pb(literal: "]")pb")))))));
193 
194   test_sink.StartCapturingLogs();
195   errno = EBADF;
196   LOG(INFO).WithPerror() << "hello world";
197 }
198 
199 #if GTEST_HAS_DEATH_TEST
TEST(ModifierMethodDeathTest,ToSinkOnlyQFatal)200 TEST(ModifierMethodDeathTest, ToSinkOnlyQFatal) {
201   EXPECT_EXIT(
202       {
203         absl::ScopedMockLog test_sink(
204             absl::MockLogDefault::kDisallowUnexpected);
205 
206         auto do_log = [&test_sink] {
207           LOG(QFATAL).ToSinkOnly(&test_sink.UseAsLocalSink()) << "hello world";
208         };
209 
210         EXPECT_CALL(test_sink, Send)
211             .Times(AnyNumber())
212             .WillRepeatedly(DeathTestUnexpectedLogging());
213 
214         EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("hello world")),
215                                           Stacktrace(IsEmpty()))))
216             .WillOnce(DeathTestExpectedLogging());
217 
218         test_sink.StartCapturingLogs();
219         do_log();
220       },
221       DiedOfQFatal, DeathTestValidateExpectations());
222 }
223 #endif
224 
225 }  // namespace
226