LCOV - code coverage report
Current view: top level - tests - catch_variable.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.5 % 393 387
Test Date: 2025-12-26 15:53:13 Functions: 71.4 % 7 5
Legend: Lines: hit not hit

            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            9 : CATCH_TEST_CASE("system_variable", "[variable][param]")
      62              : {
      63            9 :     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            9 :     CATCH_END_SECTION()
     328              : 
     329            9 :     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              : 
     381            1 :         l->reset();
     382            1 :     }
     383            9 :     CATCH_END_SECTION()
     384              : 
     385            9 :     CATCH_START_SECTION("variable: caps")
     386              :     {
     387            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "caps");
     388              : 
     389            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     390            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     391              : 
     392            1 :         char const * cargv[] =
     393              :         {
     394              :             "/usr/bin/daemon",
     395              :             nullptr
     396              :         };
     397            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     398            1 :         char ** argv = const_cast<char **>(cargv);
     399              : 
     400            1 :         advgetopt::options_environment environment_options;
     401            1 :         environment_options.f_project_name = "test-logger";
     402            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     403            1 :         advgetopt::getopt opts(environment_options);
     404            1 :         opts.parse_program_name(argv);
     405            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     406              : 
     407            1 :         buffer->set_config(opts);
     408              : 
     409            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message:caps}"));
     410            1 :         buffer->set_format(f);
     411              : 
     412            1 :         l->add_appender(buffer);
     413              : 
     414            2 :         SNAP_LOG_ERROR << "this message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
     415            1 :         CATCH_REQUIRE(buffer->str() == "This Message Words Will Get Their First-Letter Capitalized.\n");
     416              : 
     417            1 :         l->reset();
     418            1 :     }
     419            9 :     CATCH_END_SECTION()
     420              : 
     421            9 :     CATCH_START_SECTION("variable: lower/upper")
     422              :     {
     423            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "case");
     424              : 
     425            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     426            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     427              : 
     428            1 :         char const * cargv[] =
     429              :         {
     430              :             "/usr/bin/daemon",
     431              :             nullptr
     432              :         };
     433            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     434            1 :         char ** argv = const_cast<char **>(cargv);
     435              : 
     436            1 :         advgetopt::options_environment environment_options;
     437            1 :         environment_options.f_project_name = "test-logger";
     438            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     439            1 :         advgetopt::getopt opts(environment_options);
     440            1 :         opts.parse_program_name(argv);
     441            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     442              : 
     443            1 :         buffer->set_config(opts);
     444              : 
     445            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message:lower}"));
     446            1 :         buffer->set_format(f);
     447              : 
     448            1 :         l->add_appender(buffer);
     449              : 
     450            2 :         SNAP_LOG_ERROR << "This message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
     451            1 :         CATCH_REQUIRE(buffer->str() == "this message words will get their first-letter capitalized.\n");
     452              : 
     453            1 :         buffer->clear();
     454              : 
     455            1 :         f = std::make_shared<snaplogger::format>("${message:upper}");
     456            1 :         buffer->set_format(f);
     457              : 
     458            2 :         SNAP_LOG_ERROR << "This message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
     459            1 :         CATCH_REQUIRE(buffer->str() == "THIS MESSAGE WORDS WILL GET THEIR FIRST-LETTER CAPITALIZED.\n");
     460              : 
     461            1 :         l->reset();
     462            1 :     }
     463            9 :     CATCH_END_SECTION()
     464              : 
     465            9 :     CATCH_START_SECTION("variable: default align value")
     466              :     {
     467            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-default-param");
     468              : 
     469            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     470            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     471              : 
     472            1 :         char const * cargv[] =
     473              :         {
     474              :             "/usr/bin/daemon",
     475              :             nullptr
     476              :         };
     477            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     478            1 :         char ** argv = const_cast<char **>(cargv);
     479              : 
     480            1 :         advgetopt::options_environment environment_options;
     481            1 :         environment_options.f_project_name = "test-logger";
     482            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     483            1 :         advgetopt::getopt opts(environment_options);
     484            1 :         opts.parse_program_name(argv);
     485            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     486              : 
     487            1 :         buffer->set_config(opts);
     488              : 
     489            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${hostname:max_width=3} ${message}"));
     490            1 :         buffer->set_format(f);
     491              : 
     492            1 :         l->add_appender(buffer);
     493              : 
     494            1 :         char host[HOST_NAME_MAX + 2 + 30];
     495            1 :         CATCH_REQUIRE(gethostname(host, HOST_NAME_MAX + 1) == 0);
     496            1 :         host[HOST_NAME_MAX + 1] = '\0';
     497            3 :         std::string aligned(host);
     498            1 :         aligned = aligned.substr(0, 3);
     499            1 :         while(aligned.length() < 3)
     500              :         {
     501            0 :             aligned = " " + aligned;
     502              :         }
     503              : 
     504            2 :         SNAP_LOG_ERROR << "<- first three letters of hostname" << SNAP_LOG_SEND;
     505            1 :         CATCH_REQUIRE(buffer->str() == aligned + " <- first three letters of hostname\n");
     506              : 
     507            1 :         l->reset();
     508            1 :     }
     509            9 :     CATCH_END_SECTION()
     510              : 
     511            9 :     CATCH_START_SECTION("variable: systemd severity")
     512              :     {
     513            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-systemd-severity");
     514              : 
     515            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     516            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     517              : 
     518            1 :         char const * cargv[] =
     519              :         {
     520              :             "/usr/bin/daemon",
     521              :             nullptr
     522              :         };
     523            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     524            1 :         char ** argv = const_cast<char **>(cargv);
     525              : 
     526            1 :         advgetopt::options_environment environment_options;
     527            1 :         environment_options.f_project_name = "test-logger";
     528            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     529            1 :         advgetopt::getopt opts(environment_options);
     530            1 :         opts.parse_program_name(argv);
     531            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     532              : 
     533            1 :         buffer->set_config(opts);
     534              : 
     535            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity:format=systemd} ${message} (${severity:format=alpha})"));
     536            1 :         buffer->set_format(f);
     537              : 
     538            1 :         l->add_appender(buffer);
     539              : 
     540            2 :         SNAP_LOG_EMERGENCY << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     541            2 :         SNAP_LOG_ALERT << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     542            2 :         SNAP_LOG_CRIT << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     543            2 :         SNAP_LOG_ERROR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     544            2 :         SNAP_LOG_WARNING << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     545            2 :         SNAP_LOG_MINOR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;        // a.k.a. a NOTICE for syslog
     546            2 :         SNAP_LOG_INFO << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     547            2 :         SNAP_LOG_DEBUG << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     548              : 
     549            1 :         CATCH_REQUIRE(buffer->str() == "<0> <- severity tag for systemd/syslog (emergency)\n"
     550              :                                        "<1> <- severity tag for systemd/syslog (alert)\n"
     551              :                                        "<2> <- severity tag for systemd/syslog (critical)\n"
     552              :                                        "<3> <- severity tag for systemd/syslog (error)\n"
     553              :                                        "<4> <- severity tag for systemd/syslog (warning)\n"
     554              :                                        "<5> <- severity tag for systemd/syslog (minor)\n"
     555              :                                        "<6> <- severity tag for systemd/syslog (information)\n");
     556              : 
     557            1 :         l->set_severity(::snaplogger::severity_t::SEVERITY_ALL);
     558            2 :         SNAP_LOG_DEBUG << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND;
     559              : 
     560            1 :         CATCH_REQUIRE(buffer->str() == "<0> <- severity tag for systemd/syslog (emergency)\n"
     561              :                                        "<1> <- severity tag for systemd/syslog (alert)\n"
     562              :                                        "<2> <- severity tag for systemd/syslog (critical)\n"
     563              :                                        "<3> <- severity tag for systemd/syslog (error)\n"
     564              :                                        "<4> <- severity tag for systemd/syslog (warning)\n"
     565              :                                        "<5> <- severity tag for systemd/syslog (minor)\n"
     566              :                                        "<6> <- severity tag for systemd/syslog (information)\n"
     567              :                                        "<7> <- severity tag for systemd/syslog (debug)\n");
     568              : 
     569            1 :         l->reset();
     570            1 :     }
     571            9 :     CATCH_END_SECTION()
     572              : 
     573            9 :     CATCH_START_SECTION("variable: systemd severity with an invalid format")
     574              :     {
     575            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "message-variable-systemd-severity-invalid-format");
     576              : 
     577            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     578            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     579              : 
     580            1 :         char const * cargv[] =
     581              :         {
     582              :             "/usr/bin/daemon",
     583              :             nullptr
     584              :         };
     585            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     586            1 :         char ** argv = const_cast<char **>(cargv);
     587              : 
     588            1 :         advgetopt::options_environment environment_options;
     589            1 :         environment_options.f_project_name = "test-logger";
     590            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     591            1 :         advgetopt::getopt opts(environment_options);
     592            1 :         opts.parse_program_name(argv);
     593            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     594              : 
     595            1 :         buffer->set_config(opts);
     596              : 
     597            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${severity:format=invalid} ${message} (${severity:format=alpha})"));
     598            1 :         buffer->set_format(f);
     599              : 
     600            1 :         l->add_appender(buffer);
     601              : 
     602            5 :         CATCH_REQUIRE_THROWS_MATCHES(
     603              :                   SNAP_LOG_MAJOR << "<- severity tag for systemd/syslog" << SNAP_LOG_SEND
     604              :                 , snaplogger::invalid_variable
     605              :                 , Catch::Matchers::ExceptionMessage(
     606              :                       "logger_error: the ${severity:format=alpha|number|systemd}"
     607              :                       " variable cannot be set to \"invalid\"."));
     608              : 
     609            1 :         CATCH_REQUIRE(buffer->str() == "");
     610              : 
     611            1 :         l->reset();
     612            1 :     }
     613            9 :     CATCH_END_SECTION()
     614              : 
     615            9 :     CATCH_START_SECTION("variable: bad UTF-8 in message")
     616              :     {
     617            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "case");
     618              : 
     619            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     620            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     621              : 
     622            1 :         char const * cargv[] =
     623              :         {
     624              :             "/usr/bin/daemon",
     625              :             nullptr
     626              :         };
     627            1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     628            1 :         char ** argv = const_cast<char **>(cargv);
     629              : 
     630            1 :         advgetopt::options_environment environment_options;
     631            1 :         environment_options.f_project_name = "test-logger";
     632            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     633            1 :         advgetopt::getopt opts(environment_options);
     634            1 :         opts.parse_program_name(argv);
     635            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     636              : 
     637            1 :         buffer->set_config(opts);
     638              : 
     639            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("${message:caps}"));
     640            1 :         buffer->set_format(f);
     641              : 
     642            1 :         l->add_appender(buffer);
     643              : 
     644            2 :         SNAP_LOG_ERROR << "Byte 0xFF is not UTF-8 \xFF so the string does not even compile?" << SNAP_LOG_SEND;
     645            1 :         CATCH_REQUIRE(buffer->str() == "Byte 0xFF is not UTF-8 \xFF so the string does not even compile?"
     646              :                                         " {WARNING: your value has invalid UTF-8 characters; do you"
     647              :                                         " use an std::int8_t or std::uint8_t variable as a parameter"
     648              :                                         " to the log message? Those are often inserted as characters"
     649              :                                         " instead of numbers; exception message:"
     650              :                                         " \"libutf8_exception: to_u32string(): a UTF-8 character"
     651              :                                         " could not be extracted.\"} \n");
     652              : 
     653            1 :         l->reset();
     654            1 :     }
     655            9 :     CATCH_END_SECTION()
     656              : 
     657            9 :     CATCH_START_SECTION("variable: time:process_ms")
     658              :     {
     659            5 :         snaplogger::set_diagnostic(snaplogger::DIAG_KEY_PROGNAME, "on_repeat");
     660              : 
     661            1 :         snaplogger::logger::pointer_t l(snaplogger::logger::get_instance());
     662            1 :         snaplogger::buffer_appender::pointer_t buffer(std::make_shared<snaplogger::buffer_appender>("test-buffer"));
     663              : 
     664            1 :         char const * cargv[] =
     665              :         {
     666              :             "/usr/bin/daemon",
     667              :             "--no-repeat",
     668              :             "20",
     669              :             nullptr
     670              :         };
     671            1 :         int const argc(std::size(cargv) - 1);
     672            1 :         char ** argv = const_cast<char **>(cargv);
     673              : 
     674            1 :         advgetopt::option const options[] =
     675              :         {
     676              :             advgetopt::define_option(
     677              :                   advgetopt::Name("no-repeat")
     678              :                 , advgetopt::Flags(advgetopt::all_flags<
     679              :                               advgetopt::GETOPT_FLAG_REQUIRED
     680              :                             , advgetopt::GETOPT_FLAG_GROUP_OPTIONS>())
     681              :                 , advgetopt::Help("Number of lines to not repeat.")
     682              :                 , advgetopt::DefaultValue("0")
     683              :             ),
     684              :             advgetopt::end_options()
     685              :         };
     686            1 :         advgetopt::options_environment environment_options;
     687            1 :         environment_options.f_project_name = "test-logger";
     688            1 :         environment_options.f_options = options;
     689            1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     690            1 :         advgetopt::getopt opts(environment_options);
     691            1 :         opts.parse_program_name(argv);
     692            1 :         opts.parse_arguments(argc, argv, advgetopt::option_source_t::SOURCE_COMMAND_LINE);
     693              : 
     694            1 :         buffer->set_config(opts);
     695              : 
     696            1 :         snaplogger::format::pointer_t f(std::make_shared<snaplogger::format>("process:${time:process_ms}: ${message}"));
     697            1 :         buffer->set_format(f);
     698              : 
     699            1 :         l->add_appender(buffer);
     700              : 
     701            2 :         SNAP_LOG_FATAL << "We need a first message." << SNAP_LOG_SEND;
     702            2 :         SNAP_LOG_ERROR << "This calls the on_repeat function." << SNAP_LOG_SEND;
     703              :         // the time changes between runs so it's impossible to verify as is
     704              :         //CATCH_REQUIRE(buffer->str() == "process:00:00:00.0: This calls the on_repeat function.\n");
     705            1 :         std::string const result(buffer->str());
     706            1 :         CATCH_REQUIRE(result.starts_with("process:"));
     707            1 :         CATCH_REQUIRE(result.ends_with(": This calls the on_repeat function.\n"));
     708              : 
     709            1 :         buffer->clear();
     710              : 
     711            1 :         f = std::make_shared<snaplogger::format>("${message:upper}");
     712            1 :         buffer->set_format(f);
     713              : 
     714            2 :         SNAP_LOG_ERROR << "This message words will get their FIRST-LETTER capitalized." << SNAP_LOG_SEND;
     715            1 :         CATCH_REQUIRE(buffer->str() == "THIS MESSAGE WORDS WILL GET THEIR FIRST-LETTER CAPITALIZED.\n");
     716              : 
     717            1 :         l->reset();
     718            1 :     }
     719            9 :     CATCH_END_SECTION()
     720            9 : }
     721              : 
     722              : 
     723              : 
     724            3 : CATCH_TEST_CASE("duplicate_factory", "[variable][factory]")
     725              : {
     726            3 :     CATCH_START_SECTION("variable: attempt dynamically creating a factory which already exists")
     727              :     {
     728              :         class fake_variable_factory final
     729              :             : public snaplogger::variable_factory
     730              :         {
     731              :         public:
     732            1 :             fake_variable_factory()
     733            3 :                 : variable_factory("version")
     734              :             {
     735            1 :             }
     736              : 
     737            0 :             virtual snaplogger::variable::pointer_t create_variable() override final
     738              :             {
     739              :                 // we can't even register this one so returning an empty
     740              :                 // pointer is perfectly safe here
     741              :                 //
     742            0 :                 return snaplogger::variable::pointer_t();
     743              :             }
     744              :         };
     745              : 
     746            7 :         CATCH_REQUIRE_THROWS_MATCHES(
     747              :                   snaplogger::register_variable_factory(std::make_shared<fake_variable_factory>())
     748              :                 , snaplogger::duplicate_error
     749              :                 , Catch::Matchers::ExceptionMessage("logger_error: trying to add two variable factories of type \"version\"."));
     750              :     }
     751            3 :     CATCH_END_SECTION()
     752              : 
     753            3 :     CATCH_START_SECTION("variable: attempt creating a variable with a non-existant type")
     754              :     {
     755            3 :         CATCH_REQUIRE(snaplogger::get_variable("fake") == nullptr);
     756              :     }
     757            3 :     CATCH_END_SECTION()
     758              : 
     759            3 :     CATCH_START_SECTION("variable: attempt creating a function factory with an existing name")
     760              :     {
     761              :         class fake_function final
     762              :             : public snaplogger::function
     763              :         {
     764              :         public:
     765            1 :             fake_function()
     766            3 :                 : function("padding")
     767              :             {
     768            1 :             }
     769              : 
     770            0 :             virtual void apply(
     771              :                   ::snaplogger::message const & msg
     772              :                 , ::snaplogger::function_data & d
     773              :                 , ::snaplogger::param::pointer_t const & p) override
     774              :             {
     775            0 :                 snapdev::NOT_USED(msg, d, p);
     776            0 :             }
     777              :         };
     778              : 
     779            7 :         CATCH_REQUIRE_THROWS_MATCHES(
     780              :                   snaplogger::register_function(std::make_shared<fake_function>())
     781              :                 , snaplogger::duplicate_error
     782              :                 , Catch::Matchers::ExceptionMessage("logger_error: trying to add two functions named \"padding\"."));
     783              :     }
     784            3 :     CATCH_END_SECTION()
     785            3 : }
     786              : 
     787              : 
     788              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions