1 yi.zhou 1.1 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 yi.zhou 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Yi Zhou, Hewlett-Packard Company (Yi.Zhou@hp.com)
33 //
34 // Modified By:
35 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include <Pegasus/Common/PegasusAssert.h>
39 #include <Pegasus/Common/Thread.h>
40 #include <Pegasus/Common/Constants.h>
41 #include <Pegasus/Common/FileSystem.h>
42 #include <Pegasus/Common/Stopwatch.h>
43 yi.zhou 1.1 #include <Pegasus/Client/CIMClient.h>
44
45 PEGASUS_USING_PEGASUS;
46 PEGASUS_USING_STD;
47
48 const CIMNamespaceName INTEROP_NAMESPACE = CIMNamespaceName ("root/PG_InterOp");
49 const CIMNamespaceName SOURCE_NAMESPACE =
50 CIMNamespaceName ("root/SampleProvider");
51
52 const String INDICATION_CLASS_NAME = String ("RT_TestIndication");
53
54 const String SNMPV1_HANDLER_NAME = String ("SNMPHandler01");
55 const String SNMPV2C_HANDLER_NAME = String ("SNMPHandler02");
56 const String FILTER_NAME = String ("IPFilter01");
57
58 enum SNMPVersion {_SNMPV1_TRAP = 2, _SNMPV2C_TRAP = 3};
59 enum TargetHostFormat {_HOST_NAME = 2, _IPV4_ADDRESS = 3};
60
61 #define PORT_NUMBER 2006
62
63 Uint32 indicationSendCountTotal = 0;
64 yi.zhou 1.1
65 AtomicInt errorsEncountered(0);
66
67 ////////////////////////////////////////////////////////////////////////////////
68 //
69 // Thread Parameters Class
70 //
71 ////////////////////////////////////////////////////////////////////////////////
72
73 class T_Parms{
74 public:
75 AutoPtr<CIMClient> client;
76 Uint32 indicationSendCount;
77 Uint32 uniqueID;
78 };
79
80 ///////////////////////////////////////////////////////////////////////////
81
82 CIMObjectPath _getFilterObjectPath
83 (const String & name)
84 {
85 yi.zhou 1.1 Array<CIMKeyBinding> keyBindings;
86 keyBindings.append (CIMKeyBinding ("SystemCreationClassName",
87 System::getSystemCreationClassName (), CIMKeyBinding::STRING));
88 keyBindings.append (CIMKeyBinding ("SystemName",
89 System::getFullyQualifiedHostName (), CIMKeyBinding::STRING));
90 keyBindings.append (CIMKeyBinding ("CreationClassName",
91 PEGASUS_CLASSNAME_INDFILTER.getString(), CIMKeyBinding::STRING));
92 keyBindings.append (CIMKeyBinding ("Name", name,
93 CIMKeyBinding::STRING));
94 return(CIMObjectPath("", CIMNamespaceName (),
95 PEGASUS_CLASSNAME_INDFILTER, keyBindings));
96 }
97
98 CIMObjectPath _getHandlerObjectPath
99 (const String & name)
100 {
101 Array<CIMKeyBinding> keyBindings;
102 keyBindings.append (CIMKeyBinding ("SystemCreationClassName",
103 System::getSystemCreationClassName (), CIMKeyBinding::STRING));
104 keyBindings.append (CIMKeyBinding ("SystemName",
105 System::getFullyQualifiedHostName (), CIMKeyBinding::STRING));
106 yi.zhou 1.1 keyBindings.append (CIMKeyBinding ("CreationClassName",
107 PEGASUS_CLASSNAME_INDHANDLER_SNMP.getString(),
108 CIMKeyBinding::STRING));
109 keyBindings.append (CIMKeyBinding ("Name", name,
110 CIMKeyBinding::STRING));
111 return(CIMObjectPath("", CIMNamespaceName (),
112 PEGASUS_CLASSNAME_INDHANDLER_SNMP, keyBindings));
113 }
114
115 CIMObjectPath _getSubscriptionObjectPath
116 (const String & filterName,
117 const String & handlerName)
118 {
119 CIMObjectPath filterObjectPath = _getFilterObjectPath(filterName);
120
121 CIMObjectPath handlerObjectPath = _getHandlerObjectPath(handlerName);
122
123 Array<CIMKeyBinding> subscriptionKeyBindings;
124 subscriptionKeyBindings.append (CIMKeyBinding ("Filter",
125 CIMValue(filterObjectPath)));
126 subscriptionKeyBindings.append (CIMKeyBinding ("Handler",
127 yi.zhou 1.1 CIMValue(handlerObjectPath)));
128 return(CIMObjectPath("", CIMNamespaceName (),
129 PEGASUS_CLASSNAME_INDSUBSCRIPTION, subscriptionKeyBindings));
130 }
131
132 CIMObjectPath _createHandlerInstance
133 (CIMClient & client,
134 const String & name,
135 const String & targetHost,
136 const String & securityName,
137 const Uint16 targetHostFormat,
138 const Uint16 snmpVersion)
139 {
140 CIMInstance handlerInstance (PEGASUS_CLASSNAME_INDHANDLER_SNMP);
141 handlerInstance.addProperty (CIMProperty (CIMName
142 ("SystemCreationClassName"), System::getSystemCreationClassName ()));
143 handlerInstance.addProperty (CIMProperty (CIMName ("SystemName"),
144 System::getFullyQualifiedHostName ()));
145 handlerInstance.addProperty (CIMProperty (CIMName ("CreationClassName"),
146 PEGASUS_CLASSNAME_INDHANDLER_SNMP.getString ()));
147 handlerInstance.addProperty (CIMProperty (CIMName ("Name"), name));
148 yi.zhou 1.1 handlerInstance.addProperty (CIMProperty (CIMName ("TargetHost"),
149 targetHost));
150 handlerInstance.addProperty (CIMProperty (CIMName ("TargetHostFormat"),
151 CIMValue ((Uint16) targetHostFormat)));
152 handlerInstance.addProperty (CIMProperty (CIMName ("SNMPSecurityName"),
153 securityName));
154 handlerInstance.addProperty (CIMProperty (CIMName ("SnmpVersion"),
155 CIMValue ((Uint16) snmpVersion)));
156 handlerInstance.addProperty (CIMProperty (CIMName ("PortNumber"),
157 CIMValue ((Uint32) PORT_NUMBER)));
158
159 return(client.createInstance (INTEROP_NAMESPACE, handlerInstance));
160 }
161
162 CIMObjectPath _createFilterInstance
163 (CIMClient & client,
164 const String & name,
165 const String & query,
166 const String & qlang)
167 {
168 CIMInstance filterInstance (PEGASUS_CLASSNAME_INDFILTER);
169 yi.zhou 1.1 filterInstance.addProperty (CIMProperty (CIMName
170 ("SystemCreationClassName"), System::getSystemCreationClassName ()));
171 filterInstance.addProperty (CIMProperty (CIMName ("SystemName"),
172 System::getFullyQualifiedHostName ()));
173 filterInstance.addProperty (CIMProperty (CIMName ("CreationClassName"),
174 PEGASUS_CLASSNAME_INDFILTER.getString ()));
175 filterInstance.addProperty (CIMProperty (CIMName ("Name"), name));
176 filterInstance.addProperty (CIMProperty (CIMName ("Query"), query));
177 filterInstance.addProperty (CIMProperty (CIMName ("QueryLanguage"),
178 String (qlang)));
179 filterInstance.addProperty (CIMProperty (CIMName ("SourceNamespace"),
180 SOURCE_NAMESPACE.getString ()));
181
182 return(client.createInstance (INTEROP_NAMESPACE, filterInstance));
183 }
184
185 CIMObjectPath _createSubscriptionInstance
186 (CIMClient & client,
187 const CIMObjectPath & filterPath,
188 const CIMObjectPath & handlerPath)
189 {
190 yi.zhou 1.1 CIMInstance subscriptionInstance (PEGASUS_CLASSNAME_INDSUBSCRIPTION);
191 subscriptionInstance.addProperty (CIMProperty (CIMName ("Filter"),
192 filterPath, 0, PEGASUS_CLASSNAME_INDFILTER));
193 subscriptionInstance.addProperty (CIMProperty (CIMName ("Handler"),
194 handlerPath, 0, PEGASUS_CLASSNAME_INDHANDLER_SNMP));
195 subscriptionInstance.addProperty (CIMProperty
196 (CIMName ("SubscriptionState"), CIMValue ((Uint16) 2)));
197
198 return(client.createInstance (INTEROP_NAMESPACE, subscriptionInstance));
199 }
200
201 void _sendTestIndication(CIMClient* client, const CIMName & methodName,
202 Uint32 indicationSendCount)
203 {
204 //
205 // Invoke method to send test indication
206 //
207 Array <CIMParamValue> inParams;
208 Array <CIMParamValue> outParams;
209 Array <CIMKeyBinding> keyBindings;
210 Sint32 result;
211 yi.zhou 1.1
212 CIMObjectPath className (String::EMPTY, CIMNamespaceName (),
213 CIMName ("RT_TestIndication"), keyBindings);
214
215 inParams.append(CIMParamValue(String("indicationSendCount"),
216 CIMValue(indicationSendCount)));
217
218 CIMValue retValue = client->invokeMethod
219 (SOURCE_NAMESPACE,
220 className,
221 methodName,
222 inParams,
223 outParams);
224
225 retValue.get (result);
226 PEGASUS_TEST_ASSERT (result == 0);
227 }
228
229 void _deleteSubscriptionInstance
230 (CIMClient & client,
231 const String & filterName,
232 yi.zhou 1.1 const String & handlerName)
233 {
234 CIMObjectPath subscriptionObjectPath =
235 _getSubscriptionObjectPath(filterName, handlerName);
236 client.deleteInstance (INTEROP_NAMESPACE, subscriptionObjectPath);
237 }
238
239 void _deleteHandlerInstance
240 (CIMClient & client,
241 const String & name)
242 {
243 CIMObjectPath handlerObjectPath = _getHandlerObjectPath(name);
244 client.deleteInstance (INTEROP_NAMESPACE, handlerObjectPath);
245 }
246
247 void _deleteFilterInstance
248 (CIMClient & client,
249 const String & name)
250 {
251 CIMObjectPath filterObjectPath = _getFilterObjectPath(name);
252 client.deleteInstance (INTEROP_NAMESPACE, filterObjectPath);
253 yi.zhou 1.1 }
254
255 void _usage ()
256 {
257 cerr << endl
258 << "Usage:" << endl
259 << " TestSnmpHandler setup [ WQL | DMTF:CQL ]\n"
260 << " TestSnmpHandler run <indicationSendCount> "
261 << "[<threads>]\n"
262 << " where: " << endl
263 << " <indicationSendCount> is the number of indications to\n"
264 << " generate and has to be greater than zero." << endl
265 << " <threads> is an optional number of client threads to\n"
266 << " create, default is one." << endl
267 << " TestSnmpHandler cleanup\n"
268 << " TestSnmpHandler removelog"
269 << endl << endl;
270 }
271
272 void _setup (CIMClient & client, const String& qlang)
273 {
274 yi.zhou 1.1 CIMObjectPath filterObjectPath;
275 CIMObjectPath snmpv1HandlerObjectPath;
276 CIMObjectPath snmpv2HandlerObjectPath;
277
278 try
279 {
280 filterObjectPath = _createFilterInstance (client, FILTER_NAME,
281 String ("SELECT * FROM RT_TestIndication"),
282 qlang);
283 }
284 catch (CIMException& e)
285 {
286 if (e.getCode() == CIM_ERR_ALREADY_EXISTS)
287 {
288 filterObjectPath = _getFilterObjectPath(FILTER_NAME);
289 cerr << "----- Warning: Filter Instance Not Created: "
290 << e.getMessage () << endl;
291 }
292 else
293 {
294 cerr << "----- Error: Filter Instance Not Created: " << endl;
295 yi.zhou 1.1 throw;
296 }
297 }
298
299 try
300 {
301 // Create SNMPv1 trap handler
302 snmpv1HandlerObjectPath = _createHandlerInstance (client,
303 SNMPV1_HANDLER_NAME,
304 System::getFullyQualifiedHostName(),
305 "",
306 _HOST_NAME,
307 _SNMPV1_TRAP);
308 }
309 catch (CIMException& e)
310 {
311 if (e.getCode() == CIM_ERR_ALREADY_EXISTS)
312 {
313 snmpv1HandlerObjectPath = _getHandlerObjectPath(
314 SNMPV1_HANDLER_NAME);
315 cerr << "----- Warning: SNMPv1 Trap Handler Instance Not Created: "
316 yi.zhou 1.1 << e.getMessage () << endl;
317 }
318 else
319 {
320 cerr << "----- Error: SNMPv1 Trap Handler Instance Not Created: "
321 << endl;
322 throw;
323 }
324 }
325
326 try
327 {
328 _createSubscriptionInstance (client, filterObjectPath,
329 snmpv1HandlerObjectPath);
330 }
331 catch (CIMException& e)
332 {
333 if (e.getCode() == CIM_ERR_ALREADY_EXISTS)
334 {
335 cerr << "----- Warning: Client Subscription Instance: "
336 << e.getMessage () << endl;
337 yi.zhou 1.1 }
338 else
339 {
340 cerr << "----- Error: Client Subscription Instance: " << endl;
341 throw;
342 }
343 }
344
345 try
346 {
347 // Create SNMPv2 trap handler
348 snmpv2HandlerObjectPath = _createHandlerInstance (client,
349 SNMPV2C_HANDLER_NAME,
350 System::getHostIP(System::getFullyQualifiedHostName ()),
351 "public",
352 _IPV4_ADDRESS,
353 _SNMPV2C_TRAP);
354 }
355 catch (CIMException& e)
356 {
357 if (e.getCode() == CIM_ERR_ALREADY_EXISTS)
358 yi.zhou 1.1 {
359 snmpv2HandlerObjectPath = _getHandlerObjectPath(
360 SNMPV2C_HANDLER_NAME);
361 cerr << "----- Warning: SNMPv2c Trap Handler Instance Not Created: "
362 << e.getMessage () << endl;
363 }
364 else
365 {
366 cerr << "----- Error: SNMPv2c Trap Handler Instance Not Created: "
367 << endl;
368 throw;
369 }
370 }
371
372 try
373 {
374 _createSubscriptionInstance (client, filterObjectPath,
375 snmpv2HandlerObjectPath);
376 }
377 catch (CIMException& e)
378 {
379 yi.zhou 1.1 if (e.getCode() == CIM_ERR_ALREADY_EXISTS)
380 {
381 cerr << "----- Warning: Client Subscription Instance: "
382 << e.getMessage () << endl;
383 }
384 else
385 {
386 cerr << "----- Error: Client Subscription Instance: " << endl;
387 throw;
388 }
389 }
390 }
391
392 void _cleanup (CIMClient & client)
393 {
394 try
395 {
396 _deleteSubscriptionInstance (client, FILTER_NAME,
397 SNMPV1_HANDLER_NAME);
398 }
399 catch (CIMException& e)
400 yi.zhou 1.1 {
401 if (e.getCode() != CIM_ERR_NOT_FOUND)
402 {
403 cerr << "----- Error: deleteSubscriptionInstance failure: "
404 << endl;
405 throw;
406 }
407 }
408 try
409 {
410 _deleteSubscriptionInstance (client, FILTER_NAME,
411 SNMPV2C_HANDLER_NAME);
412 }
413 catch (CIMException& e)
414 {
415 if (e.getCode() != CIM_ERR_NOT_FOUND)
416 {
417 cerr << "----- Error: deleteSubscriptionInstance failure: "
418 << endl;
419 throw;
420 }
421 yi.zhou 1.1 }
422 try
423 {
424 _deleteFilterInstance (client, FILTER_NAME);
425 }
426 catch (CIMException& e)
427 {
428 if (e.getCode() != CIM_ERR_NOT_FOUND)
429 {
430 cerr << "----- Error: deleteFilterInstance failure: " << endl;
431 throw;
432 }
433 }
434
435 try
436 {
437 _deleteHandlerInstance (client, SNMPV1_HANDLER_NAME);
438 }
439 catch (CIMException& e)
440 {
441 if (e.getCode() != CIM_ERR_NOT_FOUND)
442 yi.zhou 1.1 {
443 cerr << "----- Error: deleteHandlerInstance failure: " << endl;
444 throw;
445 }
446 }
447 try
448 {
449 _deleteHandlerInstance (client, SNMPV2C_HANDLER_NAME);
450 }
451 catch (CIMException& e)
452 {
453 if (e.getCode() != CIM_ERR_NOT_FOUND)
454 {
455 cerr << "----- Error: deleteHandlerInstance failure: " << endl;
456 throw;
457 }
458 }
459 }
460
461 static void _testEnd(const String& uniqueID, const double elapsedTime)
462 {
463 yi.zhou 1.1 cout << "+++++ thread" << uniqueID << ": passed in " << elapsedTime
464 << " seconds" << endl;
465 }
466
467 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _executeTests(void *parm)
468 {
469 Thread *my_thread = (Thread *)parm;
470 T_Parms *parms = (T_Parms *)my_thread->get_parm();
471 CIMClient *client = parms->client.get();
472 Uint32 indicationSendCount = parms->indicationSendCount;
473 Uint32 id = parms->uniqueID;
474 char id_[4];
475 memset(id_,0x00,sizeof(id_));
476 sprintf(id_,"%i",id);
477 String uniqueID = "_";
478 uniqueID.append(id_);
479
480 try
481 {
482 Stopwatch elapsedTime;
483
484 yi.zhou 1.1 elapsedTime.start();
485 try
486 {
487 _sendTestIndication (client, CIMName ("SendTestIndicationTrap"),
488 indicationSendCount);
489 }
490 catch (Exception & e)
491 {
492 cerr << "----- sendTestIndication failed: " << e.getMessage () << endl;
493 exit (-1);
494 }
495 elapsedTime.stop();
496 _testEnd(uniqueID, elapsedTime.getElapsed());
497 }
498 catch(Exception & e)
499 {
500 cout << e.getMessage() << endl;
501 }
502 my_thread->exit_self((PEGASUS_THREAD_RETURN)1);
503 return(0);
504 }
505 yi.zhou 1.1
506 Thread * _runTestThreads(
507 CIMClient* client,
508 Uint32 indicationSendCount,
509 Uint32 uniqueID)
510 {
511 // package parameters, create thread and run...
512 AutoPtr<T_Parms> parms(new T_Parms());
513 parms->client.reset(client);
514 parms->indicationSendCount = indicationSendCount;
515 parms->uniqueID = uniqueID;
516 AutoPtr<Thread> t(new Thread(_executeTests, (void*)parms.release(), false));
517 t->run();
518 return t.release();
519 }
520
521 String _getLogFile()
522 {
523 return("trapLogFile");
524 }
525
526 yi.zhou 1.1 Uint32 _getReceivedTrapCount(Uint16 snmpVersion)
527 {
528 String trap1 = "Trap Info: TRAP, SNMP v1, community public";
529 String trap2 = "Trap Info: TRAP2, SNMP v2c, community public";
530
531 Uint32 receivedTrap1Count = 0;
532 Uint32 receivedTrap2Count = 0;
533
534 ifstream ifs(_getLogFile().getCString());
535 if (!ifs)
536 {
537 return (0);
538 }
539
540 String line;
541 while (GetLine(ifs, line))
542 {
543 if (String::compare(line, trap1) == 0)
544 {
545 receivedTrap1Count++;
546 }
547 yi.zhou 1.1 if (String::compare(line, trap2) == 0)
548 {
549 receivedTrap2Count++;
550 }
551 }
552
553 ifs.close();
554
555 switch (snmpVersion)
556 {
557 case _SNMPV1_TRAP:
558 {
559 return (receivedTrap1Count);
560 }
561 case _SNMPV2C_TRAP:
562 {
563 return (receivedTrap2Count);
564 }
565 default:
566 {
567 return (0);
568 yi.zhou 1.1 }
569 }
570
571 }
572
573 #ifdef PEGASUS_USE_NET_SNMP
574 // Stop snmptrapd process if it is running and remove
575 // procIdFile file if it exists
576 //
577 void _stopSnmptrapd()
578 {
579 String procIdFileName = "procIdFile";
580
581 Uint32 receiverPid;
582 FILE *fd;
583 if ((fd = fopen(procIdFileName.getCString(), "r")) != NULL)
584 {
585 fscanf(fd, "%d\n", &receiverPid);
586
587 kill(receiverPid, SIGTERM);
588
589 yi.zhou 1.1 fclose(fd);
590 }
591
592 if (FileSystem::exists(procIdFileName))
593 {
594 FileSystem::removeFile(procIdFileName);
595 }
596 }
597
598 static Boolean _startSnmptrapd(
599 FILE **trapInfo)
600 {
601 String snmptrapdCmd;
602
603 Uint32 portNumber = PORT_NUMBER;
604 char portNumberStr[32];
605 sprintf(portNumberStr, "%lu", (unsigned long) portNumber);
606
607 //
608 // build snmptrapd cmd options
609 //
610 yi.zhou 1.1
611 // Specify logging incoming traps to trapLogFile
612 // Save the process ID of the snmptrapd in procIdFile
613 snmptrapdCmd.append(
614 "/usr/sbin/snmptrapd -f -Lf trapLogFile -p procIdFile");
615
616 // Specify incoming trap format
617 snmptrapdCmd.append( " -F \"\nTrap Info: %P\nVariable: %v\n\"");
618
619 // Specify listening address
620 snmptrapdCmd.append(" UDP:");
621 snmptrapdCmd.append(System::getFullyQualifiedHostName ());
622
623 snmptrapdCmd.append(":");
624 snmptrapdCmd.append(portNumberStr);
625
626 if ((*trapInfo = popen(snmptrapdCmd.getCString(), "r")) == NULL)
627 {
628 throw Exception ("snmptrapd can not be started");
629 }
630
631 yi.zhou 1.1 #define MAX_ITERATIONS 300
632 #define SLEEP_SEC 1
633
634 Uint32 iterations = 0;
635
636 // Wait until snmptrapd startted
637 while (iterations < MAX_ITERATIONS)
638 {
639 iterations++;
640 if (FileSystem::exists("procIdFile"))
641 {
642 return (true);
643 }
644 else
645 {
646 System::sleep(SLEEP_SEC);
647
648 }
649 }
650
651 throw Exception ("snmptrapd can not be started");
652 yi.zhou 1.1 }
653 #endif
654
655 void _removeTrapLogFile ()
656 {
657 String logFile = _getLogFile();
658
659 // if trapLogFile exists, remove it
660 if (FileSystem::exists(logFile))
661 {
662 FileSystem::removeFile(logFile);
663 }
664 }
665
666 int _beginTest(CIMClient& workClient,
667 Uint32 indicationSendCount,
668 Uint32 runClientThreadCount)
669 {
670
671 #ifdef PEGASUS_USE_NET_SNMP
672
673 yi.zhou 1.1 // Stop snmptrapd process if it is running
674 _stopSnmptrapd();
675
676 // if trapLogFile exists, remove it
677 _removeTrapLogFile();
678
679 FILE * trapInfo;
680
681 try
682 {
683 _startSnmptrapd(&trapInfo);
684 }
685 catch (Exception & e)
686 {
687 cerr << e.getMessage() << endl;
688 return (-1);
689 }
690 #else
691 cerr << "Cannot create a trap receiver." << endl;
692 return (-1);
693 #endif
694 yi.zhou 1.1
695 CIMClient * clientConnections = new CIMClient[runClientThreadCount];
696
697 // determine total number of indication send count
698 indicationSendCountTotal = indicationSendCount * runClientThreadCount;
699
700 // calculate the timeout based on the total send count allowing
701 // using the MSG_PER_SEC rate
702 // allow 20 seconds of test overhead for very small tests
703
704 #define MSG_PER_SEC 4
705
706 Uint32 testTimeout = 20000+(indicationSendCountTotal/MSG_PER_SEC)*1000;
707
708 // connect the clients
709 for(Uint32 i = 0; i < runClientThreadCount; i++)
710 {
711 clientConnections[i].setTimeout(testTimeout);
712 clientConnections[i].connectLocal();
713 }
714
715 yi.zhou 1.1 // run tests
716 Thread ** clientThreads = new Thread *[runClientThreadCount];
717
718 Stopwatch trapReceiverElapsedTime;
719
720 trapReceiverElapsedTime.start();
721
722 for(Uint32 i = 0; i < runClientThreadCount; i++)
723 {
724 clientThreads[i] = _runTestThreads(&clientConnections[i],
725 indicationSendCount, i);
726 }
727
728 for(Uint32 i=0; i< runClientThreadCount; i++)
729 {
730 clientThreads[i]->join();
731 }
732
733 delete[] clientConnections;
734 delete[] clientThreads;
735
736 yi.zhou 1.1 //
737 // Allow time for the trap to be received
738 // Wait in SLEEP_SEC second intervals.
739 // Put msg out every MSG_SEC intervals
740 //
741
742 #define SLEEP_SEC 1
743 #define COUT_TIME_INTERVAL 30
744 #define MAX_NO_CHANGE_ITERATIONS COUT_TIME_INTERVAL*3
745
746 Uint32 noChangeIterations = 0;
747 Uint32 priorReceivedTrap1Count = 0;
748 Uint32 priorReceivedTrap2Count = 0;
749 Uint32 currentReceivedTrap1Count = 0;
750 Uint32 currentReceivedTrap2Count = 0;
751 Uint32 totalIterations = 0;
752
753 //
754 // Wait for the trap receiver to receive the expected
755 // number of Indication traps, indicationSendCountTotal.
756 //
757 yi.zhou 1.1 // We will continue to wait until either indicationSendCountTotal
758 // Indications have been received by the trap receiver or no new
759 // Indications have been received in the previous
760 // MAX_NO_CHANGE_ITERATIONS.
761 // iterations.
762 //
763
764 Boolean receivedTrapCountComplete = false;
765 Boolean receiverTrap1NoChange = true;
766 Boolean receiverTrap2NoChange = true;
767
768 while (noChangeIterations <= MAX_NO_CHANGE_ITERATIONS)
769 {
770 totalIterations++;
771
772 currentReceivedTrap1Count = _getReceivedTrapCount(_SNMPV1_TRAP);
773 currentReceivedTrap2Count = _getReceivedTrapCount(_SNMPV2C_TRAP);
774
775 if (totalIterations % COUT_TIME_INTERVAL == 1 &&
776 !(receivedTrapCountComplete))
777 {
778 yi.zhou 1.1 cout << "++++ The trap receiver has received "
779 << currentReceivedTrap1Count << " of "
780 << indicationSendCountTotal << " SNMPv1 trap."
781 << endl;
782 cout << "++++ The trap receiver has received "
783 << currentReceivedTrap2Count << " of "
784 << indicationSendCountTotal << " SNMPv2c trap."
785 << endl;
786 }
787
788 if ((indicationSendCountTotal == currentReceivedTrap1Count) &&
789 (indicationSendCountTotal == currentReceivedTrap2Count))
790 {
791 receivedTrapCountComplete = true;
792 trapReceiverElapsedTime.stop();
793 }
794 if (!(receiverTrap1NoChange =
795 (priorReceivedTrap1Count == currentReceivedTrap1Count)))
796 {
797 priorReceivedTrap1Count = currentReceivedTrap1Count;
798 }
799 yi.zhou 1.1
800 if (!(receiverTrap2NoChange =
801 (priorReceivedTrap2Count == currentReceivedTrap2Count)))
802 {
803 priorReceivedTrap2Count = currentReceivedTrap2Count;
804 }
805
806 if (receivedTrapCountComplete)
807 {
808 cout << "++++ The trap receiver has received "
809 << currentReceivedTrap1Count << " of "
810 << indicationSendCountTotal << " SNMPv1 trap."
811 << endl;
812 cout << "++++ The trap receiver has received "
813 << currentReceivedTrap2Count << " of "
814 << indicationSendCountTotal << " SNMPv2c trap."
815 << endl;
816
817 break;
818 }
819 if (receiverTrap1NoChange || receiverTrap2NoChange)
820 yi.zhou 1.1 {
821 noChangeIterations++;
822 }
823 else
824 {
825 noChangeIterations = 0;
826 }
827
828 System::sleep (SLEEP_SEC);
829 }
830
831 if (!receivedTrapCountComplete)
832 {
833 trapReceiverElapsedTime.stop();
834 }
835
836 // assert that all indications sent have been received.
837 PEGASUS_TEST_ASSERT(indicationSendCountTotal ==
838 currentReceivedTrap1Count);
839 PEGASUS_TEST_ASSERT(indicationSendCountTotal ==
840 currentReceivedTrap2Count);
841 yi.zhou 1.1
842 #ifdef PEGASUS_USE_NET_SNMP
843 // Stop snmptrapd process if it is running and remove procIdFile
844 _stopSnmptrapd();
845
846 pclose(trapInfo);
847 #endif
848
849 // if error encountered then fail the test.
850 if (errorsEncountered.get())
851 {
852 cout << "+++++ test failed" << endl;
853 return (-1);
854 }
855 else
856 {
857 cout << "+++++ passed all tests" << endl;
858 }
859
860 return 0;
861 }
862 yi.zhou 1.1
863 int main (int argc, char** argv)
864 {
865 // This client connection is used solely to create and delete subscriptions.
866 CIMClient workClient;
867 try
868 {
869 workClient.connectLocal();
870
871 if (argc <= 1 || argc > 4)
872 {
873 cerr << "Invalid argument count: " << argc << endl;
874 _usage();
875 return 1;
876 }
877 else if (strcmp(argv[1], "setup") == 0)
878 {
879 if (argc < 3)
880 {
881 cerr << "Missing query language" << endl;
882 _usage();
883 yi.zhou 1.1 return -1;
884 }
885
886 if ((strcmp(argv[2], "WQL") != 0) &&
887 (strcmp(argv[2], "DMTF:CQL") != 0))
888 {
889 cerr << "Invalid query language: '" << argv[2] << "'" << endl;
890 _usage();
891 return -1;
892 }
893
894 _setup(workClient, argv[2]);
895
896 cout << "+++++ setup completed successfully" << endl;
897 return 0;
898 }
899 else if (String::equalNoCase(argv[1], "run"))
900 {
901 if (argc < 3)
902 {
903 cerr << "Invalid indicationSendCount." << endl;
904 yi.zhou 1.1 _usage ();
905 return -1;
906 }
907
908 Uint32 indicationSendCount = atoi(argv[2]);
909
910 Uint32 runClientThreadCount = 1;
911
912 if (argc == 4)
913 {
914 runClientThreadCount = atoi(argv[3]);
915 }
916
917 int rc = _beginTest(workClient, indicationSendCount,
918 runClientThreadCount);
919 return rc;
920 }
921 else if (String::equalNoCase(argv[1], "cleanup"))
922 {
923 if (argc > 2)
924 {
925 yi.zhou 1.1 cerr << "Invalid argument count." << endl;
926 _usage ();
927 return -1;
928 }
929
930 _cleanup (workClient);
931
932 cout << "+++++ cleanup completed successfully" << endl;
933 return 0;
934 }
935 else if (String::equalNoCase(argv[1], "removelog"))
936 {
937 if (argc > 2)
938 {
939 cerr << "Invalid argument count." << endl;
940 _usage ();
941 return -1;
942 }
943
944 _removeTrapLogFile ();
945 cout << "+++++ removelog completed successfully" << endl;
946 yi.zhou 1.1 return 0;
947 }
948 else
949 {
950 cerr << "Invalid option: " << argv[1] << endl;
951 _usage ();
952 return -1;
953 }
954 }
955 catch (Exception & e)
956 {
957 cerr << "Error: " << e.getMessage() << endl;
958 }
959
960 PEGASUS_UNREACHABLE( return 0; )
961 }
|