tor-browser

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

log_macro_hygiene_test.cc (5511B)


      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 "gmock/gmock.h"
     17 #include "gtest/gtest.h"
     18 #include "absl/base/attributes.h"
     19 #include "absl/base/log_severity.h"
     20 #include "absl/log/log.h"
     21 #include "absl/log/scoped_mock_log.h"
     22 
     23 namespace {
     24 using ::testing::_;
     25 using ::testing::Eq;
     26 
     27 namespace not_absl {
     28 
     29 class Dummy {
     30 public:
     31  Dummy() {}
     32 
     33 private:
     34  Dummy(const Dummy&) = delete;
     35  Dummy& operator=(const Dummy&) = delete;
     36 };
     37 
     38 // This line tests that local definitions of INFO, WARNING, ERROR, and
     39 // etc don't shadow the global ones used by the logging macros.  If
     40 // they do, the LOG() calls in the tests won't compile, catching the
     41 // bug.
     42 const Dummy INFO, WARNING, ERROR, FATAL, NUM_SEVERITIES;
     43 
     44 // These makes sure that the uses of same-named types in the
     45 // implementation of the logging macros are fully qualified.
     46 class string {};
     47 class vector {};
     48 class LogMessage {};
     49 class LogMessageFatal {};
     50 class LogMessageQuietlyFatal {};
     51 class LogMessageVoidify {};
     52 class LogSink {};
     53 class NullStream {};
     54 class NullStreamFatal {};
     55 
     56 }  // namespace not_absl
     57 
     58 using namespace not_absl;  // NOLINT
     59 
     60 // Tests for LOG(LEVEL(()).
     61 
     62 TEST(LogHygieneTest, WorksForQualifiedSeverity) {
     63  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     64 
     65  ::testing::InSequence seq;
     66  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "To INFO"));
     67  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "To WARNING"));
     68  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "To ERROR"));
     69 
     70  test_sink.StartCapturingLogs();
     71  // Note that LOG(LEVEL()) expects the severity as a run-time
     72  // expression (as opposed to a compile-time constant).  Hence we
     73  // test that :: is allowed before INFO, etc.
     74  LOG(LEVEL(absl::LogSeverity::kInfo)) << "To INFO";
     75  LOG(LEVEL(absl::LogSeverity::kWarning)) << "To WARNING";
     76  LOG(LEVEL(absl::LogSeverity::kError)) << "To ERROR";
     77 }
     78 
     79 TEST(LogHygieneTest, WorksWithAlternativeINFOSymbol) {
     80  const double INFO ABSL_ATTRIBUTE_UNUSED = 7.77;
     81  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     82 
     83  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"));
     84 
     85  test_sink.StartCapturingLogs();
     86  LOG(INFO) << "Hello world";
     87 }
     88 
     89 TEST(LogHygieneTest, WorksWithAlternativeWARNINGSymbol) {
     90  const double WARNING ABSL_ATTRIBUTE_UNUSED = 7.77;
     91  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     92 
     93  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "Hello world"));
     94 
     95  test_sink.StartCapturingLogs();
     96  LOG(WARNING) << "Hello world";
     97 }
     98 
     99 TEST(LogHygieneTest, WorksWithAlternativeERRORSymbol) {
    100  const double ERROR ABSL_ATTRIBUTE_UNUSED = 7.77;
    101  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    102 
    103  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
    104 
    105  test_sink.StartCapturingLogs();
    106  LOG(ERROR) << "Hello world";
    107 }
    108 
    109 TEST(LogHygieneTest, WorksWithAlternativeLEVELSymbol) {
    110  const double LEVEL ABSL_ATTRIBUTE_UNUSED = 7.77;
    111  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    112 
    113  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
    114 
    115  test_sink.StartCapturingLogs();
    116  LOG(LEVEL(absl::LogSeverity::kError)) << "Hello world";
    117 }
    118 
    119 #define INFO Bogus
    120 #ifdef NDEBUG
    121 constexpr bool IsOptimized = false;
    122 #else
    123 constexpr bool IsOptimized = true;
    124 #endif
    125 
    126 TEST(LogHygieneTest, WorksWithINFODefined) {
    127  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    128 
    129  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
    130      .Times(2 + (IsOptimized ? 2 : 0));
    131 
    132  test_sink.StartCapturingLogs();
    133  LOG(INFO) << "Hello world";
    134  LOG_IF(INFO, true) << "Hello world";
    135 
    136  DLOG(INFO) << "Hello world";
    137  DLOG_IF(INFO, true) << "Hello world";
    138 }
    139 
    140 #undef INFO
    141 
    142 #define _INFO Bogus
    143 TEST(LogHygieneTest, WorksWithUnderscoreINFODefined) {
    144  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    145 
    146  EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
    147      .Times(2 + (IsOptimized ? 2 : 0));
    148 
    149  test_sink.StartCapturingLogs();
    150  LOG(INFO) << "Hello world";
    151  LOG_IF(INFO, true) << "Hello world";
    152 
    153  DLOG(INFO) << "Hello world";
    154  DLOG_IF(INFO, true) << "Hello world";
    155 }
    156 #undef _INFO
    157 
    158 TEST(LogHygieneTest, ExpressionEvaluationInLEVELSeverity) {
    159  auto i = static_cast<int>(absl::LogSeverity::kInfo);
    160  LOG(LEVEL(++i)) << "hello world";  // NOLINT
    161  EXPECT_THAT(i, Eq(static_cast<int>(absl::LogSeverity::kInfo) + 1));
    162 }
    163 
    164 TEST(LogHygieneTest, ExpressionEvaluationInStreamedMessage) {
    165  int i = 0;
    166  LOG(INFO) << ++i;
    167  EXPECT_THAT(i, 1);
    168  LOG_IF(INFO, false) << ++i;
    169  EXPECT_THAT(i, 1);
    170 }
    171 
    172 // Tests that macros are usable in unbraced switch statements.
    173 // -----------------------------------------------------------
    174 
    175 class UnbracedSwitchCompileTest {
    176  static void Log() {
    177    switch (0) {
    178      case 0:
    179        LOG(INFO);
    180        break;
    181      default:
    182        break;
    183    }
    184  }
    185 };
    186 
    187 }  // namespace