From 0b634f14204cd631d9110f6183d691dfec5e133a Mon Sep 17 00:00:00 2001 From: jmmv Date: Sun, 7 Nov 2010 17:45:21 +0000 Subject: [PATCH] Help merge of atf-0.12. --- external/bsd/atf/dist/atf-c++/tests.cpp | 10 ++ external/bsd/atf/dist/atf-c++/tests.hpp | 12 ++- external/bsd/atf/dist/atf-c/tc.c | 64 +++++++++++++ external/bsd/atf/dist/atf-run/atf-run.cpp | 94 ++++++++----------- external/bsd/atf/dist/atf-run/io_test.cpp | 4 - .../bsd/atf/dist/atf-run/test-program.cpp | 19 ++-- 6 files changed, 130 insertions(+), 73 deletions(-) diff --git a/external/bsd/atf/dist/atf-c++/tests.cpp b/external/bsd/atf/dist/atf-c++/tests.cpp index 307cd164d5ae..054c6fbf51c1 100644 --- a/external/bsd/atf/dist/atf-c++/tests.cpp +++ b/external/bsd/atf/dist/atf-c++/tests.cpp @@ -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. // ------------------------------------------------------------------------ diff --git a/external/bsd/atf/dist/atf-c++/tests.hpp b/external/bsd/atf/dist/atf-c++/tests.hpp index fbfed4f72a70..208e33da256b 100644 --- a/external/bsd/atf/dist/atf-c++/tests.hpp +++ b/external/bsd/atf/dist/atf-c++/tests.hpp @@ -34,6 +34,10 @@ #include #include +extern "C" { +#include +} + #include 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*, diff --git a/external/bsd/atf/dist/atf-c/tc.c b/external/bsd/atf/dist/atf-c/tc.c index 56da2af8b21c..02d2af0fa61f 100644 --- a/external/bsd/atf/dist/atf-c/tc.c +++ b/external/bsd/atf/dist/atf-c/tc.c @@ -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) { diff --git a/external/bsd/atf/dist/atf-run/atf-run.cpp b/external/bsd/atf/dist/atf-run/atf-run.cpp index 7623f182797a..8a392aabf37d 100644 --- a/external/bsd/atf/dist/atf-run/atf-run.cpp +++ b/external/bsd/atf/dist/atf-run/atf-run.cpp @@ -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); } diff --git a/external/bsd/atf/dist/atf-run/io_test.cpp b/external/bsd/atf/dist/atf-run/io_test.cpp index 4df50fa9ebff..9dad0620342b 100644 --- a/external/bsd/atf/dist/atf-run/io_test.cpp +++ b/external/bsd/atf/dist/atf-run/io_test.cpp @@ -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) { diff --git a/external/bsd/atf/dist/atf-run/test-program.cpp b/external/bsd/atf/dist/atf-run/test-program.cpp index ecc885434e94..c3c5885e5c50 100644 --- a/external/bsd/atf/dist/atf-run/test-program.cpp +++ b/external/bsd/atf/dist/atf-run/test-program.cpp @@ -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 {