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
00120 {
00121 auto_ptr<TaskContext> tc1(new TaskContext( "tc", TaskContext::Stopped ));
00122 auto_ptr<TaskContext> tc2(new TaskContext( "tc2", TaskContext::Stopped ));
00123
00124 tc1->ports()->addPort( rp1 );
00125 tc1->ports()->addPort( wp2 );
00126 tc2->ports()->addPort( rp2 );
00127 tc2->ports()->addPort( wp1 );
00128
00129 BOOST_CHECK( tc1->connectPorts(tc2.get()) );
00130 BOOST_CHECK( wp1.connected() );
00131 BOOST_CHECK( rp1.connected() );
00132 wp1.write(2);
00133 int value = 0;
00134 BOOST_CHECK( rp1.read(value) );
00135 BOOST_CHECK_EQUAL(2, value);
00136
00137 BOOST_CHECK( wp2.connected() );
00138 BOOST_CHECK( rp2.connected() );
00139 wp2.write(3);
00140 value = 0;
00141 BOOST_CHECK( rp2.read(value) );
00142 BOOST_CHECK_EQUAL(3, value);
00143 }
00144
00145
00146
00147 BOOST_CHECK( rp1.connected() );
00148 BOOST_CHECK( rp2.connected() );
00149 BOOST_CHECK( wp1.connected() );
00150 BOOST_CHECK( wp2.connected() );
00151 }
00152
00153 BOOST_AUTO_TEST_CASE(testPortConnectionInitialization)
00154 {
00155 OutputPort<int> wp("WriterName", true);
00156 InputPort<int> rp("ReaderName", ConnPolicy::data(true));
00157
00158 BOOST_CHECK( wp.createConnection(rp) );
00159 int value = 0;
00160 BOOST_CHECK( !rp.read(value) );
00161 BOOST_CHECK( !wp.getLastWrittenValue(value) );
00162 wp.write(10);
00163 BOOST_CHECK( rp.read(value) );
00164 BOOST_CHECK_EQUAL( 10, value );
00165
00166 wp.disconnect(&rp);
00167 BOOST_CHECK( !wp.connected() );
00168 BOOST_CHECK( !rp.connected() );
00169
00170 value = 0;
00171 BOOST_CHECK( wp.getLastWrittenValue(value) );
00172 BOOST_CHECK_EQUAL( 10, value );
00173 BOOST_CHECK_EQUAL( 10, wp.getLastWrittenValue() );
00174
00175 value = 0;
00176 BOOST_CHECK( wp.createConnection(rp) );
00177 BOOST_CHECK( rp.read(value) );
00178 BOOST_CHECK_EQUAL( 10, value );
00179
00180 }
00181
00182 BOOST_AUTO_TEST_CASE(testPortSimpleConnections)
00183 {
00184 OutputPort<int> wp("WriterName");
00185 InputPort<int> rp("ReaderName", ConnPolicy::data(ConnPolicy::LOCK_FREE, false));
00186
00187 BOOST_CHECK( !wp.connected() );
00188 BOOST_CHECK( !rp.connected() );
00189 {
00190 int value;
00191 BOOST_CHECK( !rp.read(value) );
00192 wp.write(value);
00193 }
00194
00195 BOOST_REQUIRE( wp.createConnection(rp) );
00196 BOOST_CHECK( wp.connected() );
00197 BOOST_CHECK( rp.connected() );
00198
00199 {
00200 int value = 0;
00201 BOOST_CHECK( !rp.read(value) );
00202 wp.write(1);
00203 BOOST_CHECK( rp.read(value) );
00204 BOOST_CHECK( 1 == value );
00205 }
00206
00207 rp.clear();
00208 {
00209 int value = 0;
00210 BOOST_CHECK( !rp.read(value) );
00211 wp.write(1);
00212 BOOST_CHECK( rp.read(value) );
00213 BOOST_CHECK( 1 == value );
00214 }
00215
00216
00217
00218 wp.disconnect();
00219 BOOST_CHECK( !wp.connected() );
00220 BOOST_CHECK( !rp.connected() );
00221 {
00222 int value;
00223 wp.write(value);
00224 BOOST_CHECK( !rp.read(value) );
00225 }
00226 wp.disconnect();
00227
00228 {
00229 int value = 0;
00230 BOOST_CHECK( !rp.read(value) );
00231 wp.createBufferConnection(rp, 4);
00232 BOOST_CHECK( !rp.read(value) );
00233 wp.write(1);
00234 wp.write(2);
00235 wp.write(3);
00236 wp.write(4);
00237 wp.write(5);
00238 BOOST_CHECK_EQUAL(0, value);
00239 BOOST_CHECK( rp.read(value) );
00240 BOOST_CHECK_EQUAL(1, value);
00241 BOOST_CHECK( rp.read(value) );
00242 BOOST_CHECK_EQUAL(2, value);
00243
00244 rp.clear();
00245 BOOST_CHECK_EQUAL( rp.read(value), NoData );
00246 wp.write(10);
00247 wp.write(20);
00248 BOOST_CHECK( rp.read(value) );
00249 BOOST_CHECK_EQUAL(10, value);
00250 BOOST_CHECK( rp.read(value) );
00251 BOOST_CHECK_EQUAL(20, value);
00252 BOOST_CHECK_EQUAL( rp.read(value), OldData );
00253 }
00254
00255
00256 rp.disconnect();
00257 BOOST_CHECK( !wp.connected() );
00258 BOOST_CHECK( !rp.connected() );
00259 {
00260 int value;
00261 wp.write(value);
00262 BOOST_CHECK( !rp.read(value) );
00263 }
00264 rp.disconnect();
00265
00266
00267 {
00268 InputPort<int> rp("ReaderName", ConnPolicy::data());
00269 BOOST_CHECK(wp.createConnection(rp));
00270 BOOST_CHECK( wp.connected() );
00271 BOOST_CHECK( rp.connected() );
00272 }
00273 BOOST_CHECK( !wp.connected() );
00274 }
00275
00276 BOOST_AUTO_TEST_CASE(testPortOneWriterThreeReaders)
00277 {
00278 OutputPort<int> wp("W");
00279 InputPort<int> rp1("R1", ConnPolicy::data());
00280 InputPort<int> rp2("R2", ConnPolicy::buffer(4));
00281 InputPort<int> rp3("R3", ConnPolicy::data());
00282
00283 wp.createConnection(rp1);
00284 BOOST_CHECK( wp.connected() );
00285 BOOST_CHECK( rp1.connected() );
00286 BOOST_CHECK( !rp2.connected() );
00287 BOOST_CHECK( !rp3.connected() );
00288 wp.createConnection(rp2);
00289 BOOST_CHECK( wp.connected() );
00290 BOOST_CHECK( rp1.connected() );
00291 BOOST_CHECK( rp2.connected() );
00292 BOOST_CHECK( !rp3.connected() );
00293 wp.createConnection(rp3);
00294 BOOST_CHECK( wp.connected() );
00295 BOOST_CHECK( rp1.connected() );
00296 BOOST_CHECK( rp2.connected() );
00297 BOOST_CHECK( rp3.connected() );
00298
00299 wp.write(10);
00300 wp.write(15);
00301 wp.write(20);
00302 wp.write(25);
00303 wp.write(30);
00304
00305 int value = 0;
00306 BOOST_CHECK( rp1.read(value));
00307 BOOST_CHECK_EQUAL(30, value);
00308
00309 BOOST_CHECK( rp2.read(value));
00310 BOOST_CHECK_EQUAL(10, value);
00311 BOOST_CHECK( rp2.read(value));
00312 BOOST_CHECK_EQUAL(15, value);
00313 BOOST_CHECK( rp2.read(value));
00314 BOOST_CHECK_EQUAL(20, value);
00315 BOOST_CHECK( rp2.read(value));
00316 BOOST_CHECK_EQUAL(25, value);
00317 BOOST_CHECK_EQUAL( rp2.read(value), OldData);
00318
00319 BOOST_CHECK( rp3.read(value));
00320 BOOST_CHECK_EQUAL(30, value);
00321
00322
00323 wp.disconnect(&rp2);
00324 BOOST_CHECK_EQUAL( rp2.read(value), NoData );
00325 BOOST_CHECK( wp.connected() );
00326 BOOST_CHECK( rp1.connected() );
00327 BOOST_CHECK( !rp2.connected() );
00328 BOOST_CHECK( rp3.connected() );
00329
00330 wp.write(10);
00331 BOOST_CHECK( rp1.read(value));
00332 BOOST_CHECK_EQUAL(10, value);
00333 BOOST_CHECK( rp3.read(value));
00334 BOOST_CHECK_EQUAL(10, value);
00335
00336
00337 wp.disconnect(&rp1);
00338 wp.disconnect(&rp3);
00339 BOOST_CHECK( !wp.connected() );
00340 BOOST_CHECK( !rp1.connected() );
00341 BOOST_CHECK( !rp2.connected() );
00342 BOOST_CHECK( !rp3.connected() );
00343 BOOST_CHECK_EQUAL( rp1.read(value), NoData );
00344 BOOST_CHECK_EQUAL( rp2.read(value), NoData );
00345 BOOST_CHECK_EQUAL( rp3.read(value), NoData );
00346 }
00347
00348 BOOST_AUTO_TEST_CASE(testPortThreeWritersOneReader)
00349 {
00350 OutputPort<int> wp1("W1");
00351 OutputPort<int> wp2("W2");
00352 OutputPort<int> wp3("W3");
00353 InputPort<int> rp("R", ConnPolicy::buffer(4));
00354
00355 wp1.createConnection(rp);
00356 BOOST_CHECK( wp1.connected() );
00357 BOOST_CHECK( rp.connected() );
00358 BOOST_CHECK( !wp2.connected() );
00359 BOOST_CHECK( !wp3.connected() );
00360 wp2.createConnection(rp);
00361 BOOST_CHECK( rp.connected() );
00362 BOOST_CHECK( wp1.connected() );
00363 BOOST_CHECK( wp2.connected() );
00364 BOOST_CHECK( !wp3.connected() );
00365 wp3.createConnection(rp);
00366 BOOST_CHECK( rp.connected() );
00367 BOOST_CHECK( wp1.connected() );
00368 BOOST_CHECK( wp2.connected() );
00369 BOOST_CHECK( wp3.connected() );
00370
00371 wp1.write(10);
00372 wp1.write(20);
00373 wp1.write(30);
00374 wp1.write(40);
00375 wp1.write(50);
00376
00377 wp2.write(12);
00378 wp2.write(22);
00379 wp2.write(32);
00380 wp2.write(42);
00381 wp2.write(52);
00382
00383 wp3.write(13);
00384 wp3.write(23);
00385 wp3.write(33);
00386 wp3.write(43);
00387 wp3.write(53);
00388
00389 int value = 0;
00390 BOOST_CHECK( rp.read(value));
00391 BOOST_CHECK_EQUAL(10, value);
00392 BOOST_CHECK( rp.read(value));
00393 BOOST_CHECK_EQUAL(20, value);
00394 BOOST_CHECK( rp.read(value));
00395 BOOST_CHECK_EQUAL(30, value);
00396 BOOST_CHECK( rp.read(value));
00397 BOOST_CHECK_EQUAL(40, value);
00398
00399
00400 wp2.disconnect(&rp);
00401 BOOST_CHECK( rp.connected() );
00402 BOOST_CHECK( wp1.connected() );
00403 BOOST_CHECK( !wp2.connected() );
00404 BOOST_CHECK( wp3.connected() );
00405
00406
00407 wp1.write(60);
00408 BOOST_CHECK( rp.read(value));
00409 BOOST_CHECK_EQUAL(60, value);
00410
00411
00412 BOOST_CHECK( rp.read(value));
00413 BOOST_CHECK_EQUAL(13, value);
00414 BOOST_CHECK( rp.read(value));
00415 BOOST_CHECK_EQUAL(23, value);
00416
00417
00418 wp1.write(70);
00419
00420 BOOST_CHECK( rp.read(value));
00421 BOOST_CHECK_EQUAL(33, value);
00422 BOOST_CHECK( rp.read(value));
00423 BOOST_CHECK_EQUAL(43, value);
00424
00425
00426 BOOST_CHECK_EQUAL( rp.read(value), NewData );
00427 BOOST_CHECK_EQUAL(70, value);
00428 value = 0;
00429 BOOST_CHECK_EQUAL( rp.read(value), OldData );
00430 BOOST_CHECK_EQUAL(70, value);
00431
00432
00433 rp.disconnect(&wp1);
00434 rp.disconnect(&wp3);
00435 BOOST_CHECK( !rp.connected() );
00436 BOOST_CHECK( !wp1.connected() );
00437 BOOST_CHECK( !wp2.connected() );
00438 BOOST_CHECK( !wp3.connected() );
00439 BOOST_CHECK_EQUAL( rp.read(value), NoData );
00440 }
00441
00442 BOOST_AUTO_TEST_CASE( testPortObjects)
00443 {
00444 OutputPort<double> wp1("Write");
00445 InputPort<double> rp1("Read");
00446
00447 tc->ports()->addPort( wp1 );
00448 tc->ports()->addPort( rp1 );
00449
00450
00451 BOOST_CHECK( tc->provides("Write") != 0 );
00452 BOOST_CHECK( tc->provides("Read") != 0 );
00453
00454
00455 wp1.write( 1.0 );
00456
00457
00458 wp1.createConnection( rp1 );
00459
00460
00461 OperationCaller<void(double const&)> mset;
00462 OperationCaller<FlowStatus(double&)> mget;
00463
00464 mset = tc->provides("Write")->getOperation("write");
00465 BOOST_CHECK( mset.ready() );
00466
00467 mget = tc->provides("Read")->getOperation("read");
00468 BOOST_CHECK( mget.ready() );
00469
00470 mset( 3.991 );
00471
00472 double get_value = 0;
00473 BOOST_CHECK( mget(get_value) );
00474 BOOST_CHECK_CLOSE( 3.991, get_value, 0.001 );
00475
00477 tc->ports()->removePort("Reader");
00478 BOOST_CHECK( tc->provides()->hasService("Reader") == 0 );
00479 BOOST_CHECK( tc->ports()->getPort("Reader") == 0 );
00480
00481 tc->ports()->removePort("Writer");
00482 BOOST_CHECK( tc->provides()->hasService("Writer") == 0 );
00483 BOOST_CHECK( tc->ports()->getPort("Writer") == 0 );
00484 }
00485
00486 #ifdef ORO_SIGNALLING_PORTS
00487 BOOST_AUTO_TEST_CASE(testPortSignalling)
00488 {
00489 OutputPort<double> wp1("Write");
00490 InputPort<double> rp1("Read");
00491
00492 Handle hl( rp1.getNewDataOnPortEvent()->setup(
00493 boost::bind(&PortsTestFixture::new_data_listener, this, _1) ) );
00494 hl.connect();
00495
00496 wp1.createConnection(rp1, ConnPolicy::data());
00497 signalled_port = 0;
00498 wp1.write(0.1);
00499 BOOST_CHECK(&rp1 == signalled_port);
00500
00501 wp1.disconnect();
00502 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00503 signalled_port = 0;
00504 wp1.write(0.1);
00505 BOOST_CHECK(&rp1 == signalled_port);
00506 signalled_port = 0;
00507 wp1.write(0.1);
00508 BOOST_CHECK(&rp1 == signalled_port);
00509 signalled_port = 0;
00510 wp1.write(0.1);
00511 BOOST_CHECK(0 == signalled_port);
00512 }
00513 #endif
00514
00515 BOOST_AUTO_TEST_CASE(testPortAddRemove)
00516 {
00517 OutputPort<double>* wp1 = new OutputPort<double>("Write");
00518 InputPort<double>* rp1 = new InputPort<double>("Read");
00519 InputPort<double>* ep1 = new InputPort<double>("ERead");
00520 TaskContext tc("tc");
00521 tc.addPort( *wp1 );
00522 tc.addEventPort( *rp1, boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00523 tc.addEventPort( *ep1 );
00524
00525 wp1->createConnection(*rp1, ConnPolicy::data());
00526 wp1->createConnection(*ep1, ConnPolicy::data());
00527
00528 tc.start();
00529 wp1->write(0.1);
00530 tc.stop();
00531
00532 tc.ports()->removePort("Write");
00533 tc.ports()->removePort("Read");
00534 tc.ports()->removePort("ERead");
00535
00536 wp1->write(0.1);
00537
00538 delete wp1;
00539 delete rp1;
00540 delete ep1;
00541
00542 tc.start();
00543 tc.stop();
00544
00545 wp1 = new OutputPort<double>("Write");
00546 rp1 = new InputPort<double>("Read");
00547 ep1 = new InputPort<double>("ERead");
00548
00549 tc.addPort( *wp1 );
00550 tc.addEventPort( *rp1, boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00551 tc.addEventPort( *ep1 );
00552
00553 wp1->createConnection(*rp1, ConnPolicy::data());
00554 wp1->createConnection(*ep1, ConnPolicy::data());
00555
00556 tc.start();
00557 wp1->write(0.1);
00558 tc.stop();
00559
00560 tc.ports()->removePort("Write");
00561 tc.ports()->removePort("Read");
00562 tc.ports()->removePort("ERead");
00563
00564 wp1->write(0.1);
00565
00566 delete wp1;
00567 delete rp1;
00568 delete ep1;
00569
00570 tc.start();
00571 tc.stop();
00572 }
00573
00574 BOOST_AUTO_TEST_CASE(testEventPortSignalling)
00575 {
00576 OutputPort<double> wp1("Write");
00577 InputPort<double> rp1("Read");
00578
00579 tce->start();
00580 tce->resetStats();
00581
00582 tce->addEventPort(rp1,boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00583
00584
00585
00586 wp1.createConnection(rp1, ConnPolicy::data());
00587 signalled_port = 0;
00588 wp1.write(0.1);
00589 BOOST_CHECK(&rp1 == signalled_port);
00590 BOOST_CHECK(tce->had_event);
00591 tce->resetStats();
00592
00593 wp1.disconnect();
00594 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00595
00596 signalled_port = 0;
00597 wp1.write(0.1);
00598 BOOST_CHECK(&rp1 == signalled_port);
00599 BOOST_CHECK(tce->had_event);
00600 tce->resetStats();
00601 signalled_port = 0;
00602 wp1.write(0.1);
00603 BOOST_CHECK(&rp1 == signalled_port);
00604 BOOST_CHECK(tce->had_event);
00605 tce->resetStats();
00606 signalled_port = 0;
00607
00608 wp1.write(0.1);
00609 BOOST_CHECK(0 == signalled_port);
00610 BOOST_CHECK( !tce->had_event);
00611 tce->resetStats();
00612 }
00613
00614 BOOST_AUTO_TEST_CASE(testPlainPortNotSignalling)
00615 {
00616 OutputPort<double> wp1("Write");
00617 InputPort<double> rp1("Read");
00618
00619 tce->start();
00620 tce->resetStats();
00621
00622 tce->addPort(rp1);
00623
00624 wp1.createConnection(rp1, ConnPolicy::data());
00625 wp1.write(0.1);
00626 BOOST_CHECK( !tce->had_event );
00627 tce->resetStats();
00628
00629 wp1.disconnect();
00630 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00631 wp1.write(0.1);
00632 BOOST_CHECK( !tce->had_event );
00633 }
00634
00635 BOOST_AUTO_TEST_CASE(testPortDataSource)
00636 {
00637 OutputPort<int> wp1("Write");
00638 auto_ptr<InputPortInterface> reader(dynamic_cast<InputPortInterface*>(wp1.antiClone()));
00639 BOOST_CHECK(wp1.connectTo(&*reader, ConnPolicy::buffer(2)));
00640
00641 DataSource<int>::shared_ptr source = static_cast< DataSource<int>* >(reader->getDataSource());
00642 BOOST_CHECK(source);
00643
00644 BOOST_CHECK(!source->evaluate());
00645 wp1.write(10);
00646 wp1.write(20);
00647
00648 BOOST_CHECK_EQUAL(0, source->value());
00649
00650
00651 BOOST_CHECK(source->evaluate());
00652 BOOST_CHECK_EQUAL(10, source->value());
00653 BOOST_CHECK_EQUAL(10, source->value());
00654
00655
00656 BOOST_CHECK_EQUAL(20, source->get());
00657
00658
00659 BOOST_CHECK(!source->evaluate());
00660 BOOST_CHECK_EQUAL(0, source->get());
00661 BOOST_CHECK_EQUAL(20, source->value());
00662 }
00663
00664 BOOST_AUTO_TEST_SUITE_END()
00665