operation_test.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:54:57 CEST 2010  operation_test.cpp
00003 
00004                         operation_test.cpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
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 
00020 #include "unit.hpp"
00021 
00022 #include <rtt-fwd.hpp>
00023 #include <rtt/Operation.hpp>
00024 #include <rtt/Service.hpp>
00025 #include <rtt/OperationCaller.hpp>
00026 #include <rtt/TaskContext.hpp>
00027 
00028 using namespace std;
00029 using namespace RTT::detail;
00030 using namespace RTT;
00031 
00037 class OperationTest
00038 {
00039 public:
00040     OperationTest() : tc("TC"),
00041     op0r("op0r"), op0cr("op0cr"), op1r("op1r"), op1cr("op1cr"), op0("op0"), op1("op1"), op2("op2"), op3("op3"), op4("op4"), op5("op5"),
00042     opc0r("op0r"), opc0cr("op0cr"), opc1r("op1r"), opc1cr("op1cr"), opc0("op0"), opc1("op1"), opc2("op2"), opc3("op3"), opc4("op4"), opc5("op5")
00043     {
00044 
00045         tc.provides()->addOperation("op", &OperationTest::func, this);
00046         tc.provides()->addOperation("op0", &OperationTest::func0, this);
00047         tc.provides()->addOperation("op1", &OperationTest::func1, this);
00048         tc.provides()->addOperation("op2", &OperationTest::func2, this);
00049         tc.provides()->addOperation("op3", &OperationTest::func3, this);
00050         tc.provides()->addOperation("op4", &OperationTest::func4, this);
00051         tc.provides()->addOperation("op5", &OperationTest::func5, this);
00052         BOOST_CHECK( tc.provides()->getOperation("op0") );
00053         BOOST_CHECK( tc.provides()->getOperation("op1") );
00054         BOOST_CHECK( tc.provides()->getOperation("op2") );
00055         BOOST_CHECK( tc.provides()->getOperation("op3") );
00056         BOOST_CHECK( tc.provides()->getOperation("op4") );
00057         BOOST_CHECK( tc.provides()->getOperation("op5") );
00058 
00059         tc.provides()->addOperation("op0r", &OperationTest::func0r, this);
00060 
00061         tc.provides()->addOperation("op1r", &OperationTest::func1r, this);
00062         tc.provides()->addOperation("op1cr", &OperationTest::func1cr, this);
00063      }
00064 
00065     ~OperationTest() {
00066 
00067     }
00068     double ret;
00069     double& func0r(void) { return ret; }
00070     const double& func0cr(void) { return ret; }
00071 
00072     double func1r(double& a) { a = 2*a; return a; }
00073     double func1cr(const double& a) { return a; }
00074 
00075     // plain argument tests:
00076     void   func() { return; }
00077     double func0() { return 1.0; }
00078     double func1(int i) { return 2.0; }
00079     double func2(int i, double d) { return 3.0; }
00080     double func3(int i, double d, bool c) { return 4.0; }
00081     double func4(int i, double d, bool c, std::string s) { return 5.0; }
00082     double func5(int i, double d, bool c, std::string s, float f) { return 6.0; }
00083 
00084     // The return values of signals are intentionally distinct than these above.
00085     double sig0() { return sig=-1.0; }
00086     double sig1(int i) { return (sig=-2.0); }
00087     double sig2(int i, double d) { return sig=-3.0; }
00088     double sig3(int i, double d, bool c) { return (sig=-4.0); }
00089     double sig4(int i, double d, bool c, std::string s) { return sig=-5.0; }
00090     double sig5(int i, double d, bool c, std::string s, float f) { return sig=-6.0; }
00091 
00092     static double freefunc0(void) { return 1.0; }
00093     static double freefunc1(int i) { return 2.0; }
00094 
00095     TaskContext tc;
00096 
00097     // check value for signals
00098     double sig;
00099 
00100     Operation<double&(void)> op0r;
00101     Operation<const double&(void)> op0cr;
00102     Operation<double(double&)> op1r;
00103     Operation<double&(const double&)> op1cr;
00104     Operation<double(void)> op0;
00105     Operation<double(int)> op1;
00106     Operation<double(int,double)> op2;
00107     Operation<double(int,double,bool)> op3;
00108     Operation<double(int,double,bool, std::string)> op4;
00109     Operation<double(int,double,bool, std::string, float)> op5;
00110 
00111     OperationCaller<double&(void)> opc0r;
00112     OperationCaller<const double&(void)> opc0cr;
00113     OperationCaller<double(double&)> opc1r;
00114     OperationCaller<double&(const double&)> opc1cr;
00115     OperationCaller<double(void)> opc0;
00116     OperationCaller<double(int)> opc1;
00117     OperationCaller<double(int,double)> opc2;
00118     OperationCaller<double(int,double,bool)> opc3;
00119     OperationCaller<double(int,double,bool, std::string)> opc4;
00120     OperationCaller<double(int,double,bool, std::string, float)> opc5;
00121 };
00122 
00123 // Registers the fixture into the 'registry'
00124 BOOST_FIXTURE_TEST_SUITE(  OperationTestSuite,  OperationTest )
00125 
00126 // Test default properties of an operation.
00127 BOOST_AUTO_TEST_CASE( testOperationCreate )
00128 {
00129     // name
00130     BOOST_CHECK( op0.getName() == "op0" );
00131     // not in interface, not ready.
00132     BOOST_CHECK( op0.ready() == false);
00133 
00134 }
00135 
00136 // Test adding and calling an operation (internal API)
00137 BOOST_AUTO_TEST_CASE( testOperationCall )
00138 {
00139     Service::shared_ptr s =  boost::make_shared<Service>("Service");
00140 
00141     tc.provides()->addService( s );
00142 
00143     op0.calls( &OperationTest::func0, this);
00144     op1.calls( &OperationTest::func1, this);
00145     op2.calls( &OperationTest::func2, this);
00146     op3.calls( &OperationTest::func3, this);
00147     op4.calls( &OperationTest::func4, this);
00148     op5.calls( &OperationTest::func5, this);
00149 
00150     s->addOperation( op0 );
00151     s->addOperation( op1 );
00152     s->addOperation( op2 );
00153     s->addOperation( op3 );
00154     s->addOperation( op4 );
00155     s->addOperation( op5 );
00156 
00157     // Test calling an operation using a OperationCaller.
00158     OperationCaller<double(void)> m0("op0");
00159     BOOST_CHECK( m0.ready() == false );
00160     m0 = op0.getImplementation();
00161     BOOST_CHECK( m0.ready() );
00162     BOOST_CHECK_EQUAL( 1.0, m0.call() );
00163 }
00164 
00165 // Test calling an operation (user API)
00166 BOOST_AUTO_TEST_CASE( testOperationCall2 )
00167 {
00168     Service::shared_ptr s =  boost::make_shared<Service>("Service");
00169 
00170     tc.provides()->addService( s );
00171 
00172     s->addOperation("op0", &OperationTest::func0, this);
00173     s->addOperation("op1", &OperationTest::func1, this);
00174     s->addOperation("op2", &OperationTest::func2, this);
00175     s->addOperation("op3", &OperationTest::func3, this);
00176     s->addOperation("op4", &OperationTest::func4, this);
00177     s->addOperation("op5", &OperationTest::func5, this);
00178 
00179     // Test calling an operation using a OperationCaller.
00180     OperationCaller<double(void)> m0("op0");
00181     BOOST_CHECK( m0.ready() == false );
00182     m0 = s->getOperation("op0");
00183     BOOST_CHECK( m0.ready() );
00184     BOOST_CHECK_EQUAL( 1.0, m0.call() );
00185 }
00186 
00187 // Test adding a C++ function to the services.
00188 BOOST_AUTO_TEST_CASE( testOperationAddCpp )
00189 {
00190     // Add to custom service:
00191     Service::shared_ptr s =  boost::make_shared<Service>("Service");
00192     tc.provides()->addService( s );
00193     s->addOperation("top0", &OperationTest::func0, this);
00194     s->addOperation("top1", &OperationTest::func1, this);
00195     BOOST_CHECK( s->getOperation("top0") );
00196     BOOST_CHECK( s->getOperation("top1") );
00197     opc0 = s->getOperation("top0");
00198     opc1 = s->getOperation("top1");
00199     BOOST_CHECK( opc0.ready() );
00200     BOOST_CHECK( opc1.ready() );
00201     BOOST_CHECK_EQUAL(opc0(), 1.0);
00202     BOOST_CHECK_EQUAL(opc1(1), 2.0);
00203 
00204     // Add to default service:
00205     tc.addOperation("tcop0", &OperationTest::func0, this);
00206     tc.addOperation("tcop1", &OperationTest::func1, this);
00207     BOOST_CHECK( tc.provides()->getOperation("tcop0") );
00208     BOOST_CHECK( tc.provides()->getOperation("tcop1") );
00209     opc0 = tc.provides()->getOperation("tcop0");
00210     opc1 = tc.provides()->getOperation("tcop1");
00211     BOOST_CHECK( opc0.ready() );
00212     BOOST_CHECK( opc1.ready() );
00213     BOOST_CHECK_EQUAL(opc0(), 1.0);
00214     BOOST_CHECK_EQUAL(opc1(1), 2.0);
00215 
00216     // Override existing ops:
00217     // note: we add different signature with same name to check if new op was used
00218     tc.addOperation("tcop0", &OperationTest::func1, this);
00219     tc.addOperation("tcop1", &OperationTest::func2, this);
00220     BOOST_CHECK( tc.provides()->getOperation("tcop0") );
00221     BOOST_CHECK( tc.provides()->getOperation("tcop1") );
00222     opc1 = tc.provides()->getOperation("tcop0");
00223     opc2 = tc.provides()->getOperation("tcop1");
00224     BOOST_CHECK( opc1.ready() );
00225     BOOST_CHECK( opc2.ready() );
00226     BOOST_CHECK_EQUAL(opc1(1), 2.0);
00227     BOOST_CHECK_EQUAL(opc2(1,2.0), 3.0);
00228 }
00229 
00230 // Test adding a C function to the services.
00231 BOOST_AUTO_TEST_CASE( testOperationAddC )
00232 {
00233     // Using custom Service
00234     Service::shared_ptr s =  boost::make_shared<Service>("Service");
00235     tc.provides()->addService( s );
00236     s->addOperation("top0", &OperationTest::freefunc0);
00237     s->addOperation("top1", &OperationTest::freefunc1);
00238     BOOST_CHECK( s->getOperation("top0") );
00239     BOOST_CHECK( s->getOperation("top1") );
00240     opc0 = s->getOperation("top0");
00241     opc1 = s->getOperation("top1");
00242     BOOST_CHECK( opc0.ready() );
00243     BOOST_CHECK( opc1.ready() );
00244     BOOST_CHECK_EQUAL(opc0(), 1.0);
00245     BOOST_CHECK_EQUAL(opc1(1), 2.0);
00246 
00247     // Using TaskContext API
00248     tc.addOperation("top0", &OperationTest::freefunc0);
00249     tc.addOperation("top1", &OperationTest::freefunc1);
00250     BOOST_CHECK( tc.getOperation("top0") );
00251     BOOST_CHECK( tc.getOperation("top1") );
00252     opc0 = tc.getOperation("top0");
00253     opc1 = tc.getOperation("top1");
00254     BOOST_CHECK( opc0.ready() );
00255     BOOST_CHECK( opc1.ready() );
00256     BOOST_CHECK_EQUAL(opc0(), 1.0);
00257     BOOST_CHECK_EQUAL(opc1(1), 2.0);
00258 }
00259 
00260 // Test calling an operation of the default service.
00261 BOOST_AUTO_TEST_CASE( testOperationCall0 )
00262 {
00263     // Test calling an operation using a OperationCaller.
00264     OperationCaller<double(void)> m0("op0");
00265     BOOST_CHECK( m0.ready() == false );
00266     m0 = tc.getOperation("op0");
00267     BOOST_CHECK( m0.ready() );
00268     BOOST_CHECK_EQUAL( 1.0, m0.call() );
00269 }
00270 
00271 #ifdef ORO_SIGNALLING_OPERATIONS
00272 // Test adding and signalling an operation without an implementation
00273 BOOST_AUTO_TEST_CASE( testOperationSignal )
00274 {
00275     // invoke sig0 according to call/thread specification.
00276     Handle h = op0.signals(&OperationTest::sig0, this);
00277 
00278     BOOST_CHECK( h.connected() );
00279     // Test signal when calling a method:
00280     OperationCaller<double(void)> m0("op0");
00281     BOOST_CHECK( m0.ready() == false );
00282     m0 = op0.getImplementation();
00283     BOOST_CHECK( m0.ready() );
00284 
00285     try {
00286         m0.call(); // return unspecified number (no implementation!).
00287     } catch (SendStatus sf) {
00288         BOOST_FAIL("Should not throw a SendFailure!");
00289     }
00290 
00291     BOOST_CHECK_EQUAL( -1.0, sig );
00292 
00293     // Test direct calling of op.signal
00294     sig = 0.0;
00295     op0.signal->emit();
00296     BOOST_CHECK_EQUAL( -1.0, sig );
00297 }
00298 
00299 BOOST_AUTO_TEST_CASE( testOperationCallAndSignal )
00300 {
00301     // invoke sig0 according to call/thread specification.
00302     Handle h = op0.signals(&OperationTest::sig0, this);
00303     op0.calls(&OperationTest::func0, this);
00304 
00305     BOOST_CHECK( h.connected() );
00306     // Test signal when calling a method:
00307     OperationCaller<double(void)> m0("op0");
00308     BOOST_CHECK( m0.ready() == false );
00309     m0 = op0.getImplementation();
00310     BOOST_CHECK( m0.ready() );
00311 
00312     BOOST_CHECK_EQUAL( 1.0, m0.call() ); // return result of func0().
00313 
00314     BOOST_CHECK_EQUAL( -1.0, sig );
00315 
00316     // Test direct calling of op.signal
00317     sig = 0.0;
00318     op0.signal->emit();
00319     BOOST_CHECK_EQUAL( -1.0, sig );
00320 }
00321 #endif
00322 BOOST_AUTO_TEST_SUITE_END()
00323 


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