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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2