summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-10-11 20:10:18 +0000
committerwilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2004-10-11 20:10:18 +0000
commit027f027576d52551ff80d9bcc5ab586823599d36 (patch)
treec96bef9b06056900ab7358d93504edc758d82632
parent77c566edf39533401136410e0f00dbfd7e525fd1 (diff)
downloadATCD-027f027576d52551ff80d9bcc5ab586823599d36.tar.gz
ChangeLogTag: Mon Oct 11 14:39:15 2004 Dale Wilson <wilson_d@ociweb.com>
-rw-r--r--TAO/ChangeLog_pnotify17
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/Notify_Unit.mpc3
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBasic.cpp190
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBasic.h22
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.cpp235
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBasicTypes.h24
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBuilder.cpp564
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestBuilder.h25
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestQoS.cpp325
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/TestQoS.h21
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/UnitTester.h64
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/main.cpp51
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/readme40
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/run_test.pl43
-rw-r--r--TAO/orbsvcs/tests/Notify/Unit/start_ns.pl32
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;