blob: f47b5a9905c02b9922f9a7307182f797584f91ad [file] [log] [blame]
Junxiao Shi7d054272016-08-04 17:00:41 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2016 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000021
Junxiao Shi7d054272016-08-04 17:00:41 +000022#include "util/logging.hpp"
23#include "util/logger.hpp"
24
25#include "boost-test.hpp"
26#include <boost/test/output_test_stream.hpp>
27#include "../unit-test-time-fixture.hpp"
28
29namespace ndn {
30namespace util {
31namespace tests {
32
33using namespace ndn::tests;
34using boost::test_tools::output_test_stream;
35
36void
37logFromModule1();
38
39void
40logFromModule2();
41
42void
43logFromNewLogger(const std::string& moduleName)
44{
45 // clang complains -Wreturn-stack-address on OSX-10.9 if Logger is allocated on stack
46 auto loggerPtr = make_unique<Logger>(moduleName);
47 Logger& logger = *loggerPtr;
48
49 auto getNdnCxxLogger = [&logger] () -> Logger& { return logger; };
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000050 NDN_LOG_TRACE("trace" << moduleName);
51 NDN_LOG_DEBUG("debug" << moduleName);
52 NDN_LOG_INFO("info" << moduleName);
53 NDN_LOG_WARN("warn" << moduleName);
54 NDN_LOG_ERROR("error" << moduleName);
55 NDN_LOG_FATAL("fatal" << moduleName);
Junxiao Shi7d054272016-08-04 17:00:41 +000056
57 BOOST_CHECK(Logging::get().removeLogger(logger));
58}
59
60const time::system_clock::Duration LOG_SYSTIME = time::microseconds(1468108800311239LL);
61const std::string LOG_SYSTIME_STR = "1468108800.311239";
62
63class LoggingFixture : public UnitTestTimeFixture
64{
65protected:
66 explicit
67 LoggingFixture()
68 : m_oldLevels(Logging::get().getLevels())
69 , m_oldDestination(Logging::get().getDestination())
70 {
71 this->systemClock->setNow(LOG_SYSTIME);
72 Logging::get().resetLevels();
73 Logging::setDestination(os);
74 }
75
76 ~LoggingFixture()
77 {
78 Logging::setLevel(m_oldLevels);
79 Logging::setDestination(m_oldDestination);
80 }
81
82protected:
83 output_test_stream os;
84
85private:
86 std::string m_oldLevels;
87 shared_ptr<std::ostream> m_oldDestination;
88};
89
90BOOST_AUTO_TEST_SUITE(Util)
91BOOST_FIXTURE_TEST_SUITE(TestLogging, LoggingFixture)
92
93BOOST_AUTO_TEST_SUITE(Severity)
94
95BOOST_AUTO_TEST_CASE(None)
96{
97 Logging::setLevel("Module1", LogLevel::NONE);
98 logFromModule1();
99
100 Logging::flush();
101 BOOST_CHECK(os.is_equal(
102 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
103 ));
104}
105
106BOOST_AUTO_TEST_CASE(Error)
107{
108 Logging::setLevel("Module1", LogLevel::ERROR);
109 logFromModule1();
110
111 Logging::flush();
112 BOOST_CHECK(os.is_equal(
113 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
114 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
115 ));
116}
117
118BOOST_AUTO_TEST_CASE(Warn)
119{
120 Logging::setLevel("Module1", LogLevel::WARN);
121 logFromModule1();
122
123 Logging::flush();
124 BOOST_CHECK(os.is_equal(
125 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
126 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
127 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
128 ));
129}
130
131BOOST_AUTO_TEST_CASE(Info)
132{
133 Logging::setLevel("Module1", LogLevel::INFO);
134 logFromModule1();
135
136 Logging::flush();
137 BOOST_CHECK(os.is_equal(
138 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
139 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
140 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
141 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
142 ));
143}
144
145BOOST_AUTO_TEST_CASE(Debug)
146{
147 Logging::setLevel("Module1", LogLevel::DEBUG);
148 logFromModule1();
149
150 Logging::flush();
151 BOOST_CHECK(os.is_equal(
152 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
153 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
154 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
155 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
156 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
157 ));
158}
159
160BOOST_AUTO_TEST_CASE(Trace)
161{
162 Logging::setLevel("Module1", LogLevel::TRACE);
163 logFromModule1();
164
165 Logging::flush();
166 BOOST_CHECK(os.is_equal(
167 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
168 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
169 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
170 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
171 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
172 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
173 ));
174}
175
176BOOST_AUTO_TEST_CASE(All)
177{
178 Logging::setLevel("Module1", LogLevel::ALL);
179 logFromModule1();
180
181 Logging::flush();
182 BOOST_CHECK(os.is_equal(
183 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
184 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
185 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
186 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
187 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
188 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
189 ));
190}
191
192BOOST_AUTO_TEST_SUITE_END() // Severity
193
194BOOST_AUTO_TEST_CASE(SameNameLoggers)
195{
196 Logging::setLevel("Module1", LogLevel::WARN);
197 logFromModule1();
198 logFromNewLogger("Module1");
199
200 Logging::flush();
201 BOOST_CHECK(os.is_equal(
202 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
203 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
204 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
205 LOG_SYSTIME_STR + " WARNING: [Module1] warnModule1\n" +
206 LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
207 LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
208 ));
209}
210
211BOOST_AUTO_TEST_CASE(LateRegistration)
212{
213 BOOST_CHECK_NO_THROW(Logging::setLevel("Module3", LogLevel::DEBUG));
214 logFromNewLogger("Module3");
215
216 Logging::flush();
217 BOOST_CHECK(os.is_equal(
218 LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
219 LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
220 LOG_SYSTIME_STR + " WARNING: [Module3] warnModule3\n" +
221 LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
222 LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
223 ));
224}
225
226BOOST_AUTO_TEST_SUITE(DefaultSeverity)
227
228BOOST_AUTO_TEST_CASE(Unset)
229{
230 logFromModule1();
231 logFromModule2();
232
233 Logging::flush();
234 BOOST_CHECK(os.is_equal(
235 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
236 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
237 ));
238}
239
240BOOST_AUTO_TEST_CASE(NoOverride)
241{
242 Logging::setLevel("*", LogLevel::WARN);
243 logFromModule1();
244 logFromModule2();
245
246 Logging::flush();
247 BOOST_CHECK(os.is_equal(
248 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
249 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
250 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
251 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
252 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
253 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
254 ));
255}
256
257BOOST_AUTO_TEST_CASE(Override)
258{
259 Logging::setLevel("*", LogLevel::WARN);
260 Logging::setLevel("Module2", LogLevel::DEBUG);
261 logFromModule1();
262 logFromModule2();
263
264 Logging::flush();
265 BOOST_CHECK(os.is_equal(
266 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
267 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
268 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
269 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
270 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
271 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
272 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
273 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
274 ));
275}
276
277BOOST_AUTO_TEST_SUITE_END() // DefaultSeverity
278
279BOOST_AUTO_TEST_SUITE(SeverityConfig)
280
281BOOST_AUTO_TEST_CASE(SetEmpty)
282{
283 Logging::setLevel("");
284 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "");
285 logFromModule1();
286 logFromModule2();
287
288 Logging::flush();
289 BOOST_CHECK(os.is_equal(
290 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
291 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
292 ));
293}
294
295BOOST_AUTO_TEST_CASE(SetDefault)
296{
297 Logging::setLevel("*=WARN");
298 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN");
299 logFromModule1();
300 logFromModule2();
301
302 Logging::flush();
303 BOOST_CHECK(os.is_equal(
304 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
305 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
306 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
307 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
308 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
309 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
310 ));
311}
312
313BOOST_AUTO_TEST_CASE(SetModule)
314{
315 Logging::setLevel("Module1=ERROR");
316 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "Module1=ERROR");
317 logFromModule1();
318 logFromModule2();
319
320 Logging::flush();
321 BOOST_CHECK(os.is_equal(
322 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
323 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
324 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
325 ));
326}
327
328BOOST_AUTO_TEST_CASE(SetOverride)
329{
330 Logging::setLevel("*=WARN:Module2=DEBUG");
331 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN:Module2=DEBUG");
332 logFromModule1();
333 logFromModule2();
334
335 Logging::flush();
336 BOOST_CHECK(os.is_equal(
337 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
338 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
339 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
340 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
341 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
342 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
343 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
344 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
345 ));
346}
347
348BOOST_AUTO_TEST_CASE(SetTwice)
349{
350 Logging::setLevel("*=WARN");
351 Logging::setLevel("Module2=DEBUG");
352 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN:Module2=DEBUG");
353 logFromModule1();
354 logFromModule2();
355
356 Logging::flush();
357 BOOST_CHECK(os.is_equal(
358 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
359 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
360 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
361 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
362 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
363 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
364 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
365 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
366 ));
367}
368
369BOOST_AUTO_TEST_CASE(Reset)
370{
371 Logging::setLevel("Module2=DEBUG");
372 Logging::setLevel("*=ERROR");
373 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=ERROR");
374 logFromModule1();
375 logFromModule2();
376
377 Logging::flush();
378 BOOST_CHECK(os.is_equal(
379 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
380 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
381 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
382 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
383 ));
384}
385
386BOOST_AUTO_TEST_CASE(Malformed)
387{
388 BOOST_CHECK_THROW(Logging::setLevel("Module1=INVALID-LEVEL"), std::invalid_argument);
389 BOOST_CHECK_THROW(Logging::setLevel("Module1-MISSING-EQUAL-SIGN"), std::invalid_argument);
390}
391
392BOOST_AUTO_TEST_SUITE_END() // SeverityConfig
393
394BOOST_AUTO_TEST_CASE(ChangeDestination)
395{
396 logFromModule1();
397
398 auto os2 = make_shared<output_test_stream>();
399 Logging::setDestination(os2);
400 weak_ptr<output_test_stream> os2weak(os2);
401 os2.reset();
402
403 logFromModule2();
404
405 Logging::flush();
406 os2 = os2weak.lock();
407 BOOST_REQUIRE(os2 != nullptr);
408
409 BOOST_CHECK(os.is_equal(
410 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
411 ));
412 BOOST_CHECK(os2->is_equal(
413 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
414 ));
415
416 os2.reset();
417 Logging::setDestination(os);
418 BOOST_CHECK(os2weak.expired());
419}
420
421BOOST_AUTO_TEST_SUITE_END() // TestLogging
422BOOST_AUTO_TEST_SUITE_END() // Util
423
424} // namespace tests
425} // namespace util
426} // namespace ndn