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 : 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 2 : };
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/file.mdi");
82 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/server.conf");
83 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-any.d/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 : 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 2 : };
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/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/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 : char const * dirs[] =
121 : {
122 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
123 : ".config",
124 : "/etc/snapwebsites",
125 : nullptr
126 2 : };
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 + "/snapfirewall.conf");
142 1 : CATCH_REQUIRE(filenames[2] == ".config/snapfirewall.conf");
143 1 : CATCH_REQUIRE(filenames[3] == ".config/unittest-with-directories.d/snapfirewall.conf");
144 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/snapfirewall.conf");
145 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-with-directories.d/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 : char const * dirs[] =
154 : {
155 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
156 : ".config",
157 : "/etc/advgetopt",
158 : nullptr
159 2 : };
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 : char const * cargv[] =
169 : {
170 : "/usr/bin/config",
171 : "--config-dir",
172 : "/var/lib/advgetopt",
173 : "--config-dir",
174 : "/opt/config",
175 : nullptr
176 1 : };
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/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/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 + "/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/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/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 : config_file <<
208 : "# Auto-generated\n"
209 : "ip=192.168.0.1\n"
210 : "wall=iptables\n"
211 1 : ;
212 : }
213 :
214 1 : unlink(SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str());
215 :
216 : 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 2 : };
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 : config_file <<
248 : "# Auto-generated\n"
249 : "block-ip=192.168.6.11\n"
250 : "firewall=iptables\n"
251 1 : ;
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 : config_file <<
259 : "# Auto-generated\n"
260 : "ip=10.0.2.5\n"
261 : "duration=6h\n"
262 1 : ;
263 : }
264 :
265 : 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 2 : };
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 : config_file <<
298 : "# Auto-generated\n"
299 : "block-ip=192.168.6.11\n"
300 : "firewall=iptables\n"
301 1 : ;
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 : config_file <<
309 : "# Auto-generated\n"
310 : "ip=10.0.2.5\n"
311 : "duration=6h\n"
312 1 : ;
313 : }
314 :
315 : 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 2 : };
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 : config_file <<
347 : "# Auto-generated\n"
348 : "block-ip=192.168.6.11\n"
349 : "firewall=iptables\n"
350 1 : ;
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 : config_file <<
358 : "# Auto-generated\n"
359 : "ip=10.0.2.5\n"
360 : "duration=6h\n"
361 1 : ;
362 : }
363 :
364 : 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 2 : };
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 : config_file <<
400 : "# Auto-generated\n"
401 : "ip=10.0.2.5\n"
402 : "duration=6h\n"
403 1 : ;
404 : }
405 :
406 : 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 2 : };
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/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/snapfirewall.conf");
432 : }
433 : CATCH_END_SECTION()
434 9 : }
435 :
436 :
437 :
438 4 : CATCH_TEST_CASE("load_configuration_file", "[config][getopt][filenames]")
439 : {
440 4 : CATCH_START_SECTION("Load a Configuration File")
441 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load", "tool");
442 :
443 : {
444 2 : std::ofstream config_file;
445 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
446 1 : CATCH_REQUIRE(config_file.good());
447 : config_file <<
448 : "# Auto-generated\n"
449 : "sizes=132\n"
450 : "filenames=green,orange,blue brown white\n"
451 1 : ;
452 : }
453 :
454 : char const * confs[] =
455 : {
456 : "~/.config/file-which-was-never-created.mdi",
457 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
458 : "/etc/snapwebsites/not/an-existing-file.conf",
459 : nullptr
460 2 : };
461 :
462 : char const * const separators[] {
463 : ",",
464 : " ",
465 : nullptr
466 1 : };
467 :
468 : advgetopt::option const options[] =
469 : {
470 : advgetopt::define_option(
471 : advgetopt::Name("sizes")
472 : , advgetopt::ShortName('s')
473 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
474 : , advgetopt::Help("sizes.")
475 : ),
476 : advgetopt::define_option(
477 : advgetopt::Name("filenames")
478 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
479 : , advgetopt::Help("enter a list of filenames.")
480 : , advgetopt::DefaultValue("a.out")
481 : , advgetopt::Separators(separators)
482 1 : ),
483 : advgetopt::end_options()
484 2 : };
485 :
486 1 : advgetopt::options_environment environment_options;
487 1 : environment_options.f_project_name = "load";
488 1 : environment_options.f_options = options;
489 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
490 1 : environment_options.f_help_header = "Testing loading a filenames";
491 1 : environment_options.f_configuration_files = confs;
492 :
493 2 : advgetopt::getopt opt(environment_options);
494 :
495 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
496 :
497 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
498 1 : CATCH_REQUIRE(opt.get_string("sizes") == "132");
499 :
500 1 : CATCH_REQUIRE(opt.size("filenames") == 5);
501 1 : CATCH_REQUIRE(opt.get_string("filenames") == "green");
502 1 : CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
503 1 : CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
504 1 : CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
505 1 : CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
506 1 : CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
507 : CATCH_END_SECTION()
508 :
509 4 : CATCH_START_SECTION("Load an Extended Configuration File")
510 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load-extended", "extended");
511 :
512 : {
513 2 : std::ofstream config_file;
514 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
515 1 : CATCH_REQUIRE(config_file.good());
516 : config_file <<
517 : "# Auto-generated\n"
518 : "sizes=132\n"
519 : "object=property.obj\n"
520 : "filenames=green,orange,blue brown white\n"
521 : "visibility=hidden\n"
522 1 : ;
523 : }
524 :
525 : char const * confs[] =
526 : {
527 : "~/.config/file-which-was-never-created.mdi",
528 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
529 : "/etc/snapwebsites/not/an-existing-file.conf",
530 : nullptr
531 2 : };
532 :
533 : char const * const separators[] {
534 : ",",
535 : " ",
536 : nullptr
537 1 : };
538 :
539 : advgetopt::option const options[] =
540 : {
541 : advgetopt::define_option(
542 : advgetopt::Name("sizes")
543 : , advgetopt::ShortName('s')
544 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
545 : , advgetopt::Help("sizes.")
546 : ),
547 : advgetopt::define_option(
548 : advgetopt::Name("filenames")
549 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
550 : , advgetopt::Help("enter a list of filenames.")
551 : , advgetopt::DefaultValue("a.out")
552 : , advgetopt::Separators(separators)
553 1 : ),
554 : advgetopt::end_options()
555 2 : };
556 :
557 1 : advgetopt::options_environment environment_options;
558 1 : environment_options.f_project_name = "load-extended";
559 1 : environment_options.f_options = options;
560 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
561 1 : environment_options.f_help_header = "Testing loading filenames";
562 1 : environment_options.f_configuration_files = confs;
563 :
564 2 : advgetopt::getopt opt(environment_options);
565 :
566 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
567 :
568 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
569 1 : CATCH_REQUIRE(opt.get_string("sizes") == "132");
570 :
571 1 : CATCH_REQUIRE(opt.size("filenames") == 5);
572 1 : CATCH_REQUIRE(opt.get_string("filenames") == "green");
573 1 : CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
574 1 : CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
575 1 : CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
576 1 : CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
577 1 : CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
578 :
579 1 : CATCH_REQUIRE(opt.size("object") == 1);
580 1 : CATCH_REQUIRE(opt.get_string("object") == "property.obj");
581 :
582 1 : CATCH_REQUIRE(opt.size("visibility") == 1);
583 1 : CATCH_REQUIRE(opt.get_string("visibility") == "hidden");
584 : CATCH_END_SECTION()
585 2 : }
586 :
587 :
588 :
589 3 : CATCH_TEST_CASE("load_multiple_configurations", "[config][getopt][filenames]")
590 : {
591 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple", "multiplicity");
592 :
593 : //string_list_t getopt::get_configuration_filenames(bool exists, bool writable)
594 :
595 2 : CATCH_START_SECTION("Configuration Files")
596 1 : advgetopt::options_environment environment_options;
597 :
598 2 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
599 1 : tmpdir += "/.config/home";
600 :
601 2 : std::stringstream ss;
602 1 : ss << "mkdir -p " << tmpdir;
603 1 : if(system(ss.str().c_str()) != 0)
604 : {
605 0 : std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
606 0 : exit(1);
607 : }
608 :
609 2 : snap::safe_setenv env("HOME", tmpdir);
610 :
611 : {
612 2 : std::ofstream config_file;
613 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
614 1 : CATCH_REQUIRE(config_file.good());
615 : config_file <<
616 : "# Auto-generated\n"
617 : "ip=10.0.2.5\n"
618 : "duration=6h\n"
619 : "size=604\n"
620 : "gap=6\n"
621 : "filename=utf9.txt\n"
622 1 : ;
623 : }
624 :
625 : {
626 2 : std::ofstream config_file;
627 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
628 1 : CATCH_REQUIRE(config_file.good());
629 : config_file <<
630 : "# Auto-generated\n"
631 : "ip=10.1.7.205\n"
632 : "gap=9\n"
633 : "filename=utf7.txt\n"
634 1 : ;
635 : }
636 :
637 : {
638 2 : std::ofstream config_file;
639 1 : config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
640 1 : CATCH_REQUIRE(config_file.good());
641 : config_file <<
642 : "# Auto-generated\n"
643 : "duration=105min\n"
644 : "filename=utf8.txt\n"
645 1 : ;
646 : }
647 :
648 : char const * confs[] =
649 : {
650 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
651 1 : SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
652 : "~/advgetopt.conf",
653 : nullptr
654 3 : };
655 :
656 : advgetopt::option const options[] =
657 : {
658 : advgetopt::define_option(
659 : advgetopt::Name("size")
660 : , advgetopt::ShortName('s')
661 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
662 : , advgetopt::Help("size.")
663 : ),
664 : advgetopt::define_option(
665 : advgetopt::Name("filename")
666 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
667 : , advgetopt::Help("enter a filenames.")
668 : , advgetopt::DefaultValue("a.out")
669 : ),
670 : advgetopt::define_option(
671 : advgetopt::Name("duration")
672 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
673 : , advgetopt::Help("how long it lasts.")
674 : ),
675 : advgetopt::define_option(
676 : advgetopt::Name("gap")
677 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
678 : , advgetopt::Help("gap size.")
679 : ),
680 : advgetopt::define_option(
681 : advgetopt::Name("ip")
682 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
683 : , advgetopt::Help("enter the ip address.")
684 : ),
685 : advgetopt::end_options()
686 1 : };
687 :
688 1 : environment_options.f_project_name = "unittest";
689 1 : environment_options.f_options = options;
690 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
691 1 : environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
692 1 : environment_options.f_configuration_files = confs;
693 :
694 2 : advgetopt::getopt opt(environment_options);
695 :
696 1 : opt.parse_configuration_files();
697 :
698 1 : CATCH_REQUIRE(opt.size("size") == 1);
699 1 : CATCH_REQUIRE(opt.get_string("size") == "604");
700 :
701 : // although it is marked as multiple, the old entries are still
702 : // overwritten with newer versions; if the last entry had multiple
703 : // filenames, then we'd get get multiple names here
704 : //
705 1 : CATCH_REQUIRE(opt.size("filename") == 1);
706 1 : CATCH_REQUIRE(opt.get_string("filename", 0) == "utf8.txt");
707 :
708 1 : CATCH_REQUIRE(opt.size("duration") == 1);
709 1 : CATCH_REQUIRE(opt.get_string("duration") == "105min");
710 :
711 1 : CATCH_REQUIRE(opt.size("gap") == 1);
712 1 : CATCH_REQUIRE(opt.get_string("gap") == "9");
713 :
714 1 : CATCH_REQUIRE(opt.size("ip") == 1);
715 1 : CATCH_REQUIRE(opt.get_string("ip") == "10.1.7.205");
716 : CATCH_END_SECTION()
717 1 : }
718 :
719 :
720 :
721 6 : CATCH_TEST_CASE("load_invalid_configuration_file", "[config][getopt][filenames][invalid]")
722 : {
723 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--dynamic allowed)")
724 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid", "invalid-one-letter");
725 :
726 : {
727 2 : std::ofstream config_file;
728 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
729 1 : CATCH_REQUIRE(config_file.good());
730 : config_file <<
731 : "# Auto-generated\n"
732 : "sizes=-132\n"
733 : "f=dynamic\n"
734 1 : ;
735 : }
736 :
737 : char const * confs[] =
738 : {
739 : "~/.config/file-which-was-never-created.mdi",
740 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
741 : "/etc/snapwebsites/not/an-existing-file.conf",
742 : nullptr
743 2 : };
744 :
745 : char const * const separators[] {
746 : ",",
747 : " ",
748 : nullptr
749 1 : };
750 :
751 : advgetopt::option const options[] =
752 : {
753 : advgetopt::define_option(
754 : advgetopt::Name("sizes")
755 : , advgetopt::ShortName('s')
756 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
757 : , advgetopt::Help("sizes.")
758 : ),
759 : advgetopt::define_option(
760 : advgetopt::Name("filenames")
761 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
762 : , advgetopt::Help("enter a list of filenames.")
763 : , advgetopt::DefaultValue("a.out")
764 : , advgetopt::Separators(separators)
765 1 : ),
766 : advgetopt::end_options()
767 2 : };
768 :
769 1 : advgetopt::options_environment environment_options;
770 1 : environment_options.f_project_name = "loading-invalid";
771 1 : environment_options.f_options = options;
772 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
773 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
774 1 : environment_options.f_configuration_files = confs;
775 :
776 2 : advgetopt::getopt opt(environment_options);
777 :
778 : SNAP_CATCH2_NAMESPACE::push_expected_log(
779 : "error: unknown option \"f\" found in configuration file \""
780 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
781 1 : + "\".");
782 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
783 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
784 :
785 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
786 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
787 1 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
788 :
789 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
790 : CATCH_END_SECTION()
791 :
792 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--no dynamic allowed)")
793 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-undefined", "undefined-one-letter");
794 :
795 : {
796 2 : std::ofstream config_file;
797 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
798 1 : CATCH_REQUIRE(config_file.good());
799 : config_file <<
800 : "# Auto-generated\n"
801 : "sizes=-132\n"
802 : "f=dynamic\n"
803 1 : ;
804 : }
805 :
806 : char const * confs[] =
807 : {
808 : "~/.config/file-which-was-never-created.mdi",
809 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
810 : "/etc/snapwebsites/not/an-existing-file.conf",
811 : nullptr
812 2 : };
813 :
814 : char const * const separators[] {
815 : ",",
816 : " ",
817 : nullptr
818 1 : };
819 :
820 : advgetopt::option const options[] =
821 : {
822 : advgetopt::define_option(
823 : advgetopt::Name("sizes")
824 : , advgetopt::ShortName('s')
825 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
826 : , advgetopt::Help("sizes.")
827 : ),
828 : advgetopt::define_option(
829 : advgetopt::Name("filenames")
830 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
831 : , advgetopt::Help("enter a list of filenames.")
832 : , advgetopt::DefaultValue("a.out")
833 : , advgetopt::Separators(separators)
834 1 : ),
835 : advgetopt::end_options()
836 2 : };
837 :
838 1 : advgetopt::options_environment environment_options;
839 1 : environment_options.f_project_name = "loading-invalid";
840 1 : environment_options.f_options = options;
841 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
842 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
843 1 : environment_options.f_configuration_files = confs;
844 :
845 2 : advgetopt::getopt opt(environment_options);
846 :
847 : SNAP_CATCH2_NAMESPACE::push_expected_log(
848 : "error: unknown option \"f\" found in configuration file \""
849 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
850 1 : + "\".");
851 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
852 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
853 :
854 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
855 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
856 1 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
857 :
858 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
859 : CATCH_END_SECTION()
860 :
861 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (undefined & no dynamic fields are allowed)")
862 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-dynamic", "invalid-dynamic");
863 :
864 : {
865 2 : std::ofstream config_file;
866 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
867 1 : CATCH_REQUIRE(config_file.good());
868 : config_file <<
869 : "# Auto-generated\n"
870 : "sizes=-1001\n"
871 : "dynamic=\"undefined argument\"\n"
872 1 : ;
873 : }
874 :
875 : char const * confs[] =
876 : {
877 : "~/.config/file-which-was-never-created.mdi",
878 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
879 : "/etc/snapwebsites/not/an-existing-file.conf",
880 : nullptr
881 2 : };
882 :
883 : char const * const separators[] {
884 : ",",
885 : " ",
886 : nullptr
887 1 : };
888 :
889 : advgetopt::option const options[] =
890 : {
891 : advgetopt::define_option(
892 : advgetopt::Name("sizes")
893 : , advgetopt::ShortName('s')
894 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
895 : , advgetopt::Help("sizes.")
896 : ),
897 : advgetopt::define_option(
898 : advgetopt::Name("filenames")
899 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
900 : , advgetopt::Help("enter a list of filenames.")
901 : , advgetopt::DefaultValue("a.out")
902 : , advgetopt::Separators(separators)
903 1 : ),
904 : advgetopt::end_options()
905 2 : };
906 :
907 1 : advgetopt::options_environment environment_options;
908 1 : environment_options.f_project_name = "loading-invalid";
909 1 : environment_options.f_options = options;
910 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
911 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
912 1 : environment_options.f_configuration_files = confs;
913 :
914 2 : advgetopt::getopt opt(environment_options);
915 :
916 : SNAP_CATCH2_NAMESPACE::push_expected_log(
917 : "error: unknown option \"dynamic\" found in configuration file \""
918 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
919 1 : + "\".");
920 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
921 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
922 :
923 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
924 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
925 1 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
926 :
927 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
928 : CATCH_END_SECTION()
929 :
930 8 : CATCH_START_SECTION("Load with Parameter not Supported in Configuration Files")
931 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-config", "invalid-param-in-config");
932 :
933 : {
934 2 : std::ofstream config_file;
935 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
936 1 : CATCH_REQUIRE(config_file.good());
937 : config_file <<
938 : "# Auto-generated\n"
939 : "sizes=-1001\n"
940 : "filenames=unexpected, argument, in, configuration, file\n"
941 1 : ;
942 : }
943 :
944 : char const * confs[] =
945 : {
946 : "~/.config/file-which-was-never-created.mdi",
947 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
948 : "/etc/snapwebsites/not/an-existing-file.conf",
949 : nullptr
950 2 : };
951 :
952 : char const * const separators[] {
953 : ",",
954 : " ",
955 : nullptr
956 1 : };
957 :
958 : advgetopt::option const options[] =
959 : {
960 : advgetopt::define_option(
961 : advgetopt::Name("sizes")
962 : , advgetopt::ShortName('s')
963 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
964 : , advgetopt::Help("sizes.")
965 : ),
966 : advgetopt::define_option(
967 : advgetopt::Name("filenames")
968 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
969 : , advgetopt::Help("enter a list of filenames.")
970 : , advgetopt::DefaultValue("a.out")
971 : , advgetopt::Separators(separators)
972 1 : ),
973 : advgetopt::end_options()
974 2 : };
975 :
976 1 : advgetopt::options_environment environment_options;
977 1 : environment_options.f_project_name = "loading-invalid";
978 1 : environment_options.f_options = options;
979 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
980 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
981 1 : environment_options.f_configuration_files = confs;
982 :
983 2 : advgetopt::getopt opt(environment_options);
984 :
985 : SNAP_CATCH2_NAMESPACE::push_expected_log(
986 : "error: option \"filenames\" is not supported in configuration files (found in \""
987 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
988 1 : + "\").");
989 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
990 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
991 :
992 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
993 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
994 1 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
995 :
996 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
997 : CATCH_END_SECTION()
998 10 : }
999 :
1000 :
1001 :
1002 : // vim: ts=4 sw=4 et nowrap
|