1 j.alex 1.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 j.alex 1.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 j.alex 1.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 j.alex 1.2 #endif
65
|
67 j.alex 1.2
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 static String convertUint64toString(Uint64 x);
86
87
88 j.alex 1.2 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 const char StressTestControllerCommand::COMMAND_NAME [] =
107 "TestStressTestController";
108
109 j.alex 1.2
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 static Uint32 DEFAULT_CLIENTS = 2;
128 static Uint32 Total_Clients = DEFAULT_CLIENTS;
129 static Uint32 Total_vClients = DEFAULT_CLIENTS;
130 j.alex 1.2 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 /**
149 Client PID's
150 */
151 j.alex 1.2 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 /**
170 Indicates if client is Active
171 */
172 j.alex 1.2 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 */
191 double StressTestControllerCommand::_duration = 180;
192
193 j.alex 1.2 /**
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 const char StressTestControllerCommand::_OPTION_SSL = 's';
212
213 /**
214 j.alex 1.2 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
233 /**
234 The minimum Duration.
235 j.alex 1.2 */
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 /**
254 The variable used to specify the port number.
255 */
256 j.alex 1.2 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 The variable used to specify the duration of the tests.
275 */
276 static const char DURATION[] = "duration";
277 j.alex 1.2
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 */
296 static const char CLASSNAME[] = "classname";
297
298 j.alex 1.2 /**
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 static const char INSTANCE[] = "INSTANCE";
317
318 /**
319 j.alex 1.2 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
338 static Boolean IsClientOptions = false;
339
340 j.alex 1.2 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 _portNumberStr = buffer;
359
360 _timeout = DEFAULT_TIMEOUT_MILLISECONDS;
361 j.alex 1.2 _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 // Allocate one table to collect all the common properties Thy use AutoPtr
380 //
381 _propertyTable = new Table;
382 j.alex 1.2
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 _stressTestClientPIDFile = String::EMPTY;
401
402 _stressTestClientLogFile = String::EMPTY;
403 j.alex 1.2
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 _usage.append (_OPTION_PASSWORD);
422 _usage.append (" password ]");
423 #endif
424 j.alex 1.2 _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 _usage.append(" username\n");
443 _usage.append(" --version - Display CIM Server version number\n");
444 _usage.append(" --verbose - Display verbose information\n");
445 j.alex 1.2 _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 @param argv the string vector of command line arguments
464
465 @exception CommandFormatException if an error is encountered in parsing
466 j.alex 1.2 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 //
485 // opens the log file
486 //
487 j.alex 1.2 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 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
506 GetOptString.append (_OPTION_PORTNUMBER);
507 GetOptString.append (getoopt::GETOPT_ARGUMENT_DESIGNATOR);
508 j.alex 1.2 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
527 getOpts.parse (argc, argv);
528
529 j.alex 1.2 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 else if (getOpts[i].getopt() == LONG_VERSION)
548 {
549 _operationType = OPERATION_TYPE_VERSION;
550 j.alex 1.2 }
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 log_file.close();
569 UnexpectedArgumentException e(getOpts[i].Value());
570 throw e;
571 j.alex 1.2 }
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 throw e;
590 }
591 _hostName = getOpts [i].Value ();
592 j.alex 1.2 _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 // More than one portNumber option was found
611 //
612 log_file.close();
613 j.alex 1.2 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 {
632 if(verboseEnabled)
633 {
634 j.alex 1.2 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 {
653 if(verboseEnabled)
654 {
655 j.alex 1.2 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 {
674 if (getOpts.isSet(_OPTION_USERNAME) > 1)
675 {
676 j.alex 1.2 //
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 break;
695 }
696 case _OPTION_PASSWORD:
697 j.alex 1.2 {
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 "password"<<endl;
716 }
717 }
718 j.alex 1.2 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 }
737 }
738 //
739 j.alex 1.2 // 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 log_file.close();
758 } /* setCommand */
759
760 j.alex 1.2 /**
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 String client_command = String::EMPTY;
779 double duration = _duration;
780 double delay = 0;
781 j.alex 1.2
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 //
800 // Stress Client Name must exist for each client/client table
801 //
802 j.alex 1.2 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 client_command.append(" -hostname ");
821 if (_hostNameSpecified)
822 {
823 j.alex 1.2 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 if (_portNumberSpecified)
842 {
843 client_command.append(_portNumberStr);
844 j.alex 1.2 }
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 else if (String::equalNoCase(i.key(),PASSWORD))
863 {
864 client_command.append(" -");
865 j.alex 1.2 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 else if (String::equalNoCase(i.key(),NAMESPACE))
884 {
885 client_command.append(" -");
886 j.alex 1.2 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 //
905 }
906 else
907 j.alex 1.2 {
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 //
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 j.alex 1.2 // 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 && (!String::equalNoCase(k.key(),CLIENTWAIT))
947 && (!String::equalNoCase(k.key(),DURATION)))
948 {
949 j.alex 1.2 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 }
968 else
969 {
970 j.alex 1.2 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 delay = atof(k.value().getCString());
989 }
990 }
991 j.alex 1.2
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 log_file<<j<<"]"<<endl;
1010 log_file<<" "<<_clientCommands[j]<<endl;
1011 log_file<<" Client Duration: "<<
1012 j.alex 1.2 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 } /* for(Uint32 j=0; j< _clientCount; j++) */
1031 return true;
1032 } /* generateClientCommands */
1033 j.alex 1.2
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 written
1052
1053 @return 0 if the command is successful
1054 j.alex 1.2 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 String act_command = String::EMPTY;
1073 Boolean TestFailed = false;
1074 char str[15];
1075 j.alex 1.2 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 if (!log_file)
1094 {
1095 log_file.close();
1096 j.alex 1.2 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 // No need for the client pid and log file.
1115 //
1116 FileSystem::removeFile(_stressTestClientPIDFile);
1117 j.alex 1.2 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 return (RC_SUCCESS);
1136 }
1137
1138 j.alex 1.2 //
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 else
1157 {
1158 errPrintWriter << "Stress Tests must have at least one Client." << endl;
1159 j.alex 1.2 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 //
1178 startMilliseconds = TimeValue::getCurrentTime().toMilliseconds();
1179 nowMilliseconds = startMilliseconds;
1180 j.alex 1.2 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 outPrintWriter<<" Start Time in milliseconds: "<<
1199 convertUint64toString(startMilliseconds)<<endl;
1200 outPrintWriter<<" Total duration in milliseconds: "<<
1201 j.alex 1.2 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
1220 //
1221 // Small delay in the while loop seemed to reduce the CPU usage
1222 j.alex 1.2 // 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 }
1241 //
1242 // The following block will be where clients are executed initially.
1243 j.alex 1.2 //
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 ErrReport.append(clientInst);
1262 throw StressTestControllerException(ErrReport);
1263 }
1264 j.alex 1.2 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 convertUint64toString(clientStartMilliseconds[j])<<
1283 endl;
1284 outPrintWriter<<"ClientStop:"<<
1285 j.alex 1.2 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 {
1304 outPrintWriter<<
1305 "Number of instances of this client:"<<
1306 j.alex 1.2 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 #endif
1325 //
1326 // Adding all the required parameters for the command.
1327 j.alex 1.2 //
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 strftime(
1346 strTime,
1347 256,
1348 j.alex 1.2 "%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 if (rc)
1367 {
1368 log_file<<"Command failed to Execute."<<endl;
1369 j.alex 1.2 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 clientStatus = new int[actual_client];
1388 prev_clientStatus = new int[actual_client];
1389 clientTimeStamp = new Uint64[actual_client];
1390 j.alex 1.2 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 int rc = _getClientPIDs(actual_client,log_file);
1409 if (!rc)
1410 {
1411 j.alex 1.2 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 */
1430
1431 //
1432 j.alex 1.2 // 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 (Uint64)convertmin2millisecs(CHECKUP_INTERVAL) +
1451 nowMilliseconds;
1452 //
1453 j.alex 1.2 // 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 //
1472 if (verboseEnabled)
1473 {
1474 j.alex 1.2 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 //
1493 Boolean withinTolerance = _checkToleranceLevel(
1494 actual_client,
1495 j.alex 1.2 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 if (verboseEnabled)
1514 {
1515 outPrintWriter<<
1516 j.alex 1.2 " ********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 if (!clientStopped[clientID])
1535 {
1536 //
1537 j.alex 1.2 // 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 clientPIDs[clientID+instanceID]<<endl;
1556 if (verboseEnabled)
1557 {
1558 j.alex 1.2 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 // Required for Windows
1577 //
1578 ofstream stop_file(
1579 j.alex 1.2 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 //
1598 // Set the client as inactive.
1599 //
1600 j.alex 1.2 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 {
1619 //
1620 // Only restart clients that are waiting.
1621 j.alex 1.2 //
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 act_command.append("start ");
1640 #endif
1641 act_command.append(
1642 j.alex 1.2 _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 {
1661 outPrintWriter<<" "<<act_command<<endl;
1662 log_file<<" ("<<
1663 j.alex 1.2 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 outPrintWriter<<act_command<<
1682 "Command failed to Execute."<<
1683 endl;
1684 j.alex 1.2 }
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
1703 } /* while(stopMilliseconds > nowMilliseconds) */
1704
1705 j.alex 1.2 }//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
1724 #ifndef PEGASUS_OS_TYPE_WINDOWS
1725 sleep(STOP_DELAY);
1726 j.alex 1.2 #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 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 j.alex 1.2 {
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 stop_file.close();
1766 #ifndef PEGASUS_OS_TYPE_WINDOWS
1767 // Another way to stop the client
1768 j.alex 1.2 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
1787 //
1788 // Waiting to allow clients to shutdown
1789 j.alex 1.2 //
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 values from either the default config file
1808
1809 @param fileName The specified or default config file for the
1810 j.alex 1.2 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
1829 ifstream ifs;
1830
1831 j.alex 1.2 //
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 //
1850 // Get each line of the file.
1851 //
1852 j.alex 1.2 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 catch (Exception& e)
1871 {
1872 char line_num[10];
1873 j.alex 1.2 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 ErrReports.append(":: ");
1892 ErrReports.append("Unknown exception caught.");
1893 log_file<<StressTestControllerCommand::COMMAND_NAME<<
1894 j.alex 1.2 ":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 _currClientCount=_clientCount;
1913 //
1914 // save the client details in a table
1915 j.alex 1.2 //
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 //
1934 if (verboseEnabled)
1935 {
1936 j.alex 1.2 cout<<" "<<name<<"\t= "<<value<<endl;
1937 }
1938 if (!_propertyTable->insert(name, value))
1939 {
1940 //
1941 // Duplicate property, ignore the new property value.
1942 //
|
2926 j.alex 1.2 cout<<"name="<<name<<endl;
2927 cout<<"value="<<value<<endl;
2928 #endif
2929 IsAClient = false;
2930 Boolean IsValid = false;
2931 //
2932 // Validate property and its value
2933 //
2934 try
2935 {
2936 IsValid=_validateConfiguration(name,value,log_file);
2937 }
2938 catch (Exception& e)
2939 {
2940 String msg(e.getMessage());
2941 throw StressTestControllerException(msg);
2942 }
2943 if (!IsValid)
2944 {
2945 String ErrReport = String("Invalid Property Value: ");
2946 ErrReport.append(name);
2947 j.alex 1.2 ErrReport.append("=");
2948 ErrReport.append(value);
2949 throw StressTestControllerException(ErrReport);
2950 }
2951 return true;
2952 } /* _parseLine */
2953
2954 /*
2955 Storing client details in a table.
2956 - Stores the Client name and instance for specific clients in their
2957 respective client table for later use.
2958
2959 @parm name The client name that will be stored.
2960 @parm value The number of instances of the client.
2961
2962 @return true Succesfully stored the name or instance.
2963 false Failed to store the name or instance.
2964 */
2965 Boolean StressTestControllerCommand::_storeClientDetails(
2966 String name,
2967 String value)
2968 j.alex 1.2 {
2969
2970 //
2971 // Expand the client table as required.
2972 //
2973 if (_clientCount >= Total_Clients)
2974 {
2975 Total_Clients += NEW_CLIENTS;
2976 Table* tempClientTable = new Table[Total_Clients];
2977 for (Uint32 i =0;i<_clientCount;i++)
2978 {
2979 tempClientTable[i] = _clientTable[i];
2980 }
2981 delete [] _clientTable;
2982 _clientTable = tempClientTable;
2983 }
2984
2985 //
2986 // Store the client Name in the table
2987 //
2988 if (!_clientTable[_clientCount].insert(NAME, name))
2989 j.alex 1.2 {
2990 //
2991 // Duplicate property, ignore the new property value.
2992 //
2993 if (verboseEnabled)
2994 {
2995 cout<< "Duplicate Client already saved: "<<endl;
2996 }
2997 return false;
2998 }
2999
3000 //
3001 // Store the number of instances for the client in the table
3002 //
3003 if (!_clientTable[_clientCount].insert(INSTANCE, value))
3004 {
3005
3006 //
3007 // Duplicate property, ignore the new property value.
3008 //
3009 if(verboseEnabled)
3010 j.alex 1.2 {
3011 cout<< "Duplicate Instance already saved: "<<endl;
3012 }
3013 return false;
3014 }
3015 ++_clientCount;
3016 return true;
3017 } /* _storeClientDetails */
3018
3019 /*
3020 Will check the current tolerance level of the running clients with
3021 respect to the expected tolerance level.
3022 @parm actual_client The total number of executed clients.
3023 @parm nowMilliseconds The current time in milliseconds.
3024 @parm log_file The log_file.
3025
3026 @return true Clients with tolerance.
3027 false Clients failed tolerance.
3028 */
3029 Boolean StressTestControllerCommand::_checkToleranceLevel(
3030 int actual_client,
3031 j.alex 1.2 Uint64 nowMilliseconds,
3032 ostream& log_file)
3033 {
3034 int count = 0;
3035 int failed_count = 0;
3036 Uint64 lastUpdateinMilliSec =0;
3037 Boolean withinTolerance = false;
3038
3039 for (int i=0;i<actual_client;i++)
3040 {
3041 //
3042 //Observe only the status of running clients
3043 //
3044 if (clientActive[i])
3045 {
3046 ++count;
3047 //
3048 // Validate the timestamps:
3049 // The timestamps on the status is compared to the previous
3050 // timestamp to ensure that the status has been updated within
3051 // the previous 2 updates.
3052 j.alex 1.2 //
3053 if(clientStatus[i]== VALID_RESPONSE)
3054 {
3055 //
3056 //check with the last timestamp
3057 //
3058 lastUpdateinMilliSec = nowMilliseconds - clientTimeStamp[i];
3059 //
3060 // Assume failure if status update is
3061 // longer than 2 * checkup interval
3062 //
3063 if ((clientTimeStamp[i] == prev_clientTimeStamp[i])
3064 && (lastUpdateinMilliSec >=
3065 (2 * (Uint64)convertmin2millisecs(CHECKUP_INTERVAL))))
3066 {
3067 if (verboseEnabled)
3068 {
3069 log_file <<" Status not updated for client (" <<i<<
3070 ")pid :"<<clientPIDs[i]<<endl;
3071 log_file << " for the past " <<
3072 2*(CHECKUP_INTERVAL) << " minutes." << endl;
3073 j.alex 1.2 cout<<" Status not updated for client ("<<i<<")pid :"<<
3074 clientPIDs[i]<<endl;
3075 cout<<" for the past " << 2*(CHECKUP_INTERVAL)<<
3076 " minutes." << endl;
3077 }
3078 ++failed_count;
3079 }
3080 }
3081 //
3082 // If unknown status - server or client may be hung.
3083 // Two consective failures on the same client will be counted
3084 // as a failed client.
3085 //
3086 if (((clientStatus[i]== NO_RESPONSE)
3087 ||(clientStatus[i]== INVALID_RESPONSE))
3088 &&((prev_clientStatus[i]== NO_RESPONSE)
3089 ||(prev_clientStatus[i]== INVALID_RESPONSE)))
3090 {
3091 if (verboseEnabled)
3092 {
3093 if (clientStatus[i]== INVALID_RESPONSE)
3094 j.alex 1.2 {
3095 log_file<<
3096 "Recieved an Invalid response Status from client("<<
3097 i <<") pid :"<<clientPIDs[i]<<endl;
3098 }
3099 else
3100 {
3101 log_file<<"Recieved a no response Status from client("<<
3102 i <<") pid :"<<clientPIDs[i]<<endl;
3103 }
3104 }
3105 ++failed_count;
3106 } /* if (((clientStatus[i]== NO_RESPONSE) ... */
3107 //
3108 // Save previous time stamp of client
3109 //
3110 prev_clientTimeStamp[i] = clientTimeStamp[i];
3111 prev_clientStatus[i] = clientStatus[i];
3112 } /* if (clientActive[i]) */
3113 }
3114 //
3115 j.alex 1.2 // check actual tolerance
3116 //
3117 if(count > 0)
3118 {
3119 double curr_tolerancePercent = getToleranceInPercent(
3120 failed_count,
3121 (double)count);
3122 if (verboseEnabled)
3123 {
3124 cout<<" total running clients ="<<count<<endl;
3125 cout<<" failed clients ="<<failed_count<<endl;
3126 cout<<"Actual Tolerance % ="<<curr_tolerancePercent<<endl;
3127 cout<<"Expected Tolerance % ="<<_toleranceLevel<<endl;
3128 log_file<<"Total Running clients:"<<count<<endl;
3129 log_file<<"Actual Failed clients:"<<failed_count<<endl;
3130 log_file<<"::Expected Tolerance:"<<_toleranceLevel<<endl;
3131 log_file<<"::Actual Tolerance:"<<curr_tolerancePercent<<endl;
3132 }
3133 if ((double)_toleranceLevel >= curr_tolerancePercent)
3134 {
3135 withinTolerance = true;
3136 j.alex 1.2 }
3137 return(withinTolerance);
3138 }
3139 //
3140 // All process are stopped.
3141 //
3142 return(withinTolerance = true);
3143 } /* _checkToleranceLevel */
3144
3145
3146 /*
3147 This will populate the client table with the hard coded
3148 values for the stress tests.
3149 This method is only used if the default configuration
3150 file does not exist.
3151 Default clients are 5 instances of
3152 "TestWrapperStressClient" and "TestModelWalkStressClient".
3153
3154 @parm log_file The log_file.
3155
3156 */
3157 j.alex 1.2 void StressTestControllerCommand::getDefaultClients(ostream& log_file)
3158 {
3159 //
3160 // Setting the client count to default client value
3161 //
3162 _clientCount = DEFAULT_CLIENTS;
3163
3164 log_file << "Populating default configuration for stress Tests." << endl;
3165 if (verboseEnabled)
3166 {
3167 cout << "Populating default configuration for stress Tests." << endl;
3168 }
3169 //
3170 // Populating default client attributes
3171 //
3172 for (Uint32 i=0;i<_clientCount; i++)
3173 {
3174 //
3175 // Adding the default instance value to each client table
3176 //
3177 if (!_clientTable[i].insert(INSTANCE, DEFAULT_INSTANCE))
3178 j.alex 1.2 {
3179 log_file << "Duplicate name already saved: "<<INSTANCE<<endl;
3180 if (verboseEnabled)
3181 {
3182 cout<< "duplicate name already saved: "<<INSTANCE<<endl;
3183 }
3184 }
3185 switch(i)
3186 {
3187 case 0:
3188 {
3189 if (!_clientTable[i].insert(NAME, MODELWALK_CLIENT))
3190 {
3191 log_file << "Duplicate name already saved: "<<NAME<<endl;
3192 if (verboseEnabled)
3193 {
3194 cout<< "Duplicate name already saved: "<<NAME<<endl;
3195 }
3196 }
3197 log_file << "Stress Test Client Name:"<<MODELWALK_CLIENT<< endl;
3198 if (verboseEnabled)
3199 j.alex 1.2 {
3200 cout<< "Stress Test Client Name:"<<MODELWALK_CLIENT<< endl;
3201 }
3202
3203 break;
3204 }
3205 case 1:
3206 {
3207 if (!_clientTable[i].insert(NAME, WRAPPER_CLIENT))
3208 {
3209 log_file << "Duplicate name already saved: "<<NAME<<endl;
3210 if (verboseEnabled)
3211 {
3212 cout<< "Duplicate name already saved: "<<NAME<<endl;
3213 }
3214 }
3215 log_file << "Stress Test Client Name:" <<WRAPPER_CLIENT<< endl;
3216 if (verboseEnabled)
3217 {
3218 cout << "Stress Test Client Name:" <<WRAPPER_CLIENT<< endl;
3219 }
3220 j.alex 1.2 if (!_clientTable[i].insert(CLIENTNAME, "CLI"))
3221 {
3222 log_file<< "Duplicate name already saved: "<<
3223 CLIENTNAME<<endl;
3224 if (verboseEnabled)
3225 {
3226 cout<< "Duplicate name already saved: "<<
3227 CLIENTNAME<<endl;
3228 }
3229 }
3230 if (!_clientTable[i].insert(OPTIONS, "niall"))
3231 {
3232 log_file<< "Duplicate name already saved: "<<OPTIONS<<endl;
3233 if (verboseEnabled)
3234 {
3235 cout<< "Duplicate name already saved: "<<OPTIONS<<endl;
3236 }
3237 }
3238 log_file<< " Client Command & options: CLI niall"<<
3239 endl;
3240 if (verboseEnabled)
3241 j.alex 1.2 {
3242 cout<< " Client Command & options: CLI niall"<<
3243 endl;
3244 }
3245 break;
3246 } /* case 1: */
3247 } /* switch(i) */
3248 } /* for(Uint32 i=0;i<_clientCount; i++) */
3249
3250 } /* getDefaultClients */
3251
3252
3253
3254
3255 /**
3256 Will generate or create all the required files for the tests.
3257 - Required log files, pid files, client log file are created here.
3258
3259 @parm strTime The time stamp for the tests.
3260 This is used in the naming of the log file.
3261
3262 j.alex 1.2 @return true The files were successfully created.
3263 false Failed to create one or more of the required
3264 files.
3265
3266 */
3267 Boolean StressTestControllerCommand::generateRequiredFileNames(char *strTime)
3268 {
3269 char pid_str[15];
3270 ofstream log_file;
3271 ofstream pid_file;
3272 ofstream clntlog_file;
3273
3274 sprintf(pid_str, "%d", getpid());
3275
3276 //
3277 // Stress Controller Log file
3278 //
3279 _stressTestLogFile.append(pegasusHome);
3280 _stressTestLogFile.append(TESTDIR);
3281 FileSystem::makeDirectory(_stressTestLogFile);
3282 _stressTestLogFile.append(STRESSTESTDIR);
3283 j.alex 1.2 FileSystem::makeDirectory(_stressTestLogFile);
3284 _stressTestLogFile.append(LOGDIR);
3285 FileSystem::makeDirectory(_stressTestLogFile);
3286 _stressTestLogFile.append(pid_str);
3287 _stressTestLogFile.append("_stressTest_");
3288 _stressTestLogFile.append(strTime);
3289 _stressTestLogFile.append("log");
3290
3291 //
3292 // StressClient PID file
3293 //
3294 _stressTestClientPIDFile.append(pegasusHome);
3295 _stressTestClientPIDFile.append(DEFAULT_TMPDIR);
3296 FileSystem::makeDirectory(_stressTestClientPIDFile);
3297 _stressTestClientPIDFile.append(pid_str);
3298 _stressTestClientPIDFile.append("_StressTestClients");
3299 _stressTestClientPIDFile.append(strTime);
3300 _stressTestClientPIDFile.append("pid");
3301
3302 //
3303 // StressClient Log file
3304 j.alex 1.2 //
3305 _stressTestClientLogFile.append(pegasusHome);
3306 _stressTestClientLogFile.append(DEFAULT_LOGDIR);
3307 _stressTestClientLogFile.append(pid_str);
3308 _stressTestClientLogFile.append("_StressTestClients");
3309 _stressTestClientLogFile.append(".log");
3310
3311 //
3312 // Temporary StressClient PID/status file
3313 //
3314 _tmpStressTestClientPIDFile.append(pegasusHome);
3315 _tmpStressTestClientPIDFile.append(DEFAULT_TMPDIR);
3316 _tmpStressTestClientPIDFile.append(pid_str);
3317 _tmpStressTestClientPIDFile.append("TEMP");
3318 _tmpStressTestClientPIDFile.append("_Clients");
3319 _tmpStressTestClientPIDFile.append(".pid");
3320
3321 //
3322 // Translate slashed for appropriate OS
3323 //
3324 FileSystem::translateSlashes(_stressTestClientPIDFile);
3325 j.alex 1.2 FileSystem::translateSlashes(_stressTestClientLogFile);
3326 FileSystem::translateSlashes(_stressTestLogFile);
3327 FileSystem::translateSlashes(_tmpStressTestClientPIDFile);
3328
3329 //
3330 // open the file
3331 //
3332 OpenAppend(log_file,_stressTestLogFile);
3333 Open(pid_file,_stressTestClientPIDFile);
3334 Open(clntlog_file,_stressTestClientLogFile);
3335
3336 //
3337 // Failed to open the log file
3338 //
3339 if (!log_file)
3340 {
3341 log_file.close();
3342 pid_file.close();
3343 clntlog_file.close();
3344 cout<<"Cannot get file "<<_stressTestLogFile<<endl;
3345 return false;
3346 j.alex 1.2
3347 }
3348 //
3349 // Failed to open the pid file
3350 //
3351 if (!pid_file)
3352 {
3353 cout<<"Cannot get file "<<_stressTestClientPIDFile<<endl;
3354 log_file<<StressTestControllerCommand::COMMAND_NAME<<
3355 "Cannot read file "<<_stressTestClientPIDFile<<endl;
3356 log_file.close();
3357 clntlog_file.close();
3358 return false;
3359 }
3360 //
3361 // Failed to open the clntlog file
3362 //
3363 if (!clntlog_file)
3364 {
3365 log_file<<StressTestControllerCommand::COMMAND_NAME<<
3366 "Cannot read file "<<_stressTestClientLogFile<<endl;
3367 j.alex 1.2 log_file.close();
3368 pid_file.close();
3369 return false;
3370 }
3371
3372 //
3373 // Successfully opened all the files.
3374 //
3375 pid_file<<"#"<<StressTestControllerCommand::COMMAND_NAME<<
3376 " has the following clients:: \n";
3377 clntlog_file<<"#"<<StressTestControllerCommand::COMMAND_NAME<<
3378 "::Process ID:"<<getpid()<<endl;
3379 clntlog_file.close();
3380 pid_file.close();
3381 return true;
3382
3383 } /* generateRequiredFileNames */
3384
3385 /**
3386 Will remove all the unused files for the tests.
3387 - Unused log files & pid files are removed here.
3388 j.alex 1.2
3389 */
3390 void StressTestControllerCommand::removeUnusedFiles()
3391 {
3392 FileSystem::removeFile(_stressTestClientPIDFile);
3393 FileSystem::removeFile(_stressTestClientLogFile);
3394 }
3395
3396 PEGASUS_NAMESPACE_END
3397
3398 /**
3399 Cleanup function for stressTestController to free allocated
3400 memory used to execute clients.
3401 */
3402 void cleanupProcess()
3403 {
3404
3405 delete [] clientPIDs;
3406 delete [] clientStatus;
3407 delete [] clientInstance;
3408 delete [] clientActive;
3409 j.alex 1.2 delete [] clientTimeStamp;
3410 delete [] prev_clientTimeStamp;
3411 delete [] prev_clientStatus;
3412 }
3413
3414 /*
3415 This will generate the current time.
3416 */
3417 struct tm getCurrentActualTime()
3418 {
3419 struct tm tmTime;
3420 time_t inTime=time(NULL);
3421 #ifdef PEGASUS_OS_TYPE_WINDOWS
3422 tmTime=*localtime(&inTime);
3423 #else
3424 localtime_r(&inTime,&tmTime);
3425 #endif
3426 return tmTime;
3427 }
3428
3429 /**
3430 j.alex 1.2 Signal handler for SIGINT, SIGABRT.
3431
3432 @param signum the signal identifier
3433 */
3434 void endAllTests(int signum)
3435 {
3436 if (verboseEnabled)
3437 {
3438 switch(signum)
3439 {
3440 case SIGINT:
3441 {
3442 cout<<StressTestControllerCommand::COMMAND_NAME<<
3443 "::Recieved interupt signal SIGINT!"<<endl;
3444 break;
3445 }
3446 case SIGABRT:
3447 {
3448 cout<<StressTestControllerCommand::COMMAND_NAME<<
3449 "::Recieved signal SIGABRT!"<<endl;
3450 break;
3451 j.alex 1.2 }
3452 default:
3453 {
3454 cout<<StressTestControllerCommand::COMMAND_NAME<<
3455 "::Recieved Signal ( "<<signum<<"!" <<endl;
3456 break;
3457 }
3458 }
3459 }
3460 //
3461 // Sets the variable that will interupt stress tests
3462 //
3463 Quit = true;
3464 } /* endAllTests */
3465
3466 /**
3467 This function will convert a Uint64
3468 to a string.
3469
3470 @param x The Uint64 integer
3471
3472 j.alex 1.2 @return String Returns the converted string.
3473 */
3474 String convertUint64toString(Uint64 x)
3475 {
3476 char buffer[32];
3477 sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", x);
3478 return(String(buffer));
3479 }/* convertUint64toString(..) */
|