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