xref: /aosp_15_r20/external/abseil-cpp/absl/log/internal/test_matchers.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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