/** Waits for a subprocess and validates its exit condition. * * \param pid The process to be waited for. Must have been started by * testutils_fork(). * \param exitstatus Expected exit status. * \param expout Expected contents of stdout. * \param experr Expected contents of stderr. */ void atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout, const char *experr) { int status; ATF_REQUIRE(waitpid(pid, &status, 0) != -1); atf_utils_cat_file("atf_utils_fork_out.txt", "subprocess stdout: "); atf_utils_cat_file("atf_utils_fork_err.txt", "subprocess stderr: "); ATF_REQUIRE(WIFEXITED(status)); ATF_REQUIRE_EQ(exitstatus, WEXITSTATUS(status)); const char *save_prefix = "save:"; const size_t save_prefix_length = strlen(save_prefix); if (strlen(expout) > save_prefix_length && strncmp(expout, save_prefix, save_prefix_length) == 0) { atf_utils_copy_file("atf_utils_fork_out.txt", expout + save_prefix_length); } else { ATF_REQUIRE(atf_utils_compare_file("atf_utils_fork_out.txt", expout)); } if (strlen(experr) > save_prefix_length && strncmp(experr, save_prefix, save_prefix_length) == 0) { atf_utils_copy_file("atf_utils_fork_err.txt", experr + save_prefix_length); } else { ATF_REQUIRE(atf_utils_compare_file("atf_utils_fork_err.txt", experr)); } ATF_REQUIRE(unlink("atf_utils_fork_out.txt") != -1); ATF_REQUIRE(unlink("atf_utils_fork_err.txt") != -1); }
ATF_TC_BODY(rewrite__missing_file, tc) { bool success; RE(kyua_atf_result_rewrite("in.txt", "out.txt", generate_wait_exitstatus(EXIT_SUCCESS), false, &success)); atf_utils_cat_file("out.txt", "OUTPUT: "); ATF_REQUIRE(atf_utils_compare_file("out.txt", "broken: Premature exit; test case exited with code 0\n")); ATF_REQUIRE(!success); }
ATF_TC_BODY(cat_file__several_lines, tc) { atf_utils_create_file("file.txt", "First\nSecond line\nAnd third\n"); atf_utils_redirect(STDOUT_FILENO, "captured.txt"); atf_utils_cat_file("file.txt", ">"); fflush(stdout); close(STDOUT_FILENO); char buffer[1024]; read_file("captured.txt", buffer, sizeof(buffer)); ATF_REQUIRE_STREQ(">First\n>Second line\n>And third\n", buffer); }
ATF_TC_BODY(cat_file__one_line, tc) { atf_utils_create_file("file.txt", "This is a single line\n"); atf_utils_redirect(STDOUT_FILENO, "captured.txt"); atf_utils_cat_file("file.txt", "PREFIX"); fflush(stdout); close(STDOUT_FILENO); char buffer[1024]; read_file("captured.txt", buffer, sizeof(buffer)); ATF_REQUIRE_STREQ("PREFIXThis is a single line\n", buffer); }
ATF_TC_BODY(cat_file__empty, tc) { atf_utils_create_file("file.txt", "%s", ""); atf_utils_redirect(STDOUT_FILENO, "captured.txt"); atf_utils_cat_file("file.txt", "PREFIX"); fflush(stdout); close(STDOUT_FILENO); char buffer[1024]; read_file("captured.txt", buffer, sizeof(buffer)); ATF_REQUIRE_STREQ("", buffer); }
ATF_TC_BODY(cat_file__no_newline_eof, tc) { atf_utils_create_file("file.txt", "Foo\n bar baz"); atf_utils_redirect(STDOUT_FILENO, "captured.txt"); atf_utils_cat_file("file.txt", "PREFIX"); fflush(stdout); close(STDOUT_FILENO); char buffer[1024]; read_file("captured.txt", buffer, sizeof(buffer)); ATF_REQUIRE_STREQ("PREFIXFoo\nPREFIX bar baz", buffer); }
ATF_TC_BODY(rewrite__too_long_with_newlines, tc) { char input[1000]; fill_buffer("failed: ", "line\n", input, sizeof(input)); // This is quite awful but is the price we have to pay for using fixed-size // buffers in the code for simplicity and speed... char exp_output[1024 + 8 /* strlen("failed: ") */ + 1]; fill_buffer("failed: ", "line<<NEWLINE>>", exp_output, sizeof(exp_output)); exp_output[sizeof(exp_output) - 2] = '\n'; bool success; atf_utils_create_file("in.txt", "%s", input); RE(kyua_atf_result_rewrite("in.txt", "out.txt", generate_wait_exitstatus(EXIT_FAILURE), false, &success)); atf_utils_cat_file("out.txt", "OUTPUT: "); printf("EXPECTED: %s", exp_output); ATF_REQUIRE(atf_utils_compare_file("out.txt", exp_output)); ATF_REQUIRE_EQ(false, success); }
void atf::utils::cat_file(const std::string& path, const std::string& prefix) { atf_utils_cat_file(path.c_str(), prefix.c_str()); }