1*00b67f09SDavid van Moolenbroek /* $NetBSD: utils_test.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Automated Testing Framework (atf)
5*00b67f09SDavid van Moolenbroek *
6*00b67f09SDavid van Moolenbroek * Copyright (c) 2010 The NetBSD Foundation, Inc.
7*00b67f09SDavid van Moolenbroek * All rights reserved.
8*00b67f09SDavid van Moolenbroek *
9*00b67f09SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
10*00b67f09SDavid van Moolenbroek * modification, are permitted provided that the following conditions
11*00b67f09SDavid van Moolenbroek * are met:
12*00b67f09SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
13*00b67f09SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
14*00b67f09SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
15*00b67f09SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
16*00b67f09SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
17*00b67f09SDavid van Moolenbroek *
18*00b67f09SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19*00b67f09SDavid van Moolenbroek * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*00b67f09SDavid van Moolenbroek * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21*00b67f09SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*00b67f09SDavid van Moolenbroek * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23*00b67f09SDavid van Moolenbroek * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*00b67f09SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25*00b67f09SDavid van Moolenbroek * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*00b67f09SDavid van Moolenbroek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27*00b67f09SDavid van Moolenbroek * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28*00b67f09SDavid van Moolenbroek * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29*00b67f09SDavid van Moolenbroek * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*00b67f09SDavid van Moolenbroek */
31*00b67f09SDavid van Moolenbroek
32*00b67f09SDavid van Moolenbroek #include <sys/stat.h>
33*00b67f09SDavid van Moolenbroek #include <sys/wait.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek #include <fcntl.h>
36*00b67f09SDavid van Moolenbroek #include <stddef.h>
37*00b67f09SDavid van Moolenbroek #include <stdio.h>
38*00b67f09SDavid van Moolenbroek #include <stdlib.h>
39*00b67f09SDavid van Moolenbroek #include <string.h>
40*00b67f09SDavid van Moolenbroek #include <unistd.h>
41*00b67f09SDavid van Moolenbroek
42*00b67f09SDavid van Moolenbroek #include <atf-c.h>
43*00b67f09SDavid van Moolenbroek
44*00b67f09SDavid van Moolenbroek #include "atf-c/utils.h"
45*00b67f09SDavid van Moolenbroek
46*00b67f09SDavid van Moolenbroek #include "detail/test_helpers.h"
47*00b67f09SDavid van Moolenbroek
48*00b67f09SDavid van Moolenbroek /** Reads the contents of a file into a buffer.
49*00b67f09SDavid van Moolenbroek *
50*00b67f09SDavid van Moolenbroek * Up to buflen-1 characters are read into buffer. If this function returns,
51*00b67f09SDavid van Moolenbroek * the contents read into the buffer are guaranteed to be nul-terminated.
52*00b67f09SDavid van Moolenbroek * Note, however, that if the file contains any nul characters itself,
53*00b67f09SDavid van Moolenbroek * comparing it "as a string" will not work.
54*00b67f09SDavid van Moolenbroek *
55*00b67f09SDavid van Moolenbroek * \param path The file to be read, which must exist.
56*00b67f09SDavid van Moolenbroek * \param buffer Buffer into which to store the file contents.
57*00b67f09SDavid van Moolenbroek * \param buflen Size of the target buffer.
58*00b67f09SDavid van Moolenbroek *
59*00b67f09SDavid van Moolenbroek * \return The count of bytes read. */
60*00b67f09SDavid van Moolenbroek static ssize_t
read_file(const char * path,void * const buffer,const size_t buflen)61*00b67f09SDavid van Moolenbroek read_file(const char *path, void *const buffer, const size_t buflen)
62*00b67f09SDavid van Moolenbroek {
63*00b67f09SDavid van Moolenbroek const int fd = open(path, O_RDONLY);
64*00b67f09SDavid van Moolenbroek ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", path);
65*00b67f09SDavid van Moolenbroek const ssize_t length = read(fd, buffer, buflen - 1);
66*00b67f09SDavid van Moolenbroek close(fd);
67*00b67f09SDavid van Moolenbroek ATF_REQUIRE(length != -1);
68*00b67f09SDavid van Moolenbroek ((char *)buffer)[length] = '\0';
69*00b67f09SDavid van Moolenbroek return length;
70*00b67f09SDavid van Moolenbroek }
71*00b67f09SDavid van Moolenbroek
72*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(cat_file__empty);
ATF_TC_BODY(cat_file__empty,tc)73*00b67f09SDavid van Moolenbroek ATF_TC_BODY(cat_file__empty, tc)
74*00b67f09SDavid van Moolenbroek {
75*00b67f09SDavid van Moolenbroek atf_utils_create_file("file.txt", "%s", "");
76*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDOUT_FILENO, "captured.txt");
77*00b67f09SDavid van Moolenbroek atf_utils_cat_file("file.txt", "PREFIX");
78*00b67f09SDavid van Moolenbroek fflush(stdout);
79*00b67f09SDavid van Moolenbroek close(STDOUT_FILENO);
80*00b67f09SDavid van Moolenbroek
81*00b67f09SDavid van Moolenbroek char buffer[1024];
82*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
83*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("", buffer);
84*00b67f09SDavid van Moolenbroek }
85*00b67f09SDavid van Moolenbroek
86*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(cat_file__one_line);
ATF_TC_BODY(cat_file__one_line,tc)87*00b67f09SDavid van Moolenbroek ATF_TC_BODY(cat_file__one_line, tc)
88*00b67f09SDavid van Moolenbroek {
89*00b67f09SDavid van Moolenbroek atf_utils_create_file("file.txt", "This is a single line\n");
90*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDOUT_FILENO, "captured.txt");
91*00b67f09SDavid van Moolenbroek atf_utils_cat_file("file.txt", "PREFIX");
92*00b67f09SDavid van Moolenbroek fflush(stdout);
93*00b67f09SDavid van Moolenbroek close(STDOUT_FILENO);
94*00b67f09SDavid van Moolenbroek
95*00b67f09SDavid van Moolenbroek char buffer[1024];
96*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
97*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("PREFIXThis is a single line\n", buffer);
98*00b67f09SDavid van Moolenbroek }
99*00b67f09SDavid van Moolenbroek
100*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(cat_file__several_lines);
ATF_TC_BODY(cat_file__several_lines,tc)101*00b67f09SDavid van Moolenbroek ATF_TC_BODY(cat_file__several_lines, tc)
102*00b67f09SDavid van Moolenbroek {
103*00b67f09SDavid van Moolenbroek atf_utils_create_file("file.txt", "First\nSecond line\nAnd third\n");
104*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDOUT_FILENO, "captured.txt");
105*00b67f09SDavid van Moolenbroek atf_utils_cat_file("file.txt", ">");
106*00b67f09SDavid van Moolenbroek fflush(stdout);
107*00b67f09SDavid van Moolenbroek close(STDOUT_FILENO);
108*00b67f09SDavid van Moolenbroek
109*00b67f09SDavid van Moolenbroek char buffer[1024];
110*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
111*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ(">First\n>Second line\n>And third\n", buffer);
112*00b67f09SDavid van Moolenbroek }
113*00b67f09SDavid van Moolenbroek
114*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(cat_file__no_newline_eof);
ATF_TC_BODY(cat_file__no_newline_eof,tc)115*00b67f09SDavid van Moolenbroek ATF_TC_BODY(cat_file__no_newline_eof, tc)
116*00b67f09SDavid van Moolenbroek {
117*00b67f09SDavid van Moolenbroek atf_utils_create_file("file.txt", "Foo\n bar baz");
118*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDOUT_FILENO, "captured.txt");
119*00b67f09SDavid van Moolenbroek atf_utils_cat_file("file.txt", "PREFIX");
120*00b67f09SDavid van Moolenbroek fflush(stdout);
121*00b67f09SDavid van Moolenbroek close(STDOUT_FILENO);
122*00b67f09SDavid van Moolenbroek
123*00b67f09SDavid van Moolenbroek char buffer[1024];
124*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
125*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("PREFIXFoo\nPREFIX bar baz", buffer);
126*00b67f09SDavid van Moolenbroek }
127*00b67f09SDavid van Moolenbroek
128*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__empty__match);
ATF_TC_BODY(compare_file__empty__match,tc)129*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__empty__match, tc)
130*00b67f09SDavid van Moolenbroek {
131*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "%s", "");
132*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("test.txt", ""));
133*00b67f09SDavid van Moolenbroek }
134*00b67f09SDavid van Moolenbroek
135*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__empty__not_match);
ATF_TC_BODY(compare_file__empty__not_match,tc)136*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__empty__not_match, tc)
137*00b67f09SDavid van Moolenbroek {
138*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "%s", "");
139*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
140*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "foo"));
141*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", " "));
142*00b67f09SDavid van Moolenbroek }
143*00b67f09SDavid van Moolenbroek
144*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__short__match);
ATF_TC_BODY(compare_file__short__match,tc)145*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__short__match, tc)
146*00b67f09SDavid van Moolenbroek {
147*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "this is a short file");
148*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("test.txt", "this is a short file"));
149*00b67f09SDavid van Moolenbroek }
150*00b67f09SDavid van Moolenbroek
151*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__short__not_match);
ATF_TC_BODY(compare_file__short__not_match,tc)152*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__short__not_match, tc)
153*00b67f09SDavid van Moolenbroek {
154*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "this is a short file");
155*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", ""));
156*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
157*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a Short file"));
158*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short fil"));
159*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short file "));
160*00b67f09SDavid van Moolenbroek }
161*00b67f09SDavid van Moolenbroek
162*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__long__match);
ATF_TC_BODY(compare_file__long__match,tc)163*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__long__match, tc)
164*00b67f09SDavid van Moolenbroek {
165*00b67f09SDavid van Moolenbroek char long_contents[3456];
166*00b67f09SDavid van Moolenbroek size_t i = 0;
167*00b67f09SDavid van Moolenbroek for (; i < sizeof(long_contents) - 1; i++)
168*00b67f09SDavid van Moolenbroek long_contents[i] = '0' + (i % 10);
169*00b67f09SDavid van Moolenbroek long_contents[i] = '\0';
170*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "%s", long_contents);
171*00b67f09SDavid van Moolenbroek
172*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("test.txt", long_contents));
173*00b67f09SDavid van Moolenbroek }
174*00b67f09SDavid van Moolenbroek
175*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(compare_file__long__not_match);
ATF_TC_BODY(compare_file__long__not_match,tc)176*00b67f09SDavid van Moolenbroek ATF_TC_BODY(compare_file__long__not_match, tc)
177*00b67f09SDavid van Moolenbroek {
178*00b67f09SDavid van Moolenbroek char long_contents[3456];
179*00b67f09SDavid van Moolenbroek size_t i = 0;
180*00b67f09SDavid van Moolenbroek for (; i < sizeof(long_contents) - 1; i++)
181*00b67f09SDavid van Moolenbroek long_contents[i] = '0' + (i % 10);
182*00b67f09SDavid van Moolenbroek long_contents[i] = '\0';
183*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "%s", long_contents);
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", ""));
186*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
187*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", "0123456789"));
188*00b67f09SDavid van Moolenbroek long_contents[i - 1] = 'Z';
189*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_compare_file("test.txt", long_contents));
190*00b67f09SDavid van Moolenbroek }
191*00b67f09SDavid van Moolenbroek
192*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(copy_file__empty);
ATF_TC_BODY(copy_file__empty,tc)193*00b67f09SDavid van Moolenbroek ATF_TC_BODY(copy_file__empty, tc)
194*00b67f09SDavid van Moolenbroek {
195*00b67f09SDavid van Moolenbroek atf_utils_create_file("src.txt", "%s", "");
196*00b67f09SDavid van Moolenbroek ATF_REQUIRE(chmod("src.txt", 0520) != -1);
197*00b67f09SDavid van Moolenbroek
198*00b67f09SDavid van Moolenbroek atf_utils_copy_file("src.txt", "dest.txt");
199*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("dest.txt", ""));
200*00b67f09SDavid van Moolenbroek struct stat sb;
201*00b67f09SDavid van Moolenbroek ATF_REQUIRE(stat("dest.txt", &sb) != -1);
202*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);
203*00b67f09SDavid van Moolenbroek }
204*00b67f09SDavid van Moolenbroek
205*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(copy_file__some_contents);
ATF_TC_BODY(copy_file__some_contents,tc)206*00b67f09SDavid van Moolenbroek ATF_TC_BODY(copy_file__some_contents, tc)
207*00b67f09SDavid van Moolenbroek {
208*00b67f09SDavid van Moolenbroek atf_utils_create_file("src.txt", "This is a\ntest file\n");
209*00b67f09SDavid van Moolenbroek atf_utils_copy_file("src.txt", "dest.txt");
210*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("dest.txt", "This is a\ntest file\n"));
211*00b67f09SDavid van Moolenbroek }
212*00b67f09SDavid van Moolenbroek
213*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(create_file);
ATF_TC_BODY(create_file,tc)214*00b67f09SDavid van Moolenbroek ATF_TC_BODY(create_file, tc)
215*00b67f09SDavid van Moolenbroek {
216*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "This is a test with %d", 12345);
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroek char buffer[128];
219*00b67f09SDavid van Moolenbroek read_file("test.txt", buffer, sizeof(buffer));
220*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("This is a test with 12345", buffer);
221*00b67f09SDavid van Moolenbroek }
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(file_exists);
ATF_TC_BODY(file_exists,tc)224*00b67f09SDavid van Moolenbroek ATF_TC_BODY(file_exists, tc)
225*00b67f09SDavid van Moolenbroek {
226*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "foo");
227*00b67f09SDavid van Moolenbroek
228*00b67f09SDavid van Moolenbroek ATF_REQUIRE( atf_utils_file_exists("test.txt"));
229*00b67f09SDavid van Moolenbroek ATF_REQUIRE( atf_utils_file_exists("./test.txt"));
230*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_file_exists("./test.tx"));
231*00b67f09SDavid van Moolenbroek ATF_REQUIRE(!atf_utils_file_exists("test.txt2"));
232*00b67f09SDavid van Moolenbroek }
233*00b67f09SDavid van Moolenbroek
234*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(fork);
ATF_TC_BODY(fork,tc)235*00b67f09SDavid van Moolenbroek ATF_TC_BODY(fork, tc)
236*00b67f09SDavid van Moolenbroek {
237*00b67f09SDavid van Moolenbroek fprintf(stdout, "Should not get into child\n");
238*00b67f09SDavid van Moolenbroek fprintf(stderr, "Should not get into child\n");
239*00b67f09SDavid van Moolenbroek pid_t pid = atf_utils_fork();
240*00b67f09SDavid van Moolenbroek if (pid == 0) {
241*00b67f09SDavid van Moolenbroek fprintf(stdout, "Child stdout\n");
242*00b67f09SDavid van Moolenbroek fprintf(stderr, "Child stderr\n");
243*00b67f09SDavid van Moolenbroek exit(EXIT_SUCCESS);
244*00b67f09SDavid van Moolenbroek }
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek int status;
247*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
248*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
249*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
250*00b67f09SDavid van Moolenbroek
251*00b67f09SDavid van Moolenbroek char buffer[1024];
252*00b67f09SDavid van Moolenbroek read_file("atf_utils_fork_out.txt", buffer, sizeof(buffer));
253*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("Child stdout\n", buffer);
254*00b67f09SDavid van Moolenbroek read_file("atf_utils_fork_err.txt", buffer, sizeof(buffer));
255*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("Child stderr\n", buffer);
256*00b67f09SDavid van Moolenbroek }
257*00b67f09SDavid van Moolenbroek
258*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(free_charpp__empty);
ATF_TC_BODY(free_charpp__empty,tc)259*00b67f09SDavid van Moolenbroek ATF_TC_BODY(free_charpp__empty, tc)
260*00b67f09SDavid van Moolenbroek {
261*00b67f09SDavid van Moolenbroek char **array = malloc(sizeof(char *) * 1);
262*00b67f09SDavid van Moolenbroek array[0] = NULL;
263*00b67f09SDavid van Moolenbroek
264*00b67f09SDavid van Moolenbroek atf_utils_free_charpp(array);
265*00b67f09SDavid van Moolenbroek }
266*00b67f09SDavid van Moolenbroek
267*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(free_charpp__some);
ATF_TC_BODY(free_charpp__some,tc)268*00b67f09SDavid van Moolenbroek ATF_TC_BODY(free_charpp__some, tc)
269*00b67f09SDavid van Moolenbroek {
270*00b67f09SDavid van Moolenbroek char **array = malloc(sizeof(char *) * 4);
271*00b67f09SDavid van Moolenbroek array[0] = strdup("first");
272*00b67f09SDavid van Moolenbroek array[1] = strdup("second");
273*00b67f09SDavid van Moolenbroek array[2] = strdup("third");
274*00b67f09SDavid van Moolenbroek array[3] = NULL;
275*00b67f09SDavid van Moolenbroek
276*00b67f09SDavid van Moolenbroek atf_utils_free_charpp(array);
277*00b67f09SDavid van Moolenbroek }
278*00b67f09SDavid van Moolenbroek
279*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(grep_file);
ATF_TC_BODY(grep_file,tc)280*00b67f09SDavid van Moolenbroek ATF_TC_BODY(grep_file, tc)
281*00b67f09SDavid van Moolenbroek {
282*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "line1\nthe second line\naaaabbbb\n");
283*00b67f09SDavid van Moolenbroek
284*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_file("line1", "test.txt"));
285*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_file("line%d", "test.txt", 1));
286*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_file("second line", "test.txt"));
287*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_file("aa.*bb", "test.txt"));
288*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_file("foo", "test.txt"));
289*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_file("bar", "test.txt"));
290*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_file("aaaaa", "test.txt"));
291*00b67f09SDavid van Moolenbroek }
292*00b67f09SDavid van Moolenbroek
293*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(grep_string);
ATF_TC_BODY(grep_string,tc)294*00b67f09SDavid van Moolenbroek ATF_TC_BODY(grep_string, tc)
295*00b67f09SDavid van Moolenbroek {
296*00b67f09SDavid van Moolenbroek const char *str = "a string - aaaabbbb";
297*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_string("a string", str));
298*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_string("^a string", str));
299*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_string("aaaabbbb$", str));
300*00b67f09SDavid van Moolenbroek ATF_CHECK(atf_utils_grep_string("a%s*bb", str, "a."));
301*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_string("foo", str));
302*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_string("bar", str));
303*00b67f09SDavid van Moolenbroek ATF_CHECK(!atf_utils_grep_string("aaaaa", str));
304*00b67f09SDavid van Moolenbroek }
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(readline__none);
ATF_TC_BODY(readline__none,tc)307*00b67f09SDavid van Moolenbroek ATF_TC_BODY(readline__none, tc)
308*00b67f09SDavid van Moolenbroek {
309*00b67f09SDavid van Moolenbroek atf_utils_create_file("empty.txt", "%s", "");
310*00b67f09SDavid van Moolenbroek
311*00b67f09SDavid van Moolenbroek const int fd = open("empty.txt", O_RDONLY);
312*00b67f09SDavid van Moolenbroek ATF_REQUIRE(fd != -1);
313*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_readline(fd) == NULL);
314*00b67f09SDavid van Moolenbroek close(fd);
315*00b67f09SDavid van Moolenbroek }
316*00b67f09SDavid van Moolenbroek
317*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(readline__some);
ATF_TC_BODY(readline__some,tc)318*00b67f09SDavid van Moolenbroek ATF_TC_BODY(readline__some, tc)
319*00b67f09SDavid van Moolenbroek {
320*00b67f09SDavid van Moolenbroek const char *l1 = "First line with % formatting % characters %";
321*00b67f09SDavid van Moolenbroek const char *l2 = "Second line; much longer than the first one";
322*00b67f09SDavid van Moolenbroek const char *l3 = "Last line, without terminator";
323*00b67f09SDavid van Moolenbroek
324*00b67f09SDavid van Moolenbroek atf_utils_create_file("test.txt", "%s\n%s\n%s", l1, l2, l3);
325*00b67f09SDavid van Moolenbroek
326*00b67f09SDavid van Moolenbroek const int fd = open("test.txt", O_RDONLY);
327*00b67f09SDavid van Moolenbroek ATF_REQUIRE(fd != -1);
328*00b67f09SDavid van Moolenbroek
329*00b67f09SDavid van Moolenbroek char *line;
330*00b67f09SDavid van Moolenbroek
331*00b67f09SDavid van Moolenbroek line = atf_utils_readline(fd);
332*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ(l1, line);
333*00b67f09SDavid van Moolenbroek free(line);
334*00b67f09SDavid van Moolenbroek
335*00b67f09SDavid van Moolenbroek line = atf_utils_readline(fd);
336*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ(l2, line);
337*00b67f09SDavid van Moolenbroek free(line);
338*00b67f09SDavid van Moolenbroek
339*00b67f09SDavid van Moolenbroek line = atf_utils_readline(fd);
340*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ(l3, line);
341*00b67f09SDavid van Moolenbroek free(line);
342*00b67f09SDavid van Moolenbroek
343*00b67f09SDavid van Moolenbroek close(fd);
344*00b67f09SDavid van Moolenbroek }
345*00b67f09SDavid van Moolenbroek
346*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(redirect__stdout);
ATF_TC_BODY(redirect__stdout,tc)347*00b67f09SDavid van Moolenbroek ATF_TC_BODY(redirect__stdout, tc)
348*00b67f09SDavid van Moolenbroek {
349*00b67f09SDavid van Moolenbroek printf("Buffer this");
350*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDOUT_FILENO, "captured.txt");
351*00b67f09SDavid van Moolenbroek printf("The printed message");
352*00b67f09SDavid van Moolenbroek fflush(stdout);
353*00b67f09SDavid van Moolenbroek
354*00b67f09SDavid van Moolenbroek char buffer[1024];
355*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
356*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("The printed message", buffer);
357*00b67f09SDavid van Moolenbroek }
358*00b67f09SDavid van Moolenbroek
359*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(redirect__stderr);
ATF_TC_BODY(redirect__stderr,tc)360*00b67f09SDavid van Moolenbroek ATF_TC_BODY(redirect__stderr, tc)
361*00b67f09SDavid van Moolenbroek {
362*00b67f09SDavid van Moolenbroek fprintf(stderr, "Buffer this");
363*00b67f09SDavid van Moolenbroek atf_utils_redirect(STDERR_FILENO, "captured.txt");
364*00b67f09SDavid van Moolenbroek fprintf(stderr, "The printed message");
365*00b67f09SDavid van Moolenbroek fflush(stderr);
366*00b67f09SDavid van Moolenbroek
367*00b67f09SDavid van Moolenbroek char buffer[1024];
368*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
369*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ("The printed message", buffer);
370*00b67f09SDavid van Moolenbroek }
371*00b67f09SDavid van Moolenbroek
372*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(redirect__other);
ATF_TC_BODY(redirect__other,tc)373*00b67f09SDavid van Moolenbroek ATF_TC_BODY(redirect__other, tc)
374*00b67f09SDavid van Moolenbroek {
375*00b67f09SDavid van Moolenbroek const char *message = "Foo bar\nbaz\n";
376*00b67f09SDavid van Moolenbroek atf_utils_redirect(15, "captured.txt");
377*00b67f09SDavid van Moolenbroek ATF_REQUIRE(write(15, message, strlen(message)) != -1);
378*00b67f09SDavid van Moolenbroek close(15);
379*00b67f09SDavid van Moolenbroek
380*00b67f09SDavid van Moolenbroek char buffer[1024];
381*00b67f09SDavid van Moolenbroek read_file("captured.txt", buffer, sizeof(buffer));
382*00b67f09SDavid van Moolenbroek ATF_REQUIRE_STREQ(message, buffer);
383*00b67f09SDavid van Moolenbroek }
384*00b67f09SDavid van Moolenbroek
385*00b67f09SDavid van Moolenbroek static void
fork_and_wait(const int exitstatus,const char * expout,const char * experr)386*00b67f09SDavid van Moolenbroek fork_and_wait(const int exitstatus, const char* expout, const char* experr)
387*00b67f09SDavid van Moolenbroek {
388*00b67f09SDavid van Moolenbroek const pid_t pid = atf_utils_fork();
389*00b67f09SDavid van Moolenbroek if (pid == 0) {
390*00b67f09SDavid van Moolenbroek fprintf(stdout, "Some output\n");
391*00b67f09SDavid van Moolenbroek fprintf(stderr, "Some error\n");
392*00b67f09SDavid van Moolenbroek exit(123);
393*00b67f09SDavid van Moolenbroek }
394*00b67f09SDavid van Moolenbroek atf_utils_wait(pid, exitstatus, expout, experr);
395*00b67f09SDavid van Moolenbroek exit(EXIT_SUCCESS);
396*00b67f09SDavid van Moolenbroek }
397*00b67f09SDavid van Moolenbroek
398*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__ok);
ATF_TC_BODY(wait__ok,tc)399*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__ok, tc)
400*00b67f09SDavid van Moolenbroek {
401*00b67f09SDavid van Moolenbroek const pid_t control = fork();
402*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
403*00b67f09SDavid van Moolenbroek if (control == 0)
404*00b67f09SDavid van Moolenbroek fork_and_wait(123, "Some output\n", "Some error\n");
405*00b67f09SDavid van Moolenbroek else {
406*00b67f09SDavid van Moolenbroek int status;
407*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
408*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
409*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
410*00b67f09SDavid van Moolenbroek }
411*00b67f09SDavid van Moolenbroek }
412*00b67f09SDavid van Moolenbroek
413*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__invalid_exitstatus);
ATF_TC_BODY(wait__invalid_exitstatus,tc)414*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__invalid_exitstatus, tc)
415*00b67f09SDavid van Moolenbroek {
416*00b67f09SDavid van Moolenbroek const pid_t control = fork();
417*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
418*00b67f09SDavid van Moolenbroek if (control == 0)
419*00b67f09SDavid van Moolenbroek fork_and_wait(120, "Some output\n", "Some error\n");
420*00b67f09SDavid van Moolenbroek else {
421*00b67f09SDavid van Moolenbroek int status;
422*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
423*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
424*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
425*00b67f09SDavid van Moolenbroek }
426*00b67f09SDavid van Moolenbroek }
427*00b67f09SDavid van Moolenbroek
428*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__invalid_stdout);
ATF_TC_BODY(wait__invalid_stdout,tc)429*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__invalid_stdout, tc)
430*00b67f09SDavid van Moolenbroek {
431*00b67f09SDavid van Moolenbroek const pid_t control = fork();
432*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
433*00b67f09SDavid van Moolenbroek if (control == 0)
434*00b67f09SDavid van Moolenbroek fork_and_wait(123, "Some output foo\n", "Some error\n");
435*00b67f09SDavid van Moolenbroek else {
436*00b67f09SDavid van Moolenbroek int status;
437*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
438*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
439*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
440*00b67f09SDavid van Moolenbroek }
441*00b67f09SDavid van Moolenbroek }
442*00b67f09SDavid van Moolenbroek
443*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__invalid_stderr);
ATF_TC_BODY(wait__invalid_stderr,tc)444*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__invalid_stderr, tc)
445*00b67f09SDavid van Moolenbroek {
446*00b67f09SDavid van Moolenbroek const pid_t control = fork();
447*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
448*00b67f09SDavid van Moolenbroek if (control == 0)
449*00b67f09SDavid van Moolenbroek fork_and_wait(123, "Some output\n", "Some error foo\n");
450*00b67f09SDavid van Moolenbroek else {
451*00b67f09SDavid van Moolenbroek int status;
452*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
453*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
454*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
455*00b67f09SDavid van Moolenbroek }
456*00b67f09SDavid van Moolenbroek }
457*00b67f09SDavid van Moolenbroek
458*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__save_stdout);
ATF_TC_BODY(wait__save_stdout,tc)459*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__save_stdout, tc)
460*00b67f09SDavid van Moolenbroek {
461*00b67f09SDavid van Moolenbroek const pid_t control = fork();
462*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
463*00b67f09SDavid van Moolenbroek if (control == 0)
464*00b67f09SDavid van Moolenbroek fork_and_wait(123, "save:my-output.txt", "Some error\n");
465*00b67f09SDavid van Moolenbroek else {
466*00b67f09SDavid van Moolenbroek int status;
467*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
468*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
469*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
470*00b67f09SDavid van Moolenbroek
471*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some output\n"));
472*00b67f09SDavid van Moolenbroek }
473*00b67f09SDavid van Moolenbroek }
474*00b67f09SDavid van Moolenbroek
475*00b67f09SDavid van Moolenbroek ATF_TC_WITHOUT_HEAD(wait__save_stderr);
ATF_TC_BODY(wait__save_stderr,tc)476*00b67f09SDavid van Moolenbroek ATF_TC_BODY(wait__save_stderr, tc)
477*00b67f09SDavid van Moolenbroek {
478*00b67f09SDavid van Moolenbroek const pid_t control = fork();
479*00b67f09SDavid van Moolenbroek ATF_REQUIRE(control != -1);
480*00b67f09SDavid van Moolenbroek if (control == 0)
481*00b67f09SDavid van Moolenbroek fork_and_wait(123, "Some output\n", "save:my-output.txt");
482*00b67f09SDavid van Moolenbroek else {
483*00b67f09SDavid van Moolenbroek int status;
484*00b67f09SDavid van Moolenbroek ATF_REQUIRE(waitpid(control, &status, 0) != -1);
485*00b67f09SDavid van Moolenbroek ATF_REQUIRE(WIFEXITED(status));
486*00b67f09SDavid van Moolenbroek ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
487*00b67f09SDavid van Moolenbroek
488*00b67f09SDavid van Moolenbroek ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some error\n"));
489*00b67f09SDavid van Moolenbroek }
490*00b67f09SDavid van Moolenbroek }
491*00b67f09SDavid van Moolenbroek
492*00b67f09SDavid van Moolenbroek HEADER_TC(include, "atf-c/utils.h");
493*00b67f09SDavid van Moolenbroek
ATF_TP_ADD_TCS(tp)494*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TCS(tp)
495*00b67f09SDavid van Moolenbroek {
496*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, cat_file__empty);
497*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, cat_file__one_line);
498*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, cat_file__several_lines);
499*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, cat_file__no_newline_eof);
500*00b67f09SDavid van Moolenbroek
501*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__empty__match);
502*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__empty__not_match);
503*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__short__match);
504*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__short__not_match);
505*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__long__match);
506*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, compare_file__long__not_match);
507*00b67f09SDavid van Moolenbroek
508*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, copy_file__empty);
509*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, copy_file__some_contents);
510*00b67f09SDavid van Moolenbroek
511*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, create_file);
512*00b67f09SDavid van Moolenbroek
513*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, file_exists);
514*00b67f09SDavid van Moolenbroek
515*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, fork);
516*00b67f09SDavid van Moolenbroek
517*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, free_charpp__empty);
518*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, free_charpp__some);
519*00b67f09SDavid van Moolenbroek
520*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, grep_file);
521*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, grep_string);
522*00b67f09SDavid van Moolenbroek
523*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, readline__none);
524*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, readline__some);
525*00b67f09SDavid van Moolenbroek
526*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, redirect__stdout);
527*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, redirect__stderr);
528*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, redirect__other);
529*00b67f09SDavid van Moolenbroek
530*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__ok);
531*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__save_stdout);
532*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__save_stderr);
533*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__invalid_exitstatus);
534*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__invalid_stdout);
535*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, wait__invalid_stderr);
536*00b67f09SDavid van Moolenbroek
537*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TC(tp, include);
538*00b67f09SDavid van Moolenbroek
539*00b67f09SDavid van Moolenbroek return atf_no_error();
540*00b67f09SDavid van Moolenbroek }
541