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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2