logging: improve the AsyncFileWriter flush test()
[folly.git] / folly / experimental / logging / test / XlogTest.cpp
1 /*
2  * Copyright 2004-present Facebook, Inc.
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  *   http://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 <folly/experimental/logging/LogCategory.h>
17 #include <folly/experimental/logging/LogHandler.h>
18 #include <folly/experimental/logging/LogMessage.h>
19 #include <folly/experimental/logging/LoggerDB.h>
20 #include <folly/experimental/logging/test/TestLogHandler.h>
21 #include <folly/experimental/logging/test/XlogHeader1.h>
22 #include <folly/experimental/logging/test/XlogHeader2.h>
23 #include <folly/experimental/logging/xlog.h>
24 #include <folly/portability/GTest.h>
25 #include <folly/test/TestUtils.h>
26
27 using namespace folly;
28 using std::make_shared;
29
30 XLOG_SET_CATEGORY_NAME("xlog_test.main_file");
31
32 // Note that the XLOG* macros always use the main LoggerDB singleton.
33 // There is no way to get them to use a test LoggerDB during unit tests.
34 //
35 // Therefore any configuration we do here affects the main log category
36 // settings for the entire program.  Fortunately all of the other unit tests do
37 // use testing LoggerDB objects.
38
39 TEST(Xlog, xlogName) {
40   EXPECT_EQ("xlog_test.main_file", XLOG_GET_CATEGORY_NAME());
41   EXPECT_EQ("xlog_test.main_file", XLOG_GET_CATEGORY()->getName());
42 }
43
44 TEST(Xlog, xlog) {
45   auto handler = make_shared<TestLogHandler>();
46   LoggerDB::get()->getCategory("xlog_test")->addHandler(handler);
47   auto& messages = handler->getMessages();
48
49   // info messages are not enabled initially.
50   EXPECT_FALSE(XLOG_IS_ON(INFO));
51   EXPECT_TRUE(XLOG_IS_ON(ERR));
52   XLOG(INFO, "testing 1");
53   EXPECT_EQ(0, messages.size());
54   messages.clear();
55
56   // Increase the log level, then log a message.
57   LoggerDB::get()->setLevel("xlog_test.main_file", LogLevel::DBG1);
58
59   XLOG(DBG1, "testing: ", 1, 2, 3);
60   ASSERT_EQ(1, messages.size());
61   EXPECT_EQ("testing: 123", messages[0].first.getMessage());
62   EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
63       << "unexpected file name: " << messages[0].first.getFileName();
64   EXPECT_EQ(LogLevel::DBG1, messages[0].first.getLevel());
65   EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
66   EXPECT_EQ("xlog_test", messages[0].second->getName());
67   messages.clear();
68
69   XLOGF(WARN, "number: {:>3d}; string: {}", 12, "foo");
70   ASSERT_EQ(1, messages.size());
71   EXPECT_EQ("number:  12; string: foo", messages[0].first.getMessage());
72   EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
73       << "unexpected file name: " << messages[0].first.getFileName();
74   EXPECT_EQ(LogLevel::WARN, messages[0].first.getLevel());
75   EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
76   EXPECT_EQ("xlog_test", messages[0].second->getName());
77   messages.clear();
78
79   XLOG(DBG2, "this log check should not pass");
80   EXPECT_EQ(0, messages.size());
81   messages.clear();
82
83   // Test stream arguments to XLOG()
84   XLOG(INFO) << "stream test: " << 1 << ", two, " << 3;
85   ASSERT_EQ(1, messages.size());
86   EXPECT_EQ("stream test: 1, two, 3", messages[0].first.getMessage());
87   EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
88       << "unexpected file name: " << messages[0].first.getFileName();
89   EXPECT_EQ(LogLevel::INFO, messages[0].first.getLevel());
90   EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
91   EXPECT_EQ("xlog_test", messages[0].second->getName());
92   messages.clear();
93 }
94
95 TEST(Xlog, perFileCategoryHandling) {
96   using namespace logging_test;
97
98   auto handler = make_shared<TestLogHandler>();
99   LoggerDB::get()
100       ->getCategory("folly.experimental.logging.test")
101       ->addHandler(handler);
102   LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::DBG9);
103   auto& messages = handler->getMessages();
104
105   // Use the simple helper function in XlogHeader2
106   testXlogHdrFunction("factor", 99);
107   ASSERT_EQ(1, messages.size());
108   EXPECT_EQ("test: factor=99", messages[0].first.getMessage());
109   EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogHeader2.h"))
110       << "unexpected file name: " << messages[0].first.getFileName();
111   EXPECT_EQ(LogLevel::DBG3, messages[0].first.getLevel());
112   EXPECT_EQ(
113       "folly.experimental.logging.test.XlogHeader2",
114       messages[0].first.getCategory()->getName());
115   EXPECT_EQ("folly.experimental.logging.test", messages[0].second->getName());
116   messages.clear();
117
118   // Test the loop function from XlogHeader1
119   testXlogHdrLoop(3, "hello world");
120   ASSERT_EQ(5, messages.size());
121   EXPECT_EQ("starting: hello world", messages[0].first.getMessage());
122   EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogHeader1.h"))
123       << "unexpected file name: " << messages[0].first.getFileName();
124   EXPECT_EQ(LogLevel::DBG1, messages[0].first.getLevel());
125   EXPECT_EQ(
126       "folly.experimental.logging.test.XlogHeader1",
127       messages[0].first.getCategory()->getName());
128   EXPECT_EQ("folly.experimental.logging.test", messages[0].second->getName());
129
130   EXPECT_EQ("test: hello world", messages[1].first.getMessage());
131   EXPECT_EQ("test: hello world", messages[2].first.getMessage());
132   EXPECT_EQ("test: hello world", messages[3].first.getMessage());
133   EXPECT_EQ("finished: hello world", messages[4].first.getMessage());
134   EXPECT_EQ(LogLevel::DBG5, messages[1].first.getLevel());
135   EXPECT_EQ(LogLevel::DBG5, messages[2].first.getLevel());
136   EXPECT_EQ(LogLevel::DBG5, messages[3].first.getLevel());
137   EXPECT_EQ(LogLevel::DBG1, messages[4].first.getLevel());
138   messages.clear();
139
140   // Reduce the log level so that the messages inside the loop
141   // should not be logged.
142   LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::DBG2);
143   testXlogHdrLoop(300, "hello world");
144   ASSERT_EQ(2, messages.size());
145   EXPECT_EQ("starting: hello world", messages[0].first.getMessage());
146   EXPECT_EQ("finished: hello world", messages[1].first.getMessage());
147   messages.clear();
148
149   // Call the helpers function in XlogFile1.cpp and XlogFile2.cpp and makes
150   // sure their categories are reported correctly.
151   testXlogFile1Dbg1("foobar 1234");
152   ASSERT_EQ(1, messages.size());
153   EXPECT_EQ("file1: foobar 1234", messages[0].first.getMessage());
154   EXPECT_EQ(
155       "folly.experimental.logging.test.XlogFile1",
156       messages[0].first.getCategory()->getName());
157   messages.clear();
158
159   testXlogFile2Dbg1("hello world");
160   ASSERT_EQ(1, messages.size());
161   EXPECT_EQ("file2: hello world", messages[0].first.getMessage());
162   EXPECT_EQ(
163       "folly.experimental.logging.test.XlogFile2",
164       messages[0].first.getCategory()->getName());
165   messages.clear();
166
167   // Adjust the log level and make sure the changes take effect for the .cpp
168   // file categories
169   LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::INFO);
170   testXlogFile1Dbg1("log check should fail now");
171   testXlogFile2Dbg1("this should fail too");
172   EXPECT_EQ(0, messages.size());
173   messages.clear();
174
175   LoggerDB::get()->setLevel(
176       "folly.experimental.logging.test.XlogFile1", LogLevel::DBG1);
177   testXlogFile1Dbg1("this log check should pass now");
178   testXlogFile2Dbg1("but this one should still fail");
179   ASSERT_EQ(1, messages.size());
180   EXPECT_EQ(
181       "file1: this log check should pass now", messages[0].first.getMessage());
182   EXPECT_EQ(
183       "folly.experimental.logging.test.XlogFile1",
184       messages[0].first.getCategory()->getName());
185   messages.clear();
186 }