summaryrefslogtreecommitdiff
path: root/ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp')
-rw-r--r--ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp478
1 files changed, 478 insertions, 0 deletions
diff --git a/ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp b/ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp
new file mode 100644
index 00000000000..787ea85518c
--- /dev/null
+++ b/ACE/TAO/orbsvcs/tests/Notify/MC/test_monitor.cpp
@@ -0,0 +1,478 @@
+// $Id$
+
+#include "ace/Get_Opt.h"
+#include "ace/Monitor_Point_Registry.h"
+
+#include "orbsvcs/Notify/MonitorControl/NotificationServiceMCC.h"
+#include "orbsvcs/Notify/MonitorControlExt/NotifyMonitoringExtC.h"
+
+#if defined (TAO_HAS_MONITOR_FRAMEWORK) && (TAO_HAS_MONITOR_FRAMEWORK == 1)
+
+using namespace ACE_VERSIONED_NAMESPACE_NAME::ACE::Monitor_Control;
+
+#include "MonitorTestInterfaceS.h"
+extern "C" int
+sorter (const void* a, const void* b)
+{
+ const char* left = *(reinterpret_cast<const char* const*> (a));
+ const char* right = *(reinterpret_cast<const char* const*> (b));
+ return ACE_OS::strcmp (left, right);
+}
+
+
+
+// It's reasonable to assume that there is only one event channel
+// factory and that we know its name.
+class MonitorTestInterface_i: public virtual POA_MonitorTestInterface
+{
+public:
+ MonitorTestInterface_i (
+ CosNotification::NotificationServiceMonitorControl_ptr nsm)
+ : nsm_ (CosNotification::NotificationServiceMonitorControl::_duplicate (nsm))
+ {
+ }
+
+ virtual void
+ running (MonitorTestInterface::Which proc);
+
+ virtual void
+ finished (MonitorTestInterface::Which proc);
+
+private:
+ void brain_dump (const char * context);
+ void stat_dump (const char * statName);
+ void consumer_stats_check (void);
+private:
+ ACE_CString base_;
+ CosNotification::NotificationServiceMonitorControl_var nsm_;
+};
+
+void
+MonitorTestInterface_i::running (MonitorTestInterface::Which proc)
+{
+ ACE_CString str;
+ Monitor::Data_var data;
+ Monitor::NameList list;
+ Monitor::Numeric num;
+
+ switch (proc)
+ {
+ case MonitorTestInterface::NotifyService:
+ {
+ data =
+ nsm_->get_statistic (NotifyMonitoringExt::EventChannelFactoryNames);
+ list = data->data_union.list ();
+
+ if (list.length () != 1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: There should be only one Event "
+ "Channel Factory\n"));
+ }
+
+ this->base_ = list[0];
+ this->base_ += "/";
+ str = this->base_ + NotifyMonitoringExt::ActiveEventChannelCount;
+ data = this->nsm_->get_statistic (str.c_str ());
+ num = data->data_union.num ();
+
+ if (num.dlist[0].value != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: There should be no active Event "
+ "Channels\n"));
+ }
+
+ str = this->base_ + NotifyMonitoringExt::InactiveEventChannelCount;
+ data = this->nsm_->get_statistic (str.c_str ());
+ num = data->data_union.num ();
+
+ if (num.dlist[0].value != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: There should be no inactive Event "
+ "Channels\n"));
+ }
+
+ break;
+ }
+ case MonitorTestInterface::Consumer:
+ {
+ str = this->base_ + NotifyMonitoringExt::ActiveEventChannelNames;
+ data = nsm_->get_statistic (str.c_str ());
+ list = data->data_union.list ();
+
+ if (list.length () != 1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: There should be only one active "
+ "Event Channel\n"));
+ }
+
+ // Base will now be the factory plus the event channel.
+ this->base_ = list[0];
+ this->base_ += "/";
+
+ str = this->base_ + NotifyMonitoringExt::EventChannelConsumerCount;
+ data = this->nsm_->get_statistic (str.c_str ());
+ num = data->data_union.num ();
+ if (num.dlist[0].value != 1)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be only one Consumer\n"));
+
+ str = this->base_ + NotifyMonitoringExt::EventChannelConsumerAdminCount;
+ data = nsm_->get_statistic(str.c_str ());
+ num = data->data_union.num ();
+ if (num.dlist[0].value != 1)
+ ACE_ERROR ((LM_ERROR,
+ "Monitor: ERROR: There should be only one ConsumerAdmin\n"));
+
+ str = this->base_ + NotifyMonitoringExt::EventChannelQueueElementCount;
+ data = nsm_->get_statistic(str.c_str ());
+ num = data->data_union.num ();
+ if (num.dlist[0].value != 0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be no events queued\n"));
+
+ brain_dump ("Running Consumer");
+
+ break;
+ }
+ case MonitorTestInterface::Supplier:
+ {
+ str = this->base_ + NotifyMonitoringExt::EventChannelSupplierCount;
+ data = nsm_->get_statistic(str.c_str ());
+ num = data->data_union.num ();
+
+ if (num.dlist[0].value != 1)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be only one Supplier\n"));
+
+ str = this->base_ + NotifyMonitoringExt::EventChannelSupplierAdminCount;
+ data = nsm_->get_statistic(str.c_str ());
+ num = data->data_union.num ();
+ if (num.dlist[0].value != 1)
+ ACE_ERROR ((LM_ERROR,
+ "Monitor: ERROR: There should be only one SupplierAdmin\n"));
+ brain_dump ("Running Supplier");
+ break;
+ }
+ default:
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: Impossible enum value %d\n", proc));
+ break;
+ }
+}
+
+void
+MonitorTestInterface_i::consumer_stats_check()
+{
+ bool foundConsumerStats = false;
+ Monitor::NameList_var names = nsm_->get_statistic_names ();
+ CORBA::ULong length = names->length ();
+ for(CORBA::ULong i = 0; i < length; i++)
+ {
+ const char * name = names[i].in ();
+ size_t slashcount = 0;
+ bool isConsumerQueueSize = false;
+ for (size_t nCh = 0; name[nCh] != 0 && slashcount < 3; ++nCh)
+ {
+ if (name[nCh] == '/')
+ {
+ slashcount += 1;
+ if(slashcount == 3)
+ {
+ isConsumerQueueSize = 0 == ACE_OS::strcmp(
+ &name[nCh + 1],
+ NotifyMonitoringExt::EventChannelQueueSize);
+ }
+ }
+ }
+ if (isConsumerQueueSize)
+ {
+ foundConsumerStats = true;
+ // We have a consumer queue
+ try
+ {
+ Monitor::Data_var queueSizeData =
+ nsm_->get_statistic(name);
+
+ Monitor::Numeric queueSizeNum = queueSizeData->data_union.num ();
+ ACE_DEBUG ((LM_DEBUG, "Monitor: %s: Average: %f, Maximum: %f, Most recent: %f\n",
+ name,
+ queueSizeNum.average, queueSizeNum.maximum, queueSizeNum.last));
+ if (queueSizeNum.average <= 0.0 || queueSizeNum.average > 2000.0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: %s average queue size [%f] should be greater than zero and less than 2000.\n",
+ name,
+ queueSizeNum.average));
+ if (queueSizeNum.last > 2000.0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: %s most recent queue size [%f] should not be greater than 2000.\n",
+ name,
+ queueSizeNum.last));
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (name);
+ }
+ }
+
+ }
+ if(! foundConsumerStats)
+ {
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: No consumer queue size statistics found.\n"
+ ));
+ }
+}
+
+void
+MonitorTestInterface_i::brain_dump(const char * /*context*/)
+{
+#if 0 // verbose output should be controlled via a command line option
+ ACE_DEBUG ((LM_DEBUG, "\nStatistics as of: %s\n", context));
+ // Temporary::Dale: Dump known names
+ CosNotification::NotificationServiceMonitorControl::NameList_var names =
+ nsm_->get_statistic_names ();
+ CORBA::ULong length = names->length ();
+ ACE_DEBUG ((LM_DEBUG, "Statistic names [%d]\n", (int)length));
+
+ // It's much easier to read once it's sorted
+ const char** narray = 0;
+ ACE_NEW_THROW_EX (narray,
+ const char* [length],
+ CORBA::NO_MEMORY ());
+ for(CORBA::ULong i = 0; i < length; i++)
+ narray[i] = names[i].in ();
+ ACE_OS::qsort (narray, length,
+ sizeof (const char*), sorter);
+
+ for(CORBA::ULong i = 0; i < length; i++)
+ {
+ stat_dump(narray[i]);
+ }
+ delete [] narray;
+#endif // verbose option
+}
+
+void
+MonitorTestInterface_i::stat_dump (const char * statName)
+{
+ try
+ {
+ Monitor::Data_var data = nsm_->get_statistic(statName);
+ switch (data->data_union._d())
+ {
+ case Monitor::DATA_NUMERIC:
+ {
+ ACE_DEBUG ((LM_DEBUG, "Numeric: %s\n", statName));
+ Monitor::Numeric num = data->data_union.num();
+ ACE_DEBUG ((LM_DEBUG, " count: %d, average: %f; sumsq: %f, min: %f, max: %f: last %f\n",
+ (unsigned int)num.count, num.average, num.sum_of_squares, num.minimum, num.maximum, num.last));
+ break;
+ }
+ default:
+ {
+ Monitor::NameList list = data->data_union.list ();
+ size_t len = list.length ();
+ ACE_DEBUG ((LM_DEBUG, "Text[%d]: %s\n", (int)len, statName));
+
+ for (size_t i = 0; i < len; i++)
+ {
+ ACE_CString str = list[i].in ();
+ ACE_DEBUG ((LM_DEBUG, " %d: %s\n", (int)i, str.c_str()));
+ }
+ break;
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+
+ ex._tao_print_exception (statName);
+ }
+}
+
+
+void
+MonitorTestInterface_i::finished (MonitorTestInterface::Which proc)
+{
+// ACE_CString str;
+// Monitor::Data_var data;
+// Monitor::NameList list;
+// Monitor::Numeric num;
+
+ switch (proc)
+ {
+ case MonitorTestInterface::NotifyService:
+ ACE_ERROR ((LM_ERROR, "This should not be called\n"));
+ break;
+ case MonitorTestInterface::Consumer:
+ // By the time the consumer finishes, it should have destroyed
+ // the event channel.
+ this->running (MonitorTestInterface::NotifyService);
+ break;
+ case MonitorTestInterface::Supplier:
+ {
+ ACE_CString consumerCountName = this->base_ + NotifyMonitoringExt::EventChannelConsumerCount;
+ Monitor::Data_var consumerCountData =
+ nsm_->get_statistic(consumerCountName.c_str ());
+ Monitor::Numeric consumerCountNum =
+ consumerCountData->data_union.num ();
+ if (consumerCountNum.last != 1)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should still be one Consumer\n"));
+
+ ACE_CString queueElementName = this->base_ + NotifyMonitoringExt::EventChannelQueueElementCount;
+ Monitor::Data_var queueElementData =
+ nsm_->get_statistic(queueElementName.c_str ());
+ Monitor::Numeric queueElementNum =
+ queueElementData->data_union.num ();
+ if (queueElementNum.last == 0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be at least one "
+ "event queued\n"));
+
+ ACE_CString adminNamesName = this->base_ + NotifyMonitoringExt::EventChannelConsumerAdminNames;
+ Monitor::Data_var adminNamesData =
+ nsm_->get_statistic(adminNamesName.c_str ());
+ Monitor::NameList nameList =
+ adminNamesData->data_union.list ();
+ for (CORBA::ULong i = 0; i < nameList.length (); i++)
+ {
+ ACE_CString queueSizeName = nameList[i].in ();
+ queueSizeName += "/";
+ queueSizeName += NotifyMonitoringExt::EventChannelQueueSize;
+ Monitor::Data_var queueSizeData =
+ nsm_->get_statistic(queueSizeName.c_str ());
+ Monitor::Numeric queueSizeNum =
+ queueSizeData->data_union.num ();
+ ACE_DEBUG ((LM_DEBUG, "Monitor: Queue Size: Average: %f, Maximum: %f, Most recent: %f\n",
+ queueSizeNum.average, queueSizeNum.maximum, queueSizeNum.last));
+ if (queueSizeNum.average <= 0.0 || queueSizeNum.average > 2000.0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: The average queue size [%f] should be greater than zero and less than 2000.\n",
+ queueSizeNum.average));
+ if (queueSizeNum.last > 2000.0)
+ ACE_ERROR ((LM_ERROR, "Monitor: ERROR: The most recent queue size [%f] should not be greater than 2000.\n",
+ queueSizeNum.last));
+ }
+
+ consumer_stats_check();
+
+ brain_dump ("Finished Supplier");
+ break;
+ }
+ default:
+ ACE_ERROR ((LM_ERROR, "Impossible enum value %d\n", proc));
+ break;
+ }
+}
+
+static const ACE_TCHAR* ior_output_file = ACE_TEXT ("test_monitor.ior");
+static const ACE_TCHAR* monitor_ior = 0;
+
+static int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("k:o:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'k':
+ monitor_ior = get_opts.opt_arg ();
+ break;
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Monitor: usage: %s "
+ "-k <ior> "
+ "-o <file> "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ return 0;
+}
+
+#endif /* TAO_HAS_MONITOR_FRAMEWORK==1 */
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR* argv[])
+{
+ int status = 0;
+
+#if defined (TAO_HAS_MONITOR_FRAMEWORK) && (TAO_HAS_MONITOR_FRAMEWORK == 1)
+
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ {
+ return 1;
+ }
+
+ CORBA::Object_var obj =
+ orb->string_to_object (monitor_ior);
+ CosNotification::NotificationServiceMonitorControl_var nsm =
+ CosNotification::NotificationServiceMonitorControl::_narrow (obj.in ());
+
+ if (CORBA::is_nil (nsm.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Monitor: Unable to locate the "
+ "Notification Service Monitor\n"),
+ 1);
+ }
+
+ MonitorTestInterface_i* mti = 0;
+ ACE_NEW_RETURN (mti, MonitorTestInterface_i (nsm.in ()), 1);
+ PortableServer::ServantBase_var owner_transfer (mti);
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA");
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in ());
+
+ PortableServer::ObjectId_var id = root_poa->activate_object (mti);
+ CORBA::Object_var object = root_poa->id_to_reference (id.in ());
+
+ MonitorTestInterface_var test =
+ MonitorTestInterface::_narrow (object.in ());
+ CORBA::String_var ior = orb->object_to_string (test.in ());
+
+ // Test the case where there are no consumers or suppliers first
+ // before we write out our IOR
+ mti->running (MonitorTestInterface::NotifyService);
+
+ FILE *output_file= ACE_OS::fopen (ACE_TEXT_ALWAYS_CHAR(ior_output_file), ACE_TEXT ("w"));
+
+ if (output_file == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s\n",
+ ior_output_file),
+ 1);
+ }
+
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager ();
+ poa_manager->activate ();
+
+ orb->run ();
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("test_monitor: ");
+ status++;
+ }
+
+#else
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+#endif /* TAO_HAS_MONITOR_FRAMEWORK==1 */
+
+ return status;
+}
+