LCOV - code coverage report
Current view: top level - tests - catch_config.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 99.4 % 684 680
Test Date: 2026-01-18 09:38:57 Functions: 100.0 % 4 4
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1

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