blob: 821e11e3c8eccc0dc1d1c9c8bbe201be6ccc16e0 [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 Pesavento541a8222022-03-01 15:08:42 -05003 * Copyright (c) 2013-2022 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#include <boost/test/tools/output_test_stream.hpp>
Junxiao Shi7d054272016-08-04 17:00:41 +000029
30namespace ndn {
31namespace util {
32namespace tests {
33
Alexander Afanasyev354f3822017-03-27 15:26:41 -050034NDN_LOG_INIT(ndn.util.tests.Logging);
35
Junxiao Shi7d054272016-08-04 17:00:41 +000036void
37logFromModule1();
38
39void
40logFromModule2();
41
42void
dmcoomese062a182017-06-12 11:10:31 -050043logFromFilterModule();
44
45static void
Davide Pesavento1c9c96c2018-04-25 10:45:08 -040046logFromNewLogger(const char* moduleName)
Junxiao Shi7d054272016-08-04 17:00:41 +000047{
Davide Pesavento0c145ec2018-04-10 21:33:57 -040048 Logger logger(moduleName);
49 auto ndn_cxx_getLogger = [&logger] () -> Logger& { return logger; };
Junxiao Shi7d054272016-08-04 17:00:41 +000050
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000051 NDN_LOG_TRACE("trace" << moduleName);
52 NDN_LOG_DEBUG("debug" << moduleName);
53 NDN_LOG_INFO("info" << moduleName);
54 NDN_LOG_WARN("warn" << moduleName);
55 NDN_LOG_ERROR("error" << moduleName);
56 NDN_LOG_FATAL("fatal" << moduleName);
Junxiao Shi7d054272016-08-04 17:00:41 +000057
58 BOOST_CHECK(Logging::get().removeLogger(logger));
59}
60
Davide Pesavento0c145ec2018-04-10 21:33:57 -040061namespace ns1 {
Junxiao Shi7d054272016-08-04 17:00:41 +000062
Davide Pesavento0c145ec2018-04-10 21:33:57 -040063NDN_LOG_INIT(ndn.util.tests.ns1);
64
65static void
66logFromNamespace1()
67{
68 NDN_LOG_INFO("hello world from ns1");
69}
70
71} // namespace ns1
72
73namespace ns2 {
74
75NDN_LOG_INIT(ndn.util.tests.ns2);
76
77static void
78logFromNamespace2()
79{
80 NDN_LOG_INFO("hi there from ns2");
81}
82
83} // namespace ns2
84
85class ClassWithLogger
86{
87public:
88 void
89 logFromConstMemberFunction() const
90 {
91 NDN_LOG_INFO("const member function");
92 }
93
94 static void
95 logFromStaticMemberFunction()
96 {
97 NDN_LOG_INFO("static member function");
98 }
99
100private:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400101 NDN_LOG_MEMBER_DECL();
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400102};
103
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400104NDN_LOG_MEMBER_INIT(ClassWithLogger, ndn.util.tests.ClassWithLogger);
105
Davide Pesavento39cb4022019-11-24 21:15:02 -0500106class AbstractClassWithLogger
107{
108public:
109 virtual
110 ~AbstractClassWithLogger() = default;
111
112 void
113 logFromConstMemberFunction() const
114 {
115 NDN_LOG_INFO("const member function");
116 }
117
118 virtual void
119 logFromVirtualFunction() = 0;
120
121protected:
122 NDN_LOG_MEMBER_DECL();
123};
124
125// Check that the macro can cope with abstract types
126NDN_LOG_MEMBER_INIT(AbstractClassWithLogger, ndn.util.tests.AbstractClassWithLogger);
127
128class DerivedClass : public AbstractClassWithLogger
129{
130public:
131 void
132 logFromVirtualFunction() final
133 {
134 NDN_LOG_INFO("overridden virtual function");
135 }
136};
137
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400138template<class T, class U>
139class ClassTemplateWithLogger
140{
141public:
142 void
143 logFromMemberFunction()
144 {
145 NDN_LOG_INFO("class template non-static member function");
146 }
147
148 static void
149 logFromStaticMemberFunction()
150 {
151 NDN_LOG_INFO("class template static member function");
152 }
153
154private:
155 NDN_LOG_MEMBER_DECL();
156};
157
158// Technically this declaration is not necessary in this case,
159// but we want to test that the macro expands to well-formed code
160NDN_LOG_MEMBER_DECL_SPECIALIZED((ClassTemplateWithLogger<int, double>));
161
162NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, double>), ndn.util.tests.Specialized1);
163NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, std::string>), ndn.util.tests.Specialized2);
164
165const time::microseconds LOG_SYSTIME(1468108800311239LL);
166const std::string LOG_SYSTIME_STR("1468108800.311239");
167
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500168class LoggingFixture : public ndn::tests::ClockFixture
Junxiao Shi7d054272016-08-04 17:00:41 +0000169{
170protected:
Junxiao Shi7d054272016-08-04 17:00:41 +0000171 LoggingFixture()
dmcoomese062a182017-06-12 11:10:31 -0500172 : m_oldEnabledLevel(Logging::get().getLevels())
Junxiao Shi7d054272016-08-04 17:00:41 +0000173 , m_oldDestination(Logging::get().getDestination())
174 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500175 m_systemClock->setNow(LOG_SYSTIME);
Junxiao Shi7d054272016-08-04 17:00:41 +0000176 Logging::get().resetLevels();
Alexander Afanasyev39535f42019-07-05 22:07:52 -0400177 Logging::setDestination(os, true);
Junxiao Shi7d054272016-08-04 17:00:41 +0000178 }
179
180 ~LoggingFixture()
181 {
dmcoomese062a182017-06-12 11:10:31 -0500182 Logging::get().setLevelImpl(m_oldEnabledLevel);
Junxiao Shi7d054272016-08-04 17:00:41 +0000183 Logging::setDestination(m_oldDestination);
184 }
185
186protected:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400187 boost::test_tools::output_test_stream os;
Junxiao Shi7d054272016-08-04 17:00:41 +0000188
189private:
dmcoomese062a182017-06-12 11:10:31 -0500190 std::unordered_map<std::string, LogLevel> m_oldEnabledLevel;
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400191 boost::shared_ptr<boost::log::sinks::sink> m_oldDestination;
Junxiao Shi7d054272016-08-04 17:00:41 +0000192};
193
194BOOST_AUTO_TEST_SUITE(Util)
195BOOST_FIXTURE_TEST_SUITE(TestLogging, LoggingFixture)
196
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500197BOOST_AUTO_TEST_CASE(GetLoggerNames)
198{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400199 // check that all names are registered from the start even if
200 // logger instances are lazily created on first use
201 auto n = Logging::getLoggerNames().size();
202 NDN_LOG_TRACE("GetLoggerNames");
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400203 auto names = Logging::getLoggerNames();
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400204 BOOST_CHECK_EQUAL(names.size(), n);
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500205 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Logging"), 1);
206}
207
Junxiao Shi7d054272016-08-04 17:00:41 +0000208BOOST_AUTO_TEST_SUITE(Severity)
209
210BOOST_AUTO_TEST_CASE(None)
211{
212 Logging::setLevel("Module1", LogLevel::NONE);
213 logFromModule1();
214
215 Logging::flush();
216 BOOST_CHECK(os.is_equal(
217 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
218 ));
219}
220
221BOOST_AUTO_TEST_CASE(Error)
222{
223 Logging::setLevel("Module1", LogLevel::ERROR);
224 logFromModule1();
225
226 Logging::flush();
227 BOOST_CHECK(os.is_equal(
228 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
229 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
230 ));
231}
232
233BOOST_AUTO_TEST_CASE(Warn)
234{
235 Logging::setLevel("Module1", LogLevel::WARN);
236 logFromModule1();
237
238 Logging::flush();
239 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400240 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000241 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
242 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
243 ));
244}
245
246BOOST_AUTO_TEST_CASE(Info)
247{
248 Logging::setLevel("Module1", LogLevel::INFO);
249 logFromModule1();
250
251 Logging::flush();
252 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400253 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
254 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000255 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
256 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
257 ));
258}
259
260BOOST_AUTO_TEST_CASE(Debug)
261{
262 Logging::setLevel("Module1", LogLevel::DEBUG);
263 logFromModule1();
264
265 Logging::flush();
266 BOOST_CHECK(os.is_equal(
267 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400268 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
269 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000270 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
271 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
272 ));
273}
274
275BOOST_AUTO_TEST_CASE(Trace)
276{
277 Logging::setLevel("Module1", LogLevel::TRACE);
278 logFromModule1();
279
280 Logging::flush();
281 BOOST_CHECK(os.is_equal(
282 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
283 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400284 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
285 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000286 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
287 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
288 ));
289}
290
291BOOST_AUTO_TEST_CASE(All)
292{
293 Logging::setLevel("Module1", LogLevel::ALL);
294 logFromModule1();
295
296 Logging::flush();
297 BOOST_CHECK(os.is_equal(
298 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
299 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400300 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
301 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000302 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
303 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
304 ));
305}
306
307BOOST_AUTO_TEST_SUITE_END() // Severity
308
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400309BOOST_AUTO_TEST_CASE(NamespaceLogger)
310{
311 Logging::setLevel("ndn.util.tests.ns1", LogLevel::INFO);
312 Logging::setLevel("ndn.util.tests.ns2", LogLevel::DEBUG);
313
314 const auto& levels = Logging::get().getLevels();
315 BOOST_CHECK_EQUAL(levels.size(), 2);
316 BOOST_CHECK_EQUAL(levels.at("ndn.util.tests.ns1"), LogLevel::INFO);
317 BOOST_CHECK_EQUAL(levels.at("ndn.util.tests.ns2"), LogLevel::DEBUG);
318
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400319 const auto& names = Logging::getLoggerNames();
320 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ns1"), 1);
321 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ns2"), 1);
322
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400323 ns1::logFromNamespace1();
324 ns2::logFromNamespace2();
325
326 Logging::flush();
327 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400328 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns1] hello world from ns1\n" +
329 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns2] hi there from ns2\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400330 ));
331}
332
333BOOST_AUTO_TEST_CASE(MemberLogger)
334{
335 Logging::setLevel("ndn.util.tests.ClassWithLogger", LogLevel::INFO);
Davide Pesavento39cb4022019-11-24 21:15:02 -0500336 Logging::setLevel("ndn.util.tests.AbstractClassWithLogger", LogLevel::INFO);
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400337 Logging::setLevel("ndn.util.tests.Specialized1", LogLevel::INFO);
338 // ndn.util.tests.Specialized2 is not enabled
339
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400340 const auto& names = Logging::getLoggerNames();
341 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.ClassWithLogger"), 1);
Davide Pesavento39cb4022019-11-24 21:15:02 -0500342 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.AbstractClassWithLogger"), 1);
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400343 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Specialized1"), 1);
344 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Specialized2"), 1);
345
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400346 ClassWithLogger::logFromStaticMemberFunction();
347 ClassWithLogger{}.logFromConstMemberFunction();
348
349 Logging::flush();
350 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400351 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] static member function\n" +
352 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] const member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400353 ));
354
Davide Pesavento39cb4022019-11-24 21:15:02 -0500355 DerivedClass{}.logFromConstMemberFunction();
356 DerivedClass{}.logFromVirtualFunction();
357
358 Logging::flush();
359 BOOST_CHECK(os.is_equal(
360 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.AbstractClassWithLogger] const member function\n" +
361 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.AbstractClassWithLogger] overridden virtual function\n"
362 ));
363
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400364 ClassTemplateWithLogger<int, double>::logFromStaticMemberFunction();
365 ClassTemplateWithLogger<int, double>{}.logFromMemberFunction();
366 ClassTemplateWithLogger<int, std::string>::logFromStaticMemberFunction();
367 ClassTemplateWithLogger<int, std::string>{}.logFromMemberFunction();
368
369 Logging::flush();
370 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400371 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template static member function\n" +
372 LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template non-static member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400373 ));
374}
375
Junxiao Shi7d054272016-08-04 17:00:41 +0000376BOOST_AUTO_TEST_CASE(SameNameLoggers)
377{
378 Logging::setLevel("Module1", LogLevel::WARN);
379 logFromModule1();
380 logFromNewLogger("Module1");
381
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400382 BOOST_CHECK_EQUAL(Logging::getLoggerNames().count("Module1"), 1);
383
Junxiao Shi7d054272016-08-04 17:00:41 +0000384 Logging::flush();
385 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400386 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000387 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
388 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400389 LOG_SYSTIME_STR + " WARN: [Module1] warnModule1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000390 LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
391 LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
392 ));
393}
394
395BOOST_AUTO_TEST_CASE(LateRegistration)
396{
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400397 Logging::setLevel("Module3", LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000398 logFromNewLogger("Module3");
399
400 Logging::flush();
401 BOOST_CHECK(os.is_equal(
402 LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400403 LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
404 LOG_SYSTIME_STR + " WARN: [Module3] warnModule3\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000405 LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
406 LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
407 ));
408}
409
410BOOST_AUTO_TEST_SUITE(DefaultSeverity)
411
412BOOST_AUTO_TEST_CASE(Unset)
413{
414 logFromModule1();
415 logFromModule2();
416
417 Logging::flush();
418 BOOST_CHECK(os.is_equal(
419 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
420 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
421 ));
422}
423
424BOOST_AUTO_TEST_CASE(NoOverride)
425{
426 Logging::setLevel("*", LogLevel::WARN);
427 logFromModule1();
428 logFromModule2();
429
430 Logging::flush();
431 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400432 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000433 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
434 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400435 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000436 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
437 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
438 ));
439}
440
441BOOST_AUTO_TEST_CASE(Override)
442{
443 Logging::setLevel("*", LogLevel::WARN);
444 Logging::setLevel("Module2", LogLevel::DEBUG);
445 logFromModule1();
446 logFromModule2();
447
448 Logging::flush();
449 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400450 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000451 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
452 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
453 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400454 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
455 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000456 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
457 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
458 ));
459}
460
461BOOST_AUTO_TEST_SUITE_END() // DefaultSeverity
462
463BOOST_AUTO_TEST_SUITE(SeverityConfig)
464
465BOOST_AUTO_TEST_CASE(SetEmpty)
466{
467 Logging::setLevel("");
dmcoomese062a182017-06-12 11:10:31 -0500468 const auto& prefixMap = Logging::get().getLevels();
469 BOOST_CHECK_EQUAL(prefixMap.size(), 0);
Junxiao Shi7d054272016-08-04 17:00:41 +0000470 logFromModule1();
471 logFromModule2();
472
473 Logging::flush();
474 BOOST_CHECK(os.is_equal(
475 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
476 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
477 ));
478}
479
480BOOST_AUTO_TEST_CASE(SetDefault)
481{
482 Logging::setLevel("*=WARN");
dmcoomese062a182017-06-12 11:10:31 -0500483 const auto& prefixMap = Logging::get().getLevels();
484 // "*" is treated as "" internally
485 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
486 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
Junxiao Shi7d054272016-08-04 17:00:41 +0000487 logFromModule1();
488 logFromModule2();
489
490 Logging::flush();
491 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400492 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000493 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
494 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400495 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000496 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
497 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
498 ));
499}
500
501BOOST_AUTO_TEST_CASE(SetModule)
502{
503 Logging::setLevel("Module1=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500504 const auto& prefixMap = Logging::get().getLevels();
505 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
506 BOOST_CHECK_EQUAL(prefixMap.at("Module1"), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000507 logFromModule1();
508 logFromModule2();
509
510 Logging::flush();
511 BOOST_CHECK(os.is_equal(
512 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
513 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
514 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
515 ));
516}
517
518BOOST_AUTO_TEST_CASE(SetOverride)
519{
520 Logging::setLevel("*=WARN:Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500521 const auto& prefixMap = Logging::get().getLevels();
522 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
523 // "*" is treated as "" internally
524 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
525 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000526 logFromModule1();
527 logFromModule2();
528
529 Logging::flush();
530 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400531 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000532 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
533 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
534 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400535 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
536 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000537 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
538 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
539 ));
540}
541
542BOOST_AUTO_TEST_CASE(SetTwice)
543{
544 Logging::setLevel("*=WARN");
545 Logging::setLevel("Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500546 const auto& prefixMap = Logging::get().getLevels();
547 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
548 // "*" is treated as "" internally
549 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
550 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000551 logFromModule1();
552 logFromModule2();
553
554 Logging::flush();
555 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400556 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000557 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
558 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
559 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400560 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
561 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000562 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
563 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
564 ));
565}
566
567BOOST_AUTO_TEST_CASE(Reset)
568{
569 Logging::setLevel("Module2=DEBUG");
570 Logging::setLevel("*=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500571 const auto& prefixMap = Logging::get().getLevels();
572 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
573 // "*" is treated as "" internally
574 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000575 logFromModule1();
576 logFromModule2();
577
578 Logging::flush();
579 BOOST_CHECK(os.is_equal(
580 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
581 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
582 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
583 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
584 ));
585}
586
587BOOST_AUTO_TEST_CASE(Malformed)
588{
589 BOOST_CHECK_THROW(Logging::setLevel("Module1=INVALID-LEVEL"), std::invalid_argument);
590 BOOST_CHECK_THROW(Logging::setLevel("Module1-MISSING-EQUAL-SIGN"), std::invalid_argument);
591}
592
dmcoomese062a182017-06-12 11:10:31 -0500593BOOST_AUTO_TEST_CASE(SetFilter)
594{
595 Logging::setLevel("*=FATAL:fm.*=DEBUG");
596 const auto& prefixMap = Logging::get().getLevels();
597 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
598 // "*" is treated as "" internally
599 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
600 // "name.*" is treated as "name." internally
601 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::DEBUG);
602 logFromModule1();
603 logFromFilterModule();
604
605 Logging::flush();
606 BOOST_CHECK(os.is_equal(
607 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
608 LOG_SYSTIME_STR + " DEBUG: [fm.FilterModule] debugFM\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400609 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
610 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500611 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
612 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
613 ));
614}
615
616BOOST_AUTO_TEST_CASE(SetOverrideFilter)
617{
618 Logging::setLevel("*=FATAL:fm.FilterModule=DEBUG");
619 Logging::setLevel("fm.*", LogLevel::INFO);
620 const auto& prefixMap = Logging::get().getLevels();
621 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
622 // "*" is treated as "" internally
623 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
624 // "name.*" is treated as "name." internally
625 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::INFO);
626 logFromModule1();
627 logFromFilterModule();
628
629 Logging::flush();
630 BOOST_CHECK(os.is_equal(
631 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400632 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
633 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500634 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
635 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
636 ));
637}
638
639BOOST_AUTO_TEST_CASE(FindPrefixRule)
640{
641 Logging::setLevel("*=FATAL:fm.a.*=ERROR:fm.a.b=INFO");
642 logFromNewLogger("fm.a.b");
643 logFromNewLogger("fm.a.b.c");
644 logFromNewLogger("fm.a.b.d");
645 logFromNewLogger("fm.b");
646
647 Logging::flush();
648 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400649 LOG_SYSTIME_STR + " INFO: [fm.a.b] infofm.a.b\n" +
650 LOG_SYSTIME_STR + " WARN: [fm.a.b] warnfm.a.b\n" +
dmcoomese062a182017-06-12 11:10:31 -0500651 LOG_SYSTIME_STR + " ERROR: [fm.a.b] errorfm.a.b\n" +
652 LOG_SYSTIME_STR + " FATAL: [fm.a.b] fatalfm.a.b\n" +
653 LOG_SYSTIME_STR + " ERROR: [fm.a.b.c] errorfm.a.b.c\n" +
654 LOG_SYSTIME_STR + " FATAL: [fm.a.b.c] fatalfm.a.b.c\n" +
655 LOG_SYSTIME_STR + " ERROR: [fm.a.b.d] errorfm.a.b.d\n" +
656 LOG_SYSTIME_STR + " FATAL: [fm.a.b.d] fatalfm.a.b.d\n" +
657 LOG_SYSTIME_STR + " FATAL: [fm.b] fatalfm.b\n"
658 ));
659}
660
Junxiao Shi7d054272016-08-04 17:00:41 +0000661BOOST_AUTO_TEST_SUITE_END() // SeverityConfig
662
663BOOST_AUTO_TEST_CASE(ChangeDestination)
664{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400665 using boost::test_tools::output_test_stream;
666
Junxiao Shi7d054272016-08-04 17:00:41 +0000667 logFromModule1();
668
669 auto os2 = make_shared<output_test_stream>();
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400670 Logging::setDestination(Logging::makeDefaultStreamDestination(os2));
Junxiao Shi7d054272016-08-04 17:00:41 +0000671 weak_ptr<output_test_stream> os2weak(os2);
672 os2.reset();
673
674 logFromModule2();
675
676 Logging::flush();
677 os2 = os2weak.lock();
678 BOOST_REQUIRE(os2 != nullptr);
679
680 BOOST_CHECK(os.is_equal(
681 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
682 ));
683 BOOST_CHECK(os2->is_equal(
684 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
685 ));
686
687 os2.reset();
Alexander Afanasyev39535f42019-07-05 22:07:52 -0400688 Logging::setDestination(os, true);
Junxiao Shi7d054272016-08-04 17:00:41 +0000689 BOOST_CHECK(os2weak.expired());
690}
691
Davide Pesavento39cb4022019-11-24 21:15:02 -0500692BOOST_AUTO_TEST_CASE(NullDestination)
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400693{
694 Logging::setDestination(nullptr);
695 logFromModule1();
696
697 Logging::flush();
698 BOOST_CHECK(os.is_equal(""));
699 // The default Boost.Log output is still expected
700}
701
Junxiao Shi7d054272016-08-04 17:00:41 +0000702BOOST_AUTO_TEST_SUITE_END() // TestLogging
703BOOST_AUTO_TEST_SUITE_END() // Util
704
705} // namespace tests
706} // namespace util
707} // namespace ndn