1 s.manicka 1.3.24.2 //%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 s.manicka 1.3.24.2 // 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: John Alex
33 //
34 // Modified By:
35 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include <iostream>
39 #include <Pegasus/Common/Config.h>
40 #include <Pegasus/Common/Constants.h>
41 #include <Pegasus/Common/System.h>
42 #include <Pegasus/Common/PegasusVersion.h>
43 s.manicka 1.3.24.2 #include <Pegasus/Common/SSLContext.h>
44 #include <Pegasus/getoopt/getoopt.h>
45 #include <Pegasus/Common/String.h>
46 #include <Pegasus/Client/CIMClient.h>
47 #include <Pegasus/Common/FileSystem.h>
48 #include <Pegasus/Common/TimeValue.h>
49 #include <time.h>
50 #include <signal.h>
51 #include "StressTestController.h"
52 #include "StressTestControllerException.h"
53 //
54 //Windows
55 //
56 #ifdef PEGASUS_OS_TYPE_WINDOWS
57 // for DWORD etc.
58 #include <windows.h>
59 // getpid() and others
60 typedef DWORD pid_t;
61 #include <process.h>
62 #elif !defined(PEGASUS_OS_OS400)
63 #include <unistd.h>
64 s.manicka 1.3.24.2 #endif
65
66 //#define STRESSTEST_DEBUG
67
68 #define SIXTYSECONDS 60
69 #define MILLISECONDS 1000
70 #define CHECKUP_INTERVAL 1
71 #define STOP_DELAY 1
72 #define SHUTDOWN_DELAY 5
73 #define RUN_DELAY 1
74 #define DEFAULT_INSTANCE "5"
75
76 #define convertmin2millisecs(x) (x * SIXTYSECONDS * MILLISECONDS)
77 #define getToleranceInPercent(x,y) (100 - (((y-x)/y) * 100))
78
79
80
81 static void endAllTests(int signum);
82
83 static void cleanupProcess();
84
85 s.manicka 1.3.24.2 static String convertUint64toString(Uint64 x);
86
87
88 PEGASUS_NAMESPACE_BEGIN
89 PEGASUS_USING_PEGASUS;
90 PEGASUS_USING_STD;
91
92
93
94 /**
95 Log file descripter
96 */
97
98 /**
99 variable for Signal handler
100 */
101 static Boolean Quit = false;
102
103 /**
104 The command name.
105 */
106 s.manicka 1.3.24.2 const char StressTestControllerCommand::COMMAND_NAME [] =
107 "TestStressTestController";
108
109
110 /**
111 StressTest Configuration file details
112 */
113 char StressTestControllerCommand::FILENAME[] = "default_stresstest.conf";
114 char StressTestControllerCommand::TESTDIR[] = "/test/";
115 char StressTestControllerCommand::STRESSTESTDIR[] = "StressTestController/";
116 char StressTestControllerCommand::LOGDIR[] = "log/";
117 char StressTestControllerCommand::BINDIR[] = "/bin/";
118 char StressTestControllerCommand::DEFAULT_CFGDIR[] =
119 STRESSTEST_DEFAULTCFGDIR;
120 char StressTestControllerCommand::DEFAULT_LOGDIR[] =
121 "/test/StressTestController/log/";
122 char StressTestControllerCommand::DEFAULT_TMPDIR[] =
123 "/test/StressTestController/tmp/";
124
125 String DEFAULT_BINDIR = String::EMPTY;
126
127 s.manicka 1.3.24.2 static Uint32 DEFAULT_CLIENTS = 2;
128 static Uint32 Total_Clients = DEFAULT_CLIENTS;
129 static Uint32 Total_vClients = DEFAULT_CLIENTS;
130 static Uint32 NEW_CLIENTS = 5;
131
132 static char MODELWALK_CLIENT[] = "TestModelWalkStressClient";
133 static char WRAPPER_CLIENT[] = "TestWrapperStressClient";
134
135 /**
136 StressTest Client Status types
137 */
138 enum CStatus{
139 VALID_RESPONSE,
140 INVALID_RESPONSE,
141 NO_RESPONSE};
142
143
144 /**
145 Temporary arrays to store client information
146 */
147
148 s.manicka 1.3.24.2 /**
149 Client PID's
150 */
151 static pid_t *clientPIDs;
152
153 /**
154 Client Status
155 */
156 static int *clientStatus;
157
158
159 /**
160 Client Status
161 */
162 static int *prev_clientStatus;
163
164 /**
165 Client Instance
166 */
167 static int *clientInstance;
168
169 s.manicka 1.3.24.2 /**
170 Indicates if client is Active
171 */
172 static Boolean *clientActive;
173
174 /**
175 Client status time stamp
176 */
177 static Uint64 *clientTimeStamp;
178
179 /**
180 Previous client status time stamp
181 */
182 static Uint64 *prev_clientTimeStamp;
183
184 /**
185 DEFAULT VALUES:
186 */
187
188 /**
189 Default duration for the stress tests
190 s.manicka 1.3.24.2 */
191 double StressTestControllerCommand::_duration = 180;
192
193 /**
194 Label for the usage string for this command.
195 */
196 const char StressTestControllerCommand::_USAGE [] = "Usage: ";
197
198 /**
199 The option character used to specify the hostname.
200 */
201 const char StressTestControllerCommand::_OPTION_HOSTNAME = 'h';
202
203 /**
204 The option character used to specify the port number.
205 */
206 const char StressTestControllerCommand::_OPTION_PORTNUMBER = 'p';
207
208 /**
209 The option character used to specify SSL usage.
210 */
211 s.manicka 1.3.24.2 const char StressTestControllerCommand::_OPTION_SSL = 's';
212
213 /**
214 The option character used to specify the username.
215 */
216 const char StressTestControllerCommand::_OPTION_USERNAME = 'u';
217
218 /**
219 The option character used to specify the password.
220 */
221 const char StressTestControllerCommand::_OPTION_PASSWORD = 'w';
222
223 /**
224 The minimum valid portnumber.
225 */
226 const Uint32 StressTestControllerCommand::_MIN_PORTNUMBER = 0;
227
228 /**
229 The maximum valid portnumber.
230 */
231 const Uint32 StressTestControllerCommand::_MAX_PORTNUMBER = 65535;
232 s.manicka 1.3.24.2
233 /**
234 The minimum Duration.
235 */
236 const Uint32 StressTestControllerCommand::_MIN_DURATION = 0;
237
238 /**
239 The minimum valid Tolerance Level.
240 */
241 const Uint32 StressTestControllerCommand::_MIN_TOLERANCE = 0;
242
243 /**
244 The maximum valid Tolerance Level.
245 */
246 const Uint32 StressTestControllerCommand::_MAX_TOLERANCE = 100;
247
248 /**
249 The variable used to specify the hostname.
250 */
251 static const char HOSTNAME[] = "hostname";
252
253 s.manicka 1.3.24.2 /**
254 The variable used to specify the port number.
255 */
256 static const char PORTNUMBER[] = "port";
257
258 /**
259 The variable used to specify SSL usage.
260 */
261 static const char SSL [] = "ssl";
262
263 /**
264 The variable used to specify the username.
265 */
266 static const char USERNAME[] = "username";
267
268 /**
269 The variable used to specify the password.
270 */
271 static const char PASSWORD[] = "password";
272
273 /**
274 s.manicka 1.3.24.2 The variable used to specify the duration of the tests.
275 */
276 static const char DURATION[] = "duration";
277
278 /**
279 The variable used to specify the duration of the Client tests.
280 */
281 static const char CLIENTDURATION[] = "ClientDuration";
282
283 /**
284 The variable used to specify the ToleranceLevel for the tests.
285 */
286 static const char TOLERANCELEVEL[] = "TOLERANCELEVEL";
287
288 /**
289 The variable used to specify the NameSpace for the tests.
290 */
291 static const char NAMESPACE[] = "namespace";
292
293 /**
294 The variable used to specify the ClassName for the tests.
295 s.manicka 1.3.24.2 */
296 static const char CLASSNAME[] = "classname";
297
298 /**
299 The variable used to specify the Name for the tests.
300 */
301 static const char NAME[] = "NAME";
302
303 /**
304 The variable used to specify the Clientname for the tests.
305 */
306 static const char CLIENTNAME[] = "clientname";
307
308 /**
309 The variable used to specify the Clientname for the tests.
310 */
311 static const char OPTIONS[] = "options";
312
313 /**
314 The variable used to specify the Clientname for the tests.
315 */
316 s.manicka 1.3.24.2 static const char INSTANCE[] = "INSTANCE";
317
318 /**
319 The variable used to specify the Clientname for the tests.
320 */
321 static const char CLIENTWAIT[] = "CLIENTWAIT";
322
323
324
325 /**
326 * Message resource name
327 */
328 static const char PASSWORD_PROMPT [] =
329 "Please enter your password: ";
330 static const char PASSWORD_BLANK [] =
331 "Password cannot be blank. Please re-enter your password.";
332 static const char LONG_HELP[] = "help";
333 static const char LONG_VERSION[] = "version";
334 static const char LONG_VERBOSE[] = "verbose";
335
336 static Boolean IsAClient = false;
337 s.manicka 1.3.24.2
338 static Boolean IsClientOptions = false;
339
340 static Boolean IgnoreLine = false;
341
342 /**
343
344 Constructs a StressTestControllerCommand and initializes instance variables.
345
346 */
347 StressTestControllerCommand::StressTestControllerCommand ()
348 {
349
350 _hostName = String ();
351 _hostNameSpecified = false;
352 _portNumber = WBEM_DEFAULT_HTTP_PORT;
353 _portNumberSpecified = false;
354
355 char buffer[32];
356 sprintf(buffer, "%lu", (unsigned long) _portNumber);
357
358 s.manicka 1.3.24.2 _portNumberStr = buffer;
359
360 _timeout = DEFAULT_TIMEOUT_MILLISECONDS;
361 _userName = String ();
362 _userNameSpecified = false;
363 _password = String ();
364 _passwordSpecified = false;
365 _useSSL = false;
366
367 //
368 // initialize
369 //
370 _clientCount = 0;
371 _currClientCount = 0;
372
373 //
374 // Set up tables for client properties.
375 //
376 _clientTable = new Table[Total_Clients];
377
378 //
379 s.manicka 1.3.24.2 // Allocate one table to collect all the common properties Thy use AutoPtr
380 //
381 _propertyTable = new Table;
382
383 //
384 // Client Information
385 //
386 _clientCommands = 0;
387 _clientDurations = 0;
388 _clientDelays = 0;
389
390 //
391 // Get environment variables:
392 //
393 pegasusHome = getenv("PEGASUS_HOME");
394
395 DEFAULT_BINDIR = String(pegasusHome);
396 DEFAULT_BINDIR.append(BINDIR);
397
398 _stressTestLogFile = String::EMPTY;
399
400 s.manicka 1.3.24.2 _stressTestClientPIDFile = String::EMPTY;
401
402 _stressTestClientLogFile = String::EMPTY;
403
404 _tmpStressTestClientPIDFile = String::EMPTY;
405
406
407
408 _usage = String (_USAGE);
409
410 _usage.append (COMMAND_NAME);
411 #ifndef DISABLE_SUPPORT_FOR_REMOTE_CONNECTIONS
412 _usage.append (" [ -");
413 _usage.append (_OPTION_SSL);
414 _usage.append (" ] [ -");
415 _usage.append (_OPTION_HOSTNAME);
416 _usage.append (" hostname ] [ -");
417 _usage.append (_OPTION_PORTNUMBER);
418 _usage.append (" portnumber ]\n [ -");
419 _usage.append (_OPTION_USERNAME);
420 _usage.append (" username ] [ -");
421 s.manicka 1.3.24.2 _usage.append (_OPTION_PASSWORD);
422 _usage.append (" password ]");
423 #endif
424 _usage.append (" [ --");
425 _usage.append (LONG_HELP);
426 _usage.append(" ]\n");
427 _usage.append(" ");
428 _usage.append("[ --").append(LONG_VERSION).append(" ]");
429 _usage.append(" [ --").append(LONG_VERBOSE).append(" ]").append(\
430 " [<config_filename>] \n");
431
432 _usage.append("Options : \n");
433 _usage.append(" -h - Connect to CIM Server on specified ");
434 _usage.append("hostname. \n");
435 _usage.append(" --help - Display this help message.\n");
436 _usage.append(" -p - Connect to CIM Server on specified ");
437 _usage.append("portnumber.\n");
438 _usage.append(" -s - Use SSL protocol between Stress Test ");
439 _usage.append("Client\n");
440 _usage.append(" and the CIM Server\n");
441 _usage.append(" -u - Connect to CIM Server using the specified");
442 s.manicka 1.3.24.2 _usage.append(" username\n");
443 _usage.append(" --version - Display CIM Server version number\n");
444 _usage.append(" --verbose - Display verbose information\n");
445 _usage.append(" -w - Connect to CIM Server using the specified");
446 _usage.append(" password\n");
447 _usage.append("\nOperands : \n");
448 _usage.append(" <config_filename>\n");
449 _usage.append(" - Specifies the name of the configuration ");
450 _usage.append("file that is to be used \n");
451 _usage.append(" for the tests.\n");
452
453 setUsage(_usage);
454
455 } /* StressTestControllerCommand */
456
457 /**
458
459 Parses the command line, validates the options, and sets instance
460 variables based on the option arguments.
461
462 @param argc the number of command line arguments
463 s.manicka 1.3.24.2 @param argv the string vector of command line arguments
464
465 @exception CommandFormatException if an error is encountered in parsing
466 the command line
467
468 */
469 void StressTestControllerCommand::setCommand (Uint32 argc, char* argv [])
470 {
471 Uint32 i = 0;
472 Uint32 c = 0;
473 String GetOptString = String ();
474 getoopt getOpts;
475 _toleranceLevel = 0;
476 _configFilePath = String ();
477 _configFilePathSpecified = false;
478
479 _operationType = OPERATION_TYPE_UNINITIALIZED;
480
481
482 ofstream log_file;
483
484 s.manicka 1.3.24.2 //
485 // opens the log file
486 //
487 OpenAppend(log_file,_stressTestLogFile);
488
489 if (!log_file)
490 {
491 if(verboseEnabled)
492 {
493 cout<<StressTestControllerCommand::COMMAND_NAME<<
494 "::Cannot get file "<<_stressTestLogFile<<endl;
495 }
496
497 }
498 log_file<<StressTestControllerCommand::COMMAND_NAME<<
499 ":: Preparing to set up parameters: "<<endl;
500
501 //
502 // Construct GetOptString
503 //
504 GetOptString.append (_OPTION_HOSTNAME);
505 s.manicka 1.3.24.2 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
506 GetOptString.append (_OPTION_PORTNUMBER);
507 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
508 GetOptString.append (_OPTION_SSL);
509 GetOptString.append (_OPTION_USERNAME);
510 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
511 GetOptString.append (_OPTION_PASSWORD);
512 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
513
514 //
515 // Initialize and parse getOpts
516 //
517 getOpts = getoopt ();
518 getOpts.addFlagspec (GetOptString);
519
520 //
521 // per PEP#167
522 //
523 getOpts.addLongFlagspec(LONG_HELP,getoopt::NOARG);
524 getOpts.addLongFlagspec(LONG_VERSION,getoopt::NOARG);
525 getOpts.addLongFlagspec(LONG_VERBOSE,getoopt::NOARG);
526 s.manicka 1.3.24.2
527 getOpts.parse (argc, argv);
528
529 if (getOpts.hasErrors ())
530 {
531 log_file.close();
532 CommandFormatException e(getOpts.getErrorStrings () [0]);
533 throw e;
534 }
535
536 //
537 // Get options and arguments from the command line
538 //
539 for (i = getOpts.first(); i < getOpts.last (); i++)
540 {
541 if (getOpts[i].getType() == Optarg::LONGFLAG)
542 {
543 if (getOpts[i].getopt() == LONG_HELP)
544 {
545 _operationType = OPERATION_TYPE_HELP;
546 }
547 s.manicka 1.3.24.2 else if (getOpts[i].getopt() == LONG_VERSION)
548 {
549 _operationType = OPERATION_TYPE_VERSION;
550 }
551 if (getOpts[i].getopt() == LONG_VERBOSE)
552 {
553 verboseEnabled = true;
554 }
555 }
556 else if (getOpts [i].getType() == Optarg::REGULAR)
557 {
558 //
559 // _configFilePath is the only non-option argument
560 //
561 if (_configFilePathSpecified)
562 {
563 //
564 // more than one _configFilePath argument was found
565 //
566 log_file<<StressTestControllerCommand::COMMAND_NAME<<
567 "::More than one arguement was found "<<endl;
568 s.manicka 1.3.24.2 log_file.close();
569 UnexpectedArgumentException e(getOpts[i].Value());
570 throw e;
571 }
572 _configFilePath = getOpts[i].Value();
573 _configFilePathSpecified = true;
574 }
575 else /* getOpts[i].getType() == FLAG */
576 {
577 c = getOpts[i].getopt()[0];
578 switch(c)
579 {
580 case _OPTION_HOSTNAME:
581 {
582 if (getOpts.isSet(_OPTION_HOSTNAME) > 1)
583 {
584 //
585 // More than one hostname option was found
586 //
587 log_file.close();
588 DuplicateOptionException e(_OPTION_HOSTNAME);
589 s.manicka 1.3.24.2 throw e;
590 }
591 _hostName = getOpts [i].Value ();
592 _hostNameSpecified = true;
593 if (!_propertyTable->insert("hostname", _hostName))
594 {
595 // shouldn't get here
596 if(verboseEnabled)
597 {
598 cout<<StressTestControllerCommand::COMMAND_NAME;
599 cout<<"::Property Name name already saved: "<<
600 "hostname"<<endl;
601 }
602 }
603 break;
604 }
605 case _OPTION_PORTNUMBER:
606 {
607 if (getOpts.isSet(_OPTION_PORTNUMBER) > 1)
608 {
609 //
610 s.manicka 1.3.24.2 // More than one portNumber option was found
611 //
612 log_file.close();
613 DuplicateOptionException e(_OPTION_PORTNUMBER);
614 throw e;
615 }
616 _portNumberStr = getOpts [i].Value ();
617 try
618 {
619 getOpts[i].Value(_portNumber);
620 }
621 catch (const TypeMismatchException&)
622 {
623 log_file.close();
624 InvalidOptionArgumentException e(
625 _portNumberStr,
626 _OPTION_PORTNUMBER);
627 throw e;
628 }
629 _portNumberSpecified = true;
630 if (!_propertyTable->insert("port", _portNumberStr))
631 s.manicka 1.3.24.2 {
632 if(verboseEnabled)
633 {
634 cout<<StressTestControllerCommand::COMMAND_NAME;
635 cout<<"::Property Name:duplicate name already saved:"
636 <<"port"<<endl;
637 }
638 }
639 break;
640 }
641 case _OPTION_SSL:
642 {
643 //
644 // Use port 5989 as the default port for SSL
645 //
646 _useSSL = true;
647 if (!_portNumberSpecified)
648 {
649 _portNumber = 5989;
650 _portNumberStr = "5989";
651 if (!_propertyTable->insert("port", _portNumberStr))
652 s.manicka 1.3.24.2 {
653 if(verboseEnabled)
654 {
655 cout<<StressTestControllerCommand::COMMAND_NAME;
656 cout<<"::Property Name already saved: "<<"port"<<
657 endl;
658 }
659 }
660 }
661 if (!_propertyTable->insert("ssl", ""))
662 {
663 if(verboseEnabled)
664 {
665 cout<<StressTestControllerCommand::COMMAND_NAME;
666 cout<<"::Property Name already saved: "<<"ssl"<<
667 endl;
668 }
669 }
670 break;
671 }
672 case _OPTION_USERNAME:
673 s.manicka 1.3.24.2 {
674 if (getOpts.isSet(_OPTION_USERNAME) > 1)
675 {
676 //
677 // More than one username option was found
678 //
679 log_file.close();
680 DuplicateOptionException e(_OPTION_USERNAME);
681 throw e;
682 }
683 _userName = getOpts[i].Value();
684 _userNameSpecified = true;
685 if (!_propertyTable->insert("username", _userName))
686 {
687 if(verboseEnabled)
688 {
689 cout<<StressTestControllerCommand::COMMAND_NAME;
690 cout<< "::Property Name already saved: "<<
691 "username"<<endl;
692 }
693 }
694 s.manicka 1.3.24.2 break;
695 }
696 case _OPTION_PASSWORD:
697 {
698 if (getOpts.isSet(_OPTION_PASSWORD) > 1)
699 {
700 //
701 // More than one password option was found
702 //
703 log_file.close();
704 DuplicateOptionException e(_OPTION_PASSWORD);
705 throw e;
706 }
707 _password = getOpts[i].Value();
708 _passwordSpecified = true;
709 if (!_propertyTable->insert("password", _password))
710 {
711 if(verboseEnabled)
712 {
713 cout<<StressTestControllerCommand::COMMAND_NAME;
714 cout<<"::Property Name already saved: "<<
715 s.manicka 1.3.24.2 "password"<<endl;
716 }
717 }
718 break;
719 }
720
721 default:
722 {
723 //
724 // This path should not be hit
725 // PEP#167 unless an empty '-' is specified
726 //
727 log_file.close();
728 String ErrReport =
729 String(StressTestControllerCommand::COMMAND_NAME);
730 ErrReport.append("::Invalid or unknown option specified");
731 throw StressTestControllerException(ErrReport);
732
733 break;
734 }
735 }
736 s.manicka 1.3.24.2 }
737 }
738 //
739 // More validation:
740 // No portNumber specified
741 // Default to WBEM_DEFAULT_PORT
742 // Already done in constructor
743 //
744 if (getOpts.isSet(_OPTION_PORTNUMBER) == 1)
745 {
746 if (_portNumber > _MAX_PORTNUMBER)
747 {
748 //
749 // Portnumber out of valid range
750 //
751 log_file.close();
752 InvalidOptionArgumentException e(_portNumberStr,
753 _OPTION_PORTNUMBER);
754 throw e;
755 }
756 }
757 s.manicka 1.3.24.2 log_file.close();
758 } /* setCommand */
759
760 /**
761
762 Generates commands and its options for each of the clients.
763 The client table is traversed to generate each of the client commands.
764 The Commands, Duration and Delays for each client are saved in
765 the following array's respectively:
766 _clientCommands
767 _clientDurations
768 _clientDelays
769
770 @param log_file The log file.
771
772 @return 0 if the command is successfully generated
773 1 if the command cannot be generated.
774 */
775 Boolean StressTestControllerCommand::generateClientCommands(ostream& log_file)
776 {
777
778 s.manicka 1.3.24.2 String client_command = String::EMPTY;
779 double duration = _duration;
780 double delay = 0;
781
782 //
783 // Array's to store client specific information
784 //
785 _clientCommands = new String[_clientCount];
786 _clientDurations = new Uint64[_clientCount];
787 _clientDelays = new Uint64[_clientCount];
788
789 //
790 // Retrieve all the client options from the client table
791 // and build commands for respective clients.
792 // Add appropriate options to command string as required
793 //
794 for (Uint32 j=0; j< _clientCount; j++)
795 {
796 delay = 0;
797 String clientName = String::EMPTY;
798 String clientInst = String::EMPTY;
799 s.manicka 1.3.24.2 //
800 // Stress Client Name must exist for each client/client table
801 //
802 if (!_clientTable[j].lookup(NAME, clientName))
803 {
804 log_file<<StressTestControllerCommand::COMMAND_NAME<<
805 "::Required property NAME not found."<<endl;
806 return false;
807 }
808 //
809 // Start the command string with the client name.
810 //
811 client_command = clientName;
812
813 //
814 // Generate the commands for each client from each client table.
815 //
816 for (Table::Iterator i = _clientTable[j].start(); i; i++)
817 {
818 if (String::equalNoCase(i.key(),HOSTNAME))
819 {
820 s.manicka 1.3.24.2 client_command.append(" -hostname ");
821 if (_hostNameSpecified)
822 {
823 client_command.append(_hostName);
824 }
825 else
826 {
827 client_command.append(i.value());
828 }
829 }
830 else if (String::equalNoCase(i.key(),NAME))
831 {
832 //
833 // should be ignored - already saved using clientName
834 //
835 }
836 else if (String::equalNoCase(i.key(),PORTNUMBER))
837 {
838 client_command.append(" -");
839 client_command.append(PORTNUMBER);
840 client_command.append(" ");
841 s.manicka 1.3.24.2 if (_portNumberSpecified)
842 {
843 client_command.append(_portNumberStr);
844 }
845 else
846 {
847 client_command.append(i.value());
848 }
849 }
850 else if (String::equalNoCase(i.key(),SSL))
851 {
852 client_command.append(" -");
853 client_command.append(SSL);
854 }
855 else if (String::equalNoCase(i.key(),USERNAME))
856 {
857 client_command.append(" -");
858 client_command.append(USERNAME);
859 client_command.append(" ");
860 client_command.append(i.value());
861 }
862 s.manicka 1.3.24.2 else if (String::equalNoCase(i.key(),PASSWORD))
863 {
864 client_command.append(" -");
865 client_command.append(PASSWORD);
866 client_command.append(" ");
867 client_command.append(i.value());
868 }
869 else if (String::equalNoCase(i.key(),CLIENTNAME))
870 {
871 client_command.append(" -");
872 client_command.append(CLIENTNAME);
873 client_command.append(" ");
874 client_command.append(i.value());
875 }
876 else if (String::equalNoCase(i.key(),OPTIONS))
877 {
878 client_command.append(" -");
879 client_command.append(OPTIONS);
880 client_command.append(" ");
881 client_command.append(i.value());
882 }
883 s.manicka 1.3.24.2 else if (String::equalNoCase(i.key(),NAMESPACE))
884 {
885 client_command.append(" -");
886 client_command.append(NAMESPACE);
887 client_command.append(" ");
888 client_command.append(i.value());
889 }
890 else if (String::equalNoCase(i.key(),CLASSNAME))
891 {
892 client_command.append(" -");
893 client_command.append(CLASSNAME);
894 client_command.append(" ");
895 client_command.append(i.value());
896 }
897 else if ((String::equalNoCase(i.key(),INSTANCE))
898 ||(String::equalNoCase(i.key(),CLIENTWAIT))
899 ||(String::equalNoCase(i.key(),CLIENTDURATION)))
900 {
901 //
902 // do nothing here
903 // will be utilized to run the clients later.
904 s.manicka 1.3.24.2 //
905 }
906 else
907 {
908 //
909 // Save all other options for the commands
910 //
911 client_command.append(" -");
912 client_command.append(i.key());
913 client_command.append(" ");
914 client_command.append(i.value());
915 }
916 }
917 //
918 // Include verbose if enabled to clients
919 //
920 if (verboseEnabled)
921 {
922 client_command.append(" -verbose ");
923 }
924
925 s.manicka 1.3.24.2 //
926 // Acquire all the common properties listed in the property table
927 // from config file and include it as part of the client command
928 // as required.
929 //
930 for (Table::Iterator k = _propertyTable->start(); k; k++)
931 {
932 String propertyValue = String::EMPTY;
933 //
934 // Only include the common properties that are not already
935 // listed for the clients.
936 //
937 if (!_clientTable[j].lookup(k.key(), propertyValue))
938 {
939 //
940 // Include options other than ToleranceLevel
941 // clientDuration,clientwait and Duration
942 // in the command string for the clients.
943 //
944 if ((!String::equalNoCase(k.key(),TOLERANCELEVEL))
945 && (!String::equalNoCase(k.key(),CLIENTDURATION))
946 s.manicka 1.3.24.2 && (!String::equalNoCase(k.key(),CLIENTWAIT))
947 && (!String::equalNoCase(k.key(),DURATION)))
948 {
949 client_command.append(" -");
950 client_command.append(k.key());
951 //
952 // No values required for SSL
953 //
954 if (!String::equalNoCase(k.key(),SSL))
955 {
956 client_command.append(" ");
957 client_command.append(k.value());
958 }
959 }
960 }
961 //
962 // Use default duration if one was not specified in the Config file.
963 //
964 if (String::equalNoCase(k.key(),DURATION))
965 {
966 duration = atof(k.value().getCString());
967 s.manicka 1.3.24.2 }
968 else
969 {
970 duration = _duration;
971 }
972 } /* for (Table::Iterator k = _propertyTable->start(); k; k++) */
973
974 //
975 // Looking up table while ignoring cases for Client Duration/Wait.
976 //
977 for (Table::Iterator k = _clientTable[j].start(); k; k++)
978 {
979 //
980 // Overwrite duration if client duration set
981 //
982 if (String::equalNoCase(k.key(),CLIENTDURATION))
983 {
984 duration = atof(k.value().getCString());
985 }
986 if (String::equalNoCase(k.key(),CLIENTWAIT))
987 {
988 s.manicka 1.3.24.2 delay = atof(k.value().getCString());
989 }
990 }
991
992 //
993 // Save the generated command to corresponding element in the
994 // clientCommand array.
995 //
996 _clientCommands[j] = client_command;
997
998 //
999 // Converting minutes to milliseconds
1000 //
1001 _clientDurations[j] = (Uint64)convertmin2millisecs(duration);
1002 _clientDelays[j] = (Uint64)convertmin2millisecs(delay);
1003
1004 //
1005 // Saving logs
1006 //
1007 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1008 "::Client Command[";
1009 s.manicka 1.3.24.2 log_file<<j<<"]"<<endl;
1010 log_file<<" "<<_clientCommands[j]<<endl;
1011 log_file<<" Client Duration: "<<
1012 convertUint64toString(_clientDurations[j])<<endl;
1013 log_file<<
1014 " Client Delay: "<<convertUint64toString(_clientDelays[j])<<endl;
1015
1016 //
1017 // Verbose
1018 //
1019 if (verboseEnabled)
1020 {
1021 cout<<
1022 StressTestControllerCommand::COMMAND_NAME<<"::Client Command[";
1023 cout<<j<<"]"<<endl;
1024 cout<<" "<<_clientCommands[j]<<endl;
1025 cout<<" Client Duration: "<<
1026 convertUint64toString(_clientDurations[j])<<endl;
1027 cout<<" Client Delay: "<<convertUint64toString(_clientDelays[j])<<
1028 endl;
1029 }
1030 s.manicka 1.3.24.2 } /* for(Uint32 j=0; j< _clientCount; j++) */
1031 return true;
1032 } /* generateClientCommands */
1033
1034 /*
1035 Executes the command and writes the results to the PrintWriters.
1036 This method is where the clients are intiated.
1037 The clients are kept running until its duration is met
1038 or the controller is interrupted by a SIGINT or SIGABRT signal
1039 or if the controller failed to acquire the clientPIDs when needed.
1040
1041 Clients with clientWait, will be stopped when its duration is met and
1042 then restarted after its wait period is completed. This will continue
1043 until the end of the overall duration.
1044 When the overall duration has ended or the controller is interupted then
1045 the controller will read the PID file to update its clients PID and
1046 request all the clients to end its processes.
1047
1048 @param outPrintWriter the ostream to which output should be
1049 written
1050 @param errPrintWriter the ostream to which error output should be
1051 s.manicka 1.3.24.2 written
1052
1053 @return 0 if the command is successful
1054 1 if an error occurs in executing the command
1055
1056 */
1057 Uint32 StressTestControllerCommand::execute (
1058 ostream& outPrintWriter,
1059 ostream& errPrintWriter)
1060 {
1061
1062 int actual_client = 0;
1063 Uint64 startMilliseconds = 0;
1064 Uint64 nowMilliseconds = 0;
1065 Uint64 stopMilliseconds = 0;
1066 Uint64 timeoutMilliseconds = 0;
1067 Uint64 *clientStartMilliseconds = 0;
1068 Uint64 *clientStopMilliseconds = 0;
1069 Uint64 *clientDelayMilliseconds = 0;
1070 Boolean *clientStopped = 0;
1071 Boolean *clientDelayed = 0;
1072 s.manicka 1.3.24.2 String act_command = String::EMPTY;
1073 Boolean TestFailed = false;
1074 char str[15];
1075 char strTime[256];
1076 struct tm tmTime;
1077
1078
1079
1080 //
1081 // log file
1082 //
1083 ofstream log_file;
1084
1085 //
1086 // open the file
1087 //
1088 OpenAppend(log_file,_stressTestLogFile);
1089
1090 //
1091 // Failed to read log file.
1092 //
1093 s.manicka 1.3.24.2 if (!log_file)
1094 {
1095 log_file.close();
1096 if (verboseEnabled)
1097 {
1098 outPrintWriter<<StressTestControllerCommand::COMMAND_NAME;
1099 outPrintWriter<<"Cannot read file "<<_stressTestLogFile<<endl;
1100 }
1101 return RC_ERROR;
1102 }
1103
1104 //
1105 // Display usage message if help was specified
1106 //
1107 if ( _operationType == OPERATION_TYPE_HELP )
1108 {
1109 outPrintWriter << _usage << endl;
1110 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1111 "::Listing usage information "<<endl;
1112 log_file.close();
1113 //
1114 s.manicka 1.3.24.2 // No need for the client pid and log file.
1115 //
1116 FileSystem::removeFile(_stressTestClientPIDFile);
1117 FileSystem::removeFile(_stressTestClientLogFile);
1118 return (RC_SUCCESS);
1119 }
1120 //
1121 // Display PEGASUS version if version was specified
1122 //
1123 else if ( _operationType == OPERATION_TYPE_VERSION )
1124 {
1125 outPrintWriter << "Version " << PEGASUS_PRODUCT_VERSION << endl;
1126 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1127 "::Listing version information "<<endl;
1128 log_file<<"Version " << PEGASUS_PRODUCT_VERSION << endl;
1129 log_file.close();
1130 //
1131 // No need for the client pid and log file.
1132 //
1133 FileSystem::removeFile(_stressTestClientPIDFile);
1134 FileSystem::removeFile(_stressTestClientLogFile);
1135 s.manicka 1.3.24.2 return (RC_SUCCESS);
1136 }
1137
1138 //
1139 // gracefully shutdown when interrupted
1140 //
1141 signal(SIGABRT, endAllTests);
1142 signal(SIGINT, endAllTests);
1143
1144 //
1145 // Allocate variables necessary to run clients.
1146 //
1147 if(_clientCount > 0)
1148 {
1149 clientInstance = new int[_clientCount];
1150 clientStartMilliseconds = new Uint64[_clientCount];
1151 clientStopMilliseconds = new Uint64[_clientCount];
1152 clientDelayMilliseconds = new Uint64[_clientCount];
1153 clientStopped = new Boolean[_clientCount];
1154 clientDelayed = new Boolean[_clientCount];
1155 }
1156 s.manicka 1.3.24.2 else
1157 {
1158 errPrintWriter << "Stress Tests must have at least one Client." << endl;
1159 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1160 "::Stress Tests must have at least one Client."<<endl;
1161 log_file.close();
1162 return (RC_ERROR);
1163 }
1164
1165 try
1166 {
1167 //
1168 // Initializing the Boolean array's to false.
1169 //
1170 for (Uint32 i=0;i<_clientCount;i++)
1171 {
1172 clientStopped[i] = false;
1173 clientDelayed[i] = false;
1174 }
1175 //
1176 // Set up duration of the tests
1177 s.manicka 1.3.24.2 //
1178 startMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
1179 nowMilliseconds = startMilliseconds;
1180 timeoutMilliseconds = (Uint64)convertmin2millisecs(_duration);
1181 stopMilliseconds = nowMilliseconds + timeoutMilliseconds;
1182
1183 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1184 ":: Test Duration information "<<endl;
1185 log_file<<" Start Time in milliseconds: "<<
1186 convertUint64toString(startMilliseconds)<<endl;
1187 log_file<<" Total duration in milliseconds: "<<
1188 convertUint64toString(timeoutMilliseconds)<<endl;
1189 log_file<<" Actual Stop Time in milliseconds: "<<
1190 convertUint64toString(stopMilliseconds)<<endl;
1191 //
1192 // Verbose details for Stress Test duration
1193 //
1194 if (verboseEnabled)
1195 {
1196 outPrintWriter<<StressTestControllerCommand::COMMAND_NAME<<
1197 ":: Test Duration information "<<endl;
1198 s.manicka 1.3.24.2 outPrintWriter<<" Start Time in milliseconds: "<<
1199 convertUint64toString(startMilliseconds)<<endl;
1200 outPrintWriter<<" Total duration in milliseconds: "<<
1201 convertUint64toString(timeoutMilliseconds)<<endl;
1202 outPrintWriter<<
1203 " Actual Stop Time in milliseconds: "<<
1204 convertUint64toString(stopMilliseconds)<<endl;
1205 }
1206
1207 //
1208 // First Tolerance check up interval is set up to be twice
1209 // the CHECKUP_INTERVAL. This should give the clients enough time
1210 // to update its PID, status etc.
1211 //
1212 Uint64 nextCheckupInMillisecs =
1213 (Uint64)convertmin2millisecs(2 * CHECKUP_INTERVAL) + nowMilliseconds;
1214 //
1215 // Main "while" loop where the clients are initiated.
1216 //
1217 while(stopMilliseconds > nowMilliseconds)
1218 {
1219 s.manicka 1.3.24.2
1220 //
1221 // Small delay in the while loop seemed to reduce the CPU usage
1222 // considerably in Windows. (From 80% to 1%)
1223 //
1224 #ifndef PEGASUS_OS_TYPE_WINDOWS
1225 sleep(RUN_DELAY);
1226 #else
1227 Sleep(RUN_DELAY * 1000);
1228 #endif
1229
1230 //
1231 // Quit if SIGINT, SIGABRT is caught
1232 // So the clients can be gracefully shutdown.
1233 //
1234 if(Quit)
1235 {
1236 log_file<<
1237 "Test interrupted by either SIGINT or SIGABORT."<<endl;
1238 TestFailed = true;
1239 break;
1240 s.manicka 1.3.24.2 }
1241 //
1242 // The following block will be where clients are executed initially.
1243 //
1244 if(!actual_client)
1245 {
1246 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1247 "::Running the following tests: "<<endl;
1248 outPrintWriter<<StressTestControllerCommand::COMMAND_NAME<<
1249 "::Running the following tests: "<<endl;
1250 for (Uint32 j=0; j< _clientCount; j++)
1251 {
1252 String clientInst = String::EMPTY;
1253 //
1254 // Acquire the client Instance for each clients
1255 //
1256 if (!_clientTable[j].lookup(INSTANCE, clientInst))
1257 {
1258 String ErrReport = String("Invalid Property Value: ");
1259 ErrReport.append(INSTANCE);
1260 ErrReport.append("=");
1261 s.manicka 1.3.24.2 ErrReport.append(clientInst);
1262 throw StressTestControllerException(ErrReport);
1263 }
1264 clientInstance[j] = atoi(clientInst.getCString());
1265
1266 //
1267 // Acquire and set client specific duration
1268 //
1269 clientStartMilliseconds[j] =
1270 TimeValue::getCurrentTime().toMilliseconds();
1271 clientStopMilliseconds[j] =
1272 clientStartMilliseconds[j] + _clientDurations[j];
1273
1274 //
1275 // for verbose only
1276 //
1277 if (verboseEnabled)
1278 {
1279 outPrintWriter<<"Client:"<<"["<<j<<"]"<<endl;
1280 log_file<<"Client:"<<"["<<j<<"]"<<endl;
1281 outPrintWriter<<"ClientStart:"<<
1282 s.manicka 1.3.24.2 convertUint64toString(clientStartMilliseconds[j])<<
1283 endl;
1284 outPrintWriter<<"ClientStop:"<<
1285 convertUint64toString(clientStopMilliseconds[j])<<
1286 endl;
1287 outPrintWriter<<"ClientDuration:"<<
1288 convertUint64toString(_clientDurations[j])<<endl;
1289 log_file<<"ClientStart:"<<
1290 convertUint64toString(clientStartMilliseconds[j])<<
1291 endl;
1292 log_file<<"ClientStop:"<<
1293 convertUint64toString(clientStopMilliseconds[j])<<
1294 endl;
1295 log_file<<
1296 "ClientDuration:"<<
1297 convertUint64toString(_clientDurations[j])<<endl;
1298 }
1299 log_file<<
1300 "Number of instances of this client: "<<
1301 clientInstance[j]<<endl;
1302 if(verboseEnabled)
1303 s.manicka 1.3.24.2 {
1304 outPrintWriter<<
1305 "Number of instances of this client:"<<
1306 clientInstance[j]<<endl;
1307 }
1308 //
1309 // Execute each instance of the client.
1310 // - Additional required parameters are added to the
1311 // commands.
1312 // like, -clientid, -pidfile, -clientlog
1313 //
1314 for (int instanceID =0;instanceID<clientInstance[j];
1315 instanceID++)
1316 {
1317 outPrintWriter<<
1318 "Running Client("<<actual_client<<")"<<endl;
1319 log_file<<
1320 "Running Client("<<actual_client<<")"<<endl;
1321 act_command=String::EMPTY;
1322 #ifdef PEGASUS_OS_TYPE_WINDOWS
1323 act_command.append("start ");
1324 s.manicka 1.3.24.2 #endif
1325 //
1326 // Adding all the required parameters for the command.
1327 //
1328 act_command.append(_clientCommands[j].getCString());
1329 act_command.append(" -clientid ");
1330 sprintf(str,"%d",actual_client);
1331 act_command.append(str);
1332 act_command.append(" -pidfile ");
1333 act_command.append(" \"");
1334 act_command.append(_stressTestClientPIDFile);
1335 act_command.append("\"");
1336 act_command.append(" -clientlog");
1337 act_command.append(" \"");
1338 act_command.append(_stressTestClientLogFile);
1339 act_command.append("\"");
1340 act_command.append("&");
1341 if (verboseEnabled)
1342 {
1343 outPrintWriter<<" "<<act_command<<endl;
1344 tmTime = getCurrentActualTime();
1345 s.manicka 1.3.24.2 strftime(
1346 strTime,
1347 256,
1348 "%d/%m/%Y at %H:%M:%S\n",
1349 &tmTime);
1350 log_file<<
1351 StressTestControllerCommand::COMMAND_NAME<<
1352 "::Running following command on "<<
1353 strTime<<endl;
1354 log_file<<" ("<<actual_client<<") \n"<<
1355 act_command<<endl;
1356 }
1357
1358 //
1359 // Executing the Client
1360 //
1361 int rc = system(act_command.getCString());
1362 //
1363 // Continue even if the client failed to Execute
1364 // This failure is validated with Tolerance level later
1365 //
1366 s.manicka 1.3.24.2 if (rc)
1367 {
1368 log_file<<"Command failed to Execute."<<endl;
1369 if (verboseEnabled)
1370 {
1371 outPrintWriter<<
1372 "Command failed to Execute."<<endl;
1373 }
1374 }
1375 //
1376 // Increment the actual number of clients
1377 //
1378 ++actual_client;
1379 } /* for(int instanceID =0;instanceID<clientInstance[j]...*/
1380
1381 }/* for(Uint32 j=0; j< _clientCount; j++) */
1382
1383 //
1384 //retrieve all PIDs and status;
1385 //
1386 clientPIDs = new pid_t[actual_client];
1387 s.manicka 1.3.24.2 clientStatus = new int[actual_client];
1388 prev_clientStatus = new int[actual_client];
1389 clientTimeStamp = new Uint64[actual_client];
1390 prev_clientTimeStamp = new Uint64[actual_client];
1391 clientActive = new Boolean[actual_client];
1392 nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
1393 for (int i=0;i<actual_client;i++)
1394 {
1395 clientPIDs[i] = 9999999;
1396 clientStatus[i] = NO_RESPONSE;
1397 clientActive[i] = true;
1398 clientTimeStamp[i] = nowMilliseconds;
1399 prev_clientTimeStamp[i] = nowMilliseconds;
1400 }
1401 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1402 "::Getting client PID's and status. "<<endl;
1403 if (verboseEnabled)
1404 {
1405 outPrintWriter<<StressTestControllerCommand::COMMAND_NAME<<
1406 "::Getting client PID's and status. "<<endl;
1407 }
1408 s.manicka 1.3.24.2 int rc = _getClientPIDs(actual_client,log_file);
1409 if (!rc)
1410 {
1411 outPrintWriter<<
1412 "Failed to communicate with clients."<<endl;
1413 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1414 "::Failed to communicate with clients. "<<endl;
1415 log_file<<
1416 " ::Failed to get client PID & status. "
1417 <<endl;
1418 TestFailed = true;
1419 break;
1420 }
1421 }/* if (!actual_client) */
1422 else
1423 {
1424 /**
1425 Every CHECKUP_INTERVAL minutes check to see if tests are
1426 within tolerance. Tests will cease to run if they
1427 are not within tolerance. The controller will stop
1428 all the clients and then exit.
1429 s.manicka 1.3.24.2 */
1430
1431 //
1432 // Retreive all the client PIDs
1433 //
1434 int rc = _getClientPIDs(actual_client,log_file);
1435
1436 //
1437 // Get Current Time
1438 //
1439 nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
1440
1441 //
1442 // Check tolerance level if its time
1443 //
1444 if (nowMilliseconds >= nextCheckupInMillisecs)
1445 {
1446 //
1447 // Set up the next tolerance time
1448 //
1449 nextCheckupInMillisecs =
1450 s.manicka 1.3.24.2 (Uint64)convertmin2millisecs(CHECKUP_INTERVAL) +
1451 nowMilliseconds;
1452 //
1453 // End tests when failed to acquire the Client PID or
1454 // status.
1455 //
1456 if (!rc)
1457 {
1458 outPrintWriter<<
1459 "Failed to communicate with clients."<<endl;
1460 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1461 "::Failed to communicate with clients. "<<endl;
1462 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1463 "::Get Client PID FAILED. "<<endl;
1464 TestFailed = true;
1465 break;
1466 }
1467 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1468 "::Checking current tolerance level. "<<endl;
1469 //
1470 // Output Client info if verbose is enabled.
1471 s.manicka 1.3.24.2 //
1472 if (verboseEnabled)
1473 {
1474 outPrintWriter<<
1475 StressTestControllerCommand::COMMAND_NAME<<
1476 "::Checking current tolerance level. "<<endl;
1477 for (int i=0;i< actual_client; i++)
1478 {
1479 outPrintWriter <<" Client: "<<i;
1480 outPrintWriter <<" PID: "<<clientPIDs[i]<<", ";
1481 outPrintWriter <<" Status: "<<clientStatus[i]<<endl;
1482 log_file <<" Client: "<<i;
1483 log_file <<" PID: "<<clientPIDs[i]<<", ";
1484 log_file <<" Status: "<<clientStatus[i]<<", ";
1485 log_file<<" TimeStamp: "<<
1486 convertUint64toString(clientTimeStamp[i])<<
1487 endl;
1488 }
1489 }
1490 //
1491 // Check the actual tolerance level
1492 s.manicka 1.3.24.2 //
1493 Boolean withinTolerance = _checkToleranceLevel(
1494 actual_client,
1495 nowMilliseconds,
1496 log_file);
1497 //
1498 // End tests if not within tolerance
1499 //
1500 if (!withinTolerance)
1501 {
1502 log_file<<"FAILED::Tests NOT within tolerance."<<endl;
1503 errPrintWriter<<"FAILED::Tests NOT within tolerance."
1504 <<endl;
1505 TestFailed = true;
1506 break;
1507 }
1508 //
1509 // Within Tolerance - Continue tests.
1510 //
1511 log_file<<"********Tests are within tolerance.********* "<<
1512 endl;
1513 s.manicka 1.3.24.2 if (verboseEnabled)
1514 {
1515 outPrintWriter<<
1516 " ********Tests are within tolerance.**********"<<
1517 endl;
1518 }
1519 } /* if (nowMilliseconds >= nextCheckupInMillisecs)*/
1520 //
1521 // Stop clients with delay
1522 //
1523 for (Uint32 clientID=0; clientID < _clientCount; clientID++)
1524 {
1525 //
1526 // Get Current time
1527 //
1528 nowMilliseconds =
1529 TimeValue::getCurrentTime().toMilliseconds();
1530
1531 //
1532 // Stop only running clients as required.
1533 //
1534 s.manicka 1.3.24.2 if (!clientStopped[clientID])
1535 {
1536 //
1537 // If Client's duration is up
1538 //
1539 if (clientStopMilliseconds[clientID]<= nowMilliseconds)
1540 {
1541 //
1542 // Stop all the instances of this client
1543 //
1544 for (int instanceID =0;
1545 instanceID<clientInstance[clientID];
1546 instanceID++)
1547 {
1548 log_file<<"Stopping client:("<<
1549 clientID+instanceID<<")"<<endl;
1550 log_file<<" with PID = "<<
1551 clientPIDs[clientID+instanceID]<<endl;
1552 outPrintWriter<<"Stopping client:("<<
1553 clientID+instanceID<<")"<<endl;
1554 outPrintWriter<<" with PID = "<<
1555 s.manicka 1.3.24.2 clientPIDs[clientID+instanceID]<<endl;
1556 if (verboseEnabled)
1557 {
1558 tmTime = getCurrentActualTime();
1559 strftime(
1560 strTime,
1561 256,
1562 "%d/%m/%Y at %H:%M:%S\n",
1563 &tmTime);
1564 log_file<<" Stopped on "<<strTime<<endl;
1565 }
1566 String stopClientFile = String::EMPTY;
1567 stopClientFile.append(pegasusHome);
1568 stopClientFile.append(DEFAULT_TMPDIR);
1569 stopClientFile.append("STOP_");
1570 sprintf(
1571 str,
1572 "%d",
1573 clientPIDs[clientID+instanceID]);
1574 stopClientFile.append(str);
1575 //
1576 s.manicka 1.3.24.2 // Required for Windows
1577 //
1578 ofstream stop_file(
1579 stopClientFile.getCString(),
1580 ios::out);
1581 stop_file << "Stop Client PID : "<<
1582 clientPIDs[clientID + instanceID]<<
1583 endl;
1584 stop_file.close();
1585 #ifndef PEGASUS_OS_TYPE_WINDOWS
1586 // one more way to stop the clients.
1587 int rc =
1588 kill(clientPIDs[clientID+instanceID], SIGINT);
1589 if (rc)
1590 {
1591 outPrintWriter<<"FAILED to stop client:("<<
1592 clientID+instanceID<<")"<<endl;
1593 log_file<<"FAILED to stop client:("<<
1594 clientID + instanceID<<")"<<endl;
1595 }
1596 #endif
1597 s.manicka 1.3.24.2 //
1598 // Set the client as inactive.
1599 //
1600 clientActive[clientID + instanceID] = false;
1601 }/* for (int instanceID =0;instanceID<clientInst..*/
1602 //
1603 // indicate that the client was stopped.
1604 //
1605 clientStopped[clientID] = true;
1606 //
1607 // If the Client has a Wait time
1608 //
1609 if (_clientDelays[clientID] !=0)
1610 {
1611 clientDelayMilliseconds[clientID] =
1612 nowMilliseconds + _clientDelays[clientID];
1613 clientDelayed[clientID] = true;
1614 }
1615 } /* if (clientStopMilliseconds[clientID]<= nowMilli..*/
1616 } /* if (!clientStopped[clientID]) */
1617 else
1618 s.manicka 1.3.24.2 {
1619 //
1620 // Only restart clients that are waiting.
1621 //
1622 if (clientDelayed[clientID])
1623 {
1624 //
1625 // When waiting period is consumed.
1626 //
1627 if (clientDelayMilliseconds[clientID]<=
1628 nowMilliseconds)
1629 {
1630 //
1631 // Restart all the instances of the client.
1632 //
1633 for (int instanceID =0;
1634 instanceID<clientInstance[clientID];
1635 instanceID++)
1636 {
1637 act_command=String::EMPTY;
1638 #ifdef PEGASUS_OS_TYPE_WINDOWS
1639 s.manicka 1.3.24.2 act_command.append("start ");
1640 #endif
1641 act_command.append(
1642 _clientCommands[clientID].getCString());
1643 act_command.append(" -clientid ");
1644 sprintf(str,"%d",clientID+instanceID);
1645 act_command.append(str);
1646 act_command.append(" -pidfile ");
1647 act_command.append(" \"");
1648 act_command.append(_stressTestClientPIDFile);
1649 act_command.append("\"");
1650 act_command.append(" -clientlog");
1651 act_command.append(" \"");
1652 act_command.append(_stressTestClientLogFile);
1653 act_command.append("\"");
1654 act_command.append("&");
1655 log_file<<"Restarting client:("<<
1656 clientID+instanceID<<")"<<endl;
1657 outPrintWriter<<"Restarting client:("<<
1658 clientID+instanceID<<")"<<endl;
1659 if (verboseEnabled)
1660 s.manicka 1.3.24.2 {
1661 outPrintWriter<<" "<<act_command<<endl;
1662 log_file<<" ("<<
1663 clientID+instanceID<<
1664 ") \n"<<act_command<<endl;
1665 tmTime = getCurrentActualTime();
1666 strftime(
1667 strTime,
1668 256,
1669 "%d/%m/%Y at %H:%M:%S\n",
1670 &tmTime);
1671 log_file<<" Restarted on "<<
1672 strTime<<endl;
1673 }
1674 int rc = system(act_command.getCString());
1675 if (rc)
1676 {
1677 log_file<<"Command failed to Execute."<<
1678 endl;
1679 if (verboseEnabled)
1680 {
1681 s.manicka 1.3.24.2 outPrintWriter<<act_command<<
1682 "Command failed to Execute."<<
1683 endl;
1684 }
1685 }
1686 clientActive[clientID+instanceID] = true;
1687 } /* for (int instanceID =0;instanceID .. */
1688 clientStopMilliseconds[clientID] =
1689 nowMilliseconds +
1690 _clientDurations[clientID];
1691 clientStopped[clientID] = false;
1692 clientDelayed[clientID] = false;
1693 }/* if(clientDelayMilliseconds[clientID]<=nowMi.. */
1694 } /* if(clientDelayed[clientID]) */
1695 } /* else ..*/
1696 } /* for(Uint32 clientID=0;clientID < _clientCount;clientID++)*/
1697 } /* else for if(!actual_client) */
1698 //
1699 // Get Current time
1700 //
1701 nowMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
1702 s.manicka 1.3.24.2
1703 } /* while(stopMilliseconds > nowMilliseconds) */
1704
1705 }//try
1706
1707 catch (const StressTestControllerException& e)
1708 {
1709 errPrintWriter << StressTestControllerCommand::COMMAND_NAME <<
1710 ": " << e.getMessage () << endl;
1711 return (RC_ERROR);
1712 }
1713
1714 //
1715 // Stress Tests should be stopped.
1716 //
1717 outPrintWriter<<"Ending tests::Preparing to stop all the clients."<<endl;
1718 log_file<<"Ending tests::Preparing to stop all the clients."<<endl;
1719
1720 // Waiting to allow any clients that might have been re-started
1721 // just before the tests were ended to add
1722 // its pid to the pid file.
1723 s.manicka 1.3.24.2
1724 #ifndef PEGASUS_OS_TYPE_WINDOWS
1725 sleep(STOP_DELAY);
1726 #else
1727 Sleep(STOP_DELAY * 1000);
1728 #endif
1729
1730 //
1731 // get all the clientPIDs before it is stopped.
1732 //
1733 int rc = _getClientPIDs(actual_client,log_file);
1734 if (!rc)
1735 {
1736 outPrintWriter<<"Failed to communicate with clients."<<endl;
1737 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1738 "::Failed to communicate with clients. "<<endl;
1739 log_file<<" ::Failed to get client PID & status. "<<
1740 endl;
1741 TestFailed = true;
1742 }
1743 tmTime = getCurrentActualTime();
1744 s.manicka 1.3.24.2 strftime(strTime,256,"%d/%m/%Y at %H:%M:%S\n",&tmTime);
1745 log_file<<"Ending tests:: Stopping all the clients on "<<strTime <<endl;
1746 for (int i=0;i<actual_client;i++)
1747 {
1748 if(verboseEnabled)
1749 {
1750 outPrintWriter<<"Stopping Client("<<i<<") with PID:"<<
1751 clientPIDs[i]<<endl;
1752 }
1753 log_file<<"Stopping Client("<<i<<") with PID:"<<clientPIDs[i]<<endl;
1754 //
1755 // Required for Windows
1756 //
1757 String stopClientFile = String::EMPTY;
1758 stopClientFile.append(pegasusHome);
1759 stopClientFile.append(DEFAULT_TMPDIR);
1760 stopClientFile.append("STOP_");
1761 sprintf(str,"%d",clientPIDs[i]);
1762 stopClientFile.append(str);
1763 ofstream stop_file(stopClientFile.getCString(),ios::out);
1764 stop_file << "Stop Client PID : "<<clientPIDs[i]<<endl;
1765 s.manicka 1.3.24.2 stop_file.close();
1766 #ifndef PEGASUS_OS_TYPE_WINDOWS
1767 // Another way to stop the client
1768 int rc = 0;
1769 rc = kill(clientPIDs[i], SIGINT);
1770 if (rc)
1771 {
1772 if (verboseEnabled)
1773 {
1774 outPrintWriter<<"Failed to stop client:("<<i<<")"<<endl;
1775 }
1776 log_file<<"Failed to stop client:("<<i<<")"<<endl;
1777 }
1778 #endif
1779 }
1780 if (verboseEnabled)
1781 {
1782 outPrintWriter<<"Cleaning all resources"<<endl;
1783 }
1784 log_file<<"Cleaning all resources."<<endl;
1785 cleanupProcess();
1786 s.manicka 1.3.24.2
1787 //
1788 // Waiting to allow clients to shutdown
1789 //
1790 #ifndef PEGASUS_OS_TYPE_WINDOWS
1791 sleep(SHUTDOWN_DELAY);
1792 #else
1793 Sleep(SHUTDOWN_DELAY * 1000);
1794 #endif
1795 //
1796 // If the test did not run to completition
1797 //
1798 if (TestFailed)
1799 return(RC_ERROR);
1800
1801 return (RC_SUCCESS);
1802 } /* execute */
1803
1804
1805 /*
1806 Retrieves the contents of the config file if specified or uses default
1807 s.manicka 1.3.24.2 values from either the default config file
1808
1809 @param fileName The specified or default config file for the
1810 tests.
1811 @param log_file The log file.
1812
1813 @return true if the file was read successfully
1814 false if file was not read successfully.
1815
1816 */
1817 Boolean StressTestControllerCommand::getFileContent(
1818 String fileName,
1819 ostream& log_file)
1820 {
1821 String configData = String::EMPTY;
1822 String line;
1823 int lineNumber = 0;
1824 Boolean isSuccess = true;
1825 String name = String::EMPTY;
1826 String value = String::EMPTY;
1827 String ErrReports = String::EMPTY;
1828 s.manicka 1.3.24.2
1829 ifstream ifs;
1830
1831 //
1832 // Open the config file and read the stress test configuration data
1833 //
1834 Open(ifs,fileName);
1835 if (!ifs)
1836 {
1837 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1838 "::Cannot read config file: "<<fileName<<endl;
1839 throw NoSuchFile(fileName);
1840 }
1841
1842 log_file<<StressTestControllerCommand::COMMAND_NAME <<
1843 "::Storing client details. "<<endl;
1844 if (verboseEnabled)
1845 {
1846 cout<<StressTestControllerCommand::COMMAND_NAME<<
1847 "::Storing config details. "<<endl;
1848 }
1849 s.manicka 1.3.24.2 //
1850 // Get each line of the file.
1851 //
1852 while (GetLine(ifs, line))
1853 {
1854 ++lineNumber;
1855 IsAClient = false;
1856 name = String::EMPTY;
1857 value = String::EMPTY;
1858 try
1859 {
1860 //
1861 // Parse each line of Config file
1862 //
1863 _parseLine(line,lineNumber,name,value,log_file);
1864 }
1865 //
1866 // catch all the exceptions if any thrown from parseLine
1867 // - Accumulate all the errors from the config file
1868 // - Report all errors if found when complete.
1869 //
1870 s.manicka 1.3.24.2 catch (Exception& e)
1871 {
1872 char line_num[10];
1873 sprintf(line_num, "%d", lineNumber);
1874 String msg(e.getMessage());
1875 ErrReports.append("\n ");
1876 ErrReports.append("line#");
1877 ErrReports.append(line_num);
1878 ErrReports.append(":: ");
1879 ErrReports.append(msg.getCString());
1880 log_file<<StressTestControllerCommand::COMMAND_NAME<<"::"
1881 <<msg<<endl;
1882 isSuccess = false;
1883 }
1884 catch(...)
1885 {
1886 char line_num[10];
1887 sprintf(line_num, "%d", lineNumber);
1888 ErrReports.append("\n ");
1889 ErrReports.append("line#");
1890 ErrReports.append(line_num);
1891 s.manicka 1.3.24.2 ErrReports.append(":: ");
1892 ErrReports.append("Unknown exception caught.");
1893 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1894 ":Unknown exception caught when parsing line."<<endl;
1895 cerr<<StressTestControllerCommand::COMMAND_NAME <<
1896 ":Unknown exception caught when parsing line."<<endl;
1897 return false;
1898 }
1899
1900 if ((IsClientOptions)||(IgnoreLine))
1901 {
1902 IsClientOptions = false;
1903 IgnoreLine = false;
1904 continue;
1905 }
1906 //
1907 // If its a client Update the table
1908 //
1909 if (IsAClient)
1910 {
1911 _currClient=name;
1912 s.manicka 1.3.24.2 _currClientCount=_clientCount;
1913 //
1914 // save the client details in a table
1915 //
1916 if (!_storeClientDetails(name,value))
1917 {
1918 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1919 "::Syntax error found in line#"<<lineNumber<<
1920 " of config file: "<<fileName<<endl;
1921 isSuccess = false;
1922 }
1923 }
1924 else
1925 {
1926 //
1927 // Common properties are updated only if they are valid.
1928 //
1929 if (isSuccess)
1930 {
1931 //
1932 // Store the property name and value in the table
1933 s.manicka 1.3.24.2 //
1934 if (verboseEnabled)
1935 {
1936 cout<<" "<<name<<"\t= "<<value<<endl;
1937 }
1938 if (!_propertyTable->insert(name, value))
1939 {
1940 //
1941 // Duplicate property, ignore the new property value.
1942 //
1943 #ifdef STRESSTEST_DEBUG
1944 cout<< "Property Name:duplicate name already saved: "<<
1945 name<<endl;
1946 #endif
1947 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1948 "::Duplicate property name "<<name<<" already saved."<<
1949 endl;
1950 }
1951 }
1952 }
1953
1954 s.manicka 1.3.24.2 }
1955 ifs.close();
1956 //
1957 // If a client is not read from the config file
1958 //
1959 if ((lineNumber==0)||(!_clientCount))
1960 {
1961 ErrReports.append("\n ");
1962 ErrReports.append(StressTestControllerCommand::COMMAND_NAME);
1963 ErrReports.append("::No clients found.");
1964 log_file<<StressTestControllerCommand::COMMAND_NAME <<
1965 "::No clients found in"<<" config file: "<<fileName<<endl;
1966 isSuccess = false;
1967 }
1968 //
1969 // Error was found.
1970 //
1971 if (!isSuccess)
1972 {
1973 //
1974 // cleanup allocated memory
1975 s.manicka 1.3.24.2 //
1976 cleanupProcess();
1977 throw StressTestControllerException(ErrReports);
1978 }
1979
1980 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1981 "::Common Properties:"<<endl;
1982 if (verboseEnabled)
1983 {
1984 cout<<StressTestControllerCommand::COMMAND_NAME<<
1985 "::Common Properties:"<<endl;
1986 }
1987 for (Table::Iterator i = _propertyTable->start(); i; i++)
1988 {
1989 log_file<<" "<<i.key()<<"\t= "<<i.value()<<endl;
1990 if (verboseEnabled)
1991 {
1992 cout<<" "<<i.key()<<"\t= "<<i.value()<<endl;
1993 }
1994 }
1995 if (verboseEnabled)
1996 s.manicka 1.3.24.2 {
1997 cout<<"Total clients found:"<<_clientCount<<endl;
1998 cout<<"CLIENT TABLE CONTENTS:"<<endl;
1999 }
2000 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2001 "::Client Properties:"<<endl;
2002 for (Uint32 j = 0; j < _clientCount; j++)
2003 {
2004 log_file<<"Client information #"<<j+1<<" from config file:"<<endl;
2005 if (verboseEnabled)
2006 {
2007 cout<<"Client("<<j<<")"<<endl;
2008 }
2009 for (Table::Iterator i = _clientTable[j].start(); i; i++)
2010 {
2011 log_file<<" "<<i.key()<<" = "<<i.value()<<endl;
2012 if (verboseEnabled)
2013 {
2014 cout<<" "<< i.key() << "=" << i.value() << endl;
2015 }
2016 }
2017 s.manicka 1.3.24.2 }
2018
2019
2020 if (isSuccess)
2021 {
2022 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2023 "::Successfully retreived config values from" <<
2024 " config file: "<<fileName<<endl;
2025 }
2026 return isSuccess;
2027 }/* getFileContent */
2028
2029
2030 /*
2031 Validates the configuration data found in the specified config file or
2032 the default config file.
2033 Will validate known common/client specific properties in configuration.
2034 Will validate valid client names.
2035 (Clients are excepted to exist in the $PEGASUS_HOME/bin directory)
2036
2037 @param vars The property name to be validated
2038 s.manicka 1.3.24.2 @param value The property value associated to the above name
2039
2040 @return true if the property was validated successfully
2041 false if the property failed validation.
2042
2043 */
2044
2045
2046 Boolean StressTestControllerCommand::_validateConfiguration(
2047 String & vars,
2048 const String & value,
2049 ostream& log_file)
2050 {
2051 Boolean IsValid = false;
2052
2053
2054 if (String::equalNoCase(vars,HOSTNAME))
2055 {
2056 vars=String::EMPTY;
2057 vars.append(HOSTNAME);
2058 if(!IsAClient)
2059 s.manicka 1.3.24.2 {
2060 if (!_hostNameSpecified)
2061 {
2062 _hostName = value;
2063 }
2064 }
2065 else
2066 {
2067
2068 if(_hostName != String::EMPTY)
2069 {
2070 if (!String::equalNoCase(value,_hostName))
2071 {
2072 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2073 "::Multiple hostnames were found. "<<endl;
2074 if (verboseEnabled)
2075 {
2076 cout<<StressTestControllerCommand::COMMAND_NAME <<
2077 "::Multiple hostnames were found. "<<endl;
2078 }
2079 return false;
2080 s.manicka 1.3.24.2 }
2081 }
2082 else
2083 {
2084 _hostName = value;
2085 }
2086 }
2087 }
2088 else if (String::equalNoCase(vars,PORTNUMBER))
2089 {
2090 vars=String::EMPTY;
2091 vars.append(PORTNUMBER);
2092 Uint32 vPortNumber = atoi(value.getCString());
2093
2094 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2095 "::Portnumber specified in config = "<<vPortNumber<<endl;
2096 if (verboseEnabled)
2097 {
2098 cout<<StressTestControllerCommand::COMMAND_NAME <<
2099 "::Portnumber specified in config = "<<vPortNumber<<endl;
2100 }
2101 s.manicka 1.3.24.2 if (vPortNumber > _MAX_PORTNUMBER)
2102 {
2103 //
2104 // Portnumber out of valid range
2105 //
2106 if (verboseEnabled)
2107 {
2108 cout<<StressTestControllerCommand::COMMAND_NAME <<
2109 "::Invalid portnumber was found. "<<endl;
2110 }
2111 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2112 "::Invalid portnumber was found. "<<endl;
2113 return false;
2114 }
2115 if (!_portNumberSpecified)
2116 {
2117 _portNumber = atoi(value.getCString());
2118 }
2119
2120 }/* else if (String::equalNoCase ... */
2121 else if (String::equalNoCase(vars,SSL))
2122 s.manicka 1.3.24.2 {
2123 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2124 "::SSL enabled in config. "<<endl;
2125 if (!_useSSL)
2126 {
2127 _useSSL = true;
2128 }
2129 }
2130 else if (String::equalNoCase(vars,USERNAME))
2131 {
2132 vars=String::EMPTY;
2133 vars.append(USERNAME);
2134 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2135 "::UserName specified in config = "<<value<<endl;
2136 if (!_userNameSpecified)
2137 {
2138 _userName = value;
2139 }
2140 }
2141 else if (String::equalNoCase(vars,PASSWORD))
2142 {
2143 s.manicka 1.3.24.2 vars=String::EMPTY;
2144 vars.append(PASSWORD);
2145 if(!_passwordSpecified)
2146 {
2147 _password = value;
2148 }
2149 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2150 "::Password specified in config = "<<value<<endl;
2151 }
2152 else if (String::equalNoCase(vars,DURATION))
2153 {
2154 vars=String::EMPTY;
2155 vars.append(DURATION);
2156 //
2157 // converting to a double
2158 //
2159 if (!IsAClient)
2160 {
2161 _duration = atof(value.getCString());
2162 if (_duration > _MIN_DURATION)
2163 {
2164 s.manicka 1.3.24.2 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2165 "::Duration specified in config = "<<value<<endl;
2166 }
2167 else
2168 {
2169 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2170 "::Invalid Duration was specified. "<<endl;
2171 return false;
2172 }
2173 }
2174 }
2175 else if (String::equalNoCase(vars,TOLERANCELEVEL))
2176 {
2177 _toleranceLevel = atoi(value.getCString());
2178 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2179 "::ToleranceLevel specified in config = "<<value<<endl;
2180 if (_toleranceLevel > _MAX_TOLERANCE)
2181 {
2182 if(verboseEnabled)
2183 {
2184 cout<<StressTestControllerCommand::COMMAND_NAME <<
2185 s.manicka 1.3.24.2 "::Invalid Tolerance level was specified. "<<endl;
2186 }
2187 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2188 "::Invalid Tolerance level was specified. "<<endl;
2189
2190 return false;
2191 }
2192 }
2193 else if (String::equalNoCase(vars,NAMESPACE))
2194 {
2195 _nameSpace = value;
2196 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2197 "::NameSpace specified in config = "<<value<<endl;
2198 }
2199 else if (String::equalNoCase(vars,CLASSNAME))
2200 {
2201 _className = value;
2202 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2203 "::Class name specified in config = "<<value<<endl;
2204 }
2205 else
2206 s.manicka 1.3.24.2 {
2207 if (!IsAClient)
2208 {
2209 IsAClient=true;
2210 int instance = atoi(value.getCString());
2211 //
2212 // Check if the instances are set correctly
2213 // Must be greater than 0
2214 //
2215 if (instance <=0)
2216 {
2217 //
2218 // Invalid Instance value
2219 //
2220 return false;
2221 }
2222 //
2223 // Check if client exists or is valid.
2224 // Clients are expected to be in the $PEGASUS_HOME/bin directory
2225 //
2226 String clientName = String(DEFAULT_BINDIR);
2227 s.manicka 1.3.24.2 clientName.append(vars.getCString());
2228 #ifdef PEGASUS_OS_TYPE_WINDOWS
2229 clientName.append(".exe");
2230 #endif
2231 if (!FileSystem::exists(clientName))
2232 {
2233 String testString = String::EMPTY;
2234 testString.append("Test");
2235 Uint32 Index = vars.find(testString);
2236 if (Index != 0)
2237 {
2238 clientName = String(DEFAULT_BINDIR);
2239 testString.append(vars.getCString());
2240 clientName.append(testString.getCString());
2241 #ifdef PEGASUS_OS_TYPE_WINDOWS
2242 clientName.append(".exe");
2243 #endif
2244 if (!FileSystem::exists(clientName))
2245 {
2246 //
2247 // Invalid client name
2248 s.manicka 1.3.24.2 //
2249 IsValid = false;
2250 }
2251 else
2252 {
2253 IsValid = true;
2254 vars=String::EMPTY;
2255 vars.append(testString.getCString());
2256 }
2257 }
2258 else
2259 {
2260
2261 //
2262 // Invalid client name
2263 //
2264 IsValid = false;
2265 }
2266 }
2267 else
2268 {
2269 s.manicka 1.3.24.2 IsValid = true;
2270 }
2271 if (!IsValid)
2272 {
2273 if (verboseEnabled)
2274 {
2275 cout<<StressTestControllerCommand::COMMAND_NAME <<
2276 "::Invalid Client Name = "<<vars<<endl;
2277 }
2278 String ErrReport = String("Invalid Client Name:");
2279 ErrReport.append(vars.getCString());
2280 throw StressTestControllerException(ErrReport);
2281 }
2282 return IsValid;
2283 }
2284 log_file<<StressTestControllerCommand::COMMAND_NAME<<"::"<<vars<<
2285 " = "<<value<<endl;
2286 //
2287 // otherwise accept the properties listed with the clients.
2288 //
2289 }
2290 s.manicka 1.3.24.2 return true;
2291
2292 } /* _validateConfiguration */
2293
2294 /*
2295 Retrieves the client specific options from the config file.
2296 Will check for syntax errors with the client options.
2297 - Will retrieve all the client options in the line until ']'
2298 - Client options/properties in Config file are
2299 represented as follows:
2300 - "[" indicates start of client options.
2301 - "]" indicates end of client options.
2302 - Client properties and values are seperated by commas.
2303 Example:
2304 [clientName=cimcli,Options=niall]
2305 - This method will throw appropriate exceptions.
2306
2307 @param p The pointer to the char in the concerned line
2308
2309
2310 */
2311 s.manicka 1.3.24.2 void StressTestControllerCommand::_getClientOptions(
2312 const Char16* p,
2313 ostream& log_file)
2314 {
2315 //
2316 // Get the property name
2317 //
2318 String name = String::EMPTY;
2319 String value = String::EMPTY;
2320
2321 while (*p != ']')
2322 {
2323 //
2324 // Skip whitespace after property name
2325 //
2326 while (*p && isspace(*p))
2327 {
2328 p++;
2329 }
2330 if (!(isalpha(*p) || *p == '_'))
2331 {
2332 s.manicka 1.3.24.2 throw StressTestControllerException
2333 (StressTestControllerException::INVALID_OPTION);
2334 }
2335
2336 name.append(*p++);
2337
2338
2339 while (isalnum(*p) || *p == '_')
2340 {
2341 name.append(*p++);
2342 }
2343
2344 //
2345 // Skip whitespace after property name
2346 //
2347 while (*p && isspace(*p))
2348 {
2349 p++;
2350 }
2351
2352 //
2353 s.manicka 1.3.24.2 // Expect an equal sign
2354 //
2355 if (*p != '=')
2356 {
2357 throw StressTestControllerException
2358 (StressTestControllerException::INVALID_OPERATOR);
2359 }
2360
2361 p++;
2362
2363 //
2364 // Skip whitespace after equal sign
2365 //
2366 while (*p && isspace(*p))
2367 {
2368 p++;
2369 }
2370
2371 //
2372 // Get the value
2373 //
2374 s.manicka 1.3.24.2
2375 while (*p && *p != ']' && *p != ',')
2376 {
2377 value.append(*p++);
2378 }
2379 //
2380 // Skip whitespace after value
2381 //
2382 while (*p && isspace(*p))
2383 {
2384 cout << "got space after value\n";
2385 p++;
2386 }
2387
2388 if(*p !=']' && *p != ',')
2389 {
2390 throw StressTestControllerException
2391 (StressTestControllerException::MISSING_BRACE);
2392 }
2393 if(value == String::EMPTY)
2394 {
2395 s.manicka 1.3.24.2 throw StressTestControllerException
2396 (StressTestControllerException::MISSING_VALUE);
2397 }
2398
2399 #ifdef STRESSTEST_DEBUG
2400 cout<<"name="<<name<<endl;
2401 cout<<"Before validate config: value="<<value<<endl;
2402 #endif
2403 //
2404 // validate client property
2405 //
2406 Boolean IsValid=_validateConfiguration(name,value,log_file);
2407 if(!IsValid)
2408 {
2409 String ErrReport = String("Invalid Client property value: ");
2410 ErrReport.append(name);
2411 ErrReport.append("=");
2412 ErrReport.append(value);
2413 throw StressTestControllerException(ErrReport);
2414 }
2415 //
2416 s.manicka 1.3.24.2 // Save client property in client table if valid.
2417 //
2418 if (!_clientTable[_currClientCount].insert(name,value))
2419 {
2420 //
2421 // Duplicate property, ignore the new property value.
2422 // Log this message in a log file.
2423 //
2424 log_file<< "duplicate name already saved: "<<name<<endl;
2425 if (verboseEnabled)
2426 {
2427 cout<< "duplicate name already saved: "<<name<<endl;
2428 }
2429 }
2430 if (*p ==',')
2431 {
2432 name = String::EMPTY;
2433 value = String::EMPTY;
2434 p++;
2435 continue;
2436 }
2437 s.manicka 1.3.24.2 }
2438
2439 if ((name == String::EMPTY)||(value == String::EMPTY))
2440 {
2441 String ErrReport = String("Missing Name & Value for client option:");
2442 throw StressTestControllerException(ErrReport);
2443 }
2444 } /* _getClientOptions */
2445
2446
2447 /*
2448 Retrieves the Client PIDs and the corresponding status of the
2449 clients started by the Controller from the PID file.
2450 Each line in the PID file if not a comment is expected to
2451 have the following format:
2452 <clientid>::<client_pid>::<client_status>::<timeStampInMillisec>
2453 Example:
2454 1::7582::0::4119329327
2455
2456 Client PID, status and Time Stamp from the PID file will be saved
2457 in the following global array's for each client.
2458 s.manicka 1.3.24.2 clientPIDs
2459 clientStatus
2460 clientTimeStamp
2461
2462
2463 @param actual_clients The actual number of clients executed by the
2464 Controller.
2465 @param log_file The log file.
2466
2467 @return true if the status and PIDs were read successfully
2468 false Failed to read the status & PIDs of clients.
2469
2470 */
2471 Boolean StressTestControllerCommand::_getClientPIDs(
2472 int actual_clients,
2473 ostream& log_file)
2474 {
2475
2476 ifstream ifs;
2477
2478 //
2479 s.manicka 1.3.24.2 // Make a temp copy of the file
2480 //
2481 Boolean cTempFile = FileSystem::copyFile(
2482 _stressTestClientPIDFile,
2483 _tmpStressTestClientPIDFile);
2484
2485 if(!cTempFile)
2486 {
2487 cout<<"Cannot copy file "<<_stressTestClientPIDFile<<endl;
2488 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2489 "::Cannot copy PID file: "<<_stressTestClientPIDFile<<endl;
2490 return (false);
2491 }
2492 //
2493 // Open the temp PID file and retreive all the client PIDs and status
2494 //
2495 Open(ifs,_tmpStressTestClientPIDFile);
2496
2497 String line;
2498
2499 const Char16* p;
2500 s.manicka 1.3.24.2 int lineNumber= 0;
2501 Boolean isSuccess=false;
2502 //
2503 // get each line until end of file.
2504 //
2505 while (GetLine(ifs, line))
2506 {
2507 ++lineNumber;
2508 #ifdef STRESSTEST_DEBUG
2509 log_file<<" Line number:"<<lineNumber<<endl;
2510 log_file<<" "<<line<<endl;
2511 #endif
2512 p = line.getChar16Data();
2513
2514 while (*p && isspace(*p))
2515 {
2516 p++;
2517 }
2518
2519 //
2520 // Skip comment lines
2521 s.manicka 1.3.24.2 //
2522 if ((!*p)||(*p == '#'))
2523 {
2524 continue;
2525 }
2526
2527 //
2528 // Get the client ID
2529 //
2530 String client = String::EMPTY;
2531 while (isalnum(*p) || *p == '_')
2532 {
2533 client.append(*p++);
2534 }
2535
2536 //
2537 // Skip whitespace after property name
2538 //
2539 while (*p && isspace(*p))
2540 {
2541 p++;
2542 s.manicka 1.3.24.2 }
2543
2544 //
2545 // Expecting a colon
2546 //
2547 if (*p != ':')
2548 {
2549 ifs.close();
2550 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2551 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2552 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2553 return(isSuccess = false);
2554 }
2555
2556 //
2557 // point to next character in line.
2558 //
2559 p++;
2560
2561 //
2562 // Expecting a colon
2563 s.manicka 1.3.24.2 //
2564 if (*p != ':')
2565 {
2566 ifs.close();
2567 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2568 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2569 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2570 return(isSuccess = false);
2571 }
2572
2573 //
2574 // point to next character in line.
2575 //
2576 p++;
2577
2578 //
2579 // Skip whitespace after colon
2580 //
2581 while (*p && isspace(*p))
2582 {
2583 p++;
2584 s.manicka 1.3.24.2 }
2585
2586 //
2587 // Get the client PID
2588 //
2589 String clntPID = String::EMPTY;
2590 while (isalnum(*p) || *p == '_')
2591 {
2592 clntPID.append(*p++);
2593 }
2594
2595 //
2596 // Skip whitespace after property name
2597 //
2598 while (*p && isspace(*p))
2599 {
2600 p++;
2601 }
2602
2603 //
2604 // Expecting a colon
2605 s.manicka 1.3.24.2 //
2606 if (*p != ':')
2607 {
2608 ifs.close();
2609 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2610 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2611 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2612 return(isSuccess = false);
2613 }
2614
2615 //
2616 // point to next character in line.
2617 //
2618 p++;
2619
2620 //
2621 // Expecting a colon
2622 //
2623 if (*p != ':')
2624 {
2625 ifs.close();
2626 s.manicka 1.3.24.2 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2627 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2628 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2629 return(isSuccess = false);
2630 }
2631 p++;
2632
2633 //
2634 // Skip whitespace after the colon if any
2635 //
2636 while (*p && isspace(*p))
2637 {
2638 p++;
2639 }
2640
2641 String clntStatus = String::EMPTY;
2642 while (isalnum(*p) || *p == '_')
2643 {
2644 clntStatus.append(*p++);
2645 }
2646
2647 s.manicka 1.3.24.2 //
2648 // Skip whitespace after property name
2649 //
2650 while (*p && isspace(*p))
2651 {
2652 p++;
2653 }
2654
2655 //
2656 // Expecting a colon
2657 //
2658 if (*p != ':')
2659 {
2660 ifs.close();
2661 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2662 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2663 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2664 return(isSuccess = false);
2665 }
2666
2667 //
2668 s.manicka 1.3.24.2 // next character in line.
2669 //
2670 p++;
2671
2672 if (*p != ':')
2673 {
2674 ifs.close();
2675 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2676 "::Syntax Error in PID file line number:"<<lineNumber<<endl;
2677 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2678 return(isSuccess = false);
2679 }
2680 //
2681 // next character in line.
2682 //
2683 p++;
2684 //
2685 // Skip whitespace after the colon if any
2686 //
2687 while (*p && isspace(*p))
2688 {
2689 s.manicka 1.3.24.2 p++;
2690 }
2691
2692 //
2693 // Get the client timestamp
2694 //
2695 String clntTmStmp = String::EMPTY;
2696 while (isalnum(*p))
2697 {
2698 clntTmStmp.append(*p++);
2699 }
2700
2701 //
2702 // Store the PID, Status and TimeStamp for each client
2703 //
2704 if(atoi(client.getCString()) <= actual_clients)
2705 {
2706 clientPIDs[atoi(client.getCString())] =
2707 (pid_t)atoi(clntPID.getCString());
2708 clientStatus[atoi(client.getCString())] =
2709 (pid_t)atoi(clntStatus.getCString());
2710 s.manicka 1.3.24.2 sscanf(
2711 (const char*)clntTmStmp.getCString(),
2712 "%" PEGASUS_64BIT_CONVERSION_WIDTH "u",
2713 &clientTimeStamp[atoi(client.getCString())]);
2714 }
2715 else
2716 {
2717 if (verboseEnabled)
2718 {
2719 log_file<<StressTestControllerCommand::COMMAND_NAME<<
2720 "::Unknown client PID for client#"<<
2721 atoi(client.getCString())<<
2722 " read at line number:"<<lineNumber<<endl;
2723 cout<<"Unknown Client PID recieved"<<endl;
2724 }
2725 }
2726 }
2727 //
2728 // remove the temporary file.
2729 //
2730 FileSystem::removeFile(_tmpStressTestClientPIDFile);
2731 s.manicka 1.3.24.2 return(isSuccess = true);
2732 }/* _getClientPIDs */
2733
2734 /*
2735 Parses specified line to retrieve valid config data for the stress tests.
2736 - Identifies client specific properties from common properties in config file
2737 - Saves all the client specific data from the config file into appropriate
2738 client tables.
2739 - Saves all the common properties in the property table
2740 - This method will throw appropriate exceptions.
2741 Config File Format:
2742 - All comments begin with "#"
2743 - Properties in Config file are represented as follows:
2744 <property> = <property value>
2745 - Client options/properties in Config file are
2746 represented as follows:
2747 - "[" indicates start of client options.
2748 - Client properties and values are seperated by commas.
2749 Example:
2750 [clientName=cimcli,Options=niall]
2751
2752 s.manicka 1.3.24.2 @param line The line that will be parsed.
2753 @parm lineNumber The line number of the line.
2754 @parm name The property name that will be retrieved.
2755 @parm value The property value of the name.
2756 @parm log_file The log file.
2757
2758 @return true Succesfully parsed the line.
2759 false Failed to parse the lines successfully.
2760 */
2761 Boolean StressTestControllerCommand::_parseLine(
2762 const String & line,
2763 int lineNumber,
2764 String &name,
2765 String &value,
2766 ostream& log_file)
2767 {
2768
2769 const Char16* p;
2770 p = line.getChar16Data();
2771
2772 //
2773 s.manicka 1.3.24.2 // Skip whitespace
2774 //
2775 while (*p && isspace(*p))
2776 {
2777 p++;
2778 }
2779
2780 //
2781 // Ignore empty lines
2782 //
2783 if (!*p)
2784 {
2785 IgnoreLine = true;
2786 return IgnoreLine;
2787 }
2788
2789 //
2790 // Skip comment lines
2791 //
2792 if (*p == '#')
2793 {
2794 s.manicka 1.3.24.2 IgnoreLine = true;
2795 return IgnoreLine;
2796 }
2797
2798 //
2799 // Retreive all the Client Options
2800 // "[" indicates start of client options.
2801 //
2802 if (*p == '[')
2803 {
2804 IsAClient = true;
2805 IsClientOptions = true;
2806 p++;
2807 //
2808 // Ignore spaces before client property
2809 //
2810 while (*p && isspace(*p))
2811 {
2812 p++;
2813 }
2814 //
2815 s.manicka 1.3.24.2 // Invalid Client property name
2816 //
2817 if (!(isalpha(*p) || *p == '_'))
2818 {
2819 String ErrReport = String("Syntax Error with client options:");
2820 ErrReport.append(line.getCString());
2821 throw StressTestControllerException(ErrReport);
2822 }
2823 //
2824 // Retrieve client options
2825 //
2826 try
2827 {
2828 //
2829 // get and validate client options
2830 //
2831 _getClientOptions(p,log_file);
2832 }
2833 catch (Exception& e)
2834 {
2835 String msg(e.getMessage());
2836 s.manicka 1.3.24.2 if ((name == String::EMPTY)
2837 ||(value == String::EMPTY))
2838 {
2839 msg.append(" in ");
2840 msg.append(line.getCString());
2841 }
2842 throw StressTestControllerException(msg);
2843 }
2844 catch (...)
2845 {
2846 String msg = String(
2847 "Unknown exception caught when geting client options.");
2848 log_file<<StressTestControllerCommand::COMMAND_NAME <<
2849 ":Unknown exception caught when geting client options."<<endl;
2850 cerr<<StressTestControllerCommand::COMMAND_NAME <<
2851 ":Unknown exception caught when geting client options."<<endl;
2852 throw StressTestControllerException(msg);
2853 }
2854
2855 //
2856 // Successfully retrieved all the client options.
2857 s.manicka 1.3.24.2 //
2858 return true;
2859 }
2860
2861 //
2862 // Get Common Properties
2863 //
2864 name = String::EMPTY;
2865
2866 //
2867 // Invalid Common Property name
2868 //
2869 if (!(isalpha(*p) || *p == '_'))
2870 {
2871 String ErrReport = String("Invalid Property Value: ");
2872 ErrReport.append(name);
2873 ErrReport.append("=");
2874 ErrReport.append(value);
2875 throw StressTestControllerException(ErrReport);
2876 }
2877
2878 s.manicka 1.3.24.2 //
2879 // Save the property Name
2880 //
2881 name.append(*p++);
2882 while (isalnum(*p) || *p == '_')
2883 {
2884 name.append(*p++);
2885 }
2886
2887 //
2888 // Skip whitespace after property name
2889 //
2890 while (*p && isspace(*p))
2891 {
2892 p++;
2893 }
2894
2895 //
2896 // Expect an equal sign
2897 //
2898 if (*p != '=')
2899 s.manicka 1.3.24.2 {
2900 String ErrReport = String("Invalid Property Value: ");
2901 ErrReport.append(name);
2902 ErrReport.append("=");
2903 ErrReport.append(value);
2904 throw StressTestControllerException(ErrReport);
2905 }
2906
2907 //
2908 // go to next
2909 //
2910 p++;
2911
2912 //
2913 // Retrive the property value
2914 // Skip whitespace after equal sign
2915 //
2916 while (*p && isspace(*p))
2917 {
2918 p++;
2919 }
2920 s.manicka 1.3.24.2
2921 //
2922 // Get the value
2923 //
2924 value = String::EMPTY;
2925 while (*p)
2926 {
2927 value.append(*p++);
2928 }
2929 #ifdef STRESSTEST_DEBUG
2930 cout<<"name="<<name<<endl;
2931 cout<<"value="<<value<<endl;
2932 #endif
2933 IsAClient = false;
2934 Boolean IsValid = false;
2935 //
2936 // Validate property and its value
2937 //
2938 try
2939 {
2940 IsValid=_validateConfiguration(name,value,log_file);
2941 s.manicka 1.3.24.2 }
2942 catch (Exception& e)
2943 {
2944 String msg(e.getMessage());
2945 throw StressTestControllerException(msg);
2946 }
2947 if (!IsValid)
2948 {
2949 String ErrReport = String("Invalid Property Value: ");
2950 ErrReport.append(name);
2951 ErrReport.append("=");
2952 ErrReport.append(value);
2953 throw StressTestControllerException(ErrReport);
2954 }
2955 return true;
2956 } /* _parseLine */
2957
2958 /*
2959 Storing client details in a table.
2960 - Stores the Client name and instance for specific clients in their
2961 respective client table for later use.
2962 s.manicka 1.3.24.2
2963 @parm name The client name that will be stored.
2964 @parm value The number of instances of the client.
2965
2966 @return true Succesfully stored the name or instance.
2967 false Failed to store the name or instance.
2968 */
2969 Boolean StressTestControllerCommand::_storeClientDetails(
2970 String name,
2971 String value)
2972 {
2973
2974 //
2975 // Expand the client table as required.
2976 //
2977 if (_clientCount >= Total_Clients)
2978 {
2979 Total_Clients += NEW_CLIENTS;
2980 Table* tempClientTable = new Table[Total_Clients];
2981 for (Uint32 i =0;i<_clientCount;i++)
2982 {
2983 s.manicka 1.3.24.2 tempClientTable[i] = _clientTable[i];
2984 }
2985 delete [] _clientTable;
2986 _clientTable = tempClientTable;
2987 }
2988
2989 //
2990 // Store the client Name in the table
2991 //
2992 if (!_clientTable[_clientCount].insert(NAME, name))
2993 {
2994 //
2995 // Duplicate property, ignore the new property value.
2996 //
2997 if (verboseEnabled)
2998 {
2999 cout<< "Duplicate Client already saved: "<<endl;
3000 }
3001 return false;
3002 }
3003
3004 s.manicka 1.3.24.2 //
3005 // Store the number of instances for the client in the table
3006 //
3007 if (!_clientTable[_clientCount].insert(INSTANCE, value))
3008 {
3009
3010 //
3011 // Duplicate property, ignore the new property value.
3012 //
3013 if(verboseEnabled)
3014 {
3015 cout<< "Duplicate Instance already saved: "<<endl;
3016 }
3017 return false;
3018 }
3019 ++_clientCount;
3020 return true;
3021 } /* _storeClientDetails */
3022
3023 /*
3024 Will check the current tolerance level of the running clients with
3025 s.manicka 1.3.24.2 respect to the expected tolerance level.
3026 @parm actual_client The total number of executed clients.
3027 @parm nowMilliseconds The current time in milliseconds.
3028 @parm log_file The log_file.
3029
3030 @return true Clients with tolerance.
3031 false Clients failed tolerance.
3032 */
3033 Boolean StressTestControllerCommand::_checkToleranceLevel(
3034 int actual_client,
3035 Uint64 nowMilliseconds,
3036 ostream& log_file)
3037 {
3038 int count = 0;
3039 int failed_count = 0;
3040 Uint64 lastUpdateinMilliSec =0;
3041 Boolean withinTolerance = false;
3042
3043 for (int i=0;i<actual_client;i++)
3044 {
3045 //
3046 s.manicka 1.3.24.2 //Observe only the status of running clients
3047 //
3048 if (clientActive[i])
3049 {
3050 ++count;
3051 //
3052 // Validate the timestamps:
3053 // The timestamps on the status is compared to the previous
3054 // timestamp to ensure that the status has been updated within
3055 // the previous 2 updates.
3056 //
3057 if(clientStatus[i]== VALID_RESPONSE)
3058 {
3059 //
3060 //check with the last timestamp
3061 //
3062 lastUpdateinMilliSec = nowMilliseconds - clientTimeStamp[i];
3063 //
3064 // Assume failure if status update is
3065 // longer than 2 * checkup interval
3066 //
3067 s.manicka 1.3.24.2 if ((clientTimeStamp[i] == prev_clientTimeStamp[i])
3068 && (lastUpdateinMilliSec >=
3069 (2 * (Uint64)convertmin2millisecs(CHECKUP_INTERVAL))))
3070 {
3071 if (verboseEnabled)
3072 {
3073 log_file <<" Status not updated for client (" <<i<<
3074 ")pid :"<<clientPIDs[i]<<endl;
3075 log_file << " for the past " <<
3076 2*(CHECKUP_INTERVAL) << " minutes." << endl;
3077 cout<<" Status not updated for client ("<<i<<")pid :"<<
3078 clientPIDs[i]<<endl;
3079 cout<<" for the past " << 2*(CHECKUP_INTERVAL)<<
3080 " minutes." << endl;
3081 }
3082 ++failed_count;
3083 }
3084 }
3085 //
3086 // If unknown status - server or client may be hung.
3087 // Two consective failures on the same client will be counted
3088 s.manicka 1.3.24.2 // as a failed client.
3089 //
3090 if (((clientStatus[i]== NO_RESPONSE)
3091 ||(clientStatus[i]== INVALID_RESPONSE))
3092 &&((prev_clientStatus[i]== NO_RESPONSE)
3093 ||(prev_clientStatus[i]== INVALID_RESPONSE)))
3094 {
3095 if (verboseEnabled)
3096 {
3097 if (clientStatus[i]== INVALID_RESPONSE)
3098 {
3099 log_file<<
3100 "Recieved an Invalid response Status from client("<<
3101 i <<") pid :"<<clientPIDs[i]<<endl;
3102 }
3103 else
3104 {
3105 log_file<<"Recieved a no response Status from client("<<
3106 i <<") pid :"<<clientPIDs[i]<<endl;
3107 }
3108 }
3109 s.manicka 1.3.24.2 ++failed_count;
3110 } /* if (((clientStatus[i]== NO_RESPONSE) ... */
3111 //
3112 // Save previous time stamp of client
3113 //
3114 prev_clientTimeStamp[i] = clientTimeStamp[i];
3115 prev_clientStatus[i] = clientStatus[i];
3116 } /* if (clientActive[i]) */
3117 }
3118 //
3119 // check actual tolerance
3120 //
3121 if(count > 0)
3122 {
3123 double curr_tolerancePercent = getToleranceInPercent(
3124 failed_count,
3125 (double)count);
3126 if (verboseEnabled)
3127 {
3128 cout<<" total running clients ="<<count<<endl;
3129 cout<<" failed clients ="<<failed_count<<endl;
3130 s.manicka 1.3.24.2 cout<<"Actual Tolerance % ="<<curr_tolerancePercent<<endl;
3131 cout<<"Expected Tolerance % ="<<_toleranceLevel<<endl;
3132 log_file<<"Total Running clients:"<<count<<endl;
3133 log_file<<"Actual Failed clients:"<<failed_count<<endl;
3134 log_file<<"::Expected Tolerance:"<<_toleranceLevel<<endl;
3135 log_file<<"::Actual Tolerance:"<<curr_tolerancePercent<<endl;
3136 }
3137 if ((double)_toleranceLevel >= curr_tolerancePercent)
3138 {
3139 withinTolerance = true;
3140 }
3141 return(withinTolerance);
3142 }
3143 //
3144 // All process are stopped.
3145 //
3146 return(withinTolerance = true);
3147 } /* _checkToleranceLevel */
3148
3149
3150 /*
3151 s.manicka 1.3.24.2 This will populate the client table with the hard coded
3152 values for the stress tests.
3153 This method is only used if the default configuration
3154 file does not exist.
3155 Default clients are 5 instances of
3156 "TestWrapperStressClient" and "TestModelWalkStressClient".
3157
3158 @parm log_file The log_file.
3159
3160 */
3161 void StressTestControllerCommand::getDefaultClients(ostream& log_file)
3162 {
3163 //
3164 // Setting the client count to default client value
3165 //
3166 _clientCount = DEFAULT_CLIENTS;
3167
3168 log_file << "Populating default configuration for stress Tests." << endl;
3169 if (verboseEnabled)
3170 {
3171 cout << "Populating default configuration for stress Tests." << endl;
3172 s.manicka 1.3.24.2 }
3173 //
3174 // Populating default client attributes
3175 //
3176 for (Uint32 i=0;i<_clientCount; i++)
3177 {
3178 //
3179 // Adding the default instance value to each client table
3180 //
3181 if (!_clientTable[i].insert(INSTANCE, DEFAULT_INSTANCE))
3182 {
3183 log_file << "Duplicate name already saved: "<<INSTANCE<<endl;
3184 if (verboseEnabled)
3185 {
3186 cout<< "duplicate name already saved: "<<INSTANCE<<endl;
3187 }
3188 }
3189 switch(i)
3190 {
3191 case 0:
3192 {
3193 s.manicka 1.3.24.2 if (!_clientTable[i].insert(NAME, MODELWALK_CLIENT))
3194 {
3195 log_file << "Duplicate name already saved: "<<NAME<<endl;
3196 if (verboseEnabled)
3197 {
3198 cout<< "Duplicate name already saved: "<<NAME<<endl;
3199 }
3200 }
3201 log_file << "Stress Test Client Name:"<<MODELWALK_CLIENT<< endl;
3202 if (verboseEnabled)
3203 {
3204 cout<< "Stress Test Client Name:"<<MODELWALK_CLIENT<< endl;
3205 }
3206
3207 break;
3208 }
3209 case 1:
3210 {
3211 if (!_clientTable[i].insert(NAME, WRAPPER_CLIENT))
3212 {
3213 log_file << "Duplicate name already saved: "<<NAME<<endl;
3214 s.manicka 1.3.24.2 if (verboseEnabled)
3215 {
3216 cout<< "Duplicate name already saved: "<<NAME<<endl;
3217 }
3218 }
3219 log_file << "Stress Test Client Name:" <<WRAPPER_CLIENT<< endl;
3220 if (verboseEnabled)
3221 {
3222 cout << "Stress Test Client Name:" <<WRAPPER_CLIENT<< endl;
3223 }
3224 if (!_clientTable[i].insert(CLIENTNAME, "cimcli"))
3225 {
3226 log_file<< "Duplicate name already saved: "<<
3227 CLIENTNAME<<endl;
3228 if (verboseEnabled)
3229 {
3230 cout<< "Duplicate name already saved: "<<
3231 CLIENTNAME<<endl;
3232 }
3233 }
3234 if (!_clientTable[i].insert(OPTIONS, "niall"))
3235 s.manicka 1.3.24.2 {
3236 log_file<< "Duplicate name already saved: "<<OPTIONS<<endl;
3237 if (verboseEnabled)
3238 {
3239 cout<< "Duplicate name already saved: "<<OPTIONS<<endl;
3240 }
3241 }
3242 log_file<< " Client Command & options: cimcli niall"<<
3243 endl;
3244 if (verboseEnabled)
3245 {
3246 cout<< " Client Command & options: cimcli niall"<<
3247 endl;
3248 }
3249 break;
3250 } /* case 1: */
3251 } /* switch(i) */
3252 } /* for(Uint32 i=0;i<_clientCount; i++) */
3253
3254 } /* getDefaultClients */
3255
3256 s.manicka 1.3.24.2
3257
3258
3259 /**
3260 Will generate or create all the required files for the tests.
3261 - Required log files, pid files, client log file are created here.
3262
3263 @parm strTime The time stamp for the tests.
3264 This is used in the naming of the log file.
3265
3266 @return true The files were successfully created.
3267 false Failed to create one or more of the required
3268 files.
3269
3270 */
3271 Boolean StressTestControllerCommand::generateRequiredFileNames(char *strTime)
3272 {
3273 char pid_str[15];
3274 ofstream log_file;
3275 ofstream pid_file;
3276 ofstream clntlog_file;
3277 s.manicka 1.3.24.2
3278 sprintf(pid_str, "%d", getpid());
3279
3280 //
3281 // Stress Controller Log file
3282 //
3283 _stressTestLogFile.append(pegasusHome);
3284 _stressTestLogFile.append(TESTDIR);
3285 FileSystem::makeDirectory(_stressTestLogFile);
3286 _stressTestLogFile.append(STRESSTESTDIR);
3287 FileSystem::makeDirectory(_stressTestLogFile);
3288 _stressTestLogFile.append(LOGDIR);
3289 FileSystem::makeDirectory(_stressTestLogFile);
3290 _stressTestLogFile.append(pid_str);
3291 _stressTestLogFile.append("_stressTest_");
3292 _stressTestLogFile.append(strTime);
3293 _stressTestLogFile.append("log");
3294
3295 //
3296 // StressClient PID file
3297 //
3298 s.manicka 1.3.24.2 _stressTestClientPIDFile.append(pegasusHome);
3299 _stressTestClientPIDFile.append(DEFAULT_TMPDIR);
3300 FileSystem::makeDirectory(_stressTestClientPIDFile);
3301 _stressTestClientPIDFile.append(pid_str);
3302 _stressTestClientPIDFile.append("_StressTestClients");
3303 _stressTestClientPIDFile.append(strTime);
3304 _stressTestClientPIDFile.append("pid");
3305
3306 //
3307 // StressClient Log file
3308 //
3309 _stressTestClientLogFile.append(pegasusHome);
3310 _stressTestClientLogFile.append(DEFAULT_LOGDIR);
3311 _stressTestClientLogFile.append(pid_str);
3312 _stressTestClientLogFile.append("_StressTestClients");
3313 _stressTestClientLogFile.append(".log");
3314
3315 //
3316 // Temporary StressClient PID/status file
3317 //
3318 _tmpStressTestClientPIDFile.append(pegasusHome);
3319 s.manicka 1.3.24.2 _tmpStressTestClientPIDFile.append(DEFAULT_TMPDIR);
3320 _tmpStressTestClientPIDFile.append(pid_str);
3321 _tmpStressTestClientPIDFile.append("TEMP");
3322 _tmpStressTestClientPIDFile.append("_Clients");
3323 _tmpStressTestClientPIDFile.append(".pid");
3324
3325 //
3326 // Translate slashed for appropriate OS
3327 //
3328 FileSystem::translateSlashes(_stressTestClientPIDFile);
3329 FileSystem::translateSlashes(_stressTestClientLogFile);
3330 FileSystem::translateSlashes(_stressTestLogFile);
3331 FileSystem::translateSlashes(_tmpStressTestClientPIDFile);
3332
3333 //
3334 // open the file
3335 //
3336 OpenAppend(log_file,_stressTestLogFile);
3337 Open(pid_file,_stressTestClientPIDFile);
3338 Open(clntlog_file,_stressTestClientLogFile);
3339
3340 s.manicka 1.3.24.2 //
3341 // Failed to open the log file
3342 //
3343 if (!log_file)
3344 {
3345 log_file.close();
3346 pid_file.close();
3347 clntlog_file.close();
3348 cout<<"Cannot get file "<<_stressTestLogFile<<endl;
3349 return false;
3350
3351 }
3352 //
3353 // Failed to open the pid file
3354 //
3355 if (!pid_file)
3356 {
3357 cout<<"Cannot get file "<<_stressTestClientPIDFile<<endl;
3358 log_file<<StressTestControllerCommand::COMMAND_NAME<<
3359 "Cannot read file "<<_stressTestClientPIDFile<<endl;
3360 log_file.close();
3361 s.manicka 1.3.24.2 clntlog_file.close();
3362 return false;
3363 }
3364 //
3365 // Failed to open the clntlog file
3366 //
3367 if (!clntlog_file)
3368 {
3369 log_file<<StressTestControllerCommand::COMMAND_NAME<<
3370 "Cannot read file "<<_stressTestClientLogFile<<endl;
3371 log_file.close();
3372 pid_file.close();
3373 return false;
3374 }
3375
3376 //
3377 // Successfully opened all the files.
3378 //
3379 pid_file<<"#"<<StressTestControllerCommand::COMMAND_NAME<<
3380 " has the following clients:: \n";
3381 clntlog_file<<"#"<<StressTestControllerCommand::COMMAND_NAME<<
3382 s.manicka 1.3.24.2 "::Process ID:"<<getpid()<<endl;
3383 clntlog_file.close();
3384 pid_file.close();
3385 return true;
3386
3387 } /* generateRequiredFileNames */
3388
3389 /**
3390 Will remove all the unused files for the tests.
3391 - Unused log files & pid files are removed here.
3392
3393 */
3394 void StressTestControllerCommand::removeUnusedFiles()
3395 {
3396 FileSystem::removeFile(_stressTestClientPIDFile);
3397 FileSystem::removeFile(_stressTestClientLogFile);
3398 }
3399
3400 PEGASUS_NAMESPACE_END
3401
3402 /**
3403 s.manicka 1.3.24.2 Cleanup function for stressTestController to free allocated
3404 memory used to execute clients.
3405 */
3406 void cleanupProcess()
3407 {
3408
3409 delete [] clientPIDs;
3410 delete [] clientStatus;
3411 delete [] clientInstance;
3412 delete [] clientActive;
3413 delete [] clientTimeStamp;
3414 delete [] prev_clientTimeStamp;
3415 delete [] prev_clientStatus;
3416 }
3417
3418 /*
3419 This will generate the current time.
3420 */
3421 struct tm getCurrentActualTime()
3422 {
3423 struct tm tmTime;
3424 s.manicka 1.3.24.2 time_t inTime=time(NULL);
3425 #ifdef PEGASUS_OS_TYPE_WINDOWS
3426 tmTime=*localtime(&inTime);
3427 #else
3428 localtime_r(&inTime,&tmTime);
3429 #endif
3430 return tmTime;
3431 }
3432
3433 /**
3434 Signal handler for SIGINT, SIGABRT.
3435
3436 @param signum the signal identifier
3437 */
3438 void endAllTests(int signum)
3439 {
3440 if (verboseEnabled)
3441 {
3442 switch(signum)
3443 {
3444 case SIGINT:
3445 s.manicka 1.3.24.2 {
3446 cout<<StressTestControllerCommand::COMMAND_NAME<<
3447 "::Recieved interupt signal SIGINT!"<<endl;
3448 break;
3449 }
3450 case SIGABRT:
3451 {
3452 cout<<StressTestControllerCommand::COMMAND_NAME<<
3453 "::Recieved signal SIGABRT!"<<endl;
3454 break;
3455 }
3456 default:
3457 {
3458 cout<<StressTestControllerCommand::COMMAND_NAME<<
3459 "::Recieved Signal ( "<<signum<<"!" <<endl;
3460 break;
3461 }
3462 }
3463 }
3464 //
3465 // Sets the variable that will interupt stress tests
3466 s.manicka 1.3.24.2 //
3467 Quit = true;
3468 } /* endAllTests */
3469
3470 /**
3471 This function will convert a Uint64
3472 to a string.
3473
3474 @param x The Uint64 integer
3475
3476 @return String Returns the converted string.
3477 */
3478 String convertUint64toString(Uint64 x)
3479 {
3480 char buffer[32];
3481 sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", x);
3482 return(String(buffer));
3483 }/* convertUint64toString(..) */
|