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