rtstring_test.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  ***************************************************************************/
00009 
00010 #include "unit.hpp"
00011 
00012 #include <rtt-config.h>
00013 #include <extras/SimulationThread.hpp>
00014 #include <extras/SimulationActivity.hpp>
00015 #include <scripting/StateMachine.hpp>
00016 #include <scripting/ParsedStateMachine.hpp>
00017 #include <scripting/DumpObject.hpp>
00018 #include <scripting/Parser.hpp>
00019 
00020 #include <Service.hpp>
00021 #include <TaskContext.hpp>
00022 #include <OperationCaller.hpp>
00023 #include <Port.hpp>
00024 #include <scripting/ScriptingService.hpp>
00025 #include "operations_fixture.hpp"
00026 
00027 #include <string>
00028 #include <iostream>
00029 #include <sstream>
00030 
00031 using namespace RTT;
00032 using namespace RTT::detail;
00033 using namespace std;
00034 
00035 class StateTest
00036     : public OperationsFixture
00037 {
00038 public:
00039     Parser parser;
00040     ScriptingService::shared_ptr sa;
00041 
00042     void doState(const std::string& name, const std::string& prog, TaskContext*, bool test=true );
00043     void parseState( const std::string& prog, TaskContext*, bool test=true );
00044     void runState(const std::string& name, TaskContext*, bool test=true );
00045     void checkState( const std::string& name, TaskContext*, bool test=true );
00046     void finishState( std::string const& name, TaskContext*, bool test=true );
00047 
00048     std::string sline;
00049 public:
00050     StateTest()
00051         :
00052          sa( ScriptingService::Create(tc) )
00053     {
00054         tc->stop();
00055         tc->setActivity( new SimulationActivity(0.001) );
00056 
00057         tc->start();
00058         i = 0;
00059         SimulationThread::Instance()->stop();
00060     }
00061     ~StateTest(){
00062     }
00063 };
00064 
00065 BOOST_FIXTURE_TEST_SUITE( RtStringTestSuite, StateTest )
00066 
00067 BOOST_AUTO_TEST_CASE( testCreateRtString )
00068 {
00069     string prog = string("StateMachine X {\n")
00070         + "   initial state INIT {\n"
00071         + "     var rt_string s1\n"
00072         + "     transitions { select FINI }\n"
00073         + "   }\n"
00074         + "   final state FINI {\n"
00075         + "   }\n"
00076         + " }\n"
00077         + " RootMachine X x\n" // instantiate a non hierarchical SC
00078         ;
00079 
00080     this->doState("x", prog, tc );
00081     this->finishState( "x", tc );
00082 }
00083 
00084 BOOST_AUTO_TEST_CASE( testCreateRtstringOfFixedSize )
00085 {
00086     string prog = string("StateMachine X {\n")
00087         + "   initial state INIT {\n"
00088         + "     var rt_string s1(22)\n"
00089         + "     transitions { select FINI }\n"
00090         + "   }\n"
00091         + "   final state FINI {\n"
00092         + "   }\n"
00093         + " }\n"
00094         + " RootMachine X x\n" // instantiate a non hierarchical SC
00095         ;
00096 
00097     this->doState("x", prog, tc );
00098     this->finishState( "x", tc );
00099 }
00100 
00101 #if 0
00102 // this is incorrect syntax:
00103 BOOST_AUTO_TEST_CASE( testCreateRtstringFromCharPtr )
00104 {
00105     string prog = string("StateMachine X {\n")
00106         + "   initial state INIT {\n"
00107         + "     var rt_string s1(\"hello world\")\n"
00108         + "     transitions { select FINI }\n"
00109         + "   }\n"
00110         + "   final state FINI {\n"
00111         + "   }\n"
00112         + " }\n"
00113         + " RootMachine X x\n" // instantiate a non hierarchical SC
00114         ;
00115     this->doState("x", prog, tc );
00116     this->finishState( "x", tc );
00117 }
00118 #endif
00119 
00120 BOOST_AUTO_TEST_CASE( testCreateRtstringFromRtString )
00121 {
00122     string prog = string("StateMachine X {\n")
00123         + "   initial state INIT {\n"
00124         + "     var rt_string s1 = rt_string(\"hello world\")\n"
00125         + "     transitions { select FINI }\n"
00126         + "   }\n"
00127         + "   final state FINI {\n"
00128         + "   }\n"
00129         + " }\n"
00130         + " RootMachine X x\n" // instantiate a non hierarchical SC
00131         ;
00132 
00133     this->doState("x", prog, tc );
00134     this->finishState( "x", tc );
00135 }
00136 
00137 BOOST_AUTO_TEST_CASE( testConcatRtstring )
00138 {
00139     string prog = string("StateMachine X {\n")
00140         + "   initial state INIT {\n"
00141         + "     var rt_string s1\n"
00142         + "     entry {\n"
00143         + "       s1 =  rt_string(\"Multiply \")\n"
00144         + "       s1 =  s1 + 10\n"
00145         + "       s1 =  s1 + rt_string(\" times \")\n"
00146         + "       s1 =  s1 + 33.3\n"
00147         + "       s1 =  rt_string(\"Now: \") + 1 + rt_string(\"st \") + s1 + '!'\n"
00148         + "     }\n"
00149         + "     transitions { select FINI }\n"
00150         + "   }\n"
00151         + "   final state FINI {\n"
00152         + "   }\n"
00153         + " }\n"
00154         + " RootMachine X x\n" // instantiate a non hierarchical SC
00155         ;
00156 
00157     this->doState("x", prog, tc );
00158     this->finishState( "x", tc );
00159 }
00160 
00161 BOOST_AUTO_TEST_CASE( testRtstringConversion )
00162 {
00163     string prog = string("StateMachine X {\n")
00164         + "   initial state INIT {\n"
00165         + "     var rt_string rts1\n"
00166         + "     var string s1\n"
00167         + "     entry {\n"
00168         + "       s1 =  \"s1\"\n"
00169         + "       rts1 =  rt_string(\"rts1\")\n"
00170         + "       test.assert(s1 ==  \"s1\")\n"
00171         + "       test.assert(rts1 ==  rt_string(\"rts1\"))\n"
00172         + "       s1 = string(rts1)\n"
00173         + "       test.assert(s1 == string(rts1))\n"
00174         + "       test.assert(s1 == \"rts1\")\n"
00175         + "       s1 =  \"s1\"\n"
00176         + "       rts1 = rt_string(s1)\n"
00177         + "       test.assert(rts1 == rt_string(\"s1\"))\n"
00178         + "       s1 =  string( rt_string(\" s1 \") )\n"
00179         + "       rts1 =  rt_string( string(\" rts1 \") )\n"
00180         + "       test.assert(s1 ==  \" s1 \")\n"
00181         + "       test.assert(rts1 ==  rt_string(\" rts1 \"))\n"
00182         + "     }\n"
00183         + "     transitions { select FINI }\n"
00184         + "   }\n"
00185         + "   final state FINI {\n"
00186         + "   }\n"
00187         + " }\n"
00188         + " RootMachine X x\n" // instantiate a non hierarchical SC
00189         ;
00190 
00191     this->doState("x", prog, tc );
00192     this->finishState( "x", tc );
00193 }
00194 
00195 
00196 BOOST_AUTO_TEST_SUITE_END()
00197 
00198 void StateTest::doState(  const std::string& name, const std::string& prog, TaskContext* tc, bool test )
00199 {
00200     BOOST_CHECK( tc->engine() );
00201 
00202     parseState( prog, tc, test);
00203     runState(name, tc, test);
00204     checkState(name, tc, test);
00205 }
00206 
00207 void StateTest::parseState(const std::string& prog, TaskContext* tc, bool test )
00208 {
00209     // Alternative way: test ScriptingService as well.
00210     try {
00211         sa->loadStateMachines( prog, std::string("state_test.cpp"), true );
00212     }
00213     catch( const file_parse_exception& exc )
00214         {
00215             BOOST_REQUIRE_MESSAGE( !test, exc.what() );
00216         }
00217     catch( const parse_exception& exc )
00218         {
00219             BOOST_REQUIRE_MESSAGE( !test, exc.what() );
00220         }
00221     catch( const program_load_exception& e)
00222         {
00223             BOOST_REQUIRE_MESSAGE( !test, e.what() );
00224         }
00225     catch( const std::exception& e ) {
00226             BOOST_CHECK_MESSAGE( !test , e.what());
00227             BOOST_REQUIRE_MESSAGE( !test, "Uncaught Processor load exception" );
00228     }
00229 }
00230 
00231 void StateTest::runState(const std::string& name, TaskContext* tc, bool test )
00232 {
00233     StateMachinePtr sm = sa->getStateMachine(name);
00234     BOOST_REQUIRE( sm );
00235     sm->trace(true);
00236     OperationCaller<bool(StateMachine*)> act = tc->provides(name)->getOperation("activate");
00237     OperationCaller<bool(StateMachine*)> autom = tc->provides(name)->getOperation("automatic");
00238     BOOST_CHECK( act(sm.get()) );
00239     BOOST_CHECK( SimulationThread::Instance()->run(1) );
00240     BOOST_CHECK_MESSAGE( sm->isActive(), "Error : Activate Command for '"+sm->getName()+"' did not have effect." );
00241     BOOST_CHECK( autom(sm.get()) || !test  );
00242 
00243     BOOST_CHECK( SimulationThread::Instance()->run(1000) );
00244 }
00245 
00246 void StateTest::checkState(const std::string& name, TaskContext* tc, bool test )
00247 {
00248     StateMachinePtr sm = sa->getStateMachine(name);
00249     BOOST_REQUIRE( sm );
00250     if ( test ) {
00251         // check error status of parent :
00252         BOOST_CHECK_MESSAGE( sm->isActive(), "Error : State Context '"+sm->getName()+"' did not get activated." );
00253         stringstream errormsg;
00254         int line = sm->getLineNumber();
00255         errormsg <<" in StateMachine "+sm->getName()
00256                  <<" in state "<< (sm->currentState() ? sm->currentState()->getName() : "(null)")
00257                  <<" on line " << line <<" of that StateMachine:"<<endl;
00258         {
00259             stringstream sctext( sm->getText() );
00260             int cnt = 1;
00261             while ( cnt++ <line && sctext ) {
00262                 string garbage;
00263                 getline( sctext, garbage, '\n' );
00264             }
00265             getline( sctext, sline, '\n' );
00266         }
00267         errormsg <<"here  > " << sline << endl;
00268         if ( sm->inError() ) {
00269             RTT::scripting::DumpObject( tc->provides() );
00270             RTT::scripting::DumpObject( tc->provides(name) );
00271         }
00272         BOOST_CHECK_MESSAGE( sm->inError() == false, "Runtime error (inError() == true) encountered" + errormsg.str() );
00273         // check error status of all children:
00274         StateMachine::ChildList cl = sm->getChildren();
00275         StateMachine::ChildList::iterator clit = cl.begin();
00276         while( clit != cl.end() ) {
00277             line = (*clit)->getLineNumber();
00278             {
00279                 stringstream sctext( (*clit)->getText() );
00280                 int cnt = 1;
00281                 while ( cnt++ <line && sctext ) {
00282                     string garbage;
00283                     getline( sctext, garbage, '\n' );
00284                 }
00285                 getline( sctext, sline, '\n' );
00286             }
00287             stringstream cerrormsg;
00288             if ( (*clit)->currentState() )
00289                 cerrormsg <<" in child "<< (*clit)->getName() <<" in state "<<(*clit)->currentState()->getName()<< " on line " <<  (*clit)->getLineNumber() <<" of that StateMachine."<<endl <<"here  > " << sline << endl;
00290             else
00291                 cerrormsg <<" child "<< (*clit)->getName() << " (deactivated) on line " <<  (*clit)->getLineNumber() <<" of that StateMachine."<<endl<<"here  > " << sline << endl;
00292 
00293             BOOST_CHECK_MESSAGE( (*clit)->inError() == false, "Runtime error (inError() == true) encountered" + cerrormsg.str() );
00294             if ( (*clit)->inError() == false && sm->inError() == true) {
00295                 cout << "Child Status:" << cerrormsg.str() << endl;
00296             }
00297             ++clit;
00298         }
00299     }
00300 }
00301 
00302 void StateTest::finishState(std::string const& name, TaskContext* tc, bool test)
00303 {
00304     StateMachinePtr sm = sa->getStateMachine(name);
00305     BOOST_REQUIRE( sm );
00306     BOOST_CHECK( sa->getStateMachine( name )->stop() );
00307     BOOST_CHECK( SimulationThread::Instance()->run(500) );
00308     if (test) {
00309         stringstream errormsg;
00310         errormsg << " on line " << sm->getLineNumber() <<", status is "<< sa->getStateMachineStatusStr(name) <<endl <<"here  > " << sline << endl;;
00311         BOOST_CHECK_MESSAGE( sm->isStopped(), "StateMachine stalled " + errormsg.str() );
00312     }
00313     // you can call deactivate even when the proc is not running.
00314     // but deactivation may be 'in progress if exit state has commands in it.
00315     BOOST_CHECK( sa->getStateMachine( name )->deactivate() );
00316     BOOST_CHECK( SimulationThread::Instance()->run(200) );
00317     if ( sm->isActive() )
00318         BOOST_CHECK( sa->getStateMachine( name )->deactivate() );
00319     BOOST_CHECK( SimulationThread::Instance()->run(200) );
00320     BOOST_CHECK( sa->getStateMachine( name )->isActive() == false );
00321 
00322     // only stop now, since deactivate won't work if simtask not running.
00323     tc->stop();
00324 
00325     try {
00326         BOOST_CHECK( sa->unloadStateMachine( name ) );
00327     }
00328     catch( const program_unload_exception& e)
00329         {
00330             BOOST_REQUIRE_MESSAGE( false, e.what() );
00331         }
00332     catch( ... ) {
00333             BOOST_REQUIRE_MESSAGE( false, "Uncaught Processor unload exception" );
00334     }
00335 
00336 }


rtt
Author(s): RTT Developers
autogenerated on Mon Oct 6 2014 03:13:39