(file) Return to StressTestController.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / test / StressTestController

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2