messagingfw/msgtestfw/Framework/src/CMtfTestCase.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18 */
       
    19 	
       
    20 #include "CMtfTestCase.h"
       
    21 #include "CMtfTestActionWait.h"
       
    22 #include "CMtfTestActionSectionComplete.h"
       
    23 #include "CMtfTestParameterStore.h"
       
    24 #include "CMtfConfigurationType.h"
       
    25 #include "CMtfTestServer.h"
       
    26 
       
    27 _LIT(KMtfTestCasePanic,"Messaging Test Case Panic");
       
    28 
       
    29 void CMtfTestCase::Panic(TMtfTestCasePanic aPanic)
       
    30 {
       
    31 	User::Panic(KMtfTestCasePanic,aPanic);
       
    32 }
       
    33 
       
    34 /** Constructor. */
       
    35 CMtfTestCase::CMtfTestCase(const CMtfTestServer& aTestServer, const TBool& aScripted,
       
    36 		const TBool& aSynchronous)
       
    37 : 	CTestStep(), iCurrentState(EMtfTestCaseInitialState),
       
    38 	iScriptedTestCase(aScripted), iSynchronous(aSynchronous), iTestServer(aTestServer) 
       
    39 {
       
    40 	SetTestStepResult(EPass);
       
    41 }
       
    42 
       
    43 /** Creates a new parameter store. */
       
    44 void CMtfTestCase::ConstructL()
       
    45 {
       
    46 	iParameterStore = CMtfTestParameterStore::NewL();
       
    47 }
       
    48 
       
    49 /** Returns a reference to the parameter store. */
       
    50 const CMtfTestParameterStore& CMtfTestCase::ParameterStore() const
       
    51 {
       
    52 	return *iParameterStore;
       
    53 }
       
    54 	
       
    55 
       
    56 CMtfTestCase::~CMtfTestCase()
       
    57 {
       
    58 	delete iParameterStore;
       
    59 	iQueuedActions.ResetAndDestroy();
       
    60 	iCurrentActions.ResetAndDestroy();
       
    61 	iCompletedActions.ResetAndDestroy();
       
    62 	iTestCaseDefaultConfigurations.ResetAndDestroy();
       
    63 	delete iScheduler;
       
    64 }
       
    65 
       
    66 /** Converts an enumerator value to its corresponding numerical value. */
       
    67 TInt CMtfTestCase::ConvertEnumeratorL(const TDesC& aEnumerator) const
       
    68 {
       
    69 	return iTestServer.ConvertEnumeratorL(aEnumerator);
       
    70 }
       
    71 
       
    72 /** Obtains the correct configuration file given a type. */
       
    73 const TDesC& CMtfTestCase::GetConfigurationFileL(const CMtfConfigurationType::TMtfConfigurationType& aType) const
       
    74 {
       
    75 	return GetConfigurationFileL(aType,0);
       
    76 }
       
    77 
       
    78 /** Tries to find a main script configuration first,
       
    79 then the test case default and if none of them exist then gets the default configuration. */
       
    80 const TDesC& CMtfTestCase::GetConfigurationFileL(const CMtfConfigurationType::TMtfConfigurationType& aType, TInt aIndex) const
       
    81 {
       
    82 	TInt error=KErrNone;
       
    83 	const TDesC* retval=0;
       
    84 	TRAP(error,retval=&iTestServer.GetMainScriptConfigurationFileL(aType,aIndex)); 
       
    85 
       
    86 	if (error==KErrNone)
       
    87 	{
       
    88 		return *retval;
       
    89 	}
       
    90 	
       
    91 	if (error != KErrNotFound)
       
    92 	{
       
    93  		// nice to print some kind of error message here !!!
       
    94 		User::Leave(error);
       
    95 	}
       
    96 	
       
    97 	// find test case default if it exists
       
    98 	
       
    99 	TInt index=0;
       
   100 	TRAP(error,index = CMtfConfigurationType::FindConfigurationL(aType,iTestCaseDefaultConfigurations));
       
   101 	
       
   102 	if (error==KErrNone)
       
   103 	{
       
   104 		// configuration found, return the required file
       
   105 		// this may leave if item aIndex does not exist
       
   106 		return iTestCaseDefaultConfigurations[index]->ConfigurationFileL(aIndex);
       
   107 	}
       
   108 	else if (error != KErrNotFound)
       
   109 	{
       
   110  		// nice to print some kind of error message here !!!
       
   111 		User::Leave(error);
       
   112 	}
       
   113 	
       
   114 	// go to the server and ask for default
       
   115 	// aIndex is ignored in this case
       
   116 	return iTestServer.GetDefaultConfigurationFileL(aType);
       
   117 	
       
   118 	// ISSUE: at the end of the test case check whether all configurations have been used
       
   119 }
       
   120 
       
   121 #if defined(__WINS__) && !defined(_DEBUG)
       
   122 #pragma warning( default : 4702 ) //  unreachable code
       
   123 #endif
       
   124 
       
   125 /** This function take ownership of aConfiguration immediately and therefore SHOULD NOT be 
       
   126 called with aConfiguration already on the Cleanup stack. */
       
   127 void CMtfTestCase::SetTestCaseDefaultConfigurationTypeL(CMtfConfigurationType* aConfiguration)
       
   128 {
       
   129 	CMtfConfigurationType::SetConfigurationTypeL(aConfiguration,iTestCaseDefaultConfigurations);
       
   130 }
       
   131 
       
   132 /** The function takes ownership of aParameter at the END. */
       
   133 void CMtfTestCase::StoreParameterL(CMtfTestParameter* aParameter)
       
   134 {
       
   135 	iParameterStore->StoreParameterL(aParameter);
       
   136 }
       
   137 
       
   138 const CMtfTestParameter& CMtfTestCase::ObtainParameterL(const TDesC& aName) const
       
   139 {
       
   140 	return iParameterStore->ObtainParameterL(aName);
       
   141 }
       
   142 
       
   143 void CMtfTestCase::DeleteParameterL(const TDesC& aName)
       
   144 {
       
   145 	iParameterStore->DeleteParameterL(aName);
       
   146 }
       
   147 
       
   148 /**
       
   149  * @return - TVerdict code
       
   150  * Override of base class virtual
       
   151  */
       
   152 TVerdict CMtfTestCase::doTestStepPreambleL()
       
   153 {
       
   154 	return TestStepResult();
       
   155 }
       
   156 
       
   157 /** Starts the execution of the test case by executing all test actions until the first wait action is 
       
   158 encountered. This function then returns. Override of base class pure virtual.
       
   159 @return - TVerdict code */
       
   160 TVerdict CMtfTestCase::doTestStepL()
       
   161 {
       
   162 	iScheduler=new (ELeave) CActiveScheduler();
       
   163 	CActiveScheduler::Install(iScheduler);
       
   164 		
       
   165 	if (iCurrentState == EMtfTestCaseInitialState)
       
   166 	{
       
   167 		ChangeState();
       
   168 	}
       
   169 	
       
   170 	if (iScriptedTestCase == EFalse)
       
   171 	{	
       
   172 		// non-scripted test case, run the first section function which builds up the queue
       
   173 		SetupTestCaseL();
       
   174 		
       
   175 		// ISSUE: assert the state hasn't changed
       
   176 			
       
   177 		if (iQueuedActions.Count() > 0)
       
   178 		{
       
   179 			// the new test action will be owned by the test case
       
   180 			CMtfTestActionSectionComplete::NewL(*this);	
       
   181 			
       
   182 			ExecuteActionsL();
       
   183 		}
       
   184 		else if (SetupTestCaseIsSynchronous())
       
   185 		{
       
   186 			// no queued actions and synchronous
       
   187 			SectionCompletedL();
       
   188 		}
       
   189 	}	
       
   190 	else
       
   191 	{
       
   192 		ExecuteActionsL();
       
   193 	}
       
   194 		
       
   195 	if (iCurrentState != EMtfTestCaseTestCompleted)
       
   196 	{
       
   197 		// the test case contains some asynchronous test actions so we need to start
       
   198 		// the scheduler
       
   199 		iActiveSchedulerRunning = ETrue;
       
   200 		iScheduler->Start();
       
   201 	}
       
   202 
       
   203 	return TestStepResult();
       
   204 }
       
   205 
       
   206 /**
       
   207  * @return - TVerdict code
       
   208  * Override of base class virtual
       
   209  */
       
   210 TVerdict CMtfTestCase::doTestStepPostambleL()
       
   211 {
       
   212 	return TestStepResult();
       
   213 }
       
   214 
       
   215 /** Add a new action to the test case. Takes ownership of the test action at the END. */
       
   216 void CMtfTestCase::QueueTestActionL(CMtfTestAction* aTestAction) 
       
   217 {
       
   218 	TBool synchronousTestCase = (iScriptedTestCase? iSynchronous: IsSynchronous());
       
   219 	
       
   220 	if (synchronousTestCase && !aTestAction->WaitAction() && !aTestAction->SectionCompleteAction())
       
   221 	{
       
   222 		// put a wait action after each test action to make it synchronous
       
   223 		CMtfTestActionWait::NewL(*this);
       
   224 		
       
   225 		// at this point we can take ownership of aTestAction by inserting it before the wait
       
   226 		User::LeaveIfError(iQueuedActions.Insert(aTestAction, iQueuedActions.Count()-1));
       
   227 	}
       
   228 	else
       
   229 	{
       
   230 		User::LeaveIfError(iQueuedActions.Append(aTestAction));
       
   231 	}
       
   232 }
       
   233 
       
   234 TBool CMtfTestCase::IsSynchronous()
       
   235 {
       
   236 	return iSynchronous;
       
   237 }
       
   238 	
       
   239 /** Handles an action completion by removing it from the list of current actions and putting it on the
       
   240 list of completed actions. */
       
   241 void CMtfTestCase::ActionCompletedL(CMtfTestAction& aAction)
       
   242 {
       
   243 	TInt index = iCurrentActions.Find(&aAction);
       
   244 	User::LeaveIfError(index);
       
   245 	User::LeaveIfError(iCompletedActions.Append(&aAction));
       
   246 	iCurrentActions.Remove(index);	
       
   247 	
       
   248 	if (aAction.CurrentlyBeingWaitedFor())
       
   249 	{
       
   250 		aAction.SetCurrentlyBeingWaitedFor(EFalse);
       
   251 		iWaitListCount--;
       
   252 	}
       
   253 	
       
   254 	if (iWaitListCount == 0)
       
   255 	{
       
   256 		// no more actions that are currently being waited for
       
   257 		ExecuteActionsL();
       
   258 	}
       
   259 }
       
   260 	
       
   261 /** Executing all queued actions until a wait action is found. */
       
   262 void CMtfTestCase::ExecuteActionsL()
       
   263 {
       
   264 	for (;;)
       
   265 	{
       
   266 		if (iQueuedActions.Count()==0)
       
   267 		{
       
   268 			break;
       
   269 		}
       
   270 		
       
   271 		CMtfTestAction& nextAction = *iQueuedActions[0];
       
   272 		
       
   273 		// remove the first action from the queue and put it on the list
       
   274 		// of current actions
       
   275 		
       
   276 		iQueuedActions.Remove(0);	
       
   277 		
       
   278 		if (!nextAction.WaitAction() && !nextAction.SectionCompleteAction())
       
   279 		{
       
   280 			User::LeaveIfError(iCurrentActions.Append(&nextAction));
       
   281 		}	
       
   282 		else
       
   283 		{
       
   284 			// two framework actions are synchronous so they complete immediately
       
   285 			User::LeaveIfError(iCompletedActions.Append(&nextAction));
       
   286 		}
       
   287 		
       
   288 		// executing an action may: 
       
   289 		//	- start off an asynchronous request in which case the action
       
   290 		//		remains on the list of currently executing actions
       
   291 		//  - start and complete a synchronous action in which case the action
       
   292 		//		signals the test case that it has completed within ExecuteActionL(), 
       
   293 		//		therefore the action must be already on iCurrentActions before
       
   294 		//		ExecuteActionL() is called. ExecuteActionL() will be called recursively
       
   295 		//		from ActionCompletedL().
       
   296 		
       
   297 		nextAction.ExecuteActionL();
       
   298 		
       
   299 		if (iWaitListCount>0)
       
   300 		{
       
   301 			// wait action was found, stop execution
       
   302 			break;
       
   303 		}
       
   304 	}
       
   305 }
       
   306 
       
   307 /** Handles a section completion. The test case changes its state to the next state. For scripted test cases it checks whether 
       
   308 the test case is finished and if it is not it simply returns. Since all test actions in a scripted test case are in the queue 
       
   309 at the beginning the remaining test actions will be executed. For a non-scripted test case this function calls the appropriate 
       
   310 function which queues more test actions for the next section. The function then attempts to start the execution of test 
       
   311 actions in the next test case section. */
       
   312 void CMtfTestCase::SectionCompletedL()
       
   313 {
       
   314 	ChangeState();
       
   315 
       
   316 	if (iCurrentState == EMtfTestCaseTestCompleted)
       
   317 	{
       
   318 		__ASSERT_ALWAYS(iQueuedActions.Count()==0,Panic(EMtfUnexpectedQueuedAction));
       
   319 		
       
   320 		if (iActiveSchedulerRunning)
       
   321 		{
       
   322 			CActiveScheduler::Stop();
       
   323 		}
       
   324 		
       
   325 		return;
       
   326 	}
       
   327 	
       
   328 	if (!iScriptedTestCase)
       
   329 	{		
       
   330 		// Non-scripted test cases queue actions as they execute each section.
       
   331 		// Therefore, actions are queued per section and when a section completes
       
   332 		// there must be no more actions in the queue, unlike the scripted test cases
       
   333 		// which queue all actions in the test case.
       
   334 		
       
   335 		__ASSERT_ALWAYS(iQueuedActions.Count()==0,Panic(EMtfUnexpectedQueuedAction));
       
   336 		
       
   337 		switch (iCurrentState)
       
   338 		{
       
   339 			case EMtfTestCaseExecutingTest:
       
   340 				ExecuteTestCaseL();
       
   341 		
       
   342 				if (iQueuedActions.Count() > 0)
       
   343 				{
       
   344 					// owned by the test case
       
   345 					CMtfTestActionSectionComplete::NewL(*this);	
       
   346 					ExecuteActionsL();
       
   347 				}
       
   348 				else if (ExecuteTestCaseIsSynchronous())
       
   349 				{
       
   350 					SectionCompletedL();
       
   351 				}	
       
   352 				break;
       
   353 			case EMtfTestCaseCheckingPostconditions:
       
   354 				CheckPostConditionsL();
       
   355 				if (iQueuedActions.Count() > 0)
       
   356 				{
       
   357 					// owned by the test case
       
   358 					CMtfTestActionSectionComplete::NewL(*this);	
       
   359 					ExecuteActionsL();
       
   360 				} 
       
   361 				else if (CheckPostconditionsIsSynchronous())
       
   362 				{
       
   363 					SectionCompletedL();
       
   364 				}
       
   365 				break;
       
   366 			default:
       
   367 				break;
       
   368 		}    	
       
   369 	}	
       
   370 }
       
   371 
       
   372 /** Sets the test case to wait for the specified action. */
       
   373 void CMtfTestCase::WaitForActionL(const TDesC& aActionId)
       
   374 {
       
   375 	TInt countCurrent = iCurrentActions.Count();
       
   376 	
       
   377 	for (TInt count=0; count<countCurrent; count++)
       
   378 	{
       
   379 		if (iCurrentActions[count]->ActionIdL() == aActionId)
       
   380 		{
       
   381 			iCurrentActions[count]->SetCurrentlyBeingWaitedFor(ETrue);
       
   382 			iWaitListCount++;
       
   383 			break;
       
   384 		}
       
   385 	}
       
   386 	
       
   387 	// ISSUE: if not found maybe log this fact
       
   388 }
       
   389 
       
   390 /** Sets the test case to wait for all currently executing actions. */
       
   391 void CMtfTestCase::WaitForAllActionsL()
       
   392 {
       
   393 	TInt numberOfCurrentActions = iCurrentActions.Count();
       
   394 	
       
   395 	for (TInt count=0; count < numberOfCurrentActions; count++)
       
   396 	{
       
   397 		iCurrentActions[count]->SetCurrentlyBeingWaitedFor(ETrue);
       
   398 		iWaitListCount++;
       
   399 	} 
       
   400 }
       
   401 
       
   402 void CMtfTestCase::ChangeState()
       
   403 {
       
   404 	switch (iCurrentState)
       
   405 	{
       
   406 		case EMtfTestCaseInitialState:
       
   407 			iCurrentState = EMtfTestCaseExecutingSetup;
       
   408 			break; 
       
   409 		case EMtfTestCaseExecutingSetup:
       
   410 			iCurrentState = EMtfTestCaseExecutingTest;
       
   411 			break; 
       
   412 		case EMtfTestCaseExecutingTest:
       
   413 			iCurrentState = EMtfTestCaseCheckingPostconditions;
       
   414 			break; 
       
   415 		case EMtfTestCaseCheckingPostconditions:
       
   416 			iCurrentState = EMtfTestCaseTestCompleted;
       
   417 			break; 
       
   418 		case EMtfTestCaseTestCompleted:
       
   419 			User::Invariant();
       
   420 			break;
       
   421 		default:
       
   422 			User::Invariant();
       
   423 	}
       
   424 }	
       
   425 
       
   426 TBool CMtfTestCase::SetupTestCaseIsSynchronous() const
       
   427 {
       
   428 	return ETrue;
       
   429 }
       
   430 
       
   431 TBool CMtfTestCase::ExecuteTestCaseIsSynchronous() const
       
   432 {
       
   433 	return ETrue;
       
   434 }
       
   435 
       
   436 TBool CMtfTestCase::CheckPostconditionsIsSynchronous() const
       
   437 {
       
   438 	return ETrue;
       
   439 }