Line data Source code
1 : /*
2 : * Files:
3 : * tests/config.cpp
4 : *
5 : * License:
6 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
7 : *
8 : * https://snapwebsites.org/
9 : * contact@m2osw.com
10 : *
11 : * This program is free software; you can redistribute it and/or modify
12 : * it under the terms of the GNU General Public License as published by
13 : * the Free Software Foundation; either version 2 of the License, or
14 : * (at your option) any later version.
15 : *
16 : * This program is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU General Public License for more details.
20 : *
21 : * You should have received a copy of the GNU General Public License along
22 : * with this program; if not, write to the Free Software Foundation, Inc.,
23 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 : *
25 : * Authors:
26 : * Alexis Wilke alexis@m2osw.com
27 : */
28 :
29 : // self
30 : //
31 : #include "main.h"
32 :
33 : // advgetopt lib
34 : //
35 : #include <advgetopt/exception.h>
36 :
37 : // snapdev lib
38 : //
39 : #include <snapdev/safe_setenv.h>
40 :
41 : // C++ lib
42 : //
43 : #include <fstream>
44 :
45 : // C lib
46 : //
47 : #include <unistd.h>
48 :
49 :
50 :
51 :
52 :
53 :
54 :
55 11 : CATCH_TEST_CASE("configuration_filenames", "[config][getopt][filenames]")
56 : {
57 18 : CATCH_START_SECTION("Configuration Files")
58 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-any", "any");
59 :
60 1 : advgetopt::options_environment environment_options;
61 :
62 : char const * confs[] =
63 : {
64 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
65 : ".config/file.mdi",
66 : "/etc/snapwebsites/server.conf",
67 : nullptr
68 2 : };
69 :
70 1 : environment_options.f_project_name = "unittest-any";
71 1 : environment_options.f_options = nullptr;
72 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
73 1 : environment_options.f_help_header = "Testing all possible filenames";
74 1 : environment_options.f_configuration_files = confs;
75 :
76 2 : advgetopt::getopt opt(environment_options);
77 :
78 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
79 :
80 1 : CATCH_REQUIRE(filenames.size() == 6);
81 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
82 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
83 1 : CATCH_REQUIRE(filenames[2] == ".config/file.mdi");
84 1 : CATCH_REQUIRE(filenames[3] == ".config/unittest-any.d/file.mdi");
85 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/server.conf");
86 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-any.d/server.conf");
87 : CATCH_END_SECTION()
88 :
89 18 : CATCH_START_SECTION("Configuration Files (writable)")
90 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable", "writable");
91 :
92 1 : advgetopt::options_environment environment_options;
93 :
94 : char const * confs[] =
95 : {
96 : ".config/file.mdi",
97 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
98 : "/etc/snapwebsites/server.conf",
99 : nullptr
100 2 : };
101 :
102 1 : environment_options.f_project_name = "unittest-writable";
103 1 : environment_options.f_options = nullptr;
104 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
105 1 : environment_options.f_help_header = "Testing all possible filenames";
106 1 : environment_options.f_configuration_files = confs;
107 :
108 2 : advgetopt::getopt opt(environment_options);
109 :
110 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, true));
111 :
112 1 : CATCH_REQUIRE(filenames.size() == 3);
113 1 : CATCH_REQUIRE(filenames[0] == ".config/unittest-writable.d/file.mdi");
114 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
115 1 : CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/unittest-writable.d/server.conf");
116 : CATCH_END_SECTION()
117 :
118 18 : CATCH_START_SECTION("Configuration File + Directories")
119 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories", "with-dirs", true);
120 :
121 1 : advgetopt::options_environment environment_options;
122 :
123 : char const * dirs[] =
124 : {
125 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
126 : ".config",
127 : "/etc/snapwebsites",
128 : nullptr
129 2 : };
130 :
131 1 : environment_options.f_project_name = "unittest-with-directories";
132 1 : environment_options.f_options = nullptr;
133 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
134 1 : environment_options.f_help_header = "Testing all possible filenames";
135 1 : environment_options.f_configuration_filename = "snapfirewall.conf";
136 1 : environment_options.f_configuration_directories = dirs;
137 :
138 2 : advgetopt::getopt opt(environment_options);
139 :
140 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
141 :
142 1 : CATCH_REQUIRE(filenames.size() == 6);
143 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
144 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/snapfirewall.conf");
145 1 : CATCH_REQUIRE(filenames[2] == ".config/snapfirewall.conf");
146 1 : CATCH_REQUIRE(filenames[3] == ".config/unittest-with-directories.d/snapfirewall.conf");
147 1 : CATCH_REQUIRE(filenames[4] == "/etc/snapwebsites/snapfirewall.conf");
148 1 : CATCH_REQUIRE(filenames[5] == "/etc/snapwebsites/unittest-with-directories.d/snapfirewall.conf");
149 : CATCH_END_SECTION()
150 :
151 18 : CATCH_START_SECTION("Configuration File + Directories + '--config-dir'")
152 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-with-directories-and-config-dir", "with-many-dirs", true);
153 :
154 1 : advgetopt::options_environment environment_options;
155 :
156 : char const * dirs[] =
157 : {
158 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
159 : ".config",
160 : "/etc/advgetopt",
161 : nullptr
162 2 : };
163 :
164 1 : environment_options.f_project_name = "unittest-with-directories-and-config-dir";
165 1 : environment_options.f_options = nullptr;
166 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
167 1 : environment_options.f_help_header = "Testing all possible filenames";
168 1 : environment_options.f_configuration_filename = "snapmerger.conf";
169 1 : environment_options.f_configuration_directories = dirs;
170 :
171 : char const * cargv[] =
172 : {
173 : "/usr/bin/config",
174 : "--config-dir",
175 : "/var/lib/advgetopt",
176 : "--config-dir",
177 : "/opt/config",
178 : nullptr
179 1 : };
180 1 : int const argc(sizeof(cargv) / sizeof(cargv[0]) - 1);
181 1 : char ** argv = const_cast<char **>(cargv);
182 :
183 2 : advgetopt::getopt opt(environment_options, argc, argv);
184 :
185 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
186 :
187 1 : CATCH_REQUIRE(filenames.size() == 10);
188 1 : CATCH_REQUIRE(filenames[0] == "/var/lib/advgetopt/snapmerger.conf");
189 1 : CATCH_REQUIRE(filenames[1] == "/var/lib/advgetopt/unittest-with-directories-and-config-dir.d/snapmerger.conf");
190 1 : CATCH_REQUIRE(filenames[2] == "/opt/config/snapmerger.conf");
191 1 : CATCH_REQUIRE(filenames[3] == "/opt/config/unittest-with-directories-and-config-dir.d/snapmerger.conf");
192 1 : CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapmerger.conf");
193 1 : CATCH_REQUIRE(filenames[5] == SNAP_CATCH2_NAMESPACE::g_config_project_filename + "/snapmerger.conf");
194 1 : CATCH_REQUIRE(filenames[6] == ".config/snapmerger.conf");
195 1 : CATCH_REQUIRE(filenames[7] == ".config/unittest-with-directories-and-config-dir.d/snapmerger.conf");
196 1 : CATCH_REQUIRE(filenames[8] == "/etc/advgetopt/snapmerger.conf");
197 1 : CATCH_REQUIRE(filenames[9] == "/etc/advgetopt/unittest-with-directories-and-config-dir.d/snapmerger.conf");
198 : CATCH_END_SECTION()
199 :
200 18 : CATCH_START_SECTION("Existing Configuration Files")
201 :
202 10 : CATCH_WHEN("R/W Config must exist--no user defined config")
203 : {
204 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-must-exist", "must-be-here");
205 :
206 : {
207 2 : std::ofstream config_file;
208 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
209 1 : CATCH_REQUIRE(config_file.good());
210 : config_file <<
211 : "# Auto-generated\n"
212 : "ip=192.168.0.1\n"
213 : "wall=iptables\n"
214 1 : ;
215 : }
216 :
217 1 : unlink(SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str());
218 :
219 : char const * confs[] =
220 : {
221 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
222 : ".config/file-which-was-never-created.mdi",
223 : "/etc/snapwebsites/not-an-existing-file.conf",
224 : nullptr
225 2 : };
226 :
227 1 : advgetopt::options_environment environment_options;
228 1 : environment_options.f_project_name = "unittest";
229 1 : environment_options.f_options = nullptr;
230 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
231 1 : environment_options.f_help_header = "Testing all possible filenames";
232 1 : environment_options.f_configuration_files = confs;
233 :
234 2 : advgetopt::getopt opt(environment_options);
235 :
236 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
237 :
238 1 : CATCH_REQUIRE(filenames.size() == 1);
239 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
240 : }
241 :
242 10 : CATCH_WHEN("R/W Config must exist--user defined config exists")
243 : {
244 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-exist", "existing");
245 :
246 : {
247 2 : std::ofstream config_file;
248 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
249 1 : CATCH_REQUIRE(config_file.good());
250 : config_file <<
251 : "# Auto-generated\n"
252 : "block-ip=192.168.6.11\n"
253 : "firewall=iptables\n"
254 1 : ;
255 : }
256 :
257 : {
258 2 : std::ofstream config_file;
259 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
260 1 : CATCH_REQUIRE(config_file.good());
261 : config_file <<
262 : "# Auto-generated\n"
263 : "ip=10.0.2.5\n"
264 : "duration=6h\n"
265 1 : ;
266 : }
267 :
268 : char const * confs[] =
269 : {
270 : ".config/file-which-was-never-created.mdi",
271 : "/etc/snapwebsites/not-an-existing-file.conf",
272 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
273 : nullptr
274 2 : };
275 :
276 1 : advgetopt::options_environment environment_options;
277 1 : environment_options.f_project_name = "unittest-user-exist";
278 1 : environment_options.f_options = nullptr;
279 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
280 1 : environment_options.f_help_header = "Testing all possible filenames";
281 1 : environment_options.f_configuration_files = confs;
282 :
283 2 : advgetopt::getopt opt(environment_options);
284 :
285 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, false));
286 :
287 1 : CATCH_REQUIRE(filenames.size() == 2);
288 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_filename);
289 1 : CATCH_REQUIRE(filenames[1] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
290 : }
291 :
292 10 : CATCH_WHEN("Writable Config must exist--user defined config exists")
293 : {
294 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-exist", "present");
295 :
296 : {
297 2 : std::ofstream config_file;
298 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
299 1 : CATCH_REQUIRE(config_file.good());
300 : config_file <<
301 : "# Auto-generated\n"
302 : "block-ip=192.168.6.11\n"
303 : "firewall=iptables\n"
304 1 : ;
305 : }
306 :
307 : {
308 2 : std::ofstream config_file;
309 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
310 1 : CATCH_REQUIRE(config_file.good());
311 : config_file <<
312 : "# Auto-generated\n"
313 : "ip=10.0.2.5\n"
314 : "duration=6h\n"
315 1 : ;
316 : }
317 :
318 : char const * confs[] =
319 : {
320 : ".config/file-which-was-never-created.mdi",
321 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
322 : "/etc/snapwebsites/not/an-existing-file.conf",
323 : nullptr
324 2 : };
325 :
326 1 : advgetopt::options_environment environment_options;
327 1 : environment_options.f_project_name = "unittest-writable-exist";
328 1 : environment_options.f_options = nullptr;
329 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
330 1 : environment_options.f_help_header = "Testing all possible filenames";
331 1 : environment_options.f_configuration_files = confs;
332 :
333 2 : advgetopt::getopt opt(environment_options);
334 :
335 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
336 :
337 1 : CATCH_REQUIRE(filenames.size() == 1);
338 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
339 : }
340 :
341 10 : CATCH_WHEN("Writable Config must exist--user defined config exists and we test with a user folder")
342 : {
343 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-writable-user", "user-write");
344 :
345 : {
346 2 : std::ofstream config_file;
347 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
348 1 : CATCH_REQUIRE(config_file.good());
349 : config_file <<
350 : "# Auto-generated\n"
351 : "block-ip=192.168.6.11\n"
352 : "firewall=iptables\n"
353 1 : ;
354 : }
355 :
356 : {
357 2 : std::ofstream config_file;
358 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
359 1 : CATCH_REQUIRE(config_file.good());
360 : config_file <<
361 : "# Auto-generated\n"
362 : "ip=10.0.2.5\n"
363 : "duration=6h\n"
364 1 : ;
365 : }
366 :
367 : char const * confs[] =
368 : {
369 : "~/.config/file-which-was-never-created.mdi",
370 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
371 : "/etc/snapwebsites/not/an-existing-file.conf",
372 : nullptr
373 2 : };
374 :
375 1 : advgetopt::options_environment environment_options;
376 1 : environment_options.f_project_name = "unittest-writable-user";
377 1 : environment_options.f_options = nullptr;
378 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
379 1 : environment_options.f_help_header = "Testing all possible filenames";
380 1 : environment_options.f_configuration_files = confs;
381 :
382 2 : advgetopt::getopt opt(environment_options);
383 :
384 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(true, true));
385 :
386 1 : CATCH_REQUIRE(filenames.size() == 1);
387 1 : CATCH_REQUIRE(filenames[0] == SNAP_CATCH2_NAMESPACE::g_config_project_filename);
388 : }
389 :
390 10 : CATCH_WHEN("R/W Config test must exist--user defined config exists and we test with a user folder")
391 : {
392 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("unittest-user-folder", "tilde");
393 :
394 2 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
395 1 : tmpdir += "/.config/home-that-never-gets-created";
396 2 : snap::safe_setenv env("HOME", tmpdir);
397 :
398 : {
399 2 : std::ofstream config_file;
400 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
401 1 : CATCH_REQUIRE(config_file.good());
402 : config_file <<
403 : "# Auto-generated\n"
404 : "ip=10.0.2.5\n"
405 : "duration=6h\n"
406 1 : ;
407 : }
408 :
409 : char const * dirs[] =
410 : {
411 : "~/.config/folder-which-was-never-created",
412 : "/etc/snapwebsites/not-an-existing-folder",
413 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
414 : nullptr
415 2 : };
416 :
417 1 : advgetopt::options_environment environment_options;
418 1 : environment_options.f_project_name = "unittest-user-folder";
419 1 : environment_options.f_options = nullptr;
420 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
421 1 : environment_options.f_help_header = "Testing all possible filenames";
422 1 : environment_options.f_configuration_filename = "snapfirewall.conf";
423 1 : environment_options.f_configuration_directories = dirs;
424 :
425 2 : advgetopt::getopt opt(environment_options);
426 :
427 2 : advgetopt::string_list_t const filenames(opt.get_configuration_filenames(false, false));
428 :
429 1 : CATCH_REQUIRE(filenames.size() == 5);
430 1 : CATCH_REQUIRE(filenames[0] == tmpdir + "/.config/folder-which-was-never-created/snapfirewall.conf");
431 1 : CATCH_REQUIRE(filenames[1] == "/etc/snapwebsites/not-an-existing-folder/snapfirewall.conf");
432 1 : CATCH_REQUIRE(filenames[2] == "/etc/snapwebsites/not-an-existing-folder/unittest-user-folder.d/snapfirewall.conf");
433 1 : CATCH_REQUIRE(filenames[3] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/snapfirewall.conf");
434 1 : CATCH_REQUIRE(filenames[4] == SNAP_CATCH2_NAMESPACE::g_config_filename + "/unittest-user-folder.d/snapfirewall.conf");
435 : }
436 : CATCH_END_SECTION()
437 9 : }
438 :
439 :
440 :
441 4 : CATCH_TEST_CASE("load_configuration_file", "[config][getopt][filenames]")
442 : {
443 4 : CATCH_START_SECTION("Load a Configuration File")
444 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("load", "tool");
445 :
446 : {
447 2 : std::ofstream config_file;
448 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
449 1 : CATCH_REQUIRE(config_file.good());
450 : config_file <<
451 : "# Auto-generated\n"
452 : "sizes=132\n"
453 : "filenames=green,orange,blue brown white\n"
454 1 : ;
455 : }
456 :
457 : char const * confs[] =
458 : {
459 : "~/.config/file-which-was-never-created.mdi",
460 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
461 : "/etc/snapwebsites/not/an-existing-file.conf",
462 : nullptr
463 2 : };
464 :
465 : char const * const separators[] {
466 : ",",
467 : " ",
468 : nullptr
469 1 : };
470 :
471 : advgetopt::option const options[] =
472 : {
473 : advgetopt::define_option(
474 : advgetopt::Name("sizes")
475 : , advgetopt::ShortName('s')
476 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
477 : , advgetopt::Help("sizes.")
478 : ),
479 : advgetopt::define_option(
480 : advgetopt::Name("filenames")
481 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
482 : , advgetopt::Help("enter a list of filenames.")
483 : , advgetopt::DefaultValue("a.out")
484 : , advgetopt::Separators(separators)
485 1 : ),
486 : advgetopt::end_options()
487 2 : };
488 :
489 1 : advgetopt::options_environment environment_options;
490 1 : environment_options.f_project_name = "load";
491 1 : environment_options.f_options = options;
492 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
493 1 : environment_options.f_help_header = "Testing loading a filenames";
494 1 : environment_options.f_configuration_files = confs;
495 :
496 2 : advgetopt::getopt opt(environment_options);
497 :
498 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
499 :
500 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
501 1 : CATCH_REQUIRE(opt.get_string("sizes") == "132");
502 :
503 1 : CATCH_REQUIRE(opt.size("filenames") == 5);
504 1 : CATCH_REQUIRE(opt.get_string("filenames") == "green");
505 1 : CATCH_REQUIRE(opt.get_string("filenames", 0) == "green");
506 1 : CATCH_REQUIRE(opt.get_string("filenames", 1) == "orange");
507 1 : CATCH_REQUIRE(opt.get_string("filenames", 2) == "blue");
508 1 : CATCH_REQUIRE(opt.get_string("filenames", 3) == "brown");
509 1 : CATCH_REQUIRE(opt.get_string("filenames", 4) == "white");
510 : CATCH_END_SECTION()
511 :
512 4 : CATCH_START_SECTION("Load an Extended Configuration File")
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 : 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 1 : ;
526 : }
527 :
528 : 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 2 : };
535 :
536 : char const * const separators[] {
537 : ",",
538 : " ",
539 : nullptr
540 1 : };
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 1 : ),
557 : advgetopt::end_options()
558 2 : };
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 : CATCH_END_SECTION()
588 2 : }
589 :
590 :
591 :
592 3 : CATCH_TEST_CASE("load_multiple_configurations", "[config][getopt][filenames]")
593 : {
594 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("multiple", "multiplicity");
595 :
596 : //string_list_t getopt::get_configuration_filenames(bool exists, bool writable)
597 :
598 2 : CATCH_START_SECTION("Configuration Files")
599 1 : advgetopt::options_environment environment_options;
600 :
601 2 : std::string tmpdir(SNAP_CATCH2_NAMESPACE::g_tmp_dir);
602 1 : tmpdir += "/.config/home";
603 :
604 2 : std::stringstream ss;
605 1 : ss << "mkdir -p " << tmpdir;
606 1 : if(system(ss.str().c_str()) != 0)
607 : {
608 0 : std::cerr << "fatal error: creating sub-temporary directory \"" << tmpdir << "\" failed.\n";
609 0 : exit(1);
610 : }
611 :
612 2 : snap::safe_setenv env("HOME", tmpdir);
613 :
614 : {
615 2 : std::ofstream config_file;
616 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
617 1 : CATCH_REQUIRE(config_file.good());
618 : config_file <<
619 : "# Auto-generated\n"
620 : "ip=10.0.2.5\n"
621 : "duration=6h\n"
622 : "size=604\n"
623 : "gap=6\n"
624 : "filename=utf9.txt\n"
625 1 : ;
626 : }
627 :
628 : {
629 2 : std::ofstream config_file;
630 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_project_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
631 1 : CATCH_REQUIRE(config_file.good());
632 : config_file <<
633 : "# Auto-generated\n"
634 : "ip=10.1.7.205\n"
635 : "gap=9\n"
636 : "filename=utf7.txt\n"
637 1 : ;
638 : }
639 :
640 : {
641 2 : std::ofstream config_file;
642 1 : config_file.open(tmpdir + "/advgetopt.conf", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
643 1 : CATCH_REQUIRE(config_file.good());
644 : config_file <<
645 : "# Auto-generated\n"
646 : "duration=105min\n"
647 : "filename=utf8.txt\n"
648 1 : ;
649 : }
650 :
651 : char const * confs[] =
652 : {
653 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
654 1 : SNAP_CATCH2_NAMESPACE::g_config_project_filename.c_str(),
655 : "~/advgetopt.conf",
656 : nullptr
657 3 : };
658 :
659 : advgetopt::option const options[] =
660 : {
661 : advgetopt::define_option(
662 : advgetopt::Name("size")
663 : , advgetopt::ShortName('s')
664 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
665 : , advgetopt::Help("size.")
666 : ),
667 : advgetopt::define_option(
668 : advgetopt::Name("filename")
669 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
670 : , advgetopt::Help("enter a filenames.")
671 : , advgetopt::DefaultValue("a.out")
672 : ),
673 : advgetopt::define_option(
674 : advgetopt::Name("duration")
675 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
676 : , advgetopt::Help("how long it lasts.")
677 : ),
678 : advgetopt::define_option(
679 : advgetopt::Name("gap")
680 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
681 : , advgetopt::Help("gap size.")
682 : ),
683 : advgetopt::define_option(
684 : advgetopt::Name("ip")
685 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
686 : , advgetopt::Help("enter the ip address.")
687 : ),
688 : advgetopt::end_options()
689 1 : };
690 :
691 1 : environment_options.f_project_name = "unittest";
692 1 : environment_options.f_options = options;
693 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
694 1 : environment_options.f_help_header = "Testing a load with multiple filenames and see that we get the latest";
695 1 : environment_options.f_configuration_files = confs;
696 :
697 2 : advgetopt::getopt opt(environment_options);
698 :
699 1 : opt.parse_configuration_files();
700 :
701 1 : CATCH_REQUIRE(opt.size("size") == 1);
702 1 : CATCH_REQUIRE(opt.get_string("size") == "604");
703 :
704 : // although it is marked as multiple, the old entries are still
705 : // overwritten with newer versions; if the last entry had multiple
706 : // filenames, then we'd get get multiple names here
707 : //
708 1 : CATCH_REQUIRE(opt.size("filename") == 1);
709 1 : CATCH_REQUIRE(opt.get_string("filename", 0) == "utf8.txt");
710 :
711 1 : CATCH_REQUIRE(opt.size("duration") == 1);
712 1 : CATCH_REQUIRE(opt.get_string("duration") == "105min");
713 :
714 1 : CATCH_REQUIRE(opt.size("gap") == 1);
715 1 : CATCH_REQUIRE(opt.get_string("gap") == "9");
716 :
717 1 : CATCH_REQUIRE(opt.size("ip") == 1);
718 1 : CATCH_REQUIRE(opt.get_string("ip") == "10.1.7.205");
719 : CATCH_END_SECTION()
720 1 : }
721 :
722 :
723 :
724 6 : CATCH_TEST_CASE("load_invalid_configuration_file", "[config][getopt][filenames][invalid]")
725 : {
726 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--dynamic allowed)")
727 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid", "invalid-one-letter");
728 :
729 : {
730 2 : std::ofstream config_file;
731 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
732 1 : CATCH_REQUIRE(config_file.good());
733 : config_file <<
734 : "# Auto-generated\n"
735 : "sizes=-132\n"
736 : "f=dynamic\n"
737 1 : ;
738 : }
739 :
740 : char const * confs[] =
741 : {
742 : "~/.config/file-which-was-never-created.mdi",
743 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
744 : "/etc/snapwebsites/not/an-existing-file.conf",
745 : nullptr
746 2 : };
747 :
748 : char const * const separators[] {
749 : ",",
750 : " ",
751 : nullptr
752 1 : };
753 :
754 : advgetopt::option const options[] =
755 : {
756 : advgetopt::define_option(
757 : advgetopt::Name("sizes")
758 : , advgetopt::ShortName('s')
759 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
760 : , advgetopt::Help("sizes.")
761 : ),
762 : advgetopt::define_option(
763 : advgetopt::Name("filenames")
764 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
765 : , advgetopt::Help("enter a list of filenames.")
766 : , advgetopt::DefaultValue("a.out")
767 : , advgetopt::Separators(separators)
768 1 : ),
769 : advgetopt::end_options()
770 2 : };
771 :
772 1 : advgetopt::options_environment environment_options;
773 1 : environment_options.f_project_name = "loading-invalid";
774 1 : environment_options.f_options = options;
775 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS | advgetopt::GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS;
776 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
777 1 : environment_options.f_configuration_files = confs;
778 :
779 2 : advgetopt::getopt opt(environment_options);
780 :
781 : SNAP_CATCH2_NAMESPACE::push_expected_log(
782 : "error: unknown option \"f\" found in configuration file \""
783 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
784 1 : + "\".");
785 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
786 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
787 :
788 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
789 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
790 1 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
791 :
792 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
793 : CATCH_END_SECTION()
794 :
795 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (one letter--no dynamic allowed)")
796 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-undefined", "undefined-one-letter");
797 :
798 : {
799 2 : std::ofstream config_file;
800 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
801 1 : CATCH_REQUIRE(config_file.good());
802 : config_file <<
803 : "# Auto-generated\n"
804 : "sizes=-132\n"
805 : "f=dynamic\n"
806 1 : ;
807 : }
808 :
809 : char const * confs[] =
810 : {
811 : "~/.config/file-which-was-never-created.mdi",
812 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
813 : "/etc/snapwebsites/not/an-existing-file.conf",
814 : nullptr
815 2 : };
816 :
817 : char const * const separators[] {
818 : ",",
819 : " ",
820 : nullptr
821 1 : };
822 :
823 : advgetopt::option const options[] =
824 : {
825 : advgetopt::define_option(
826 : advgetopt::Name("sizes")
827 : , advgetopt::ShortName('s')
828 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
829 : , advgetopt::Help("sizes.")
830 : ),
831 : advgetopt::define_option(
832 : advgetopt::Name("filenames")
833 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
834 : , advgetopt::Help("enter a list of filenames.")
835 : , advgetopt::DefaultValue("a.out")
836 : , advgetopt::Separators(separators)
837 1 : ),
838 : advgetopt::end_options()
839 2 : };
840 :
841 1 : advgetopt::options_environment environment_options;
842 1 : environment_options.f_project_name = "loading-invalid";
843 1 : environment_options.f_options = options;
844 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
845 1 : environment_options.f_help_header = "Testing loading a one letter parameter";
846 1 : environment_options.f_configuration_files = confs;
847 :
848 2 : advgetopt::getopt opt(environment_options);
849 :
850 : SNAP_CATCH2_NAMESPACE::push_expected_log(
851 : "error: unknown option \"f\" found in configuration file \""
852 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
853 1 : + "\".");
854 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
855 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
856 :
857 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
858 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-132");
859 1 : CATCH_REQUIRE(opt.get_long("sizes") == -132);
860 :
861 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
862 : CATCH_END_SECTION()
863 :
864 8 : CATCH_START_SECTION("Load with Unexpected Parameter Name (undefined & no dynamic fields are allowed)")
865 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-dynamic", "invalid-dynamic");
866 :
867 : {
868 2 : std::ofstream config_file;
869 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
870 1 : CATCH_REQUIRE(config_file.good());
871 : config_file <<
872 : "# Auto-generated\n"
873 : "sizes=-1001\n"
874 : "dynamic=\"undefined argument\"\n"
875 1 : ;
876 : }
877 :
878 : char const * confs[] =
879 : {
880 : "~/.config/file-which-was-never-created.mdi",
881 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
882 : "/etc/snapwebsites/not/an-existing-file.conf",
883 : nullptr
884 2 : };
885 :
886 : char const * const separators[] {
887 : ",",
888 : " ",
889 : nullptr
890 1 : };
891 :
892 : advgetopt::option const options[] =
893 : {
894 : advgetopt::define_option(
895 : advgetopt::Name("sizes")
896 : , advgetopt::ShortName('s')
897 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
898 : , advgetopt::Help("sizes.")
899 : ),
900 : advgetopt::define_option(
901 : advgetopt::Name("filenames")
902 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
903 : , advgetopt::Help("enter a list of filenames.")
904 : , advgetopt::DefaultValue("a.out")
905 : , advgetopt::Separators(separators)
906 1 : ),
907 : advgetopt::end_options()
908 2 : };
909 :
910 1 : advgetopt::options_environment environment_options;
911 1 : environment_options.f_project_name = "loading-invalid";
912 1 : environment_options.f_options = options;
913 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
914 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
915 1 : environment_options.f_configuration_files = confs;
916 :
917 2 : advgetopt::getopt opt(environment_options);
918 :
919 : SNAP_CATCH2_NAMESPACE::push_expected_log(
920 : "error: unknown option \"dynamic\" found in configuration file \""
921 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
922 1 : + "\".");
923 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
924 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
925 :
926 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
927 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
928 1 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
929 :
930 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
931 : CATCH_END_SECTION()
932 :
933 8 : CATCH_START_SECTION("Load with Parameter not Supported in Configuration Files")
934 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("loading-invalid-config", "invalid-param-in-config");
935 :
936 : {
937 2 : std::ofstream config_file;
938 1 : config_file.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
939 1 : CATCH_REQUIRE(config_file.good());
940 : config_file <<
941 : "# Auto-generated\n"
942 : "sizes=-1001\n"
943 : "filenames=unexpected, argument, in, configuration, file\n"
944 1 : ;
945 : }
946 :
947 : char const * confs[] =
948 : {
949 : "~/.config/file-which-was-never-created.mdi",
950 1 : SNAP_CATCH2_NAMESPACE::g_config_filename.c_str(),
951 : "/etc/snapwebsites/not/an-existing-file.conf",
952 : nullptr
953 2 : };
954 :
955 : char const * const separators[] {
956 : ",",
957 : " ",
958 : nullptr
959 1 : };
960 :
961 : advgetopt::option const options[] =
962 : {
963 : advgetopt::define_option(
964 : advgetopt::Name("sizes")
965 : , advgetopt::ShortName('s')
966 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_REQUIRED>())
967 : , advgetopt::Help("sizes.")
968 : ),
969 : advgetopt::define_option(
970 : advgetopt::Name("filenames")
971 : , advgetopt::Flags(advgetopt::command_flags<advgetopt::GETOPT_FLAG_REQUIRED, advgetopt::GETOPT_FLAG_MULTIPLE>())
972 : , advgetopt::Help("enter a list of filenames.")
973 : , advgetopt::DefaultValue("a.out")
974 : , advgetopt::Separators(separators)
975 1 : ),
976 : advgetopt::end_options()
977 2 : };
978 :
979 1 : advgetopt::options_environment environment_options;
980 1 : environment_options.f_project_name = "loading-invalid";
981 1 : environment_options.f_options = options;
982 1 : environment_options.f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS;
983 1 : environment_options.f_help_header = "Testing loading an unknown parameter and no dynamic allowed";
984 1 : environment_options.f_configuration_files = confs;
985 :
986 2 : advgetopt::getopt opt(environment_options);
987 :
988 : SNAP_CATCH2_NAMESPACE::push_expected_log(
989 : "error: option \"filenames\" is not supported in configuration files (found in \""
990 2 : + SNAP_CATCH2_NAMESPACE::g_config_filename
991 1 : + "\").");
992 1 : opt.process_configuration_file(SNAP_CATCH2_NAMESPACE::g_config_filename);
993 1 : SNAP_CATCH2_NAMESPACE::expected_logs_stack_is_empty();
994 :
995 1 : CATCH_REQUIRE(opt.size("sizes") == 1);
996 1 : CATCH_REQUIRE(opt.get_string("sizes") == "-1001");
997 1 : CATCH_REQUIRE(opt.get_long("sizes") == -1001);
998 :
999 1 : CATCH_REQUIRE(opt.size("filenames") == 0);
1000 : CATCH_END_SECTION()
1001 10 : }
1002 :
1003 :
1004 :
1005 : // vim: ts=4 sw=4 et nowrap
|