Path: blob/main/contrib/atf/atf-c++/utils_test.cpp
39507 views
// Copyright (c) 2007 The NetBSD Foundation, Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions5// are met:6// 1. Redistributions of source code must retain the above copyright7// notice, this list of conditions and the following disclaimer.8// 2. Redistributions in binary form must reproduce the above copyright9// notice, this list of conditions and the following disclaimer in the10// documentation and/or other materials provided with the distribution.11//12// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND13// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,14// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF15// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE19// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS20// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER21// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN23// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2425#include "atf-c++/utils.hpp"2627extern "C" {28#include <sys/stat.h>29#include <sys/wait.h>3031#include <fcntl.h>32#include <unistd.h>33}3435#include <cstdlib>36#include <iostream>37#include <set>38#include <sstream>39#include <string>40#include <vector>4142#include <atf-c++.hpp>4344static std::string45read_file(const std::string& path)46{47char buffer[1024];4849const int fd = open(path.c_str(), O_RDONLY);50if (fd == -1)51ATF_FAIL("Cannot open " + path);52const ssize_t length = read(fd, buffer, sizeof(buffer) - 1);53close(fd);54ATF_REQUIRE(length != -1);55if (length == sizeof(buffer) - 1)56ATF_FAIL("Internal buffer not long enough to read temporary file");57((char *)buffer)[length] = '\0';5859return buffer;60}6162// ------------------------------------------------------------------------63// Tests cases for the free functions.64// ------------------------------------------------------------------------6566ATF_TEST_CASE_WITHOUT_HEAD(cat_file__empty);67ATF_TEST_CASE_BODY(cat_file__empty)68{69atf::utils::create_file("file.txt", "");70atf::utils::redirect(STDOUT_FILENO, "captured.txt");71atf::utils::cat_file("file.txt", "PREFIX");72std::cout.flush();73close(STDOUT_FILENO);7475ATF_REQUIRE_EQ("", read_file("captured.txt"));76}7778ATF_TEST_CASE_WITHOUT_HEAD(cat_file__one_line);79ATF_TEST_CASE_BODY(cat_file__one_line)80{81atf::utils::create_file("file.txt", "This is a single line\n");82atf::utils::redirect(STDOUT_FILENO, "captured.txt");83atf::utils::cat_file("file.txt", "PREFIX");84std::cout.flush();85close(STDOUT_FILENO);8687ATF_REQUIRE_EQ("PREFIXThis is a single line\n", read_file("captured.txt"));88}8990ATF_TEST_CASE_WITHOUT_HEAD(cat_file__several_lines);91ATF_TEST_CASE_BODY(cat_file__several_lines)92{93atf::utils::create_file("file.txt", "First\nSecond line\nAnd third\n");94atf::utils::redirect(STDOUT_FILENO, "captured.txt");95atf::utils::cat_file("file.txt", ">");96std::cout.flush();97close(STDOUT_FILENO);9899ATF_REQUIRE_EQ(">First\n>Second line\n>And third\n",100read_file("captured.txt"));101}102103ATF_TEST_CASE_WITHOUT_HEAD(cat_file__no_newline_eof);104ATF_TEST_CASE_BODY(cat_file__no_newline_eof)105{106atf::utils::create_file("file.txt", "Foo\n bar baz");107atf::utils::redirect(STDOUT_FILENO, "captured.txt");108atf::utils::cat_file("file.txt", "PREFIX");109std::cout.flush();110close(STDOUT_FILENO);111112ATF_REQUIRE_EQ("PREFIXFoo\nPREFIX bar baz", read_file("captured.txt"));113}114115ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__match);116ATF_TEST_CASE_BODY(compare_file__empty__match)117{118atf::utils::create_file("test.txt", "");119ATF_REQUIRE(atf::utils::compare_file("test.txt", ""));120}121122ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__not_match);123ATF_TEST_CASE_BODY(compare_file__empty__not_match)124{125atf::utils::create_file("test.txt", "");126ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));127ATF_REQUIRE(!atf::utils::compare_file("test.txt", "foo"));128ATF_REQUIRE(!atf::utils::compare_file("test.txt", " "));129}130131ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__match);132ATF_TEST_CASE_BODY(compare_file__short__match)133{134atf::utils::create_file("test.txt", "this is a short file");135ATF_REQUIRE(atf::utils::compare_file("test.txt", "this is a short file"));136}137138ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__not_match);139ATF_TEST_CASE_BODY(compare_file__short__not_match)140{141atf::utils::create_file("test.txt", "this is a short file");142ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));143ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));144ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a Short file"));145ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short fil"));146ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short file "));147}148149ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__match);150ATF_TEST_CASE_BODY(compare_file__long__match)151{152char long_contents[3456];153size_t i = 0;154for (; i < sizeof(long_contents) - 1; i++)155long_contents[i] = '0' + (i % 10);156long_contents[i] = '\0';157atf::utils::create_file("test.txt", long_contents);158159ATF_REQUIRE(atf::utils::compare_file("test.txt", long_contents));160}161162ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__not_match);163ATF_TEST_CASE_BODY(compare_file__long__not_match)164{165char long_contents[3456];166size_t i = 0;167for (; i < sizeof(long_contents) - 1; i++)168long_contents[i] = '0' + (i % 10);169long_contents[i] = '\0';170atf::utils::create_file("test.txt", long_contents);171172ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));173ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));174ATF_REQUIRE(!atf::utils::compare_file("test.txt", "0123456789"));175long_contents[i - 1] = 'Z';176ATF_REQUIRE(!atf::utils::compare_file("test.txt", long_contents));177}178179ATF_TEST_CASE_WITHOUT_HEAD(copy_file__empty);180ATF_TEST_CASE_BODY(copy_file__empty)181{182atf::utils::create_file("src.txt", "");183ATF_REQUIRE(chmod("src.txt", 0520) != -1);184185atf::utils::copy_file("src.txt", "dest.txt");186ATF_REQUIRE(atf::utils::compare_file("dest.txt", ""));187struct stat sb;188ATF_REQUIRE(stat("dest.txt", &sb) != -1);189ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);190}191192ATF_TEST_CASE_WITHOUT_HEAD(copy_file__some_contents);193ATF_TEST_CASE_BODY(copy_file__some_contents)194{195atf::utils::create_file("src.txt", "This is a\ntest file\n");196atf::utils::copy_file("src.txt", "dest.txt");197ATF_REQUIRE(atf::utils::compare_file("dest.txt", "This is a\ntest file\n"));198}199200ATF_TEST_CASE_WITHOUT_HEAD(create_file);201ATF_TEST_CASE_BODY(create_file)202{203atf::utils::create_file("test.txt", "This is a %d test");204205ATF_REQUIRE_EQ("This is a %d test", read_file("test.txt"));206}207208ATF_TEST_CASE_WITHOUT_HEAD(file_exists);209ATF_TEST_CASE_BODY(file_exists)210{211atf::utils::create_file("test.txt", "foo");212213ATF_REQUIRE( atf::utils::file_exists("test.txt"));214ATF_REQUIRE( atf::utils::file_exists("./test.txt"));215ATF_REQUIRE(!atf::utils::file_exists("./test.tx"));216ATF_REQUIRE(!atf::utils::file_exists("test.txt2"));217}218219ATF_TEST_CASE_WITHOUT_HEAD(fork);220ATF_TEST_CASE_BODY(fork)221{222std::cout << "Should not get into child\n";223std::cerr << "Should not get into child\n";224pid_t pid = atf::utils::fork();225if (pid == 0) {226std::cout << "Child stdout\n";227std::cerr << "Child stderr\n";228exit(EXIT_SUCCESS);229}230231int status;232ATF_REQUIRE(waitpid(pid, &status, 0) != -1);233ATF_REQUIRE(WIFEXITED(status));234ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));235236std::ostringstream out_name;237out_name << "atf_utils_fork_" << pid << "_out.txt";238std::ostringstream err_name;239err_name << "atf_utils_fork_" << pid << "_err.txt";240241ATF_REQUIRE_EQ("Child stdout\n", read_file(out_name.str()));242ATF_REQUIRE_EQ("Child stderr\n", read_file(err_name.str()));243}244245ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__set);246ATF_TEST_CASE_BODY(grep_collection__set)247{248std::set< std::string > strings;249strings.insert("First");250strings.insert("Second");251252ATF_REQUIRE( atf::utils::grep_collection("irs", strings));253ATF_REQUIRE( atf::utils::grep_collection("cond", strings));254ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));255}256257ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__vector);258ATF_TEST_CASE_BODY(grep_collection__vector)259{260std::vector< std::string > strings;261strings.push_back("First");262strings.push_back("Second");263264ATF_REQUIRE( atf::utils::grep_collection("irs", strings));265ATF_REQUIRE( atf::utils::grep_collection("cond", strings));266ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));267}268269ATF_TEST_CASE_WITHOUT_HEAD(grep_file);270ATF_TEST_CASE_BODY(grep_file)271{272atf::utils::create_file("test.txt", "line1\nthe second line\naaaabbbb\n");273274ATF_REQUIRE(atf::utils::grep_file("line1", "test.txt"));275ATF_REQUIRE(atf::utils::grep_file("second line", "test.txt"));276ATF_REQUIRE(atf::utils::grep_file("aa.*bb", "test.txt"));277ATF_REQUIRE(!atf::utils::grep_file("foo", "test.txt"));278ATF_REQUIRE(!atf::utils::grep_file("bar", "test.txt"));279ATF_REQUIRE(!atf::utils::grep_file("aaaaa", "test.txt"));280}281282ATF_TEST_CASE_WITHOUT_HEAD(grep_string);283ATF_TEST_CASE_BODY(grep_string)284{285const char *str = "a string - aaaabbbb";286ATF_REQUIRE(atf::utils::grep_string("a string", str));287ATF_REQUIRE(atf::utils::grep_string("^a string", str));288ATF_REQUIRE(atf::utils::grep_string("aaaabbbb$", str));289ATF_REQUIRE(atf::utils::grep_string("aa.*bb", str));290ATF_REQUIRE(!atf::utils::grep_string("foo", str));291ATF_REQUIRE(!atf::utils::grep_string("bar", str));292ATF_REQUIRE(!atf::utils::grep_string("aaaaa", str));293}294295ATF_TEST_CASE_WITHOUT_HEAD(redirect__stdout);296ATF_TEST_CASE_BODY(redirect__stdout)297{298std::cout << "Buffer this";299atf::utils::redirect(STDOUT_FILENO, "captured.txt");300std::cout << "The printed message";301std::cout.flush();302303ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));304}305306ATF_TEST_CASE_WITHOUT_HEAD(redirect__stderr);307ATF_TEST_CASE_BODY(redirect__stderr)308{309std::cerr << "Buffer this";310atf::utils::redirect(STDERR_FILENO, "captured.txt");311std::cerr << "The printed message";312std::cerr.flush();313314ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));315}316317ATF_TEST_CASE_WITHOUT_HEAD(redirect__other);318ATF_TEST_CASE_BODY(redirect__other)319{320const std::string message = "Foo bar\nbaz\n";321atf::utils::redirect(15, "captured.txt");322ATF_REQUIRE(write(15, message.c_str(), message.length()) != -1);323close(15);324325ATF_REQUIRE_EQ(message, read_file("captured.txt"));326}327328static void329fork_and_wait(const int exitstatus, const char* expout, const char* experr)330{331const pid_t pid = atf::utils::fork();332if (pid == 0) {333std::cout << "Some output\n";334std::cerr << "Some error\n";335exit(123);336}337atf::utils::reset_resultsfile();338atf::utils::wait(pid, exitstatus, expout, experr);339exit(EXIT_SUCCESS);340}341342ATF_TEST_CASE_WITHOUT_HEAD(wait__ok);343ATF_TEST_CASE_BODY(wait__ok)344{345const pid_t control = fork();346ATF_REQUIRE(control != -1);347if (control == 0)348fork_and_wait(123, "Some output\n", "Some error\n");349else {350int status;351ATF_REQUIRE(waitpid(control, &status, 0) != -1);352ATF_REQUIRE(WIFEXITED(status));353ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));354}355}356357ATF_TEST_CASE_WITHOUT_HEAD(wait__ok_nested);358ATF_TEST_CASE_BODY(wait__ok_nested)359{360const pid_t parent = atf::utils::fork();361ATF_REQUIRE(parent != -1);362if (parent == 0) {363const pid_t child = atf::utils::fork();364ATF_REQUIRE(child != -1);365if (child == 0) {366std::cerr.flush();367std::cout << "Child output\n";368std::cout.flush();369std::cerr << "Child error\n";370std::exit(50);371} else {372std::cout << "Parent output\n";373std::cerr << "Parent error\n";374atf::utils::wait(child, 50, "Child output\n", "Child error\n");375std::exit(40);376}377} else {378atf::utils::wait(parent, 40,379"Parent output\n"380"subprocess stdout: Child output\n"381"subprocess stderr: Child error\n",382"Parent error\n");383}384}385386ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_exitstatus);387ATF_TEST_CASE_BODY(wait__invalid_exitstatus)388{389const pid_t control = fork();390ATF_REQUIRE(control != -1);391if (control == 0)392fork_and_wait(120, "Some output\n", "Some error\n");393else {394int status;395ATF_REQUIRE(waitpid(control, &status, 0) != -1);396ATF_REQUIRE(WIFEXITED(status));397ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));398}399}400401ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stdout);402ATF_TEST_CASE_BODY(wait__invalid_stdout)403{404const pid_t control = fork();405ATF_REQUIRE(control != -1);406if (control == 0)407fork_and_wait(123, "Some output foo\n", "Some error\n");408else {409int status;410ATF_REQUIRE(waitpid(control, &status, 0) != -1);411ATF_REQUIRE(WIFEXITED(status));412ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));413}414}415416ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stderr);417ATF_TEST_CASE_BODY(wait__invalid_stderr)418{419const pid_t control = fork();420ATF_REQUIRE(control != -1);421if (control == 0)422fork_and_wait(123, "Some output\n", "Some error foo\n");423else {424int status;425ATF_REQUIRE(waitpid(control, &status, 0) != -1);426ATF_REQUIRE(WIFEXITED(status));427ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));428}429}430431ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stdout);432ATF_TEST_CASE_BODY(wait__save_stdout)433{434const pid_t control = fork();435ATF_REQUIRE(control != -1);436if (control == 0)437fork_and_wait(123, "save:my-output.txt", "Some error\n");438else {439int status;440ATF_REQUIRE(waitpid(control, &status, 0) != -1);441ATF_REQUIRE(WIFEXITED(status));442ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));443444ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some output\n"));445}446}447448ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stderr);449ATF_TEST_CASE_BODY(wait__save_stderr)450{451const pid_t control = fork();452ATF_REQUIRE(control != -1);453if (control == 0)454fork_and_wait(123, "Some output\n", "save:my-output.txt");455else {456int status;457ATF_REQUIRE(waitpid(control, &status, 0) != -1);458ATF_REQUIRE(WIFEXITED(status));459ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));460461ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some error\n"));462}463}464465// ------------------------------------------------------------------------466// Main.467// ------------------------------------------------------------------------468469ATF_INIT_TEST_CASES(tcs)470{471// Add the test for the free functions.472ATF_ADD_TEST_CASE(tcs, cat_file__empty);473ATF_ADD_TEST_CASE(tcs, cat_file__one_line);474ATF_ADD_TEST_CASE(tcs, cat_file__several_lines);475ATF_ADD_TEST_CASE(tcs, cat_file__no_newline_eof);476477ATF_ADD_TEST_CASE(tcs, compare_file__empty__match);478ATF_ADD_TEST_CASE(tcs, compare_file__empty__not_match);479ATF_ADD_TEST_CASE(tcs, compare_file__short__match);480ATF_ADD_TEST_CASE(tcs, compare_file__short__not_match);481ATF_ADD_TEST_CASE(tcs, compare_file__long__match);482ATF_ADD_TEST_CASE(tcs, compare_file__long__not_match);483484ATF_ADD_TEST_CASE(tcs, copy_file__empty);485ATF_ADD_TEST_CASE(tcs, copy_file__some_contents);486487ATF_ADD_TEST_CASE(tcs, create_file);488489ATF_ADD_TEST_CASE(tcs, file_exists);490491ATF_ADD_TEST_CASE(tcs, fork);492493ATF_ADD_TEST_CASE(tcs, grep_collection__set);494ATF_ADD_TEST_CASE(tcs, grep_collection__vector);495ATF_ADD_TEST_CASE(tcs, grep_file);496ATF_ADD_TEST_CASE(tcs, grep_string);497498ATF_ADD_TEST_CASE(tcs, redirect__stdout);499ATF_ADD_TEST_CASE(tcs, redirect__stderr);500ATF_ADD_TEST_CASE(tcs, redirect__other);501502ATF_ADD_TEST_CASE(tcs, wait__ok);503ATF_ADD_TEST_CASE(tcs, wait__ok_nested);504ATF_ADD_TEST_CASE(tcs, wait__invalid_exitstatus);505ATF_ADD_TEST_CASE(tcs, wait__invalid_stdout);506ATF_ADD_TEST_CASE(tcs, wait__invalid_stderr);507ATF_ADD_TEST_CASE(tcs, wait__save_stdout);508ATF_ADD_TEST_CASE(tcs, wait__save_stderr);509}510511512