2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include "atf-c/check.h"
40 #include "atf-c/config.h"
42 #include "detail/fs.h"
43 #include "detail/map.h"
44 #include "detail/process.h"
45 #include "detail/test_helpers.h"
47 /* ---------------------------------------------------------------------
48 * Auxiliary functions.
49 * --------------------------------------------------------------------- */
53 do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
55 atf_fs_path_t process_helpers;
58 get_process_helpers_path(tc, false, &process_helpers);
60 argv[0] = atf_fs_path_cstring(&process_helpers);
61 argv[1] = helper_name;
63 printf("Executing %s %s\n", argv[0], argv[1]);
64 RE(atf_check_exec_array(argv, r));
66 atf_fs_path_fini(&process_helpers);
71 do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
72 atf_check_result_t *r)
74 atf_fs_path_t process_helpers;
77 get_process_helpers_path(tc, false, &process_helpers);
79 argv[0] = atf_fs_path_cstring(&process_helpers);
80 argv[1] = helper_name;
83 printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
84 RE(atf_check_exec_array(argv, r));
86 atf_fs_path_fini(&process_helpers);
91 check_line(int fd, const char *exp)
95 atf_dynstr_init(&line);
96 ATF_CHECK(!read_line(fd, &line));
97 ATF_CHECK_MSG(atf_equal_dynstr_cstring(&line, exp),
98 "read: '%s', expected: '%s'",
99 atf_dynstr_cstring(&line), exp);
100 atf_dynstr_fini(&line);
103 /* ---------------------------------------------------------------------
104 * Helper test cases for the free functions.
105 * --------------------------------------------------------------------- */
107 ATF_TC(h_build_c_o_ok);
108 ATF_TC_HEAD(h_build_c_o_ok, tc)
110 atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
112 ATF_TC_BODY(h_build_c_o_ok, tc)
117 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
118 fprintf(sfile, "#include <stdio.h>\n");
121 RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
122 ATF_REQUIRE(success);
125 ATF_TC(h_build_c_o_fail);
126 ATF_TC_HEAD(h_build_c_o_fail, tc)
128 atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
130 ATF_TC_BODY(h_build_c_o_fail, tc)
135 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
136 fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
139 RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
140 ATF_REQUIRE(!success);
143 ATF_TC(h_build_cpp_ok);
144 ATF_TC_HEAD(h_build_cpp_ok, tc)
146 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
148 ATF_TC_BODY(h_build_cpp_ok, tc)
152 atf_fs_path_t test_p;
154 RE(atf_fs_path_init_fmt(&test_p, "test.p"));
156 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
157 fprintf(sfile, "#define A foo\n");
158 fprintf(sfile, "#define B bar\n");
159 fprintf(sfile, "A B\n");
162 RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
164 ATF_REQUIRE(success);
166 atf_fs_path_fini(&test_p);
169 ATF_TC(h_build_cpp_fail);
170 ATF_TC_HEAD(h_build_cpp_fail, tc)
172 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
174 ATF_TC_BODY(h_build_cpp_fail, tc)
179 ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
180 fprintf(sfile, "#include \"./non-existent.h\"\n");
183 RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
184 ATF_REQUIRE(!success);
187 ATF_TC(h_build_cxx_o_ok);
188 ATF_TC_HEAD(h_build_cxx_o_ok, tc)
190 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
192 ATF_TC_BODY(h_build_cxx_o_ok, tc)
197 ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
198 fprintf(sfile, "#include <iostream>\n");
201 RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
202 ATF_REQUIRE(success);
205 ATF_TC(h_build_cxx_o_fail);
206 ATF_TC_HEAD(h_build_cxx_o_fail, tc)
208 atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
210 ATF_TC_BODY(h_build_cxx_o_fail, tc)
215 ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
216 fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
219 RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
220 ATF_REQUIRE(!success);
223 /* ---------------------------------------------------------------------
224 * Test cases for the free functions.
225 * --------------------------------------------------------------------- */
229 init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
230 const char *outname, const char *errname)
232 const char *const config[] = { NULL };
234 RE(atf_tc_init_pack(tc, tcpack, config));
235 run_h_tc(tc, outname, errname, "result");
240 ATF_TC_HEAD(build_c_o, tc)
242 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
245 ATF_TC_BODY(build_c_o, tc)
247 init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
248 &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
249 ATF_CHECK(grep_file("stdout", "-o test.o"));
250 ATF_CHECK(grep_file("stdout", "-c test.c"));
252 init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
253 &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
254 ATF_CHECK(grep_file("stdout", "-o test.o"));
255 ATF_CHECK(grep_file("stdout", "-c test.c"));
256 ATF_CHECK(grep_file("stderr", "test.c"));
257 ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
261 ATF_TC_HEAD(build_cpp, tc)
263 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
266 ATF_TC_BODY(build_cpp, tc)
268 init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
269 &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
270 ATF_CHECK(grep_file("stdout", "-o.*test.p"));
271 ATF_CHECK(grep_file("stdout", "test.c"));
272 ATF_CHECK(grep_file("test.p", "foo bar"));
274 init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
275 &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
276 ATF_CHECK(grep_file("stdout", "-o test.p"));
277 ATF_CHECK(grep_file("stdout", "test.c"));
278 ATF_CHECK(grep_file("stderr", "test.c"));
279 ATF_CHECK(grep_file("stderr", "non-existent.h"));
283 ATF_TC_HEAD(build_cxx_o, tc)
285 atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
288 ATF_TC_BODY(build_cxx_o, tc)
290 init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
291 &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
292 ATF_CHECK(grep_file("stdout", "-o test.o"));
293 ATF_CHECK(grep_file("stdout", "-c test.cpp"));
295 init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
296 &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
297 ATF_CHECK(grep_file("stdout", "-o test.o"));
298 ATF_CHECK(grep_file("stdout", "-c test.cpp"));
299 ATF_CHECK(grep_file("stderr", "test.cpp"));
300 ATF_CHECK(grep_file("stderr", "UNDEFINED_SYMBOL"));
304 ATF_TC_HEAD(exec_array, tc)
306 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
309 ATF_TC_BODY(exec_array, tc)
311 atf_fs_path_t process_helpers;
312 atf_check_result_t result;
314 get_process_helpers_path(tc, false, &process_helpers);
317 argv[0] = atf_fs_path_cstring(&process_helpers);
319 argv[2] = "test-message";
322 RE(atf_check_exec_array(argv, &result));
324 ATF_CHECK(atf_check_result_exited(&result));
325 ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
328 const char *path = atf_check_result_stdout(&result);
329 int fd = open(path, O_RDONLY);
331 check_line(fd, "test-message");
335 atf_check_result_fini(&result);
336 atf_fs_path_fini(&process_helpers);
339 ATF_TC(exec_cleanup);
340 ATF_TC_HEAD(exec_cleanup, tc)
342 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
343 "properly cleans up the temporary files it creates");
345 ATF_TC_BODY(exec_cleanup, tc)
347 atf_fs_path_t out, err;
348 atf_check_result_t result;
351 do_exec(tc, "exit-success", &result);
352 RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
353 RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
355 RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
356 RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
357 atf_check_result_fini(&result);
358 RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
359 RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
361 atf_fs_path_fini(&err);
362 atf_fs_path_fini(&out);
365 ATF_TC(exec_exitstatus);
366 ATF_TC_HEAD(exec_exitstatus, tc)
368 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
369 "properly captures the exit status of the executed "
372 ATF_TC_BODY(exec_exitstatus, tc)
375 atf_check_result_t result;
376 do_exec(tc, "exit-success", &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_SUCCESS);
380 atf_check_result_fini(&result);
384 atf_check_result_t result;
385 do_exec(tc, "exit-failure", &result);
386 ATF_CHECK(atf_check_result_exited(&result));
387 ATF_CHECK(!atf_check_result_signaled(&result));
388 ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
389 atf_check_result_fini(&result);
393 atf_check_result_t result;
394 do_exec(tc, "exit-signal", &result);
395 ATF_CHECK(!atf_check_result_exited(&result));
396 ATF_CHECK(atf_check_result_signaled(&result));
397 ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
398 atf_check_result_fini(&result);
402 ATF_TC(exec_stdout_stderr);
403 ATF_TC_HEAD(exec_stdout_stderr, tc)
405 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
406 "properly captures the stdout and stderr streams "
407 "of the child process");
409 ATF_TC_BODY(exec_stdout_stderr, tc)
411 atf_check_result_t result1, result2;
412 const char *out1, *out2;
413 const char *err1, *err2;
415 do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
416 ATF_CHECK(atf_check_result_exited(&result1));
417 ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
419 do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
420 ATF_CHECK(atf_check_result_exited(&result2));
421 ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
423 out1 = atf_check_result_stdout(&result1);
424 out2 = atf_check_result_stdout(&result2);
425 err1 = atf_check_result_stderr(&result1);
426 err2 = atf_check_result_stderr(&result2);
428 ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
429 ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
430 ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
431 ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
433 ATF_CHECK(strstr(out1, "/check") != NULL);
434 ATF_CHECK(strstr(out2, "/check") != NULL);
435 ATF_CHECK(strstr(err1, "/check") != NULL);
436 ATF_CHECK(strstr(err2, "/check") != NULL);
438 ATF_CHECK(strstr(out1, "/stdout") != NULL);
439 ATF_CHECK(strstr(out2, "/stdout") != NULL);
440 ATF_CHECK(strstr(err1, "/stderr") != NULL);
441 ATF_CHECK(strstr(err2, "/stderr") != NULL);
443 ATF_CHECK(strcmp(out1, out2) != 0);
444 ATF_CHECK(strcmp(err1, err2) != 0);
446 #define CHECK_LINES(path, outname, resname) \
448 int fd = open(path, O_RDONLY); \
449 ATF_CHECK(fd != -1); \
450 check_line(fd, "Line 1 to " outname " for " resname); \
451 check_line(fd, "Line 2 to " outname " for " resname); \
455 CHECK_LINES(out1, "stdout", "result1");
456 CHECK_LINES(out2, "stdout", "result2");
457 CHECK_LINES(err1, "stderr", "result1");
458 CHECK_LINES(err2, "stderr", "result2");
462 atf_check_result_fini(&result2);
463 atf_check_result_fini(&result1);
467 ATF_TC_HEAD(exec_umask, tc)
469 atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
470 "correctly reports an error if the umask is too "
471 "restrictive to create temporary files");
473 ATF_TC_BODY(exec_umask, tc)
475 atf_check_result_t result;
476 atf_fs_path_t process_helpers;
479 get_process_helpers_path(tc, false, &process_helpers);
480 argv[0] = atf_fs_path_cstring(&process_helpers);
481 argv[1] = "exit-success";
485 atf_error_t err = atf_check_exec_array(argv, &result);
486 ATF_CHECK(atf_is_error(err));
487 ATF_CHECK(atf_error_is(err, "invalid_umask"));
490 atf_fs_path_fini(&process_helpers);
493 ATF_TC(exec_unknown);
494 ATF_TC_HEAD(exec_unknown, tc)
496 atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
497 "binary is handled correctly");
499 ATF_TC_BODY(exec_unknown, tc)
502 snprintf(buf, sizeof(buf), "%s/non-existent",
503 atf_config_get("atf_workdir"));
509 atf_check_result_t result;
510 RE(atf_check_exec_array(argv, &result));
511 ATF_CHECK(atf_check_result_exited(&result));
512 ATF_CHECK(atf_check_result_exitcode(&result) == 127);
513 atf_check_result_fini(&result);
516 /* ---------------------------------------------------------------------
517 * Tests cases for the header file.
518 * --------------------------------------------------------------------- */
520 HEADER_TC(include, "atf-c/check.h");
522 /* ---------------------------------------------------------------------
524 * --------------------------------------------------------------------- */
528 /* Add the test cases for the free functions. */
529 ATF_TP_ADD_TC(tp, build_c_o);
530 ATF_TP_ADD_TC(tp, build_cpp);
531 ATF_TP_ADD_TC(tp, build_cxx_o);
532 ATF_TP_ADD_TC(tp, exec_array);
533 ATF_TP_ADD_TC(tp, exec_cleanup);
534 ATF_TP_ADD_TC(tp, exec_exitstatus);
535 ATF_TP_ADD_TC(tp, exec_stdout_stderr);
536 ATF_TP_ADD_TC(tp, exec_umask);
537 ATF_TP_ADD_TC(tp, exec_unknown);
539 /* Add the test cases for the header file. */
540 ATF_TP_ADD_TC(tp, include);
542 return atf_no_error();