Import atf 0.12:

Experimental version released on November 7th, 2010.

* Added the ATF_REQUIRE_THROW_RE to atf-c++, which is the same as
  ATF_REQUIRE_THROW but allows checking for the validity of the exception's
  error message by means of a regular expression.

* Added the ATF_REQUIRE_MATCH to atf-c++, which allows checking for a
  regular expression match in a string.

* Changed the default timeout for test cases from 5 minutes to 30 seconds.
  30 seconds is long enough for virtually all tests to complete, and 5
  minutes is a way too long pause in a test suite where a single test case
  stalls.

* Deprecated the use.fs property.  While this seemed like a good idea in
  the first place to impose more control on what test cases can do, it
  turns out to be bad.  First, use.fs=false prevents bogus test cases
  from dumping core so after-the-fact debugging is harder.  Second,
  supporting use.fs adds a lot of unnecessary complexity.  atf-run will
  now ignore any value provided to use.fs and will allow test cases to
  freely access the file system if they wish to.

* Added the atf_tc_get_config_var_as_{bool,long}{,_wd} functions to the atf-c
  library.  The 'text' module became private in 0.11 but was being used
  externally to simplify the parsing of configuration variables.

* Made atf-run recognize the 'unprivileged-user' configuration variable
  and automatically drop root privileges when a test case sets
  require.user=unprivileged.  Note that this is, by no means, done for
  security purposes; this is just for user convenience; tests should, in
  general, not be blindly run as root in the first place.
This commit is contained in:
jmmv 2010-11-07 17:43:22 +00:00
parent 4e1e5c3604
commit 0ebb519dda
53 changed files with 442 additions and 422 deletions

View File

@ -2,6 +2,42 @@ Major changes between releases Automated Testing Framework
===========================================================================
Changes in version 0.12
***********************
Experimental version released on November 7th, 2010.
* Added the ATF_REQUIRE_THROW_RE to atf-c++, which is the same as
ATF_REQUIRE_THROW but allows checking for the validity of the exception's
error message by means of a regular expression.
* Added the ATF_REQUIRE_MATCH to atf-c++, which allows checking for a
regular expression match in a string.
* Changed the default timeout for test cases from 5 minutes to 30 seconds.
30 seconds is long enough for virtually all tests to complete, and 5
minutes is a way too long pause in a test suite where a single test case
stalls.
* Deprecated the use.fs property. While this seemed like a good idea in
the first place to impose more control on what test cases can do, it
turns out to be bad. First, use.fs=false prevents bogus test cases
from dumping core so after-the-fact debugging is harder. Second,
supporting use.fs adds a lot of unnecessary complexity. atf-run will
now ignore any value provided to use.fs and will allow test cases to
freely access the file system if they wish to.
* Added the atf_tc_get_config_var_as_{bool,long}{,_wd} functions to the atf-c
library. The 'text' module became private in 0.11 but was being used
externally to simplify the parsing of configuration variables.
* Made atf-run recognize the 'unprivileged-user' configuration variable
and automatically drop root privileges when a test case sets
require.user=unprivileged. Note that this is, by no means, done for
security purposes; this is just for user convenience; tests should, in
general, not be blindly run as root in the first place.
Changes in version 0.11
***********************

View File

@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd July 4, 2010
.Dd October 21, 2010
.Dt ATF-C++-API 3
.Os
.Sh NAME
@ -38,7 +38,9 @@
.Nm ATF_REQUIRE ,
.Nm ATF_REQUIRE_EQ ,
.Nm ATF_REQUIRE_ERRNO ,
.Nm ATF_REQUIRE_MATCH ,
.Nm ATF_REQUIRE_THROW ,
.Nm ATF_REQUIRE_THROW_RE ,
.Nm ATF_SKIP ,
.Nm ATF_TEST_CASE ,
.Nm ATF_TEST_CASE_BODY ,
@ -57,7 +59,9 @@
.Fn ATF_REQUIRE "expression"
.Fn ATF_REQUIRE_EQ "expression_1" "expression_2"
.Fn ATF_REQUIRE_ERRNO "exp_errno" "bool_expression"
.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
.Fn ATF_SKIP "reason"
.Fn ATF_TEST_CASE "name"
.Fn ATF_TEST_CASE_BODY "name"
@ -276,6 +280,10 @@ This is the normal mode of execution.
In this mode, any failure is reported as such to the user and the test case
is marked as
.Sq failed .
.It Fn expect_race "reason"
Any failure or timeout during the execution of the test case will be
considered as if a race condition has been triggered and reported as such.
If no problems arise, the test will continue execution as usual.
.It Fn expect_signal "signo" "reason"
Expects the test case to terminate due to the reception of a signal.
If
@ -305,9 +313,17 @@ takes an expression and raises a failure if it evaluates to false.
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
.Pp
.Fn ATF_REQUIRE_MATCH
takes a regular expression and a string and raises a failure if the regular
expression does not match the string.
.Pp
.Fn ATF_REQUIRE_THROW
takes the name of an exception and a statement and raises a failure if
the statement does not throw the specified exception.
.Fn ATF_REQUIRE_THROW_EQ
takes the name of an exception, a regular expresion and a statement and raises a
failure if the statement does not throw the specified exception and if the
message of the exception does not match the regular expression.
.Pp
.Fn ATF_CHECK_ERRNO
and

View File

@ -145,7 +145,7 @@ impl::build_cxx_o(const std::string& sfile, const std::string& ofile,
return success;
}
impl::check_result
std::auto_ptr< impl::check_result >
impl::exec(const atf::process::argv_array& argva)
{
atf_check_result_t result;
@ -154,5 +154,5 @@ impl::exec(const atf::process::argv_array& argva)
if (atf_is_error(err))
throw_atf_error(err);
return impl::check_result(&result);
return std::auto_ptr< impl::check_result >(new impl::check_result(&result));
}

View File

@ -39,6 +39,8 @@ extern "C" {
#include <string>
#include <vector>
#include <atf-c++/utils.hpp>
namespace atf {
namespace process {
@ -58,11 +60,10 @@ namespace check {
//! of executing arbitrary command and manages files containing
//! its output.
//!
class check_result {
class check_result : utils::noncopyable {
//!
//! \brief Internal representation of a result.
//!
// XXX: This is non-copyable! The class must define it as such.
atf_check_result_t m_result;
//!
@ -72,7 +73,7 @@ class check_result {
check_result(const atf_check_result_t* result);
friend check_result test_constructor(const char* const*);
friend check_result exec(const atf::process::argv_array&);
friend std::auto_ptr< check_result > exec(const atf::process::argv_array&);
public:
//!
@ -121,7 +122,7 @@ bool build_cpp(const std::string&, const std::string&,
const atf::process::argv_array&);
bool build_cxx_o(const std::string&, const std::string&,
const atf::process::argv_array&);
check_result exec(const atf::process::argv_array&);
std::auto_ptr< check_result > exec(const atf::process::argv_array&);
// Useful for testing only.
check_result test_constructor(void);

View File

@ -57,7 +57,7 @@ extern "C" {
// ------------------------------------------------------------------------
static
atf::check::check_result
std::auto_ptr< atf::check::check_result >
do_exec(const atf::tests::tc* tc, const char* helper_name)
{
std::vector< std::string > argv;
@ -70,7 +70,7 @@ do_exec(const atf::tests::tc* tc, const char* helper_name)
}
static
atf::check::check_result
std::auto_ptr< atf::check::check_result >
do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
{
std::vector< std::string > argv;
@ -188,7 +188,6 @@ ATF_TEST_CASE(build_c_o);
ATF_TEST_CASE_HEAD(build_c_o)
{
set_md_var("descr", "Tests the build_c_o function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(build_c_o)
{
@ -207,7 +206,6 @@ ATF_TEST_CASE(build_cpp);
ATF_TEST_CASE_HEAD(build_cpp)
{
set_md_var("descr", "Tests the build_cpp function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(build_cpp)
{
@ -227,7 +225,6 @@ ATF_TEST_CASE(build_cxx_o);
ATF_TEST_CASE_HEAD(build_cxx_o)
{
set_md_var("descr", "Tests the build_cxx_o function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(build_cxx_o)
{
@ -254,9 +251,10 @@ ATF_TEST_CASE_BODY(exec_cleanup)
std::auto_ptr< atf::fs::path > err;
{
const atf::check::check_result r = do_exec(this, "exit-success");
out.reset(new atf::fs::path(r.stdout_path()));
err.reset(new atf::fs::path(r.stderr_path()));
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-success");
out.reset(new atf::fs::path(r->stdout_path()));
err.reset(new atf::fs::path(r->stderr_path()));
ATF_REQUIRE(atf::fs::exists(*out.get()));
ATF_REQUIRE(atf::fs::exists(*err.get()));
}
@ -273,24 +271,27 @@ ATF_TEST_CASE_HEAD(exec_exitstatus)
ATF_TEST_CASE_BODY(exec_exitstatus)
{
{
atf::check::check_result r = do_exec(this, "exit-success");
ATF_REQUIRE(r.exited());
ATF_REQUIRE(!r.signaled());
ATF_REQUIRE_EQ(r.exitcode(), EXIT_SUCCESS);
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-success");
ATF_REQUIRE(r->exited());
ATF_REQUIRE(!r->signaled());
ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);
}
{
atf::check::check_result r = do_exec(this, "exit-failure");
ATF_REQUIRE(r.exited());
ATF_REQUIRE(!r.signaled());
ATF_REQUIRE_EQ(r.exitcode(), EXIT_FAILURE);
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-failure");
ATF_REQUIRE(r->exited());
ATF_REQUIRE(!r->signaled());
ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);
}
{
atf::check::check_result r = do_exec(this, "exit-signal");
ATF_REQUIRE(!r.exited());
ATF_REQUIRE(r.signaled());
ATF_REQUIRE_EQ(r.termsig(), SIGKILL);
std::auto_ptr< atf::check::check_result > r =
do_exec(this, "exit-signal");
ATF_REQUIRE(!r->exited());
ATF_REQUIRE(r->signaled());
ATF_REQUIRE_EQ(r->termsig(), SIGKILL);
}
}
@ -319,20 +320,20 @@ ATF_TEST_CASE_HEAD(exec_stdout_stderr)
}
ATF_TEST_CASE_BODY(exec_stdout_stderr)
{
const atf::check::check_result r1 = do_exec(this, "stdout-stderr",
"result1");
ATF_REQUIRE(r1.exited());
ATF_REQUIRE_EQ(r1.exitcode(), EXIT_SUCCESS);
std::auto_ptr< atf::check::check_result > r1 =
do_exec(this, "stdout-stderr", "result1");
ATF_REQUIRE(r1->exited());
ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);
const atf::check::check_result r2 = do_exec(this, "stdout-stderr",
"result2");
ATF_REQUIRE(r2.exited());
ATF_REQUIRE_EQ(r2.exitcode(), EXIT_SUCCESS);
std::auto_ptr< atf::check::check_result > r2 =
do_exec(this, "stdout-stderr", "result2");
ATF_REQUIRE(r2->exited());
ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);
const std::string out1 = r1.stdout_path();
const std::string out2 = r2.stdout_path();
const std::string err1 = r1.stderr_path();
const std::string err2 = r2.stderr_path();
const std::string out1 = r1->stdout_path();
const std::string out2 = r2->stdout_path();
const std::string err1 = r1->stderr_path();
const std::string err2 = r2->stderr_path();
ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);
ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);
@ -370,9 +371,9 @@ ATF_TEST_CASE_BODY(exec_unknown)
argv.push_back(atf::config::get("atf_workdir") + "/non-existent");
atf::process::argv_array argva(argv);
const atf::check::check_result r = atf::check::exec(argva);
ATF_REQUIRE(r.exited());
ATF_REQUIRE_EQ(r.exitcode(), 127);
std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva);
ATF_REQUIRE(r->exited());
ATF_REQUIRE_EQ(r->exitcode(), 127);
}
// ------------------------------------------------------------------------

View File

@ -212,7 +212,6 @@ ATF_TEST_CASE_HEAD(path_to_absolute)
{
set_md_var("descr", "Tests the conversion of a relative path to an "
"absolute one");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(path_to_absolute)
{
@ -270,7 +269,6 @@ ATF_TEST_CASE_HEAD(directory_read)
{
set_md_var("descr", "Tests the directory class creation, which reads "
"the contents of a directory");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(directory_read)
{
@ -292,7 +290,6 @@ ATF_TEST_CASE_HEAD(directory_file_info)
{
set_md_var("descr", "Tests that the file_info objects attached to the "
"directory are valid");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(directory_file_info)
{
@ -323,7 +320,6 @@ ATF_TEST_CASE(directory_names);
ATF_TEST_CASE_HEAD(directory_names)
{
set_md_var("descr", "Tests the directory's names method");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(directory_names)
{
@ -349,7 +345,6 @@ ATF_TEST_CASE(file_info_stat);
ATF_TEST_CASE_HEAD(file_info_stat)
{
set_md_var("descr", "Tests the file_info creation and its basic contents");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(file_info_stat)
{
@ -376,7 +371,6 @@ ATF_TEST_CASE_HEAD(file_info_perms)
{
set_md_var("descr", "Tests the file_info methods to get the file's "
"permissions");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(file_info_perms)
{
@ -452,7 +446,6 @@ ATF_TEST_CASE(exists);
ATF_TEST_CASE_HEAD(exists)
{
set_md_var("descr", "Tests the exists function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(exists)
{
@ -476,7 +469,6 @@ ATF_TEST_CASE(is_executable);
ATF_TEST_CASE_HEAD(is_executable)
{
set_md_var("descr", "Tests the is_executable function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(is_executable)
{
@ -501,7 +493,6 @@ ATF_TEST_CASE(remove);
ATF_TEST_CASE_HEAD(remove)
{
set_md_var("descr", "Tests the remove function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(remove)
{

View File

@ -50,7 +50,6 @@
{ \
set_md_var("descr", "Tests that the " hdrname " file can be " \
"included on its own, without any prerequisites"); \
set_md_var("use.fs", "true"); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
@ -62,7 +61,6 @@
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", descr); \
set_md_var("use.fs", "true"); \
} \
ATF_TEST_CASE_BODY(name) \
{ \

View File

@ -101,6 +101,16 @@
} \
} while (false)
#define ATF_REQUIRE_MATCH(regexp, string) \
do { \
if (!atf::tests::detail::match(regexp, string)) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \
<< "match regexp '" << regexp << "'"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_REQUIRE_THROW(e, x) \
do { \
try { \
@ -123,6 +133,35 @@
} \
} while (false)
#define ATF_REQUIRE_THROW_RE(type, regexp, x) \
do { \
try { \
x; \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " did not throw " \
#type " as expected"; \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (const type& e) { \
if (!atf::tests::detail::match(regexp, e.what())) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " threw " #type "(" \
<< e.what() << "), but does not match '" << regexp \
<< "'"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} catch (const std::exception& atfu_e) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
"unexpected error (not " #type "): " << atfu_e.what(); \
atf::tests::tc::fail(atfu_ss.str()); \
} catch (...) { \
std::ostringstream atfu_ss; \
atfu_ss << "Line " << __LINE__ << ": " #x " threw an " \
"unexpected error (not " #type ")"; \
atf::tests::tc::fail(atfu_ss.str()); \
} \
} while (false)
#define ATF_CHECK_ERRNO(exp_errno, bool_expr) \
atf::tests::tc::check_errno(__FILE__, __LINE__, exp_errno, #bool_expr, \
bool_expr)

View File

@ -125,6 +125,21 @@ ATF_TEST_CASE_BODY(h_require_eq)
create_ctl_file(*this, "after");
}
ATF_TEST_CASE(h_require_match);
ATF_TEST_CASE_HEAD(h_require_match)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_match)
{
const std::string regexp = get_config_var("regexp");
const std::string string = get_config_var("string");
create_ctl_file(*this, "before");
ATF_REQUIRE_MATCH(regexp, string);
create_ctl_file(*this, "after");
}
ATF_TEST_CASE(h_require_throw);
ATF_TEST_CASE_HEAD(h_require_throw)
{
@ -146,6 +161,30 @@ ATF_TEST_CASE_BODY(h_require_throw)
create_ctl_file(*this, "after");
}
ATF_TEST_CASE(h_require_throw_re);
ATF_TEST_CASE_HEAD(h_require_throw_re)
{
set_md_var("descr", "Helper test case");
}
ATF_TEST_CASE_BODY(h_require_throw_re)
{
create_ctl_file(*this, "before");
if (get_config_var("what") == "throw_int")
ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
else if (get_config_var("what") == "throw_rt_match")
ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
if (1) throw std::runtime_error("a foo bar baz"));
else if (get_config_var("what") == "throw_rt_no_match")
ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
if (1) throw std::runtime_error("baz foo bar a"));
else if (get_config_var("what") == "no_throw_rt")
ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
if (0) throw std::runtime_error("e"));
create_ctl_file(*this, "after");
}
static int
errno_fail_stub(const int raised_errno)
{
@ -209,7 +248,6 @@ ATF_TEST_CASE(pass);
ATF_TEST_CASE_HEAD(pass)
{
set_md_var("descr", "Tests the ATF_PASS macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(pass)
{
@ -223,7 +261,6 @@ ATF_TEST_CASE(fail);
ATF_TEST_CASE_HEAD(fail)
{
set_md_var("descr", "Tests the ATF_FAIL macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(fail)
{
@ -237,7 +274,6 @@ ATF_TEST_CASE(skip);
ATF_TEST_CASE_HEAD(skip)
{
set_md_var("descr", "Tests the ATF_SKIP macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(skip)
{
@ -251,7 +287,6 @@ ATF_TEST_CASE(require);
ATF_TEST_CASE_HEAD(require)
{
set_md_var("descr", "Tests the ATF_REQUIRE macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(require)
{
@ -294,7 +329,6 @@ ATF_TEST_CASE(require_eq);
ATF_TEST_CASE_HEAD(require_eq)
{
set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(require_eq)
{
@ -339,11 +373,56 @@ ATF_TEST_CASE_BODY(require_eq)
}
}
ATF_TEST_CASE(require_match);
ATF_TEST_CASE_HEAD(require_match)
{
set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
}
ATF_TEST_CASE_BODY(require_match)
{
struct test {
const char *regexp;
const char *string;
bool ok;
} *t, tests[] = {
{ "foo.*bar", "this is a foo, bar, baz", true },
{ "bar.*baz", "this is a baz, bar, foo", false },
{ NULL, NULL, false }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->regexp != NULL; t++) {
atf::tests::vars_map config;
config["regexp"] = t->regexp;
config["string"] = t->string;
std::cout << "Checking with " << t->regexp << ", " << t->string
<< " and expecting " << (t->ok ? "true" : "false")
<< "\n";
run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(grep_file("result", "^passed"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
ATF_REQUIRE(grep_file("result", "^failed: "));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(require_throw);
ATF_TEST_CASE_HEAD(require_throw)
{
set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(require_throw)
{
@ -388,11 +467,60 @@ ATF_TEST_CASE_BODY(require_throw)
}
}
ATF_TEST_CASE(require_throw_re);
ATF_TEST_CASE_HEAD(require_throw_re)
{
set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
}
ATF_TEST_CASE_BODY(require_throw_re)
{
struct test {
const char *what;
bool ok;
const char *msg;
} *t, tests[] = {
{ "throw_int", false, "unexpected error" },
{ "throw_rt_match", true, NULL },
{ "throw_rt_no_match", true, "threw.*runtime_error(baz foo bar a).*"
"does not match 'a foo bar baz'" },
{ "no_throw_rt", false, "did not throw" },
{ NULL, false, NULL }
};
const atf::fs::path before("before");
const atf::fs::path after("after");
for (t = &tests[0]; t->what != NULL; t++) {
atf::tests::vars_map config;
config["what"] = t->what;
std::cout << "Checking with " << t->what << " and expecting "
<< (t->ok ? "true" : "false") << "\n";
run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
ATF_REQUIRE(atf::fs::exists(before));
if (t->ok) {
ATF_REQUIRE(grep_file("result", "^passed"));
ATF_REQUIRE(atf::fs::exists(after));
} else {
std::cout << "Checking that message contains '" << t->msg
<< "'\n";
std::string exp_result = std::string("^failed: .*") + t->msg;
ATF_REQUIRE(grep_file("result", exp_result.c_str()));
ATF_REQUIRE(!atf::fs::exists(after));
}
atf::fs::remove(before);
if (t->ok)
atf::fs::remove(after);
}
}
ATF_TEST_CASE(check_errno);
ATF_TEST_CASE_HEAD(check_errno)
{
set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(check_errno)
{
@ -440,7 +568,6 @@ ATF_TEST_CASE(require_errno);
ATF_TEST_CASE_HEAD(require_errno)
{
set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(require_errno)
{
@ -508,7 +635,9 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, check_errno);
ATF_ADD_TEST_CASE(tcs, require);
ATF_ADD_TEST_CASE(tcs, require_eq);
ATF_ADD_TEST_CASE(tcs, require_match);
ATF_ADD_TEST_CASE(tcs, require_throw);
ATF_ADD_TEST_CASE(tcs, require_throw_re);
ATF_ADD_TEST_CASE(tcs, require_errno);
// Add the test cases for the header file.

View File

@ -60,7 +60,6 @@ version_head()
{
atf_set "descr" "Checks that the version in atf-c++ is correct"
atf_set "require.progs" "pkg-config"
atf_set "use.fs" "true"
}
version_body()
{
@ -75,7 +74,6 @@ build_head()
atf_set "descr" "Checks that a test program can be built against" \
"the C++ library based on the pkg-config information"
atf_set "require.progs" "pkg-config"
atf_set "use.fs" "true"
}
build_body()
{

View File

@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 28, 2010
.Dd November 1, 2010
.Dt ATF-C-API 3
.Os
.Sh NAME
@ -233,11 +233,21 @@ Both of them are strings.
The test case has read-only access to the current configuration variables
by means of the
.Ft bool
.Fn atf_tc_has_config_var
and the
.Fn atf_tc_has_config_var ,
.Ft const char *
.Fn atf_tc_get_config_var
methods, which can be called in any of the three parts of a test case.
.Fn atf_tc_get_config_var ,
.Ft const char *
.Fn atf_tc_get_config_var_wd ,
.Ft bool
.Fn atf_tc_get_config_var_as_bool ,
.Ft bool
.Fn atf_tc_get_config_var_as_bool_wd ,
.Ft long
.Fn atf_tc_get_config_var_as_long ,
and the
.Ft long
.Fn atf_tc_get_config_var_as_long_wd
functions, which can be called in any of the three parts of a test case.
.Ss Access to the source directory
It is possible to get the path to the test case's source directory from any
of its three components by querying the

View File

@ -470,25 +470,21 @@ atf_check_exec_array(const char *const *argv, atf_check_result_t *r)
goto out;
err = atf_check_result_init(r, argv, &dir);
if (atf_is_error(err))
goto err_dir;
if (atf_is_error(err)) {
atf_error_t err2 = atf_fs_rmdir(&dir);
INV(!atf_is_error(err2));
goto out;
}
err = fork_and_wait(argv, &r->pimpl->m_stdout, &r->pimpl->m_stderr,
&r->pimpl->m_status);
if (atf_is_error(err))
goto err_r;
if (atf_is_error(err)) {
atf_check_result_fini(r);
goto out;
}
INV(!atf_is_error(err));
goto out_dir;
err_r:
atf_check_result_fini(r);
err_dir:
{
atf_error_t err2 = atf_fs_rmdir(&dir);
INV(!atf_is_error(err2));
}
out_dir:
atf_fs_path_fini(&dir);
out:
return err;

View File

@ -241,7 +241,6 @@ ATF_TC_HEAD(build_c_o, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
"function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(build_c_o, tc)
{
@ -263,7 +262,6 @@ ATF_TC_HEAD(build_cpp, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
"function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(build_cpp, tc)
{
@ -286,7 +284,6 @@ ATF_TC_HEAD(build_cxx_o, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
"function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(build_cxx_o, tc)
{

View File

@ -368,7 +368,6 @@ ATF_TC_HEAD(path_to_absolute, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute "
"function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(path_to_absolute, tc)
{
@ -436,7 +435,6 @@ ATF_TC_HEAD(stat_mode, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function "
"and, indirectly, the constructor");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(stat_mode, tc)
{
@ -464,7 +462,6 @@ ATF_TC_HEAD(stat_type, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function "
"and, indirectly, the constructor");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(stat_type, tc)
{
@ -491,7 +488,6 @@ ATF_TC(stat_perms);
ATF_TC_HEAD(stat_perms, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(stat_perms, tc)
{
@ -569,7 +565,6 @@ ATF_TC(exists);
ATF_TC_HEAD(exists, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(exists, tc)
{
@ -618,7 +613,6 @@ ATF_TC(eaccess);
ATF_TC_HEAD(eaccess, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(eaccess, tc)
{
@ -725,7 +719,6 @@ ATF_TC(getcwd);
ATF_TC_HEAD(getcwd, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(getcwd, tc)
{
@ -749,7 +742,6 @@ ATF_TC(rmdir_empty);
ATF_TC_HEAD(rmdir_empty, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(rmdir_empty, tc)
{
@ -769,7 +761,6 @@ ATF_TC(rmdir_enotempty);
ATF_TC_HEAD(rmdir_enotempty, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(rmdir_enotempty, tc)
{
@ -795,7 +786,6 @@ ATF_TC(rmdir_eperm);
ATF_TC_HEAD(rmdir_eperm, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(rmdir_eperm, tc)
{
@ -827,7 +817,6 @@ ATF_TC_HEAD(mkdtemp_ok, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
"successful execution");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(mkdtemp_ok, tc)
{
@ -878,7 +867,6 @@ ATF_TC_HEAD(mkdtemp_err, tc)
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
"error conditions");
atf_tc_set_md_var(tc, "require.user", "unprivileged");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(mkdtemp_err, tc)
{
@ -951,7 +939,6 @@ ATF_TC_HEAD(mkstemp_ok, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
"successful execution");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(mkstemp_ok, tc)
{
@ -1011,7 +998,6 @@ ATF_TC_HEAD(mkstemp_err, tc)
atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
"error conditions");
atf_tc_set_md_var(tc, "require.user", "unprivileged");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(mkstemp_err, tc)
{

View File

@ -662,7 +662,6 @@ ATF_TC_HEAD(status_coredump, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
"that crash");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(status_coredump, tc)
{
@ -913,7 +912,6 @@ ATF_TC(exec_list);
ATF_TC_HEAD(exec_list, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests execing a command");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(exec_list, tc)
{
@ -1034,7 +1032,6 @@ ATF_TC_BODY(fork_cookie, tc)
{ \
atf_tc_set_md_var(tc, "descr", "Tests forking a child, with " \
"stdout " #outlc " and stderr " #errlc); \
atf_tc_set_md_var(tc, "use.fs", "true"); \
} \
ATF_TC_BODY(fork_out_ ## outlc ## _err_ ## errlc, tc) \
{ \

View File

@ -49,7 +49,6 @@ struct atf_fs_path;
{ \
atf_tc_set_md_var(tc, "descr", "Tests that the " hdrname " file can " \
"be included on its own, without any prerequisites"); \
atf_tc_set_md_var(tc, "use.fs", "true"); \
} \
ATF_TC_BODY(name, tc) \
{ \
@ -61,7 +60,6 @@ struct atf_fs_path;
ATF_TC_HEAD(name, tc) \
{ \
atf_tc_set_md_var(tc, "descr", descr); \
atf_tc_set_md_var(tc, "use.fs", "true"); \
} \
ATF_TC_BODY(name, tc) \
{ \

View File

@ -70,7 +70,6 @@ ATF_TC(grep_file);
ATF_TC_HEAD(grep_file, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the grep_file helper function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(grep_file, tc)
{
@ -96,7 +95,6 @@ ATF_TC(read_line);
ATF_TC_HEAD(read_line, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the read_line function");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(read_line, tc)
{

View File

@ -212,7 +212,6 @@ ATF_TC(check_errno);
ATF_TC_HEAD(check_errno, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(check_errno, tc)
{
@ -257,7 +256,6 @@ ATF_TC(require_errno);
ATF_TC_HEAD(require_errno, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(require_errno, tc)
{
@ -312,7 +310,6 @@ ATF_TC_HEAD(check, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
"ATF_CHECK_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(check, tc)
{
@ -410,7 +407,6 @@ ATF_TC_HEAD(check_eq, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and "
"ATF_CHECK_EQ_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(check_eq, tc)
{
@ -455,7 +451,6 @@ ATF_TC_HEAD(check_streq, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and "
"ATF_CHECK_STREQ_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(check_streq, tc)
{
@ -503,7 +498,6 @@ ATF_TC_HEAD(require, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
"ATF_REQUIRE_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(require, tc)
{
@ -601,7 +595,6 @@ ATF_TC_HEAD(require_eq, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and "
"ATF_REQUIRE_EQ_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(require_eq, tc)
{
@ -646,7 +639,6 @@ ATF_TC_HEAD(require_streq, tc)
{
atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and "
"ATF_REQUIRE_STREQ_MSG macros");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(require_streq, tc)
{
@ -709,7 +701,6 @@ ATF_TC_HEAD(msg_embedded_fmt, tc)
atf_tc_set_md_var(tc, "descr", "Tests that format strings passed "
"as part of the automatically-generated messages "
"do not get expanded");
atf_tc_set_md_var(tc, "use.fs", "true");
}
ATF_TC_BODY(msg_embedded_fmt, tc)
{

View File

@ -60,7 +60,6 @@ version_head()
{
atf_set "descr" "Checks that the version in atf-c is correct"
atf_set "require.progs" "pkg-config"
atf_set "use.fs" "true"
}
version_body()
{
@ -75,7 +74,6 @@ build_head()
atf_set "descr" "Checks that a test program can be built against" \
"the C library based on the pkg-config information"
atf_set "require.progs" "pkg-config"
atf_set "use.fs" "true"
}
build_body()
{

View File

@ -81,6 +81,12 @@ const char *atf_tc_get_ident(const atf_tc_t *);
const char *atf_tc_get_config_var(const atf_tc_t *, const char *);
const char *atf_tc_get_config_var_wd(const atf_tc_t *, const char *,
const char *);
bool atf_tc_get_config_var_as_bool(const atf_tc_t *, const char *);
bool atf_tc_get_config_var_as_bool_wd(const atf_tc_t *, const char *,
const bool);
long atf_tc_get_config_var_as_long(const atf_tc_t *, const char *);
long atf_tc_get_config_var_as_long_wd(const atf_tc_t *, const char *,
const long);
const char *atf_tc_get_md_var(const atf_tc_t *, const char *);
char **atf_tc_get_md_vars(const atf_tc_t *);
bool atf_tc_has_config_var(const atf_tc_t *, const char *);

View File

@ -49,7 +49,6 @@ list_all_head()
{
atf_set "descr" "Tests that at atf-config prints all expected" \
"variables, and not more"
atf_set "use.fs" "true"
}
list_all_body()
{
@ -65,7 +64,6 @@ atf_test_case query_one
query_one_head()
{
atf_set "descr" "Tests that querying a single variable works"
atf_set "use.fs" "true"
}
query_one_body()
{
@ -82,7 +80,6 @@ query_one_terse_head()
{
atf_set "descr" "Tests that querying a single variable in terse mode" \
"works"
atf_set "use.fs" "true"
}
query_one_terse_body()
{
@ -101,7 +98,6 @@ atf_test_case query_multiple
query_multiple_head()
{
atf_set "descr" "Tests that querying multiple variables works"
atf_set "use.fs" "true"
}
query_multiple_body()
{
@ -116,7 +112,6 @@ query_unknown_head()
{
atf_set "descr" "Tests that querying an unknown variable delivers" \
"the correct error"
atf_set "use.fs" "true"
}
query_unknown_body()
{
@ -129,7 +124,6 @@ query_mixture_head()
{
atf_set "descr" "Tests that querying a known and an unknown variable" \
"delivers the correct error"
atf_set "use.fs" "true"
}
query_mixture_body()
{
@ -146,7 +140,6 @@ override_env_head()
{
atf_set "descr" "Tests that build-time variables can be overriden" \
"through their corresponding environment variables"
atf_set "use.fs" "true"
}
override_env_body()
{

View File

@ -88,7 +88,6 @@ default_head()
{
atf_set "descr" "Checks that the default output uses the ticker" \
"format"
atf_set "use.fs" "true"
}
default_body()
{
@ -104,10 +103,6 @@ default_body()
# tests. However, to do that, we need to migrate to using C helpers for
# simplicity in raising signals...
atf_test_case expect
expect_head()
{
atf_set "use.fs" "true"
}
expect_body()
{
ln -s "$(atf_get_srcdir)/../atf-run/expect_helpers" .
@ -197,7 +192,6 @@ atf_test_case oflag
oflag_head()
{
atf_set "descr" "Checks that the -o flag works"
atf_set "use.fs" "true"
}
oflag_body()
{
@ -251,7 +245,6 @@ atf_test_case output_csv
output_csv_head()
{
atf_set "descr" "Checks the CSV output format"
atf_set "use.fs" "true"
}
output_csv_body()
{
@ -279,7 +272,6 @@ atf_test_case output_ticker
output_ticker_head()
{
atf_set "descr" "Checks the ticker output format"
atf_set "use.fs" "true"
}
output_ticker_body()
{
@ -324,7 +316,6 @@ atf_test_case output_xml
output_xml_head()
{
atf_set "descr" "Checks the XML output format"
atf_set "use.fs" "true"
}
output_xml_body()
{
@ -375,7 +366,6 @@ output_xml_space_head()
atf_set "descr" "Checks that the XML output format properly preserves" \
"leading and trailing whitespace in stdout and stderr" \
"lines"
atf_set "use.fs" "true"
}
output_xml_space_body()
{

View File

@ -1,7 +1,7 @@
.\"
.\" Automated Testing Framework (atf)
.\"
.\" Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
.\" Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 25, 2007
.Dd November 1, 2010
.Dt ATF-RUN 1
.Os
.Sh NAME
@ -129,6 +129,17 @@ The value of
.Va ATF_CONFDIR
in the above list determined as detailed in
.Xr atf-config 1 .
.Pp
The following configuration variables are globally recognized:
.Bl -tag -width XunprivilegedXuserXX
.It Va unprivileged-user
The name of the system user that atf-run will drop root privileges into
for test cases defining
.Sq require.user=unprivileged .
Note that this is
.Em not provided for security purposes ;
this feature is only for the convenience of the user.
.El
.Ss Hooks
.Nm Ns 's
internal behavior can be customized by the system administrator and the

View File

@ -517,10 +517,7 @@ ATF_TEST_CASE_BODY(atffile_getters) {
// Tests cases for the free functions.
// ------------------------------------------------------------------------
ATF_TEST_CASE(read_ok_simple);
ATF_TEST_CASE_HEAD(read_ok_simple) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_ok_simple);
ATF_TEST_CASE_BODY(read_ok_simple) {
std::auto_ptr< std::ofstream > os = new_atffile();
(*os) << "prop: test-suite = foo\n";
@ -550,10 +547,7 @@ ATF_TEST_CASE_BODY(read_ok_simple) {
ATF_REQUIRE_EQ("propvalue1", atffile.props().find("prop1")->second);
}
ATF_TEST_CASE(read_ok_some_globs);
ATF_TEST_CASE_HEAD(read_ok_some_globs) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_ok_some_globs);
ATF_TEST_CASE_BODY(read_ok_some_globs) {
std::auto_ptr< std::ofstream > os = new_atffile();
(*os) << "prop: test-suite = foo\n";
@ -580,10 +574,7 @@ ATF_TEST_CASE_BODY(read_ok_some_globs) {
ATF_REQUIRE(is_in("t_hello", atffile.tps()));
}
ATF_TEST_CASE(read_missing_test_suite);
ATF_TEST_CASE_HEAD(read_missing_test_suite) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_missing_test_suite);
ATF_TEST_CASE_BODY(read_missing_test_suite) {
std::auto_ptr< std::ofstream > os = new_atffile();
(*os).close();
@ -596,10 +587,7 @@ ATF_TEST_CASE_BODY(read_missing_test_suite) {
}
}
ATF_TEST_CASE(read_missing_test_program);
ATF_TEST_CASE_HEAD(read_missing_test_program) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_missing_test_program);
ATF_TEST_CASE_BODY(read_missing_test_program) {
std::auto_ptr< std::ofstream > os = new_atffile();
(*os) << "tp: foo\n";

View File

@ -92,8 +92,6 @@ cleanup_aux_dir(const atf::fs::path& p, const atf::fs::file_info& fi,
bool erase)
{
if (erase && ((fi.get_mode() & S_IRWXU) != S_IRWXU)) {
(void)impl::set_immutable(p, false);
if (chmod(p.c_str(), fi.get_mode() | S_IRWXU) == -1)
throw atf::system_error(IMPL_NAME "::cleanup(" +
p.str() + ")", "chmod(2) failed", errno);
@ -212,44 +210,3 @@ impl::get_current_dir(void)
return atf::fs::path(cwd.get());
}
bool
impl::set_immutable(const atf::fs::path& p, bool value)
{
#if HAVE_CHFLAGS
struct stat sb;
if (::lstat(p.c_str(), &sb) == -1)
throw atf::system_error(IMPL_NAME "::set_immutable(" + p.str() + ")",
"lstat(" + p.str() + ") failed", errno);
unsigned long new_flags = sb.st_flags;
if (value)
new_flags |= UF_IMMUTABLE;
else
new_flags &= ~UF_IMMUTABLE;
if (::chflags(p.c_str(), new_flags) == -1)
throw atf::system_error(IMPL_NAME "::set_immutable(" + p.str() + ")",
"chflags(" + p.str() + ") failed", errno);
return true;
#elif HAVE_CHATTR
if (p.is_root()) {
const atf::fs::path prog(CHATTR);
const atf::process::argv_array argv("chattr", value ? "+i" : "-i",
p.c_str(), NULL);
const atf::process::status s =
atf::process::exec(prog, argv, atf::process::stream_inherit(),
atf::process::stream_inherit());
if (!s.exited() || s.exitstatus() != EXIT_SUCCESS)
throw std::runtime_error("Failed to exec chattr");
return true;
} else {
return false;
}
#else
return false;
#endif
}

View File

@ -50,7 +50,6 @@ public:
atf::fs::path change_directory(const atf::fs::path&);
void cleanup(const atf::fs::path&);
atf::fs::path get_current_dir(void);
bool set_immutable(const atf::fs::path&, bool);
} // namespace atf_run
} // namespace atf

View File

@ -63,7 +63,6 @@ ATF_TEST_CASE(temp_dir_raii);
ATF_TEST_CASE_HEAD(temp_dir_raii)
{
set_md_var("descr", "Tests the RAII behavior of the temp_dir class");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(temp_dir_raii)
{
@ -123,7 +122,6 @@ ATF_TEST_CASE(cleanup);
ATF_TEST_CASE_HEAD(cleanup)
{
set_md_var("descr", "Tests the cleanup function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(cleanup)
{
@ -149,7 +147,6 @@ ATF_TEST_CASE(cleanup_eacces_on_root);
ATF_TEST_CASE_HEAD(cleanup_eacces_on_root)
{
set_md_var("descr", "Tests the cleanup function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(cleanup_eacces_on_root)
{
@ -172,7 +169,6 @@ ATF_TEST_CASE(cleanup_eacces_on_subdir);
ATF_TEST_CASE_HEAD(cleanup_eacces_on_subdir)
{
set_md_var("descr", "Tests the cleanup function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(cleanup_eacces_on_subdir)
{
@ -194,7 +190,6 @@ ATF_TEST_CASE(change_directory);
ATF_TEST_CASE_HEAD(change_directory)
{
set_md_var("descr", "Tests the change_directory function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(change_directory)
{
@ -224,7 +219,6 @@ ATF_TEST_CASE(get_current_dir);
ATF_TEST_CASE_HEAD(get_current_dir)
{
set_md_var("descr", "Tests the get_current_dir function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(get_current_dir)
{
@ -248,32 +242,6 @@ ATF_TEST_CASE_BODY(get_current_dir)
ATF_REQUIRE(get_current_dir() == curdir);
}
ATF_TEST_CASE(set_immutable);
ATF_TEST_CASE_HEAD(set_immutable)
{
set_md_var("descr", "Tests the set_immutable function");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(set_immutable)
{
using atf::atf_run::set_immutable;
if (::mkdir("dir", 0755) == -1)
ATF_FAIL("Failed to create test directory");
if (!set_immutable(atf::fs::path("dir"), true))
ATF_SKIP("Don't know how to set the immutable flag");
if (::mkdir("dir/other", 0755) != -1)
ATF_FAIL("Immutable flag was not correctly set");
if (!set_immutable(atf::fs::path("dir"), false))
ATF_SKIP("Don't know how to unset the immutable flag");
if (::mkdir("dir/other", 0755) == -1)
ATF_FAIL("Immutable flag was not correctly unset");
}
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
@ -289,5 +257,4 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, cleanup_eacces_on_subdir);
ATF_ADD_TEST_CASE(tcs, change_directory);
ATF_ADD_TEST_CASE(tcs, get_current_dir);
ATF_ADD_TEST_CASE(tcs, set_immutable);
}

View File

@ -103,7 +103,6 @@ do_mount() {
atf_test_case main
main_head() {
atf_set "use.fs" "true"
atf_set "require.user" "root"
}
main_body() {
@ -124,7 +123,6 @@ config_head()
{
atf_set "descr" "Tests that the config files are read in the correct" \
"order"
atf_set "use.fs" "true"
}
config_body()
{
@ -198,7 +196,6 @@ vflag_head()
{
atf_set "descr" "Tests that the -v flag works and that it properly" \
"overrides the values in configuration files"
atf_set "use.fs" "true"
}
vflag_body()
{
@ -234,7 +231,6 @@ atffile_head()
{
atf_set "descr" "Tests that the variables defined by the Atffile" \
"are recognized and that they take the lowest priority"
atf_set "use.fs" "true"
}
atffile_body()
{
@ -272,7 +268,6 @@ atffile_recursive_head()
{
atf_set "descr" "Tests that variables defined by an Atffile are not" \
"inherited by other Atffiles."
atf_set "use.fs" "true"
}
atffile_recursive_body()
{
@ -296,7 +291,6 @@ atf_test_case fds
fds_head()
{
atf_set "descr" "Tests that all streams are properly captured"
atf_set "use.fs" "true"
}
fds_body()
{
@ -314,7 +308,6 @@ atf_test_case mux_streams
mux_streams_head()
{
atf_set "descr" "Tests for a race condition in stream multiplexing"
atf_set "use.fs" "true"
}
mux_streams_body()
{
@ -331,7 +324,6 @@ expect_head()
{
atf_set "descr" "Tests the processing of test case results and the" \
"expect features"
atf_set "use.fs" "true"
}
expect_body()
{
@ -364,7 +356,6 @@ missing_results_head()
{
atf_set "descr" "Ensures that atf-run correctly handles test cases that " \
"do not create the results file"
atf_set "use.fs" "true"
}
missing_results_body()
{
@ -387,7 +378,6 @@ broken_results_head()
{
atf_set "descr" "Ensures that atf-run reports test programs that" \
"provide a bogus results output as broken programs"
atf_set "use.fs" "true"
}
broken_results_body()
{
@ -411,7 +401,6 @@ broken_tp_list_head()
{
atf_set "descr" "Ensures that atf-run reports test programs that" \
"provide a bogus test case list"
atf_set "use.fs" "true"
}
broken_tp_list_body()
{
@ -443,7 +432,6 @@ zero_tcs_head()
{
atf_set "descr" "Ensures that atf-run reports test programs without" \
"test cases as errors"
atf_set "use.fs" "true"
}
zero_tcs_body()
{
@ -466,7 +454,6 @@ exit_codes_head()
{
atf_set "descr" "Ensures that atf-run reports bogus exit codes for" \
"programs correctly"
atf_set "use.fs" "true"
}
exit_codes_body()
{
@ -488,7 +475,6 @@ signaled_head()
{
atf_set "descr" "Ensures that atf-run reports test program's crashes" \
"correctly regardless of their actual results"
atf_set "use.fs" "true"
}
signaled_body()
{
@ -512,7 +498,6 @@ hooks_head()
{
atf_set "descr" "Checks that the default hooks work and that they" \
"can be overriden by the user"
atf_set "use.fs" "true"
}
hooks_body()
{
@ -592,7 +577,6 @@ isolation_env_head()
{
atf_set "descr" "Tests that atf-run sets a set of environment variables" \
"to known sane values"
atf_set "use.fs" "true"
}
isolation_env_body()
{
@ -627,7 +611,6 @@ atf_test_case isolation_home
isolation_home_head()
{
atf_set "descr" "Tests that atf-run sets HOME to a sane and valid value"
atf_set "use.fs" "true"
}
isolation_home_body()
{
@ -640,7 +623,6 @@ atf_test_case isolation_umask
isolation_umask_head()
{
atf_set "descr" "Tests that atf-run sets the umask to a known value"
atf_set "use.fs" "true"
}
isolation_umask_body()
{
@ -656,7 +638,6 @@ cleanup_pass_head()
{
atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
"case when the test case result is passed"
atf_set "use.fs" "true"
}
cleanup_pass_body()
{
@ -676,7 +657,6 @@ cleanup_fail_head()
{
atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
"case when the test case result is failed"
atf_set "use.fs" "true"
}
cleanup_fail_body()
{
@ -696,7 +676,6 @@ cleanup_skip_head()
{
atf_set "descr" "Tests that atf-run calls the cleanup routine of the test" \
"case when the test case result is skipped"
atf_set "use.fs" "true"
}
cleanup_skip_body()
{
@ -716,7 +695,6 @@ cleanup_curdir_head()
{
atf_set "descr" "Tests that atf-run calls the cleanup routine in the same" \
"work directory as the body so that they can share data"
atf_set "use.fs" "true"
}
cleanup_curdir_body()
{
@ -744,7 +722,6 @@ cleanup_mount_head()
atf_set "descr" "Tests that the removal algorithm does not cross" \
"mount points"
atf_set "require.user" "root"
atf_set "use.fs" "true"
}
cleanup_mount_body()
{
@ -787,7 +764,6 @@ cleanup_symlink_head()
"symlinks, which may live in another device and thus" \
"be treated as mount points"
atf_set "require.user" "root"
atf_set "use.fs" "true"
}
cleanup_symlink_body()
{
@ -823,7 +799,6 @@ atf_test_case require_arch
require_arch_head()
{
atf_set "descr" "Tests that atf-run validates the require.arch property"
atf_set "use.fs" "true"
}
require_arch_body()
{
@ -864,7 +839,6 @@ atf_test_case require_config
require_config_head()
{
atf_set "descr" "Tests that atf-run validates the require.config property"
atf_set "use.fs" "true"
}
require_config_body()
{
@ -883,7 +857,6 @@ atf_test_case require_machine
require_machine_head()
{
atf_set "descr" "Tests that atf-run validates the require.machine property"
atf_set "use.fs" "true"
}
require_machine_body()
{
@ -924,7 +897,6 @@ atf_test_case require_progs
require_progs_head()
{
atf_set "descr" "Tests that atf-run validates the require.progs property"
atf_set "use.fs" "true"
}
require_progs_body()
{
@ -956,7 +928,6 @@ require_user_root_head()
{
atf_set "descr" "Tests that atf-run validates the require.user property" \
"when it is set to 'root'"
atf_set "use.fs" "true"
}
require_user_root_body()
{
@ -977,7 +948,6 @@ require_user_unprivileged_head()
{
atf_set "descr" "Tests that atf-run validates the require.user property" \
"when it is set to 'root'"
atf_set "use.fs" "true"
}
require_user_unprivileged_body()
{
@ -998,7 +968,6 @@ require_user_bad_head()
{
atf_set "descr" "Tests that atf-run validates the require.user property" \
"when it is set to 'root'"
atf_set "use.fs" "true"
}
require_user_bad_body()
{
@ -1013,7 +982,6 @@ atf_test_case timeout
timeout_head()
{
atf_set "descr" "Tests that atf-run kills a test case that times out"
atf_set "use.fs" "true"
}
timeout_body()
{
@ -1033,7 +1001,6 @@ timeout_forkexit_head()
{
atf_set "descr" "Tests that atf-run deals gracefully with a test program" \
"that forks, exits, but the child process hangs"
atf_set "use.fs" "true"
}
timeout_forkexit_body()
{
@ -1047,28 +1014,17 @@ timeout_forkexit_body()
"been forcibly terminated" || true
}
atf_test_case use_fs
use_fs_head()
atf_test_case ignore_deprecated_use_fs
ignore_deprecated_use_fs_head()
{
atf_set "descr" "Tests that atf-run correctly handles the use.fs property"
atf_set "use.fs" "true"
atf_set "descr" "Tests that atf-run ignores the deprecated use.fs property"
}
use_fs_body()
ignore_deprecated_use_fs_body()
{
create_helper use_fs
create_atffile helper
atf_check -s eq:0 -o ignore -e ignore atf-run \
-v allowed=false -v access=false helper
atf_check -s eq:1 -o ignore -e ignore atf-run \
-v allowed=false -v access=true helper
atf_check -s eq:0 -o ignore -e ignore atf-run \
-v allowed=true -v access=false helper
atf_check -s eq:0 -o ignore -e ignore atf-run \
-v allowed=true -v access=true helper
atf_check -s eq:0 -o ignore -e ignore atf-run helper
}
atf_init_test_cases()
@ -1106,7 +1062,7 @@ atf_init_test_cases()
atf_add_test_case require_user_bad
atf_add_test_case timeout
atf_add_test_case timeout_forkexit
atf_add_test_case use_fs
atf_add_test_case ignore_deprecated_use_fs
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

View File

@ -202,7 +202,6 @@ ATF_TEST_CASE_WITH_CLEANUP(cleanup_curdir);
ATF_TEST_CASE_HEAD(cleanup_curdir)
{
set_md_var("descr", "Helper test case for the t_integration test program");
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_BODY(cleanup_curdir)
{
@ -321,12 +320,11 @@ ATF_TEST_CASE(use_fs);
ATF_TEST_CASE_HEAD(use_fs)
{
set_md_var("descr", "Helper test case for the t_integration test program");
set_md_var("use.fs", get_config_var("allowed", "not-set"));
set_md_var("use.fs", "this-is-deprecated");
}
ATF_TEST_CASE_BODY(use_fs)
{
if (get_config_var("access") == "true")
touch("test-file");
touch("test-file");
}
// ------------------------------------------------------------------------

View File

@ -137,7 +137,7 @@ check_progs(const std::string& progs)
static
std::string
check_user(const std::string& user)
check_user(const std::string& user, const atf::tests::vars_map& config)
{
if (user == "root") {
if (!impl::is_root())
@ -145,9 +145,23 @@ check_user(const std::string& user)
else
return "";
} else if (user == "unprivileged") {
if (impl::is_root())
return "Requires an unprivileged user";
else
if (impl::is_root()) {
const atf::tests::vars_map::const_iterator iter = config.find(
"unprivileged-user");
if (iter == config.end())
return "Requires an unprivileged user and the "
"'unprivileged-user' configuration variable is not set";
else {
const std::string& unprivileged_user = (*iter).second;
try {
(void)impl::get_user_ids(unprivileged_user);
return "";
} catch (const std::runtime_error& e) {
return "Failed to get information for user " +
unprivileged_user;
}
}
} else
return "";
} else
throw std::runtime_error("Invalid value '" + user + "' for property "
@ -177,7 +191,7 @@ impl::check_requirements(const atf::tests::vars_map& metadata,
else if (name == "require.progs")
failure_reason = check_progs(value);
else if (name == "require.user")
failure_reason = check_user(value);
failure_reason = check_user(value, config);
else {
// Unknown require.* properties are forbidden by the
// application/X-atf-tp parser.
@ -187,3 +201,29 @@ impl::check_requirements(const atf::tests::vars_map& metadata,
return failure_reason;
}
std::pair< int, int >
impl::get_required_user(const atf::tests::vars_map& metadata,
const atf::tests::vars_map& config)
{
const atf::tests::vars_map::const_iterator user = metadata.find(
"require.user");
if (user == metadata.end())
return std::make_pair(-1, -1);
if ((*user).second == "unprivileged") {
if (impl::is_root()) {
const atf::tests::vars_map::const_iterator iter = config.find(
"unprivileged-user");
try {
return impl::get_user_ids((*iter).second);
} catch (const std::exception& e) {
UNREACHABLE; // This has been validated by check_user.
throw e;
}
} else {
return std::make_pair(-1, -1);
}
} else
return std::make_pair(-1, -1);
}

View File

@ -28,6 +28,7 @@
//
#include <string>
#include <utility>
#include "atf-c++/tests.hpp"
@ -36,6 +37,8 @@ namespace atf_run {
std::string check_requirements(const atf::tests::vars_map&,
const atf::tests::vars_map&);
std::pair< int, int > get_required_user(const atf::tests::vars_map&,
const atf::tests::vars_map&);
} // namespace atf_run
} // namespace atf

View File

@ -251,7 +251,8 @@ ATF_TEST_CASE_BODY(require_user_unprivileged) {
atf::tests::vars_map metadata;
metadata["require.user"] = "unprivileged";
if (atf::atf_run::is_root())
do_check("Requires an unprivileged user", metadata);
do_check("Requires an unprivileged user and the 'unprivileged-user' "
"configuration variable is not set", metadata);
else
do_check("", metadata);
}

View File

@ -0,0 +1,11 @@
Content-Type: application/X-atf-config; version="1"
#
# Sample configuration file for properties affecting all test suites.
#
# When running the test suite as root, some tests require to switch to
# an unprivileged user to perform extra checks. Set this variable to
# the user you want to use in those cases. If not set, those tests will
# be skipped.
#unprivileged-user = "_atf"

View File

@ -43,7 +43,6 @@ ATF_TC_HEAD(second, tc)
{
atf_tc_set_md_var(tc, "descr", "Description 2");
atf_tc_set_md_var(tc, "timeout", "500");
atf_tc_set_md_var(tc, "use.fs", "true");
atf_tc_set_md_var(tc, "X-property", "Custom property");
}
ATF_TC_BODY(second, tc)

View File

@ -190,7 +190,7 @@ ATF_TEST_CASE_BODY(tp_2)
"\n"
"ident: test_case_1\n"
"descr: This is the description\n"
"timeout: 300\n"
"timeout: 30\n"
"\n"
"ident: test_case_2\n"
"\n"
@ -201,7 +201,7 @@ ATF_TEST_CASE_BODY(tp_2)
// NO_CHECK_STYLE_BEGIN
const char* exp_calls[] = {
"got_tc(test_case_1, {descr=This is the description, ident=test_case_1, timeout=300})",
"got_tc(test_case_1, {descr=This is the description, ident=test_case_1, timeout=30})",
"got_tc(test_case_2, {ident=test_case_2})",
"got_tc(test_case_3, {X-prop1=A custom property, descr=Third test case, ident=test_case_3})",
"got_eof()",
@ -224,7 +224,7 @@ ATF_TEST_CASE_BODY(tp_3)
"\n"
"ident: single_test\n"
"descr: Some description\n"
"timeout: 300\n"
"timeout: 30\n"
"require.arch: thearch\n"
"require.config: foo-bar\n"
"require.machine: themachine\n"
@ -234,7 +234,7 @@ ATF_TEST_CASE_BODY(tp_3)
// NO_CHECK_STYLE_BEGIN
const char* exp_calls[] = {
"got_tc(single_test, {descr=Some description, ident=single_test, require.arch=thearch, require.config=foo-bar, require.machine=themachine, require.progs=/bin/cp mv, require.user=root, timeout=300})",
"got_tc(single_test, {descr=Some description, ident=single_test, require.arch=thearch, require.config=foo-bar, require.machine=themachine, require.progs=/bin/cp mv, require.user=root, timeout=30})",
"got_eof()",
NULL
};
@ -474,7 +474,7 @@ ATF_TEST_CASE_BODY(tp_59)
"\n"
"\n"
"ident: test\n"
"timeout: 300\n"
"timeout: 30\n"
;
const char* exp_calls[] = {
@ -758,12 +758,11 @@ ATF_TEST_CASE_BODY(get_metadata_several_tcs) {
md.test_cases.find("first");
ATF_REQUIRE(iter != md.test_cases.end());
ATF_REQUIRE_EQ(5, (*iter).second.size());
ATF_REQUIRE_EQ(4, (*iter).second.size());
check_property((*iter).second, "descr", "Description 1");
check_property((*iter).second, "has.cleanup", "false");
check_property((*iter).second, "ident", "first");
check_property((*iter).second, "timeout", "300");
check_property((*iter).second, "use.fs", "false");
check_property((*iter).second, "timeout", "30");
}
{
@ -771,12 +770,11 @@ ATF_TEST_CASE_BODY(get_metadata_several_tcs) {
md.test_cases.find("second");
ATF_REQUIRE(iter != md.test_cases.end());
ATF_REQUIRE_EQ(6, (*iter).second.size());
ATF_REQUIRE_EQ(5, (*iter).second.size());
check_property((*iter).second, "descr", "Description 2");
check_property((*iter).second, "has.cleanup", "true");
check_property((*iter).second, "ident", "second");
check_property((*iter).second, "timeout", "500");
check_property((*iter).second, "use.fs", "true");
check_property((*iter).second, "X-property", "Custom property");
}
@ -785,11 +783,10 @@ ATF_TEST_CASE_BODY(get_metadata_several_tcs) {
md.test_cases.find("third");
ATF_REQUIRE(iter != md.test_cases.end());
ATF_REQUIRE_EQ(4, (*iter).second.size());
ATF_REQUIRE_EQ(3, (*iter).second.size());
check_property((*iter).second, "has.cleanup", "false");
check_property((*iter).second, "ident", "third");
check_property((*iter).second, "timeout", "300");
check_property((*iter).second, "use.fs", "false");
check_property((*iter).second, "timeout", "30");
}
}
@ -899,10 +896,7 @@ ATF_TEST_CASE_BODY(parse_test_case_result_unknown) {
detail::parse_test_case_result("baz: foo"));
}
ATF_TEST_CASE(read_test_case_result_failed);
ATF_TEST_CASE_HEAD(read_test_case_result_failed) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_failed);
ATF_TEST_CASE_BODY(read_test_case_result_failed) {
write_test_case_result("resfile", "failed: foo bar\n");
const impl::test_case_result tcr = impl::read_test_case_result(
@ -911,10 +905,7 @@ ATF_TEST_CASE_BODY(read_test_case_result_failed) {
ATF_REQUIRE_EQ("foo bar", tcr.reason());
}
ATF_TEST_CASE(read_test_case_result_skipped);
ATF_TEST_CASE_HEAD(read_test_case_result_skipped) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_skipped);
ATF_TEST_CASE_BODY(read_test_case_result_skipped) {
write_test_case_result("resfile", "skipped: baz bar\n");
const impl::test_case_result tcr = impl::read_test_case_result(
@ -931,30 +922,21 @@ ATF_TEST_CASE_BODY(read_test_case_result_no_file) {
impl::read_test_case_result(atf::fs::path("resfile")));
}
ATF_TEST_CASE(read_test_case_result_empty_file);
ATF_TEST_CASE_HEAD(read_test_case_result_empty_file) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_empty_file);
ATF_TEST_CASE_BODY(read_test_case_result_empty_file) {
write_test_case_result("resfile", "");
ATF_REQUIRE_THROW(std::runtime_error,
impl::read_test_case_result(atf::fs::path("resfile")));
}
ATF_TEST_CASE(read_test_case_result_invalid);
ATF_TEST_CASE_HEAD(read_test_case_result_invalid) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_invalid);
ATF_TEST_CASE_BODY(read_test_case_result_invalid) {
write_test_case_result("resfile", "passed: hello\n");
ATF_REQUIRE_THROW(std::runtime_error,
impl::read_test_case_result(atf::fs::path("resfile")));
}
ATF_TEST_CASE(read_test_case_result_multiline);
ATF_TEST_CASE_HEAD(read_test_case_result_multiline) {
set_md_var("use.fs", "true");
}
ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_multiline);
ATF_TEST_CASE_BODY(read_test_case_result_multiline) {
write_test_case_result("resfile", "skipped: foo\nbar\n");
const impl::test_case_result tcr = impl::read_test_case_result(

View File

@ -28,9 +28,15 @@
//
extern "C" {
#include <sys/types.h>
#include <pwd.h>
#include "../atf-c/detail/user.h"
}
#include <stdexcept>
#include "../atf-c++/detail/sanity.hpp"
#include "user.hpp"
@ -44,6 +50,24 @@ impl::euid(void)
return atf_user_euid();
}
void
impl::drop_privileges(const std::pair< int, int > ids)
{
if (::setgid(ids.second) == -1)
throw std::runtime_error("Failed to drop group privileges");
if (::setuid(ids.first) == -1)
throw std::runtime_error("Failed to drop user privileges");
}
std::pair< int, int >
impl::get_user_ids(const std::string& user)
{
const struct passwd* pw = ::getpwnam(user.c_str());
if (pw == NULL)
throw std::runtime_error("Failed to get information for user " + user);
return std::make_pair(pw->pw_uid, pw->pw_gid);
}
bool
impl::is_member_of_group(gid_t gid)
{

View File

@ -34,10 +34,14 @@ extern "C" {
#include <sys/types.h>
}
#include <utility>
namespace atf {
namespace atf_run {
uid_t euid(void);
void drop_privileges(const std::pair< int, int >);
std::pair< int, int > get_user_ids(const std::string&);
bool is_member_of_group(gid_t);
bool is_root(void);
bool is_unprivileged(void);

View File

@ -325,7 +325,7 @@ flatten_argv(char* const* argv)
}
static
atf::check::check_result
std::auto_ptr< atf::check::check_result >
execute(const char* const* argv)
{
std::cout << "Executing command [ ";
@ -338,7 +338,7 @@ execute(const char* const* argv)
}
static
atf::check::check_result
std::auto_ptr< atf::check::check_result >
execute_with_shell(char* const* argv)
{
const std::string cmd = flatten_argv(argv);
@ -802,7 +802,7 @@ atf_check::main(void)
int status = EXIT_FAILURE;
atf::check::check_result r =
std::auto_ptr< atf::check::check_result > r =
m_xflag ? execute_with_shell(m_argv) : execute(m_argv);
if (m_status_checks.empty())
@ -817,9 +817,9 @@ atf_check::main(void)
if (m_stderr_checks.empty())
m_stderr_checks.push_back(output_check(oc_empty, false, ""));
if ((run_status_checks(m_status_checks, r) == false) ||
(run_output_checks(r, "stderr") == false) ||
(run_output_checks(r, "stdout") == false))
if ((run_status_checks(m_status_checks, *r) == false) ||
(run_output_checks(*r, "stderr") == false) ||
(run_output_checks(*r, "stdout") == false))
status = EXIT_FAILURE;
else
status = EXIT_SUCCESS;

View File

@ -69,7 +69,6 @@ atf_test_case sflag_eq_ne
sflag_eq_ne_head()
{
atf_set "descr" "Tests for the -s option using the 'eq' and 'ne' qualifiers"
atf_set "use.fs" "true"
}
sflag_eq_ne_body()
{
@ -88,7 +87,6 @@ atf_test_case sflag_exit
sflag_exit_head()
{
atf_set "descr" "Tests for the -s option using the 'exit' qualifier"
atf_set "use.fs" "true"
}
sflag_exit_body()
{
@ -113,7 +111,6 @@ atf_test_case sflag_ignore
sflag_ignore_head()
{
atf_set "descr" "Tests for the -s option using the 'ignore' qualifier"
atf_set "use.fs" "true"
}
sflag_ignore_body()
{
@ -128,7 +125,6 @@ atf_test_case sflag_signal
sflag_signal_head()
{
atf_set "descr" "Tests for the -s option using the 'signal' qualifier"
atf_set "use.fs" "true"
}
sflag_signal_body()
{
@ -168,7 +164,6 @@ atf_test_case oflag_empty
oflag_empty_head()
{
atf_set "descr" "Tests for the -o option using the 'empty' argument"
atf_set "use.fs" "true"
}
oflag_empty_body()
{
@ -180,7 +175,6 @@ atf_test_case oflag_ignore
oflag_ignore_head()
{
atf_set "descr" "Tests for the -o option using the 'ignore' argument"
atf_set "use.fs" "true"
}
oflag_ignore_body()
{
@ -192,7 +186,6 @@ atf_test_case oflag_file
oflag_file_head()
{
atf_set "descr" "Tests for the -o option using the 'file:' argument"
atf_set "use.fs" "true"
}
oflag_file_body()
{
@ -211,7 +204,6 @@ atf_test_case oflag_inline
oflag_inline_head()
{
atf_set "descr" "Tests for the -o option using the 'inline:' argument"
atf_set "use.fs" "true"
}
oflag_inline_body()
{
@ -239,7 +231,6 @@ atf_test_case oflag_match
oflag_match_head()
{
atf_set "descr" "Tests for the -o option using the 'match:' argument"
atf_set "use.fs" "true"
}
oflag_match_body()
{
@ -253,7 +244,6 @@ atf_test_case oflag_save
oflag_save_head()
{
atf_set "descr" "Tests for the -o option using the 'save:' argument"
atf_set "use.fs" "true"
}
oflag_save_body()
{
@ -266,7 +256,6 @@ atf_test_case oflag_multiple
oflag_multiple_head()
{
atf_set "descr" "Tests for multiple occurrences of the -o option"
atf_set "use.fs" "true"
}
oflag_multiple_body()
{
@ -280,7 +269,6 @@ atf_test_case oflag_negated
oflag_negated_head()
{
atf_set "descr" "Tests for negated occurrences of the -o option"
atf_set "use.fs" "true"
}
oflag_negated_body()
{
@ -295,7 +283,6 @@ atf_test_case eflag_empty
eflag_empty_head()
{
atf_set "descr" "Tests for the -e option using the 'empty' argument"
atf_set "use.fs" "true"
}
eflag_empty_body()
{
@ -307,7 +294,6 @@ atf_test_case eflag_ignore
eflag_ignore_head()
{
atf_set "descr" "Tests for the -e option using the 'ignore' argument"
atf_set "use.fs" "true"
}
eflag_ignore_body()
{
@ -319,7 +305,6 @@ atf_test_case eflag_file
eflag_file_head()
{
atf_set "descr" "Tests for the -e option using the 'file:' argument"
atf_set "use.fs" "true"
}
eflag_file_body()
{
@ -338,7 +323,6 @@ atf_test_case eflag_inline
eflag_inline_head()
{
atf_set "descr" "Tests for the -e option using the 'inline:' argument"
atf_set "use.fs" "true"
}
eflag_inline_body()
{
@ -366,7 +350,6 @@ atf_test_case eflag_save
eflag_save_head()
{
atf_set "descr" "Tests for the -e option using the 'save:' argument"
atf_set "use.fs" "true"
}
eflag_save_body()
{
@ -379,7 +362,6 @@ atf_test_case eflag_match
eflag_match_head()
{
atf_set "descr" "Tests for the -e option using the 'match:' argument"
atf_set "use.fs" "true"
}
eflag_match_body()
{
@ -393,7 +375,6 @@ atf_test_case eflag_multiple
eflag_multiple_head()
{
atf_set "descr" "Tests for multiple occurrences of the -e option"
atf_set "use.fs" "true"
}
eflag_multiple_body()
{
@ -407,7 +388,6 @@ atf_test_case eflag_negated
eflag_negated_head()
{
atf_set "descr" "Tests for negated occurrences of the -e option"
atf_set "use.fs" "true"
}
eflag_negated_body()
{
@ -423,7 +403,6 @@ invalid_umask_head()
{
atf_set "descr" "Tests for a correct error condition if the umask is" \
"too restrictive"
atf_set "use.fs" "true"
}
invalid_umask_body()
{

View File

@ -34,7 +34,6 @@ info_ok_head()
{
atf_set "descr" "Verifies that atf_check prints an informative" \
"message even when the command is successful"
atf_set "use.fs" "true"
}
info_ok_body()
{
@ -57,7 +56,6 @@ expout_mismatch_head()
atf_set "descr" "Verifies that atf_check prints a diff of the" \
"stdout and the expected stdout if the two do no" \
"match"
atf_set "use.fs" "true"
}
expout_mismatch_body()
{
@ -83,7 +81,6 @@ experr_mismatch_head()
atf_set "descr" "Verifies that atf_check prints a diff of the" \
"stderr and the expected stderr if the two do no" \
"match"
atf_set "use.fs" "true"
}
experr_mismatch_body()
{
@ -108,7 +105,6 @@ null_stdout_head()
{
atf_set "descr" "Verifies that atf_check prints a the stdout it got" \
"when it was supposed to be null"
atf_set "use.fs" "true"
}
null_stdout_body()
{
@ -131,7 +127,6 @@ null_stderr_head()
{
atf_set "descr" "Verifies that atf_check prints a the stderr it got" \
"when it was supposed to be null"
atf_set "use.fs" "true"
}
null_stderr_body()
{
@ -153,7 +148,6 @@ atf_test_case equal
equal_head()
{
atf_set "descr" "Verifies that atf_check_equal works"
atf_set "use.fs" "true"
}
equal_body()
{

View File

@ -31,7 +31,6 @@ atf_test_case has
has_head()
{
atf_set "descr" "Verifies that atf_config_has works"
atf_set "use.fs" "true"
}
has_body()
{
@ -52,7 +51,6 @@ atf_test_case get
get_head()
{
atf_set "descr" "Verifies that atf_config_get works"
atf_set "use.fs" "true"
}
get_body()
{

View File

@ -34,9 +34,6 @@ create_test_program() {
}
atf_test_case no_args
no_args_head() {
atf_set "use.fs" "true"
}
no_args_body()
{
cat >experr <<EOF
@ -47,9 +44,6 @@ EOF
}
atf_test_case missing_script
missing_script_head() {
atf_set "use.fs" "true"
}
missing_script_body()
{
cat >experr <<EOF
@ -59,9 +53,6 @@ EOF
}
atf_test_case arguments
arguments_head() {
atf_set "use.fs" "true"
}
arguments_body()
{
create_test_program tp <<EOF

View File

@ -32,7 +32,6 @@ main_head()
{
atf_set "descr" "Verifies that variable names with symbols not" \
"allowed as part of shell variable names work"
atf_set "use.fs" "true"
}
main_body()
{

View File

@ -32,7 +32,6 @@ default_status_head()
{
atf_set "descr" "Verifies that test cases get the correct default" \
"status if they did not provide any"
atf_set "use.fs" "true"
}
default_status_body()
{

View File

@ -32,7 +32,6 @@ srcdir_head()
{
atf_set "descr" "Verifies that the source directory can be queried" \
"from the initialization function"
atf_set "use.fs" "true"
}
srcdir_body()
{

View File

@ -26,7 +26,7 @@
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd July 12, 2010
.Dd October 31, 2010
.Dt ATF-TEST-CASE 4
.Os
.Sh NAME
@ -230,7 +230,7 @@ unprivileged user will be supported.
.It timeout
Type: integral.
Optional; defaults to
.Sq 300 .
.Sq 30 .
.Pp
Specifies the maximum amount of time the test case can run.
This is particularly useful because some tests can stall either because they
@ -242,13 +242,6 @@ test program.
Can optionally be set to zero, in which case the test case has no run-time
limit.
This is discouraged.
.It use.fs
Type: boolean.
Optional; defaults to
.Sq false .
If false, the test case will not be allowed to create any files in its work
directory.
Otherwise, a writable, empty work directory will be created for the test case.
.El
.Ss Environment
Every time a test case is executed, several environment variables are

View File

@ -85,11 +85,7 @@ ATF_TC_BODY(cleanup_pass, tc)
}
ATF_TC_CLEANUP(cleanup_pass, tc)
{
bool cleanup;
RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
if (cleanup)
if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
}
@ -106,11 +102,7 @@ ATF_TC_BODY(cleanup_fail, tc)
}
ATF_TC_CLEANUP(cleanup_fail, tc)
{
bool cleanup;
RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
if (cleanup)
if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
}
@ -127,11 +119,7 @@ ATF_TC_BODY(cleanup_skip, tc)
}
ATF_TC_CLEANUP(cleanup_skip, tc)
{
bool cleanup;
RE(atf_text_to_bool(atf_tc_get_config_var(tc, "cleanup"), &cleanup));
if (cleanup)
if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
}

View File

@ -32,7 +32,6 @@ vflag_head()
{
atf_set "descr" "Tests that the -v flag works correctly to set" \
"configuration variables"
atf_set "use.fs" "true"
}
vflag_body()
{

View File

@ -35,9 +35,6 @@ check_result() {
}
atf_test_case expect_pass
expect_pass_head() {
atf_set "use.fs" "true"
}
expect_pass_body() {
for h in $(get_helpers); do
atf_check -s eq:0 "${h}" -r result expect_pass_and_pass
@ -57,9 +54,6 @@ expect_pass_body() {
}
atf_test_case expect_fail
expect_fail_head() {
atf_set "use.fs" "true"
}
expect_fail_body() {
for h in $(get_helpers c_helpers cpp_helpers); do
atf_check -s eq:0 "${h}" -r result expect_fail_and_fail_requirement
@ -92,9 +86,6 @@ expect_fail_body() {
}
atf_test_case expect_exit
expect_exit_head() {
atf_set "use.fs" "true"
}
expect_exit_body() {
for h in $(get_helpers); do
atf_check -s eq:0 "${h}" -r result expect_exit_any_and_exit
@ -109,9 +100,6 @@ expect_exit_body() {
}
atf_test_case expect_signal
expect_signal_head() {
atf_set "use.fs" "true"
}
expect_signal_body() {
for h in $(get_helpers); do
atf_check -s signal:9 "${h}" -r result expect_signal_any_and_signal
@ -126,9 +114,6 @@ expect_signal_body() {
}
atf_test_case expect_death
expect_death_head() {
atf_set "use.fs" "true"
}
expect_death_body() {
for h in $(get_helpers); do
atf_check -s eq:123 "${h}" -r result expect_death_and_exit
@ -143,9 +128,6 @@ expect_death_body() {
}
atf_test_case expect_timeout
expect_timeout_head() {
atf_set "use.fs" "true"
}
expect_timeout_body() {
for h in $(get_helpers); do
atf_check -s eq:1 "${h}" -r result expect_timeout_but_pass

View File

@ -35,7 +35,6 @@ stop_head()
{
atf_set "descr" "Tests that sending a stop signal to a test case does" \
"not report it as failed"
atf_set "use.fs" "true"
}
stop_body()
{

View File

@ -31,7 +31,6 @@ atf_test_case no_descr
no_descr_head()
{
atf_set "descr" "Tests that the description may not be present"
atf_set "use.fs" "true"
}
no_descr_body()
{
@ -46,7 +45,6 @@ atf_test_case no_head
no_head_head()
{
atf_set "descr" "Tests that the head may not be present"
atf_set "use.fs" "true"
}
no_head_body()
{

View File

@ -51,7 +51,6 @@ result_to_file_head()
{
atf_set "descr" "Tests that the test case result is sent to a file if -r" \
"is used"
atf_set "use.fs" "true"
}
result_to_file_body()
{
@ -77,7 +76,6 @@ result_to_file_fail_head()
atf_set "descr" "Tests controlled failure if the test program fails to" \
"create the results file"
atf_set "require.user" "unprivileged"
atf_set "use.fs" "true"
}
result_to_file_fail_body()
{
@ -103,7 +101,6 @@ atf_test_case result_exception
result_exception_head()
{
atf_set "descr" "Tests that an unhandled exception is correctly captured"
atf_set "use.fs" "true"
}
result_exception_body()
{

View File

@ -38,7 +38,6 @@ default_head()
{
atf_set "descr" "Checks that the program can find its files if" \
"executed from the same directory"
atf_set "use.fs" "true"
}
default_body()
{
@ -60,7 +59,6 @@ libtool_head()
atf_set "descr" "Checks that the program can find its files if" \
"executed from the source directory and if it" \
"was built with libtool"
atf_set "use.fs" "true"
}
libtool_body()
{
@ -93,7 +91,6 @@ sflag_head()
{
atf_set "descr" "Checks that the program can find its files when" \
"using the -s flag"
atf_set "use.fs" "true"
}
sflag_body()
{
@ -117,7 +114,6 @@ relative_head()
{
atf_set "descr" "Checks that passing a relative path through -s" \
"works"
atf_set "use.fs" "true"
}
relative_body()
{