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