LCOV - code coverage report
Current view: top level - test/unittests/base - logging-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 74 84 88.1 %
Date: 2017-10-20 Functions: 29 56 51.8 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cstdint>
       6             : 
       7             : #include "src/base/logging.h"
       8             : #include "src/objects.h"
       9             : #include "testing/gtest-support.h"
      10             : 
      11             : namespace v8 {
      12             : namespace base {
      13             : namespace logging_unittest {
      14             : 
      15             : namespace {
      16             : 
      17             : #define CHECK_SUCCEED(NAME, lhs, rhs)                                      \
      18             :   {                                                                        \
      19             :     std::string* error_message =                                           \
      20             :         Check##NAME##Impl<decltype(lhs), decltype(rhs)>((lhs), (rhs), ""); \
      21             :     EXPECT_EQ(nullptr, error_message);                                     \
      22             :   }
      23             : 
      24             : #define CHECK_FAIL(NAME, lhs, rhs)                                         \
      25             :   {                                                                        \
      26             :     std::string* error_message =                                           \
      27             :         Check##NAME##Impl<decltype(lhs), decltype(rhs)>((lhs), (rhs), ""); \
      28             :     EXPECT_NE(nullptr, error_message);                                     \
      29             :     delete error_message;                                                  \
      30             :   }
      31             : 
      32             : }  // namespace
      33             : 
      34       13158 : TEST(LoggingTest, CheckEQImpl) {
      35           1 :   CHECK_SUCCEED(EQ, 0.0, 0.0)
      36           1 :   CHECK_SUCCEED(EQ, 0.0, -0.0)
      37           1 :   CHECK_SUCCEED(EQ, -0.0, 0.0)
      38           1 :   CHECK_SUCCEED(EQ, -0.0, -0.0)
      39           1 : }
      40             : 
      41       13158 : TEST(LoggingTest, CompareSignedMismatch) {
      42           1 :   CHECK_SUCCEED(EQ, static_cast<int32_t>(14), static_cast<uint32_t>(14))
      43           3 :   CHECK_FAIL(EQ, static_cast<int32_t>(14), static_cast<uint32_t>(15))
      44           3 :   CHECK_FAIL(EQ, static_cast<int32_t>(-1), static_cast<uint32_t>(-1))
      45           1 :   CHECK_SUCCEED(LT, static_cast<int32_t>(-1), static_cast<uint32_t>(0))
      46           1 :   CHECK_SUCCEED(LT, static_cast<int32_t>(-1), static_cast<uint32_t>(-1))
      47           1 :   CHECK_SUCCEED(LE, static_cast<int32_t>(-1), static_cast<uint32_t>(0))
      48           1 :   CHECK_SUCCEED(LE, static_cast<int32_t>(55), static_cast<uint32_t>(55))
      49           1 :   CHECK_SUCCEED(LT, static_cast<int32_t>(55), static_cast<uint32_t>(0x7fffff00))
      50           1 :   CHECK_SUCCEED(LE, static_cast<int32_t>(55), static_cast<uint32_t>(0x7fffff00))
      51           1 :   CHECK_SUCCEED(GE, static_cast<uint32_t>(0x7fffff00), static_cast<int32_t>(55))
      52           1 :   CHECK_SUCCEED(GT, static_cast<uint32_t>(0x7fffff00), static_cast<int32_t>(55))
      53           1 :   CHECK_SUCCEED(GT, static_cast<uint32_t>(-1), static_cast<int32_t>(-1))
      54           1 :   CHECK_SUCCEED(GE, static_cast<uint32_t>(0), static_cast<int32_t>(-1))
      55           1 :   CHECK_SUCCEED(LT, static_cast<int8_t>(-1), static_cast<uint32_t>(0))
      56           1 :   CHECK_SUCCEED(GT, static_cast<uint64_t>(0x7f01010101010101), 0)
      57           1 :   CHECK_SUCCEED(LE, static_cast<int64_t>(0xff01010101010101),
      58             :                 static_cast<uint8_t>(13))
      59           1 : }
      60             : 
      61       13158 : TEST(LoggingTest, CompareAgainstStaticConstPointer) {
      62             :   // These used to produce link errors before http://crrev.com/2524093002.
      63           3 :   CHECK_FAIL(EQ, v8::internal::Smi::kZero, v8::internal::Smi::FromInt(17));
      64           1 :   CHECK_SUCCEED(GT, 0, v8::internal::Smi::kMinValue);
      65           1 : }
      66             : 
      67             : #define CHECK_BOTH(name, lhs, rhs) \
      68             :   CHECK_##name(lhs, rhs);          \
      69             :   DCHECK_##name(lhs, rhs)
      70             : 
      71             : namespace {
      72          10 : std::string FailureMessage(const char* msg, const char* debug_msg) {
      73          10 :   std::string regexp(msg);
      74             : #ifdef DEBUG
      75             :   regexp.append(" (").append(debug_msg).append(")");
      76             : #endif
      77             :   size_t last_pos = 0;
      78             :   do {
      79          20 :     size_t pos = regexp.find_first_of("(){}+*", last_pos);
      80          20 :     if (pos == std::string::npos) break;
      81          10 :     regexp.insert(pos, "\\");
      82          10 :     last_pos = pos + 2;
      83             :   } while (true);
      84          10 :   return regexp;
      85             : }
      86             : }  // namespace
      87             : 
      88       13158 : TEST(LoggingTest, CompareWithDifferentSignedness) {
      89           1 :   int32_t i32 = 10;
      90             :   uint32_t u32 = 20;
      91             :   int64_t i64 = 30;
      92           1 :   uint64_t u64 = 40;
      93             : 
      94             :   // All these checks should compile (!) and succeed.
      95           1 :   CHECK_BOTH(EQ, i32 + 10, u32);
      96           1 :   CHECK_BOTH(LT, i32, u64);
      97             :   CHECK_BOTH(LE, u32, i64);
      98             :   CHECK_BOTH(IMPLIES, i32, i64);
      99             :   CHECK_BOTH(IMPLIES, u32, i64);
     100             :   CHECK_BOTH(IMPLIES, !u32, !i64);
     101             : 
     102             :   // Check that the values are output correctly on error.
     103           4 :   ASSERT_DEATH_IF_SUPPORTED(
     104             :       ([&] { CHECK_GT(i32, u64); })(),
     105             :       FailureMessage("Check failed: i32 > u64", "10 vs. 40"));
     106             : }
     107             : 
     108       13158 : TEST(LoggingTest, CompareWithReferenceType) {
     109           1 :   int32_t i32 = 10;
     110             :   uint32_t u32 = 20;
     111             :   int64_t i64 = 30;
     112           1 :   uint64_t u64 = 40;
     113             : 
     114             :   // All these checks should compile (!) and succeed.
     115           1 :   CHECK_BOTH(EQ, i32 + 10, *&u32);
     116           1 :   CHECK_BOTH(LT, *&i32, u64);
     117             :   CHECK_BOTH(IMPLIES, *&i32, i64);
     118           1 :   CHECK_BOTH(IMPLIES, *&i32, u64);
     119             : 
     120             :   // Check that the values are output correctly on error.
     121           4 :   ASSERT_DEATH_IF_SUPPORTED(
     122             :       ([&] { CHECK_GT(*&i32, u64); })(),
     123             :       FailureMessage("Check failed: *&i32 > u64", "10 vs. 40"));
     124             : }
     125             : 
     126             : enum TestEnum1 { ONE, TWO };
     127             : enum TestEnum2 : uint16_t { FOO = 14, BAR = 5 };
     128             : enum class TestEnum3 { A, B };
     129             : enum class TestEnum4 : uint8_t { FIRST, SECOND };
     130             : 
     131       13158 : TEST(LoggingTest, CompareEnumTypes) {
     132             :   // All these checks should compile (!) and succeed.
     133             :   CHECK_BOTH(EQ, ONE, ONE);
     134             :   CHECK_BOTH(LT, ONE, TWO);
     135             :   CHECK_BOTH(EQ, BAR, 5);
     136             :   CHECK_BOTH(LT, BAR, FOO);
     137             :   CHECK_BOTH(EQ, TestEnum3::A, TestEnum3::A);
     138             :   CHECK_BOTH(LT, TestEnum3::A, TestEnum3::B);
     139             :   CHECK_BOTH(EQ, TestEnum4::FIRST, TestEnum4::FIRST);
     140             :   CHECK_BOTH(LT, TestEnum4::FIRST, TestEnum4::SECOND);
     141           1 : }
     142             : 
     143             : class TestClass1 {
     144             :  public:
     145           1 :   bool operator==(const TestClass1&) const { return true; }
     146           0 :   bool operator!=(const TestClass1&) const { return false; }
     147             : };
     148             : class TestClass2 {
     149             :  public:
     150           1 :   explicit TestClass2(int val) : val_(val) {}
     151           1 :   bool operator<(const TestClass2& other) const { return val_ < other.val_; }
     152           0 :   int val() const { return val_; }
     153             : 
     154             :  private:
     155             :   int val_;
     156             : };
     157           0 : std::ostream& operator<<(std::ostream& str, const TestClass2& val) {
     158           0 :   return str << "TestClass2(" << val.val() << ")";
     159             : }
     160             : 
     161       13158 : TEST(LoggingTest, CompareClassTypes) {
     162             :   // All these checks should compile (!) and succeed.
     163           1 :   CHECK_BOTH(EQ, TestClass1{}, TestClass1{});
     164           1 :   CHECK_BOTH(LT, TestClass2{2}, TestClass2{7});
     165             : 
     166             :   // Check that the values are output correctly on error.
     167           4 :   ASSERT_DEATH_IF_SUPPORTED(
     168             :       ([&] { CHECK_NE(TestClass1{}, TestClass1{}); })(),
     169             :       FailureMessage("Check failed: TestClass1{} != TestClass1{}",
     170             :                      "<unprintable> vs. <unprintable>"));
     171           5 :   ASSERT_DEATH_IF_SUPPORTED(
     172             :       ([&] { CHECK_LT(TestClass2{4}, TestClass2{3}); })(),
     173             :       FailureMessage("Check failed: TestClass2{4} < TestClass2{3}",
     174             :                      "TestClass2(4) vs. TestClass2(3)"));
     175             : }
     176             : 
     177       13158 : TEST(LoggingDeathTest, OutputEnumValues) {
     178           4 :   ASSERT_DEATH_IF_SUPPORTED(
     179             :       ([&] { CHECK_EQ(ONE, TWO); })(),
     180             :       FailureMessage("Check failed: ONE == TWO", "0 vs. 1"));
     181           5 :   ASSERT_DEATH_IF_SUPPORTED(
     182             :       ([&] { CHECK_NE(BAR, 2 + 3); })(),
     183             :       FailureMessage("Check failed: BAR != 2 + 3", "5 vs. 5"));
     184           5 :   ASSERT_DEATH_IF_SUPPORTED(
     185             :       ([&] { CHECK_EQ(TestEnum3::A, TestEnum3::B); })(),
     186             :       FailureMessage("Check failed: TestEnum3::A == TestEnum3::B", "0 vs. 1"));
     187           5 :   ASSERT_DEATH_IF_SUPPORTED(
     188             :       ([&] { CHECK_GE(TestEnum4::FIRST, TestEnum4::SECOND); })(),
     189             :       FailureMessage("Check failed: TestEnum4::FIRST >= TestEnum4::SECOND",
     190             :                      "0 vs. 1"));
     191             : }
     192             : 
     193             : enum TestEnum5 { TEST_A, TEST_B };
     194             : enum class TestEnum6 { TEST_C, TEST_D };
     195           0 : std::ostream& operator<<(std::ostream& str, TestEnum5 val) {
     196           0 :   return str << (val == TEST_A ? "A" : "B");
     197             : }
     198           0 : void operator<<(std::ostream& str, TestEnum6 val) {
     199           0 :   str << (val == TestEnum6::TEST_C ? "C" : "D");
     200           0 : }
     201             : 
     202       13158 : TEST(LoggingDeathTest, OutputEnumWithOutputOperator) {
     203           4 :   ASSERT_DEATH_IF_SUPPORTED(
     204             :       ([&] { CHECK_EQ(TEST_A, TEST_B); })(),
     205             :       FailureMessage("Check failed: TEST_A == TEST_B", "A vs. B"));
     206           5 :   ASSERT_DEATH_IF_SUPPORTED(
     207             :       ([&] { CHECK_GE(TestEnum6::TEST_C, TestEnum6::TEST_D); })(),
     208             :       FailureMessage("Check failed: TestEnum6::TEST_C >= TestEnum6::TEST_D",
     209             :                      "C vs. D"));
     210             : }
     211             : 
     212       13158 : TEST(LoggingDeathTest, FatalKills) {
     213           4 :   ASSERT_DEATH_IF_SUPPORTED(FATAL("Dread pirate"), "Dread pirate");
     214             : }
     215             : 
     216       13158 : TEST(LoggingDeathTest, DcheckIsOnlyFatalInDebug) {
     217             : #ifdef DEBUG
     218             :   ASSERT_DEATH_IF_SUPPORTED(DCHECK(false && "Dread pirate"), "Dread pirate");
     219             : #else
     220             :   // DCHECK should be non-fatal if DEBUG is undefined.
     221             :   DCHECK(false && "I'm a benign teapot");
     222             : #endif
     223           1 : }
     224             : 
     225             : namespace {
     226           0 : void DcheckOverrideFunction(const char*, int, const char*) {}
     227             : }  // namespace
     228             : 
     229       13158 : TEST(LoggingDeathTest, V8_DcheckCanBeOverridden) {
     230             :   // Default DCHECK state should be fatal.
     231           4 :   ASSERT_DEATH_IF_SUPPORTED(V8_Dcheck(__FILE__, __LINE__, "Dread pirate"),
     232             :                             "Dread pirate");
     233             : 
     234           4 :   ASSERT_DEATH_IF_SUPPORTED(
     235             :       {
     236             :         v8::base::SetDcheckFunction(&DcheckOverrideFunction);
     237             :         // This should be non-fatal.
     238             :         V8_Dcheck(__FILE__, __LINE__, "I'm a benign teapot.");
     239             : 
     240             :         // Restore default behavior, and assert on lethality.
     241             :         v8::base::SetDcheckFunction(nullptr);
     242             :         V8_Dcheck(__FILE__, __LINE__, "Dread pirate");
     243             :       },
     244             :       "Dread pirate");
     245             : }
     246             : 
     247             : }  // namespace logging_unittest
     248             : }  // namespace base
     249        7893 : }  // namespace v8

Generated by: LCOV version 1.10