xref: /netbsd-src/external/bsd/atf/dist/atf-c/check_test.c (revision 0659fc670c1f32aa49ff1d817af283a035107f2d)
1edebbb8eSjmmv /*
2edebbb8eSjmmv  * Automated Testing Framework (atf)
3edebbb8eSjmmv  *
4a551a20fSjmmv  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5edebbb8eSjmmv  * All rights reserved.
6edebbb8eSjmmv  *
7edebbb8eSjmmv  * Redistribution and use in source and binary forms, with or without
8edebbb8eSjmmv  * modification, are permitted provided that the following conditions
9edebbb8eSjmmv  * are met:
10edebbb8eSjmmv  * 1. Redistributions of source code must retain the above copyright
11edebbb8eSjmmv  *    notice, this list of conditions and the following disclaimer.
12edebbb8eSjmmv  * 2. Redistributions in binary form must reproduce the above copyright
13edebbb8eSjmmv  *    notice, this list of conditions and the following disclaimer in the
14edebbb8eSjmmv  *    documentation and/or other materials provided with the distribution.
15edebbb8eSjmmv  *
16edebbb8eSjmmv  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17edebbb8eSjmmv  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18edebbb8eSjmmv  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19edebbb8eSjmmv  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20edebbb8eSjmmv  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21edebbb8eSjmmv  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22edebbb8eSjmmv  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23edebbb8eSjmmv  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24edebbb8eSjmmv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25edebbb8eSjmmv  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26edebbb8eSjmmv  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27edebbb8eSjmmv  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28edebbb8eSjmmv  */
29edebbb8eSjmmv 
30edebbb8eSjmmv #include <fcntl.h>
31edebbb8eSjmmv #include <signal.h>
32edebbb8eSjmmv #include <stdio.h>
33edebbb8eSjmmv #include <stdlib.h>
34edebbb8eSjmmv #include <string.h>
35edebbb8eSjmmv #include <unistd.h>
36edebbb8eSjmmv 
37edebbb8eSjmmv #include <atf-c.h>
38edebbb8eSjmmv 
39edebbb8eSjmmv #include "atf-c/check.h"
40edebbb8eSjmmv #include "atf-c/config.h"
41edebbb8eSjmmv 
42895f502bSjmmv #include "detail/fs.h"
43895f502bSjmmv #include "detail/map.h"
44895f502bSjmmv #include "detail/process.h"
45895f502bSjmmv #include "detail/test_helpers.h"
46edebbb8eSjmmv 
47edebbb8eSjmmv /* ---------------------------------------------------------------------
48edebbb8eSjmmv  * Auxiliary functions.
49edebbb8eSjmmv  * --------------------------------------------------------------------- */
50edebbb8eSjmmv 
51edebbb8eSjmmv static
52edebbb8eSjmmv void
do_exec(const atf_tc_t * tc,const char * helper_name,atf_check_result_t * r)53edebbb8eSjmmv do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
54edebbb8eSjmmv {
55edebbb8eSjmmv     atf_fs_path_t process_helpers;
56edebbb8eSjmmv     const char *argv[3];
57edebbb8eSjmmv 
58895f502bSjmmv     get_process_helpers_path(tc, false, &process_helpers);
59edebbb8eSjmmv 
60edebbb8eSjmmv     argv[0] = atf_fs_path_cstring(&process_helpers);
61edebbb8eSjmmv     argv[1] = helper_name;
62edebbb8eSjmmv     argv[2] = NULL;
63edebbb8eSjmmv     printf("Executing %s %s\n", argv[0], argv[1]);
64edebbb8eSjmmv     RE(atf_check_exec_array(argv, r));
65edebbb8eSjmmv 
66edebbb8eSjmmv     atf_fs_path_fini(&process_helpers);
67edebbb8eSjmmv }
68edebbb8eSjmmv 
69edebbb8eSjmmv static
70edebbb8eSjmmv void
do_exec_with_arg(const atf_tc_t * tc,const char * helper_name,const char * arg,atf_check_result_t * r)71edebbb8eSjmmv do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
72edebbb8eSjmmv                  atf_check_result_t *r)
73edebbb8eSjmmv {
74edebbb8eSjmmv     atf_fs_path_t process_helpers;
75edebbb8eSjmmv     const char *argv[4];
76edebbb8eSjmmv 
77895f502bSjmmv     get_process_helpers_path(tc, false, &process_helpers);
78edebbb8eSjmmv 
79edebbb8eSjmmv     argv[0] = atf_fs_path_cstring(&process_helpers);
80edebbb8eSjmmv     argv[1] = helper_name;
81edebbb8eSjmmv     argv[2] = arg;
82edebbb8eSjmmv     argv[3] = NULL;
83edebbb8eSjmmv     printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
84edebbb8eSjmmv     RE(atf_check_exec_array(argv, r));
85edebbb8eSjmmv 
86edebbb8eSjmmv     atf_fs_path_fini(&process_helpers);
87edebbb8eSjmmv }
88edebbb8eSjmmv 
89edebbb8eSjmmv static
90edebbb8eSjmmv void
check_line(int fd,const char * exp)91edebbb8eSjmmv check_line(int fd, const char *exp)
92edebbb8eSjmmv {
93*0659fc67Sjmmv     char *line = atf_utils_readline(fd);
94*0659fc67Sjmmv     ATF_CHECK(line != NULL);
95*0659fc67Sjmmv     ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
96*0659fc67Sjmmv     free(line);
97edebbb8eSjmmv }
98edebbb8eSjmmv 
99edebbb8eSjmmv /* ---------------------------------------------------------------------
100edebbb8eSjmmv  * Helper test cases for the free functions.
101edebbb8eSjmmv  * --------------------------------------------------------------------- */
102edebbb8eSjmmv 
103edebbb8eSjmmv ATF_TC(h_build_c_o_ok);
ATF_TC_HEAD(h_build_c_o_ok,tc)104edebbb8eSjmmv ATF_TC_HEAD(h_build_c_o_ok, tc)
105edebbb8eSjmmv {
106edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
107edebbb8eSjmmv }
ATF_TC_BODY(h_build_c_o_ok,tc)108edebbb8eSjmmv ATF_TC_BODY(h_build_c_o_ok, tc)
109edebbb8eSjmmv {
110edebbb8eSjmmv     FILE *sfile;
111edebbb8eSjmmv     bool success;
112edebbb8eSjmmv 
113edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
114edebbb8eSjmmv     fprintf(sfile, "#include <stdio.h>\n");
115edebbb8eSjmmv     fclose(sfile);
116edebbb8eSjmmv 
117edebbb8eSjmmv     RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
118edebbb8eSjmmv     ATF_REQUIRE(success);
119edebbb8eSjmmv }
120edebbb8eSjmmv 
121edebbb8eSjmmv ATF_TC(h_build_c_o_fail);
ATF_TC_HEAD(h_build_c_o_fail,tc)122edebbb8eSjmmv ATF_TC_HEAD(h_build_c_o_fail, tc)
123edebbb8eSjmmv {
124edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
125edebbb8eSjmmv }
ATF_TC_BODY(h_build_c_o_fail,tc)126edebbb8eSjmmv ATF_TC_BODY(h_build_c_o_fail, tc)
127edebbb8eSjmmv {
128edebbb8eSjmmv     FILE *sfile;
129edebbb8eSjmmv     bool success;
130edebbb8eSjmmv 
131edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
132edebbb8eSjmmv     fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
133edebbb8eSjmmv     fclose(sfile);
134edebbb8eSjmmv 
135edebbb8eSjmmv     RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
136edebbb8eSjmmv     ATF_REQUIRE(!success);
137edebbb8eSjmmv }
138edebbb8eSjmmv 
139edebbb8eSjmmv ATF_TC(h_build_cpp_ok);
ATF_TC_HEAD(h_build_cpp_ok,tc)140edebbb8eSjmmv ATF_TC_HEAD(h_build_cpp_ok, tc)
141edebbb8eSjmmv {
142edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
143edebbb8eSjmmv }
ATF_TC_BODY(h_build_cpp_ok,tc)144edebbb8eSjmmv ATF_TC_BODY(h_build_cpp_ok, tc)
145edebbb8eSjmmv {
146edebbb8eSjmmv     FILE *sfile;
147edebbb8eSjmmv     bool success;
148edebbb8eSjmmv     atf_fs_path_t test_p;
149edebbb8eSjmmv 
150edebbb8eSjmmv     RE(atf_fs_path_init_fmt(&test_p, "test.p"));
151edebbb8eSjmmv 
152edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
153edebbb8eSjmmv     fprintf(sfile, "#define A foo\n");
154edebbb8eSjmmv     fprintf(sfile, "#define B bar\n");
155edebbb8eSjmmv     fprintf(sfile, "A B\n");
156edebbb8eSjmmv     fclose(sfile);
157edebbb8eSjmmv 
158edebbb8eSjmmv     RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
159edebbb8eSjmmv                            &success));
160edebbb8eSjmmv     ATF_REQUIRE(success);
161edebbb8eSjmmv 
162edebbb8eSjmmv     atf_fs_path_fini(&test_p);
163edebbb8eSjmmv }
164edebbb8eSjmmv 
165edebbb8eSjmmv ATF_TC(h_build_cpp_fail);
ATF_TC_HEAD(h_build_cpp_fail,tc)166edebbb8eSjmmv ATF_TC_HEAD(h_build_cpp_fail, tc)
167edebbb8eSjmmv {
168edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
169edebbb8eSjmmv }
ATF_TC_BODY(h_build_cpp_fail,tc)170edebbb8eSjmmv ATF_TC_BODY(h_build_cpp_fail, tc)
171edebbb8eSjmmv {
172edebbb8eSjmmv     FILE *sfile;
173edebbb8eSjmmv     bool success;
174edebbb8eSjmmv 
175edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
176edebbb8eSjmmv     fprintf(sfile, "#include \"./non-existent.h\"\n");
177edebbb8eSjmmv     fclose(sfile);
178edebbb8eSjmmv 
179edebbb8eSjmmv     RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
180edebbb8eSjmmv     ATF_REQUIRE(!success);
181edebbb8eSjmmv }
182edebbb8eSjmmv 
183edebbb8eSjmmv ATF_TC(h_build_cxx_o_ok);
ATF_TC_HEAD(h_build_cxx_o_ok,tc)184edebbb8eSjmmv ATF_TC_HEAD(h_build_cxx_o_ok, tc)
185edebbb8eSjmmv {
186edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
187edebbb8eSjmmv }
ATF_TC_BODY(h_build_cxx_o_ok,tc)188edebbb8eSjmmv ATF_TC_BODY(h_build_cxx_o_ok, tc)
189edebbb8eSjmmv {
190edebbb8eSjmmv     FILE *sfile;
191edebbb8eSjmmv     bool success;
192edebbb8eSjmmv 
193edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
194edebbb8eSjmmv     fprintf(sfile, "#include <iostream>\n");
195edebbb8eSjmmv     fclose(sfile);
196edebbb8eSjmmv 
197edebbb8eSjmmv     RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
198edebbb8eSjmmv     ATF_REQUIRE(success);
199edebbb8eSjmmv }
200edebbb8eSjmmv 
201edebbb8eSjmmv ATF_TC(h_build_cxx_o_fail);
ATF_TC_HEAD(h_build_cxx_o_fail,tc)202edebbb8eSjmmv ATF_TC_HEAD(h_build_cxx_o_fail, tc)
203edebbb8eSjmmv {
204edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
205edebbb8eSjmmv }
ATF_TC_BODY(h_build_cxx_o_fail,tc)206edebbb8eSjmmv ATF_TC_BODY(h_build_cxx_o_fail, tc)
207edebbb8eSjmmv {
208edebbb8eSjmmv     FILE *sfile;
209edebbb8eSjmmv     bool success;
210edebbb8eSjmmv 
211edebbb8eSjmmv     ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
212edebbb8eSjmmv     fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
213edebbb8eSjmmv     fclose(sfile);
214edebbb8eSjmmv 
215edebbb8eSjmmv     RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
216edebbb8eSjmmv     ATF_REQUIRE(!success);
217edebbb8eSjmmv }
218edebbb8eSjmmv 
219edebbb8eSjmmv /* ---------------------------------------------------------------------
220edebbb8eSjmmv  * Test cases for the free functions.
221edebbb8eSjmmv  * --------------------------------------------------------------------- */
222edebbb8eSjmmv 
223edebbb8eSjmmv static
224edebbb8eSjmmv void
init_and_run_h_tc(atf_tc_t * tc,const atf_tc_pack_t * tcpack,const char * outname,const char * errname)225edebbb8eSjmmv init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
226edebbb8eSjmmv                   const char *outname, const char *errname)
227edebbb8eSjmmv {
228895f502bSjmmv     const char *const config[] = { NULL };
229edebbb8eSjmmv 
230895f502bSjmmv     RE(atf_tc_init_pack(tc, tcpack, config));
231edebbb8eSjmmv     run_h_tc(tc, outname, errname, "result");
232edebbb8eSjmmv     atf_tc_fini(tc);
233edebbb8eSjmmv }
234edebbb8eSjmmv 
235edebbb8eSjmmv ATF_TC(build_c_o);
ATF_TC_HEAD(build_c_o,tc)236edebbb8eSjmmv ATF_TC_HEAD(build_c_o, tc)
237edebbb8eSjmmv {
238edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
239edebbb8eSjmmv                       "function");
240edebbb8eSjmmv }
ATF_TC_BODY(build_c_o,tc)241edebbb8eSjmmv ATF_TC_BODY(build_c_o, tc)
242edebbb8eSjmmv {
243edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
244edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
245*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
246*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
247edebbb8eSjmmv 
248edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
249edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
250*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
251*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
252*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
253*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
254edebbb8eSjmmv }
255edebbb8eSjmmv 
256edebbb8eSjmmv ATF_TC(build_cpp);
ATF_TC_HEAD(build_cpp,tc)257edebbb8eSjmmv ATF_TC_HEAD(build_cpp, tc)
258edebbb8eSjmmv {
259edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
260edebbb8eSjmmv                       "function");
261edebbb8eSjmmv }
ATF_TC_BODY(build_cpp,tc)262edebbb8eSjmmv ATF_TC_BODY(build_cpp, tc)
263edebbb8eSjmmv {
264edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
265edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
266*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o.*test.p", "stdout"));
267*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
268*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("foo bar", "test.p"));
269edebbb8eSjmmv 
270edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
271edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
272*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o test.p", "stdout"));
273*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
274*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
275*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("non-existent.h", "stderr"));
276edebbb8eSjmmv }
277edebbb8eSjmmv 
278edebbb8eSjmmv ATF_TC(build_cxx_o);
ATF_TC_HEAD(build_cxx_o,tc)279edebbb8eSjmmv ATF_TC_HEAD(build_cxx_o, tc)
280edebbb8eSjmmv {
281edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
282edebbb8eSjmmv                       "function");
283edebbb8eSjmmv }
ATF_TC_BODY(build_cxx_o,tc)284edebbb8eSjmmv ATF_TC_BODY(build_cxx_o, tc)
285edebbb8eSjmmv {
286edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
287edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
288*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
289*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
290edebbb8eSjmmv 
291edebbb8eSjmmv     init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
292edebbb8eSjmmv              &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
293*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
294*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
295*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("test.cpp", "stderr"));
296*0659fc67Sjmmv     ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
297edebbb8eSjmmv }
298edebbb8eSjmmv 
299895f502bSjmmv ATF_TC(exec_array);
ATF_TC_HEAD(exec_array,tc)300895f502bSjmmv ATF_TC_HEAD(exec_array, tc)
301edebbb8eSjmmv {
302edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
303895f502bSjmmv                       "works properly");
304edebbb8eSjmmv }
ATF_TC_BODY(exec_array,tc)305895f502bSjmmv ATF_TC_BODY(exec_array, tc)
306edebbb8eSjmmv {
307edebbb8eSjmmv     atf_fs_path_t process_helpers;
308edebbb8eSjmmv     atf_check_result_t result;
309edebbb8eSjmmv 
310895f502bSjmmv     get_process_helpers_path(tc, false, &process_helpers);
311edebbb8eSjmmv 
312895f502bSjmmv     const char *argv[4];
313895f502bSjmmv     argv[0] = atf_fs_path_cstring(&process_helpers);
314895f502bSjmmv     argv[1] = "echo";
315895f502bSjmmv     argv[2] = "test-message";
316895f502bSjmmv     argv[3] = NULL;
317895f502bSjmmv 
318895f502bSjmmv     RE(atf_check_exec_array(argv, &result));
319895f502bSjmmv 
320895f502bSjmmv     ATF_CHECK(atf_check_result_exited(&result));
321895f502bSjmmv     ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
322895f502bSjmmv 
323895f502bSjmmv     {
324895f502bSjmmv         const char *path = atf_check_result_stdout(&result);
325895f502bSjmmv         int fd = open(path, O_RDONLY);
326895f502bSjmmv         ATF_CHECK(fd != -1);
327895f502bSjmmv         check_line(fd, "test-message");
328895f502bSjmmv         close(fd);
329895f502bSjmmv     }
330edebbb8eSjmmv 
331edebbb8eSjmmv     atf_check_result_fini(&result);
332edebbb8eSjmmv     atf_fs_path_fini(&process_helpers);
333edebbb8eSjmmv }
334edebbb8eSjmmv 
335edebbb8eSjmmv ATF_TC(exec_cleanup);
ATF_TC_HEAD(exec_cleanup,tc)336edebbb8eSjmmv ATF_TC_HEAD(exec_cleanup, tc)
337edebbb8eSjmmv {
338edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
339edebbb8eSjmmv                       "properly cleans up the temporary files it creates");
340edebbb8eSjmmv }
ATF_TC_BODY(exec_cleanup,tc)341edebbb8eSjmmv ATF_TC_BODY(exec_cleanup, tc)
342edebbb8eSjmmv {
343edebbb8eSjmmv     atf_fs_path_t out, err;
344edebbb8eSjmmv     atf_check_result_t result;
345edebbb8eSjmmv     bool exists;
346edebbb8eSjmmv 
347edebbb8eSjmmv     do_exec(tc, "exit-success", &result);
348895f502bSjmmv     RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
349895f502bSjmmv     RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
350edebbb8eSjmmv 
351edebbb8eSjmmv     RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
352edebbb8eSjmmv     RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
353edebbb8eSjmmv     atf_check_result_fini(&result);
354edebbb8eSjmmv     RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
355edebbb8eSjmmv     RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
356edebbb8eSjmmv 
357edebbb8eSjmmv     atf_fs_path_fini(&err);
358edebbb8eSjmmv     atf_fs_path_fini(&out);
359edebbb8eSjmmv }
360edebbb8eSjmmv 
361edebbb8eSjmmv ATF_TC(exec_exitstatus);
ATF_TC_HEAD(exec_exitstatus,tc)362edebbb8eSjmmv ATF_TC_HEAD(exec_exitstatus, tc)
363edebbb8eSjmmv {
364edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
365edebbb8eSjmmv                       "properly captures the exit status of the executed "
366edebbb8eSjmmv                       "command");
367edebbb8eSjmmv }
ATF_TC_BODY(exec_exitstatus,tc)368edebbb8eSjmmv ATF_TC_BODY(exec_exitstatus, tc)
369edebbb8eSjmmv {
370edebbb8eSjmmv     {
371edebbb8eSjmmv         atf_check_result_t result;
372edebbb8eSjmmv         do_exec(tc, "exit-success", &result);
373edebbb8eSjmmv         ATF_CHECK(atf_check_result_exited(&result));
374edebbb8eSjmmv         ATF_CHECK(!atf_check_result_signaled(&result));
375edebbb8eSjmmv         ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
376edebbb8eSjmmv         atf_check_result_fini(&result);
377edebbb8eSjmmv     }
378edebbb8eSjmmv 
379edebbb8eSjmmv     {
380edebbb8eSjmmv         atf_check_result_t result;
381edebbb8eSjmmv         do_exec(tc, "exit-failure", &result);
382edebbb8eSjmmv         ATF_CHECK(atf_check_result_exited(&result));
383edebbb8eSjmmv         ATF_CHECK(!atf_check_result_signaled(&result));
384edebbb8eSjmmv         ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
385edebbb8eSjmmv         atf_check_result_fini(&result);
386edebbb8eSjmmv     }
387edebbb8eSjmmv 
388edebbb8eSjmmv     {
389edebbb8eSjmmv         atf_check_result_t result;
390edebbb8eSjmmv         do_exec(tc, "exit-signal", &result);
391edebbb8eSjmmv         ATF_CHECK(!atf_check_result_exited(&result));
392edebbb8eSjmmv         ATF_CHECK(atf_check_result_signaled(&result));
393edebbb8eSjmmv         ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
394edebbb8eSjmmv         atf_check_result_fini(&result);
395edebbb8eSjmmv     }
396edebbb8eSjmmv }
397edebbb8eSjmmv 
398edebbb8eSjmmv ATF_TC(exec_stdout_stderr);
ATF_TC_HEAD(exec_stdout_stderr,tc)399edebbb8eSjmmv ATF_TC_HEAD(exec_stdout_stderr, tc)
400edebbb8eSjmmv {
401edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
402edebbb8eSjmmv                       "properly captures the stdout and stderr streams "
403edebbb8eSjmmv                       "of the child process");
404edebbb8eSjmmv }
ATF_TC_BODY(exec_stdout_stderr,tc)405edebbb8eSjmmv ATF_TC_BODY(exec_stdout_stderr, tc)
406edebbb8eSjmmv {
407edebbb8eSjmmv     atf_check_result_t result1, result2;
408895f502bSjmmv     const char *out1, *out2;
409895f502bSjmmv     const char *err1, *err2;
410edebbb8eSjmmv 
411edebbb8eSjmmv     do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
412edebbb8eSjmmv     ATF_CHECK(atf_check_result_exited(&result1));
413edebbb8eSjmmv     ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
414edebbb8eSjmmv 
415edebbb8eSjmmv     do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
416edebbb8eSjmmv     ATF_CHECK(atf_check_result_exited(&result2));
417edebbb8eSjmmv     ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
418edebbb8eSjmmv 
419edebbb8eSjmmv     out1 = atf_check_result_stdout(&result1);
420edebbb8eSjmmv     out2 = atf_check_result_stdout(&result2);
421edebbb8eSjmmv     err1 = atf_check_result_stderr(&result1);
422edebbb8eSjmmv     err2 = atf_check_result_stderr(&result2);
423edebbb8eSjmmv 
424895f502bSjmmv     ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
425895f502bSjmmv     ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
426895f502bSjmmv     ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
427895f502bSjmmv     ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
428edebbb8eSjmmv 
429895f502bSjmmv     ATF_CHECK(strstr(out1, "/check") != NULL);
430895f502bSjmmv     ATF_CHECK(strstr(out2, "/check") != NULL);
431895f502bSjmmv     ATF_CHECK(strstr(err1, "/check") != NULL);
432895f502bSjmmv     ATF_CHECK(strstr(err2, "/check") != NULL);
433edebbb8eSjmmv 
434895f502bSjmmv     ATF_CHECK(strstr(out1, "/stdout") != NULL);
435895f502bSjmmv     ATF_CHECK(strstr(out2, "/stdout") != NULL);
436895f502bSjmmv     ATF_CHECK(strstr(err1, "/stderr") != NULL);
437895f502bSjmmv     ATF_CHECK(strstr(err2, "/stderr") != NULL);
438edebbb8eSjmmv 
439895f502bSjmmv     ATF_CHECK(strcmp(out1, out2) != 0);
440895f502bSjmmv     ATF_CHECK(strcmp(err1, err2) != 0);
441edebbb8eSjmmv 
442edebbb8eSjmmv #define CHECK_LINES(path, outname, resname) \
443edebbb8eSjmmv     do { \
444895f502bSjmmv         int fd = open(path, O_RDONLY); \
445edebbb8eSjmmv         ATF_CHECK(fd != -1); \
446edebbb8eSjmmv         check_line(fd, "Line 1 to " outname " for " resname); \
447edebbb8eSjmmv         check_line(fd, "Line 2 to " outname " for " resname); \
448edebbb8eSjmmv         close(fd); \
449edebbb8eSjmmv     } while (false)
450edebbb8eSjmmv 
451edebbb8eSjmmv     CHECK_LINES(out1, "stdout", "result1");
452edebbb8eSjmmv     CHECK_LINES(out2, "stdout", "result2");
453edebbb8eSjmmv     CHECK_LINES(err1, "stderr", "result1");
454edebbb8eSjmmv     CHECK_LINES(err2, "stderr", "result2");
455edebbb8eSjmmv 
456edebbb8eSjmmv #undef CHECK_LINES
457edebbb8eSjmmv 
458edebbb8eSjmmv     atf_check_result_fini(&result2);
459edebbb8eSjmmv     atf_check_result_fini(&result1);
460edebbb8eSjmmv }
461edebbb8eSjmmv 
462edebbb8eSjmmv ATF_TC(exec_umask);
ATF_TC_HEAD(exec_umask,tc)463edebbb8eSjmmv ATF_TC_HEAD(exec_umask, tc)
464edebbb8eSjmmv {
465edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
466edebbb8eSjmmv                       "correctly reports an error if the umask is too "
467edebbb8eSjmmv                       "restrictive to create temporary files");
468edebbb8eSjmmv }
ATF_TC_BODY(exec_umask,tc)469edebbb8eSjmmv ATF_TC_BODY(exec_umask, tc)
470edebbb8eSjmmv {
471edebbb8eSjmmv     atf_check_result_t result;
472edebbb8eSjmmv     atf_fs_path_t process_helpers;
473edebbb8eSjmmv     const char *argv[3];
474edebbb8eSjmmv 
475895f502bSjmmv     get_process_helpers_path(tc, false, &process_helpers);
476edebbb8eSjmmv     argv[0] = atf_fs_path_cstring(&process_helpers);
477edebbb8eSjmmv     argv[1] = "exit-success";
478edebbb8eSjmmv     argv[2] = NULL;
479edebbb8eSjmmv 
480edebbb8eSjmmv     umask(0222);
481edebbb8eSjmmv     atf_error_t err = atf_check_exec_array(argv, &result);
482edebbb8eSjmmv     ATF_CHECK(atf_is_error(err));
483edebbb8eSjmmv     ATF_CHECK(atf_error_is(err, "invalid_umask"));
484edebbb8eSjmmv     atf_error_free(err);
485edebbb8eSjmmv 
486edebbb8eSjmmv     atf_fs_path_fini(&process_helpers);
487edebbb8eSjmmv }
488edebbb8eSjmmv 
489edebbb8eSjmmv ATF_TC(exec_unknown);
ATF_TC_HEAD(exec_unknown,tc)490edebbb8eSjmmv ATF_TC_HEAD(exec_unknown, tc)
491edebbb8eSjmmv {
492edebbb8eSjmmv     atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
493edebbb8eSjmmv                       "binary is handled correctly");
494edebbb8eSjmmv }
ATF_TC_BODY(exec_unknown,tc)495edebbb8eSjmmv ATF_TC_BODY(exec_unknown, tc)
496edebbb8eSjmmv {
497edebbb8eSjmmv     char buf[1024];
498edebbb8eSjmmv     snprintf(buf, sizeof(buf), "%s/non-existent",
499edebbb8eSjmmv              atf_config_get("atf_workdir"));
500edebbb8eSjmmv 
501edebbb8eSjmmv     const char *argv[2];
502edebbb8eSjmmv     argv[0] = buf;
503edebbb8eSjmmv     argv[1] = NULL;
504edebbb8eSjmmv 
505edebbb8eSjmmv     atf_check_result_t result;
506edebbb8eSjmmv     RE(atf_check_exec_array(argv, &result));
507edebbb8eSjmmv     ATF_CHECK(atf_check_result_exited(&result));
508edebbb8eSjmmv     ATF_CHECK(atf_check_result_exitcode(&result) == 127);
509edebbb8eSjmmv     atf_check_result_fini(&result);
510edebbb8eSjmmv }
511edebbb8eSjmmv 
512edebbb8eSjmmv /* ---------------------------------------------------------------------
513edebbb8eSjmmv  * Tests cases for the header file.
514edebbb8eSjmmv  * --------------------------------------------------------------------- */
515edebbb8eSjmmv 
516edebbb8eSjmmv HEADER_TC(include, "atf-c/check.h");
517edebbb8eSjmmv 
518edebbb8eSjmmv /* ---------------------------------------------------------------------
519edebbb8eSjmmv  * Main.
520edebbb8eSjmmv  * --------------------------------------------------------------------- */
521edebbb8eSjmmv 
ATF_TP_ADD_TCS(tp)522edebbb8eSjmmv ATF_TP_ADD_TCS(tp)
523edebbb8eSjmmv {
524edebbb8eSjmmv     /* Add the test cases for the free functions. */
525edebbb8eSjmmv     ATF_TP_ADD_TC(tp, build_c_o);
526edebbb8eSjmmv     ATF_TP_ADD_TC(tp, build_cpp);
527edebbb8eSjmmv     ATF_TP_ADD_TC(tp, build_cxx_o);
528895f502bSjmmv     ATF_TP_ADD_TC(tp, exec_array);
529edebbb8eSjmmv     ATF_TP_ADD_TC(tp, exec_cleanup);
530edebbb8eSjmmv     ATF_TP_ADD_TC(tp, exec_exitstatus);
531edebbb8eSjmmv     ATF_TP_ADD_TC(tp, exec_stdout_stderr);
532edebbb8eSjmmv     ATF_TP_ADD_TC(tp, exec_umask);
533edebbb8eSjmmv     ATF_TP_ADD_TC(tp, exec_unknown);
534edebbb8eSjmmv 
535edebbb8eSjmmv     /* Add the test cases for the header file. */
536edebbb8eSjmmv     ATF_TP_ADD_TC(tp, include);
537edebbb8eSjmmv 
538edebbb8eSjmmv     return atf_no_error();
539edebbb8eSjmmv }
540