From 9b24d7c33da80b4e0d4f59ebee219d2285d6bc26 Mon Sep 17 00:00:00 2001 From: Stephen Roderick Date: Mon, 20 Sep 2010 20:21:43 -0400 Subject: [PATCH 1/2] plugins/rtalloc: Add test case demonstrating failing rtstring construction --- plugins/rtalloc/tests/CMakeLists.txt | 23 ++++ plugins/rtalloc/tests/state_test.cpp | 199 +++++++++++++++++++++++++++++++++ plugins/rtalloc/tests/state_test.hpp | 46 ++++++++ plugins/rtalloc/tests/test-runner.cpp | 95 ++++++++++++++++ 4 files changed, 363 insertions(+), 0 deletions(-) create mode 100644 plugins/rtalloc/tests/state_test.cpp create mode 100644 plugins/rtalloc/tests/state_test.hpp create mode 100644 plugins/rtalloc/tests/test-runner.cpp diff --git a/plugins/rtalloc/tests/CMakeLists.txt b/plugins/rtalloc/tests/CMakeLists.txt index e331cf8..7152c51 100644 --- a/plugins/rtalloc/tests/CMakeLists.txt +++ b/plugins/rtalloc/tests/CMakeLists.txt @@ -1,5 +1,20 @@ IF (BUILD_TESTS) + if (NOT RUNTIME_OUTPUT_DIRECTORY) + set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + + find_package(Boost 1.33 REQUIRED unit_test_framework) + IF (OROCOS_TARGET STREQUAL win32) + #SET(TEST_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + LIST(APPEND OROCOS-RTT_DEFINITIONS BOOST_TEST_NO_LIB) + ENDIF() + + SET(TEST_LIBRARIES ${Boost_SERIALIZATION_LIBRARY} ${Boost_THREAD_LIBRARY}) + + INCLUDE_DIRECTORIES( ${OROCOS-RTT_INCLUDE_DIRS} ) + INCLUDE_DIRECTORIES( "../" ) + ADD_EXECUTABLE(rtalloc-combined combined.cpp send.cpp recv.cpp) TARGET_LINK_LIBRARIES(rtalloc-combined orocos-taskbrowser-${OROCOS_TARGET} @@ -7,4 +22,12 @@ IF (BUILD_TESTS) orocos-rtt-${OROCOS_TARGET} ) + ADD_EXECUTABLE( state-test test-runner.cpp state_test.cpp ) + TARGET_LINK_LIBRARIES(state-test + orocos-rtalloctk-${OROCOS_TARGET} + orocos-rtt-${OROCOS_TARGET} + ${TEST_LIBRARIES} + ) + ADD_TEST( state-test ${RUNTIME_OUTPUT_DIRECTORY}/state-test ) + ENDIF (BUILD_TESTS) diff --git a/plugins/rtalloc/tests/state_test.cpp b/plugins/rtalloc/tests/state_test.cpp new file mode 100644 index 0000000..5cecbc4 --- /dev/null +++ b/plugins/rtalloc/tests/state_test.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + tag: Peter Soetens Mon Jan 10 15:59:51 CET 2005 state_test.cpp + + state_test.cpp - description + ------------------- + begin : Mon January 10 2005 + copyright : (C) 2005 Peter Soetens + email : peter.soetens@mech.kuleuven.ac.be + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + + +#include +#include "state_test.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace RTT; + +#include + +StateTest::StateTest() + :gtc("root"), + gtask( 0.01, gtc.engine() ) +{ + setUp(); +} + +void +StateTest::setUp() +{ + SimulationThread::Instance()->stop(); +} + + +void +StateTest::tearDown() +{ + // if a test failed, we must still stop : + gtask.stop(); +} + +BOOST_FIXTURE_TEST_SUITE( StateTestSuite, StateTest ) + +BOOST_AUTO_TEST_CASE( testCreateRtstring ) +{ + // test creation of rtstring from char* + string prog = string("StateMachine X {\n") + + " initial state INIT {\n" + + " var rtstring s = rtstring(\"hello world\");\n" + + " transitions { state FINI };\n" + + " }\n" + + " final state FINI {\n" + + " }\n" + + " RootMachine X x\n" // instantiate a non hierarchical SC + ; + this->doState( prog, >c ); + BOOST_CHECK( gtc.engine()->states()->getStateMachine( "x" )->inState("FINI") ); + this->finishState( >c, "x"); +} + + +BOOST_AUTO_TEST_SUITE_END() + +void StateTest::doState( const std::string& prog, TaskContext* tc, bool test ) +{ + BOOST_CHECK( tc->engine() ); + BOOST_CHECK( tc->engine()->states()); + + // Alternative way: test ScriptingAccess as well. + try { + tc->scripting()->loadStateMachines( prog, std::string("state_test.cpp"), true ); + } + catch( const file_parse_exception& exc ) + { + BOOST_REQUIRE_MESSAGE( false, exc.what() ); + } + catch( const parse_exception& exc ) + { + BOOST_REQUIRE_MESSAGE( false, exc.what() ); + } + catch( const program_load_exception& e) + { + BOOST_REQUIRE_MESSAGE( false, e.what() ); + } + catch( const std::exception& e ) { + BOOST_CHECK_MESSAGE( false , e.what()); + BOOST_REQUIRE_MESSAGE( false, "Uncaught Processor load exception" ); + } + BOOST_CHECK( gtask.start() ); + StateMachinePtr sm = tc->engine()->states()->getStateMachine("x"); + BOOST_CHECK( sm ); + CommandInterface* ca = newCommandFunctor(boost::bind(&StateMachine::activate, sm )); + CommandInterface* cs = newCommandFunctor(boost::bind(&StateMachine::automatic,sm )); +// cerr << "Before activate :"<getPeer("states")->getPeer("x")->debug(true); + BOOST_CHECK( ca->execute() ); + BOOST_CHECK_MESSAGE( sm->isActive(), "Error : Activate Command for '"+sm->getName()+"' did not have effect." ); +// cerr << "After activate :"<getPeer("states")->getPeer("x")->debug(true); + BOOST_CHECK( gtc.engine()->commands()->process( cs ) != 0 ); +// while (1) + BOOST_CHECK( SimulationThread::Instance()->run(1000) ); + delete ca; + delete cs; +// cerr << "After run :"<getPeer("states")->getPeer("x")->debug(true); +// // tc->getPeer("__states")->getPeer("X")->debug(false); +// if( tc->getPeer("__states")->getPeer("Y")) +// tc->getPeer("__states")->getPeer("Y")->debug(false); +// cerr << " x.y1 running : "<< (gprocessor.getStateMachineStatus("x.y1") == Processor::StateMachineStatus::running) << endl; +// cerr << " x running : "<< (gprocessor.getStateMachineStatus("x") == Processor::StateMachineStatus::running) << endl; + + if (test ) { + // check error status of parent : + BOOST_CHECK_MESSAGE( sm->isActive(), "Error : State Context '"+sm->getName()+"' did not get activated." ); + stringstream errormsg; + int line = sm->getLineNumber(); + errormsg <<" in StateMachine "+sm->getName() + <<" in state "<< sm->currentState()->getName() + <<" on line " << line <<" of that StateMachine:"<getText() ); + int cnt = 1; + while ( cnt++ " << sline << endl; + if ( sm->inError() ) { + RTT::detail::DumpObject( tc ); + } + BOOST_CHECK_MESSAGE( sm->inError() == false, "Runtime error (inError() == true) encountered" + errormsg.str() ); + // check error status of all children: + StateMachine::ChildList cl = sm->getChildren(); + StateMachine::ChildList::iterator clit = cl.begin(); + while( clit != cl.end() ) { + stringstream cerrormsg; + if ( (*clit)->currentState() ) + cerrormsg <<" in state "<<(*clit)->currentState()->getName()<< " on line " << (*clit)->getLineNumber() <<" of that StateMachine."< " << sline << endl; + else + cerrormsg <<" (deactivated) on line " << (*clit)->getLineNumber() <<" of that StateMachine."< " << sline << endl; + BOOST_CHECK_MESSAGE( (*clit)->inError() == false, "Runtime error (inError() == true) encountered in child "+(*clit)->getName() + cerrormsg.str() ); + ++clit; + } + } +} + +void StateTest::finishState(TaskContext* tc, std::string prog_name, bool test) +{ + StateMachinePtr sm = tc->engine()->states()->getStateMachine(prog_name); + BOOST_CHECK( sm ); + BOOST_CHECK( tc->engine()->states()->getStateMachine( prog_name )->stop() ); + BOOST_CHECK( SimulationThread::Instance()->run(500) ); + if (test) { + stringstream errormsg; + errormsg << " on line " << sm->getLineNumber() <<", status is "<< tc->engine()->states()->getStateMachineStatusStr(prog_name) < " << sline << endl;; + BOOST_CHECK_MESSAGE( sm->isStopped(), "StateMachine stalled " + errormsg.str() ); + } + // you can call deactivate even when the proc is not running. + // but deactivation may be 'in progress if exit state has commands in it. + BOOST_CHECK( tc->engine()->states()->getStateMachine( prog_name )->deactivate() ); + BOOST_CHECK( SimulationThread::Instance()->run(200) ); + BOOST_CHECK( tc->engine()->states()->getStateMachine( prog_name )->isActive() == false ); + + // only stop now, since deactivate won't work if simtask not running. + tc->stop(); + + try { + tc->engine()->states()->unloadStateMachine( prog_name ); + } + catch( const program_unload_exception& e) + { + BOOST_CHECK_MESSAGE( false, e.what() ); + } + catch( ... ) { + BOOST_CHECK_MESSAGE( false, "Uncaught Processor unload exception" ); + } + +} + diff --git a/plugins/rtalloc/tests/state_test.hpp b/plugins/rtalloc/tests/state_test.hpp new file mode 100644 index 0000000..b4c70d6 --- /dev/null +++ b/plugins/rtalloc/tests/state_test.hpp @@ -0,0 +1,46 @@ +/*************************************************************************** + tag: Peter Soetens Mon Jan 10 15:59:18 CET 2005 state_test.hpp + + state_test.hpp - description + ------------------- + begin : Mon January 10 2005 + copyright : (C) 2005 Peter Soetens + email : peter.soetens@mech.kuleuven.ac.be + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef STATETEST_H +#define STATETEST_H + +#include +#include +#include + +class StateTest +{ +public: + RTT::TaskContext gtc; + RTT::SimulationActivity gtask; + void doState( const std::string& prog, RTT::TaskContext*, bool test=true ); + void finishState( RTT::TaskContext* , std::string, bool test=true ); + + std::string sline; +public: + StateTest(); + ~StateTest(){ tearDown();}; + + void setUp(); + void tearDown(); + + void testCreateRtstring(); +}; + +#endif diff --git a/plugins/rtalloc/tests/test-runner.cpp b/plugins/rtalloc/tests/test-runner.cpp new file mode 100644 index 0000000..d432e0f --- /dev/null +++ b/plugins/rtalloc/tests/test-runner.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + tag: Peter Soetens Mon Jan 10 15:59:50 CET 2005 test-runner.cpp + + test-runner.cpp - description + ------------------- + begin : Mon January 10 2005 + copyright : (C) 2005 Peter Soetens + email : peter.soetens@mech.kuleuven.ac.be + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +using boost::unit_test::test_suite; + +using namespace RTT; +using namespace std; + +struct InitOrocos { +public: + InitOrocos(){ } + ~InitOrocos(){ + // If we call __os_exit() in Xenomai, we get an ABORT + // because the main task is cleaned up too early. + // The work around for now is to stop all threads but + // the main thread. To be fixed if boost::test allows it. +#ifndef OROCOS_TARGET_XENOMAI + __os_exit(); +#else + OS::StartStopManager::Instance()->stop(); + OS::StartStopManager::Release(); +#endif +} + +}; + +BOOST_GLOBAL_FIXTURE( InitOrocos ) + +boost::unit_test::test_suite* init_unit_test_suite(int argc, char** const argv) +{ + if ( argc > 1 && strncmp(argv[1],"--help",6) == 0 ) { + cout << "This unit test executable takes the following options:" <] "< "< "< "<"< "< "<1> "< "<"< "< "<