00001
00022 #ifndef OutPortPullConnector_cpp
00023 #define OutPortPullConnector_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/OutPortPullConnector.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
00053 namespace OutPortPullConnector
00054 {
00055
00056 class DataListener
00057 : public RTC::ConnectorDataListenerT<RTC::TimedLong>
00058 {
00059 public:
00060 DataListener(const char* name) : m_name(name) {}
00061 virtual ~DataListener()
00062 {
00063
00064 }
00065
00066 virtual void operator()(const RTC::ConnectorInfo& info,
00067 const RTC::TimedLong& data)
00068 {
00069
00070
00071
00072
00073 };
00074 std::string m_name;
00075 };
00076
00077
00078 class ConnListener
00079 : public RTC::ConnectorListener
00080 {
00081 public:
00082 ConnListener(const char* name) : m_name(name) {}
00083 virtual ~ConnListener()
00084 {
00085
00086 }
00087
00088 virtual void operator()(const RTC::ConnectorInfo& info)
00089 {
00090 std::cout << "------------------------------" << std::endl;
00091 std::cout << "Connector Listener: " << m_name << std::endl;
00092 std::cout << "Profile::name: " << info.name << std::endl;
00093 std::cout << "------------------------------" << std::endl;
00094 };
00095 std::string m_name;
00096 };
00097
00103 class Logger
00104 {
00105 public:
00106 void log(const std::string& msg)
00107 {
00108 m_log.push_back(msg);
00109 }
00110
00111 int countLog(const std::string& msg)
00112 {
00113 int count = 0;
00114 for (int i = 0; i < (int) m_log.size(); ++i)
00115 {
00116 if (m_log[i] == msg) ++count;
00117 }
00118 return count;
00119 }
00120
00121 private:
00122 std::vector<std::string> m_log;
00123 };
00124
00130 template <class DataType>
00131 class RingBufferMock
00132 : public RTC::BufferBase<DataType>
00133 {
00134 public:
00135 BUFFERSTATUS_ENUM
00136 RingBufferMock(long int length = 8)
00137 {
00138 m_logger = NULL;
00139 logger.log("RingBufferMock::Constructor");
00140 m_read_return_value = BUFFER_OK;
00141 }
00142 virtual ~RingBufferMock(void)
00143 {
00144 }
00145
00146
00151 void set_read_return_value(::RTC::BufferStatus::Enum value)
00152 {
00153 m_read_return_value = value;
00154 }
00159 virtual void init(const coil::Properties& prop)
00160 {
00161 }
00166 virtual size_t length(void) const
00167 {
00168 return 0;
00169 }
00174 virtual ReturnCode length(size_t n)
00175 {
00176 return ::RTC::BufferStatus::BUFFER_OK;
00177 }
00182 virtual ReturnCode reset()
00183 {
00184 return ::RTC::BufferStatus::BUFFER_OK;
00185 }
00190 virtual DataType* wptr(long int n = 0)
00191 {
00192 return &m_data;
00193 }
00198 virtual ReturnCode advanceWptr(long int n = 1)
00199 {
00200 return ::RTC::BufferStatus::BUFFER_OK;
00201 }
00206 virtual ReturnCode put(const DataType& value)
00207 {
00208 return ::RTC::BufferStatus::BUFFER_OK;
00209 }
00214 virtual ReturnCode write(const DataType& value,
00215 long int sec = -1, long int nsec = -1)
00216 {
00217 return ::RTC::BufferStatus::BUFFER_OK;
00218 }
00223 virtual size_t writable() const
00224 {
00225 return 0;
00226 }
00231 virtual bool full(void) const
00232 {
00233 return true;
00234 }
00239 virtual DataType* rptr(long int n = 0)
00240 {
00241 return &m_data;
00242 }
00247 virtual ReturnCode advanceRptr(long int n = 1)
00248 {
00249 return ::RTC::BufferStatus::BUFFER_OK;
00250 }
00255 virtual ReturnCode get(DataType& value)
00256 {
00257 return ::RTC::BufferStatus::BUFFER_OK;
00258 }
00263 virtual DataType& get()
00264 {
00265 return m_data;
00266 }
00271 virtual ReturnCode read(DataType& value,
00272 long int sec = -1, long int nsec = -1)
00273 {
00274 if (m_logger != NULL)
00275 {
00276 m_logger->log("RingBufferMock::read");
00277 }
00278 logger.log("RingBufferMock::read");
00279 return m_read_return_value;
00280 }
00285 virtual size_t readable() const
00286 {
00287 return 0;
00288 }
00293 virtual bool empty(void) const
00294 {
00295 return true;
00296 }
00301 void setLogger(Logger* logger)
00302 {
00303 m_logger = logger;
00304 }
00305
00306 static Logger logger;
00307 private:
00308 DataType m_data;
00309 std::vector<DataType> m_buffer;
00310 Logger* m_logger;
00311 ::RTC::BufferStatus::Enum m_read_return_value;
00312 };
00313
00314 template <class DataType>
00315 Logger RingBufferMock<DataType>::logger;
00316 typedef RingBufferMock<cdrMemoryStream> CdrRingBufferMock;
00317
00323 class OutPortCorbaCdrProviderMock
00324 : public RTC::OutPortProvider,
00325 public virtual ::POA_OpenRTM::OutPortCdr,
00326 public virtual PortableServer::RefCountServantBase
00327 {
00328
00329 public:
00330 OutPortCorbaCdrProviderMock(void)
00331 {
00332 m_logger = NULL;
00333 }
00334 virtual ~OutPortCorbaCdrProviderMock(void)
00335 {
00336 }
00341 void init(coil::Properties& prop)
00342 {
00343 if (m_logger != NULL)
00344 {
00345 m_logger->log("OutPortCorbaCdrProviderMock::init");
00346 }
00347 }
00352 virtual ::OpenRTM::PortStatus get(::OpenRTM::CdrData_out data)
00353 {
00354 return ::OpenRTM::PORT_OK;
00355 }
00360 RTC::InPortConsumer::ReturnCode put(const cdrMemoryStream& data)
00361 {
00362 return PORT_OK;
00363 }
00368 void publishInterfaceProfile(SDOPackage::NVList& properties)
00369 {
00370 return;
00371 }
00372
00377 bool subscribeInterface(const SDOPackage::NVList& properties)
00378 {
00379
00380 return true;;
00381 }
00382
00387 void unsubscribeInterface(const SDOPackage::NVList& properties)
00388 {
00389 }
00390
00391
00396 void setLogger(Logger* logger)
00397 {
00398 m_logger = logger;
00399 }
00400
00401 void setBuffer(RTC::CdrBufferBase* buffer)
00402 {
00403 }
00404
00405 void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListeners* listeners)
00406 {
00407 }
00408 void setConnector(RTC::OutPortConnector* connector)
00409 {
00410 }
00411
00412 private:
00413 Logger* m_logger;
00414
00415 };
00416
00417 class OutPortPullConnectorTests
00418 : public CppUnit::TestFixture
00419 {
00420 CPPUNIT_TEST_SUITE(OutPortPullConnectorTests);
00421
00422 CPPUNIT_TEST(test_OutPortPullConnector);
00423 CPPUNIT_TEST(test_write);
00424 CPPUNIT_TEST(test_disconnect_getBuffer);
00425 CPPUNIT_TEST(test_activate_deactivate);
00426
00427 CPPUNIT_TEST_SUITE_END();
00428
00429 private:
00430 CORBA::ORB_ptr m_pORB;
00431 PortableServer::POA_ptr m_pPOA;
00432
00433
00434 public:
00435 RTC::ConnectorListeners m_listeners;
00436
00440 OutPortPullConnectorTests()
00441 {
00442
00443 int argc(0);
00444 char** argv(NULL);
00445 m_pORB = CORBA::ORB_init(argc, argv);
00446 m_pPOA = PortableServer::POA::_narrow(
00447 m_pORB->resolve_initial_references("RootPOA"));
00448 m_pPOA->the_POAManager()->activate();
00449
00450 }
00451
00455 ~OutPortPullConnectorTests()
00456 {
00457 }
00458
00462 virtual void setUp()
00463 {
00464
00465 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE].addListener(
00466 new DataListener("ON_BUFFER_WRITE"), true);
00467 m_listeners.connectorData_[RTC::ON_BUFFER_FULL].addListener(
00468 new DataListener("ON_BUFFER_FULL"), true);
00469 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE_TIMEOUT].addListener(
00470 new DataListener("ON_BUFFER_WRITE_TIMEOUT"), true);
00471 m_listeners.connectorData_[RTC::ON_BUFFER_OVERWRITE].addListener(
00472 new DataListener("ON_BUFFER_OVERWRITE"), true);
00473 m_listeners.connectorData_[RTC::ON_BUFFER_READ].addListener(
00474 new DataListener("ON_BUFFER_READ"), true);
00475 m_listeners.connectorData_[RTC::ON_SEND].addListener(
00476 new DataListener("ON_SEND"), true);
00477 m_listeners.connectorData_[RTC::ON_RECEIVED].addListener(
00478 new DataListener("ON_RECEIVED"), true);
00479 m_listeners.connectorData_[RTC::ON_RECEIVER_FULL].addListener(
00480 new DataListener("ON_RECEIVER_FULL"), true);
00481 m_listeners.connectorData_[RTC::ON_RECEIVER_TIMEOUT].addListener(
00482 new DataListener("ON_RECEIVER_TIMEOUT"), true);
00483 m_listeners.connectorData_[RTC::ON_RECEIVER_ERROR].addListener(
00484 new DataListener("ON_RECEIVER_ERROR"), true);
00485
00486
00487 m_listeners.connector_[RTC::ON_BUFFER_EMPTY].addListener(
00488 new ConnListener("ON_BUFFER_EMPTY"), true);
00489 m_listeners.connector_[RTC::ON_BUFFER_READ_TIMEOUT].addListener(
00490 new ConnListener("ON_BUFFER_READ_TIMEOUT"), true);
00491 m_listeners.connector_[RTC::ON_SENDER_EMPTY].addListener(
00492 new ConnListener("ON_SENDER_EMPTY"), true);
00493 m_listeners.connector_[RTC::ON_SENDER_TIMEOUT].addListener(
00494 new ConnListener("ON_SENDER_TIMEOUT"), true);
00495 m_listeners.connector_[RTC::ON_SENDER_ERROR].addListener(
00496 new ConnListener("ON_SENDER_ERROR"), true);
00497 m_listeners.connector_[RTC::ON_CONNECT].addListener(
00498 new ConnListener("ON_CONNECT"), true);
00499 m_listeners.connector_[RTC::ON_DISCONNECT].addListener(
00500 new ConnListener("ON_DISCONNECT"), true);
00501 }
00502
00506 virtual void tearDown()
00507 {
00508 }
00509
00514 void test_OutPortPullConnector()
00515 {
00516 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00517
00518 RTC::ConnectorProfile prof;
00519 CORBA_SeqUtil::push_back(prof.properties,
00520 NVUtil::newNV("dataport.interface_type",
00521 "corba_cdr"));
00522 CORBA_SeqUtil::push_back(prof.properties,
00523 NVUtil::newNV("dataport.dataflow_type",
00524 "push"));
00525 CORBA_SeqUtil::push_back(prof.properties,
00526 NVUtil::newNV("dataport.subscription_type",
00527 "new"));
00528 coil::Properties prop;
00529 {
00530 coil::Properties conn_prop;
00531 NVUtil::copyToProperties(conn_prop, prof.properties);
00532 prop << conn_prop.getNode("dataport");
00533 }
00534 OutPortCorbaCdrProviderMock* provider = new OutPortCorbaCdrProviderMock();
00535 Logger logger;
00536 provider->setLogger(&logger);
00537 RTC::ConnectorInfo profile_new(prof.name,
00538 prof.connector_id,
00539 CORBA_SeqUtil::refToVstring(prof.ports),
00540 prop);
00541 RTC::OutPortConnector* connector(0);
00542 connector = new RTC::OutPortPullConnector(profile_new, provider, m_listeners, pbuffer);
00543
00544 delete connector;
00545
00546
00547
00548 CORBA_SeqUtil::push_back(prof.properties,
00549 NVUtil::newNV("dataport.subscription_type",
00550 ""));
00551 {
00552 coil::Properties conn_prop;
00553 NVUtil::copyToProperties(conn_prop, prof.properties);
00554 prop << conn_prop.getNode("dataport");
00555 }
00556 RTC::ConnectorInfo profile_flush(prof.name,
00557 prof.connector_id,
00558 CORBA_SeqUtil::refToVstring(prof.ports),
00559 prop);
00560 connector = new RTC::OutPortPullConnector(profile_flush, provider, m_listeners, 0);
00561
00562 delete connector;
00563 delete provider;
00564 delete pbuffer;
00565 }
00566
00571 void test_write()
00572 {
00573 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00574 RTC::ConnectorProfile prof;
00575 CORBA_SeqUtil::push_back(prof.properties,
00576 NVUtil::newNV("dataport.interface_type",
00577 "corba_cdr"));
00578 CORBA_SeqUtil::push_back(prof.properties,
00579 NVUtil::newNV("dataport.dataflow_type",
00580 "push"));
00581 CORBA_SeqUtil::push_back(prof.properties,
00582 NVUtil::newNV("dataport.subscription_type",
00583 "new"));
00584 coil::Properties prop;
00585 {
00586 coil::Properties conn_prop;
00587 NVUtil::copyToProperties(conn_prop, prof.properties);
00588 prop << conn_prop.getNode("dataport");
00589 }
00590 OutPortCorbaCdrProviderMock* provider = new OutPortCorbaCdrProviderMock();
00591 Logger logger;
00592 provider->setLogger(&logger);
00593 RTC::ConnectorInfo profile_new(prof.name,
00594 prof.connector_id,
00595 CORBA_SeqUtil::refToVstring(prof.ports),
00596 prop);
00597 RTC::OutPortConnector* connector(0);
00598 connector = new RTC::OutPortPullConnector(profile_new, provider, m_listeners, pbuffer);
00599 cdrMemoryStream cdr;
00600 RTC::TimedLong td;
00601 td.data = 12345;
00602 td >>= cdr;
00603
00604 RTC::ConnectorBase::ReturnCode ret;
00605 ret = connector->write(cdr);
00606 CPPUNIT_ASSERT_EQUAL(RTC::DataPortStatus::PORT_OK, ret);
00607
00608 delete connector;
00609 delete provider;
00610 delete pbuffer;
00611
00612 }
00613
00618 void test_disconnect_getBuffer()
00619 {
00620 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00621 RTC::ConnectorProfile prof;
00622 CORBA_SeqUtil::push_back(prof.properties,
00623 NVUtil::newNV("dataport.interface_type",
00624 "corba_cdr"));
00625 CORBA_SeqUtil::push_back(prof.properties,
00626 NVUtil::newNV("dataport.dataflow_type",
00627 "push"));
00628 CORBA_SeqUtil::push_back(prof.properties,
00629 NVUtil::newNV("dataport.subscription_type",
00630 "new"));
00631 coil::Properties prop;
00632 {
00633 coil::Properties conn_prop;
00634 NVUtil::copyToProperties(conn_prop, prof.properties);
00635 prop << conn_prop.getNode("dataport");
00636 }
00637 OutPortCorbaCdrProviderMock* provider = new OutPortCorbaCdrProviderMock();
00638 Logger logger;
00639 provider->setLogger(&logger);
00640 RTC::ConnectorInfo profile_new(prof.name,
00641 prof.connector_id,
00642 CORBA_SeqUtil::refToVstring(prof.ports),
00643 prop);
00644 RTC::OutPortConnector* connector(0);
00645 connector = new RTC::OutPortPullConnector(profile_new, provider, m_listeners, pbuffer);
00646 CPPUNIT_ASSERT(pbuffer == connector->getBuffer());
00647
00648 RTC::ConnectorBase::ReturnCode ret;
00649 ret = connector->disconnect();
00650 CPPUNIT_ASSERT_EQUAL(RTC::DataPortStatus::PORT_OK, ret);
00651
00652 delete connector;
00653 delete provider;
00654 delete pbuffer;
00655 }
00656
00661 void test_activate_deactivate()
00662 {
00663 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00664 RTC::ConnectorProfile prof;
00665 CORBA_SeqUtil::push_back(prof.properties,
00666 NVUtil::newNV("dataport.interface_type",
00667 "corba_cdr"));
00668 CORBA_SeqUtil::push_back(prof.properties,
00669 NVUtil::newNV("dataport.dataflow_type",
00670 "push"));
00671 CORBA_SeqUtil::push_back(prof.properties,
00672 NVUtil::newNV("dataport.subscription_type",
00673 "new"));
00674 coil::Properties prop;
00675 {
00676 coil::Properties conn_prop;
00677 NVUtil::copyToProperties(conn_prop, prof.properties);
00678 prop << conn_prop.getNode("dataport");
00679 }
00680 OutPortCorbaCdrProviderMock* provider = new OutPortCorbaCdrProviderMock();
00681 Logger logger;
00682 provider->setLogger(&logger);
00683 RTC::ConnectorInfo profile_new(prof.name,
00684 prof.connector_id,
00685 CORBA_SeqUtil::refToVstring(prof.ports),
00686 prop);
00687 RTC::OutPortConnector* connector(0);
00688 connector = new RTC::OutPortPullConnector(profile_new, provider, m_listeners, pbuffer);
00689 connector->activate();
00690 delete connector;
00691
00692 connector = new RTC::OutPortPullConnector(profile_new, provider, m_listeners, pbuffer);
00693
00694 delete connector;
00695 delete provider;
00696 delete pbuffer;
00697 }
00698 };
00699 };
00700
00701
00702
00703
00704 CPPUNIT_TEST_SUITE_REGISTRATION(OutPortPullConnector::OutPortPullConnectorTests);
00705
00706 #ifdef LOCAL_MAIN
00707 int main(int argc, char* argv[])
00708 {
00709
00710 FORMAT format = TEXT_OUT;
00711 int target = 0;
00712 std::string xsl;
00713 std::string ns;
00714 std::string fname;
00715 std::ofstream ofs;
00716
00717 int i(1);
00718 while (i < argc)
00719 {
00720 std::string arg(argv[i]);
00721 std::string next_arg;
00722 if (i + 1 < argc) next_arg = argv[i + 1];
00723 else next_arg = "";
00724
00725 if (arg == "--text") { format = TEXT_OUT; break; }
00726 if (arg == "--xml")
00727 {
00728 if (next_arg == "")
00729 {
00730 fname = argv[0];
00731 fname += ".xml";
00732 }
00733 else
00734 {
00735 fname = next_arg;
00736 }
00737 format = XML_OUT;
00738 ofs.open(fname.c_str());
00739 }
00740 if ( arg == "--compiler" ) { format = COMPILER_OUT; break; }
00741 if ( arg == "--cerr" ) { target = 1; break; }
00742 if ( arg == "--xsl" )
00743 {
00744 if (next_arg == "") xsl = "default.xsl";
00745 else xsl = next_arg;
00746 }
00747 if ( arg == "--namespace" )
00748 {
00749 if (next_arg == "")
00750 {
00751 std::cerr << "no namespace specified" << std::endl;
00752 exit(1);
00753 }
00754 else
00755 {
00756 xsl = next_arg;
00757 }
00758 }
00759 ++i;
00760 }
00761 CppUnit::TextUi::TestRunner runner;
00762 if ( ns.empty() )
00763 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00764 else
00765 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(ns).makeTest());
00766 CppUnit::Outputter* outputter = 0;
00767 std::ostream* stream = target ? &std::cerr : &std::cout;
00768 switch ( format )
00769 {
00770 case TEXT_OUT :
00771 outputter = new CppUnit::TextOutputter(&runner.result(),*stream);
00772 break;
00773 case XML_OUT :
00774 std::cout << "XML_OUT" << std::endl;
00775 outputter = new CppUnit::XmlOutputter(&runner.result(),
00776 ofs, "shift_jis");
00777 static_cast<CppUnit::XmlOutputter*>(outputter)->setStyleSheet(xsl);
00778 break;
00779 case COMPILER_OUT :
00780 outputter = new CppUnit::CompilerOutputter(&runner.result(),*stream);
00781 break;
00782 }
00783 runner.setOutputter(outputter);
00784 runner.run();
00785 return 0;
00786 }
00787 #endif // MAIN
00788 #endif // InPort_cpp