HardenedBSD/contrib/kyua/engine/atf_result_test.cpp
Brooks Davis b0d29bc47d Import the kyua test framework.
Having kyua in the base system will simplify automated testing in CI and
eliminates bootstrapping issues on new platforms.

The build of kyua is controlled by WITH(OUT)_TESTS_SUPPORT.

Reviewed by:	emaste
Obtained from:	CheriBSD
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D24103
2020-03-23 19:01:23 +00:00

789 lines
31 KiB
C++

// Copyright 2010 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "engine/atf_result.hpp"
extern "C" {
#include <signal.h>
}
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <atf-c++.hpp>
#include "engine/exceptions.hpp"
#include "model/test_result.hpp"
#include "utils/format/macros.hpp"
#include "utils/fs/path.hpp"
#include "utils/process/status.hpp"
namespace fs = utils::fs;
namespace process = utils::process;
using utils::none;
using utils::optional;
namespace {
/// Performs a test for results::parse() that should succeed.
///
/// \param exp_type The expected type of the result.
/// \param exp_argument The expected argument in the result, if any.
/// \param exp_reason The expected reason describing the result, if any.
/// \param text The literal input to parse; can include multiple lines.
static void
parse_ok_test(const engine::atf_result::types& exp_type,
const optional< int >& exp_argument,
const char* exp_reason, const char* text)
{
std::istringstream input(text);
const engine::atf_result actual = engine::atf_result::parse(input);
ATF_REQUIRE(exp_type == actual.type());
ATF_REQUIRE_EQ(exp_argument, actual.argument());
if (exp_reason != NULL) {
ATF_REQUIRE(actual.reason());
ATF_REQUIRE_EQ(exp_reason, actual.reason().get());
} else {
ATF_REQUIRE(!actual.reason());
}
}
/// Wrapper around parse_ok_test to define a test case.
///
/// \param name The name of the test case; will be prefixed with
/// "atf_result__parse__".
/// \param exp_type The expected type of the result.
/// \param exp_argument The expected argument in the result, if any.
/// \param exp_reason The expected reason describing the result, if any.
/// \param input The literal input to parse.
#define PARSE_OK(name, exp_type, exp_argument, exp_reason, input) \
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__parse__ ## name); \
ATF_TEST_CASE_BODY(atf_result__parse__ ## name) \
{ \
parse_ok_test(exp_type, exp_argument, exp_reason, input); \
}
/// Performs a test for results::parse() that should fail.
///
/// \param reason_regexp The reason to match against the broken reason.
/// \param text The literal input to parse; can include multiple lines.
static void
parse_broken_test(const char* reason_regexp, const char* text)
{
std::istringstream input(text);
ATF_REQUIRE_THROW_RE(engine::format_error, reason_regexp,
engine::atf_result::parse(input));
}
/// Wrapper around parse_broken_test to define a test case.
///
/// \param name The name of the test case; will be prefixed with
/// "atf_result__parse__".
/// \param reason_regexp The reason to match against the broken reason.
/// \param input The literal input to parse.
#define PARSE_BROKEN(name, reason_regexp, input) \
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__parse__ ## name); \
ATF_TEST_CASE_BODY(atf_result__parse__ ## name) \
{ \
parse_broken_test(reason_regexp, input); \
}
} // anonymous namespace
PARSE_BROKEN(empty,
"Empty.*no new line",
"");
PARSE_BROKEN(no_newline__unknown,
"Empty.*no new line",
"foo");
PARSE_BROKEN(no_newline__known,
"Empty.*no new line",
"passed");
PARSE_BROKEN(multiline__no_newline,
"multiple lines.*foo<<NEWLINE>>bar",
"failed: foo\nbar");
PARSE_BROKEN(multiline__with_newline,
"multiple lines.*foo<<NEWLINE>>bar",
"failed: foo\nbar\n");
PARSE_BROKEN(unknown_status__no_reason,
"Unknown.*result.*'cba'",
"cba\n");
PARSE_BROKEN(unknown_status__with_reason,
"Unknown.*result.*'hgf'",
"hgf: foo\n");
PARSE_BROKEN(missing_reason__no_delim,
"failed.*followed by.*reason",
"failed\n");
PARSE_BROKEN(missing_reason__bad_delim,
"failed.*followed by.*reason",
"failed:\n");
PARSE_BROKEN(missing_reason__empty,
"failed.*followed by.*reason",
"failed: \n");
PARSE_OK(broken__ok,
engine::atf_result::broken, none, "a b c",
"broken: a b c\n");
PARSE_OK(broken__blanks,
engine::atf_result::broken, none, " ",
"broken: \n");
PARSE_OK(expected_death__ok,
engine::atf_result::expected_death, none, "a b c",
"expected_death: a b c\n");
PARSE_OK(expected_death__blanks,
engine::atf_result::expected_death, none, " ",
"expected_death: \n");
PARSE_OK(expected_exit__ok__any,
engine::atf_result::expected_exit, none, "any exit code",
"expected_exit: any exit code\n");
PARSE_OK(expected_exit__ok__specific,
engine::atf_result::expected_exit, optional< int >(712),
"some known exit code",
"expected_exit(712): some known exit code\n");
PARSE_BROKEN(expected_exit__bad_int,
"Invalid integer.*45a3",
"expected_exit(45a3): this is broken\n");
PARSE_OK(expected_failure__ok,
engine::atf_result::expected_failure, none, "a b c",
"expected_failure: a b c\n");
PARSE_OK(expected_failure__blanks,
engine::atf_result::expected_failure, none, " ",
"expected_failure: \n");
PARSE_OK(expected_signal__ok__any,
engine::atf_result::expected_signal, none, "any signal code",
"expected_signal: any signal code\n");
PARSE_OK(expected_signal__ok__specific,
engine::atf_result::expected_signal, optional< int >(712),
"some known signal code",
"expected_signal(712): some known signal code\n");
PARSE_BROKEN(expected_signal__bad_int,
"Invalid integer.*45a3",
"expected_signal(45a3): this is broken\n");
PARSE_OK(expected_timeout__ok,
engine::atf_result::expected_timeout, none, "a b c",
"expected_timeout: a b c\n");
PARSE_OK(expected_timeout__blanks,
engine::atf_result::expected_timeout, none, " ",
"expected_timeout: \n");
PARSE_OK(failed__ok,
engine::atf_result::failed, none, "a b c",
"failed: a b c\n");
PARSE_OK(failed__blanks,
engine::atf_result::failed, none, " ",
"failed: \n");
PARSE_OK(passed__ok,
engine::atf_result::passed, none, NULL,
"passed\n");
PARSE_BROKEN(passed__reason,
"cannot have a reason",
"passed a b c\n");
PARSE_OK(skipped__ok,
engine::atf_result::skipped, none, "a b c",
"skipped: a b c\n");
PARSE_OK(skipped__blanks,
engine::atf_result::skipped, none, " ",
"skipped: \n");
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__load__ok);
ATF_TEST_CASE_BODY(atf_result__load__ok)
{
std::ofstream output("result.txt");
ATF_REQUIRE(output);
output << "skipped: a b c\n";
output.close();
const engine::atf_result result = engine::atf_result::load(
utils::fs::path("result.txt"));
ATF_REQUIRE(engine::atf_result::skipped == result.type());
ATF_REQUIRE(!result.argument());
ATF_REQUIRE(result.reason());
ATF_REQUIRE_EQ("a b c", result.reason().get());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__load__missing_file);
ATF_TEST_CASE_BODY(atf_result__load__missing_file)
{
ATF_REQUIRE_THROW_RE(
std::runtime_error, "Cannot open",
engine::atf_result::load(utils::fs::path("result.txt")));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__load__format_error);
ATF_TEST_CASE_BODY(atf_result__load__format_error)
{
std::ofstream output("abc.txt");
ATF_REQUIRE(output);
output << "passed: foo\n";
output.close();
ATF_REQUIRE_THROW_RE(engine::format_error, "cannot have a reason",
engine::atf_result::load(utils::fs::path("abc.txt")));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__broken__ok);
ATF_TEST_CASE_BODY(atf_result__apply__broken__ok)
{
const engine::atf_result in_result(engine::atf_result::broken,
"Passthrough");
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
ATF_REQUIRE_EQ(in_result, in_result.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__timed_out);
ATF_TEST_CASE_BODY(atf_result__apply__timed_out)
{
const engine::atf_result timed_out(engine::atf_result::broken,
"Some arbitrary error");
ATF_REQUIRE_EQ(engine::atf_result(engine::atf_result::broken,
"Test case body timed out"),
timed_out.apply(none));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_death__ok);
ATF_TEST_CASE_BODY(atf_result__apply__expected_death__ok)
{
const engine::atf_result in_result(engine::atf_result::expected_death,
"Passthrough");
const process::status status = process::status::fake_signaled(SIGINT, true);
ATF_REQUIRE_EQ(in_result, in_result.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_exit__ok);
ATF_TEST_CASE_BODY(atf_result__apply__expected_exit__ok)
{
const process::status success = process::status::fake_exited(EXIT_SUCCESS);
const process::status failure = process::status::fake_exited(EXIT_FAILURE);
const engine::atf_result any_code(engine::atf_result::expected_exit, none,
"The reason");
ATF_REQUIRE_EQ(any_code, any_code.apply(utils::make_optional(success)));
ATF_REQUIRE_EQ(any_code, any_code.apply(utils::make_optional(failure)));
const engine::atf_result a_code(engine::atf_result::expected_exit,
utils::make_optional(EXIT_FAILURE), "The reason");
ATF_REQUIRE_EQ(a_code, a_code.apply(utils::make_optional(failure)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_exit__failed);
ATF_TEST_CASE_BODY(atf_result__apply__expected_exit__failed)
{
const process::status success = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result a_code(engine::atf_result::expected_exit,
utils::make_optional(EXIT_FAILURE), "The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::failed,
"Test case expected to exit with code 1 but got "
"code 0"),
a_code.apply(utils::make_optional(success)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_exit__broken);
ATF_TEST_CASE_BODY(atf_result__apply__expected_exit__broken)
{
const process::status sig3 = process::status::fake_signaled(3, false);
const engine::atf_result any_code(engine::atf_result::expected_exit, none,
"The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected clean exit but received signal 3"),
any_code.apply(utils::make_optional(sig3)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_failure__ok);
ATF_TEST_CASE_BODY(atf_result__apply__expected_failure__ok)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result xfailure(engine::atf_result::expected_failure,
"The reason");
ATF_REQUIRE_EQ(xfailure, xfailure.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_failure__broken);
ATF_TEST_CASE_BODY(atf_result__apply__expected_failure__broken)
{
const process::status failure = process::status::fake_exited(EXIT_FAILURE);
const process::status sig3 = process::status::fake_signaled(3, true);
const process::status sig4 = process::status::fake_signaled(4, false);
const engine::atf_result xfailure(engine::atf_result::expected_failure,
"The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected failure should have reported success but "
"exited with code 1"),
xfailure.apply(utils::make_optional(failure)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected failure should have reported success but "
"received signal 3 (core dumped)"),
xfailure.apply(utils::make_optional(sig3)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected failure should have reported success but "
"received signal 4"),
xfailure.apply(utils::make_optional(sig4)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_signal__ok);
ATF_TEST_CASE_BODY(atf_result__apply__expected_signal__ok)
{
const process::status sig1 = process::status::fake_signaled(1, false);
const process::status sig3 = process::status::fake_signaled(3, true);
const engine::atf_result any_sig(engine::atf_result::expected_signal, none,
"The reason");
ATF_REQUIRE_EQ(any_sig, any_sig.apply(utils::make_optional(sig1)));
ATF_REQUIRE_EQ(any_sig, any_sig.apply(utils::make_optional(sig3)));
const engine::atf_result a_sig(engine::atf_result::expected_signal,
utils::make_optional(3), "The reason");
ATF_REQUIRE_EQ(a_sig, a_sig.apply(utils::make_optional(sig3)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_signal__failed);
ATF_TEST_CASE_BODY(atf_result__apply__expected_signal__failed)
{
const process::status sig5 = process::status::fake_signaled(5, false);
const engine::atf_result a_sig(engine::atf_result::expected_signal,
utils::make_optional(4), "The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::failed,
"Test case expected to receive signal 4 but got 5"),
a_sig.apply(utils::make_optional(sig5)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_signal__broken);
ATF_TEST_CASE_BODY(atf_result__apply__expected_signal__broken)
{
const process::status success = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result any_sig(engine::atf_result::expected_signal, none,
"The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected signal but exited with code 0"),
any_sig.apply(utils::make_optional(success)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_timeout__ok);
ATF_TEST_CASE_BODY(atf_result__apply__expected_timeout__ok)
{
const engine::atf_result timeout(engine::atf_result::expected_timeout,
"The reason");
ATF_REQUIRE_EQ(timeout, timeout.apply(none));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__expected_timeout__broken);
ATF_TEST_CASE_BODY(atf_result__apply__expected_timeout__broken)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result timeout(engine::atf_result::expected_timeout,
"The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Expected timeout but exited with code 0"),
timeout.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__failed__ok);
ATF_TEST_CASE_BODY(atf_result__apply__failed__ok)
{
const process::status status = process::status::fake_exited(EXIT_FAILURE);
const engine::atf_result failed(engine::atf_result::failed, "The reason");
ATF_REQUIRE_EQ(failed, failed.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__failed__broken);
ATF_TEST_CASE_BODY(atf_result__apply__failed__broken)
{
const process::status success = process::status::fake_exited(EXIT_SUCCESS);
const process::status sig3 = process::status::fake_signaled(3, true);
const process::status sig4 = process::status::fake_signaled(4, false);
const engine::atf_result failed(engine::atf_result::failed, "The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Failed test case should have reported failure but "
"exited with code 0"),
failed.apply(utils::make_optional(success)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Failed test case should have reported failure but "
"received signal 3 (core dumped)"),
failed.apply(utils::make_optional(sig3)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Failed test case should have reported failure but "
"received signal 4"),
failed.apply(utils::make_optional(sig4)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__passed__ok);
ATF_TEST_CASE_BODY(atf_result__apply__passed__ok)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result passed(engine::atf_result::passed);
ATF_REQUIRE_EQ(passed, passed.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__passed__broken);
ATF_TEST_CASE_BODY(atf_result__apply__passed__broken)
{
const process::status failure = process::status::fake_exited(EXIT_FAILURE);
const process::status sig3 = process::status::fake_signaled(3, true);
const process::status sig4 = process::status::fake_signaled(4, false);
const engine::atf_result passed(engine::atf_result::passed);
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Passed test case should have reported success but "
"exited with code 1"),
passed.apply(utils::make_optional(failure)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Passed test case should have reported success but "
"received signal 3 (core dumped)"),
passed.apply(utils::make_optional(sig3)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Passed test case should have reported success but "
"received signal 4"),
passed.apply(utils::make_optional(sig4)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__skipped__ok);
ATF_TEST_CASE_BODY(atf_result__apply__skipped__ok)
{
const process::status status = process::status::fake_exited(EXIT_SUCCESS);
const engine::atf_result skipped(engine::atf_result::skipped, "The reason");
ATF_REQUIRE_EQ(skipped, skipped.apply(utils::make_optional(status)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__apply__skipped__broken);
ATF_TEST_CASE_BODY(atf_result__apply__skipped__broken)
{
const process::status failure = process::status::fake_exited(EXIT_FAILURE);
const process::status sig3 = process::status::fake_signaled(3, true);
const process::status sig4 = process::status::fake_signaled(4, false);
const engine::atf_result skipped(engine::atf_result::skipped, "The reason");
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Skipped test case should have reported success but "
"exited with code 1"),
skipped.apply(utils::make_optional(failure)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Skipped test case should have reported success but "
"received signal 3 (core dumped)"),
skipped.apply(utils::make_optional(sig3)));
ATF_REQUIRE_EQ(
engine::atf_result(engine::atf_result::broken,
"Skipped test case should have reported success but "
"received signal 4"),
skipped.apply(utils::make_optional(sig4)));
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__broken);
ATF_TEST_CASE_BODY(atf_result__externalize__broken)
{
const engine::atf_result raw(engine::atf_result::broken, "The reason");
const model::test_result expected(model::test_result_broken,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__expected_death);
ATF_TEST_CASE_BODY(atf_result__externalize__expected_death)
{
const engine::atf_result raw(engine::atf_result::expected_death,
"The reason");
const model::test_result expected(model::test_result_expected_failure,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__expected_exit);
ATF_TEST_CASE_BODY(atf_result__externalize__expected_exit)
{
const engine::atf_result raw(engine::atf_result::expected_exit,
"The reason");
const model::test_result expected(model::test_result_expected_failure,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__expected_failure);
ATF_TEST_CASE_BODY(atf_result__externalize__expected_failure)
{
const engine::atf_result raw(engine::atf_result::expected_failure,
"The reason");
const model::test_result expected(model::test_result_expected_failure,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__expected_signal);
ATF_TEST_CASE_BODY(atf_result__externalize__expected_signal)
{
const engine::atf_result raw(engine::atf_result::expected_signal,
"The reason");
const model::test_result expected(model::test_result_expected_failure,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__expected_timeout);
ATF_TEST_CASE_BODY(atf_result__externalize__expected_timeout)
{
const engine::atf_result raw(engine::atf_result::expected_timeout,
"The reason");
const model::test_result expected(model::test_result_expected_failure,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__failed);
ATF_TEST_CASE_BODY(atf_result__externalize__failed)
{
const engine::atf_result raw(engine::atf_result::failed, "The reason");
const model::test_result expected(model::test_result_failed,
"The reason");
ATF_REQUIRE(expected == raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__passed);
ATF_TEST_CASE_BODY(atf_result__externalize__passed)
{
const engine::atf_result raw(engine::atf_result::passed);
const model::test_result expected(model::test_result_passed);
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(atf_result__externalize__skipped);
ATF_TEST_CASE_BODY(atf_result__externalize__skipped)
{
const engine::atf_result raw(engine::atf_result::skipped, "The reason");
const model::test_result expected(model::test_result_skipped,
"The reason");
ATF_REQUIRE_EQ(expected, raw.externalize());
}
ATF_TEST_CASE_WITHOUT_HEAD(calculate_atf_result__missing_file);
ATF_TEST_CASE_BODY(calculate_atf_result__missing_file)
{
using process::status;
const status body_status = status::fake_exited(EXIT_SUCCESS);
const model::test_result expected(
model::test_result_broken,
"Premature exit; test case exited with code 0");
ATF_REQUIRE_EQ(expected, engine::calculate_atf_result(
utils::make_optional(body_status), fs::path("foo")));
}
ATF_TEST_CASE_WITHOUT_HEAD(calculate_atf_result__bad_file);
ATF_TEST_CASE_BODY(calculate_atf_result__bad_file)
{
using process::status;
const status body_status = status::fake_exited(EXIT_SUCCESS);
atf::utils::create_file("foo", "invalid\n");
const model::test_result expected(model::test_result_broken,
"Unknown test result 'invalid'");
ATF_REQUIRE_EQ(expected, engine::calculate_atf_result(
utils::make_optional(body_status), fs::path("foo")));
}
ATF_TEST_CASE_WITHOUT_HEAD(calculate_atf_result__body_ok);
ATF_TEST_CASE_BODY(calculate_atf_result__body_ok)
{
using process::status;
atf::utils::create_file("result.txt", "skipped: Something\n");
const status body_status = status::fake_exited(EXIT_SUCCESS);
ATF_REQUIRE_EQ(
model::test_result(model::test_result_skipped, "Something"),
engine::calculate_atf_result(utils::make_optional(body_status),
fs::path("result.txt")));
}
ATF_TEST_CASE_WITHOUT_HEAD(calculate_atf_result__body_bad);
ATF_TEST_CASE_BODY(calculate_atf_result__body_bad)
{
using process::status;
atf::utils::create_file("result.txt", "skipped: Something\n");
const status body_status = status::fake_exited(EXIT_FAILURE);
ATF_REQUIRE_EQ(
model::test_result(model::test_result_broken, "Skipped test case "
"should have reported success but exited with "
"code 1"),
engine::calculate_atf_result(utils::make_optional(body_status),
fs::path("result.txt")));
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, atf_result__parse__empty);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__no_newline__unknown);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__no_newline__known);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__multiline__no_newline);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__multiline__with_newline);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__unknown_status__no_reason);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__unknown_status__with_reason);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__missing_reason__no_delim);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__missing_reason__bad_delim);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__missing_reason__empty);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__broken__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__broken__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_death__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_death__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_exit__ok__any);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_exit__ok__specific);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_exit__bad_int);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_failure__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_failure__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_signal__ok__any);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_signal__ok__specific);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_signal__bad_int);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_timeout__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__expected_timeout__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__failed__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__failed__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__passed__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__passed__reason);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__skipped__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__parse__skipped__blanks);
ATF_ADD_TEST_CASE(tcs, atf_result__load__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__load__missing_file);
ATF_ADD_TEST_CASE(tcs, atf_result__load__format_error);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__broken__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__timed_out);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_death__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_exit__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_exit__failed);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_exit__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_failure__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_failure__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_signal__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_signal__failed);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_signal__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_timeout__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__expected_timeout__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__failed__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__failed__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__passed__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__passed__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__skipped__ok);
ATF_ADD_TEST_CASE(tcs, atf_result__apply__skipped__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__broken);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__expected_death);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__expected_exit);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__expected_failure);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__expected_signal);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__expected_timeout);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__failed);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__passed);
ATF_ADD_TEST_CASE(tcs, atf_result__externalize__skipped);
ATF_ADD_TEST_CASE(tcs, calculate_atf_result__missing_file);
ATF_ADD_TEST_CASE(tcs, calculate_atf_result__bad_file);
ATF_ADD_TEST_CASE(tcs, calculate_atf_result__body_ok);
ATF_ADD_TEST_CASE(tcs, calculate_atf_result__body_bad);
}