LCOV - code coverage report
Current view: top level - tests - catch_message.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 390 391 99.7 %
Date: 2022-07-01 22:43:09 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13