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