proxygen
PrintfTest.cpp File Reference

Go to the source code of this file.

Functions

 TEST (PrintfTest, printfStyleMacros)
 

Function Documentation

TEST ( PrintfTest  ,
printfStyleMacros   
)

Definition at line 23 of file PrintfTest.cpp.

References ASSERT_EQ, folly::DBG, folly::DBG0, folly::DBG1, folly::DBG2, folly::DBG3, folly::DBG5, folly::DBG7, folly::DBG9, folly::ERR, EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, FB_LOGC, folly::gen::first, folly::Logger::getCategory(), handler(), i, messages, folly::LoggerDB::TESTING, XLOG_GET_CATEGORY, XLOGC, and XLOGC_IF.

23  {
24  LoggerDB db{LoggerDB::TESTING};
25  Logger logger{&db, "test"};
26  auto* category = logger.getCategory();
27 
28  auto handler = make_shared<TestLogHandler>();
29  category->addHandler(handler);
30  category->setLevel(LogLevel::DBG, true);
31 
32  Logger foo{&db, "test.foo.bar"};
33  Logger foobar{&db, "test.foo.bar"};
34  Logger footest{&db, "test.foo.test"};
35  Logger footest1234{&db, "test.foo.test.1234"};
36  Logger other{&db, "test.other"};
37  db.setLevel("test", LogLevel::ERR);
38  db.setLevel("test.foo", LogLevel::DBG2);
39  db.setLevel("test.foo.test", LogLevel::DBG7);
40 
41  auto& messages = handler->getMessages();
42 
43  // test.other's effective level should be INFO, so a DBG0
44  // message to it should be discarded
45  FB_LOGC(other, DBG0, "this should be discarded: %d", 5);
46  ASSERT_EQ(0, messages.size());
47 
48  // Disabled log messages should not evaluate their arguments
49  bool argumentEvaluated = false;
50  auto getValue = [&] {
51  argumentEvaluated = true;
52  return 5;
53  };
54  FB_LOGC(foobar, DBG3, "discarded message: %d", getValue());
55  EXPECT_FALSE(argumentEvaluated);
56 
57  FB_LOGC(foobar, DBG1, "this message should pass: %d", getValue());
58  ASSERT_EQ(1, messages.size());
59  EXPECT_EQ("this message should pass: 5", messages[0].first.getMessage());
60  EXPECT_TRUE(argumentEvaluated);
61  messages.clear();
62 
63  // The FB_LOGC() macro should work even if the format string does not contain
64  // any format sequences. Ideally people would just use FB_LOG() if they
65  // aren't actually formatting anything, but making FB_LOGC() work in this
66  // scenario still makes it easier for people to switch legacy printf-style
67  // code to FB_LOGC().
68  FB_LOGC(foobar, DBG1, "no actual format arguments");
69  ASSERT_EQ(1, messages.size());
70  EXPECT_EQ("no actual format arguments", messages[0].first.getMessage());
71  messages.clear();
72 
73  // Similar checks with XLOGC()
74  auto* xlogCategory = XLOG_GET_CATEGORY();
75  xlogCategory->addHandler(handler);
76  xlogCategory->setLevel(LogLevel::DBG5, true);
77 
78  argumentEvaluated = false;
79  XLOGC(DBG9, "failing log check: %d", getValue());
80  EXPECT_FALSE(argumentEvaluated);
81 
82  XLOGC(DBG5, "passing log: %03d", getValue());
83  ASSERT_EQ(1, messages.size());
84  EXPECT_EQ("passing log: 005", messages[0].first.getMessage());
85  EXPECT_TRUE(argumentEvaluated);
86  messages.clear();
87 
88  XLOGC(DBG1, "no xlog format arguments");
89  ASSERT_EQ(1, messages.size());
90  EXPECT_EQ("no xlog format arguments", messages[0].first.getMessage());
91  messages.clear();
92 
93  XLOGC_IF(DBG1, false, "no xlog format arguments");
94  ASSERT_EQ(0, messages.size());
95  XLOGC_IF(DBG1, true, "xlog format arguments");
96  ASSERT_EQ(1, messages.size());
97  messages.clear();
98 
99  argumentEvaluated = false;
100  XLOGC_IF(DBG1, true, "xlog format string %d", getValue());
101  ASSERT_EQ(1, messages.size());
102  EXPECT_TRUE(argumentEvaluated);
103  messages.clear();
104 
105  argumentEvaluated = false;
106  XLOGC_IF(DBG1, false, "xlog format string %d", getValue());
107  ASSERT_EQ(0, messages.size());
108  EXPECT_FALSE(argumentEvaluated);
109  messages.clear();
110 
111  // more complex conditional expressions
112  std::array<bool, 2> conds = {{false, true}};
113  for (unsigned i = 0; i < conds.size(); i++) {
114  for (unsigned j = 0; j < conds.size(); j++) {
115  argumentEvaluated = false;
116  XLOGC_IF(
117  DBG1, conds[i] && conds[j], "testing conditional %d", getValue());
118  EXPECT_EQ((conds[i] && conds[j]) ? 1 : 0, messages.size());
119  messages.clear();
120  if (conds[i] && conds[j]) {
121  EXPECT_TRUE(argumentEvaluated);
122  } else {
123  EXPECT_FALSE(argumentEvaluated);
124  }
125 
126  argumentEvaluated = false;
127  XLOGC_IF(
128  DBG1, conds[i] || conds[j], "testing conditional %d", getValue());
129  EXPECT_EQ((conds[i] || conds[j]) ? 1 : 0, messages.size());
130  messages.clear();
131  if (conds[i] || conds[j]) {
132  EXPECT_TRUE(argumentEvaluated);
133  } else {
134  EXPECT_FALSE(argumentEvaluated);
135  }
136  }
137  }
138 
139  XLOGC_IF(DBG1, 0x6 & 0x2, "More conditional 1");
140  EXPECT_EQ(1, messages.size());
141  messages.clear();
142 
143  XLOGC_IF(DBG1, 0x6 | 0x2, "More conditional 2");
144  EXPECT_EQ(1, messages.size());
145  messages.clear();
146 
147  XLOGC_IF(DBG1, 0x6 | 0x2 ? true : false, "More conditional 3");
148  EXPECT_EQ(1, messages.size());
149  messages.clear();
150 
151  XLOGC_IF(DBG1, 0x6 | 0x2 ? true : false, "More conditional 3");
152  EXPECT_EQ(1, messages.size());
153  messages.clear();
154 
155  XLOGC_IF(DBG1, 0x3 & 0x4 ? true : false, "More conditional 4");
156  EXPECT_EQ(0, messages.size());
157  messages.clear();
158 
159  XLOGC_IF(DBG1, false ? true : false, "More conditional 5");
160  EXPECT_EQ(0, messages.size());
161  messages.clear();
162 
163  // Errors attempting to format the message should not throw
164  FB_LOGC(footest1234, ERR, "width overflow: %999999999999999999999d", 5);
165  ASSERT_EQ(1, messages.size());
166  EXPECT_EQ(
167  "error formatting printf-style log message: "
168  "width overflow: %999999999999999999999d",
169  messages[0].first.getMessage());
170  messages.clear();
171 }
static struct message messages[5]
Definition: test.c:75
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define XLOGC_IF(level, cond, fmt,...)
Definition: printf.h:61
void handler(int, siginfo_t *, void *)
LogCategory * getCategory() const
Definition: Logger.h:183
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define XLOG_GET_CATEGORY()
Definition: xlog.h:286
#define XLOGC(level, fmt,...)
Definition: printf.h:50
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
#define FB_LOGC(logger, level, fmt,...)
Definition: printf.h:43
constexpr detail::First first
Definition: Base-inl.h:2553