LCOV - code coverage report
Current view: top level - tests - config.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 571 575 99.3 %
Date: 2021-09-08 13:54:31 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * License:
       3             :  *    Copyright (c) 2006-2021  Made to Order Software Corp.  All Rights Reserved
       4             :  *
       5             :  *    https://snapwebsites.org/
       6             :  *    contact@m2osw.com
       7             :  *
       8             :  *    This program is free software; you can redistribute it and/or modify
       9             :  *    it under the terms of the GNU General Public License as published by
      10             :  *    the Free Software Foundation; either version 2 of the License, or
      11             :  *    (at your option) any later version.
      12             :  *
      13             :  *    This program is distributed in the hope that it will be useful,
      14             :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *    GNU General Public License for more details.
      17             :  *
      18             :  *    You should have received a copy of the GNU General Public License along
      19             :  *    with this program; if not, write to the Free Software Foundation, Inc.,
      20             :  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      21             :  *
      22             :  * Authors:
      23             :  *    Alexis Wilke   alexis@m2osw.com
      24             :  */
      25             : 
      26             : // self
      27             : //
      28             : #include "main.h"
      29             : 
      30             : // advgetopt lib
      31             : //
      32             : #include <advgetopt/exception.h>
      33             : 
      34             : // snapdev lib
      35             : //
      36             : #include <snapdev/safe_setenv.h>
      37             : 
      38             : // C++ lib
      39             : //
      40             : #include <fstream>
      41             : 
      42             : // C lib
      43             : //
      44             : #include <unistd.h>
      45             : 
      46             : 
      47             : 
      48             : 
      49             : 
      50             : 
      51             : 
      52          11 : CATCH_TEST_CASE("configuration_filenames", "[config][getopt][filenames]")
      53             : {
      54          18 :     CATCH_START_SECTION("Configuration Files")
      55           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-any", "any");
      56             : 
      57           1 :         advgetopt::options_environment environment_options;
      58             : 
      59           1 :         char const * confs[] =
      60             :         {
      61           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
      62             :             ".config/file.mdi",
      63             :             "/etc/snapwebsites/server.conf",
      64             :             nullptr
      65           1 :         };
      66             :     
      67           1 :         environment_options.f_project_name = "unittest-any";
      68           1 :         environment_options.f_options = nullptr;
      69           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
      70           1 :         environment_options.f_help_header = "Testing all possible filenames";
      71           1 :         environment_options.f_configuration_files = confs;
      72             : 
      73           2 :         advgetopt::getopt opt(environment_options);
      74             : 
      75           2 :         advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
      76             : 
      77           1 :         CATCH_REQUIRE(filenames.size() == 6);
      78           1 :         CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
      79           1 :         CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
      80           1 :         CATCH_REQUIRE(filenames[2] == ".config/file.mdi");
      81           1 :         CATCH_REQUIRE(filenames[3] == ".config/unittest-any.d/50-file.mdi");
      82           1 :         CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/server.conf");
      83           1 :         CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-any.d/50-server.conf");
      84             :     CATCH_END_SECTION()
      85             : 
      86          18 :     CATCH_START_SECTION("Configuration Files (writable)")
      87           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable", "writable");
      88             : 
      89           1 :         advgetopt::options_environment environment_options;
      90             : 
      91           1 :         char const * confs[] =
      92             :         {
      93             :             ".config/file.mdi",
      94           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
      95             :             "/etc/snapwebsites/server.conf",
      96             :             nullptr
      97           1 :         };
      98             :     
      99           1 :         environment_options.f_project_name = "unittest-writable";
     100           1 :         environment_options.f_options = nullptr;
     101           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     102           1 :         environment_options.f_help_header = "Testing all possible filenames";
     103           1 :         environment_options.f_configuration_files = confs;
     104             : 
     105           2 :         advgetopt::getopt opt(environment_options);
     106             : 
     107           2 :         advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, true));
     108             : 
     109           1 :         CATCH_REQUIRE(filenames.size() == 3);
     110           1 :         CATCH_REQUIRE(filenames[0] == ".config/unittest-writable.d/50-file.mdi");
     111           1 :         CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
     112           1 :         CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/unittest-writable.d/50-server.conf");
     113             :     CATCH_END_SECTION()
     114             : 
     115          18 :     CATCH_START_SECTION("Configuration File + Directories")
     116           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories", "with-dirs", true);
     117             : 
     118           1 :         advgetopt::options_environment environment_options;
     119             : 
     120           1 :         char const * dirs[] =
     121             :         {
     122           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     123             :             ".config",
     124             :             "/etc/snapwebsites",
     125             :             nullptr
     126           1 :         };
     127             :     
     128           1 :         environment_options.f_project_name = "unittest-with-directories";
     129           1 :         environment_options.f_options = nullptr;
     130           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     131           1 :         environment_options.f_help_header = "Testing all possible filenames";
     132           1 :         environment_options.f_configuration_filename = "snapfirewall.conf";
     133           1 :         environment_options.f_configuration_directories = dirs;
     134             : 
     135           2 :         advgetopt::getopt opt(environment_options);
     136             : 
     137           2 :         advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
     138             : 
     139           1 :         CATCH_REQUIRE(filenames.size() == 6);
     140           1 :         CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
     141           1 :         CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/50-snapfirewall.conf");
     142           1 :         CATCH_REQUIRE(filenames[2] == ".config/snapfirewall.conf");
     143           1 :         CATCH_REQUIRE(filenames[3] == ".config/unittest-with-directories.d/50-snapfirewall.conf");
     144           1 :         CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/snapfirewall.conf");
     145           1 :         CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-with-directories.d/50-snapfirewall.conf");
     146             :     CATCH_END_SECTION()
     147             : 
     148          18 :     CATCH_START_SECTION("Configuration File + Directories + '--config-dir'")
     149           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories-and-config-dir", "with-many-dirs", true);
     150             : 
     151           1 :         advgetopt::options_environment environment_options;
     152             : 
     153           1 :         char const * dirs[] =
     154             :         {
     155           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     156             :             ".config",
     157             :             "/etc/advgetopt",
     158             :             nullptr
     159           1 :         };
     160             :     
     161           1 :         environment_options.f_project_name = "unittest-with-directories-and-config-dir";
     162           1 :         environment_options.f_options = nullptr;
     163           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     164           1 :         environment_options.f_help_header = "Testing all possible filenames";
     165           1 :         environment_options.f_configuration_filename = "snapmerger.conf";
     166           1 :         environment_options.f_configuration_directories = dirs;
     167             : 
     168           1 :         char const * cargv[] =
     169             :         {
     170             :             "/usr/bin/config",
     171             :             "--config-dir",
     172             :             "/var/lib/advgetopt",
     173             :             "--config-dir",
     174             :             "/opt/config",
     175             :             nullptr
     176             :         };
     177           1 :         int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
     178           1 :         char ** argv = const_cast<char **>(cargv);
     179             : 
     180           2 :         advgetopt::getopt opt(environment_options, argc, argv);
     181             : 
     182           2 :         advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
     183             : 
     184           1 :         CATCH_REQUIRE(filenames.size() == 10);
     185           1 :         CATCH_REQUIRE(filenames[0] == "/var/lib/advgetopt/snapmerger.conf");
     186           1 :         CATCH_REQUIRE(filenames[1] == "/var/lib/advgetopt/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
     187           1 :         CATCH_REQUIRE(filenames[2] == "/opt/config/snapmerger.conf");
     188           1 :         CATCH_REQUIRE(filenames[3] == "/opt/config/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
     189           1 :         CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapmerger.conf");
     190           1 :         CATCH_REQUIRE(filenames[5] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/50-snapmerger.conf");
     191           1 :         CATCH_REQUIRE(filenames[6] == ".config/snapmerger.conf");
     192           1 :         CATCH_REQUIRE(filenames[7] == ".config/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
     193           1 :         CATCH_REQUIRE(filenames[8] == "/etc/advgetopt/snapmerger.conf");
     194           1 :         CATCH_REQUIRE(filenames[9] == "/etc/advgetopt/unittest-with-directories-and-config-dir.d/50-snapmerger.conf");
     195             :     CATCH_END_SECTION()
     196             : 
     197          18 :     CATCH_START_SECTION("Existing Configuration Files")
     198             : 
     199          10 :         CATCH_WHEN("R/W Config must exist--no user defined config")
     200             :         {
     201           1 :             SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-must-exist", "must-be-here");
     202             : 
     203             :             {
     204           2 :                 std::ofstream config_file;
     205           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     206           1 :                 CATCH_REQUIRE(config_file.good());
     207           1 :                 config_file <<
     208             :                     "# Auto-generated\n"
     209             :                     "ip=192.168.0.1\n"
     210             :                     "wall=iptables\n"
     211             :                 ;
     212             :             }
     213             : 
     214           1 :             unlink(SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str());
     215             : 
     216           1 :             char const * confs[] =
     217             :             {
     218           1 :                 SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     219             :                 ".config/file-which-was-never-created.mdi",
     220             :                 "/etc/snapwebsites/not-an-existing-file.conf",
     221             :                 nullptr
     222           1 :             };
     223             : 
     224           1 :             advgetopt::options_environment environment_options;
     225           1 :             environment_options.f_project_name = "unittest";
     226           1 :             environment_options.f_options = nullptr;
     227           1 :             environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     228           1 :             environment_options.f_help_header = "Testing all possible filenames";
     229           1 :             environment_options.f_configuration_files = confs;
     230             : 
     231           2 :             advgetopt::getopt opt(environment_options);
     232             : 
     233           2 :             advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
     234             : 
     235           1 :             CATCH_REQUIRE(filenames.size() == 1);
     236           1 :             CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
     237             :         }
     238             : 
     239          10 :         CATCH_WHEN("R/W Config must exist--user defined config exists")
     240             :         {
     241           1 :             SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-exist", "existing");
     242             : 
     243             :             {
     244           2 :                 std::ofstream config_file;
     245           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     246           1 :                 CATCH_REQUIRE(config_file.good());
     247           1 :                 config_file <<
     248             :                     "# Auto-generated\n"
     249             :                     "block-ip=192.168.6.11\n"
     250             :                     "firewall=iptables\n"
     251             :                 ;
     252             :             }
     253             : 
     254             :             {
     255           2 :                 std::ofstream config_file;
     256           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     257           1 :                 CATCH_REQUIRE(config_file.good());
     258           1 :                 config_file <<
     259             :                     "# Auto-generated\n"
     260             :                     "ip=10.0.2.5\n"
     261             :                     "duration=6h\n"
     262             :                 ;
     263             :             }
     264             : 
     265           1 :             char const * confs[] =
     266             :             {
     267             :                 ".config/file-which-was-never-created.mdi",
     268             :                 "/etc/snapwebsites/not-an-existing-file.conf",
     269           1 :                 SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     270             :                 nullptr
     271           1 :             };
     272             : 
     273           1 :             advgetopt::options_environment environment_options;
     274           1 :             environment_options.f_project_name = "unittest-user-exist";
     275           1 :             environment_options.f_options = nullptr;
     276           1 :             environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     277           1 :             environment_options.f_help_header = "Testing all possible filenames";
     278           1 :             environment_options.f_configuration_files = confs;
     279             : 
     280           2 :             advgetopt::getopt opt(environment_options);
     281             : 
     282           2 :             advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
     283             : 
     284           1 :             CATCH_REQUIRE(filenames.size() == 2);
     285           1 :             CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
     286           1 :             CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
     287             :         }
     288             : 
     289          10 :         CATCH_WHEN("Writable Config must exist--user defined config exists")
     290             :         {
     291           1 :             SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-exist", "present");
     292             : 
     293             :             {
     294           2 :                 std::ofstream config_file;
     295           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     296           1 :                 CATCH_REQUIRE(config_file.good());
     297           1 :                 config_file <<
     298             :                     "# Auto-generated\n"
     299             :                     "block-ip=192.168.6.11\n"
     300             :                     "firewall=iptables\n"
     301             :                 ;
     302             :             }
     303             : 
     304             :             {
     305           2 :                 std::ofstream config_file;
     306           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     307           1 :                 CATCH_REQUIRE(config_file.good());
     308           1 :                 config_file <<
     309             :                     "# Auto-generated\n"
     310             :                     "ip=10.0.2.5\n"
     311             :                     "duration=6h\n"
     312             :                 ;
     313             :             }
     314             : 
     315           1 :             char const * confs[] =
     316             :             {
     317             :                 ".config/file-which-was-never-created.mdi",
     318           1 :                 SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     319             :                 "/etc/snapwebsites/not/an-existing-file.conf",
     320             :                 nullptr
     321           1 :             };
     322             : 
     323           1 :             advgetopt::options_environment environment_options;
     324           1 :             environment_options.f_project_name = "unittest-writable-exist";
     325           1 :             environment_options.f_options = nullptr;
     326           1 :             environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     327           1 :             environment_options.f_help_header = "Testing all possible filenames";
     328           1 :             environment_options.f_configuration_files = confs;
     329             : 
     330           2 :             advgetopt::getopt opt(environment_options);
     331             : 
     332           2 :             advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
     333             : 
     334           1 :             CATCH_REQUIRE(filenames.size() == 1);
     335           1 :             CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
     336             :         }
     337             : 
     338          10 :         CATCH_WHEN("Writable Config must exist--user defined config exists and we test with a user folder")
     339             :         {
     340           1 :             SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-user", "user-write");
     341             : 
     342             :             {
     343           2 :                 std::ofstream config_file;
     344           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     345           1 :                 CATCH_REQUIRE(config_file.good());
     346           1 :                 config_file <<
     347             :                     "# Auto-generated\n"
     348             :                     "block-ip=192.168.6.11\n"
     349             :                     "firewall=iptables\n"
     350             :                 ;
     351             :             }
     352             : 
     353             :             {
     354           2 :                 std::ofstream config_file;
     355           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     356           1 :                 CATCH_REQUIRE(config_file.good());
     357           1 :                 config_file <<
     358             :                     "# Auto-generated\n"
     359             :                     "ip=10.0.2.5\n"
     360             :                     "duration=6h\n"
     361             :                 ;
     362             :             }
     363             : 
     364           1 :             char const * confs[] =
     365             :             {
     366             :                 "~/.config/file-which-was-never-created.mdi",
     367           1 :                 SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     368             :                 "/etc/snapwebsites/not/an-existing-file.conf",
     369             :                 nullptr
     370           1 :             };
     371             : 
     372           1 :             advgetopt::options_environment environment_options;
     373           1 :             environment_options.f_project_name = "unittest-writable-user";
     374           1 :             environment_options.f_options = nullptr;
     375           1 :             environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     376           1 :             environment_options.f_help_header = "Testing all possible filenames";
     377           1 :             environment_options.f_configuration_files = confs;
     378             : 
     379           2 :             advgetopt::getopt opt(environment_options);
     380             : 
     381           2 :             advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
     382             : 
     383           1 :             CATCH_REQUIRE(filenames.size() == 1);
     384           1 :             CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
     385             :         }
     386             : 
     387          10 :         CATCH_WHEN("R/W Config test must exist--user defined config exists and we test with a user folder")
     388             :         {
     389           1 :             SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-folder", "tilde");
     390             : 
     391           2 :             std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
     392           1 :             tmpdir += "/.config/home-that-never-gets-created";
     393           2 :             snap::safe_setenv env("HOME", tmpdir);
     394             : 
     395             :             {
     396           2 :                 std::ofstream config_file;
     397           1 :                 config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     398           1 :                 CATCH_REQUIRE(config_file.good());
     399           1 :                 config_file <<
     400             :                     "# Auto-generated\n"
     401             :                     "ip=10.0.2.5\n"
     402             :                     "duration=6h\n"
     403             :                 ;
     404             :             }
     405             : 
     406           1 :             char const * dirs[] =
     407             :             {
     408             :                 "~/.config/folder-which-was-never-created",
     409             :                 "/etc/snapwebsites/not-an-existing-folder",
     410           1 :                 SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     411             :                 nullptr
     412           1 :             };
     413             : 
     414           1 :             advgetopt::options_environment environment_options;
     415           1 :             environment_options.f_project_name = "unittest-user-folder";
     416           1 :             environment_options.f_options = nullptr;
     417           1 :             environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     418           1 :             environment_options.f_help_header = "Testing all possible filenames";
     419           1 :             environment_options.f_configuration_filename = "snapfirewall.conf";
     420           1 :             environment_options.f_configuration_directories = dirs;
     421             : 
     422           2 :             advgetopt::getopt opt(environment_options);
     423             : 
     424           2 :             advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
     425             : 
     426           1 :             CATCH_REQUIRE(filenames.size() == 5);
     427           1 :             CATCH_REQUIRE(filenames[0] == tmpdir + "/.config/folder-which-was-never-created/snapfirewall.conf");
     428           1 :             CATCH_REQUIRE(filenames[1] == "/etc/snapwebsites/not-an-existing-folder/snapfirewall.conf");
     429           1 :             CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/not-an-existing-folder/unittest-user-folder.d/50-snapfirewall.conf");
     430           1 :             CATCH_REQUIRE(filenames[3] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
     431           1 :             CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/unittest-user-folder.d/50-snapfirewall.conf");
     432             :         }
     433             :     CATCH_END_SECTION()
     434           9 : }
     435             : 
     436             : 
     437             : 
     438           5 : CATCH_TEST_CASE("load_configuration_file", "[config][getopt][filenames]")
     439             : {
     440           6 :     CATCH_START_SECTION("Load a Configuration File")
     441             :     {
     442           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("load", "tool");
     443             : 
     444             :         {
     445           2 :             std::ofstream config_file;
     446           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     447           1 :             CATCH_REQUIRE(config_file.good());
     448           1 :             config_file <<
     449             :                 "# Auto-generated\n"
     450             :                 "sizes=132\n"
     451             :                 "filenames=green,orange,blue brown white\n"
     452             :             ;
     453             :         }
     454             : 
     455           1 :         char const * confs[] =
     456             :         {
     457             :             "~/.config/file-which-was-never-created.mdi",
     458           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     459             :             "/etc/snapwebsites/not/an-existing-file.conf",
     460             :             nullptr
     461           1 :         };
     462             : 
     463           1 :         char const * const separators[] {
     464             :             ",",
     465             :             " ",
     466             :             nullptr
     467             :         };
     468             : 
     469           1 :         advgetopt::option const options[] =
     470             :         {
     471             :             advgetopt::define_option(
     472             :                   advgetopt::Name("sizes")
     473             :                 , advgetopt::ShortName('s')
     474             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     475             :                 , advgetopt::Help("sizes.")
     476             :             ),
     477             :             advgetopt::define_option(
     478             :                   advgetopt::Name("filenames")
     479             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
     480             :                 , advgetopt::Help("enter a list of filenames.")
     481             :                 , advgetopt::DefaultValue("a.out")
     482             :                 , advgetopt::Separators(separators)
     483           6 :             ),
     484             :             advgetopt::end_options()
     485           7 :         };
     486             : 
     487           1 :         advgetopt::options_environment environment_options;
     488           1 :         environment_options.f_project_name = "load";
     489           1 :         environment_options.f_options = options;
     490           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     491           1 :         environment_options.f_help_header = "Testing loading a filenames";
     492           1 :         environment_options.f_configuration_files = confs;
     493             : 
     494           2 :         advgetopt::getopt opt(environment_options);
     495             : 
     496           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
     497             : 
     498           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
     499           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "132");
     500             : 
     501           1 :         CATCH_REQUIRE(opt.size("filenames") == 5);
     502           1 :         CATCH_REQUIRE(opt.get_string("filenames") == "green");
     503           1 :         CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
     504           1 :         CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
     505           1 :         CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
     506           1 :         CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
     507           1 :         CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
     508             :     }
     509             :     CATCH_END_SECTION()
     510             : 
     511           6 :     CATCH_START_SECTION("Load an Extended Configuration File")
     512             :     {
     513           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-extended", "extended");
     514             : 
     515             :         {
     516           2 :             std::ofstream config_file;
     517           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     518           1 :             CATCH_REQUIRE(config_file.good());
     519           1 :             config_file <<
     520             :                 "# Auto-generated\n"
     521             :                 "sizes=132\n"
     522             :                 "object=property.obj\n"
     523             :                 "filenames=green,orange,blue brown white\n"
     524             :                 "visibility=hidden\n"
     525             :             ;
     526             :         }
     527             : 
     528           1 :         char const * confs[] =
     529             :         {
     530             :             "~/.config/file-which-was-never-created.mdi",
     531           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     532             :             "/etc/snapwebsites/not/an-existing-file.conf",
     533             :             nullptr
     534           1 :         };
     535             : 
     536           1 :         char const * const separators[] {
     537             :             ",",
     538             :             " ",
     539             :             nullptr
     540             :         };
     541             : 
     542           1 :         advgetopt::option const options[] =
     543             :         {
     544             :             advgetopt::define_option(
     545             :                   advgetopt::Name("sizes")
     546             :                 , advgetopt::ShortName('s')
     547             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     548             :                 , advgetopt::Help("sizes.")
     549             :             ),
     550             :             advgetopt::define_option(
     551             :                   advgetopt::Name("filenames")
     552             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
     553             :                 , advgetopt::Help("enter a list of filenames.")
     554             :                 , advgetopt::DefaultValue("a.out")
     555             :                 , advgetopt::Separators(separators)
     556           6 :             ),
     557             :             advgetopt::end_options()
     558           7 :         };
     559             : 
     560           1 :         advgetopt::options_environment environment_options;
     561           1 :         environment_options.f_project_name = "load-extended";
     562           1 :         environment_options.f_options = options;
     563           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
     564           1 :         environment_options.f_help_header = "Testing loading filenames";
     565           1 :         environment_options.f_configuration_files = confs;
     566             : 
     567           2 :         advgetopt::getopt opt(environment_options);
     568             : 
     569           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
     570             : 
     571           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
     572           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "132");
     573             : 
     574           1 :         CATCH_REQUIRE(opt.size("filenames") == 5);
     575           1 :         CATCH_REQUIRE(opt.get_string("filenames") == "green");
     576           1 :         CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
     577           1 :         CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
     578           1 :         CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
     579           1 :         CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
     580           1 :         CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
     581             : 
     582           1 :         CATCH_REQUIRE(opt.size("object") == 1);
     583           1 :         CATCH_REQUIRE(opt.get_string("object") == "property.obj");
     584             : 
     585           1 :         CATCH_REQUIRE(opt.size("visibility") == 1);
     586           1 :         CATCH_REQUIRE(opt.get_string("visibility") == "hidden");
     587             :     }
     588             :     CATCH_END_SECTION()
     589             : 
     590           6 :     CATCH_START_SECTION("Load a Configuration File with Sections")
     591             :     {
     592           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-with-sections", "sections");
     593             : 
     594             :         {
     595           2 :             std::ofstream config_file;
     596           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     597           1 :             CATCH_REQUIRE(config_file.good());
     598           1 :             config_file <<
     599             :                 "# Auto-generated\n"
     600             :                 "\n"
     601             :                 "[integers]\n"
     602             :                 "sizes=132\n"
     603             :                 "\n"
     604             :                 "[objects]\n"
     605             :                 "object=property.obj\n"
     606             :                 "filenames=green orange blue brown white\n"
     607             :                 "\n"
     608             :                 "[flags]\n"
     609             :                 "visibility=hidden\n"
     610             :                 "\n"
     611             :                 "[integers]\n"
     612             :                 "max=1111\n"
     613             :                 "\n"
     614             :                 "# vim: ts=4 sw=4 et\n"
     615             :             ;
     616             :         }
     617             : 
     618           1 :         char const * confs[] =
     619             :         {
     620             :             "~/.config/file-which-was-never-created.mdi",
     621           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     622             :             "/etc/snapwebsites/not/an-existing-file.conf",
     623             :             nullptr
     624           1 :         };
     625             : 
     626           1 :         char const * const separators[] {
     627             :             ",",
     628             :             " ",
     629             :             nullptr
     630             :         };
     631             : 
     632           1 :         advgetopt::option const options[] =
     633             :         {
     634             :             advgetopt::define_option(
     635             :                   advgetopt::Name("objects::object")
     636             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     637             :                 , advgetopt::Help("object.")
     638             :             ),
     639             :             advgetopt::define_option(
     640             :                   advgetopt::Name("integers::sizes")
     641             :                 , advgetopt::ShortName('s')
     642             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     643             :                 , advgetopt::Help("sizes.")
     644             :             ),
     645             :             advgetopt::define_option(
     646             :                   advgetopt::Name("objects::filenames")
     647             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
     648             :                 , advgetopt::Help("enter a list of filenames.")
     649             :                 , advgetopt::DefaultValue("a.out")
     650             :                 , advgetopt::Separators(separators)
     651           6 :             ),
     652             :             advgetopt::define_option(
     653             :                   advgetopt::Name("integers::max")
     654             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     655             :                 , advgetopt::Help("maximum value.")
     656             :                 , advgetopt::DefaultValue("+oo")
     657             :             ),
     658             :             advgetopt::define_option(
     659             :                   advgetopt::Name("flags::visibility")
     660             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     661             :                 , advgetopt::Help("visibility.")
     662             :                 , advgetopt::DefaultValue("flashy")
     663             :             ),
     664             :             advgetopt::end_options()
     665           7 :         };
     666             : 
     667           1 :         advgetopt::options_environment environment_options;
     668           1 :         environment_options.f_project_name = "load-sections";
     669           1 :         environment_options.f_options = options;
     670           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     671           1 :         environment_options.f_help_header = "Testing loading sections";
     672           1 :         environment_options.f_configuration_files = confs;
     673             : 
     674           2 :         advgetopt::getopt opt(environment_options);
     675             : 
     676           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
     677             : 
     678           1 :         CATCH_REQUIRE(opt.size("integers::sizes") == 1);
     679           1 :         CATCH_REQUIRE(opt.get_string("integers::sizes") == "132");
     680             : 
     681           1 :         CATCH_REQUIRE(opt.size("objects::filenames") == 5);
     682           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames") == "green");
     683           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames", 0) == "green");
     684           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames", 1) == "orange");
     685           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames", 2) == "blue");
     686           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames", 3) == "brown");
     687           1 :         CATCH_REQUIRE(opt.get_string("objects::filenames", 4) == "white");
     688             : 
     689           1 :         CATCH_REQUIRE(opt.size("integers::max") == 1);
     690           1 :         CATCH_REQUIRE(opt.get_string("integers::max") == "1111");
     691             : 
     692           1 :         CATCH_REQUIRE(opt.size("objects::object") == 1);
     693           1 :         CATCH_REQUIRE(opt.get_string("objects::object") == "property.obj");
     694             : 
     695           1 :         CATCH_REQUIRE(opt.size("flags::visibility") == 1);
     696           1 :         CATCH_REQUIRE(opt.get_string("flags::visibility") == "hidden");
     697             : 
     698           2 :         std::string const name(advgetopt::CONFIGURATION_SECTIONS);
     699           1 :         CATCH_REQUIRE(opt.size(name) == 3);
     700           1 :         CATCH_REQUIRE(opt.get_string(name) == "flags");
     701           1 :         CATCH_REQUIRE(opt.get_string(name, 0) == "flags");
     702           1 :         CATCH_REQUIRE(opt.get_string(name, 1) == "integers");
     703           1 :         CATCH_REQUIRE(opt.get_string(name, 2) == "objects");
     704             :     }
     705             :     CATCH_END_SECTION()
     706           3 : }
     707             : 
     708             : 
     709             : 
     710           4 : CATCH_TEST_CASE("load_multiple_configurations", "[config][getopt][filenames]")
     711             : {
     712           4 :     CATCH_START_SECTION("Configuration Files")
     713             :     {
     714           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple", "multiplicity");
     715             : 
     716           1 :         advgetopt::options_environment environment_options;
     717             : 
     718           2 :         std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
     719           1 :         tmpdir += "/.config/home";
     720             : 
     721           2 :         std::stringstream ss;
     722           1 :         ss << "mkdir -p " << tmpdir;
     723           1 :         if(system(ss.str().c_str()) != 0)
     724             :         {
     725           0 :             std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
     726           0 :             exit(1);
     727             :         }
     728             : 
     729           2 :         snap::safe_setenv env("HOME", tmpdir);
     730             : 
     731             :         {
     732           2 :             std::ofstream config_file;
     733           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     734           1 :             CATCH_REQUIRE(config_file.good());
     735           1 :             config_file <<
     736             :                 "# Auto-generated\n"
     737             :                 "ip=10.0.2.5\n"
     738             :                 "duration=6h\n"
     739             :                 "size=604\n"
     740             :                 "gap=6\n"
     741             :                 "filename=utf9.txt\n"
     742             :             ;
     743             :         }
     744             : 
     745             :         {
     746           2 :             std::ofstream config_file;
     747           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     748           1 :             CATCH_REQUIRE(config_file.good());
     749           1 :             config_file <<
     750             :                 "# Auto-generated\n"
     751             :                 "ip=10.1.7.205\n"
     752             :                 "gap=9\n"
     753             :                 "filename=utf7.txt\n"
     754             :             ;
     755             :         }
     756             : 
     757             :         {
     758           2 :             std::ofstream config_file;
     759           1 :             config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     760           1 :             CATCH_REQUIRE(config_file.good());
     761           1 :             config_file <<
     762             :                 "# Auto-generated\n"
     763             :                 "duration=105min\n"
     764             :                 "filename=utf8.txt\n"
     765             :             ;
     766             :         }
     767             : 
     768           1 :         char const * confs[] =
     769             :         {
     770           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     771           1 :             SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
     772             :             "~/advgetopt.conf",
     773             :             nullptr
     774           2 :         };
     775             :     
     776           1 :         advgetopt::option const options[] =
     777             :         {
     778             :             advgetopt::define_option(
     779             :                   advgetopt::Name("size")
     780             :                 , advgetopt::ShortName('s')
     781             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     782             :                 , advgetopt::Help("size.")
     783             :             ),
     784             :             advgetopt::define_option(
     785             :                   advgetopt::Name("filename")
     786             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
     787             :                 , advgetopt::Help("enter a filenames.")
     788             :                 , advgetopt::DefaultValue("a.out")
     789             :             ),
     790             :             advgetopt::define_option(
     791             :                   advgetopt::Name("duration")
     792             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     793             :                 , advgetopt::Help("how long it lasts.")
     794             :             ),
     795             :             advgetopt::define_option(
     796             :                   advgetopt::Name("gap")
     797             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     798             :                 , advgetopt::Help("gap size.")
     799             :             ),
     800             :             advgetopt::define_option(
     801             :                   advgetopt::Name("ip")
     802             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     803             :                 , advgetopt::Help("enter the ip address.")
     804             :             ),
     805             :             advgetopt::end_options()
     806             :         };
     807             : 
     808           1 :         environment_options.f_project_name = "unittest";
     809           1 :         environment_options.f_options = options;
     810           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     811           1 :         environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
     812           1 :         environment_options.f_configuration_files = confs;
     813             : 
     814           2 :         advgetopt::getopt opt(environment_options);
     815             : 
     816           1 :         opt.parse_configuration_files(0, nullptr);
     817             : 
     818           1 :         CATCH_REQUIRE(opt.size("size") == 1);
     819           1 :         CATCH_REQUIRE(opt.get_string("size") == "604");
     820             : 
     821             :         // although it is marked as multiple, the old entries are still
     822             :         // overwritten with newer versions; if the last entry had multiple
     823             :         // filenames, then we'd get get multiple names here
     824             :         //
     825           1 :         CATCH_REQUIRE(opt.size("filename") == 1);
     826           1 :         CATCH_REQUIRE(opt.get_string("filename", 0) == "utf8.txt");
     827             : 
     828           1 :         CATCH_REQUIRE(opt.size("duration") == 1);
     829           1 :         CATCH_REQUIRE(opt.get_string("duration") == "105min");
     830             : 
     831           1 :         CATCH_REQUIRE(opt.size("gap") == 1);
     832           1 :         CATCH_REQUIRE(opt.get_string("gap") == "9");
     833             : 
     834           1 :         CATCH_REQUIRE(opt.size("ip") == 1);
     835           1 :         CATCH_REQUIRE(opt.get_string("ip") == "10.1.7.205");
     836             :     }
     837             :     CATCH_END_SECTION()
     838             : 
     839           4 :     CATCH_START_SECTION("Configuration Files with Sections")
     840             :     {
     841           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple-with-sections", "multiplicity-with-sections");
     842             : 
     843           1 :         advgetopt::options_environment environment_options;
     844             : 
     845           2 :         std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
     846           1 :         tmpdir += "/.config/home2";
     847             : 
     848           2 :         std::stringstream ss;
     849           1 :         ss << "mkdir -p " << tmpdir;
     850           1 :         if(system(ss.str().c_str()) != 0)
     851             :         {
     852           0 :             std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
     853           0 :             exit(1);
     854             :         }
     855             : 
     856           2 :         snap::safe_setenv env("HOME", tmpdir);
     857             : 
     858             :         {
     859           2 :             std::ofstream config_file;
     860           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     861           1 :             CATCH_REQUIRE(config_file.good());
     862           1 :             config_file <<
     863             :                 "# Auto-generated\n"
     864             :                 "\n"
     865             :                 "[connection]\n"
     866             :                 "ip=10.0.2.5\n"
     867             :                 "duration=6h\n"
     868             :                 "size=604\n"
     869             :                 "\n"
     870             :                 "[data-settings]\n"
     871             :                 "gap=6\n"
     872             :                 "filename=utf9.txt\n"
     873             :             ;
     874             :         }
     875             : 
     876             :         {
     877           2 :             std::ofstream config_file;
     878           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     879           1 :             CATCH_REQUIRE(config_file.good());
     880           1 :             config_file <<
     881             :                 "# Auto-generated\n"
     882             :                 "\n"
     883             :                 "[connection]\n"
     884             :                 "duration=3min\n"
     885             :                 "\n"
     886             :                 "[data-settings]\n"
     887             :                 "gap=9\n"
     888             :                 "filename=utf7.txt\n"
     889             :             ;
     890             :         }
     891             : 
     892             :         {
     893           2 :             std::ofstream config_file;
     894           1 :             config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     895           1 :             CATCH_REQUIRE(config_file.good());
     896           1 :             config_file <<
     897             :                 "# Auto-generated\n"
     898             :                 "\n"
     899             :                 "[connection]\n"
     900             :                 "ip=192.168.255.3\n"
     901             :                 "\n"
     902             :                 "[data-settings]\n"
     903             :                 "filename=utf8.txt\n"
     904             :             ;
     905             :         }
     906             : 
     907           1 :         char const * confs[] =
     908             :         {
     909           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
     910           1 :             SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
     911             :             "~/advgetopt.conf",
     912             :             nullptr
     913           2 :         };
     914             :     
     915           1 :         advgetopt::option const options[] =
     916             :         {
     917             :             advgetopt::define_option(
     918             :                   advgetopt::Name("connection::size")
     919             :                 , advgetopt::ShortName('s')
     920             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     921             :                 , advgetopt::Help("size.")
     922             :             ),
     923             :             advgetopt::define_option(
     924             :                   advgetopt::Name("data-settings::filename")
     925             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
     926             :                 , advgetopt::Help("enter a filenames.")
     927             :                 , advgetopt::DefaultValue("a.out")
     928             :             ),
     929             :             advgetopt::define_option(
     930             :                   advgetopt::Name("connection::duration")
     931             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     932             :                 , advgetopt::Help("how long it lasts.")
     933             :             ),
     934             :             advgetopt::define_option(
     935             :                   advgetopt::Name("data-settings::gap")
     936             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     937             :                 , advgetopt::Help("gap size.")
     938             :             ),
     939             :             advgetopt::define_option(
     940             :                   advgetopt::Name("connection::ip")
     941             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
     942             :                 , advgetopt::Help("enter the ip address.")
     943             :             ),
     944             :             advgetopt::end_options()
     945             :         };
     946             : 
     947           1 :         environment_options.f_project_name = "unittest";
     948           1 :         environment_options.f_options = options;
     949           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
     950           1 :         environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
     951           1 :         environment_options.f_configuration_files = confs;
     952             : 
     953           2 :         advgetopt::getopt opt(environment_options);
     954             : 
     955           1 :         opt.parse_configuration_files(0, nullptr);
     956             : 
     957           1 :         CATCH_REQUIRE(opt.size("connection::size") == 1);
     958           1 :         CATCH_REQUIRE(opt.get_string("connection::size") == "604");
     959             : 
     960             :         // although it is marked as multiple, the old entries are still
     961             :         // overwritten with newer versions; if the last entry had multiple
     962             :         // filenames, then we'd get get multiple names here
     963             :         //
     964           1 :         CATCH_REQUIRE(opt.size("data-settings::filename") == 1);
     965           1 :         CATCH_REQUIRE(opt.get_string("data-settings::filename", 0) == "utf8.txt");
     966             : 
     967           1 :         CATCH_REQUIRE(opt.size("connection::duration") == 1);
     968           1 :         CATCH_REQUIRE(opt.get_string("connection::duration") == "3min");
     969             : 
     970           1 :         CATCH_REQUIRE(opt.size("data-settings::gap") == 1);
     971           1 :         CATCH_REQUIRE(opt.get_string("data-settings::gap") == "9");
     972             : 
     973           1 :         CATCH_REQUIRE(opt.size("connection::ip") == 1);
     974           1 :         CATCH_REQUIRE(opt.get_string("connection::ip") == "192.168.255.3");
     975             : 
     976           2 :         std::string const name(advgetopt::CONFIGURATION_SECTIONS);
     977           1 :         CATCH_REQUIRE(opt.size(name) == 2);
     978           1 :         CATCH_REQUIRE(opt.get_string(name) == "connection");
     979           1 :         CATCH_REQUIRE(opt.get_string(name, 1) == "data-settings");
     980             :     }
     981             :     CATCH_END_SECTION()
     982           2 : }
     983             : 
     984             : 
     985             : 
     986           8 : CATCH_TEST_CASE("load_invalid_configuration_file", "[config][getopt][filenames][invalid]")
     987             : {
     988          12 :     CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--dynamic allowed)")
     989             :     {
     990           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid", "invalid-one-letter");
     991             : 
     992             :         {
     993           2 :             std::ofstream config_file;
     994           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
     995           1 :             CATCH_REQUIRE(config_file.good());
     996           1 :             config_file <<
     997             :                 "# Auto-generated\n"
     998             :                 "sizes=-132\n"
     999             :                 "f=dynamic\n"
    1000             :             ;
    1001             :         }
    1002             : 
    1003           1 :         char const * confs[] =
    1004             :         {
    1005             :             "~/.config/file-which-was-never-created.mdi",
    1006           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1007             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1008             :             nullptr
    1009           1 :         };
    1010             : 
    1011           1 :         char const * const separators[] {
    1012             :             ",",
    1013             :             " ",
    1014             :             nullptr
    1015             :         };
    1016             : 
    1017           1 :         advgetopt::option const options[] =
    1018             :         {
    1019             :             advgetopt::define_option(
    1020             :                   advgetopt::Name("sizes")
    1021             :                 , advgetopt::ShortName('s')
    1022             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1023             :                 , advgetopt::Help("sizes.")
    1024             :             ),
    1025             :             advgetopt::define_option(
    1026             :                   advgetopt::Name("filenames")
    1027             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
    1028             :                 , advgetopt::Help("enter a list of filenames.")
    1029             :                 , advgetopt::DefaultValue("a.out")
    1030             :                 , advgetopt::Separators(separators)
    1031           6 :             ),
    1032             :             advgetopt::end_options()
    1033           7 :         };
    1034             : 
    1035           1 :         advgetopt::options_environment environment_options;
    1036           1 :         environment_options.f_project_name = "loading-invalid";
    1037           1 :         environment_options.f_options = options;
    1038           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
    1039           1 :         environment_options.f_help_header = "Testing loading a one letter parameter";
    1040           1 :         environment_options.f_configuration_files = confs;
    1041             : 
    1042           2 :         advgetopt::getopt opt(environment_options);
    1043             : 
    1044           2 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
    1045             :                   "error: unknown option \"f\" found in configuration file \""
    1046           2 :                 + SNAP_CATCH2_NAMESPACE::g_config_filename
    1047           3 :                 + "\".");
    1048           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1049           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1050             : 
    1051           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
    1052           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "-132");
    1053           1 :         CATCH_REQUIRE(opt.get_long("sizes") == -132);
    1054             : 
    1055           1 :         CATCH_REQUIRE(opt.size("filenames") == 0);
    1056             :     }
    1057             :     CATCH_END_SECTION()
    1058             : 
    1059          12 :     CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--no dynamic allowed)")
    1060             :     {
    1061           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-undefined", "undefined-one-letter");
    1062             : 
    1063             :         {
    1064           2 :             std::ofstream config_file;
    1065           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
    1066           1 :             CATCH_REQUIRE(config_file.good());
    1067           1 :             config_file <<
    1068             :                 "# Auto-generated\n"
    1069             :                 "sizes=-132\n"
    1070             :                 "f=dynamic\n"
    1071             :             ;
    1072             :         }
    1073             : 
    1074           1 :         char const * confs[] =
    1075             :         {
    1076             :             "~/.config/file-which-was-never-created.mdi",
    1077           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1078             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1079             :             nullptr
    1080           1 :         };
    1081             : 
    1082           1 :         char const * const separators[] {
    1083             :             ",",
    1084             :             " ",
    1085             :             nullptr
    1086             :         };
    1087             : 
    1088           1 :         advgetopt::option const options[] =
    1089             :         {
    1090             :             advgetopt::define_option(
    1091             :                   advgetopt::Name("sizes")
    1092             :                 , advgetopt::ShortName('s')
    1093             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1094             :                 , advgetopt::Help("sizes.")
    1095             :             ),
    1096             :             advgetopt::define_option(
    1097             :                   advgetopt::Name("filenames")
    1098             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
    1099             :                 , advgetopt::Help("enter a list of filenames.")
    1100             :                 , advgetopt::DefaultValue("a.out")
    1101             :                 , advgetopt::Separators(separators)
    1102           6 :             ),
    1103             :             advgetopt::end_options()
    1104           7 :         };
    1105             : 
    1106           1 :         advgetopt::options_environment environment_options;
    1107           1 :         environment_options.f_project_name = "loading-invalid";
    1108           1 :         environment_options.f_options = options;
    1109           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1110           1 :         environment_options.f_help_header = "Testing loading a one letter parameter";
    1111           1 :         environment_options.f_configuration_files = confs;
    1112             : 
    1113           2 :         advgetopt::getopt opt(environment_options);
    1114             : 
    1115           2 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
    1116             :                   "error: unknown option \"f\" found in configuration file \""
    1117           2 :                 + SNAP_CATCH2_NAMESPACE::g_config_filename
    1118           3 :                 + "\".");
    1119           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1120           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1121             : 
    1122           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
    1123           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "-132");
    1124           1 :         CATCH_REQUIRE(opt.get_long("sizes") == -132);
    1125             : 
    1126           1 :         CATCH_REQUIRE(opt.size("filenames") == 0);
    1127             :     }
    1128             :     CATCH_END_SECTION()
    1129             : 
    1130          12 :     CATCH_START_SECTION("Load with Unexpected Parameter Name (undefined & no dynamic fields are allowed)")
    1131             :     {
    1132           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-dynamic", "invalid-dynamic");
    1133             : 
    1134             :         {
    1135           2 :             std::ofstream config_file;
    1136           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
    1137           1 :             CATCH_REQUIRE(config_file.good());
    1138           1 :             config_file <<
    1139             :                 "# Auto-generated\n"
    1140             :                 "sizes=-1001\n"
    1141             :                 "dynamic=\"undefined argument\"\n"
    1142             :             ;
    1143             :         }
    1144             : 
    1145           1 :         char const * confs[] =
    1146             :         {
    1147             :             "~/.config/file-which-was-never-created.mdi",
    1148           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1149             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1150             :             nullptr
    1151           1 :         };
    1152             : 
    1153           1 :         char const * const separators[] {
    1154             :             ",",
    1155             :             " ",
    1156             :             nullptr
    1157             :         };
    1158             : 
    1159           1 :         advgetopt::option const options[] =
    1160             :         {
    1161             :             advgetopt::define_option(
    1162             :                   advgetopt::Name("sizes")
    1163             :                 , advgetopt::ShortName('s')
    1164             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1165             :                 , advgetopt::Help("sizes.")
    1166             :             ),
    1167             :             advgetopt::define_option(
    1168             :                   advgetopt::Name("filenames")
    1169             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
    1170             :                 , advgetopt::Help("enter a list of filenames.")
    1171             :                 , advgetopt::DefaultValue("a.out")
    1172             :                 , advgetopt::Separators(separators)
    1173           6 :             ),
    1174             :             advgetopt::end_options()
    1175           7 :         };
    1176             : 
    1177           1 :         advgetopt::options_environment environment_options;
    1178           1 :         environment_options.f_project_name = "loading-invalid";
    1179           1 :         environment_options.f_options = options;
    1180           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1181           1 :         environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
    1182           1 :         environment_options.f_configuration_files = confs;
    1183             : 
    1184           2 :         advgetopt::getopt opt(environment_options);
    1185             : 
    1186           2 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
    1187             :                   "error: unknown option \"dynamic\" found in configuration file \""
    1188           2 :                 + SNAP_CATCH2_NAMESPACE::g_config_filename
    1189           3 :                 + "\".");
    1190           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1191           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1192             : 
    1193           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
    1194           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
    1195           1 :         CATCH_REQUIRE(opt.get_long("sizes") == -1001);
    1196             : 
    1197           1 :         CATCH_REQUIRE(opt.size("filenames") == 0);
    1198             :     }
    1199             :     CATCH_END_SECTION()
    1200             : 
    1201          12 :     CATCH_START_SECTION("Load with Parameter not Supported in Configuration Files")
    1202             :     {
    1203           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-config", "invalid-param-in-config");
    1204             : 
    1205             :         {
    1206           2 :             std::ofstream config_file;
    1207           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
    1208           1 :             CATCH_REQUIRE(config_file.good());
    1209           1 :             config_file <<
    1210             :                 "# Auto-generated\n"
    1211             :                 "sizes=-1001\n"
    1212             :                 "filenames=unexpected, argument, in, configuration, file\n"
    1213             :             ;
    1214             :         }
    1215             : 
    1216           1 :         char const * confs[] =
    1217             :         {
    1218             :             "~/.config/file-which-was-never-created.mdi",
    1219           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1220             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1221             :             nullptr
    1222           1 :         };
    1223             : 
    1224           1 :         char const * const separators[] {
    1225             :             ",",
    1226             :             " ",
    1227             :             nullptr
    1228             :         };
    1229             : 
    1230           1 :         advgetopt::option const options[] =
    1231             :         {
    1232             :             advgetopt::define_option(
    1233             :                   advgetopt::Name("sizes")
    1234             :                 , advgetopt::ShortName('s')
    1235             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1236             :                 , advgetopt::Help("sizes.")
    1237             :             ),
    1238             :             advgetopt::define_option(
    1239             :                   advgetopt::Name("filenames")
    1240             :                 , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
    1241             :                 , advgetopt::Help("enter a list of filenames.")
    1242             :                 , advgetopt::DefaultValue("a.out")
    1243             :                 , advgetopt::Separators(separators)
    1244           6 :             ),
    1245             :             advgetopt::end_options()
    1246           7 :         };
    1247             : 
    1248           1 :         advgetopt::options_environment environment_options;
    1249           1 :         environment_options.f_project_name = "loading-invalid";
    1250           1 :         environment_options.f_options = options;
    1251           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1252           1 :         environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
    1253           1 :         environment_options.f_configuration_files = confs;
    1254             : 
    1255           2 :         advgetopt::getopt opt(environment_options);
    1256             : 
    1257           2 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
    1258             :                   "error: option \"filenames\" is not supported in configuration files (found in \""
    1259           2 :                 + SNAP_CATCH2_NAMESPACE::g_config_filename
    1260           3 :                 + "\").");
    1261           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1262           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1263             : 
    1264           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
    1265           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
    1266           1 :         CATCH_REQUIRE(opt.get_long("sizes") == -1001);
    1267             : 
    1268           1 :         CATCH_REQUIRE(opt.size("filenames") == 0);
    1269             :     }
    1270             :     CATCH_END_SECTION()
    1271             : 
    1272          12 :     CATCH_START_SECTION("Load a Configuration File with a Flag given a Value")
    1273             :     {
    1274           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-flag-with-value", "unexpected-value-in-config");
    1275             : 
    1276             :         {
    1277           2 :             std::ofstream config_file;
    1278           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
    1279           1 :             CATCH_REQUIRE(config_file.good());
    1280           1 :             config_file <<
    1281             :                 "# Auto-generated\n"
    1282             :                 "sizes=4153629\n"
    1283             :                 "color-flag=true\n"
    1284             :             ;
    1285             :         }
    1286             : 
    1287           1 :         char const * confs[] =
    1288             :         {
    1289             :             "~/.config/file-which-was-never-created.mdi",
    1290           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1291             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1292             :             nullptr
    1293           1 :         };
    1294             : 
    1295           1 :         advgetopt::option const options[] =
    1296             :         {
    1297             :             advgetopt::define_option(
    1298             :                   advgetopt::Name("sizes")
    1299             :                 , advgetopt::ShortName('s')
    1300             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1301             :                 , advgetopt::Help("sizes.")
    1302             :             ),
    1303             :             advgetopt::define_option(
    1304             :                   advgetopt::Name("color-flag")
    1305             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_FLAG>())
    1306             :                 , advgetopt::Help("flag that you want color.")
    1307             :             ),
    1308             :             advgetopt::end_options()
    1309             :         };
    1310             : 
    1311           1 :         advgetopt::options_environment environment_options;
    1312           1 :         environment_options.f_project_name = "load";
    1313           1 :         environment_options.f_options = options;
    1314           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1315           1 :         environment_options.f_help_header = "Testing loading an invalid flag";
    1316           1 :         environment_options.f_configuration_files = confs;
    1317             : 
    1318           2 :         advgetopt::getopt opt(environment_options);
    1319             : 
    1320           2 :         SNAP_CATCH2_NAMESPACE::push_expected_log(
    1321             :                   "error: option \"color_flag\" cannot be given a value in configuration file \""
    1322           2 :                 + SNAP_CATCH2_NAMESPACE::g_config_filename
    1323           3 :                 + "\".");
    1324           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1325           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1326             : 
    1327           1 :         CATCH_REQUIRE(opt.size("sizes") == 1);
    1328           1 :         CATCH_REQUIRE(opt.get_string("sizes") == "4153629");
    1329             : 
    1330           1 :         CATCH_REQUIRE(opt.size("color-flag") == 0);
    1331           1 :         CATCH_REQUIRE_FALSE(opt.is_defined("color-flag"));
    1332             :     }
    1333             :     CATCH_END_SECTION()
    1334             : 
    1335          12 :     CATCH_START_SECTION("Load a Configuration File with an Invalid Sections Definition")
    1336             :     {
    1337           1 :         SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-with-invalid-sections", "invalid-sections");
    1338             : 
    1339             :         {
    1340           2 :             std::ofstream config_file;
    1341           1 :             config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
    1342           1 :             CATCH_REQUIRE(config_file.good());
    1343           1 :             config_file <<
    1344             :                 "# Auto-generated\n"
    1345             :                 "[integers]\n"
    1346             :                 "sizes=639\n"
    1347             :             ;
    1348             :         }
    1349             : 
    1350           1 :         char const * confs[] =
    1351             :         {
    1352             :             "~/.config/file-which-was-never-created.mdi",
    1353           1 :             SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
    1354             :             "/etc/snapwebsites/not/an-existing-file.conf",
    1355             :             nullptr
    1356           1 :         };
    1357             : 
    1358           1 :         advgetopt::option const options[] =
    1359             :         {
    1360             :             advgetopt::define_option(
    1361             :                   advgetopt::Name("integers::sizes")
    1362             :                 , advgetopt::ShortName('s')
    1363             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1364             :                 , advgetopt::Help("sizes.")
    1365             :             ),
    1366             :             advgetopt::define_option(
    1367             :                   advgetopt::Name(advgetopt::CONFIGURATION_SECTIONS)
    1368             :                 , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
    1369             :                 , advgetopt::Help("MULTIPLE missing.")
    1370             :             ),
    1371             :             advgetopt::end_options()
    1372             :         };
    1373             : 
    1374           1 :         advgetopt::options_environment environment_options;
    1375           1 :         environment_options.f_project_name = "load-invalid-sections";
    1376           1 :         environment_options.f_options = options;
    1377           1 :         environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
    1378           1 :         environment_options.f_help_header = "Testing loading invalid sections declaration";
    1379           1 :         environment_options.f_configuration_files = confs;
    1380             : 
    1381           2 :         advgetopt::getopt opt(environment_options);
    1382             : 
    1383           1 :         SNAP_CATCH2_NAMESPACE::push_expected_log("error: option \"configuration_sections\" must have GETOPT_FLAG_MULTIPLE set.");
    1384           1 :         opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
    1385           1 :         SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
    1386             : 
    1387             :         // it failed early so it's not considered to be 100% initialized
    1388             :         //
    1389           1 :         CATCH_REQUIRE_THROWS_MATCHES(
    1390             :                   opt.size("integers::sizes-parameter")
    1391             :                 , advgetopt::getopt_initialization
    1392             :                 , Catch::Matchers::ExceptionMessage(
    1393             :                               "getopt_exception: function called too soon, parser is not done yet (i.e. is_defined(), get_string(), get_integer() cannot be called until the parser is done)"));
    1394             :     }
    1395             :     CATCH_END_SECTION()
    1396          12 : }
    1397             : 
    1398             : 
    1399             : 
    1400             : // vim: ts=4 sw=4 et nowrap

Generated by: LCOV version 1.13