stif/TestServer/src/Testundertaker.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 0 a03f92240627
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     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 CUnderTaker 
       
    15 * class member functions. CUnderTaker is a class, which listens 
       
    16 * on Test Execution Thread death, and if that thread dies, then 
       
    17 * UnderTaker aborts the ongoing test execution request.
       
    18 *
       
    19 */
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <e32std.h>
       
    23 #include <e32svr.h>
       
    24 #include "TestEngineClient.h"
       
    25 #include <StifTestModule.h>
       
    26 #include <stifinternal/TestServerClient.h>
       
    27 #include "TestServer.h"
       
    28 #include "TestServerModuleIf.h"
       
    29 #include "TestServerCommon.h"
       
    30 #include "PrintQueue.h"
       
    31 
       
    32 // EXTERNAL DATA STRUCTURES
       
    33 
       
    34 // EXTERNAL FUNCTION PROTOTYPES  
       
    35 
       
    36 // CONSTANTS
       
    37 
       
    38 // MACROS
       
    39 
       
    40 // LOCAL CONSTANTS AND MACROS
       
    41 
       
    42 // MODULE DATA STRUCTURES
       
    43 
       
    44 // LOCAL FUNCTION PROTOTYPES
       
    45 
       
    46 // FORWARD DECLARATIONS
       
    47 
       
    48 // ==================== LOCAL FUNCTIONS =======================================
       
    49 
       
    50 // ================= MEMBER FUNCTIONS =========================================
       
    51 
       
    52 
       
    53 /*
       
    54 -------------------------------------------------------------------------------
       
    55 
       
    56     Class: CUnderTaker
       
    57 
       
    58     Method: NewL
       
    59 
       
    60     Description: Constructs a new CUnderTaker object.
       
    61 
       
    62     Parameters: CTestModuleContainer* aContainer :in:   "Parent"
       
    63 
       
    64     Return Values: CUnderTaker*                         New undertaker
       
    65 
       
    66     Errors/Exceptions: Leaves if memory allocation or ConstructL leaves.
       
    67 
       
    68     Status: Proposal
       
    69 
       
    70 -------------------------------------------------------------------------------
       
    71 */
       
    72 CUnderTaker* CUnderTaker::NewL( CTestModuleContainer* aContainer )
       
    73     {
       
    74 
       
    75     CUnderTaker* self = new( ELeave ) CUnderTaker();
       
    76     CleanupStack::PushL( self );
       
    77     self->ConstructL( aContainer );
       
    78     CleanupStack::Pop( self );
       
    79     return self;
       
    80 
       
    81     }
       
    82 
       
    83 /*
       
    84 -------------------------------------------------------------------------------
       
    85 
       
    86     Class: CUnderTaker
       
    87 
       
    88     Method: ConstructL
       
    89 
       
    90     Description: Second level constructor.
       
    91 
       
    92     Parameters: CTestModuleContainer* aExecution :in:   "Parent"
       
    93 
       
    94     Return Values: None
       
    95 
       
    96     Errors/Exceptions: Panics if aContainer is NULL
       
    97 
       
    98     Status: Proposal
       
    99 
       
   100 -------------------------------------------------------------------------------
       
   101 */
       
   102 void CUnderTaker::ConstructL( CTestModuleContainer* aContainer )
       
   103     {
       
   104 
       
   105     __ASSERT_ALWAYS( aContainer, 
       
   106                      CTestServer::PanicServer( ENullTestModuleContainer ) );
       
   107 
       
   108     iModuleContainer = aContainer;
       
   109 
       
   110     }
       
   111 
       
   112 /*
       
   113 -------------------------------------------------------------------------------
       
   114 
       
   115     Class: CUnderTaker
       
   116 
       
   117     Method: CUnderTaker
       
   118 
       
   119     Description: Constructor
       
   120 
       
   121     Parameters: None
       
   122 
       
   123     Return Values: None
       
   124 
       
   125     Errors/Exceptions: None
       
   126 
       
   127     Status: Proposal
       
   128     
       
   129 -------------------------------------------------------------------------------
       
   130 */
       
   131 CUnderTaker::CUnderTaker() :
       
   132     CActive( CActive::EPriorityHigh+1 )
       
   133     {
       
   134 
       
   135     // By default in asynchronous mode
       
   136     iSynchronousMode = EFalse;
       
   137 
       
   138     }
       
   139 
       
   140 /*
       
   141 -------------------------------------------------------------------------------
       
   142 
       
   143     Class: CUnderTaker
       
   144 
       
   145     Method: ~CUnderTaker
       
   146 
       
   147     Description: Destructor. 
       
   148     Cancels active request.
       
   149 
       
   150     Parameters: None
       
   151 
       
   152     Return Values: None
       
   153 
       
   154     Errors/Exceptions: None
       
   155 
       
   156     Status: Proposal
       
   157     
       
   158 -------------------------------------------------------------------------------
       
   159 */
       
   160 CUnderTaker::~CUnderTaker()
       
   161     {
       
   162 
       
   163     Cancel();
       
   164 
       
   165     }
       
   166 
       
   167 
       
   168 
       
   169 
       
   170 /*
       
   171 -------------------------------------------------------------------------------
       
   172 
       
   173     Class: CUnderTaker
       
   174 
       
   175     Method: StartL
       
   176 
       
   177     Description: Starts to monitor thread.
       
   178 
       
   179     Parameters: None
       
   180 
       
   181     Return Values: TInt                             Always KErrNone
       
   182 
       
   183     Errors/Exceptions: None
       
   184 
       
   185     Status: Proposal
       
   186     
       
   187 -------------------------------------------------------------------------------
       
   188 */
       
   189 TInt CUnderTaker::StartL()
       
   190     {
       
   191     
       
   192     SetActive();
       
   193     iModuleContainer->iThread.Logon( iStatus );
       
   194     iCancelNeeded = ETrue;
       
   195 
       
   196     return KErrNone;
       
   197 
       
   198     }
       
   199 
       
   200 /*
       
   201 -------------------------------------------------------------------------------
       
   202 
       
   203     Class: CUnderTaker
       
   204 
       
   205     Method: RunL
       
   206 
       
   207     Description: Handles thread death.
       
   208     Function does:
       
   209     1 ) Stops monitoring thread
       
   210     1 ) Marks thread death
       
   211     2 ) Completes ongoing requests
       
   212     3 ) Cleans the memory
       
   213 
       
   214     Parameters: None
       
   215 
       
   216     Return Values: None
       
   217 
       
   218     Errors/Exceptions: None
       
   219 
       
   220     Status: Proposal
       
   221 
       
   222 -------------------------------------------------------------------------------
       
   223 */
       
   224 void CUnderTaker::RunL()
       
   225     {
       
   226 
       
   227     // Make sure that any of the test interference thread's won't stay to run.
       
   228     iModuleContainer->KillTestinterferenceThread();
       
   229 
       
   230     // Make sure that any of the test measurement's process won't stay to run.
       
   231     iModuleContainer->KillTestMeasurement();
       
   232 
       
   233     // Get the exit category
       
   234     TName exitCategory = _L( "Crash reason:" );
       
   235     exitCategory.Append( iModuleContainer->iThread.ExitCategory() );
       
   236     TInt exitReason = iModuleContainer->iThread.ExitReason();
       
   237     TFullTestResult::TCaseExecutionResult exitType = TFullTestResult::ECaseException;
       
   238     if( iModuleContainer->iThread.ExitType() == EExitPanic )
       
   239         {
       
   240         exitType = TFullTestResult::ECasePanic;
       
   241         }    
       
   242 
       
   243     // it is not running anymore..
       
   244     iModuleContainer->iUpAndRunning = EFalse;
       
   245 
       
   246     // Do not monitor anymore.
       
   247     iModuleContainer->iThread.LogonCancel( iStatus );
       
   248     iCancelNeeded = EFalse;
       
   249 
       
   250     __TRACE( KError,( CStifLogger::ERed, _L( "Execution thread crashed, exitReason = %d" ), exitReason ) );
       
   251     __TRACE( KError,( CStifLogger::ERed, exitCategory ) );    
       
   252 
       
   253     if ( iSynchronousMode )
       
   254         {        
       
   255 
       
   256         // Synchronous request was running. Complete that 
       
   257           // operation.
       
   258         __TRACE( KVerbose,( _L( "CUnderTaker::RunL Crash during synchronous operation" ) ) );
       
   259         iModuleContainer->iErrorResult = KErrDied;
       
   260         iModuleContainer->Cancel();
       
   261         iModuleContainer->iUpAndRunning = EFalse;
       
   262 
       
   263         // Print notification
       
   264         TName operationText = _L("Test module died when calling:");
       
   265         operationText.Append( iModuleContainer->iOperationText );
       
   266 
       
   267         // Print to log file        
       
   268         __TRACE( KError,( CStifLogger::ERed, operationText ) );
       
   269         // Print to UI
       
   270         iModuleContainer->iCTestModule->ErrorPrint ( 1, operationText );        
       
   271 
       
   272         // Stop active scheduler.
       
   273         CActiveScheduler::Stop();
       
   274 
       
   275         // Execution continues from CTestModuleContainer::StartAndWaitOperation.
       
   276 
       
   277         }
       
   278     else
       
   279         {// Test case was running, 
       
   280 
       
   281         __TRACE( KError,( _L( "Test case execution aborted" ) ) );
       
   282         __TRACE( KVerbose,( _L( "CUnderTaker::Run crash during test execution" ) ) );      
       
   283 
       
   284         TInt caseResult = KErrGeneral;
       
   285         
       
   286         // Check if case have any special panic or exception codes that are "passed"
       
   287         if ( iModuleContainer->iAllowedExitReason != 
       
   288              CTestModuleIf::ENormal )            
       
   289             {
       
   290                 
       
   291             if ( iModuleContainer->iAllowedExitReason == 
       
   292                  CTestModuleIf::EPanic &&
       
   293                  exitType == TFullTestResult::ECasePanic &&
       
   294                  iModuleContainer->iAllowedExitCode == exitReason )
       
   295                 {
       
   296                 exitType = TFullTestResult::ECaseExecuted;
       
   297                 caseResult = KErrNone;
       
   298                 exitCategory = _L("Allowed case panic");
       
   299                 
       
   300                 __TRACE( KError,( _L( "Test case execution panic, setting to OK" ) ) );
       
   301                 }
       
   302 
       
   303             if ( iModuleContainer->iAllowedExitReason == 
       
   304                  CTestModuleIf::EException &&
       
   305                  exitType == TFullTestResult::ECaseException &&
       
   306                  iModuleContainer->iAllowedExitCode == exitReason )
       
   307                 {
       
   308                 exitType = TFullTestResult::ECaseExecuted;
       
   309                 caseResult = KErrNone;
       
   310                 exitCategory = _L("Allowed case exception");
       
   311 
       
   312                 __TRACE( KError,( _L( "Test case execution exception, setting to OK" ) ) );
       
   313                 }
       
   314             
       
   315             
       
   316             }
       
   317 
       
   318         // This was asynchronous request, and nobody is waiting for it
       
   319         // completion in server, so all clean-up must be done here
       
   320 
       
   321         // Forget iTestThreadContainer pointer, memory is freed because test thread
       
   322         // is destroyed   
       
   323         // This is needed to prevent from accessing memory from thread that is destroyed.
       
   324         // Do this only if test is been executed.
       
   325         iModuleContainer->iThreadContainer = NULL;
       
   326 
       
   327         if (iModuleContainer->iCTestExecution != NULL)
       
   328         	{
       
   329 			// Execution thread have been killed
       
   330 			iModuleContainer->iCTestExecution->SetThreadState( CTestExecution::ECancelled );
       
   331 	
       
   332 			
       
   333 			// Cancel the request
       
   334 			iModuleContainer->iCTestExecution->CompleteTestExecution( KErrNone,
       
   335 																	  exitType,
       
   336 																	  exitReason,
       
   337 																	  caseResult,
       
   338 																	  exitCategory );
       
   339 	
       
   340 			// If the print queue is empty, and there is active print
       
   341 			// request, then cancel that request. 
       
   342 			// NOTE: Case queue not empty AND request waiting AND
       
   343 			//       thread terminated can't happen due iPrintMutex
       
   344 			iModuleContainer->iCTestExecution->CompletePrintRequestIfQueueEmpty();
       
   345         	}
       
   346         else
       
   347         	{
       
   348         	__TRACE( KError,( _L( "STIF internal error - iCTestExecution is NULL in CUnderTaker::RunL." ) ) );
       
   349         	User::Leave(KErrGeneral);
       
   350         	}
       
   351         // Free the memory
       
   352         // Remove undertaker from module container to make sure that
       
   353         // it does not delete this.
       
   354         iModuleContainer->iUnderTaker = NULL;
       
   355         delete iModuleContainer;
       
   356         iModuleContainer = NULL;
       
   357 
       
   358         // Suicide. "Parent", i.e iModuleContainer has already died
       
   359         // and no-one have pointer to this active object, so die.
       
   360         delete this;
       
   361 
       
   362         }
       
   363        
       
   364     }
       
   365 
       
   366 
       
   367 /*
       
   368 -------------------------------------------------------------------------------
       
   369 
       
   370     Class: CUnderTaker
       
   371 
       
   372     Method: DoCancel
       
   373 
       
   374     Description: Stops thread monitoring
       
   375 
       
   376     Parameters: None
       
   377 
       
   378     Return Values: None
       
   379 
       
   380     Errors/Exceptions: None
       
   381 
       
   382     Status: Proposal
       
   383     
       
   384 -------------------------------------------------------------------------------
       
   385 */
       
   386 
       
   387 void CUnderTaker::DoCancel()
       
   388     {
       
   389 
       
   390     if( iCancelNeeded && iModuleContainer )
       
   391         {
       
   392         iModuleContainer->iThread.LogonCancel( iStatus );
       
   393         }
       
   394     else
       
   395         {
       
   396         // Note that iModuleContainer can be NULL if iCancelNeeded is EFalse
       
   397         __ASSERT_ALWAYS( iModuleContainer, 
       
   398                          CTestServer::PanicServer( ENullTestModuleContainer ) );
       
   399         }
       
   400 
       
   401     }
       
   402 
       
   403 /*
       
   404 -------------------------------------------------------------------------------
       
   405 
       
   406     Class: CUnderTaker
       
   407 
       
   408     Method: RunError
       
   409 
       
   410     Description: Handle errors. RunL function does not leave, so one should
       
   411     never come here. 
       
   412 
       
   413     Print trace and let framework handle error( i.e to do Panic )
       
   414 
       
   415     Parameters: TInt aError:                  :in:  Error code
       
   416 
       
   417     Return Values:  TInt                            Error code
       
   418 
       
   419     Errors/Exceptions: None
       
   420 
       
   421     Status: Proposal
       
   422 
       
   423 -------------------------------------------------------------------------------
       
   424 */
       
   425 TInt CUnderTaker::RunError( TInt aError )
       
   426     {
       
   427     __TRACE( KError,( _L( "CUnderTaker::RunError" ) ) );
       
   428 
       
   429     return aError;
       
   430 
       
   431     }
       
   432 
       
   433 /*
       
   434 -------------------------------------------------------------------------------
       
   435 
       
   436     Class: CUnderTaker
       
   437 
       
   438     Method: Completed
       
   439 
       
   440     Description: Is request completed
       
   441 
       
   442     Parameters: None
       
   443 
       
   444     Return Values:  TBool                           Completed?
       
   445 
       
   446     Errors/Exceptions: None
       
   447 
       
   448     Status: Proposal
       
   449 
       
   450 -------------------------------------------------------------------------------
       
   451 */
       
   452 TBool CUnderTaker::Completed()
       
   453     {
       
   454 
       
   455     if( iStatus == KRequestPending )
       
   456         {
       
   457         return EFalse;
       
   458         }
       
   459     else
       
   460         {
       
   461         return ETrue;
       
   462         }
       
   463 
       
   464     }
       
   465 
       
   466 /*
       
   467 -------------------------------------------------------------------------------
       
   468 
       
   469     Class: CUnderTaker
       
   470 
       
   471     Method: SetSynchronousMode
       
   472 
       
   473     Description: Set or unsets local processing mode
       
   474 
       
   475     Parameters: const TBool aMode             :in:  Mode
       
   476 
       
   477     Return Values:  None
       
   478 
       
   479     Errors/Exceptions: None
       
   480 
       
   481     Status: Proposal
       
   482 
       
   483 -------------------------------------------------------------------------------
       
   484 */
       
   485 void CUnderTaker::SetSynchronousMode( const TBool aMode )
       
   486     {
       
   487 
       
   488     iSynchronousMode = aMode;
       
   489    
       
   490     }
       
   491 
       
   492 // End of File