blob: 937b41bfe762cf38fb1347ddc5ec42d94d5496f3 [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 Pesavento3fdb02f2023-04-12 02:32:38 -04003 * Copyright (c) 2013-2023 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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040030namespace ndn::tests {
Junxiao Shi7d054272016-08-04 17:00:41 +000031
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040032using ndn::util::Logger;
33using ndn::util::Logging;
34using ndn::util::LogLevel;
35
36NDN_LOG_INIT(ndn.tests.Logging);
Alexander Afanasyev354f3822017-03-27 15:26:41 -050037
Junxiao Shi7d054272016-08-04 17:00:41 +000038void
39logFromModule1();
40
41void
42logFromModule2();
43
44void
dmcoomese062a182017-06-12 11:10:31 -050045logFromFilterModule();
46
47static void
Davide Pesavento1c9c96c2018-04-25 10:45:08 -040048logFromNewLogger(const char* moduleName)
Junxiao Shi7d054272016-08-04 17:00:41 +000049{
Davide Pesavento0c145ec2018-04-10 21:33:57 -040050 Logger logger(moduleName);
51 auto ndn_cxx_getLogger = [&logger] () -> Logger& { return logger; };
Junxiao Shi7d054272016-08-04 17:00:41 +000052
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000053 NDN_LOG_TRACE("trace" << moduleName);
54 NDN_LOG_DEBUG("debug" << moduleName);
55 NDN_LOG_INFO("info" << moduleName);
56 NDN_LOG_WARN("warn" << moduleName);
57 NDN_LOG_ERROR("error" << moduleName);
58 NDN_LOG_FATAL("fatal" << moduleName);
Junxiao Shi7d054272016-08-04 17:00:41 +000059
60 BOOST_CHECK(Logging::get().removeLogger(logger));
61}
62
Davide Pesavento0c145ec2018-04-10 21:33:57 -040063namespace ns1 {
Junxiao Shi7d054272016-08-04 17:00:41 +000064
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040065NDN_LOG_INIT(ndn.tests.ns1);
Davide Pesavento0c145ec2018-04-10 21:33:57 -040066
67static void
68logFromNamespace1()
69{
70 NDN_LOG_INFO("hello world from ns1");
71}
72
73} // namespace ns1
74
75namespace ns2 {
76
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040077NDN_LOG_INIT(ndn.tests.ns2);
Davide Pesavento0c145ec2018-04-10 21:33:57 -040078
79static void
80logFromNamespace2()
81{
82 NDN_LOG_INFO("hi there from ns2");
83}
84
85} // namespace ns2
86
87class ClassWithLogger
88{
89public:
90 void
91 logFromConstMemberFunction() const
92 {
93 NDN_LOG_INFO("const member function");
94 }
95
96 static void
97 logFromStaticMemberFunction()
98 {
99 NDN_LOG_INFO("static member function");
100 }
101
102private:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400103 NDN_LOG_MEMBER_DECL();
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400104};
105
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400106NDN_LOG_MEMBER_INIT(ClassWithLogger, ndn.tests.ClassWithLogger);
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400107
Davide Pesavento39cb4022019-11-24 21:15:02 -0500108class AbstractClassWithLogger
109{
110public:
111 virtual
112 ~AbstractClassWithLogger() = default;
113
114 void
115 logFromConstMemberFunction() const
116 {
117 NDN_LOG_INFO("const member function");
118 }
119
120 virtual void
121 logFromVirtualFunction() = 0;
122
123protected:
124 NDN_LOG_MEMBER_DECL();
125};
126
127// Check that the macro can cope with abstract types
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400128NDN_LOG_MEMBER_INIT(AbstractClassWithLogger, ndn.tests.AbstractClassWithLogger);
Davide Pesavento39cb4022019-11-24 21:15:02 -0500129
130class DerivedClass : public AbstractClassWithLogger
131{
132public:
133 void
134 logFromVirtualFunction() final
135 {
136 NDN_LOG_INFO("overridden virtual function");
137 }
138};
139
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400140template<class T, class U>
141class ClassTemplateWithLogger
142{
143public:
144 void
145 logFromMemberFunction()
146 {
147 NDN_LOG_INFO("class template non-static member function");
148 }
149
150 static void
151 logFromStaticMemberFunction()
152 {
153 NDN_LOG_INFO("class template static member function");
154 }
155
156private:
157 NDN_LOG_MEMBER_DECL();
158};
159
160// Technically this declaration is not necessary in this case,
161// but we want to test that the macro expands to well-formed code
162NDN_LOG_MEMBER_DECL_SPECIALIZED((ClassTemplateWithLogger<int, double>));
163
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400164NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, double>), ndn.tests.Specialized1);
165NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, std::string>), ndn.tests.Specialized2);
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400166
Davide Pesavento3fdb02f2023-04-12 02:32:38 -0400167constexpr time::microseconds LOG_SYSTIME{1468108800311239LL};
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400168const std::string LOG_SYSTIME_STR("1468108800.311239");
169
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400170class LoggingFixture : public ClockFixture
Junxiao Shi7d054272016-08-04 17:00:41 +0000171{
172protected:
Junxiao Shi7d054272016-08-04 17:00:41 +0000173 LoggingFixture()
dmcoomese062a182017-06-12 11:10:31 -0500174 : m_oldEnabledLevel(Logging::get().getLevels())
Junxiao Shi7d054272016-08-04 17:00:41 +0000175 , m_oldDestination(Logging::get().getDestination())
176 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500177 m_systemClock->setNow(LOG_SYSTIME);
Junxiao Shi7d054272016-08-04 17:00:41 +0000178 Logging::get().resetLevels();
Alexander Afanasyev39535f42019-07-05 22:07:52 -0400179 Logging::setDestination(os, true);
Junxiao Shi7d054272016-08-04 17:00:41 +0000180 }
181
Davide Pesavento3fdb02f2023-04-12 02:32:38 -0400182 ~LoggingFixture() override
Junxiao Shi7d054272016-08-04 17:00:41 +0000183 {
dmcoomese062a182017-06-12 11:10:31 -0500184 Logging::get().setLevelImpl(m_oldEnabledLevel);
Junxiao Shi7d054272016-08-04 17:00:41 +0000185 Logging::setDestination(m_oldDestination);
186 }
187
188protected:
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400189 boost::test_tools::output_test_stream os;
Junxiao Shi7d054272016-08-04 17:00:41 +0000190
191private:
dmcoomese062a182017-06-12 11:10:31 -0500192 std::unordered_map<std::string, LogLevel> m_oldEnabledLevel;
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400193 boost::shared_ptr<boost::log::sinks::sink> m_oldDestination;
Junxiao Shi7d054272016-08-04 17:00:41 +0000194};
195
196BOOST_AUTO_TEST_SUITE(Util)
197BOOST_FIXTURE_TEST_SUITE(TestLogging, LoggingFixture)
198
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500199BOOST_AUTO_TEST_CASE(GetLoggerNames)
200{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400201 // check that all names are registered from the start even if
202 // logger instances are lazily created on first use
203 auto n = Logging::getLoggerNames().size();
204 NDN_LOG_TRACE("GetLoggerNames");
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400205 auto names = Logging::getLoggerNames();
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400206 BOOST_CHECK_EQUAL(names.size(), n);
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400207 BOOST_CHECK_EQUAL(names.count("ndn.tests.Logging"), 1);
Alexander Afanasyev354f3822017-03-27 15:26:41 -0500208}
209
Junxiao Shi7d054272016-08-04 17:00:41 +0000210BOOST_AUTO_TEST_SUITE(Severity)
211
212BOOST_AUTO_TEST_CASE(None)
213{
214 Logging::setLevel("Module1", LogLevel::NONE);
215 logFromModule1();
216
217 Logging::flush();
218 BOOST_CHECK(os.is_equal(
219 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
220 ));
221}
222
223BOOST_AUTO_TEST_CASE(Error)
224{
225 Logging::setLevel("Module1", LogLevel::ERROR);
226 logFromModule1();
227
228 Logging::flush();
229 BOOST_CHECK(os.is_equal(
230 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
231 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
232 ));
233}
234
235BOOST_AUTO_TEST_CASE(Warn)
236{
237 Logging::setLevel("Module1", LogLevel::WARN);
238 logFromModule1();
239
240 Logging::flush();
241 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400242 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000243 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
244 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
245 ));
246}
247
248BOOST_AUTO_TEST_CASE(Info)
249{
250 Logging::setLevel("Module1", LogLevel::INFO);
251 logFromModule1();
252
253 Logging::flush();
254 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400255 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
256 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000257 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
258 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
259 ));
260}
261
262BOOST_AUTO_TEST_CASE(Debug)
263{
264 Logging::setLevel("Module1", LogLevel::DEBUG);
265 logFromModule1();
266
267 Logging::flush();
268 BOOST_CHECK(os.is_equal(
269 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400270 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
271 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000272 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
273 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
274 ));
275}
276
277BOOST_AUTO_TEST_CASE(Trace)
278{
279 Logging::setLevel("Module1", LogLevel::TRACE);
280 logFromModule1();
281
282 Logging::flush();
283 BOOST_CHECK(os.is_equal(
284 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
285 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400286 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
287 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000288 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
289 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
290 ));
291}
292
293BOOST_AUTO_TEST_CASE(All)
294{
295 Logging::setLevel("Module1", LogLevel::ALL);
296 logFromModule1();
297
298 Logging::flush();
299 BOOST_CHECK(os.is_equal(
300 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
301 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400302 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
303 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000304 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
305 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
306 ));
307}
308
309BOOST_AUTO_TEST_SUITE_END() // Severity
310
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400311BOOST_AUTO_TEST_CASE(NamespaceLogger)
312{
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400313 Logging::setLevel("ndn.tests.ns1", LogLevel::INFO);
314 Logging::setLevel("ndn.tests.ns2", LogLevel::DEBUG);
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400315
316 const auto& levels = Logging::get().getLevels();
317 BOOST_CHECK_EQUAL(levels.size(), 2);
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400318 BOOST_CHECK_EQUAL(levels.at("ndn.tests.ns1"), LogLevel::INFO);
319 BOOST_CHECK_EQUAL(levels.at("ndn.tests.ns2"), LogLevel::DEBUG);
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400320
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400321 const auto& names = Logging::getLoggerNames();
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400322 BOOST_CHECK_EQUAL(names.count("ndn.tests.ns1"), 1);
323 BOOST_CHECK_EQUAL(names.count("ndn.tests.ns2"), 1);
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400324
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400325 ns1::logFromNamespace1();
326 ns2::logFromNamespace2();
327
328 Logging::flush();
329 BOOST_CHECK(os.is_equal(
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400330 LOG_SYSTIME_STR + " INFO: [ndn.tests.ns1] hello world from ns1\n" +
331 LOG_SYSTIME_STR + " INFO: [ndn.tests.ns2] hi there from ns2\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400332 ));
333}
334
335BOOST_AUTO_TEST_CASE(MemberLogger)
336{
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400337 Logging::setLevel("ndn.tests.ClassWithLogger", LogLevel::INFO);
338 Logging::setLevel("ndn.tests.AbstractClassWithLogger", LogLevel::INFO);
339 Logging::setLevel("ndn.tests.Specialized1", LogLevel::INFO);
340 // ndn.tests.Specialized2 is not enabled
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400341
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400342 const auto& names = Logging::getLoggerNames();
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400343 BOOST_CHECK_EQUAL(names.count("ndn.tests.ClassWithLogger"), 1);
344 BOOST_CHECK_EQUAL(names.count("ndn.tests.AbstractClassWithLogger"), 1);
345 BOOST_CHECK_EQUAL(names.count("ndn.tests.Specialized1"), 1);
346 BOOST_CHECK_EQUAL(names.count("ndn.tests.Specialized2"), 1);
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400347
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400348 ClassWithLogger::logFromStaticMemberFunction();
349 ClassWithLogger{}.logFromConstMemberFunction();
350
351 Logging::flush();
352 BOOST_CHECK(os.is_equal(
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400353 LOG_SYSTIME_STR + " INFO: [ndn.tests.ClassWithLogger] static member function\n" +
354 LOG_SYSTIME_STR + " INFO: [ndn.tests.ClassWithLogger] const member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400355 ));
356
Davide Pesavento39cb4022019-11-24 21:15:02 -0500357 DerivedClass{}.logFromConstMemberFunction();
358 DerivedClass{}.logFromVirtualFunction();
359
360 Logging::flush();
361 BOOST_CHECK(os.is_equal(
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400362 LOG_SYSTIME_STR + " INFO: [ndn.tests.AbstractClassWithLogger] const member function\n" +
363 LOG_SYSTIME_STR + " INFO: [ndn.tests.AbstractClassWithLogger] overridden virtual function\n"
Davide Pesavento39cb4022019-11-24 21:15:02 -0500364 ));
365
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400366 ClassTemplateWithLogger<int, double>::logFromStaticMemberFunction();
367 ClassTemplateWithLogger<int, double>{}.logFromMemberFunction();
368 ClassTemplateWithLogger<int, std::string>::logFromStaticMemberFunction();
369 ClassTemplateWithLogger<int, std::string>{}.logFromMemberFunction();
370
371 Logging::flush();
372 BOOST_CHECK(os.is_equal(
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400373 LOG_SYSTIME_STR + " INFO: [ndn.tests.Specialized1] class template static member function\n" +
374 LOG_SYSTIME_STR + " INFO: [ndn.tests.Specialized1] class template non-static member function\n"
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400375 ));
376}
377
Junxiao Shi7d054272016-08-04 17:00:41 +0000378BOOST_AUTO_TEST_CASE(SameNameLoggers)
379{
380 Logging::setLevel("Module1", LogLevel::WARN);
381 logFromModule1();
382 logFromNewLogger("Module1");
383
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400384 BOOST_CHECK_EQUAL(Logging::getLoggerNames().count("Module1"), 1);
385
Junxiao Shi7d054272016-08-04 17:00:41 +0000386 Logging::flush();
387 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400388 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000389 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
390 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400391 LOG_SYSTIME_STR + " WARN: [Module1] warnModule1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000392 LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
393 LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
394 ));
395}
396
397BOOST_AUTO_TEST_CASE(LateRegistration)
398{
Davide Pesavento0c145ec2018-04-10 21:33:57 -0400399 Logging::setLevel("Module3", LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000400 logFromNewLogger("Module3");
401
402 Logging::flush();
403 BOOST_CHECK(os.is_equal(
404 LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400405 LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
406 LOG_SYSTIME_STR + " WARN: [Module3] warnModule3\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000407 LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
408 LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
409 ));
410}
411
412BOOST_AUTO_TEST_SUITE(DefaultSeverity)
413
414BOOST_AUTO_TEST_CASE(Unset)
415{
416 logFromModule1();
417 logFromModule2();
418
419 Logging::flush();
420 BOOST_CHECK(os.is_equal(
421 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
422 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
423 ));
424}
425
426BOOST_AUTO_TEST_CASE(NoOverride)
427{
428 Logging::setLevel("*", LogLevel::WARN);
429 logFromModule1();
430 logFromModule2();
431
432 Logging::flush();
433 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400434 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000435 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
436 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400437 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000438 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
439 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
440 ));
441}
442
443BOOST_AUTO_TEST_CASE(Override)
444{
445 Logging::setLevel("*", LogLevel::WARN);
446 Logging::setLevel("Module2", LogLevel::DEBUG);
447 logFromModule1();
448 logFromModule2();
449
450 Logging::flush();
451 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400452 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000453 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
454 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
455 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400456 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
457 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000458 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
459 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
460 ));
461}
462
463BOOST_AUTO_TEST_SUITE_END() // DefaultSeverity
464
465BOOST_AUTO_TEST_SUITE(SeverityConfig)
466
467BOOST_AUTO_TEST_CASE(SetEmpty)
468{
469 Logging::setLevel("");
dmcoomese062a182017-06-12 11:10:31 -0500470 const auto& prefixMap = Logging::get().getLevels();
471 BOOST_CHECK_EQUAL(prefixMap.size(), 0);
Junxiao Shi7d054272016-08-04 17:00:41 +0000472 logFromModule1();
473 logFromModule2();
474
475 Logging::flush();
476 BOOST_CHECK(os.is_equal(
477 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
478 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
479 ));
480}
481
482BOOST_AUTO_TEST_CASE(SetDefault)
483{
484 Logging::setLevel("*=WARN");
dmcoomese062a182017-06-12 11:10:31 -0500485 const auto& prefixMap = Logging::get().getLevels();
486 // "*" is treated as "" internally
487 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
488 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
Junxiao Shi7d054272016-08-04 17:00:41 +0000489 logFromModule1();
490 logFromModule2();
491
492 Logging::flush();
493 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400494 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000495 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
496 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400497 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000498 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
499 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
500 ));
501}
502
503BOOST_AUTO_TEST_CASE(SetModule)
504{
505 Logging::setLevel("Module1=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500506 const auto& prefixMap = Logging::get().getLevels();
507 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
508 BOOST_CHECK_EQUAL(prefixMap.at("Module1"), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000509 logFromModule1();
510 logFromModule2();
511
512 Logging::flush();
513 BOOST_CHECK(os.is_equal(
514 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
515 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
516 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
517 ));
518}
519
520BOOST_AUTO_TEST_CASE(SetOverride)
521{
522 Logging::setLevel("*=WARN:Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500523 const auto& prefixMap = Logging::get().getLevels();
524 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
525 // "*" is treated as "" internally
526 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
527 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000528 logFromModule1();
529 logFromModule2();
530
531 Logging::flush();
532 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400533 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000534 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
535 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
536 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400537 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
538 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000539 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
540 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
541 ));
542}
543
544BOOST_AUTO_TEST_CASE(SetTwice)
545{
546 Logging::setLevel("*=WARN");
547 Logging::setLevel("Module2=DEBUG");
dmcoomese062a182017-06-12 11:10:31 -0500548 const auto& prefixMap = Logging::get().getLevels();
549 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
550 // "*" is treated as "" internally
551 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::WARN);
552 BOOST_CHECK_EQUAL(prefixMap.at("Module2"), LogLevel::DEBUG);
Junxiao Shi7d054272016-08-04 17:00:41 +0000553 logFromModule1();
554 logFromModule2();
555
556 Logging::flush();
557 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400558 LOG_SYSTIME_STR + " WARN: [Module1] warn1\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000559 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
560 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
561 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400562 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
563 LOG_SYSTIME_STR + " WARN: [Module2] warn2\n" +
Junxiao Shi7d054272016-08-04 17:00:41 +0000564 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
565 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
566 ));
567}
568
569BOOST_AUTO_TEST_CASE(Reset)
570{
571 Logging::setLevel("Module2=DEBUG");
572 Logging::setLevel("*=ERROR");
dmcoomese062a182017-06-12 11:10:31 -0500573 const auto& prefixMap = Logging::get().getLevels();
574 BOOST_CHECK_EQUAL(prefixMap.size(), 1);
575 // "*" is treated as "" internally
576 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::ERROR);
Junxiao Shi7d054272016-08-04 17:00:41 +0000577 logFromModule1();
578 logFromModule2();
579
580 Logging::flush();
581 BOOST_CHECK(os.is_equal(
582 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
583 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
584 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
585 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
586 ));
587}
588
589BOOST_AUTO_TEST_CASE(Malformed)
590{
591 BOOST_CHECK_THROW(Logging::setLevel("Module1=INVALID-LEVEL"), std::invalid_argument);
592 BOOST_CHECK_THROW(Logging::setLevel("Module1-MISSING-EQUAL-SIGN"), std::invalid_argument);
593}
594
dmcoomese062a182017-06-12 11:10:31 -0500595BOOST_AUTO_TEST_CASE(SetFilter)
596{
597 Logging::setLevel("*=FATAL:fm.*=DEBUG");
598 const auto& prefixMap = Logging::get().getLevels();
599 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
600 // "*" is treated as "" internally
601 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
602 // "name.*" is treated as "name." internally
603 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::DEBUG);
604 logFromModule1();
605 logFromFilterModule();
606
607 Logging::flush();
608 BOOST_CHECK(os.is_equal(
609 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
610 LOG_SYSTIME_STR + " DEBUG: [fm.FilterModule] debugFM\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400611 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
612 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500613 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
614 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
615 ));
616}
617
618BOOST_AUTO_TEST_CASE(SetOverrideFilter)
619{
620 Logging::setLevel("*=FATAL:fm.FilterModule=DEBUG");
621 Logging::setLevel("fm.*", LogLevel::INFO);
622 const auto& prefixMap = Logging::get().getLevels();
623 BOOST_CHECK_EQUAL(prefixMap.size(), 2);
624 // "*" is treated as "" internally
625 BOOST_CHECK_EQUAL(prefixMap.at(""), LogLevel::FATAL);
626 // "name.*" is treated as "name." internally
627 BOOST_CHECK_EQUAL(prefixMap.at("fm."), LogLevel::INFO);
628 logFromModule1();
629 logFromFilterModule();
630
631 Logging::flush();
632 BOOST_CHECK(os.is_equal(
633 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400634 LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
635 LOG_SYSTIME_STR + " WARN: [fm.FilterModule] warnFM\n" +
dmcoomese062a182017-06-12 11:10:31 -0500636 LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
637 LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
638 ));
639}
640
641BOOST_AUTO_TEST_CASE(FindPrefixRule)
642{
643 Logging::setLevel("*=FATAL:fm.a.*=ERROR:fm.a.b=INFO");
644 logFromNewLogger("fm.a.b");
645 logFromNewLogger("fm.a.b.c");
646 logFromNewLogger("fm.a.b.d");
647 logFromNewLogger("fm.b");
648
649 Logging::flush();
650 BOOST_CHECK(os.is_equal(
Alexander Afanasyev576b4ff2019-07-05 22:06:04 -0400651 LOG_SYSTIME_STR + " INFO: [fm.a.b] infofm.a.b\n" +
652 LOG_SYSTIME_STR + " WARN: [fm.a.b] warnfm.a.b\n" +
dmcoomese062a182017-06-12 11:10:31 -0500653 LOG_SYSTIME_STR + " ERROR: [fm.a.b] errorfm.a.b\n" +
654 LOG_SYSTIME_STR + " FATAL: [fm.a.b] fatalfm.a.b\n" +
655 LOG_SYSTIME_STR + " ERROR: [fm.a.b.c] errorfm.a.b.c\n" +
656 LOG_SYSTIME_STR + " FATAL: [fm.a.b.c] fatalfm.a.b.c\n" +
657 LOG_SYSTIME_STR + " ERROR: [fm.a.b.d] errorfm.a.b.d\n" +
658 LOG_SYSTIME_STR + " FATAL: [fm.a.b.d] fatalfm.a.b.d\n" +
659 LOG_SYSTIME_STR + " FATAL: [fm.b] fatalfm.b\n"
660 ));
661}
662
Junxiao Shi7d054272016-08-04 17:00:41 +0000663BOOST_AUTO_TEST_SUITE_END() // SeverityConfig
664
665BOOST_AUTO_TEST_CASE(ChangeDestination)
666{
Davide Pesavento1c9c96c2018-04-25 10:45:08 -0400667 using boost::test_tools::output_test_stream;
668
Junxiao Shi7d054272016-08-04 17:00:41 +0000669 logFromModule1();
670
671 auto os2 = make_shared<output_test_stream>();
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400672 Logging::setDestination(Logging::makeDefaultStreamDestination(os2));
Junxiao Shi7d054272016-08-04 17:00:41 +0000673 weak_ptr<output_test_stream> os2weak(os2);
674 os2.reset();
675
676 logFromModule2();
677
678 Logging::flush();
679 os2 = os2weak.lock();
680 BOOST_REQUIRE(os2 != nullptr);
681
682 BOOST_CHECK(os.is_equal(
683 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
684 ));
685 BOOST_CHECK(os2->is_equal(
686 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
687 ));
688
689 os2.reset();
Alexander Afanasyev39535f42019-07-05 22:07:52 -0400690 Logging::setDestination(os, true);
Junxiao Shi7d054272016-08-04 17:00:41 +0000691 BOOST_CHECK(os2weak.expired());
692}
693
Davide Pesavento39cb4022019-11-24 21:15:02 -0500694BOOST_AUTO_TEST_CASE(NullDestination)
Alexander Afanasyev7b2f58c2019-07-13 11:50:19 -0400695{
696 Logging::setDestination(nullptr);
697 logFromModule1();
698
699 Logging::flush();
700 BOOST_CHECK(os.is_equal(""));
701 // The default Boost.Log output is still expected
702}
703
Junxiao Shi7d054272016-08-04 17:00:41 +0000704BOOST_AUTO_TEST_SUITE_END() // TestLogging
705BOOST_AUTO_TEST_SUITE_END() // Util
706
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400707} // namespace ndn::tests