tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_matchers.cc (7186B)


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