Line data Source code
1 : // Copyright (c) 2006-2025 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 3 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
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // self
20 : //
21 : #include "catch_main.h"
22 :
23 :
24 : // snaplogger
25 : //
26 : #include <snaplogger/buffer_appender.h>
27 : #include <snaplogger/exception.h>
28 : #include <snaplogger/format.h>
29 : #include <snaplogger/logger.h>
30 : #include <snaplogger/map_diagnostic.h>
31 : #include <snaplogger/message.h>
32 : #include <snaplogger/severity.h>
33 : #include <snaplogger/version.h>
34 :
35 :
36 : // C
37 : //
38 : #include <unistd.h>
39 : #include <netdb.h>
40 : #include <sys/param.h>
41 :
42 :
43 :
44 :
45 :
46 1 : CATCH_TEST_CASE("variable_param", "[variable][param][error]")
47 : {
48 1 : CATCH_START_SECTION("variable: Param Name is Mandatory")
49 : {
50 6 : CATCH_REQUIRE_THROWS_MATCHES(
51 : new snaplogger::param(std::string())
52 : , snaplogger::invalid_parameter
53 : , Catch::Matchers::ExceptionMessage(
54 : "logger_error: a parameter must have a non-empty name."));
55 : }
56 1 : CATCH_END_SECTION()
57 1 : }
58 :
59 :
60 :
61 7 : CATCH_TEST_CASE("system_variable", "[variable][param]")
62 : {
63 7 : CATCH_START_SECTION("variable: get_type() to use padding as integer or string (hostname)")
64 : {
65 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-logging");
66 :
67 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
68 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
69 :
70 1 : char const * cargv[] =
71 : {
72 : "/usr/bin/daemon",
73 : nullptr
74 : };
75 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
76 1 : char ** argv = const_cast<char **>(cargv);
77 :
78 1 : advgetopt::options_environment environment_options;
79 1 : environment_options.f_project_name = "test-logger";
80 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
81 1 : advgetopt::getopt opts(environment_options);
82 1 : opts.parse_program_name(argv);
83 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
84 :
85 1 : buffer->set_config(opts);
86 :
87 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname:padding=3:align=right:min_width=30} ${message}"));
88 1 : buffer->set_format(f);
89 :
90 1 : l->add_appender(buffer);
91 :
92 1 : char host[HOST_NAME_MAX + 2 + 30];
93 1 : CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
94 1 : host[HOST_NAME_MAX + 1] = '\0';
95 3 : std::string aligned(host);
96 24 : while(aligned.length() < 30)
97 : {
98 23 : aligned = "3" + aligned;
99 : }
100 :
101 2 : SNAP_LOG_ERROR << "Check the param::get_type()" << SNAP_LOG_SEND;
102 1 : CATCH_REQUIRE(buffer->str() == aligned + " Check the param::get_type()\n");
103 :
104 1 : buffer->clear();
105 :
106 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"t\":align=center:min_width=30} ${message}");
107 1 : buffer->set_format(f);
108 :
109 1 : aligned = host;
110 1 : std::string::size_type const low((30 - aligned.length()) / 2 + aligned.length());
111 12 : while(aligned.length() < low)
112 : {
113 11 : aligned = "t" + aligned;
114 : }
115 13 : while(aligned.length() < 30)
116 : {
117 12 : aligned = aligned + "t";
118 : }
119 :
120 2 : SNAP_LOG_ERROR << "Try again with a string" << SNAP_LOG_SEND;
121 1 : CATCH_REQUIRE(buffer->str() == aligned + " Try again with a string\n");
122 :
123 1 : buffer->clear();
124 :
125 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=center:max_width=30}");
126 1 : buffer->set_format(f);
127 :
128 2 : SNAP_LOG_ERROR << "This message will have a maximum width of 30 chars" << SNAP_LOG_SEND;
129 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " ge will have a maximum width o\n");
130 :
131 1 : buffer->clear();
132 :
133 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=right:max_width=25}");
134 1 : buffer->set_format(f);
135 :
136 2 : SNAP_LOG_ERROR << "This message will have a maximum width of 25 chars" << SNAP_LOG_SEND;
137 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " maximum width of 25 chars\n");
138 :
139 1 : buffer->clear();
140 :
141 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=center:min_width=25}");
142 1 : buffer->set_format(f);
143 :
144 2 : SNAP_LOG_ERROR << "minimum width 25" << SNAP_LOG_SEND;
145 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " ttttminimum width 25ttttt\n");
146 :
147 1 : buffer->clear();
148 :
149 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=left:min_width=25}");
150 1 : buffer->set_format(f);
151 :
152 2 : SNAP_LOG_ERROR << "minimum width 25" << SNAP_LOG_SEND;
153 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " minimum width 25ttttttttt\n");
154 :
155 1 : buffer->clear();
156 :
157 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=left:exact_width=25}");
158 1 : buffer->set_format(f);
159 :
160 2 : SNAP_LOG_ERROR << "First we get this message cut to the specified width." << SNAP_LOG_SEND;
161 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " First we get this message\n");
162 :
163 1 : buffer->clear();
164 :
165 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=center:exact_width=25}");
166 1 : buffer->set_format(f);
167 :
168 2 : SNAP_LOG_ERROR << "First we get this message cut to the specified width." << SNAP_LOG_SEND;
169 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " his message cut to the sp\n");
170 :
171 1 : buffer->clear();
172 :
173 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"t\":align=right:exact_width=25}");
174 1 : buffer->set_format(f);
175 :
176 2 : SNAP_LOG_ERROR << "First we get this message cut to the specified width." << SNAP_LOG_SEND;
177 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " t to the specified width.\n");
178 :
179 1 : buffer->clear();
180 :
181 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"x\":align=left:exact_width=25}");
182 1 : buffer->set_format(f);
183 :
184 2 : SNAP_LOG_ERROR << "Small Message" << SNAP_LOG_SEND;
185 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " Small Messagexxxxxxxxxxxx\n");
186 :
187 1 : buffer->clear();
188 :
189 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"x\":align=center:exact_width=25}");
190 1 : buffer->set_format(f);
191 :
192 2 : SNAP_LOG_ERROR << "Small Message" << SNAP_LOG_SEND;
193 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " xxxxxxSmall Messagexxxxxx\n");
194 :
195 1 : buffer->clear();
196 :
197 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"x\":align=center:exact_width=25}");
198 1 : buffer->set_format(f);
199 :
200 2 : SNAP_LOG_ERROR << "Small Message (even)" << SNAP_LOG_SEND;
201 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " xxSmall Message (even)xxx\n");
202 :
203 1 : buffer->clear();
204 :
205 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:padding=\"x\":align=right:exact_width=25}");
206 1 : buffer->set_format(f);
207 :
208 2 : SNAP_LOG_ERROR << "Small Message" << SNAP_LOG_SEND;
209 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " xxxxxxxxxxxxSmall Message\n");
210 :
211 1 : buffer->clear();
212 :
213 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:prepend=\"(P) \":padding=\"z\":align=right:exact_width=25}");
214 1 : buffer->set_format(f);
215 :
216 2 : SNAP_LOG_ERROR << "Small Message" << SNAP_LOG_SEND;
217 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " zzzzzzzz(P) Small Message\n");
218 :
219 1 : buffer->clear();
220 :
221 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:append=\" (A)\":padding=\"z\":align=right:exact_width=25}");
222 1 : buffer->set_format(f);
223 :
224 2 : SNAP_LOG_ERROR << "Small Message" << SNAP_LOG_SEND;
225 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " zzzzzzzzSmall Message (A)\n");
226 :
227 1 : buffer->clear();
228 :
229 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"q\":align=101:min_width=30} ${message}");
230 1 : buffer->set_format(f);
231 :
232 1 : snaplogger::message::pointer_t msg(std::make_shared<snaplogger::message>
233 1 : (::snaplogger::severity_t::SEVERITY_ERROR));
234 1 : *msg << "The align=101 parameter is the wrong type";
235 3 : CATCH_REQUIRE_THROWS_MATCHES(
236 : l->log_message(*msg)
237 : , snaplogger::invalid_parameter
238 : , Catch::Matchers::ExceptionMessage(
239 : "logger_error: the ${...:align=<value>} parameter must be a valid string (not an integer)."));
240 :
241 : // this is important here because we want to make sure that the
242 : // `message` destructor works as expected (i.e. it does not call
243 : // std::terminate() because of the throw as the align=101 is
244 : // invalid)
245 : //
246 1 : msg.reset();
247 :
248 1 : buffer->clear();
249 :
250 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"t\":align=justify:min_width=30} ${message}");
251 1 : buffer->set_format(f);
252 :
253 1 : msg = std::make_shared<snaplogger::message>
254 1 : (::snaplogger::severity_t::SEVERITY_ERROR);
255 1 : *msg << "Try align=\"justify\" which has to fail.";
256 3 : CATCH_REQUIRE_THROWS_MATCHES(
257 : l->log_message(*msg)
258 : , snaplogger::invalid_parameter
259 : , Catch::Matchers::ExceptionMessage(
260 : "logger_error: the ${...:align=left|center|right} was expected, got \"justify\"."));
261 :
262 1 : buffer->clear();
263 :
264 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=\"q\":align=left:min_width=wide} ${message}");
265 1 : buffer->set_format(f);
266 :
267 1 : msg = std::make_shared<snaplogger::message>
268 1 : (::snaplogger::severity_t::SEVERITY_ERROR);
269 1 : *msg << "The min_width=wide parameter is the wrong type";
270 3 : CATCH_REQUIRE_THROWS_MATCHES(
271 : l->log_message(*msg)
272 : , snaplogger::invalid_parameter
273 : , Catch::Matchers::ExceptionMessage(
274 : "logger_error: the ${...:min_width=<value>} parameter must be a valid integer."));
275 :
276 : // this is important here because we want to make sure that the
277 : // `message` destructor works as expected (i.e. it does not call
278 : // std::terminate() because of the throw as the align=101 is
279 : // invalid)
280 : //
281 1 : msg.reset();
282 :
283 1 : buffer->clear();
284 :
285 1 : f = std::make_shared<snaplogger::format>("${hostname:padding=99:align=left:min_width=wide} ${message}");
286 1 : buffer->set_format(f);
287 :
288 1 : msg = std::make_shared<snaplogger::message>
289 1 : (::snaplogger::severity_t::SEVERITY_ERROR);
290 1 : *msg << "The padding=... accepts a number between 0 and 9 inclusive";
291 3 : CATCH_REQUIRE_THROWS_MATCHES(
292 : l->log_message(*msg)
293 : , snaplogger::invalid_parameter
294 : , Catch::Matchers::ExceptionMessage(
295 : "logger_error: the ${...:padding=<value>} when set to a number must be one digit ('0' to '9'), not \"99\"."));
296 :
297 : // this is important here because we want to make sure that the
298 : // `message` destructor works as expected (i.e. it does not call
299 : // std::terminate() because of the throw as the align=101 is
300 : // invalid)
301 : //
302 1 : msg.reset();
303 :
304 1 : buffer->clear();
305 :
306 1 : f = std::make_shared<snaplogger::format>("${hostname:padding='abc':align=left:min_width=wide} ${message}");
307 1 : buffer->set_format(f);
308 :
309 1 : msg = std::make_shared<snaplogger::message>
310 1 : (::snaplogger::severity_t::SEVERITY_ERROR);
311 1 : *msg << "The padding=... accepts one character";
312 3 : CATCH_REQUIRE_THROWS_MATCHES(
313 : l->log_message(*msg)
314 : , snaplogger::invalid_parameter
315 : , Catch::Matchers::ExceptionMessage(
316 : "logger_error: the ${...:padding=' '} must be exactly one character, not \"abc\"."));
317 :
318 : // this is important here because we want to make sure that the
319 : // `message` destructor works as expected (i.e. it does not call
320 : // std::terminate() because of the throw as the align=101 is
321 : // invalid)
322 : //
323 1 : msg.reset();
324 :
325 1 : l->reset();
326 1 : }
327 7 : CATCH_END_SECTION()
328 :
329 7 : CATCH_START_SECTION("variable: escape")
330 : {
331 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "escape");
332 :
333 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
334 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
335 :
336 1 : char const * cargv[] =
337 : {
338 : "/usr/bin/daemon",
339 : nullptr
340 : };
341 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
342 1 : char ** argv = const_cast<char **>(cargv);
343 :
344 1 : advgetopt::options_environment environment_options;
345 1 : environment_options.f_project_name = "test-logger";
346 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
347 1 : advgetopt::getopt opts(environment_options);
348 1 : opts.parse_program_name(argv);
349 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
350 :
351 1 : buffer->set_config(opts);
352 :
353 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname} ${message:escape}"));
354 1 : buffer->set_format(f);
355 :
356 1 : l->add_appender(buffer);
357 :
358 1 : char host[HOST_NAME_MAX + 2 + 30];
359 1 : CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
360 1 : host[HOST_NAME_MAX + 1] = '\0';
361 :
362 2 : SNAP_LOG_ERROR << "Default escape for newline (\n), carriage return (\r), and tab (\t)" << SNAP_LOG_SEND;
363 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " Default escape for newline (\\n), carriage return (\\r), and tab (\\t)\n");
364 :
365 1 : buffer->clear();
366 :
367 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:escape=\"[]\"}");
368 1 : buffer->set_format(f);
369 :
370 2 : SNAP_LOG_ERROR << "Try again [with a string]" << SNAP_LOG_SEND;
371 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " Try again \\[with a string\\]\n");
372 :
373 1 : buffer->clear();
374 :
375 1 : f = std::make_shared<snaplogger::format>("${hostname} ${message:escape=\"\a\b\f\n\r\t\v\x1f\xC2\x88\xC2\x97\"}");
376 1 : buffer->set_format(f);
377 :
378 2 : SNAP_LOG_ERROR << "Escape all \a\b\f\n\r\t\v\x1f\xC2\x88\xC2\x97 types" << SNAP_LOG_SEND;
379 3 : CATCH_REQUIRE(buffer->str() == std::string(host) + " Escape all \\a\\b\\f\\n\\r\\t\\v^_@H@W types\n");
380 1 : }
381 7 : CATCH_END_SECTION()
382 :
383 7 : CATCH_START_SECTION("variable: caps")
384 : {
385 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "caps");
386 :
387 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
388 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
389 :
390 1 : char const * cargv[] =
391 : {
392 : "/usr/bin/daemon",
393 : nullptr
394 : };
395 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
396 1 : char ** argv = const_cast<char **>(cargv);
397 :
398 1 : advgetopt::options_environment environment_options;
399 1 : environment_options.f_project_name = "test-logger";
400 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
401 1 : advgetopt::getopt opts(environment_options);
402 1 : opts.parse_program_name(argv);
403 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
404 :
405 1 : buffer->set_config(opts);
406 :
407 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message:caps}"));
408 1 : buffer->set_format(f);
409 :
410 1 : l->add_appender(buffer);
411 :
412 2 : SNAP_LOG_ERROR << "this message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
413 1 : CATCH_REQUIRE(buffer->str() == "This Message Words Will Get Their First-Letter Capitalized.\n");
414 1 : }
415 7 : CATCH_END_SECTION()
416 :
417 7 : CATCH_START_SECTION("variable: lower/upper")
418 : {
419 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "case");
420 :
421 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
422 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
423 :
424 1 : char const * cargv[] =
425 : {
426 : "/usr/bin/daemon",
427 : nullptr
428 : };
429 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
430 1 : char ** argv = const_cast<char **>(cargv);
431 :
432 1 : advgetopt::options_environment environment_options;
433 1 : environment_options.f_project_name = "test-logger";
434 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
435 1 : advgetopt::getopt opts(environment_options);
436 1 : opts.parse_program_name(argv);
437 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
438 :
439 1 : buffer->set_config(opts);
440 :
441 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message:lower}"));
442 1 : buffer->set_format(f);
443 :
444 1 : l->add_appender(buffer);
445 :
446 2 : SNAP_LOG_ERROR << "This message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
447 1 : CATCH_REQUIRE(buffer->str() == "this message words will get their first-letter capitalized.\n");
448 :
449 1 : buffer->clear();
450 :
451 1 : f = std::make_shared<snaplogger::format>("${message:upper}");
452 1 : buffer->set_format(f);
453 :
454 2 : SNAP_LOG_ERROR << "This message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
455 1 : CATCH_REQUIRE(buffer->str() == "THIS MESSAGE WORDS WILL GET THEIR FIRST-LETTER CAPITALIZED.\n");
456 1 : }
457 7 : CATCH_END_SECTION()
458 :
459 7 : CATCH_START_SECTION("variable: default align value")
460 : {
461 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-default-param");
462 :
463 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
464 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
465 :
466 1 : char const * cargv[] =
467 : {
468 : "/usr/bin/daemon",
469 : nullptr
470 : };
471 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
472 1 : char ** argv = const_cast<char **>(cargv);
473 :
474 1 : advgetopt::options_environment environment_options;
475 1 : environment_options.f_project_name = "test-logger";
476 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
477 1 : advgetopt::getopt opts(environment_options);
478 1 : opts.parse_program_name(argv);
479 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
480 :
481 1 : buffer->set_config(opts);
482 :
483 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname:max_width=3} ${message}"));
484 1 : buffer->set_format(f);
485 :
486 1 : l->add_appender(buffer);
487 :
488 1 : char host[HOST_NAME_MAX + 2 + 30];
489 1 : CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
490 1 : host[HOST_NAME_MAX + 1] = '\0';
491 3 : std::string aligned(host);
492 1 : aligned = aligned.substr(0, 3);
493 1 : while(aligned.length() < 3)
494 : {
495 0 : aligned = " " + aligned;
496 : }
497 :
498 2 : SNAP_LOG_ERROR << "<- first three letters of hostname" << SNAP_LOG_SEND;
499 1 : CATCH_REQUIRE(buffer->str() == aligned + " <- first three letters of hostname\n");
500 1 : }
501 7 : CATCH_END_SECTION()
502 :
503 7 : CATCH_START_SECTION("variable: systemd severity")
504 : {
505 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-systemd-severity");
506 :
507 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
508 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
509 :
510 1 : char const * cargv[] =
511 : {
512 : "/usr/bin/daemon",
513 : nullptr
514 : };
515 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
516 1 : char ** argv = const_cast<char **>(cargv);
517 :
518 1 : advgetopt::options_environment environment_options;
519 1 : environment_options.f_project_name = "test-logger";
520 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
521 1 : advgetopt::getopt opts(environment_options);
522 1 : opts.parse_program_name(argv);
523 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
524 :
525 1 : buffer->set_config(opts);
526 :
527 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity:format=systemd} ${message} (${severity:format=alpha})"));
528 1 : buffer->set_format(f);
529 :
530 1 : l->add_appender(buffer);
531 :
532 2 : SNAP_LOG_EMERGENCY << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
533 2 : SNAP_LOG_ALERT << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
534 2 : SNAP_LOG_CRIT << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
535 2 : SNAP_LOG_ERROR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
536 2 : SNAP_LOG_WARNING << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
537 2 : SNAP_LOG_MINOR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND; // a.k.a. a NOTICE for syslog
538 2 : SNAP_LOG_INFO << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
539 2 : SNAP_LOG_DEBUG << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
540 :
541 1 : CATCH_REQUIRE(buffer->str() == "<0> <- severity tag for systemd/syslog (emergency)\n"
542 : "<1> <- severity tag for systemd/syslog (alert)\n"
543 : "<2> <- severity tag for systemd/syslog (critical)\n"
544 : "<3> <- severity tag for systemd/syslog (error)\n"
545 : "<4> <- severity tag for systemd/syslog (warning)\n"
546 : "<5> <- severity tag for systemd/syslog (minor)\n"
547 : "<6> <- severity tag for systemd/syslog (information)\n");
548 :
549 1 : l->set_severity(::snaplogger::severity_t::SEVERITY_ALL);
550 2 : SNAP_LOG_DEBUG << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
551 :
552 1 : CATCH_REQUIRE(buffer->str() == "<0> <- severity tag for systemd/syslog (emergency)\n"
553 : "<1> <- severity tag for systemd/syslog (alert)\n"
554 : "<2> <- severity tag for systemd/syslog (critical)\n"
555 : "<3> <- severity tag for systemd/syslog (error)\n"
556 : "<4> <- severity tag for systemd/syslog (warning)\n"
557 : "<5> <- severity tag for systemd/syslog (minor)\n"
558 : "<6> <- severity tag for systemd/syslog (information)\n"
559 : "<7> <- severity tag for systemd/syslog (debug)\n");
560 1 : }
561 7 : CATCH_END_SECTION()
562 :
563 7 : CATCH_START_SECTION("variable: systemd severity with an invalid format")
564 : {
565 5 : snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-systemd-severity-invalid-format");
566 :
567 1 : snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
568 1 : snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
569 :
570 1 : char const * cargv[] =
571 : {
572 : "/usr/bin/daemon",
573 : nullptr
574 : };
575 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
576 1 : char ** argv = const_cast<char **>(cargv);
577 :
578 1 : advgetopt::options_environment environment_options;
579 1 : environment_options.f_project_name = "test-logger";
580 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
581 1 : advgetopt::getopt opts(environment_options);
582 1 : opts.parse_program_name(argv);
583 1 : opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
584 :
585 1 : buffer->set_config(opts);
586 :
587 1 : snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity:format=invalid} ${message} (${severity:format=alpha})"));
588 1 : buffer->set_format(f);
589 :
590 1 : l->add_appender(buffer);
591 :
592 5 : CATCH_REQUIRE_THROWS_MATCHES(
593 : SNAP_LOG_MAJOR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND
594 : , snaplogger::invalid_variable
595 : , Catch::Matchers::ExceptionMessage(
596 : "logger_error: the ${severity:format=alpha|number|systemd}"
597 : " variable cannot be set to \"invalid\"."));
598 :
599 1 : CATCH_REQUIRE(buffer->str() == "");
600 1 : }
601 7 : CATCH_END_SECTION()
602 7 : }
603 :
604 :
605 :
606 3 : CATCH_TEST_CASE("duplicate_factory", "[variable][factory]")
607 : {
608 3 : CATCH_START_SECTION("variable: attempt dynamically creating a factory which already exists")
609 : {
610 : class fake_variable_factory final
611 : : public snaplogger::variable_factory
612 : {
613 : public:
614 1 : fake_variable_factory()
615 3 : : variable_factory("version")
616 : {
617 1 : }
618 :
619 0 : virtual snaplogger::variable::pointer_t create_variable() override final
620 : {
621 : // we can't even register this one so returning an empty
622 : // pointer is perfectly safe here
623 : //
624 0 : return snaplogger::variable::pointer_t();
625 : }
626 : };
627 :
628 7 : CATCH_REQUIRE_THROWS_MATCHES(
629 : snaplogger::register_variable_factory(std::make_shared<fake_variable_factory>())
630 : , snaplogger::duplicate_error
631 : , Catch::Matchers::ExceptionMessage("logger_error: trying to add two variable factories of type \"version\"."));
632 : }
633 3 : CATCH_END_SECTION()
634 :
635 3 : CATCH_START_SECTION("variable: attempt creating a variable with a non-existant type")
636 : {
637 3 : CATCH_REQUIRE(snaplogger::get_variable("fake") == nullptr);
638 : }
639 3 : CATCH_END_SECTION()
640 :
641 3 : CATCH_START_SECTION("variable: attempt creating a function factory with an existing name")
642 : {
643 : class fake_function final
644 : : public snaplogger::function
645 : {
646 : public:
647 1 : fake_function()
648 3 : : function("padding")
649 : {
650 1 : }
651 :
652 0 : virtual void apply(
653 : ::snaplogger::message const & msg
654 : , ::snaplogger::function_data & d
655 : , ::snaplogger::param::pointer_t const & p) override
656 : {
657 0 : snapdev::NOT_USED(msg, d, p);
658 0 : }
659 : };
660 :
661 7 : CATCH_REQUIRE_THROWS_MATCHES(
662 : snaplogger::register_function(std::make_shared<fake_function>())
663 : , snaplogger::duplicate_error
664 : , Catch::Matchers::ExceptionMessage("logger_error: trying to add two functions named \"padding\"."));
665 : }
666 3 : CATCH_END_SECTION()
667 3 : }
668 :
669 :
670 : // vim: ts=4 sw=4 et
|