brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · 4df5a80 Raw
328 lines · cpp
1//===- llvm/unittest/Support/DebugLogTest.cpp -----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/DebugLog.h"10#include "llvm/ADT/Sequence.h"11#include "llvm/Support/raw_ostream.h"12#include "gmock/gmock.h"13#include "gtest/gtest.h"14 15#include <string>16using namespace llvm;17using testing::Eq;18using testing::HasSubstr;19 20#ifndef NDEBUG21TEST(DebugLogTest, Basic) {22  llvm::DebugFlag = true;23  static const char *DT[] = {"A", "B"};24 25  // Clear debug types.26  setCurrentDebugTypes(DT, 0);27  {28    std::string str;29    raw_string_ostream os(str);30    LDGB_STREAM_LEVEL_AND_TYPE(os, "", 0) << "NoType";31    EXPECT_TRUE(StringRef(os.str()).starts_with('['));32    EXPECT_TRUE(StringRef(os.str()).ends_with("NoType\n"));33  }34 35  setCurrentDebugTypes(DT, 2);36  {37    std::string str;38    raw_string_ostream os(str);39    LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "A") << "A";40    LDGB_STREAM_LEVEL_AND_TYPE(os, "B", 0) << "B";41    EXPECT_TRUE(StringRef(os.str()).starts_with('['));42    EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n")));43  }44 45  setCurrentDebugType("A");46  {47    std::string str;48    raw_string_ostream os(str);49    // Just check that the macro doesn't result in dangling else.50    if (true)51      LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "A") << "A";52    else53      LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "A") << "B";54    LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "B") << "B";55    EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), Not(HasSubstr("B\n"))));56 57    int count = 0;58    auto inc = [&]() { return ++count; };59    EXPECT_THAT(count, Eq(0));60    LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "A") << inc();61    EXPECT_THAT(count, Eq(1));62    LDGB_STREAM_LEVEL_AND_TYPE(os, 0, "B") << inc();63    EXPECT_THAT(count, Eq(1));64  }65}66 67TEST(DebugLogTest, BasicWithLevel) {68  llvm::DebugFlag = true;69  // We expect A to be always printed, B to be printed only when level is 1 or70  // below, and C to be printed only when level is 0 or below.71  static const char *DT[] = {"A", "B:1", "C:"};72 73  setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0]));74  std::string str;75  raw_string_ostream os(str);76  for (auto type : {"A", "B", "C", "D"})77    for (int level : llvm::seq<int>(0, 4))78      LDBG_STREAM_LEVEL_TYPE_FILE_AND_LINE(os, level, type, type, level)79          << level;80  EXPECT_EQ(os.str(), "[A:0 0] 0\n[A:1 1] 1\n[A:2 2] 2\n[A:3 3] 3\n[B:0 0] "81                      "0\n[B:1 1] 1\n[C:0 0] 0\n");82}83 84TEST(DebugLogTest, NegativeLevel) {85  llvm::DebugFlag = true;86  // Test the special behavior when all the levels are 0.87  // In this case we expect all the debug types to be printed.88  static const char *DT[] = {"A:"};89 90  setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0]));91  std::string str;92  raw_string_ostream os(str);93  for (auto type : {"A", "B"})94    for (int level : llvm::seq<int>(0, 2))95      LDBG_STREAM_LEVEL_TYPE_FILE_AND_LINE(96          os, level, type, (std::string(type) + ".cpp").c_str(), level)97          << level;98  EXPECT_EQ(os.str(), "[A A.cpp:0 0] 0\n[B B.cpp:0 0] 0\n[B B.cpp:1 1] 1\n");99}100 101TEST(DebugLogTest, StreamPrefix) {102  llvm::DebugFlag = true;103  static const char *DT[] = {"A", "B"};104  setCurrentDebugTypes(DT, 2);105 106  std::string str;107  raw_string_ostream os(str);108  std::string expected = "PrefixA 1\nPrefixA 2\nPrefixA \nPrefixB "109                         "3\nPrefixB 4\nPrefixA 5";110  {111    llvm::impl::raw_ldbg_ostream ldbg_osB("PrefixB ", os);112    llvm::impl::raw_ldbg_ostream ldbg_osA("PrefixA ", os);113    ldbg_osA << "1\n2";114    ldbg_osA << "\n\n";115    ldbg_osB << "3\n4\n";116    ldbg_osA << "5";117    EXPECT_EQ(os.str(), expected);118  }119  EXPECT_EQ(os.str(), expected);120}121 122TEST(DebugLogTest, DestructorPrefix) {123  llvm::DebugFlag = true;124  std::string str;125  raw_string_ostream os(str);126  {127    llvm::impl::raw_ldbg_ostream ldbg_osB("PrefixB ", os);128  }129  // After destructors, nothing should have been printed.130  EXPECT_EQ(os.str(), "");131}132 133TEST(DebugLogTest, LDBG_MACROS) {134  llvm::DebugFlag = true;135  static const char *DT[] = {"A:3", "B:2"};136  setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0]));137  std::string Str;138  raw_string_ostream DebugOs(Str);139  std::string StrExpected;140  raw_string_ostream ExpectedOs(StrExpected);141#undef LDBG_STREAM142#define LDBG_STREAM DebugOs143#define DEBUG_TYPE "A"144  LDBG() << "Hello, world!";145  ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)146             << " 1] Hello, world!\n";147  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());148  Str.clear();149  StrExpected.clear();150 151  // Test with a level, no type.152  LDBG(2) << "Hello, world!";153  ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)154             << " 2] Hello, world!\n";155  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());156  Str.clear();157  StrExpected.clear();158 159// Now check when we don't use DEBUG_TYPE, the file name is implicitly used160// instead.161#undef DEBUG_TYPE162 163  // Repeat the tests above, they won't match since the debug types defined164  // above don't match the file name.165  LDBG() << "Hello, world!";166  EXPECT_EQ(DebugOs.str(), "");167  Str.clear();168  StrExpected.clear();169 170  // Test with a level, no type.171  LDBG(2) << "Hello, world!";172  EXPECT_EQ(DebugOs.str(), "");173  Str.clear();174  StrExpected.clear();175 176  // Now enable the debug types that match the file name.177  auto fileNameAndLevel = std::string(__LLVM_FILE_NAME__) + ":3";178  static const char *DT2[] = {fileNameAndLevel.c_str(), "B:2"};179  setCurrentDebugTypes(DT2, sizeof(DT2) / sizeof(DT2[0]));180 181  // Repeat the tests above, they should match now.182 183  LDBG() << "Hello, world!";184  ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)185             << " 1] Hello, world!\n";186  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());187  Str.clear();188  StrExpected.clear();189 190  // Test with a level, no type.191  LDBG(2) << "Hello, world!";192  ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)193             << " 2] Hello, world!\n";194  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());195  Str.clear();196  StrExpected.clear();197 198  // Test with a type199  LDBG("B") << "Hello, world!";200  ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)201             << " 1] Hello, world!\n";202  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());203  Str.clear();204  StrExpected.clear();205 206  // Test with a type and a level207  LDBG("B", 2) << "Hello, world!";208  ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)209             << " 2] Hello, world!\n";210  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());211  Str.clear();212  StrExpected.clear();213 214  // Test with a type not enabled.215  LDBG("C", 1) << "Hello, world!";216  EXPECT_EQ(DebugOs.str(), "");217 218  // Test with a level not enabled.219  LDBG("B", 3) << "Hello, world!";220  EXPECT_EQ(DebugOs.str(), "");221  LDBG(__LLVM_FILE_NAME__, 4) << "Hello, world!";222  EXPECT_EQ(DebugOs.str(), "");223}224 225TEST(DebugLogTest, LDBG_OS_MACROS) {226  llvm::DebugFlag = true;227  static const char *DT[] = {"A:3", "B:2"};228  setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0]));229  std::string Str;230  raw_string_ostream DebugOs(Str);231  std::string StrExpected;232  raw_string_ostream ExpectedOs(StrExpected);233#undef LDBG_STREAM234#define LDBG_STREAM DebugOs235#define DEBUG_TYPE "A"236  LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });237  ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)238             << " 1] Hello, world!\n";239  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());240  Str.clear();241  StrExpected.clear();242 243  // Test with a level, no type.244  LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });245  ExpectedOs << "[A " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)246             << " 2] Hello, world!\n";247  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());248  Str.clear();249  StrExpected.clear();250 251// Now check when we don't use DEBUG_TYPE, the file name is implicitly used252// instead.253#undef DEBUG_TYPE254 255  // Repeat the tests above, they won't match since the debug types defined256  // above don't match the file name.257  LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });258  EXPECT_EQ(DebugOs.str(), "");259  Str.clear();260  StrExpected.clear();261 262  // Test with a level, no type.263  LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });264  EXPECT_EQ(DebugOs.str(), "");265  Str.clear();266  StrExpected.clear();267 268  // Now enable the debug types that match the file name.269  auto fileNameAndLevel = std::string(__LLVM_FILE_NAME__) + ":3";270  static const char *DT2[] = {fileNameAndLevel.c_str(), "B:2"};271  setCurrentDebugTypes(DT2, sizeof(DT2) / sizeof(DT2[0]));272 273  // Repeat the tests above, they should match now.274  LDBG_OS([](raw_ostream &Os) { Os << "Hello, world!"; });275  ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)276             << " 1] Hello, world!\n";277  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());278  Str.clear();279  StrExpected.clear();280 281  // Test with a level, no type.282  LDBG_OS(2, [](raw_ostream &Os) { Os << "Hello, world!"; });283  ExpectedOs << "[" << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)284             << " 2] Hello, world!\n";285  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());286  Str.clear();287  StrExpected.clear();288 289  // Test with a type.290  LDBG_OS("B", [](raw_ostream &Os) { Os << "Hello, world!"; });291  ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)292             << " 1] Hello, world!\n";293  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());294  Str.clear();295  StrExpected.clear();296 297  // Test with a type and a level298  LDBG_OS("B", 2, [](raw_ostream &Os) { Os << "Hello, world!"; });299  ExpectedOs << "[B " << __LLVM_FILE_NAME__ << ":" << (__LINE__ - 1)300             << " 2] Hello, world!\n";301  EXPECT_EQ(DebugOs.str(), ExpectedOs.str());302  Str.clear();303  StrExpected.clear();304 305  // Test with a type not enabled.306  LDBG_OS("C", 1, [](raw_ostream &Os) { Os << "Hello, world!"; });307  EXPECT_EQ(DebugOs.str(), "");308 309  // Test with a level not enabled.310  LDBG_OS("B", 3, [](raw_ostream &Os) { Os << "Hello, world!"; });311  EXPECT_EQ(DebugOs.str(), "");312}313 314#else315TEST(DebugLogTest, Basic) {316  // LDBG should be compiled out in NDEBUG, so just check it compiles and has317  // no effect.318  llvm::DebugFlag = true;319  static const char *DT[] = {"A"};320  setCurrentDebugTypes(DT, 0);321  int count = 0;322  auto inc = [&]() { return ++count; };323  EXPECT_THAT(count, Eq(0));324  LDBG() << inc();325  EXPECT_THAT(count, Eq(0));326}327#endif328