00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "unit.hpp"
00020 #include <InputPort.hpp>
00021 #include <OutputPort.hpp>
00022
00023 #include <TaskContext.hpp>
00024 #include <extras/SlaveActivity.hpp>
00025 #include <extras/SequentialActivity.hpp>
00026 #include <extras/SimulationActivity.hpp>
00027 #include <extras/SimulationThread.hpp>
00028
00029 #include <boost/function_types/function_type.hpp>
00030 #include <OperationCaller.hpp>
00031
00032 using namespace std;
00033 using namespace RTT;
00034 using namespace RTT::detail;
00035
00036
00037 class EventPortsTC : public TaskContext
00038 {
00039 public:
00040 bool had_event;
00041 int nb_events;
00042 EventPortsTC(): TaskContext("eptc") { resetStats(); }
00043 void updateHook()
00044 {
00045 nb_events++;
00046 had_event = true;
00047 }
00048 void resetStats() {
00049 nb_events = 0;
00050 had_event = false;
00051 }
00052 };
00053
00057 class PortsTestFixture
00058 {
00059 public:
00060 TaskContext* tc;
00061 EventPortsTC* tce;
00062 EventPortsTC* tc2;
00063 ActivityInterface* tsim;
00064 ActivityInterface* stsim;
00065
00066 PortInterface* signalled_port;
00067 void new_data_listener(PortInterface* port)
00068 {
00069 signalled_port = port;
00070 }
00071
00072 public:
00073 PortsTestFixture()
00074 {
00075 tc = new TaskContext( "root", TaskContext::Stopped );
00076 tce = new EventPortsTC();
00077 tc2 = new EventPortsTC();
00078 tce->setActivity( new SequentialActivity() );
00079 tc2->setActivity( new SequentialActivity() );
00080 tc->setActivity( new SimulationActivity(0.001) );
00081 tsim = tc->getActivity();
00082 stsim = tc->getActivity();
00083 SimulationThread::Instance()->stop();
00084 }
00085
00086 ~PortsTestFixture()
00087 {
00088
00089
00090 tsim->stop();
00091 stsim->stop();
00092 delete tc;
00093 delete tce;
00094 delete tc2;
00095 }
00096 };
00097
00098
00099
00100 BOOST_FIXTURE_TEST_SUITE( PortsTestSuite, PortsTestFixture )
00101
00102 BOOST_AUTO_TEST_CASE( testPortTaskInterface )
00103 {
00104 InputPort<int> rp1("Port1");
00105 OutputPort<int> wp1("Port1");
00106 InputPort<int> rp2("Port2");
00107 OutputPort<int> wp2("Port2");
00108
00109 tc->ports()->addPort( wp1 );
00110 tc->ports()->addPort( rp2 );
00111
00112
00113 tc->ports()->addPort( wp1 );
00114 {
00115
00116 InputPort<double> other_rp("Port1");
00117 tc->ports()->addPort( other_rp );
00118
00119 tc->ports()->removePort( other_rp.getName() );
00120 }
00121
00122
00123
00124 {
00125 auto_ptr<TaskContext> tc1(new TaskContext( "tc", TaskContext::Stopped ));
00126 auto_ptr<TaskContext> tc2(new TaskContext( "tc2", TaskContext::Stopped ));
00127
00128 tc1->ports()->addPort( rp1 );
00129 tc1->ports()->addPort( wp2 );
00130 tc2->ports()->addPort( rp2 );
00131 tc2->ports()->addPort( wp1 );
00132
00133 BOOST_CHECK( tc1->connectPorts(tc2.get()) );
00134 BOOST_CHECK( wp1.connected() );
00135 BOOST_CHECK( rp1.connected() );
00136 wp1.write(2);
00137 int value = 0;
00138 BOOST_CHECK( rp1.read(value) );
00139 BOOST_CHECK_EQUAL(2, value);
00140
00141 BOOST_CHECK( wp2.connected() );
00142 BOOST_CHECK( rp2.connected() );
00143 wp2.write(3);
00144 value = 0;
00145 BOOST_CHECK( rp2.read(value) );
00146 BOOST_CHECK_EQUAL(3, value);
00147 }
00148
00149
00150
00151 BOOST_CHECK( rp1.connected() );
00152 BOOST_CHECK( rp2.connected() );
00153 BOOST_CHECK( wp1.connected() );
00154 BOOST_CHECK( wp2.connected() );
00155
00156
00157 tc->ports()->removePort( wp1.getName() );
00158 tc->ports()->removePort( rp2.getName() );
00159 }
00160
00161 BOOST_AUTO_TEST_CASE(testPortConnectionInitialization)
00162 {
00163 OutputPort<int> wp("WriterName", true);
00164 InputPort<int> rp("ReaderName", ConnPolicy::data(true));
00165
00166 BOOST_CHECK( wp.createConnection(rp) );
00167 int value = 0;
00168 BOOST_CHECK( !rp.read(value) );
00169 BOOST_CHECK( !wp.getLastWrittenValue(value) );
00170 wp.write(10);
00171 BOOST_CHECK( rp.read(value) );
00172 BOOST_CHECK_EQUAL( 10, value );
00173
00174 wp.disconnect(&rp);
00175 BOOST_CHECK( !wp.connected() );
00176 BOOST_CHECK( !rp.connected() );
00177
00178 value = 0;
00179 BOOST_CHECK( wp.getLastWrittenValue(value) );
00180 BOOST_CHECK_EQUAL( 10, value );
00181 BOOST_CHECK_EQUAL( 10, wp.getLastWrittenValue() );
00182
00183 value = 0;
00184 BOOST_CHECK( wp.createConnection(rp) );
00185 BOOST_CHECK( rp.read(value) );
00186 BOOST_CHECK_EQUAL( 10, value );
00187
00188 }
00189
00190 BOOST_AUTO_TEST_CASE(testPortSimpleConnections)
00191 {
00192 OutputPort<int> wp("WriterName");
00193 InputPort<int> rp("ReaderName", ConnPolicy::data(ConnPolicy::LOCK_FREE, false));
00194
00195 BOOST_CHECK( !wp.connected() );
00196 BOOST_CHECK( !rp.connected() );
00197 {
00198 int value;
00199 BOOST_CHECK( !rp.read(value) );
00200 wp.write(value);
00201 }
00202
00203 BOOST_REQUIRE( wp.createConnection(rp) );
00204 BOOST_CHECK( wp.connected() );
00205 BOOST_CHECK( rp.connected() );
00206
00207 {
00208 int value = 0;
00209 BOOST_CHECK( !rp.read(value) );
00210 wp.write(1);
00211 BOOST_CHECK( rp.read(value) );
00212 BOOST_CHECK( 1 == value );
00213 }
00214
00215 rp.clear();
00216 {
00217 int value = 0;
00218 BOOST_CHECK( !rp.read(value) );
00219 wp.write(1);
00220 BOOST_CHECK( rp.read(value) );
00221 BOOST_CHECK( 1 == value );
00222 }
00223
00224
00225
00226 wp.disconnect();
00227 BOOST_CHECK( !wp.connected() );
00228 BOOST_CHECK( !rp.connected() );
00229 {
00230 int value;
00231 wp.write(value);
00232 BOOST_CHECK( !rp.read(value) );
00233 }
00234 wp.disconnect();
00235
00236 {
00237 int value = 0;
00238 BOOST_CHECK( !rp.read(value) );
00239 wp.createBufferConnection(rp, 4);
00240 BOOST_CHECK( !rp.read(value) );
00241 wp.write(1);
00242 wp.write(2);
00243 wp.write(3);
00244 wp.write(4);
00245 wp.write(5);
00246 BOOST_CHECK_EQUAL(0, value);
00247 BOOST_CHECK( rp.read(value) );
00248 BOOST_CHECK_EQUAL(1, value);
00249 BOOST_CHECK( rp.read(value) );
00250 BOOST_CHECK_EQUAL(2, value);
00251
00252 rp.clear();
00253 BOOST_CHECK_EQUAL( rp.read(value), NoData );
00254 wp.write(10);
00255 wp.write(20);
00256 BOOST_CHECK( rp.read(value) );
00257 BOOST_CHECK_EQUAL(10, value);
00258 BOOST_CHECK( rp.read(value) );
00259 BOOST_CHECK_EQUAL(20, value);
00260 BOOST_CHECK_EQUAL( rp.read(value), OldData );
00261 }
00262
00263
00264 rp.disconnect();
00265 BOOST_CHECK( !wp.connected() );
00266 BOOST_CHECK( !rp.connected() );
00267 {
00268 int value;
00269 wp.write(value);
00270 BOOST_CHECK( !rp.read(value) );
00271 }
00272 rp.disconnect();
00273
00274
00275 {
00276 InputPort<int> rp("ReaderName", ConnPolicy::data());
00277 BOOST_CHECK(wp.createConnection(rp));
00278 BOOST_CHECK( wp.connected() );
00279 BOOST_CHECK( rp.connected() );
00280 }
00281 BOOST_CHECK( !wp.connected() );
00282 }
00283
00284 BOOST_AUTO_TEST_CASE(testPortOneWriterThreeReaders)
00285 {
00286 OutputPort<int> wp("W");
00287 InputPort<int> rp1("R1", ConnPolicy::data());
00288 InputPort<int> rp2("R2", ConnPolicy::buffer(4));
00289 InputPort<int> rp3("R3", ConnPolicy::data());
00290
00291 wp.createConnection(rp1);
00292 BOOST_CHECK( wp.connected() );
00293 BOOST_CHECK( rp1.connected() );
00294 BOOST_CHECK( !rp2.connected() );
00295 BOOST_CHECK( !rp3.connected() );
00296 wp.createConnection(rp2);
00297 BOOST_CHECK( wp.connected() );
00298 BOOST_CHECK( rp1.connected() );
00299 BOOST_CHECK( rp2.connected() );
00300 BOOST_CHECK( !rp3.connected() );
00301 wp.createConnection(rp3);
00302 BOOST_CHECK( wp.connected() );
00303 BOOST_CHECK( rp1.connected() );
00304 BOOST_CHECK( rp2.connected() );
00305 BOOST_CHECK( rp3.connected() );
00306
00307 wp.write(10);
00308 wp.write(15);
00309 wp.write(20);
00310 wp.write(25);
00311 wp.write(30);
00312
00313 int value = 0;
00314 BOOST_CHECK( rp1.read(value));
00315 BOOST_CHECK_EQUAL(30, value);
00316
00317 BOOST_CHECK( rp2.read(value));
00318 BOOST_CHECK_EQUAL(10, value);
00319 BOOST_CHECK( rp2.read(value));
00320 BOOST_CHECK_EQUAL(15, value);
00321 BOOST_CHECK( rp2.read(value));
00322 BOOST_CHECK_EQUAL(20, value);
00323 BOOST_CHECK( rp2.read(value));
00324 BOOST_CHECK_EQUAL(25, value);
00325 BOOST_CHECK_EQUAL( rp2.read(value), OldData);
00326
00327 BOOST_CHECK( rp3.read(value));
00328 BOOST_CHECK_EQUAL(30, value);
00329
00330
00331 wp.disconnect(&rp2);
00332 BOOST_CHECK_EQUAL( rp2.read(value), NoData );
00333 BOOST_CHECK( wp.connected() );
00334 BOOST_CHECK( rp1.connected() );
00335 BOOST_CHECK( !rp2.connected() );
00336 BOOST_CHECK( rp3.connected() );
00337
00338 wp.write(10);
00339 BOOST_CHECK( rp1.read(value));
00340 BOOST_CHECK_EQUAL(10, value);
00341 BOOST_CHECK( rp3.read(value));
00342 BOOST_CHECK_EQUAL(10, value);
00343
00344
00345 wp.disconnect(&rp1);
00346 wp.disconnect(&rp3);
00347 BOOST_CHECK( !wp.connected() );
00348 BOOST_CHECK( !rp1.connected() );
00349 BOOST_CHECK( !rp2.connected() );
00350 BOOST_CHECK( !rp3.connected() );
00351 BOOST_CHECK_EQUAL( rp1.read(value), NoData );
00352 BOOST_CHECK_EQUAL( rp2.read(value), NoData );
00353 BOOST_CHECK_EQUAL( rp3.read(value), NoData );
00354 }
00355
00356 BOOST_AUTO_TEST_CASE(testPortThreeWritersOneReader)
00357 {
00358 OutputPort<int> wp1("W1");
00359 OutputPort<int> wp2("W2");
00360 OutputPort<int> wp3("W3");
00361 InputPort<int> rp("R", ConnPolicy::buffer(4));
00362
00363 wp1.createConnection(rp);
00364 BOOST_CHECK( wp1.connected() );
00365 BOOST_CHECK( rp.connected() );
00366 BOOST_CHECK( !wp2.connected() );
00367 BOOST_CHECK( !wp3.connected() );
00368 wp2.createConnection(rp);
00369 BOOST_CHECK( rp.connected() );
00370 BOOST_CHECK( wp1.connected() );
00371 BOOST_CHECK( wp2.connected() );
00372 BOOST_CHECK( !wp3.connected() );
00373 wp3.createConnection(rp);
00374 BOOST_CHECK( rp.connected() );
00375 BOOST_CHECK( wp1.connected() );
00376 BOOST_CHECK( wp2.connected() );
00377 BOOST_CHECK( wp3.connected() );
00378
00379 wp1.write(10);
00380 wp1.write(20);
00381 wp1.write(30);
00382 wp1.write(40);
00383 wp1.write(50);
00384
00385 wp2.write(12);
00386 wp2.write(22);
00387 wp2.write(32);
00388 wp2.write(42);
00389 wp2.write(52);
00390
00391 wp3.write(13);
00392 wp3.write(23);
00393 wp3.write(33);
00394 wp3.write(43);
00395 wp3.write(53);
00396
00397 int value = 0;
00398 BOOST_CHECK( rp.read(value));
00399 BOOST_CHECK_EQUAL(10, value);
00400 BOOST_CHECK( rp.read(value));
00401 BOOST_CHECK_EQUAL(20, value);
00402 BOOST_CHECK( rp.read(value));
00403 BOOST_CHECK_EQUAL(30, value);
00404 BOOST_CHECK( rp.read(value));
00405 BOOST_CHECK_EQUAL(40, value);
00406
00407
00408 wp2.disconnect(&rp);
00409 BOOST_CHECK( rp.connected() );
00410 BOOST_CHECK( wp1.connected() );
00411 BOOST_CHECK( !wp2.connected() );
00412 BOOST_CHECK( wp3.connected() );
00413
00414
00415 wp1.write(60);
00416 BOOST_CHECK( rp.read(value));
00417 BOOST_CHECK_EQUAL(60, value);
00418
00419
00420 BOOST_CHECK( rp.read(value));
00421 BOOST_CHECK_EQUAL(13, value);
00422 BOOST_CHECK( rp.read(value));
00423 BOOST_CHECK_EQUAL(23, value);
00424
00425
00426 wp1.write(70);
00427
00428 BOOST_CHECK( rp.read(value));
00429 BOOST_CHECK_EQUAL(33, value);
00430 BOOST_CHECK( rp.read(value));
00431 BOOST_CHECK_EQUAL(43, value);
00432
00433
00434 BOOST_CHECK_EQUAL( rp.read(value), NewData );
00435 BOOST_CHECK_EQUAL(70, value);
00436 value = 0;
00437 BOOST_CHECK_EQUAL( rp.read(value), OldData );
00438 BOOST_CHECK_EQUAL(70, value);
00439
00440
00441 rp.disconnect(&wp1);
00442 rp.disconnect(&wp3);
00443 BOOST_CHECK( !rp.connected() );
00444 BOOST_CHECK( !wp1.connected() );
00445 BOOST_CHECK( !wp2.connected() );
00446 BOOST_CHECK( !wp3.connected() );
00447 BOOST_CHECK_EQUAL( rp.read(value), NoData );
00448 }
00449
00450 BOOST_AUTO_TEST_CASE( testPortObjects)
00451 {
00452 OutputPort<double> wp1("Write");
00453 InputPort<double> rp1("Read");
00454
00455 tc->ports()->addPort( wp1 );
00456 tc->ports()->addPort( rp1 );
00457
00458
00459 BOOST_CHECK( tc->provides("Write") != 0 );
00460 BOOST_CHECK( tc->provides("Read") != 0 );
00461
00462
00463 wp1.write( 1.0 );
00464
00465
00466 wp1.createConnection( rp1 );
00467
00468
00469 OperationCaller<void(double const&)> mset;
00470 OperationCaller<FlowStatus(double&)> mget;
00471
00472 mset = tc->provides("Write")->getOperation("write");
00473 BOOST_CHECK( mset.ready() );
00474
00475 mget = tc->provides("Read")->getOperation("read");
00476 BOOST_CHECK( mget.ready() );
00477
00478 mset( 3.991 );
00479
00480 double get_value = 0;
00481 BOOST_CHECK( mget(get_value) );
00482 BOOST_CHECK_CLOSE( 3.991, get_value, 0.001 );
00483
00485 tc->ports()->removePort("Read");
00486 BOOST_CHECK( tc->provides()->hasService("Read") == 0 );
00487 BOOST_CHECK( tc->ports()->getPort("Read") == 0 );
00488
00489 tc->ports()->removePort("Write");
00490 BOOST_CHECK( tc->provides()->hasService("Write") == 0 );
00491 BOOST_CHECK( tc->ports()->getPort("Write") == 0 );
00492 }
00493
00494 #ifdef ORO_SIGNALLING_PORTS
00495 BOOST_AUTO_TEST_CASE(testPortSignalling)
00496 {
00497 OutputPort<double> wp1("Write");
00498 InputPort<double> rp1("Read");
00499
00500 Handle hl( rp1.getNewDataOnPortEvent()->setup(
00501 boost::bind(&PortsTestFixture::new_data_listener, this, _1) ) );
00502 hl.connect();
00503
00504 wp1.createConnection(rp1, ConnPolicy::data());
00505 signalled_port = 0;
00506 wp1.write(0.1);
00507 BOOST_CHECK(&rp1 == signalled_port);
00508
00509 wp1.disconnect();
00510 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00511 signalled_port = 0;
00512 wp1.write(0.1);
00513 BOOST_CHECK(&rp1 == signalled_port);
00514 signalled_port = 0;
00515 wp1.write(0.1);
00516 BOOST_CHECK(&rp1 == signalled_port);
00517 signalled_port = 0;
00518 wp1.write(0.1);
00519 BOOST_CHECK(0 == signalled_port);
00520 }
00521 #endif
00522
00523 BOOST_AUTO_TEST_CASE(testPortAddRemove)
00524 {
00525 OutputPort<double>* wp1 = new OutputPort<double>("Write");
00526 InputPort<double>* rp1 = new InputPort<double>("Read");
00527 InputPort<double>* ep1 = new InputPort<double>("ERead");
00528 TaskContext tc("tc");
00529 tc.addPort( *wp1 );
00530 tc.addEventPort( *rp1, boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00531 tc.addEventPort( *ep1 );
00532
00533 wp1->createConnection(*rp1, ConnPolicy::data());
00534 wp1->createConnection(*ep1, ConnPolicy::data());
00535
00536 tc.start();
00537 wp1->write(0.1);
00538 tc.stop();
00539
00540 tc.ports()->removePort("Write");
00541 tc.ports()->removePort("Read");
00542 tc.ports()->removePort("ERead");
00543
00544 wp1->write(0.1);
00545
00546 delete wp1;
00547 delete rp1;
00548 delete ep1;
00549
00550 tc.start();
00551 tc.stop();
00552
00553 wp1 = new OutputPort<double>("Write");
00554 rp1 = new InputPort<double>("Read");
00555 ep1 = new InputPort<double>("ERead");
00556
00557 tc.addPort( *wp1 );
00558 tc.addEventPort( *rp1, boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00559 tc.addEventPort( *ep1 );
00560
00561 wp1->createConnection(*rp1, ConnPolicy::data());
00562 wp1->createConnection(*ep1, ConnPolicy::data());
00563
00564 tc.start();
00565 wp1->write(0.1);
00566 tc.stop();
00567
00568 tc.ports()->removePort("Write");
00569 tc.ports()->removePort("Read");
00570 tc.ports()->removePort("ERead");
00571
00572 wp1->write(0.1);
00573
00574 delete wp1;
00575 delete rp1;
00576 delete ep1;
00577
00578 tc.start();
00579 tc.stop();
00580 }
00581
00582 BOOST_AUTO_TEST_CASE(testEventPortSignalling)
00583 {
00584 OutputPort<double> wp1("Write");
00585 InputPort<double> rp1("Read");
00586
00587 tce->start();
00588 tce->resetStats();
00589
00590 tce->addEventPort(rp1,boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00591
00592
00593
00594 wp1.createConnection(rp1, ConnPolicy::data());
00595 signalled_port = 0;
00596 wp1.write(0.1);
00597 BOOST_CHECK(&rp1 == signalled_port);
00598 BOOST_CHECK(tce->had_event);
00599 tce->resetStats();
00600
00601 wp1.disconnect();
00602 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00603
00604 signalled_port = 0;
00605 wp1.write(0.1);
00606 BOOST_CHECK(&rp1 == signalled_port);
00607 BOOST_CHECK(tce->had_event);
00608 tce->resetStats();
00609 signalled_port = 0;
00610 wp1.write(0.1);
00611 BOOST_CHECK(&rp1 == signalled_port);
00612 BOOST_CHECK(tce->had_event);
00613 tce->resetStats();
00614 signalled_port = 0;
00615
00616 wp1.write(0.1);
00617 BOOST_CHECK(0 == signalled_port);
00618 BOOST_CHECK( !tce->had_event);
00619 tce->resetStats();
00620
00621
00622 tce->ports()->removePort( rp1.getName() );
00623 }
00624
00625 BOOST_AUTO_TEST_CASE(testPlainPortNotSignalling)
00626 {
00627 OutputPort<double> wp1("Write");
00628 InputPort<double> rp1("Read");
00629
00630 tce->start();
00631 tce->resetStats();
00632
00633 tce->addPort(rp1);
00634
00635 wp1.createConnection(rp1, ConnPolicy::data());
00636 wp1.write(0.1);
00637 BOOST_CHECK( !tce->had_event );
00638 tce->resetStats();
00639
00640 wp1.disconnect();
00641 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00642 wp1.write(0.1);
00643 BOOST_CHECK( !tce->had_event );
00644
00645
00646 tce->ports()->removePort( rp1.getName() );
00647 }
00648
00649 BOOST_AUTO_TEST_CASE(testPortDataSource)
00650 {
00651 OutputPort<int> wp1("Write");
00652 auto_ptr<InputPortInterface> reader(dynamic_cast<InputPortInterface*>(wp1.antiClone()));
00653 BOOST_CHECK(wp1.connectTo(&*reader, ConnPolicy::buffer(2)));
00654
00655 DataSource<int>::shared_ptr source = static_cast< DataSource<int>* >(reader->getDataSource());
00656 BOOST_CHECK(source);
00657
00658 BOOST_CHECK(!source->evaluate());
00659 wp1.write(10);
00660 wp1.write(20);
00661
00662 BOOST_CHECK_EQUAL(0, source->value());
00663
00664
00665 BOOST_CHECK(source->evaluate());
00666 BOOST_CHECK_EQUAL(10, source->value());
00667 BOOST_CHECK_EQUAL(10, source->value());
00668
00669
00670 BOOST_CHECK_EQUAL(20, source->get());
00671
00672
00673 BOOST_CHECK(!source->evaluate());
00674 BOOST_CHECK_EQUAL(0, source->get());
00675 BOOST_CHECK_EQUAL(20, source->value());
00676 }
00677
00678 BOOST_AUTO_TEST_SUITE_END()
00679