Help merge of atf-0.12.

This commit is contained in:
jmmv 2010-11-07 17:45:21 +00:00
parent 0ebb519dda
commit 0b634f1420
6 changed files with 130 additions and 73 deletions

View File

@ -110,6 +110,16 @@ detail::atf_tp_writer::tc_meta_data(const std::string& name,
m_os.flush();
}
// ------------------------------------------------------------------------
// Free helper functions.
// ------------------------------------------------------------------------
bool
detail::match(const std::string& regexp, const std::string& str)
{
return atf::text::match(str, regexp);
}
// ------------------------------------------------------------------------
// The "tc" class.
// ------------------------------------------------------------------------

View File

@ -34,6 +34,10 @@
#include <memory>
#include <string>
extern "C" {
#include <atf-c/defs.h>
}
#include <atf-c++/utils.hpp>
namespace atf {
@ -54,6 +58,8 @@ public:
void tc_meta_data(const std::string&, const std::string&);
};
bool match(const std::string&, const std::string&);
} // namespace
// ------------------------------------------------------------------------
@ -99,10 +105,10 @@ public:
void run_cleanup(void) const;
// To be called from the child process only.
static void pass(void);
static void fail(const std::string&);
static void pass(void) ATF_DEFS_ATTRIBUTE_NORETURN;
static void fail(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
static void fail_nonfatal(const std::string&);
static void skip(const std::string&);
static void skip(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
static void check_errno(const char*, const int, const int, const char*,
const bool);
static void require_errno(const char*, const int, const int, const char*,

View File

@ -642,6 +642,70 @@ atf_tc_get_config_var_wd(const atf_tc_t *tc, const char *name,
return val;
}
bool
atf_tc_get_config_var_as_bool(const atf_tc_t *tc, const char *name)
{
bool val;
const char *strval;
atf_error_t err;
strval = atf_tc_get_config_var(tc, name);
err = atf_text_to_bool(strval, &val);
if (atf_is_error(err)) {
atf_error_free(err);
atf_tc_fail("Configuration variable %s does not have a valid "
"boolean value; found %s", name, strval);
}
return val;
}
bool
atf_tc_get_config_var_as_bool_wd(const atf_tc_t *tc, const char *name,
const bool defval)
{
bool val;
if (!atf_tc_has_config_var(tc, name))
val = defval;
else
val = atf_tc_get_config_var_as_bool(tc, name);
return val;
}
long
atf_tc_get_config_var_as_long(const atf_tc_t *tc, const char *name)
{
long val;
const char *strval;
atf_error_t err;
strval = atf_tc_get_config_var(tc, name);
err = atf_text_to_long(strval, &val);
if (atf_is_error(err)) {
atf_error_free(err);
atf_tc_fail("Configuration variable %s does not have a valid "
"long value; found %s", name, strval);
}
return val;
}
long
atf_tc_get_config_var_as_long_wd(const atf_tc_t *tc, const char *name,
const long defval)
{
long val;
if (!atf_tc_has_config_var(tc, name))
val = defval;
else
val = atf_tc_get_config_var_as_long(tc, name);
return val;
}
const char *
atf_tc_get_md_var(const atf_tc_t *tc, const char *name)
{

View File

@ -84,16 +84,11 @@ class atf_run : public atf::application::app {
size_t count_tps(std::vector< std::string >) const;
int run_test(const atf::fs::path&,
impl::atf_tps_writer&,
const atf::tests::vars_map&,
const atf::fs::path&);
int run_test_directory(const atf::fs::path&,
impl::atf_tps_writer&,
const atf::fs::path&);
int run_test(const atf::fs::path&, impl::atf_tps_writer&,
const atf::tests::vars_map&);
int run_test_directory(const atf::fs::path&, impl::atf_tps_writer&);
int run_test_program(const atf::fs::path&, impl::atf_tps_writer&,
const atf::tests::vars_map&,
const atf::fs::path&);
const atf::tests::vars_map&);
impl::test_case_result get_test_case_result(const std::string&,
const atf::process::status&, const atf::fs::path&) const;
@ -166,27 +161,25 @@ atf_run::parse_vflag(const std::string& str)
int
atf_run::run_test(const atf::fs::path& tp,
impl::atf_tps_writer& w,
const atf::tests::vars_map& config,
const atf::fs::path& ro_workdir)
const atf::tests::vars_map& config)
{
atf::fs::file_info fi(tp);
int errcode;
if (fi.get_type() == atf::fs::file_info::dir_type)
errcode = run_test_directory(tp, w, ro_workdir);
errcode = run_test_directory(tp, w);
else {
const atf::tests::vars_map effective_config =
impl::merge_configs(config, m_cmdline_vars);
errcode = run_test_program(tp, w, effective_config, ro_workdir);
errcode = run_test_program(tp, w, effective_config);
}
return errcode;
}
int
atf_run::run_test_directory(const atf::fs::path& tp,
impl::atf_tps_writer& w,
const atf::fs::path& ro_workdir)
impl::atf_tps_writer& w)
{
impl::atffile af = impl::read_atffile(tp / "Atffile");
@ -202,7 +195,7 @@ atf_run::run_test_directory(const atf::fs::path& tp,
for (std::vector< std::string >::const_iterator iter = af.tps().begin();
iter != af.tps().end(); iter++) {
const bool result = run_test(tp / *iter, w,
impl::merge_configs(af.conf(), test_suite_vars), ro_workdir);
impl::merge_configs(af.conf(), test_suite_vars));
ok &= (result == EXIT_SUCCESS);
}
@ -317,8 +310,7 @@ atf_run::get_test_case_result(const std::string& broken_reason,
int
atf_run::run_test_program(const atf::fs::path& tp,
impl::atf_tps_writer& w,
const atf::tests::vars_map& config,
const atf::fs::path& ro_workdir)
const atf::tests::vars_map& config)
{
int errcode = EXIT_SUCCESS;
@ -364,40 +356,39 @@ atf_run::run_test_program(const atf::fs::path& tp,
continue;
}
const atf::fs::path resfile = resdir.get_path() / "tcr";
const std::pair< int, int > user = impl::get_required_user(
tcmd, config);
atf::fs::path resfile = resdir.get_path() / "tcr";
INV(!atf::fs::exists(resfile));
try {
const bool has_cleanup = atf::text::to_bool(
(*tcmd.find("has.cleanup")).second);
const bool use_fs = atf::text::to_bool(
(*tcmd.find("use.fs")).second);
impl::test_case_result tcr;
if (use_fs) {
impl::temp_dir workdir(atf::fs::path(atf::config::get(
"atf_workdir")) / "atf-run.XXXXXX");
std::pair< std::string, const atf::process::status > s =
impl::run_test_case(tp, tcname, "body", tcmd, config,
resfile, workdir.get_path(), w);
if (has_cleanup)
(void)impl::run_test_case(tp, tcname, "cleanup", tcmd,
config, resfile, workdir.get_path(), w);
// TODO: Force deletion of workdir.
tcr = get_test_case_result(s.first, s.second, resfile);
} else {
std::pair< std::string, const atf::process::status > s =
impl::run_test_case(tp, tcname, "body", tcmd, config,
resfile, ro_workdir, w);
if (has_cleanup)
(void)impl::run_test_case(tp, tcname, "cleanup", tcmd,
config, resfile, ro_workdir, w);
tcr = get_test_case_result(s.first, s.second, resfile);
impl::temp_dir workdir(atf::fs::path(atf::config::get(
"atf_workdir")) / "atf-run.XXXXXX");
if (user.first != -1 && user.second != -1) {
if (::chown(workdir.get_path().c_str(), user.first,
user.second) == -1) {
throw atf::system_error("chmod(" +
workdir.get_path().str() + ")", "chmod(2) failed",
errno);
}
resfile = workdir.get_path() / "tcr";
}
std::pair< std::string, const atf::process::status > s =
impl::run_test_case(tp, tcname, "body", tcmd, config,
resfile, workdir.get_path(), w);
if (has_cleanup)
(void)impl::run_test_case(tp, tcname, "cleanup", tcmd,
config, resfile, workdir.get_path(), w);
// TODO: Force deletion of workdir.
impl::test_case_result tcr = get_test_case_result(s.first,
s.second, resfile);
w.end_tc(tcr.state(), tcr.reason());
if (tcr.state() == "failed")
errcode = EXIT_FAILURE;
@ -490,20 +481,11 @@ atf_run::main(void)
call_hook("atf-run", "info_start_hook");
w.ntps(count_tps(tps));
impl::temp_dir ro_workdir(atf::fs::path(atf::config::get(
"atf_workdir")) / "atf-run.XXXXXX");
if (::chmod(ro_workdir.get_path().c_str(), S_IXUSR) == -1)
throw std::runtime_error("Failed to create read-only work directory");
if (!impl::set_immutable(ro_workdir.get_path(), true)) {
// TODO: Report that use.fs may not work. Non-fatal though.
}
bool ok = true;
for (std::vector< std::string >::const_iterator iter = tps.begin();
iter != tps.end(); iter++) {
const bool result = run_test(atf::fs::path(*iter), w,
impl::merge_configs(af.conf(), test_suite_vars),
ro_workdir.get_path());
impl::merge_configs(af.conf(), test_suite_vars));
ok &= (result == EXIT_SUCCESS);
}

View File

@ -232,7 +232,6 @@ ATF_TEST_CASE_HEAD(systembuf_short_read)
{
set_md_var("descr", "Tests that a short read (one that fits in the "
"internal buffer) works when using systembuf");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(systembuf_short_read)
{
@ -244,7 +243,6 @@ ATF_TEST_CASE_HEAD(systembuf_long_read)
{
set_md_var("descr", "Tests that a long read (one that does not fit in "
"the internal buffer) works when using systembuf");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(systembuf_long_read)
{
@ -256,7 +254,6 @@ ATF_TEST_CASE_HEAD(systembuf_short_write)
{
set_md_var("descr", "Tests that a short write (one that fits in the "
"internal buffer) works when using systembuf");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(systembuf_short_write)
{
@ -268,7 +265,6 @@ ATF_TEST_CASE_HEAD(systembuf_long_write)
{
set_md_var("descr", "Tests that a long write (one that does not fit "
"in the internal buffer) works when using systembuf");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(systembuf_long_write)
{

View File

@ -50,9 +50,11 @@ extern "C" {
#include "config.hpp"
#include "fs.hpp"
#include "io.hpp"
#include "requirements.hpp"
#include "signals.hpp"
#include "test-program.hpp"
#include "timer.hpp"
#include "user.hpp"
namespace impl = atf::atf_run;
namespace detail = atf::atf_run::detail;
@ -108,10 +110,7 @@ class metadata_reader : public detail::atf_tp_reader {
m_tcs[ident].insert(std::make_pair("has.cleanup", "false"));
if (m_tcs[ident].find("timeout") == m_tcs[ident].end())
m_tcs[ident].insert(std::make_pair("timeout", "300"));
if (m_tcs[ident].find("use.fs") == m_tcs[ident].end())
m_tcs[ident].insert(std::make_pair("use.fs", "false"));
m_tcs[ident].insert(std::make_pair("timeout", "30"));
}
public:
@ -267,6 +266,11 @@ run_test_case_child(void* raw_params)
const test_case_params* params =
static_cast< const test_case_params* >(raw_params);
const std::pair< int, int > user = impl::get_required_user(
params->metadata, params->config);
if (user.first != -1 && user.second != -1)
impl::drop_privileges(user);
// The input 'tp' parameter may be relative and become invalid once
// we change the current working directory.
const atf::fs::path absolute_executable = params->executable.to_absolute();
@ -422,12 +426,7 @@ detail::atf_tp_reader::validate_and_insert(const std::string& name,
throw parse_error(lineno, "The timeout property requires an integer"
" value");
} else if (name == "use.fs") {
try {
(void)atf::text::to_bool(value);
} catch (const std::runtime_error&) {
throw parse_error(lineno, "The use.fs property requires a boolean"
" value");
}
// Deprecated; ignore it.
} else if (name.size() > 2 && name[0] == 'X' && name[1] == '-') {
// Any non-empty value is valid.
} else {