1 /* Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 #include "atf-c/check.h"
37 #include "atf-c/detail/fs.h"
38 #include "atf-c/detail/map.h"
39 #include "atf-c/detail/process.h"
40 #include "atf-c/detail/test_helpers.h"
42 /* ---------------------------------------------------------------------
43 * Auxiliary functions.
44 * --------------------------------------------------------------------- */
48 do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
50 atf_fs_path_t process_helpers;
53 get_process_helpers_path(tc, false, &process_helpers);
55 argv[0] = atf_fs_path_cstring(&process_helpers);
56 argv[1] = helper_name;
58 printf("Executing %s %s\n", argv[0], argv[1]);
59 RE(atf_check_exec_array(argv, r));
61 atf_fs_path_fini(&process_helpers);
66 do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
67 atf_check_result_t *r)
69 atf_fs_path_t process_helpers;
72 get_process_helpers_path(tc, false, &process_helpers);
74 argv[0] = atf_fs_path_cstring(&process_helpers);
75 argv[1] = helper_name;
78 printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
79 RE(atf_check_exec_array(argv, r));
81 atf_fs_path_fini(&process_helpers);
86 check_line(int fd, const char *exp)
88 char *line = atf_utils_readline(fd);
89 ATF_CHECK(line != NULL);
90 ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
94 /* ---------------------------------------------------------------------
95 * Helper test cases for the free functions.
96 * --------------------------------------------------------------------- */
98 ATF_TC(h_build_c_o_ok);
99 ATF_TC_HEAD(h_build_c_o_ok, tc)
101 atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
103 ATF_TC_BODY(h_build_c_o_ok, tc)
108 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
109 fprintf(sfile, "#include <stdio.h>\n");
112 RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
113 ATF_REQUIRE(success);
116 ATF_TC(h_build_c_o_fail);
117 ATF_TC_HEAD(h_build_c_o_fail, tc)
119 atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
121 ATF_TC_BODY(h_build_c_o_fail, tc)
126 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
127 fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
130 RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
131 ATF_REQUIRE(!success);
134 ATF_TC(h_build_cpp_ok);
135 ATF_TC_HEAD(h_build_cpp_ok, tc)
137 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
139 ATF_TC_BODY(h_build_cpp_ok, tc)
143 atf_fs_path_t test_p;
145 RE(atf_fs_path_init_fmt(&test_p, "test.p"));
147 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
148 fprintf(sfile, "#define A foo\n");
149 fprintf(sfile, "#define B bar\n");
150 fprintf(sfile, "A B\n");
153 RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
155 ATF_REQUIRE(success);
157 atf_fs_path_fini(&test_p);
160 ATF_TC(h_build_cpp_fail);
161 ATF_TC_HEAD(h_build_cpp_fail, tc)
163 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
165 ATF_TC_BODY(h_build_cpp_fail, tc)
170 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
171 fprintf(sfile, "#include \"./non-existent.h\"\n");
174 RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
175 ATF_REQUIRE(!success);
178 ATF_TC(h_build_cxx_o_ok);
179 ATF_TC_HEAD(h_build_cxx_o_ok, tc)
181 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
183 ATF_TC_BODY(h_build_cxx_o_ok, tc)
188 ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
189 fprintf(sfile, "#include <iostream>\n");
192 RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
193 ATF_REQUIRE(success);
196 ATF_TC(h_build_cxx_o_fail);
197 ATF_TC_HEAD(h_build_cxx_o_fail, tc)
199 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
201 ATF_TC_BODY(h_build_cxx_o_fail, tc)
206 ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
207 fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
210 RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
211 ATF_REQUIRE(!success);
214 /* ---------------------------------------------------------------------
215 * Test cases for the free functions.
216 * --------------------------------------------------------------------- */
220 init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
221 const char *outname, const char *errname)
223 const char *const config[] = { NULL };
225 RE(atf_tc_init_pack(tc, tcpack, config));
226 run_h_tc(tc, outname, errname, "result");
231 ATF_TC_HEAD(build_c_o, tc)
233 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
236 ATF_TC_BODY(build_c_o, tc)
238 init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
239 &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
240 ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
241 ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
243 init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
244 &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
245 ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
246 ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
247 ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
248 ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
252 ATF_TC_HEAD(build_cpp, tc)
254 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
257 ATF_TC_BODY(build_cpp, tc)
259 init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
260 &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
261 ATF_CHECK(atf_utils_grep_file("-o.*test.p", "stdout"));
262 ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
263 ATF_CHECK(atf_utils_grep_file("foo bar", "test.p"));
265 init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
266 &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
267 ATF_CHECK(atf_utils_grep_file("-o test.p", "stdout"));
268 ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
269 ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
270 ATF_CHECK(atf_utils_grep_file("non-existent.h", "stderr"));
274 ATF_TC_HEAD(build_cxx_o, tc)
276 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
279 ATF_TC_BODY(build_cxx_o, tc)
281 init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
282 &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
283 ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
284 ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
286 init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
287 &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
288 ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
289 ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
290 ATF_CHECK(atf_utils_grep_file("test.cpp", "stderr"));
291 ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
295 ATF_TC_HEAD(exec_array, tc)
297 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
300 ATF_TC_BODY(exec_array, tc)
302 atf_fs_path_t process_helpers;
303 atf_check_result_t result;
305 get_process_helpers_path(tc, false, &process_helpers);
308 argv[0] = atf_fs_path_cstring(&process_helpers);
310 argv[2] = "test-message";
313 RE(atf_check_exec_array(argv, &result));
315 ATF_CHECK(atf_check_result_exited(&result));
316 ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
319 const char *path = atf_check_result_stdout(&result);
320 int fd = open(path, O_RDONLY);
322 check_line(fd, "test-message");
326 atf_check_result_fini(&result);
327 atf_fs_path_fini(&process_helpers);
330 ATF_TC(exec_cleanup);
331 ATF_TC_HEAD(exec_cleanup, tc)
333 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
334 "properly cleans up the temporary files it creates");
336 ATF_TC_BODY(exec_cleanup, tc)
338 atf_fs_path_t out, err;
339 atf_check_result_t result;
342 do_exec(tc, "exit-success", &result);
343 RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
344 RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
346 RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
347 RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
348 atf_check_result_fini(&result);
349 RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
350 RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
352 atf_fs_path_fini(&err);
353 atf_fs_path_fini(&out);
356 ATF_TC(exec_exitstatus);
357 ATF_TC_HEAD(exec_exitstatus, tc)
359 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
360 "properly captures the exit status of the executed "
363 ATF_TC_BODY(exec_exitstatus, tc)
366 atf_check_result_t result;
367 do_exec(tc, "exit-success", &result);
368 ATF_CHECK(atf_check_result_exited(&result));
369 ATF_CHECK(!atf_check_result_signaled(&result));
370 ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
371 atf_check_result_fini(&result);
375 atf_check_result_t result;
376 do_exec(tc, "exit-failure", &result);
377 ATF_CHECK(atf_check_result_exited(&result));
378 ATF_CHECK(!atf_check_result_signaled(&result));
379 ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
380 atf_check_result_fini(&result);
384 atf_check_result_t result;
385 do_exec(tc, "exit-signal", &result);
386 ATF_CHECK(!atf_check_result_exited(&result));
387 ATF_CHECK(atf_check_result_signaled(&result));
388 ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
389 atf_check_result_fini(&result);
393 ATF_TC(exec_stdout_stderr);
394 ATF_TC_HEAD(exec_stdout_stderr, tc)
396 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
397 "properly captures the stdout and stderr streams "
398 "of the child process");
400 ATF_TC_BODY(exec_stdout_stderr, tc)
402 atf_check_result_t result1, result2;
403 const char *out1, *out2;
404 const char *err1, *err2;
406 do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
407 ATF_CHECK(atf_check_result_exited(&result1));
408 ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
410 do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
411 ATF_CHECK(atf_check_result_exited(&result2));
412 ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
414 out1 = atf_check_result_stdout(&result1);
415 out2 = atf_check_result_stdout(&result2);
416 err1 = atf_check_result_stderr(&result1);
417 err2 = atf_check_result_stderr(&result2);
419 ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
420 ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
421 ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
422 ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
424 ATF_CHECK(strstr(out1, "/check") != NULL);
425 ATF_CHECK(strstr(out2, "/check") != NULL);
426 ATF_CHECK(strstr(err1, "/check") != NULL);
427 ATF_CHECK(strstr(err2, "/check") != NULL);
429 ATF_CHECK(strstr(out1, "/stdout") != NULL);
430 ATF_CHECK(strstr(out2, "/stdout") != NULL);
431 ATF_CHECK(strstr(err1, "/stderr") != NULL);
432 ATF_CHECK(strstr(err2, "/stderr") != NULL);
434 ATF_CHECK(strcmp(out1, out2) != 0);
435 ATF_CHECK(strcmp(err1, err2) != 0);
437 #define CHECK_LINES(path, outname, resname) \
439 int fd = open(path, O_RDONLY); \
440 ATF_CHECK(fd != -1); \
441 check_line(fd, "Line 1 to " outname " for " resname); \
442 check_line(fd, "Line 2 to " outname " for " resname); \
446 CHECK_LINES(out1, "stdout", "result1");
447 CHECK_LINES(out2, "stdout", "result2");
448 CHECK_LINES(err1, "stderr", "result1");
449 CHECK_LINES(err2, "stderr", "result2");
453 atf_check_result_fini(&result2);
454 atf_check_result_fini(&result1);
458 ATF_TC_HEAD(exec_umask, tc)
460 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
461 "correctly reports an error if the umask is too "
462 "restrictive to create temporary files");
464 ATF_TC_BODY(exec_umask, tc)
466 atf_check_result_t result;
467 atf_fs_path_t process_helpers;
470 get_process_helpers_path(tc, false, &process_helpers);
471 argv[0] = atf_fs_path_cstring(&process_helpers);
472 argv[1] = "exit-success";
476 atf_error_t err = atf_check_exec_array(argv, &result);
477 ATF_CHECK(atf_is_error(err));
478 ATF_CHECK(atf_error_is(err, "invalid_umask"));
481 atf_fs_path_fini(&process_helpers);
484 ATF_TC(exec_unknown);
485 ATF_TC_HEAD(exec_unknown, tc)
487 atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
488 "binary is handled correctly");
490 ATF_TC_BODY(exec_unknown, tc)
493 argv[0] = "/foo/bar/non-existent";
496 atf_check_result_t result;
497 RE(atf_check_exec_array(argv, &result));
498 ATF_CHECK(atf_check_result_exited(&result));
499 ATF_CHECK(atf_check_result_exitcode(&result) == 127);
500 atf_check_result_fini(&result);
503 /* ---------------------------------------------------------------------
505 * --------------------------------------------------------------------- */
509 /* Add the test cases for the free functions. */
510 ATF_TP_ADD_TC(tp, build_c_o);
511 ATF_TP_ADD_TC(tp, build_cpp);
512 ATF_TP_ADD_TC(tp, build_cxx_o);
513 ATF_TP_ADD_TC(tp, exec_array);
514 ATF_TP_ADD_TC(tp, exec_cleanup);
515 ATF_TP_ADD_TC(tp, exec_exitstatus);
516 ATF_TP_ADD_TC(tp, exec_stdout_stderr);
517 ATF_TP_ADD_TC(tp, exec_umask);
518 ATF_TP_ADD_TC(tp, exec_unknown);
520 return atf_no_error();