blob: 24ae88b9b9739e1e248a28fb7c43057d63388a60 [file] [log] [blame]
Junxiao Shi7d054272016-08-04 17:00:41 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
dmcoomese062a182017-06-12 11:10:31 -05002/*
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -05003 * Copyright (c) 2013-2020 Regents of the University of California.
Junxiao Shi7d054272016-08-04 17:00:41 +00004 *
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
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/util/logging.hpp"
23#include "ndn-cxx/util/logger.hpp"
Junxiao Shi7d054272016-08-04 17:00:41 +000024
Davide Pesavento7e780642018-11-24 15:51:34 -050025#include "tests/boost-test.hpp"
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050026#include "tests/unit/clock-fixture.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050027
Davide Pesavento21a4ea52019-12-22 13:35:37 -050028#if BOOST_VERSION >= 105900
29#include <boost/test/tools/output_test_stream.hpp>
30#else
Davide Pesavento7e780642018-11-24 15:51:34 -050031#include <boost/test/output_test_stream.hpp>
Davide Pesavento21a4ea52019-12-22 13:35:37 -050032#endif
Junxiao Shi7d054272016-08-04 17:00:41 +000033
34namespace ndn {
35namespace util {
36namespace tests {
37
Alexander Afanasyev354f3822017-03-27 15:26:41 -050038NDN_LOG_INIT(ndn.util.tests.Logging);
39
Junxiao Shi7d054272016-08-04 17:00:41 +000040void
41logFromModule1();
42
43void
44logFromModule2();
45
46void
dmcoomese062a182017-06-12 11:10:31 -050047logFromFilterModule();
48
49static void
Davide Pesavento1c9c96c2018-04-25 10:45:08 -040050logFromNewLogger(const char* moduleName)
Junxiao Shi7d054272016-08-04 17:00:41 +000051{
Davide Pesavento0c145ec2018-04-10 21:33:57 -040052 Logger logger(moduleName);
53 auto ndn_cxx_getLogger = [&logger] () -> Logger& { return logger; };
Junxiao Shi7d054272016-08-04 17:00:41 +000054
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000055 NDN_LOG_TRACE("trace" << moduleName);
56 NDN_LOG_DEBUG("debug" << moduleName);
57 NDN_LOG_INFO("info" << moduleName);
58 NDN_LOG_WARN("warn" << moduleName);
59 NDN_LOG_ERROR("error" << moduleName);
60 NDN_LOG_FATAL("fatal" << moduleName);
Junxiao Shi7d054272016-08-04 17:00:41 +000061
62 BOOST_CHECK(Logging::get().removeLogger(logger));
63}
64
Davide Pesavento0c145ec2018-04-10 21:33:57 -040065namespace ns1 {
Junxiao Shi7d054272016-08-04 17:00:41 +000066
Davide Pesavento0c145ec2018-04-10 21:33:57 -040067NDN_LOG_INIT(ndn.util.tests.ns1);
68
69static void
70logFromNamespace1()
71{
72 NDN_LOG_INFO("hello world from ns1");
73}
74
75} // namespace ns1
76
77namespace ns2 {
78
79NDN_LOG_INIT(ndn.util.tests.ns2);
80
81static void
82logFromNamespace2()
83{
84 NDN_LOG_INFO("hi there from ns2");
85}
86
87} // namespace ns2
88
89class ClassWithLogger
90{
91public:
92 void
93 logFromConstMemberFunction() const
94 {
95 NDN_LOG_INFO("const member function");
96 }
97
98 static void
99 logFromStaticMemberFunction()
100 {
101 NDN_LOG_INFO("static member function");
102 }
103
104private:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400105 NDN_LOG_MEMBER_DECL();
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400106};
107
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400108NDN_LOG_MEMBER_INIT(ClassWithLogger, ndn.util.tests.ClassWithLogger);
109
Davide Pesavento39cb4022019-11-24 21:15:02 -0500110class AbstractClassWithLogger
111{
112public:
113 virtual
114 ~AbstractClassWithLogger() = default;
115
116 void
117 logFromConstMemberFunction() const
118 {
119 NDN_LOG_INFO("const member function");
120 }
121
122 virtual void
123 logFromVirtualFunction() = 0;
124
125protected:
126 NDN_LOG_MEMBER_DECL();
127};
128
129// Check that the macro can cope with abstract types
130NDN_LOG_MEMBER_INIT(AbstractClassWithLogger, ndn.util.tests.AbstractClassWithLogger);
131
132class DerivedClass : public AbstractClassWithLogger
133{
134public:
135 void
136 logFromVirtualFunction() final
137 {
138 NDN_LOG_INFO("overridden virtual function");
139 }
140};
141
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400142template<class T, class U>
143class ClassTemplateWithLogger
144{
145public:
146 void
147 logFromMemberFunction()
148 {
149 NDN_LOG_INFO("class template non-static member function");
150 }
151
152 static void
153 logFromStaticMemberFunction()
154 {
155 NDN_LOG_INFO("class template static member function");
156 }
157
158private:
159 NDN_LOG_MEMBER_DECL();
160};
161
162// Technically this declaration is not necessary in this case,
163// but we want to test that the macro expands to well-formed code
164NDN_LOG_MEMBER_DECL_SPECIALIZED((ClassTemplateWithLogger<int, double>));
165
166NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, double>), ndn.util.tests.Specialized1);
167NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, std::string>), ndn.util.tests.Specialized2);
168
169const time::microseconds LOG_SYSTIME(1468108800311239LL);
170const std::string LOG_SYSTIME_STR("1468108800.311239");
171
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500172class LoggingFixture : public ndn::tests::ClockFixture
Junxiao Shi7d054272016-08-04 17:00:41 +0000173{
174protected:
Junxiao Shi7d054272016-08-04 17:00:41 +0000175 LoggingFixture()
dmcoomese062a182017-06-12 11:10:31 -0500176 : m_oldEnabledLevel(Logging::get().getLevels())
Junxiao Shi7d054272016-08-04 17:00:41 +0000177 , m_oldDestination(Logging::get().getDestination())
178 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500179 m_systemClock->setNow(LOG_SYSTIME);
Junxiao Shi7d054272016-08-04 17:00:41 +0000180 Logging::get().resetLevels();
181 Logging::setDestination(os);
182 }
183
184 ~LoggingFixture()
185 {
dmcoomese062a182017-06-12 11:10:31 -0500186 Logging::get().setLevelImpl(m_oldEnabledLevel);
Junxiao Shi7d054272016-08-04 17:00:41 +0000187 Logging::setDestination(m_oldDestination);
188 }
189
190protected:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400191 boost::test_tools::output_test_stream os;
Junxiao Shi7d054272016-08-04 17:00:41 +0000192
193private:
dmcoomese062a182017-06-12 11:10:31 -0500194 std::unordered_map<std::string, LogLevel> m_oldEnabledLevel;
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400195 boost::shared_ptr<boost::log::sinks::sink> m_oldDestination;
Junxiao Shi7d054272016-08-04 17:00:41 +0000196};
197
198BOOST_AUTO_TEST_SUITE(Util)
199BOOST_FIXTURE_TEST_SUITE(TestLogging, LoggingFixture)
200
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500201BOOST_AUTO_TEST_CASE(GetLoggerNames)
202{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400203 // check that all names are registered from the start even if
204 // logger instances are lazily created on first use
205 auto n = Logging::getLoggerNames().size();
206 NDN_LOG_TRACE("GetLoggerNames");
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400207 auto names = Logging::getLoggerNames();
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400208 BOOST_CHECK_EQUAL(names.size(), n);
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500209 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Logging"), 1);
210}
211
Junxiao Shi7d054272016-08-04 17:00:41 +0000212BOOST_AUTO_TEST_SUITE(Severity)
213
214BOOST_AUTO_TEST_CASE(None)
215{
216 Logging::setLevel("Module1", LogLevel::NONE);
217 logFromModule1();
218
219 Logging::flush();
220 BOOST_CHECK(os.is_equal(
221 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
222 ));
223}
224
225BOOST_AUTO_TEST_CASE(Error)
226{
227 Logging::setLevel("Module1", LogLevel::ERROR);
228 logFromModule1();
229
230 Logging::flush();
231 BOOST_CHECK(os.is_equal(
232 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
233 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
234 ));
235}
236
237BOOST_AUTO_TEST_CASE(Warn)
238{
239 Logging::setLevel("Module1", LogLevel::WARN);
240 logFromModule1();
241
242 Logging::flush();
243 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400244 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000245 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
246 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
247 ));
248}
249
250BOOST_AUTO_TEST_CASE(Info)
251{
252 Logging::setLevel("Module1", LogLevel::INFO);
253 logFromModule1();
254
255 Logging::flush();
256 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400257 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
258 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000259 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
260 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
261 ));
262}
263
264BOOST_AUTO_TEST_CASE(Debug)
265{
266 Logging::setLevel("Module1", LogLevel::DEBUG);
267 logFromModule1();
268
269 Logging::flush();
270 BOOST_CHECK(os.is_equal(
271 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400272 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
273 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000274 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
275 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
276 ));
277}
278
279BOOST_AUTO_TEST_CASE(Trace)
280{
281 Logging::setLevel("Module1", LogLevel::TRACE);
282 logFromModule1();
283
284 Logging::flush();
285 BOOST_CHECK(os.is_equal(
286 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
287 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400288 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
289 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000290 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
291 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
292 ));
293}
294
295BOOST_AUTO_TEST_CASE(All)
296{
297 Logging::setLevel("Module1", LogLevel::ALL);
298 logFromModule1();
299
300 Logging::flush();
301 BOOST_CHECK(os.is_equal(
302 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
303 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400304 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
305 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000306 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
307 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
308 ));
309}
310
311BOOST_AUTO_TEST_SUITE_END() // Severity
312
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400313BOOST_AUTO_TEST_CASE(NamespaceLogger)
314{
315 Logging::setLevel("ndn.util.tests.ns1", LogLevel::INFO);
316 Logging::setLevel("ndn.util.tests.ns2", LogLevel::DEBUG);
317
318 const auto& levels = Logging::get().getLevels();
319 BOOST_CHECK_EQUAL(levels.size(), 2);
320 BOOST_CHECK_EQUAL(levels.at("ndn.util.tests.ns1"), LogLevel::INFO);
321 BOOST_CHECK_EQUAL(levels.at("ndn.util.tests.ns2"), LogLevel::DEBUG);
322
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400323 const auto& names = Logging::getLoggerNames();
324 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ns1"), 1);
325 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ns2"), 1);
326
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400327 ns1::logFromNamespace1();
328 ns2::logFromNamespace2();
329
330 Logging::flush();
331 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400332 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns1] hello world from ns1\n" +
333 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns2] hi there from ns2\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400334 ));
335}
336
337BOOST_AUTO_TEST_CASE(MemberLogger)
338{
339 Logging::setLevel("ndn.util.tests.ClassWithLogger", LogLevel::INFO);
Davide Pesavento39cb4022019-11-24 21:15:02 -0500340 Logging::setLevel("ndn.util.tests.AbstractClassWithLogger", LogLevel::INFO);
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400341 Logging::setLevel("ndn.util.tests.Specialized1", LogLevel::INFO);
342 // ndn.util.tests.Specialized2 is not enabled
343
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400344 const auto& names = Logging::getLoggerNames();
345 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ClassWithLogger"), 1);
Davide Pesavento39cb4022019-11-24 21:15:02 -0500346 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.AbstractClassWithLogger"), 1);
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400347 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Specialized1"), 1);
348 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Specialized2"), 1);
349
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400350 ClassWithLogger::logFromStaticMemberFunction();
351 ClassWithLogger{}.logFromConstMemberFunction();
352
353 Logging::flush();
354 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400355 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] static member function\n" +
356 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] const member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400357 ));
358
Davide Pesavento39cb4022019-11-24 21:15:02 -0500359 DerivedClass{}.logFromConstMemberFunction();
360 DerivedClass{}.logFromVirtualFunction();
361
362 Logging::flush();
363 BOOST_CHECK(os.is_equal(
364 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.AbstractClassWithLogger] const member function\n" +
365 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.AbstractClassWithLogger] overridden virtual function\n"
366 ));
367
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400368 ClassTemplateWithLogger<int, double>::logFromStaticMemberFunction();
369 ClassTemplateWithLogger<int, double>{}.logFromMemberFunction();
370 ClassTemplateWithLogger<int, std::string>::logFromStaticMemberFunction();
371 ClassTemplateWithLogger<int, std::string>{}.logFromMemberFunction();
372
373 Logging::flush();
374 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400375 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template static member function\n" +
376 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template non-static member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400377 ));
378}
379
Junxiao Shi7d054272016-08-04 17:00:41 +0000380BOOST_AUTO_TEST_CASE(SameNameLoggers)
381{
382 Logging::setLevel("Module1", LogLevel::WARN);
383 logFromModule1();
384 logFromNewLogger("Module1");
385
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400386 BOOST_CHECK_EQUAL(Logging::getLoggerNames().count("Module1"), 1);
387
Junxiao Shi7d054272016-08-04 17:00:41 +0000388 Logging::flush();
389 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400390 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000391 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
392 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400393 LOG_SYSTIME_STR + " WARN: [Module1] warnModule1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000394 LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
395 LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
396 ));
397}
398
399BOOST_AUTO_TEST_CASE(LateRegistration)
400{
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400401 Logging::setLevel("Module3", LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000402 logFromNewLogger("Module3");
403
404 Logging::flush();
405 BOOST_CHECK(os.is_equal(
406 LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400407 LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
408 LOG_SYSTIME_STR + " WARN: [Module3] warnModule3\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000409 LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
410 LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
411 ));
412}
413
414BOOST_AUTO_TEST_SUITE(DefaultSeverity)
415
416BOOST_AUTO_TEST_CASE(Unset)
417{
418 logFromModule1();
419 logFromModule2();
420
421 Logging::flush();
422 BOOST_CHECK(os.is_equal(
423 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
424 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
425 ));
426}
427
428BOOST_AUTO_TEST_CASE(NoOverride)
429{
430 Logging::setLevel("*", LogLevel::WARN);
431 logFromModule1();
432 logFromModule2();
433
434 Logging::flush();
435 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400436 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000437 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
438 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400439 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000440 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
441 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
442 ));
443}
444
445BOOST_AUTO_TEST_CASE(Override)
446{
447 Logging::setLevel("*", LogLevel::WARN);
448 Logging::setLevel("Module2", LogLevel::DEBUG);
449 logFromModule1();
450 logFromModule2();
451
452 Logging::flush();
453 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400454 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000455 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
456 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
457 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400458 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
459 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000460 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
461 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
462 ));
463}
464
465BOOST_AUTO_TEST_SUITE_END() // DefaultSeverity
466
467BOOST_AUTO_TEST_SUITE(SeverityConfig)
468
469BOOST_AUTO_TEST_CASE(SetEmpty)
470{
471 Logging::setLevel("");
dmcoomese062a182017-06-12 11:10:31 -0500472 const auto& prefixMap = Logging::get().getLevels();
473 BOOST_CHECK_EQUAL(prefixMap.size(), 0);
Junxiao Shi7d054272016-08-04 17:00:41 +0000474 logFromModule1();
475 logFromModule2();
476
477 Logging::flush();
478 BOOST_CHECK(os.is_equal(
479 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
480 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
481 ));
482}
483
484BOOST_AUTO_TEST_CASE(SetDefault)
485{
486 Logging::setLevel("*=WARN");
dmcoomese062a182017-06-12 11:10:31 -0500487 const auto& prefixMap = Logging::get().getLevels();
488 // "*" is treated as "" internally
489 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
490 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
Junxiao Shi7d054272016-08-04 17:00:41 +0000491 logFromModule1();
492 logFromModule2();
493
494 Logging::flush();
495 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400496 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000497 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
498 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400499 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000500 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
501 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
502 ));
503}
504
505BOOST_AUTO_TEST_CASE(SetModule)
506{
507 Logging::setLevel("Module1=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500508 const auto& prefixMap = Logging::get().getLevels();
509 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
510 BOOST_CHECK_EQUAL(prefixMap.at("Module1"), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000511 logFromModule1();
512 logFromModule2();
513
514 Logging::flush();
515 BOOST_CHECK(os.is_equal(
516 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
517 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
518 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
519 ));
520}
521
522BOOST_AUTO_TEST_CASE(SetOverride)
523{
524 Logging::setLevel("*=WARN:Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500525 const auto& prefixMap = Logging::get().getLevels();
526 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
527 // "*" is treated as "" internally
528 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
529 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000530 logFromModule1();
531 logFromModule2();
532
533 Logging::flush();
534 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400535 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000536 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
537 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
538 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400539 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
540 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000541 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
542 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
543 ));
544}
545
546BOOST_AUTO_TEST_CASE(SetTwice)
547{
548 Logging::setLevel("*=WARN");
549 Logging::setLevel("Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500550 const auto& prefixMap = Logging::get().getLevels();
551 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
552 // "*" is treated as "" internally
553 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
554 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000555 logFromModule1();
556 logFromModule2();
557
558 Logging::flush();
559 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400560 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000561 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
562 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
563 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400564 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
565 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000566 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
567 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
568 ));
569}
570
571BOOST_AUTO_TEST_CASE(Reset)
572{
573 Logging::setLevel("Module2=DEBUG");
574 Logging::setLevel("*=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500575 const auto& prefixMap = Logging::get().getLevels();
576 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
577 // "*" is treated as "" internally
578 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000579 logFromModule1();
580 logFromModule2();
581
582 Logging::flush();
583 BOOST_CHECK(os.is_equal(
584 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
585 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
586 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
587 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
588 ));
589}
590
591BOOST_AUTO_TEST_CASE(Malformed)
592{
593 BOOST_CHECK_THROW(Logging::setLevel("Module1=INVALID-LEVEL"), std::invalid_argument);
594 BOOST_CHECK_THROW(Logging::setLevel("Module1-MISSING-EQUAL-SIGN"), std::invalid_argument);
595}
596
dmcoomese062a182017-06-12 11:10:31 -0500597BOOST_AUTO_TEST_CASE(SetFilter)
598{
599 Logging::setLevel("*=FATAL:fm.*=DEBUG");
600 const auto& prefixMap = Logging::get().getLevels();
601 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
602 // "*" is treated as "" internally
603 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
604 // "name.*" is treated as "name." internally
605 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::DEBUG);
606 logFromModule1();
607 logFromFilterModule();
608
609 Logging::flush();
610 BOOST_CHECK(os.is_equal(
611 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
612 LOG_SYSTIME_STR + " DEBUG: [fm.FilterModule] debugFM\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400613 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
614 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500615 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
616 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
617 ));
618}
619
620BOOST_AUTO_TEST_CASE(SetOverrideFilter)
621{
622 Logging::setLevel("*=FATAL:fm.FilterModule=DEBUG");
623 Logging::setLevel("fm.*", LogLevel::INFO);
624 const auto& prefixMap = Logging::get().getLevels();
625 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
626 // "*" is treated as "" internally
627 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
628 // "name.*" is treated as "name." internally
629 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::INFO);
630 logFromModule1();
631 logFromFilterModule();
632
633 Logging::flush();
634 BOOST_CHECK(os.is_equal(
635 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400636 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
637 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500638 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
639 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
640 ));
641}
642
643BOOST_AUTO_TEST_CASE(FindPrefixRule)
644{
645 Logging::setLevel("*=FATAL:fm.a.*=ERROR:fm.a.b=INFO");
646 logFromNewLogger("fm.a.b");
647 logFromNewLogger("fm.a.b.c");
648 logFromNewLogger("fm.a.b.d");
649 logFromNewLogger("fm.b");
650
651 Logging::flush();
652 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400653 LOG_SYSTIME_STR + " INFO: [fm.a.b] infofm.a.b\n" +
654 LOG_SYSTIME_STR + " WARN: [fm.a.b] warnfm.a.b\n" +
dmcoomese062a182017-06-12 11:10:31 -0500655 LOG_SYSTIME_STR + " ERROR: [fm.a.b] errorfm.a.b\n" +
656 LOG_SYSTIME_STR + " FATAL: [fm.a.b] fatalfm.a.b\n" +
657 LOG_SYSTIME_STR + " ERROR: [fm.a.b.c] errorfm.a.b.c\n" +
658 LOG_SYSTIME_STR + " FATAL: [fm.a.b.c] fatalfm.a.b.c\n" +
659 LOG_SYSTIME_STR + " ERROR: [fm.a.b.d] errorfm.a.b.d\n" +
660 LOG_SYSTIME_STR + " FATAL: [fm.a.b.d] fatalfm.a.b.d\n" +
661 LOG_SYSTIME_STR + " FATAL: [fm.b] fatalfm.b\n"
662 ));
663}
664
Junxiao Shi7d054272016-08-04 17:00:41 +0000665BOOST_AUTO_TEST_SUITE_END() // SeverityConfig
666
667BOOST_AUTO_TEST_CASE(ChangeDestination)
668{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400669 using boost::test_tools::output_test_stream;
670
Junxiao Shi7d054272016-08-04 17:00:41 +0000671 logFromModule1();
672
673 auto os2 = make_shared<output_test_stream>();
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400674 Logging::setDestination(Logging::makeDefaultStreamDestination(os2));
Junxiao Shi7d054272016-08-04 17:00:41 +0000675 weak_ptr<output_test_stream> os2weak(os2);
676 os2.reset();
677
678 logFromModule2();
679
680 Logging::flush();
681 os2 = os2weak.lock();
682 BOOST_REQUIRE(os2 != nullptr);
683
684 BOOST_CHECK(os.is_equal(
685 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
686 ));
687 BOOST_CHECK(os2->is_equal(
688 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
689 ));
690
691 os2.reset();
692 Logging::setDestination(os);
693 BOOST_CHECK(os2weak.expired());
694}
695
Davide Pesavento39cb4022019-11-24 21:15:02 -0500696BOOST_AUTO_TEST_CASE(NullDestination)
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400697{
698 Logging::setDestination(nullptr);
699 logFromModule1();
700
701 Logging::flush();
702 BOOST_CHECK(os.is_equal(""));
703 // The default Boost.Log output is still expected
704}
705
Junxiao Shi7d054272016-08-04 17:00:41 +0000706BOOST_AUTO_TEST_SUITE_END() // TestLogging
707BOOST_AUTO_TEST_SUITE_END() // Util
708
709} // namespace tests
710} // namespace util
711} // namespace ndn