stif/TestServer/src/Testserversession.cpp
changeset 0 a03f92240627
child 7 8a14024f954a
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description: This module contains implementation of CTestServer 
       
    15 * class member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32std.h>
       
    21 #include <e32svr.h>
       
    22 #include "TestEngineClient.h"
       
    23 #include <StifTestModule.h>
       
    24 #include <stifinternal/TestServerClient.h>
       
    25 #include "TestServer.h"
       
    26 #include "TestServerCommon.h"
       
    27 #include "TestServerModuleIf.h"
       
    28 
       
    29 // EXTERNAL DATA STRUCTURES
       
    30 
       
    31 // EXTERNAL FUNCTION PROTOTYPES  
       
    32 
       
    33 // CONSTANTS
       
    34 
       
    35 // MACROS
       
    36 
       
    37 // LOCAL CONSTANTS AND MACROS
       
    38 
       
    39 // MODULE DATA STRUCTURES
       
    40 // Struct to pass parameters to server thread
       
    41 struct TThreadStartTestServerSession
       
    42     {
       
    43     RThread    iServerThread; // The server thread
       
    44     RSemaphore iStarted;      // Startup syncronisation semaphore   
       
    45     TInt       iStartupResult;// Start-up result
       
    46     };
       
    47 
       
    48 // LOCAL FUNCTION PROTOTYPES
       
    49 
       
    50 // FORWARD DECLARATIONS
       
    51 
       
    52 // ==================== LOCAL FUNCTIONS =======================================
       
    53 
       
    54 // None
       
    55 
       
    56 // ================= MEMBER FUNCTIONS =========================================
       
    57 
       
    58 
       
    59 /*
       
    60 -------------------------------------------------------------------------------
       
    61 
       
    62     Class: CTestModule
       
    63 
       
    64     Method: NewL
       
    65 
       
    66     Description: Create new Test Module    
       
    67 
       
    68     Parameters: RThread& aClient              :in:  Handle to client
       
    69                 CTestServer* aServer          :in:  Pointer to server
       
    70 
       
    71     Return Values: CTestModule*                     Pointer to new test module
       
    72 
       
    73     Errors/Exceptions: Leaves if memory allocation fails or ConstructL leaves.
       
    74 
       
    75     Status: Approved
       
    76 
       
    77 -------------------------------------------------------------------------------
       
    78 */
       
    79 CTestModule* CTestModule::NewL( CTestServer* aServer )
       
    80     {
       
    81 
       
    82     CTestModule* self=new( ELeave ) CTestModule();
       
    83     CleanupStack::PushL( self );
       
    84     self->ConstructL( aServer );
       
    85     CleanupStack::Pop();
       
    86     return self;
       
    87     }
       
    88 
       
    89 /*
       
    90 -------------------------------------------------------------------------------
       
    91 
       
    92     Class: CTestModule
       
    93 
       
    94     Method: CTestModule
       
    95 
       
    96     Description: Constructor.
       
    97     Initialise base class.
       
    98 
       
    99     Parameters: RThread& aClient              :in:  Handle to client
       
   100 
       
   101     Return Values: None
       
   102 
       
   103     Errors/Exceptions: None
       
   104 
       
   105     Status: Approved
       
   106 
       
   107 -------------------------------------------------------------------------------
       
   108 */
       
   109 CTestModule::CTestModule() :
       
   110     CSession2(),
       
   111     iIni(0, 0)
       
   112     {
       
   113     }
       
   114 
       
   115 /*
       
   116 -------------------------------------------------------------------------------
       
   117 
       
   118     Class: CTestModule
       
   119 
       
   120     Method: ~CTestModule
       
   121 
       
   122     Description: Destructor.
       
   123     Deallocate memory and close handles.
       
   124 
       
   125     Parameters: None
       
   126 
       
   127     Return Values: None
       
   128 
       
   129     Errors/Exceptions: None.
       
   130 
       
   131     Status: Proposal
       
   132 
       
   133 -------------------------------------------------------------------------------
       
   134 */
       
   135 CTestModule::~CTestModule()
       
   136     {
       
   137 
       
   138     __TRACE( KVerbose, ( _L( "Closing test module" ) ) );
       
   139         
       
   140     // Free test case related data. No error checking here, because if freeing
       
   141     // fails, then nothing can be done in destructor.
       
   142     FreeCaseData();
       
   143 
       
   144     // Delete all test module instances.
       
   145     // Cleanup all RTestExecution has been opened by client but not properly
       
   146     // closed for example if timeout occurs and client died. This almost do
       
   147     // same than CloseSession() in "if( iTestExecutionHandle )" branch.
       
   148     if( iTestExecutionHandle )
       
   149         {
       
   150         TInt handle = 0;
       
   151         CObject* theObj = NULL;
       
   152         TInt count = iTestExecutionHandle->Count();
       
   153 
       
   154         for( TInt i = 0 ; i < count; i++ )
       
   155             {
       
   156             // Get pointer to CTestExecution
       
   157             theObj=iTestExecutionHandle->operator[]( i );
       
   158             if( theObj )
       
   159                 {
       
   160                 handle=iTestExecutionHandle->At( theObj );
       
   161 
       
   162                 CTestExecution* testcase = (CTestExecution*) theObj;
       
   163                 // Cancels test(s) execution(timeout, exit, etc)
       
   164                 // For example TestCombiner is timeouted => TestCombiner's
       
   165                 // TestServer+TestModule(s) should cancel also.
       
   166                 testcase->CancelTestExecution();
       
   167                 // CTestExecution will panic if test case is ongoing!!! This
       
   168                 // should be stopped, client should handless this.
       
   169                 iTestExecutionHandle->Remove( handle );
       
   170                 }
       
   171             }
       
   172 
       
   173         delete iTestExecutionHandle;
       
   174         iTestExecutionHandle = NULL;
       
   175 
       
   176         }
       
   177 
       
   178     // Delete all FREE Test Module instances.
       
   179     if( iTestModuleInstances )
       
   180         {
       
   181         iTestModuleInstances->ResetAndDestroy();
       
   182         delete iTestModuleInstances;
       
   183         iTestModuleInstances = NULL;
       
   184         }
       
   185 
       
   186     // Delete ini file heap buffer
       
   187     delete iIniBuffer;
       
   188     iIniBuffer = NULL;
       
   189 
       
   190     // Delete array of test case titles
       
   191     iTestCaseTitles.ResetAndDestroy();
       
   192     iTestCaseTitles.Close();
       
   193     }
       
   194 
       
   195 /*
       
   196 -------------------------------------------------------------------------------
       
   197 
       
   198     Class: CTestModule
       
   199 
       
   200     Method: ConstructL
       
   201 
       
   202     Description: Second level constructor.
       
   203     
       
   204     Parameters: CTestServer* aServer          :in:  Server
       
   205 
       
   206     Return Values: None
       
   207 
       
   208     Errors/Exceptions: Leaves if:
       
   209                        base class CreateL leaves
       
   210                        Object index creation fails
       
   211                        Object container creation fails
       
   212                        Pointer array construction fails                       
       
   213 
       
   214     Status: Approved
       
   215 
       
   216 -------------------------------------------------------------------------------
       
   217 */
       
   218 void CTestModule::ConstructL( CTestServer* aServer )
       
   219     {
       
   220 
       
   221 	__TRACE( KVerbose, ( _L( "CTestModule::ConstructL - constructing server session" ) ) );
       
   222 
       
   223     // second-phase construct base class
       
   224     //CSession2::CreateL( /* *aServer */ );
       
   225     iTestServer = aServer;
       
   226 
       
   227     // create new object index
       
   228     iTestExecutionHandle = CObjectIx::NewL();
       
   229 
       
   230     // Initialize the object container using the object
       
   231     // container index in the server.
       
   232     iContainer = iTestServer->NewContainerL();
       
   233 
       
   234     iTestModuleInstances = new( ELeave ) RPointerArray<CTestModuleContainer>;
       
   235 
       
   236 	__TRACE( KError, ( _L( "CTestModule::ConstructL - constructing server session done" ) ) );
       
   237 
       
   238     }
       
   239 
       
   240 
       
   241 /*
       
   242 -------------------------------------------------------------------------------
       
   243 
       
   244     Class: CTestModule
       
   245 
       
   246     Method: CountResources
       
   247 
       
   248     Description: Resource counting
       
   249 
       
   250     Parameters: None
       
   251 
       
   252     Return Values: TInt                             Resource count
       
   253 
       
   254     Errors/Exceptions: None
       
   255 
       
   256     Status: Approved
       
   257 
       
   258 -------------------------------------------------------------------------------
       
   259 */
       
   260 TInt CTestModule::CountResources()
       
   261     {
       
   262 
       
   263     return iResourceCount;
       
   264 
       
   265     }
       
   266 
       
   267 
       
   268 /*
       
   269 -------------------------------------------------------------------------------
       
   270 
       
   271     Class: CTestModule
       
   272 
       
   273     Method: NumResources
       
   274 
       
   275     Description: Get resources, writes to Message()
       
   276 
       
   277     Parameters: None
       
   278 
       
   279     Return Values: None
       
   280 
       
   281     Errors/Exceptions: Panic client if result can't be written to descriptor.
       
   282 
       
   283     Status: Approved
       
   284 
       
   285 -------------------------------------------------------------------------------
       
   286 */
       
   287 void CTestModule::NumResources( const RMessage2& aMessage )
       
   288     {
       
   289 
       
   290     TPckgBuf<TInt> countPckg( iResourceCount );
       
   291 
       
   292     TRAPD( r, aMessage.WriteL( 0, countPckg ) );
       
   293     if( r !=KErrNone )
       
   294         {
       
   295         PanicClient( EBadDescriptor, aMessage );
       
   296         }
       
   297 
       
   298     }
       
   299 
       
   300 /*
       
   301 -------------------------------------------------------------------------------
       
   302 
       
   303     Class: CTestModule
       
   304 
       
   305     Method: PanicClient
       
   306 
       
   307     Description: Panic clients.
       
   308 
       
   309     Parameters: TInt aPanic                   :in:  Panic code
       
   310 
       
   311     Return Values: None
       
   312 
       
   313     Errors/Exceptions: None
       
   314 
       
   315     Status: Approved
       
   316 
       
   317 -------------------------------------------------------------------------------
       
   318 */
       
   319 void CTestModule::PanicClient( const TInt aPanic, const RMessage2& aMessage ) const
       
   320     {
       
   321 
       
   322     __TRACE( KError,( _L( "CTestModule::PanicClient code = %d" ), aPanic ) );
       
   323 
       
   324     _LIT( KTxtTestModule,"CTestModule" );
       
   325 
       
   326     aMessage.Panic( KTxtTestModule, aPanic );
       
   327     }
       
   328 
       
   329 
       
   330 /*
       
   331 -------------------------------------------------------------------------------
       
   332 
       
   333     Class: CTestModule
       
   334 
       
   335     Method: CloseSession
       
   336 
       
   337     Description: Close session
       
   338 
       
   339     Parameters: None
       
   340 
       
   341     Return Values: TInt: Symbian error code.
       
   342 
       
   343     Errors/Exceptions: None
       
   344 
       
   345     Status: Approved
       
   346 
       
   347 -------------------------------------------------------------------------------
       
   348 */
       
   349 TInt CTestModule::CloseSession( const RMessage2& aMessage )
       
   350     {
       
   351 
       
   352     __TRACE( KMessage,( _L( "CTestModule::CloseSession in" ) ) );
       
   353 
       
   354     // Delete all unclosed subsession handle before closing session.
       
   355     // Remove iTestExecutionHandle contents. iTestExecutionHandle countains
       
   356     // CTestExecution that handles test case have been created.
       
   357     if( iTestExecutionHandle )
       
   358         {
       
   359         TInt handle = 0;
       
   360         CObject* theObj = NULL;
       
   361         TInt count = iTestExecutionHandle->Count();
       
   362             
       
   363         for( TInt i = 0 ; i < count; i++ )
       
   364             {
       
   365             theObj=iTestExecutionHandle->operator[]( i );
       
   366             if( theObj )
       
   367                 {
       
   368                 handle=iTestExecutionHandle->At( theObj );
       
   369                 // CTestExecution will panic if test case is ongoing!!! This
       
   370                 // should be stopped, client should handle this.
       
   371                 iTestExecutionHandle->Remove( handle );
       
   372                 }
       
   373             }
       
   374 
       
   375         delete iTestExecutionHandle;
       
   376         iTestExecutionHandle = NULL;
       
   377 
       
   378         }
       
   379 
       
   380     // Deletion must be done here, because the "CloseSession" message is 
       
   381     // completed before execution continues from CActiveScheduler::Start 
       
   382     // location, and the main thread can continue execution 
       
   383     // and therefore shutdown itself and all threads in that process.
       
   384     
       
   385     // Delete the object container
       
   386     iTestServer->DeleteContainer( iContainer );
       
   387 
       
   388     // Free test case related data
       
   389     TInt r = FreeCaseData();
       
   390 
       
   391     // Delete all FREE Test Module instances
       
   392     iTestModuleInstances->ResetAndDestroy();
       
   393     delete iTestModuleInstances;
       
   394     iTestModuleInstances = NULL;
       
   395 
       
   396      // Inform server that session is closed
       
   397     iTestServer->SessionClosed();
       
   398 
       
   399 	// Check for avoiding multiple complete, see CTestModule::ServiceL()
       
   400     if( r != KErrNone )
       
   401         {
       
   402 		// In error cases do not complete, just return
       
   403         __TRACE( KMessage,( _L( "CTestModule::CloseSession out (1)" ) ) );
       
   404         return r;
       
   405         }
       
   406 
       
   407     aMessage.Complete( KErrNone );
       
   408 
       
   409     // After active scheduler shutdown is done, execution continues from
       
   410     // CTestServer::ThreadFunction()
       
   411 
       
   412     __TRACE( KMessage,( _L( "CTestModule::CloseSession out (2)" ) ) );
       
   413     return r;
       
   414     }
       
   415 
       
   416 
       
   417 /*
       
   418 -------------------------------------------------------------------------------
       
   419 
       
   420     Class: CTestModule
       
   421 
       
   422     Method: ServiceL
       
   423 
       
   424     Description: Trap harness for dispatcher
       
   425 
       
   426     Parameters: const RMessage& aMessage  :inout:   Message
       
   427 
       
   428     Return Values: None
       
   429 
       
   430     Errors/Exceptions: None
       
   431 
       
   432     Status: Proposal
       
   433 
       
   434 -------------------------------------------------------------------------------
       
   435 */
       
   436 void CTestModule::ServiceL( const RMessage2& aMessage )
       
   437     {
       
   438 
       
   439     // NOTE! HW testing slows down dramatically if adds commants here
       
   440 
       
   441     //__TRACE( KMessage,( _L( "CTestModule::ServiceL in" ) ) );
       
   442 
       
   443     TInt r = KErrNone;
       
   444     TRAPD( ret, r = DispatchMessageL( aMessage ) );
       
   445 
       
   446     if ( ret != KErrNone )
       
   447         {
       
   448         // Complete message on leaving cases with leave code.
       
   449         __TRACE( KError, ( CStifLogger::ERed, _L( "CTestModule::DispatchMessageL leaved" ) ) );
       
   450         aMessage.Complete( ret );
       
   451         }
       
   452 
       
   453     // Complete message with error code originating from message handling
       
   454     // function.
       
   455     if ( r != KErrNone )
       
   456         {
       
   457         __TRACE( KError, ( CStifLogger::ERed, _L( "CTestModule::DispatchMessageL returned error" ) ) );
       
   458         aMessage.Complete( r );
       
   459         }
       
   460 
       
   461      // __TRACE( KMessage,( _L( "CTestModule::ServiceL out" ) ) );
       
   462 
       
   463     }
       
   464 
       
   465 
       
   466 /*
       
   467 -------------------------------------------------------------------------------
       
   468 
       
   469     Class: CTestModule
       
   470 
       
   471     Method: DispatchMessageL
       
   472 
       
   473     Description: Dispatch message, calls corresponding function to do it.
       
   474 
       
   475     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
   476 
       
   477     Return Values: TInt                             Error code
       
   478 
       
   479     Errors/Exceptions: Leaves if operation handling function leaves
       
   480 
       
   481     Status: Proposal
       
   482 
       
   483 -------------------------------------------------------------------------------
       
   484 */
       
   485 TInt CTestModule::DispatchMessageL( const RMessage2& aMessage )
       
   486     {
       
   487 
       
   488     __TRACE( KMessage,( _L( "CTestModule::DispatchMessageL %d" ),
       
   489         aMessage.Function()  ) );
       
   490     switch( aMessage.Function() )
       
   491     {
       
   492     // Session specific
       
   493     case ETestServerCloseSession:                // Close whole session
       
   494         {
       
   495 		__TRACE( KError ,( _L( "Closing test module session" ) ) );
       
   496         return CloseSession( aMessage );
       
   497         }
       
   498     case ETestServerGetServerThreadId:           // Get Server ThreadId
       
   499         {
       
   500 		__TRACE( KError ,( _L( "Return server thread id" ) ) );
       
   501         return GetServerThreadIdL( aMessage );
       
   502         }
       
   503 
       
   504     case ETestModuleCreateSubSession :           // Create new test module subsession
       
   505         {
       
   506 		__TRACE( KError,( _L( "Creating test module session" ) ) );
       
   507         return CreateModuleSessionL( aMessage );
       
   508         }
       
   509 
       
   510     case ETestModuleCloseSubSession:             // Close module subsession
       
   511         {
       
   512         // Nothing to do.
       
   513         aMessage.Complete( KErrNone );
       
   514         return KErrNone;
       
   515         }
       
   516 
       
   517     case ETestExecutionCreateSubSession:         // Create new test execution subsession
       
   518         {
       
   519         return NewTestExecutionL( aMessage );
       
   520         }
       
   521  
       
   522     case ETestModuleEnumerateTestCases:          // Enumerate test cases
       
   523         {
       
   524 		__TRACE( KError,( _L( "Enumerating test cases" ) ) );
       
   525         return EnumerateTestCasesL( aMessage );
       
   526         }
       
   527         
       
   528     case ETestModuleGetTestCases:                // Get test cases
       
   529         {
       
   530         return GetTestCasesL( aMessage );
       
   531         }
       
   532 
       
   533     case ETestModuleErrorNotification:           // Request error notification
       
   534         {
       
   535         return HandleErrorNotificationL( aMessage );
       
   536         }
       
   537 
       
   538     case ETestModuleCancelAsyncRequest:
       
   539         {
       
   540         return CancelAsyncRequestL( aMessage );
       
   541         }
       
   542   
       
   543     // Subsession specific
       
   544     case ETestExecutionRunTestCase:              // Run test case
       
   545         {
       
   546 		__TRACE( KInit,( _L( "Running test case" ) ) );
       
   547         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   548         return testCase->RunTestCase( aMessage );
       
   549         }
       
   550         
       
   551     case ETestExecutionNotifyProgress:           // Test case prints
       
   552         {
       
   553         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   554         return testCase->NotifyPrint( aMessage );
       
   555         }
       
   556 
       
   557     case ETestExecutionNotifyEvent:              // Event notifications
       
   558         {
       
   559         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   560         return testCase->NotifyEvent( aMessage );
       
   561         }
       
   562         
       
   563     case ETestExecutionNotifyRemoteCmd:          // RemoteCmd notifications
       
   564         {
       
   565         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   566         return testCase->NotifyRemoteCmd( aMessage );
       
   567         }
       
   568     case ETestExecutionReadRemoteCmdInfo:          // RemoteCmd reading
       
   569         {
       
   570         //CTestExecution* testCase=CaseFromHandle( aMessage.Int3() );
       
   571         //return testCase->NotifyRemoteCmd( aMessage );
       
   572         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   573         return testCase->ReadRemoteCmdInfo( aMessage );
       
   574         }
       
   575 
       
   576 
       
   577     case ETestExecutionResume:                   // Resume case execution
       
   578         {
       
   579 		__TRACE( KVerbose,( _L( "Resuming test execution" ) ) );
       
   580         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   581         return testCase->Resume( aMessage );
       
   582         }
       
   583         
       
   584     case ETestExecutionPause:                    // Pause case execution
       
   585         {
       
   586 		__TRACE( KVerbose,( _L( "Pausing test execution" ) ) );
       
   587         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   588         return testCase->Pause( aMessage );
       
   589         }
       
   590             
       
   591     case ETestExecutionCloseSubSession:          // Close execution subsession
       
   592         {
       
   593         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   594         return testCase->CloseTestExecution( aMessage );
       
   595         }
       
   596 
       
   597     case ETestExecutionCancelAsyncRequest:       // Cancel async request
       
   598         {
       
   599         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   600         return testCase->CancelRequestL( aMessage );
       
   601         }
       
   602     case ETestExecutionNotifyCommand:            // Command notifications
       
   603         {
       
   604         CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage );
       
   605         return testCase->NotifyCommand( aMessage );
       
   606         }
       
   607 
       
   608     default:                                     // Invalid request
       
   609         {
       
   610         PanicClient( EBadRequest, aMessage );
       
   611         return KErrNotSupported;
       
   612         }
       
   613     }
       
   614 
       
   615     }
       
   616 
       
   617 
       
   618 /*
       
   619 -------------------------------------------------------------------------------
       
   620 
       
   621     Class: CTestModule
       
   622 
       
   623     Method: EnumerateTestCases
       
   624 
       
   625     Description: Enumerates test cases and returns test case count by writing
       
   626     result to client side package.
       
   627 
       
   628     Function obtains a TestModule and calls EnumerateTestCases from it.
       
   629     Test module will be released when calling GetTestCases function.
       
   630 
       
   631     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
   632 
       
   633     Return Values: TInt                             Operation result
       
   634 
       
   635     Errors/Exceptions: None
       
   636 
       
   637     Status: Proposal
       
   638 
       
   639 -------------------------------------------------------------------------------
       
   640 */
       
   641 TInt CTestModule::EnumerateTestCasesL( const RMessage2& aMessage )
       
   642     {
       
   643 
       
   644     __TRACE( KMessage,( _L( "CTestModule::EnumerateTestCasesL in" ) ) );
       
   645  
       
   646     // Get data from message
       
   647     TFileName config;
       
   648     TRAPD( res, aMessage.ReadL( 0, config ) );
       
   649     if( res != KErrNone )
       
   650         {
       
   651         PanicClient( EBadDescriptor, aMessage );
       
   652         return res;
       
   653         }
       
   654 
       
   655     // Free old case data
       
   656     User::LeaveIfError( FreeCaseData() );
       
   657 
       
   658     // Get test cases from the test module
       
   659     User::LeaveIfError( GetTestModule( iEnumerateModule, config ) );
       
   660 
       
   661     // Enumerate test cases
       
   662     iEnumerateModule->EnumerateTestCases( config );
       
   663 
       
   664     // Something fatal?
       
   665     TInt r = iEnumerateModule->OperationErrorResult();
       
   666     if(  r != KErrNone )
       
   667         {
       
   668         // Enumeration module have crashed.
       
   669         delete iEnumerateModule;
       
   670         iEnumerateModule = NULL;
       
   671 
       
   672         return r;
       
   673         }
       
   674 
       
   675     // Error from module?
       
   676     if( iEnumerateModule->ModuleResult() != KErrNone )
       
   677         {
       
   678         return iEnumerateModule->ModuleResult();
       
   679         }
       
   680 
       
   681     // Write count to Ptr1()
       
   682     const RPointerArray<TTestCaseInfo>* testCases = iEnumerateModule->TestCases();
       
   683     
       
   684     if( testCases == NULL )
       
   685         {
       
   686         User::Leave( KErrGeneral );
       
   687         }
       
   688     
       
   689     // Store titles (for further use, i.e. when asked for title from the interface via CTestModuleIf->CTestThreadContainer->CTestModuleContainer)
       
   690     iTestCaseTitles.ResetAndDestroy();
       
   691     TInt i;
       
   692     for(i = 0; i < testCases->Count(); i++)
       
   693         {
       
   694         //Handle situation when test cases are enumerated not as 0-based (testscripter, ...)
       
   695         if(i == 0 && (*testCases)[i]->iCaseNumber > 0)
       
   696             {
       
   697             iTestCaseTitles.Append(NULL);
       
   698             }
       
   699         HBufC* title = (*testCases)[i]->iTitle.AllocL();
       
   700         iTestCaseTitles.Append(title);
       
   701         }
       
   702     
       
   703     TPckgBuf<TInt> countPckg( testCases->Count() );
       
   704     TRAP( res, aMessage.WriteL( 1, countPckg ) );
       
   705     if( res != KErrNone )
       
   706         {
       
   707         PanicClient( EBadDescriptor, aMessage );
       
   708         return res;
       
   709         }
       
   710 
       
   711     // All ok, complete message
       
   712     aMessage.Complete( KErrNone );
       
   713 
       
   714     __TRACE( KMessage,( _L( "CTestModule::EnumerateTestCasesL out" ) ) );
       
   715     
       
   716     return KErrNone;
       
   717 
       
   718     }
       
   719 
       
   720 
       
   721 /*
       
   722 -------------------------------------------------------------------------------
       
   723 
       
   724     Class: CTestModule
       
   725 
       
   726     Method: GetTestCasesL
       
   727 
       
   728     Description: Get test cases. Enumerate test cases must be called before
       
   729     calling this function.
       
   730 
       
   731     Function releases the test module reserved by EnumerateTestCase().
       
   732 
       
   733     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
   734 
       
   735     Return Values: TInt                             Operation result
       
   736 
       
   737     Errors/Exceptions: Leaves if cases have not been enumerated.
       
   738 
       
   739     Status: Proposal
       
   740 
       
   741 -------------------------------------------------------------------------------
       
   742 */
       
   743 TInt CTestModule::GetTestCasesL( const RMessage2& aMessage )
       
   744     {
       
   745 
       
   746     __TRACE( KMessage,( _L( "CTestModule::GetTestCasesL in" ) ) );
       
   747 
       
   748     // Leave if cases have not been enumerated.
       
   749     //User::LeaveIfNull(( TAny* ) iEnumerateModule->TestCases() );
       
   750     if( ( TAny* ) iEnumerateModule->TestCases() == NULL )
       
   751         {
       
   752         User::Leave( KErrGeneral );
       
   753         }
       
   754 
       
   755     const TInt len = sizeof( TTestCaseInfo );
       
   756     
       
   757     // Get cases
       
   758     const RPointerArray<TTestCaseInfo>& cases = *iEnumerateModule->TestCases();
       
   759 
       
   760     // Get number of cases
       
   761     const TInt Kcount = cases.Count();
       
   762 
       
   763     // Loop through case and copy then to client's descriptor.
       
   764     for( TInt i = 0; i < Kcount; i++ )
       
   765         {
       
   766 
       
   767         // Construct package for source data
       
   768         TTestCaseInfoPckg tmpPackage( *cases[i] );
       
   769 
       
   770         // Write to correct location
       
   771         aMessage.WriteL( 0, tmpPackage, i *len );
       
   772 
       
   773         }
       
   774 
       
   775     // Free case data and the test module
       
   776     User::LeaveIfError( FreeCaseData() );
       
   777 
       
   778     // Finished
       
   779     aMessage.Complete( KErrNone );
       
   780 
       
   781     __TRACE( KMessage,( _L( "CTestModule::GetTestCasesL out" ) ) );
       
   782 
       
   783     return KErrNone;
       
   784 
       
   785     }
       
   786 
       
   787 
       
   788 /*
       
   789 -------------------------------------------------------------------------------
       
   790 
       
   791     Class: CTestModule
       
   792 
       
   793     Method: HandleErrorNotification
       
   794 
       
   795     Description: Request error notification.
       
   796 
       
   797     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
   798 
       
   799     Return Values: TInt                             Operation result
       
   800 
       
   801     Errors/Exceptions: None
       
   802 
       
   803     Status: Proposal
       
   804 
       
   805 -------------------------------------------------------------------------------
       
   806 */
       
   807 TInt CTestModule::HandleErrorNotificationL( const RMessage2& aMessage )
       
   808     {
       
   809     
       
   810     iErrorMessage = aMessage;
       
   811     iErrorMessageAvailable = ETrue;
       
   812 
       
   813     return KErrNone;
       
   814 
       
   815     }
       
   816 
       
   817 /*
       
   818 -------------------------------------------------------------------------------
       
   819 
       
   820     Class: CTestModule
       
   821 
       
   822     Method: GetServerThreadId
       
   823 
       
   824     Description: Request server state notification.
       
   825 
       
   826     Parameters: const RMessage& aMessage :inout: Message to be handled
       
   827 
       
   828     Return Values: TInt Operation result
       
   829 
       
   830     Errors/Exceptions: None
       
   831 
       
   832     Status: Proposal
       
   833 
       
   834 -------------------------------------------------------------------------------
       
   835 */
       
   836 TInt CTestModule::GetServerThreadIdL( const RMessage2& aMessage )
       
   837     {
       
   838       
       
   839     TInt id( iTestServer->GetServerThreadId() );
       
   840    
       
   841     TPckg<TThreadId> threadIdPckg( id );
       
   842    
       
   843     TRAPD( res, aMessage.WriteL( 0, threadIdPckg ) );
       
   844     
       
   845       // Finished
       
   846     aMessage.Complete( res );
       
   847     
       
   848     return KErrNone;
       
   849 
       
   850     }      
       
   851 
       
   852 /*
       
   853 -------------------------------------------------------------------------------
       
   854 
       
   855     Class: CTestModule
       
   856 
       
   857     Method: CancelAsyncRequest
       
   858 
       
   859     Description: Cancels asynchronous request
       
   860 
       
   861     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
   862 
       
   863     Return Values: TInt                             Operation result
       
   864 
       
   865     Errors/Exceptions: None
       
   866 
       
   867     Status: Proposal
       
   868 
       
   869 -------------------------------------------------------------------------------
       
   870 */
       
   871 TInt CTestModule::CancelAsyncRequestL( const RMessage2& aMessage )
       
   872     {
       
   873     
       
   874     switch ( aMessage.Int0() )
       
   875         {
       
   876         case ETestModuleErrorNotification:
       
   877             {
       
   878             if ( iErrorMessageAvailable )
       
   879                 {
       
   880                 iErrorMessage.Complete ( KErrCancel );
       
   881                 iErrorMessageAvailable = EFalse;
       
   882                 }
       
   883             aMessage.Complete ( KErrNone );
       
   884             break;
       
   885             }
       
   886 
       
   887         default:
       
   888             {
       
   889             PanicClient( EInvalidRequestCancel, aMessage );
       
   890             break;
       
   891             }
       
   892         }
       
   893 
       
   894     return KErrNone;
       
   895 
       
   896     }
       
   897 
       
   898 /*
       
   899 -------------------------------------------------------------------------------
       
   900 
       
   901     Class: CTestModule
       
   902 
       
   903     Method: ErrorPrint
       
   904 
       
   905     Description: Prints error
       
   906 
       
   907     Parameters: const TInt aPriority :in: Priority
       
   908                 TPtrC aError: in: Error
       
   909 
       
   910     Return Values: None
       
   911 
       
   912     Errors/Exceptions: None
       
   913 
       
   914     Status: Proposal
       
   915 
       
   916 -------------------------------------------------------------------------------
       
   917 */
       
   918 void CTestModule::ErrorPrint( const TInt aPriority, 
       
   919                               TPtrC aError )
       
   920     {
       
   921 
       
   922     if ( iErrorMessageAvailable )
       
   923         {        
       
   924         TErrorNotification error;
       
   925         TErrorNotificationPckg errorPckg ( error );
       
   926 
       
   927         error.iModule = _L("TestServer");
       
   928         error.iPriority = aPriority;
       
   929         error.iText = aError;
       
   930 
       
   931         TRAPD( r, iErrorMessage.WriteL( 0, errorPckg ) );
       
   932         
       
   933         // Do not handle errors
       
   934         iErrorMessageAvailable = EFalse;
       
   935         iErrorMessage.Complete( r );
       
   936 
       
   937         }
       
   938     else
       
   939         {
       
   940         RDebug::Print (_L("Error message lost %d [%S]"), aPriority, &aError );
       
   941         }
       
   942     
       
   943     }
       
   944 
       
   945 /*
       
   946 -------------------------------------------------------------------------------
       
   947 
       
   948     Class: CTestModule
       
   949 
       
   950     Method: FreeCaseData
       
   951 
       
   952     Description: Frees the test case data and test module that is used in
       
   953     enumeration.
       
   954 
       
   955     Parameters: None
       
   956 
       
   957     Return Values: TInt                             Error code
       
   958 
       
   959     Errors/Exceptions: None
       
   960 
       
   961     Status: Proposal
       
   962 
       
   963 -------------------------------------------------------------------------------
       
   964 */
       
   965 TInt CTestModule::FreeCaseData()
       
   966     {
       
   967 
       
   968     __TRACE( KMessage,( _L( "CTestModule::FreeCaseData in" ) ) );
       
   969  
       
   970     TInt r = KErrNone;
       
   971 
       
   972     if( iEnumerateModule )
       
   973         {
       
   974         
       
   975         // Deallocate testcase memory
       
   976         iEnumerateModule->FreeEnumerationData();
       
   977 
       
   978         // Free the module
       
   979         r = FreeTestModule( iEnumerateModule );
       
   980 
       
   981         iEnumerateModule = NULL;
       
   982 
       
   983         }
       
   984 
       
   985     __TRACE( KMessage,( _L( "CTestModule::FreeCaseData out" ) ) );
       
   986 
       
   987     return r;
       
   988 
       
   989     }
       
   990 
       
   991 
       
   992 /*
       
   993 -------------------------------------------------------------------------------
       
   994 
       
   995     Class: CTestModule
       
   996 
       
   997     Method: CreateModuleSessionL
       
   998 
       
   999     Description: Creates a new module session.
       
  1000     Just take the initialisation file name from message.
       
  1001 
       
  1002     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
  1003 
       
  1004     Return Values: TInt                             Operation result
       
  1005 
       
  1006     Errors/Exceptions: Leaves if memory allocation fails
       
  1007 
       
  1008     Status: Proposal
       
  1009 
       
  1010 -------------------------------------------------------------------------------
       
  1011 */
       
  1012 TInt CTestModule::CreateModuleSessionL( const RMessage2& aMessage )
       
  1013     {
       
  1014 
       
  1015     __TRACE( KMessage,( _L( "CTestModule::CreateModuleSession in" ) ) );
       
  1016 
       
  1017     // Take parameters
       
  1018     TFileName ini;
       
  1019     TRAPD( res, aMessage.ReadL( 0, ini ) );
       
  1020     if( res != KErrNone )
       
  1021         {
       
  1022         PanicClient( EBadDescriptor, aMessage );
       
  1023         return res;
       
  1024         }
       
  1025 
       
  1026     // Construct heap buffer for initialization file name
       
  1027     iIniBuffer = HBufC::NewL( ini.Length() );
       
  1028     iIni.Set ( iIniBuffer->Des() );
       
  1029     iIni.Copy ( ini );
       
  1030 
       
  1031     aMessage.Complete( KErrNone );
       
  1032 
       
  1033     __TRACE( KMessage,( _L( "CTestModule::CreateModuleSession out" ) ) );
       
  1034 
       
  1035     return KErrNone;
       
  1036 
       
  1037     }
       
  1038 
       
  1039 /*
       
  1040 -------------------------------------------------------------------------------
       
  1041 
       
  1042     Class: CTestModule
       
  1043 
       
  1044     Method: NewTestExecutionL
       
  1045 
       
  1046     Description: Create new test execution subsession
       
  1047     
       
  1048     Parameters: const RMessage& aMessage  :inout:   Message to be handled
       
  1049     
       
  1050     Return Values: TInt                             Operation result
       
  1051 
       
  1052     Errors/Exceptions: Function leaves if object can't be created or
       
  1053                        it can't be added to container.
       
  1054                        Function panics client if message contains invalid
       
  1055                        descriptor.
       
  1056 
       
  1057     Status: Proposal
       
  1058     
       
  1059 -------------------------------------------------------------------------------
       
  1060 */
       
  1061 TInt CTestModule::NewTestExecutionL( const RMessage2& aMessage )
       
  1062     {
       
  1063 
       
  1064     __TRACE( KMessage,( _L( "CTestModule::NewTestExecutionL in" ) ) );
       
  1065 
       
  1066     // Get data from message
       
  1067     TInt caseNumber = aMessage.Int0();
       
  1068     TFileName config;
       
  1069     
       
  1070     TRAPD( res, aMessage.ReadL( 1, config ) );
       
  1071     if( res != KErrNone )
       
  1072         {
       
  1073         PanicClient( EBadDescriptor, aMessage );
       
  1074         return res;
       
  1075         }
       
  1076 
       
  1077     // Make new object
       
  1078     CTestExecution* execution=CTestExecution::NewL( this, caseNumber, config );
       
  1079 
       
  1080     // add object to object container to generate unique id
       
  1081     iContainer->AddL( execution );
       
  1082 
       
  1083     // add object to object index; this returns a unique handle so we can get it again
       
  1084     TInt handle=iTestExecutionHandle->AddL( execution );
       
  1085 
       
  1086     // write the handle to client
       
  1087     TPckg<TInt> handlePckg( handle );
       
  1088     TRAP( res, aMessage.WriteL( 3, handlePckg ) );
       
  1089     if( res != KErrNone )
       
  1090         {
       
  1091         iTestExecutionHandle->Remove( handle );
       
  1092         PanicClient( EBadDescriptor, aMessage );
       
  1093         return res;
       
  1094         }
       
  1095 
       
  1096     // notch up another resource
       
  1097     iResourceCount++;
       
  1098 
       
  1099     // Complete message
       
  1100     aMessage.Complete( KErrNone );
       
  1101 
       
  1102     __TRACE( KMessage,( _L( "CTestModule::NewTestExecutionL out" ) ) );
       
  1103 
       
  1104     return KErrNone;
       
  1105     }
       
  1106 
       
  1107 /*
       
  1108 -------------------------------------------------------------------------------
       
  1109 
       
  1110     Class: CTestModule
       
  1111 
       
  1112     Method: DeleteTestExecution
       
  1113 
       
  1114     Description: Deletes Test Execution by handle
       
  1115 
       
  1116     Parameters: const TUint aHandle           :in:  Handle
       
  1117 
       
  1118     Return Values: None
       
  1119 
       
  1120     Errors/Exceptions: Panics client if invalid handle
       
  1121 
       
  1122     Status: Proposal
       
  1123 
       
  1124 -------------------------------------------------------------------------------
       
  1125 */
       
  1126 void CTestModule::DeleteTestExecution( const TUint aHandle, const RMessage2& aMessage )
       
  1127     {
       
  1128 
       
  1129     // Verify that handle is valid
       
  1130     CaseFromHandle( aHandle, aMessage );
       
  1131 
       
  1132     // Remove object
       
  1133     iTestExecutionHandle->Remove( aHandle );
       
  1134 
       
  1135     // Decrement resource count.
       
  1136     iResourceCount--;
       
  1137 
       
  1138     }
       
  1139 
       
  1140 
       
  1141 /*
       
  1142 -------------------------------------------------------------------------------
       
  1143 
       
  1144     Class: CTestModule
       
  1145 
       
  1146     Method: CaseFromHandle
       
  1147 
       
  1148     Description: Return subsession from handle
       
  1149 
       
  1150     Parameters: const TUint aHandle           :in:  Handle
       
  1151 
       
  1152     Return Values: CTestExecution*                  Test Execution object
       
  1153 
       
  1154     Errors/Exceptions: Function panics client if invalid handle.
       
  1155 
       
  1156     Status: Approved
       
  1157     
       
  1158 -------------------------------------------------------------------------------
       
  1159 */
       
  1160 CTestExecution* CTestModule::CaseFromHandle( const TUint aHandle, const RMessage2& aMessage ) const
       
  1161     {
       
  1162 
       
  1163     CTestExecution* testcase =( CTestExecution* ) iTestExecutionHandle->At( aHandle );
       
  1164 
       
  1165     if( testcase == NULL )
       
  1166         {
       
  1167         PanicClient( EBadSubsessionHandle, aMessage );
       
  1168         }
       
  1169 
       
  1170     return testcase;
       
  1171 
       
  1172     }
       
  1173 
       
  1174 
       
  1175 /*
       
  1176 -------------------------------------------------------------------------------
       
  1177 
       
  1178     Class: CTestModule
       
  1179 
       
  1180     Method: GetTestModule
       
  1181 
       
  1182     Description: Gets a CTestModuleBase*. If there is a free entry
       
  1183     in the free list, then it is returned. Otherwise a new one is created.
       
  1184 
       
  1185     Parameters: CTestModuleContainer*& aContainer: out: container pointer.
       
  1186                 const TDesC& aConfig: in: Test case (config) file name.
       
  1187 
       
  1188     Return Values: Symbian OS error code
       
  1189     
       
  1190     Errors/Exceptions: None
       
  1191 
       
  1192     Status: Proposal
       
  1193 
       
  1194 -------------------------------------------------------------------------------
       
  1195 */
       
  1196 TInt CTestModule::GetTestModule( CTestModuleContainer*& aContainer,
       
  1197                                     const TDesC& aConfig )
       
  1198     {
       
  1199     TInt ret = KErrNone;
       
  1200 
       
  1201     if( iTestModuleInstances->Count() )
       
  1202         {
       
  1203         // Return an existing one        
       
  1204         aContainer =( *iTestModuleInstances )[0];
       
  1205         iTestModuleInstances->Remove( 0 );
       
  1206 		__TRACE( KInit,( _L( "Reusing old test module container instance at 0x%x" ), (TUint32) aContainer ) );
       
  1207         }
       
  1208     else
       
  1209         {
       
  1210         // Create a new one    
       
  1211         __TRACE( KInit,( _L( "Creating new test module instance" ) ) );
       
  1212         TRAPD( err, aContainer = CTestModuleContainer::NewL( 
       
  1213                                                 iTestServer->ModuleName(),
       
  1214                                                 this,
       
  1215                                                 aConfig ) );
       
  1216 
       
  1217         // If module can't be created, then return NULL.
       
  1218         if( err )
       
  1219             {
       
  1220             __TRACE( KError,( _L( "Can't create new test module container instance" ) ) );
       
  1221             aContainer = NULL;
       
  1222             ret = err;
       
  1223             }
       
  1224 		else
       
  1225 			{
       
  1226 			__TRACE( KInit,( _L( "Test module instance container created" ) ) );
       
  1227 			}
       
  1228 
       
  1229         if( aContainer )
       
  1230             {
       
  1231 
       
  1232             // Initialise module
       
  1233             aContainer->Initialize( iTestServer->ModuleName(), iTestServer->FirstTime() );
       
  1234 
       
  1235             if( aContainer->OperationErrorResult() != KErrNone )
       
  1236                 {
       
  1237                 // Can't initialise module, delete it
       
  1238                 __TRACE( KError,( CStifLogger::ERed, _L( "Operation error, can't initialize test module container instance" ) ) );
       
  1239                 ret = aContainer->OperationErrorResult();                    
       
  1240                 delete aContainer;
       
  1241                 aContainer = NULL;
       
  1242                 }
       
  1243             else if( aContainer->ModuleResult() != KErrNone )
       
  1244                 {
       
  1245                 // Can't initialise module, delete it
       
  1246                 __TRACE( KError,( CStifLogger::ERed, _L( "Module error, can't initialize test module container instance" ) ) );
       
  1247                 ret = aContainer->ModuleResult();
       
  1248                 delete aContainer;
       
  1249                 aContainer = NULL;
       
  1250                 }
       
  1251             else
       
  1252                 {
       
  1253                 // Module initialised properly, clear the first time flag.
       
  1254                 iTestServer->ClearFirstTime();
       
  1255 				__TRACE( KInit,( _L( "Test module container initialized at 0x%x" ), (TUint32) aContainer ) );
       
  1256                 }
       
  1257             }
       
  1258         }
       
  1259 
       
  1260     return ret;
       
  1261 
       
  1262     }
       
  1263 
       
  1264 
       
  1265 /*
       
  1266 -------------------------------------------------------------------------------
       
  1267 
       
  1268     Class: CTestModule
       
  1269 
       
  1270     Method: FreeTestModule
       
  1271 
       
  1272     Description:Frees a CTestModuleContainer. This function can be called
       
  1273     from the context of the test execution thread.
       
  1274     
       
  1275     Parameters: CTestModuleContainer* aModule :in:  Module to be freed
       
  1276     
       
  1277     Return Values: TInt                             Error code
       
  1278 
       
  1279     Errors/Exceptions: None
       
  1280 
       
  1281     Status: Proposal
       
  1282     
       
  1283 -------------------------------------------------------------------------------
       
  1284 */
       
  1285 TInt CTestModule::FreeTestModule( CTestModuleContainer* aModule )
       
  1286     {
       
  1287   
       
  1288     // Free the module
       
  1289     TInt r = iTestModuleInstances->Append( aModule );
       
  1290     if( r != KErrNone )
       
  1291         {
       
  1292         delete aModule;
       
  1293         aModule = NULL;
       
  1294         }
       
  1295 
       
  1296     return r;
       
  1297 
       
  1298     }
       
  1299 
       
  1300 /*
       
  1301 -------------------------------------------------------------------------------
       
  1302 
       
  1303     Class: CTestModule
       
  1304 
       
  1305     Method: IniName
       
  1306 
       
  1307     Returns the initialisation file name
       
  1308     
       
  1309     Parameters: None
       
  1310     
       
  1311     Return Values: const TDesC&                     Initialisation file name
       
  1312 
       
  1313     Errors/Exceptions: None
       
  1314 
       
  1315     Status: Proposal
       
  1316     
       
  1317 -------------------------------------------------------------------------------
       
  1318 */
       
  1319 
       
  1320 const TDesC& CTestModule::IniName() const
       
  1321     {
       
  1322 
       
  1323     return iIni;
       
  1324 
       
  1325     }
       
  1326 
       
  1327 /*
       
  1328 -------------------------------------------------------------------------------
       
  1329 
       
  1330     Class: CTestModule
       
  1331 
       
  1332     Method: Name
       
  1333 
       
  1334     Returns the module name
       
  1335     
       
  1336     Parameters: None
       
  1337     
       
  1338     Return Values: const TDesC&                     Initialisation file name
       
  1339 
       
  1340     Errors/Exceptions: None
       
  1341 
       
  1342     Status: Proposal
       
  1343     
       
  1344 -------------------------------------------------------------------------------
       
  1345 */
       
  1346 const TDesC& CTestModule::Name() const
       
  1347     {
       
  1348 
       
  1349     return iTestServer->ModuleName();
       
  1350 
       
  1351     }
       
  1352 
       
  1353 /*
       
  1354 -------------------------------------------------------------------------------
       
  1355 
       
  1356     Class: CTestModule
       
  1357 
       
  1358     Method: GetTestCaseTitleL
       
  1359 
       
  1360     Gets title of currently running test case
       
  1361     
       
  1362     Parameters: None
       
  1363     
       
  1364     Return Values: TInt aTestCaseNumber: in: index of currently running test case
       
  1365                    TDes& aTestCaseTitle: out: test case title
       
  1366 
       
  1367     Errors/Exceptions: None
       
  1368 
       
  1369     Status: Proposal
       
  1370     
       
  1371 -------------------------------------------------------------------------------
       
  1372 */
       
  1373 void CTestModule::GetTestCaseTitleL(TInt aTestCaseNumber, TDes& aTestCaseTitle)
       
  1374     {
       
  1375     RDebug::Print(_L("Trying to get test case title from module. Index=%d, count=%d"), aTestCaseNumber, iTestCaseTitles.Count());
       
  1376     aTestCaseTitle.Copy(*(iTestCaseTitles[aTestCaseNumber]));
       
  1377     }
       
  1378 
       
  1379 
       
  1380 /*
       
  1381 -------------------------------------------------------------------------------
       
  1382 
       
  1383     Class: CTestModule
       
  1384 
       
  1385     Method: GetTestServer
       
  1386 
       
  1387     Gets pointer to TestServer
       
  1388     
       
  1389     Parameters: None
       
  1390     
       
  1391     Return Values: CTestServer : pointer to TestServer
       
  1392 
       
  1393     Errors/Exceptions: None
       
  1394 
       
  1395     Status: Proposal
       
  1396     
       
  1397 -------------------------------------------------------------------------------
       
  1398 */
       
  1399 CTestServer* CTestModule::GetTestServer()
       
  1400     {
       
  1401     return iTestServer;
       
  1402     }
       
  1403 
       
  1404 
       
  1405 
       
  1406 //  End of File