tor-browser

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

log_streamer_test.cc (16566B)


      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/log_streamer.h"
     17 
     18 #include <ios>
     19 #include <iostream>
     20 #include <utility>
     21 
     22 #include "gmock/gmock.h"
     23 #include "gtest/gtest.h"
     24 #include "absl/base/attributes.h"
     25 #include "absl/base/internal/sysinfo.h"
     26 #include "absl/base/log_severity.h"
     27 #include "absl/log/internal/test_actions.h"
     28 #include "absl/log/internal/test_helpers.h"
     29 #include "absl/log/internal/test_matchers.h"
     30 #include "absl/log/log.h"
     31 #include "absl/log/scoped_mock_log.h"
     32 #include "absl/strings/string_view.h"
     33 
     34 namespace {
     35 using ::absl::log_internal::DeathTestExpectedLogging;
     36 using ::absl::log_internal::DeathTestUnexpectedLogging;
     37 using ::absl::log_internal::DeathTestValidateExpectations;
     38 #if GTEST_HAS_DEATH_TEST
     39 using ::absl::log_internal::DiedOfFatal;
     40 #endif
     41 using ::absl::log_internal::InMatchWindow;
     42 using ::absl::log_internal::LogSeverity;
     43 using ::absl::log_internal::Prefix;
     44 using ::absl::log_internal::SourceFilename;
     45 using ::absl::log_internal::SourceLine;
     46 using ::absl::log_internal::Stacktrace;
     47 using ::absl::log_internal::TextMessage;
     48 using ::absl::log_internal::ThreadID;
     49 using ::absl::log_internal::Timestamp;
     50 using ::testing::_;
     51 using ::testing::AnyNumber;
     52 using ::testing::Eq;
     53 using ::testing::HasSubstr;
     54 using ::testing::IsEmpty;
     55 using ::testing::IsTrue;
     56 
     57 auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
     58    new absl::log_internal::LogTestEnvironment);
     59 
     60 void WriteToStream(absl::string_view data, std::ostream* os) {
     61  *os << "WriteToStream: " << data;
     62 }
     63 void WriteToStreamRef(absl::string_view data, std::ostream& os) {
     64  os << "WriteToStreamRef: " << data;
     65 }
     66 
     67 TEST(LogStreamerTest, LogInfoStreamer) {
     68  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     69 
     70  EXPECT_CALL(
     71      test_sink,
     72      Send(
     73          AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
     74                Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kInfo)),
     75                Timestamp(InMatchWindow()),
     76                ThreadID(Eq(absl::base_internal::GetTID())),
     77                TextMessage(Eq("WriteToStream: foo")),
     78                ENCODED_MESSAGE(MatchesEvent(
     79                    Eq("path/file.cc"), Eq(1234), InMatchWindow(),
     80                    Eq(logging::proto::INFO), Eq(absl::base_internal::GetTID()),
     81                    ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
     82                Stacktrace(IsEmpty()))));
     83 
     84  test_sink.StartCapturingLogs();
     85  WriteToStream("foo", &absl::LogInfoStreamer("path/file.cc", 1234).stream());
     86 }
     87 
     88 TEST(LogStreamerTest, LogWarningStreamer) {
     89  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     90 
     91  EXPECT_CALL(
     92      test_sink,
     93      Send(AllOf(
     94          SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
     95          Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kWarning)),
     96          Timestamp(InMatchWindow()),
     97          ThreadID(Eq(absl::base_internal::GetTID())),
     98          TextMessage(Eq("WriteToStream: foo")),
     99          ENCODED_MESSAGE(MatchesEvent(
    100              Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    101              Eq(logging::proto::WARNING), Eq(absl::base_internal::GetTID()),
    102              ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
    103          Stacktrace(IsEmpty()))));
    104 
    105  test_sink.StartCapturingLogs();
    106  WriteToStream("foo",
    107                &absl::LogWarningStreamer("path/file.cc", 1234).stream());
    108 }
    109 
    110 TEST(LogStreamerTest, LogErrorStreamer) {
    111  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    112 
    113  EXPECT_CALL(
    114      test_sink,
    115      Send(AllOf(
    116          SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    117          Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
    118          Timestamp(InMatchWindow()),
    119          ThreadID(Eq(absl::base_internal::GetTID())),
    120          TextMessage(Eq("WriteToStream: foo")),
    121          ENCODED_MESSAGE(MatchesEvent(
    122              Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    123              Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
    124              ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
    125          Stacktrace(IsEmpty()))));
    126 
    127  test_sink.StartCapturingLogs();
    128  WriteToStream("foo", &absl::LogErrorStreamer("path/file.cc", 1234).stream());
    129 }
    130 
    131 #if GTEST_HAS_DEATH_TEST
    132 TEST(LogStreamerDeathTest, LogFatalStreamer) {
    133  EXPECT_EXIT(
    134      {
    135        absl::ScopedMockLog test_sink;
    136 
    137        EXPECT_CALL(test_sink, Send)
    138            .Times(AnyNumber())
    139            .WillRepeatedly(DeathTestUnexpectedLogging());
    140 
    141        EXPECT_CALL(
    142            test_sink,
    143            Send(AllOf(
    144                SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    145                Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
    146                Timestamp(InMatchWindow()),
    147                ThreadID(Eq(absl::base_internal::GetTID())),
    148                TextMessage(Eq("WriteToStream: foo")),
    149                ENCODED_MESSAGE(MatchesEvent(
    150                    Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    151                    Eq(logging::proto::FATAL),
    152                    Eq(absl::base_internal::GetTID()),
    153                    ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
    154            .WillOnce(DeathTestExpectedLogging());
    155 
    156        test_sink.StartCapturingLogs();
    157        WriteToStream("foo",
    158                      &absl::LogFatalStreamer("path/file.cc", 1234).stream());
    159      },
    160      DiedOfFatal, DeathTestValidateExpectations());
    161 }
    162 #endif
    163 
    164 #ifdef NDEBUG
    165 TEST(LogStreamerTest, LogDebugFatalStreamer) {
    166  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    167 
    168  EXPECT_CALL(
    169      test_sink,
    170      Send(AllOf(
    171          SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    172          Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
    173          Timestamp(InMatchWindow()),
    174          ThreadID(Eq(absl::base_internal::GetTID())),
    175          TextMessage(Eq("WriteToStream: foo")),
    176          ENCODED_MESSAGE(MatchesEvent(
    177              Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    178              Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
    179              ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
    180          Stacktrace(IsEmpty()))));
    181 
    182  test_sink.StartCapturingLogs();
    183  WriteToStream("foo",
    184                &absl::LogDebugFatalStreamer("path/file.cc", 1234).stream());
    185 }
    186 #elif GTEST_HAS_DEATH_TEST
    187 TEST(LogStreamerDeathTest, LogDebugFatalStreamer) {
    188  EXPECT_EXIT(
    189      {
    190        absl::ScopedMockLog test_sink;
    191 
    192        EXPECT_CALL(test_sink, Send)
    193            .Times(AnyNumber())
    194            .WillRepeatedly(DeathTestUnexpectedLogging());
    195 
    196        EXPECT_CALL(
    197            test_sink,
    198            Send(AllOf(
    199                SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    200                Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
    201                Timestamp(InMatchWindow()),
    202                ThreadID(Eq(absl::base_internal::GetTID())),
    203                TextMessage(Eq("WriteToStream: foo")),
    204                ENCODED_MESSAGE(MatchesEvent(
    205                    Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    206                    Eq(logging::proto::FATAL),
    207                    Eq(absl::base_internal::GetTID()),
    208                    ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
    209            .WillOnce(DeathTestExpectedLogging());
    210 
    211        test_sink.StartCapturingLogs();
    212        WriteToStream(
    213            "foo", &absl::LogDebugFatalStreamer("path/file.cc", 1234).stream());
    214      },
    215      DiedOfFatal, DeathTestValidateExpectations());
    216 }
    217 #endif
    218 
    219 TEST(LogStreamerTest, LogStreamer) {
    220  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    221 
    222  EXPECT_CALL(
    223      test_sink,
    224      Send(AllOf(
    225          SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    226          Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
    227          Timestamp(InMatchWindow()),
    228          ThreadID(Eq(absl::base_internal::GetTID())),
    229          TextMessage(Eq("WriteToStream: foo")),
    230          ENCODED_MESSAGE(MatchesEvent(
    231              Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    232              Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
    233              ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
    234          Stacktrace(IsEmpty()))));
    235 
    236  test_sink.StartCapturingLogs();
    237  WriteToStream(
    238      "foo", &absl::LogStreamer(absl::LogSeverity::kError, "path/file.cc", 1234)
    239                  .stream());
    240 }
    241 
    242 #if GTEST_HAS_DEATH_TEST
    243 TEST(LogStreamerDeathTest, LogStreamer) {
    244  EXPECT_EXIT(
    245      {
    246        absl::ScopedMockLog test_sink;
    247 
    248        EXPECT_CALL(test_sink, Send)
    249            .Times(AnyNumber())
    250            .WillRepeatedly(DeathTestUnexpectedLogging());
    251 
    252        EXPECT_CALL(
    253            test_sink,
    254            Send(AllOf(
    255                SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    256                Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
    257                Timestamp(InMatchWindow()),
    258                ThreadID(Eq(absl::base_internal::GetTID())),
    259                TextMessage(Eq("WriteToStream: foo")),
    260                ENCODED_MESSAGE(MatchesEvent(
    261                    Eq("path/file.cc"), Eq(1234), InMatchWindow(),
    262                    Eq(logging::proto::FATAL),
    263                    Eq(absl::base_internal::GetTID()),
    264                    ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
    265            .WillOnce(DeathTestExpectedLogging());
    266 
    267        test_sink.StartCapturingLogs();
    268        WriteToStream("foo", &absl::LogStreamer(absl::LogSeverity::kFatal,
    269                                                "path/file.cc", 1234)
    270                                  .stream());
    271      },
    272      DiedOfFatal, DeathTestValidateExpectations());
    273 }
    274 #endif
    275 
    276 TEST(LogStreamerTest, PassedByReference) {
    277  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    278 
    279  EXPECT_CALL(
    280      test_sink,
    281      Send(AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    282                 TextMessage(Eq("WriteToStreamRef: foo")),
    283                 ENCODED_MESSAGE(MatchesEvent(
    284                     Eq("path/file.cc"), Eq(1234), _, _, _,
    285                     ElementsAre(ValueWithStr(Eq("WriteToStreamRef: foo"))))),
    286                 Stacktrace(IsEmpty()))));
    287 
    288  test_sink.StartCapturingLogs();
    289  WriteToStreamRef("foo", absl::LogInfoStreamer("path/file.cc", 1234).stream());
    290 }
    291 
    292 TEST(LogStreamerTest, StoredAsLocal) {
    293  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    294 
    295  auto streamer = absl::LogInfoStreamer("path/file.cc", 1234);
    296  WriteToStream("foo", &streamer.stream());
    297  streamer.stream() << " ";
    298  WriteToStreamRef("bar", streamer.stream());
    299 
    300  // The call should happen when `streamer` goes out of scope; if it
    301  // happened before this `EXPECT_CALL` the call would be unexpected and the
    302  // test would fail.
    303  EXPECT_CALL(
    304      test_sink,
    305      Send(AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    306                 TextMessage(Eq("WriteToStream: foo WriteToStreamRef: bar")),
    307                 ENCODED_MESSAGE(MatchesEvent(
    308                     Eq("path/file.cc"), Eq(1234), _, _, _,
    309                     ElementsAre(ValueWithStr(
    310                         Eq("WriteToStream: foo WriteToStreamRef: bar"))))),
    311                 Stacktrace(IsEmpty()))));
    312 
    313  test_sink.StartCapturingLogs();
    314 }
    315 
    316 #if GTEST_HAS_DEATH_TEST
    317 TEST(LogStreamerDeathTest, StoredAsLocal) {
    318  EXPECT_EXIT(
    319      {
    320        // This is fatal when it goes out of scope, but not until then:
    321        auto streamer = absl::LogFatalStreamer("path/file.cc", 1234);
    322        std::cerr << "I'm still alive" << std::endl;
    323        WriteToStream("foo", &streamer.stream());
    324      },
    325      DiedOfFatal, HasSubstr("I'm still alive"));
    326 }
    327 #endif
    328 
    329 TEST(LogStreamerTest, LogsEmptyLine) {
    330  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    331 
    332  EXPECT_CALL(test_sink, Send(AllOf(SourceFilename(Eq("path/file.cc")),
    333                                    SourceLine(Eq(1234)), TextMessage(Eq("")),
    334                                    ENCODED_MESSAGE(MatchesEvent(
    335                                        Eq("path/file.cc"), Eq(1234), _, _, _,
    336                                        ElementsAre(ValueWithStr(Eq(""))))),
    337                                    Stacktrace(IsEmpty()))));
    338 
    339  test_sink.StartCapturingLogs();
    340  absl::LogInfoStreamer("path/file.cc", 1234);
    341 }
    342 
    343 #if GTEST_HAS_DEATH_TEST
    344 TEST(LogStreamerDeathTest, LogsEmptyLine) {
    345  EXPECT_EXIT(
    346      {
    347        absl::ScopedMockLog test_sink;
    348 
    349        EXPECT_CALL(test_sink, Log)
    350            .Times(AnyNumber())
    351            .WillRepeatedly(DeathTestUnexpectedLogging());
    352 
    353        EXPECT_CALL(
    354            test_sink,
    355            Send(AllOf(SourceFilename(Eq("path/file.cc")), TextMessage(Eq("")),
    356                       ENCODED_MESSAGE(
    357                           MatchesEvent(Eq("path/file.cc"), _, _, _, _,
    358                                        ElementsAre(ValueWithStr(Eq(""))))))))
    359            .WillOnce(DeathTestExpectedLogging());
    360 
    361        test_sink.StartCapturingLogs();
    362        // This is fatal even though it's never used:
    363        auto streamer = absl::LogFatalStreamer("path/file.cc", 1234);
    364      },
    365      DiedOfFatal, DeathTestValidateExpectations());
    366 }
    367 #endif
    368 
    369 TEST(LogStreamerTest, MoveConstruction) {
    370  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    371 
    372  EXPECT_CALL(
    373      test_sink,
    374      Send(
    375          AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    376                LogSeverity(Eq(absl::LogSeverity::kInfo)),
    377                TextMessage(Eq("hello 0x10 world 0x10")),
    378                ENCODED_MESSAGE(MatchesEvent(
    379                    Eq("path/file.cc"), Eq(1234), _, Eq(logging::proto::INFO),
    380                    _, ElementsAre(ValueWithStr(Eq("hello 0x10 world 0x10"))))),
    381                Stacktrace(IsEmpty()))));
    382 
    383  test_sink.StartCapturingLogs();
    384  auto streamer1 = absl::LogInfoStreamer("path/file.cc", 1234);
    385  streamer1.stream() << "hello " << std::hex << 16;
    386  absl::LogStreamer streamer2(std::move(streamer1));
    387  streamer2.stream() << " world " << 16;
    388 }
    389 
    390 TEST(LogStreamerTest, MoveAssignment) {
    391  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    392 
    393  testing::InSequence seq;
    394  EXPECT_CALL(
    395      test_sink,
    396      Send(AllOf(
    397          SourceFilename(Eq("path/file2.cc")), SourceLine(Eq(5678)),
    398          LogSeverity(Eq(absl::LogSeverity::kWarning)),
    399          TextMessage(Eq("something else")),
    400          ENCODED_MESSAGE(MatchesEvent(
    401              Eq("path/file2.cc"), Eq(5678), _, Eq(logging::proto::WARNING), _,
    402              ElementsAre(ValueWithStr(Eq("something else"))))),
    403          Stacktrace(IsEmpty()))));
    404  EXPECT_CALL(
    405      test_sink,
    406      Send(
    407          AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
    408                LogSeverity(Eq(absl::LogSeverity::kInfo)),
    409                TextMessage(Eq("hello 0x10 world 0x10")),
    410                ENCODED_MESSAGE(MatchesEvent(
    411                    Eq("path/file.cc"), Eq(1234), _, Eq(logging::proto::INFO),
    412                    _, ElementsAre(ValueWithStr(Eq("hello 0x10 world 0x10"))))),
    413                Stacktrace(IsEmpty()))));
    414 
    415  test_sink.StartCapturingLogs();
    416  auto streamer1 = absl::LogInfoStreamer("path/file.cc", 1234);
    417  streamer1.stream() << "hello " << std::hex << 16;
    418  auto streamer2 = absl::LogWarningStreamer("path/file2.cc", 5678);
    419  streamer2.stream() << "something else";
    420  streamer2 = std::move(streamer1);
    421  streamer2.stream() << " world " << 16;
    422 }
    423 
    424 TEST(LogStreamerTest, CorrectDefaultFlags) {
    425  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    426 
    427  // The `boolalpha` and `showbase` flags should be set by default, to match
    428  // `LOG`.
    429  EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("false0xdeadbeef")))))
    430      .Times(2);
    431 
    432  test_sink.StartCapturingLogs();
    433  absl::LogInfoStreamer("path/file.cc", 1234).stream()
    434      << false << std::hex << 0xdeadbeef;
    435  LOG(INFO) << false << std::hex << 0xdeadbeef;
    436 }
    437 
    438 }  // namespace