Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snaplogger
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // header being tested
21 : //
22 : #include <snaplogger/message.h>
23 :
24 :
25 : // self
26 : //
27 : #include "catch_main.h"
28 :
29 :
30 : // snaplogger
31 : //
32 : #include <snaplogger/buffer_appender.h>
33 : #include <snaplogger/exception.h>
34 : #include <snaplogger/format.h>
35 : #include <snaplogger/logger.h>
36 : #include <snaplogger/map_diagnostic.h>
37 : #include <snaplogger/severity.h>
38 : #include <snaplogger/version.h>
39 :
40 :
41 : // advgetopt
42 : //
43 : #include <advgetopt/exception.h>
44 :
45 :
46 : // C
47 : //
48 : #include <math.h>
49 : #include <unistd.h>
50 :
51 :
52 :
53 4 : CATCH_TEST_CASE("not_a_message", "[message]")
54 : {
55 4 : CATCH_START_SECTION("message: Call send_message() with wrong ostream")
56 : {
57 1 : CATCH_REQUIRE_THROWS_MATCHES(
58 : snaplogger::send_message(std::cout)
59 : , snaplogger::not_a_message
60 : , Catch::Matchers::ExceptionMessage(
61 : "logger_error: the 'out' parameter to the send_message() function is expected to be a snaplogger::message object."));
62 : }
63 : CATCH_END_SECTION()
64 :
65 4 : CATCH_START_SECTION("message: Print snaplogger::secure to wrong ostream")
66 : {
67 2 : std::stringstream buffer;
68 1 : std::streambuf * old(std::cout.rdbuf(buffer.rdbuf()));
69 1 : std::cout << snaplogger::secure << std::endl;
70 1 : CATCH_REQUIRE(buffer.str() == "(section:secure)\n");
71 1 : std::cout.rdbuf(old);
72 : }
73 : CATCH_END_SECTION()
74 2 : }
75 :
76 :
77 :
78 4 : CATCH_TEST_CASE("message_capture", "[message]")
79 : {
80 4 : CATCH_START_SECTION("message: Buffering")
81 : {
82 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-logging");
83 :
84 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
85 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
86 :
87 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
88 :
89 1 : char const * cargv[] =
90 : {
91 : "/usr/bin/daemon",
92 : nullptr
93 : };
94 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
95 1 : char ** argv = const_cast<char **>(cargv);
96 :
97 1 : advgetopt::options_environment environment_options;
98 1 : environment_options.f_project_name = "test-logger";
99 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
100 2 : advgetopt::getopt opts(environment_options);
101 1 : opts.parse_program_name(argv);
102 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
103 :
104 1 : buffer->set_config(opts);
105 :
106 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity}: ${message}"));
107 1 : buffer->set_format(f);
108 :
109 1 : l->add_appender(buffer);
110 :
111 1 : SNAP_LOG_ERROR << snaplogger::precise_time << "Logging this error" << SNAP_LOG_SEND;
112 1 : CATCH_REQUIRE(buffer->str() == "error: Logging this error\n");
113 :
114 : // test the other str() function too
115 : //
116 1 : buffer->str("Start: ");
117 :
118 : // show that the "\n" does not get duplicated
119 : //
120 1 : SNAP_LOG_ERROR << "Error with newline\n" << SNAP_LOG_SEND;
121 1 : CATCH_REQUIRE(buffer->str() == "Start: error: Error with newline\n");
122 1 : buffer->clear();
123 :
124 : // show that the "\r\n" gets replaced by "\n"
125 : //
126 1 : SNAP_LOG_ERROR << "Error with CRLF\r\n" << SNAP_LOG_SEND;
127 1 : CATCH_REQUIRE(buffer->str() == "error: Error with CRLF\n");
128 1 : buffer->clear();
129 :
130 : // severity too low, no change to buffer
131 : //
132 1 : SNAP_LOG_DEBUG << "Debug Message " << M_PI << " which does not make it at all...\n" << SNAP_LOG_SEND;
133 1 : CATCH_REQUIRE(buffer->empty());
134 :
135 1 : l->reset();
136 : }
137 : CATCH_END_SECTION()
138 :
139 4 : CATCH_START_SECTION("message: JSON Buffering")
140 : {
141 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "json-logging");
142 :
143 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
144 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("json-buffer"));
145 :
146 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
147 :
148 1 : char const * cargv[] =
149 : {
150 : "/usr/bin/daemon",
151 : nullptr
152 : };
153 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
154 1 : char ** argv = const_cast<char **>(cargv);
155 :
156 1 : advgetopt::options_environment environment_options;
157 1 : environment_options.f_project_name = "json-logger";
158 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
159 2 : advgetopt::getopt opts(environment_options);
160 1 : opts.parse_program_name(argv);
161 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
162 :
163 1 : buffer->set_config(opts);
164 :
165 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>(
166 : "{\"version\":1,"
167 2 : "\"message\":\"${message:escape='\\\r\n\t\"'}\"}"));
168 1 : buffer->set_format(f);
169 :
170 1 : l->add_appender(buffer);
171 :
172 3 : SNAP_LOG_ERROR
173 2 : << SNAP_LOG_FIELD(std::string("format"), std::string("json"))
174 : << "A JSON error message (format:${field:name=format})"
175 : << SNAP_LOG_SEND;
176 1 : CATCH_REQUIRE(buffer->str() == "{\"version\":1,\"message\":\"A JSON error message (format:json)\"}\n");
177 1 : buffer->clear();
178 :
179 : // show that the "\n" does not get duplicated
180 : //
181 4 : SNAP_LOG_ERROR
182 : << "See what happens with a \"quoted string\" within the message (${fields})\n"
183 2 : << SNAP_LOG_FIELD(std::string("format"), std::string("json"))
184 2 : << SNAP_LOG_FIELD(std::string("language"), std::string("js"))
185 : << SNAP_LOG_SEND;
186 2 : std::string const expected(std::regex_replace(buffer->str(), std::regex("\\\\\"id\\\\\":\\\\\"[0-9]+\\\\\","), ""));
187 1 : CATCH_REQUIRE(expected == "{\"version\":1,\"message\":\"See what happens with a \\\"quoted string\\\" within the message ({\\\"format\\\":\\\"json\\\",\\\"language\\\":\\\"js\\\"})\"}\n");
188 1 : buffer->clear();
189 :
190 1 : l->reset();
191 : }
192 : CATCH_END_SECTION()
193 2 : }
194 :
195 :
196 3 : CATCH_TEST_CASE("message_copy", "[message]")
197 : {
198 2 : CATCH_START_SECTION("message: Copy")
199 : {
200 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-copying");
201 :
202 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
203 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
204 :
205 1 : CATCH_REQUIRE(buffer->get_type() == "buffer");
206 :
207 1 : char const * cargv[] =
208 : {
209 : "/usr/bin/daemon",
210 : nullptr
211 : };
212 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
213 1 : char ** argv = const_cast<char **>(cargv);
214 :
215 1 : advgetopt::options_environment environment_options;
216 1 : environment_options.f_project_name = "test-logger";
217 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
218 2 : advgetopt::getopt opts(environment_options);
219 1 : opts.parse_program_name(argv);
220 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
221 :
222 1 : buffer->set_config(opts);
223 :
224 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
225 1 : buffer->set_format(f);
226 :
227 1 : l->add_appender(buffer);
228 :
229 1 : int const line_number = __LINE__;
230 1 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
231 2 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, line_number));
232 :
233 1 : CATCH_REQUIRE(msg->get_filename() == __FILE__);
234 1 : CATCH_REQUIRE(msg->get_function() == __func__);
235 1 : CATCH_REQUIRE(msg->get_line() == line_number);
236 :
237 1 : msg->set_filename("logger.cpp");
238 1 : msg->set_function("magical");
239 1 : msg->set_line(701);
240 :
241 1 : CATCH_REQUIRE(msg->get_filename() == "logger.cpp");
242 1 : CATCH_REQUIRE(msg->get_function() == "magical");
243 1 : CATCH_REQUIRE(msg->get_line() == 701);
244 :
245 1 : *msg << "Logging an error.";
246 :
247 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
248 :
249 2 : snaplogger::message::pointer_t copy(std::make_shared<snaplogger::message>(*msg, *msg));
250 :
251 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
252 1 : CATCH_REQUIRE(copy->str() == "Logging an error.");
253 :
254 : // no destructor called, the output is still empty
255 : //
256 1 : CATCH_REQUIRE(buffer->empty());
257 :
258 1 : copy.reset();
259 :
260 : // msg not lost
261 : //
262 1 : CATCH_REQUIRE(msg->str() == "Logging an error.");
263 :
264 : // destructor against copy does not trigger send_message()
265 : //
266 1 : CATCH_REQUIRE(buffer->empty());
267 :
268 1 : snaplogger::send_message(*msg);
269 :
270 : // now we get the message as expected!
271 : //
272 : // (note that internally we can skip receiving the message on the
273 : // original, but not as a client... we may want to have the ability
274 : // to cancel a message, though.)
275 : //
276 1 : CATCH_REQUIRE(buffer->str() == "Logging an error.\n");
277 :
278 1 : msg.reset();
279 :
280 1 : CATCH_REQUIRE(buffer->str() == "Logging an error.\n");
281 :
282 1 : l->reset();
283 : }
284 : CATCH_END_SECTION()
285 1 : }
286 :
287 :
288 4 : CATCH_TEST_CASE("message_severity", "[message][severity]")
289 : {
290 4 : CATCH_START_SECTION("message: Appender vs Message severity")
291 : {
292 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-severity");
293 :
294 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
295 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
296 :
297 1 : char const * cargv[] =
298 : {
299 : "/usr/bin/daemon",
300 : nullptr
301 : };
302 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
303 1 : char ** argv = const_cast<char **>(cargv);
304 :
305 1 : advgetopt::options_environment environment_options;
306 1 : environment_options.f_project_name = "test-logger";
307 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
308 2 : advgetopt::getopt opts(environment_options);
309 1 : opts.parse_program_name(argv);
310 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
311 :
312 1 : buffer->set_config(opts);
313 :
314 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
315 1 : buffer->set_format(f);
316 :
317 1 : l->add_appender(buffer);
318 :
319 1 : int const min_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MIN));
320 1 : int const max_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MAX));
321 257 : for(int i(min_severity); i <= max_severity; ++i)
322 : {
323 256 : buffer->set_severity(static_cast<snaplogger::severity_t>(i));
324 65792 : for(int j(min_severity); j <= max_severity; ++j)
325 : {
326 131072 : snaplogger::send_message(
327 131072 : *::snaplogger::create_message(
328 : static_cast<::snaplogger::severity_t>(j)
329 : , __FILE__
330 : , __func__
331 : , __LINE__
332 65536 : ) << "The message itself");
333 :
334 65536 : if(j >= i
335 32896 : && i != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF)
336 32895 : && j != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
337 : {
338 32640 : CATCH_REQUIRE(buffer->str() == "The message itself\n");
339 : }
340 : else
341 : {
342 32896 : CATCH_REQUIRE(buffer->empty());
343 : }
344 65536 : buffer->clear();
345 : }
346 : }
347 :
348 1 : l->reset();
349 : }
350 : CATCH_END_SECTION()
351 :
352 4 : CATCH_START_SECTION("message: Changing message severity (takes about 3.5min)")
353 : {
354 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-copying");
355 :
356 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
357 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
358 :
359 1 : char const * cargv[] =
360 : {
361 : "/usr/bin/daemon",
362 : nullptr
363 : };
364 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
365 1 : char ** argv = const_cast<char **>(cargv);
366 :
367 1 : advgetopt::options_environment environment_options;
368 1 : environment_options.f_project_name = "test-logger";
369 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
370 2 : advgetopt::getopt opts(environment_options);
371 1 : opts.parse_program_name(argv);
372 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
373 :
374 1 : buffer->set_config(opts);
375 :
376 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
377 1 : buffer->set_format(f);
378 :
379 1 : l->add_appender(buffer);
380 :
381 1 : int const min_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MIN));
382 1 : int const max_severity(static_cast<int>(snaplogger::severity_t::SEVERITY_MAX));
383 34 : for(int i(min_severity); i <= max_severity; i += 1 + (rand() & 15))
384 : {
385 33 : buffer->set_severity(static_cast<snaplogger::severity_t>(i));
386 1017 : for(int j(min_severity); j <= max_severity; j += 1 + (rand() & 15))
387 : {
388 31213 : for(int k(min_severity); k <= max_severity; k += 1 + (rand() & 15))
389 : {
390 30229 : ::snaplogger::message::pointer_t msg(std::make_shared<::snaplogger::message>(
391 60458 : static_cast<::snaplogger::severity_t>(j)
392 : , __FILE__
393 : , __func__
394 : , __LINE__
395 120916 : ));
396 30229 : *msg << "Start of message";
397 30229 : msg->set_severity(static_cast<::snaplogger::severity_t>(k));
398 30229 : *msg << " -- end of message";
399 30229 : snaplogger::send_message(*msg);
400 : //std::cerr << "checking with " << i << ", " << j << ", " << k << "\n";
401 :
402 30229 : if(j >= i
403 14114 : && k >= i
404 9173 : && i != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF)
405 9173 : && j != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
406 : //&& k != static_cast<int>(snaplogger::severity_t::SEVERITY_OFF))
407 : {
408 9173 : if(j >= i)
409 : {
410 9173 : CATCH_REQUIRE(buffer->str() == "Start of message -- end of message\n");
411 : }
412 : else
413 : {
414 0 : CATCH_REQUIRE(buffer->str() == "Start of message\n");
415 9173 : }
416 : }
417 : else
418 : {
419 21056 : CATCH_REQUIRE(buffer->empty());
420 : }
421 30229 : buffer->clear();
422 : }
423 : }
424 : }
425 :
426 1 : l->reset();
427 : }
428 : CATCH_END_SECTION()
429 2 : }
430 :
431 :
432 6 : CATCH_TEST_CASE("message_format", "[message][format]")
433 : {
434 8 : CATCH_START_SECTION("message: Recursivity")
435 : {
436 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "basic-format");
437 :
438 : // these two are not called in this test
439 : //
440 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROJECT_NAME, "test-logger");
441 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_VERSION, "5.32.1024");
442 :
443 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
444 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
445 :
446 1 : char const * cargv[] =
447 : {
448 : "/usr/bin/daemon",
449 : nullptr
450 : };
451 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
452 1 : char ** argv = const_cast<char **>(cargv);
453 :
454 1 : advgetopt::options_environment environment_options;
455 1 : environment_options.f_project_name = "test-logger";
456 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
457 1 : environment_options.f_version = "5.32.1024";
458 2 : advgetopt::getopt opts(environment_options);
459 1 : opts.parse_program_name(argv);
460 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
461 :
462 1 : buffer->set_config(opts);
463 :
464 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${project_name} ${message} v${version}"));
465 1 : buffer->set_format(f);
466 :
467 1 : l->add_appender(buffer);
468 :
469 1 : SNAP_LOG_WARNING
470 : << "Message Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
471 : << SNAP_LOG_SEND;
472 :
473 1 : CATCH_REQUIRE(buffer->str() ==
474 : "test-logger Message Project Name = test-logger and"
475 : " Version = 5.32.1024 -- uses \"recursive\" v5.32.1024"
476 : "\n");
477 :
478 1 : l->reset();
479 : }
480 : CATCH_END_SECTION()
481 :
482 8 : CATCH_START_SECTION("message: ${message} itself is not recursive")
483 : {
484 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "prevent-infinite-loop");
485 :
486 : // these two are not called in this test
487 : //
488 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROJECT_NAME, "test-logger");
489 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_VERSION, "5.32.1024");
490 :
491 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
492 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
493 :
494 1 : char const * cargv[] =
495 : {
496 : "/usr/bin/daemon",
497 : nullptr
498 : };
499 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
500 1 : char ** argv = const_cast<char **>(cargv);
501 :
502 1 : advgetopt::options_environment environment_options;
503 1 : environment_options.f_project_name = "test-logger";
504 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
505 1 : environment_options.f_version = "5.32.1024";
506 2 : advgetopt::getopt opts(environment_options);
507 1 : opts.parse_program_name(argv);
508 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
509 :
510 1 : buffer->set_config(opts);
511 :
512 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${project_name} ${message} v${version}"));
513 1 : buffer->set_format(f);
514 :
515 1 : l->add_appender(buffer);
516 :
517 1 : SNAP_LOG_WARNING
518 : << "Message ${message} says: Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
519 : << SNAP_LOG_SEND;
520 :
521 1 : CATCH_REQUIRE(buffer->str() ==
522 : "test-logger Message says: Project Name = test-logger and"
523 : " Version = 5.32.1024 -- uses \"recursive\" v5.32.1024"
524 : "\n");
525 :
526 1 : buffer->clear();
527 :
528 1 : snaplogger::unset_diagnostic(snaplogger::DIAG_KEY_VERSION);
529 :
530 1 : SNAP_LOG_WARNING
531 : << "Removed the version: ${message} says: Project Name = ${project_name} and Version = ${version} -- uses \"recursive\""
532 : << SNAP_LOG_SEND;
533 :
534 1 : CATCH_REQUIRE(buffer->str() ==
535 : "test-logger Removed the version: says: Project Name = test-logger and"
536 : " Version = -- uses \"recursive\" v"
537 : "\n");
538 :
539 1 : l->reset();
540 : }
541 : CATCH_END_SECTION()
542 :
543 8 : CATCH_START_SECTION("message: ${pid} uses the get_environment() function")
544 : {
545 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "get-environment");
546 :
547 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
548 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
549 :
550 1 : char const * cargv[] =
551 : {
552 : "/usr/bin/daemon",
553 : nullptr
554 : };
555 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
556 1 : char ** argv = const_cast<char **>(cargv);
557 :
558 1 : advgetopt::options_environment environment_options;
559 1 : environment_options.f_project_name = "test-logger";
560 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
561 2 : advgetopt::getopt opts(environment_options);
562 1 : opts.parse_program_name(argv);
563 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
564 :
565 1 : buffer->set_config(opts);
566 :
567 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
568 1 : buffer->set_format(f);
569 :
570 1 : l->add_appender(buffer);
571 :
572 1 : SNAP_LOG_WARNING
573 : << "Test PID = ${pid} == ${pid:running}"
574 : << SNAP_LOG_SEND;
575 :
576 1 : CATCH_REQUIRE(buffer->str() ==
577 : "Test PID = " + std::to_string(getpid())
578 : + " == " + std::to_string(getpid())
579 : + "\n");
580 :
581 1 : l->reset();
582 : }
583 : CATCH_END_SECTION()
584 :
585 8 : CATCH_START_SECTION("message: Verify year")
586 : {
587 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "get-environment");
588 :
589 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
590 1 : CATCH_REQUIRE(l->get_appender("test-buffer") == nullptr);
591 :
592 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
593 :
594 1 : char const * cargv[] =
595 : {
596 : "/usr/bin/daemon",
597 : nullptr
598 : };
599 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
600 1 : char ** argv = const_cast<char **>(cargv);
601 :
602 1 : advgetopt::options_environment environment_options;
603 1 : environment_options.f_project_name = "test-logger";
604 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
605 2 : advgetopt::getopt opts(environment_options);
606 1 : opts.parse_program_name(argv);
607 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
608 :
609 1 : buffer->set_config(opts);
610 :
611 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message}"));
612 1 : buffer->set_format(f);
613 :
614 1 : l->add_appender(buffer);
615 :
616 1 : CATCH_REQUIRE(l->get_appender("test-buffer") == buffer);
617 :
618 : // we create a message so we can check the timestamp in our test
619 : //
620 1 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
621 2 : (::snaplogger::severity_t::SEVERITY_ERROR, __FILE__, __func__, __LINE__));
622 1 : *msg << "Created message on YYYY = ${date:year}, MM = ${date:month}, DD = ${date:day}";
623 :
624 1 : timespec const stamp(msg->get_timestamp());
625 :
626 1 : snaplogger::send_message(*msg);
627 :
628 1 : tm t;
629 1 : gmtime_r(&stamp.tv_sec, &t);
630 1 : char year[16];
631 1 : char month[16];
632 1 : char day[16];
633 1 : strftime(year, 16, "%Y", &t);
634 1 : strftime(month, 16, "%m", &t);
635 1 : strftime(day, 16, "%d", &t);
636 :
637 1 : CATCH_REQUIRE(buffer->str() ==
638 : std::string("Created message on YYYY = ")
639 : + year
640 : + ", MM = "
641 : + std::to_string(std::atoi(month)) // remove the leading '0' if necessary
642 : + ", DD = "
643 : + std::to_string(std::atoi(day)) // remove the leading '0' if necessary
644 : + "\n");
645 :
646 1 : l->reset();
647 : }
648 : CATCH_END_SECTION()
649 4 : }
650 :
651 :
652 3 : CATCH_TEST_CASE("message_component_filter", "[message][component]")
653 : {
654 2 : CATCH_START_SECTION("message: Filter Message with Component")
655 : {
656 1 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "component-filter");
657 :
658 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
659 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
660 :
661 1 : char const * cargv[] =
662 : {
663 : "/usr/bin/daemon",
664 : nullptr
665 : };
666 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
667 1 : char ** argv = const_cast<char **>(cargv);
668 :
669 1 : advgetopt::options_environment environment_options;
670 1 : environment_options.f_project_name = "test-logger";
671 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
672 2 : advgetopt::getopt opts(environment_options);
673 1 : opts.parse_program_name(argv);
674 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
675 :
676 1 : buffer->set_config(opts);
677 :
678 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message} (${severity:format=number})"));
679 1 : buffer->set_format(f);
680 :
681 1 : l->add_appender(buffer);
682 :
683 2 : SNAP_LOG_WARNING
684 1 : << snaplogger::secure // mark as a secure message
685 : << "This message is secure but not the buffer"
686 : << SNAP_LOG_SEND;
687 :
688 1 : CATCH_REQUIRE(buffer->empty());
689 :
690 2 : SNAP_LOG_WARNING
691 1 : << "Test number: "
692 : << 2
693 1 : << " with buffer still unsecure..."
694 1 : << SNAP_LOG_SEND_SECURELY; // mark at the end
695 :
696 1 : CATCH_REQUIRE(buffer->empty());
697 :
698 : // mark the buffer as a secure buffer now
699 : //
700 1 : buffer->add_component(snaplogger::g_secure_component);
701 :
702 2 : SNAP_LOG_WARNING
703 1 : << snaplogger::secure // mark as a secure message
704 : << "This message is secure and so is the buffer"
705 : << SNAP_LOG_SEND;
706 :
707 : // TODO: get the WARNING severity level dynamically
708 1 : CATCH_REQUIRE(buffer->str() == "This message is secure and so is the buffer (" + std::to_string(static_cast<int>(snaplogger::severity_t::SEVERITY_WARNING)) + ")\n");
709 :
710 1 : buffer->clear();
711 :
712 2 : SNAP_LOG_WARNING
713 1 : << "Test number: "
714 : << 4
715 1 : << " with secure buffer...\r\n"
716 1 : << SNAP_LOG_SEND_SECURELY; // mark at the end
717 :
718 : // TODO: get the WARNING severity level dynamically
719 1 : CATCH_REQUIRE(buffer->str() == "Test number: 4 with secure buffer... (" + std::to_string(static_cast<int>(snaplogger::severity_t::SEVERITY_WARNING)) + ")\n");
720 :
721 1 : l->reset();
722 : }
723 : CATCH_END_SECTION()
724 1 : }
725 :
726 :
727 :
728 4 : CATCH_TEST_CASE("message_exception", "[message][exception]")
729 : {
730 4 : CATCH_START_SECTION("message: Use '... << exception << ...")
731 : {
732 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
733 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
734 :
735 1 : char const * cargv[] =
736 : {
737 : "/usr/bin/daemon",
738 : nullptr
739 : };
740 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
741 1 : char ** argv = const_cast<char **>(cargv);
742 :
743 1 : advgetopt::options_environment environment_options;
744 1 : environment_options.f_project_name = "test-logger";
745 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
746 2 : advgetopt::getopt opts(environment_options);
747 1 : opts.parse_program_name(argv);
748 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
749 :
750 1 : buffer->set_config(opts);
751 :
752 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>(
753 2 : "${message} (${severity:format=number}) exit code: ${field:name=exception_exit_code}"));
754 1 : buffer->set_format(f);
755 :
756 1 : l->add_appender(buffer);
757 :
758 2 : advgetopt::getopt_exit const error("testing an exception -> logging", 123);
759 :
760 1 : SNAP_LOG_WARNING
761 : << "We got an exception! ["
762 : << error
763 : << "]"
764 : << SNAP_LOG_SEND;
765 :
766 1 : CATCH_REQUIRE_FALSE(buffer->empty());
767 :
768 1 : std::string const expected("We got an exception! [getopt_exception: testing an exception -> logging] ("
769 2 : + std::to_string(static_cast<int>(::snaplogger::severity_t::SEVERITY_WARNING))
770 3 : + ") exit code: 123\n");
771 1 : CATCH_REQUIRE(buffer->str() == expected);
772 :
773 1 : buffer->clear();
774 :
775 1 : l->reset();
776 : }
777 : CATCH_END_SECTION()
778 :
779 4 : CATCH_START_SECTION("message: Use '... << stringstream << ...")
780 : {
781 2 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
782 2 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
783 :
784 1 : char const * cargv[] =
785 : {
786 : "/usr/bin/daemon",
787 : nullptr
788 : };
789 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
790 1 : char ** argv = const_cast<char **>(cargv);
791 :
792 1 : advgetopt::options_environment environment_options;
793 1 : environment_options.f_project_name = "test-logger";
794 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
795 2 : advgetopt::getopt opts(environment_options);
796 1 : opts.parse_program_name(argv);
797 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
798 :
799 1 : buffer->set_config(opts);
800 :
801 2 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message} (${severity:format=number})"));
802 1 : buffer->set_format(f);
803 :
804 1 : l->add_appender(buffer);
805 :
806 2 : std::stringstream ss;
807 1 : ss << "testing that we can also \"send\" the content of a string stream";
808 :
809 1 : SNAP_LOG_WARNING
810 : << "We got an exception! ["
811 : << ss
812 : << "]"
813 : << SNAP_LOG_SEND;
814 :
815 1 : CATCH_REQUIRE_FALSE(buffer->empty());
816 :
817 1 : std::string const expected("We got an exception! [testing that we can also \"send\" the content of a string stream] ("
818 2 : + std::to_string(static_cast<int>(::snaplogger::severity_t::SEVERITY_WARNING))
819 3 : + ")\n");
820 1 : CATCH_REQUIRE(buffer->str() == expected);
821 :
822 1 : buffer->clear();
823 :
824 1 : l->reset();
825 : }
826 : CATCH_END_SECTION()
827 8 : }
828 :
829 :
830 :
831 : // vim: ts=4 sw=4 et
|