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