LCOV - code coverage report
Current view: top level - tests - catch_daemon.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 589 704 83.7 %
Date: 2025-01-27 20:52:47 Functions: 26 26 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2016-2024  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/cluck
       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             : 
      25             : // cluckd
      26             : //
      27             : #include    <daemon/cluckd.h>
      28             : 
      29             : 
      30             : // cluck
      31             : //
      32             : #include    <cluck/exception.h>
      33             : 
      34             : 
      35             : // eventdispatcher
      36             : //
      37             : #include    <eventdispatcher/reporter/executor.h>
      38             : #include    <eventdispatcher/reporter/parser.h>
      39             : #include    <eventdispatcher/reporter/variable_integer.h>
      40             : 
      41             : 
      42             : // snapdev
      43             : //
      44             : #include    <snapdev/gethostname.h>
      45             : 
      46             : 
      47             : // advgetopt
      48             : //
      49             : #include    <advgetopt/exception.h>
      50             : 
      51             : 
      52             : // last include
      53             : //
      54             : #include    <snapdev/poison.h>
      55             : 
      56             : 
      57             : 
      58             : namespace
      59             : {
      60             : 
      61             : 
      62             : 
      63          16 : addr::addr get_address()
      64             : {
      65          16 :     addr::addr a;
      66          16 :     sockaddr_in ip = {
      67             :         .sin_family = AF_INET,
      68          16 :         .sin_port = htons(20002),
      69             :         .sin_addr = {
      70          16 :             .s_addr = htonl(0x7f000001),
      71             :         },
      72             :         .sin_zero = {},
      73          16 :     };
      74          16 :     a.set_ipv4(ip);
      75          32 :     return a;
      76           0 : }
      77             : 
      78             : 
      79             : 
      80             : } // no name namespace
      81             : 
      82             : 
      83             : 
      84           1 : CATCH_TEST_CASE("cluck_daemon_one_computer", "[cluckd][daemon]")
      85             : {
      86           3 :     CATCH_START_SECTION("cluck_daemon_one_computer: verify cluckd")
      87             :     {
      88           1 :         addr::addr a(get_address());
      89             : 
      90           1 :         std::vector<std::string> const args = {
      91             :             "cluckd", // name of command
      92             :             "--communicatord-listen",
      93           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
      94             :             "--path-to-message-definitions",
      95             : 
      96             :             // WARNING: the order matters, we want to test with our source
      97             :             //          (i.e. original) files first
      98             :             //
      99           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     100           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     101          13 :         };
     102             : 
     103             :         // convert arguments
     104             :         //
     105           1 :         std::vector<char const *> args_strings;
     106           1 :         args_strings.reserve(args.size() + 1);
     107           6 :         for(auto const & arg : args)
     108             :         {
     109           5 :             args_strings.push_back(arg.c_str());
     110             :         }
     111           1 :         args_strings.push_back(nullptr); // NULL terminated
     112             : 
     113           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     114           1 :         lock->add_connections();
     115             : 
     116             :         // no elections happened, 'lock' is not a leader
     117             :         //
     118           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     119           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     120             :               lock->get_leader_a()
     121             :             , cluck::logic_error
     122             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     123           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     124             :               lock->get_leader_b()
     125             :             , cluck::logic_error
     126             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     127             : 
     128             :         // messenger is not yet connected, it's not ready
     129             :         //
     130           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     131             : 
     132           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     133           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_one_computer.rprtr");
     134           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     135           1 :         CATCH_REQUIRE(l != nullptr);
     136           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     137           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     138           1 :         p->parse_program();
     139             : 
     140           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     141           1 :         e->start();
     142             : 
     143           1 :         e->set_thread_done_callback([lock]()
     144             :             {
     145           1 :                 lock->stop(true);
     146           1 :             });
     147             : 
     148             :         try
     149             :         {
     150           1 :             lock->run();
     151             :         }
     152           0 :         catch(std::exception const & ex)
     153             :         {
     154           0 :             SNAP_LOG_FATAL
     155             :                 << "an exception occurred while running cluckd (1 cluckd): "
     156             :                 << ex
     157             :                 << SNAP_LOG_SEND;
     158             : 
     159           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     160           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     161             :             {
     162           0 :                 SNAP_LOG_FATAL
     163             :                     << "    "
     164             :                     << line
     165             :                     << SNAP_LOG_SEND;
     166             :             }
     167             : 
     168           0 :             throw;
     169           0 :         }
     170             : 
     171           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     172           1 :     }
     173           2 :     CATCH_END_SECTION()
     174           1 : }
     175             : 
     176             : 
     177           1 : CATCH_TEST_CASE("cluck_daemon_two_computers", "[cluckd][daemon]")
     178             : {
     179           3 :     CATCH_START_SECTION("cluck_daemon_two_computers: verify cluckd")
     180             :     {
     181           1 :         addr::addr a(get_address());
     182             : 
     183           1 :         std::vector<std::string> const args = {
     184             :             "cluckd", // name of command
     185             :             "--communicatord-listen",
     186           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     187             :             "--path-to-message-definitions",
     188             : 
     189             :             // WARNING: the order matters, we want to test with our source
     190             :             //          (i.e. original) files first
     191             :             //
     192           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     193           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     194             : 
     195             :             "--server-name",
     196             :             snapdev::gethostname(),
     197             :             "--candidate-priority",
     198             :             "10",
     199          20 :         };
     200             : 
     201             :         // convert arguments
     202             :         //
     203           1 :         std::vector<char const *> args_strings;
     204           1 :         args_strings.reserve(args.size() + 1);
     205          10 :         for(auto const & arg : args)
     206             :         {
     207           9 :             args_strings.push_back(arg.c_str());
     208             :         }
     209           1 :         args_strings.push_back(nullptr); // NULL terminated
     210             : 
     211           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     212           1 :         lock->add_connections();
     213             : 
     214             :         // no elections happened, 'lock' is not a leader
     215             :         //
     216           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     217           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     218             :               lock->get_leader_a()
     219             :             , cluck::logic_error
     220             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     221           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     222             :               lock->get_leader_b()
     223             :             , cluck::logic_error
     224             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     225             : 
     226             :         // messenger is not yet connected, it's not ready
     227             :         //
     228           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     229             : 
     230           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     231           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_two_computers.rprtr");
     232           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     233           1 :         CATCH_REQUIRE(l != nullptr);
     234           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     235           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     236           1 :         p->parse_program();
     237             : 
     238           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     239           1 :         e->start();
     240             : 
     241           1 :         e->set_thread_done_callback([lock]()
     242             :             {
     243           1 :                 lock->stop(true);
     244           1 :             });
     245             : 
     246             :         try
     247             :         {
     248           1 :             lock->run();
     249             :         }
     250           0 :         catch(std::exception const & ex)
     251             :         {
     252           0 :             SNAP_LOG_FATAL
     253             :                 << "an exception occurred while running cluckd (2 cluckd): "
     254             :                 << ex
     255             :                 << SNAP_LOG_SEND;
     256             : 
     257           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     258           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     259             :             {
     260           0 :                 SNAP_LOG_FATAL
     261             :                     << "    "
     262             :                     << line
     263             :                     << SNAP_LOG_SEND;
     264             :             }
     265             : 
     266           0 :             throw;
     267           0 :         }
     268             : 
     269           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     270           1 :     }
     271           2 :     CATCH_END_SECTION()
     272           1 : }
     273             : 
     274             : 
     275           1 : CATCH_TEST_CASE("cluck_daemon_three_computers", "[cluckd][daemon]")
     276             : {
     277           3 :     CATCH_START_SECTION("cluck_daemon_three_computers: verify cluckd")
     278             :     {
     279           1 :         addr::addr a(get_address());
     280             : 
     281           1 :         std::vector<std::string> const args = {
     282             :             "cluckd", // name of command
     283             :             "--communicatord-listen",
     284           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     285             :             "--path-to-message-definitions",
     286             : 
     287             :             // WARNING: the order matters, we want to test with our source
     288             :             //          (i.e. original) files first
     289             :             //
     290           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     291           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     292          13 :         };
     293             : 
     294             :         // convert arguments
     295             :         //
     296           1 :         std::vector<char const *> args_strings;
     297           1 :         args_strings.reserve(args.size() + 1);
     298           6 :         for(auto const & arg : args)
     299             :         {
     300           5 :             args_strings.push_back(arg.c_str());
     301             :         }
     302           1 :         args_strings.push_back(nullptr); // NULL terminated
     303             : 
     304           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     305           1 :         lock->add_connections();
     306             : 
     307             :         // no elections happened, 'lock' is not a leader
     308             :         //
     309           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     310           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     311             :               lock->get_leader_a()
     312             :             , cluck::logic_error
     313             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     314           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     315             :               lock->get_leader_b()
     316             :             , cluck::logic_error
     317             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     318             : 
     319             :         // messenger is not yet connected, it's not ready
     320             :         //
     321           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     322             : 
     323           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     324           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_three_computers.rprtr");
     325           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     326           1 :         CATCH_REQUIRE(l != nullptr);
     327           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     328           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     329           1 :         p->parse_program();
     330             : 
     331           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     332           1 :         e->start();
     333             : 
     334           1 :         e->set_thread_done_callback([lock]()
     335             :             {
     336           1 :                 lock->stop(true);
     337           1 :             });
     338             : 
     339             :         try
     340             :         {
     341           1 :             lock->run();
     342             :         }
     343           0 :         catch(std::exception const & ex)
     344             :         {
     345           0 :             SNAP_LOG_FATAL
     346             :                 << "an exception occurred while running cluckd (3 cluckd): "
     347             :                 << ex
     348             :                 << SNAP_LOG_SEND;
     349             : 
     350           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     351           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     352             :             {
     353           0 :                 SNAP_LOG_FATAL
     354             :                     << "    "
     355             :                     << line
     356             :                     << SNAP_LOG_SEND;
     357             :             }
     358             : 
     359           0 :             throw;
     360           0 :         }
     361             : 
     362           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     363           1 :     }
     364           2 :     CATCH_END_SECTION()
     365           1 : }
     366             : 
     367             : 
     368           1 : CATCH_TEST_CASE("cluck_daemon_four_computers", "[cluckd][daemon]")
     369             : {
     370           3 :     CATCH_START_SECTION("cluck_daemon_four_computers: verify cluckd")
     371             :     {
     372           1 :         addr::addr a(get_address());
     373             : 
     374           1 :         std::vector<std::string> const args = {
     375             :             "cluckd", // name of command
     376             :             "--communicatord-listen",
     377           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     378             :             "--path-to-message-definitions",
     379             : 
     380             :             // WARNING: the order matters, we want to test with our source
     381             :             //          (i.e. original) files first
     382             :             //
     383           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     384           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     385          13 :         };
     386             : 
     387             :         // convert arguments
     388             :         //
     389           1 :         std::vector<char const *> args_strings;
     390           1 :         args_strings.reserve(args.size() + 1);
     391           6 :         for(auto const & arg : args)
     392             :         {
     393           5 :             args_strings.push_back(arg.c_str());
     394             :         }
     395           1 :         args_strings.push_back(nullptr); // NULL terminated
     396             : 
     397           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     398           1 :         lock->add_connections();
     399             : 
     400             :         // no elections happened, 'lock' is not a leader
     401             :         //
     402           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     403           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     404             :               lock->get_leader_a()
     405             :             , cluck::logic_error
     406             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     407           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     408             :               lock->get_leader_b()
     409             :             , cluck::logic_error
     410             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     411             : 
     412             :         // messenger is not yet connected, it's not ready
     413             :         //
     414           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     415             : 
     416           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     417           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_four_computers.rprtr");
     418           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     419           1 :         CATCH_REQUIRE(l != nullptr);
     420           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     421           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     422           1 :         p->parse_program();
     423             : 
     424           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     425           1 :         e->start();
     426             : 
     427           1 :         e->set_thread_done_callback([lock]()
     428             :             {
     429           1 :                 lock->stop(true);
     430           1 :             });
     431             : 
     432             :         try
     433             :         {
     434           1 :             lock->run();
     435             :         }
     436           0 :         catch(std::exception const & ex)
     437             :         {
     438           0 :             SNAP_LOG_FATAL
     439             :                 << "an exception occurred while running cluckd (4 cluckd): "
     440             :                 << ex
     441             :                 << SNAP_LOG_SEND;
     442             : 
     443           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     444           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     445             :             {
     446           0 :                 SNAP_LOG_FATAL
     447             :                     << "    "
     448             :                     << line
     449             :                     << SNAP_LOG_SEND;
     450             :             }
     451             : 
     452           0 :             throw;
     453           0 :         }
     454             : 
     455           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     456           1 :     }
     457           2 :     CATCH_END_SECTION()
     458           1 : }
     459             : 
     460             : 
     461           1 : CATCH_TEST_CASE("cluck_daemon_ten_computers", "[cluckd][daemon]")
     462             : {
     463           3 :     CATCH_START_SECTION("cluck_daemon_ten_computers: verify cluckd")
     464             :     {
     465           1 :         addr::addr a(get_address());
     466             : 
     467           1 :         std::vector<std::string> const args = {
     468             :             "cluckd", // name of command
     469             :             "--communicatord-listen",
     470           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     471             :             "--candidate-priority",
     472             :             "5",
     473             :             "--path-to-message-definitions",
     474             : 
     475             :             // WARNING: the order matters, we want to test with our source
     476             :             //          (i.e. original) files first
     477             :             //
     478           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     479           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     480          17 :         };
     481             : 
     482             :         // convert arguments
     483             :         //
     484           1 :         std::vector<char const *> args_strings;
     485           1 :         args_strings.reserve(args.size() + 1);
     486           8 :         for(auto const & arg : args)
     487             :         {
     488           7 :             args_strings.push_back(arg.c_str());
     489             :         }
     490           1 :         args_strings.push_back(nullptr); // NULL terminated
     491             : 
     492           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     493           1 :         lock->add_connections();
     494             : 
     495             :         // no elections happened, 'lock' is not a leader
     496             :         //
     497           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     498           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     499             :               lock->get_leader_a()
     500             :             , cluck::logic_error
     501             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     502           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     503             :               lock->get_leader_b()
     504             :             , cluck::logic_error
     505             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     506             : 
     507             :         // messenger is not yet connected, it's not ready
     508             :         //
     509           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     510             : 
     511           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     512           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_ten_computers.rprtr");
     513           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     514           1 :         CATCH_REQUIRE(l != nullptr);
     515           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     516           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     517           1 :         p->parse_program();
     518             : 
     519           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     520           1 :         e->start();
     521             : 
     522           1 :         e->set_thread_done_callback([lock]()
     523             :             {
     524           1 :                 lock->stop(true);
     525           1 :             });
     526             : 
     527             :         try
     528             :         {
     529           1 :             lock->run();
     530             :         }
     531           0 :         catch(std::exception const & ex)
     532             :         {
     533           0 :             SNAP_LOG_FATAL
     534             :                 << "an exception occurred while running cluckd (10 cluckd): "
     535             :                 << ex
     536             :                 << SNAP_LOG_SEND;
     537             : 
     538           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     539           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     540             :             {
     541           0 :                 SNAP_LOG_FATAL
     542             :                     << "    "
     543             :                     << line
     544             :                     << SNAP_LOG_SEND;
     545             :             }
     546             : 
     547           0 :             throw;
     548           0 :         }
     549             : 
     550           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     551           1 :     }
     552           2 :     CATCH_END_SECTION()
     553           1 : }
     554             : 
     555             : 
     556           1 : CATCH_TEST_CASE("cluck_daemon_lock_tickets", "[cluckd][daemon]")
     557             : {
     558           3 :     CATCH_START_SECTION("cluck_daemon_lock_tickets: verify cluckd")
     559             :     {
     560           1 :         addr::addr a(get_address());
     561             : 
     562           1 :         std::vector<std::string> const args = {
     563             :             "cluckd", // name of command
     564             :             "--communicatord-listen",
     565           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     566             :             "--candidate-priority",
     567             :             "2",
     568             :             "--path-to-message-definitions",
     569             : 
     570             :             // WARNING: the order matters, we want to test with our source
     571             :             //          (i.e. original) files first
     572             :             //
     573           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     574           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     575          17 :         };
     576             : 
     577             :         // convert arguments
     578             :         //
     579           1 :         std::vector<char const *> args_strings;
     580           1 :         args_strings.reserve(args.size() + 1);
     581           8 :         for(auto const & arg : args)
     582             :         {
     583           7 :             args_strings.push_back(arg.c_str());
     584             :         }
     585           1 :         args_strings.push_back(nullptr); // NULL terminated
     586             : 
     587           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     588           1 :         lock->add_connections();
     589             : 
     590             :         // no elections happened, 'lock' is not a leader
     591             :         //
     592           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     593           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     594             :               lock->get_leader_a()
     595             :             , cluck::logic_error
     596             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     597           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     598             :               lock->get_leader_b()
     599             :             , cluck::logic_error
     600             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     601             : 
     602             :         // messenger is not yet connected, it's not ready
     603             :         //
     604           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     605             : 
     606           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     607           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_lock_tickets.rprtr");
     608           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     609           1 :         CATCH_REQUIRE(l != nullptr);
     610           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     611           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     612           1 :         p->parse_program();
     613             : 
     614           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     615           1 :         e->start();
     616             : 
     617           1 :         e->set_thread_done_callback([lock]()
     618             :             {
     619           1 :                 lock->stop(true);
     620           1 :             });
     621             : 
     622             :         try
     623             :         {
     624           1 :             lock->run();
     625             :         }
     626           0 :         catch(std::exception const & ex)
     627             :         {
     628           0 :             SNAP_LOG_FATAL
     629             :                 << "an exception occurred while running cluckd (10 cluckd): "
     630             :                 << ex
     631             :                 << SNAP_LOG_SEND;
     632             : 
     633           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     634           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     635             :             {
     636           0 :                 SNAP_LOG_FATAL
     637             :                     << "    "
     638             :                     << line
     639             :                     << SNAP_LOG_SEND;
     640             :             }
     641             : 
     642           0 :             throw;
     643           0 :         }
     644             : 
     645           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     646           1 :     }
     647           2 :     CATCH_END_SECTION()
     648           1 : }
     649             : 
     650             : 
     651           3 : CATCH_TEST_CASE("cluck_daemon_specialized_tests", "[cluckd][daemon]")
     652             : {
     653           5 :     CATCH_START_SECTION("cluck_daemon_specialized_tests: verify early LOCK_LEADERS")
     654             :     {
     655           1 :         addr::addr a(get_address());
     656             : 
     657           1 :         std::vector<std::string> const args = {
     658             :             "cluckd", // name of command
     659             :             "--communicatord-listen",
     660           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     661             :             "--path-to-message-definitions",
     662             : 
     663             :             // WARNING: the order matters, we want to test with our source
     664             :             //          (i.e. original) files first
     665             :             //
     666           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     667           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     668          13 :         };
     669             : 
     670             :         // convert arguments
     671             :         //
     672           1 :         std::vector<char const *> args_strings;
     673           1 :         args_strings.reserve(args.size() + 1);
     674           6 :         for(auto const & arg : args)
     675             :         {
     676           5 :             args_strings.push_back(arg.c_str());
     677             :         }
     678           1 :         args_strings.push_back(nullptr); // NULL terminated
     679             : 
     680           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     681           1 :         lock->add_connections();
     682             : 
     683             :         // no elections happened, 'lock' is not a leader
     684             :         //
     685           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     686           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     687             :               lock->get_leader_a()
     688             :             , cluck::logic_error
     689             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     690           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     691             :               lock->get_leader_b()
     692             :             , cluck::logic_error
     693             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     694             : 
     695             :         // messenger is not yet connected, it's not ready
     696             :         //
     697           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     698             : 
     699           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     700           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_early_lock_leaders.rprtr");
     701           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     702           1 :         CATCH_REQUIRE(l != nullptr);
     703           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     704           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     705           1 :         p->parse_program();
     706             : 
     707           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     708           1 :         e->start();
     709             : 
     710           1 :         e->set_thread_done_callback([lock]()
     711             :             {
     712           1 :                 lock->stop(true);
     713           1 :             });
     714             : 
     715             :         try
     716             :         {
     717           1 :             lock->run();
     718             :         }
     719           0 :         catch(std::exception const & ex)
     720             :         {
     721           0 :             SNAP_LOG_FATAL
     722             :                 << "an exception occurred while running cluckd (3 cluckd): "
     723             :                 << ex
     724             :                 << SNAP_LOG_SEND;
     725             : 
     726           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     727           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     728             :             {
     729           0 :                 SNAP_LOG_FATAL
     730             :                     << "    "
     731             :                     << line
     732             :                     << SNAP_LOG_SEND;
     733             :             }
     734             : 
     735           0 :             throw;
     736           0 :         }
     737             : 
     738           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     739           1 :     }
     740           4 :     CATCH_END_SECTION()
     741             : 
     742           5 :     CATCH_START_SECTION("cluck_daemon_specialized_tests: verify forwarded (off)")
     743             :     {
     744           1 :         addr::addr a(get_address());
     745             : 
     746           1 :         std::vector<std::string> const args = {
     747             :             "cluckd", // name of command
     748             :             "--communicatord-listen",
     749           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     750             :             "--candidate-priority",
     751             :             "off",
     752             :             "--path-to-message-definitions",
     753             : 
     754             :             // WARNING: the order matters, we want to test with our source
     755             :             //          (i.e. original) files first
     756             :             //
     757           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     758           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     759          17 :         };
     760             : 
     761             :         // convert arguments
     762             :         //
     763           1 :         std::vector<char const *> args_strings;
     764           1 :         args_strings.reserve(args.size() + 1);
     765           8 :         for(auto const & arg : args)
     766             :         {
     767           7 :             args_strings.push_back(arg.c_str());
     768             :         }
     769           1 :         args_strings.push_back(nullptr); // NULL terminated
     770             : 
     771           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     772           1 :         lock->add_connections();
     773             : 
     774             :         // no elections happened, 'lock' is not a leader
     775             :         //
     776           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     777           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     778             :               lock->get_leader_a()
     779             :             , cluck::logic_error
     780             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     781           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     782             :               lock->get_leader_b()
     783             :             , cluck::logic_error
     784             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     785             : 
     786             :         // messenger is not yet connected, it's not ready
     787             :         //
     788           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     789             : 
     790           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     791           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_forwarder.rprtr");
     792           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     793           1 :         CATCH_REQUIRE(l != nullptr);
     794           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     795           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     796           1 :         p->parse_program();
     797             : 
     798           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     799           1 :         e->start();
     800             : 
     801           1 :         e->set_thread_done_callback([lock]()
     802             :             {
     803           1 :                 lock->stop(true);
     804           1 :             });
     805             : 
     806             :         try
     807             :         {
     808           1 :             lock->run();
     809             :         }
     810           0 :         catch(std::exception const & ex)
     811             :         {
     812           0 :             SNAP_LOG_FATAL
     813             :                 << "an exception occurred while running cluckd (3 cluckd): "
     814             :                 << ex
     815             :                 << SNAP_LOG_SEND;
     816             : 
     817           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     818           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     819             :             {
     820           0 :                 SNAP_LOG_FATAL
     821             :                     << "    "
     822             :                     << line
     823             :                     << SNAP_LOG_SEND;
     824             :             }
     825             : 
     826           0 :             throw;
     827           0 :         }
     828             : 
     829           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     830           1 :     }
     831           4 :     CATCH_END_SECTION()
     832             : 
     833           5 :     CATCH_START_SECTION("cluck_daemon_specialized_tests: try an interrupt to stop the cluck daemon")
     834             :     {
     835           1 :         addr::addr a(get_address());
     836             : 
     837           1 :         std::vector<std::string> const args = {
     838             :             "cluckd", // name of command
     839             :             "--communicatord-listen",
     840           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     841             :             "--path-to-message-definitions",
     842             : 
     843             :             // WARNING: the order matters, we want to test with our source
     844             :             //          (i.e. original) files first
     845             :             //
     846           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     847           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     848          13 :         };
     849             : 
     850             :         // convert arguments
     851             :         //
     852           1 :         std::vector<char const *> args_strings;
     853           1 :         args_strings.reserve(args.size() + 1);
     854           6 :         for(auto const & arg : args)
     855             :         {
     856           5 :             args_strings.push_back(arg.c_str());
     857             :         }
     858           1 :         args_strings.push_back(nullptr); // NULL terminated
     859             : 
     860           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     861           1 :         lock->add_connections();
     862             : 
     863             :         // no elections happened, 'lock' is not a leader
     864             :         //
     865           1 :         CATCH_REQUIRE(lock->is_leader() == nullptr);
     866           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     867             :               lock->get_leader_a()
     868             :             , cluck::logic_error
     869             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_a(): only a leader can call this function."));
     870           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     871             :               lock->get_leader_b()
     872             :             , cluck::logic_error
     873             :             , Catch::Matchers::ExceptionMessage("logic_error: cluckd::get_leader_b(): only a leader can call this function."));
     874             : 
     875             :         // messenger is not yet connected, it's not ready
     876             :         //
     877           1 :         CATCH_REQUIRE_FALSE(lock->is_daemon_ready());
     878             : 
     879           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     880           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_interrupt_signal.rprtr");
     881           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     882           1 :         CATCH_REQUIRE(l != nullptr);
     883           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     884           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     885           1 :         p->parse_program();
     886             : 
     887           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     888           1 :         e->start();
     889             : 
     890           1 :         e->set_thread_done_callback([lock]()
     891             :             {
     892           1 :                 lock->stop(true);
     893           1 :             });
     894             : 
     895             :         try
     896             :         {
     897           1 :             lock->run();
     898             :         }
     899           0 :         catch(std::exception const & ex)
     900             :         {
     901           0 :             SNAP_LOG_FATAL
     902             :                 << "an exception occurred while running cluckd (interrupt signal): "
     903             :                 << ex
     904             :                 << SNAP_LOG_SEND;
     905             : 
     906           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     907           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     908             :             {
     909           0 :                 SNAP_LOG_FATAL
     910             :                     << "    "
     911             :                     << line
     912             :                     << SNAP_LOG_SEND;
     913             :             }
     914             : 
     915           0 :             throw;
     916           0 :         }
     917             : 
     918           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     919           1 :     }
     920           4 :     CATCH_END_SECTION()
     921           3 : }
     922             : 
     923             : 
     924           4 : CATCH_TEST_CASE("cluck_daemon_failures", "[cluckd][daemon][fail]")
     925             : {
     926           6 :     CATCH_START_SECTION("cluck_daemon_failures: entering too slowly")
     927             :     {
     928           1 :         addr::addr a(get_address());
     929             : 
     930           1 :         std::vector<std::string> const args = {
     931             :             "cluckd", // name of command
     932             :             "--communicatord-listen",
     933           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
     934             :             "--path-to-message-definitions",
     935             : 
     936             :             // WARNING: the order matters, we want to test with our source
     937             :             //          (i.e. original) files first
     938             :             //
     939           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
     940           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
     941          13 :         };
     942             : 
     943             :         // convert arguments
     944             :         //
     945           1 :         std::vector<char const *> args_strings;
     946           1 :         args_strings.reserve(args.size() + 1);
     947           6 :         for(auto const & arg : args)
     948             :         {
     949           5 :             args_strings.push_back(arg.c_str());
     950             :         }
     951           1 :         args_strings.push_back(nullptr); // NULL terminated
     952             : 
     953           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
     954           1 :         lock->add_connections();
     955             : 
     956           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
     957           1 :         std::string const filename(source_dir + "/tests/rprtr/failed_with_timing_out_entering.rprtr");
     958           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
     959           1 :         CATCH_REQUIRE(l != nullptr);
     960           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
     961           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
     962           1 :         p->parse_program();
     963             : 
     964           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
     965           1 :         e->start();
     966             : 
     967           1 :         e->set_thread_done_callback([lock]()
     968             :             {
     969           1 :                 lock->stop(true);
     970           1 :             });
     971             : 
     972             :         try
     973             :         {
     974           1 :             lock->run();
     975             :         }
     976           0 :         catch(std::exception const & ex)
     977             :         {
     978           0 :             SNAP_LOG_FATAL
     979             :                 << "an exception occurred while running cluckd (entering timing out): "
     980             :                 << ex
     981             :                 << SNAP_LOG_SEND;
     982             : 
     983           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
     984           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
     985             :             {
     986           0 :                 SNAP_LOG_FATAL
     987             :                     << "    "
     988             :                     << line
     989             :                     << SNAP_LOG_SEND;
     990             :             }
     991             : 
     992           0 :             throw;
     993           0 :         }
     994             : 
     995           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
     996           1 :     }
     997           5 :     CATCH_END_SECTION()
     998             : 
     999           6 :     CATCH_START_SECTION("cluck_daemon_failures: cache timeout")
    1000             :     {
    1001           1 :         addr::addr a(get_address());
    1002             : 
    1003           1 :         std::vector<std::string> const args = {
    1004             :             "cluckd", // name of command
    1005             :             "--communicatord-listen",
    1006           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1007             :             "--path-to-message-definitions",
    1008             : 
    1009             :             // WARNING: the order matters, we want to test with our source
    1010             :             //          (i.e. original) files first
    1011             :             //
    1012           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1013           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1014          13 :         };
    1015             : 
    1016             :         // convert arguments
    1017             :         //
    1018           1 :         std::vector<char const *> args_strings;
    1019           1 :         args_strings.reserve(args.size() + 1);
    1020           6 :         for(auto const & arg : args)
    1021             :         {
    1022           5 :             args_strings.push_back(arg.c_str());
    1023             :         }
    1024           1 :         args_strings.push_back(nullptr); // NULL terminated
    1025             : 
    1026           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1027           1 :         lock->add_connections();
    1028             : 
    1029           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1030           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_cache_timeout.rprtr");
    1031           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1032           1 :         CATCH_REQUIRE(l != nullptr);
    1033           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1034           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1035           1 :         p->parse_program();
    1036             : 
    1037           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1038           1 :         e->start();
    1039             : 
    1040           1 :         e->set_thread_done_callback([lock]()
    1041             :             {
    1042           1 :                 lock->stop(true);
    1043           1 :             });
    1044             : 
    1045             :         try
    1046             :         {
    1047           1 :             lock->run();
    1048             :         }
    1049           0 :         catch(std::exception const & ex)
    1050             :         {
    1051           0 :             SNAP_LOG_FATAL
    1052             :                 << "an exception occurred while running cluckd (entering timing out): "
    1053             :                 << ex
    1054             :                 << SNAP_LOG_SEND;
    1055             : 
    1056           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1057           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1058             :             {
    1059           0 :                 SNAP_LOG_FATAL
    1060             :                     << "    "
    1061             :                     << line
    1062             :                     << SNAP_LOG_SEND;
    1063             :             }
    1064             : 
    1065           0 :             throw;
    1066           0 :         }
    1067             : 
    1068           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
    1069           1 :     }
    1070           5 :     CATCH_END_SECTION()
    1071             : 
    1072           6 :     CATCH_START_SECTION("cluck_daemon_failures: too many locks")
    1073             :     {
    1074           1 :         addr::addr a(get_address());
    1075             : 
    1076           1 :         cluck::timeout_t const default_obtention_timeout(cluck::get_lock_obtention_timeout());
    1077           1 :         cluck::set_lock_obtention_timeout(cluck::timeout_t(120, 0));
    1078             : 
    1079           1 :         std::vector<std::string> const args = {
    1080             :             "cluckd", // name of command
    1081             :             "--communicatord-listen",
    1082           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1083             :             "--candidate-priority",
    1084             :             "10",
    1085             :             "--path-to-message-definitions",
    1086             : 
    1087             :             // WARNING: the order matters, we want to test with our source
    1088             :             //          (i.e. original) files first
    1089             :             //
    1090           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1091           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1092          17 :         };
    1093             : 
    1094             :         // convert arguments
    1095             :         //
    1096           1 :         std::vector<char const *> args_strings;
    1097           1 :         args_strings.reserve(args.size() + 1);
    1098           8 :         for(auto const & arg : args)
    1099             :         {
    1100           7 :             args_strings.push_back(arg.c_str());
    1101             :         }
    1102           1 :         args_strings.push_back(nullptr); // NULL terminated
    1103             : 
    1104           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1105           1 :         lock->add_connections();
    1106             : 
    1107           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1108           1 :         std::string const filename(source_dir + "/tests/rprtr/failed_with_too_many_locks.rprtr");
    1109           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1110           1 :         CATCH_REQUIRE(l != nullptr);
    1111           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1112           1 :         SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t var(
    1113             :                 std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(
    1114           1 :                           "cluck_maximum_entering_locks"));
    1115           1 :         var->set_integer(cluck::CLUCK_MAXIMUM_ENTERING_LOCKS);
    1116           1 :         s->set_variable(var);
    1117           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1118           1 :         p->parse_program();
    1119             : 
    1120           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1121           1 :         e->start();
    1122             : 
    1123           1 :         e->set_thread_done_callback([lock]()
    1124             :             {
    1125           1 :                 lock->stop(true);
    1126           1 :             });
    1127             : 
    1128             :         try
    1129             :         {
    1130           1 :             lock->run();
    1131             :         }
    1132           0 :         catch(std::exception const & ex)
    1133             :         {
    1134           0 :             SNAP_LOG_FATAL
    1135             :                 << "an exception occurred while running cluckd (entering timing out): "
    1136             :                 << ex
    1137             :                 << SNAP_LOG_SEND;
    1138             : 
    1139           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1140           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1141             :             {
    1142           0 :                 SNAP_LOG_FATAL
    1143             :                     << "    "
    1144             :                     << line
    1145             :                     << SNAP_LOG_SEND;
    1146             :             }
    1147             : 
    1148           0 :             throw;
    1149           0 :         }
    1150             : 
    1151           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
    1152             : 
    1153           1 :         cluck::set_lock_obtention_timeout(default_obtention_timeout);
    1154           1 :     }
    1155           5 :     CATCH_END_SECTION()
    1156             : 
    1157           6 :     CATCH_START_SECTION("cluck_daemon_failures: send a DROP_TICKET to cancel an entering LOCK")
    1158             :     {
    1159           1 :         addr::addr a(get_address());
    1160             : 
    1161           1 :         std::vector<std::string> const args = {
    1162             :             "cluckd", // name of command
    1163             :             "--candidate-priority",
    1164             :             "10",
    1165             :             "--communicatord-listen",
    1166           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1167             :             "--path-to-message-definitions",
    1168             : 
    1169             :             // WARNING: the order matters, we want to test with our source
    1170             :             //          (i.e. original) files first
    1171             :             //
    1172           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1173           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1174             : 
    1175             :             "--server-name",
    1176             :             snapdev::gethostname(),
    1177          20 :         };
    1178             : 
    1179             :         // convert arguments
    1180             :         //
    1181           1 :         std::vector<char const *> args_strings;
    1182           1 :         args_strings.reserve(args.size() + 1);
    1183          10 :         for(auto const & arg : args)
    1184             :         {
    1185           9 :             args_strings.push_back(arg.c_str());
    1186             :         }
    1187           1 :         args_strings.push_back(nullptr); // NULL terminated
    1188             : 
    1189           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1190           1 :         lock->add_connections();
    1191             : 
    1192           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1193           1 :         std::string const filename(source_dir + "/tests/rprtr/drop_entering_ticket.rprtr");
    1194           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1195           1 :         CATCH_REQUIRE(l != nullptr);
    1196           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1197           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1198           1 :         p->parse_program();
    1199             : 
    1200           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1201           1 :         e->start();
    1202             : 
    1203           1 :         e->set_thread_done_callback([lock]()
    1204             :             {
    1205           1 :                 lock->stop(true);
    1206           1 :             });
    1207             : 
    1208             :         try
    1209             :         {
    1210           1 :             lock->run();
    1211             :         }
    1212           0 :         catch(std::exception const & ex)
    1213             :         {
    1214           0 :             SNAP_LOG_FATAL
    1215             :                 << "an exception occurred while running cluckd (get max ticket overflow): "
    1216             :                 << ex
    1217             :                 << SNAP_LOG_SEND;
    1218             : 
    1219           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1220           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1221             :             {
    1222           0 :                 SNAP_LOG_FATAL
    1223             :                     << "    "
    1224             :                     << line
    1225             :                     << SNAP_LOG_SEND;
    1226             :             }
    1227             : 
    1228           0 :             throw;
    1229           0 :         }
    1230             : 
    1231           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
    1232           1 :     }
    1233           5 :     CATCH_END_SECTION()
    1234           4 : }
    1235             : 
    1236             : 
    1237           6 : CATCH_TEST_CASE("cluck_daemon_errors", "[cluckd][daemon][error]")
    1238             : {
    1239           8 :     CATCH_START_SECTION("cluck_daemon_errors: invalid logger parameter")
    1240             :     {
    1241           1 :         SNAP_CATCH2_NAMESPACE::reset_log_errors safe_counters;
    1242           1 :         char const * const args[] = {
    1243             :             "cluckd", // name of command
    1244             :             "--log-severity",
    1245             :             "unknown-severity-name",
    1246             :             nullptr
    1247             :         };
    1248             : 
    1249           3 :         CATCH_REQUIRE_THROWS_MATCHES(
    1250             :               std::make_shared<cluck_daemon::cluckd>(3, const_cast<char **>(args))
    1251             :             , advgetopt::getopt_exit
    1252             :             , Catch::Matchers::ExceptionMessage("getopt_exception: logger options generated an error."));
    1253           1 :     }
    1254           7 :     CATCH_END_SECTION()
    1255             : 
    1256           8 :     CATCH_START_SECTION("cluck_daemon_errors: standalone command line options are not allowed")
    1257             :     {
    1258           1 :         SNAP_CATCH2_NAMESPACE::reset_log_errors safe_counters;
    1259           1 :         char const * const args[] = {
    1260             :             "cluckd", // name of command
    1261             :             "filename",
    1262             :             nullptr
    1263             :         };
    1264             : 
    1265           3 :         CATCH_REQUIRE_THROWS_MATCHES(
    1266             :               std::make_shared<cluck_daemon::cluckd>(2, const_cast<char **>(args))
    1267             :             , advgetopt::getopt_exit
    1268             :             , Catch::Matchers::ExceptionMessage("getopt_exception: errors were found on your command line, environment variable, or configuration file."));
    1269           1 :     }
    1270           7 :     CATCH_END_SECTION()
    1271             : 
    1272           8 :     CATCH_START_SECTION("cluck_daemon_errors: double severity")
    1273             :     {
    1274           1 :         SNAP_CATCH2_NAMESPACE::reset_log_errors safe_counters;
    1275           1 :         char const * const args[] = {
    1276             :             "cluckd", // name of command
    1277             :             "--log-severity",
    1278             :             "INFO",
    1279             :             "ERROR",        // oops, the log severity level "leaked"
    1280             :             nullptr
    1281             :         };
    1282             : 
    1283           3 :         CATCH_REQUIRE_THROWS_MATCHES(
    1284             :               std::make_shared<cluck_daemon::cluckd>(4, const_cast<char **>(args))
    1285             :             , advgetopt::getopt_exit
    1286             :             , Catch::Matchers::ExceptionMessage("getopt_exception: errors were found on your command line, environment variable, or configuration file."));
    1287           1 :     }
    1288           7 :     CATCH_END_SECTION()
    1289             : 
    1290           8 :     CATCH_START_SECTION("cluck_daemon_errors: get max ticket overflow")
    1291             :     {
    1292           1 :         addr::addr a(get_address());
    1293             : 
    1294           1 :         std::vector<std::string> const args = {
    1295             :             "cluckd", // name of command
    1296             :             "--candidate-priority",
    1297             :             "10",
    1298             :             "--communicatord-listen",
    1299           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1300             :             "--path-to-message-definitions",
    1301             : 
    1302             :             // WARNING: the order matters, we want to test with our source
    1303             :             //          (i.e. original) files first
    1304             :             //
    1305           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1306           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1307          17 :         };
    1308             : 
    1309             :         // convert arguments
    1310             :         //
    1311           1 :         std::vector<char const *> args_strings;
    1312           1 :         args_strings.reserve(args.size() + 1);
    1313           8 :         for(auto const & arg : args)
    1314             :         {
    1315           7 :             args_strings.push_back(arg.c_str());
    1316             :         }
    1317           1 :         args_strings.push_back(nullptr); // NULL terminated
    1318             : 
    1319           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1320           1 :         lock->add_connections();
    1321             : 
    1322           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1323           1 :         std::string const filename(source_dir + "/tests/rprtr/failed_with_max_ticket_too_large.rprtr");
    1324           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1325           1 :         CATCH_REQUIRE(l != nullptr);
    1326           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1327           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1328           1 :         p->parse_program();
    1329             : 
    1330           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1331           1 :         e->start();
    1332             : 
    1333           1 :         e->set_thread_done_callback([lock]()
    1334             :             {
    1335           1 :                 lock->stop(true);
    1336           1 :             });
    1337             : 
    1338             :         try
    1339             :         {
    1340           1 :             lock->run();
    1341             :         }
    1342           1 :         catch(cluck::out_of_range const & ex)
    1343             :         {
    1344           1 :             SNAP_LOG_INFO
    1345             :                 << "got the expected exception: "
    1346             :                 << ex
    1347             :                 << SNAP_LOG_SEND;
    1348             : 
    1349           2 :             std::string const expected("out_of_range: ticket::max_ticket() tried to generate the next ticket and got a wrapping around number.");
    1350           1 :             CATCH_REQUIRE(ex.what() == expected);
    1351             : 
    1352             :             // the communicator daemon may still have connections because of
    1353             :             // the exception
    1354             :             //
    1355           2 :             ed::connection::vector_t connections(ed::communicator::instance()->get_connections());
    1356           1 :             for(auto c : connections)
    1357             :             {
    1358           0 :                 ed::communicator::instance()->remove_connection(c);
    1359           0 :             }
    1360           2 :         }
    1361           0 :         catch(std::exception const & ex)
    1362             :         {
    1363           0 :             SNAP_LOG_FATAL
    1364             :                 << "an exception occurred while running cluckd (get max ticket overflow): "
    1365             :                 << ex
    1366             :                 << SNAP_LOG_SEND;
    1367             : 
    1368           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1369           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1370             :             {
    1371           0 :                 SNAP_LOG_FATAL
    1372             :                     << "    "
    1373             :                     << line
    1374             :                     << SNAP_LOG_SEND;
    1375             :             }
    1376             : 
    1377           0 :             throw;
    1378           0 :         }
    1379             : 
    1380           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
    1381           1 :     }
    1382           7 :     CATCH_END_SECTION()
    1383             : 
    1384           8 :     CATCH_START_SECTION("cluck_daemon_errors: too many computers are off")
    1385             :     {
    1386           1 :         addr::addr a(get_address());
    1387             : 
    1388           5 :         for(int version(1); version <= 4; ++version)
    1389             :         {
    1390          14 :             for(int off_mask(1); off_mask < (version == 4 ? 8 : 2); ++off_mask)
    1391             :             {
    1392          20 :                 std::string diagnostic_msg("version: " + std::to_string(version));
    1393          10 :                 if(version == 4)
    1394             :                 {
    1395           7 :                     diagnostic_msg += '/';
    1396           7 :                     diagnostic_msg += std::to_string(off_mask);
    1397             :                 }
    1398          10 :                 ::snaplogger::nested_diagnostic version_diagnostic(diagnostic_msg, true);
    1399             : 
    1400          10 :                 std::vector<std::string> const args = {
    1401             :                     "cluckd", // name of command
    1402             :                     "--candidate-priority",
    1403           9 :                     (version == 2 || (version == 4 && (off_mask & 0x04) != 0) ? "15" : "10"),
    1404             :                     "--communicatord-listen",
    1405          20 :                     "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1406             :                     "--path-to-message-definitions",
    1407             : 
    1408             :                     // WARNING: the order matters, we want to test with our source
    1409             :                     //          (i.e. original) files first
    1410             :                     //
    1411          20 :                     SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1412          30 :                         + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1413         179 :                 };
    1414             : 
    1415             :                 // convert arguments
    1416             :                 //
    1417          10 :                 std::vector<char const *> args_strings;
    1418          10 :                 args_strings.reserve(args.size() + 1);
    1419          80 :                 for(auto const & arg : args)
    1420             :                 {
    1421          70 :                     args_strings.push_back(arg.c_str());
    1422             :                 }
    1423          10 :                 args_strings.push_back(nullptr); // NULL terminated
    1424             : 
    1425          10 :                 cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1426          10 :                 lock->add_connections();
    1427             : 
    1428          10 :                 std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1429          40 :                 std::string const filename(source_dir + "/tests/rprtr/failed_with_too_many_off_v" + std::to_string(version) + ".rprtr");
    1430          10 :                 SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1431          10 :                 CATCH_REQUIRE(l != nullptr);
    1432          10 :                 SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1433          10 :                 if(version == 4)
    1434             :                 {
    1435           7 :                     SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t var(
    1436             :                             std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(
    1437           7 :                                       "off_mask"));
    1438           7 :                     var->set_integer(off_mask);
    1439           7 :                     s->set_variable(var);
    1440           7 :                 }
    1441          10 :                 SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1442          10 :                 p->parse_program();
    1443             : 
    1444          10 :                 SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1445          10 :                 e->start();
    1446             : 
    1447          10 :                 e->set_thread_done_callback([lock]()
    1448             :                     {
    1449          10 :                         lock->stop(true);
    1450          10 :                     });
    1451             : 
    1452             :                 try
    1453             :                 {
    1454          10 :                     lock->run();
    1455             :                 }
    1456           0 :                 catch(std::exception const & ex)
    1457             :                 {
    1458           0 :                     SNAP_LOG_FATAL
    1459             :                         << "an exception occurred while running cluckd (get max ticket overflow): "
    1460             :                         << ex
    1461             :                         << SNAP_LOG_SEND;
    1462             : 
    1463           0 :                     libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1464           0 :                     if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1465             :                     {
    1466           0 :                         SNAP_LOG_FATAL
    1467             :                             << "    "
    1468             :                             << line
    1469             :                             << SNAP_LOG_SEND;
    1470             :                     }
    1471             : 
    1472           0 :                     throw;
    1473           0 :                 }
    1474             : 
    1475          10 :                 CATCH_REQUIRE(s->get_exit_code() == 0);
    1476          10 :             }
    1477             :         }
    1478           1 :     }
    1479           7 :     CATCH_END_SECTION()
    1480             : 
    1481           8 :     CATCH_START_SECTION("cluck_daemon_errors: 100% time out")
    1482             :     {
    1483           1 :         addr::addr a(get_address());
    1484             : 
    1485           1 :         std::vector<std::string> const args = {
    1486             :             "cluckd", // name of command
    1487             :             "--candidate-priority",
    1488             :             "10",
    1489             :             "--communicatord-listen",
    1490           2 :             "cd://" + a.to_ipv4or6_string(addr::STRING_IP_ADDRESS_PORT),
    1491             :             "--path-to-message-definitions",
    1492             : 
    1493             :             // WARNING: the order matters, we want to test with our source
    1494             :             //          (i.e. original) files first
    1495             :             //
    1496           2 :             SNAP_CATCH2_NAMESPACE::g_source_dir() + "/daemon/message-definitions:"
    1497           3 :                 + SNAP_CATCH2_NAMESPACE::g_dist_dir() + "/share/eventdispatcher/messages",
    1498          17 :         };
    1499             : 
    1500             :         // convert arguments
    1501             :         //
    1502           1 :         std::vector<char const *> args_strings;
    1503           1 :         args_strings.reserve(args.size() + 1);
    1504           8 :         for(auto const & arg : args)
    1505             :         {
    1506           7 :             args_strings.push_back(arg.c_str());
    1507             :         }
    1508           1 :         args_strings.push_back(nullptr); // NULL terminated
    1509             : 
    1510           1 :         cluck_daemon::cluckd::pointer_t lock(std::make_shared<cluck_daemon::cluckd>(args.size(), const_cast<char **>(args_strings.data())));
    1511           1 :         lock->add_connections();
    1512             : 
    1513           1 :         std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
    1514           1 :         std::string const filename(source_dir + "/tests/rprtr/cluck_daemon_test_timeout.rprtr");
    1515           1 :         SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
    1516           1 :         CATCH_REQUIRE(l != nullptr);
    1517           1 :         SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
    1518           1 :         SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
    1519           1 :         p->parse_program();
    1520             : 
    1521           1 :         SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
    1522           1 :         e->start();
    1523             : 
    1524           1 :         e->set_thread_done_callback([lock]()
    1525             :             {
    1526           1 :                 lock->stop(true);
    1527           1 :             });
    1528             : 
    1529             :         try
    1530             :         {
    1531           1 :             lock->run();
    1532             :         }
    1533           0 :         catch(std::exception const & ex)
    1534             :         {
    1535           0 :             SNAP_LOG_FATAL
    1536             :                 << "an exception occurred while running cluckd (get max ticket overflow): "
    1537             :                 << ex
    1538             :                 << SNAP_LOG_SEND;
    1539             : 
    1540           0 :             libexcept::exception_base_t const * b(dynamic_cast<libexcept::exception_base_t const *>(&ex));
    1541           0 :             if(b != nullptr) for(auto const & line : b->get_stack_trace())
    1542             :             {
    1543           0 :                 SNAP_LOG_FATAL
    1544             :                     << "    "
    1545             :                     << line
    1546             :                     << SNAP_LOG_SEND;
    1547             :             }
    1548             : 
    1549           0 :             throw;
    1550           0 :         }
    1551             : 
    1552           1 :         CATCH_REQUIRE(s->get_exit_code() == 0);
    1553           1 :     }
    1554           7 :     CATCH_END_SECTION()
    1555           6 : }
    1556             : 
    1557             : 
    1558             : 
    1559             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14

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