1273929Sjmmv/* Copyright (c) 2008 The NetBSD Foundation, Inc.
2240116Smarcel * All rights reserved.
3240116Smarcel *
4240116Smarcel * Redistribution and use in source and binary forms, with or without
5240116Smarcel * modification, are permitted provided that the following conditions
6240116Smarcel * are met:
7240116Smarcel * 1. Redistributions of source code must retain the above copyright
8240116Smarcel *    notice, this list of conditions and the following disclaimer.
9240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel *    notice, this list of conditions and the following disclaimer in the
11240116Smarcel *    documentation and/or other materials provided with the distribution.
12240116Smarcel *
13240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24273929Sjmmv * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
25240116Smarcel
26273929Sjmmv#include "atf-c/check.h"
27273929Sjmmv
28240116Smarcel#include <fcntl.h>
29240116Smarcel#include <signal.h>
30240116Smarcel#include <stdio.h>
31240116Smarcel#include <stdlib.h>
32240116Smarcel#include <string.h>
33240116Smarcel#include <unistd.h>
34240116Smarcel
35240116Smarcel#include <atf-c.h>
36240116Smarcel
37273929Sjmmv#include "atf-c/detail/fs.h"
38273929Sjmmv#include "atf-c/detail/map.h"
39273929Sjmmv#include "atf-c/detail/process.h"
40273929Sjmmv#include "atf-c/detail/test_helpers.h"
41240116Smarcel
42240116Smarcel/* ---------------------------------------------------------------------
43240116Smarcel * Auxiliary functions.
44240116Smarcel * --------------------------------------------------------------------- */
45240116Smarcel
46240116Smarcelstatic
47240116Smarcelvoid
48240116Smarceldo_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
49240116Smarcel{
50240116Smarcel    atf_fs_path_t process_helpers;
51240116Smarcel    const char *argv[3];
52240116Smarcel
53240116Smarcel    get_process_helpers_path(tc, false, &process_helpers);
54240116Smarcel
55240116Smarcel    argv[0] = atf_fs_path_cstring(&process_helpers);
56240116Smarcel    argv[1] = helper_name;
57240116Smarcel    argv[2] = NULL;
58240116Smarcel    printf("Executing %s %s\n", argv[0], argv[1]);
59240116Smarcel    RE(atf_check_exec_array(argv, r));
60240116Smarcel
61240116Smarcel    atf_fs_path_fini(&process_helpers);
62240116Smarcel}
63240116Smarcel
64240116Smarcelstatic
65240116Smarcelvoid
66240116Smarceldo_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
67240116Smarcel                 atf_check_result_t *r)
68240116Smarcel{
69240116Smarcel    atf_fs_path_t process_helpers;
70240116Smarcel    const char *argv[4];
71240116Smarcel
72240116Smarcel    get_process_helpers_path(tc, false, &process_helpers);
73240116Smarcel
74240116Smarcel    argv[0] = atf_fs_path_cstring(&process_helpers);
75240116Smarcel    argv[1] = helper_name;
76240116Smarcel    argv[2] = arg;
77240116Smarcel    argv[3] = NULL;
78240116Smarcel    printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
79240116Smarcel    RE(atf_check_exec_array(argv, r));
80240116Smarcel
81240116Smarcel    atf_fs_path_fini(&process_helpers);
82240116Smarcel}
83240116Smarcel
84240116Smarcelstatic
85240116Smarcelvoid
86240116Smarcelcheck_line(int fd, const char *exp)
87240116Smarcel{
88258289Sjmmv    char *line = atf_utils_readline(fd);
89258289Sjmmv    ATF_CHECK(line != NULL);
90258289Sjmmv    ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
91258289Sjmmv    free(line);
92240116Smarcel}
93240116Smarcel
94240116Smarcel/* ---------------------------------------------------------------------
95240116Smarcel * Helper test cases for the free functions.
96240116Smarcel * --------------------------------------------------------------------- */
97240116Smarcel
98240116SmarcelATF_TC(h_build_c_o_ok);
99240116SmarcelATF_TC_HEAD(h_build_c_o_ok, tc)
100240116Smarcel{
101240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
102240116Smarcel}
103240116SmarcelATF_TC_BODY(h_build_c_o_ok, tc)
104240116Smarcel{
105240116Smarcel    FILE *sfile;
106240116Smarcel    bool success;
107240116Smarcel
108240116Smarcel    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
109240116Smarcel    fprintf(sfile, "#include <stdio.h>\n");
110240116Smarcel    fclose(sfile);
111240116Smarcel
112240116Smarcel    RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
113240116Smarcel    ATF_REQUIRE(success);
114240116Smarcel}
115240116Smarcel
116240116SmarcelATF_TC(h_build_c_o_fail);
117240116SmarcelATF_TC_HEAD(h_build_c_o_fail, tc)
118240116Smarcel{
119240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
120240116Smarcel}
121240116SmarcelATF_TC_BODY(h_build_c_o_fail, tc)
122240116Smarcel{
123240116Smarcel    FILE *sfile;
124240116Smarcel    bool success;
125240116Smarcel
126240116Smarcel    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
127240116Smarcel    fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
128240116Smarcel    fclose(sfile);
129240116Smarcel
130240116Smarcel    RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
131240116Smarcel    ATF_REQUIRE(!success);
132240116Smarcel}
133240116Smarcel
134240116SmarcelATF_TC(h_build_cpp_ok);
135240116SmarcelATF_TC_HEAD(h_build_cpp_ok, tc)
136240116Smarcel{
137240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
138240116Smarcel}
139240116SmarcelATF_TC_BODY(h_build_cpp_ok, tc)
140240116Smarcel{
141240116Smarcel    FILE *sfile;
142240116Smarcel    bool success;
143240116Smarcel    atf_fs_path_t test_p;
144240116Smarcel
145240116Smarcel    RE(atf_fs_path_init_fmt(&test_p, "test.p"));
146240116Smarcel
147240116Smarcel    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
148240116Smarcel    fprintf(sfile, "#define A foo\n");
149240116Smarcel    fprintf(sfile, "#define B bar\n");
150240116Smarcel    fprintf(sfile, "A B\n");
151240116Smarcel    fclose(sfile);
152240116Smarcel
153240116Smarcel    RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
154240116Smarcel                           &success));
155240116Smarcel    ATF_REQUIRE(success);
156240116Smarcel
157240116Smarcel    atf_fs_path_fini(&test_p);
158240116Smarcel}
159240116Smarcel
160240116SmarcelATF_TC(h_build_cpp_fail);
161240116SmarcelATF_TC_HEAD(h_build_cpp_fail, tc)
162240116Smarcel{
163240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
164240116Smarcel}
165240116SmarcelATF_TC_BODY(h_build_cpp_fail, tc)
166240116Smarcel{
167240116Smarcel    FILE *sfile;
168240116Smarcel    bool success;
169240116Smarcel
170240116Smarcel    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
171240116Smarcel    fprintf(sfile, "#include \"./non-existent.h\"\n");
172240116Smarcel    fclose(sfile);
173240116Smarcel
174240116Smarcel    RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
175240116Smarcel    ATF_REQUIRE(!success);
176240116Smarcel}
177240116Smarcel
178240116SmarcelATF_TC(h_build_cxx_o_ok);
179240116SmarcelATF_TC_HEAD(h_build_cxx_o_ok, tc)
180240116Smarcel{
181240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
182240116Smarcel}
183240116SmarcelATF_TC_BODY(h_build_cxx_o_ok, tc)
184240116Smarcel{
185240116Smarcel    FILE *sfile;
186240116Smarcel    bool success;
187240116Smarcel
188240116Smarcel    ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
189240116Smarcel    fprintf(sfile, "#include <iostream>\n");
190240116Smarcel    fclose(sfile);
191240116Smarcel
192240116Smarcel    RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
193240116Smarcel    ATF_REQUIRE(success);
194240116Smarcel}
195240116Smarcel
196240116SmarcelATF_TC(h_build_cxx_o_fail);
197240116SmarcelATF_TC_HEAD(h_build_cxx_o_fail, tc)
198240116Smarcel{
199240116Smarcel    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
200240116Smarcel}
201240116SmarcelATF_TC_BODY(h_build_cxx_o_fail, tc)
202240116Smarcel{
203240116Smarcel    FILE *sfile;
204240116Smarcel    bool success;
205240116Smarcel
206240116Smarcel    ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
207240116Smarcel    fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
208240116Smarcel    fclose(sfile);
209240116Smarcel
210240116Smarcel    RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
211240116Smarcel    ATF_REQUIRE(!success);
212240116Smarcel}
213240116Smarcel
214240116Smarcel/* ---------------------------------------------------------------------
215240116Smarcel * Test cases for the free functions.
216240116Smarcel * --------------------------------------------------------------------- */
217240116Smarcel
218240116Smarcelstatic
219240116Smarcelvoid
220240116Smarcelinit_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
221240116Smarcel                  const char *outname, const char *errname)
222240116Smarcel{
223240116Smarcel    const char *const config[] = { NULL };
224240116Smarcel
225240116Smarcel    RE(atf_tc_init_pack(tc, tcpack, config));
226240116Smarcel    run_h_tc(tc, outname, errname, "result");
227240116Smarcel    atf_tc_fini(tc);
228240116Smarcel}
229240116Smarcel
230240116SmarcelATF_TC(build_c_o);
231240116SmarcelATF_TC_HEAD(build_c_o, tc)
232240116Smarcel{
233240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
234240116Smarcel                      "function");
235240116Smarcel}
236240116SmarcelATF_TC_BODY(build_c_o, tc)
237240116Smarcel{
238240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
239240116Smarcel             &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
240258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
241258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
242240116Smarcel
243240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
244240116Smarcel             &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
245258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
246258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
247258289Sjmmv    ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
248258289Sjmmv    ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
249240116Smarcel}
250240116Smarcel
251240116SmarcelATF_TC(build_cpp);
252240116SmarcelATF_TC_HEAD(build_cpp, tc)
253240116Smarcel{
254240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
255240116Smarcel                      "function");
256240116Smarcel}
257240116SmarcelATF_TC_BODY(build_cpp, tc)
258240116Smarcel{
259240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
260240116Smarcel             &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
261258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o.*test.p", "stdout"));
262258289Sjmmv    ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
263258289Sjmmv    ATF_CHECK(atf_utils_grep_file("foo bar", "test.p"));
264240116Smarcel
265240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
266240116Smarcel             &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
267258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o test.p", "stdout"));
268258289Sjmmv    ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
269258289Sjmmv    ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
270258289Sjmmv    ATF_CHECK(atf_utils_grep_file("non-existent.h", "stderr"));
271240116Smarcel}
272240116Smarcel
273240116SmarcelATF_TC(build_cxx_o);
274240116SmarcelATF_TC_HEAD(build_cxx_o, tc)
275240116Smarcel{
276240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
277240116Smarcel                      "function");
278240116Smarcel}
279240116SmarcelATF_TC_BODY(build_cxx_o, tc)
280240116Smarcel{
281240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
282240116Smarcel             &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
283258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
284258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
285240116Smarcel
286240116Smarcel    init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
287240116Smarcel             &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
288258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
289258289Sjmmv    ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
290258289Sjmmv    ATF_CHECK(atf_utils_grep_file("test.cpp", "stderr"));
291258289Sjmmv    ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
292240116Smarcel}
293240116Smarcel
294240116SmarcelATF_TC(exec_array);
295240116SmarcelATF_TC_HEAD(exec_array, tc)
296240116Smarcel{
297240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
298240116Smarcel                      "works properly");
299240116Smarcel}
300240116SmarcelATF_TC_BODY(exec_array, tc)
301240116Smarcel{
302240116Smarcel    atf_fs_path_t process_helpers;
303240116Smarcel    atf_check_result_t result;
304240116Smarcel
305240116Smarcel    get_process_helpers_path(tc, false, &process_helpers);
306240116Smarcel
307240116Smarcel    const char *argv[4];
308240116Smarcel    argv[0] = atf_fs_path_cstring(&process_helpers);
309240116Smarcel    argv[1] = "echo";
310240116Smarcel    argv[2] = "test-message";
311240116Smarcel    argv[3] = NULL;
312240116Smarcel
313240116Smarcel    RE(atf_check_exec_array(argv, &result));
314240116Smarcel
315240116Smarcel    ATF_CHECK(atf_check_result_exited(&result));
316240116Smarcel    ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
317240116Smarcel
318240116Smarcel    {
319240116Smarcel        const char *path = atf_check_result_stdout(&result);
320240116Smarcel        int fd = open(path, O_RDONLY);
321240116Smarcel        ATF_CHECK(fd != -1);
322240116Smarcel        check_line(fd, "test-message");
323240116Smarcel        close(fd);
324240116Smarcel    }
325240116Smarcel
326240116Smarcel    atf_check_result_fini(&result);
327240116Smarcel    atf_fs_path_fini(&process_helpers);
328240116Smarcel}
329240116Smarcel
330240116SmarcelATF_TC(exec_cleanup);
331240116SmarcelATF_TC_HEAD(exec_cleanup, tc)
332240116Smarcel{
333240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
334240116Smarcel                      "properly cleans up the temporary files it creates");
335240116Smarcel}
336240116SmarcelATF_TC_BODY(exec_cleanup, tc)
337240116Smarcel{
338240116Smarcel    atf_fs_path_t out, err;
339240116Smarcel    atf_check_result_t result;
340240116Smarcel    bool exists;
341240116Smarcel
342240116Smarcel    do_exec(tc, "exit-success", &result);
343240116Smarcel    RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
344240116Smarcel    RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
345240116Smarcel
346240116Smarcel    RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
347240116Smarcel    RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
348240116Smarcel    atf_check_result_fini(&result);
349240116Smarcel    RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
350240116Smarcel    RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
351240116Smarcel
352240116Smarcel    atf_fs_path_fini(&err);
353240116Smarcel    atf_fs_path_fini(&out);
354240116Smarcel}
355240116Smarcel
356240116SmarcelATF_TC(exec_exitstatus);
357240116SmarcelATF_TC_HEAD(exec_exitstatus, tc)
358240116Smarcel{
359240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
360240116Smarcel                      "properly captures the exit status of the executed "
361240116Smarcel                      "command");
362240116Smarcel}
363240116SmarcelATF_TC_BODY(exec_exitstatus, tc)
364240116Smarcel{
365240116Smarcel    {
366240116Smarcel        atf_check_result_t result;
367240116Smarcel        do_exec(tc, "exit-success", &result);
368240116Smarcel        ATF_CHECK(atf_check_result_exited(&result));
369240116Smarcel        ATF_CHECK(!atf_check_result_signaled(&result));
370240116Smarcel        ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
371240116Smarcel        atf_check_result_fini(&result);
372240116Smarcel    }
373240116Smarcel
374240116Smarcel    {
375240116Smarcel        atf_check_result_t result;
376240116Smarcel        do_exec(tc, "exit-failure", &result);
377240116Smarcel        ATF_CHECK(atf_check_result_exited(&result));
378240116Smarcel        ATF_CHECK(!atf_check_result_signaled(&result));
379240116Smarcel        ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
380240116Smarcel        atf_check_result_fini(&result);
381240116Smarcel    }
382240116Smarcel
383240116Smarcel    {
384240116Smarcel        atf_check_result_t result;
385240116Smarcel        do_exec(tc, "exit-signal", &result);
386240116Smarcel        ATF_CHECK(!atf_check_result_exited(&result));
387240116Smarcel        ATF_CHECK(atf_check_result_signaled(&result));
388240116Smarcel        ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
389240116Smarcel        atf_check_result_fini(&result);
390240116Smarcel    }
391240116Smarcel}
392240116Smarcel
393240116SmarcelATF_TC(exec_stdout_stderr);
394240116SmarcelATF_TC_HEAD(exec_stdout_stderr, tc)
395240116Smarcel{
396240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
397240116Smarcel                      "properly captures the stdout and stderr streams "
398240116Smarcel                      "of the child process");
399240116Smarcel}
400240116SmarcelATF_TC_BODY(exec_stdout_stderr, tc)
401240116Smarcel{
402240116Smarcel    atf_check_result_t result1, result2;
403240116Smarcel    const char *out1, *out2;
404240116Smarcel    const char *err1, *err2;
405240116Smarcel
406240116Smarcel    do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
407240116Smarcel    ATF_CHECK(atf_check_result_exited(&result1));
408240116Smarcel    ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
409240116Smarcel
410240116Smarcel    do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
411240116Smarcel    ATF_CHECK(atf_check_result_exited(&result2));
412240116Smarcel    ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
413240116Smarcel
414240116Smarcel    out1 = atf_check_result_stdout(&result1);
415240116Smarcel    out2 = atf_check_result_stdout(&result2);
416240116Smarcel    err1 = atf_check_result_stderr(&result1);
417240116Smarcel    err2 = atf_check_result_stderr(&result2);
418240116Smarcel
419240116Smarcel    ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
420240116Smarcel    ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
421240116Smarcel    ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
422240116Smarcel    ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
423240116Smarcel
424240116Smarcel    ATF_CHECK(strstr(out1, "/check") != NULL);
425240116Smarcel    ATF_CHECK(strstr(out2, "/check") != NULL);
426240116Smarcel    ATF_CHECK(strstr(err1, "/check") != NULL);
427240116Smarcel    ATF_CHECK(strstr(err2, "/check") != NULL);
428240116Smarcel
429240116Smarcel    ATF_CHECK(strstr(out1, "/stdout") != NULL);
430240116Smarcel    ATF_CHECK(strstr(out2, "/stdout") != NULL);
431240116Smarcel    ATF_CHECK(strstr(err1, "/stderr") != NULL);
432240116Smarcel    ATF_CHECK(strstr(err2, "/stderr") != NULL);
433240116Smarcel
434240116Smarcel    ATF_CHECK(strcmp(out1, out2) != 0);
435240116Smarcel    ATF_CHECK(strcmp(err1, err2) != 0);
436240116Smarcel
437240116Smarcel#define CHECK_LINES(path, outname, resname) \
438240116Smarcel    do { \
439240116Smarcel        int fd = open(path, O_RDONLY); \
440240116Smarcel        ATF_CHECK(fd != -1); \
441240116Smarcel        check_line(fd, "Line 1 to " outname " for " resname); \
442240116Smarcel        check_line(fd, "Line 2 to " outname " for " resname); \
443240116Smarcel        close(fd); \
444240116Smarcel    } while (false)
445240116Smarcel
446240116Smarcel    CHECK_LINES(out1, "stdout", "result1");
447240116Smarcel    CHECK_LINES(out2, "stdout", "result2");
448240116Smarcel    CHECK_LINES(err1, "stderr", "result1");
449240116Smarcel    CHECK_LINES(err2, "stderr", "result2");
450240116Smarcel
451240116Smarcel#undef CHECK_LINES
452240116Smarcel
453240116Smarcel    atf_check_result_fini(&result2);
454240116Smarcel    atf_check_result_fini(&result1);
455240116Smarcel}
456240116Smarcel
457240116SmarcelATF_TC(exec_umask);
458240116SmarcelATF_TC_HEAD(exec_umask, tc)
459240116Smarcel{
460240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
461240116Smarcel                      "correctly reports an error if the umask is too "
462240116Smarcel                      "restrictive to create temporary files");
463240116Smarcel}
464240116SmarcelATF_TC_BODY(exec_umask, tc)
465240116Smarcel{
466240116Smarcel    atf_check_result_t result;
467240116Smarcel    atf_fs_path_t process_helpers;
468240116Smarcel    const char *argv[3];
469240116Smarcel
470240116Smarcel    get_process_helpers_path(tc, false, &process_helpers);
471240116Smarcel    argv[0] = atf_fs_path_cstring(&process_helpers);
472240116Smarcel    argv[1] = "exit-success";
473240116Smarcel    argv[2] = NULL;
474240116Smarcel
475240116Smarcel    umask(0222);
476240116Smarcel    atf_error_t err = atf_check_exec_array(argv, &result);
477240116Smarcel    ATF_CHECK(atf_is_error(err));
478240116Smarcel    ATF_CHECK(atf_error_is(err, "invalid_umask"));
479240116Smarcel    atf_error_free(err);
480240116Smarcel
481240116Smarcel    atf_fs_path_fini(&process_helpers);
482240116Smarcel}
483240116Smarcel
484240116SmarcelATF_TC(exec_unknown);
485240116SmarcelATF_TC_HEAD(exec_unknown, tc)
486240116Smarcel{
487240116Smarcel    atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
488240116Smarcel                      "binary is handled correctly");
489240116Smarcel}
490240116SmarcelATF_TC_BODY(exec_unknown, tc)
491240116Smarcel{
492240116Smarcel    const char *argv[2];
493273929Sjmmv    argv[0] = "/foo/bar/non-existent";
494240116Smarcel    argv[1] = NULL;
495240116Smarcel
496240116Smarcel    atf_check_result_t result;
497240116Smarcel    RE(atf_check_exec_array(argv, &result));
498240116Smarcel    ATF_CHECK(atf_check_result_exited(&result));
499240116Smarcel    ATF_CHECK(atf_check_result_exitcode(&result) == 127);
500240116Smarcel    atf_check_result_fini(&result);
501240116Smarcel}
502240116Smarcel
503240116Smarcel/* ---------------------------------------------------------------------
504240116Smarcel * Main.
505240116Smarcel * --------------------------------------------------------------------- */
506240116Smarcel
507240116SmarcelATF_TP_ADD_TCS(tp)
508240116Smarcel{
509240116Smarcel    /* Add the test cases for the free functions. */
510240116Smarcel    ATF_TP_ADD_TC(tp, build_c_o);
511240116Smarcel    ATF_TP_ADD_TC(tp, build_cpp);
512240116Smarcel    ATF_TP_ADD_TC(tp, build_cxx_o);
513240116Smarcel    ATF_TP_ADD_TC(tp, exec_array);
514240116Smarcel    ATF_TP_ADD_TC(tp, exec_cleanup);
515240116Smarcel    ATF_TP_ADD_TC(tp, exec_exitstatus);
516240116Smarcel    ATF_TP_ADD_TC(tp, exec_stdout_stderr);
517240116Smarcel    ATF_TP_ADD_TC(tp, exec_umask);
518240116Smarcel    ATF_TP_ADD_TC(tp, exec_unknown);
519240116Smarcel
520240116Smarcel    return atf_no_error();
521240116Smarcel}
522