phonebookengines/contactsmodel/tsrc/Integration/PerfFuncSuite/src/TransactionsStep.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/Integration/PerfFuncSuite/src/TransactionsStep.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,757 @@
+// Copyright (c) 2006-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 
+ @publishedAll
+ @released
+*/
+#include "TransactionsStep.h"
+#include "PerformanceFunctionalityDefs.h"
+
+_LIT(KVcardFile,"c:\\ExportedContacts.vcf");
+const TInt KTransactionSize = 16;//number of crud operations performed within a transaction
+
+//number of contacts used by transaction performance
+const TInt KMinContacts = 10;
+const TInt KMidContacts = 100;
+const TInt KManyContacts = 300;
+const TInt KMaxContacts = 1000;
+
+const TInt KPerfIter = 1;//number of times performance tests are repeated to get a more accurate average
+const TInt KMediumFields = 10;//number of fields to use when a contact is partially filled
+const TInt KManyFields = 69;//number of (template-derived) fields in a Contact Item
+
+_LIT(KRun1,"Nested");
+_LIT(KRun2,"EmptyCommit");
+_LIT(KRun3,"EmptyRevert");
+_LIT(KRun4,"UpdateCommit");
+_LIT(KRun5,"UpdateRevert");
+_LIT(KRun6,"CreateCommit");
+_LIT(KRun7,"CreatRevert");
+_LIT(KRun8,"DeleteCommit");
+_LIT(KRun9,"DeleteRevert");
+_LIT(KRun10,"CudCommit");
+_LIT(KRun11,"CudRevert");
+_LIT(KRun12,"EmptyPerfomance");
+_LIT(KRun13,"EmptyEmptyPerformance");
+_LIT(KRun14,"MediumPerformance");
+_LIT(KRun15,"MediumEmptyPerformance");
+_LIT(KRun16,"FullPerformance");
+_LIT(KRun17,"FullEmptyPerformance");
+_LIT(KRun18,"MultipleCommit");
+_LIT(KRun19,"TransactionMultiple");
+
+_LIT(KTest1, "Nested Transaction tests");
+_LIT(KTest2, "Empty; Commit Transaction tests");
+_LIT(KTest3, "Empty; Revert Transaction tests");
+_LIT(KTest4, "Update; Commit Transaction tests");
+_LIT(KTest5, "Update; Revert Transaction tests");
+_LIT(KTest6, "Create; Commit Transaction tests");
+_LIT(KTest7, "Create; Revert Transaction tests");
+_LIT(KTest8, "Delete; Commit Transaction tests");
+_LIT(KTest9, "Delete; Revert Transaction tests");
+_LIT(KTest10, "Many CUD; Commit Transaction tests");
+_LIT(KTest11, "Many CUD; Revert Transaction tests");
+_LIT(KTest12, "***Empty fields; Performance Transaction tests***");
+_LIT(KTest13, "***Empty fields, Empty DB; Performance Transaction tests***");
+_LIT(KTest14, "***Medium fields; Performance Transaction tests***");
+_LIT(KTest15, "***Medium fields, Empty DB; Performance Transaction tests***");
+_LIT(KTest16, "***Full fields; Performance Transaction tests***");
+_LIT(KTest17, "***Full fields, Empty DB; Performance Transaction tests***");
+_LIT(KTest18, "Multiple commit test");
+_LIT(KTest19, "Transaction Multiple commit test");
+
+//number of contacts used by this test step							
+#define KNumberOfContacts 10
+
+#ifdef __WINSCW__
+#define KMaxTimeAllowed	500 //seconds, minimum performance
+#else
+#define KMaxTimeAllowed	10000 //hardware is much slower
+#endif
+
+#define KNumCUDOperations 3
+
+_LIT(KMinContactsPrint,"$Min contacts$");
+_LIT(KMidContactsPrint,"$Mid contacts$");
+_LIT(KManyContactsPrint,"$Many contacts$");
+_LIT(KMaxContactsPrint,"$Max contacts$");
+
+							
+CTransactionsStep::CTransactionsStep(CPerformanceFunctionalityTestsSuite &aParent) : CPerformanceFunctionalityBase(KNumberOfContacts, aParent)
+	{
+	SetTestStepName(KTransactionsStep);
+	}
+
+TVerdict CTransactionsStep::doTestStepPostambleL()
+	{
+	const TInt error = iParent->Fs().Delete(KVcardFile);
+	if( KErrNotFound != error && KErrNone != KErrNone )
+		{
+		_LIT(KDeleteError,"Unexpected error when deleting vcard file, error: %d");
+		ERR_PRINTF2(KDeleteError, error);
+		}
+	return CPerformanceFunctionalityBase::doTestStepPostambleL();
+	}
+	
+void CTransactionsStep::PreTestL()
+	{
+	User::LeaveIfError( iParent->Fs().Connect() );
+	}
+
+
+TVerdict CTransactionsStep::doTestStepL()
+/**
+ * @return - TVerdict code
+ * Override of base class pure virtual
+ * Our implementation only gets called if the base class doTestStepPreambleL() did
+ * not leave. That being the case, the current test result value will be EPass.
+ */
+	{	
+	__UHEAP_MARK;
+	InitializeL();
+	_LIT(KStartTest,"CTransactionsStep::doTestStepL()");
+	ALLPRINT(KStartTest);  //Block start 
+	iIterate->Reset();
+	
+	const TDesC &run = ConfigSection();
+	
+	if( run == KRun1 )
+		{
+		ALLPRINT(KTest1);
+		NestedTransactionTestL();
+		}
+	else if( run == KRun2 )
+		{
+		ALLPRINT(KTest2);
+		EmptyCommitTransactionTestL(EFalse);
+		}
+	else if( run == KRun3 )
+		{
+		ALLPRINT(KTest3);
+		EmptyCommitTransactionTestL(ETrue);
+		}
+	else if( run == KRun4 )
+		{
+		ALLPRINT(KTest4);
+		UpdateCommitTransactionTestL(EFalse);
+		}
+	else if( run == KRun5 )
+		{
+		ALLPRINT(KTest5);
+		UpdateCommitTransactionTestL(ETrue);
+		}
+	else if( run == KRun6 )
+		{
+		ALLPRINT(KTest6);
+		CreateCommitTransactionTestL(EFalse);
+		}
+	else if( run == KRun7 )
+		{
+		ALLPRINT(KTest7);
+		CreateCommitTransactionTestL(ETrue);
+		}
+	else if( run == KRun8 )
+		{
+		ALLPRINT(KTest8);
+		DeleteCommitTransactionTestL(EFalse);
+		}
+	else if( run == KRun9 )
+		{
+		ALLPRINT(KTest9);
+		DeleteCommitTransactionTestL(ETrue);
+		}
+	else if( run == KRun10 )
+		{
+		ALLPRINT(KTest10);
+		ManyUpdateCommitTransactionTestL(EFalse);
+		}
+	else if( run == KRun11 )
+		{
+		ALLPRINT(KTest11);
+		ManyUpdateCommitTransactionTestL(ETrue);
+		}
+	else if( run == KRun12 )
+		{
+		ALLPRINT(KTest12);
+		EmptyTransactionPerformanceTestL( EFalse);
+		}
+	else if( run == KRun13 )
+		{
+		ALLPRINT(KTest13);
+		EmptyTransactionPerformanceTestL( ETrue );
+		}
+	else if( run == KRun14 )
+		{
+		ALLPRINT(KTest14);
+		MediumTransactionPerformanceTestL( EFalse);
+		}
+	else if( run == KRun15 )
+		{
+		ALLPRINT(KTest15);
+		MediumTransactionPerformanceTestL( ETrue);
+		}
+	else if( run == KRun16 )
+		{
+		ALLPRINT(KTest16);
+		FullTransactionPerformanceTestL( EFalse);
+		}
+	else if( run == KRun17 )
+		{
+		ALLPRINT(KTest17);
+		FullTransactionPerformanceTestL( ETrue);
+		}
+	else if( run == KRun18 )
+		{
+		ALLPRINT(KTest18);
+		MultipleCommitTestL( EFalse);
+		}
+	else if( run == KRun19 )
+		{
+		ALLPRINT(KTest19);
+		MultipleCommitTestL( ETrue);
+		}
+	else
+		{
+		MissingTestPanic();
+		}
+
+	Cleanup();
+	__UHEAP_MARKEND;
+
+	return TestStepResult();
+	}
+
+/**
+if in revert mode rollback transaction, otherwise commit
+*/
+void CTransactionsStep::EndTransactionL(const TBool aRevert)
+	{
+	if(aRevert)
+		{
+		iContactsDatabase->DatabaseRollback();
+		CleanupStack::Pop();
+		if( iContactsDatabase->IsDamaged() )
+			{
+			iContactsDatabase->RecoverL();
+			}
+		}
+	else
+		{
+		iContactsDatabase->DatabaseCommitLP(EFalse);
+		}
+	}
+
+void CTransactionsStep::NestedTransactionTestL()
+	{
+	TContactItemId cid = iIterate->NextL();
+	
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	iContactsDatabase->DatabaseBeginLC(ETrue);
+	OpenL(cid);
+	SetFieldL(1, GetFieldL(KStringFields, KField, 1) );
+	CommitL(ETrue);
+	iContactsDatabase->DatabaseCommitLP(ETrue);
+	OpenL(cid);
+	SetFieldL(2, GetFieldL(KStringFields, KField, 2) );
+	CommitL(ETrue);	
+	EndTransactionL(ETrue);
+	
+	iIterate->Reset();
+	TInt err = KErrNone;
+	TInt k = 0;
+	TESTPRINT( iContactsDatabase->CountL() == iContacts );
+	
+	for( k = 0; k < iContacts; ++k)
+		{
+		TRAP(err, ReadL( iIterate->NextL() ) );
+		TESTPRINTI( KErrNone == err, k );
+		TESTPRINTI( CheckAllFieldsL(KNullDesC), k );
+		CloseL( ETrue );
+		}	
+	}
+
+void CTransactionsStep::EmptyCommitTransactionTestL(const TBool aRevert)
+	{
+	CPerformanceFunctionalityBase::InitializeL();
+	
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	EndTransactionL(aRevert);
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	ReadL( iIterate->NextL() );
+	EndTransactionL(aRevert);
+	CloseL( ETrue );
+	
+	iIterate->Reset();
+	TInt i = 0;
+	for(; i < iContacts; ++i)
+		{
+		ReadL( iIterate->NextL() );
+		TESTPRINTI( CheckAllFieldsL(KNullDesC), i );
+		CloseL( ETrue );
+		}
+			
+	}
+	
+void CTransactionsStep::UpdateCommitTransactionTestL(const TBool aRevert)
+	{
+	CPerformanceFunctionalityBase::InitializeL();
+	
+	const TContactItemId cid = iIterate->NextL();
+	const TContactItemId cid2 = iIterate->NextL();
+	
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	OpenL( cid );
+	SetAllFieldsL( GetNextFieldL(KStringFields, KField, ETrue) );
+	CommitL(ETrue);
+	EndTransactionL(aRevert);
+
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	ReadL( cid2 );
+	SetAllFieldsL( GetNextFieldL(KStringFields, KField, EFalse) );
+	iContactsDatabase->UpdateContactLC(cid2, iContactItem);
+	CleanupStack::PopAndDestroy();
+	CloseL( ETrue );
+	EndTransactionL(aRevert);
+	
+	if(aRevert)
+		{
+		iIterate->Reset();
+		TInt i = 0;
+		for(; i < iContacts; ++i)
+			{
+			ReadL( iIterate->NextL() );
+			TESTPRINTI( CheckAllFieldsL(KNullDesC), i );
+			CloseL( ETrue );
+			}
+		}
+	else
+		{
+		ReadL( cid );
+		TESTPRINT( CheckAllFieldsL( GetNextFieldL(KStringFields, KField, ETrue) ) );
+		CloseL( ETrue );
+		
+		ReadL( cid2 );
+		TESTPRINT( CheckAllFieldsL( GetNextFieldL(KStringFields, KField, EFalse) ) );
+		CloseL( ETrue );
+		}
+	}
+	
+void CTransactionsStep::CreateCommitTransactionTestL(const TBool aRevert)
+	{
+	iContacts = 0;
+	CPerformanceFunctionalityBase::InitializeL();
+	
+	CContactItemFieldSet& templateFields = iTemplate->CardFields();
+	TInt fieldsCount = templateFields.Count() - 1;
+	
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	
+	iContacts = 2;
+	TInt k = 0;
+	CContactCard* contact = CContactCard::NewLC(iTemplate);
+	for(; k < iContacts; k++)
+		{		
+		iIterate->AddL( iContactsDatabase->doAddNewContactL(*contact,EFalse,ETrue) );
+		}	
+	CleanupStack::PopAndDestroy(contact);
+	
+	EndTransactionL(aRevert);
+	
+	if(aRevert)
+		{
+		iIterate->Reset();
+		TInt err = KErrNone;
+		TESTPRINT( iContactsDatabase->CountL() == 0 );
+		
+		for( k = 0; k < iContacts; ++k)
+			{
+			TRAP(err, ReadL( iIterate->NextL() ) );
+			TESTPRINTI( KErrNotFound == err, k );
+			CloseL( ETrue );
+			}
+		}
+	else
+		{
+		iIterate->Reset();
+		TESTPRINT( ( iContactsDatabase->CountL() == iContacts ) );
+		
+		for(k = 0; k < iContacts; ++k)
+			{
+			ReadL( iIterate->NextL() );
+			TESTPRINTI( iFields->Count() == fieldsCount, k );
+			TESTPRINTI( CheckAllFieldsL(KNullDesC), k );
+			CloseL( ETrue );
+			}
+		}
+	}	
+	
+void CTransactionsStep::DeleteCommitTransactionTestL(const TBool aRevert)
+	{
+	iContacts = 10;
+	CPerformanceFunctionalityBase::InitializeL();
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	
+	TInt k = 0;
+	for(; k < iContacts; k++)
+		{		
+		iContactsDatabase->doDeleteContactL(iIterate->NextL(), ETrue, ETrue);
+		}
+	
+	EndTransactionL(aRevert);
+	
+	if(aRevert)
+		{
+		TESTPRINT( iContactsDatabase->CountL() == iContacts );
+		iIterate->Reset();
+		TInt err = KErrNone;
+		for(k = 0; k < iContacts; ++k)
+			{
+			TRAP(err, ReadL( iIterate->NextL() ) );
+			TESTPRINTI( KErrNone == err, k );
+			TESTPRINTI( CheckAllFieldsL( KNullDesC ), k );
+			CloseL( ETrue );
+			}
+		}
+	else
+		{
+		TESTPRINT( iContactsDatabase->CountL() == 0 );
+		
+		iIterate->Reset();
+		TInt err = KErrNone;
+		for(k = 0; k < iContacts; ++k)
+			{
+			TRAP(err, ReadL( iIterate->NextL() ) );
+			TESTPRINTI( KErrNotFound == err, k );
+			CloseL( ETrue );
+			}
+		iIterate->Clear();
+		}
+	}
+	
+void CTransactionsStep::ManyUpdateCommitTransactionTestL( const TBool aRevert )
+	{
+	iContacts = 1000;
+	CPerformanceFunctionalityBase::InitializeL();
+	RCntList backuplist;
+	backuplist.CopyL( *iIterate );
+	iContactsDatabase->DatabaseBeginLC(EFalse);
+	
+	TInt added = 0;
+	TInt deleted = 0;
+	TInt updated = 0;
+	TInt k = 0;
+	for(; k < iContacts; k++)
+		{
+		switch( k % KNumCUDOperations )
+			{
+			case ( EOpen ):
+				{
+				OpenL( iIterate->NextL() );
+				//if setting first contact read first field from stringfields section
+				//otherwise read next field in list of fields stored in ini file secion
+				SetAllFieldsL( GetNextFieldL(KStringFields, KField, 0 == k ) );
+				CommitL(ETrue);
+				++updated;
+				}
+			break;
+			case ( EUpdate ):
+				{
+				TContactItemId cid = iIterate->NextL();
+				ReadL( cid );
+				//if setting first contact read first field from stringfields section
+				//otherwise read next field in list of fields stored in ini file secion
+				SetAllFieldsL( GetNextFieldL(KStringFields, KField, 0 == k ) );
+				iContactsDatabase->UpdateContactLC(cid, iContactItem);
+				CleanupStack::PopAndDestroy();
+				CloseL( ETrue );
+				++updated;
+				}
+			break;
+			case ( EAddDelete ):
+				{
+				DeleteContactL( iIterate->NextL(), ETrue );
+				//iterator position is shifted back, so that next nextL call is correct
+				iIterate->PreviousL();
+				++deleted;
+				//Empty contact is appended to the database, 
+				//Contact id is stored at the end of iterator list not at current iterator position
+				AddEmptyContactsL( 1, ETrue );
+				++added;
+				}
+			break;
+			default:
+				{
+				_LIT(KInvalidTest, "Invalid Case");
+				User::Panic(KInvalidTest, 555);
+				}
+			break;
+			}
+		}
+	
+	EndTransactionL(aRevert);
+	TESTPRINT( iContactsDatabase->CountL() == iContacts );
+	
+	CContactItemFieldSet& templateFields = iTemplate->CardFields();
+	TInt fieldsCount = templateFields.Count() - 1;
+	
+	if(aRevert)
+		{
+		//if transaction is reverted / rolledback, all contacts should be
+		//unchanged, i.e. they should all contain empty fields only
+		backuplist.Reset();
+		TInt err = KErrNone;
+		for(k = 0; k < iContacts; ++k)
+			{
+			TRAP(err, ReadL( backuplist.NextL() ) );
+			TESTPRINTI( KErrNone == err, k );
+			TESTPRINTI( CheckAllFieldsL( KNullDesC ), k );
+			CloseL( ETrue );
+			}
+		}
+	else
+		{
+		iIterate->Reset();
+		//all updated contact should contain the appropriated updated field value
+		for(k = 0; k < updated; ++k)
+			{
+			ReadL( iIterate->NextL() );
+			TESTPRINTI(iFields->Count() == fieldsCount, k);
+			//if reading first contact read first field from stringfields section
+			//otherwise read next field in list of fields stored in ini file secion
+			TESTPRINTI( CheckAllFieldsL( GetNextFieldL(KStringFields, KField, 0 == k ) ), k );
+			CloseL( ETrue );
+			}
+			
+		//all newly	added contacts, should contain empty fields only.
+		for(k = 0; k < added; ++k)
+			{
+			ReadL( iIterate->NextL() );
+			TESTPRINTI( iFields->Count() == fieldsCount, k);
+			TESTPRINTI( CheckAllFieldsL( KNullDesC ), k);
+			CloseL( ETrue );
+			}
+		}
+	}
+
+void CTransactionsStep::TransactionPerformanceL(	const TBool aDelete, 
+													const FieldFullness aField,
+													const TInt aContacts,
+													TReal &aDiffseconds,
+													TReal &aCumseconds)
+	{
+	iContacts = ( ( aContacts / KTransactionSize ) + 1 ) * KTransactionSize ;
+	TInt64 cumlative = 0;
+	TInt64 diff = 0;
+	TTime startT;
+	TTime finishT;
+	TTime start;
+	TTime finish;
+
+	TInt j = 0;
+	for(; j < KPerfIter; ++j)
+		{
+		CPerformanceFunctionalityBase::InitializeL();
+		ModifyContactsL(aField);
+		ExportVcardL( aDelete, KVcardFile );
+		RFileReadStream rfrs;
+		CleanupClosePushL( rfrs );
+		User::LeaveIfError( rfrs.Open( iParent->Fs(), KVcardFile, EFileRead | EFileShareAny ) );
+		
+		TInt i = 0;
+		start.UniversalTime();
+		for(; i < iContacts; i+=KTransactionSize)
+			{
+			iContactsDatabase->DatabaseBeginLC(EFalse);
+			ImportVcardL(KTransactionSize, rfrs);
+			startT.UniversalTime();
+			iContactsDatabase->DatabaseCommitLP(EFalse);
+			finishT.UniversalTime();
+			cumlative += ( finishT.MicroSecondsFrom( startT ).Int64() );
+			}
+		finish.UniversalTime();
+		diff += ( finish.MicroSecondsFrom(start).Int64() );
+		CleanupStack::PopAndDestroy(&rfrs);
+		}
+	User::LeaveIfError( iParent->Fs().Delete(KVcardFile) );
+	
+	aDiffseconds = (TReal) diff / (1000000 * KPerfIter);
+	aCumseconds = (TReal) cumlative / (1000000 * KPerfIter);
+	
+	_LIT(KMicroPerformance, "Micro performance: %d");
+	_LIT(KSecondsPerformance, "performance in seconds: %f");
+	_LIT(KCommitPerformance, "commit performance in seconds: %f");
+	ALLPRINT2(KMicroPerformance, diff); 
+	ALLPRINT2(KSecondsPerformance, aDiffseconds ); 
+	ALLPRINT2(KCommitPerformance, aCumseconds ); 
+	}
+
+void CTransactionsStep::EmptyTransactionPerformanceTestL(const TBool aDelete)
+	{
+	TReal diffsecondsMax = 0;
+	TReal commitsecondsMax = 0;
+	
+	_LIT(KMaxContactsPrint,"$Max contacts$");
+	ALLPRINT(KMaxContactsPrint); 
+	TransactionPerformanceL(aDelete, EEmpty, KMaxContacts, diffsecondsMax, commitsecondsMax);
+	
+	TESTPRINT( diffsecondsMax < KMaxTimeAllowed );
+	}
+
+void CTransactionsStep::MediumTransactionPerformanceTestL(const TBool aDelete)
+	{
+	TReal diffsecondsMin = 0;
+	TReal commitsecondsMin = 0;
+	TReal diffsecondsMid = 0;
+	TReal commitsecondsMid = 0;
+	TReal diffsecondsMan = 0;
+	TReal commitsecondsMan = 0;
+	TReal diffsecondsMax = 0;
+	TReal commitsecondsMax = 0;
+		
+	ALLPRINT(KMinContactsPrint); 
+	TransactionPerformanceL(aDelete, EMedium, KMinContacts, diffsecondsMin, commitsecondsMin);
+	ALLPRINT(KMidContactsPrint); 
+	TransactionPerformanceL(aDelete, EMedium, KMidContacts, diffsecondsMid, commitsecondsMid);
+	ALLPRINT(KManyContactsPrint); 
+	TransactionPerformanceL(aDelete, EMedium, KManyContacts, diffsecondsMan, commitsecondsMan);
+	ALLPRINT(KMaxContactsPrint); 
+	TransactionPerformanceL(aDelete, EMedium, KMaxContacts, diffsecondsMax, commitsecondsMax);
+
+
+	TESTPRINT( diffsecondsMax < KMaxTimeAllowed );
+	}
+
+void CTransactionsStep::FullTransactionPerformanceTestL(const TBool aDelete)
+	{
+	TReal diffsecondsMin = 0;
+	TReal commitsecondsMin = 0;
+	TReal diffsecondsMid = 0;
+	TReal commitsecondsMid = 0;
+	TReal diffsecondsMan = 0;
+	TReal commitsecondsMan = 0;
+	TReal diffsecondsMax = 0;
+#ifdef __WINSCW__
+	TReal commitsecondsMax = 0;
+#endif
+	
+	ALLPRINT(KMinContactsPrint); 
+	TransactionPerformanceL(aDelete, EFull, KMinContacts, diffsecondsMin, commitsecondsMin);
+	ALLPRINT(KMidContactsPrint); 
+	TransactionPerformanceL(aDelete, EFull, KMidContacts, diffsecondsMid, commitsecondsMid);
+	ALLPRINT(KManyContactsPrint); 
+	TransactionPerformanceL(aDelete, EFull, KManyContacts, diffsecondsMan, commitsecondsMan);
+	//is too slow on hardware, also takes up too much disk space
+	#ifdef __WINSCW__
+	ALLPRINT(KMaxContactsPrint); 
+	TransactionPerformanceL(aDelete, EFull, KMaxContacts, diffsecondsMax, commitsecondsMax);
+	#endif
+	
+	TESTPRINT( diffsecondsMax < KMaxTimeAllowed );
+	}
+
+void CTransactionsStep::MultipleCommitTestL(const TBool aTrans)
+	{
+	iContacts = 40;
+	CPerformanceFunctionalityBase::InitializeL();
+	if(aTrans)
+		{
+		iContactsDatabase->DatabaseBeginLC(EFalse);
+		}
+	MultipleCommitL(aTrans);
+	if(aTrans)
+		{
+		EndTransactionL(EFalse);
+		}
+	TInt k = 0;
+	iIterate->Reset();
+	for(; k < iContacts; ++k)
+		{
+		ReadL( iIterate->NextL() );
+		TESTPRINTI( CheckAllFieldsL( GetNextFieldL(KStringFields, KField, 0 == k ) ), k );
+		CloseL( ETrue );
+		}
+	}
+
+/**
+destroy array from within cleanupstack
+*/
+static void ArrayCleanup(TAny *aArray)
+	{
+	RPointerArray<CContactItem> *parray = static_cast< RPointerArray<CContactItem> * >(aArray);
+	parray->ResetAndDestroy();
+	}
+
+void CTransactionsStep::MultipleCommitL(const TBool aTrans)
+	{
+	RPointerArray<CContactItem> itemarray( 500, 512 );
+	TCleanupItem tclean(ArrayCleanup,&itemarray);
+	CleanupStack::PushL( tclean );
+	TInt k = 0;
+	iIterate->Reset();
+	for(; k < iContacts; ++k)
+		{
+		itemarray.Append( iContactsDatabase->OpenContactLX( iIterate->NextL(), *iViewAll ) );
+		iFields = &( itemarray[k]->CardFields() );
+		SetAllFieldsL( GetNextFieldL(KStringFields, KField, 0 == k ) );
+		}
+
+	iIterate->Reset();
+	if(aTrans)
+		{
+		for( k = iContacts - 1; k >=0 ; --k )
+			{
+			iContactsDatabase->doCommitContactL(*itemarray[k], ETrue, ETrue );
+			CleanupStack::Pop();
+			}
+		}
+	else
+		{
+		for( k = iContacts - 1; k >=0 ; --k )
+			{
+			iContactsDatabase->CommitContactL(*itemarray[k]);
+			CleanupStack::Pop();
+			}
+		}
+	CleanupStack::PopAndDestroy();//tclean
+	}
+
+/**
+populates all contacts either moderately, fully, or not at all
+*/
+void CTransactionsStep::ModifyContactsL(const FieldFullness aField)
+	{
+	if(aField == EEmpty)
+		{
+		return;
+		}
+	iIterate->Reset();
+	TInt j = 0;
+	for(; j < iContacts; ++j)
+		{
+		OpenL(iIterate->NextL());
+		if(aField == EFull)
+			{
+			SetAllFieldsL( GetFieldL(KStringFields, KField, 2) );
+			}
+		else
+			{
+			SetManyFieldsL(GetFieldL(KStringFields, KField, 4) , KMediumFields);
+			}
+		CommitL(EFalse);
+		}
+	}
+