On 2011-03-23 07:52, Stirling Westrup wrote:
I have been using Boost.test to run some simple unit tests as I build
my code. I've come across a case where I need to test if my code runs
within an acceptable time limit. I know that the execution monitor has
a timeout system for testing that sort of thing, but I can't figure
out how it is supposed to be integrated into the unit test framework.

Ideally, I'd love to just have a BOOST_CHECK_TIMED( f(), timeout) that
I could invoke to ensure that the code returns true, and returns
within the specified timeout interval.

I just came with a basic solution that I have not fully tested but seems to work. However it demands some optimization. (Please, be soft on me, I have not been working much on this one).

I created a ( TestCaseName, TimeOutValue ) macro.
This macro is extended to something like

#define BOOST_AUTO_TEST_CASE_TIMED( NAME , TIMEOUT)                                        \
class NAME##_timeout {                                                                     \
public:                                                                                    \
NAME##_timeout(){ConfigurationVisitor::getInstance()->registerTimeOut(#NAME, TIMEOUT);}    \
};                                                                                         \
NAME##_timeout* NAME##_timeInstance = new NAME##_timeout();                                \
BOOST_AUTO_TEST_CASE( NAME )


I am using test_tree_visitor implementation -
ConfigurationVisitor - instantiated before the boost::monitor execution is called.

void ConfigurationVisitor::visit( test_case const& itc ) {
    test_case & tc=*(test_case *)&itc; // Hack !
    tc.p_timeout.set(boost::unit_test::class_property<unsigned>(getTimeOut(tc.p_name.value)));
}

This will update test_case timeout to the value return by getTimeOut (0 if none, of the actual TimeOutvalue registered for the test case.

This test tree visitor also exposed some static functions :

static void registerTimeOut(std::string iTestName, int iTimeOut);
static int getTimeOut(
std::string iTestName);

The time out value is store in a std::map.

Runtime, before calling the ::boost::unit_test::unit_test_main, I do  traverse_test_tree(framework::master_test_suite().p_id, *
ConfigurationVisitor::getInstance());

At the end, I got something like that :

BOOST_AUTO_TEST_CASE_TIMED( MyTestCase1, 5 ) {
    while(1){
        usleep(1000);
        BOOST_TEST_MESSAGE("HelloWorld");
    }
}

And log will be :

Entering test case "
MyTestCase1"
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
unknown location(0): fatal error in "MyTestCase2": signal: SIGALRM (timeout while executing function)
.../MyTimeOutTestSuite.cpp(64): last checkpoint
Leaving test case "MyTestCase1"

-----

However, the hack in the visit function is actually my main concern about this solution.
It may not be what you are look for, but I hope this will help though.

Guillaume.