1273929Sjmmv/* Copyright (c) 2010 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/utils.h" 27273929Sjmmv 28258289Sjmmv#include <sys/stat.h> 29258289Sjmmv#include <sys/wait.h> 30258289Sjmmv 31258289Sjmmv#include <fcntl.h> 32258289Sjmmv#include <stddef.h> 33258289Sjmmv#include <stdio.h> 34240116Smarcel#include <stdlib.h> 35240116Smarcel#include <string.h> 36258289Sjmmv#include <unistd.h> 37240116Smarcel 38240116Smarcel#include <atf-c.h> 39240116Smarcel 40273929Sjmmv#include "atf-c/detail/dynstr.h" 41273929Sjmmv#include "atf-c/detail/test_helpers.h" 42240116Smarcel 43258289Sjmmv/** Reads the contents of a file into a buffer. 44258289Sjmmv * 45258289Sjmmv * Up to buflen-1 characters are read into buffer. If this function returns, 46258289Sjmmv * the contents read into the buffer are guaranteed to be nul-terminated. 47258289Sjmmv * Note, however, that if the file contains any nul characters itself, 48258289Sjmmv * comparing it "as a string" will not work. 49258289Sjmmv * 50258289Sjmmv * \param path The file to be read, which must exist. 51258289Sjmmv * \param buffer Buffer into which to store the file contents. 52258289Sjmmv * \param buflen Size of the target buffer. 53258289Sjmmv * 54258289Sjmmv * \return The count of bytes read. */ 55258289Sjmmvstatic ssize_t 56258289Sjmmvread_file(const char *path, void *const buffer, const size_t buflen) 57240116Smarcel{ 58258289Sjmmv const int fd = open(path, O_RDONLY); 59258289Sjmmv ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", path); 60258289Sjmmv const ssize_t length = read(fd, buffer, buflen - 1); 61258289Sjmmv close(fd); 62258289Sjmmv ATF_REQUIRE(length != -1); 63258289Sjmmv ((char *)buffer)[length] = '\0'; 64258289Sjmmv return length; 65258289Sjmmv} 66258289Sjmmv 67258289SjmmvATF_TC_WITHOUT_HEAD(cat_file__empty); 68258289SjmmvATF_TC_BODY(cat_file__empty, tc) 69258289Sjmmv{ 70258289Sjmmv atf_utils_create_file("file.txt", "%s", ""); 71258289Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 72258289Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 73258289Sjmmv fflush(stdout); 74258289Sjmmv close(STDOUT_FILENO); 75258289Sjmmv 76258289Sjmmv char buffer[1024]; 77258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 78258289Sjmmv ATF_REQUIRE_STREQ("", buffer); 79258289Sjmmv} 80258289Sjmmv 81258289SjmmvATF_TC_WITHOUT_HEAD(cat_file__one_line); 82258289SjmmvATF_TC_BODY(cat_file__one_line, tc) 83258289Sjmmv{ 84258289Sjmmv atf_utils_create_file("file.txt", "This is a single line\n"); 85258289Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 86258289Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 87258289Sjmmv fflush(stdout); 88258289Sjmmv close(STDOUT_FILENO); 89258289Sjmmv 90258289Sjmmv char buffer[1024]; 91258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 92258289Sjmmv ATF_REQUIRE_STREQ("PREFIXThis is a single line\n", buffer); 93258289Sjmmv} 94258289Sjmmv 95258289SjmmvATF_TC_WITHOUT_HEAD(cat_file__several_lines); 96258289SjmmvATF_TC_BODY(cat_file__several_lines, tc) 97258289Sjmmv{ 98258289Sjmmv atf_utils_create_file("file.txt", "First\nSecond line\nAnd third\n"); 99258289Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 100258289Sjmmv atf_utils_cat_file("file.txt", ">"); 101258289Sjmmv fflush(stdout); 102258289Sjmmv close(STDOUT_FILENO); 103258289Sjmmv 104258289Sjmmv char buffer[1024]; 105258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 106258289Sjmmv ATF_REQUIRE_STREQ(">First\n>Second line\n>And third\n", buffer); 107258289Sjmmv} 108258289Sjmmv 109258289SjmmvATF_TC_WITHOUT_HEAD(cat_file__no_newline_eof); 110258289SjmmvATF_TC_BODY(cat_file__no_newline_eof, tc) 111258289Sjmmv{ 112258289Sjmmv atf_utils_create_file("file.txt", "Foo\n bar baz"); 113258289Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 114258289Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 115258289Sjmmv fflush(stdout); 116258289Sjmmv close(STDOUT_FILENO); 117258289Sjmmv 118258289Sjmmv char buffer[1024]; 119258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 120258289Sjmmv ATF_REQUIRE_STREQ("PREFIXFoo\nPREFIX bar baz", buffer); 121258289Sjmmv} 122258289Sjmmv 123258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__empty__match); 124258289SjmmvATF_TC_BODY(compare_file__empty__match, tc) 125258289Sjmmv{ 126258289Sjmmv atf_utils_create_file("test.txt", "%s", ""); 127258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", "")); 128258289Sjmmv} 129258289Sjmmv 130258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__empty__not_match); 131258289SjmmvATF_TC_BODY(compare_file__empty__not_match, tc) 132258289Sjmmv{ 133258289Sjmmv atf_utils_create_file("test.txt", "%s", ""); 134258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 135258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "foo")); 136258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", " ")); 137258289Sjmmv} 138258289Sjmmv 139258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__short__match); 140258289SjmmvATF_TC_BODY(compare_file__short__match, tc) 141258289Sjmmv{ 142258289Sjmmv atf_utils_create_file("test.txt", "this is a short file"); 143258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", "this is a short file")); 144258289Sjmmv} 145258289Sjmmv 146258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__short__not_match); 147258289SjmmvATF_TC_BODY(compare_file__short__not_match, tc) 148258289Sjmmv{ 149258289Sjmmv atf_utils_create_file("test.txt", "this is a short file"); 150258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "")); 151258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 152258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a Short file")); 153258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short fil")); 154258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short file ")); 155258289Sjmmv} 156258289Sjmmv 157258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__long__match); 158258289SjmmvATF_TC_BODY(compare_file__long__match, tc) 159258289Sjmmv{ 160258289Sjmmv char long_contents[3456]; 161258289Sjmmv size_t i = 0; 162258289Sjmmv for (; i < sizeof(long_contents) - 1; i++) 163258289Sjmmv long_contents[i] = '0' + (i % 10); 164258289Sjmmv long_contents[i] = '\0'; 165258289Sjmmv atf_utils_create_file("test.txt", "%s", long_contents); 166258289Sjmmv 167258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", long_contents)); 168258289Sjmmv} 169258289Sjmmv 170258289SjmmvATF_TC_WITHOUT_HEAD(compare_file__long__not_match); 171258289SjmmvATF_TC_BODY(compare_file__long__not_match, tc) 172258289Sjmmv{ 173258289Sjmmv char long_contents[3456]; 174258289Sjmmv size_t i = 0; 175258289Sjmmv for (; i < sizeof(long_contents) - 1; i++) 176258289Sjmmv long_contents[i] = '0' + (i % 10); 177258289Sjmmv long_contents[i] = '\0'; 178258289Sjmmv atf_utils_create_file("test.txt", "%s", long_contents); 179258289Sjmmv 180258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "")); 181258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 182258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "0123456789")); 183258289Sjmmv long_contents[i - 1] = 'Z'; 184258289Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", long_contents)); 185258289Sjmmv} 186258289Sjmmv 187258289SjmmvATF_TC_WITHOUT_HEAD(copy_file__empty); 188258289SjmmvATF_TC_BODY(copy_file__empty, tc) 189258289Sjmmv{ 190258289Sjmmv atf_utils_create_file("src.txt", "%s", ""); 191258289Sjmmv ATF_REQUIRE(chmod("src.txt", 0520) != -1); 192258289Sjmmv 193258289Sjmmv atf_utils_copy_file("src.txt", "dest.txt"); 194258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("dest.txt", "")); 195258289Sjmmv struct stat sb; 196258289Sjmmv ATF_REQUIRE(stat("dest.txt", &sb) != -1); 197258289Sjmmv ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff); 198258289Sjmmv} 199258289Sjmmv 200258289SjmmvATF_TC_WITHOUT_HEAD(copy_file__some_contents); 201258289SjmmvATF_TC_BODY(copy_file__some_contents, tc) 202258289Sjmmv{ 203258289Sjmmv atf_utils_create_file("src.txt", "This is a\ntest file\n"); 204258289Sjmmv atf_utils_copy_file("src.txt", "dest.txt"); 205258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("dest.txt", "This is a\ntest file\n")); 206258289Sjmmv} 207258289Sjmmv 208258289SjmmvATF_TC_WITHOUT_HEAD(create_file); 209258289SjmmvATF_TC_BODY(create_file, tc) 210258289Sjmmv{ 211258289Sjmmv atf_utils_create_file("test.txt", "This is a test with %d", 12345); 212258289Sjmmv 213258289Sjmmv char buffer[128]; 214258289Sjmmv read_file("test.txt", buffer, sizeof(buffer)); 215258289Sjmmv ATF_REQUIRE_STREQ("This is a test with 12345", buffer); 216258289Sjmmv} 217258289Sjmmv 218258289SjmmvATF_TC_WITHOUT_HEAD(file_exists); 219258289SjmmvATF_TC_BODY(file_exists, tc) 220258289Sjmmv{ 221258289Sjmmv atf_utils_create_file("test.txt", "foo"); 222258289Sjmmv 223258289Sjmmv ATF_REQUIRE( atf_utils_file_exists("test.txt")); 224258289Sjmmv ATF_REQUIRE( atf_utils_file_exists("./test.txt")); 225258289Sjmmv ATF_REQUIRE(!atf_utils_file_exists("./test.tx")); 226258289Sjmmv ATF_REQUIRE(!atf_utils_file_exists("test.txt2")); 227258289Sjmmv} 228258289Sjmmv 229258289SjmmvATF_TC_WITHOUT_HEAD(fork); 230258289SjmmvATF_TC_BODY(fork, tc) 231258289Sjmmv{ 232258289Sjmmv fprintf(stdout, "Should not get into child\n"); 233258289Sjmmv fprintf(stderr, "Should not get into child\n"); 234258289Sjmmv pid_t pid = atf_utils_fork(); 235258289Sjmmv if (pid == 0) { 236258289Sjmmv fprintf(stdout, "Child stdout\n"); 237258289Sjmmv fprintf(stderr, "Child stderr\n"); 238258289Sjmmv exit(EXIT_SUCCESS); 239258289Sjmmv } 240258289Sjmmv 241258289Sjmmv int status; 242258289Sjmmv ATF_REQUIRE(waitpid(pid, &status, 0) != -1); 243258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 244258289Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 245258289Sjmmv 246273929Sjmmv atf_dynstr_t out_name; 247273929Sjmmv RE(atf_dynstr_init_fmt(&out_name, "atf_utils_fork_%d_out.txt", (int)pid)); 248273929Sjmmv atf_dynstr_t err_name; 249273929Sjmmv RE(atf_dynstr_init_fmt(&err_name, "atf_utils_fork_%d_err.txt", (int)pid)); 250273929Sjmmv 251258289Sjmmv char buffer[1024]; 252273929Sjmmv read_file(atf_dynstr_cstring(&out_name), buffer, sizeof(buffer)); 253258289Sjmmv ATF_REQUIRE_STREQ("Child stdout\n", buffer); 254273929Sjmmv read_file(atf_dynstr_cstring(&err_name), buffer, sizeof(buffer)); 255258289Sjmmv ATF_REQUIRE_STREQ("Child stderr\n", buffer); 256273929Sjmmv 257273929Sjmmv atf_dynstr_fini(&err_name); 258273929Sjmmv atf_dynstr_fini(&out_name); 259258289Sjmmv} 260258289Sjmmv 261258289SjmmvATF_TC_WITHOUT_HEAD(free_charpp__empty); 262258289SjmmvATF_TC_BODY(free_charpp__empty, tc) 263258289Sjmmv{ 264240116Smarcel char **array = malloc(sizeof(char *) * 1); 265240116Smarcel array[0] = NULL; 266240116Smarcel 267240116Smarcel atf_utils_free_charpp(array); 268240116Smarcel} 269240116Smarcel 270258289SjmmvATF_TC_WITHOUT_HEAD(free_charpp__some); 271258289SjmmvATF_TC_BODY(free_charpp__some, tc) 272240116Smarcel{ 273240116Smarcel char **array = malloc(sizeof(char *) * 4); 274240116Smarcel array[0] = strdup("first"); 275240116Smarcel array[1] = strdup("second"); 276240116Smarcel array[2] = strdup("third"); 277240116Smarcel array[3] = NULL; 278240116Smarcel 279240116Smarcel atf_utils_free_charpp(array); 280240116Smarcel} 281240116Smarcel 282258289SjmmvATF_TC_WITHOUT_HEAD(grep_file); 283258289SjmmvATF_TC_BODY(grep_file, tc) 284258289Sjmmv{ 285258289Sjmmv atf_utils_create_file("test.txt", "line1\nthe second line\naaaabbbb\n"); 286258289Sjmmv 287258289Sjmmv ATF_CHECK(atf_utils_grep_file("line1", "test.txt")); 288258289Sjmmv ATF_CHECK(atf_utils_grep_file("line%d", "test.txt", 1)); 289258289Sjmmv ATF_CHECK(atf_utils_grep_file("second line", "test.txt")); 290258289Sjmmv ATF_CHECK(atf_utils_grep_file("aa.*bb", "test.txt")); 291258289Sjmmv ATF_CHECK(!atf_utils_grep_file("foo", "test.txt")); 292258289Sjmmv ATF_CHECK(!atf_utils_grep_file("bar", "test.txt")); 293258289Sjmmv ATF_CHECK(!atf_utils_grep_file("aaaaa", "test.txt")); 294258289Sjmmv} 295258289Sjmmv 296258289SjmmvATF_TC_WITHOUT_HEAD(grep_string); 297258289SjmmvATF_TC_BODY(grep_string, tc) 298258289Sjmmv{ 299258289Sjmmv const char *str = "a string - aaaabbbb"; 300258289Sjmmv ATF_CHECK(atf_utils_grep_string("a string", str)); 301258289Sjmmv ATF_CHECK(atf_utils_grep_string("^a string", str)); 302258289Sjmmv ATF_CHECK(atf_utils_grep_string("aaaabbbb$", str)); 303258289Sjmmv ATF_CHECK(atf_utils_grep_string("a%s*bb", str, "a.")); 304258289Sjmmv ATF_CHECK(!atf_utils_grep_string("foo", str)); 305258289Sjmmv ATF_CHECK(!atf_utils_grep_string("bar", str)); 306258289Sjmmv ATF_CHECK(!atf_utils_grep_string("aaaaa", str)); 307258289Sjmmv} 308258289Sjmmv 309258289SjmmvATF_TC_WITHOUT_HEAD(readline__none); 310258289SjmmvATF_TC_BODY(readline__none, tc) 311258289Sjmmv{ 312258289Sjmmv atf_utils_create_file("empty.txt", "%s", ""); 313258289Sjmmv 314258289Sjmmv const int fd = open("empty.txt", O_RDONLY); 315258289Sjmmv ATF_REQUIRE(fd != -1); 316258289Sjmmv ATF_REQUIRE(atf_utils_readline(fd) == NULL); 317258289Sjmmv close(fd); 318258289Sjmmv} 319258289Sjmmv 320258289SjmmvATF_TC_WITHOUT_HEAD(readline__some); 321258289SjmmvATF_TC_BODY(readline__some, tc) 322258289Sjmmv{ 323258289Sjmmv const char *l1 = "First line with % formatting % characters %"; 324258289Sjmmv const char *l2 = "Second line; much longer than the first one"; 325258289Sjmmv const char *l3 = "Last line, without terminator"; 326258289Sjmmv 327258289Sjmmv atf_utils_create_file("test.txt", "%s\n%s\n%s", l1, l2, l3); 328258289Sjmmv 329258289Sjmmv const int fd = open("test.txt", O_RDONLY); 330258289Sjmmv ATF_REQUIRE(fd != -1); 331258289Sjmmv 332258289Sjmmv char *line; 333258289Sjmmv 334258289Sjmmv line = atf_utils_readline(fd); 335258289Sjmmv ATF_REQUIRE_STREQ(l1, line); 336258289Sjmmv free(line); 337258289Sjmmv 338258289Sjmmv line = atf_utils_readline(fd); 339258289Sjmmv ATF_REQUIRE_STREQ(l2, line); 340258289Sjmmv free(line); 341258289Sjmmv 342258289Sjmmv line = atf_utils_readline(fd); 343258289Sjmmv ATF_REQUIRE_STREQ(l3, line); 344258289Sjmmv free(line); 345258289Sjmmv 346258289Sjmmv close(fd); 347258289Sjmmv} 348258289Sjmmv 349258289SjmmvATF_TC_WITHOUT_HEAD(redirect__stdout); 350258289SjmmvATF_TC_BODY(redirect__stdout, tc) 351258289Sjmmv{ 352258289Sjmmv printf("Buffer this"); 353258289Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 354258289Sjmmv printf("The printed message"); 355258289Sjmmv fflush(stdout); 356258289Sjmmv 357258289Sjmmv char buffer[1024]; 358258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 359258289Sjmmv ATF_REQUIRE_STREQ("The printed message", buffer); 360258289Sjmmv} 361258289Sjmmv 362258289SjmmvATF_TC_WITHOUT_HEAD(redirect__stderr); 363258289SjmmvATF_TC_BODY(redirect__stderr, tc) 364258289Sjmmv{ 365258289Sjmmv fprintf(stderr, "Buffer this"); 366258289Sjmmv atf_utils_redirect(STDERR_FILENO, "captured.txt"); 367258289Sjmmv fprintf(stderr, "The printed message"); 368258289Sjmmv fflush(stderr); 369258289Sjmmv 370258289Sjmmv char buffer[1024]; 371258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 372258289Sjmmv ATF_REQUIRE_STREQ("The printed message", buffer); 373258289Sjmmv} 374258289Sjmmv 375258289SjmmvATF_TC_WITHOUT_HEAD(redirect__other); 376258289SjmmvATF_TC_BODY(redirect__other, tc) 377258289Sjmmv{ 378258289Sjmmv const char *message = "Foo bar\nbaz\n"; 379258289Sjmmv atf_utils_redirect(15, "captured.txt"); 380258289Sjmmv ATF_REQUIRE(write(15, message, strlen(message)) != -1); 381258289Sjmmv close(15); 382258289Sjmmv 383258289Sjmmv char buffer[1024]; 384258289Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 385258289Sjmmv ATF_REQUIRE_STREQ(message, buffer); 386258289Sjmmv} 387258289Sjmmv 388258289Sjmmvstatic void 389258289Sjmmvfork_and_wait(const int exitstatus, const char* expout, const char* experr) 390258289Sjmmv{ 391258289Sjmmv const pid_t pid = atf_utils_fork(); 392273929Sjmmv ATF_REQUIRE(pid != -1); 393258289Sjmmv if (pid == 0) { 394258289Sjmmv fprintf(stdout, "Some output\n"); 395258289Sjmmv fprintf(stderr, "Some error\n"); 396258289Sjmmv exit(123); 397258289Sjmmv } 398258289Sjmmv atf_utils_wait(pid, exitstatus, expout, experr); 399258289Sjmmv exit(EXIT_SUCCESS); 400258289Sjmmv} 401258289Sjmmv 402258289SjmmvATF_TC_WITHOUT_HEAD(wait__ok); 403258289SjmmvATF_TC_BODY(wait__ok, tc) 404258289Sjmmv{ 405258289Sjmmv const pid_t control = fork(); 406258289Sjmmv ATF_REQUIRE(control != -1); 407258289Sjmmv if (control == 0) 408258289Sjmmv fork_and_wait(123, "Some output\n", "Some error\n"); 409258289Sjmmv else { 410258289Sjmmv int status; 411258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 412258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 413258289Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 414258289Sjmmv } 415258289Sjmmv} 416258289Sjmmv 417273929SjmmvATF_TC_WITHOUT_HEAD(wait__ok_nested); 418273929SjmmvATF_TC_BODY(wait__ok_nested, tc) 419273929Sjmmv{ 420273929Sjmmv const pid_t parent = atf_utils_fork(); 421273929Sjmmv ATF_REQUIRE(parent != -1); 422273929Sjmmv if (parent == 0) { 423273929Sjmmv const pid_t child = atf_utils_fork(); 424273929Sjmmv ATF_REQUIRE(child != -1); 425273929Sjmmv if (child == 0) { 426273929Sjmmv fflush(stderr); 427273929Sjmmv fprintf(stdout, "Child output\n"); 428273929Sjmmv fflush(stdout); 429273929Sjmmv fprintf(stderr, "Child error\n"); 430273929Sjmmv exit(50); 431273929Sjmmv } else { 432273929Sjmmv fprintf(stdout, "Parent output\n"); 433273929Sjmmv fprintf(stderr, "Parent error\n"); 434273929Sjmmv atf_utils_wait(child, 50, "Child output\n", "Child error\n"); 435273929Sjmmv exit(40); 436273929Sjmmv } 437273929Sjmmv } else { 438273929Sjmmv atf_utils_wait(parent, 40, 439273929Sjmmv "Parent output\n" 440273929Sjmmv "subprocess stdout: Child output\n" 441273929Sjmmv "subprocess stderr: Child error\n", 442273929Sjmmv "Parent error\n"); 443273929Sjmmv } 444273929Sjmmv} 445273929Sjmmv 446258289SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_exitstatus); 447258289SjmmvATF_TC_BODY(wait__invalid_exitstatus, tc) 448258289Sjmmv{ 449258289Sjmmv const pid_t control = fork(); 450258289Sjmmv ATF_REQUIRE(control != -1); 451258289Sjmmv if (control == 0) 452258289Sjmmv fork_and_wait(120, "Some output\n", "Some error\n"); 453258289Sjmmv else { 454258289Sjmmv int status; 455258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 456258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 457258289Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 458258289Sjmmv } 459258289Sjmmv} 460258289Sjmmv 461258289SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_stdout); 462258289SjmmvATF_TC_BODY(wait__invalid_stdout, tc) 463258289Sjmmv{ 464258289Sjmmv const pid_t control = fork(); 465258289Sjmmv ATF_REQUIRE(control != -1); 466258289Sjmmv if (control == 0) 467258289Sjmmv fork_and_wait(123, "Some output foo\n", "Some error\n"); 468258289Sjmmv else { 469258289Sjmmv int status; 470258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 471258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 472258289Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 473258289Sjmmv } 474258289Sjmmv} 475258289Sjmmv 476258289SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_stderr); 477258289SjmmvATF_TC_BODY(wait__invalid_stderr, tc) 478258289Sjmmv{ 479258289Sjmmv const pid_t control = fork(); 480258289Sjmmv ATF_REQUIRE(control != -1); 481258289Sjmmv if (control == 0) 482258289Sjmmv fork_and_wait(123, "Some output\n", "Some error foo\n"); 483258289Sjmmv else { 484258289Sjmmv int status; 485258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 486258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 487258289Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 488258289Sjmmv } 489258289Sjmmv} 490258289Sjmmv 491258289SjmmvATF_TC_WITHOUT_HEAD(wait__save_stdout); 492258289SjmmvATF_TC_BODY(wait__save_stdout, tc) 493258289Sjmmv{ 494258289Sjmmv const pid_t control = fork(); 495258289Sjmmv ATF_REQUIRE(control != -1); 496258289Sjmmv if (control == 0) 497258289Sjmmv fork_and_wait(123, "save:my-output.txt", "Some error\n"); 498258289Sjmmv else { 499258289Sjmmv int status; 500258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 501258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 502258289Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 503258289Sjmmv 504258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some output\n")); 505258289Sjmmv } 506258289Sjmmv} 507258289Sjmmv 508258289SjmmvATF_TC_WITHOUT_HEAD(wait__save_stderr); 509258289SjmmvATF_TC_BODY(wait__save_stderr, tc) 510258289Sjmmv{ 511258289Sjmmv const pid_t control = fork(); 512258289Sjmmv ATF_REQUIRE(control != -1); 513258289Sjmmv if (control == 0) 514258289Sjmmv fork_and_wait(123, "Some output\n", "save:my-output.txt"); 515258289Sjmmv else { 516258289Sjmmv int status; 517258289Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 518258289Sjmmv ATF_REQUIRE(WIFEXITED(status)); 519258289Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 520258289Sjmmv 521258289Sjmmv ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some error\n")); 522258289Sjmmv } 523258289Sjmmv} 524258289Sjmmv 525240116SmarcelATF_TP_ADD_TCS(tp) 526240116Smarcel{ 527258289Sjmmv ATF_TP_ADD_TC(tp, cat_file__empty); 528258289Sjmmv ATF_TP_ADD_TC(tp, cat_file__one_line); 529258289Sjmmv ATF_TP_ADD_TC(tp, cat_file__several_lines); 530258289Sjmmv ATF_TP_ADD_TC(tp, cat_file__no_newline_eof); 531240116Smarcel 532258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__empty__match); 533258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__empty__not_match); 534258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__short__match); 535258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__short__not_match); 536258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__long__match); 537258289Sjmmv ATF_TP_ADD_TC(tp, compare_file__long__not_match); 538258289Sjmmv 539258289Sjmmv ATF_TP_ADD_TC(tp, copy_file__empty); 540258289Sjmmv ATF_TP_ADD_TC(tp, copy_file__some_contents); 541258289Sjmmv 542258289Sjmmv ATF_TP_ADD_TC(tp, create_file); 543258289Sjmmv 544258289Sjmmv ATF_TP_ADD_TC(tp, file_exists); 545258289Sjmmv 546258289Sjmmv ATF_TP_ADD_TC(tp, fork); 547258289Sjmmv 548258289Sjmmv ATF_TP_ADD_TC(tp, free_charpp__empty); 549258289Sjmmv ATF_TP_ADD_TC(tp, free_charpp__some); 550258289Sjmmv 551258289Sjmmv ATF_TP_ADD_TC(tp, grep_file); 552258289Sjmmv ATF_TP_ADD_TC(tp, grep_string); 553258289Sjmmv 554258289Sjmmv ATF_TP_ADD_TC(tp, readline__none); 555258289Sjmmv ATF_TP_ADD_TC(tp, readline__some); 556258289Sjmmv 557258289Sjmmv ATF_TP_ADD_TC(tp, redirect__stdout); 558258289Sjmmv ATF_TP_ADD_TC(tp, redirect__stderr); 559258289Sjmmv ATF_TP_ADD_TC(tp, redirect__other); 560258289Sjmmv 561258289Sjmmv ATF_TP_ADD_TC(tp, wait__ok); 562273929Sjmmv ATF_TP_ADD_TC(tp, wait__ok_nested); 563258289Sjmmv ATF_TP_ADD_TC(tp, wait__save_stdout); 564258289Sjmmv ATF_TP_ADD_TC(tp, wait__save_stderr); 565258289Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_exitstatus); 566258289Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_stdout); 567258289Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_stderr); 568258289Sjmmv 569240116Smarcel return atf_no_error(); 570240116Smarcel} 571