diff options
Diffstat (limited to 'TAO')
-rw-r--r-- | TAO/ChangeLog_pnotify | 17 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/Notify_Unit.mpc | 3 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBasic.cpp | 190 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBasic.h | 22 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp | 235 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.h | 24 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBuilder.cpp | 564 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestBuilder.h | 25 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestQoS.cpp | 325 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/TestQoS.h | 21 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/UnitTester.h | 64 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/main.cpp | 51 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/readme | 40 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/run_test.pl | 43 | ||||
-rw-r--r-- | TAO/orbsvcs/tests/Notify/Unit/start_ns.pl | 32 |
15 files changed, 1656 insertions, 0 deletions
diff --git a/TAO/ChangeLog_pnotify b/TAO/ChangeLog_pnotify index 5b3d2a6cca5..a3714bd6bb0 100644 --- a/TAO/ChangeLog_pnotify +++ b/TAO/ChangeLog_pnotify @@ -1,3 +1,20 @@ +Mon Oct 11 14:39:15 2004 Dale Wilson <wilson_d@ociweb.com> + + * orbsvcs/tests/Notify/Unit/Notify_Unit.mpc: + * orbsvcs/tests/Notify/Unit/TestBasic.h: + * orbsvcs/tests/Notify/Unit/TestBasic.cpp: + * orbsvcs/tests/Notify/Unit/TestBasicTypes.h: + * orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp: + * orbsvcs/tests/Notify/Unit/TestBuilder.h: + * orbsvcs/tests/Notify/Unit/TestBuilder.cpp: + * orbsvcs/tests/Notify/Unit/TestQoS.h: + * orbsvcs/tests/Notify/Unit/TestQoS.cpp: + * orbsvcs/tests/Notify/Unit/UnitTester.h: + * orbsvcs/tests/Notify/Unit/main.cpp: + * orbsvcs/tests/Notify/Unit/readme: + * orbsvcs/tests/Notify/Unit/run_test.pl: + * orbsvcs/tests/Notify/Unit/start_ns.pl: + Copy Unit test from OCI branch. Needs work. Thu Oct 7 09:40:51 2004 Dale Wilson <wilson_d@ociweb.com> * ChangeLog_pnotify: diff --git a/TAO/orbsvcs/tests/Notify/Unit/Notify_Unit.mpc b/TAO/orbsvcs/tests/Notify/Unit/Notify_Unit.mpc new file mode 100644 index 00000000000..71bd2023293 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/Notify_Unit.mpc @@ -0,0 +1,3 @@ +project : orbsvcsexe, notify { + requires += exceptions +} diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBasic.cpp b/TAO/orbsvcs/tests/Notify/Unit/TestBasic.cpp new file mode 100644 index 00000000000..7255cb80c99 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBasic.cpp @@ -0,0 +1,190 @@ +// $Id$ +#include "TestBasic.h" + +#include <orbsvcs/CosNotifyChannelAdminC.h> +#include <orbsvcs/CosNotifyCommS.h> +#include <orbsvcs/CosNotificationS.h> + +#include <ace/ARGV.h> + +using namespace CORBA; +using namespace PortableServer; +namespace CNCA = CosNotifyChannelAdmin; +namespace CN = CosNotification; +namespace CNC = CosNotifyComm; + +namespace +{ + void destroy_all_channels(CNCA::EventChannelFactory_ptr ecf) + { + CNCA::ChannelIDSeq_var channel_ids = ecf->get_all_channels(); + for (ULong i = 0; i < channel_ids->length(); ++i) + { + CNCA::ChannelID id = channel_ids[i]; + CNCA::EventChannel_var ec = ecf->get_event_channel(id); + ec->destroy(); + } + } +} + +namespace TestBasic +{ + const char* NOTIFY_IOR = "corbaloc::localhost:9050/NotifyEventChannelFactory"; + + ORB_var orb; + POA_var poa; + CNCA::EventChannelFactory_var ecf; + + class SetupTeardown { + public: + SetupTeardown() { + setUp(); + } + ~SetupTeardown() { + try { + tearDown(); + } catch (...) { + } + } + private: + void setUp() + { + ACE_ARGV av; + int ac = 0; + orb = ORB_init(ac, av.argv()); + ACE_ASSERT(! is_nil(orb.in())); + Object_var obj = orb->resolve_initial_references("RootPOA"); + ACE_ASSERT(! is_nil(obj.in())); + poa = POA::_narrow(obj.in()); + ACE_ASSERT(! is_nil(poa.in())); + POAManager_var mgr = poa->the_POAManager(); + mgr->activate(); + obj = orb->string_to_object(NOTIFY_IOR); + ACE_ASSERT(! is_nil(obj.in())); + ecf = CNCA::EventChannelFactory::_narrow(obj.in()); + ACE_ASSERT(! is_nil(ecf.in())); + destroy_all_channels(ecf.in()); + } + + void tearDown() + { + destroy_all_channels(ecf.in()); + ecf = CNCA::EventChannelFactory::_nil(); + poa->destroy(1,1); + orb->destroy(); + poa = POA::_nil(); + orb = ORB::_nil(); + } + }; + + void testChannelCreate(ACE_ENV_SINGLE_ARG_DECL) + { + SetupTeardown sutd; + + // Should be not channels when starting + CNCA::ChannelIDSeq_var channel_ids = ecf->get_all_channels(ACE_ENV_SINGLE_ARG_PARAMETER); + assertTrue(channel_ids->length() == 0); + + // get_event_channel(non_existent_id) should throw ChannelNotFound + ACE_TRY_NEW_ENV + { + CNCA::EventChannel_var ec = ecf->get_event_channel(0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + failIt("Expected ChannelNotFound exception."); + } + ACE_CATCH(CNCA::ChannelNotFound, ex) + { + } + ACE_ENDTRY; + ACE_CHECK; + + // ChannelID should match the one in the lst + CNCA::ChannelID ecid; + CNCA::EventChannel_var ec = ecf->create_channel(CN::QoSProperties(), CN::AdminProperties(), ecid); + assertTrue(! is_nil(ec.in())); + CNCA::EventChannelFactory_var ecf2 = ec->MyFactory(); + assertTrue(! is_nil(ecf2.in())); + // Note : Not guaranteed in general, but expected to work in this case + assertTrue(ecf->_is_equivalent(ecf2.in())); + + channel_ids = ecf->get_all_channels(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(channel_ids->length() == 1); + assertTrue(channel_ids[0] == ecid); + + // Channels should be retrievable by id + CNCA::EventChannel_var ec2 = ecf->get_event_channel(ecid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + assertTrue(! is_nil(ec2.in())); + ecf2 = ec2->MyFactory(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(! is_nil(ecf2.in())); + // Note : Not guaranteed in general, but expected to work in this case + assertTrue(ecf->_is_equivalent(ecf2.in())); + assertTrue(ec->_is_equivalent(ec2.in())); + } + + void testAdminCreate() { + + SetupTeardown sutd; + + CNCA::ChannelID ecid; + CNCA::EventChannel_var ec = ecf->create_channel(CN::QoSProperties(), CN::AdminProperties(), ecid); + + // The default SA and CA should exist, but they do not get returned with the others + CNCA::AdminIDSeq_var admins = ec->get_all_consumeradmins(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(admins->length() == 0); + admins = ec->get_all_supplieradmins(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(admins->length() == 0); + + ACE_TRY_NEW_ENV + { + CNCA::ConsumerAdmin_var sa = ec->get_consumeradmin(1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + failIt("Expected AdminNotFound exception."); + } + ACE_CATCH(CNCA::AdminNotFound, ex) + { + } + ACE_ENDTRY; + ACE_CHECK; + + ACE_TRY_NEW_ENV + { + CNCA::SupplierAdmin_var sa = ec->get_supplieradmin(1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + failIt("Expected AdminNotFound exception."); + } + ACE_CATCH(CNCA::AdminNotFound, ex) + { + } + ACE_ENDTRY; + ACE_CHECK; + + // get_consumeradmin(0) is synonymous with default_consumer_admin() + CNCA::ConsumerAdmin_var ca = ec->default_consumer_admin(ACE_ENV_SINGLE_ARG_PARAMETER); + CNCA::ConsumerAdmin_var ca2 = ec->get_consumeradmin(0 ACE_ENV_ARG_PARAMETER); + assertTrue(! is_nil(ca.in())); + assertTrue(! is_nil(ca2.in())); + // Note : Not guaranteed in general, but expected to work in this case + assertTrue(ca->_is_equivalent(ca2.in())); + + CNCA::SupplierAdmin_var sa = ec->get_supplieradmin(0 ACE_ENV_ARG_PARAMETER); + CNCA::SupplierAdmin_var sa2 = ec->default_supplier_admin(ACE_ENV_SINGLE_ARG_PARAMETER); + assertTrue(! is_nil(sa.in())); + assertTrue(! is_nil(sa2.in())); + // Note : Not guaranteed in general, but expected to work in this case + assertTrue(sa->_is_equivalent(sa2.in())); + + // The default SA and CA should exist, but they do not get returned with the others + admins = ec->get_all_consumeradmins(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(admins->length() == 0); + admins = ec->get_all_supplieradmins(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + assertTrue(admins->length() == 0); + } + +} diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBasic.h b/TAO/orbsvcs/tests/Notify/Unit/TestBasic.h new file mode 100644 index 00000000000..453457abb37 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBasic.h @@ -0,0 +1,22 @@ +// $Id$ +// This file is kept as simple as possible, with hopes that it will +// be maintained as features are added to the NS. +#ifndef TAO_NOTIFY_UTEST_TESTBASIC_H +#define TAO_NOTIFY_UTEST_TESTBASIC_H +#include "UnitTester.h" + +// This particular unit test case is for testing out the basic +// features available to a corba client application. (ie Utils, Suppliers, Consumers) +namespace TestBasic { + + // Test that all NS objects have an ID which can be used in various ways + void testChannelCreate(ACE_ENV_SINGLE_ARG_DECL); + void testAdminCreate(ACE_ENV_SINGLE_ARG_DECL); + + inline void testAll(ACE_ENV_SINGLE_ARG_DECL) { + testChannelCreate(ACE_ENV_SINGLE_ARG_PARAMETER); + testAdminCreate(ACE_ENV_SINGLE_ARG_PARAMETER); + } +} + +#endif diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp b/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp new file mode 100644 index 00000000000..acc0dbb3822 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp @@ -0,0 +1,235 @@ +// $Id$ +#include "TestBasicTypes.h" + +#include <orbsvcs/Notify/Name_Value_Pair.h> +#include <orbsvcs/Notify/Property.h> +#include <orbsvcs/Notify/QoSProperties.h> +#include <orbsvcs/Notify/AdminProperties.h> + +#include <orbsvcs/CosNotificationC.h> + +#include <ace/ARGV.h> + +using namespace CORBA; +namespace CN = CosNotification; + +using namespace TAO_NOTIFY; + +// Tests for simple basic types that don't require the creation +// of a Notify Service, or complex setup. +namespace TestBasicTypes +{ + ORB_var orb; + + class SetupTeardown { + public: + SetupTeardown() { + setUp(); + } + ~SetupTeardown() { + try { + tearDown(); + } catch (...) { + } + } + private: + void setUp() + { + // We have to initialize an orb, or Any will not work. + ACE_ARGV av; + int ac = 0; + orb = ORB_init(ac, av.argv()); + ACE_ASSERT(! is_nil(orb.in())); + } + + void tearDown() + { + orb->shutdown(); + orb->destroy(); + orb = ORB::_nil(); + } + }; + + void testProperty() { + TAO_NS_Property_Long n("myprop"); + assertTrue(n.name().compare("myprop") == 0); + assertEquals(0, n.value()); + assertEquals(1, n.is_valid()); + n.invalidate(); + assertEquals(0, n.is_valid()); + n = 42; + assertEquals(42, n.value()); + assertEquals(1, n.is_valid()); + + TAO_NS_Property_Long n2(n); + assertEquals(42, n2.value()); + assertEquals(1, n2.is_valid()); + assertTrue(n2.name().compare("myprop") == 0); + + TAO_NS_Property_Long n3("myprop2", 1234); + n.invalidate(); + n3 = n; + // The assignment operator won't copy if the rhs is invalid + assertEquals(1234, n3.value()); + assertEquals(1, n3.is_valid()); + assertTrue(n3.name().compare("myprop2") == 0); + n3 = n2; + assertEquals(42, n3.value()); + assertEquals(1, n3.is_valid()); + assertTrue(n3.name().compare("myprop") == 0); + + // We should test bool and struct version separately, or figure + // out a way to safely combine their implementations into the base. + } + + void testNVP(ACE_ENV_SINGLE_ARG_DECL) { + SetupTeardown sutd; + TAO_NS_Property_Long p_long("mylong", 42); + TAO_NS_Property_Short p_short("myshort", 43); + TAO_NS_Property_Time p_time("mytime", 44); + TAO_NS_Property_Boolean p_bool("mybool", 45); // On purpose + + NVPList lst; + lst.push_back(NVP(p_long)); + assertEquals(1, lst.size()); + + // adding a duplicate should just replace the existing value + lst.push_back(NVP(p_long)); + assertEquals(1, lst.size()); + + lst.push_back(NVP(p_short)); + lst.push_back(NVP(p_time)); + lst.push_back(NVP(p_bool)); + lst.push_back(NVP("mystr", "46")); + lst.push_back(NVP("mylong2", 47)); + assertEquals(6, lst.size()); + + p_long = 0; + p_short = 0; + p_time = 0; + p_bool = 0; + p_long.invalidate(); + p_short.invalidate(); + p_time.invalidate(); + p_bool.invalidate(); + + Long n = -1; + ACE_CString str = "invalid"; + lst.load("mylong2", n); + assertEquals(47, n); + lst.load("mylong", n); + assertEquals(42, n); + lst.load("myshort", n); + assertEquals(43, n); + lst.load("mybool", str); + assertTrue(str == "true"); + lst.load("mybool", n); + assertEquals(0, n); + + lst.load(p_long); + assertTrue(p_long.is_valid()); + assertEquals(42, p_long.value()); + lst.load(p_short); + assertTrue(p_short.is_valid()); + assertEquals(43, p_short.value()); + lst.load(p_bool); + assertTrue(p_bool.is_valid()); + assertTrue(p_bool.value()); + lst.load(p_time); + assertTrue(p_time.is_valid()); + assertEquals(44, p_time.value()); + + // Update the number to an invalid value + lst.push_back(NVP("mylong2", "invalid1234")); + lst.load("mylong2", n); + assertEquals(0, n); + lst.push_back(NVP("mylong2", "1234invalid")); + lst.load("mylong2", n); + assertEquals(1234, n); + // Do the same for time + lst.push_back(NVP("mytime", "invalid1234")); + lst.load(p_time); + p_time.invalidate(); + assertTrue(! p_time.is_valid()); + lst.push_back(NVP("mytime", "1234invalid")); + lst.load(p_time); + assertTrue(p_time.is_valid()); + assertEquals(1234, p_time.value()); + } + + void testQoSBasic() + { + // There are two ways to init qos and admin. 1) init() from a corba sequence + // or 2) load manually, and then call init(). + TAO_NS_AdminProperties a; + + a.max_global_queue_length() = 1234; + a.max_consumers() = 2345; + a.max_suppliers() = 3456; + a.reject_new_events() = 1; + a.init(); + + // After setting the properties, we have to init() before they are available + // as a sequence. + + assertEquals(a.max_global_queue_length().value(), 1234); + assertEquals(a.max_consumers().value(), 2345); + assertEquals(a.max_suppliers().value(), 3456); + assertEquals(a.reject_new_events().value(), 1); + + CN::AdminProperties aseq; + a.populate(aseq); + + assertEquals(4, aseq.length()); + for (ULong i = 0; i < 4; ++i) { + ACE_CString last; + if (a.max_global_queue_length().name() == aseq[i].name.in()) { + Long tmp = 0; + assertTrue(aseq[i].value >>= tmp); + assertEquals(1234, tmp); + } else if (a.max_consumers().name() == aseq[i].name.in()) { + Long tmp = 0; + assertTrue(aseq[i].value >>= tmp); + assertEquals(2345, tmp); + } else if (a.max_suppliers().name() == aseq[i].name.in()) { + Long tmp = 0; + assertTrue(aseq[i].value >>= tmp); + assertEquals(3456, tmp); + } else if (a.reject_new_events().name() == aseq[i].name.in()) { + Boolean tmp = 0; + aseq[i].value >>= Any::to_boolean(tmp); + assertTrue(1); + assertEquals(1, tmp); + } else { + failIt("Unexpected property name"); + } + assertTrue(last != aseq[i].name.in()); + last = aseq[i].name.in(); + } + + // Populate a new admin props from the seq + TAO_NS_AdminProperties a2; + int err = a2.init(aseq); + assertEquals(0, err); + + assertEquals(a2.max_global_queue_length().value(), 1234); + assertEquals(a2.max_consumers().value(), 2345); + assertEquals(a2.max_suppliers().value(), 3456); + assertEquals(a2.reject_new_events().value(), 1); + + // Finally, show a flaw in the current design where the internal hash + // map could get out of sync with the properties. + a2.max_consumers() = 42; + + a2.populate(aseq); + assertEquals(4, aseq.length()); + err = a.init(aseq); + assertEquals(0, err); + + assertEquals(a.max_global_queue_length().value(), 1234); + assertEquals(a.max_consumers().value(), 2345); + assertEquals(a.max_suppliers().value(), 3456); + assertEquals(a.reject_new_events().value(), 1); + } + +} // namespace diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.h b/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.h new file mode 100644 index 00000000000..957e038e993 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.h @@ -0,0 +1,24 @@ +// $Id$ +// This file is kept as simple as possible, with hopes that it will +// be maintained as features are added to the NS. +#ifndef TAO_NOTIFY_UTEST_TESTBASICTYPES_H +#define TAO_NOTIFY_UTEST_TESTBASICTYPES_H +#include "UnitTester.h" + +// This particular unit test case is for testing out the basic +// features available to a corba client application. (ie Utils, Suppliers, Consumers) +namespace TestBasicTypes { + + // Test that all NS objects have an ID which can be used in various ways + void testNVP(ACE_ENV_SINGLE_ARG_DECL); + void testQoSBasic(ACE_ENV_SINGLE_ARG_DECL); + + inline void testAll(ACE_ENV_SINGLE_ARG_DECL) { + testNVP(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + testQoSBasic(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} + +#endif diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.cpp b/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.cpp new file mode 100644 index 00000000000..c34616909cb --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.cpp @@ -0,0 +1,564 @@ +// $Id$ +#include "TestBuilder.h" + +#include <orbsvcs/Notify/Builder.h> +#include <orbsvcs/Notify/Factory.h> +#include <orbsvcs/Notify/Properties.h> +#include <orbsvcs/Notify/EventChannelFactory.h> +// The following includes are only needed for vc6 +#include <orbsvcs/Notify/EventChannel.h> +#include <orbsvcs/Notify/ConsumerAdmin.h> +#include <orbsvcs/Notify/SupplierAdmin.h> +#include <orbsvcs/Notify/Admin.h> +#include <orbsvcs/Notify/Proxy.h> +#include <orbsvcs/Notify/ProxyConsumer.h> +#include <orbsvcs/Notify/ProxySupplier.h> + +#include <orbsvcs/Notify/Topology_Saver.h> + +#include <ace/ARGV.h> + +using namespace CORBA; +using namespace PortableServer; +namespace CNCA = CosNotifyChannelAdmin; +namespace CN = CosNotification; +namespace CNC = CosNotifyComm; +namespace CNF = CosNotifyFilter; +using namespace TAO_NOTIFY; + +namespace { + void init_qos_props(CN::QoSProperties& qos, bool topology_persist) { + qos.length(13); + ULong i = 0; + qos[i].name = CORBA::string_dup ("EventReliability"); + qos[i++].value <<= CN::BestEffort; + if (topology_persist) { + qos[i].name = CORBA::string_dup ("ConnectionReliability"); + qos[i++].value <<= CN::Persistent; + } + else + { + qos[i].name = CORBA::string_dup ("ConnectionReliability"); + qos[i++].value <<= CN::BestEffort; + } + qos[i].name = CORBA::string_dup ("Priority"); + qos[i++].value <<= (Short) 1234; + qos[i].name = CORBA::string_dup ("Timeout"); + qos[i++].value <<= (TimeBase::TimeT) 55555; + qos[i].name = CORBA::string_dup ("MaximumBatchSize"); + qos[i++].value <<= (Long) 200; + qos[i].name = CORBA::string_dup ("PacingInterval"); + qos[i++].value <<= (TimeBase::TimeT) 420000; + qos[i].name = CORBA::string_dup ("StopTimeSupported"); + qos[i++].value <<= Any::from_boolean(0); + qos.length(i); + } + void init_admin_props(CN::AdminProperties& admin) { + admin.length(13); + ULong i = 0; + admin[i].name = CORBA::string_dup ("MaxQueueLength"); + admin[i++].value <<= (Long) 200; + admin[i].name = CORBA::string_dup ("MaxConsumers"); + admin[i++].value <<= (Long) 3; + admin[i].name = CORBA::string_dup ("MaxSuppliers"); + admin[i++].value <<= (Long) 3; + admin[i].name = CORBA::string_dup ("RejectNewEvents"); + admin[i++].value <<= Any::from_boolean(1); + } +} + +namespace TestBuilder +{ + class DestroyChecker : public TAO_NS_Destroy_Callback { + public: + DestroyChecker() : cnt(0) { + } + virtual void release (void) { + cnt++; + } + int cnt; + }; + + class TestTopologyFactory; + + class TestSaver : public TAO_NOTIFY::Topology_Saver { + TestTopologyFactory& f_; + bool verbose_; + public: + TestSaver(TestTopologyFactory& fact, bool verbose) + : f_(fact) + , verbose_ (verbose) + { + } + virtual bool begin_object (CORBA::Long id, + const ACE_CString &type, + const NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL); + + virtual void end_object (CORBA::Long id, + const ACE_CString &type ACE_ENV_ARG_DECL); + }; + + class TestTopologyFactory : public TAO_NOTIFY::Topology_Factory { + public: + int num_begin; // @@ todo: public data? Aw, comon guys! + int num_end; + bool verbose_; + + TestTopologyFactory(bool verbose = false) + : num_begin(0) + , num_end(0) + , verbose_ (verbose) + { + } + virtual Topology_Saver* create_saver() + { + return new TestSaver(*this, this->verbose_); + } + + virtual Topology_Loader* create_loader() + { + return 0; + } + + void reset() + { + num_begin = 0; + num_end = 0; + } + }; + + inline bool TestSaver::begin_object (CORBA::Long id, + const ACE_CString& name, + const NVPList& attrs, + bool + ACE_ENV_ARG_DECL) + { + if (this->verbose_) + { + cout << "begin [" << f_.num_begin + 1 << "] " << id << " " << name << " {" << attrs.size() << "}" << endl; + } + ++f_.num_begin; + return true; + } + inline void TestSaver::end_object (CORBA::Long id, + const ACE_CString& name ACE_ENV_ARG_DECL) + { + if (this->verbose_) + { + cout << "end [" << f_.num_end + 1 << "] " << id << " " << name << endl; + } + ++f_.num_end; + } + + ORB_var orb; + POA_var poa; + + TAO_NS_Properties* props; + TAO_NS_Factory factory; + TAO_NS_Builder builder; + + class SetupTeardown { + public: + SetupTeardown() { + setUp(); + } + ~SetupTeardown() { + try { + tearDown(); + } catch (...) { + } + } + private: + void setUp() + { + ACE_ARGV av; + int ac = 0; + orb = ORB_init(ac, av.argv()); + ACE_ASSERT(! is_nil(orb.in())); + Object_var obj = orb->resolve_initial_references("RootPOA"); + ACE_ASSERT(! is_nil(obj.in())); + poa = POA::_narrow(obj.in()); + ACE_ASSERT(! is_nil(poa.in())); + POAManager_var mgr = poa->the_POAManager(); + mgr->activate(); + + props = TAO_NS_PROPERTIES::instance(); + props->orb(orb.in()); + props->default_poa(poa.in()); + props->factory(&factory); + props->builder(&builder); + } + void tearDown() + { + poa->destroy(1,1); + orb->destroy(); + poa = POA::_nil(); + orb = ORB::_nil(); + } + }; + + void testBuildECF(ACE_ENV_SINGLE_ARG_DECL) { + SetupTeardown sutd; + TAO_NS_EventChannelFactory* ecf = builder.build_event_channel_factory(poa.in()); + assertTrue(ecf != 0); + assertEquals(-1, ecf->id()); + + // Test that the object is destroyed. + DestroyChecker dc; + ecf->destroy_callback(&dc); + ecf->deactivate(); + assertEquals(1, dc.cnt); + delete ecf; + } + + void testBuildEC(ACE_ENV_SINGLE_ARG_DECL) { + SetupTeardown sutd; + TAO_NS_EventChannelFactory* ecf = builder.build_event_channel_factory(poa.in()); + TAO_NS_EventChannel* ec = builder.build_event_channel(ecf->object_poa(), CN::QoSProperties(), CN::AdminProperties(), 42); + assertTrue(ec != 0); + assertEquals(-1, ecf->id()); + assertEquals(42, ec->id()); + + // Test that the object is destroyed. + DestroyChecker dc; + ec->destroy_callback(&dc); + ec->deactivate(); + assertEquals(1, dc.cnt); + delete ec; + + ec = builder.build_event_channel(ecf->object_poa(), CN::QoSProperties(), CN::AdminProperties(), 0); + assertTrue(ec != 0); + ec->destroy_callback(&dc); + dc.cnt = 0; + assertEquals(43, ec->id()); + + ec = builder.build_event_channel(ecf->object_poa(), CN::QoSProperties(), CN::AdminProperties(), 10); + assertTrue(ec != 0); + ec->destroy_callback(&dc); + assertEquals(0, dc.cnt); + assertEquals(10, ec->id()); + + ec = builder.build_event_channel(ecf->object_poa(), CN::QoSProperties(), CN::AdminProperties(), 0); + assertTrue(ec != 0); + ec->destroy_callback(&dc); + assertEquals(0, dc.cnt); + assertEquals(44, ec->id()); // will be 11 if the id generator is broken. + + ecf->deactivate(); + // @@ todo : assertEquals(3, dc.cnt); because destroying the ecf should destroy the ecs + } + + void testTopologySaveBasic(ACE_ENV_SINGLE_ARG_DECL) { + SetupTeardown sutd; + TAO_NS_EventChannelFactory* ecf = builder.build_event_channel_factory(poa.in()); + assertTrue(ecf != 0); + TestTopologyFactory tsf; + ecf->set_topology_factory(&tsf); + + assertEquals(0, tsf.num_begin); + assertEquals(0, tsf.num_end); + + // This will cause the ecf to use our tsf to create a saver, and save. + ecf->child_change(ACE_ENV_SINGLE_ARG_PARAMETER); + + // Since we start persisting topology at the ecf level, there will always be + // at least a minimal empty topology persisted. + assertEquals(1, tsf.num_begin); + assertEquals(1, tsf.num_end); + tsf.reset(); + assertEquals(0, tsf.num_begin); + assertEquals(0, tsf.num_end); + + CN::QoSProperties qos; + CN::AdminProperties admin; + init_qos_props(qos, false); + init_admin_props(admin); + + // Creating a channel, should call signal_change, but topology + // persistence is disabled, so only the ecf should be written again. + TAO_NS_EventChannel* ec = ecf->create_channel_i(qos, admin); + assertTrue(ec != 0); + assertEquals(1, ec->id()); + assertEquals(1, tsf.num_begin); // + begin ecf + assertEquals(1, tsf.num_end); + tsf.reset(); + + // This time we'll persist the new channel + init_qos_props(qos, true); + ec = ecf->create_channel_i(qos, admin); + assertTrue(ec != 0); + assertEquals(2, ec->id()); + assertEquals(2, tsf.num_begin); + assertEquals(2, tsf.num_end); + } + + void testTopologyPersist(ACE_ENV_SINGLE_ARG_DECL) + { + SetupTeardown sutd; + TAO_NS_EventChannelFactory* ecf = builder.build_event_channel_factory(poa.in()); + + TestTopologyFactory tsf; + ecf->set_topology_factory(&tsf); + + // This will cause the ecf to use our tsf to create a saver, and save. + ecf->child_change(ACE_ENV_SINGLE_ARG_PARAMETER); + int expected = 2; // 1 ecf, +1 reconnect reg + + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + CN::QoSProperties qos; + CN::AdminProperties admin; + init_qos_props(qos, true); + init_admin_props(admin); + + // Creating a channel, should call signal_change + TAO_NS_EventChannel* ec = ecf->create_channel_i(qos, admin); + expected += 1; // 1 channel + assertTrue(ec != 0); + assertEquals(1, ec->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + TAO_NS_ConsumerAdmin* ca = ec->new_for_consumers_i(CNCA::OR_OP); + expected += 3; // 1 consumeradmin, 1 subs section, 1 subscription (*/%ALL) + assertTrue(ca != 0); + assertEquals(2, ca->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + TAO_NS_SupplierAdmin* sa = ec->new_for_suppliers_i(CNCA::OR_OP); + expected += 3; // 1 supplieradmin, 1 subs section, 1 subscription (*/%ALL) + assertTrue(sa != 0); + assertEquals(3, sa->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // consumer #1 + TAO_NS_ProxySupplier* ps = ca->obtain_notification_push_supplier_i(CNCA::STRUCTURED_EVENT); + expected += 1; // 1 proxy + assertTrue(ps != 0); + assertEquals(4, ps->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // consumer #2 + ps = ca->obtain_notification_push_supplier_i(CNCA::SEQUENCE_EVENT); + expected += 1; // 1 proxy + assertTrue(ps != 0); + assertEquals(5, ps->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // consumer #3 + ps = ca->obtain_notification_push_supplier_i(CNCA::ANY_EVENT); + expected += 1; // 1 proxy + assertTrue(ps != 0); + assertEquals(6, ps->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // supplier #1 + TAO_NS_ProxyConsumer* pc = sa->obtain_notification_push_consumer_i(CNCA::STRUCTURED_EVENT); + expected += 1; // 1 proxy + assertTrue(pc != 0); + assertEquals(7, pc->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // supplier #2 + pc = sa->obtain_notification_push_consumer_i(CNCA::SEQUENCE_EVENT); + expected += 1; // 1 proxy + assertTrue(pc != 0); + assertEquals(8, pc->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // supplier #3 + pc = sa->obtain_notification_push_consumer_i(CNCA::ANY_EVENT); + expected += 1; // 1 proxy + assertTrue(pc != 0); + assertEquals(9, pc->id()); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + // Setting the ConnectionReliability = false should not only trigger + // another save, but should cause the last push consumer to no longer + // be persisted + // On one hand if we save it, we're saving something + // that's not suposed to be saved. On the other hand + // if we don't save it, we're leaving the old version + // out there with the old qos (on updatable as opposed + // to replacable persisnt stores. + + init_qos_props(qos, false); + pc->set_qos(qos); + int nothing = 0; + // a change of a non-persistent object does not + // trigger a save + assertEquals(nothing, tsf.num_begin); + + ec->child_change (ACE_ENV_SINGLE_ARG_PARAMETER); + expected -= 1; // 1 proxy + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + ps->set_qos(qos); + assertEquals(nothing, tsf.num_begin); + + ec->child_change (ACE_ENV_SINGLE_ARG_PARAMETER); + expected -= 1; // 1 proxy + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + //SCOPE + { + ACE_TRY_NEW_ENV + { + ca->set_qos(qos ACE_ENV_ARG_PARAMETER); + failIt("Expected UnsupportedQoS, because children exist."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + // this is good + } + ACE_CATCHALL; + { + failIt("unknown exception received from set_qos."); + } + ACE_ENDTRY; + } // endscope + + ecf->deactivate(ACE_ENV_ARG_PARAMETER); + } + + // Test that at least one object (CA) supports subscription topo correctly + // and test a few basic subscription functions + void testSubscriptionTopology() + { + SetupTeardown sutd; + TAO_NS_EventChannelFactory* ecf = builder.build_event_channel_factory(poa.in()); + TestTopologyFactory tsf(false); + + CN::QoSProperties qos; + CN::AdminProperties admin; + init_qos_props(qos, true); + init_admin_props(admin); + + ecf->set_topology_factory(0); + TAO_NS_EventChannel* ec = ecf->create_channel_i(qos, admin); + TAO_NS_ConsumerAdmin* ca = ec->new_for_consumers_i(CNCA::OR_OP); + + ecf->set_topology_factory(&tsf); + assertEquals(0, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + + CN::EventTypeSeq added; + CN::EventTypeSeq removed; + + ca->subscription_change(added, removed); + // Should force the topo save of ecf, ec, ca, recreg + assertEquals(4, tsf.num_begin); + // todo : This exposes what's probably a bug, because we didn't add or remove anything. + // The default subscriptions should have been included. + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + ecf->set_topology_factory(0); + + // Now that the basic have been established ensure that it works for each of the other + CNCA::ProxyID id; + CNCA::ProxySupplier_var ps = ca->obtain_notification_push_supplier(CNCA::STRUCTURED_EVENT, id); + CNCA::StructuredProxyPushSupplier_var structps = CNCA::StructuredProxyPushSupplier::_narrow(ps.in()); + assertTrue(! is_nil(structps.in())); + ps = ca->obtain_notification_push_supplier(CNCA::SEQUENCE_EVENT, id); + CNCA::SequenceProxyPushSupplier_var seqps = CNCA::SequenceProxyPushSupplier::_narrow(ps.in()); + assertTrue(! is_nil(seqps.in())); + ps = ca->obtain_notification_push_supplier(CNCA::ANY_EVENT, id); + CNCA::ProxyPushSupplier_var anyps = CNCA::ProxyPushSupplier::_narrow(ps.in()); + assertTrue(! is_nil(anyps.in())); + TAO_NS_SupplierAdmin* sa = ec->new_for_suppliers_i(CNCA::OR_OP); + CNCA::ProxyConsumer_var pc = sa->obtain_notification_push_consumer(CNCA::STRUCTURED_EVENT, id); + CNCA::StructuredProxyPushConsumer_var structpc = CNCA::StructuredProxyPushConsumer::_narrow(pc.in()); + assertTrue(! is_nil(structpc.in())); + pc = sa->obtain_notification_push_consumer(CNCA::SEQUENCE_EVENT, id); + CNCA::SequenceProxyPushConsumer_var seqpc = CNCA::SequenceProxyPushConsumer::_narrow(pc.in()); + assertTrue(! is_nil(seqpc.in())); + pc = sa->obtain_notification_push_consumer(CNCA::ANY_EVENT, id); + CNCA::ProxyPushConsumer_var anypc = CNCA::ProxyPushConsumer::_narrow(pc.in()); + assertTrue(! is_nil(anypc.in())); + + // Call each one once to set the initial subscriptions so that the topology + // is consistent + added.length(1); + added[0].domain_name = string_dup("a"); + ca->subscription_change(added, removed); + structps->subscription_change(added, removed); + seqps->subscription_change(added, removed); + anyps->subscription_change(added, removed); + sa->offer_change(added, removed); + structpc->offer_change(added, removed); + seqpc->offer_change(added, removed); + anypc->offer_change(added, removed); + + ecf->set_topology_factory(&tsf); + assertEquals(0, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + + int expected = 27; + ca->subscription_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + structps->subscription_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + seqps->subscription_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + anyps->subscription_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + sa->offer_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + structpc->offer_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + seqpc->offer_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + anypc->offer_change(added, removed); + assertEquals(expected, tsf.num_begin); + assertEquals(tsf.num_begin, tsf.num_end); + tsf.reset(); + + ecf->deactivate(ACE_ENV_ARG_PARAMETER); + } +} diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.h b/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.h new file mode 100644 index 00000000000..4e6afb8ec16 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestBuilder.h @@ -0,0 +1,25 @@ +// $Id$ +#ifndef TAO_NOTIFY_UTEST_TESTBUILDER_H +#define TAO_NOTIFY_UTEST_TESTBUILDER_H +#include "UnitTester.h" + +namespace TestBuilder { + + void testBuildECF(ACE_ENV_SINGLE_ARG_DECL); + void testBuildEC(ACE_ENV_SINGLE_ARG_DECL); + void testTopologyPersist(ACE_ENV_SINGLE_ARG_DECL); + void testSubscriptionTopology(ACE_ENV_SINGLE_ARG_DECL); + + inline void testAll(ACE_ENV_SINGLE_ARG_DECL) { + testBuildECF(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + testBuildEC(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + testTopologyPersist(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + testSubscriptionTopology(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} + +#endif diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestQoS.cpp b/TAO/orbsvcs/tests/Notify/Unit/TestQoS.cpp new file mode 100644 index 00000000000..a8a5b991576 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestQoS.cpp @@ -0,0 +1,325 @@ +// $Id$ +#include "TestQoS.h" + +#include <orbsvcs/CosNotifyChannelAdminS.h> +#include <orbsvcs/CosNotifyCommS.h> +#include <orbsvcs/CosNotificationS.h> +#include <tao/TimeBaseC.h> + +#include <ace/ARGV.h> + +using namespace CORBA; +using namespace PortableServer; +namespace CNCA = CosNotifyChannelAdmin; +namespace CN = CosNotification; +namespace CNC = CosNotifyComm; + +namespace +{ + void destroy_all_channels(CNCA::EventChannelFactory_ptr ecf) + { + CNCA::ChannelIDSeq_var channel_ids = ecf->get_all_channels(); + for (ULong i = 0; i < channel_ids->length(); ++i) + { + CNCA::ChannelID id = channel_ids[i]; + CNCA::EventChannel_var ec = ecf->get_event_channel(id); + ec->destroy(); + } + } +} + +namespace TestQoS +{ + const char* NOTIFY_IOR = "corbaloc::localhost:9050/NotifyEventChannelFactory"; + + ORB_var orb; + POA_var poa; + CNCA::EventChannelFactory_var ecf; + + class SetupTeardown { + public: + SetupTeardown() { + setUp(); + } + ~SetupTeardown() { + try { + tearDown(); + } catch (...) { + } + } + private: + void setUp() + { + ACE_ARGV av; + int ac = 0; + orb = ORB_init(ac, av.argv()); + ACE_ASSERT(! is_nil(orb.in())); + Object_var obj = orb->resolve_initial_references("RootPOA"); + ACE_ASSERT(! is_nil(obj.in())); + poa = POA::_narrow(obj.in()); + ACE_ASSERT(! is_nil(poa.in())); + POAManager_var mgr = poa->the_POAManager(); + mgr->activate(); + obj = orb->string_to_object(NOTIFY_IOR); + ACE_ASSERT(! is_nil(obj.in())); + ecf = CNCA::EventChannelFactory::_narrow(obj.in()); + ACE_ASSERT(! is_nil(ecf.in())); + destroy_all_channels(ecf.in()); + } + + void tearDown() + { + destroy_all_channels(ecf.in()); + ecf = CNCA::EventChannelFactory::_nil(); + poa->destroy(1,1); + orb->destroy(); + poa = POA::_nil(); + orb = ORB::_nil(); + } + }; + + void testQoSChannel(ACE_ENV_SINGLE_ARG_DECL) { + SetupTeardown sutd; + + // Create a channel, check that it's qos contains the expected defaults + CNCA::ChannelID ecid; + CNCA::EventChannel_var ec = ecf->create_channel(CN::QoSProperties(), CN::AdminProperties(), ecid); + assertTrue( ! is_nil(ec.in())); + + ACE_CString name; + ULong i = 0; + + CN::QoSProperties_var qos = ec->get_qos(); + assertEquals(1, qos->length()); + name = qos[i].name.in(); + assertTrue(name == "ThreadPool"); + // Don't really care about the value of ThreadPool + + TimeBase::UtcT defutc; + defutc.time = 12345; + defutc.inacclo = 10; + defutc.inacchi = 50; + defutc.tdf = 100; + + // The TAO implementation accepts all settings without error + CN::QoSProperties qos2(13); + qos2.length(13); + i = 0; + qos2[i].name = CORBA::string_dup ("EventReliability"); + qos2[i++].value <<= CN::BestEffort; + qos2[i].name = CORBA::string_dup ("ConnectionReliability"); + qos2[i++].value <<= CN::Persistent; + qos2[i].name = CORBA::string_dup ("Priority"); + qos2[i++].value <<= (Short) 1234; + //qos2[i].name = CORBA::string_dup ("StartTime"); + //qos2[i++].value <<= defutc; + //qos2[i].name = CORBA::string_dup ("StopTime"); + //qos2[i++].value <<= defutc; + qos2[i].name = CORBA::string_dup ("Timeout"); + qos2[i++].value <<= (TimeBase::TimeT) 55555; + qos2[i].name = CORBA::string_dup ("OrderPolicy"); + qos2[i++].value <<= CN::FifoOrder; + qos2[i].name = CORBA::string_dup ("DiscardPolicy"); + qos2[i++].value <<= CN::PriorityOrder; + qos2[i].name = CORBA::string_dup ("MaximumBatchSize"); + qos2[i++].value <<= (Long) 200; + qos2[i].name = CORBA::string_dup ("PacingInterval"); + qos2[i++].value <<= (TimeBase::TimeT) 420000; + //qos2[i].name = CORBA::string_dup ("StartTimeSupported"); + //qos2[i++].value <<= 0; + qos2[i].name = CORBA::string_dup ("StopTimeSupported"); + qos2[i++].value <<= Any::from_boolean(0); + qos2[i].name = CORBA::string_dup ("MaxEventsPerConsumer"); + qos2[i++].value <<= (Long) 150; + + qos2.length(i); + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + Short sv = 0; + Long lv = 0; + Boolean bv = 0; + + // Get channel qos settings, and ensure they match what was added. + qos = ec->get_qos(); + ULong len = qos->length(); + assertEquals(i + 1, len); // The number we added, plus the original ThreadPool setting. + + i = 0; + TimeBase::TimeT t; + + for (i =0; i < len; ++i) + { + name = qos[i].name.in(); + + if (name == "ThreadPool") + { + // that's nice. + } + else if (name == "EventReliability") + { + assertTrue((qos[i].value >>= sv) != 0); + assertEquals(CN::BestEffort, sv); + } + else if (name == "ConnectionReliability") + { + assertTrue((qos[i].value >>= sv) != 0); + assertEquals(CN::Persistent, sv); + } + else if (name == "Priority") + { + assertTrue((qos[i].value >>= sv) != 0); + assertEquals(1234, sv); + } + else if (name == "Timeout") + { + assertTrue((qos[i].value >>= t) != 0); + assertEquals(55555, t); + } + else if (name == "OrderPolicy") + { + assertTrue((qos[i].value >>= sv) != 0); + assertEquals(CN::FifoOrder, sv); + } + else if (name == "DiscardPolicy") + { + assertTrue((qos[i].value >>= sv) != 0); + assertEquals(CN::PriorityOrder, sv); + } + else if (name == "MaximumBatchSize") + { + assertTrue((qos[i].value >>= lv) != 0); + assertEquals(200, lv); + } + else if (name == "PacingInterval") + { + assertTrue((qos[i].value >>= t) != 0); + assertEquals(420000, t); + } + else if (name == "StopTimeSupported") + { + assertTrue((qos[i].value >>= Any::to_boolean(bv)) != 0); + assertTrue(bv == 0); + } + else if (name == "MaxEventsPerConsumer") + { + assertTrue((qos[i].value >>= lv) != 0); + assertEquals(150, lv); + } + else + { + cout << "Unknown property name: " << name.c_str () << endl; + assertTrue(0); + } + } + qos2.length(1); + i = 0; + // Test that each unsupported option throws + //scope + { + ACE_TRY_NEW_ENV + { + qos2[i].name = CORBA::string_dup ("StartTime"); + qos2[i].value <<= defutc; + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + failIt("Expected UnsupportedQoS exception."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + //ok; + } + ACE_CATCHANY; + { + failIt("set_qos threw wrong exception."); + } + ACE_ENDTRY; + } //scope + + //scope + { + ACE_TRY_NEW_ENV + { + qos2[i].name = CORBA::string_dup ("StopTime"); + qos2[i].value <<= defutc; + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + failIt("Expected UnsupportedQoS exception."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + //ok; + } + ACE_CATCHANY; + { + failIt("set_qos threw wrong exception."); + } + ACE_ENDTRY; + } //scope + + //scope + { + ACE_TRY_NEW_ENV + { + qos2[i].name = CORBA::string_dup ("StartTimeSupported"); + qos2[i].value <<= Any::from_boolean(0); + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + failIt("Expected UnsupportedQoS exception."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + //ok; + } + ACE_CATCHANY; + { + failIt("set_qos threw wrong exception."); + } + ACE_ENDTRY; + } //scope + + // Test that common incorrect use of boolean throws + //scope + { + ACE_TRY_NEW_ENV + { + qos2[i].name = CORBA::string_dup ("StopTimeSupported"); + qos2[i].value <<= 0; // test no from_boolean() + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + failIt("Expected UnsupportedQoS exception."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + //ok; + } + ACE_CATCHANY; + { + failIt("set_qos threw wrong exception."); + } + ACE_ENDTRY; + } //scope + + // ditto for using an int as a Short + //scope + { + ACE_TRY_NEW_ENV + { + qos2[i].name = CORBA::string_dup ("Priority"); + qos2[i].value <<= 0; // test no <<= (Short) 0; + ec->set_qos(qos2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + failIt("Expected UnsupportedQoS exception."); + } + ACE_CATCH (CN::UnsupportedQoS, ex) + { + //ok; + } + ACE_CATCHANY; + { + failIt("set_qos threw wrong exception."); + } + ACE_ENDTRY; + } //scope + } +} // namespace diff --git a/TAO/orbsvcs/tests/Notify/Unit/TestQoS.h b/TAO/orbsvcs/tests/Notify/Unit/TestQoS.h new file mode 100644 index 00000000000..132081694d4 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/TestQoS.h @@ -0,0 +1,21 @@ +// $Id$ +// This file is kept as simple as possible, with hopes that it will +// be maintained as features are added to the NS. +#ifndef TAO_NOTIFY_UTEST_TESTQOS_H +#define TAO_NOTIFY_UTEST_TESTQOS_H +#include "UnitTester.h" + +// This particular unit test case is for testing out the basic +// features available to a corba client application. (ie Utils, Suppliers, Consumers) +namespace TestQoS { + + // Test that all NS objects have an ID which can be used in various ways + void testQoSChannel(ACE_ENV_SINGLE_ARG_DECL); + + inline void testAll(ACE_ENV_SINGLE_ARG_DECL) { + testQoSChannel(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} + +#endif diff --git a/TAO/orbsvcs/tests/Notify/Unit/UnitTester.h b/TAO/orbsvcs/tests/Notify/Unit/UnitTester.h new file mode 100644 index 00000000000..f95236cc7d3 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/UnitTester.h @@ -0,0 +1,64 @@ +// $Id$ +// No real framework is provided per se, just a bunch of macros that +// throw an exception class that must then be handled by a main program. +// Each project, such as the Notification service, should define a +// single main() which calls functions that may throw UnitTestException. + +#ifndef TAO_NOTIFY_UNITTESTER_H +#define TAO_NOTIFY_UNITTESTER_H +#include <tao/corba.h> +#include <ace/SString.h> + +#ifdef ACE_HAS_EXCEPTIONS + +class UnitTesterException { +public: + static ACE_CString create_message(const ACE_CString& s, const ACE_CString& file, int line) { + char tmp[100]; + ACE_OS::snprintf(tmp, 100, "%d", line); + return s + ACE_CString("\n ") + file + ACE_CString(":") + tmp; + } + + UnitTesterException(const ACE_CString& s, const ACE_CString& file, int line) + : msg_(create_message(s, file, line)) + { + } + const char* what() const { + return msg_.c_str(); + } +private: + ACE_CString msg_; +}; + +#define assertTrue(CONDITION) \ + if ((CONDITION) == false) { \ + throw UnitTesterException(#CONDITION, __FILE__, __LINE__); \ + } +#define failIt(MESSAGE)\ + throw UnitTesterException(#MESSAGE, __FILE__, __LINE__); + +#define assertEquals(COND1, COND2) \ + if ((COND1) != (COND2)) { \ + throw UnitTesterException(#COND1" != "#COND2, __FILE__, __LINE__); \ + } + +// Feel free to add other JUnit style assert tests here +#else /*ACE_HAS_EXCEPTIONS*/ +#define assertTrue(CONDITION) \ + if ((CONDITION) == false) { \ + ACE_ERROR((LM_ERROR, "Test Failed : %s\n %s:%d\n", #CONDITION, __FILE__, __LINE__));\ + ACE_OS::abort();\ + } +#define failIt(MESSAGE)\ + ACE_ERROR((LM_ERROR, "Test Failed : %s\n %s:%d\n", #MESSAGE, __FILE__, __LINE__));\ + ACE_OS::abort(); + +#define assertEquals(COND1, COND2) \ + if ((COND1) != (COND2)) { \ + ACE_ERROR((LM_ERROR, "Test Failed : %s != %s\n%s:%d\n", #COND1, #COND2, __FILE__, __LINE__));\ + ACE_OS::abort(); + +// Feel free to add other JUnit style assert tests here +#endif /*ACE_HAS_EXCEPTIONS*/ + +#endif diff --git a/TAO/orbsvcs/tests/Notify/Unit/main.cpp b/TAO/orbsvcs/tests/Notify/Unit/main.cpp new file mode 100644 index 00000000000..9257ea83fb8 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/main.cpp @@ -0,0 +1,51 @@ +// $Id$ +#include "TestBasicTypes.h" +#include "TestBuilder.h" +#include "TestBasic.h" +#include "TestQoS.h" + +#include <tao/corba.h> + +//// Uncomment for automatic memory leak detection on Windows. +//#include <stdlib.h> +//#include <crtdbg.h> + +int main(int, char**) +{ + //// Uncomment for automatic memory leak detection on Windows. + //_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + + int result = 0; + ACE_TRY_NEW_ENV + { + // To aid debugging, always put new tests first. + TestBasicTypes::testAll(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + TestBasic::testAll(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + TestBuilder::testAll(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + TestQoS::testAll(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Test failures throw UnitTesterException, so if we get here + ACE_OS::printf ("All Unit Tests passed successfully.\n"); + } + ACE_CATCHANY + { + ACE_ANY_EXCEPTION._tao_print_exception (ACE_TEXT ("Error caught in main"), stderr); + result = 1; + } + ACE_CATCH(UnitTesterException, ex) + { + ACE_OS::fprintf (stderr, "Error : Test Failed %s\n", ex.what()); + result = 1; + } + ACE_CATCHALL + { + cerr << "Error : Unknown exception running unit test." << endl; + result = 1; + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/tests/Notify/Unit/readme b/TAO/orbsvcs/tests/Notify/Unit/readme new file mode 100644 index 00000000000..9acec0faf6d --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/readme @@ -0,0 +1,40 @@ +$Id$ +README for the Notification Service Unit Tests +---------------------------------------------- + +This directory contains unit tests for the Notification Service. + +A lightweight unit test framework is used, and could later be +extended and used for other tests. + +Files in this directory +----------------------- + main.cpp -- runs tests, catches and prints exceptions + UnitTester.h -- declare test exception, assert functions, etc. + Test*.h, Test*.cpp -- the actual tests + Notify_Unit.mpc -- mpc to generate build files + readme -- this file + run_test.pl -- run tests automatically + start_ns.pl -- start naming service/notification service to + allow manual testing. + +The Tests and Subtests +---------------------- +TestBasicTypes -- tests for underlying data structures + testNVP -- name value pair to support properties + testQoSBasic -- QoS properties test + +TestBasic -- test basic channel and admin creation + testChannelCreate -- tests the creation of a channel + testAdminCreate -- tests creation of an admin in the channel. + +TestBuilder -- tests topology objects and "builder" operation + testBuildECF -- event channel factory + testBuildEC -- event channel + testTopologyPersist -- save / load persistent topology information + testSubscriptionTopology -- basic subcription operation. + +TestQoS -- test Quality of Service parameters + testQoSChannel -- sets QoS parameters at the channel level + + diff --git a/TAO/orbsvcs/tests/Notify/Unit/run_test.pl b/TAO/orbsvcs/tests/Notify/Unit/run_test.pl new file mode 100644 index 00000000000..b238949ea88 --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/run_test.pl @@ -0,0 +1,43 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# ex + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +$ACE_ROOT = $ENV{ACE_ROOT}; +$TAO_ROOT = "$ACE_ROOT/TAO"; + +$notify_ior = PerlACE::LocalFile("notify.ior"); + +unlink $notify_ior; + +$NS = new PerlACE::Process("$TAO_ROOT/orbsvcs/Notify_Service/Notify_Service"); +$NS->Arguments(" -NoNameSvc -Boot -IORoutput $notify_ior -ORBEndpoint iiop://:9050 "); +$NS->Spawn(); + +if (PerlACE::waitforfile_timed ($notify_ior, 5) == -1) { + print STDERR "ERROR: Timed out waiting for $notify_ior\n"; + $NS->Kill (); + return 1; +} + +## Note : For ease of use, the unit test is hardcoded to use a +## corbaloc, which requires that the NS be started with +## -Boot and -NoNameSvc on the expected port. +## The ior file written above is only used so that this perl script +## will know when it's safe to start the unit test. + +$UTEST = new PerlACE::Process("main"); +$ret = $UTEST->SpawnWaitKill(5); + +$NS->Kill(); + +unlink $notify_ior; + +exit $ret; diff --git a/TAO/orbsvcs/tests/Notify/Unit/start_ns.pl b/TAO/orbsvcs/tests/Notify/Unit/start_ns.pl new file mode 100644 index 00000000000..7df54591dab --- /dev/null +++ b/TAO/orbsvcs/tests/Notify/Unit/start_ns.pl @@ -0,0 +1,32 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +$ACE_ROOT = $ENV{ACE_ROOT}; +$TAO_ROOT = "$ACE_ROOT/TAO"; + +$notify_ior = PerlACE::LocalFile("notify.ior"); + +unlink $notify_ior; + +$NS = new PerlACE::Process("$TAO_ROOT/orbsvcs/Notify_Service/Notify_Service"); +$NS->Arguments(" -NoNameSvc -Boot -IORoutput $notify_ior -ORBEndpoint iiop://:9050 "); +$NS->Spawn(); + +if (PerlACE::waitforfile_timed ($notify_ior, 5) == -1) { + print STDERR "ERROR: Timed out waiting for $notify_ior\n"; + $NS->Kill (); + return 1; +} + +$NS->Wait(); + +unlink $notify_ior; + +exit $ret; |