stif/TestServer/src/TestExecutionThread.cpp
branchRCL_3
changeset 19 07b41fa8d1dd
parent 18 3406c99bc375
child 20 ca8a1b6995f6
equal deleted inserted replaced
18:3406c99bc375 19:07b41fa8d1dd
     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 
       
    15 * CTestThreadContainer class implementation. These functions are 
       
    16 * called from the context of the test execution thread.
       
    17 *
       
    18 */
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32std.h>
       
    22 #include <e32svr.h>
       
    23 #include <e32uid.h>
       
    24 #include <StifTestModule.h>
       
    25 #include "ThreadLogging.h"
       
    26 #include "TestEngineClient.h"
       
    27 #include <stifinternal/TestServerClient.h>
       
    28 #include "TestServer.h"
       
    29 #include "TestThreadContainer.h"
       
    30 #include "TestServerCommon.h"
       
    31 #include "TestServerModuleIf.h"
       
    32 #include "TestServerEvent.h"
       
    33 #include "TestThreadContainerRunner.h"
       
    34 #include <stifinternal/TestThreadContainerRunnerFactory.h>
       
    35 
       
    36 // EXTERNAL DATA STRUCTURES
       
    37 
       
    38 // EXTERNAL FUNCTION PROTOTYPES
       
    39 
       
    40 // CONSTANTS
       
    41 
       
    42 // MACROS
       
    43 #ifdef THREADLOGGER
       
    44 #undef THREADLOGGER
       
    45 #endif
       
    46 #define THREADLOGGER iThreadLogger 
       
    47 
       
    48 // LOCAL CONSTANTS AND MACROS
       
    49 
       
    50 // MODULE DATA STRUCTURES
       
    51 
       
    52 // LOCAL FUNCTION PROTOTYPES
       
    53 
       
    54 // FORWARD DECLARATIONS
       
    55 
       
    56 // ==================== LOCAL FUNCTIONS =======================================
       
    57 
       
    58 // None
       
    59 
       
    60 // ================= MEMBER FUNCTIONS =========================================
       
    61 
       
    62 /*
       
    63 -------------------------------------------------------------------------------
       
    64 
       
    65     Class: CTestThreadContainer
       
    66 
       
    67     Method: NewL
       
    68 
       
    69     Description: Returns new CTestThreadContainer instance.
       
    70 
       
    71     Parameters: None
       
    72 
       
    73     Return Values: CTestThreadContainer*            New instance
       
    74 
       
    75     Errors/Exceptions: Function leaves if memory allocation fails or
       
    76                        CTestThreadContainer ConstructL leaves.
       
    77 
       
    78     Status: Proposal
       
    79 
       
    80 -------------------------------------------------------------------------------
       
    81 */
       
    82 CTestThreadContainer* CTestThreadContainer::NewL( 
       
    83     CTestModuleContainer* aModuleContainer,
       
    84     TThreadId aServerThreadId )
       
    85     {
       
    86 
       
    87     CTestThreadContainer* self = 
       
    88         new ( ELeave ) CTestThreadContainer( aModuleContainer );
       
    89     CleanupStack::PushL( self );
       
    90     self->ConstructL( aServerThreadId );
       
    91     CleanupStack::Pop( self );
       
    92     return self;
       
    93 
       
    94     }
       
    95 
       
    96 /*
       
    97 -------------------------------------------------------------------------------
       
    98 
       
    99     Class: CTestThreadContainer
       
   100 
       
   101     Method: ConstructL
       
   102 
       
   103     Description: Second level constructor.
       
   104 
       
   105     Parameters: None
       
   106 
       
   107     Return Values: CTestThreadContainer*            New instance
       
   108 
       
   109     Errors/Exceptions: None
       
   110 
       
   111     Status: Proposal
       
   112     
       
   113 -------------------------------------------------------------------------------
       
   114 */
       
   115 void CTestThreadContainer::ConstructL( TThreadId aServerThreadId )
       
   116     {
       
   117     
       
   118     User::LeaveIfError( iServerThread.Open( aServerThreadId ) );
       
   119     
       
   120     iErrorPrintSem.SetHandle( ModuleContainer().ErrorPrintSemHandle() );
       
   121     User::LeaveIfError( iErrorPrintSem.Duplicate( iServerThread ) );
       
   122     
       
   123     }
       
   124 
       
   125 /*
       
   126 -------------------------------------------------------------------------------
       
   127 
       
   128     Class: CTestThreadContainer
       
   129 
       
   130     Method: CTestThreadContainer
       
   131 
       
   132     Description: Constructor.
       
   133 
       
   134     Parameters: None
       
   135 
       
   136     Return Values: None
       
   137 
       
   138     Errors/Exceptions: None
       
   139 
       
   140     Status: Proposal
       
   141     
       
   142 -------------------------------------------------------------------------------
       
   143 */
       
   144 CTestThreadContainer::CTestThreadContainer( 
       
   145     CTestModuleContainer* aModuleContainer ):
       
   146     iModuleContainer( aModuleContainer ),
       
   147     iCheckResourceFlags( 0 )
       
   148     {
       
   149    
       
   150     ModuleContainer().SetThreadContainer( this );
       
   151     
       
   152     StifMacroErrorInit(); // Initialization
       
   153 
       
   154     }
       
   155 
       
   156 /*
       
   157 -------------------------------------------------------------------------------
       
   158 
       
   159     Class: CTestThreadContainer
       
   160 
       
   161     Method: ~CTestThreadContainer
       
   162 
       
   163     Description: Destructor
       
   164 
       
   165     Parameters: None
       
   166 
       
   167     Return Values: None
       
   168 
       
   169     Errors/Exceptions: None
       
   170 
       
   171     Status: Proposal
       
   172 
       
   173 -------------------------------------------------------------------------------
       
   174 */
       
   175 CTestThreadContainer::~CTestThreadContainer()
       
   176     {
       
   177 
       
   178     // Close mutexes
       
   179     if ( iPrintMutex.Handle() != 0 ) iPrintMutex.Close();
       
   180     if ( iEventMutex.Handle() != 0 ) iEventMutex.Close();
       
   181     if ( iSndMutex.Handle() != 0 ) iSndMutex.Close();
       
   182     if ( iRcvMutex.Handle() != 0 ) iRcvMutex.Close();
       
   183     if ( iInterferenceMutex.Handle() != 0 ) iInterferenceMutex.Close();
       
   184     if ( iMeasurementMutex.Handle() != 0 ) iMeasurementMutex.Close();
       
   185     if ( iCommandMutex.Handle() != 0 ) iCommandMutex.Close();
       
   186 
       
   187     // Mutex for testcomplete and cancel operations. Close duplicate mutex
       
   188     if ( iTestThreadMutex.Handle() != 0 ) iTestThreadMutex.Close();
       
   189 
       
   190     // Close semaphores
       
   191     if ( iPrintSem.Handle() != 0 ) iPrintSem.Close();
       
   192     if ( iErrorPrintSem.Handle() != 0 ) iErrorPrintSem.Close();
       
   193     if ( iEventSem.Handle() != 0 ) iEventSem.Close();
       
   194     if ( iSndSem.Handle() != 0 ) iSndSem.Close();
       
   195     if ( iRcvSem.Handle() != 0 ) iRcvSem.Close();
       
   196     if ( iInterferenceSem.Handle() != 0 ) iInterferenceSem.Close();
       
   197     if ( iMeasurementSem.Handle() != 0 ) iMeasurementSem.Close();
       
   198     //if ( iReceiverSem.Handle() != 0 ) iReceiverSem.Close();
       
   199     if ( iCommandSem.Handle() != 0) iCommandSem.Close();
       
   200     
       
   201     iServerThread.Close();
       
   202     
       
   203     }
       
   204 
       
   205 /*
       
   206 -------------------------------------------------------------------------------
       
   207 
       
   208     Class: CTestThreadContainer
       
   209 
       
   210     Method: InitializeModule
       
   211 
       
   212     Description: Initialize test module.
       
   213 
       
   214     Function obtains pointer to the first exported function of the test module,
       
   215     and calls that function to obtain an instance of CTestModuleBase derived
       
   216     object. After that the "Init()"-method is called. If some operation fails,
       
   217     module will be deleted and error code is returned.
       
   218 
       
   219     This function is a static member function, which is intented to be called
       
   220     from the context of the test module thread.
       
   221 
       
   222     Parameters: RLibrary& aModule                 :in: Module to be loaded
       
   223     
       
   224     Return Values: TInt                                Error code from module
       
   225                                                        or memory allocation.
       
   226 
       
   227     Errors/Exceptions: None.
       
   228 
       
   229     Status: Proposal
       
   230 
       
   231 -------------------------------------------------------------------------------
       
   232 */
       
   233 TInt CTestThreadContainer::InitializeModuleInThread ( RLibrary& aModule )
       
   234     {        
       
   235         
       
   236     __TRACEI ( KInit, ( _L("Starting test module initialization") ) );
       
   237     __TRACEI ( KInit, ( CStifLogger::EBold,  _L("Module name \"%S\""), 
       
   238         &ModuleContainer().OperationName() ) );
       
   239     ModuleContainer().OperationText() = _L("E32DLL");
       
   240 
       
   241     TFileName moduleName;
       
   242     TFileName tmpBuffer;
       
   243 
       
   244     TInt r( KErrNone );
       
   245     TFileName newNameBuffer;
       
   246     TInt check = CheckModuleName( ModuleContainer().OperationName(), newNameBuffer );
       
   247     if( check == KErrNone )
       
   248         {
       
   249         // Load the module(TestScripter)
       
   250         r = aModule.Load( newNameBuffer );
       
   251         }
       
   252     else
       
   253         {
       
   254         // Load the module(Others)
       
   255         RemoveOptionalIndex(ModuleContainer().OperationName(), newNameBuffer);
       
   256         __TRACEI(KInit, (_L( "Valid module name is [%S] (extracted from [%S])"), &newNameBuffer, &ModuleContainer().OperationName()));
       
   257         r = aModule.Load(newNameBuffer);
       
   258         }
       
   259     
       
   260     if ( r != KErrNone )
       
   261         {
       
   262         __TRACEI (KError, ( CStifLogger::EError, _L("Can't initialize test module code = %d"), r));
       
   263 
       
   264         // Set error codes
       
   265         ModuleContainer().OperationErrorResult() = r;
       
   266         return r;
       
   267         }
       
   268     else
       
   269         {
       
   270         // Print module name
       
   271         moduleName = aModule.FileName();    
       
   272         __TRACEI (KInit, (  _L("Loaded test module[%S]"), &moduleName ) );
       
   273         }
       
   274 
       
   275     
       
   276     // Get pointer to first exported function
       
   277     ModuleContainer().OperationText() = _L("1st EXPORTED function");
       
   278     CTestInterfaceFactory libEntry;
       
   279     libEntry = (CTestInterfaceFactory) aModule.Lookup(1);
       
   280     if ( libEntry == NULL )
       
   281         {
       
   282         // New instance can't be created
       
   283         __TRACEI (KError, ( CStifLogger::EError, _L("Can't initialize test module, NULL libEntry")));
       
   284 
       
   285         // Set error codes
       
   286         ModuleContainer().OperationErrorResult() = KErrNoMemory;
       
   287         return KErrNoMemory;
       
   288         }
       
   289     else
       
   290         {
       
   291         __TRACEI ( KInit, ( _L("Pointer to 1st exported received")));
       
   292         }
       
   293 
       
   294     // initialize test module
       
   295     __TRACEI ( KVerbose, (_L("Calling 1st exported at 0x%x"), (TUint32) libEntry ));
       
   296     TRAPD ( err, iTestModule =  (*libEntry)() );
       
   297 
       
   298      // Handle leave from test module
       
   299     if ( err != KErrNone )
       
   300         {
       
   301         __TRACEI (KError, ( CStifLogger::EError, _L("Leave when calling 1st exported function, code %d"), err));
       
   302         tmpBuffer = _L("Leave from test module 1st EXPORTED function");        
       
   303         ErrorPrint( 1, tmpBuffer );        
       
   304         delete iTestModule;
       
   305         iTestModule = NULL;
       
   306 
       
   307         // Set error codes
       
   308         ModuleContainer().OperationErrorResult() = err;
       
   309         return err;
       
   310         }
       
   311     else if ( iTestModule == NULL )     // Handle NULL from test module init
       
   312         {
       
   313         __TRACEI (KError, ( CStifLogger::EError, _L("NULL pointer received when constructing test module")));
       
   314         tmpBuffer = _L("Test module 1st EXPORTED function returned NULL");        
       
   315         ErrorPrint( 1, tmpBuffer );        
       
   316         delete iTestModule;
       
   317         iTestModule = NULL;
       
   318 
       
   319         // Set error codes
       
   320         ModuleContainer().OperationErrorResult() = KErrNoMemory;
       
   321         return KErrNoMemory;
       
   322         }
       
   323     else
       
   324         {
       
   325         __TRACEI (KInit, (_L("Entrypoint successfully called, test module instance at 0x%x"), (TUint32)iTestModule ) );
       
   326         }
       
   327 
       
   328     // Verify version number.
       
   329     ModuleContainer().OperationText() = _L("Version");
       
   330     TVersion moduleAPIVersion(0,0,0);
       
   331     TVersion myOldAPIVersion( KOldTestModuleAPIMajor, KOldTestModuleAPIMinor, KOldTestModuleAPIBuild );
       
   332     TVersion myAPIVersion( KTestModuleAPIMajor, KTestModuleAPIMinor, KTestModuleAPIBuild );
       
   333     TRAP ( err,  moduleAPIVersion = iTestModule->Version() );
       
   334 
       
   335     if ( err != KErrNone ||  (( myOldAPIVersion.iMajor !=  moduleAPIVersion.iMajor ||
       
   336                                 myOldAPIVersion.iMinor !=  moduleAPIVersion.iMinor  )
       
   337                                 &&
       
   338                               ( myAPIVersion.iMajor != moduleAPIVersion.iMajor ||
       
   339                               	myAPIVersion.iMinor != moduleAPIVersion.iMinor ))
       
   340         )
       
   341         {
       
   342         tmpBuffer = moduleAPIVersion.Name();
       
   343         __TRACEI (KError, ( CStifLogger::EError, _L("Incorrect test module version. Module version %S"), &tmpBuffer ) );        
       
   344         tmpBuffer = myOldAPIVersion.Name();
       
   345         __TRACEI (KError, ( CStifLogger::EError, _L("Required version %S"), &tmpBuffer  ) );
       
   346                 
       
   347         tmpBuffer.Format(_L("Invalid version in [%S]"), &moduleName );
       
   348         ErrorPrint( 1, tmpBuffer );        
       
   349 
       
   350          // Set error codes
       
   351         ModuleContainer().OperationErrorResult() = KErrNotSupported;
       
   352         return KErrNotSupported;
       
   353         }
       
   354 
       
   355     ModuleContainer().OperationText() = _L("InitL");
       
   356     // Initialize test module
       
   357     TInt initResult = KErrNone;
       
   358     TRAP ( err, 
       
   359         CTestModuleIf::NewL( NULL, iTestModule );
       
   360         TFileName tmp = ModuleContainer().TestModuleIniFile();
       
   361         initResult = iTestModule->InitL( tmp, ModuleContainer().OperationIntBuffer() );
       
   362     );
       
   363 
       
   364     // Handle leave from test module
       
   365     if ( err != KErrNone )
       
   366         {
       
   367         __TRACEI (KError, ( CStifLogger::EError, _L("Leave when initializing test module code %d"), err));
       
   368         tmpBuffer = _L("Leave from test module InitL");        
       
   369         ErrorPrint( 1, tmpBuffer );   
       
   370         ModuleContainer().OperationText() = _L("DESTRUCTOR");
       
   371         delete iTestModule;
       
   372         iTestModule = NULL;
       
   373         ModuleContainer().OperationText() = _L("");
       
   374 
       
   375         // Set error codes
       
   376         ModuleContainer().OperationErrorResult() = err;
       
   377         return err;
       
   378         }      
       
   379     else if ( initResult != KErrNone ) 
       
   380         {     // Handle failed initialisation of test module
       
   381         __TRACEI (KError, ( CStifLogger::EError, _L("Can't initialize test module, code %d"), initResult));
       
   382         ModuleContainer().OperationText() = _L("DESTRUCTOR");
       
   383         delete iTestModule;
       
   384         iTestModule = NULL;
       
   385         ModuleContainer().OperationText() = _L("");
       
   386         
       
   387         // Set error code
       
   388         ModuleContainer().ModuleResult() = initResult;
       
   389         return initResult;
       
   390         }
       
   391     ModuleContainer().OperationText() = _L("");
       
   392 
       
   393     __TRACEI (KInit, ( CStifLogger::EBold, _L("Test module initialization done")));     
       
   394 
       
   395     return KErrNone;
       
   396 
       
   397     }
       
   398 
       
   399 /*
       
   400 -------------------------------------------------------------------------------
       
   401 
       
   402     Class: CTestThreadContainer
       
   403 
       
   404     Method: EnumerateInThread
       
   405 
       
   406     Description: Enumerate test cases. Function calls GetTestCases method
       
   407     from the test module.
       
   408 
       
   409     This function is a static member function, which is intented to be called
       
   410     from the context of the test module thread.
       
   411         
       
   412     Parameters: None
       
   413     
       
   414     Return Values: TInt                           Error code.
       
   415 
       
   416     Errors/Exceptions: None
       
   417 
       
   418     Status: Proposal
       
   419 
       
   420 -------------------------------------------------------------------------------
       
   421 */
       
   422 TInt CTestThreadContainer::EnumerateInThread()
       
   423     {
       
   424 
       
   425     TInt err = KErrNone;
       
   426     __TRACEI ( KInit, ( CStifLogger::EBold, _L("Calling GetTestCasesL") ) );
       
   427 
       
   428     if ( iCases == NULL )
       
   429         {
       
   430         iCases = new RPointerArray<TTestCaseInfo>;
       
   431         if ( iCases == NULL )
       
   432             {
       
   433             ModuleContainer().OperationErrorResult() = KErrNoMemory;
       
   434             __TRACEI ( KError, ( _L("Can't create pointer array for cases") ) );
       
   435             return ModuleContainer().OperationErrorResult();
       
   436             }
       
   437         }
       
   438 
       
   439     // Thread ID logging(For error situations) !!!!! ----------
       
   440     /*
       
   441     RThread t;
       
   442     RDebug::Print(_L("XXXXXXXXXXXXXXXXXXXXXX CurrentThread=[%d]"), t.Id() );
       
   443     t.Open( t.Id() );   
       
   444     RDebug::Print(_L("XXXXXXXXXXXXXXXXXXXXXX Real id=[%d]"), t.Id() );
       
   445     t.Close();
       
   446     */
       
   447     // --------------------------------------------------------
       
   448 
       
   449     ModuleContainer().OperationText() = _L("GetTestCasesL");
       
   450     TRAPD (r, err = iTestModule->GetTestCasesL( 
       
   451                         ModuleContainer().OperationName(),
       
   452                         *iCases ) );
       
   453     ModuleContainer().OperationText() = _L("");
       
   454 
       
   455     // Leave
       
   456     if ( r != KErrNone )
       
   457         {
       
   458         __TRACEI ( KError, ( CStifLogger::ERed, _L("GetTestCasesL leave code %d"), r ) );
       
   459         TName tmpBuffer = _L("Leave from test module GetTestCasesL");        
       
   460         ErrorPrint( 1, tmpBuffer );        
       
   461         FreeEnumerationDataInThread();
       
   462 
       
   463         ModuleContainer().OperationErrorResult() = r;
       
   464         return r;
       
   465         }
       
   466         
       
   467     // Error originating from test module
       
   468     if ( err != KErrNone )
       
   469         {
       
   470         __TRACEI ( KError, ( CStifLogger::ERed, _L("GetTestCasesL returned error %d"), err ) );
       
   471         FreeEnumerationDataInThread();
       
   472 
       
   473         ModuleContainer().ModuleResult() = err;
       
   474         return err;
       
   475         }
       
   476 
       
   477     __TRACEI ( KInit, ( _L("GetTestCasesL successfully called") ) );
       
   478 
       
   479     // All ok.
       
   480     return KErrNone;
       
   481 
       
   482     }
       
   483 
       
   484 /*
       
   485 -------------------------------------------------------------------------------
       
   486 
       
   487     Class: CTestThreadContainer
       
   488 
       
   489     Method: FreeEnumerationDataInThread
       
   490 
       
   491     Description: Frees the enumeration data. This function is called, when
       
   492     the enumeration data is read from execution thread heap to server thread
       
   493     heap. If cases have not been enumerated function does nothing.
       
   494     
       
   495     Function is intented to be called from the context of the test module thread.
       
   496 
       
   497     Parameters: None
       
   498 
       
   499     Return Values: None
       
   500 
       
   501     Errors/Exceptions: None
       
   502 
       
   503     Status: Proposal
       
   504 
       
   505 -------------------------------------------------------------------------------
       
   506 */
       
   507 void CTestThreadContainer::FreeEnumerationDataInThread()
       
   508     {
       
   509 
       
   510     __TRACEI ( KInit, ( _L("Freeing test case array") ) );
       
   511 
       
   512     if ( iCases )
       
   513         {
       
   514         iCases->ResetAndDestroy();
       
   515         delete iCases;
       
   516         iCases = NULL;
       
   517         }
       
   518     
       
   519     __TRACEI ( KInit, ( _L("Freeing test case array done") ) );
       
   520 
       
   521     }
       
   522 
       
   523 /*
       
   524 -------------------------------------------------------------------------------
       
   525 
       
   526     Class: CTestThreadContainer
       
   527 
       
   528     Method: ExecuteTestCaseInThread
       
   529 
       
   530     Description: Execute test case. This function calls either RunTestCase or 
       
   531     ExecuteOOMTestCase to execute and report the results.
       
   532 
       
   533     This function is a static member function, which is intented to be called
       
   534     from the context of the test module thread.
       
   535 
       
   536     Parameters: None
       
   537 
       
   538     Return Values: TInt: Error code
       
   539 
       
   540     Errors/Exceptions: None
       
   541 
       
   542     Status: Approved
       
   543 
       
   544 -------------------------------------------------------------------------------
       
   545 */
       
   546 TInt CTestThreadContainer::ExecuteTestCaseInThread()
       
   547     {        
       
   548     TVersion moduleAPIVersion;
       
   549     moduleAPIVersion = iTestModule->Version(); 
       
   550 
       
   551     __TRACEI ( KInit, 
       
   552         ( CStifLogger::EBold, _L("Executing test case file=[%S] case=%d"), 
       
   553             &ModuleContainer().OperationName(), 
       
   554             ModuleContainer().OperationIntBuffer() ) );
       
   555 
       
   556     TInt r = KErrNone;
       
   557     
       
   558     // Thread handle
       
   559     RThread thisRt;
       
   560     r = DuplicateMutexHandles( thisRt );
       
   561        
       
   562     // Result from RunTestCase       
       
   563     TTestResult caseResult; 
       
   564     
       
   565     // Execution result from RunTestCase
       
   566     TInt err = KErrNone;
       
   567 
       
   568     // Fill in initial values
       
   569     TestExecution().FullResult().iCaseExecutionResultType = 
       
   570         TFullTestResult::ECaseExecuted;
       
   571     TestExecution().FullResult().iCaseExecutionResultCode = KErrNone;            
       
   572     TestExecution().FullResult().iStartTime.HomeTime();
       
   573     TestExecution().TestThreadFailure() = CTestExecution::ETestThreadOk;
       
   574 
       
   575     // Set handle to test execution
       
   576     TRAP( r, CTestModuleIf::NewL( this,
       
   577                                   iTestModule ) );
       
   578 
       
   579     ModuleContainer().OperationText() =_L("RunTestCaseL");
       
   580     
       
   581     // Do resource checks before starting test case
       
   582     iCheckResourceFlags = 0;        
       
   583     
       
   584     TInt tmp;
       
   585     TInt threadHandleCountBeforeTest;
       
   586 
       
   587     // Request count check
       
   588     TInt requestCountBeforeTest = thisRt.RequestCount();
       
   589     // Handle count check, not checking process handles
       
   590     thisRt.HandleCount( tmp, threadHandleCountBeforeTest );
       
   591 
       
   592     // If handle ok, then execute test          
       
   593     if( r == KErrNone )
       
   594         {       
       
   595         TInt testCaseNumber = ModuleContainer().OperationIntBuffer();
       
   596 
       
   597         // Do the test
       
   598         __TRACEI ( KInit, ( _L("About to call RunTestCaseL. If nothing in log \
       
   599             after line \"Calling RunTestCaseL\", check testserver log file.") ) );        
       
   600                     
       
   601         TInt firstMemFailure = 0; 
       
   602         TInt lastMemFailure = 0;        
       
   603         // Store the OOM test type
       
   604         CTestModuleBase::TOOMFailureType failureType;
       
   605                 
       
   606         // Check if the current test case is supposed to be run using OOM
       
   607         if( iTestModule->OOMTestQueryL( ModuleContainer().OperationName(), 
       
   608                                         testCaseNumber, 
       
   609                                         failureType,
       
   610                                         firstMemFailure, 
       
   611                                         lastMemFailure ) )
       
   612             {
       
   613             //  Run the test case in OOM conditions      
       
   614             r = ExecuteOOMTestCase( testCaseNumber, 
       
   615                                     firstMemFailure, 
       
   616                                     lastMemFailure, 
       
   617                                     err, 
       
   618                                     caseResult );
       
   619             }
       
   620         else
       
   621             {
       
   622             // Run the test case the old way, without OOM testing           
       
   623             __TRACEI ( KInit, ( _L("Calling RunTestCaseL - \
       
   624                 OOM condition is not set") ) );
       
   625             TRAP( r, err = iTestModule->RunTestCaseL( 
       
   626                                             testCaseNumber,
       
   627                                             ModuleContainer().OperationName(),
       
   628                                             caseResult ) );
       
   629             }
       
   630         }        
       
   631      
       
   632     // Do resource checks after test case execution
       
   633     // Handle count check
       
   634     TInt threadHandleCountAfterTest;
       
   635     thisRt.HandleCount( tmp, threadHandleCountAfterTest );
       
   636     // Request count check
       
   637     TInt requestCountAfterTest = thisRt.RequestCount();           
       
   638           
       
   639     ModuleContainer().OperationText() =_L("");
       
   640 
       
   641     // Store end time
       
   642     TestExecution().FullResult().iEndTime.HomeTime();   
       
   643     // Remove handle to testexecution 
       
   644     TRAPD( rr, CTestModuleIf::NewL( NULL, iTestModule ) );
       
   645     
       
   646 
       
   647     if ( rr != KErrNone )
       
   648         {        
       
   649         __TRACEI ( KError, ( _L("Memory low in executionthread.") ) );        
       
   650         // Do not actually handle error
       
   651         }
       
   652   
       
   653     // Report test result. Parts of this will be overwritten if error
       
   654     // is detected
       
   655     TestExecution().FullResult().iTestResult = caseResult;
       
   656 
       
   657     // Get target exit reasons
       
   658     CTestModuleIf::TExitReason allowedExitReason;
       
   659     TInt allowedExitCode = KErrNone;
       
   660     ExitReason( allowedExitReason, allowedExitCode );
       
   661     
       
   662     TBool returnLeakCheckFail = EFalse;
       
   663 
       
   664     // Check are STIF macros used
       
   665     if( iTestMacroInfo.iIndication ) 
       
   666         {
       
   667         // STIF macros are used. Set description info, test case to
       
   668         // ECaseExecuted state and case execution result code to KErrNone
       
   669         // to get test case to failed category.
       
   670         TName tmpResultDes;
       
   671         __TRACEI ( KError, ( CStifLogger::ERed, _L("Leave from RunTestCaseL(STIF TF's macro is used)" ) ) );
       
   672         // Set result description
       
   673         tmpResultDes.Copy( _L( "FILE[") );
       
   674         tmpResultDes.Append( iTestMacroInfo.iFileDes );
       
   675         tmpResultDes.Append( _L( "] FUNCTION[" ) );
       
   676         tmpResultDes.Append( iTestMacroInfo.iFunctionDes );
       
   677         tmpResultDes.Append( _L( "] LINE[" ) );
       
   678         tmpResultDes.AppendNum( iTestMacroInfo.iLine );
       
   679         tmpResultDes.Append( _L( "]" ) );
       
   680         // Other result information
       
   681         TestExecution().FullResult().iTestResult.iResult =
       
   682                                             iTestMacroInfo.iReceivedError;
       
   683         TestExecution().FullResult().iTestResult.iResultDes = tmpResultDes;
       
   684         TestExecution().FullResult().iCaseExecutionResultType = 
       
   685                                             TFullTestResult::ECaseExecuted;
       
   686         // Set category to failed cases
       
   687         TestExecution().FullResult().iCaseExecutionResultCode = KErrNone;
       
   688         StifMacroErrorInit(); // Initialization back to default
       
   689         }
       
   690     else if( r != KErrNone )
       
   691         {   // Case has left, overwrite normal result description string
       
   692         __TRACEI ( KError, ( CStifLogger::ERed, _L("Leave from RunTestCaseL, code %d"), r ) );
       
   693         // Set result description
       
   694         TName tmpResultDes = _L("Leave during case:");
       
   695         // Check if there was already some description passed to result object
       
   696         if(caseResult.iResultDes.Length() > 0)
       
   697             {
       
   698             tmpResultDes.Format(_L("Leave during case [%S]:"), &caseResult.iResultDes);
       
   699             if(tmpResultDes.Length() > KStifMaxResultDes)
       
   700                 {
       
   701                 tmpResultDes.SetLength(KStifMaxResultDes);
       
   702                 }
       
   703             }
       
   704         // Other result information
       
   705         TestExecution().FullResult().iTestResult.iResult = KErrGeneral;
       
   706         TestExecution().FullResult().iTestResult.iResultDes = tmpResultDes;
       
   707         TestExecution().FullResult().iCaseExecutionResultType = 
       
   708             TFullTestResult::ECaseLeave;
       
   709         TestExecution().FullResult().iCaseExecutionResultCode = r;
       
   710         }    
       
   711     else if ( err != KErrNone )
       
   712         {   
       
   713         // Case has returned error (e.g. case not found )       
       
   714         __TRACEI ( KError, ( CStifLogger::ERed, _L("RunTestCaseL returned error %d"), err ) ); 
       
   715         TestExecution().FullResult().iCaseExecutionResultType = 
       
   716             TFullTestResult::ECaseErrorFromModule;
       
   717         TestExecution().FullResult().iCaseExecutionResultCode = err;
       
   718         }
       
   719     else if ( allowedExitReason != CTestModuleIf::ENormal )
       
   720         {
       
   721         // Test is failed, because it should end to panic or exception.
       
   722         __TRACEI ( KInit, ( _L("Case ended normally even if it should end to panic/exception") ) ); 
       
   723         TestExecution().FullResult().iTestResult.iResult = KErrGeneral;
       
   724         TestExecution().FullResult().iTestResult.iResultDes = 
       
   725             _L("Case did not ended to panic/exception");
       
   726         }
       
   727     // If test case is passed, check memory leak, handles etc...    
       
   728     else if( caseResult.iResult == KErrNone )
       
   729         {
       
   730         returnLeakCheckFail = ETrue;
       
   731         }
       
   732    
       
   733    // Test case leak checks
       
   734     // In EKA2 heap size cannot be measured because THeapWalk is no longer supported    
       
   735     LeakChecksForTestCase( returnLeakCheckFail, 
       
   736                            threadHandleCountBeforeTest,
       
   737                            threadHandleCountAfterTest,
       
   738                            requestCountBeforeTest,
       
   739                            requestCountAfterTest );
       
   740 
       
   741     // Close execution specific handles
       
   742 
       
   743     iPrintMutex.Close();
       
   744     iEventMutex.Close();
       
   745     iSndMutex.Close();
       
   746     iRcvMutex.Close();
       
   747     iInterferenceMutex.Close();
       
   748     iMeasurementMutex.Close();
       
   749     iCommandMutex.Close();
       
   750     
       
   751     // The Wait operation is performed to let the message from TestServer 
       
   752     // to TestEngine achieve TestEngine or TestCombiner.   
       
   753     iCommandSem.Wait();
       
   754     
       
   755     // Note: iTestThreadMutex.iClose() mutex will be used later, close in destructor.
       
   756     
       
   757     iPrintSem.Close();
       
   758     iEventSem.Close();
       
   759     iSndSem.Close();
       
   760     iRcvSem.Close();
       
   761     iInterferenceSem.Close();
       
   762     iMeasurementSem.Close();
       
   763     iCommandSem.Close();
       
   764 
       
   765     // Close thread handle 
       
   766     thisRt.Close();
       
   767 
       
   768     __TRACEI ( KVerbose, ( _L("ExecuteTestCase out") ) );
       
   769 
       
   770     // continues from CTestModuleContainer::RunL
       
   771         
       
   772     return KErrNone;
       
   773     }
       
   774 
       
   775 /*
       
   776 -------------------------------------------------------------------------------
       
   777 
       
   778     Class: CTestThreadContainer
       
   779 
       
   780     Method: DuplicateMutexHandles
       
   781 
       
   782     Description: Duplicates mutex handles
       
   783 
       
   784     Parameters: None
       
   785 
       
   786     Return Values: TInt
       
   787 
       
   788     Errors/Exceptions: Panic if duplication fails
       
   789 
       
   790     Status: Approved
       
   791 
       
   792 -------------------------------------------------------------------------------
       
   793 */
       
   794 TInt CTestThreadContainer::DuplicateMutexHandles( RThread& aThread )
       
   795     {
       
   796     // For duplicating mutexes
       
   797     iPrintMutex.SetHandle( TestExecution().PrintMutexHandle() );
       
   798     iEventMutex.SetHandle( TestExecution().EventMutexHandle() );
       
   799     iSndMutex.SetHandle( TestExecution().SndMutexHandle() );
       
   800     iRcvMutex.SetHandle( TestExecution().RcvMutexHandle() );
       
   801     iInterferenceMutex.SetHandle( TestExecution().InterferenceMutexHandle() );
       
   802     iMeasurementMutex.SetHandle( TestExecution().MeasurementMutexHandle() );
       
   803     iCommandMutex.SetHandle(TestExecution().CommandMutexHandle());
       
   804 
       
   805     // Mutex for testcomplete and cancel operations. For duplicating mutex
       
   806     iTestThreadMutex.SetHandle( TestExecution().TestThreadMutexHandle() );
       
   807 
       
   808     // For duplicating semaphores
       
   809     iPrintSem.SetHandle( TestExecution().PrintSemHandle() );
       
   810     iEventSem.SetHandle( TestExecution().EventSemHandle() );
       
   811     iSndSem.SetHandle( TestExecution().SndSemHandle() );
       
   812     iRcvSem.SetHandle( TestExecution().RcvSemHandle() );
       
   813     iInterferenceSem.SetHandle( TestExecution().InterferenceSemHandle() );
       
   814     iMeasurementSem.SetHandle( TestExecution().MeasurementSemHandle() );
       
   815     iCommandSem.SetHandle(TestExecution().CommandSemHandle());
       
   816     
       
   817     // Store thread id for later use
       
   818     TestExecution().SetTestThread( aThread.Id() );
       
   819     
       
   820     // Duplicate handles from server thread
       
   821     TRAPD( r,
       
   822         User::LeaveIfError( iPrintMutex.Duplicate( iServerThread ) );
       
   823         User::LeaveIfError( iEventMutex.Duplicate( iServerThread ) );
       
   824         User::LeaveIfError( iSndMutex.Duplicate( iServerThread ) );
       
   825         User::LeaveIfError( iRcvMutex.Duplicate( iServerThread ) );
       
   826         User::LeaveIfError( iInterferenceMutex.Duplicate( iServerThread ) );
       
   827         User::LeaveIfError( iMeasurementMutex.Duplicate( iServerThread ) );
       
   828         User::LeaveIfError( iCommandMutex.Duplicate( iServerThread ) );
       
   829         
       
   830         User::LeaveIfError( iTestThreadMutex.Duplicate( iServerThread ) );
       
   831 
       
   832         User::LeaveIfError( iPrintSem.Duplicate( iServerThread ) );
       
   833         User::LeaveIfError( iEventSem.Duplicate( iServerThread ) );
       
   834         User::LeaveIfError( iSndSem.Duplicate( iServerThread ) );
       
   835         User::LeaveIfError( iRcvSem.Duplicate( iServerThread ) );
       
   836         User::LeaveIfError( iInterferenceSem.Duplicate( iServerThread ) );
       
   837         User::LeaveIfError( iMeasurementSem.Duplicate( iServerThread ) );
       
   838         User::LeaveIfError( iCommandSem.Duplicate( iServerThread ) );
       
   839         );
       
   840 
       
   841     // Raise panic if duplications failed        
       
   842     if( r != KErrNone )
       
   843         {
       
   844         Panic( EDuplicateFail );
       
   845         }
       
   846     
       
   847     // Return the result, no error occurred
       
   848     return KErrNone;            
       
   849     }
       
   850 
       
   851 /*
       
   852 -------------------------------------------------------------------------------
       
   853 
       
   854     Class: CTestThreadContainer
       
   855 
       
   856     Method: ExecuteOOMTestCase
       
   857 
       
   858     Description: Executes OOM test case
       
   859 
       
   860     Parameters: None
       
   861 
       
   862     Return Values: TInt
       
   863 
       
   864     Errors/Exceptions: Panic if EOOMDisableLeakChecks is not set and test case
       
   865     leaks memory.                       
       
   866 
       
   867     Status: Approved
       
   868 
       
   869 -------------------------------------------------------------------------------
       
   870 */
       
   871 TInt CTestThreadContainer::ExecuteOOMTestCase( TInt aTestCaseNumber,
       
   872                                                TInt aFirst, 
       
   873                                                TInt aLast, 
       
   874                                                TInt& aResult, 
       
   875                                                TTestResult& caseResult )
       
   876     {
       
   877     TBool OOMwarning = EFalse;  
       
   878     __TRACEI ( KInit, ( _L("CTestThreadContainer::ExecuteOOMTestCase") ) );            
       
   879     __TRACEI ( KInit, ( _L("Executing test case #%d using OOM"), aTestCaseNumber ) );               
       
   880     
       
   881     // OOM test environment initialization
       
   882     TRAPD( r, iTestModule->OOMTestInitializeL( 
       
   883                                 ModuleContainer().OperationName(),
       
   884                                 aTestCaseNumber ); );               
       
   885     
       
   886     for( TInt i=aFirst; i<aLast; i++ )
       
   887         {   
       
   888         // Fail the i:nth heap allocation
       
   889         User::__DbgSetAllocFail( RHeap::EUser, RHeap::EFailNext, i  );
       
   890         
       
   891         //__TRACEI ( KInit, ( _L("Setting %d:nth heap allocation to fail"), i  ) );             
       
   892                 
       
   893         // Intersection of iCheckResourceFlags and 
       
   894         // EDisableMemoryLeakChecksInOOM to check if memory leak checks are to 
       
   895         // be used with OOM testing.        
       
   896         if( !( iCheckResourceFlags & CTestModuleIf::EOOMDisableLeakChecks ) )
       
   897             {
       
   898             User::__DbgMarkStart( RHeap::EUser );
       
   899             }
       
   900             
       
   901         TRAP( r, aResult = iTestModule->RunTestCaseL( 
       
   902                         aTestCaseNumber,
       
   903                         ModuleContainer().OperationName(),
       
   904                         caseResult ) );
       
   905         
       
   906         // Raise panic if test case leaks memory and EOOMDisableLeakChecks is not
       
   907         // set        
       
   908         if( !( iCheckResourceFlags & CTestModuleIf::EOOMDisableLeakChecks ) )
       
   909             {
       
   910             User::__DbgMarkEnd( RHeap::EUser, 0 );
       
   911             }
       
   912         
       
   913         // If no error occurred, fake a memory error to make sure that this is
       
   914         // the last test. If this last allocation goes wrong, it proves that 
       
   915         // either the FAILNEXT() macro has reached its limit or that somewhere
       
   916         // in the code some object TRAPped the OOM exception and did not leave.     
       
   917         if( ( r != KErrNoMemory ) && ( aResult != KErrNoMemory  )
       
   918             && ( caseResult.iResult != KErrNoMemory ) )
       
   919             {
       
   920             TInt* dummy = new TInt;
       
   921             OOMwarning = ( dummy != NULL );
       
   922             delete dummy;
       
   923             }
       
   924 
       
   925         // Cancel the simulated heap allocation failure
       
   926         User::__DbgSetAllocFail( RHeap::EUser, RHeap::ENone, 1 );
       
   927     
       
   928         if( ( r != KErrNoMemory ) && !OOMwarning && ( aResult != KErrNoMemory )
       
   929             && ( caseResult.iResult != KErrNoMemory ) )
       
   930             {
       
   931             // If we get here test was executed properly (= no memory error
       
   932             // and no warning)
       
   933             break;
       
   934             }
       
   935 
       
   936         if( OOMwarning )
       
   937             {            
       
   938             // It is possible that during testing some components TRAP the OOM
       
   939             // exception and continue to run (do not leave) or they return an 
       
   940             // error other than KErrNoMemory. These situations are making the
       
   941             // OOM testing really difficult, so they should be detected and 
       
   942             // make the tester aware.
       
   943              
       
   944             // Since each test case might have a specific oppinion on handling
       
   945             // this situation, it is left up to the tester to handle it by 
       
   946             // implementing the OOMHandleWarningL method. STIF will log a
       
   947             // warning and call OOMHandleWarningL method.
       
   948 
       
   949             // Print the OOM error message
       
   950             __TRACEI ( KInit, ( _L("Possible trapped or non-leaving allocation in test case #%d"), i  ) );                          
       
   951 
       
   952             iTestModule->OOMHandleWarningL( ModuleContainer().OperationName(), aTestCaseNumber, i );
       
   953 
       
   954             // Clear the warning flag
       
   955             OOMwarning = EFalse;
       
   956             }
       
   957         }
       
   958         
       
   959     // OOM test environment finalization                    
       
   960     __TRACEI ( KInit, ( _L("Calling OOMTestFinalizeL") ) ); 
       
   961     TRAPD( fres, iTestModule->OOMTestFinalizeL( 
       
   962                                     ModuleContainer().OperationName(), 
       
   963                                     aTestCaseNumber ); );
       
   964     // Check the result
       
   965     if( fres != KErrNone )
       
   966         {
       
   967         __TRACEI ( KInit, ( _L("OOMTestFinalizeL execution failed with error %d"), fres ) );                            
       
   968         }
       
   969                 
       
   970     return r;
       
   971     }
       
   972 
       
   973 /*
       
   974 -------------------------------------------------------------------------------
       
   975 
       
   976     Class: CTestThreadContainer
       
   977 
       
   978     Method: LeakChecksForTestCase
       
   979 
       
   980     Description: Checks test case for memory, handle and request leaks
       
   981 
       
   982     Parameters: None    
       
   983 
       
   984     Return Values: None
       
   985 
       
   986     Errors/Exceptions: None
       
   987 
       
   988     Status: Proposal
       
   989 
       
   990 -------------------------------------------------------------------------------
       
   991 */
       
   992 void CTestThreadContainer::LeakChecksForTestCase( TBool aReturnLeakCheckFail,
       
   993                                                   TInt aThreadHandleCountBeforeTest,
       
   994                                                   TInt aThreadHandleCountAfterTest,
       
   995                                                   TInt aRequestCountBeforeTest, 
       
   996                                                   TInt aRequestCountAfterTest )
       
   997                                                 
       
   998     {      
       
   999     __TRACEI ( KInit, ( _L("CTestThreadContainer::LeakChecksForTestCase") ) );                          
       
  1000 
       
  1001     // Note: Request leaks detection is disabled in UI components testing
       
  1002     if( !( iCheckResourceFlags & CTestModuleIf::ETestLeaksRequests ) && 
       
  1003              ( aRequestCountBeforeTest != aRequestCountAfterTest ) &&
       
  1004              ( !iModuleContainer->GetTestModule()->GetTestServer()->UiTesting()))
       
  1005         {
       
  1006         // Test is failed, because it should end to panic or exception.
       
  1007         __TRACEI ( KError, ( CStifLogger::ERed, 
       
  1008             _L("Asynchronous request leak from test module. Request count before:[%d] and after:[%d] test."),
       
  1009             aRequestCountBeforeTest, aRequestCountAfterTest ) );
       
  1010             
       
  1011         // Set failure status    
       
  1012         TestExecution().TestThreadFailure() |= CTestExecution::ETestRequestLeak;
       
  1013         if( aReturnLeakCheckFail )
       
  1014             {
       
  1015             aReturnLeakCheckFail = EFalse;   // return first fail   
       
  1016 #ifndef STIF_DISABLE_LEAK_CHECK 
       
  1017             // Testcase set to failed when request leak occurred
       
  1018             TestExecution().FullResult().iTestResult.iResult = KErrGeneral;
       
  1019 #endif
       
  1020             TestExecution().FullResult().iTestResult.iResultDes = 
       
  1021                 _L("Asynchronous request leak from testmodule");
       
  1022             TestExecution().FullResult().iTestResult.iResultDes.
       
  1023                 AppendNum( aRequestCountAfterTest );
       
  1024             }
       
  1025         }
       
  1026     // Note: Handle leaks detection is disabled in UI components testing
       
  1027     if( !( iCheckResourceFlags & CTestModuleIf::ETestLeaksHandles ) && 
       
  1028              ( aThreadHandleCountBeforeTest != aThreadHandleCountAfterTest ) &&
       
  1029              ( !iModuleContainer->GetTestModule()->GetTestServer()->UiTesting()) )
       
  1030         {
       
  1031         // Test is failed, because it should end to panic or exception.
       
  1032         __TRACEI ( KError, ( CStifLogger::ERed, 
       
  1033             _L("Thread handle leak from test module. Handle count before:[%d] and after:[%d] test."),
       
  1034             aThreadHandleCountBeforeTest, aThreadHandleCountAfterTest ) ); 
       
  1035             
       
  1036         // Set failure status
       
  1037         TestExecution().TestThreadFailure() |= CTestExecution::ETestHandleLeak;    
       
  1038         if( aReturnLeakCheckFail )
       
  1039             {
       
  1040             aReturnLeakCheckFail = EFalse;   // return first fail   
       
  1041 #ifndef STIF_DISABLE_LEAK_CHECK 
       
  1042             // Testcase is set to failed yet when handle leak occurred
       
  1043             TestExecution().FullResult().iTestResult.iResult = KErrGeneral;
       
  1044 #endif
       
  1045             TestExecution().FullResult().iTestResult.iResultDes = 
       
  1046                 _L("Thread handle leak from testmodule");
       
  1047             TestExecution().FullResult().iTestResult.iResultDes.
       
  1048                 AppendNum( aRequestCountAfterTest );
       
  1049             }
       
  1050         }       
       
  1051     }
       
  1052 
       
  1053 /*
       
  1054 -------------------------------------------------------------------------------
       
  1055 
       
  1056     Class: CTestThreadContainer
       
  1057 
       
  1058     Method: DeleteTestModule
       
  1059 
       
  1060     Description: Deletes a test module
       
  1061 
       
  1062     Parameters: None
       
  1063 
       
  1064     Return Values: None
       
  1065 
       
  1066     Errors/Exceptions: None
       
  1067 
       
  1068     Status: Proposal
       
  1069 
       
  1070 -------------------------------------------------------------------------------
       
  1071 */
       
  1072 void CTestThreadContainer::DeleteTestModule()
       
  1073     {
       
  1074 
       
  1075     __TRACEI ( KInit, ( _L("Deleting test module instance at 0x%x"), iTestModule ) );
       
  1076     // Delete the test module
       
  1077     ModuleContainer().OperationText() = _L("DESTRUCTOR");
       
  1078     TRAPD( r, delete iTestModule );
       
  1079     ModuleContainer().OperationText() = _L("");
       
  1080     iTestModule = NULL;
       
  1081 
       
  1082     if ( r )
       
  1083         {
       
  1084         __TRACEI ( KError, ( _L("Leave when deleting test module, code %d"), r ) );
       
  1085         }
       
  1086 
       
  1087     __TRACEI ( KInit, ( _L("Test module instance deleted") ) );
       
  1088 
       
  1089     }
       
  1090     
       
  1091     /*
       
  1092 -------------------------------------------------------------------------------
       
  1093 
       
  1094     Class: CTestThreadContainer
       
  1095 
       
  1096     Method: TestCases
       
  1097 
       
  1098     Description: Returns constant pointer to test case array
       
  1099 
       
  1100     Parameters: None
       
  1101     
       
  1102     Return Values: const RPointerArray<TTestCaseInfo>*  Test cases
       
  1103 
       
  1104     Errors/Exceptions: None
       
  1105 
       
  1106     Status: Proposal
       
  1107     
       
  1108 -------------------------------------------------------------------------------
       
  1109 */
       
  1110 const RPointerArray<TTestCaseInfo>* CTestThreadContainer::TestCases() const
       
  1111     {
       
  1112     
       
  1113     return iCases;
       
  1114 
       
  1115     }
       
  1116     
       
  1117 /*
       
  1118 -------------------------------------------------------------------------------
       
  1119 
       
  1120     Class: CTestThreadContainer
       
  1121 
       
  1122     Method: ErrorPrint
       
  1123 
       
  1124     Description: Prints error
       
  1125 
       
  1126     Parameters: const TInt aPriority :in: Priority
       
  1127                 TPtrC aError: in: Error
       
  1128 
       
  1129     Return Values: None
       
  1130 
       
  1131     Errors/Exceptions: None
       
  1132 
       
  1133     Status: Proposal
       
  1134 
       
  1135 -------------------------------------------------------------------------------
       
  1136 */
       
  1137 void CTestThreadContainer::ErrorPrint( const TInt aPriority, 
       
  1138                                        TPtrC aError )
       
  1139     {
       
  1140     
       
  1141     // Get access to print stuff
       
  1142     iErrorPrintSem.Wait();
       
  1143     
       
  1144     // Get status variable from server
       
  1145     TRequestStatus* status = 
       
  1146         ModuleContainer().GetRequest( CTestModuleContainer::ERqErrorPrint );
       
  1147     
       
  1148     if( status == NULL )
       
  1149         {
       
  1150         Panic( ENullRequest );
       
  1151         return;
       
  1152         }
       
  1153     
       
  1154     // Fill in progress
       
  1155     TErrorNotification& progress = ModuleContainer().ErrorNotification();
       
  1156     progress.iPriority = aPriority;
       
  1157     progress.iText = aError;
       
  1158     
       
  1159     // Complete action to server
       
  1160     iServerThread.RequestComplete( status, KErrNone );
       
  1161     
       
  1162     }
       
  1163     
       
  1164 /*
       
  1165 -------------------------------------------------------------------------------
       
  1166 
       
  1167     Class: CTestThreadContainer
       
  1168 
       
  1169     Method: DoNotifyPrint
       
  1170 
       
  1171     Description: If print notification available, notification is copied to
       
  1172                     client memory space and request is completed.
       
  1173                  Else new print queue item is created and appended to print 
       
  1174                     queue. If queue is full or memory can't be allocated,
       
  1175                     then message will be discarded.
       
  1176         
       
  1177     Parameters: const TInt aPriority  :       :in:  Priority
       
  1178                 const TStifInfoName& aDes         :in:  Description
       
  1179                 const TName& aBuffer          :in:  Value
       
  1180     
       
  1181     Return Values: None
       
  1182 
       
  1183     Errors/Exceptions: None
       
  1184 
       
  1185     Status: Proposal
       
  1186     
       
  1187 -------------------------------------------------------------------------------
       
  1188 */
       
  1189 void CTestThreadContainer::DoNotifyPrint( const TInt aPriority,
       
  1190                                     const TStifInfoName& aDes,
       
  1191                                     const TName& aBuffer )
       
  1192     {    
       
  1193     // Get access to print stuff
       
  1194     iPrintSem.Wait();
       
  1195     
       
  1196     iPrintMutex.Wait(); // Take mutex to get access to server thread.
       
  1197                         // Between Wait and Signal is critical section and this
       
  1198                         // verifies that iPrintSem and RequestComplete is done
       
  1199                         // successfully.
       
  1200     
       
  1201     // Get status variable from server
       
  1202     TRequestStatus* status = 
       
  1203         TestExecution().GetRq( CTestExecution::ERqPrint );
       
  1204     
       
  1205     if( status == NULL )
       
  1206         {
       
  1207         iPrintMutex.Signal();
       
  1208         Panic( ENullRequest );
       
  1209         return;
       
  1210         }
       
  1211 
       
  1212     if( *status != KRequestPending )
       
  1213         {
       
  1214         // CPrintHandler::DoCancel called before getting here, just return
       
  1215         iPrintMutex.Signal();
       
  1216         return;    
       
  1217         }
       
  1218     // Fill in progress
       
  1219     TTestProgress& progress = TestExecution().TestProgress();
       
  1220     progress.iPosition = aPriority;
       
  1221     progress.iDescription = aDes;
       
  1222     progress.iText = aBuffer;
       
  1223     
       
  1224     // Complete action to server
       
  1225     iServerThread.RequestComplete( status, KErrNone );
       
  1226 
       
  1227     iPrintMutex.Signal();
       
  1228 
       
  1229     }
       
  1230 
       
  1231 /*
       
  1232 -------------------------------------------------------------------------------
       
  1233 
       
  1234     Class: CTestThreadContainer
       
  1235 
       
  1236     Method: DoNotifyEvent
       
  1237 
       
  1238     Description: Forward event request.
       
  1239         
       
  1240     Parameters: const TEventIf: in: Event definition
       
  1241                 TRequestStatus* aStatus: in: TRequestStatus to complete 
       
  1242     
       
  1243     Return Values: None
       
  1244 
       
  1245     Errors/Exceptions: Panics if event array can't be created
       
  1246 
       
  1247     Status: Proposal
       
  1248     
       
  1249 -------------------------------------------------------------------------------
       
  1250 */
       
  1251 TInt CTestThreadContainer::DoNotifyEvent( TEventIf& aEvent, 
       
  1252                                           TRequestStatus* aStatus )
       
  1253     {
       
  1254     
       
  1255     TInt ret = KErrNone;
       
  1256     
       
  1257     // Send event req
       
  1258     SetEventReq( TEventDef::EEventCmd, aEvent, aStatus );
       
  1259     
       
  1260     if( aStatus == NULL )
       
  1261         {
       
  1262         // Synchronous Event command used ->
       
  1263         // Block until completed with ECmdComplete from NotifyEvent
       
  1264         // Cannot be done before ERelEvent, 
       
  1265         // because Unset may be blocking the server  
       
  1266         User::WaitForRequest( iReqStatus ); 
       
  1267         
       
  1268         User::After( 1 );// workaround found for STIF 347 
       
  1269         
       
  1270         // Return result from engine 
       
  1271         ret = iReqStatus.Int();
       
  1272         
       
  1273         }    
       
  1274     
       
  1275     return ret;
       
  1276     
       
  1277     }
       
  1278     
       
  1279 /*
       
  1280 -------------------------------------------------------------------------------
       
  1281 
       
  1282     Class: CTestThreadContainer
       
  1283 
       
  1284     Method: CancelEvent
       
  1285 
       
  1286     Description: Cancels pending event request.
       
  1287         
       
  1288     Parameters: None
       
  1289     
       
  1290     Return Values: None
       
  1291 
       
  1292     Errors/Exceptions: None
       
  1293     
       
  1294     Status: Proposal
       
  1295     
       
  1296 -------------------------------------------------------------------------------
       
  1297 */
       
  1298 void CTestThreadContainer::CancelEvent( TEventIf& aEvent, 
       
  1299                                         TRequestStatus* aStatus )
       
  1300     {
       
  1301 
       
  1302     __TRACEI( KMessage, ( _L( "CTestThreadContainer::CancelEvent(%d): %S [%p]" ), 
       
  1303             aEvent.Type(), &aEvent.Name(), aStatus ) );
       
  1304             
       
  1305     // Send event req
       
  1306     SetEventReq( TEventDef::EEventCmdCancel, aEvent, aStatus );
       
  1307     
       
  1308     }
       
  1309 
       
  1310 /*
       
  1311 -------------------------------------------------------------------------------
       
  1312 
       
  1313     Class: CTestThreadContainer
       
  1314 
       
  1315     Method: SetExitReason
       
  1316 
       
  1317     Description: Set exit reason
       
  1318         
       
  1319     Parameters: const TExitReason aExitReason in: Exit reason
       
  1320                 const TInt aExitCode in: Exit code
       
  1321 
       
  1322     Return Values: None
       
  1323     
       
  1324     Errors/Exceptions: None
       
  1325 
       
  1326     
       
  1327     Status: Proposal
       
  1328     
       
  1329 -------------------------------------------------------------------------------
       
  1330 */
       
  1331 void CTestThreadContainer::SetExitReason( const CTestModuleIf::TExitReason aExitReason, 
       
  1332                                     const TInt aExitCode )
       
  1333     {
       
  1334     
       
  1335     TInt exitCode = aExitCode;
       
  1336     
       
  1337     if( ( aExitReason == CTestModuleIf::ENormal ) &&
       
  1338         ( aExitCode != KErrNone ) )
       
  1339         {
       
  1340         __TRACEI( KError, 
       
  1341             ( _L( "SetExitReason: Exit type normal uses always exit code 0 (given %d is not used)" ), 
       
  1342                 exitCode ) );
       
  1343         exitCode = KErrNone;
       
  1344         }
       
  1345 
       
  1346     ModuleContainer().AllowedExitReason() = aExitReason;
       
  1347     ModuleContainer().AllowedExitCode() = exitCode;              
       
  1348         
       
  1349     }
       
  1350 
       
  1351 /*
       
  1352 -------------------------------------------------------------------------------
       
  1353 
       
  1354     Class: CTestThreadContainer
       
  1355 
       
  1356     Method: SetBehavior
       
  1357 
       
  1358     Description: Set test behaviour.
       
  1359         
       
  1360     Parameters:  const CTestModuleIf::TTestBehavior aType: in: behaviour type 
       
  1361                  TAny* aPtr: in: data
       
  1362 
       
  1363     Return Values: Symbian OS error code.
       
  1364     
       
  1365     Errors/Exceptions: None
       
  1366     
       
  1367     Status: Proposal
       
  1368     
       
  1369 -------------------------------------------------------------------------------
       
  1370 */
       
  1371 TInt CTestThreadContainer::SetBehavior( const CTestModuleIf::TTestBehavior aType, 
       
  1372                                         TAny* /*aPtr*/ )
       
  1373     {
       
  1374     
       
  1375     if( aType & CTestModuleIf::ETestLeaksMem )
       
  1376         {
       
  1377         iCheckResourceFlags |= CTestModuleIf::ETestLeaksMem;
       
  1378         }
       
  1379     if( aType & CTestModuleIf::ETestLeaksRequests )
       
  1380         {
       
  1381         iCheckResourceFlags |= CTestModuleIf::ETestLeaksRequests;
       
  1382         } 
       
  1383     if( aType & CTestModuleIf::ETestLeaksHandles )
       
  1384         {
       
  1385         iCheckResourceFlags |= CTestModuleIf::ETestLeaksHandles;
       
  1386         }
       
  1387     // For OOM testing
       
  1388     if( aType & CTestModuleIf::EOOMDisableLeakChecks )
       
  1389         {
       
  1390         iCheckResourceFlags |= CTestModuleIf::EOOMDisableLeakChecks;
       
  1391         }                
       
  1392     if( !( aType & iCheckResourceFlags ) )
       
  1393         {
       
  1394         return KErrNotFound;
       
  1395         }
       
  1396         
       
  1397     return KErrNone;
       
  1398     
       
  1399     }
       
  1400 
       
  1401 /*
       
  1402 -------------------------------------------------------------------------------
       
  1403 
       
  1404     Class: CTestThreadContainer
       
  1405 
       
  1406     Method: ExitReason
       
  1407 
       
  1408     Description: Gets exit reason
       
  1409         
       
  1410     Parameters: TExitReason& aExitReason out: Exit reason
       
  1411                 TInt& aExitCode out: Exit code
       
  1412 
       
  1413     Return Values: None
       
  1414     
       
  1415     Errors/Exceptions: None
       
  1416     
       
  1417     Status: Proposal
       
  1418     
       
  1419 -------------------------------------------------------------------------------
       
  1420 */
       
  1421 void CTestThreadContainer::ExitReason( CTestModuleIf::TExitReason& aExitReason, 
       
  1422                                    TInt& aExitCode )
       
  1423     {
       
  1424 
       
  1425     aExitReason = ModuleContainer().AllowedExitReason();
       
  1426     aExitCode = ModuleContainer().AllowedExitCode();
       
  1427           
       
  1428         
       
  1429     }
       
  1430     
       
  1431 /*
       
  1432 -------------------------------------------------------------------------------
       
  1433 
       
  1434     Class: CTestThreadContainer
       
  1435 
       
  1436     Method: SetEventReq 
       
  1437 
       
  1438     Description: Sets asynchronous event request.
       
  1439         
       
  1440     Parameters: None
       
  1441     
       
  1442     Return Values: None
       
  1443 
       
  1444     Errors/Exceptions: None
       
  1445     
       
  1446     Status: Proposal
       
  1447     
       
  1448 -------------------------------------------------------------------------------
       
  1449 */
       
  1450 void CTestThreadContainer::SetEventReq( TEventDef::TEventCmdType aType, 
       
  1451                                         TEventIf& aEvent, 
       
  1452                                         TRequestStatus* aStatus )
       
  1453     {
       
  1454     // Get access to event stuff
       
  1455     iEventSem.Wait();
       
  1456 
       
  1457     iEventMutex.Wait(); // Take mutex to get access to server thread.
       
  1458                         // Between Wait and Signal is critical section and this
       
  1459                         // verifies that iPrintSem and RequestComplete is done
       
  1460                         // successfully.
       
  1461     
       
  1462     // Get status variable from server
       
  1463     TRequestStatus* status = 
       
  1464         TestExecution().GetRq( CTestExecution::ERqEvent );
       
  1465     
       
  1466     if( status == NULL )
       
  1467         {
       
  1468         iEventMutex.Signal();
       
  1469         Panic( ENullRequest );
       
  1470         return;
       
  1471         }
       
  1472     if( *status != KRequestPending )
       
  1473         {
       
  1474         // CEventHandler::DoCancel called before getting here, just return
       
  1475         iEventMutex.Signal();
       
  1476         return;    
       
  1477         }
       
  1478     
       
  1479     // Fill in event on server thread
       
  1480     TEventDef& event = TestExecution().EventDef();
       
  1481     event.iType = aType;
       
  1482     event.iEvent.Copy( aEvent );
       
  1483 
       
  1484     if( aStatus )
       
  1485         {
       
  1486         // Store TRequestStatus which is completed when next EEnable comes in
       
  1487         event.iStatus = aStatus;
       
  1488         } 
       
  1489     else
       
  1490         {
       
  1491         iReqStatus = KRequestPending;
       
  1492         event.iStatus = &iReqStatus;
       
  1493         }   
       
  1494 
       
  1495     __TRACEI( KMessage ,(_L("SetReq Stat %d, %x"), this, 
       
  1496         aStatus ));
       
  1497     
       
  1498     // Complete action to server
       
  1499     iServerThread.RequestComplete( status, KErrNone );
       
  1500     
       
  1501     iEventMutex.Signal();
       
  1502 
       
  1503     }
       
  1504 
       
  1505 /*
       
  1506 -------------------------------------------------------------------------------
       
  1507 
       
  1508     Class: CTestThreadContainer
       
  1509 
       
  1510     Method: DoRemoteReceive
       
  1511 
       
  1512     Description: Enable remote receive and send.
       
  1513     
       
  1514     Parameters: 
       
  1515     
       
  1516     Return Values: None
       
  1517 
       
  1518     Errors/Exceptions: None
       
  1519 
       
  1520     Status: Proposal
       
  1521     
       
  1522 -------------------------------------------------------------------------------
       
  1523 */
       
  1524 void CTestThreadContainer::DoRemoteReceive( TStifCommand aRemoteCommand,
       
  1525                                             TParams aParams,
       
  1526                                             TInt aLen,
       
  1527                                             TRequestStatus& aStatus )
       
  1528     {    
       
  1529     
       
  1530     switch( aRemoteCommand )
       
  1531         {
       
  1532         case EStifCmdSend:             // "Send"
       
  1533         case EStifCmdReboot:           // "Send"
       
  1534         case EStifCmdStoreState:       // "Send"
       
  1535         case EStifCmdGetStoredState:   // "Receive, this must be done with two phase"
       
  1536         case EStifCmdMeasurement:      // "Receive"
       
  1537             {
       
  1538             __TRACEI( KMessage, ( _L( "CTestThreadContainer::DoRemoteReceive Wait SndSem" ) ) );
       
  1539             
       
  1540             // Get access to sender 
       
  1541             // (for receive, used for securing access to shared memory)
       
  1542             iSndSem.Wait();
       
  1543 
       
  1544             iSndMutex.Wait();   // Take mutex to get access to server thread.
       
  1545                                 // Between Wait and Signal is critical section and this
       
  1546                                 // verifies that iPrintSem and RequestComplete is done
       
  1547                                 // successfully.
       
  1548 
       
  1549             // Get status variable from server
       
  1550             TRequestStatus* status = 
       
  1551                 TestExecution().GetRq( CTestExecution::ERqSnd );
       
  1552 
       
  1553             if( status == NULL )
       
  1554                 {
       
  1555                 iSndMutex.Signal();
       
  1556                 Panic( ENullRequest );
       
  1557                 return;
       
  1558                 }
       
  1559             if( *status != KRequestPending )
       
  1560                 {
       
  1561                 // CSndHandler::DoCancel called before getting here, just return
       
  1562                 iSndMutex.Signal();
       
  1563                 return;    
       
  1564                 }                
       
  1565 
       
  1566             // Fill in information
       
  1567             TCmdDef& aDef = TestExecution().SndInfo();
       
  1568             aDef.iCommand = aRemoteCommand;
       
  1569             aDef.iParam = aParams;
       
  1570             aDef.iLen = aLen;
       
  1571             aDef.iStatus = &aStatus;
       
  1572             
       
  1573             __TRACEI( KMessage ,
       
  1574                 (_L("CTestThreadContainer::DoRemoteReceive Complete request 0x%x"),
       
  1575                     status ));
       
  1576             // Complete action to server
       
  1577             iServerThread.RequestComplete( status, KErrNone );  
       
  1578 
       
  1579             iSndMutex.Signal();
       
  1580             }
       
  1581             break;
       
  1582         case EStifCmdReceive:          // "Receive"
       
  1583              {
       
  1584             __TRACEI( KMessage, ( _L( "CTestThreadContainer::DoRemoteReceive Wait RcvSem" ) ) );
       
  1585 
       
  1586             // Get access to receive handler 
       
  1587             iRcvSem.Wait();
       
  1588 
       
  1589             iRcvMutex.Wait();   // Take mutex to get access to server thread.
       
  1590                                 // Between Wait and Signal is critical section and this
       
  1591                                 // verifies that iPrintSem and RequestComplete is done
       
  1592                                 // successfully.
       
  1593 
       
  1594             // Get status variable from server
       
  1595             TRequestStatus* status = 
       
  1596                 TestExecution().GetRq( CTestExecution::ERqRcv );
       
  1597 
       
  1598             if( status == NULL )
       
  1599                 {
       
  1600                 iRcvMutex.Signal();
       
  1601                 Panic( ENullRequest );
       
  1602                 return;
       
  1603                 }
       
  1604             if( *status != KRequestPending )
       
  1605                 {
       
  1606                 // CRcvHandler::DoCancel called before getting here, just return
       
  1607                 iRcvMutex.Signal();
       
  1608                 return;    
       
  1609                 }                
       
  1610 
       
  1611             // Fill in information
       
  1612             TCmdDef& aDef = TestExecution().RcvInfo();
       
  1613             aDef.iCommand = aRemoteCommand;
       
  1614             aDef.iParam = aParams;
       
  1615             aDef.iLen = aLen;
       
  1616             aDef.iStatus = &aStatus;
       
  1617             
       
  1618             __TRACEI( KMessage ,
       
  1619                 (_L("CTestThreadContainer::DoRemoteReceive Complete request 0x%x"),
       
  1620                     status ));
       
  1621             __TRACEI( KMessage, ( _L( "CTestThreadContainer::DoRemoteReceive signal RcvSem" ) ) );
       
  1622             //iReceiverSem.Signal();
       
  1623 
       
  1624             // Complete action to server
       
  1625             iServerThread.RequestComplete( status, KErrNone );  
       
  1626 
       
  1627             iRcvMutex.Signal();
       
  1628             
       
  1629             }
       
  1630             break;
       
  1631 
       
  1632         default:
       
  1633             TRequestStatus* rs = &aStatus;
       
  1634             User::RequestComplete( rs, KErrNotSupported );
       
  1635             break;
       
  1636         }
       
  1637         
       
  1638     }
       
  1639     
       
  1640 /*
       
  1641 -------------------------------------------------------------------------------
       
  1642 
       
  1643     Class: CTestThreadContainer
       
  1644 
       
  1645     Method: DoRemoteReceiveCancel
       
  1646 
       
  1647     Description: Cancel DoRemoteReceive
       
  1648     
       
  1649     Parameters: None
       
  1650     
       
  1651     Return Values: None
       
  1652 
       
  1653     Errors/Exceptions: None
       
  1654 
       
  1655     Status: Proposal
       
  1656     
       
  1657 -------------------------------------------------------------------------------
       
  1658 */
       
  1659 TInt CTestThreadContainer::DoRemoteReceiveCancel()
       
  1660     {   
       
  1661            
       
  1662     // Get access to receive handler
       
  1663     iRcvSem.Wait();
       
  1664 
       
  1665     iRcvMutex.Wait();   // Take mutex to get access to server thread.
       
  1666                         // Between Wait and Signal is critical section and this
       
  1667                         // verifies that iPrintSem and RequestComplete is done
       
  1668                         // successfully. 
       
  1669 
       
  1670     // Get status variable from server
       
  1671     TRequestStatus* status = 
       
  1672         TestExecution().GetRq( CTestExecution::ERqRcv );
       
  1673 
       
  1674     if( status == NULL )
       
  1675         {
       
  1676         iRcvMutex.Signal();
       
  1677         return KErrNotFound;
       
  1678         }
       
  1679         
       
  1680     if( *status != KRequestPending )
       
  1681         {
       
  1682         // CRcvHandler::DoCancel called before getting here, just return
       
  1683         iRcvMutex.Signal();
       
  1684         Panic( ENullRequest );
       
  1685         return KErrNone;    
       
  1686         }        
       
  1687 
       
  1688     // Fill in information
       
  1689     TCmdDef& aDef = TestExecution().RcvInfo();
       
  1690     aDef.iCommand = EStifCmdReceiveCancel;
       
  1691     // Complete action to server
       
  1692     iServerThread.RequestComplete( status, KErrNone );  
       
  1693     
       
  1694     iRcvMutex.Signal();
       
  1695 
       
  1696     return KErrNone;
       
  1697     
       
  1698     }
       
  1699 
       
  1700 /*
       
  1701 -------------------------------------------------------------------------------
       
  1702 
       
  1703     Class: CTestThreadContainer
       
  1704 
       
  1705     Method: TestComplete
       
  1706 
       
  1707     Description: Complete test operation: Get test case, run test case,
       
  1708                  complete test case, etc.
       
  1709         
       
  1710     Parameters: TInt aCompletionCode: in: completion code.
       
  1711     
       
  1712     Return Values: None
       
  1713 
       
  1714     Errors/Exceptions: None
       
  1715 
       
  1716     Status: Approved
       
  1717     
       
  1718 -------------------------------------------------------------------------------
       
  1719 */
       
  1720 void CTestThreadContainer::TestComplete( TInt aCompletionCode )
       
  1721     {    
       
  1722     
       
  1723     // Get status variable from server
       
  1724     TRequestStatus* status = 
       
  1725         ModuleContainer().GetRequest( CTestModuleContainer::ERqTestCase );
       
  1726     
       
  1727     if( status == NULL )
       
  1728         {
       
  1729         Panic( ENullRequest );
       
  1730         return;
       
  1731         }
       
  1732         
       
  1733     // Complete action to server
       
  1734     if( iTestThreadMutex.Handle() == 0 )
       
  1735         {
       
  1736         // Actual test case is not started yet. Inititialization phase is ongoing.
       
  1737         // Before the completion check if the status was not already completed
       
  1738         // from other thread in CTestModuleContainer::DoCancel().
       
  1739         // For details see Jira STIF-564
       
  1740         if(*status == KRequestPending)
       
  1741             iServerThread.RequestComplete( status, aCompletionCode );
       
  1742         }
       
  1743     else
       
  1744         {
       
  1745         // Test case execution is started. Test is ongoing.
       
  1746         // Before the completion check if the status was not already completed
       
  1747         // from other thread in CTestModuleContainer::DoCancel().
       
  1748         // For details see Jira STIF-564
       
  1749         if(*status == KRequestPending)
       
  1750             {
       
  1751             iTestThreadMutex.Wait(); // Block that complete and cancel do not
       
  1752                                      // executed at the same time.
       
  1753             iServerThread.RequestComplete( status, aCompletionCode );
       
  1754             iTestThreadMutex.Signal();
       
  1755             }            
       
  1756         }
       
  1757     
       
  1758     }
       
  1759 
       
  1760 /*
       
  1761 -------------------------------------------------------------------------------
       
  1762 
       
  1763     Class: CTestThreadContainer
       
  1764 
       
  1765     Method: UIExecutionThread
       
  1766 
       
  1767     Description: This is the test module execution thread "main" function".
       
  1768     All test module function calls are executed in context of this execution
       
  1769     thread.
       
  1770 
       
  1771     When the thread is resumed first time, function goes to wait a semaphore.
       
  1772     Operations are initiated by setting operation and signaling the semaphore.
       
  1773     If operation is synchronous, then end of operation is signaled by using
       
  1774     OperationCompleted -Semaphore. When operation is done, function (and thread)
       
  1775     are going to wait OperationSemaphore.
       
  1776 
       
  1777     Function exist either when operation does fatal error, or operation type
       
  1778     is "Exit". The thread function exist from it's main loop and the thread
       
  1779     will be terminated.
       
  1780 
       
  1781     Parameters: TAny* aParams:                :in:  Pointer to CTestModuleContainer
       
  1782     
       
  1783     Return Values: TInt                        KErrNone
       
  1784 
       
  1785     Errors/Exceptions: None
       
  1786 
       
  1787     Status: Proposal
       
  1788 
       
  1789 -------------------------------------------------------------------------------
       
  1790 */
       
  1791 TInt CTestThreadContainer::UIExecutionThread( TAny* aParams )
       
  1792 	{
       
  1793 	
       
  1794     CTestModuleContainer* moduleContainer = 
       
  1795     	(CTestModuleContainer*) aParams;
       
  1796     
       
  1797     CTestModule* module = moduleContainer->GetTestModule();
       
  1798     CTestServer* testServer = module->GetTestServer();
       
  1799     CTestThreadContainerRunnerFactory* factory = testServer->GetTestThreadContainerRunnerFactory();    
       
  1800     
       
  1801     RThread server;
       
  1802     // Duplicate handles from server thread
       
  1803     TInt ret = server.Open( moduleContainer->ServerThreadId() );
       
  1804     if( ret != KErrNone )
       
  1805     	{
       
  1806     	Panic( EThreadHandleOpenFail );
       
  1807     	}
       
  1808     RSemaphore OperationStartSemaphore;
       
  1809     OperationStartSemaphore.SetHandle( 
       
  1810     		moduleContainer->OperationStartSemHandle() );
       
  1811     if( OperationStartSemaphore.Duplicate( server ) != KErrNone )
       
  1812         {
       
  1813         Panic( EDuplicateFail );
       
  1814         }        
       
  1815     RSemaphore OperationChangeSemaphore;
       
  1816     OperationChangeSemaphore.SetHandle( 
       
  1817     		moduleContainer->OperationChangeSemHandle() );
       
  1818     if( OperationChangeSemaphore.Duplicate( server ) != KErrNone )
       
  1819         {
       
  1820         Panic( EDuplicateFail );
       
  1821         }
       
  1822     server.Close();
       
  1823     
       
  1824     CTestThreadContainerRunner* runner = factory->CreateL();
       
  1825     
       
  1826     runner->Setup( moduleContainer );
       
  1827     
       
  1828     while ( runner->IsReusable() )
       
  1829         {
       
  1830         // Thread is going to suspend        
       
  1831         runner->CheckSignalFromSuspend();
       
  1832         
       
  1833         // Wait next operation
       
  1834         OperationStartSemaphore.Wait();
       
  1835 
       
  1836         // Get operation semaphore
       
  1837         OperationChangeSemaphore.Wait();    
       
  1838     
       
  1839         // Run and wait active object
       
  1840         runner->RunOneIteration();
       
  1841         
       
  1842         OperationChangeSemaphore.Signal();        
       
  1843         }
       
  1844         
       
  1845     OperationStartSemaphore.Close();
       
  1846     OperationChangeSemaphore.Close();        
       
  1847         
       
  1848     runner->TeareDown();
       
  1849     
       
  1850     runner->Deque();
       
  1851     
       
  1852     factory->DeleteL( runner );    
       
  1853     
       
  1854     return KErrNone;    
       
  1855 	}
       
  1856 
       
  1857 
       
  1858 /*
       
  1859 -------------------------------------------------------------------------------
       
  1860 
       
  1861     Class: CTestThreadContainer
       
  1862 
       
  1863     Method: ExecutionThread
       
  1864 
       
  1865     Description: This is the test module execution thread "main" function".
       
  1866     All test module function calls are executed in context of this execution
       
  1867     thread.
       
  1868 
       
  1869     When the thread is resumed first time, function goes to wait a semaphore.
       
  1870     Operations are initiated by setting operation and signaling the semaphore.
       
  1871     If operation is synchronous, then end of operation is signaled by using
       
  1872     OperationCompleted -Semaphore. When operation is done, function (and thread)
       
  1873     are going to wait OperationSemaphore.
       
  1874 
       
  1875     Function exist either when operation does fatal error, or operation type
       
  1876     is "Exit". The thread function exist from it's main loop and the thread
       
  1877     will be terminated.
       
  1878 
       
  1879     Parameters: TAny* aParams:                :in:  Pointer to CTestModuleContainer
       
  1880     
       
  1881     Return Values: TInt                        KErrNone
       
  1882 
       
  1883     Errors/Exceptions: None
       
  1884 
       
  1885     Status: Proposal
       
  1886 
       
  1887 -------------------------------------------------------------------------------
       
  1888 */
       
  1889 TInt CTestThreadContainer::ExecutionThread( TAny* aParams )
       
  1890     {
       
  1891     TInt error( KErrNone );
       
  1892     
       
  1893     const TUint32 KAll = 0xFFFFFFFF;
       
  1894 #ifndef __HIDE_IPC_V1__ // e.g. 7.0s, 8.0a
       
  1895     RThread currentThread;
       
  1896     currentThread.SetExceptionHandler( ExceptionHandler, KAll );
       
  1897 #else // PlatSec used. Thread exception management is part of the User class.
       
  1898     User::SetExceptionHandler( ExceptionHandler, KAll );
       
  1899 #endif // __HIDE_IPC_V1__
       
  1900 
       
  1901      // Check parameters
       
  1902     __ASSERT_ALWAYS( aParams, Panic( EInvalidCTestThreadContainer ) );
       
  1903 
       
  1904     CTestModuleContainer* moduleContainer = 
       
  1905         (CTestModuleContainer*) aParams;
       
  1906        
       
  1907     // Create cleanup stack
       
  1908     CTrapCleanup* tc = CTrapCleanup::New();
       
  1909     __ASSERT_ALWAYS( tc, Panic( ECreateTrapCleanup ) );
       
  1910 
       
  1911     CTestThreadContainer* exec = NULL;    
       
  1912     TRAPD( err,
       
  1913         exec = CTestThreadContainer::NewL( moduleContainer, 
       
  1914                                            moduleContainer->ServerThreadId() );
       
  1915         );    
       
  1916     if( err != KErrNone )
       
  1917         {
       
  1918         Panic( ENullTestThreadContainer );
       
  1919         }
       
  1920 
       
  1921     // Construct the logger
       
  1922     TName path = _L("C:\\logs\\testframework\\testserver\\");
       
  1923     TFileName name = _L("testserver_thread_");  
       
  1924     name.Append( moduleContainer->TestModuleName() );
       
  1925 
       
  1926     // Create logger, in Wins use HTML in HW default logger
       
  1927     TLoggerSettings loggerSettings;
       
  1928 
       
  1929     // Directory must create by hand if test server log wanted
       
  1930     loggerSettings.iCreateLogDirectories = EFalse;
       
  1931 
       
  1932     loggerSettings.iOverwrite = ETrue;
       
  1933     loggerSettings.iTimeStamp = ETrue;
       
  1934     loggerSettings.iLineBreak = ETrue;
       
  1935     loggerSettings.iEventRanking = EFalse;
       
  1936     loggerSettings.iThreadId = EFalse;
       
  1937     loggerSettings.iHardwareFormat = CStifLogger::ETxt;
       
  1938 #ifndef FORCE_STIF_INTERNAL_LOGGING_TO_RDEBUG
       
  1939     loggerSettings.iEmulatorFormat = CStifLogger::EHtml;
       
  1940     loggerSettings.iHardwareOutput = CStifLogger::EFile;
       
  1941     loggerSettings.iEmulatorOutput = CStifLogger::EFile;
       
  1942 #else
       
  1943     RDebug::Print( _L( "STIF Test Server's thread logging forced to RDebug" ) );
       
  1944     loggerSettings.iEmulatorFormat = CStifLogger::ETxt;
       
  1945     loggerSettings.iHardwareOutput = CStifLogger::ERDebug;
       
  1946     loggerSettings.iEmulatorOutput = CStifLogger::ERDebug;
       
  1947 #endif
       
  1948     loggerSettings.iUnicode = EFalse;
       
  1949     loggerSettings.iAddTestCaseTitle = EFalse;
       
  1950 
       
  1951     TRAP ( error, exec->iThreadLogger = CStifLogger::NewL( path, name,
       
  1952                                                             loggerSettings ) );
       
  1953 
       
  1954     RLibrary module;                    // Handle to test module library
       
  1955     TBool reusable = ETrue;             // Is test module reusable?
       
  1956     TBool initialized = EFalse;         // Is module initialized?
       
  1957     TBool signalFromSuspend = EFalse;   // Send signal from suspend state?
       
  1958 
       
  1959     RThread server;
       
  1960     // Duplicate handles from server thread
       
  1961     TInt ret = server.Open( moduleContainer->ServerThreadId() );
       
  1962     if( ret != KErrNone )
       
  1963     	{
       
  1964     	Panic( EThreadHandleOpenFail );
       
  1965     	}
       
  1966     RSemaphore OperationStartSemaphore;
       
  1967     OperationStartSemaphore.SetHandle( 
       
  1968         exec->ModuleContainer().OperationStartSemHandle() );
       
  1969     if( OperationStartSemaphore.Duplicate( server ) != KErrNone )
       
  1970         {
       
  1971         Panic( EDuplicateFail );
       
  1972         }        
       
  1973     RSemaphore OperationChangeSemaphore;
       
  1974     OperationChangeSemaphore.SetHandle( 
       
  1975         exec->ModuleContainer().OperationChangeSemHandle() );
       
  1976     if( OperationChangeSemaphore.Duplicate( server ) != KErrNone )
       
  1977         {
       
  1978         Panic( EDuplicateFail );
       
  1979         }
       
  1980     server.Close();
       
  1981    
       
  1982     
       
  1983     ret = KErrNone;
       
  1984 
       
  1985     // The test module thread will stay in this loop until it either
       
  1986     // dies or is exited nicely.
       
  1987     while ( reusable )
       
  1988         {
       
  1989         // Thread is going to suspend
       
  1990         
       
  1991         if ( signalFromSuspend )
       
  1992             {
       
  1993             signalFromSuspend = EFalse;
       
  1994             exec->TestComplete( ret );
       
  1995             }
       
  1996         ret = KErrNone;
       
  1997         
       
  1998         // Wait next operation
       
  1999         OperationStartSemaphore.Wait();
       
  2000 
       
  2001         // Get operation semaphore
       
  2002         OperationChangeSemaphore.Wait();
       
  2003         switch ( moduleContainer->OperationType() )
       
  2004             {
       
  2005 
       
  2006             // Test module initialisation
       
  2007             case CTestModuleContainer::EInitializeModule:
       
  2008                 {
       
  2009                 __ASSERT_ALWAYS ( !initialized,
       
  2010                                   Panic( EReInitializingTestModule ) );
       
  2011 
       
  2012                 // Initialize module
       
  2013                 if ( exec->InitializeModuleInThread( module ) == KErrNone )
       
  2014                     {
       
  2015                     initialized = ETrue;
       
  2016                     }
       
  2017 
       
  2018                 signalFromSuspend = ETrue;
       
  2019                 break;
       
  2020                 }
       
  2021 
       
  2022             // Test case enumeration
       
  2023             case CTestModuleContainer::EEnumerateInThread:
       
  2024                 {
       
  2025                 __ASSERT_ALWAYS ( initialized,
       
  2026                                   Panic( ETestModuleNotInitialized ) );
       
  2027                 ret = exec->EnumerateInThread();
       
  2028 
       
  2029                 signalFromSuspend = ETrue;
       
  2030                 break;
       
  2031                 }
       
  2032 
       
  2033             // Free test case enumeration data
       
  2034             case CTestModuleContainer::EFreeEnumerationData:
       
  2035                 {
       
  2036                 __ASSERT_ALWAYS ( initialized,
       
  2037                                   Panic( ETestModuleNotInitialized ) );
       
  2038                 exec->FreeEnumerationDataInThread ();
       
  2039                 
       
  2040                 signalFromSuspend = ETrue;
       
  2041                 break;
       
  2042                 }
       
  2043 
       
  2044             // Execute test case
       
  2045             case CTestModuleContainer::EExecuteTestInThread:
       
  2046                 {
       
  2047                 __ASSERT_ALWAYS ( initialized,
       
  2048                                   Panic( ETestModuleNotInitialized ) );
       
  2049                 ret = exec->ExecuteTestCaseInThread ();
       
  2050 
       
  2051                 signalFromSuspend = ETrue;
       
  2052                 break;
       
  2053                 }
       
  2054 
       
  2055             // Exiting (i.e test server is unloading)
       
  2056             case CTestModuleContainer::EExit:
       
  2057                 {
       
  2058                 reusable = EFalse;
       
  2059                 break;
       
  2060                 }
       
  2061 
       
  2062             // Illegal state
       
  2063             default:
       
  2064                 {
       
  2065                 Panic( EInvalidTestModuleOperation );
       
  2066                 }
       
  2067             }
       
  2068             OperationChangeSemaphore.Signal();
       
  2069         
       
  2070         }
       
  2071         
       
  2072     OperationStartSemaphore.Close();
       
  2073     OperationChangeSemaphore.Close();
       
  2074 
       
  2075     exec->DeleteTestModule();
       
  2076 
       
  2077     // Close handle to module. No function calls to test
       
  2078     // module are possible after this line.
       
  2079     module.Close();
       
  2080 
       
  2081     // Delete logger    
       
  2082     delete exec->iThreadLogger;
       
  2083     exec->iThreadLogger = NULL;
       
  2084 
       
  2085     // Delete clean-up stack.
       
  2086     delete tc;
       
  2087     tc = NULL;
       
  2088 
       
  2089     // Operation completed ( = Exit completed )
       
  2090     exec->TestComplete( KErrNone );
       
  2091     
       
  2092     delete exec;
       
  2093     
       
  2094     return KErrNone;
       
  2095 
       
  2096     }
       
  2097 
       
  2098 /*
       
  2099 -------------------------------------------------------------------------------
       
  2100 
       
  2101     Class: CTestThreadContainer
       
  2102 
       
  2103     Method: Panic
       
  2104 
       
  2105     Description: Panicing function for test thread.
       
  2106 
       
  2107     Parameters: TPanicReason aReason: in: Reason code
       
  2108     
       
  2109     Return Values: None
       
  2110 
       
  2111     Errors/Exceptions: None
       
  2112 
       
  2113     Status: Proposal
       
  2114 
       
  2115 -------------------------------------------------------------------------------
       
  2116 */
       
  2117 void CTestThreadContainer::Panic( TPanicReason aReason )
       
  2118     {
       
  2119     
       
  2120     RDebug::Print( _L("CTestThreadContainer::Panic %d"), aReason );
       
  2121     
       
  2122     User::Panic( _L("CTestThreadContainer::Panic"), aReason );
       
  2123     
       
  2124     }
       
  2125 /*
       
  2126 -------------------------------------------------------------------------------
       
  2127 
       
  2128     Class: CTestThreadContainer
       
  2129 
       
  2130     Method: ServerAlive
       
  2131 
       
  2132     Description: Check that server is alive.
       
  2133 
       
  2134     Parameters: None
       
  2135     
       
  2136     Return Values: None
       
  2137 
       
  2138     Errors/Exceptions: Panics thread if server has died.
       
  2139 
       
  2140     Status: Proposal
       
  2141 
       
  2142 -------------------------------------------------------------------------------
       
  2143 */
       
  2144 void CTestThreadContainer::IsServerAlive() const
       
  2145     {
       
  2146         
       
  2147     if( iServerThread.ExitType() != EExitPending ) 
       
  2148         {
       
  2149         // Server thread has died
       
  2150         __RDEBUG( ( _L( "Server died" ) ) );
       
  2151         Panic( EServerDied );
       
  2152         }
       
  2153         
       
  2154     }
       
  2155     
       
  2156 /*
       
  2157 -------------------------------------------------------------------------------
       
  2158 
       
  2159     Class: CTestThreadContainer
       
  2160 
       
  2161     Method: TestExecution
       
  2162 
       
  2163     Description: Return CTestExecution handle to "parent" i.e. server.
       
  2164 
       
  2165     Parameters: None
       
  2166     
       
  2167     Return Values: CTestExecution&
       
  2168 
       
  2169     Errors/Exceptions: Panics thread if server has died.
       
  2170 
       
  2171     Status: Proposal
       
  2172 
       
  2173 -------------------------------------------------------------------------------
       
  2174 */
       
  2175 CTestExecution& CTestThreadContainer::TestExecution() const
       
  2176     { 
       
  2177     
       
  2178     IsServerAlive();
       
  2179     CTestExecution* execution = iModuleContainer->TestExecution();
       
  2180     if( execution == NULL )
       
  2181         {
       
  2182         Panic( ENullExecution );
       
  2183         }
       
  2184     return *execution;
       
  2185     
       
  2186     };
       
  2187 
       
  2188 /*
       
  2189 -------------------------------------------------------------------------------
       
  2190 
       
  2191     Class: CTestThreadContainer
       
  2192 
       
  2193     Method: GetTestCaseArguments
       
  2194 
       
  2195     Description: Get test case arguments
       
  2196 
       
  2197     Parameters: None
       
  2198     
       
  2199     Return Values: test case arguments
       
  2200 
       
  2201     Errors/Exceptions: 
       
  2202 
       
  2203     Status: Proposal
       
  2204 
       
  2205 -------------------------------------------------------------------------------
       
  2206 */
       
  2207 const TDesC& CTestThreadContainer::GetTestCaseArguments() const
       
  2208     {
       
  2209     return TestExecution().GetTestCaseArguments();
       
  2210     }
       
  2211 
       
  2212 
       
  2213 /*
       
  2214 -------------------------------------------------------------------------------
       
  2215 
       
  2216     Class: CTestThreadContainer
       
  2217 
       
  2218     Method: TestExecution
       
  2219 
       
  2220     Description: Return CTestExecution handle to "parent" i.e. server.
       
  2221 
       
  2222     Parameters: None
       
  2223     
       
  2224     Return Values: CTestExecution&
       
  2225 
       
  2226     Errors/Exceptions: Panics thread if server has died.
       
  2227 
       
  2228     Status: Proposal
       
  2229 
       
  2230 -------------------------------------------------------------------------------
       
  2231 */
       
  2232 CTestModuleContainer& CTestThreadContainer::ModuleContainer()
       
  2233     { 
       
  2234     
       
  2235     IsServerAlive();
       
  2236     return *iModuleContainer; 
       
  2237     
       
  2238     };
       
  2239  
       
  2240 /*
       
  2241 -------------------------------------------------------------------------------
       
  2242 
       
  2243     Class: CTestThreadContainer
       
  2244 
       
  2245     Method: ExceptionHandler
       
  2246 
       
  2247     Description: Test execution thread exception handler
       
  2248 
       
  2249     Just kill thread. Undertaker handles rest.
       
  2250 
       
  2251     Parameters: TExcType: in: Exception type
       
  2252     
       
  2253     Return Values: None
       
  2254 
       
  2255     Errors/Exceptions: This function kills the thread where it is executed in.
       
  2256 
       
  2257     Status: Proposal
       
  2258     
       
  2259 -------------------------------------------------------------------------------
       
  2260 */
       
  2261 void CTestThreadContainer::ExceptionHandler ( TExcType aType )
       
  2262     {
       
  2263 
       
  2264     // Kill the current thread, undertaker handles rest
       
  2265     RThread current;
       
  2266     current.Kill( aType );
       
  2267 
       
  2268     // This line is never executed, because thread has been killed.
       
  2269     }
       
  2270 
       
  2271 /*
       
  2272 -------------------------------------------------------------------------------
       
  2273 
       
  2274     Class: CTestThreadContainer
       
  2275 
       
  2276     Method: StifMacroErrorInit
       
  2277 
       
  2278     Description: STIF TF's macro. Initialized TTestMacro.
       
  2279 
       
  2280     Parameters: None
       
  2281     
       
  2282     Return Values: None
       
  2283 
       
  2284     Errors/Exceptions: None
       
  2285 
       
  2286     Status: Proposal
       
  2287     
       
  2288 -------------------------------------------------------------------------------
       
  2289 */
       
  2290 void CTestThreadContainer::StifMacroErrorInit()
       
  2291     {
       
  2292     iTestMacroInfo.iIndication = EFalse;
       
  2293     iTestMacroInfo.iFileDes = KNullDesC;
       
  2294     iTestMacroInfo.iFunctionDes = KNullDesC;
       
  2295     iTestMacroInfo.iLine = 0;
       
  2296     iTestMacroInfo.iReceivedError = 0;
       
  2297 
       
  2298     }
       
  2299 
       
  2300 /*
       
  2301 -------------------------------------------------------------------------------
       
  2302 
       
  2303     Class: CTestThreadContainer
       
  2304 
       
  2305     Method: StifMacroError
       
  2306 
       
  2307     Description: STIF TF's macros. Saves information for later use.
       
  2308 
       
  2309     Parameters: TInt aMacroType: in: Macro type(0:TL, 1:T1L, 2:T2L, etc.)
       
  2310                 TDesC& aFile: in: Modified file information.
       
  2311                 TDesC& aFunction: in: Modified function information.
       
  2312                 TInt aLine: in: Line information.
       
  2313                 TInt aResult: in: Received result.
       
  2314                 TInt aExpected1: in: Expected result from user.
       
  2315                 TInt aExpected2: in: Expected result from user.
       
  2316                 TInt aExpected3: in: Expected result from user.
       
  2317                 TInt aExpected4: in: Expected result from user.
       
  2318                 TInt aExpected5: in: Expected result from user.
       
  2319     
       
  2320     Return Values: Symbian OS error code
       
  2321 
       
  2322     Errors/Exceptions: None
       
  2323 
       
  2324     Status: Proposal
       
  2325     
       
  2326 -------------------------------------------------------------------------------
       
  2327 */
       
  2328 TInt CTestThreadContainer::StifMacroError( TInt aMacroType,
       
  2329                                            const TText8* aFile,
       
  2330                                            const char* aFunction,
       
  2331                                            TInt aLine,
       
  2332                                            TInt aResult,
       
  2333                                            TInt aExpected1,
       
  2334                                            TInt aExpected2,
       
  2335                                            TInt aExpected3,
       
  2336                                            TInt aExpected4,
       
  2337                                            TInt aExpected5 )
       
  2338     {
       
  2339     TStifMacroDes file;
       
  2340     TStifMacroDes function;
       
  2341 
       
  2342     // Modifies aFile and aFunction lengths if nesessarily.
       
  2343     // File and function maximun length is KStifMacroMax.
       
  2344     SetMacroInformation( KStifMacroMax, KStifMacroMax, 
       
  2345                             aFile, aFunction, file, function );
       
  2346 
       
  2347     // Log more information to file and rdebug
       
  2348     switch( aMacroType )
       
  2349         {
       
  2350         case 0: // TL macro
       
  2351             {
       
  2352             __TRACEI( KError, ( CStifLogger::ERed, 
       
  2353                 _L( "FAIL: STIF TF's macro. FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2354                 &file, &function, aLine ) );
       
  2355             RDebug::Print( 
       
  2356                 _L( "FAIL: STIF TF's macro. FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2357                 &file, &function, aLine );
       
  2358             break;
       
  2359             }
       
  2360        case 1: // T1L macro
       
  2361             {
       
  2362            __TRACEI( KError, ( CStifLogger::ERed,
       
  2363                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2364                 aResult, aExpected1, &file, &function, aLine ) );
       
  2365             RDebug::Print( 
       
  2366                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2367                 aResult, aExpected1, &file, &function, aLine );
       
  2368             break;
       
  2369             }
       
  2370        case 2: // T2L macro
       
  2371             {
       
  2372             __TRACEI( KError, ( CStifLogger::ERed,
       
  2373                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2374                 aResult, aExpected1, aExpected2, &file, &function, aLine ) );
       
  2375             RDebug::Print( 
       
  2376                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2377                 aResult, aExpected1, aExpected2, &file, &function, aLine );
       
  2378             break;
       
  2379             }
       
  2380        case 3: // T3L macro
       
  2381             {
       
  2382             __TRACEI( KError, ( CStifLogger::ERed,
       
  2383                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2384                 aResult, aExpected1, aExpected2, aExpected3, &file, &function, aLine ) );
       
  2385             RDebug::Print( 
       
  2386                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2387                 aResult, aExpected1, aExpected2, aExpected3, &file, &function, aLine );
       
  2388             break;
       
  2389             }
       
  2390        case 4: // T4L macro
       
  2391             {
       
  2392             __TRACEI( KError, ( CStifLogger::ERed,
       
  2393                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2394                 aResult, aExpected1, aExpected2, aExpected3, aExpected4, &file, &function, aLine ) );
       
  2395             RDebug::Print( 
       
  2396                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2397                 aResult, aExpected1, aExpected2, aExpected3, aExpected4, &file, &function, aLine );
       
  2398             break;
       
  2399             }
       
  2400        case 5: // T5L macro
       
  2401             {
       
  2402             __TRACEI( KError, ( CStifLogger::ERed,
       
  2403                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2404                 aResult, aExpected1, aExpected2, aExpected3, aExpected4, aExpected5, &file, &function, aLine ) );
       
  2405             RDebug::Print( 
       
  2406                 _L( "FAIL: STIF TF's macro. RECEIVED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], EXPECTED[%d], FILE[%S], FUNCTION[%S], LINE[%d]" ),
       
  2407                 aResult, aExpected1, aExpected2, aExpected3, aExpected4, aExpected5, &file, &function, aLine );
       
  2408             break;
       
  2409             }
       
  2410         default: // default, faulty handling
       
  2411             {
       
  2412             __TRACEI( KError, ( CStifLogger::EError,
       
  2413                 _L( "CTestThreadContainer::StifMacroError(): Macro faulty handling(Macro type is incorrect)" ) ) );
       
  2414             RDebug::Print( 
       
  2415                 _L( "ERROR: CTestThreadContainer::StifMacroError(): Macro faulty handling(Macro type is incorrect)" ) );
       
  2416             return KErrArgument; // Test case goes to crashed category
       
  2417             }        
       
  2418         }
       
  2419 
       
  2420     // Modifies aFile and aFunction lengths if nesessarily.
       
  2421     // File maximun length is KStifMacroMaxFile.
       
  2422     // Function maximun length is KStifMacroMaxFunction.
       
  2423     SetMacroInformation( KStifMacroMaxFile, KStifMacroMaxFunction, 
       
  2424                             aFile, aFunction, file, function );
       
  2425 
       
  2426     // Set information for later use(this information is
       
  2427     // limited and can be seen in UI)
       
  2428     iTestMacroInfo.iIndication = ETrue;
       
  2429     iTestMacroInfo.iFileDes = file;
       
  2430     iTestMacroInfo.iFunctionDes = function;
       
  2431     iTestMacroInfo.iLine = aLine;
       
  2432     if( aResult == KErrNone )
       
  2433         {
       
  2434         // aResult is KErrNone. TL macro is used or expected result(s) are/is
       
  2435         // negative value(s). Received error code is mapped to KErrArgument
       
  2436         // because this is erronous case.
       
  2437         iTestMacroInfo.iReceivedError = KErrArgument;
       
  2438         }
       
  2439     else
       
  2440         {
       
  2441         iTestMacroInfo.iReceivedError = aResult;
       
  2442         }
       
  2443 
       
  2444     return KErrNone;
       
  2445 
       
  2446     }
       
  2447 
       
  2448 /*
       
  2449 -------------------------------------------------------------------------------
       
  2450 
       
  2451     Class: CTestThreadContainer
       
  2452 
       
  2453     Method: SetMacroInformation
       
  2454 
       
  2455     Description: Modifies aRecFile and aRecFunction lengths if nesessarily.
       
  2456 
       
  2457     Parameters: TInt aMaxLength: in: Maximum length of file information.
       
  2458                 TInt aMaxLength: in: Maximum length of function information.
       
  2459                 const TText8* aRecFile: in: Received file information.
       
  2460                 char* aRecFunction: in: Received function information.
       
  2461                 TDes& aFile: inout: Modified file.
       
  2462                 TDes& aFunction: inout: Modified function.
       
  2463 
       
  2464     Return Values: None
       
  2465 
       
  2466     Errors/Exceptions: None
       
  2467 
       
  2468     Status: Proposal
       
  2469 
       
  2470 -------------------------------------------------------------------------------
       
  2471 */
       
  2472 void CTestThreadContainer::SetMacroInformation( TInt aFileMaxLength,
       
  2473                                                 TInt aFuntionMaxLength,
       
  2474                                                 const TText8* aRecFile,
       
  2475                                                 const char* aRecFunction,
       
  2476                                                 TDes& aFile,
       
  2477                                                 TDes& aFunction )
       
  2478     {
       
  2479     // Create 8 to 16
       
  2480     TPtrC8 buf_file;
       
  2481     buf_file.Set( aRecFile );
       
  2482     // File description length is limited. Extracts the rightmost part of the
       
  2483     // data.
       
  2484     aFile.Copy( buf_file.Right( aFileMaxLength ) );
       
  2485     aFile.LowerCase();
       
  2486 
       
  2487     if( aRecFunction )
       
  2488         {
       
  2489         // Create 8 to 16
       
  2490         TPtrC8 buf_func;
       
  2491         buf_func.Set( (const unsigned char*)aRecFunction );
       
  2492         // Function description length is limited. Extracts the leftmost part
       
  2493         // of the data.
       
  2494         aFunction.Copy( buf_func.Left( aFuntionMaxLength ) );
       
  2495         aFunction.LowerCase();
       
  2496         }
       
  2497     else
       
  2498         {
       
  2499         // Function is not given(WINS)
       
  2500         aFunction.Copy( _L( "-" ) );
       
  2501         }
       
  2502 
       
  2503     }
       
  2504 
       
  2505 /*
       
  2506 -------------------------------------------------------------------------------
       
  2507 
       
  2508     Class: CTestThreadContainer
       
  2509 
       
  2510     Method: AddInterferenceThread
       
  2511 
       
  2512     Description: With this can be store information about test interference
       
  2513                  thread to client space.
       
  2514 
       
  2515     Parameters: RThread aSTIFTestInterference: in: Thread information to store
       
  2516 
       
  2517     Return Values: TInt: Symbian OS error code.
       
  2518 
       
  2519     Errors/Exceptions: None
       
  2520 
       
  2521     Status: Proposal
       
  2522 
       
  2523 -------------------------------------------------------------------------------
       
  2524 */
       
  2525 TInt CTestThreadContainer::AddInterferenceThread( 
       
  2526                                 RThread aSTIFTestInterference )
       
  2527     {
       
  2528     // Get access to test interference stuff
       
  2529     iInterferenceSem.Wait();
       
  2530     
       
  2531     iInterferenceMutex.Wait();  // Take mutex to get access to server thread.
       
  2532                                 // Between Wait and Signal is critical section
       
  2533                                 // and this verifies that iInterferenceSem and
       
  2534                                 // RequestComplete is done successfully.
       
  2535     
       
  2536     // Get status variable from server
       
  2537     TRequestStatus* status = 
       
  2538         TestExecution().GetRq( CTestExecution::ERqInterference );
       
  2539     
       
  2540     if( status == NULL )
       
  2541         {
       
  2542         iInterferenceMutex.Signal();
       
  2543         Panic( ENullRequest );
       
  2544         return KErrNone;
       
  2545         }
       
  2546 
       
  2547     if( *status != KRequestPending )
       
  2548         {
       
  2549         // CInterferenceHandler::DoCancel called before getting here,
       
  2550         // just return
       
  2551         iInterferenceMutex.Signal();
       
  2552         return KErrNone;    
       
  2553         }
       
  2554 
       
  2555     // Add thread to Array. Via array can handle test interference thread's
       
  2556     // kill in panic etc. cases
       
  2557     TTestInterference& testInterface = TestExecution().TestInterference();
       
  2558     testInterface.iThreadId = aSTIFTestInterference.Id();    
       
  2559     testInterface.iOperation = TTestInterference::EAppend;
       
  2560 
       
  2561     // Complete action to server
       
  2562     iServerThread.RequestComplete( status, KErrNone );
       
  2563     // Goes to CInterferenceHandler::RunL()
       
  2564 
       
  2565     iInterferenceMutex.Signal();
       
  2566 
       
  2567     return KErrNone;
       
  2568 
       
  2569     }
       
  2570 
       
  2571 /*
       
  2572 -------------------------------------------------------------------------------
       
  2573 
       
  2574     Class: CTestThreadContainer
       
  2575 
       
  2576     Method: RemoveInterferenceThread
       
  2577 
       
  2578     Description: With this can be remove information about test interference
       
  2579                  thread from client space.
       
  2580 
       
  2581     Parameters:  RThread aSTIFTestInterference: in: Thread information to store
       
  2582 
       
  2583     Return Values: TInt: Symbian OS error code.
       
  2584 
       
  2585     Errors/Exceptions: None
       
  2586 
       
  2587     Status: Proposal
       
  2588 
       
  2589 -------------------------------------------------------------------------------
       
  2590 */
       
  2591 TInt CTestThreadContainer::RemoveInterferenceThread( 
       
  2592                                 RThread aSTIFTestInterference )
       
  2593     {
       
  2594     // Get access to test interference stuff
       
  2595     iInterferenceSem.Wait();
       
  2596     
       
  2597     iInterferenceMutex.Wait();  // Take mutex to get access to server thread.
       
  2598                                 // Between Wait and Signal is critical section
       
  2599                                 // and this verifies that iInterferenceSem and
       
  2600                                 // RequestComplete is done successfully.
       
  2601     
       
  2602     // Get status variable from server
       
  2603     TRequestStatus* status = 
       
  2604         TestExecution().GetRq( CTestExecution::ERqInterference );
       
  2605     
       
  2606     if( status == NULL )
       
  2607         {
       
  2608         iInterferenceMutex.Signal();
       
  2609         Panic( ENullRequest );
       
  2610         return KErrNone;
       
  2611         }
       
  2612 
       
  2613     if( *status != KRequestPending )
       
  2614         {
       
  2615         // CInterferenceHandler::DoCancel called before getting here, just return
       
  2616         iInterferenceMutex.Signal();
       
  2617         return KErrNone;    
       
  2618         }
       
  2619 
       
  2620     // Add thread to Array. Via array can handle test interference thread's
       
  2621     // kill in panic etc. cases
       
  2622     TTestInterference& testInterface = TestExecution().TestInterference();
       
  2623     testInterface.iThreadId = aSTIFTestInterference.Id();    
       
  2624     testInterface.iOperation = TTestInterference::ERemove;
       
  2625 
       
  2626     // Complete action to server
       
  2627     iServerThread.RequestComplete( status, KErrNone );
       
  2628     // Goes to CInterferenceHandler::RunL()
       
  2629 
       
  2630     iInterferenceMutex.Signal();
       
  2631 
       
  2632     return KErrNone;
       
  2633 
       
  2634     }
       
  2635 
       
  2636 /*
       
  2637 -------------------------------------------------------------------------------
       
  2638 
       
  2639     Class: CTestThreadContainer
       
  2640 
       
  2641     Method: HandleMeasurementProcess
       
  2642 
       
  2643     Description: With this can be stored information about test measurement
       
  2644                  to TestServer space.
       
  2645 
       
  2646     Parameters: CSTIFTestMeasurement::TMeasurement aSTIFMeasurementInfo: in:
       
  2647                 Struct for measurement information.
       
  2648 
       
  2649     Return Values: TInt: Symbian OS error code.
       
  2650 
       
  2651     Errors/Exceptions: None
       
  2652 
       
  2653     Status: Approved
       
  2654 
       
  2655 -------------------------------------------------------------------------------
       
  2656 */
       
  2657 TInt CTestThreadContainer::HandleMeasurementProcess( 
       
  2658             CSTIFTestMeasurement::TStifMeasurementStruct aSTIFMeasurementInfo )
       
  2659     {
       
  2660     // Get access to test measurement stuff
       
  2661 
       
  2662     // This is syncronous operation and other request cannot executed at the
       
  2663     // same time. In this case iMeasurementSem is not signaled in StarL().
       
  2664     // So iMeasurementSem.Wait(); is not needed in this case.
       
  2665 
       
  2666     iMeasurementMutex.Wait();   // Take mutex to get access to server thread.
       
  2667                                 // Between Wait and Signal is critical section
       
  2668                                 // and this verifies that iMeasurementSem and
       
  2669                                 // RequestComplete is done successfully.
       
  2670 
       
  2671     // Get status variable from server
       
  2672     TRequestStatus* status = 
       
  2673         TestExecution().GetRq( CTestExecution::ERqMeasurement );
       
  2674 
       
  2675     if( status == NULL )
       
  2676         {
       
  2677         iMeasurementMutex.Signal();
       
  2678         Panic( ENullRequest );
       
  2679         return KErrNone;
       
  2680         }
       
  2681 
       
  2682     if( *status != KRequestPending )
       
  2683         {
       
  2684         // CMeasurementHandler::DoCancel called before getting here,
       
  2685         // just return
       
  2686         iMeasurementMutex.Signal();
       
  2687         return KErrNone;
       
  2688         }
       
  2689 
       
  2690     TTestMeasurement& testmeasurement = TestExecution().TestMeasurement();
       
  2691     testmeasurement.iMeasurementStruct = aSTIFMeasurementInfo;
       
  2692 
       
  2693     // Complete action to server
       
  2694     iServerThread.RequestComplete( status, KErrNone );
       
  2695     // Goes to CMeasurementHandler::RunL()
       
  2696 
       
  2697     // Make this synchronous and block until needed operations are done.
       
  2698     iMeasurementSem.Wait();
       
  2699     // This continue here when iMeasurementSem.Signal is said in 
       
  2700     // CMeasurementHandler::RunL(). So when measurement operations are done.
       
  2701 
       
  2702     // Error code from measurement related operations
       
  2703     TInt ret( testmeasurement.iMeasurementStruct.iOperationResult );
       
  2704 
       
  2705     iMeasurementMutex.Signal();
       
  2706 
       
  2707     return ret;
       
  2708 
       
  2709     }
       
  2710 
       
  2711 /*
       
  2712 -------------------------------------------------------------------------------
       
  2713 
       
  2714     Class: CTestThreadContainer
       
  2715 
       
  2716     Method: SetEventReq
       
  2717 
       
  2718     Description: Sets asynchronous event request.
       
  2719 
       
  2720     Parameters: None
       
  2721 
       
  2722     Return Values: None
       
  2723 
       
  2724     Errors/Exceptions: None
       
  2725 
       
  2726     Status: Proposal
       
  2727 
       
  2728 -------------------------------------------------------------------------------
       
  2729 */
       
  2730 void CTestThreadContainer::DoNotifyCommand(TCommand aCommand, const TDesC8& aParamsPckg)
       
  2731     {
       
  2732     // Get access to command stuff
       
  2733     iCommandSem.Wait();
       
  2734 
       
  2735     iCommandMutex.Wait(); // Take mutex to get access to server thread.
       
  2736                           // Between Wait and Signal is critical section and this
       
  2737                           // verifies that iCommandSem and RequestComplete is done
       
  2738                           // successfully.
       
  2739 
       
  2740     // Get status variable from server
       
  2741     TRequestStatus* status = TestExecution().GetRq(CTestExecution::ERqCommand);
       
  2742 
       
  2743     if(status == NULL)
       
  2744         {
       
  2745         iCommandMutex.Signal();
       
  2746         Panic(ENullRequest);
       
  2747         return;
       
  2748         }
       
  2749     if(*status != KRequestPending)
       
  2750         {
       
  2751         iCommandMutex.Signal();
       
  2752         return;
       
  2753         }
       
  2754 
       
  2755     // Fill in information
       
  2756     CCommandDef& aDef = TestExecution().CommandDef();
       
  2757     aDef.iCommand = aCommand;
       
  2758     aDef.iParamsPckg.Copy(aParamsPckg);
       
  2759 
       
  2760     // Complete action to server
       
  2761     iServerThread.RequestComplete(status, KErrNone);
       
  2762 
       
  2763     iCommandMutex.Signal();
       
  2764 
       
  2765     }
       
  2766 
       
  2767 /*
       
  2768 -------------------------------------------------------------------------------
       
  2769 
       
  2770     Class: CTestThreadContainer
       
  2771 
       
  2772     Method: GetTestCaseTitleL
       
  2773 
       
  2774     Description: Gets title of currently running test.
       
  2775 
       
  2776     Parameters: aTestCaseTitle: OUT: test case title descriptor
       
  2777 
       
  2778     Return Values: None
       
  2779 
       
  2780     Errors/Exceptions: None
       
  2781 
       
  2782     Status: Proposal
       
  2783 
       
  2784 -------------------------------------------------------------------------------
       
  2785 */
       
  2786 void CTestThreadContainer::GetTestCaseTitleL(TDes& aTestCaseTitle)
       
  2787     {
       
  2788     ModuleContainer().GetTestCaseTitleL(aTestCaseTitle); 
       
  2789     }
       
  2790 
       
  2791 /*
       
  2792 -------------------------------------------------------------------------------
       
  2793 
       
  2794     Class: CTestThreadContainer
       
  2795 
       
  2796     Method: SetThreadLogger
       
  2797 
       
  2798     Description: Sets thread logger.
       
  2799 
       
  2800     Parameters: CStifLogger* aThreadLogger: in: Pointer to thread logger.
       
  2801 
       
  2802     Return Values: None
       
  2803 
       
  2804     Errors/Exceptions: None
       
  2805 
       
  2806     Status: Proposal
       
  2807 
       
  2808 -------------------------------------------------------------------------------
       
  2809 */
       
  2810 void CTestThreadContainer::SetThreadLogger( CStifLogger* aThreadLogger )
       
  2811 	{
       
  2812 	
       
  2813 	iThreadLogger = aThreadLogger;
       
  2814 	}
       
  2815 
       
  2816 /*
       
  2817 -------------------------------------------------------------------------------
       
  2818 
       
  2819     Class: CTestThreadContainer
       
  2820 
       
  2821     Method: SetThreadLogger
       
  2822 
       
  2823     Description: Gets thread logger.
       
  2824 
       
  2825     Parameters: None
       
  2826 
       
  2827     Return Values: Pointer to CStifLogger. 
       
  2828 
       
  2829     Errors/Exceptions: None
       
  2830 
       
  2831     Status: Proposal
       
  2832 
       
  2833 -------------------------------------------------------------------------------
       
  2834 */
       
  2835 CStifLogger* CTestThreadContainer::GetThreadLogger()
       
  2836 	{
       
  2837 	
       
  2838 	return iThreadLogger;
       
  2839 	}
       
  2840 
       
  2841 /*
       
  2842 -------------------------------------------------------------------------------
       
  2843 
       
  2844     Class: CTestThreadContainer
       
  2845 
       
  2846     Method: UITesting
       
  2847 
       
  2848     Description: Gets information if testserver supports UI testing.
       
  2849 
       
  2850     Parameters: None
       
  2851 
       
  2852     Return Values: True if testserver supports UI testing, False if testserver
       
  2853     			   doesn't support UI testing. 
       
  2854 
       
  2855     Errors/Exceptions: None
       
  2856 
       
  2857     Status: Proposal
       
  2858 
       
  2859 -------------------------------------------------------------------------------
       
  2860 */
       
  2861 EXPORT_C TBool CTestThreadContainer::UITesting()
       
  2862 	{
       
  2863 	
       
  2864 	return iModuleContainer->GetTestModule()->GetTestServer()->UiTesting();	
       
  2865 	}
       
  2866 
       
  2867 /*
       
  2868 -------------------------------------------------------------------------------
       
  2869 
       
  2870     Class: CTestThreadContainer
       
  2871 
       
  2872     Method: GetUiEnvProxy
       
  2873 
       
  2874     Description: Gets UIEnvProxy.
       
  2875 
       
  2876     Parameters: None
       
  2877 
       
  2878     Return Values: Pointer to UIEnvProxy 
       
  2879 
       
  2880     Errors/Exceptions: None
       
  2881 
       
  2882     Status: Proposal
       
  2883 
       
  2884 -------------------------------------------------------------------------------
       
  2885 */
       
  2886 EXPORT_C CUiEnvProxy* CTestThreadContainer::GetUiEnvProxy()
       
  2887 	{
       
  2888 	
       
  2889 	return iModuleContainer->GetTestModule()->GetTestServer()->GetUiEnvProxy();
       
  2890 	}
       
  2891 
       
  2892 // End of File