state_test.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: Peter Soetens  Mon Jan 10 15:59:51 CET 2005  state_test.cpp
00003 
00004                         state_test.cpp -  description
00005                            -------------------
00006     begin                : Mon January 10 2005
00007     copyright            : (C) 2005 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.be
00009 
00010  ***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "unit.hpp"
00020 
00021 #include <rtt-config.h>
00022 #include <extras/SimulationThread.hpp>
00023 #include <extras/SimulationActivity.hpp>
00024 #include <scripting/StateMachine.hpp>
00025 #include <scripting/ParsedStateMachine.hpp>
00026 #include <scripting/DumpObject.hpp>
00027 #include <scripting/Parser.hpp>
00028 
00029 #include <Service.hpp>
00030 #include <TaskContext.hpp>
00031 #include <OperationCaller.hpp>
00032 #include <Port.hpp>
00033 #include <scripting/ScriptingService.hpp>
00034 #include <rt_string.hpp>
00035 #include "operations_fixture.hpp"
00036 
00037 #include <string>
00038 #include <iostream>
00039 #include <sstream>
00040 
00041 using namespace RTT;
00042 using namespace RTT::detail;
00043 using namespace std;
00044 
00045 class StateTest
00046     : public OperationsFixture
00047 {
00048 public:
00049     Parser parser;
00050     InputPort<double> d_event;
00051     InputPort<bool>   b_event;
00052     InputPort<int>    t_event;
00053     Operation<void(void)>   v_event;
00054     Operation<void(double)> o_event;
00055     Operation<void(void)>   v1_event;
00056     Operation<void(void)>   v2_event;
00057     Operation<void(void)>   v3_event;
00058     OutputPort<double> d_event_source;
00059     OutputPort<bool>   b_event_source;
00060     OutputPort<int>    t_event_source;
00061     Operation<void(double)> c_event;
00062     ScriptingService::shared_ptr sa;
00063 
00064     RTT::Operation<void(RTT::rt_string)>    setState_op;
00065     void setState(RTT::rt_string state) {
00066         mrt_state = state;
00067         //cout << "State = " << mrt_state.c_str() << endl;
00068     }
00069 
00070     RTT::rt_string mrt_state;
00071 
00072     void log(const std::string& msg) {
00073         Logger::log(Logger::Info) << msg << endlog();
00074     }
00075     void doState(const std::string& name, const std::string& prog, TaskContext*, bool test=true );
00076     void parseState( const std::string& prog, TaskContext*, bool test=true );
00077     void runState(const std::string& name, TaskContext*, bool test=true );
00078     void checkState( const std::string& name, TaskContext*, bool test=true );
00079     void finishState( std::string const& name, TaskContext*, bool test=true );
00080 
00081     std::string sline;
00082 public:
00083     StateTest()
00084         :
00085          d_event("d_event"), b_event("b_event"), t_event("t_event"), v_event("v_event"),o_event("o_event"),
00086          v1_event("v1_event"),v2_event("v2_event"),v3_event("v3_event"),c_event("c_event"),
00087          d_event_source("d_event_source"), b_event_source("b_event_source"), t_event_source("t_event_source")
00088          ,sa( ScriptingService::Create(tc) ),
00089          setState_op("setState", &StateTest::setState, this, RTT::OwnThread)
00090     {
00091         tc->stop();
00092         tc->setActivity( new SimulationActivity(0.001) );
00093 
00094         tc->addPeer(caller);
00095 
00096         tc->ports()->addPort( d_event );
00097         tc->ports()->addPort( b_event );
00098         tc->ports()->addPort( t_event );
00099 #ifdef ORO_SIGNALLING_OPERATIONS
00100         tc->provides()->addEventOperation( o_event );
00101         tc->provides()->addEventOperation( v_event );
00102         tc->provides()->addEventOperation( v1_event );
00103         tc->provides()->addEventOperation( v2_event );
00104         tc->provides()->addEventOperation( v3_event );
00105         caller->provides()->addEventOperation( c_event );
00106 #else
00107         tc->provides()->addOperation( o_event );
00108         tc->provides()->addOperation( v_event );
00109         tc->provides()->addOperation( v1_event );
00110         tc->provides()->addOperation( v2_event );
00111         tc->provides()->addOperation( v3_event );
00112         caller->provides()->addOperation( c_event );
00113 #endif
00114 
00115         tc->provides()->addOperation(setState_op).doc("Communicates state from SM").arg("state", "Name of state");
00116 
00117         tc->ports()->addPort( d_event_source );
00118         tc->ports()->addPort( b_event_source );
00119         tc->ports()->addPort( t_event_source );
00120 
00121         d_event_source.connectTo( &d_event );
00122         b_event_source.connectTo( &b_event );
00123         t_event_source.connectTo( &t_event );
00124         tc->start();
00125         i = 0;
00126         SimulationThread::Instance()->stop();
00127 
00128         tc->addOperation("log", &StateTest::log, this);
00129     }
00130     ~StateTest(){
00131     }
00132 };
00133 
00134 BOOST_FIXTURE_TEST_SUITE( StateTestSuite, StateTest )
00135 
00136 BOOST_AUTO_TEST_CASE( testParseState)
00137 {
00138     // a state which should never fail
00139     string prog = string("StateMachine X {\n")
00140         + " param int isten\n"
00141         + " param bool isflse\n"
00142         + " param bool isok\n"
00143         + " param double isnegative\n"
00144         + " var bool istrrue = true\n"
00145         + " var double d_dummy = -1.0\n"
00146         + " var int    i_dummy = -1\n"
00147         + " var bool   varinit = false\n"
00148         + " var bool   b_dummy = true\n" // 10
00149         + " initial state INIT {\n"
00150         // XXX bug : preconditions are not checked in the initial state.
00151 //         + " preconditions {\n"
00152 //         + "     if (istrrue == false) || (isflse == true) || (isten != 10) ||( isnegative >= 0. )  then select PRE_PARAMFAIL\n"
00153 //         + "     if false then select PRE_ERROR\n"
00154 //         + "     if (isnegative != -1.) then select PRE_PARAMFAIL\n"
00155 //         + "     if (istrrue != true) then select PRE_PARAMFAIL\n"
00156 //         + "     if (isflse != false) then select PRE_PARAMFAIL\n"
00157 //         + "     if (isten != 10 ) then select PRE_PARAMFAIL\n"
00158 //         + "     if (d_dummy != -1.) || (i_dummy != -1) then select PRE_VARFAIL\n"
00159 //         + " }\n"
00160         + " entry {\n"
00161         + "     set varinit = (d_dummy != -1.) || (i_dummy != -1) \n"
00162         + "     do test.good()\n"
00163         + "     set d_dummy = 1.234\n"
00164         + "     set i_dummy = -2\n"
00165         + "     do test.good()\n"
00166         + " }\n"
00167         + " handle {\n"
00168         + "     do test.good()\n" // 20
00169         + " }\n"
00170         + " exit {\n"
00171         + "     do test.good()\n"
00172         + "     set d_dummy = 0.0\n"
00173         + "     set i_dummy = 0\n"
00174         + " }\n"
00175         + " transitions {\n"
00176         + "     if false then select ERROR\n"
00177         + "     if varinit == true then select PRE_VARFAIL\n"
00178         + "     if (d_dummy != 1.234) || (i_dummy != -2)  then select ENTRYFAIL\n" // 30
00179         + " }\n"
00180         + " transition if (istrrue == false) || (isflse == true) || (isten != 10) ||( isnegative >= 0. )  then select PARAMFAIL\n"
00181         + " transition if isok == false then select PARAMFAIL\n"
00182         + " transition select FINI\n"
00183         + " transition select ERROR\n" // do not reach
00184         + " }\n"
00185         + " state PRE_ERROR { entry { do test.assert(false) }\n"
00186         + " }\n"
00187         + " state PRE_PARAMFAIL { entry { do test.assert(false) }\n"
00188         + " }\n"
00189         + " state PRE_VARFAIL { entry { do test.assert(false) }\n"
00190         + " }\n"
00191         + " state ERROR { entry { do test.assert(false) }\n"
00192         + " }\n"
00193         + " state PARAMFAIL {\n"
00194         + "      entry { \n"
00195         + "      do test.assertMsg( isten == 10, \"isten parameter not correctly initialised\")\n"
00196         + "      do test.assertMsg( istrrue == true, \"istrrue parameter not correctly initialised\")\n"
00197         + "      do test.assertMsg( isok == true, \"isok parameter not correctly initialised\")\n"
00198         + "      do test.assertMsg( isflse == false, \"isflse parameter not correctly initialised\")\n"
00199         + "      do test.assertMsg( true == true, \"true ident not correctly done\")\n"
00200         + "      do test.assertMsg( false == false, \"false ident not correctly done\")\n"
00201         + "      do test.assertMsg( isnegative == -1.0, \"isnegative parameter not correctly initialised\")\n"
00202         + "      }\n"
00203         + " }\n"
00204         + " state VARFAIL { entry { do test.assert(false) }\n"
00205         + " }\n"
00206         + " state EXITFAIL { entry { do test.assert(false) }\n"
00207         + " }\n"
00208         + " state ENTRYFAIL { entry { do test.assert(false) }\n"
00209         + " }\n"
00210         + " final state FINI {\n"
00211         + " preconditions {\n"
00212         + "     if (d_dummy != 0.) || (i_dummy != 0)  then select EXITFAIL\n"
00213         + "     if false then select ERROR\n"
00214         + " }\n"
00215         + " entry {\n"
00216         + "     do test.good()\n"
00217         + "     set d_dummy = -1.\n"
00218         + "     set i_dummy = -1\n"
00219         + " }\n"
00220         + " handle {\n"
00221         + "     do test.good()\n"
00222         + " }\n"
00223         + " exit {\n"
00224         + "     do test.good()\n"
00225         + " }\n"
00226         + " transitions {\n"
00227         + "     if false then select ERROR\n"
00228         + "     select INIT\n"
00229         + "     select ERROR\n" // do not reach
00230         + " }\n"
00231         + " }\n"
00232         + " }\n"
00233         //        + " RootMachine X x( isten = 10, isflse = false, isnegative = -1.0) \n" // instantiate a non hierarchical SC
00234         + " RootMachine X x( isten = 10, isok = true, isflse=false, isnegative = -1.0) \n" // instantiate a non hierarchical SC
00235         ;
00236 
00237     this->doState("x", prog, tc );
00238     this->finishState( "x", tc );
00239 }
00240 
00241 BOOST_AUTO_TEST_CASE( testStateFailure)
00242 {
00243     // test _command_ (through methods though) failure detection on several places.
00244     // it is an incomplete test, even more that parsing should fail on the second
00245     // run since the type 'X' is defined twice.
00246     string prog = string("StateMachine X {\n")
00247         + " initial state INIT {\n"
00248         + " entry {\n"
00249         + "     do test.increase()\n"                // set i to i+1
00250         + "     do test.assert( test.i != 1)\n" // fail if i == 1
00251         + " }\n"
00252         + " run {\n"
00253         + "     do test.assert( test.i != 2)\n"
00254         + " }\n"
00255         + " exit {\n"
00256         + "     do test.assert( test.i != 3)\n"
00257         + " }\n"
00258         + " transitions {\n"
00259         + "     if (true) then { do test.assert( test.i != 7); } select FINI\n"
00260         + " }\n"
00261         + " }\n"
00262         + " state ERROR {\n"
00263         + " }\n"
00264         + " final state FINI {\n"
00265         + " entry {\n"
00266         + "     do test.assert( test.i != 4)\n"
00267         + " }\n"
00268         + " run {\n"
00269         + "     do test.assert( test.i != 5)\n"
00270         + " }\n"
00271         + " exit {\n"
00272         + "     do test.assert( test.i != 6)\n"
00273         + " }\n"
00274         + " transitions {\n"
00275         + "     select ERROR\n"
00276         + " }\n"
00277         + " }\n"
00278         + " }\n"
00279         + " RootMachine X x\n" // instantiate a non hierarchical SC
00280         ;
00281 
00282     // should fail each time
00283     const int max = 7;
00284     int x = 0;
00285     while ( i < max && x < max) {
00286         this->doState("x", prog, tc, false );
00287         //cout << "i is: "<< i <<endl;
00288         // assert that an error happened :
00289         BOOST_CHECK_MESSAGE( sa->getStateMachineStatus("x") == StateMachine::Status::error, "Status is: " + sa->getStateMachineStatusStr("x") );
00290 
00291         this->finishState( "x", tc, false);
00292         ++x;
00293     }
00294 }
00295 BOOST_AUTO_TEST_CASE( testStateChildren)
00296 {
00297     // instantiate two children and check init of vars and params
00298     string prog = string("StateMachine Y {\n")
00299         + " param double isnegative\n"
00300         + " var   double t = 1.0\n"
00301         + " initial state INIT {\n"
00302         + " entry {\n"
00303         + "     do test.good()\n"
00304         + " }\n"
00305         + " transitions {\n"
00306         + "     if isnegative >= 0. then select PARAMFAIL\n"
00307         + "     select FINI\n"
00308         + " }\n"
00309         + " }\n"
00310         + " state ERROR { entry { do test.assert(false) }\n"
00311         + " }\n"
00312         + " state PARAMFAIL { entry { do test.assert(false) }\n"
00313         + " }\n"
00314         + " state VARFAIL { entry { do test.assert(false) }\n"
00315         + " }\n"
00316         + " state EXITFAIL { entry { do test.assert(false) }\n"
00317         + " }\n"
00318         + " state ENTRYFAIL { entry { do test.assert(false) }\n"
00319         + " }\n"
00320         + " final state FINI {\n"
00321         + " entry {\n"
00322         + "     do test.good()\n"
00323         + " }\n"
00324         + " transitions {\n"
00325         + "     select INIT\n"
00326         + " }\n"
00327         + " }\n"
00328         + " }\n"
00329         + string("StateMachine Z {\n")
00330         + " param double neg\n"
00331         + " initial state INIT {\n"
00332         + " transitions {\n"
00333         + "     if neg >= 0. then select PARAMFAIL\n"
00334         + "     select FINI\n"
00335         + " }\n"
00336         + " }\n"
00337         + " state PARAMFAIL { entry { do test.assert(false) }\n"
00338         + " }\n"
00339         + " final state FINI {\n"
00340         + " transitions {\n"
00341         + "     select INIT\n"
00342         + " }\n"
00343         + " }\n"
00344         + " }\n"
00345         + string("StateMachine X {\n")
00346         + " param double isnegative\n"
00347         + " var double d_dummy = -2.0\n"
00348         + " var int    i_dummy = -1\n"
00349         + " SubMachine Y y1(isnegative = d_dummy)\n"
00350         + " SubMachine Y y2(isnegative = -3.0)\n"
00351         + " SubMachine Y y3(isnegative = isnegative)\n"
00352         + " SubMachine Z z1( neg = d_dummy)\n"
00353         + " initial state INIT {\n"
00354         + " entry {\n"
00355         + "     do test.good()\n"
00356         + "     do y1.activate()\n"
00357         + "     do y2.activate()\n"
00358         + "     do y3.activate()\n"
00359         + "     do z1.activate()\n"
00360         + " }\n"
00361         + " exit {\n"
00362         + "     do y1.start()\n"
00363         + "     do y2.start()\n"
00364         + "     do y3.start()\n"
00365         + "     do z1.start()\n"
00366         + " }\n"
00367         + " transitions {\n"
00368         + "     select FINI\n"
00369         + " }\n"
00370         + " }\n"
00371         + " state ERROR { entry { do test.assert(false) }\n"
00372         + " }\n"
00373         + " state PARAMFAIL {\n"
00374         + "      entry { \n"
00375         + "      do test.assertMsg( y3.isnegative == isnegative, \"y3 parameter not correctly initialised\")\n"
00376         + "      do test.assertMsg( y2.isnegative == -3.0, \"y2 parameter not correctly initialised\")\n"
00377         + "      do test.assertMsg( y1.isnegative == d_dummy, \"y1 parameter not correctly initialised\")\n"
00378         + "      do test.assertMsg( z1.neg == d_dummy, \"z1 parameter not correctly initialised\")\n"
00379         + "      }\n"
00380         + " }\n"
00381         + " state VARFAIL { entry { do test.assert(false) }\n"
00382         + " }\n"
00383         + " state EXITFAIL { entry { do test.assert(false) }\n"
00384         + " }\n"
00385         + " state ENTRYFAIL { entry { do test.assert(false) }\n"
00386         + " }\n"
00387         + " final state FINI {\n"
00388         + " entry {\n"
00389         + "     do test.good()\n"
00390         + "     do y1.stop()\n"
00391         + "     do y2.stop()\n"
00392         + "     do y3.stop()\n"
00393         + "     do z1.stop()\n"
00394         + " }\n"
00395         + " exit {\n"
00396         + "     do test.good()\n"
00397         + "     do y1.deactivate()\n"
00398         + "     do y2.deactivate()\n"
00399         + "     do y3.deactivate()\n"
00400         + "     do z1.deactivate()\n"
00401         + " }\n"
00402         + " transitions {\n"
00403         + "     if z1.neg != d_dummy then select PARAMFAIL\n"
00404         + "     if y1.isnegative != d_dummy then select PARAMFAIL\n"
00405         + "     if y2.isnegative != -3.0 then select PARAMFAIL\n"
00406         + "     if y3.isnegative != isnegative then select PARAMFAIL\n"
00407         + "     select INIT\n"
00408         + " }\n"
00409         + " }\n"
00410         + " }\n"
00411         + " RootMachine X x( isnegative = -1.0) \n" // instantiate a hierarchical SC
00412         ;
00413 
00414     this->doState("x", prog, tc );
00415     this->finishState( "x", tc);
00416 }
00417 
00418 BOOST_AUTO_TEST_CASE( testStateEmpty)
00419 {
00420     // test processing of completely empty states
00421     string prog = string("StateMachine X {\n")
00422         + " initial state INIT {\n"
00423         + " transitions {\n"
00424         + "     select TEST;\n" // only a transition
00425         + " }\n"
00426         + " }\n"
00427         + " state TEST {\n"  // not even used
00428         + " }\n"
00429         + " final state FINI {\n" // completely empty
00430         + " }\n"
00431         + " }\n"
00432         + " RootMachine X x\n" // instantiate a non hierarchical SC
00433         ;
00434      this->doState("x", prog, tc );
00435      this->finishState( "x", tc);
00436 }
00437 
00438 BOOST_AUTO_TEST_CASE( testStateEmptyChild)
00439 {
00440     // test processing of completely empty states
00441     string prog = string("StateMachine Y {\n")
00442         + " initial state INIT {\n"
00443         + " }\n"
00444         + " final state FINI {\n"
00445         + " }\n"
00446         + "}\n"
00447         + "StateMachine X {\n"
00448         + "  SubMachine Y y;\n"
00449         + " initial state INIT {\n"
00450         + " }\n"
00451         + " final state FINI {\n"
00452         + " }\n"
00453         + "}\n"
00454         + "RootMachine X x\n"
00455         ;
00456 
00457     this->doState("x", prog, tc );
00458     this->finishState( "x", tc);
00459 }
00460 
00461 BOOST_AUTO_TEST_CASE( testStateComments)
00462 {
00463     // test parsing of comments
00464     string prog = string("// Start here\n")
00465         + "StateMachine X { //\n"
00466         + " // comment on INIT\n"
00467         + " initial state INIT /* INIT */ { // \n"
00468         + " // comment in INIT\n"
00469         + " entry /* entry */ { // \n"
00470         + " // in entry\n"
00471         + " } // end \n\n"
00472         + "//\n"
00473         + " }\n"
00474         + " // intermediate comment \n"
00475         + " final state FINI // \n"
00476         + " /* ... */\n"
00477         + " {\n"
00478         + "//\n"
00479         + " entry {\n"
00480         + " // in entry\n"
00481         + " /* in entry */\n"
00482         + " }\n\n"
00483         + "//\n"
00484         + " }\n"
00485         + "// final comment\n"
00486         + "//\n"
00487         + "}\n"
00488         + "// instantiate comment\n"
00489         + "//\n"
00490         + "RootMachine X x // end\n"
00491         ;
00492     this->doState("x", prog, tc );
00493     this->finishState( "x", tc);
00494 }
00495 
00496 BOOST_AUTO_TEST_CASE( testStateOperations)
00497 {
00498     // test processing of operations (OwnThread + ClientThread):
00499     string prog = string("StateMachine X {\n")
00500         + " initial state INIT {\n"
00501         + "   entry {\n"
00502         + "   setState( rt_string(\"INIT-ENTRY\") )\n"
00503         + " }\n"
00504         + " transitions {\n"
00505         + "     select TEST;\n" // only a transition
00506         + " }\n"
00507         + " }\n"
00508         + " state TEST {\n"
00509         + "   var double dret\n"
00510         + "   entry {\n"
00511         + "   setState( rt_string(\"TEST-ENTRY\") )\n"
00512         + "   methods.m0()\n"
00513         + "   methods.m1(1)\n"
00514         + "   methods.m2(1,2.0)\n"
00515         + "   methods.m3(1,2.0,true)\n"
00516         + "   methods.m4(1,2.0,true,\"hello\")\n"
00517         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00518         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00519         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00520         + "   test.assert( dret == -8.0 )\n"
00521         + "   methods.o0()\n"
00522         + "   methods.o1(1)\n"
00523         + "   methods.o2(1,2.0)\n"
00524         + "   methods.o3(1,2.0,true)\n"
00525         + "   methods.o4(1,2.0,true,\"hello\")\n"
00526         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00527         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00528         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00529         + "   test.assert( dret == -8.0 )\n"
00530         + "   }\n"
00531         + "   run {"
00532         + "   setState( rt_string(\"TEST-RUN\") )\n"
00533         + "   methods.m0()\n"
00534         + "   methods.m1(1)\n"
00535         + "   methods.m2(1,2.0)\n"
00536         + "   methods.m3(1,2.0,true)\n"
00537         + "   methods.m4(1,2.0,true,\"hello\")\n"
00538         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00539         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00540         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00541         + "   test.assert( dret == -8.0 )\n"
00542         + "   methods.o0()\n"
00543         + "   methods.o1(1)\n"
00544         + "   methods.o2(1,2.0)\n"
00545         + "   methods.o3(1,2.0,true)\n"
00546         + "   methods.o4(1,2.0,true,\"hello\")\n"
00547         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00548         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00549         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00550         + "   test.assert( dret == -8.0 )\n"
00551         + "   }\n"
00552         + "   exit {"
00553         + "   setState( rt_string(\"TEST-EXIT\") )\n"
00554         + "   methods.m0()\n"
00555         + "   methods.m1(1)\n"
00556         + "   methods.m2(1,2.0)\n"
00557         + "   methods.m3(1,2.0,true)\n"
00558         + "   methods.m4(1,2.0,true,\"hello\")\n"
00559         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00560         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00561         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00562         + "   test.assert( dret == -8.0 )\n"
00563         + "   methods.o0()\n"
00564         + "   methods.o1(1)\n"
00565         + "   methods.o2(1,2.0)\n"
00566         + "   methods.o3(1,2.0,true)\n"
00567         + "   methods.o4(1,2.0,true,\"hello\")\n"
00568         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00569         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00570         + "   methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00571         + "   }\n"
00572         + " transitions {\n"
00573         + "     if true then \n"
00574         + "   {"
00575         + "   setState( rt_string(\"TEST-TRANSIT\") )\n"
00576         + "   methods.m0()\n"
00577         + "   methods.m1(1)\n"
00578         + "   methods.m2(1,2.0)\n"
00579         + "   methods.m3(1,2.0,true)\n"
00580         + "   methods.m4(1,2.0,true,\"hello\")\n"
00581         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00582         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00583         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00584         + "   test.assert( dret == -8.0 )\n"
00585         + "   methods.o0()\n"
00586         + "   methods.o1(1)\n"
00587         + "   methods.o2(1,2.0)\n"
00588         + "   methods.o3(1,2.0,true)\n"
00589         + "   methods.o4(1,2.0,true,\"hello\")\n"
00590         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00591         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00592         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00593         + "   test.assert( dret == -8.0 )\n"
00594         + "   } select TEST2;\n"
00595         + " }\n"
00596         + " }\n"
00597         + " state TEST2 {\n"
00598         + "   entry {\n"
00599         + "   setState( rt_string(\"TEST-ENTRY\") )\n"
00600         + "   methods.m0()\n"
00601         + "   methods.m1(1)\n"
00602         + "   methods.m2(1,2.0)\n"
00603         + "   methods.m3(1,2.0,true)\n"
00604         + "   methods.m4(1,2.0,true,\"hello\")\n"
00605         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00606         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00607         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00608         + "   test.assert( dret == -8.0 )\n"
00609         + "   methods.o0()\n"
00610         + "   methods.o1(1)\n"
00611         + "   methods.o2(1,2.0)\n"
00612         + "   methods.o3(1,2.0,true)\n"
00613         + "   methods.o4(1,2.0,true,\"hello\")\n"
00614         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00615         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00616         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00617         + "   test.assert( dret == -8.0 )\n"
00618         + "   }\n"
00619         + "   run {"
00620         + "   setState( rt_string(\"TEST-RUN\") )\n"
00621         + "   methods.m0()\n"
00622         + "   methods.m1(1)\n"
00623         + "   methods.m2(1,2.0)\n"
00624         + "   methods.m3(1,2.0,true)\n"
00625         + "   methods.m4(1,2.0,true,\"hello\")\n"
00626         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00627         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00628         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00629         + "   test.assert( dret == -8.0 )\n"
00630         + "   methods.o0()\n"
00631         + "   methods.o1(1)\n"
00632         + "   methods.o2(1,2.0)\n"
00633         + "   methods.o3(1,2.0,true)\n"
00634         + "   methods.o4(1,2.0,true,\"hello\")\n"
00635         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00636         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00637         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00638         + "   test.assert( dret == -8.0 )\n"
00639         + "   }\n"
00640         + "   exit {"
00641         + "   setState( rt_string(\"TEST-EXIT\") )\n"
00642         + "   methods.m0()\n"
00643         + "   methods.m1(1)\n"
00644         + "   methods.m2(1,2.0)\n"
00645         + "   methods.m3(1,2.0,true)\n"
00646         + "   methods.m4(1,2.0,true,\"hello\")\n"
00647         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00648         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00649         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00650         + "   test.assert( dret == -8.0 )\n"
00651         + "   methods.o0()\n"
00652         + "   methods.o1(1)\n"
00653         + "   methods.o2(1,2.0)\n"
00654         + "   methods.o3(1,2.0,true)\n"
00655         + "   methods.o4(1,2.0,true,\"hello\")\n"
00656         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00657         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00658         + "   methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00659         + "   }\n"
00660         + " transitions {\n"
00661         + "     if true then \n"
00662         + "   {"
00663         + "   setState( rt_string(\"TEST-TRANSIT\") )\n"
00664         + "   methods.m0()\n"
00665         + "   methods.m1(1)\n"
00666         + "   methods.m2(1,2.0)\n"
00667         + "   methods.m3(1,2.0,true)\n"
00668         + "   methods.m4(1,2.0,true,\"hello\")\n"
00669         + "   methods.m5(1,2.0,true,\"hello\",5.0)\n"
00670         + "   methods.m6(1,2.0,true,\"hello\",5.0,'a')\n"
00671         + "   dret = methods.m7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00672         + "   test.assert( dret == -8.0 )\n"
00673         + "   methods.o0()\n"
00674         + "   methods.o1(1)\n"
00675         + "   methods.o2(1,2.0)\n"
00676         + "   methods.o3(1,2.0,true)\n"
00677         + "   methods.o4(1,2.0,true,\"hello\")\n"
00678         + "   methods.o5(1,2.0,true,\"hello\",5.0)\n"
00679         + "   methods.o6(1,2.0,true,\"hello\",5.0,'a')\n"
00680         + "   dret = methods.o7(1,2.0,true,\"hello\",5.0,'a',7)\n"
00681         + "   test.assert( dret == -8.0 )\n"
00682         + "   } select FINI;\n"
00683         + " }\n"
00684         + " }\n"
00685         + " final state FINI {\n" // completely empty
00686         + " }\n"
00687         + " }\n"
00688         + " RootMachine X x\n" // instantiate a non hierarchical SC
00689         ;
00690      parseState( prog, tc, true);
00691 
00692      tc->stop();
00693      tc->setActivity( new Activity(0, 0.001) ); // deliberately test with real thread instead of simulation.
00694      tc->start();
00695 
00696      StateMachinePtr sm = sa->getStateMachine("x");
00697      BOOST_REQUIRE( sm );
00698      sm->trace(true);
00699      OperationCaller<bool(StateMachine*)> act = tc->provides("x")->getOperation("activate");
00700      OperationCaller<bool(StateMachine*)> autom = tc->provides("x")->getOperation("automatic");
00701      BOOST_CHECK( act(sm.get()) );
00702      BOOST_CHECK( autom(sm.get()) );
00703 
00704      sleep(1); // we must allow the thread to transition...
00705 
00706      checkState( "x", tc);
00707      BOOST_CHECK( sa->getStateMachine( "x" )->inState("FINI") );
00708      this->finishState( "x", tc, false); // don't test
00709 }
00710 
00711 
00712 BOOST_AUTO_TEST_CASE( testStateTransitions)
00713 {
00714     // test processing of transition statements.
00715     string prog = string("StateMachine X {\n")
00716         + " initial state INIT {\n"
00717         + " var int i = 0;\n" // transition counter
00718         + " var int j = 0;\n" // entry counter
00719         + " var int k = 0;\n" // run counter
00720         + " entry {\n"
00721         + "   set j = j + 1\n"
00722         + " }\n"
00723         + " run {\n"
00724         + "   set k = k + 1\n"
00725         + " }\n"
00726         + " transitions {\n"
00727         + "  if i < 5 then {\n"
00728         + "    set i = i + 1;\n" // execute this program
00729         + "  } select INIT\n" // test EXPLICIT transition to self: no entry/exit.
00730         + "  if i < 10 then {\n"
00731         + "    set i = i + 1;\n" // execute this program
00732         + "  }\n" // test IMPLICIT transition to self: no entry/exit.
00733         + "  if i < 10 then {\n"
00734         + "  } select TRANS_SHOULD_NOT_CHECK\n" // should never be reached.
00735         + "  if i == 10 then {\n"
00736         + "    set i = i + 1;\n" // execute this program
00737         + "  } select TEST_ENTRY\n"
00738         + " }\n"
00739         + " }\n"
00740         + " state TEST_ENTRY {\n" // test if entry was executed one time
00741         + " transitions {\n"
00742         + "  if k != i then {\n"
00743         + "  } select RUN_FAILED\n"
00744         + "  if j != 1 then {\n"
00745         + "  } select ENTRY_FAILED\n"
00746         + "  else select FINI\n"
00747         + " }\n"
00748         + " }\n"
00749         + " state TRANS_SHOULD_NOT_CHECK {\n" // failure state
00750         + " entry { do test.assert(false); }\n"
00751         + " }\n"
00752         + " state ENTRY_FAILED {\n"           // failure state
00753         + " entry { do test.assert(false); }\n"
00754         + " }\n"
00755         + " state RUN_FAILED {\n"           // failure state
00756         + " entry { do test.assert(false); }\n"
00757         + " }\n"
00758         + " final state FINI {\n" // Success state.
00759         + " }\n"
00760         + " }\n"
00761         + " RootMachine X x\n" // instantiate a non hierarchical SC
00762         ;
00763      this->doState("x", prog, tc );
00764      BOOST_CHECK( sa->getStateMachine( "x" )->inState("FINI") );
00765      this->finishState( "x", tc);
00766 }
00767 
00768 BOOST_AUTO_TEST_CASE( testStateTransitionStop )
00769 {
00770     // test processing of transition statements.
00771     string prog = string("StateMachine X {\n")
00772         + " initial state INIT {\n"
00773         + " transitions {\n"
00774         + "  if stop() == true then select NEXT\n" // calls stop on the component !
00775         + " }\n"
00776         + " }\n"
00777         + " state NEXT {\n" // Success state.
00778         + " entry { do test.assert(true); }\n"
00779         + " }\n"
00780         + " final state FINI {\n" // Failure state.
00781         + " entry { do test.assert(true); }\n"
00782         + " }\n"
00783         + " }\n"
00784         + " RootMachine X x\n" // instantiate a non hierarchical SC
00785         ;
00786      this->doState("x", prog, tc );
00787      BOOST_CHECK( sa->getStateMachine( "x" )->inState("NEXT") );
00788      this->finishState( "x", tc);
00789 }
00790 
00791 BOOST_AUTO_TEST_CASE( testStateGlobalTransitions)
00792 {
00793     // test processing of transition statements.
00794     string prog = string("StateMachine X {\n")
00795         + " var int gi = 0;\n" // transition counter
00796         + " transitions {\n"
00797 
00798         + "  if gi < 5 then {\n"
00799         + "    set gi = gi + 1;\n" // execute this program
00800         + "  } select INIT\n" // test EXPLICIT transition to self: no entry/exit.
00801 
00802         + "  if gi < 10 then {\n"
00803         + "    if gi < 5 then do test.assert(false);\n"
00804         + "    set gi = gi + 1;\n" // execute this program
00805         + "  }\n" // test IMPLICIT transition to self: no entry/exit.
00806         + "  if gi < 10 then {\n"
00807         + "   do test.assert(false);\n"
00808         + "  } select TRANS_SHOULD_NOT_CHECK\n" // should never be reached.
00809         + "  if gi >= 10 then {\n"
00810         + "  } select FINI\n" // we must be checked before
00811         + " }\n"
00812         + " initial state INIT {\n"
00813         + " var int i = 0;\n" // transition counter
00814         + " var int j = 0;\n" // entry counter
00815         + " var int k = 0;\n" // run counter
00816         + " entry {\n"
00817         + "   set j = j + 1\n"
00818         + " }\n"
00819         + " run {\n"
00820         + "   set k = k + 1\n"
00821         + " }\n"
00822         + " transitions {\n"
00823         + "  if i < 5 then {\n"
00824         + "    set i = i + 1;\n" // execute this program
00825         + "  } select INIT\n" // test EXPLICIT transition to self: no entry/exit.
00826         + "  if i < 10 then {\n"
00827         + "    set i = i + 1;\n" // execute this program
00828         + "  }\n" // test IMPLICIT transition to self: no entry/exit.
00829         + "  if i < 10 then {\n"
00830         + "  } select TRANS_SHOULD_NOT_CHECK\n" // should never be reached.
00831         + " }\n"
00832         + " }\n"
00833         + " state TRANS_SHOULD_NOT_CHECK {\n" // failure state
00834         + " entry { do test.assert(false); }\n"
00835         + " }\n"
00836         + " state ENTRY_FAILED {\n"           // failure state
00837         + " entry { do test.assert(false); }\n"
00838         + " }\n"
00839         + " state RUN_FAILED {\n"           // failure state
00840         + " entry { do test.assert(false); }\n"
00841         + " }\n"
00842         + " final state FINI {\n" // Success state.
00843         + " }\n"
00844         + " }\n"
00845         + " RootMachine X x\n" // instantiate a non hierarchical SC
00846         ;
00847      this->doState("x", prog, tc );
00848      BOOST_CHECK( sa->getStateMachine( "x" )->inState("FINI") );
00849      this->finishState( "x", tc);
00850 }
00851 
00852 
00853 BOOST_AUTO_TEST_CASE( testStateSubStateVars)
00854 {
00855     // test get/set access of substate variables and parameters
00856     string prog = string("StateMachine Y {\n")
00857         + " param double isnegative\n"
00858         + " var   double t = 1.0\n"
00859         + " initial state INIT {\n"
00860         + " transitions {\n"
00861         + "     if isnegative >= 0. then select PARAMFAIL\n"
00862         + "     if t >= 0. then select VARFAIL\n"
00863         + "     select FINI\n"
00864         + " }\n"
00865         + " exit { set isnegative = +1.0 }\n"
00866         + " }\n" // 11
00867         + " state ERROR { entry { do test.assert(false) }\n"
00868         + " }\n"
00869         + " state PARAMFAIL { entry { do test.assert(false) }\n"
00870         + " }\n"
00871         + " state VARFAIL { entry { do test.assert(false) }\n"
00872         + " }\n"
00873         + " state EXITFAIL { entry { do test.assert(false) }\n"
00874         + " }\n"
00875         + " state ENTRYFAIL { entry { do test.assert(false) }\n"
00876         + " }\n" // 21
00877         + " final state FINI {\n"
00878         + " transitions {\n"
00879         + "     if isnegative <= 0. then select PARAMFAIL\n"
00880         + " }\n"
00881         + " }\n"
00882         + " }\n"
00883         + string("StateMachine X {\n")
00884         + " param double isnegative\n"
00885         + " var double d_dummy = -2.0\n"
00886         + " var int    i_dummy = -1\n" //31
00887         + " SubMachine Y y1(isnegative = d_dummy)\n"
00888         + " initial state INIT {\n"
00889         + " entry {\n"
00890         + "     do y1.activate()\n"
00891         + "     set y1.t = -1.0 \n"
00892         + " }\n"
00893         + " exit {\n"
00894         + "     do y1.start()\n"
00895         + " }\n"
00896         + " transitions {\n"
00897         + "     select TEST\n"
00898         + " }\n"
00899         + " }\n"
00900         + " state TEST {\n"
00901         + " entry {\n"
00902         + "     do yield\n"
00903         + "     do test.assert( y1.inState(\"FINI\") )\n" // if y1 not in FINI, stop here.
00904         + " }\n"
00905         + " transitions {\n"
00906         + "     select FINI\n"
00907         + " }\n"
00908         + " }\n"
00909         + " final state FINI {\n"
00910         + " entry {\n"
00911         + "     do y1.stop()\n" // prepare y1 to start-over
00912         + " }\n"
00913         + " exit {\n"
00914         + "     set y1.isnegative = -1.0 \n"
00915         + "     do y1.deactivate()\n"
00916         + " }\n"
00917         + " transitions {\n"
00918         + "     select INIT\n" // start-over y1.
00919         + " }\n"
00920         + " }\n"
00921         + " }\n"
00922         + " RootMachine X x( isnegative = -1.0) \n" // instantiate a hierarchical SC
00923         ;
00924 
00925      this->doState("x", prog, tc );
00926      this->finishState( "x", tc);
00927 }
00928 
00929 BOOST_AUTO_TEST_CASE( testStateSubStateCommands)
00930 {
00931     // test get/set access of substate variables and parameters
00932     string prog = string("StateMachine Y {\n")
00933         + " param double isnegative\n"
00934         + " var   double t = 1.0\n"
00935         + " initial state INIT {\n"
00936         + " transitions {\n"
00937         + "     if isnegative < 0. then select ISNEGATIVE\n"
00938         + "     if t >= 0. then select ISPOSITIVE\n"
00939         + "     select DEFAULT\n"
00940         + " }\n"
00941         + " }\n"
00942         + " state ISNEGATIVE {\n"
00943         + " transitions {\n"
00944         + "      select INIT\n"
00945         + " }\n"
00946         + " }\n"
00947         + " state ISPOSITIVE {\n"
00948         + " transitions {\n"
00949         + "      select INIT\n"
00950         + " }\n"
00951         // 20 :
00952         + " }\n"
00953         + " state DEFAULT {\n"
00954         + " transitions {\n"
00955         + "      select FINI\n"
00956         + " }\n"
00957         + " }\n"
00958         + " final state FINI {\n"
00959         + " }\n"
00960         + " }\n"
00961         + string("StateMachine X {\n") // 1
00962         + " SubMachine Y y1(isnegative = -1.0)\n"
00963         + " initial state INIT {\n"
00964         + " entry {\n"
00965         + "     set y1.t = -1.0 \n"
00966         + "     do y1.activate()\n"
00967         + "     do y1.requestState(\"ISNEGATIVE\")\n"
00968         + "     do test.assert( y1.inState(\"ISNEGATIVE\") )\n"
00969         + "     do y1.requestState(\"INIT\")\n"
00970         + "     do test.assert( y1.inState(\"INIT\") )\n"
00971         + "     set y1.isnegative = +1.0 \n"
00972         + "     try y1.requestState(\"ISNEGATIVE\") \n "
00973         + "     catch \n{\n"
00974         + "         do test.assert( y1.inState(\"INIT\") )\n" // do not leave INIT
00975         + "     }\n"
00976         + "     do test.assert( y1.inState(\"INIT\") )\n" // do not leave INIT
00977         + "     do y1.requestState(\"FINI\")\n"      // request final state
00978         + "     do test.assert( y1.inState(\"FINI\") )\n"
00979         + " }\n"
00980         + " exit {\n"
00981         + "     do y1.requestState(\"INIT\")\n"      // request initial state
00982         + "     do test.assert( y1.inState(\"INIT\") )\n"
00983         + "     set y1.isnegative = +1.0 \n"
00984         + "     set y1.t = -1.0 \n"
00985         + "     do y1.start()\n"  // must reach FINI after a while.
00986         + "     while ! y1.inState(\"FINI\") \n"
00987         + "        do nothing\n"
00988         + " }\n"
00989         + " transitions {\n"
00990         + "     select FINI\n"
00991         + " }\n"
00992         + " }\n"
00993         + " final state FINI {\n"
00994         + " entry {\n"
00995         + "     do y1.stop()\n"
00996         + " }\n"
00997         + " exit {\n"
00998         + "     do y1.deactivate()\n"
00999         + " }\n"
01000         + " transitions {\n"
01001         + "     select INIT\n"
01002         + " }\n"
01003         + " }\n"
01004         + " }\n"
01005         + " RootMachine X x() \n" // instantiate a hierarchical SC
01006         ;
01007 
01008      this->doState("x", prog, tc );
01009      this->finishState( "x", tc);
01010 }
01011 
01012 #ifdef ORO_SIGNALLING_OPERATIONS
01013 BOOST_AUTO_TEST_CASE( testStateOperationSignalTransition )
01014 {
01015     // test event reception from own component
01016     string prog = string("StateMachine X {\n")
01017         + " var   double et = 0.0\n"
01018         + " initial state INIT {\n"
01019         + "    transition o_event(et) select FINI\n" // test signal transition
01020         + " }\n"
01021         + " final state FINI {} \n"
01022         + "}\n"
01023         + "RootMachine X x()\n";
01024     this->parseState( prog, tc );
01025     StateMachinePtr sm = sa->getStateMachine("x");
01026     BOOST_REQUIRE( sm );
01027     this->runState("x", tc);
01028     checkState( "x", tc);
01029     OperationCaller<void(double)> mo( tc->provides()->getOperation("o_event") );
01030     mo(3.33);
01031     checkState( "x", tc);
01032     BOOST_CHECK( SimulationThread::Instance()->run(2) );
01033     checkState( "x", tc);
01034     BOOST_CHECK( sm->inState("FINI") );
01035     this->checkState("x",tc);
01036     this->finishState("x", tc);
01037 }
01038 
01039 BOOST_AUTO_TEST_CASE( testStateOperationCallerSignalTransition )
01040 {
01041     // test event reception from another component
01042     string prog = string("StateMachine X {\n")
01043         + " var   double et = 0.0\n"
01044         + " initial state INIT {\n"
01045         + "    transition caller.c_event(et) select FINI\n" // test signal transition
01046         + " }\n"
01047         + " final state FINI {} \n"
01048         + "}\n"
01049         + "RootMachine X x()\n";
01050     this->parseState( prog, tc );
01051     StateMachinePtr sm = sa->getStateMachine("x");
01052     BOOST_REQUIRE( sm );
01053     this->runState("x", tc);
01054     checkState( "x", tc);
01055     BOOST_CHECK( SimulationThread::Instance()->run(2) );
01056     checkState( "x", tc);
01057     OperationCaller<void(double)> mc( caller->provides()->getOperation("c_event") );
01058     mc(6.66);
01059     checkState( "x", tc);
01060     BOOST_CHECK( SimulationThread::Instance()->run(2) );
01061     checkState( "x", tc);
01062     BOOST_CHECK( sm->inState("FINI") );
01063     this->checkState("x",tc);
01064     this->finishState("x", tc);
01065 }
01066 
01067 BOOST_AUTO_TEST_CASE( testStateOperationSignalMultiTransition )
01068 {
01069     // test multi-event reception from own component
01070     string prog = string("StateMachine X {\n")
01071     + " initial state INIT {\n"
01072     + "    transitions { select STATE1 }\n"
01073     + " }\n"
01074     + " state STATE1 {\n"
01075     + "    transition v_event() select STATE2\n" // test signal transition
01076     + " }\n"
01077     + " state STATE2 {\n"
01078     + "    transition v_event() select FINI\n"   // test signal transition
01079     + " }\n"
01080     + " final state FINI {} \n"
01081     + "}\n"
01082     + "RootMachine X x()\n";
01083     this->parseState( prog, tc );
01084     StateMachinePtr sm = sa->getStateMachine("x");
01085     BOOST_REQUIRE( sm );
01086     sm->trace(true);
01087     // into STATE1
01088     this->runState("x", tc);
01089     checkState( "x", tc);
01090     BOOST_CHECK_EQUAL( "STATE1", sm->getCurrentStateName() );
01091     // remain in STATE1
01092     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01093     checkState( "x", tc);
01094     BOOST_CHECK_EQUAL( "STATE1", sm->getCurrentStateName() );
01095     // into STATE2
01096     OperationCaller<void(void)> mo( tc->provides()->getOperation("v_event"), tc->engine());
01097     BOOST_REQUIRE( mo.ready() );
01098     mo();
01099     BOOST_CHECK( SimulationThread::Instance()->run(1) ); // allow to transition
01100     checkState( "x", tc);
01101     BOOST_CHECK_EQUAL( "STATE2", sm->getCurrentStateName() );
01102     // remain in STATE2
01103     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01104     checkState( "x", tc);
01105     BOOST_CHECK_EQUAL( "STATE2", sm->getCurrentStateName() );
01106     // into FINI
01107     mo();
01108     BOOST_CHECK( SimulationThread::Instance()->run(1) ); // allow to transition
01109     checkState( "x", tc);
01110     BOOST_CHECK_EQUAL( "FINI", sm->getCurrentStateName() );
01111     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01112     checkState( "x", tc);
01113     BOOST_CHECK_EQUAL( "FINI", sm->getCurrentStateName() );
01114     this->checkState("x",tc);
01115     this->finishState("x", tc);
01116 }
01117 
01118 BOOST_AUTO_TEST_CASE( testStateOperationSignalTransitionPriority )
01119 {
01120     // test event reception transition priority
01121     string prog = string("StateMachine X {\n")
01122     + " initial state INIT {\n"
01123     + "    transitions { select STATE1 }\n"
01124     + " }\n"
01125     + " state STATE1 {\n"
01126     + "    var double d;\n"       
01127     + "    transition v_event() select STATE2\n" // test signal transition
01128     + "    transition v_event() select ERROR\n"   // This one should not be taken.
01129     + "    transition o_event(d) select ERROR\n"   // This one should not be taken.
01130     + "    transition v_event() select ERROR\n"   // This one should not be taken.
01131     + " }\n"
01132     + " state STATE2 {\n"
01133     + "    transition v_event() select FINI\n"   // test signal transition
01134     + "    transition v_event() select ERROR\n"   // This one should not be taken.
01135     + "    transition o_event(d) select ERROR\n"   // This one should not be taken.
01136     + "    transition v_event() select ERROR\n"   // This one should not be taken.
01137     + " }\n"
01138     + " state ERROR {} \n"
01139     + " final state FINI {} \n"
01140     + "}\n"
01141     + "RootMachine X x()\n";
01142     this->parseState( prog, tc );
01143     StateMachinePtr sm = sa->getStateMachine("x");
01144     BOOST_REQUIRE( sm );
01145     sm->trace(true);
01146     // into STATE1
01147     this->runState("x", tc);
01148     checkState( "x", tc);
01149     BOOST_CHECK_EQUAL( "STATE1", sm->getCurrentStateName() );
01150     // remain in STATE1
01151     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01152     checkState( "x", tc);
01153     BOOST_CHECK_EQUAL( "STATE1", sm->getCurrentStateName() );
01154     // into STATE2
01155     OperationCaller<void(void)> mo( tc->provides()->getOperation("v_event"), tc->engine());
01156     OperationCaller<void(double)> mo2( tc->provides()->getOperation("o_event"), tc->engine());
01157     BOOST_REQUIRE( mo.ready() );
01158     mo();
01159     mo();
01160     mo2(3);
01161     mo2(3);
01162     BOOST_CHECK( SimulationThread::Instance()->run(1) ); // allow to transition
01163     checkState( "x", tc);
01164     BOOST_CHECK_EQUAL( "STATE2", sm->getCurrentStateName() );
01165     // remain in STATE2
01166     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01167     checkState( "x", tc);
01168     BOOST_CHECK_EQUAL( "STATE2", sm->getCurrentStateName() );
01169     // into FINI
01170     mo();
01171     mo();
01172     mo2(3);
01173     mo2(3);
01174     BOOST_CHECK( SimulationThread::Instance()->run(1) ); // allow to transition
01175     checkState( "x", tc);
01176     BOOST_CHECK_EQUAL( "FINI", sm->getCurrentStateName() );
01177     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01178     checkState( "x", tc);
01179     BOOST_CHECK_EQUAL( "FINI", sm->getCurrentStateName() );
01180     this->checkState("x",tc);
01181     this->finishState("x", tc);
01182 }
01183 
01184 BOOST_AUTO_TEST_CASE( testStateOperationSignalTransitionAround )
01185 {
01186     // test event reception hopping from one state to another
01187     string prog = string("StateMachine X {\n")
01188     + " initial state INIT {\n"
01189     + "    transitions { select IDLE }\n"
01190     + " }\n"
01191     + " state IDLE {\n"
01192     + "    transition v1_event() select STATE1\n"
01193     + "    transition v2_event() select STATE2\n"
01194     + "    transition v3_event() select STATE3\n"
01195     + " }\n"
01196     + " state STATE1 {\n"
01197     + "    transition v_event()  select IDLE\n"
01198     + "    transition v2_event() select STATE2\n"
01199     + "    transition v3_event() select STATE3\n"
01200     + " }\n"
01201     + " state STATE2 {\n"
01202     + "    transition v_event()  select IDLE\n"
01203     + "    transition v1_event() select STATE1\n"
01204     + "    transition v3_event() select STATE3\n"
01205     + " }\n"
01206     + " state STATE3 {\n"
01207     + "    transition v_event()  select IDLE\n"
01208     + "    transition v1_event() select STATE1\n"
01209     + "    transition v2_event() select STATE2\n"
01210     + " }\n"
01211     + " final state FINI {} \n"
01212     + "}\n"
01213     + "RootMachine X x()\n";
01214     this->parseState( prog, tc );
01215     StateMachinePtr sm = sa->getStateMachine("x");
01216     BOOST_REQUIRE( sm );
01217     this->runState("x", tc);
01218     // into IDLE
01219     checkState( "x", tc);
01220     BOOST_CHECK_EQUAL( "IDLE", sm->getCurrentStateName() );
01221     BOOST_CHECK( SimulationThread::Instance()->run(100) );
01222     checkState( "x", tc);
01223     BOOST_CHECK_EQUAL( "IDLE", sm->getCurrentStateName() );
01224 
01225     OperationCaller<void(void)> v( tc->provides()->getOperation("v_event"), tc->engine());
01226     BOOST_REQUIRE( v.ready() );
01227     OperationCaller<void(void)> v1( tc->provides()->getOperation("v1_event"), tc->engine());
01228     BOOST_REQUIRE( v1.ready() );
01229     OperationCaller<void(void)> v2( tc->provides()->getOperation("v2_event"), tc->engine());
01230     BOOST_REQUIRE( v2.ready() );
01231     OperationCaller<void(void)> v3( tc->provides()->getOperation("v3_event"), tc->engine());
01232     BOOST_REQUIRE( v3.ready() );
01233 
01234 #define DO_EVENT(event, name)                               \
01235     event();                                                \
01236     BOOST_CHECK( SimulationThread::Instance()->run(1) );  \
01237     checkState( "x", tc);                                   \
01238     BOOST_CHECK_EQUAL( name, sm->getCurrentStateName() );   \
01239     BOOST_CHECK( SimulationThread::Instance()->run(100) );  \
01240     checkState( "x", tc);                                   \
01241     BOOST_CHECK_EQUAL( name, sm->getCurrentStateName() )
01242 
01243     DO_EVENT(v2, "STATE2");
01244     DO_EVENT(v1, "STATE1");
01245     DO_EVENT(v1, "STATE1");     // no change
01246     DO_EVENT(v3, "STATE3");
01247     DO_EVENT(v,  "IDLE");
01248     DO_EVENT(v3, "STATE3");
01249     DO_EVENT(v,  "IDLE");
01250     DO_EVENT(v1, "STATE1");
01251 
01252 #undef DO_EVENT
01253 
01254     this->checkState("x",tc);
01255     this->finishState("x", tc);
01256 }
01257 
01258 BOOST_AUTO_TEST_CASE( testStateOperationSignalTransitionProgram )
01259 {
01260     string prog = string("StateMachine X {\n")
01261         + " var   double et = 0.0\n"
01262         + " initial state INIT {\n"
01263         + "    transition o_event(et) { test.i = 5; } select FINI\n" // test program
01264         + " }\n"
01265         + " final state FINI {} \n"
01266         + "}\n"
01267         + "RootMachine X x()\n";
01268     this->parseState( prog, tc );
01269     StateMachinePtr sm = sa->getStateMachine("x");
01270     BOOST_REQUIRE( sm );
01271     //checkState( prog, tc);
01272     this->runState("x", tc);
01273     checkState( "x", tc);
01274     // transition to FINI:
01275     OperationCaller<void(double)> mo( tc->provides()->getOperation("o_event"), tc->engine());
01276     mo(3.33);
01277     mo(6.33); // should be ignored
01278     checkState( "x", tc);
01279     BOOST_CHECK( SimulationThread::Instance()->run(10) );
01280     BOOST_CHECK_EQUAL( i, 5 );
01281     checkState( "x", tc);
01282     BOOST_CHECK( sm->inState("FINI") );
01283     this->checkState("x",tc);
01284     this->finishState("x", tc);
01285 }
01286 
01287 BOOST_AUTO_TEST_CASE( testStateOperationSignalGuard )
01288 {
01289     string prog = string("StateMachine X {\n")
01290         + " var   double et = 0.0\n"
01291         + " initial state INIT {\n"
01292         + "    transition o_event(et) if (et == 3.33) then \n"
01293         + "        select FINI\n" // test guard
01294         + "        else select FAIL\n" // test guard
01295         + " }\n"
01296         + " final state FINI {} \n"
01297         + " state FAIL {} \n"
01298         + "}\n"
01299         + "RootMachine X x()\n";
01300     this->parseState( prog, tc );
01301     StateMachinePtr sm = sa->getStateMachine("x");
01302     BOOST_REQUIRE( sm );
01303     //checkState( prog, tc);
01304     this->runState("x", tc);
01305     checkState( "x", tc);
01306     // transition to FINI:
01307     OperationCaller<void(double)> mo( tc->provides()->getOperation("o_event") );
01308     mo(3.33);
01309     mo(6.33); // should be ignored
01310     checkState( "x", tc);
01311     BOOST_CHECK( SimulationThread::Instance()->run(10) );
01312     checkState( "x", tc);
01313     BOOST_CHECK( sm->inState("FINI") );
01314     this->checkState("x",tc);
01315     this->finishState("x", tc);
01316 }
01317 
01318 BOOST_AUTO_TEST_CASE( testStateOperationCallerSignalGuard )
01319 {
01320     string prog = string("StateMachine X {\n")
01321         + " var   double et = 0.0\n"
01322         + " initial state INIT {\n"
01323         + "    transition caller.c_event(et) if (et == 3.33) then\n"
01324         + "       select FINI\n"
01325         + "       else select FAIL\n" // test guard
01326         + " }\n"
01327         + " final state FINI {} \n"
01328         + " state FAIL {} \n"
01329         + "}\n"
01330         + "RootMachine X x()\n";
01331     this->parseState( prog, tc );
01332     StateMachinePtr sm = sa->getStateMachine("x");
01333     BOOST_REQUIRE( sm );
01334     //checkState( prog, tc);
01335     this->runState("x", tc);
01336     checkState( "x", tc);
01337     // causes error state when received in INIT:
01338     OperationCaller<void(double)> mo( caller->provides()->getOperation("c_event") );
01339     mo(3.33);
01340     checkState( "x", tc);
01341     BOOST_CHECK( SimulationThread::Instance()->run(1000) );
01342     checkState( "x", tc);
01343     BOOST_CHECK( sm->inState("FINI") );
01344     this->checkState("x",tc);
01345     this->finishState("x", tc);
01346 }
01347 #endif
01348 
01349 BOOST_AUTO_TEST_CASE( testStateEvents)
01350 {
01351     // test event reception in sub states.
01352     string prog = string("StateMachine Y {\n")
01353         + " var   int t = 0\n"
01354         + " var   double et = 0.0\n"
01355         + " var   bool eb = false\n"
01356         + " var   bool eflag = false\n"
01357         + " transition t_event(t) { do log(\"Global Transition to TESTSELF\");} select TESTSELF\n" // test self transition
01358         + " transition d_event(et)\n"
01359         + "     if et < 0. then { do log(\"Global ISNEGATIVE Transition\");} select ISNEGATIVE\n"
01360         + "     else { do log(\"Global ISPOSITIVE Transition\");} select ISPOSITIVE\n" // NewData == false !!!
01361         + " initial state INIT {\n"
01362         + "   entry { do log(\"INIT\"); set eb = false; }\n"
01363         + " }\n"
01364         + " state ISNEGATIVE {\n"
01365         + "   entry { do log(\"ISNEGATIVE\");}\n"
01366         + "   transition b_event(eb)\n"
01367         + "      if (eb) then { do log(\"Local ISNEGATIVE->INIT Transition\");} select INIT\n"
01368         + " }\n"
01369         + " state ISPOSITIVE {\n"
01370         + "   entry { do log(\"ISPOSITIVE\");}\n"
01371         + "   transition b_event(eb)\n" // 20
01372         + "      if (eb == true) then { do log(\"Local ISPOSITIVE->INIT Transition for b_event\");} select INIT\n"
01373 #ifdef ORO_SIGNALLING_OPERATIONS
01374         + "   transition o_event(et)\n"
01375         + "      if ( et == 3.0 ) then { do log(\"Local ISPOSITIVE->INIT Transition for o_event\");} select INIT\n"
01376 #endif
01377         + " }\n"
01378         + " state TESTSELF {\n"
01379         + "   entry {\n"
01380         + "      do log(\"TESTSELF\");\n"
01381         + "      set eflag = !eflag\n"
01382         + "   }\n"
01383         + "   transition t_event(t) { do log(\"Self Transition in TESTSELF\");} select TESTSELF\n"     // does not execute entry {}, overrides global t_event()
01384         + "   transition b_event(eb)\n"
01385         + "      if (eb == true) then { do log(\"Local TESTSELF->INIT Transition\");} select INIT\n"
01386         + "      else { log(\"Failed to select INIT upon event.\");}\n"
01387         + " }\n"
01388         + " final state FINI {\n"
01389         + "   entry { do log(\"FINI\");}\n"
01390         + " }\n"
01391         + " }\n" // 40
01392         + string("StateMachine X {\n") // 1
01393         + " SubMachine Y y1()\n"
01394         + " initial state INIT {\n"
01395         + " entry {\n"
01396         + "     do y1.trace(true)\n"
01397         + "     do y1.activate()\n"
01398         + "     do y1.start()\n"
01399         + "     do yield\n"
01400         + " }"
01401         + " run {\n"
01402 
01403         + "     do d_event_source.write(-1.0)\n"
01404         + "     do nothing\n"
01405         + "     do test.assert( !y1.inState(\"INIT\") )\n"
01406         + "     do test.assert( !y1.inState(\"ISPOSITIVE\") )\n"
01407         + "     do test.assert( y1.inState(\"ISNEGATIVE\") )\n"
01408         + "     do b_event_source.write( true )\n" // go to INIT.
01409         + "     do yield\n"
01410         + "     do test.assert( y1.inState(\"INIT\") )\n"
01411 
01412         + "     do d_event_source.write(+1.0)\n"
01413         + "     do nothing\n"
01414         + "     do test.assert( !y1.inState(\"INIT\") )\n"
01415         + "     do test.assert( y1.inState(\"ISPOSITIVE\") )\n"
01416         + "     do test.assert( !y1.inState(\"ISNEGATIVE\") )\n"
01417         + "     if ( !y1.inState(\"ISPOSITIVE\") ) then\n"
01418         + "          do test.assertMsg( false, \"Not ISNEGATIVE but \" + y1.getState() )\n"
01419         + "     do test.assert( y1.inState(\"ISPOSITIVE\") )\n"
01420         + "     do b_event_source.write( true )\n" // go to INIT.
01421         + "     do yield\n"
01422         + "     do test.assert( y1.inState(\"INIT\") )\n"
01423 #ifdef ORO_SIGNALLING_OPERATIONS
01424         // test operation
01425         + "     do d_event_source.write(+1.0)\n"
01426         + "     do nothing\n"
01427         + "     do test.assert( !y1.inState(\"INIT\") )\n"
01428         + "     do test.assert( y1.inState(\"ISPOSITIVE\") )\n"
01429         + "     do test.assert( !y1.inState(\"ISNEGATIVE\") )\n"
01430         + "     if ( !y1.inState(\"ISPOSITIVE\") ) then\n"
01431         + "          do test.assertMsg( false, \"Not ISPOSITIVE but \" + y1.getState() )\n"
01432         + "     do test.assert( y1.inState(\"ISPOSITIVE\") )\n"
01433         + "     do o_event( 3.0 )\n" // go to INIT.
01434         + "     do yield\n"
01435         + "     do test.assert( y1.inState(\"INIT\") )\n"
01436 #endif
01437         // test self transitions
01438         + "     set y1.eflag = true;\n"
01439         + "     do t_event_source.write(1)\n"
01440         + "     do nothing\n"
01441         + "     do test.assert( !y1.inState(\"INIT\") )\n"
01442         + "     do test.assert( !y1.inState(\"ISPOSITIVE\") )\n"
01443         + "     do test.assert( !y1.inState(\"ISNEGATIVE\") )\n"
01444         + "     do test.assert( y1.inState(\"TESTSELF\") )\n"
01445         + "     do test.assert( y1.eflag == false ) /* first */\n"
01446         + "     do t_event_source.write(1)\n"
01447         + "     do nothing\n"
01448         + "     do test.assert( y1.inState(\"TESTSELF\") )\n"
01449         + "     do test.assert( y1.eflag == false ) /* second */\n" // no entry
01450         + "     do log(\"Trigger b_event.\");\n"
01451         + "     do b_event_source.write(true);\n"
01452         + "     yield;\n"
01453         + "     do test.assert( y1.inState(\"INIT\") ) /* last */\n"
01454         + " }\n"
01455         + " transitions {\n"
01456         + "     select FINI\n"
01457         + " }\n"
01458         + " }\n"
01459         + " final state FINI {\n"
01460         + " entry {\n"
01461         + "     do y1.deactivate()\n"
01462         //+ "     do test.assert(false)\n"
01463         + " }\n"
01464         + " transitions {\n"
01465         + "     select INIT\n"
01466         + " }\n"
01467         + " }\n"
01468         + " }\n"
01469         + " RootMachine X x() \n" // instantiate a hierarchical SC
01470         ;
01471 
01472      this->doState("x", prog, tc );
01473      //BOOST_CHECK( tc->engine()->states()->getStateMachine( "x" )->inState("FINI") );
01474      this->finishState( "x", tc);
01475 }
01476 
01477 BOOST_AUTO_TEST_SUITE_END()
01478 
01479 void StateTest::doState(  const std::string& name, const std::string& prog, TaskContext* tc, bool test )
01480 {
01481     BOOST_CHECK( tc->engine() );
01482 
01483     parseState( prog, tc, test);
01484     runState(name, tc, test);
01485     checkState(name, tc, test);
01486 }
01487 
01488 void StateTest::parseState(const std::string& prog, TaskContext* tc, bool test )
01489 {
01490     // Alternative way: test ScriptingService as well.
01491     try {
01492         sa->loadStateMachines( prog, std::string("state_test.cpp"), true );
01493     }
01494     catch( const file_parse_exception& exc )
01495         {
01496             BOOST_REQUIRE_MESSAGE( !test, exc.what() );
01497         }
01498     catch( const parse_exception& exc )
01499         {
01500             BOOST_REQUIRE_MESSAGE( !test, exc.what() );
01501         }
01502     catch( const program_load_exception& e)
01503         {
01504             BOOST_REQUIRE_MESSAGE( !test, e.what() );
01505         }
01506     catch( const std::exception& e ) {
01507             BOOST_CHECK_MESSAGE( !test , e.what());
01508             BOOST_REQUIRE_MESSAGE( !test, "Uncaught Processor load exception" );
01509     }
01510 }
01511 
01512 void StateTest::runState(const std::string& name, TaskContext* tc, bool test )
01513 {
01514     StateMachinePtr sm = sa->getStateMachine(name);
01515     BOOST_REQUIRE( sm );
01516     sm->trace(true);
01517     OperationCaller<bool(StateMachine*)> act = tc->provides(name)->getOperation("activate");
01518     OperationCaller<bool(StateMachine*)> autom = tc->provides(name)->getOperation("automatic");
01519     BOOST_CHECK( act(sm.get()) );
01520     BOOST_CHECK( SimulationThread::Instance()->run(1) );
01521     BOOST_CHECK_MESSAGE( sm->isActive(), "Error : Activate Command for '"+sm->getName()+"' did not have effect." );
01522     BOOST_CHECK( autom(sm.get()) || !test  );
01523 
01524     BOOST_CHECK( SimulationThread::Instance()->run(1000) );
01525 }
01526 
01527 void StateTest::checkState(const std::string& name, TaskContext* tc, bool test )
01528 {
01529     StateMachinePtr sm = sa->getStateMachine(name);
01530     BOOST_REQUIRE( sm );
01531     if ( test ) {
01532         // check error status of parent :
01533         BOOST_CHECK_MESSAGE( sm->isActive(), "Error : State Context '"+sm->getName()+"' did not get activated." );
01534         stringstream errormsg;
01535         int line = sm->getLineNumber();
01536         errormsg <<" in StateMachine "+sm->getName()
01537                  <<" in state "<< (sm->currentState() ? sm->currentState()->getName() : "(null)")
01538                  <<" on line " << line <<" of that StateMachine:"<<endl;
01539         {
01540             stringstream sctext( sm->getText() );
01541             int cnt = 1;
01542             while ( cnt++ <line && sctext ) {
01543                 string garbage;
01544                 getline( sctext, garbage, '\n' );
01545             }
01546             getline( sctext, sline, '\n' );
01547         }
01548         errormsg <<"here  > " << sline << endl;
01549         if ( sm->inError() ) {
01550             RTT::scripting::DumpObject( tc->provides() );
01551             RTT::scripting::DumpObject( tc->provides(name) );
01552         }
01553         BOOST_CHECK_MESSAGE( sm->inError() == false, "Runtime error (inError() == true) encountered" + errormsg.str() );
01554         // check error status of all children:
01555         StateMachine::ChildList cl = sm->getChildren();
01556         StateMachine::ChildList::iterator clit = cl.begin();
01557         while( clit != cl.end() ) {
01558             line = (*clit)->getLineNumber();
01559             {
01560                 stringstream sctext( (*clit)->getText() );
01561                 int cnt = 1;
01562                 while ( cnt++ <line && sctext ) {
01563                     string garbage;
01564                     getline( sctext, garbage, '\n' );
01565                 }
01566                 getline( sctext, sline, '\n' );
01567             }
01568             stringstream cerrormsg;
01569             if ( (*clit)->currentState() )
01570                 cerrormsg <<" in child "<< (*clit)->getName() <<" in state "<<(*clit)->currentState()->getName()<< " on line " <<  (*clit)->getLineNumber() <<" of that StateMachine."<<endl <<"here  > " << sline << endl;
01571             else
01572                 cerrormsg <<" child "<< (*clit)->getName() << " (deactivated) on line " <<  (*clit)->getLineNumber() <<" of that StateMachine."<<endl<<"here  > " << sline << endl;
01573 
01574             BOOST_CHECK_MESSAGE( (*clit)->inError() == false, "Runtime error (inError() == true) encountered" + cerrormsg.str() );
01575             if ( (*clit)->inError() == false && sm->inError() == true) {
01576                 cout << "Child Status:" << cerrormsg.str() << endl;
01577             }
01578             ++clit;
01579         }
01580     }
01581 }
01582 
01583 void StateTest::finishState(std::string const& name, TaskContext* tc, bool test)
01584 {
01585     StateMachinePtr sm = sa->getStateMachine(name);
01586     BOOST_REQUIRE( sm );
01587     BOOST_CHECK( sa->getStateMachine( name )->stop() );
01588     BOOST_CHECK( SimulationThread::Instance()->run(500) );
01589     if (test) {
01590         stringstream errormsg;
01591         errormsg << " on line " << sm->getLineNumber() <<", status is "<< sa->getStateMachineStatusStr(name) <<endl <<"here  > " << sline << endl;;
01592         BOOST_CHECK_MESSAGE( sm->isStopped(), "StateMachine stalled " + errormsg.str() );
01593     }
01594     // you can call deactivate even when the proc is not running.
01595     // but deactivation may be 'in progress if exit state has commands in it.
01596     BOOST_CHECK( sa->getStateMachine( name )->deactivate() );
01597     BOOST_CHECK( SimulationThread::Instance()->run(200) );
01598     if ( sm->isActive() )
01599         BOOST_CHECK( sa->getStateMachine( name )->deactivate() );
01600     BOOST_CHECK( SimulationThread::Instance()->run(200) );
01601     BOOST_CHECK( sa->getStateMachine( name )->isActive() == false );
01602 
01603     // only stop now, since deactivate won't work if simtask not running.
01604     tc->stop();
01605 
01606     try {
01607         BOOST_CHECK( sa->unloadStateMachine( name ) );
01608     }
01609     catch( const program_unload_exception& e)
01610         {
01611             BOOST_REQUIRE_MESSAGE( false, e.what() );
01612         }
01613     catch( ... ) {
01614             BOOST_REQUIRE_MESSAGE( false, "Uncaught Processor unload exception" );
01615     }
01616 
01617 }
01618 


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:16:18