Line data Source code
1 : // Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/as2js
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // as2js
20 : //
21 : // the resources.h is private hence the use of "..."
22 : //
23 : #include "as2js/file/resources.h"
24 :
25 : #include <as2js/exception.h>
26 : #include <as2js/message.h>
27 :
28 :
29 :
30 : // self
31 : //
32 : #include "catch_main.h"
33 :
34 :
35 : // snapdev
36 : //
37 : #include <snapdev/mkdir_p.h>
38 : #include <snapdev/safe_setenv.h>
39 :
40 :
41 : // C++
42 : //
43 : #include <cstring>
44 :
45 :
46 : // C
47 : //
48 : #include <sys/stat.h>
49 : #include <unistd.h>
50 :
51 :
52 : // last include
53 : //
54 : #include <snapdev/poison.h>
55 :
56 :
57 :
58 :
59 : namespace
60 : {
61 :
62 :
63 : class test_callback
64 : : public as2js::message_callback
65 : {
66 : public:
67 4 : test_callback()
68 4 : {
69 4 : as2js::set_message_callback(this);
70 4 : g_warning_count = as2js::warning_count();
71 4 : g_error_count = as2js::error_count();
72 4 : }
73 :
74 4 : ~test_callback()
75 4 : {
76 : // make sure the pointer gets reset!
77 4 : as2js::set_message_callback(nullptr);
78 4 : }
79 :
80 : // implementation of the output
81 10 : virtual void output(as2js::message_level_t message_level, as2js::err_code_t error_code, as2js::position const& pos, std::string const& message)
82 : {
83 10 : if(f_expected.empty())
84 : {
85 0 : std::cerr << "\nfilename = " << pos.get_filename() << "\n";
86 0 : std::cerr << "msg = " << message << "\n";
87 0 : std::cerr << "page = " << pos.get_page() << "\n";
88 0 : std::cerr << "line = " << pos.get_line() << "\n";
89 0 : std::cerr << "error_code = " << static_cast<int>(error_code) << "\n";
90 : }
91 :
92 10 : CATCH_REQUIRE(!f_expected.empty());
93 :
94 : //std::cerr << "filename = " << pos.get_filename() << " / " << f_expected[0].f_pos.get_filename() << "\n";
95 : //std::cerr << "msg = " << message << " / " << f_expected[0].f_message << "\n";
96 : //std::cerr << "page = " << pos.get_page() << " / " << f_expected[0].f_pos.get_page() << "\n";
97 : //std::cerr << "line = " << pos.get_line() << " / " << f_expected[0].f_pos.get_line() << "\n";
98 : //std::cerr << "error_code = " << static_cast<int>(error_code) << " / " << static_cast<int>(f_expected[0].f_error_code) << "\n";
99 :
100 10 : CATCH_REQUIRE(f_expected[0].f_call);
101 10 : CATCH_REQUIRE(message_level == f_expected[0].f_message_level);
102 10 : CATCH_REQUIRE(error_code == f_expected[0].f_error_code);
103 10 : CATCH_REQUIRE(pos.get_filename() == f_expected[0].f_pos.get_filename());
104 10 : CATCH_REQUIRE(pos.get_function() == f_expected[0].f_pos.get_function());
105 10 : CATCH_REQUIRE(pos.get_page() == f_expected[0].f_pos.get_page());
106 10 : CATCH_REQUIRE(pos.get_page_line() == f_expected[0].f_pos.get_page_line());
107 10 : CATCH_REQUIRE(pos.get_paragraph() == f_expected[0].f_pos.get_paragraph());
108 10 : CATCH_REQUIRE(pos.get_line() == f_expected[0].f_pos.get_line());
109 10 : CATCH_REQUIRE(message == f_expected[0].f_message);
110 :
111 10 : if(message_level == as2js::message_level_t::MESSAGE_LEVEL_WARNING)
112 : {
113 0 : ++g_warning_count;
114 0 : CATCH_REQUIRE(g_warning_count == as2js::warning_count());
115 : }
116 :
117 10 : if(message_level == as2js::message_level_t::MESSAGE_LEVEL_FATAL
118 0 : || message_level == as2js::message_level_t::MESSAGE_LEVEL_ERROR)
119 : {
120 10 : ++g_error_count;
121 : //std::cerr << "error: " << g_error_count << " / " << as2js::error_count() << "\n";
122 10 : CATCH_REQUIRE(g_error_count == as2js::error_count());
123 : }
124 :
125 10 : f_expected.erase(f_expected.begin());
126 10 : }
127 :
128 10 : void got_called()
129 : {
130 10 : if(!f_expected.empty())
131 : {
132 0 : std::cerr << "\n*** STILL EXPECTED: ***\n";
133 0 : std::cerr << "filename = " << f_expected[0].f_pos.get_filename() << "\n";
134 0 : std::cerr << "msg = " << f_expected[0].f_message << "\n";
135 0 : std::cerr << "page = " << f_expected[0].f_pos.get_page() << "\n";
136 0 : std::cerr << "error_code = " << static_cast<int>(f_expected[0].f_error_code) << "\n";
137 : }
138 10 : CATCH_REQUIRE(f_expected.empty());
139 10 : }
140 :
141 : struct expected_t
142 : {
143 : bool f_call = true;
144 : as2js::message_level_t f_message_level = as2js::message_level_t::MESSAGE_LEVEL_OFF;
145 : as2js::err_code_t f_error_code = as2js::err_code_t::AS_ERR_NONE;
146 : as2js::position f_pos = as2js::position();
147 : std::string f_message = std::string(); // UTF-8 string
148 : };
149 :
150 : std::vector<expected_t> f_expected = std::vector<expected_t>();
151 :
152 : static int32_t g_warning_count;
153 : static int32_t g_error_count;
154 : };
155 :
156 : int32_t test_callback::g_warning_count = 0;
157 : int32_t test_callback::g_error_count = 0;
158 :
159 : int32_t g_empty_home_too_late = 0;
160 :
161 : }
162 : // no name namespace
163 :
164 :
165 :
166 :
167 : namespace SNAP_CATCH2_NAMESPACE
168 : {
169 :
170 :
171 :
172 1 : int catch_rc_init()
173 : {
174 : // verify that this user does not have existing rc files because
175 : // that can interfer with the tests! (and we do not want to delete
176 : // those under their feet)
177 :
178 : // AS2JS_RC variable must not exist
179 : //
180 1 : if(getenv("AS2JS_RC") != nullptr)
181 : {
182 0 : std::cerr << "error: the \"AS2JS_RC\" environment variable is defined; please make sure you want to run this test on this system and unset that variable before doing so.\n";
183 0 : return 1;
184 : }
185 :
186 : // local file
187 : //
188 1 : struct stat st;
189 1 : if(stat("as2js/as2js.rc", &st) != -1)
190 : {
191 0 : std::cerr << "error: file \"as2js/as2js.rc\" already exists; please check it out to make sure you can delete it and try running the test again.\n";
192 0 : return 1;
193 : }
194 :
195 : // user defined .config file
196 : //
197 1 : if(getenv("HOME") == nullptr)
198 : {
199 0 : std::cerr << "error: the \"HOME\" environment variable is expected to be defined.\n";
200 0 : return 1;
201 : }
202 2 : std::string const home(getenv("HOME"));
203 1 : std::string config(home);
204 1 : config += "/.config/as2js/as2js.rc";
205 1 : if(stat(config.c_str(), &st) != -1)
206 : {
207 : std::cerr << "error: file \""
208 : << config
209 0 : << "\" already exists; please check it out to make sure you can delete it and try running the test again.\n";
210 0 : return 1;
211 : }
212 :
213 : // system defined configuration file
214 : //
215 1 : if(stat("/etc/as2js/as2js.rc", &st) != -1)
216 : {
217 : std::cerr << "error: file \""
218 : << "/etc/as2js/as2js.rc"
219 0 : << "\" already exists; please check it out to make sure you can delete it and try running the test again.\n";
220 0 : return 1;
221 : }
222 :
223 : // create the local as2js directory now
224 : //
225 1 : if(mkdir("as2js", 0700) != 0)
226 : {
227 0 : int const e(errno);
228 : std::cerr << "error: could not create directory \""
229 : << home
230 : << "as2js"
231 0 : << "\". (errno: "
232 : << e
233 : << ", "
234 0 : << strerror(e)
235 0 : << ")\n";
236 0 : return 1;
237 : }
238 :
239 1 : return 0;
240 1 : }
241 :
242 :
243 :
244 : } // namespace SNAP_CATCH2_NAMESPACE
245 :
246 :
247 1 : CATCH_TEST_CASE("resources_basics", "[resources][file]")
248 : {
249 1 : CATCH_START_SECTION("resources_basics: check paths & filenames")
250 : {
251 : // this test is not going to work if the get_home() function was
252 : // already called with an empty HOME variable...
253 : //
254 1 : if(g_empty_home_too_late == 2)
255 : {
256 0 : std::cout << " --- test_empty_home() not run, the other rc unit tests are not compatible with this test --- ";
257 0 : return;
258 : }
259 :
260 1 : g_empty_home_too_late = 1;
261 :
262 : {
263 : // test the get_home()
264 : //
265 2 : std::string const home(getenv("HOME"));
266 1 : std::string rc_home(as2js::resources::get_home());
267 1 : CATCH_REQUIRE(rc_home == home);
268 :
269 : // verify that changing the variable after the first call returns
270 : // the first value...
271 : //
272 5 : snapdev::transparent_setenv safe_home("HOME", "/got/changed/now");
273 1 : rc_home = as2js::resources::get_home();
274 1 : CATCH_REQUIRE(rc_home == home);
275 1 : } // restore original HOME
276 :
277 : // without the as2js/scripts sub-directory, we get nothing
278 : {
279 1 : as2js::resources rc;
280 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
281 1 : CATCH_REQUIRE(paths.empty());
282 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
283 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "@temp");
284 1 : }
285 :
286 : {
287 : //std::string const home(getenv("HOME"));
288 : //CATCH_REQUIRE(snapdev::mkdir_p(home + "/as2js/scripts", false, 0700) == 0);
289 1 : CATCH_REQUIRE(snapdev::mkdir_p("as2js/scripts", false, 0700) == 0);
290 1 : char * cwd(get_current_dir_name());
291 1 : as2js::resources rc;
292 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
293 1 : CATCH_REQUIRE(paths.size() == 1);
294 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
295 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
296 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "@temp");
297 1 : free(cwd);
298 1 : }
299 :
300 : {
301 1 : as2js::resources rc;
302 :
303 1 : test_callback tc;
304 :
305 1 : test_callback::expected_t expected1;
306 1 : expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
307 1 : expected1.f_error_code = as2js::err_code_t::AS_ERR_INSTALLATION;
308 1 : expected1.f_pos.set_filename("unknown-file");
309 1 : expected1.f_pos.set_function("unknown-func");
310 1 : expected1.f_message = "cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\".";
311 1 : tc.f_expected.push_back(expected1);
312 :
313 1 : CATCH_REQUIRE_THROWS_MATCHES(
314 : rc.init(false)
315 : , as2js::as2js_exit
316 : , Catch::Matchers::ExceptionMessage(
317 : "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
318 1 : tc.got_called();
319 :
320 1 : rc.init(true);
321 :
322 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
323 1 : CATCH_REQUIRE(paths.size() == 1);
324 1 : char * cwd(get_current_dir_name());
325 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
326 1 : free(cwd);
327 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
328 1 : }
329 : }
330 1 : CATCH_END_SECTION()
331 : }
332 :
333 :
334 1 : CATCH_TEST_CASE("resources_load_from_var", "[resources][config][file][variable]")
335 : {
336 1 : CATCH_START_SECTION("resources_load_from_var: NULL value")
337 : {
338 : // this test is not going to work if the get_home() function was
339 : // already called with an empty HOME variable...
340 1 : if(g_empty_home_too_late == 2)
341 : {
342 0 : std::cout << " --- test_empty_home() not run, the other rc unit tests are not compatible with this test --- ";
343 0 : return;
344 : }
345 :
346 1 : g_empty_home_too_late = 1;
347 :
348 : // just in case it failed before...
349 : //
350 1 : unlink("as2js.rc");
351 :
352 : {
353 1 : setenv("AS2JS_RC", ".", 1);
354 :
355 1 : test_callback tc;
356 :
357 1 : test_callback::expected_t expected1;
358 1 : expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
359 1 : expected1.f_error_code = as2js::err_code_t::AS_ERR_INSTALLATION;
360 1 : expected1.f_pos.set_filename("unknown-file");
361 1 : expected1.f_pos.set_function("unknown-func");
362 1 : expected1.f_message = "cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\".";
363 1 : tc.f_expected.push_back(expected1);
364 :
365 1 : as2js::resources rc;
366 1 : CATCH_REQUIRE_THROWS_MATCHES(
367 : rc.init(false)
368 : , as2js::as2js_exit
369 : , Catch::Matchers::ExceptionMessage(
370 : "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
371 1 : tc.got_called();
372 :
373 : {
374 : // create an .rc file
375 1 : CATCH_REQUIRE(snapdev::mkdir_p("the/script", false, 0700) == 0);
376 : {
377 1 : std::ofstream rc_file;
378 1 : rc_file.open("as2js.rc");
379 1 : CATCH_REQUIRE(rc_file.is_open());
380 : rc_file << "// rc file\n"
381 : << "{\n"
382 : << " 'scripts': 'the/script',\n"
383 : << " 'db': 'that/db',\n"
384 : << " 'temporary_variable_name': '@temp$'\n"
385 1 : << "}\n";
386 1 : }
387 :
388 1 : rc.init(true);
389 1 : unlink("as2js.rc");
390 :
391 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
392 1 : CATCH_REQUIRE(paths.size() == 1);
393 1 : char * cwd(get_current_dir_name());
394 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
395 1 : free(cwd);
396 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
397 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "@temp$");
398 1 : }
399 :
400 : {
401 : // create an .rc file, without scripts
402 : {
403 1 : std::ofstream rc_file;
404 1 : rc_file.open("as2js.rc");
405 1 : CATCH_REQUIRE(rc_file.is_open());
406 : rc_file << "// rc file\n"
407 : << "{\n"
408 : << " 'db': 'that/db'\n"
409 1 : << "}\n";
410 1 : }
411 :
412 1 : rc.init(true);
413 1 : unlink("as2js.rc");
414 :
415 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
416 1 : CATCH_REQUIRE(paths.size() == 1);
417 1 : char * cwd(get_current_dir_name());
418 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
419 1 : free(cwd);
420 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
421 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "@temp");
422 1 : }
423 :
424 : {
425 : // create an .rc file, without scripts
426 1 : CATCH_REQUIRE(snapdev::mkdir_p("the/script", false, 0700) == 0);
427 : {
428 1 : std::ofstream rc_file;
429 1 : rc_file.open("as2js.rc");
430 1 : CATCH_REQUIRE(rc_file.is_open());
431 : rc_file << "// rc file\n"
432 : << "{\n"
433 : << " 'scripts': 'the/script'\n"
434 1 : << "}\n";
435 1 : }
436 :
437 1 : rc.init(true);
438 1 : unlink("as2js.rc");
439 :
440 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
441 1 : CATCH_REQUIRE(paths.size() == 1);
442 1 : char * cwd(get_current_dir_name());
443 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
444 1 : free(cwd);
445 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
446 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "@temp");
447 1 : }
448 :
449 : {
450 : // create an .rc file, with just the temporary variable name
451 : {
452 1 : std::ofstream rc_file;
453 1 : rc_file.open("as2js.rc");
454 1 : CATCH_REQUIRE(rc_file.is_open());
455 : rc_file << "// rc file\n"
456 : << "{\n"
457 : << " \"temporary_variable_name\": \"what about validity of the value? -- we on purpose use @ because it is not valid in identifiers\"\n"
458 1 : << "}\n";
459 1 : }
460 :
461 1 : rc.init(true);
462 1 : unlink("as2js.rc");
463 :
464 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
465 1 : CATCH_REQUIRE(paths.size() == 1);
466 1 : char * cwd(get_current_dir_name());
467 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
468 1 : free(cwd);
469 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
470 1 : CATCH_REQUIRE(rc.get_temporary_variable_name() == "what about validity of the value? -- we on purpose use @ because it is not valid in identifiers");
471 1 : }
472 :
473 : {
474 : // create an .rc file, without scripts
475 : {
476 1 : std::ofstream rc_file;
477 1 : rc_file.open("as2js.rc");
478 1 : CATCH_REQUIRE(rc_file.is_open());
479 : rc_file << "// rc file\n"
480 : << "{\n"
481 : << " 'scripts': 123\n"
482 1 : << "}\n";
483 1 : }
484 :
485 1 : test_callback::expected_t expected2;
486 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
487 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
488 1 : expected2.f_pos.set_filename("./as2js.rc");
489 1 : expected2.f_pos.set_function("unknown-func");
490 1 : expected2.f_pos.new_line();
491 1 : expected2.f_pos.new_line();
492 1 : expected2.f_pos.new_line();
493 1 : expected2.f_message = "a resource file is expected to be an object of string elements.";
494 1 : tc.f_expected.push_back(expected2);
495 :
496 1 : CATCH_REQUIRE_THROWS_MATCHES(
497 : rc.init(true)
498 : , as2js::as2js_exit
499 : , Catch::Matchers::ExceptionMessage(
500 : "as2js_exception: a resource file is expected to be an object of string elements."));
501 1 : tc.got_called();
502 1 : unlink("as2js.rc");
503 :
504 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
505 1 : CATCH_REQUIRE(paths.size() == 1);
506 1 : char * cwd(get_current_dir_name());
507 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
508 1 : free(cwd);
509 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
510 1 : }
511 :
512 : {
513 : // create a null .rc file
514 : {
515 1 : std::ofstream rc_file;
516 1 : rc_file.open("as2js.rc");
517 1 : CATCH_REQUIRE(rc_file.is_open());
518 : rc_file << "// rc file\n"
519 1 : << "null\n";
520 1 : }
521 :
522 1 : rc.init(false);
523 1 : unlink("as2js.rc");
524 :
525 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
526 1 : CATCH_REQUIRE(paths.size() == 1);
527 1 : char * cwd(get_current_dir_name());
528 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
529 1 : free(cwd);
530 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
531 1 : }
532 :
533 : {
534 : // create an .rc file, without an object nor null
535 : {
536 1 : std::ofstream rc_file;
537 1 : rc_file.open("as2js.rc");
538 1 : CATCH_REQUIRE(rc_file.is_open());
539 : rc_file << "// rc file\n"
540 1 : << "['scripts', 123]\n";
541 1 : }
542 :
543 1 : test_callback::expected_t expected2;
544 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
545 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
546 1 : expected2.f_pos.set_filename("./as2js.rc");
547 1 : expected2.f_pos.set_function("unknown-func");
548 1 : expected2.f_pos.new_line();
549 1 : expected2.f_message = "./as2js.rc: a resource file (.rc) must be defined as a JSON object, or set to \"null\".";
550 1 : tc.f_expected.push_back(expected2);
551 :
552 1 : CATCH_REQUIRE_THROWS_MATCHES(
553 : rc.init(true)
554 : , as2js::as2js_exit
555 : , Catch::Matchers::ExceptionMessage(
556 : "as2js_exception: ./as2js.rc: a resource file (.rc) must be defined as a JSON object, or set to \"null\"."));
557 1 : tc.got_called();
558 1 : unlink("as2js.rc");
559 :
560 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
561 1 : CATCH_REQUIRE(paths.size() == 1);
562 1 : char * cwd(get_current_dir_name());
563 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
564 1 : free(cwd);
565 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
566 1 : }
567 :
568 : // test some other directory too
569 1 : setenv("AS2JS_RC", "/tmp", 1);
570 :
571 : {
572 : // create an .rc file
573 1 : CATCH_REQUIRE(snapdev::mkdir_p("the/script", false, 0700) == 0);
574 : {
575 1 : std::ofstream rc_file;
576 1 : rc_file.open("/tmp/as2js.rc");
577 1 : CATCH_REQUIRE(rc_file.is_open());
578 : rc_file << "// rc file\n"
579 : << "{\n"
580 : << " 'scripts': 'the/script',\n"
581 : << " 'db': 'that/db'\n"
582 1 : << "}\n";
583 1 : }
584 :
585 1 : rc.init(true);
586 1 : unlink("/tmp/as2js.rc");
587 :
588 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
589 1 : CATCH_REQUIRE(paths.size() == 1);
590 1 : char * cwd(get_current_dir_name());
591 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
592 1 : free(cwd);
593 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
594 1 : }
595 :
596 : // make sure to delete that before exiting
597 : //
598 1 : unsetenv("AS2JS_RC");
599 1 : }
600 : }
601 1 : CATCH_END_SECTION()
602 : }
603 :
604 :
605 1 : CATCH_TEST_CASE("resources_load_from_local_config", "[resources][config][file]")
606 : {
607 1 : CATCH_START_SECTION("resources_load_from_local_config: check that the local as2js.rc gets picked up")
608 : {
609 : // this test is not going to work if the get_home() function was
610 : // already called with an empty HOME variable...
611 1 : if(g_empty_home_too_late == 2)
612 : {
613 0 : std::cout << "--- test_empty_home() not run, the other rc unit tests are not compatible with this test ---\n";
614 0 : return;
615 : }
616 :
617 1 : g_empty_home_too_late = 1;
618 :
619 : // just in case it failed before...
620 : //
621 1 : static_cast<void>(unlink(".config/as2js.rc"));
622 1 : static_cast<void>(rmdir(".config"));
623 :
624 1 : CATCH_REQUIRE(mkdir(".config", 0700) == 0);
625 :
626 : {
627 1 : test_callback tc;
628 :
629 1 : test_callback::expected_t expected1;
630 1 : expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
631 1 : expected1.f_error_code = as2js::err_code_t::AS_ERR_INSTALLATION;
632 1 : expected1.f_pos.set_filename("unknown-file");
633 1 : expected1.f_pos.set_function("unknown-func");
634 1 : expected1.f_message = "cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\".";
635 1 : tc.f_expected.push_back(expected1);
636 :
637 1 : as2js::resources rc;
638 1 : CATCH_REQUIRE_THROWS_MATCHES(
639 : rc.init(false)
640 : , as2js::as2js_exit
641 : , Catch::Matchers::ExceptionMessage(
642 : "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
643 1 : tc.got_called();
644 :
645 : {
646 : // create an .rc file
647 : {
648 1 : std::ofstream rc_file;
649 1 : rc_file.open("as2js/as2js.rc");
650 1 : CATCH_REQUIRE(rc_file.is_open());
651 : rc_file << "// rc file\n"
652 : << "{\n"
653 : << " 'scripts': 'the/script',\n"
654 : << " 'db': 'that/db'\n"
655 1 : << "}\n";
656 1 : }
657 :
658 1 : rc.init(true);
659 1 : unlink("as2js/as2js.rc");
660 :
661 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
662 1 : CATCH_REQUIRE(paths.size() == 1);
663 1 : char * cwd(get_current_dir_name());
664 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
665 1 : free(cwd);
666 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
667 1 : }
668 :
669 : {
670 : // create an .rc file, without scripts
671 : {
672 1 : std::ofstream rc_file;
673 1 : rc_file.open("as2js/as2js.rc");
674 1 : CATCH_REQUIRE(rc_file.is_open());
675 : rc_file << "// rc file\n"
676 : << "{\n"
677 : << " 'db': 'that/db'\n"
678 1 : << "}\n";
679 1 : }
680 :
681 1 : rc.init(true);
682 1 : unlink("as2js/as2js.rc");
683 :
684 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
685 1 : CATCH_REQUIRE(paths.size() == 1);
686 1 : char * cwd(get_current_dir_name());
687 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
688 1 : free(cwd);
689 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
690 1 : }
691 :
692 : {
693 : // create an .rc file, without scripts
694 : {
695 1 : std::ofstream rc_file;
696 1 : rc_file.open("as2js/as2js.rc");
697 1 : CATCH_REQUIRE(rc_file.is_open());
698 : rc_file << "// rc file\n"
699 : << "{\n"
700 : << " 'scripts': 'the/script'\n"
701 1 : << "}\n";
702 1 : }
703 :
704 1 : rc.init(true);
705 1 : unlink("as2js/as2js.rc");
706 :
707 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
708 1 : CATCH_REQUIRE(paths.size() == 1);
709 1 : char * cwd(get_current_dir_name());
710 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
711 1 : free(cwd);
712 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
713 1 : }
714 :
715 : {
716 : // create an .rc file, without scripts
717 : {
718 1 : std::ofstream rc_file;
719 1 : rc_file.open("as2js/as2js.rc");
720 1 : CATCH_REQUIRE(rc_file.is_open());
721 : rc_file << "// rc file\n"
722 : << "{\n"
723 : << " 'scripts': 123\n"
724 1 : << "}\n";
725 1 : }
726 :
727 1 : test_callback::expected_t expected2;
728 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
729 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
730 1 : expected2.f_pos.set_filename("as2js/as2js.rc");
731 1 : expected2.f_pos.set_function("unknown-func");
732 1 : expected2.f_pos.new_line();
733 1 : expected2.f_pos.new_line();
734 1 : expected2.f_pos.new_line();
735 1 : expected2.f_message = "a resource file is expected to be an object of string elements.";
736 1 : tc.f_expected.push_back(expected2);
737 :
738 1 : CATCH_REQUIRE_THROWS_MATCHES(
739 : rc.init(true)
740 : , as2js::as2js_exit
741 : , Catch::Matchers::ExceptionMessage(
742 : "as2js_exception: a resource file is expected to be an object of string elements."));
743 1 : tc.got_called();
744 1 : unlink("as2js/as2js.rc");
745 :
746 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
747 1 : CATCH_REQUIRE(paths.size() == 1);
748 1 : char * cwd(get_current_dir_name());
749 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
750 1 : free(cwd);
751 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
752 1 : }
753 :
754 : {
755 : // create a null .rc file
756 : {
757 1 : std::ofstream rc_file;
758 1 : rc_file.open("as2js/as2js.rc");
759 1 : CATCH_REQUIRE(rc_file.is_open());
760 : rc_file << "// rc file\n"
761 1 : << "null\n";
762 1 : }
763 :
764 1 : rc.init(false);
765 1 : unlink("as2js/as2js.rc");
766 :
767 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
768 1 : CATCH_REQUIRE(paths.size() == 1);
769 1 : char * cwd(get_current_dir_name());
770 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
771 1 : free(cwd);
772 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
773 1 : }
774 :
775 : {
776 : // create an .rc file, without an object nor null
777 : {
778 1 : std::ofstream rc_file;
779 1 : rc_file.open("as2js/as2js.rc");
780 1 : CATCH_REQUIRE(rc_file.is_open());
781 : rc_file << "// rc file\n"
782 1 : << "['scripts', 123]\n";
783 1 : }
784 :
785 1 : test_callback::expected_t expected2;
786 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
787 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
788 1 : expected2.f_pos.set_filename("as2js/as2js.rc");
789 1 : expected2.f_pos.set_function("unknown-func");
790 1 : expected2.f_pos.new_line();
791 1 : expected2.f_message = "as2js/as2js.rc: a resource file (.rc) must be defined as a JSON object, or set to \"null\".";
792 1 : tc.f_expected.push_back(expected2);
793 :
794 1 : CATCH_REQUIRE_THROWS_MATCHES(
795 : rc.init(true)
796 : , as2js::as2js_exit
797 : , Catch::Matchers::ExceptionMessage(
798 : "as2js_exception: as2js/as2js.rc: a resource file (.rc) must be defined as a JSON object, or set to \"null\"."));
799 1 : tc.got_called();
800 1 : unlink("as2js/as2js.rc");
801 :
802 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
803 1 : CATCH_REQUIRE(paths.size() == 1);
804 1 : char * cwd(get_current_dir_name());
805 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
806 1 : free(cwd);
807 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
808 1 : }
809 1 : }
810 :
811 : // delete our temporary .rc file (should already have been deleted)
812 1 : unlink("as2js/as2js.rc");
813 :
814 : // if possible get rid of the directory (don't check for errors)
815 1 : rmdir("as2js");
816 : }
817 1 : CATCH_END_SECTION()
818 : }
819 :
820 :
821 1 : CATCH_TEST_CASE("resources_load_from_user_config", "[resources][config][file]")
822 : {
823 1 : CATCH_START_SECTION("resources_load_from_user_config: NULL value")
824 : {
825 : // this test is not going to work if the get_home() function was
826 : // already called with an empty HOME variable...
827 1 : if(g_empty_home_too_late == 2)
828 : {
829 0 : std::cout << "--- test_empty_home() not run, the other rc unit tests are not compatible with this test ---\n";
830 0 : return;
831 : }
832 :
833 1 : g_empty_home_too_late = 1;
834 :
835 2 : std::string const home(getenv("HOME"));
836 :
837 : // create the folders and make sure we clean up any existing .rc file
838 : // (although it was checked in the setUp() function and thus we should
839 : // not reach here if the .rc already existed!)
840 : //
841 1 : std::string config(home);
842 1 : config += "/.config";
843 1 : std::cout << "--- config path \"" << config << "\" ---\n";
844 1 : bool del_config(true);
845 1 : if(mkdir(config.c_str(), 0700) != 0) // usually this is 0755, but for security we cannot take that risk...
846 : {
847 : // if this mkdir() fails, it is because it exists?
848 : //
849 0 : CATCH_REQUIRE(errno == EEXIST);
850 0 : del_config = false;
851 : }
852 1 : std::string as2js_conf(config);
853 1 : as2js_conf += "/as2js";
854 1 : CATCH_REQUIRE(snapdev::mkdir_p(as2js_conf.c_str(), false, 0700) == 0);
855 1 : std::string as2js_rc(as2js_conf);
856 1 : as2js_rc += "/as2js.rc";
857 1 : unlink(as2js_rc.c_str()); // delete that, just in case (the setup verifies that it does not exist)
858 : //system(("ls -lR " + config).c_str());
859 :
860 : {
861 1 : test_callback tc;
862 :
863 1 : test_callback::expected_t expected1;
864 1 : expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
865 1 : expected1.f_error_code = as2js::err_code_t::AS_ERR_INSTALLATION;
866 1 : expected1.f_pos.set_filename("unknown-file");
867 1 : expected1.f_pos.set_function("unknown-func");
868 1 : expected1.f_message = "cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\".";
869 1 : tc.f_expected.push_back(expected1);
870 :
871 1 : as2js::resources rc;
872 1 : CATCH_REQUIRE_THROWS_MATCHES(
873 : rc.init(false)
874 : , as2js::as2js_exit
875 : , Catch::Matchers::ExceptionMessage(
876 : "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
877 1 : tc.got_called();
878 :
879 : {
880 : // create an .rc file
881 1 : CATCH_REQUIRE(snapdev::mkdir_p("the/script", false, 0700) == 0);
882 1 : CATCH_REQUIRE(snapdev::mkdir_p("another/script", false, 0700) == 0);
883 1 : CATCH_REQUIRE(snapdev::mkdir_p("here/script", false, 0700) == 0);
884 : {
885 1 : std::ofstream rc_file;
886 1 : rc_file.open(as2js_rc.c_str());
887 1 : CATCH_REQUIRE(rc_file.is_open());
888 : rc_file << "// rc file\n"
889 : << "{\n"
890 : << " 'scripts': 'the/script:another/script:here/script',\n"
891 : << " 'db': 'that/db'\n"
892 1 : << "}\n";
893 1 : }
894 :
895 1 : rc.init(true);
896 1 : unlink(as2js_rc.c_str());
897 :
898 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
899 1 : CATCH_REQUIRE(paths.size() == 3);
900 1 : auto it(paths.begin());
901 1 : char * cwd(get_current_dir_name());
902 1 : CATCH_REQUIRE(*it == std::string(cwd) + "/the/script");
903 1 : ++it;
904 1 : CATCH_REQUIRE(*it == std::string(cwd) + "/another/script");
905 1 : ++it;
906 1 : CATCH_REQUIRE(*it == std::string(cwd) + "/here/script");
907 1 : free(cwd);
908 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
909 1 : }
910 :
911 : {
912 : // create an .rc file, without scripts
913 : {
914 1 : std::ofstream rc_file;
915 1 : rc_file.open(as2js_rc.c_str());
916 1 : CATCH_REQUIRE(rc_file.is_open());
917 : rc_file << "// rc file\n"
918 : << "{\n"
919 : << " 'db': 'that/db'\n"
920 1 : << "}\n";
921 1 : }
922 :
923 1 : rc.init(true);
924 1 : unlink(as2js_rc.c_str());
925 :
926 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
927 1 : CATCH_REQUIRE(paths.size() == 1);
928 1 : char * cwd(get_current_dir_name());
929 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
930 1 : free(cwd);
931 1 : CATCH_REQUIRE(rc.get_db() == "that/db");
932 1 : }
933 :
934 : {
935 : // create an .rc file, without scripts
936 : {
937 1 : std::ofstream rc_file;
938 1 : rc_file.open(as2js_rc.c_str());
939 1 : CATCH_REQUIRE(rc_file.is_open());
940 : rc_file << "// rc file\n"
941 : << "{\n"
942 : << " 'scripts': 'the/script'\n"
943 1 : << "}\n";
944 1 : }
945 :
946 1 : rc.init(true);
947 1 : unlink(as2js_rc.c_str());
948 :
949 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
950 1 : CATCH_REQUIRE(paths.size() == 1);
951 1 : char * cwd(get_current_dir_name());
952 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/the/script");
953 1 : free(cwd);
954 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
955 1 : }
956 :
957 : {
958 : // create an .rc file, without scripts
959 : {
960 1 : std::ofstream rc_file;
961 1 : rc_file.open(as2js_rc.c_str());
962 1 : CATCH_REQUIRE(rc_file.is_open());
963 : rc_file << "// rc file\n"
964 : << "{\n"
965 : << " 'scripts': 123\n"
966 1 : << "}\n";
967 1 : }
968 :
969 1 : test_callback::expected_t expected2;
970 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
971 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
972 1 : expected2.f_pos.set_filename(as2js_rc.c_str());
973 1 : expected2.f_pos.set_function("unknown-func");
974 1 : expected2.f_pos.new_line();
975 1 : expected2.f_pos.new_line();
976 1 : expected2.f_pos.new_line();
977 1 : expected2.f_message = "a resource file is expected to be an object of string elements.";
978 1 : tc.f_expected.push_back(expected2);
979 :
980 1 : CATCH_REQUIRE_THROWS_MATCHES(
981 : rc.init(true)
982 : , as2js::as2js_exit
983 : , Catch::Matchers::ExceptionMessage(
984 : "as2js_exception: a resource file is expected to be an object of string elements."));
985 1 : tc.got_called();
986 1 : unlink(as2js_rc.c_str());
987 :
988 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
989 1 : CATCH_REQUIRE(paths.size() == 1);
990 1 : char * cwd(get_current_dir_name());
991 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
992 1 : free(cwd);
993 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
994 1 : }
995 :
996 : {
997 : // create a null .rc file
998 : {
999 1 : std::ofstream rc_file;
1000 1 : rc_file.open(as2js_rc.c_str());
1001 1 : CATCH_REQUIRE(rc_file.is_open());
1002 : rc_file << "// rc file\n"
1003 1 : << "null\n";
1004 1 : }
1005 :
1006 1 : rc.init(false);
1007 1 : unlink(as2js_rc.c_str());
1008 :
1009 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
1010 1 : CATCH_REQUIRE(paths.size() == 1);
1011 1 : char * cwd(get_current_dir_name());
1012 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
1013 1 : free(cwd);
1014 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1015 1 : }
1016 :
1017 : {
1018 : // create an .rc file, without an object nor null
1019 : {
1020 1 : std::ofstream rc_file;
1021 1 : rc_file.open(as2js_rc.c_str());
1022 1 : CATCH_REQUIRE(rc_file.is_open());
1023 : rc_file << "// rc file\n"
1024 1 : << "['scripts', 123]\n";
1025 1 : }
1026 :
1027 1 : char * cwd(get_current_dir_name());
1028 1 : test_callback::expected_t expected2;
1029 1 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
1030 1 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
1031 1 : expected2.f_pos.set_filename(as2js_rc.c_str());
1032 1 : expected2.f_pos.set_function("unknown-func");
1033 1 : expected2.f_pos.new_line();
1034 1 : expected2.f_message = std::string(cwd) + "/home/.config/as2js/as2js.rc: a resource file (.rc) must be defined as a JSON object, or set to \"null\".";
1035 1 : tc.f_expected.push_back(expected2);
1036 :
1037 1 : CATCH_REQUIRE_THROWS_MATCHES(
1038 : rc.init(true)
1039 : , as2js::as2js_exit
1040 : , Catch::Matchers::ExceptionMessage(
1041 : "as2js_exception: " + expected2.f_message));
1042 : //"as2js_exception: a resource file (.rc) must be defined as a JSON object, or set to \"null\"."));
1043 1 : tc.got_called();
1044 1 : unlink(as2js_rc.c_str());
1045 :
1046 1 : as2js::resources::script_paths_t paths(rc.get_scripts());
1047 1 : CATCH_REQUIRE(paths.size() == 1);
1048 1 : CATCH_REQUIRE(*paths.begin() == std::string(cwd) + "/as2js/scripts");
1049 1 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1050 1 : free(cwd);
1051 1 : }
1052 1 : }
1053 :
1054 : // delete our temporary .rc file (should already have been deleted)
1055 1 : unlink(as2js_rc.c_str());
1056 :
1057 : // if possible get rid of the directories (don't check for errors)
1058 1 : rmdir(as2js_conf.c_str());
1059 1 : if(del_config)
1060 : {
1061 1 : rmdir(config.c_str());
1062 : }
1063 1 : }
1064 1 : CATCH_END_SECTION()
1065 : }
1066 :
1067 :
1068 : //
1069 : // WARNING: this test requires root permissions, it can generally be
1070 : // ignored though because it uses the same process as the
1071 : // user local file in "as2js/as2js.rc"; it is here for
1072 : // completeness in case you absolutely want to prove that
1073 : // works as expected
1074 : //
1075 1 : CATCH_TEST_CASE("resources_load_from_system_config", "[resources][config][file]")
1076 : {
1077 1 : CATCH_START_SECTION("resources_load_from_system_config: NULL value")
1078 : {
1079 1 : if(getuid() != 0)
1080 : {
1081 1 : std::cout << "--- test_load_from_system_config() requires root access to modify the /etc/as2js directory ---\n";
1082 1 : CATCH_REQUIRE(getuid() != 0);
1083 1 : return;
1084 : }
1085 :
1086 : // this test is not going to work if the get_home() function was
1087 : // already called with an empty HOME variable...
1088 : //
1089 0 : if(g_empty_home_too_late == 2)
1090 : {
1091 0 : std::cout << "--- test_empty_home() not run, the other rc unit tests are not compatible with this test ---\n";
1092 0 : return;
1093 : }
1094 :
1095 0 : g_empty_home_too_late = 1;
1096 :
1097 : // create the folders and make sure we clean up any existing .rc file
1098 : // (although it was checked in the setUp() function and thus we should
1099 : // not reach here if the .rc already existed!)
1100 0 : std::string as2js_conf("/etc/as2js");
1101 0 : int const r(mkdir(as2js_conf.c_str(), 0700)); // usually this is 0755, but for security we cannot take that risk...
1102 0 : if(r != 0)
1103 : {
1104 : // if this mkdir() fails, it is because it exists?
1105 : //
1106 0 : CATCH_REQUIRE(errno == EEXIST);
1107 : }
1108 0 : std::string as2js_rc(as2js_conf);
1109 0 : as2js_rc += "/as2js.rc";
1110 0 : unlink(as2js_rc.c_str()); // delete that, just in case (the setup verifies that it does not exist)
1111 :
1112 : {
1113 0 : test_callback tc;
1114 :
1115 0 : test_callback::expected_t expected1;
1116 0 : expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
1117 0 : expected1.f_error_code = as2js::err_code_t::AS_ERR_INSTALLATION;
1118 0 : expected1.f_pos.set_filename("unknown-file");
1119 0 : expected1.f_pos.set_function("unknown-func");
1120 0 : expected1.f_message = "cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\".";
1121 0 : tc.f_expected.push_back(expected1);
1122 :
1123 0 : as2js::resources rc;
1124 0 : CATCH_REQUIRE_THROWS_MATCHES(
1125 : rc.init(false)
1126 : , as2js::as2js_exit
1127 : , Catch::Matchers::ExceptionMessage(
1128 : "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
1129 0 : tc.got_called();
1130 :
1131 : {
1132 : // create an .rc file
1133 : {
1134 0 : std::ofstream rc_file;
1135 0 : rc_file.open(as2js_rc.c_str());
1136 0 : CATCH_REQUIRE(rc_file.is_open());
1137 : rc_file << "// rc file\n"
1138 : << "{\n"
1139 : << " 'scripts': 'the/script',\n"
1140 : << " 'db': 'that/db'\n"
1141 0 : << "}\n";
1142 0 : }
1143 :
1144 0 : rc.init(true);
1145 0 : unlink(as2js_rc.c_str());
1146 :
1147 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1148 0 : CATCH_REQUIRE(paths.size() == 1);
1149 0 : CATCH_REQUIRE(*paths.begin() == "the/script");
1150 0 : CATCH_REQUIRE(rc.get_db() == "that/db");
1151 0 : }
1152 :
1153 : {
1154 : // create an .rc file, without scripts
1155 : {
1156 0 : std::ofstream rc_file;
1157 0 : rc_file.open(as2js_rc.c_str());
1158 0 : CATCH_REQUIRE(rc_file.is_open());
1159 : rc_file << "// rc file\n"
1160 : << "{\n"
1161 : << " 'db': 'that/db'\n"
1162 0 : << "}\n";
1163 0 : }
1164 :
1165 0 : rc.init(true);
1166 0 : unlink(as2js_rc.c_str());
1167 :
1168 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1169 0 : CATCH_REQUIRE(paths.size() == 1);
1170 0 : CATCH_REQUIRE(*paths.begin() == "as2js/scripts");
1171 0 : CATCH_REQUIRE(rc.get_db() == "that/db");
1172 0 : }
1173 :
1174 : {
1175 : // create an .rc file, without scripts
1176 : {
1177 0 : std::ofstream rc_file;
1178 0 : rc_file.open(as2js_rc.c_str());
1179 0 : CATCH_REQUIRE(rc_file.is_open());
1180 : rc_file << "// rc file\n"
1181 : << "{\n"
1182 : << " 'scripts': 'the/script'\n"
1183 0 : << "}\n";
1184 0 : }
1185 :
1186 0 : rc.init(true);
1187 0 : unlink(as2js_rc.c_str());
1188 :
1189 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1190 0 : CATCH_REQUIRE(paths.size() == 1);
1191 0 : CATCH_REQUIRE(*paths.begin() == "the/script");
1192 0 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1193 0 : }
1194 :
1195 : {
1196 : // create an .rc file, without scripts
1197 : {
1198 0 : std::ofstream rc_file;
1199 0 : rc_file.open(as2js_rc.c_str());
1200 0 : CATCH_REQUIRE(rc_file.is_open());
1201 : rc_file << "// rc file\n"
1202 : << "{\n"
1203 : << " 'scripts': 123\n"
1204 0 : << "}\n";
1205 0 : }
1206 :
1207 0 : test_callback::expected_t expected2;
1208 0 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
1209 0 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
1210 0 : expected2.f_pos.set_filename(as2js_rc.c_str());
1211 0 : expected2.f_pos.set_function("unknown-func");
1212 0 : expected2.f_pos.new_line();
1213 0 : expected2.f_pos.new_line();
1214 0 : expected2.f_pos.new_line();
1215 0 : expected2.f_message = "a resource file is expected to be an object of string elements.";
1216 0 : tc.f_expected.push_back(expected2);
1217 :
1218 0 : CATCH_REQUIRE_THROWS_MATCHES(
1219 : rc.init(true)
1220 : , as2js::as2js_exit
1221 : , Catch::Matchers::ExceptionMessage(
1222 : "as2js_exception: a resource file is expected to be an object of string elements."));
1223 0 : tc.got_called();
1224 0 : unlink(as2js_rc.c_str());
1225 :
1226 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1227 0 : CATCH_REQUIRE(paths.size() == 1);
1228 0 : CATCH_REQUIRE(*paths.begin() == "as2js/scripts");
1229 0 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1230 0 : }
1231 :
1232 : {
1233 : // create a null .rc file
1234 : {
1235 0 : std::ofstream rc_file;
1236 0 : rc_file.open(as2js_rc.c_str());
1237 0 : CATCH_REQUIRE(rc_file.is_open());
1238 : rc_file << "// rc file\n"
1239 0 : << "null\n";
1240 0 : }
1241 :
1242 0 : rc.init(false);
1243 0 : unlink(as2js_rc.c_str());
1244 :
1245 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1246 0 : CATCH_REQUIRE(paths.size() == 1);
1247 0 : CATCH_REQUIRE(*paths.begin() == "as2js/scripts");
1248 0 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1249 0 : }
1250 :
1251 : {
1252 : // create an .rc file, without an object nor null
1253 : {
1254 0 : std::ofstream rc_file;
1255 0 : rc_file.open(as2js_rc.c_str());
1256 0 : CATCH_REQUIRE(rc_file.is_open());
1257 : rc_file << "// rc file\n"
1258 0 : << "['scripts', 123]\n";
1259 0 : }
1260 :
1261 0 : test_callback::expected_t expected2;
1262 0 : expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_FATAL;
1263 0 : expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_RC;
1264 0 : expected2.f_pos.set_filename(as2js_rc.c_str());
1265 0 : expected2.f_pos.set_function("unknown-func");
1266 0 : expected2.f_pos.new_line();
1267 0 : expected2.f_message = "a resource file (.rc) must be defined as a JSON object, or set to \"null\".";
1268 0 : tc.f_expected.push_back(expected2);
1269 :
1270 0 : CATCH_REQUIRE_THROWS_MATCHES(
1271 : rc.init(true)
1272 : , as2js::as2js_exit
1273 : , Catch::Matchers::ExceptionMessage(
1274 : "as2js_exception: a resource file (.rc) must be defined as a JSON object, or set to \"null\"."));
1275 0 : tc.got_called();
1276 0 : unlink(as2js_rc.c_str());
1277 :
1278 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1279 0 : CATCH_REQUIRE(paths.size() == 1);
1280 0 : CATCH_REQUIRE(*paths.begin() == "as2js/scripts");
1281 0 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1282 0 : }
1283 0 : }
1284 :
1285 : // delete our temporary .rc file (should already have been deleted)
1286 0 : unlink(as2js_rc.c_str());
1287 :
1288 : // if possible get rid of the directories (don't check for errors)
1289 0 : rmdir(as2js_conf.c_str());
1290 0 : }
1291 1 : CATCH_END_SECTION()
1292 : }
1293 :
1294 :
1295 1 : CATCH_TEST_CASE("resources_empty_home", "[resources][config][file]")
1296 : {
1297 1 : CATCH_START_SECTION("resources_empty_home: NULL value")
1298 : {
1299 : // this test is not going to work if the get_home() function was
1300 : // already called...
1301 1 : if(g_empty_home_too_late == 1)
1302 : {
1303 1 : std::cout << "--- test_empty_home() not run, the other rc unit tests are not compatible with this test ---\n";
1304 1 : CATCH_REQUIRE(g_empty_home_too_late == 1);
1305 1 : return;
1306 : }
1307 :
1308 0 : g_empty_home_too_late = 2;
1309 :
1310 : // create an .rc file in the user's config directory
1311 : //
1312 0 : std::string home(getenv("HOME"));
1313 :
1314 0 : std::string config(home);
1315 0 : config += "/.config";
1316 0 : std::cout << "--- config path \"" << config << "\" ---\n";
1317 0 : bool del_config(true);
1318 0 : if(mkdir(config.c_str(), 0700) != 0) // usually this is 0755, but for security we cannot take that risk...
1319 : {
1320 : // if this mkdir() fails, it is because it exists?
1321 : //
1322 0 : CATCH_REQUIRE(errno == EEXIST);
1323 0 : del_config = false;
1324 : }
1325 :
1326 0 : std::string rc_path(config);
1327 0 : rc_path += "/as2js";
1328 0 : CATCH_REQUIRE(mkdir(rc_path.c_str(), 0700) == 0);
1329 :
1330 0 : std::string rc_filename(rc_path);
1331 0 : rc_filename += "/as2js.rc";
1332 :
1333 0 : std::ofstream rc_file;
1334 0 : rc_file.open(rc_filename.c_str());
1335 0 : CATCH_REQUIRE(rc_file.is_open());
1336 : rc_file << "// rc file\n"
1337 : << "{\n"
1338 : << " 'scripts': 'cannot read this one',\n"
1339 : << " 'db': 'because it is not accessible'\n"
1340 0 : << "}\n";
1341 :
1342 : // remove the variable from the environment
1343 : //
1344 0 : snapdev::transparent_setenv safe("HOME", std::string());
1345 :
1346 : {
1347 0 : test_callback tc;
1348 :
1349 : // although we have an rc file under ~/.config/as2js/as2js.rc the
1350 : // rc class cannot find it because the $HOME variable was just deleted
1351 0 : as2js::resources rc;
1352 0 : rc.init(true);
1353 :
1354 0 : as2js::resources::script_paths_t paths(rc.get_scripts());
1355 0 : CATCH_REQUIRE(paths.size() == 1);
1356 0 : CATCH_REQUIRE(*paths.begin() == "as2js/scripts");
1357 0 : CATCH_REQUIRE(rc.get_db() == "/tmp/as2js_packages.db");
1358 0 : }
1359 :
1360 0 : unlink(rc_filename.c_str());
1361 0 : rmdir(rc_path.c_str());
1362 0 : }
1363 1 : CATCH_END_SECTION()
1364 : }
1365 :
1366 :
1367 : // vim: ts=4 sw=4 et
|