diff options
Diffstat (limited to 'absl/log/log_modifier_methods_test.cc')
-rw-r--r-- | absl/log/log_modifier_methods_test.cc | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/absl/log/log_modifier_methods_test.cc b/absl/log/log_modifier_methods_test.cc new file mode 100644 index 00000000..a9bf38b7 --- /dev/null +++ b/absl/log/log_modifier_methods_test.cc @@ -0,0 +1,231 @@ +// +// Copyright 2022 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <errno.h> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/log/internal/test_actions.h" +#include "absl/log/internal/test_helpers.h" +#include "absl/log/internal/test_matchers.h" +#include "absl/log/log.h" +#include "absl/log/log_sink.h" +#include "absl/log/scoped_mock_log.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" + +namespace { +#if GTEST_HAS_DEATH_TEST +using ::absl::log_internal::DeathTestExpectedLogging; +using ::absl::log_internal::DeathTestUnexpectedLogging; +using ::absl::log_internal::DeathTestValidateExpectations; +using ::absl::log_internal::DiedOfQFatal; +#endif +using ::absl::log_internal::LogSeverity; +using ::absl::log_internal::Prefix; +using ::absl::log_internal::SourceBasename; +using ::absl::log_internal::SourceFilename; +using ::absl::log_internal::SourceLine; +using ::absl::log_internal::Stacktrace; +using ::absl::log_internal::TextMessage; +using ::absl::log_internal::TextMessageWithPrefix; +using ::absl::log_internal::TextMessageWithPrefixAndNewline; +using ::absl::log_internal::TextPrefix; +using ::absl::log_internal::ThreadID; +using ::absl::log_internal::Timestamp; +using ::absl::log_internal::Verbosity; + +using ::testing::AllOf; +using ::testing::AnyNumber; +using ::testing::AnyOf; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::IsFalse; +using ::testing::Truly; + +TEST(TailCallsModifiesTest, AtLocationFileLine) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL( + test_sink, + Send(AllOf( + // The metadata should change: + SourceFilename(Eq("/my/very/very/very_long_source_file.cc")), + SourceBasename(Eq("very_long_source_file.cc")), SourceLine(Eq(777)), + // The logged line should change too, even though the prefix must + // grow to fit the new metadata. + TextMessageWithPrefix(Truly([](absl::string_view msg) { + return absl::EndsWith(msg, + " very_long_source_file.cc:777] hello world"); + }))))); + + test_sink.StartCapturingLogs(); + LOG(INFO).AtLocation("/my/very/very/very_long_source_file.cc", 777) + << "hello world"; +} + +TEST(TailCallsModifiesTest, NoPrefix) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()), + TextMessageWithPrefix(Eq("hello world"))))); + + test_sink.StartCapturingLogs(); + LOG(INFO).NoPrefix() << "hello world"; +} + +TEST(TailCallsModifiesTest, NoPrefixNoMessageNoShirtNoShoesNoService) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, + Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()), + TextMessageWithPrefix(IsEmpty()), + TextMessageWithPrefixAndNewline(Eq("\n"))))); + test_sink.StartCapturingLogs(); + LOG(INFO).NoPrefix(); +} + +TEST(TailCallsModifiesTest, WithVerbosity) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, Send(Verbosity(Eq(2)))); + + test_sink.StartCapturingLogs(); + LOG(INFO).WithVerbosity(2) << "hello world"; +} + +TEST(TailCallsModifiesTest, WithVerbosityNoVerbosity) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, + Send(Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)))); + + test_sink.StartCapturingLogs(); + LOG(INFO).WithVerbosity(2).WithVerbosity(absl::LogEntry::kNoVerbosityLevel) + << "hello world"; +} + +TEST(TailCallsModifiesTest, WithTimestamp) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, Send(Timestamp(Eq(absl::UnixEpoch())))); + + test_sink.StartCapturingLogs(); + LOG(INFO).WithTimestamp(absl::UnixEpoch()) << "hello world"; +} + +TEST(TailCallsModifiesTest, WithThreadID) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL(test_sink, Send(AllOf(ThreadID(Eq(1234))))); + + test_sink.StartCapturingLogs(); + LOG(INFO).WithThreadID(1234) << "hello world"; +} + +TEST(TailCallsModifiesTest, WithMetadataFrom) { + class ForwardingLogSink : public absl::LogSink { + public: + void Send(const absl::LogEntry &entry) override { + LOG(LEVEL(entry.log_severity())).WithMetadataFrom(entry) + << "forwarded: " << entry.text_message(); + } + } forwarding_sink; + + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL( + test_sink, + Send(AllOf(SourceFilename(Eq("fake/file")), SourceBasename(Eq("file")), + SourceLine(Eq(123)), Prefix(IsFalse()), + LogSeverity(Eq(absl::LogSeverity::kWarning)), + Timestamp(Eq(absl::UnixEpoch())), ThreadID(Eq(456)), + TextMessage(Eq("forwarded: hello world")), Verbosity(Eq(7)), + ENCODED_MESSAGE( + EqualsProto(R"pb(value { literal: "forwarded: " } + value { str: "hello world" })pb"))))); + + test_sink.StartCapturingLogs(); + LOG(WARNING) + .AtLocation("fake/file", 123) + .NoPrefix() + .WithTimestamp(absl::UnixEpoch()) + .WithThreadID(456) + .WithVerbosity(7) + .ToSinkOnly(&forwarding_sink) + << "hello world"; +} + +TEST(TailCallsModifiesTest, WithPerror) { + absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + + EXPECT_CALL( + test_sink, + Send(AllOf(TextMessage(AnyOf(Eq("hello world: Bad file number [9]"), + Eq("hello world: Bad file descriptor [9]"), + Eq("hello world: Bad file descriptor [8]"))), + ENCODED_MESSAGE( + AnyOf(EqualsProto(R"pb(value { literal: "hello world" } + value { literal: ": " } + value { str: "Bad file number" } + value { literal: " [" } + value { str: "9" } + value { literal: "]" })pb"), + EqualsProto(R"pb(value { literal: "hello world" } + value { literal: ": " } + value { str: "Bad file descriptor" } + value { literal: " [" } + value { str: "9" } + value { literal: "]" })pb"), + EqualsProto(R"pb(value { literal: "hello world" } + value { literal: ": " } + value { str: "Bad file descriptor" } + value { literal: " [" } + value { str: "8" } + value { literal: "]" })pb")))))); + + test_sink.StartCapturingLogs(); + errno = EBADF; + LOG(INFO).WithPerror() << "hello world"; +} + +#if GTEST_HAS_DEATH_TEST +TEST(ModifierMethodDeathTest, ToSinkOnlyQFatal) { + EXPECT_EXIT( + { + absl::ScopedMockLog test_sink( + absl::MockLogDefault::kDisallowUnexpected); + + auto do_log = [&test_sink] { + LOG(QFATAL).ToSinkOnly(&test_sink.UseAsLocalSink()) << "hello world"; + }; + + EXPECT_CALL(test_sink, Send) + .Times(AnyNumber()) + .WillRepeatedly(DeathTestUnexpectedLogging()); + + EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("hello world")), + Stacktrace(IsEmpty())))) + .WillOnce(DeathTestExpectedLogging()); + + test_sink.StartCapturingLogs(); + do_log(); + }, + DiedOfQFatal, DeathTestValidateExpectations()); +} +#endif + +} // namespace |