blob: 3447968e01c8f6c879f7709443061e1021a43c92 [file] [log] [blame]
Junxiao Shi7d054272016-08-04 17:00:41 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev354f3822017-03-27 15:26:41 -05003 * Copyright (c) 2013-2017 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
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
Alexander Afanasyev354f3822017-03-27 15:26:41 -050033NDN_LOG_INIT(ndn.util.tests.Logging);
34
Junxiao Shi7d054272016-08-04 17:00:41 +000035using namespace ndn::tests;
36using boost::test_tools::output_test_stream;
37
38void
39logFromModule1();
40
41void
42logFromModule2();
43
44void
45logFromNewLogger(const std::string& moduleName)
46{
47 // clang complains -Wreturn-stack-address on OSX-10.9 if Logger is allocated on stack
48 auto loggerPtr = make_unique<Logger>(moduleName);
49 Logger& logger = *loggerPtr;
50
51 auto getNdnCxxLogger = [&logger] () -> Logger& { return logger; };
Junxiao Shi1fe7ce52016-08-08 05:48:02 +000052 NDN_LOG_TRACE("trace" << moduleName);
53 NDN_LOG_DEBUG("debug" << moduleName);
54 NDN_LOG_INFO("info" << moduleName);
55 NDN_LOG_WARN("warn" << moduleName);
56 NDN_LOG_ERROR("error" << moduleName);
57 NDN_LOG_FATAL("fatal" << moduleName);
Junxiao Shi7d054272016-08-04 17:00:41 +000058
59 BOOST_CHECK(Logging::get().removeLogger(logger));
60}
61
62const time::system_clock::Duration LOG_SYSTIME = time::microseconds(1468108800311239LL);
63const std::string LOG_SYSTIME_STR = "1468108800.311239";
64
65class LoggingFixture : public UnitTestTimeFixture
66{
67protected:
68 explicit
69 LoggingFixture()
70 : m_oldLevels(Logging::get().getLevels())
71 , m_oldDestination(Logging::get().getDestination())
72 {
73 this->systemClock->setNow(LOG_SYSTIME);
74 Logging::get().resetLevels();
75 Logging::setDestination(os);
76 }
77
78 ~LoggingFixture()
79 {
80 Logging::setLevel(m_oldLevels);
81 Logging::setDestination(m_oldDestination);
82 }
83
84protected:
85 output_test_stream os;
86
87private:
88 std::string m_oldLevels;
89 shared_ptr<std::ostream> m_oldDestination;
90};
91
92BOOST_AUTO_TEST_SUITE(Util)
93BOOST_FIXTURE_TEST_SUITE(TestLogging, LoggingFixture)
94
Alexander Afanasyev354f3822017-03-27 15:26:41 -050095BOOST_AUTO_TEST_CASE(GetLoggerNames)
96{
97 NDN_LOG_TRACE("GetLoggerNames"); // to avoid unused function warning
98 std::set<std::string> names = Logging::getLoggerNames();
99 BOOST_CHECK_GT(names.size(), 0);
100 BOOST_CHECK_EQUAL(names.count("ndn.util.tests.Logging"), 1);
101}
102
Junxiao Shi7d054272016-08-04 17:00:41 +0000103BOOST_AUTO_TEST_SUITE(Severity)
104
105BOOST_AUTO_TEST_CASE(None)
106{
107 Logging::setLevel("Module1", LogLevel::NONE);
108 logFromModule1();
109
110 Logging::flush();
111 BOOST_CHECK(os.is_equal(
112 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
113 ));
114}
115
116BOOST_AUTO_TEST_CASE(Error)
117{
118 Logging::setLevel("Module1", LogLevel::ERROR);
119 logFromModule1();
120
121 Logging::flush();
122 BOOST_CHECK(os.is_equal(
123 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
124 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
125 ));
126}
127
128BOOST_AUTO_TEST_CASE(Warn)
129{
130 Logging::setLevel("Module1", LogLevel::WARN);
131 logFromModule1();
132
133 Logging::flush();
134 BOOST_CHECK(os.is_equal(
135 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
136 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
137 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
138 ));
139}
140
141BOOST_AUTO_TEST_CASE(Info)
142{
143 Logging::setLevel("Module1", LogLevel::INFO);
144 logFromModule1();
145
146 Logging::flush();
147 BOOST_CHECK(os.is_equal(
148 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
149 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
150 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
151 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
152 ));
153}
154
155BOOST_AUTO_TEST_CASE(Debug)
156{
157 Logging::setLevel("Module1", LogLevel::DEBUG);
158 logFromModule1();
159
160 Logging::flush();
161 BOOST_CHECK(os.is_equal(
162 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
163 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
164 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
165 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
166 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
167 ));
168}
169
170BOOST_AUTO_TEST_CASE(Trace)
171{
172 Logging::setLevel("Module1", LogLevel::TRACE);
173 logFromModule1();
174
175 Logging::flush();
176 BOOST_CHECK(os.is_equal(
177 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
178 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
179 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
180 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
181 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
182 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
183 ));
184}
185
186BOOST_AUTO_TEST_CASE(All)
187{
188 Logging::setLevel("Module1", LogLevel::ALL);
189 logFromModule1();
190
191 Logging::flush();
192 BOOST_CHECK(os.is_equal(
193 LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
194 LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
195 LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
196 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
197 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
198 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
199 ));
200}
201
202BOOST_AUTO_TEST_SUITE_END() // Severity
203
204BOOST_AUTO_TEST_CASE(SameNameLoggers)
205{
206 Logging::setLevel("Module1", LogLevel::WARN);
207 logFromModule1();
208 logFromNewLogger("Module1");
209
210 Logging::flush();
211 BOOST_CHECK(os.is_equal(
212 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
213 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
214 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
215 LOG_SYSTIME_STR + " WARNING: [Module1] warnModule1\n" +
216 LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
217 LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
218 ));
219}
220
221BOOST_AUTO_TEST_CASE(LateRegistration)
222{
223 BOOST_CHECK_NO_THROW(Logging::setLevel("Module3", LogLevel::DEBUG));
224 logFromNewLogger("Module3");
225
226 Logging::flush();
227 BOOST_CHECK(os.is_equal(
228 LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
229 LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
230 LOG_SYSTIME_STR + " WARNING: [Module3] warnModule3\n" +
231 LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
232 LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
233 ));
234}
235
236BOOST_AUTO_TEST_SUITE(DefaultSeverity)
237
238BOOST_AUTO_TEST_CASE(Unset)
239{
240 logFromModule1();
241 logFromModule2();
242
243 Logging::flush();
244 BOOST_CHECK(os.is_equal(
245 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
246 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
247 ));
248}
249
250BOOST_AUTO_TEST_CASE(NoOverride)
251{
252 Logging::setLevel("*", LogLevel::WARN);
253 logFromModule1();
254 logFromModule2();
255
256 Logging::flush();
257 BOOST_CHECK(os.is_equal(
258 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
259 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
260 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
261 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
262 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
263 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
264 ));
265}
266
267BOOST_AUTO_TEST_CASE(Override)
268{
269 Logging::setLevel("*", LogLevel::WARN);
270 Logging::setLevel("Module2", LogLevel::DEBUG);
271 logFromModule1();
272 logFromModule2();
273
274 Logging::flush();
275 BOOST_CHECK(os.is_equal(
276 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
277 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
278 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
279 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
280 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
281 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
282 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
283 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
284 ));
285}
286
287BOOST_AUTO_TEST_SUITE_END() // DefaultSeverity
288
289BOOST_AUTO_TEST_SUITE(SeverityConfig)
290
291BOOST_AUTO_TEST_CASE(SetEmpty)
292{
293 Logging::setLevel("");
294 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "");
295 logFromModule1();
296 logFromModule2();
297
298 Logging::flush();
299 BOOST_CHECK(os.is_equal(
300 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
301 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
302 ));
303}
304
305BOOST_AUTO_TEST_CASE(SetDefault)
306{
307 Logging::setLevel("*=WARN");
308 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN");
309 logFromModule1();
310 logFromModule2();
311
312 Logging::flush();
313 BOOST_CHECK(os.is_equal(
314 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
315 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
316 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
317 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
318 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
319 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
320 ));
321}
322
323BOOST_AUTO_TEST_CASE(SetModule)
324{
325 Logging::setLevel("Module1=ERROR");
326 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "Module1=ERROR");
327 logFromModule1();
328 logFromModule2();
329
330 Logging::flush();
331 BOOST_CHECK(os.is_equal(
332 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
333 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
334 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
335 ));
336}
337
338BOOST_AUTO_TEST_CASE(SetOverride)
339{
340 Logging::setLevel("*=WARN:Module2=DEBUG");
341 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN:Module2=DEBUG");
342 logFromModule1();
343 logFromModule2();
344
345 Logging::flush();
346 BOOST_CHECK(os.is_equal(
347 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
348 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
349 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
350 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
351 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
352 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
353 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
354 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
355 ));
356}
357
358BOOST_AUTO_TEST_CASE(SetTwice)
359{
360 Logging::setLevel("*=WARN");
361 Logging::setLevel("Module2=DEBUG");
362 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=WARN:Module2=DEBUG");
363 logFromModule1();
364 logFromModule2();
365
366 Logging::flush();
367 BOOST_CHECK(os.is_equal(
368 LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
369 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
370 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
371 LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
372 LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
373 LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
374 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
375 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
376 ));
377}
378
379BOOST_AUTO_TEST_CASE(Reset)
380{
381 Logging::setLevel("Module2=DEBUG");
382 Logging::setLevel("*=ERROR");
383 BOOST_CHECK_EQUAL(Logging::get().getLevels(), "*=ERROR");
384 logFromModule1();
385 logFromModule2();
386
387 Logging::flush();
388 BOOST_CHECK(os.is_equal(
389 LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
390 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
391 LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
392 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
393 ));
394}
395
396BOOST_AUTO_TEST_CASE(Malformed)
397{
398 BOOST_CHECK_THROW(Logging::setLevel("Module1=INVALID-LEVEL"), std::invalid_argument);
399 BOOST_CHECK_THROW(Logging::setLevel("Module1-MISSING-EQUAL-SIGN"), std::invalid_argument);
400}
401
402BOOST_AUTO_TEST_SUITE_END() // SeverityConfig
403
404BOOST_AUTO_TEST_CASE(ChangeDestination)
405{
406 logFromModule1();
407
408 auto os2 = make_shared<output_test_stream>();
409 Logging::setDestination(os2);
410 weak_ptr<output_test_stream> os2weak(os2);
411 os2.reset();
412
413 logFromModule2();
414
415 Logging::flush();
416 os2 = os2weak.lock();
417 BOOST_REQUIRE(os2 != nullptr);
418
419 BOOST_CHECK(os.is_equal(
420 LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
421 ));
422 BOOST_CHECK(os2->is_equal(
423 LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
424 ));
425
426 os2.reset();
427 Logging::setDestination(os);
428 BOOST_CHECK(os2weak.expired());
429}
430
431BOOST_AUTO_TEST_SUITE_END() // TestLogging
432BOOST_AUTO_TEST_SUITE_END() // Util
433
434} // namespace tests
435} // namespace util
436} // namespace ndn