1240116Smarcel/* 2240116Smarcel * Automated Testing Framework (atf) 3240116Smarcel * 4240116Smarcel * Copyright (c) 2010 The NetBSD Foundation, Inc. 5240116Smarcel * All rights reserved. 6240116Smarcel * 7240116Smarcel * Redistribution and use in source and binary forms, with or without 8240116Smarcel * modification, are permitted provided that the following conditions 9240116Smarcel * are met: 10240116Smarcel * 1. Redistributions of source code must retain the above copyright 11240116Smarcel * notice, this list of conditions and the following disclaimer. 12240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright 13240116Smarcel * notice, this list of conditions and the following disclaimer in the 14240116Smarcel * documentation and/or other materials provided with the distribution. 15240116Smarcel * 16240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27240116Smarcel * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28240116Smarcel */ 29240116Smarcel 30260029Sjmmv#include <sys/stat.h> 31260029Sjmmv#include <sys/wait.h> 32260029Sjmmv 33260029Sjmmv#include <fcntl.h> 34260029Sjmmv#include <stddef.h> 35260029Sjmmv#include <stdio.h> 36240116Smarcel#include <stdlib.h> 37240116Smarcel#include <string.h> 38260029Sjmmv#include <unistd.h> 39240116Smarcel 40240116Smarcel#include <atf-c.h> 41240116Smarcel 42240116Smarcel#include "atf-c/utils.h" 43240116Smarcel 44240116Smarcel#include "detail/test_helpers.h" 45240116Smarcel 46260029Sjmmv/** Reads the contents of a file into a buffer. 47260029Sjmmv * 48260029Sjmmv * Up to buflen-1 characters are read into buffer. If this function returns, 49260029Sjmmv * the contents read into the buffer are guaranteed to be nul-terminated. 50260029Sjmmv * Note, however, that if the file contains any nul characters itself, 51260029Sjmmv * comparing it "as a string" will not work. 52260029Sjmmv * 53260029Sjmmv * \param path The file to be read, which must exist. 54260029Sjmmv * \param buffer Buffer into which to store the file contents. 55260029Sjmmv * \param buflen Size of the target buffer. 56260029Sjmmv * 57260029Sjmmv * \return The count of bytes read. */ 58260029Sjmmvstatic ssize_t 59260029Sjmmvread_file(const char *path, void *const buffer, const size_t buflen) 60240116Smarcel{ 61260029Sjmmv const int fd = open(path, O_RDONLY); 62260029Sjmmv ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", path); 63260029Sjmmv const ssize_t length = read(fd, buffer, buflen - 1); 64260029Sjmmv close(fd); 65260029Sjmmv ATF_REQUIRE(length != -1); 66260029Sjmmv ((char *)buffer)[length] = '\0'; 67260029Sjmmv return length; 68260029Sjmmv} 69260029Sjmmv 70260029SjmmvATF_TC_WITHOUT_HEAD(cat_file__empty); 71260029SjmmvATF_TC_BODY(cat_file__empty, tc) 72260029Sjmmv{ 73260029Sjmmv atf_utils_create_file("file.txt", "%s", ""); 74260029Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 75260029Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 76260029Sjmmv fflush(stdout); 77260029Sjmmv close(STDOUT_FILENO); 78260029Sjmmv 79260029Sjmmv char buffer[1024]; 80260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 81260029Sjmmv ATF_REQUIRE_STREQ("", buffer); 82260029Sjmmv} 83260029Sjmmv 84260029SjmmvATF_TC_WITHOUT_HEAD(cat_file__one_line); 85260029SjmmvATF_TC_BODY(cat_file__one_line, tc) 86260029Sjmmv{ 87260029Sjmmv atf_utils_create_file("file.txt", "This is a single line\n"); 88260029Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 89260029Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 90260029Sjmmv fflush(stdout); 91260029Sjmmv close(STDOUT_FILENO); 92260029Sjmmv 93260029Sjmmv char buffer[1024]; 94260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 95260029Sjmmv ATF_REQUIRE_STREQ("PREFIXThis is a single line\n", buffer); 96260029Sjmmv} 97260029Sjmmv 98260029SjmmvATF_TC_WITHOUT_HEAD(cat_file__several_lines); 99260029SjmmvATF_TC_BODY(cat_file__several_lines, tc) 100260029Sjmmv{ 101260029Sjmmv atf_utils_create_file("file.txt", "First\nSecond line\nAnd third\n"); 102260029Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 103260029Sjmmv atf_utils_cat_file("file.txt", ">"); 104260029Sjmmv fflush(stdout); 105260029Sjmmv close(STDOUT_FILENO); 106260029Sjmmv 107260029Sjmmv char buffer[1024]; 108260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 109260029Sjmmv ATF_REQUIRE_STREQ(">First\n>Second line\n>And third\n", buffer); 110260029Sjmmv} 111260029Sjmmv 112260029SjmmvATF_TC_WITHOUT_HEAD(cat_file__no_newline_eof); 113260029SjmmvATF_TC_BODY(cat_file__no_newline_eof, tc) 114260029Sjmmv{ 115260029Sjmmv atf_utils_create_file("file.txt", "Foo\n bar baz"); 116260029Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 117260029Sjmmv atf_utils_cat_file("file.txt", "PREFIX"); 118260029Sjmmv fflush(stdout); 119260029Sjmmv close(STDOUT_FILENO); 120260029Sjmmv 121260029Sjmmv char buffer[1024]; 122260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 123260029Sjmmv ATF_REQUIRE_STREQ("PREFIXFoo\nPREFIX bar baz", buffer); 124260029Sjmmv} 125260029Sjmmv 126260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__empty__match); 127260029SjmmvATF_TC_BODY(compare_file__empty__match, tc) 128260029Sjmmv{ 129260029Sjmmv atf_utils_create_file("test.txt", "%s", ""); 130260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", "")); 131260029Sjmmv} 132260029Sjmmv 133260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__empty__not_match); 134260029SjmmvATF_TC_BODY(compare_file__empty__not_match, tc) 135260029Sjmmv{ 136260029Sjmmv atf_utils_create_file("test.txt", "%s", ""); 137260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 138260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "foo")); 139260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", " ")); 140260029Sjmmv} 141260029Sjmmv 142260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__short__match); 143260029SjmmvATF_TC_BODY(compare_file__short__match, tc) 144260029Sjmmv{ 145260029Sjmmv atf_utils_create_file("test.txt", "this is a short file"); 146260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", "this is a short file")); 147260029Sjmmv} 148260029Sjmmv 149260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__short__not_match); 150260029SjmmvATF_TC_BODY(compare_file__short__not_match, tc) 151260029Sjmmv{ 152260029Sjmmv atf_utils_create_file("test.txt", "this is a short file"); 153260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "")); 154260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 155260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a Short file")); 156260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short fil")); 157260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short file ")); 158260029Sjmmv} 159260029Sjmmv 160260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__long__match); 161260029SjmmvATF_TC_BODY(compare_file__long__match, tc) 162260029Sjmmv{ 163260029Sjmmv char long_contents[3456]; 164260029Sjmmv size_t i = 0; 165260029Sjmmv for (; i < sizeof(long_contents) - 1; i++) 166260029Sjmmv long_contents[i] = '0' + (i % 10); 167260029Sjmmv long_contents[i] = '\0'; 168260029Sjmmv atf_utils_create_file("test.txt", "%s", long_contents); 169260029Sjmmv 170260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("test.txt", long_contents)); 171260029Sjmmv} 172260029Sjmmv 173260029SjmmvATF_TC_WITHOUT_HEAD(compare_file__long__not_match); 174260029SjmmvATF_TC_BODY(compare_file__long__not_match, tc) 175260029Sjmmv{ 176260029Sjmmv char long_contents[3456]; 177260029Sjmmv size_t i = 0; 178260029Sjmmv for (; i < sizeof(long_contents) - 1; i++) 179260029Sjmmv long_contents[i] = '0' + (i % 10); 180260029Sjmmv long_contents[i] = '\0'; 181260029Sjmmv atf_utils_create_file("test.txt", "%s", long_contents); 182260029Sjmmv 183260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "")); 184260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n")); 185260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", "0123456789")); 186260029Sjmmv long_contents[i - 1] = 'Z'; 187260029Sjmmv ATF_REQUIRE(!atf_utils_compare_file("test.txt", long_contents)); 188260029Sjmmv} 189260029Sjmmv 190260029SjmmvATF_TC_WITHOUT_HEAD(copy_file__empty); 191260029SjmmvATF_TC_BODY(copy_file__empty, tc) 192260029Sjmmv{ 193260029Sjmmv atf_utils_create_file("src.txt", "%s", ""); 194260029Sjmmv ATF_REQUIRE(chmod("src.txt", 0520) != -1); 195260029Sjmmv 196260029Sjmmv atf_utils_copy_file("src.txt", "dest.txt"); 197260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("dest.txt", "")); 198260029Sjmmv struct stat sb; 199260029Sjmmv ATF_REQUIRE(stat("dest.txt", &sb) != -1); 200260029Sjmmv ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff); 201260029Sjmmv} 202260029Sjmmv 203260029SjmmvATF_TC_WITHOUT_HEAD(copy_file__some_contents); 204260029SjmmvATF_TC_BODY(copy_file__some_contents, tc) 205260029Sjmmv{ 206260029Sjmmv atf_utils_create_file("src.txt", "This is a\ntest file\n"); 207260029Sjmmv atf_utils_copy_file("src.txt", "dest.txt"); 208260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("dest.txt", "This is a\ntest file\n")); 209260029Sjmmv} 210260029Sjmmv 211260029SjmmvATF_TC_WITHOUT_HEAD(create_file); 212260029SjmmvATF_TC_BODY(create_file, tc) 213260029Sjmmv{ 214260029Sjmmv atf_utils_create_file("test.txt", "This is a test with %d", 12345); 215260029Sjmmv 216260029Sjmmv char buffer[128]; 217260029Sjmmv read_file("test.txt", buffer, sizeof(buffer)); 218260029Sjmmv ATF_REQUIRE_STREQ("This is a test with 12345", buffer); 219260029Sjmmv} 220260029Sjmmv 221260029SjmmvATF_TC_WITHOUT_HEAD(file_exists); 222260029SjmmvATF_TC_BODY(file_exists, tc) 223260029Sjmmv{ 224260029Sjmmv atf_utils_create_file("test.txt", "foo"); 225260029Sjmmv 226260029Sjmmv ATF_REQUIRE( atf_utils_file_exists("test.txt")); 227260029Sjmmv ATF_REQUIRE( atf_utils_file_exists("./test.txt")); 228260029Sjmmv ATF_REQUIRE(!atf_utils_file_exists("./test.tx")); 229260029Sjmmv ATF_REQUIRE(!atf_utils_file_exists("test.txt2")); 230260029Sjmmv} 231260029Sjmmv 232260029SjmmvATF_TC_WITHOUT_HEAD(fork); 233260029SjmmvATF_TC_BODY(fork, tc) 234260029Sjmmv{ 235260029Sjmmv fprintf(stdout, "Should not get into child\n"); 236260029Sjmmv fprintf(stderr, "Should not get into child\n"); 237260029Sjmmv pid_t pid = atf_utils_fork(); 238260029Sjmmv if (pid == 0) { 239260029Sjmmv fprintf(stdout, "Child stdout\n"); 240260029Sjmmv fprintf(stderr, "Child stderr\n"); 241260029Sjmmv exit(EXIT_SUCCESS); 242260029Sjmmv } 243260029Sjmmv 244260029Sjmmv int status; 245260029Sjmmv ATF_REQUIRE(waitpid(pid, &status, 0) != -1); 246260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 247260029Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 248260029Sjmmv 249260029Sjmmv char buffer[1024]; 250260029Sjmmv read_file("atf_utils_fork_out.txt", buffer, sizeof(buffer)); 251260029Sjmmv ATF_REQUIRE_STREQ("Child stdout\n", buffer); 252260029Sjmmv read_file("atf_utils_fork_err.txt", buffer, sizeof(buffer)); 253260029Sjmmv ATF_REQUIRE_STREQ("Child stderr\n", buffer); 254260029Sjmmv} 255260029Sjmmv 256260029SjmmvATF_TC_WITHOUT_HEAD(free_charpp__empty); 257260029SjmmvATF_TC_BODY(free_charpp__empty, tc) 258260029Sjmmv{ 259240116Smarcel char **array = malloc(sizeof(char *) * 1); 260240116Smarcel array[0] = NULL; 261240116Smarcel 262240116Smarcel atf_utils_free_charpp(array); 263240116Smarcel} 264240116Smarcel 265260029SjmmvATF_TC_WITHOUT_HEAD(free_charpp__some); 266260029SjmmvATF_TC_BODY(free_charpp__some, tc) 267240116Smarcel{ 268240116Smarcel char **array = malloc(sizeof(char *) * 4); 269240116Smarcel array[0] = strdup("first"); 270240116Smarcel array[1] = strdup("second"); 271240116Smarcel array[2] = strdup("third"); 272240116Smarcel array[3] = NULL; 273240116Smarcel 274240116Smarcel atf_utils_free_charpp(array); 275240116Smarcel} 276240116Smarcel 277260029SjmmvATF_TC_WITHOUT_HEAD(grep_file); 278260029SjmmvATF_TC_BODY(grep_file, tc) 279260029Sjmmv{ 280260029Sjmmv atf_utils_create_file("test.txt", "line1\nthe second line\naaaabbbb\n"); 281260029Sjmmv 282260029Sjmmv ATF_CHECK(atf_utils_grep_file("line1", "test.txt")); 283260029Sjmmv ATF_CHECK(atf_utils_grep_file("line%d", "test.txt", 1)); 284260029Sjmmv ATF_CHECK(atf_utils_grep_file("second line", "test.txt")); 285260029Sjmmv ATF_CHECK(atf_utils_grep_file("aa.*bb", "test.txt")); 286260029Sjmmv ATF_CHECK(!atf_utils_grep_file("foo", "test.txt")); 287260029Sjmmv ATF_CHECK(!atf_utils_grep_file("bar", "test.txt")); 288260029Sjmmv ATF_CHECK(!atf_utils_grep_file("aaaaa", "test.txt")); 289260029Sjmmv} 290260029Sjmmv 291260029SjmmvATF_TC_WITHOUT_HEAD(grep_string); 292260029SjmmvATF_TC_BODY(grep_string, tc) 293260029Sjmmv{ 294260029Sjmmv const char *str = "a string - aaaabbbb"; 295260029Sjmmv ATF_CHECK(atf_utils_grep_string("a string", str)); 296260029Sjmmv ATF_CHECK(atf_utils_grep_string("^a string", str)); 297260029Sjmmv ATF_CHECK(atf_utils_grep_string("aaaabbbb$", str)); 298260029Sjmmv ATF_CHECK(atf_utils_grep_string("a%s*bb", str, "a.")); 299260029Sjmmv ATF_CHECK(!atf_utils_grep_string("foo", str)); 300260029Sjmmv ATF_CHECK(!atf_utils_grep_string("bar", str)); 301260029Sjmmv ATF_CHECK(!atf_utils_grep_string("aaaaa", str)); 302260029Sjmmv} 303260029Sjmmv 304260029SjmmvATF_TC_WITHOUT_HEAD(readline__none); 305260029SjmmvATF_TC_BODY(readline__none, tc) 306260029Sjmmv{ 307260029Sjmmv atf_utils_create_file("empty.txt", "%s", ""); 308260029Sjmmv 309260029Sjmmv const int fd = open("empty.txt", O_RDONLY); 310260029Sjmmv ATF_REQUIRE(fd != -1); 311260029Sjmmv ATF_REQUIRE(atf_utils_readline(fd) == NULL); 312260029Sjmmv close(fd); 313260029Sjmmv} 314260029Sjmmv 315260029SjmmvATF_TC_WITHOUT_HEAD(readline__some); 316260029SjmmvATF_TC_BODY(readline__some, tc) 317260029Sjmmv{ 318260029Sjmmv const char *l1 = "First line with % formatting % characters %"; 319260029Sjmmv const char *l2 = "Second line; much longer than the first one"; 320260029Sjmmv const char *l3 = "Last line, without terminator"; 321260029Sjmmv 322260029Sjmmv atf_utils_create_file("test.txt", "%s\n%s\n%s", l1, l2, l3); 323260029Sjmmv 324260029Sjmmv const int fd = open("test.txt", O_RDONLY); 325260029Sjmmv ATF_REQUIRE(fd != -1); 326260029Sjmmv 327260029Sjmmv char *line; 328260029Sjmmv 329260029Sjmmv line = atf_utils_readline(fd); 330260029Sjmmv ATF_REQUIRE_STREQ(l1, line); 331260029Sjmmv free(line); 332260029Sjmmv 333260029Sjmmv line = atf_utils_readline(fd); 334260029Sjmmv ATF_REQUIRE_STREQ(l2, line); 335260029Sjmmv free(line); 336260029Sjmmv 337260029Sjmmv line = atf_utils_readline(fd); 338260029Sjmmv ATF_REQUIRE_STREQ(l3, line); 339260029Sjmmv free(line); 340260029Sjmmv 341260029Sjmmv close(fd); 342260029Sjmmv} 343260029Sjmmv 344260029SjmmvATF_TC_WITHOUT_HEAD(redirect__stdout); 345260029SjmmvATF_TC_BODY(redirect__stdout, tc) 346260029Sjmmv{ 347260029Sjmmv printf("Buffer this"); 348260029Sjmmv atf_utils_redirect(STDOUT_FILENO, "captured.txt"); 349260029Sjmmv printf("The printed message"); 350260029Sjmmv fflush(stdout); 351260029Sjmmv 352260029Sjmmv char buffer[1024]; 353260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 354260029Sjmmv ATF_REQUIRE_STREQ("The printed message", buffer); 355260029Sjmmv} 356260029Sjmmv 357260029SjmmvATF_TC_WITHOUT_HEAD(redirect__stderr); 358260029SjmmvATF_TC_BODY(redirect__stderr, tc) 359260029Sjmmv{ 360260029Sjmmv fprintf(stderr, "Buffer this"); 361260029Sjmmv atf_utils_redirect(STDERR_FILENO, "captured.txt"); 362260029Sjmmv fprintf(stderr, "The printed message"); 363260029Sjmmv fflush(stderr); 364260029Sjmmv 365260029Sjmmv char buffer[1024]; 366260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 367260029Sjmmv ATF_REQUIRE_STREQ("The printed message", buffer); 368260029Sjmmv} 369260029Sjmmv 370260029SjmmvATF_TC_WITHOUT_HEAD(redirect__other); 371260029SjmmvATF_TC_BODY(redirect__other, tc) 372260029Sjmmv{ 373260029Sjmmv const char *message = "Foo bar\nbaz\n"; 374260029Sjmmv atf_utils_redirect(15, "captured.txt"); 375260029Sjmmv ATF_REQUIRE(write(15, message, strlen(message)) != -1); 376260029Sjmmv close(15); 377260029Sjmmv 378260029Sjmmv char buffer[1024]; 379260029Sjmmv read_file("captured.txt", buffer, sizeof(buffer)); 380260029Sjmmv ATF_REQUIRE_STREQ(message, buffer); 381260029Sjmmv} 382260029Sjmmv 383260029Sjmmvstatic void 384260029Sjmmvfork_and_wait(const int exitstatus, const char* expout, const char* experr) 385260029Sjmmv{ 386260029Sjmmv const pid_t pid = atf_utils_fork(); 387260029Sjmmv if (pid == 0) { 388260029Sjmmv fprintf(stdout, "Some output\n"); 389260029Sjmmv fprintf(stderr, "Some error\n"); 390260029Sjmmv exit(123); 391260029Sjmmv } 392260029Sjmmv atf_utils_wait(pid, exitstatus, expout, experr); 393260029Sjmmv exit(EXIT_SUCCESS); 394260029Sjmmv} 395260029Sjmmv 396260029SjmmvATF_TC_WITHOUT_HEAD(wait__ok); 397260029SjmmvATF_TC_BODY(wait__ok, tc) 398260029Sjmmv{ 399260029Sjmmv const pid_t control = fork(); 400260029Sjmmv ATF_REQUIRE(control != -1); 401260029Sjmmv if (control == 0) 402260029Sjmmv fork_and_wait(123, "Some output\n", "Some error\n"); 403260029Sjmmv else { 404260029Sjmmv int status; 405260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 406260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 407260029Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 408260029Sjmmv } 409260029Sjmmv} 410260029Sjmmv 411260029SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_exitstatus); 412260029SjmmvATF_TC_BODY(wait__invalid_exitstatus, tc) 413260029Sjmmv{ 414260029Sjmmv const pid_t control = fork(); 415260029Sjmmv ATF_REQUIRE(control != -1); 416260029Sjmmv if (control == 0) 417260029Sjmmv fork_and_wait(120, "Some output\n", "Some error\n"); 418260029Sjmmv else { 419260029Sjmmv int status; 420260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 421260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 422260029Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 423260029Sjmmv } 424260029Sjmmv} 425260029Sjmmv 426260029SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_stdout); 427260029SjmmvATF_TC_BODY(wait__invalid_stdout, tc) 428260029Sjmmv{ 429260029Sjmmv const pid_t control = fork(); 430260029Sjmmv ATF_REQUIRE(control != -1); 431260029Sjmmv if (control == 0) 432260029Sjmmv fork_and_wait(123, "Some output foo\n", "Some error\n"); 433260029Sjmmv else { 434260029Sjmmv int status; 435260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 436260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 437260029Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 438260029Sjmmv } 439260029Sjmmv} 440260029Sjmmv 441260029SjmmvATF_TC_WITHOUT_HEAD(wait__invalid_stderr); 442260029SjmmvATF_TC_BODY(wait__invalid_stderr, tc) 443260029Sjmmv{ 444260029Sjmmv const pid_t control = fork(); 445260029Sjmmv ATF_REQUIRE(control != -1); 446260029Sjmmv if (control == 0) 447260029Sjmmv fork_and_wait(123, "Some output\n", "Some error foo\n"); 448260029Sjmmv else { 449260029Sjmmv int status; 450260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 451260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 452260029Sjmmv ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status)); 453260029Sjmmv } 454260029Sjmmv} 455260029Sjmmv 456260029SjmmvATF_TC_WITHOUT_HEAD(wait__save_stdout); 457260029SjmmvATF_TC_BODY(wait__save_stdout, tc) 458260029Sjmmv{ 459260029Sjmmv const pid_t control = fork(); 460260029Sjmmv ATF_REQUIRE(control != -1); 461260029Sjmmv if (control == 0) 462260029Sjmmv fork_and_wait(123, "save:my-output.txt", "Some error\n"); 463260029Sjmmv else { 464260029Sjmmv int status; 465260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 466260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 467260029Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 468260029Sjmmv 469260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some output\n")); 470260029Sjmmv } 471260029Sjmmv} 472260029Sjmmv 473260029SjmmvATF_TC_WITHOUT_HEAD(wait__save_stderr); 474260029SjmmvATF_TC_BODY(wait__save_stderr, tc) 475260029Sjmmv{ 476260029Sjmmv const pid_t control = fork(); 477260029Sjmmv ATF_REQUIRE(control != -1); 478260029Sjmmv if (control == 0) 479260029Sjmmv fork_and_wait(123, "Some output\n", "save:my-output.txt"); 480260029Sjmmv else { 481260029Sjmmv int status; 482260029Sjmmv ATF_REQUIRE(waitpid(control, &status, 0) != -1); 483260029Sjmmv ATF_REQUIRE(WIFEXITED(status)); 484260029Sjmmv ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 485260029Sjmmv 486260029Sjmmv ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some error\n")); 487260029Sjmmv } 488260029Sjmmv} 489260029Sjmmv 490240116SmarcelHEADER_TC(include, "atf-c/utils.h"); 491240116Smarcel 492240116SmarcelATF_TP_ADD_TCS(tp) 493240116Smarcel{ 494260029Sjmmv ATF_TP_ADD_TC(tp, cat_file__empty); 495260029Sjmmv ATF_TP_ADD_TC(tp, cat_file__one_line); 496260029Sjmmv ATF_TP_ADD_TC(tp, cat_file__several_lines); 497260029Sjmmv ATF_TP_ADD_TC(tp, cat_file__no_newline_eof); 498240116Smarcel 499260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__empty__match); 500260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__empty__not_match); 501260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__short__match); 502260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__short__not_match); 503260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__long__match); 504260029Sjmmv ATF_TP_ADD_TC(tp, compare_file__long__not_match); 505260029Sjmmv 506260029Sjmmv ATF_TP_ADD_TC(tp, copy_file__empty); 507260029Sjmmv ATF_TP_ADD_TC(tp, copy_file__some_contents); 508260029Sjmmv 509260029Sjmmv ATF_TP_ADD_TC(tp, create_file); 510260029Sjmmv 511260029Sjmmv ATF_TP_ADD_TC(tp, file_exists); 512260029Sjmmv 513260029Sjmmv ATF_TP_ADD_TC(tp, fork); 514260029Sjmmv 515260029Sjmmv ATF_TP_ADD_TC(tp, free_charpp__empty); 516260029Sjmmv ATF_TP_ADD_TC(tp, free_charpp__some); 517260029Sjmmv 518260029Sjmmv ATF_TP_ADD_TC(tp, grep_file); 519260029Sjmmv ATF_TP_ADD_TC(tp, grep_string); 520260029Sjmmv 521260029Sjmmv ATF_TP_ADD_TC(tp, readline__none); 522260029Sjmmv ATF_TP_ADD_TC(tp, readline__some); 523260029Sjmmv 524260029Sjmmv ATF_TP_ADD_TC(tp, redirect__stdout); 525260029Sjmmv ATF_TP_ADD_TC(tp, redirect__stderr); 526260029Sjmmv ATF_TP_ADD_TC(tp, redirect__other); 527260029Sjmmv 528260029Sjmmv ATF_TP_ADD_TC(tp, wait__ok); 529260029Sjmmv ATF_TP_ADD_TC(tp, wait__save_stdout); 530260029Sjmmv ATF_TP_ADD_TC(tp, wait__save_stderr); 531260029Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_exitstatus); 532260029Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_stdout); 533260029Sjmmv ATF_TP_ADD_TC(tp, wait__invalid_stderr); 534260029Sjmmv 535240116Smarcel ATF_TP_ADD_TC(tp, include); 536240116Smarcel 537240116Smarcel return atf_no_error(); 538240116Smarcel} 539