Reputation: 8074
I have the following code:
bool f()
{
command = "mkdir -p /\/\/";
result = aSystemCall(command);
if (result == ...
}
BOOST_AUTO_TEST_CASE(BadDir)
{
BOOST_CHECK_EQUAL(false, f());
}
If I execute command
in command line, I get a permission denied error. I'm aware of this. That's exactly what I want to test.
aSystemCall
executes the command as a child process. As the child exits with a nonzero error for this command, aSystemCall
returns an error. It doesn't throw.
If I run BadDir
test case in command line, the code after aSystemCall
is never executed, and the test fails, with the following output:
mkdir: cannot create directory '/\/\/': Permission denied
unknown location(0): fatal error in "BadDir": child has exited; pid: 25356; uid: 19753; exit value: 1
test.cpp(100): last checkpoint
Leaving test case "BadDir"; testing time: 10ms
Leaving test suite "Test"
Leaving test suite "Master Test Suite"
If I run BadDir
test case within gdb, aSystemCall
returns, the result can be checked, and the test passes.
Is there a way to telling boost::unit_test to filter out possible errors like this one, so that execution can continue? I've tried BOOST_AUTO_TEST_CASE_EXPECTED_FAILURE(blah, 1)
, but this is just to tell boost::unit_test that you are expecting a failure. It reports failure detected (failure expected) in test. I would like a passed test situation instead.
Upvotes: 5
Views: 2990
Reputation: 2226
Expanding a bit on Chip Christian's answer: (re)compiling boost.test with the BOOST_TEST_IGNORE_NON_ZERO_CHILD_CODE flag works (tested for boost 1.53). On the bjam command line, add:
cxxflags="-DBOOST_TEST_IGNORE_NON_ZERO_CHILD_CODE"
Note that adding this flag did not always seem to force a recompile, so I did the following to force recompiling:
touch boost/test/impl/execution_monitor.ipp
Upvotes: 0
Reputation: 777
First of all i get this odd behavior only on Linux.
I've found that Boost.Test changes the way it handles child exit codes with the deploy model you choose.
If you are using static linking of boost libraries or the "all in one" header boost/test/included/unit_test.hpp
inserting a define:
#define BOOST_TEST_IGNORE_NON_ZERO_CHILD_CODE
before any include directive solves the problem.
If you are using dynamic linking, this isn't enough. You have either to call the resulting test with the command line option "--catch_system_errors=no" or define the following environment variable.
export BOOST_TEST_CATCH_SYSTEM_ERRORS="no"
I'm using boost 1.52 and 1.57, GCC 4.7.2, on a debian wheezy.
Here is the reference to deploy models of Boost.Test
see also this question: how-to-cancel-fatal-error-detection-in-boost-test
Upvotes: 4
Reputation: 1278
If you run your test from terminal you should set to "no" Boost environment variable catch_system_errors. In case Ubuntu OS, you have to type next command in terminal before test execution:
export BOOST_TEST_CATCH_SYSTEM_ERRORS="no"
Upvotes: 0
Reputation: 115
Adding --catch_system_errors=no at run-time also works.
I would prefer to be able to handle this with a a macro similar to BOOST_CHECK_THROW or a #define that doesn't require recompiling unit_test, but at least there's a solution in place.
Upvotes: 1