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