00001
00022 #ifndef InPortPullConnector_cpp
00023 #define InPortPullConnector_cpp
00024
00025 #include <cppunit/ui/text/TestRunner.h>
00026 #include <cppunit/TextOutputter.h>
00027 #include <cppunit/extensions/TestFactoryRegistry.h>
00028 #include <cppunit/extensions/HelperMacros.h>
00029 #include <cppunit/TestAssert.h>
00030
00031 #include <coil/Properties.h>
00032
00033 #include <rtm/idl/BasicDataTypeSkel.h>
00034 #include <rtm/idl/DataPortSkel.h>
00035 #include <rtm/Typename.h>
00036 #include <rtm/InPortPullConnector.h>
00037 #include <rtm/CdrBufferBase.h>
00038 #include <rtm/CORBA_SeqUtil.h>
00039 #include <rtm/NVUtil.h>
00040 #include <rtm/ConnectorBase.h>
00041 #include <rtm/DataPortStatus.h>
00042 #include <rtm/InPortBase.h>
00043 #include <rtm/InPortConsumer.h>
00044 #include <rtm/OutPortBase.h>
00045 #include <rtm/PortAdmin.h>
00046 #include <rtm/CorbaConsumer.h>
00047 #include <rtm/PublisherBase.h>
00048 #include <rtm/BufferBase.h>
00049 #include <rtm/OutPortConsumer.h>
00050 #include <rtm/Manager.h>
00051
00056 namespace InPortPullConnector
00057 {
00058
00059 class DataListener
00060 : public RTC::ConnectorDataListenerT<RTC::TimedLong>
00061 {
00062 public:
00063 DataListener(const char* name) : m_name(name) {}
00064 virtual ~DataListener()
00065 {
00066
00067 }
00068
00069 virtual void operator()(const RTC::ConnectorInfo& info,
00070 const RTC::TimedLong& data)
00071 {
00072
00073
00074
00075
00076 };
00077 std::string m_name;
00078 };
00079
00080
00081 class ConnListener
00082 : public RTC::ConnectorListener
00083 {
00084 public:
00085 ConnListener(const char* name) : m_name(name) {}
00086 virtual ~ConnListener()
00087 {
00088
00089 }
00090
00091 virtual void operator()(const RTC::ConnectorInfo& info)
00092 {
00093 std::cout << "------------------------------" << std::endl;
00094 std::cout << "Connector Listener: " << m_name << std::endl;
00095 std::cout << "Profile::name: " << info.name << std::endl;
00096 std::cout << "------------------------------" << std::endl;
00097 };
00098 std::string m_name;
00099 };
00100
00106 class Logger
00107 {
00108 public:
00109 void log(const std::string& msg)
00110 {
00111
00112 m_log.push_back(msg);
00113 }
00114
00115 int countLog(const std::string& msg)
00116 {
00117 int count = 0;
00118 for (int i = 0; i < (int) m_log.size(); ++i)
00119 {
00120 if (m_log[i] == msg) ++count;
00121 }
00122 return count;
00123 }
00124
00125 private:
00126 std::vector<std::string> m_log;
00127 };
00133 template <class DataType>
00134 class RingBufferMock
00135 : public RTC::BufferBase<DataType>
00136 {
00137 public:
00138 BUFFERSTATUS_ENUM
00139 RingBufferMock(long int length = 8)
00140 {
00141 m_logger = NULL;
00142 logger.log("RingBufferMock::Constructor");
00143 m_read_return_value = BUFFER_OK;
00144 m_write_return_value = BUFFER_OK;
00145 }
00146 virtual ~RingBufferMock(void)
00147 {
00148 }
00149
00150
00155 void set_read_return_value(::RTC::BufferStatus::Enum value)
00156 {
00157 m_read_return_value = value;
00158 }
00163 void set_write_return_value(::RTC::BufferStatus::Enum value)
00164 {
00165 m_write_return_value = value;
00166 }
00171 virtual void init(const coil::Properties& prop)
00172 {
00173 }
00178 virtual size_t length(void) const
00179 {
00180 return 0;
00181 }
00186 virtual ReturnCode length(size_t n)
00187 {
00188 return ::RTC::BufferStatus::BUFFER_OK;
00189 }
00194 virtual ReturnCode reset()
00195 {
00196 return ::RTC::BufferStatus::BUFFER_OK;
00197 }
00202 virtual DataType* wptr(long int n = 0)
00203 {
00204 return &m_data;
00205 }
00210 virtual ReturnCode advanceWptr(long int n = 1)
00211 {
00212 return ::RTC::BufferStatus::BUFFER_OK;
00213 }
00218 virtual ReturnCode put(const DataType& value)
00219 {
00220 return ::RTC::BufferStatus::BUFFER_OK;
00221 }
00226 virtual ReturnCode write(const DataType& value,
00227 long int sec = -1, long int nsec = -1)
00228 {
00229 if (m_logger != NULL)
00230 {
00231 m_logger->log("RingBufferMock::write");
00232 }
00233 logger.log("RingBufferMock::write");
00234 return m_write_return_value;
00235 }
00240 virtual size_t writable() const
00241 {
00242 return 0;
00243 }
00248 virtual bool full(void) const
00249 {
00250 return true;
00251 }
00256 virtual DataType* rptr(long int n = 0)
00257 {
00258 return &m_data;
00259 }
00264 virtual ReturnCode advanceRptr(long int n = 1)
00265 {
00266 return ::RTC::BufferStatus::BUFFER_OK;
00267 }
00272 virtual ReturnCode get(DataType& value)
00273 {
00274 return ::RTC::BufferStatus::BUFFER_OK;
00275 }
00280 virtual DataType& get()
00281 {
00282 return m_data;
00283 }
00288 virtual ReturnCode read(DataType& value,
00289 long int sec = -1, long int nsec = -1)
00290 {
00291 if (m_logger != NULL)
00292 {
00293 m_logger->log("RingBufferMock::read");
00294 }
00295 logger.log("RingBufferMock::read");
00296 return m_read_return_value;
00297 }
00302 virtual size_t readable() const
00303 {
00304 return 0;
00305 }
00310 virtual bool empty(void) const
00311 {
00312 return true;
00313 }
00318 void setLogger(Logger* logger)
00319 {
00320 m_logger = logger;
00321 }
00322
00323 static Logger logger;
00324 private:
00325 DataType m_data;
00326 std::vector<DataType> m_buffer;
00327 Logger* m_logger;
00328 ::RTC::BufferStatus::Enum m_read_return_value;
00329 ::RTC::BufferStatus::Enum m_write_return_value;
00330 };
00331
00332 template <class DataType>
00333 Logger RingBufferMock<DataType>::logger;
00334 typedef RingBufferMock<cdrMemoryStream> CdrRingBufferMock;
00335
00341 class OutPortCorbaCdrConsumerMock
00342 : public RTC::OutPortConsumer,
00343 public RTC::CorbaConsumer< ::OpenRTM::OutPortCdr >
00344 {
00345
00346 public:
00347 OutPortCorbaCdrConsumerMock(void)
00348 {
00349 m_logger = NULL;
00350 }
00351 virtual ~OutPortCorbaCdrConsumerMock(void)
00352 {
00353 }
00358 void setBuffer(RTC::BufferBase<cdrMemoryStream>* buffer)
00359 {
00360 if (m_logger != NULL)
00361 {
00362 m_logger->log("OutPortCorbaCdrConsumerMock::setBuffer");
00363 }
00364 }
00369 ::OpenRTM::PortStatus put(const ::OpenRTM::CdrData& data)
00370 throw (CORBA::SystemException)
00371 {
00372 return ::OpenRTM::PORT_OK;
00373 }
00378 void init(coil::Properties& prop)
00379 {
00380 if (m_logger != NULL)
00381 {
00382 m_logger->log("OutPortCorbaCdrConsumerMock::init");
00383 }
00384 }
00389 RTC::OutPortConsumer::ReturnCode put(const cdrMemoryStream& data)
00390 {
00391 return PORT_OK;
00392 }
00397 void publishInterfaceProfile(SDOPackage::NVList& properties)
00398 {
00399 return;
00400 }
00401
00406 bool subscribeInterface(const SDOPackage::NVList& properties)
00407 {
00408
00409 return true;;
00410 }
00411
00416 void unsubscribeInterface(const SDOPackage::NVList& properties)
00417 {
00418 }
00423 virtual ReturnCode get(cdrMemoryStream& data)
00424 {
00425 if (m_logger != NULL)
00426 {
00427 m_logger->log("OutPortCorbaCdrConsumerMock::get");
00428 }
00429 return PORT_OK;
00430 }
00431
00432
00437 void setLogger(Logger* logger)
00438 {
00439 m_logger = logger;
00440 }
00441
00442 void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListeners* listeners)
00443 {
00444 }
00445
00446 private:
00447 Logger* m_logger;
00448
00449 };
00455 class InPortPullConnectorTests
00456 : public CppUnit::TestFixture
00457 {
00458 CPPUNIT_TEST_SUITE(InPortPullConnectorTests);
00459
00460 CPPUNIT_TEST(test_InPortPullConnector);
00461 CPPUNIT_TEST(test_read);
00462 CPPUNIT_TEST(test_disconnect);
00463 CPPUNIT_TEST_SUITE_END();
00464
00465 private:
00466 CORBA::ORB_ptr m_pORB;
00467 PortableServer::POA_ptr m_pPOA;
00468
00469
00470 public:
00471 RTC::ConnectorListeners m_listeners;
00472
00476 InPortPullConnectorTests()
00477 {
00478
00479 int argc(0);
00480 char** argv(NULL);
00481 m_pORB = CORBA::ORB_init(argc, argv);
00482 m_pPOA = PortableServer::POA::_narrow(
00483 m_pORB->resolve_initial_references("RootPOA"));
00484 m_pPOA->the_POAManager()->activate();
00485 }
00486
00490 ~InPortPullConnectorTests()
00491 {
00492 }
00493
00497 virtual void setUp()
00498 {
00499
00500 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE].addListener(
00501 new DataListener("ON_BUFFER_WRITE"), true);
00502 m_listeners.connectorData_[RTC::ON_BUFFER_FULL].addListener(
00503 new DataListener("ON_BUFFER_FULL"), true);
00504 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE_TIMEOUT].addListener(
00505 new DataListener("ON_BUFFER_WRITE_TIMEOUT"), true);
00506 m_listeners.connectorData_[RTC::ON_BUFFER_OVERWRITE].addListener(
00507 new DataListener("ON_BUFFER_OVERWRITE"), true);
00508 m_listeners.connectorData_[RTC::ON_BUFFER_READ].addListener(
00509 new DataListener("ON_BUFFER_READ"), true);
00510 m_listeners.connectorData_[RTC::ON_SEND].addListener(
00511 new DataListener("ON_SEND"), true);
00512 m_listeners.connectorData_[RTC::ON_RECEIVED].addListener(
00513 new DataListener("ON_RECEIVED"), true);
00514 m_listeners.connectorData_[RTC::ON_RECEIVER_FULL].addListener(
00515 new DataListener("ON_RECEIVER_FULL"), true);
00516 m_listeners.connectorData_[RTC::ON_RECEIVER_TIMEOUT].addListener(
00517 new DataListener("ON_RECEIVER_TIMEOUT"), true);
00518 m_listeners.connectorData_[RTC::ON_RECEIVER_ERROR].addListener(
00519 new DataListener("ON_RECEIVER_ERROR"), true);
00520
00521
00522 m_listeners.connector_[RTC::ON_BUFFER_EMPTY].addListener(
00523 new ConnListener("ON_BUFFER_EMPTY"), true);
00524 m_listeners.connector_[RTC::ON_BUFFER_READ_TIMEOUT].addListener(
00525 new ConnListener("ON_BUFFER_READ_TIMEOUT"), true);
00526 m_listeners.connector_[RTC::ON_SENDER_EMPTY].addListener(
00527 new ConnListener("ON_SENDER_EMPTY"), true);
00528 m_listeners.connector_[RTC::ON_SENDER_TIMEOUT].addListener(
00529 new ConnListener("ON_SENDER_TIMEOUT"), true);
00530 m_listeners.connector_[RTC::ON_SENDER_ERROR].addListener(
00531 new ConnListener("ON_SENDER_ERROR"), true);
00532 m_listeners.connector_[RTC::ON_CONNECT].addListener(
00533 new ConnListener("ON_CONNECT"), true);
00534 m_listeners.connector_[RTC::ON_DISCONNECT].addListener(
00535 new ConnListener("ON_DISCONNECT"), true);
00536 }
00537
00541 virtual void tearDown()
00542 {
00543 }
00544
00549 void test_InPortPullConnector()
00550 {
00551 RTC::CdrBufferFactory::instance().
00552 addFactory("ring_buffer_mock",
00553 coil::Creator<RTC::CdrBufferBase, CdrRingBufferMock>,
00554 coil::Destructor<RTC::CdrBufferBase, CdrRingBufferMock>);
00555
00556 RTC::ConnectorProfile prof;
00557 CORBA_SeqUtil::push_back(prof.properties,
00558 NVUtil::newNV("dataport.buffer_type",
00559 "ring_buffer_mock"));
00560
00561 coil::Properties prop;
00562 {
00563 coil::Properties conn_prop;
00564 NVUtil::copyToProperties(conn_prop, prof.properties);
00565 prop << conn_prop.getNode("dataport");
00566 }
00567 OutPortCorbaCdrConsumerMock* consumer = new OutPortCorbaCdrConsumerMock();
00568 Logger logger;
00569 consumer->setLogger(&logger);
00570 RTC::ConnectorInfo profile_new(prof.name,
00571 prof.connector_id,
00572 CORBA_SeqUtil::refToVstring(prof.ports),
00573 prop);
00574 RTC::InPortConnector* connector(0);
00575 CPPUNIT_ASSERT_EQUAL(0,
00576 logger.countLog("OutPortCorbaCdrConsumerMock::setBuffer"));
00577 CPPUNIT_ASSERT_EQUAL(0,
00578 CdrRingBufferMock::logger.countLog("RingBufferMock::Constructor"));
00579 connector = new RTC::InPortPullConnector(profile_new, consumer, m_listeners);
00580 CPPUNIT_ASSERT_EQUAL(1,
00581 logger.countLog("OutPortCorbaCdrConsumerMock::setBuffer"));
00582 CPPUNIT_ASSERT_EQUAL(1,
00583 CdrRingBufferMock::logger.countLog("RingBufferMock::Constructor"));
00584
00585
00586 delete connector;
00587
00588
00589 RTC::InPortConnector* connector_err(0);
00590 try {
00591 RTC::ConnectorProfile prof_err;
00592
00593 {
00594 coil::Properties conn_prop;
00595 NVUtil::copyToProperties(conn_prop, prof_err.properties);
00596 prop << conn_prop.getNode("dataport");
00597 }
00598 RTC::ConnectorInfo profile_err(prof_err.name,
00599 prof_err.connector_id,
00600 CORBA_SeqUtil::refToVstring(prof_err.ports),
00601 prop);
00602 connector_err = new RTC::InPortPullConnector(profile_err, NULL, m_listeners);
00603 CPPUNIT_FAIL("The exception was not thrown. ");
00604 }
00605 catch(std::bad_alloc& e)
00606 {
00607 }
00608 catch(...)
00609 {
00610 CPPUNIT_FAIL("The exception not intended was thrown .");
00611 }
00612
00613 delete connector_err;
00614 delete consumer;
00615
00616 }
00621 void test_read()
00622 {
00623 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00624
00625 RTC::ConnectorProfile prof;
00626 CORBA_SeqUtil::push_back(prof.properties,
00627 NVUtil::newNV("dataport.buffer_type",
00628 "ring_buffer_mock"));
00629
00630 coil::Properties prop;
00631 {
00632 coil::Properties conn_prop;
00633 NVUtil::copyToProperties(conn_prop, prof.properties);
00634 prop << conn_prop.getNode("dataport");
00635 }
00636 OutPortCorbaCdrConsumerMock* consumer = new OutPortCorbaCdrConsumerMock();
00637 Logger logger;
00638 consumer->setLogger(&logger);
00639 RTC::ConnectorInfo profile_new(prof.name,
00640 prof.connector_id,
00641 CORBA_SeqUtil::refToVstring(prof.ports),
00642 prop);
00643 RTC::InPortConnector* connector(0);
00644 connector = new RTC::InPortPullConnector(profile_new, consumer, m_listeners, pbuffer);
00645 cdrMemoryStream cdr;
00646 RTC::ConnectorBase::ReturnCode ret;
00647 CPPUNIT_ASSERT_EQUAL(0,
00648 logger.countLog("OutPortCorbaCdrConsumerMock::get"));
00649 ret = connector->read(cdr);
00650
00651 CPPUNIT_ASSERT_EQUAL(1,
00652 logger.countLog("OutPortCorbaCdrConsumerMock::get"));
00653
00654 pbuffer->set_write_return_value(::RTC::BufferStatus::BUFFER_OK);
00655 ret = connector->read(cdr);
00656 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::PORT_OK,ret);
00657
00658 delete connector;
00659 delete consumer;
00660 delete pbuffer;
00661
00662 }
00667 void test_disconnect()
00668 {
00669 RTC::CdrBufferFactory::instance().
00670 addFactory("ring_buffer_mock",
00671 coil::Creator<RTC::CdrBufferBase, CdrRingBufferMock>,
00672 coil::Destructor<RTC::CdrBufferBase, CdrRingBufferMock>);
00673
00674 RTC::ConnectorProfile prof;
00675 CORBA_SeqUtil::push_back(prof.properties,
00676 NVUtil::newNV("dataport.buffer_type",
00677 "ring_buffer_mock"));
00678
00679 coil::Properties prop;
00680 {
00681 coil::Properties conn_prop;
00682 NVUtil::copyToProperties(conn_prop, prof.properties);
00683 prop << conn_prop.getNode("dataport");
00684 }
00685 OutPortCorbaCdrConsumerMock* consumer = new OutPortCorbaCdrConsumerMock();
00686 Logger logger;
00687 consumer->setLogger(&logger);
00688 RTC::ConnectorInfo profile_new(prof.name,
00689 prof.connector_id,
00690 CORBA_SeqUtil::refToVstring(prof.ports),
00691 prop);
00692 RTC::InPortConnector* connector(0);
00693 connector = new RTC::InPortPullConnector(profile_new, consumer, m_listeners);
00694
00695 RTC::ConnectorBase::ReturnCode ret = connector->disconnect();
00696 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::PORT_OK,ret);
00697
00698 delete connector;
00699 delete consumer;
00700
00701 }
00702 };
00703 };
00704
00705
00706
00707
00708 CPPUNIT_TEST_SUITE_REGISTRATION(InPortPullConnector::InPortPullConnectorTests);
00709
00710 #ifdef LOCAL_MAIN
00711 int main(int argc, char* argv[])
00712 {
00713
00714 FORMAT format = TEXT_OUT;
00715 int target = 0;
00716 std::string xsl;
00717 std::string ns;
00718 std::string fname;
00719 std::ofstream ofs;
00720
00721 int i(1);
00722 while (i < argc)
00723 {
00724 std::string arg(argv[i]);
00725 std::string next_arg;
00726 if (i + 1 < argc) next_arg = argv[i + 1];
00727 else next_arg = "";
00728
00729 if (arg == "--text") { format = TEXT_OUT; break; }
00730 if (arg == "--xml")
00731 {
00732 if (next_arg == "")
00733 {
00734 fname = argv[0];
00735 fname += ".xml";
00736 }
00737 else
00738 {
00739 fname = next_arg;
00740 }
00741 format = XML_OUT;
00742 ofs.open(fname.c_str());
00743 }
00744 if ( arg == "--compiler" ) { format = COMPILER_OUT; break; }
00745 if ( arg == "--cerr" ) { target = 1; break; }
00746 if ( arg == "--xsl" )
00747 {
00748 if (next_arg == "") xsl = "default.xsl";
00749 else xsl = next_arg;
00750 }
00751 if ( arg == "--namespace" )
00752 {
00753 if (next_arg == "")
00754 {
00755 std::cerr << "no namespace specified" << std::endl;
00756 exit(1);
00757 }
00758 else
00759 {
00760 xsl = next_arg;
00761 }
00762 }
00763 ++i;
00764 }
00765 CppUnit::TextUi::TestRunner runner;
00766 if ( ns.empty() )
00767 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00768 else
00769 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(ns).makeTest());
00770 CppUnit::Outputter* outputter = 0;
00771 std::ostream* stream = target ? &std::cerr : &std::cout;
00772 switch ( format )
00773 {
00774 case TEXT_OUT :
00775 outputter = new CppUnit::TextOutputter(&runner.result(),*stream);
00776 break;
00777 case XML_OUT :
00778 std::cout << "XML_OUT" << std::endl;
00779 outputter = new CppUnit::XmlOutputter(&runner.result(),
00780 ofs, "shift_jis");
00781 static_cast<CppUnit::XmlOutputter*>(outputter)->setStyleSheet(xsl);
00782 break;
00783 case COMPILER_OUT :
00784 outputter = new CppUnit::CompilerOutputter(&runner.result(),*stream);
00785 break;
00786 }
00787 runner.setOutputter(outputter);
00788 runner.run();
00789 return 0;
00790 }
00791 #endif // MAIN
00792 #endif // InPort_cpp