$search
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:54:57 CEST 2010 remote_method_test.cpp 00003 00004 remote_method_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 00021 #define ORO_TEST_OPERATION_CALLER 00022 00023 #include <iostream> 00024 #include <TaskContext.hpp> 00025 #include <OperationCaller.hpp> 00026 #include <Operation.hpp> 00027 #include <internal/RemoteOperationCaller.hpp> 00028 #include <Service.hpp> 00029 00030 #include "unit.hpp" 00031 #include "operations_fixture.hpp" 00032 00037 BOOST_FIXTURE_TEST_SUITE( RemoteOperationCallerTestSuite, OperationsFixture ) 00038 00039 BOOST_AUTO_TEST_CASE(testRemoteOperationCaller) 00040 { 00041 OperationCaller<double(void)> m0("mo"); 00042 boost::shared_ptr<DisposableInterface> implementation( new RemoteOperationCaller<double(void)>(tc->provides("methods")->getPart("m0"),"m0", caller->engine() ) ); 00043 m0 = implementation; 00044 BOOST_CHECK( m0.ready() ); 00045 00046 OperationCaller<double(int)> m1; 00047 implementation.reset( new RemoteOperationCaller<double(int)>(tc->provides("methods")->getPart("m1"),"m1", caller->engine()) ); 00048 m1 = implementation; 00049 BOOST_CHECK( m1.ready() ); 00050 00051 OperationCaller<void(void)> m0e; 00052 implementation.reset( new RemoteOperationCaller<void(void)>(tc->provides("methods")->getPart("m0except"),"m0except", caller->engine()) ); 00053 m0e = implementation; 00054 BOOST_CHECK( m0e.ready() ); 00055 00056 BOOST_CHECK_EQUAL( 2.0, m1(0) ); 00057 BOOST_CHECK_EQUAL( -2.0, m1(1) ); 00058 BOOST_CHECK_EQUAL( -1.0, m0() ); 00059 BOOST_CHECK_THROW( m0e(), std::runtime_error); 00060 BOOST_REQUIRE( tc->inException() ); 00061 } 00062 00063 BOOST_AUTO_TEST_CASE(testOperationCallerC_Call) 00064 { 00065 OperationCallerC mc; 00066 double r = 0.0; 00067 mc = tc->provides("methods")->create("m0", caller->engine()).ret( r ); 00068 BOOST_CHECK( mc.call() ); 00069 BOOST_CHECK_EQUAL( r, -1.0 ); 00070 00071 mc = tc->provides("methods")->create("m2", caller->engine()).argC(1).argC(2.0).ret( r ); 00072 BOOST_CHECK( mc.call() ); 00073 BOOST_CHECK_EQUAL( r, -3.0 ); 00074 00075 mc = tc->provides("methods")->create("m3", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true); 00076 BOOST_CHECK( mc.call() ); 00077 BOOST_CHECK( r == -4.0 ); 00078 00079 mc = tc->provides("methods")->create("m4", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")); 00080 BOOST_CHECK( mc.call() ); 00081 BOOST_CHECK( r == -5.0 ); 00082 00083 mc = tc->provides("methods")->create("m5", caller->engine()).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f).ret( r ); 00084 BOOST_CHECK( mc.call() ); 00085 BOOST_CHECK( r == -6.0 ); 00086 00087 mc = tc->provides("methods")->create("m6", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f).argC('a'); 00088 BOOST_CHECK( mc.call() ); 00089 BOOST_CHECK( r == -7.0 ); 00090 00091 mc = tc->provides("methods")->create("m7", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f).argC('a').argC((unsigned int)7); 00092 BOOST_CHECK( mc.call() ); 00093 BOOST_CHECK( r == -8.0 ); 00094 00095 mc = tc->provides("methods")->create("m0except", caller->engine()); 00096 BOOST_CHECK_THROW( mc.call(), std::runtime_error); 00097 00098 mc = tc->provides("methods")->create("o0except", caller->engine()); 00099 BOOST_CHECK_THROW( mc.call(), std::runtime_error); 00100 BOOST_REQUIRE( tc->inException() ); 00101 } 00102 00103 BOOST_AUTO_TEST_CASE(testOperationCallerC_Send) 00104 { 00105 OperationCallerC mc; 00106 SendHandleC shc; 00107 double r = 0.0; 00108 double cr = 0.0; 00109 mc = tc->provides("methods")->create("m0", caller->engine()).ret( r ); 00110 BOOST_CHECK_NO_THROW( mc.check() ); 00111 shc = mc.send(); 00112 shc.arg(cr); 00113 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00114 BOOST_CHECK_NO_THROW( shc.check() ); 00115 // now collect: 00116 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00117 BOOST_CHECK_EQUAL( r, 0.0 ); 00118 BOOST_CHECK_EQUAL( cr, -1.0 ); 00119 00120 mc = tc->provides("methods")->create("m2", caller->engine()).argC(1).argC(2.0).ret( r ); 00121 BOOST_CHECK_NO_THROW( mc.check() ); 00122 shc = mc.send(); 00123 shc.arg(cr); 00124 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00125 BOOST_CHECK_NO_THROW( shc.check() ); 00126 // now collect: 00127 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00128 BOOST_CHECK_EQUAL( r, 0.0 ); 00129 BOOST_CHECK_EQUAL( cr, -3.0 ); 00130 00131 mc = tc->provides("methods")->create("m3", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true); 00132 BOOST_CHECK_NO_THROW( mc.check() ); 00133 shc = mc.send(); 00134 shc.arg(cr); 00135 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00136 BOOST_CHECK_NO_THROW( shc.check() ); 00137 // now collect: 00138 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00139 BOOST_CHECK_EQUAL( r, 0.0 ); 00140 BOOST_CHECK_EQUAL( cr, -4.0 ); 00141 00142 mc = tc->provides("methods")->create("m4", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")); 00143 BOOST_CHECK_NO_THROW( mc.check() ); 00144 shc = mc.send(); 00145 shc.arg(cr); 00146 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00147 BOOST_CHECK_NO_THROW( shc.check() ); 00148 // now collect: 00149 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00150 BOOST_CHECK_EQUAL( r, 0.0 ); 00151 BOOST_CHECK_EQUAL( cr, -5.0 ); 00152 00153 mc = tc->provides("methods")->create("m5", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f); 00154 BOOST_CHECK_NO_THROW( mc.check() ); 00155 shc = mc.send(); 00156 shc.arg(cr); 00157 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00158 BOOST_CHECK_NO_THROW( shc.check() ); 00159 // now collect: 00160 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00161 BOOST_CHECK_EQUAL( r, 0.0 ); 00162 BOOST_CHECK_EQUAL( cr, -6.0 ); 00163 00164 mc = tc->provides("methods")->create("m6", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f).argC('a'); 00165 BOOST_CHECK_NO_THROW( mc.check() ); 00166 shc = mc.send(); 00167 shc.arg(cr); 00168 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00169 BOOST_CHECK_NO_THROW( shc.check() ); 00170 // now collect: 00171 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00172 BOOST_CHECK_EQUAL( r, 0.0 ); 00173 BOOST_CHECK_EQUAL( cr, -7.0 ); 00174 00175 mc = tc->provides("methods")->create("m7", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello")).argC(5.0f).argC('a').argC((unsigned int)7); 00176 BOOST_CHECK_NO_THROW( mc.check() ); 00177 shc = mc.send(); 00178 shc.arg(cr); 00179 BOOST_CHECK( shc.ready() ); // 1 argument to collect. 00180 BOOST_CHECK_NO_THROW( shc.check() ); 00181 // now collect: 00182 BOOST_CHECK_EQUAL( shc.collect(), SendSuccess); 00183 BOOST_CHECK_EQUAL( r, 0.0 ); 00184 BOOST_CHECK_EQUAL( cr, -8.0 ); 00185 00186 mc = tc->provides("methods")->create("m0except", caller->engine()); 00187 BOOST_CHECK_NO_THROW( mc.check() ); 00188 shc = mc.send(); 00189 BOOST_CHECK( shc.ready() ); 00190 BOOST_CHECK_NO_THROW( shc.check() ); 00191 // now collect: 00192 BOOST_CHECK_THROW( shc.collect(), std::runtime_error ); 00193 BOOST_REQUIRE(tc->inException() ); 00194 } 00195 00196 BOOST_AUTO_TEST_CASE(testOperationCallerFromDS) 00197 { 00198 ServicePtr sp = tc->provides("methods"); 00199 00200 double ret; 00201 OperationCallerC mc0 = sp->create("m0", caller->engine() ); 00202 mc0.ret(ret); 00203 OperationCallerC mc1 = sp->create("m1", caller->engine() ); 00204 mc1.argC(1).ret(ret); 00205 OperationCallerC mc2 = sp->create("m2", caller->engine() ); 00206 mc2.argC(1).argC(2.0).ret(ret); 00207 OperationCallerC mc3 = sp->create("m3", caller->engine() ); 00208 mc3.argC(1).argC(2.0).argC(true).ret(ret); 00209 OperationCallerC mc4 = sp->create("m4", caller->engine() ); 00210 mc4.argC(1).argC(2.0).argC(true).argC(std::string("hello")).ret(ret); 00211 OperationCallerC mc5 = sp->create("m5", caller->engine() ); 00212 mc5.argC(1).argC(2.0).argC(true).argC(std::string("hello")).argC(5.0f).ret(ret); 00213 OperationCallerC mc6 = sp->create("m6", caller->engine() ); 00214 mc6.argC(1).argC(2.0).argC(true).argC(std::string("hello")).argC(5.0f).argC('a').ret(ret); 00215 OperationCallerC mc7 = sp->create("m7", caller->engine() ); 00216 mc7.argC(1).argC(2.0).argC(true).argC(std::string("hello")).argC(5.0f).argC('a').argC((unsigned int)7).ret(ret); 00217 00218 OperationCallerC mc0e = sp->create("m0except", caller->engine() ); 00219 00220 BOOST_CHECK( mc0.call() ); 00221 BOOST_CHECK_EQUAL(-1.0, ret); 00222 BOOST_CHECK( mc1.call() ); 00223 BOOST_CHECK_EQUAL(-2.0, ret); 00224 BOOST_CHECK( mc2.call() ); 00225 BOOST_CHECK_EQUAL(-3.0, ret); 00226 BOOST_CHECK( mc3.call() ); 00227 BOOST_CHECK_EQUAL(-4.0, ret); 00228 BOOST_CHECK( mc4.call() ); 00229 BOOST_CHECK_EQUAL(-5.0, ret); 00230 BOOST_CHECK( mc5.call() ); 00231 BOOST_CHECK_EQUAL(-6.0, ret); 00232 BOOST_CHECK( mc6.call() ); 00233 BOOST_CHECK_EQUAL(-7.0, ret); 00234 BOOST_CHECK( mc7.call() ); 00235 BOOST_CHECK_EQUAL(-8.0, ret); 00236 00237 BOOST_CHECK_THROW( mc0e.call(), std::runtime_error ); 00238 BOOST_REQUIRE(tc->inException() ); 00239 } 00240 00241 BOOST_AUTO_TEST_CASE(testRemoteOperationCallerFactory) 00242 { 00243 // Test the addition of methods to the operation interface, 00244 // and retrieving it back in a new OperationCaller object. 00245 // these operations may use the remoting facility to adapt 00246 00247 Operation<double(void)> m0("m0"); 00248 m0.calls(&OperationsFixture::m0, this); 00249 Operation<double(int)> m1("m1"); 00250 m1.calls(&OperationsFixture::m1, this); 00251 Operation<double(int,double)> m2("m2"); 00252 m2.calls(&OperationsFixture::m2, this); 00253 Operation<void(void)> m0e("m0e"); 00254 m0e.calls(&OperationsFixture::m0except, this); 00255 00256 Service to("task"); 00257 00258 BOOST_CHECK( !to.addOperation(m0).ready() ); 00259 to.setOwner(tc); 00260 BOOST_CHECK( to.addOperation(m0).ready() ); 00261 BOOST_CHECK( to.addOperation(m0).ready() ); 00262 BOOST_CHECK( to.addOperation(m1).ready() ); 00263 BOOST_CHECK( to.addOperation(m2).ready() ); 00264 BOOST_CHECK( to.addOperation(m0e).ready() ); 00265 00266 // test constructor 00267 OperationCaller<double(void)> mm0 = to.getOperation("m0"); 00268 BOOST_CHECK( mm0.getOperationCallerImpl() ); 00269 BOOST_CHECK( mm0.ready() ); 00270 00271 OperationCaller<void(void)> mm0e = to.getOperation("m0e"); 00272 BOOST_CHECK( mm0e.getOperationCallerImpl() ); 00273 BOOST_CHECK( mm0e.ready() ); 00274 00275 // test operator=() 00276 OperationCaller<double(int)> mm1; 00277 mm1 = to.getOperation("m1"); 00278 BOOST_CHECK( mm1.getOperationCallerImpl() ); 00279 BOOST_CHECK( mm1.ready() ); 00280 00281 OperationCaller<double(int,double)> mm2 = to.getOperation("m2"); 00282 BOOST_CHECK( mm2.getOperationCallerImpl() ); 00283 BOOST_CHECK( mm2.ready() ); 00284 00285 // execute methods and check status: 00286 BOOST_CHECK_EQUAL( -1.0, mm0() ); 00287 00288 BOOST_CHECK_EQUAL( -2.0, mm1(1) ); 00289 BOOST_CHECK_EQUAL( -3.0, mm2(1, 2.0) ); 00290 00291 BOOST_CHECK_THROW( mm0e(), std::runtime_error ); 00292 00293 // Add uninitialised op: 00294 Operation<void(void)> ovoid("ovoid"); 00295 BOOST_CHECK(to.addOperation( ovoid ).ready() == true); 00296 ovoid = Operation<void(void)>("ovoid"); 00297 BOOST_CHECK(to.addOperation( ovoid ).ready() == true); 00298 00299 // wrong type 1: 00300 OperationCaller<void(void)> mvoid; 00301 mvoid = to.getOperation("m1"); 00302 BOOST_CHECK( mvoid.ready() == false ); 00303 // wrong type 2: 00304 mvoid = to.getOperation("m2"); 00305 BOOST_CHECK( mvoid.ready() == false ); 00306 // auto-converts double to void: 00307 mvoid = to.getOperation("m0"); 00308 BOOST_CHECK( mvoid.ready() == true ); 00309 // non existing 00310 mvoid = to.getOperation("voidm"); 00311 BOOST_CHECK( mvoid.ready() == false ); 00312 00313 // this line may not crash: 00314 mvoid(); 00315 00316 } 00317 00318 BOOST_AUTO_TEST_SUITE_END()