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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2