/**+ −
* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).+ −
* All rights reserved.+ −
* This component and the accompanying materials are made available+ −
* under the terms of "Eclipse Public License v1.0"+ −
* which accompanies this distribution, and is available+ −
* at the URL "http://www.eclipse.org/legal/epl-v10.html".+ −
*+ −
* Initial Contributors:+ −
* Nokia Corporation - initial contribution.+ −
*+ −
* Contributors:+ −
*+ −
* Description:+ −
*+ −
*/+ −
+ −
+ −
+ −
/**+ −
@file+ −
*/+ −
+ −
#ifndef __CMTF_TEST_CASE_H__+ −
#define __CMTF_TEST_CASE_H__+ −
+ −
#include <test/testexecutestepbase.h>+ −
#include "TMtfTestParameterType.h"+ −
#include "CMtfTestParameter.h"+ −
#include "CMtfTestParameterStore.h"+ −
#include "CMtfConfigurationType.h"+ −
#include "CMtfEnumeratorConverter.h"+ −
#include "CMtfTestAction.h"+ −
+ −
class CMtfTestServer;+ −
class CMtfTestAction;+ −
+ −
_LIT(KMtfDontCare,"_");+ −
_LIT(_,"_"); // Short form for nonscripted test scripts+ −
+ −
+ −
/** Base class from which all test cases are derived. To create a new test case class the functions+ −
SetupTestCaseL(), ExecuteTestCaseL() and CheckPostConditionsL() must be overridden. */+ −
class CMtfTestCase: public CTestStep+ −
{+ −
public:+ −
+ −
// These panics signify that the test case script is invalid in case of a scripted+ −
// test case. In case of a non-scripted test case, the overridden sections of the test + −
// case are invalid. The test actions are not used correctly.+ −
//+ −
enum TMtfTestCasePanic+ −
{+ −
EMtfGeneralTypeMismatch, // mismatch of general parameter types+ −
EMtfSpecificTypeMismatch, // mismatch of specific parameter types+ −
EMtfMissingParameters, // a test action was used without providing all+ −
// required parameters+ −
EMtfUnexpectedQueuedAction, // the test case expected iQueuedActions to be empty+ −
EMtfInvalidParameter, // invalid parameter+ −
EMtfInternalError+ −
};+ −
+ −
static void Panic(TMtfTestCasePanic aPanic);+ −
virtual ~CMtfTestCase();+ −
+ −
/** Required by TestExecute */+ −
virtual TVerdict doTestStepPreambleL();+ −
+ −
/** Required by TestExecute */+ −
virtual TVerdict doTestStepL();+ −
+ −
/** Required by TestExecute */+ −
virtual TVerdict doTestStepPostambleL();+ −
+ −
/** Notifies the test case that an action has been completed. Used by test actions. */+ −
void ActionCompletedL(CMtfTestAction& aTestAction);+ −
+ −
/** Notifies the test case that a section has been completed. Used by the framework. */+ −
void SectionCompletedL();+ −
+ −
/** Queues an action for execution. Takes ownership */+ −
void QueueTestActionL(CMtfTestAction* aTestAction);+ −
+ −
TBool ScriptedTestCase() const;+ −
+ −
/** Sets the test case to wait for the specified action to complete before executing+ −
any other actions. */+ −
void WaitForActionL(const TDesC& aActionId);+ −
+ −
/** Sets the test case to wait for the completion of all currently executing actions+ −
before starting the execution of any other actions. */+ −
void WaitForAllActionsL();+ −
+ −
TBool IsSynchronous();+ −
+ −
void DeleteParameterL(const TDesC& aName);+ −
+ −
/** Obtains the configuration file corresponding to the required type. Configuration file returned was either set+ −
from the main script, set as the test case default, or a global default one is used.*/+ −
const TDesC& GetConfigurationFileL(const CMtfConfigurationType::TMtfConfigurationType& aType, TInt aIndex) const;+ −
const TDesC& GetConfigurationFileL(const CMtfConfigurationType::TMtfConfigurationType& aType) const;+ −
+ −
/** Sets the default configuration for this test case only.*/+ −
void SetTestCaseDefaultConfigurationTypeL(CMtfConfigurationType* aConfiguration);+ −
+ −
TInt ConvertEnumeratorL(const TDesC& aParameter) const;+ −
+ −
const CMtfTestParameterStore& ParameterStore() const;+ −
void StoreParameterL(CMtfTestParameter* aParameter);+ −
const CMtfTestParameter& ObtainParameterL(const TDesC& aName) const;+ −
+ −
enum TMtfTestCaseState+ −
{+ −
EMtfTestCaseInitialState,+ −
EMtfTestCaseExecutingSetup,+ −
EMtfTestCaseExecutingTest,+ −
EMtfTestCaseCheckingPostconditions,+ −
EMtfTestCaseTestCompleted+ −
};+ −
+ −
const CMtfTestServer& Server() { return iTestServer; }+ −
+ −
protected:+ −
CMtfTestCase(const CMtfTestServer& aTestServer, const TBool& aScripted, const TBool& aSynchronous);+ −
void ConstructL();+ −
+ −
private:+ −
+ −
virtual void SetupTestCaseL()=0;+ −
virtual void ExecuteTestCaseL()=0;+ −
virtual void CheckPostConditionsL()=0;+ −
+ −
/** Can be overridden if this section is not synchronous. By default returns true. */ + −
virtual TBool SetupTestCaseIsSynchronous() const;+ −
+ −
/** Can be overridden if this section is not synchronous. By default returns true. */ + −
virtual TBool ExecuteTestCaseIsSynchronous() const;+ −
+ −
/** Can be overridden if this section is not synchronous. By default returns true. */ + −
virtual TBool CheckPostconditionsIsSynchronous() const; + −
+ −
void ExecuteActionsL();+ −
void ChangeState();+ −
+ −
private:+ −
RPointerArray<CMtfTestAction> iQueuedActions;+ −
RPointerArray<CMtfTestAction> iCurrentActions;+ −
RPointerArray<CMtfTestAction> iCompletedActions;+ −
TInt iWaitListCount;+ −
CMtfTestParameterStore* iParameterStore;+ −
TMtfTestCaseState iCurrentState;+ −
TBool iScriptedTestCase;+ −
TBool iActiveSchedulerRunning;+ −
TBool iSynchronous; // used if scripted+ −
CActiveScheduler* iScheduler;+ −
RPointerArray<CMtfConfigurationType> iTestCaseDefaultConfigurations;+ −
const CMtfTestServer& iTestServer;+ −
};+ −
+ −
+ −
/** Used for optional parameters. This function requires a default value for the optional parameter to be+ −
provided. This function should be a member function of CMtfTestCase but unfortunately member template functions+ −
are not supported by all three compilers. */+ −
template<class T>+ −
T* ObtainParameterReferenceL(CMtfTestCase& aTestCase, const TDesC& aParameterName,T* aDefault)+ −
{+ −
// if parameter is not provided use default+ −
if (aParameterName == KMtfDontCare)+ −
{+ −
return aDefault;+ −
}+ −
+ −
return ObtainParameterReferenceL<T>(aTestCase,aParameterName);+ −
}+ −
+ −
/** Used to obtain non-optional reference parameters. This function should be a member function of CMtfTestCase + −
but unfortunately member template functions are not supported by all three compilers. Type T and the type of the+ −
requested parameter must match exactly, otherwise the function leaves. T must be either a CBase derived class or HBufC. */+ −
template<class T>+ −
T* ObtainParameterReferenceL(CMtfTestCase& aTestCase, const TDesC& aParameterName)+ −
{+ −
// if optional leave+ −
if (aParameterName == KMtfDontCare)+ −
{+ −
User::Leave(KErrNotFound);+ −
}+ −
+ −
// obtain type information for T+ −
TMtfTestParameterType<T> parameterType;+ −
TMtfTestParameterGeneralType generalTypeId = parameterType.GeneralTypeId();+ −
TMtfTestParameterSpecificType specificTypeId = parameterType.SpecificTypeId();+ −
+ −
// This function must only be called with T being either a CBase derived class+ −
// or HBufC, otherwise it is a programming error.+ −
// can also be called with an RArray type ptr+ −
+ −
__ASSERT_ALWAYS( (generalTypeId == EMtfCBaseType) || (generalTypeId == EMtfHBufCType) || (generalTypeId == EMtfValueType) ,+ −
CMtfTestAction::Panic(CMtfTestAction::EMtfNonReferenceParameter));+ −
+ −
T* returnPtr = NULL;+ −
+ −
if (generalTypeId == EMtfHBufCType) + −
{+ −
// if hbufc check if it is a constant descriptor+ −
if (aParameterName[0] == '\"')+ −
{+ −
if (aParameterName[aParameterName.Length()-1] == '\"')+ −
{+ −
// find parameter in const store first+ −
+ −
if (specificTypeId == EMtfHBufC)+ −
{+ −
// add the constant to parameter store+ −
+ −
HBufC* buf = HBufC::NewLC(aParameterName.Length()-2);+ −
+ −
for(TInt c=0; c<aParameterName.Length()-2; c++)+ −
buf->Des().Append(aParameterName[c+1]);+ −
+ −
// parameter store takes ownership+ −
+ −
CMtfTestParameter* newParameter = CMtfTestParameter::NewL(aParameterName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(buf));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter); + −
CleanupStack::Pop(2,buf);+ −
returnPtr = reinterpret_cast<T*>(buf);+ −
}+ −
else if (specificTypeId == EMtfHBufC8)+ −
{+ −
HBufC8* buf = HBufC8::NewLC(aParameterName.Length()-2);+ −
+ −
for(TInt c=0; c<aParameterName.Length()-2; c++)+ −
buf->Des().Append(aParameterName[c+1]);+ −
+ −
CMtfTestParameter* newParameter = CMtfTestParameter::NewL(aParameterName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(buf));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter); + −
CleanupStack::Pop(2,buf);+ −
returnPtr = reinterpret_cast<T*>(buf);+ −
}+ −
else+ −
User::Panic(KMtfTypeMismatch,0);+ −
}+ −
}+ −
}+ −
+ −
if(returnPtr == NULL) // not a constant descriptor+ −
{+ −
const CMtfTestParameter& parameter = aTestCase.ObtainParameterL(aParameterName);+ −
+ −
__ASSERT_ALWAYS(generalTypeId == parameter.GeneralTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
__ASSERT_ALWAYS(specificTypeId == parameter.SpecificTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
+ −
returnPtr = reinterpret_cast<T*>(parameter.Parameter());+ −
}+ −
return returnPtr;+ −
}+ −
+ −
+ −
/** Used for value and reference parameters. */+ −
template<class T>+ −
void StoreParameterL(CMtfTestCase& aTestCase,T& aPtr, const TDesC& aName)+ −
{+ −
// if the parameter is "don't care" then don't store the parameter+ −
if (aName == KMtfDontCare)+ −
{+ −
return;+ −
}+ −
+ −
// obtain type information for T+ −
TMtfTestParameterType<T> parameterType;+ −
TMtfTestParameterGeneralType generalTypeId = parameterType.GeneralTypeId();+ −
TMtfTestParameterSpecificType specificTypeId = parameterType.SpecificTypeId();+ −
+ −
CMtfTestParameter* newParameter=NULL;+ −
// TPckgC<T> pack(aPtr);+ −
// HBufC8 *valueStorage;+ −
+ −
switch(generalTypeId)+ −
{+ −
case EMtfCBaseType:+ −
case EMtfHBufCType:+ −
{+ −
newParameter = CMtfTestParameter::NewL(+ −
aName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(&aPtr));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter);+ −
CleanupStack::Pop(newParameter);+ −
return;+ −
}+ −
case EMtfValueType:+ −
if(specificTypeId == EMtfTTime)+ −
{+ −
newParameter = CMtfTestParameter::NewL(+ −
aName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(&aPtr));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter);+ −
CleanupStack::Pop(newParameter);+ −
return; + −
}+ −
else+ −
{+ −
TPckgC<T> pack(aPtr);+ −
HBufC8 *valueStorage = pack.AllocLC();+ −
newParameter = CMtfTestParameter::NewL(+ −
aName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(valueStorage));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter);+ −
CleanupStack::Pop(2,valueStorage);+ −
return; + −
}+ −
case EMtfEnumeratorType:+ −
{+ −
TPckgC<T> pack(aPtr);+ −
HBufC8 *valueStorage = pack.AllocLC();+ −
newParameter = CMtfTestParameter::NewL(+ −
aName,generalTypeId,specificTypeId,reinterpret_cast<TAny*>(valueStorage));+ −
CleanupStack::PushL(newParameter);+ −
aTestCase.StoreParameterL(newParameter);+ −
CleanupStack::Pop(2,valueStorage);+ −
return;+ −
}+ −
default:+ −
User::Panic(KMtfTypeMismatch,0); + −
}+ −
}+ −
+ −
/** Usef for optional value parameters. A default value must be provided. */+ −
template<class T>+ −
T ObtainValueParameterL(CMtfTestCase& aTestCase, const TDesC& aParameterName,T aDefault)+ −
{+ −
if (aParameterName == KMtfDontCare)+ −
{+ −
return aDefault;+ −
}+ −
+ −
return ObtainValueParameterL<T>(aTestCase,aParameterName);+ −
}+ −
+ −
/** Used for non-optional value parameters. TInt parameters and enumerator parameters may be constant values. */+ −
template<class T>+ −
T ObtainValueParameterL(CMtfTestCase& aTestCase, const TDesC& aParameterName)+ −
{+ −
// if optional leave+ −
if (aParameterName == KMtfDontCare)+ −
{+ −
User::Leave(KErrNotFound);+ −
}+ −
+ −
T result;+ −
T* resultPtr = NULL;+ −
+ −
TMtfTestParameterType<T> parameterType;+ −
TMtfTestParameterGeneralType generalTypeId = parameterType.GeneralTypeId();+ −
TMtfTestParameterSpecificType specificTypeId = parameterType.SpecificTypeId();+ −
+ −
// check that id is value+ −
__ASSERT_ALWAYS(((generalTypeId == EMtfValueType) || (generalTypeId == EMtfEnumeratorType)),User::Panic(KMtfTypeMismatch,0));+ −
+ −
if (generalTypeId == EMtfEnumeratorType)+ −
{+ −
// check if it is a constant enumerator+ −
if (CMtfEnumeratorConverter::IsConstantEnumerator(aParameterName))+ −
{ + −
*reinterpret_cast<TInt*>(&result) = aTestCase.ConvertEnumeratorL(aParameterName);+ −
resultPtr = &result;+ −
}+ −
}+ −
else if (specificTypeId == EMtfTInt)+ −
{+ −
// if TInt then check if it is a constant parameter+ −
TLex converter(aParameterName);+ −
+ −
if (converter.Val(*(reinterpret_cast<TInt*>(&result))) == KErrNone)+ −
{+ −
// const parameter+ −
resultPtr = &result;+ −
}+ −
}+ −
+ −
if(resultPtr == NULL)+ −
{+ −
const CMtfTestParameter& parameter=aTestCase.ObtainParameterL(aParameterName);+ −
+ −
__ASSERT_ALWAYS(generalTypeId == parameter.GeneralTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
__ASSERT_ALWAYS(specificTypeId == parameter.SpecificTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
+ −
HBufC8* buf=reinterpret_cast<HBufC8*>(parameter.Parameter());+ −
T value; + −
TPckgC<T> unpack(value);+ −
unpack.Set(*buf);+ −
result = unpack();+ −
resultPtr = &result;+ −
}+ −
+ −
return *resultPtr;+ −
}+ −
+ −
/** Deletes the named parameter. */+ −
template<class T>+ −
#if defined (__WINS__) + −
T* // vc6bug - doesn't expand to correct type if T is not employed as param or return + −
#else+ −
void // normal case+ −
#endif+ −
DeleteParameterL(CMtfTestCase& aTestCase, const TDesC& aParameterName)+ −
{+ −
TMtfTestParameterType<T> parameterType;+ −
TMtfTestParameterGeneralType generalTypeId = parameterType.GeneralTypeId();+ −
TMtfTestParameterSpecificType specificTypeId = parameterType.SpecificTypeId();+ −
+ −
const CMtfTestParameter& parameter = aTestCase.ObtainParameterL(aParameterName);+ −
+ −
__ASSERT_ALWAYS(generalTypeId == parameter.GeneralTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
__ASSERT_ALWAYS(specificTypeId == parameter.SpecificTypeId(), User::Panic(KMtfTypeMismatch,0));+ −
+ −
aTestCase.DeleteParameterL(aParameterName);+ −
#if defined (__WINS__) + −
return (reinterpret_cast<T*>(0)); // vc6bug+ −
#endif+ −
}+ −
+ −
+ −
#endif+ −