corba_test.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon Jun 26 13:26:02 CEST 2006 generictask_test.cpp
3 
4  generictask_test.cpp - description
5  -------------------
6  begin : Mon June 26 2006
7  copyright : (C) 2006 Peter Soetens
8  email : peter.soetens@fmtc.be
9 
10  ***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 
20 
21 #include "unit.hpp"
22 
23 #include <transports/corba/corba.h>
24 #include <rtt/InputPort.hpp>
25 #include <rtt/OutputPort.hpp>
26 #include <rtt/OperationCaller.hpp>
27 #include <rtt/TaskContext.hpp>
30 #include <rtt/Service.hpp>
33 #include <transports/corba/ServiceC.h>
37 
38 #include "operations_fixture.hpp"
39 
40 #include <memory>
41 
42 using namespace std;
44 
45 class CorbaTest : public OperationsFixture
46 {
47 public:
49  pint1("pint1", "", 3), pdouble1(new Property<double>("pdouble1", "", -3.0)),
50  aint1(3), adouble1(-3.0)
51  {
52  // check operations (moved from OperationCallerComponent constructor for reuseability in corba-ipc-server)
53  BOOST_REQUIRE( caller->ready() );
54 
55  // connect DataPorts
56  mi1 = new InputPort<double> ("mi");
57  mo1 = new OutputPort<double> ("mo");
58 
59  mi2 = new InputPort<double> ("mi");
60  mo2 = new OutputPort<double> ("mo");
61 
62  tc->ports()->addEventPort(*mi1);
63  tc->ports()->addPort(*mo1);
64  tc->start();
65 
66  t2 = new TaskContext("local");
67  t2->ports()->addEventPort(*mi2,boost::bind(&CorbaTest::new_data_listener, this, _1));
68  t2->ports()->addPort(*mo2);
69 
70  ts2 = ts = 0;
71  tp2 = tp = 0;
72 
73  // store nested properties:
74  tc->provides()->addProperty(pint1);
75  storeProperty(*tc->provides()->properties(), "s1.s2", pdouble1 );
76 
77  tc->addAttribute("aint1", aint1);
78  tc->addAttribute("adouble1", adouble1);
79  }
81  {
82  delete tp;
83  delete ts;
84  delete tp2;
85  delete ts2;
86  delete t2;
87 
88  delete mi1;
89  delete mo1;
90  delete mi2;
91  delete mo2;
92  }
93 
94  TaskContext* t2;
97  TaskContext* tp2;
99 
100  base::PortInterface* signalled_port;
101  void new_data_listener(base::PortInterface* port);
102 
103  // Ports
108 
111 
112  int aint1;
113  double adouble1;
114 
115  // helper test functions
116  void testPortDataConnection();
117  void testPortBufferConnection();
118  void testPortDisconnected();
119 };
120 
122 {
123  signalled_port = port;
124 }
125 
126 
127 #define ASSERT_PORT_SIGNALLING(code, read_port) do { \
128  signalled_port = 0; \
129  int wait = 0; \
130  code; \
131  while (read_port != signalled_port && wait++ != 5) \
132  usleep(100000); \
133  BOOST_CHECK( read_port == signalled_port ); \
134 } while(0)
135 
136 #define wait_for( cond, times ) do { \
137  bool wait_for_helper; \
138  int wait = 0; \
139  while( (wait_for_helper = !(cond)) && wait++ != times ) \
140  usleep(100000); \
141  if (wait_for_helper) BOOST_CHECK( cond ); \
142 } while(0)
143 
144 #define wait_for_equal( a, b, times ) do { \
145  bool wait_for_helper; \
146  int wait = 0; \
147  while( (wait_for_helper = ((a) != (b))) && wait++ != times ) \
148  usleep(100000); \
149  if (wait_for_helper) BOOST_CHECK_EQUAL( a, b ); \
150 } while(0)
151 
153 {
154  // This test assumes that there is a data connection mo1 => mi2
155  // Check if connection succeeded both ways:
156  BOOST_CHECK( mo1->connected() );
157  BOOST_CHECK( mi2->connected() );
158 
159  double value = 0;
160 
161  // Check if no-data works
162  BOOST_CHECK_EQUAL( mi2->read(value), NoData );
163 
164  // Check if writing works (including signalling)
165  ASSERT_PORT_SIGNALLING(mo1->write(1.0), mi2);
166  BOOST_CHECK( mi2->read(value) );
167  BOOST_CHECK_EQUAL( 1.0, value );
168  ASSERT_PORT_SIGNALLING(mo1->write(2.0), mi2);
169  BOOST_CHECK( mi2->read(value) );
170  BOOST_CHECK_EQUAL( 2.0, value );
171 }
172 
174 {
175  // This test assumes that there is a buffer connection mo1 => mi2 of size 3
176  // Check if connection succeeded both ways:
177  BOOST_CHECK( mo1->connected() );
178  BOOST_CHECK( mi2->connected() );
179 
180  double value = 0;
181 
182  // Check if no-data works
183  BOOST_CHECK_EQUAL( mi2->read(value), NoData );
184 
185  // Check if writing works
186  ASSERT_PORT_SIGNALLING(mo1->write(1.0), mi2);
187  ASSERT_PORT_SIGNALLING(mo1->write(2.0), mi2);
188  ASSERT_PORT_SIGNALLING(mo1->write(3.0), mi2);
189  BOOST_CHECK( mi2->read(value) );
190  BOOST_CHECK_EQUAL( 1.0, value );
191  BOOST_CHECK( mi2->read(value) );
192  BOOST_CHECK_EQUAL( 2.0, value );
193  BOOST_CHECK( mi2->read(value) );
194  BOOST_CHECK_EQUAL( 3.0, value );
195  BOOST_CHECK_EQUAL( mi2->read(value), OldData );
196 }
197 
199 {
200  BOOST_CHECK( !mo1->connected() );
201  BOOST_CHECK( !mi2->connected() );
202 }
203 
204 template <typename T>
205 static void testCorbaType(const T &value = T()) {
206  CORBA::Any any;
207  T copy = T();
208 
209  BOOST_TEST_CHECKPOINT("Testing CORBA conversion for type " << typeid(T).name());
210  BOOST_CHECK( RTT::corba::AnyConversion<T>::updateAny(value, any) );
211  BOOST_CHECK( RTT::corba::AnyConversion<T>::update(any, copy) );
212  BOOST_CHECK_EQUAL( copy, value );
213 }
214 
215 template <typename T>
216 static void testCorbaTypeSequence(std::size_t size = 3, const T &value = T())
217 {
218  CORBA::Any any;
219 
220  BOOST_TEST_CHECKPOINT("Testing CORBA conversion for a vector with elements of type " << typeid(T).name());
221  std::vector<T> vec(size, value);
222  BOOST_CHECK( RTT::corba::AnyConversion< std::vector<T> >::updateAny(vec, any) );
223  BOOST_CHECK( RTT::corba::AnyConversion< std::vector<T> >::update(any, vec) );
224 }
225 
226 namespace RTT {
227  static bool operator==(const ConnPolicy &, const ConnPolicy &) { return true; }
228 }
229 
230 BOOST_AUTO_TEST_CASE( testCorbaTypes )
231 {
232  testCorbaType<double>(1.0);
233  testCorbaTypeSequence<double>(3, 1.0);
234  testCorbaType<float>(2.0);
235  testCorbaTypeSequence<float>(3, 2.0);
236  testCorbaType<int>(-3);
237  testCorbaTypeSequence<int>(3, -3);
238  testCorbaType<unsigned int>(4);
239  testCorbaTypeSequence<unsigned int>(3, 4);
240  testCorbaType<long long>(-9223372036854775807ll);
241  testCorbaTypeSequence<long long>(3, 9223372036854775807ll);
242  testCorbaType<unsigned long long>(18446744073709551615ull);
243  testCorbaTypeSequence<unsigned long long>(3, 18446744073709551615ull);
244  testCorbaType<bool>(true);
245  testCorbaType<char>('c');
246  testCorbaTypeSequence<char>(3, 'c');
247  testCorbaType<std::string>("foo");
248  testCorbaTypeSequence<std::string>(3, "foo");
249  testCorbaType<RTT::ConnPolicy>();
250 #ifdef OS_RT_MALLOC
251  testCorbaType<rt_string>("bar");
252 #endif
253 }
254 
255 // Registers the fixture into the 'registry'
256 BOOST_FIXTURE_TEST_SUITE( CorbaTestSuite, CorbaTest )
257 
258 BOOST_AUTO_TEST_CASE( testAttributes )
259 {
260  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
261  BOOST_CHECK( ts );
262  tp = corba::TaskContextProxy::Create( ts->server(), true );
263  BOOST_CHECK( tp );
264 
265  BOOST_CHECK( tp->provides()->hasAttribute("aint1") );
266  Attribute<int> proxy_int = tp->provides()->getAttribute("aint1");
267  BOOST_REQUIRE( proxy_int.ready() );
268 
269  // initial read through get:
270  BOOST_CHECK_EQUAL( proxy_int.get(), 3);
271  // reading through set:
272  aint1 = 4;
273  BOOST_CHECK_EQUAL( proxy_int.set(), 4);
274  // doing remote set:
275  proxy_int.set( 5 );
276  BOOST_CHECK_EQUAL( aint1, 5);
277 
278  BOOST_CHECK( tp->provides()->hasAttribute("adouble1") );
279  Attribute<double> proxy_double = tp->provides()->getAttribute("adouble1");
280  BOOST_REQUIRE( proxy_double.ready() );
281 
282  // initial reading through set:
283  BOOST_CHECK_EQUAL( proxy_double.set(), -3.0 );
284  // doing remote set, check local and remote result:
285  proxy_double.set( 5.0 );
286  BOOST_CHECK_EQUAL( adouble1, 5.0 );
287  BOOST_CHECK_EQUAL( proxy_double.get(), 5.0);
288  adouble1 = 6.0;
289  // reading changed remote:
290  BOOST_CHECK_EQUAL( proxy_double.get(), 6.0);
291 }
292 
293 BOOST_AUTO_TEST_CASE( testProperties )
294 {
295  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
296  BOOST_CHECK( ts );
297  tp = corba::TaskContextProxy::Create( ts->server(), true );
298  BOOST_CHECK( tp );
299 
300  BOOST_CHECK( findProperty( *tp->provides()->properties(), "pint1") );
301  Property<int> proxy_int = findProperty( *tp->provides()->properties(), "pint1");
302  BOOST_REQUIRE( proxy_int.ready() );
303  // initial read through get:
304  BOOST_CHECK_EQUAL( proxy_int.get(), 3);
305  // reading through set:
306  pint1 = 4;
307  BOOST_CHECK_EQUAL( proxy_int.set(), 4);
308  // doing remote set:
309  proxy_int.set( 5 );
310  BOOST_CHECK_EQUAL( pint1, 5);
311 
312  BOOST_CHECK( findProperty( *tp->provides()->properties(), "s1.s2.pdouble1") );
313  Property<double> proxy_d = findProperty( *tp->provides()->properties(), "s1.s2.pdouble1");
314  BOOST_REQUIRE( proxy_d.ready() );
315  // initial reading through set:
316  BOOST_CHECK_EQUAL( proxy_d.set(), -3.0 );
317  // doing remote set, check local and remote result:
318  proxy_d.set( 5.0 );
319  BOOST_CHECK_EQUAL( pdouble1->get(), 5.0 );
320  BOOST_CHECK_EQUAL( proxy_d.get(), 5.0);
321  pdouble1->set( 6.0 );
322  // reading changed remote:
323  BOOST_CHECK_EQUAL( proxy_d.get(), 6.0);
324 }
325 
326 BOOST_AUTO_TEST_CASE( testOperationCallerC_Call )
327 {
328 
329  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
330  BOOST_CHECK( ts );
331  tp = corba::TaskContextProxy::Create( ts->server(), true );
332  BOOST_CHECK( tp );
333 
334  // This test tests 'transparant' remote invocation of Orocos internal::OperationCallerC objects.
336  double r = 0.0;
337  mc = tp->provides("methods")->create("vm0", tc->engine() );
338  BOOST_CHECK( mc.call() );
339  BOOST_CHECK( r == 0.0 );
340 
341  mc = tp->provides("methods")->create("m0", tc->engine() ).ret( r );
342  BOOST_CHECK( mc.call() );
343  BOOST_CHECK( r == -1.0 );
344 
345  mc = tp->provides("methods")->create("m2", tc->engine() ).argC(1).argC(2.0).ret( r );
346  BOOST_CHECK( mc.call() );
347  BOOST_CHECK( r == -3.0 );
348 
349  mc = tp->provides("methods")->create("m3", tc->engine() ).ret( r ).argC(1).argC(2.0).argC(true);
350  BOOST_CHECK( mc.call() );
351  BOOST_CHECK( r == -4.0 );
352 
353  mc = tp->provides("methods")->create("m0except", tc->engine() );
354  BOOST_CHECK_THROW( mc.call(), std::runtime_error );
355  BOOST_REQUIRE( tc->inException() );
356 }
357 
358 BOOST_AUTO_TEST_CASE( testOperationCallerC_Send )
359 {
360 
361  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
362  BOOST_CHECK( ts );
363  tp = corba::TaskContextProxy::Create( ts->server(), true );
364  BOOST_CHECK( tp );
365 
366  OperationCallerC mc;
367  SendHandleC shc;
368  double r = 0.0;
369  double cr = 0.0;
370  mc = tp->provides("methods")->create("m0", caller->engine()).ret( r );
371  BOOST_CHECK_NO_THROW( mc.check() );
372  shc = mc.send();
373  shc.arg(cr);
374  BOOST_CHECK( shc.ready() ); // 1 argument to collect.
375  BOOST_CHECK_NO_THROW( shc.check() );
376  // now collect:
377  BOOST_CHECK_EQUAL( shc.collect(), SendSuccess);
378  BOOST_CHECK_EQUAL( r, 0.0 );
379  BOOST_CHECK_EQUAL( cr, -1.0 );
380 
381  mc = tp->provides("methods")->create("m2", caller->engine()).argC(1).argC(2.0).ret( r );
382  BOOST_CHECK_NO_THROW( mc.check() );
383  shc = mc.send();
384  shc.arg(cr);
385  BOOST_CHECK( shc.ready() ); // 1 argument to collect.
386  BOOST_CHECK_NO_THROW( shc.check() );
387  // now collect:
388  BOOST_CHECK_EQUAL( shc.collect(), SendSuccess);
389  BOOST_CHECK_EQUAL( r, 0.0 );
390  BOOST_CHECK_EQUAL( cr, -3.0 );
391 
392  mc = tp->provides("methods")->create("m3", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true);
393  BOOST_CHECK_NO_THROW( mc.check() );
394  shc = mc.send();
395  shc.arg(cr);
396  BOOST_CHECK( shc.ready() ); // 1 argument to collect.
397  BOOST_CHECK_NO_THROW( shc.check() );
398  // now collect:
399  BOOST_CHECK_EQUAL( shc.collect(), SendSuccess);
400  BOOST_CHECK_EQUAL( r, 0.0 );
401  BOOST_CHECK_EQUAL( cr, -4.0 );
402 
403  mc = tp->provides("methods")->create("m4", caller->engine()).ret( r ).argC(1).argC(2.0).argC(true).argC(string("hello"));
404  BOOST_CHECK_NO_THROW( mc.check() );
405  shc = mc.send();
406  shc.arg(cr);
407  BOOST_CHECK( shc.ready() ); // 1 argument to collect.
408  BOOST_CHECK_NO_THROW( shc.check() );
409  // now collect:
410  BOOST_CHECK_EQUAL( shc.collect(), SendSuccess);
411  BOOST_CHECK_EQUAL( r, 0.0 );
412  BOOST_CHECK_EQUAL( cr, -5.0 );
413 
414 #ifndef RTT_CORBA_SEND_ONEWAY_OPERATIONS
415  mc = tp->provides("methods")->create("m0except", caller->engine());
416  BOOST_CHECK_NO_THROW( mc.check() );
417  shc = mc.send();
418  BOOST_CHECK( shc.ready() ); // 1 argument to collect.
419  BOOST_CHECK_NO_THROW( shc.check() );
420  // now collect:
421  BOOST_CHECK_THROW( shc.collect(), std::runtime_error);
422  BOOST_REQUIRE( tc->inException() );
423 #endif
424 }
425 
426 BOOST_AUTO_TEST_CASE( testRemoteOperationCallerCall )
427 {
428 
429  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
430  tp = corba::TaskContextProxy::Create( ts->server(), true );
431 
432  // This test tests 'transparant' remote invocation of Orocos methods.
433  // This requires the internal::RemoteOperationCaller class, which does not work yet.
434  RTT::OperationCaller<double(void)> m0 = tp->provides("methods")->getOperation("m0");
435  RTT::OperationCaller<double(int)> m1 = tp->provides("methods")->getOperation("m1");
436  RTT::OperationCaller<double(int,double)> m2 = tp->provides("methods")->getOperation("m2");
437  RTT::OperationCaller<double(int,double,bool)> m3 = tp->provides("methods")->getOperation("m3");
438  RTT::OperationCaller<double(int,double,bool,std::string)> m4 = tp->provides("methods")->getOperation("m4");
439  RTT::OperationCaller<void(void)> m0e = tp->provides("methods")->getOperation("m0except");
440 
441  BOOST_CHECK_EQUAL( -1.0, m0() );
442  BOOST_CHECK_EQUAL( -2.0, m1(1) );
443  BOOST_CHECK_EQUAL( -3.0, m2(1, 2.0) );
444  BOOST_CHECK_EQUAL( -4.0, m3(1, 2.0, true) );
445  BOOST_CHECK_EQUAL( -5.0, m4(1, 2.0, true,"hello") );
446  BOOST_CHECK_THROW( m0e(), std::runtime_error );
447  BOOST_REQUIRE( tc->inException() );
448 }
449 
450 BOOST_AUTO_TEST_CASE( testAnyOperationCaller )
451 {
452  double d;
453 
454  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
455  tp = corba::TaskContextProxy::Create( ts->server() , true);
456 
457  // This test tests the callOperation() function of the server.
458  corba::CService_var co = ts->server()->getProvider("methods");
459  BOOST_CHECK( co.in() );
460 
461  corba::CAnyArguments_var any_args = new corba::CAnyArguments(0);
462  CORBA::Any_var vm0 = co->callOperation("vm0", any_args.inout() );
463  //BOOST_CHECK( vm0.in() );
464 
465  CORBA::Any_var m0 = co->callOperation("m0", any_args.inout());
466  BOOST_CHECK( m0 >>= d );
467  BOOST_CHECK_EQUAL(d, -1.0 );
468 
469  any_args = new corba::CAnyArguments(1);
470  any_args->length(1);
471  unsigned int index = 0;
472  any_args[index] <<= (CORBA::Long) 1;
473  CORBA::Any_var m1;
474  BOOST_CHECK_NO_THROW( m1 = co->callOperation("m1", any_args.inout()));
475  BOOST_CHECK( m1 >>= d );
476  BOOST_CHECK_EQUAL(d, -2.0 );
477 
478  any_args = new corba::CAnyArguments(2);
479  any_args->length(2);
480  index = 0;
481  any_args[index] <<= (CORBA::Long) 1;
482  ++index;
483  any_args[index] <<= (CORBA::Double) 2.0;
484  CORBA::Any_var m2;
485  BOOST_CHECK_NO_THROW( m2 = co->callOperation("m2", any_args.inout()));
486  BOOST_CHECK( m2 >>= d );
487  BOOST_CHECK_EQUAL(d, -3.0 );
488 
489  any_args = new corba::CAnyArguments(3);
490  any_args->length(3);
491  index = 0;
492  any_args[index] <<= (CORBA::Long) 1;
493  ++index;
494  any_args[index] <<= (CORBA::Double) 2.0;
495  ++index;
496  any_args[index] <<= CORBA::Any::from_boolean( true );
497  CORBA::Any_var m3;
498  BOOST_CHECK_NO_THROW( m3= co->callOperation("m3", any_args.inout()) );
499  BOOST_CHECK( m3 >>= d );
500  BOOST_CHECK_EQUAL(d, -4.0 );
501 
502  any_args = new corba::CAnyArguments(4);
503  any_args->length(4);
504  index = 0;
505  any_args[index] <<= (CORBA::Long) 1;
506  ++index;
507  any_args[index] <<= (CORBA::Double) 2.0;
508  ++index;
509  any_args[index] <<= CORBA::Any::from_boolean( true );
510  ++index;
511  any_args[index] <<= "hello";
512  CORBA::Any_var m4;
513  BOOST_CHECK_NO_THROW ( m4 = co->callOperation("m4", any_args.inout()) );
514  BOOST_CHECK( m4 >>= d );
515  BOOST_CHECK_EQUAL(d, -5.0 );
516 
517  any_args = new corba::CAnyArguments(0);
518  BOOST_CHECK_THROW(co->callOperation("m0except", any_args.inout() ), ::RTT::corba::CCallError);
519  BOOST_REQUIRE( tc->inException() );
520 }
521 
522 BOOST_AUTO_TEST_CASE(testDataFlowInterface)
523 {
524  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
525 
526  corba::CDataFlowInterface_var ports = ts->server()->ports();
527 
528  corba::CDataFlowInterface::CPortNames_var names =
529  ports->getPorts();
530 
531  BOOST_CHECK_EQUAL(CORBA::ULong(2), names->length());
532  BOOST_CHECK_EQUAL(string("mi"), string(names[CORBA::ULong(0)]));
533  BOOST_CHECK_EQUAL(string("mo"), string(names[CORBA::ULong(1)]));
534 
535  // Now check directions
536  BOOST_CHECK_EQUAL(RTT::corba::COutput,
537  ports->getPortType("mo"));
538  BOOST_CHECK_EQUAL(RTT::corba::CInput,
539  ports->getPortType("mi"));
540 
541  // And check type names
542  CORBA::String_var cstr = ports->getDataType("mo");
543  BOOST_CHECK_EQUAL(string("double"),
544  string(cstr.in()));
545 }
546 
547 BOOST_AUTO_TEST_CASE( testPortConnections )
548 {
549  // This test tests the different port-to-port connections.
550  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
551  ts2 = corba::TaskContextServer::Create( t2, false ); //no-naming
552 
553  // Create a default CORBA policy specification
554  RTT::corba::CConnPolicy policy = toCORBA(ConnPolicy::data());
555  policy.init = false;
556  policy.transport = ORO_CORBA_PROTOCOL_ID; // force creation of non-local connections
557 
558  corba::CDataFlowInterface_var ports = ts->server()->ports();
559  corba::CDataFlowInterface_var ports2 = ts2->server()->ports();
560 
561  // Test cases that should not connect
562  BOOST_CHECK_THROW( ports->createConnection("mo", ports2, "does_not_exist", policy), CNoSuchPortException );
563  BOOST_CHECK_THROW( ports->createConnection("does_not_exist", ports2, "mi", policy), CNoSuchPortException );
564  BOOST_CHECK_THROW( ports->createConnection("does_not_exist", ports2, "does_not_exist", policy), CNoSuchPortException );
565  BOOST_CHECK_THROW( ports->createConnection("mo", ports2, "mo", policy), CNoSuchPortException );
566  BOOST_CHECK_THROW( ports->createConnection("mi", ports2, "mi", policy), CNoSuchPortException );
567  BOOST_CHECK_THROW( ports->createConnection("mi", ports2, "mo", policy), CNoSuchPortException );
568 
569  // must be running to catch event port signalling.
570  BOOST_CHECK( t2->start() );
571  // WARNING: in the following, there is four configuration tested. There is
572  // also three different ways to disconnect. We need to test those three
573  // "disconnection methods", so beware when you change something ...
574 
575  policy.type = RTT::corba::CData;
576  policy.pull = false;
577  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
578  testPortDataConnection();
579  ports->disconnectPort("mo");
580  testPortDisconnected();
581 
582  policy.type = RTT::corba::CData;
583  policy.pull = true;
584  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
585 #ifndef RTT_CORBA_PORTS_DISABLE_SIGNAL
586  testPortDataConnection();
587 #endif // RTT_CORBA_PORTS_DISABLE_SIGNAL
588  ports2->disconnectPort("mi");
589  testPortDisconnected();
590 
591  policy.type = RTT::corba::CBuffer;
592  policy.pull = false;
593  policy.size = 3;
594  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
595  testPortBufferConnection();
596  ports->disconnectPort("mo");
597  testPortDisconnected();
598 
599  policy.type = RTT::corba::CBuffer;
600  policy.pull = true;
601  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
602 #ifndef RTT_CORBA_PORTS_DISABLE_SIGNAL
603  testPortBufferConnection();
604 #endif // RTT_CORBA_PORTS_DISABLE_SIGNAL
605  // Here, check removal of specific connections. So first add another
606  // connection ...
607  mo1->createConnection(*mi1);
608  // Remove the remote connection
609  ports->removeConnection("mo", ports2, "mi");
610  // Check it is removed
611  BOOST_CHECK(mo1->connected());
612  BOOST_CHECK(mi1->connected());
613  BOOST_CHECK(!mi2->connected());
614 }
615 
616 BOOST_AUTO_TEST_CASE( testSharedConnections )
617 {
618  // This test installs shared connections between mo1 and mo2 as writers and mi2 and mi3 as readers
619 
620 // // Add a second input port mo3 to tc
621 //#if __cplusplus > 199711L
622 // unique_ptr<RTT::OutputPort<double> >
623 //#else
624 // auto_ptr<RTT::OutputPort<double> >
625 //#endif
626 // mo3(new RTT::OutputPort<double>());
627 
628 // tc->addPort("mo3", *mo3);
629 
630  // Add a second input port mi3 to t2
631 #if __cplusplus > 199711L
632  unique_ptr<RTT::InputPort<double> >
633 #else
634  auto_ptr<RTT::InputPort<double> >
635 #endif
636  mi3(new RTT::InputPort<double>());
637  t2->addPort("mi3", *mi3);
638 
639  // This test tests shared connections port-to-port connections.
640  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
641  ts2 = corba::TaskContextServer::Create( t2, false ); //no-naming
642 
643  // must be running to catch event port signalling.
644  BOOST_CHECK( t2->start() );
645 
646  // Create a CORBA policy specification
647  RTT::corba::CConnPolicy policy = toCORBA(ConnPolicy::data(ConnPolicy::LOCKED));
648  policy.init = false;
649  policy.transport = ORO_CORBA_PROTOCOL_ID; // force creation of non-local connections
650 
651  corba::CDataFlowInterface_var ports = ts->server()->ports();
652  corba::CDataFlowInterface_var ports2 = ts2->server()->ports();
653  double value = 0.0;
654 
655  // Shared push connection...
656  policy.buffer_policy = RTT::corba::CShared;
657  policy.pull = false;
658  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
659  BOOST_CHECK( ports->createConnection("mo", ports2, "mi3", policy) );
660  BOOST_CHECK( ports2->createConnection("mo", ports2, "mi", policy) );
661  BOOST_CHECK( mi3->connected() );
662  BOOST_CHECK( mo2->connected() );
663  BOOST_REQUIRE( mi2->getManager()->getSharedConnection() );
664  BOOST_REQUIRE( mi3->getManager()->getSharedConnection() );
665  BOOST_CHECK_EQUAL( mi2->getManager()->getSharedConnection()->getName(), mi3->getManager()->getSharedConnection()->getName() );
666  BOOST_CHECK_EQUAL( mi3->read(value), NoData );
667  testPortDataConnection(); // communication between mo and mi should work the same as for private connections
668  BOOST_CHECK_EQUAL( mi3->read(value), OldData );
669  BOOST_CHECK_EQUAL( value, 2.0 );
670  BOOST_CHECK_EQUAL( mo2->write(3.0), WriteSuccess );
671  value = 0.0;
672  BOOST_CHECK_EQUAL( mi3->read(value), NewData );
673  BOOST_CHECK_EQUAL( value, 3.0 );
674  value = 0.0;
675  BOOST_CHECK_EQUAL( mi2->read(value), OldData );
676  BOOST_CHECK_EQUAL( value, 3.0 );
677 
678  ports->disconnectPort("mo"); // disconnect from the output side
679  ports2->disconnectPort("mo"); // disconnect from the output side
680  BOOST_CHECK( !mo1->connected() );
681  BOOST_CHECK( !mo2->connected() );
682  BOOST_CHECK( !mi2->connected() );
683  BOOST_CHECK( !mi3->connected() );
684 
685  // Shared pull connection...
686  policy.buffer_policy = RTT::corba::CShared;
687  policy.pull = true;
688  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
689  BOOST_CHECK( ports->createConnection("mo", ports2, "mi3", policy) );
690  BOOST_CHECK( ports2->createConnection("mo", ports2, "mi", policy) );
691  BOOST_CHECK( mi3->connected() );
692  BOOST_CHECK( mo2->connected() );
693  BOOST_REQUIRE( mi2->getManager()->getSharedConnection() );
694  BOOST_REQUIRE( mi3->getManager()->getSharedConnection() );
695  BOOST_CHECK_EQUAL( mi2->getManager()->getSharedConnection()->getName(), mi3->getManager()->getSharedConnection()->getName() );
696  BOOST_CHECK_EQUAL( mi3->read(value), NoData );
697 #ifndef RTT_CORBA_PORTS_DISABLE_SIGNAL
698  testPortDataConnection(); // communication between mo and mi should work the same as for private connections
699  BOOST_CHECK_EQUAL( mi3->read(value), OldData );
700  BOOST_CHECK_EQUAL( value, 2.0 );
701 #endif // RTT_CORBA_PORTS_DISABLE_SIGNAL
702  BOOST_CHECK_EQUAL( mo2->write(3.0), WriteSuccess );
703  value = 0.0;
704  BOOST_CHECK_EQUAL( mi3->read(value), NewData );
705  BOOST_CHECK_EQUAL( value, 3.0 );
706  value = 0.0;
707  BOOST_CHECK_EQUAL( mi2->read(value), OldData );
708  BOOST_CHECK_EQUAL( value, 3.0 );
709 
710  ports->disconnectPort("mo"); // disconnect from the output side
711  ports2->disconnectPort("mo"); // disconnect from the output side
712  BOOST_CHECK( !mo1->connected() );
713  BOOST_CHECK( !mo2->connected() );
714  BOOST_CHECK( !mi2->connected() );
715  BOOST_CHECK( !mi3->connected() );
716 
717  // PerOutputPort pull connection...
718  policy.buffer_policy = RTT::corba::CPerOutputPort;
719  policy.pull = true;
720  BOOST_CHECK( ports->createConnection("mo", ports2, "mi", policy) );
721  BOOST_CHECK( ports->createConnection("mo", ports2, "mi3", policy) );
722  BOOST_CHECK( ports2->createConnection("mo", ports2, "mi", policy) ); // cannot use the DataFlowInterface CORBA API here, as it will find the local SharedConnection instance and fail.
723  BOOST_CHECK( mi3->connected() );
724  BOOST_CHECK( mo2->connected() );
725  BOOST_CHECK( mo1->getSharedBuffer() );
726  BOOST_CHECK( mo2->getSharedBuffer() );
727  BOOST_CHECK_EQUAL( mi3->read(value), NoData );
728 #ifndef RTT_CORBA_PORTS_DISABLE_SIGNAL
729  testPortDataConnection(); // communication between mo and mi should work the same as for private connections
730  BOOST_CHECK_EQUAL( mi3->read(value), OldData );
731  BOOST_CHECK_EQUAL( value, 2.0 );
732 #endif // RTT_CORBA_PORTS_DISABLE_SIGNAL
733  BOOST_CHECK_EQUAL( mo1->write(3.0), WriteSuccess );
734  BOOST_CHECK_EQUAL( mo2->write(4.0), WriteSuccess );
735  value = 0.0;
736  BOOST_CHECK_EQUAL( mi3->read(value), NewData );
737  BOOST_CHECK_EQUAL( value, 3.0 );
738  value = 0.0;
739  BOOST_CHECK_EQUAL( mi2->read(value), NewData );
740  BOOST_CHECK_EQUAL( value, 4.0 );
741  value = 0.0;
742  BOOST_CHECK_EQUAL( mi3->read(value), OldData );
743  BOOST_CHECK_EQUAL( value, 3.0 );
744  value = 0.0;
745  BOOST_CHECK_EQUAL( mi2->read(value), OldData );
746  BOOST_CHECK_EQUAL( value, 4.0 );
747 
748  ports2->disconnectPort("mi"); // disconnect from the input side
749  ports2->disconnectPort("mi3"); // disconnect from the input side
750  BOOST_CHECK( !mo1->connected() );
751  BOOST_CHECK( !mo2->connected() );
752  BOOST_CHECK( !mi2->connected() );
753  BOOST_CHECK( !mi3->connected() );
754 }
755 
756 BOOST_AUTO_TEST_CASE( testPortProxying )
757 {
758  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
759  tp = corba::TaskContextProxy::Create( ts->server(), true );
760  ts2 = corba::TaskContextServer::Create( t2, false ); //no-naming
761  tp2 = corba::TaskContextProxy::Create( ts2->server(), true );
762 
763  base::PortInterface* untyped_port;
764 
765  untyped_port = tp->ports()->getPort("mi");
766  BOOST_CHECK(untyped_port);
767  base::InputPortInterface* read_port = dynamic_cast<base::InputPortInterface*>(tp->ports()->getPort("mi"));
768  BOOST_CHECK(read_port);
769 
770  untyped_port = tp->ports()->getPort("mi");
771  BOOST_CHECK(untyped_port);
772  base::OutputPortInterface* write_port = dynamic_cast<base::OutputPortInterface*>(tp2->ports()->getPort("mo"));
773  BOOST_CHECK(write_port);
774 
775  // Just make sure 'read_port' and 'write_port' are actually proxies and not
776  // the real thing
777  BOOST_CHECK(dynamic_cast<corba::RemoteInputPort*>(read_port));
778  BOOST_CHECK(dynamic_cast<corba::RemoteOutputPort*>(write_port));
779 
780  BOOST_CHECK(!read_port->connected());
781  BOOST_CHECK(read_port->getTypeInfo() == mi1->getTypeInfo());
782  BOOST_CHECK(!write_port->connected());
783  BOOST_CHECK(write_port->getTypeInfo() == mo2->getTypeInfo());
784 
785  mo2->createConnection(*read_port);
786  BOOST_CHECK(read_port->connected());
787  BOOST_CHECK(write_port->connected());
788  read_port->disconnect();
789  BOOST_CHECK(!read_port->connected());
790  BOOST_CHECK(!write_port->connected());
791 
792  mo2->createConnection(*read_port);
793  BOOST_CHECK(read_port->connected());
794  BOOST_CHECK(write_port->connected());
795  write_port->disconnect();
796  BOOST_CHECK(!read_port->connected());
797  BOOST_CHECK(!write_port->connected());
798 
799  // Test cloning
800 #if __cplusplus > 199711L
801  unique_ptr<base::InputPortInterface>
802 #else
803  auto_ptr<base::InputPortInterface>
804 #endif
805  read_clone(dynamic_cast<base::InputPortInterface*>(read_port->clone()));
806  BOOST_CHECK(mo2->createConnection(*read_clone));
807  BOOST_CHECK(read_clone->connected());
808  BOOST_CHECK(!read_port->connected());
809  mo2->disconnect();
810 }
811 
812 BOOST_AUTO_TEST_CASE( testRemotePortDisconnect )
813 {
814  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
815  tp = corba::TaskContextProxy::Create( ts->server(), true );
816  ts2 = corba::TaskContextServer::Create( t2, false ); //no-naming
817  tp2 = corba::TaskContextProxy::Create( ts2->server(), true );
818 
819  // Create a default CORBA policy specification
821  policy.init = false;
822  policy.transport = ORO_CORBA_PROTOCOL_ID; // force creation of non-local connections
823 
824  base::PortInterface* untyped_port;
825 
826  //mi1
827  untyped_port = tp->ports()->getPort("mi");
828  BOOST_CHECK(untyped_port);
829  base::InputPortInterface* read_port1 = dynamic_cast<base::InputPortInterface*>(tp->ports()->getPort("mi"));
830  BOOST_CHECK(read_port1);
831 
832  //mi2
833  untyped_port = tp2->ports()->getPort("mi");
834  BOOST_CHECK(untyped_port);
835  base::InputPortInterface* read_port2 = dynamic_cast<base::InputPortInterface*>(tp2->ports()->getPort("mi"));
836  BOOST_CHECK(read_port2);
837 
838  //mo2
839  untyped_port = tp2->ports()->getPort("mo");
840  BOOST_CHECK(untyped_port);
841  base::OutputPortInterface* write_port2 = dynamic_cast<base::OutputPortInterface*>(tp2->ports()->getPort("mo"));
842  BOOST_CHECK(write_port2);
843 
844  //mo1
845  untyped_port = tp->ports()->getPort("mo");
846  BOOST_CHECK(untyped_port);
847  base::OutputPortInterface* write_port1 = dynamic_cast<base::OutputPortInterface*>(tp->ports()->getPort("mo"));
848  BOOST_CHECK(write_port1);
849 
850  // Just make sure 'read_port' and 'write_port' are actually proxies and not
851  // the real thing
852  BOOST_CHECK(dynamic_cast<corba::RemoteInputPort*>(read_port1));
853  BOOST_CHECK(dynamic_cast<corba::RemoteInputPort*>(read_port2));
854  BOOST_CHECK(dynamic_cast<corba::RemoteOutputPort*>(write_port1));
855  BOOST_CHECK(dynamic_cast<corba::RemoteOutputPort*>(write_port2));
856 
857  //create remote connections:
858  write_port2->connectTo(read_port1, policy);
859  BOOST_CHECK(read_port1->connected());
860  BOOST_CHECK(write_port2->connected());
861 
862  //second connection to this input port
863  write_port1->connectTo(read_port1, policy);
864  BOOST_CHECK(write_port1->connected());
865 
866  //disconnect single port connection (both remote), same tcs object.
867  write_port1->disconnect(read_port1);
868  BOOST_CHECK(read_port1->connected());
869  BOOST_CHECK(!write_port1->connected());
870 
871  //disconnect single port connection, both remote, different tcs.
872  write_port2->disconnect(read_port1);
873  BOOST_CHECK(!read_port1->connected());
874 
875  //check disconnecting call on reader port. (build connection again beforehand).
876  write_port2->connectTo(read_port1, policy);
877  BOOST_CHECK(read_port1->connected());
878  BOOST_CHECK(write_port2->connected());
879  BOOST_CHECK(read_port1->disconnect(write_port2));
880  BOOST_CHECK(!read_port1->connected());
881  BOOST_CHECK(!write_port2->connected());
882 
883  //check connect and disconnect certain port, remote output to local input
884  //should give false cause not supported yet!
885  write_port2->connectTo(mi1, policy);
886  BOOST_CHECK(mi1->connected());
887  BOOST_CHECK(write_port2->connected());
888  BOOST_CHECK(!write_port2->disconnect(mi1));
889  mi1->disconnect(); //remove all connections works, so required for cleanup.
890 
891  //check disconnect remote input port from local output port.
892  mo2->connectTo(read_port1, policy);
893  BOOST_CHECK(read_port1->connected());
894  BOOST_CHECK(mo2->connected());
895  BOOST_CHECK(read_port1->disconnect(mo2));
896  BOOST_CHECK(!mo2->connected());
897  BOOST_CHECK(!read_port1->connected());
898 
899 }
900 
901 BOOST_AUTO_TEST_CASE( testDataHalfs )
902 {
903  double result;
904  // This test tests the differen port-to-port connections.
905  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
906 
907  // Create a default CORBA policy specification
908  RTT::corba::CConnPolicy policy = toCORBA(ConnPolicy::data());
909  policy.init = false;
910  policy.transport = ORO_CORBA_PROTOCOL_ID; // force creation of non-local connections
911 
912  corba::CDataFlowInterface_var ports = ts->server()->ports();
913  BOOST_REQUIRE( ports.in() );
914 
915  // test unbuffered C++ write --> Corba read
916  policy.pull = false; // note: buildChannelInput must correct policy to pull = true (adds a buffer).
917  CChannelElement_var cce = ports->buildChannelInput("mo", policy);
918  CORBA::Any_var sample = new CORBA::Any();
919  BOOST_REQUIRE( cce.in() );
920 
921  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), CNoData );
922  // Check read of new data
923  mo1->write( 3.33 );
924  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), CNewData );
925  sample >>= result;
926  BOOST_CHECK_EQUAL( result, 3.33);
927 
928  // Check re-read of old data.
929  sample <<= 0.0;
930  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), COldData );
931  sample >>= result;
932  BOOST_CHECK_EQUAL( result, 3.33);
933 
934  cce->disconnect();
935 
936  // test unbuffered Corba write --> C++ read
937  cce = ports->buildChannelOutput("mi", policy);
938  cce->channelReady(policy);
939  sample = new CORBA::Any();
940  BOOST_REQUIRE( cce.in() );
941 
942  // Check read of new data
943  result = 0.0;
944  sample <<= 4.44;
945  cce->write( sample.in() );
946  BOOST_CHECK_EQUAL( mi1->read( result ), NewData );
947  BOOST_CHECK_EQUAL( result, 4.44 );
948 
949  // Check re-read of old data.
950  result = 0.0;
951  BOOST_CHECK_EQUAL( mi1->read( result ), OldData );
952  BOOST_CHECK_EQUAL( result, 4.44);
953 }
954 
955 BOOST_AUTO_TEST_CASE( testBufferHalfs )
956 {
957  double result;
958  // This test tests the differen port-to-port connections.
959  ts = corba::TaskContextServer::Create( tc, false ); //no-naming
960 
961  // Create a default CORBA policy specification
962  RTT::corba::CConnPolicy policy = toCORBA(ConnPolicy::buffer(10));
963  policy.init = false;
964  policy.transport = ORO_CORBA_PROTOCOL_ID; // force creation of non-local connections
965 
966  corba::CDataFlowInterface_var ports = ts->server()->ports();
967  BOOST_REQUIRE( ports.in() );
968 
969  // test unbuffered C++ write --> Corba read
970  policy.pull = false; // note: buildChannelInput must correct policy to pull = true (adds a buffer).
971  CChannelElement_var cce = ports->buildChannelInput("mo", policy);
972  CORBA::Any_var sample = new CORBA::Any();
973  BOOST_REQUIRE( cce.in() );
974 
975  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), CNoData );
976  // Check read of new data
977  mo1->write( 6.33 );
978  mo1->write( 3.33 );
979  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), CNewData );
980  sample >>= result;
981  BOOST_CHECK_EQUAL( result, 6.33);
982  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), CNewData );
983  sample >>= result;
984  BOOST_CHECK_EQUAL( result, 3.33);
985 
986  // Check re-read of old data.
987  sample <<= 0.0;
988  BOOST_CHECK_EQUAL( cce->read( sample.out(), true ), COldData );
989  sample >>= result;
990  BOOST_CHECK_EQUAL( result, 3.33);
991 
992  cce->disconnect();
993 
994  // test unbuffered Corba write --> C++ read
995  cce = ports->buildChannelOutput("mi", policy);
996  cce->channelReady(policy);
997  sample = new CORBA::Any();
998  BOOST_REQUIRE( cce.in() );
999 
1000  // Check read of new data
1001  result = 0.0;
1002  sample <<= 6.44;
1003  cce->write( sample.in() );
1004  sample <<= 4.44;
1005  cce->write( sample.in() );
1006  BOOST_CHECK_EQUAL( mi1->read( result ), NewData );
1007  BOOST_CHECK_EQUAL( result, 6.44 );
1008  BOOST_CHECK_EQUAL( mi1->read( result ), NewData );
1009  BOOST_CHECK_EQUAL( result, 4.44 );
1010 
1011  // Check re-read of old data.
1012  result = 0.0;
1013  BOOST_CHECK_EQUAL( mi1->read( result ), OldData );
1014  BOOST_CHECK_EQUAL( result, 4.44);
1015 }
1016 
1018 
virtual PortInterface * clone() const =0
InputPort< double > * mi2
Definition: corba_test.cpp:106
static ConnPolicy data(int lock_policy=LOCK_FREE, bool init_connection=true, bool pull=false)
Definition: ConnPolicy.cpp:99
#define BOOST_FIXTURE_TEST_SUITE(suite_name, F)
DataSourceType get() const
Definition: Property.hpp:246
void new_data_listener(base::PortInterface *port)
virtual const types::TypeInfo * getTypeInfo() const =0
OutputPort< double > * mo1
Definition: corba_test.cpp:105
OutputPort< double > * mo2
Definition: corba_test.cpp:107
void testPortDisconnected()
#define BOOST_AUTO_TEST_SUITE_END()
Definition: mystd.hpp:163
void set(T const &t)
Definition: Attribute.hpp:199
#define ASSERT_PORT_SIGNALLING(code, read_port)
Definition: corba_test.cpp:127
static const int LOCKED
Definition: ConnPolicy.hpp:116
BOOST_AUTO_TEST_CASE(testCorbaTypes)
Definition: corba_test.cpp:230
static void testCorbaTypeSequence(std::size_t size=3, const T &value=T())
Definition: corba_test.cpp:216
PropertyBase * findProperty(const PropertyBag &bag, const std::string &nameSequence, const std::string &separator)
SendHandleC & arg(base::DataSourceBase::shared_ptr a)
static void testCorbaType(const T &value=T())
Definition: corba_test.cpp:205
A property represents a named value of any type with a description.
Definition: Property.hpp:76
virtual bool connectTo(PortInterface *other, ConnPolicy const &policy)
static ConnPolicy buffer(int size, int lock_policy=LOCK_FREE, bool init_connection=false, bool pull=false)
Definition: ConnPolicy.cpp:77
Property< int > pint1
Definition: corba_test.cpp:109
static bool operator==(const ConnPolicy &, const ConnPolicy &)
Definition: corba_test.cpp:227
void testPortBufferConnection()
double adouble1
Definition: corba_test.cpp:113
OperationCallerC & ret(base::AttributeBase *r)
RTT::corba::CConnPolicy toCORBA(RTT::ConnPolicy const &policy)
bool storeProperty(PropertyBag &bag, const std::string &path, base::PropertyBase *item, const std::string &separator)
#define ORO_CORBA_PROTOCOL_ID
Definition: CorbaLib.hpp:45
OperationCallerC & argC(const ArgT a)
void testPortDataConnection()
reference_t set()
Definition: Property.hpp:257
InputPort< double > * mi1
Definition: corba_test.cpp:104
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
Property< double > * pdouble1
Definition: corba_test.cpp:110
TaskContext * tp
Definition: corba_test.cpp:95
static bool update(TaskContext *tc)


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:23