Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / orbsvcs / tests / Notify / MC / test_monitor.cpp
blob6f3a741ea986fb262c500208c3c151358892e065
1 #include "ace/Get_Opt.h"
2 #include "ace/Monitor_Point_Registry.h"
4 #include "orbsvcs/Notify/MonitorControl/NotificationServiceMCC.h"
5 #include "orbsvcs/Notify/MonitorControlExt/NotifyMonitoringExtC.h"
7 #if defined (TAO_HAS_MONITOR_FRAMEWORK) && (TAO_HAS_MONITOR_FRAMEWORK == 1)
9 using namespace ACE_VERSIONED_NAMESPACE_NAME::ACE::Monitor_Control;
11 #include "MonitorTestInterfaceS.h"
12 extern "C" int
13 sorter (const void* a, const void* b)
15 const char* left = *(reinterpret_cast<const char* const*> (a));
16 const char* right = *(reinterpret_cast<const char* const*> (b));
17 return ACE_OS::strcmp (left, right);
22 // It's reasonable to assume that there is only one event channel
23 // factory and that we know its name.
24 class MonitorTestInterface_i: public virtual POA_MonitorTestInterface
26 public:
27 MonitorTestInterface_i (
28 CosNotification::NotificationServiceMonitorControl_ptr nsm)
29 : nsm_ (CosNotification::NotificationServiceMonitorControl::_duplicate (nsm))
33 virtual void
34 running (MonitorTestInterface::Which proc);
36 virtual void
37 finished (MonitorTestInterface::Which proc);
39 private:
40 void brain_dump (const char * context);
41 void stat_dump (const char * statName);
42 void consumer_stats_check (void);
43 private:
44 ACE_CString base_;
45 CosNotification::NotificationServiceMonitorControl_var nsm_;
48 void
49 MonitorTestInterface_i::running (MonitorTestInterface::Which proc)
51 ACE_CString str;
52 Monitor::Data_var data;
53 Monitor::NameList list;
54 Monitor::Numeric num;
56 switch (proc)
58 case MonitorTestInterface::NotifyService:
60 data =
61 nsm_->get_statistic (NotifyMonitoringExt::EventChannelFactoryNames);
62 list = data->data_union.list ();
64 if (list.length () != 1)
66 ACE_ERROR ((LM_ERROR,
67 "ERROR: There should be only one Event "
68 "Channel Factory\n"));
71 this->base_ = list[0];
72 this->base_ += "/";
73 str = this->base_ + NotifyMonitoringExt::ActiveEventChannelCount;
74 data = this->nsm_->get_statistic (str.c_str ());
75 num = data->data_union.num ();
77 if (!ACE::is_equal (num.dlist[0].value, 0.0))
79 ACE_ERROR ((LM_ERROR,
80 "ERROR: There should be no active Event "
81 "Channels\n"));
84 str = this->base_ + NotifyMonitoringExt::InactiveEventChannelCount;
85 data = this->nsm_->get_statistic (str.c_str ());
86 num = data->data_union.num ();
88 if (!ACE::is_equal (num.dlist[0].value, 0.0))
90 ACE_ERROR ((LM_ERROR,
91 "ERROR: There should be no inactive Event "
92 "Channels\n"));
95 break;
97 case MonitorTestInterface::Consumer:
99 str = this->base_ + NotifyMonitoringExt::ActiveEventChannelNames;
100 data = nsm_->get_statistic (str.c_str ());
101 list = data->data_union.list ();
103 if (list.length () != 1)
105 ACE_ERROR ((LM_ERROR,
106 "ERROR: There should be only one active "
107 "Event Channel\n"));
110 // Base will now be the factory plus the event channel.
111 this->base_ = list[0];
112 this->base_ += "/";
114 str = this->base_ + NotifyMonitoringExt::EventChannelConsumerCount;
115 data = this->nsm_->get_statistic (str.c_str ());
116 num = data->data_union.num ();
117 if (!ACE::is_equal (num.dlist[0].value, 1.0))
118 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be only one Consumer\n"));
120 str = this->base_ + NotifyMonitoringExt::EventChannelConsumerAdminCount;
121 data = nsm_->get_statistic(str.c_str ());
122 num = data->data_union.num ();
123 if (!ACE::is_equal (num.dlist[0].value, 1.0))
124 ACE_ERROR ((LM_ERROR,
125 "Monitor: ERROR: There should be only one ConsumerAdmin\n"));
127 str = this->base_ + NotifyMonitoringExt::EventChannelQueueElementCount;
128 data = nsm_->get_statistic(str.c_str ());
129 num = data->data_union.num ();
130 if (!ACE::is_equal (num.dlist[0].value, 0.0))
131 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be no events queued\n"));
133 brain_dump ("Running Consumer");
135 break;
137 case MonitorTestInterface::Supplier:
139 str = this->base_ + NotifyMonitoringExt::EventChannelSupplierCount;
140 data = nsm_->get_statistic(str.c_str ());
141 num = data->data_union.num ();
143 if (!ACE::is_equal (num.dlist[0].value, 1.0))
144 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be only one Supplier\n"));
146 str = this->base_ + NotifyMonitoringExt::EventChannelSupplierAdminCount;
147 data = nsm_->get_statistic(str.c_str ());
148 num = data->data_union.num ();
149 if (!ACE::is_equal (num.dlist[0].value, 1.0))
150 ACE_ERROR ((LM_ERROR,
151 "Monitor: ERROR: There should be only one SupplierAdmin\n"));
152 brain_dump ("Running Supplier");
153 break;
155 default:
156 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: Impossible enum value %d\n", proc));
157 break;
161 void
162 MonitorTestInterface_i::consumer_stats_check()
164 bool foundConsumerStats = false;
165 Monitor::NameList_var names = nsm_->get_statistic_names ();
166 CORBA::ULong length = names->length ();
167 for(CORBA::ULong i = 0; i < length; i++)
169 const char * name = names[i].in ();
170 size_t slashcount = 0;
171 bool isConsumerQueueSize = false;
172 for (size_t nCh = 0; name[nCh] != 0 && slashcount < 3; ++nCh)
174 if (name[nCh] == '/')
176 slashcount += 1;
177 if(slashcount == 3)
179 isConsumerQueueSize = 0 == ACE_OS::strcmp(
180 &name[nCh + 1],
181 NotifyMonitoringExt::EventChannelQueueSize);
185 if (isConsumerQueueSize)
187 foundConsumerStats = true;
188 // We have a consumer queue
191 Monitor::Data_var queueSizeData =
192 nsm_->get_statistic(name);
194 Monitor::Numeric queueSizeNum = queueSizeData->data_union.num ();
195 ACE_DEBUG ((LM_DEBUG, "Monitor: %s: Average: %f, Maximum: %f, Most recent: %f\n",
196 name,
197 queueSizeNum.average, queueSizeNum.maximum, queueSizeNum.last));
198 if (queueSizeNum.average <= 0.0 || queueSizeNum.average > 2000.0)
199 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: %s average queue size [%f] should be greater than zero and less than 2000.\n",
200 name,
201 queueSizeNum.average));
202 if (queueSizeNum.last > 2000.0)
203 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: %s most recent queue size [%f] should not be greater than 2000.\n",
204 name,
205 queueSizeNum.last));
207 catch (const CORBA::Exception& ex)
209 ex._tao_print_exception (name);
214 if(! foundConsumerStats)
216 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: No consumer queue size statistics found.\n"
221 void
222 MonitorTestInterface_i::brain_dump(const char * /*context*/)
224 #if 0 // verbose output should be controlled via a command line option
225 ACE_DEBUG ((LM_DEBUG, "\nStatistics as of: %s\n", context));
226 // Temporary::Dale: Dump known names
227 CosNotification::NotificationServiceMonitorControl::NameList_var names =
228 nsm_->get_statistic_names ();
229 CORBA::ULong length = names->length ();
230 ACE_DEBUG ((LM_DEBUG, "Statistic names [%d]\n", (int)length));
232 // It's much easier to read once it's sorted
233 const char** narray = 0;
234 ACE_NEW_THROW_EX (narray,
235 const char* [length],
236 CORBA::NO_MEMORY ());
237 for(CORBA::ULong i = 0; i < length; i++)
238 narray[i] = names[i].in ();
239 ACE_OS::qsort (narray, length,
240 sizeof (const char*), sorter);
242 for(CORBA::ULong i = 0; i < length; i++)
244 stat_dump(narray[i]);
246 delete [] narray;
247 #endif // verbose option
250 void
251 MonitorTestInterface_i::stat_dump (const char * statName)
255 Monitor::Data_var data = nsm_->get_statistic(statName);
256 switch (data->data_union._d())
258 case Monitor::DATA_NUMERIC:
260 ACE_DEBUG ((LM_DEBUG, "Numeric: %s\n", statName));
261 Monitor::Numeric num = data->data_union.num();
262 ACE_DEBUG ((LM_DEBUG, " count: %d, average: %f; sumsq: %f, min: %f, max: %f: last %f\n",
263 (unsigned int)num.count, num.average, num.sum_of_squares, num.minimum, num.maximum, num.last));
264 break;
266 default:
268 Monitor::NameList list = data->data_union.list ();
269 size_t len = list.length ();
270 ACE_DEBUG ((LM_DEBUG, "Text[%d]: %s\n", (int)len, statName));
272 for (size_t i = 0; i < len; i++)
274 ACE_CString str = list[i].in ();
275 ACE_DEBUG ((LM_DEBUG, " %d: %s\n", (int)i, str.c_str()));
277 break;
281 catch (const CORBA::Exception& ex)
284 ex._tao_print_exception (statName);
289 void
290 MonitorTestInterface_i::finished (MonitorTestInterface::Which proc)
292 // ACE_CString str;
293 // Monitor::Data_var data;
294 // Monitor::NameList list;
295 // Monitor::Numeric num;
297 switch (proc)
299 case MonitorTestInterface::NotifyService:
300 ACE_ERROR ((LM_ERROR, "This should not be called\n"));
301 break;
302 case MonitorTestInterface::Consumer:
303 // By the time the consumer finishes, it should have destroyed
304 // the event channel.
305 this->running (MonitorTestInterface::NotifyService);
306 break;
307 case MonitorTestInterface::Supplier:
309 ACE_CString consumerCountName = this->base_ + NotifyMonitoringExt::EventChannelConsumerCount;
310 Monitor::Data_var consumerCountData =
311 nsm_->get_statistic(consumerCountName.c_str ());
312 Monitor::Numeric consumerCountNum =
313 consumerCountData->data_union.num ();
314 if (!ACE::is_equal (consumerCountNum.last, 1.0))
315 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should still be one Consumer\n"));
317 ACE_CString queueElementName = this->base_ + NotifyMonitoringExt::EventChannelQueueElementCount;
318 Monitor::Data_var queueElementData =
319 nsm_->get_statistic(queueElementName.c_str ());
320 Monitor::Numeric queueElementNum =
321 queueElementData->data_union.num ();
322 if (ACE::is_equal (queueElementNum.last, 0.0))
323 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: There should be at least one "
324 "event queued\n"));
326 ACE_CString adminNamesName = this->base_ + NotifyMonitoringExt::EventChannelConsumerAdminNames;
327 Monitor::Data_var adminNamesData =
328 nsm_->get_statistic(adminNamesName.c_str ());
329 Monitor::NameList nameList =
330 adminNamesData->data_union.list ();
331 for (CORBA::ULong i = 0; i < nameList.length (); i++)
333 ACE_CString queueSizeName = nameList[i].in ();
334 queueSizeName += "/";
335 queueSizeName += NotifyMonitoringExt::EventChannelQueueSize;
336 Monitor::Data_var queueSizeData =
337 nsm_->get_statistic(queueSizeName.c_str ());
338 Monitor::Numeric queueSizeNum =
339 queueSizeData->data_union.num ();
340 ACE_DEBUG ((LM_DEBUG, "Monitor: Queue Size: Average: %f, Maximum: %f, Most recent: %f\n",
341 queueSizeNum.average, queueSizeNum.maximum, queueSizeNum.last));
342 if (queueSizeNum.average <= 0.0 || queueSizeNum.average > 2000.0)
343 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: The average queue size [%f] should be greater than zero and less than 2000.\n",
344 queueSizeNum.average));
345 if (queueSizeNum.last > 2000.0)
346 ACE_ERROR ((LM_ERROR, "Monitor: ERROR: The most recent queue size [%f] should not be greater than 2000.\n",
347 queueSizeNum.last));
350 consumer_stats_check();
352 brain_dump ("Finished Supplier");
353 break;
355 default:
356 ACE_ERROR ((LM_ERROR, "Impossible enum value %d\n", proc));
357 break;
361 static const ACE_TCHAR* ior_output_file = ACE_TEXT ("test_monitor.ior");
362 static const ACE_TCHAR* monitor_ior = 0;
364 static int
365 parse_args (int argc, ACE_TCHAR *argv[])
367 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("k:o:"));
368 int c;
370 while ((c = get_opts ()) != -1)
371 switch (c)
373 case 'k':
374 monitor_ior = get_opts.opt_arg ();
375 break;
376 case 'o':
377 ior_output_file = get_opts.opt_arg ();
378 break;
379 case '?':
380 default:
381 ACE_ERROR_RETURN ((LM_ERROR,
382 "Monitor: usage: %s "
383 "-k <ior> "
384 "-o <file> "
385 "\n",
386 argv [0]),
387 -1);
389 return 0;
392 #endif /* TAO_HAS_MONITOR_FRAMEWORK==1 */
395 ACE_TMAIN (int argc, ACE_TCHAR* argv[])
397 int status = 0;
399 #if defined (TAO_HAS_MONITOR_FRAMEWORK) && (TAO_HAS_MONITOR_FRAMEWORK == 1)
403 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
405 if (parse_args (argc, argv) != 0)
407 return 1;
410 CORBA::Object_var obj =
411 orb->string_to_object (monitor_ior);
412 CosNotification::NotificationServiceMonitorControl_var nsm =
413 CosNotification::NotificationServiceMonitorControl::_narrow (obj.in ());
415 if (CORBA::is_nil (nsm.in ()))
417 ACE_ERROR_RETURN ((LM_ERROR,
418 "Monitor: Unable to locate the "
419 "Notification Service Monitor\n"),
423 MonitorTestInterface_i* mti = 0;
424 ACE_NEW_RETURN (mti, MonitorTestInterface_i (nsm.in ()), 1);
425 PortableServer::ServantBase_var owner_transfer (mti);
427 CORBA::Object_var poa_object =
428 orb->resolve_initial_references("RootPOA");
429 PortableServer::POA_var root_poa =
430 PortableServer::POA::_narrow (poa_object.in ());
432 PortableServer::ObjectId_var id = root_poa->activate_object (mti);
433 CORBA::Object_var object = root_poa->id_to_reference (id.in ());
435 MonitorTestInterface_var test =
436 MonitorTestInterface::_narrow (object.in ());
437 CORBA::String_var ior = orb->object_to_string (test.in ());
439 // Test the case where there are no consumers or suppliers first
440 // before we write out our IOR
441 mti->running (MonitorTestInterface::NotifyService);
443 FILE *output_file= ACE_OS::fopen (ACE_TEXT_ALWAYS_CHAR(ior_output_file), ACE_TEXT ("w"));
445 if (output_file == 0)
447 ACE_ERROR_RETURN ((LM_ERROR,
448 "Cannot open output file for writing IOR: %s\n",
449 ior_output_file),
453 ACE_OS::fprintf (output_file, "%s", ior.in ());
454 ACE_OS::fclose (output_file);
456 PortableServer::POAManager_var poa_manager =
457 root_poa->the_POAManager ();
458 poa_manager->activate ();
460 orb->run ();
461 orb->destroy ();
463 catch (const CORBA::Exception& ex)
465 ex._tao_print_exception ("test_monitor: ");
466 status++;
469 #else
470 ACE_UNUSED_ARG (argc);
471 ACE_UNUSED_ARG (argv);
472 #endif /* TAO_HAS_MONITOR_FRAMEWORK==1 */
474 return status;