00001
00022 #ifndef InPortPushConnector_cpp
00023 #define InPortPushConnector_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/InPortPushConnector.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/InPortProvider.h>
00050 #include <rtm/Manager.h>
00051
00056 namespace InPortPushConnector
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 m_log.push_back(msg);
00112 }
00113
00114 int countLog(const std::string& msg)
00115 {
00116 int count = 0;
00117 for (int i = 0; i < (int) m_log.size(); ++i)
00118 {
00119 if (m_log[i] == msg) ++count;
00120 }
00121 return count;
00122 }
00123
00124 private:
00125 std::vector<std::string> m_log;
00126 };
00132 template <class DataType>
00133 class RingBufferMock
00134 : public RTC::BufferBase<DataType>
00135 {
00136 public:
00137 BUFFERSTATUS_ENUM
00138 RingBufferMock(long int length = 8)
00139 {
00140 m_logger = NULL;
00141 logger.log("RingBufferMock::Constructor");
00142 m_read_return_value = BUFFER_OK;
00143 }
00144 virtual ~RingBufferMock(void)
00145 {
00146 }
00147
00148
00153 void set_read_return_value(::RTC::BufferStatus::Enum value)
00154 {
00155 m_read_return_value = value;
00156 }
00161 virtual void init(const coil::Properties& prop)
00162 {
00163 }
00168 virtual size_t length(void) const
00169 {
00170 return 0;
00171 }
00176 virtual ReturnCode length(size_t n)
00177 {
00178 return ::RTC::BufferStatus::BUFFER_OK;
00179 }
00184 virtual ReturnCode reset()
00185 {
00186 return ::RTC::BufferStatus::BUFFER_OK;
00187 }
00192 virtual DataType* wptr(long int n = 0)
00193 {
00194 return &m_data;
00195 }
00200 virtual ReturnCode advanceWptr(long int n = 1)
00201 {
00202 return ::RTC::BufferStatus::BUFFER_OK;
00203 }
00208 virtual ReturnCode put(const DataType& value)
00209 {
00210 return ::RTC::BufferStatus::BUFFER_OK;
00211 }
00216 virtual ReturnCode write(const DataType& value,
00217 long int sec = -1, long int nsec = -1)
00218 {
00219 return ::RTC::BufferStatus::BUFFER_OK;
00220 }
00225 virtual size_t writable() const
00226 {
00227 return 0;
00228 }
00233 virtual bool full(void) const
00234 {
00235 return true;
00236 }
00241 virtual DataType* rptr(long int n = 0)
00242 {
00243 return &m_data;
00244 }
00249 virtual ReturnCode advanceRptr(long int n = 1)
00250 {
00251 return ::RTC::BufferStatus::BUFFER_OK;
00252 }
00257 virtual ReturnCode get(DataType& value)
00258 {
00259 return ::RTC::BufferStatus::BUFFER_OK;
00260 }
00265 virtual DataType& get()
00266 {
00267 return m_data;
00268 }
00273 virtual ReturnCode read(DataType& value,
00274 long int sec = -1, long int nsec = -1)
00275 {
00276 if (m_logger != NULL)
00277 {
00278 m_logger->log("RingBufferMock::read");
00279 }
00280 logger.log("RingBufferMock::read");
00281 return m_read_return_value;
00282 }
00287 virtual size_t readable() const
00288 {
00289 return 0;
00290 }
00295 virtual bool empty(void) const
00296 {
00297 return true;
00298 }
00303 void setLogger(Logger* logger)
00304 {
00305 m_logger = logger;
00306 }
00307
00308 static Logger logger;
00309 private:
00310 DataType m_data;
00311 std::vector<DataType> m_buffer;
00312 Logger* m_logger;
00313 ::RTC::BufferStatus::Enum m_read_return_value;
00314 };
00315 template <class DataType>
00316 Logger RingBufferMock<DataType>::logger;
00317 typedef RingBufferMock<cdrMemoryStream> CdrRingBufferMock;
00323 class InPortCorbaCdrProviderMock
00324 : public RTC::InPortProvider,
00325 public virtual POA_OpenRTM::InPortCdr,
00326 public virtual PortableServer::RefCountServantBase
00327 {
00328
00329 public:
00330 InPortCorbaCdrProviderMock(void)
00331 {
00332 m_logger = NULL;
00333 }
00334 virtual ~InPortCorbaCdrProviderMock(void)
00335 {
00336 }
00341 void setBuffer(RTC::BufferBase<cdrMemoryStream>* buffer)
00342 {
00343 if (m_logger != NULL)
00344 {
00345 m_logger->log("InPortCorbaCdrProviderMock::setBuffer");
00346 }
00347 }
00352 ::OpenRTM::PortStatus put(const ::OpenRTM::CdrData& data)
00353 throw (CORBA::SystemException)
00354 {
00355 return ::OpenRTM::PORT_OK;
00356 }
00361 void init(coil::Properties& prop)
00362 {
00363 if (m_logger != NULL)
00364 {
00365 m_logger->log("InPortCorbaCdrProviderMock::init");
00366 }
00367 }
00372 RTC::InPortConsumer::ReturnCode put(const cdrMemoryStream& data)
00373 {
00374 return PORT_OK;
00375 }
00380 void publishInterfaceProfile(SDOPackage::NVList& properties)
00381 {
00382 return;
00383 }
00384
00389 bool subscribeInterface(const SDOPackage::NVList& properties)
00390 {
00391
00392 return true;;
00393 }
00394
00399 void unsubscribeInterface(const SDOPackage::NVList& properties)
00400 {
00401 }
00402
00407 void setLogger(Logger* logger)
00408 {
00409 m_logger = logger;
00410 }
00411
00412 void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListeners* listeners)
00413 {
00414 }
00415 void setConnector(RTC::InPortConnector* connector)
00416 {
00417 }
00418
00419 private:
00420 Logger* m_logger;
00421
00422 };
00428 class InPortPushConnectorTests
00429 : public CppUnit::TestFixture
00430 {
00431 CPPUNIT_TEST_SUITE(InPortPushConnectorTests);
00432
00433 CPPUNIT_TEST(test_InPortPushConnector);
00434 CPPUNIT_TEST(test_read);
00435 CPPUNIT_TEST(test_disconnect);
00436
00437 CPPUNIT_TEST_SUITE_END();
00438
00439 private:
00440 CORBA::ORB_ptr m_pORB;
00441 PortableServer::POA_ptr m_pPOA;
00442
00443
00444 public:
00445 RTC::ConnectorListeners m_listeners;
00446
00450 InPortPushConnectorTests()
00451 {
00452
00453 int argc(0);
00454 char** argv(NULL);
00455 m_pORB = CORBA::ORB_init(argc, argv);
00456 m_pPOA = PortableServer::POA::_narrow(
00457 m_pORB->resolve_initial_references("RootPOA"));
00458 m_pPOA->the_POAManager()->activate();
00459
00460
00461
00462 }
00463
00467 ~InPortPushConnectorTests()
00468 {
00469 }
00470
00474 virtual void setUp()
00475 {
00476
00477 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE].addListener(
00478 new DataListener("ON_BUFFER_WRITE"), true);
00479 m_listeners.connectorData_[RTC::ON_BUFFER_FULL].addListener(
00480 new DataListener("ON_BUFFER_FULL"), true);
00481 m_listeners.connectorData_[RTC::ON_BUFFER_WRITE_TIMEOUT].addListener(
00482 new DataListener("ON_BUFFER_WRITE_TIMEOUT"), true);
00483 m_listeners.connectorData_[RTC::ON_BUFFER_OVERWRITE].addListener(
00484 new DataListener("ON_BUFFER_OVERWRITE"), true);
00485 m_listeners.connectorData_[RTC::ON_BUFFER_READ].addListener(
00486 new DataListener("ON_BUFFER_READ"), true);
00487 m_listeners.connectorData_[RTC::ON_SEND].addListener(
00488 new DataListener("ON_SEND"), true);
00489 m_listeners.connectorData_[RTC::ON_RECEIVED].addListener(
00490 new DataListener("ON_RECEIVED"), true);
00491 m_listeners.connectorData_[RTC::ON_RECEIVER_FULL].addListener(
00492 new DataListener("ON_RECEIVER_FULL"), true);
00493 m_listeners.connectorData_[RTC::ON_RECEIVER_TIMEOUT].addListener(
00494 new DataListener("ON_RECEIVER_TIMEOUT"), true);
00495 m_listeners.connectorData_[RTC::ON_RECEIVER_ERROR].addListener(
00496 new DataListener("ON_RECEIVER_ERROR"), true);
00497
00498
00499 m_listeners.connector_[RTC::ON_BUFFER_EMPTY].addListener(
00500 new ConnListener("ON_BUFFER_EMPTY"), true);
00501 m_listeners.connector_[RTC::ON_BUFFER_READ_TIMEOUT].addListener(
00502 new ConnListener("ON_BUFFER_READ_TIMEOUT"), true);
00503 m_listeners.connector_[RTC::ON_SENDER_EMPTY].addListener(
00504 new ConnListener("ON_SENDER_EMPTY"), true);
00505 m_listeners.connector_[RTC::ON_SENDER_TIMEOUT].addListener(
00506 new ConnListener("ON_SENDER_TIMEOUT"), true);
00507 m_listeners.connector_[RTC::ON_SENDER_ERROR].addListener(
00508 new ConnListener("ON_SENDER_ERROR"), true);
00509 m_listeners.connector_[RTC::ON_CONNECT].addListener(
00510 new ConnListener("ON_CONNECT"), true);
00511 m_listeners.connector_[RTC::ON_DISCONNECT].addListener(
00512 new ConnListener("ON_DISCONNECT"), true);
00513 }
00514
00518 virtual void tearDown()
00519 {
00520 }
00521
00526 void test_InPortPushConnector()
00527 {
00528 RTC::CdrBufferFactory::instance().
00529 addFactory("ring_buffer_mock",
00530 coil::Creator<RTC::CdrBufferBase, CdrRingBufferMock>,
00531 coil::Destructor<RTC::CdrBufferBase, CdrRingBufferMock>);
00532
00533 RTC::ConnectorProfile prof;
00534 CORBA_SeqUtil::push_back(prof.properties,
00535 NVUtil::newNV("dataport.buffer_type",
00536 "ring_buffer_mock"));
00537
00538 coil::Properties prop;
00539 {
00540 coil::Properties conn_prop;
00541 NVUtil::copyToProperties(conn_prop, prof.properties);
00542 prop << conn_prop.getNode("dataport");
00543 }
00544 InPortCorbaCdrProviderMock* provider = new InPortCorbaCdrProviderMock();
00545 Logger logger;
00546 provider->setLogger(&logger);
00547 RTC::ConnectorInfo profile_new(prof.name,
00548 prof.connector_id,
00549 CORBA_SeqUtil::refToVstring(prof.ports),
00550 prop);
00551 RTC::InPortConnector* connector(0);
00552 CPPUNIT_ASSERT_EQUAL(0,
00553 logger.countLog("InPortCorbaCdrProviderMock::init"));
00554 CPPUNIT_ASSERT_EQUAL(0,
00555 logger.countLog("InPortCorbaCdrProviderMock::setBuffer"));
00556 CPPUNIT_ASSERT_EQUAL(0,
00557 CdrRingBufferMock::logger.countLog("RingBufferMock::Constructor"));
00558 connector = new RTC::InPortPushConnector(profile_new, provider, m_listeners);
00559 CPPUNIT_ASSERT_EQUAL(1,
00560 logger.countLog("InPortCorbaCdrProviderMock::init"));
00561 CPPUNIT_ASSERT_EQUAL(1,
00562 logger.countLog("InPortCorbaCdrProviderMock::setBuffer"));
00563 CPPUNIT_ASSERT_EQUAL(1,
00564 CdrRingBufferMock::logger.countLog("RingBufferMock::Constructor"));
00565
00566
00567 delete connector;
00568
00569
00570 RTC::InPortConnector* connector_err(0);
00571 try {
00572 RTC::ConnectorProfile prof_err;
00573
00574 {
00575 coil::Properties conn_prop;
00576 NVUtil::copyToProperties(conn_prop, prof_err.properties);
00577 prop << conn_prop.getNode("dataport");
00578 }
00579 RTC::ConnectorInfo profile_err(prof_err.name,
00580 prof_err.connector_id,
00581 CORBA_SeqUtil::refToVstring(prof_err.ports),
00582 prop);
00583 connector_err = new RTC::InPortPushConnector(profile_err, NULL, m_listeners);
00584 CPPUNIT_FAIL("The exception was not thrown. ");
00585 }
00586 catch(std::bad_alloc& e)
00587 {
00588 }
00589 catch(...)
00590 {
00591 CPPUNIT_FAIL("The exception not intended was thrown .");
00592 }
00593 delete connector_err;
00594 delete provider;
00595
00596 }
00601 void test_read()
00602 {
00603 CdrRingBufferMock* pbuffer = new CdrRingBufferMock();
00604
00605 RTC::ConnectorProfile prof;
00606 CORBA_SeqUtil::push_back(prof.properties,
00607 NVUtil::newNV("dataport.buffer_type",
00608 "ring_buffer_mock"));
00609
00610 coil::Properties prop;
00611 {
00612 coil::Properties conn_prop;
00613 NVUtil::copyToProperties(conn_prop, prof.properties);
00614 prop << conn_prop.getNode("dataport");
00615 }
00616 InPortCorbaCdrProviderMock* provider = new InPortCorbaCdrProviderMock();
00617 Logger logger;
00618 provider->setLogger(&logger);
00619 RTC::ConnectorInfo profile_new(prof.name,
00620 prof.connector_id,
00621 CORBA_SeqUtil::refToVstring(prof.ports),
00622 prop);
00623 RTC::InPortConnector* connector(0);
00624 connector = new RTC::InPortPushConnector(profile_new, provider, m_listeners, pbuffer);
00625 cdrMemoryStream cdr;
00626 CPPUNIT_ASSERT_EQUAL(0,
00627 CdrRingBufferMock::logger.countLog("RingBufferMock::read"));
00628 connector->read(cdr);
00629 CPPUNIT_ASSERT_EQUAL(1,
00630 CdrRingBufferMock::logger.countLog("RingBufferMock::read"));
00631
00632 RTC::ConnectorBase::ReturnCode ret;
00633 pbuffer->set_read_return_value(::RTC::BufferStatus::BUFFER_OK);
00634 ret = connector->read(cdr);
00635 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::PORT_OK,ret);
00636
00637 pbuffer->set_read_return_value(::RTC::BufferStatus::BUFFER_EMPTY);
00638 ret = connector->read(cdr);
00639 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::BUFFER_EMPTY,ret);
00640
00641 pbuffer->set_read_return_value(::RTC::BufferStatus::TIMEOUT);
00642 ret = connector->read(cdr);
00643 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::BUFFER_TIMEOUT,ret);
00644
00645 pbuffer->set_read_return_value(::RTC::BufferStatus::PRECONDITION_NOT_MET);
00646 ret = connector->read(cdr);
00647 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::PRECONDITION_NOT_MET,ret);
00648
00649 delete connector;
00650 delete provider;
00651 delete pbuffer;
00652
00653 }
00658 void test_disconnect()
00659 {
00660 RTC::CdrBufferFactory::instance().
00661 addFactory("ring_buffer_mock",
00662 coil::Creator<RTC::CdrBufferBase, CdrRingBufferMock>,
00663 coil::Destructor<RTC::CdrBufferBase, CdrRingBufferMock>);
00664
00665 RTC::ConnectorProfile prof;
00666 CORBA_SeqUtil::push_back(prof.properties,
00667 NVUtil::newNV("dataport.buffer_type",
00668 "ring_buffer_mock"));
00669
00670 coil::Properties prop;
00671 {
00672 coil::Properties conn_prop;
00673 NVUtil::copyToProperties(conn_prop, prof.properties);
00674 prop << conn_prop.getNode("dataport");
00675 }
00676 InPortCorbaCdrProviderMock* provider = new InPortCorbaCdrProviderMock();
00677 Logger logger;
00678 provider->setLogger(&logger);
00679 RTC::ConnectorInfo profile_new(prof.name,
00680 prof.connector_id,
00681 CORBA_SeqUtil::refToVstring(prof.ports),
00682 prop);
00683 RTC::InPortConnector* connector(0);
00684 connector = new RTC::InPortPushConnector(profile_new, provider, m_listeners);
00685
00686 connector->disconnect();
00687 cdrMemoryStream cdr;
00688 RTC::ConnectorBase::ReturnCode ret = connector->read(cdr);
00689 CPPUNIT_ASSERT_EQUAL(RTC::ConnectorBase::PRECONDITION_NOT_MET,ret);
00690
00691 delete connector;
00692 delete provider;
00693
00694 }
00695 };
00696 };
00697
00698
00699
00700
00701 CPPUNIT_TEST_SUITE_REGISTRATION(InPortPushConnector::InPortPushConnectorTests);
00702
00703 #ifdef LOCAL_MAIN
00704 int main(int argc, char* argv[])
00705 {
00706
00707 FORMAT format = TEXT_OUT;
00708 int target = 0;
00709 std::string xsl;
00710 std::string ns;
00711 std::string fname;
00712 std::ofstream ofs;
00713
00714 int i(1);
00715 while (i < argc)
00716 {
00717 std::string arg(argv[i]);
00718 std::string next_arg;
00719 if (i + 1 < argc) next_arg = argv[i + 1];
00720 else next_arg = "";
00721
00722 if (arg == "--text") { format = TEXT_OUT; break; }
00723 if (arg == "--xml")
00724 {
00725 if (next_arg == "")
00726 {
00727 fname = argv[0];
00728 fname += ".xml";
00729 }
00730 else
00731 {
00732 fname = next_arg;
00733 }
00734 format = XML_OUT;
00735 ofs.open(fname.c_str());
00736 }
00737 if ( arg == "--compiler" ) { format = COMPILER_OUT; break; }
00738 if ( arg == "--cerr" ) { target = 1; break; }
00739 if ( arg == "--xsl" )
00740 {
00741 if (next_arg == "") xsl = "default.xsl";
00742 else xsl = next_arg;
00743 }
00744 if ( arg == "--namespace" )
00745 {
00746 if (next_arg == "")
00747 {
00748 std::cerr << "no namespace specified" << std::endl;
00749 exit(1);
00750 }
00751 else
00752 {
00753 xsl = next_arg;
00754 }
00755 }
00756 ++i;
00757 }
00758 CppUnit::TextUi::TestRunner runner;
00759 if ( ns.empty() )
00760 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
00761 else
00762 runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(ns).makeTest());
00763 CppUnit::Outputter* outputter = 0;
00764 std::ostream* stream = target ? &std::cerr : &std::cout;
00765 switch ( format )
00766 {
00767 case TEXT_OUT :
00768 outputter = new CppUnit::TextOutputter(&runner.result(),*stream);
00769 break;
00770 case XML_OUT :
00771 std::cout << "XML_OUT" << std::endl;
00772 outputter = new CppUnit::XmlOutputter(&runner.result(),
00773 ofs, "shift_jis");
00774 static_cast<CppUnit::XmlOutputter*>(outputter)->setStyleSheet(xsl);
00775 break;
00776 case COMPILER_OUT :
00777 outputter = new CppUnit::CompilerOutputter(&runner.result(),*stream);
00778 break;
00779 }
00780 runner.setOutputter(outputter);
00781 runner.run();
00782 return 0;
00783 }
00784 #endif // MAIN
00785 #endif // InPort_cpp