1*9356374aSAndroid Build Coastguard Worker //
2*9356374aSAndroid Build Coastguard Worker // Copyright 2022 The Abseil Authors.
3*9356374aSAndroid Build Coastguard Worker //
4*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*9356374aSAndroid Build Coastguard Worker //
8*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
9*9356374aSAndroid Build Coastguard Worker //
10*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*9356374aSAndroid Build Coastguard Worker // limitations under the License.
15*9356374aSAndroid Build Coastguard Worker
16*9356374aSAndroid Build Coastguard Worker #include "absl/log/internal/test_matchers.h"
17*9356374aSAndroid Build Coastguard Worker
18*9356374aSAndroid Build Coastguard Worker #include <ostream>
19*9356374aSAndroid Build Coastguard Worker #include <sstream>
20*9356374aSAndroid Build Coastguard Worker #include <string>
21*9356374aSAndroid Build Coastguard Worker #include <type_traits>
22*9356374aSAndroid Build Coastguard Worker #include <utility>
23*9356374aSAndroid Build Coastguard Worker
24*9356374aSAndroid Build Coastguard Worker #include "gmock/gmock.h"
25*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
26*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/log/internal/test_helpers.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/log/log_entry.h"
30*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
31*9356374aSAndroid Build Coastguard Worker #include "absl/time/clock.h"
32*9356374aSAndroid Build Coastguard Worker #include "absl/time/time.h"
33*9356374aSAndroid Build Coastguard Worker
34*9356374aSAndroid Build Coastguard Worker namespace absl {
35*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
36*9356374aSAndroid Build Coastguard Worker namespace log_internal {
37*9356374aSAndroid Build Coastguard Worker namespace {
38*9356374aSAndroid Build Coastguard Worker using ::testing::_;
39*9356374aSAndroid Build Coastguard Worker using ::testing::AllOf;
40*9356374aSAndroid Build Coastguard Worker using ::testing::Ge;
41*9356374aSAndroid Build Coastguard Worker using ::testing::HasSubstr;
42*9356374aSAndroid Build Coastguard Worker using ::testing::MakeMatcher;
43*9356374aSAndroid Build Coastguard Worker using ::testing::Matcher;
44*9356374aSAndroid Build Coastguard Worker using ::testing::MatcherInterface;
45*9356374aSAndroid Build Coastguard Worker using ::testing::MatchResultListener;
46*9356374aSAndroid Build Coastguard Worker using ::testing::Not;
47*9356374aSAndroid Build Coastguard Worker using ::testing::Property;
48*9356374aSAndroid Build Coastguard Worker using ::testing::ResultOf;
49*9356374aSAndroid Build Coastguard Worker using ::testing::Truly;
50*9356374aSAndroid Build Coastguard Worker
51*9356374aSAndroid Build Coastguard Worker class AsStringImpl final
52*9356374aSAndroid Build Coastguard Worker : public MatcherInterface<absl::string_view> {
53*9356374aSAndroid Build Coastguard Worker public:
AsStringImpl(const Matcher<const std::string &> & str_matcher)54*9356374aSAndroid Build Coastguard Worker explicit AsStringImpl(
55*9356374aSAndroid Build Coastguard Worker const Matcher<const std::string&>& str_matcher)
56*9356374aSAndroid Build Coastguard Worker : str_matcher_(str_matcher) {}
MatchAndExplain(absl::string_view actual,MatchResultListener * listener) const57*9356374aSAndroid Build Coastguard Worker bool MatchAndExplain(
58*9356374aSAndroid Build Coastguard Worker absl::string_view actual,
59*9356374aSAndroid Build Coastguard Worker MatchResultListener* listener) const override {
60*9356374aSAndroid Build Coastguard Worker return str_matcher_.MatchAndExplain(std::string(actual), listener);
61*9356374aSAndroid Build Coastguard Worker }
DescribeTo(std::ostream * os) const62*9356374aSAndroid Build Coastguard Worker void DescribeTo(std::ostream* os) const override {
63*9356374aSAndroid Build Coastguard Worker return str_matcher_.DescribeTo(os);
64*9356374aSAndroid Build Coastguard Worker }
65*9356374aSAndroid Build Coastguard Worker
DescribeNegationTo(std::ostream * os) const66*9356374aSAndroid Build Coastguard Worker void DescribeNegationTo(std::ostream* os) const override {
67*9356374aSAndroid Build Coastguard Worker return str_matcher_.DescribeNegationTo(os);
68*9356374aSAndroid Build Coastguard Worker }
69*9356374aSAndroid Build Coastguard Worker
70*9356374aSAndroid Build Coastguard Worker private:
71*9356374aSAndroid Build Coastguard Worker const Matcher<const std::string&> str_matcher_;
72*9356374aSAndroid Build Coastguard Worker };
73*9356374aSAndroid Build Coastguard Worker
74*9356374aSAndroid Build Coastguard Worker class MatchesOstreamImpl final
75*9356374aSAndroid Build Coastguard Worker : public MatcherInterface<absl::string_view> {
76*9356374aSAndroid Build Coastguard Worker public:
MatchesOstreamImpl(std::string expected)77*9356374aSAndroid Build Coastguard Worker explicit MatchesOstreamImpl(std::string expected)
78*9356374aSAndroid Build Coastguard Worker : expected_(std::move(expected)) {}
MatchAndExplain(absl::string_view actual,MatchResultListener *) const79*9356374aSAndroid Build Coastguard Worker bool MatchAndExplain(absl::string_view actual,
80*9356374aSAndroid Build Coastguard Worker MatchResultListener*) const override {
81*9356374aSAndroid Build Coastguard Worker return actual == expected_;
82*9356374aSAndroid Build Coastguard Worker }
DescribeTo(std::ostream * os) const83*9356374aSAndroid Build Coastguard Worker void DescribeTo(std::ostream* os) const override {
84*9356374aSAndroid Build Coastguard Worker *os << "matches the contents of the ostringstream, which are \""
85*9356374aSAndroid Build Coastguard Worker << expected_ << "\"";
86*9356374aSAndroid Build Coastguard Worker }
87*9356374aSAndroid Build Coastguard Worker
DescribeNegationTo(std::ostream * os) const88*9356374aSAndroid Build Coastguard Worker void DescribeNegationTo(std::ostream* os) const override {
89*9356374aSAndroid Build Coastguard Worker *os << "does not match the contents of the ostringstream, which are \""
90*9356374aSAndroid Build Coastguard Worker << expected_ << "\"";
91*9356374aSAndroid Build Coastguard Worker }
92*9356374aSAndroid Build Coastguard Worker
93*9356374aSAndroid Build Coastguard Worker private:
94*9356374aSAndroid Build Coastguard Worker const std::string expected_;
95*9356374aSAndroid Build Coastguard Worker };
96*9356374aSAndroid Build Coastguard Worker } // namespace
97*9356374aSAndroid Build Coastguard Worker
AsString(const Matcher<const std::string &> & str_matcher)98*9356374aSAndroid Build Coastguard Worker Matcher<absl::string_view> AsString(
99*9356374aSAndroid Build Coastguard Worker const Matcher<const std::string&>& str_matcher) {
100*9356374aSAndroid Build Coastguard Worker return MakeMatcher(new AsStringImpl(str_matcher));
101*9356374aSAndroid Build Coastguard Worker }
102*9356374aSAndroid Build Coastguard Worker
SourceFilename(const Matcher<absl::string_view> & source_filename)103*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> SourceFilename(
104*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& source_filename) {
105*9356374aSAndroid Build Coastguard Worker return Property("source_filename", &absl::LogEntry::source_filename,
106*9356374aSAndroid Build Coastguard Worker source_filename);
107*9356374aSAndroid Build Coastguard Worker }
108*9356374aSAndroid Build Coastguard Worker
SourceBasename(const Matcher<absl::string_view> & source_basename)109*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> SourceBasename(
110*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& source_basename) {
111*9356374aSAndroid Build Coastguard Worker return Property("source_basename", &absl::LogEntry::source_basename,
112*9356374aSAndroid Build Coastguard Worker source_basename);
113*9356374aSAndroid Build Coastguard Worker }
114*9356374aSAndroid Build Coastguard Worker
SourceLine(const Matcher<int> & source_line)115*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> SourceLine(
116*9356374aSAndroid Build Coastguard Worker const Matcher<int>& source_line) {
117*9356374aSAndroid Build Coastguard Worker return Property("source_line", &absl::LogEntry::source_line, source_line);
118*9356374aSAndroid Build Coastguard Worker }
119*9356374aSAndroid Build Coastguard Worker
Prefix(const Matcher<bool> & prefix)120*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> Prefix(
121*9356374aSAndroid Build Coastguard Worker const Matcher<bool>& prefix) {
122*9356374aSAndroid Build Coastguard Worker return Property("prefix", &absl::LogEntry::prefix, prefix);
123*9356374aSAndroid Build Coastguard Worker }
124*9356374aSAndroid Build Coastguard Worker
LogSeverity(const Matcher<absl::LogSeverity> & log_severity)125*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> LogSeverity(
126*9356374aSAndroid Build Coastguard Worker const Matcher<absl::LogSeverity>& log_severity) {
127*9356374aSAndroid Build Coastguard Worker return Property("log_severity", &absl::LogEntry::log_severity, log_severity);
128*9356374aSAndroid Build Coastguard Worker }
129*9356374aSAndroid Build Coastguard Worker
Timestamp(const Matcher<absl::Time> & timestamp)130*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> Timestamp(
131*9356374aSAndroid Build Coastguard Worker const Matcher<absl::Time>& timestamp) {
132*9356374aSAndroid Build Coastguard Worker return Property("timestamp", &absl::LogEntry::timestamp, timestamp);
133*9356374aSAndroid Build Coastguard Worker }
134*9356374aSAndroid Build Coastguard Worker
InMatchWindow()135*9356374aSAndroid Build Coastguard Worker Matcher<absl::Time> InMatchWindow() {
136*9356374aSAndroid Build Coastguard Worker return AllOf(Ge(absl::Now()),
137*9356374aSAndroid Build Coastguard Worker Truly([](absl::Time arg) { return arg <= absl::Now(); }));
138*9356374aSAndroid Build Coastguard Worker }
139*9356374aSAndroid Build Coastguard Worker
ThreadID(const Matcher<absl::LogEntry::tid_t> & tid)140*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> ThreadID(
141*9356374aSAndroid Build Coastguard Worker const Matcher<absl::LogEntry::tid_t>& tid) {
142*9356374aSAndroid Build Coastguard Worker return Property("tid", &absl::LogEntry::tid, tid);
143*9356374aSAndroid Build Coastguard Worker }
144*9356374aSAndroid Build Coastguard Worker
TextMessageWithPrefixAndNewline(const Matcher<absl::string_view> & text_message_with_prefix_and_newline)145*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> TextMessageWithPrefixAndNewline(
146*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>&
147*9356374aSAndroid Build Coastguard Worker text_message_with_prefix_and_newline) {
148*9356374aSAndroid Build Coastguard Worker return Property("text_message_with_prefix_and_newline",
149*9356374aSAndroid Build Coastguard Worker &absl::LogEntry::text_message_with_prefix_and_newline,
150*9356374aSAndroid Build Coastguard Worker text_message_with_prefix_and_newline);
151*9356374aSAndroid Build Coastguard Worker }
152*9356374aSAndroid Build Coastguard Worker
TextMessageWithPrefix(const Matcher<absl::string_view> & text_message_with_prefix)153*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> TextMessageWithPrefix(
154*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& text_message_with_prefix) {
155*9356374aSAndroid Build Coastguard Worker return Property("text_message_with_prefix",
156*9356374aSAndroid Build Coastguard Worker &absl::LogEntry::text_message_with_prefix,
157*9356374aSAndroid Build Coastguard Worker text_message_with_prefix);
158*9356374aSAndroid Build Coastguard Worker }
159*9356374aSAndroid Build Coastguard Worker
TextMessage(const Matcher<absl::string_view> & text_message)160*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> TextMessage(
161*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& text_message) {
162*9356374aSAndroid Build Coastguard Worker return Property("text_message", &absl::LogEntry::text_message, text_message);
163*9356374aSAndroid Build Coastguard Worker }
164*9356374aSAndroid Build Coastguard Worker
TextPrefix(const Matcher<absl::string_view> & text_prefix)165*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> TextPrefix(
166*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& text_prefix) {
167*9356374aSAndroid Build Coastguard Worker return ResultOf(
168*9356374aSAndroid Build Coastguard Worker [](const absl::LogEntry& entry) {
169*9356374aSAndroid Build Coastguard Worker absl::string_view msg = entry.text_message_with_prefix();
170*9356374aSAndroid Build Coastguard Worker msg.remove_suffix(entry.text_message().size());
171*9356374aSAndroid Build Coastguard Worker return msg;
172*9356374aSAndroid Build Coastguard Worker },
173*9356374aSAndroid Build Coastguard Worker text_prefix);
174*9356374aSAndroid Build Coastguard Worker }
RawEncodedMessage(const Matcher<absl::string_view> & raw_encoded_message)175*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> RawEncodedMessage(
176*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& raw_encoded_message) {
177*9356374aSAndroid Build Coastguard Worker return Property("encoded_message", &absl::LogEntry::encoded_message,
178*9356374aSAndroid Build Coastguard Worker raw_encoded_message);
179*9356374aSAndroid Build Coastguard Worker }
180*9356374aSAndroid Build Coastguard Worker
Verbosity(const Matcher<int> & verbosity)181*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> Verbosity(
182*9356374aSAndroid Build Coastguard Worker const Matcher<int>& verbosity) {
183*9356374aSAndroid Build Coastguard Worker return Property("verbosity", &absl::LogEntry::verbosity, verbosity);
184*9356374aSAndroid Build Coastguard Worker }
185*9356374aSAndroid Build Coastguard Worker
Stacktrace(const Matcher<absl::string_view> & stacktrace)186*9356374aSAndroid Build Coastguard Worker Matcher<const absl::LogEntry&> Stacktrace(
187*9356374aSAndroid Build Coastguard Worker const Matcher<absl::string_view>& stacktrace) {
188*9356374aSAndroid Build Coastguard Worker return Property("stacktrace", &absl::LogEntry::stacktrace, stacktrace);
189*9356374aSAndroid Build Coastguard Worker }
190*9356374aSAndroid Build Coastguard Worker
MatchesOstream(const std::ostringstream & stream)191*9356374aSAndroid Build Coastguard Worker Matcher<absl::string_view> MatchesOstream(
192*9356374aSAndroid Build Coastguard Worker const std::ostringstream& stream) {
193*9356374aSAndroid Build Coastguard Worker return MakeMatcher(new MatchesOstreamImpl(stream.str()));
194*9356374aSAndroid Build Coastguard Worker }
195*9356374aSAndroid Build Coastguard Worker
196*9356374aSAndroid Build Coastguard Worker // We need to validate what is and isn't logged as the process dies due to
197*9356374aSAndroid Build Coastguard Worker // `FATAL`, `QFATAL`, `CHECK`, etc., but assertions inside a death test
198*9356374aSAndroid Build Coastguard Worker // subprocess don't directly affect the pass/fail status of the parent process.
199*9356374aSAndroid Build Coastguard Worker // Instead, we use the mock actions `DeathTestExpectedLogging` and
200*9356374aSAndroid Build Coastguard Worker // `DeathTestUnexpectedLogging` to write specific phrases to `stderr` that we
201*9356374aSAndroid Build Coastguard Worker // can validate in the parent process using this matcher.
DeathTestValidateExpectations()202*9356374aSAndroid Build Coastguard Worker Matcher<const std::string&> DeathTestValidateExpectations() {
203*9356374aSAndroid Build Coastguard Worker if (log_internal::LoggingEnabledAt(absl::LogSeverity::kFatal)) {
204*9356374aSAndroid Build Coastguard Worker return Matcher<const std::string&>(
205*9356374aSAndroid Build Coastguard Worker AllOf(HasSubstr("Mock received expected entry"),
206*9356374aSAndroid Build Coastguard Worker Not(HasSubstr("Mock received unexpected entry"))));
207*9356374aSAndroid Build Coastguard Worker }
208*9356374aSAndroid Build Coastguard Worker // If `FATAL` logging is disabled, neither message should have been written.
209*9356374aSAndroid Build Coastguard Worker return Matcher<const std::string&>(
210*9356374aSAndroid Build Coastguard Worker AllOf(Not(HasSubstr("Mock received expected entry")),
211*9356374aSAndroid Build Coastguard Worker Not(HasSubstr("Mock received unexpected entry"))));
212*9356374aSAndroid Build Coastguard Worker }
213*9356374aSAndroid Build Coastguard Worker
214*9356374aSAndroid Build Coastguard Worker } // namespace log_internal
215*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
216*9356374aSAndroid Build Coastguard Worker } // namespace absl
217