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 BOOST_AUTO_TEST_CASE(testPortSignalling)
00487 {
00488 OutputPort<double> wp1("Write");
00489 InputPort<double> rp1("Read");
00490
00491 Handle hl( rp1.getNewDataOnPortEvent()->setup(
00492 boost::bind(&PortsTestFixture::new_data_listener, this, _1) ) );
00493 hl.connect();
00494
00495 wp1.createConnection(rp1, ConnPolicy::data());
00496 signalled_port = 0;
00497 wp1.write(0.1);
00498 BOOST_CHECK(&rp1 == signalled_port);
00499
00500 wp1.disconnect();
00501 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00502 signalled_port = 0;
00503 wp1.write(0.1);
00504 BOOST_CHECK(&rp1 == signalled_port);
00505 signalled_port = 0;
00506 wp1.write(0.1);
00507 BOOST_CHECK(&rp1 == signalled_port);
00508 signalled_port = 0;
00509 wp1.write(0.1);
00510 BOOST_CHECK(0 == signalled_port);
00511 }
00512
00513 BOOST_AUTO_TEST_CASE(testPortAddRemove)
00514 {
00515 OutputPort<double>* wp1 = new OutputPort<double>("Write");
00516 InputPort<double>* rp1 = new InputPort<double>("Read");
00517 InputPort<double>* ep1 = new InputPort<double>("ERead");
00518 TaskContext tc("tc");
00519 tc.addPort( *wp1 );
00520 tc.addPort( *rp1 );
00521 tc.addEventPort( *ep1 );
00522
00523 Handle hl( rp1->getNewDataOnPortEvent()->setup(
00524 boost::bind(&PortsTestFixture::new_data_listener, this, _1) ) );
00525 hl.connect();
00526
00527 wp1->createConnection(*rp1, ConnPolicy::data());
00528 wp1->createConnection(*ep1, ConnPolicy::data());
00529
00530 tc.start();
00531 wp1->write(0.1);
00532 tc.stop();
00533
00534 tc.ports()->removePort("Write");
00535 tc.ports()->removePort("Read");
00536 tc.ports()->removePort("ERead");
00537
00538 wp1->write(0.1);
00539
00540 delete wp1;
00541 delete rp1;
00542 delete ep1;
00543
00544 tc.start();
00545 tc.stop();
00546
00547 wp1 = new OutputPort<double>("Write");
00548 rp1 = new InputPort<double>("Read");
00549 ep1 = new InputPort<double>("ERead");
00550
00551 tc.addPort( *wp1 );
00552 tc.addPort( *rp1 );
00553 tc.addEventPort( *ep1 );
00554
00555 hl = rp1->getNewDataOnPortEvent()->setup(
00556 boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00557 hl.connect();
00558
00559 wp1->createConnection(*rp1, ConnPolicy::data());
00560 wp1->createConnection(*ep1, ConnPolicy::data());
00561
00562 tc.start();
00563 wp1->write(0.1);
00564 tc.stop();
00565
00566 tc.ports()->removePort("Write");
00567 tc.ports()->removePort("Read");
00568 tc.ports()->removePort("ERead");
00569
00570 wp1->write(0.1);
00571
00572 delete wp1;
00573 delete rp1;
00574 delete ep1;
00575
00576 tc.start();
00577 tc.stop();
00578 }
00579
00580 BOOST_AUTO_TEST_CASE(testEventPortSignalling)
00581 {
00582 OutputPort<double> wp1("Write");
00583 InputPort<double> rp1("Read");
00584
00585 tce->start();
00586
00587 tce->addEventPort(rp1,boost::bind(&PortsTestFixture::new_data_listener, this, _1) );
00588
00589
00590
00591 wp1.createConnection(rp1, ConnPolicy::data());
00592 signalled_port = 0;
00593 wp1.write(0.1);
00594 BOOST_CHECK(&rp1 == signalled_port);
00595 BOOST_CHECK(tce->had_event);
00596 tce->resetStats();
00597
00598 wp1.disconnect();
00599 wp1.createConnection(rp1, ConnPolicy::buffer(2));
00600
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 wp1.write(0.1);
00608 BOOST_CHECK(&rp1 == signalled_port);
00609 BOOST_CHECK(tce->had_event);
00610 tce->resetStats();
00611 signalled_port = 0;
00612
00613 wp1.write(0.1);
00614 BOOST_CHECK(0 == signalled_port);
00615 BOOST_CHECK( !tce->had_event);
00616 tce->resetStats();
00617 }
00618
00619 BOOST_AUTO_TEST_CASE(testPortDataSource)
00620 {
00621 OutputPort<int> wp1("Write");
00622 auto_ptr<InputPortInterface> reader(dynamic_cast<InputPortInterface*>(wp1.antiClone()));
00623 BOOST_CHECK(wp1.connectTo(&*reader, ConnPolicy::buffer(2)));
00624
00625 DataSource<int>::shared_ptr source = static_cast< DataSource<int>* >(reader->getDataSource());
00626 BOOST_CHECK(source);
00627
00628 BOOST_CHECK(!source->evaluate());
00629 wp1.write(10);
00630 wp1.write(20);
00631
00632 BOOST_CHECK_EQUAL(0, source->value());
00633
00634
00635 BOOST_CHECK(source->evaluate());
00636 BOOST_CHECK_EQUAL(10, source->value());
00637 BOOST_CHECK_EQUAL(10, source->value());
00638
00639
00640 BOOST_CHECK_EQUAL(20, source->get());
00641
00642
00643 BOOST_CHECK(!source->evaluate());
00644 BOOST_CHECK_EQUAL(0, source->get());
00645 BOOST_CHECK_EQUAL(20, source->value());
00646 }
00647
00648 BOOST_AUTO_TEST_SUITE_END()
00649