messagingfw/msgtestfw/Framework/inc/CMtfTestCase.h
changeset 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgtestfw/Framework/inc/CMtfTestCase.h	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,424 @@
+/**
+* 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