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