phonebookengines_old/contactsmodel/tsrc/cntmodel2/T_DBTransactionTest.cpp
changeset 40 b46a585f6909
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/cntmodel2/T_DBTransactionTest.cpp	Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,1197 @@
+// Copyright (c) 2005-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:
+//
+
+#include "T_DBTransactionTest.h"
+_LIT(KTestName, "T_Database_Transaction_Tests"); // Used by Testhelper - gives an warning under ARMv5
+const TInt MAX_TRY = 10;
+#include "..\..\tsrc\testhelpers.h"
+#include <e32base.h>
+
+#include "T_CAsyncTest.h"
+
+/*
+					How to Add a new concurrent Test
+	++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Add a new header and cpp file for each new test class.
+	Additions to the CConcurrentController
+		1. Add a new private Method called Start-TestName
+		2. Call the new method from StartTestL	
+		3. Add a new enum value called E-TestName to TTestCodes in 
+			the header file.
+		4. Within the new Start-TestName method, call RunTestThreadL passing in
+			the new enum. Refer to StartTimeOutTestL
+	Additions to the CConcurrentTester
+		1. Instantiate and execute your test class in the RunTestL method.
+	
+*/
+
+CConcurrentController::~CConcurrentController()
+	{
+	iStore.ResetAndDestroy();
+	}
+	
+CConcurrentController* CConcurrentController::NewLC()
+	{
+	CConcurrentController* self = new (ELeave) CConcurrentController();
+	CleanupStack::PushL(self);
+	return self;	
+	}
+	
+CConcurrentController::CConcurrentController()
+	{}
+	
+
+void CConcurrentController::StartTestL(TInt aNoOfTesters)
+	{
+//	StartTransactionTestL(aNoOfTesters);
+	StartTimeOutTestL(aNoOfTesters);
+//	StartAsyncOpenTestL(aNoOfTesters);
+	}
+	
+void CConcurrentController::StartTransactionTestL(TInt aNoOfTesters)
+	{
+	test.Printf(_L("Starting Transaction Tests"));
+	CreateTestersL(aNoOfTesters);
+	// Create the tests and kick off the thread.
+	for (TInt ii = 0; ii < aNoOfTesters; ++ii)
+		{
+		iStore[ii]->RunTestThreadL(); 
+		}
+	
+	while (!Completed())	
+		User::WaitForAnyRequest();
+	}
+
+void CConcurrentController::CreateTestersL(TInt aNoOfTesters)
+	{
+	if (iStore.Count() == 0)
+		{
+		_LIT(KThreadName,"Thread_%d");
+		TBuf<256> buf;
+
+		for (TInt ii = 0; ii < aNoOfTesters; ++ii)
+			{
+			buf.Format(KThreadName, ii);
+			iStore.AppendL(CConcurrentTester::NewL(CEventResponse::NewL(*this), buf));
+			}
+		}
+	}
+
+void CConcurrentController::StartAsyncOpenTestL(TInt aNoOfTesters)
+	{
+	test.Printf(_L("Starting Async Open Tests"));
+	CreateTestersL(aNoOfTesters);
+	// Create the tests and kick off the thread.
+	for (TInt ii = 0; ii < aNoOfTesters; ++ii)
+		{
+		iStore[ii]->RunTestThreadL(EAsyncOpenTest); 
+		}
+	
+	while (!Completed())	
+		User::WaitForAnyRequest();
+	
+	}
+
+void CConcurrentController::StartTimeOutTestL(TInt aNoOfTesters)
+	{
+	test.Printf(_L("Starting TimeOut Test\n\r"));
+	CreateTestersL(aNoOfTesters);
+	
+	for (TInt ii = 0; ii < aNoOfTesters; ++ii)
+		{
+		if (ii%2 == 0)
+			{
+			iStore[ii]->RunTestThreadL(ENonTimeOutTest);	
+			}
+		else
+			{
+			iStore[ii]->RunTestThreadL(ETimeOutTest);				
+			}
+		}
+	while (!Completed())	
+		User::WaitForAnyRequest();
+	}
+
+
+TBool CConcurrentController::Completed()
+	{
+	TInt noOfTesters = iStore.Count();
+	for (TInt ii = 0; ii < noOfTesters; ++ii)
+		{
+		if (iStore[ii]->IsCompleted())
+			return EFalse;	
+		}
+	return ETrue;
+	}
+	
+void CConcurrentController::PublishError(TInt aError)
+	{
+	test.Printf(_L(" ->  TEST FAILED - Error %d was reported during execution"), aError);
+	}
+
+
+
+
+
+CEventResponse* CEventResponse::NewL(CConcurrentController& aController)
+	{
+	CEventResponse* self = new (ELeave) CEventResponse(aController);
+	return self;	
+	}
+
+
+CEventResponse::CEventResponse(CConcurrentController& aController) : CActive(EPriorityIdle), iController(aController) 
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+CEventResponse::~CEventResponse()
+	{}
+
+
+void CEventResponse::RunL()
+	{
+	test.Next(_L("-> Thread Finished\r"));
+
+	}
+
+
+void CEventResponse::DoCancel()
+	{
+	Cancel();
+	}
+
+
+TInt CEventResponse::RunError(TInt aError)
+	{
+	iController.PublishError(aError);
+	return aError;
+	}
+
+
+void CEventResponse::CompleteRequest(TInt aError)
+	{
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, aError);
+	}
+			
+TRequestStatus& CEventResponse::RequestStatus()
+	{
+	return iStatus;
+	}
+			
+
+CConcurrentTester::~CConcurrentTester()
+	{
+	delete iResponse;	
+	iThread.Close();	
+	}
+
+
+CConcurrentTester* CConcurrentTester::NewL(CEventResponse* aResponse, const TDesC& aThreadName)
+	{
+	CConcurrentTester* self = new (ELeave) CConcurrentTester(aResponse, aThreadName);
+	return self;	
+	}
+
+	
+TInt CConcurrentTester::ThreadFunction(TAny* aTester)
+	{
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+	if	(!cleanup)
+		return KErrNoMemory;
+	
+	CActiveScheduler*  scheduler = new CActiveScheduler;
+	CActiveScheduler::Install(scheduler);
+	
+	TRAPD(err, static_cast<CConcurrentTester*>(aTester)->RunTestL());	
+
+	delete scheduler;	
+	scheduler = NULL;
+    delete cleanup;
+    cleanup   = NULL;
+    
+	return err;
+	}
+
+TBool CConcurrentTester::IsCompleted()
+	{
+	return iResponse->RequestStatus() == KRequestPending;	
+	}
+
+// Wrapper method for Test class RunTestL()
+// This method is called from within the ThreadFunction() method
+// and runs in a new thread. Apart from this function all the concurrent
+// logic is in the CTransactionThreadTest class.
+
+void CConcurrentTester::RunTestL()
+	{
+	switch(iTestCode)
+		{
+		case ETransactionTest:
+			{
+			CTransactionThreadTest* transTest = CTransactionThreadTest::NewLC();
+			transTest->RunTestL();
+			CleanupStack::PopAndDestroy(transTest);
+			transTest = NULL;
+			break;
+			}
+		case ETimeOutTest:
+			{
+			CTransTimeOutThread* timeOut = CTransTimeOutThread::NewLC();
+			timeOut->RunTestL();
+			CleanupStack::PopAndDestroy(timeOut);
+			timeOut = NULL;	
+			break;
+			}
+		case ENonTimeOutTest:
+			{
+			CReqTimeOutThread* nonTimeOut = CReqTimeOutThread::NewLC();
+			nonTimeOut->RunTestL();
+			CleanupStack::PopAndDestroy(nonTimeOut);
+			nonTimeOut = NULL;
+			break;
+			}
+		case EAsyncOpenTest:
+			{
+			CAsyncTest* asyncTest = CAsyncTest::NewLC();
+			CleanupStack::PopAndDestroy(asyncTest);
+			asyncTest = NULL;
+			break;
+			}
+		default:
+			{
+			User::Leave(KErrNotFound);
+			}	
+		}
+	}
+	
+
+void CConcurrentTester::RunTestThreadL(TInt aTestCode)
+	{
+	iTestCode = aTestCode;
+	test.Next(_L("-> %s Started \r"));
+
+	User::LeaveIfError(iThread.Create(iThreadName, CConcurrentTester::ThreadFunction, KDefaultStackSize, 0x2000, 0x200000, this, EOwnerThread));
+	iThread.SetPriority(EPriorityMuchLess);
+	iThread.Logon (iResponse->RequestStatus());
+	iThread.Resume();
+	}
+
+
+
+	
+
+
+//
+// CTransactionThreadTest
+CTransactionThreadTest::~CTransactionThreadTest()
+	{
+	delete iMatchAll;
+	delete iCntItemBldr;
+	delete iDB;
+	delete iGoldenTemplate;
+	delete iTest;
+	}
+	
+CTransactionThreadTest* CTransactionThreadTest::NewLC()
+	{
+	CTransactionThreadTest* self = new (ELeave) CTransactionThreadTest();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;	
+	}
+	
+	
+const CContactTemplate&  CTransactionThreadTest::GetSysTemplateL()
+	{
+	if (!iGoldenTemplate)
+		{
+		CContactItemViewDef* matchAll = CContactItemViewDef::NewLC(CContactItemViewDef::EIncludeFields,CContactItemViewDef::EIncludeHiddenFields);
+		matchAll->AddL(KUidContactFieldMatchAll);
+
+		iGoldenTemplate = static_cast<CContactTemplate*>(iDB->ReadContactL(iDB->TemplateId(), *matchAll));
+		CleanupStack::PopAndDestroy(matchAll);
+		}
+	return *iGoldenTemplate;
+	}
+	
+
+
+void CTransactionThreadTest::CreateAndCommitTestL()
+	{
+	iTest->Next((_L(" %s -> Create Contact and Commit Test"), RThread().Name() ));
+	TInt cntID = AddAndCommitContactL();
+	
+	if (IsContactInDbL(cntID))
+		{
+		iTest->Next((_L(" %s  -> TEST SUCCESS - Contact FOUND after commit test"), RThread().Name() ));
+		return;
+		}
+	iTest->Next((_L(" %s  -> TEST FAILED - Contact NOT FOUND after commit test"), RThread().Name() ));
+	}
+
+
+
+void CTransactionThreadTest::RollbackAndRecoverTestL()
+	{
+	iTest->Next((_L(" %s -> Rollback & Recover Test"), RThread().Name() ));
+	iDB->DatabaseBeginLC(EFalse); 
+
+	TInt cntID = AddContactL();
+	
+	iDB->DatabaseRollback();
+	iDB->RecoverL();
+	
+	CleanupStack::Pop();// Need to pop the rollback
+		
+	if (!IsContactInDbL(cntID))
+		{
+		iTest->Next((_L(" %s -> TEST SUCCESS - Contact was NOT Found after Rollback test"), RThread().Name() ));
+		return;
+		}
+	iTest->Next((_L(" %s -> TEST FAILED - Contact WAS Found after ROLLBACK test"), RThread().Name() ));
+	}
+
+
+	
+void CTransactionThreadTest::UpdateAndCommitTestL()
+	{
+	iTest->Next((_L(" %s  -> Update Contact and Commit Test"), RThread().Name() ));
+
+	TInt cntID = AddAndCommitContactL();
+
+	iDB->DatabaseBeginL(EFalse);	
+	UpdateContactL(cntID);
+	iDB->DatabaseCommitL(EFalse);
+	
+	if (CheckChangedFieldL(cntID))
+		{
+		iTest->Next((_L(" %s -> TEST SUCCESS - Contact FOUND after Update commit test"), RThread().Name() ));
+		return;
+		}
+	iTest->Next((_L(" %s  -> TEST FAILED - Contact NOT FOUND after Update commit test"), RThread().Name() ));
+	}
+
+
+void CTransactionThreadTest::DeleteAndCommitTestL()
+	{
+	iTest->Next((_L(" %s  -> Contact and Commit Test"), RThread().Name() ));
+
+	TInt cntID = AddAndCommitContactL();
+
+	iDB->DatabaseBeginL(EFalse);	
+	DeleteContactL(cntID);
+	iDB->DatabaseCommitL(EFalse);
+	
+	if (!IsContactInDbL(cntID))
+		{
+		iTest->Next((_L(" %s  -> TEST SUCCESS - Contact FOUND after Update commit test"), RThread().Name() ));
+		return;
+		}
+	iTest->Next((_L(" %s  -> TEST FAILED - Contact NOT FOUND after Update commit test"), RThread().Name() ));
+	}
+
+
+
+// ----------- Helper methods -----------
+
+TInt CTransactionThreadTest::AddContactL()
+	{
+	// Create the contact
+	CContactItem* cntItem = iCntItemBldr->GetCntItemLC();    
+
+    TInt cntID = 0;
+    TRAP_IGNORE(cntID = iDB->AddNewContactL(*cntItem));
+		
+
+	CleanupStack::PopAndDestroy(cntItem);
+	cntItem = NULL;
+	return cntID;
+	}
+
+
+TInt CTransactionThreadTest::AddAndCommitContactL()
+	{
+	iDB->DatabaseBeginL(EFalse);
+	TInt cntID = AddContactL();
+
+	for (TInt ii = 0; ii < 100; ++ii)
+	 	AddContactL();
+
+	iDB->DatabaseCommitL(EFalse);
+	return cntID;
+	}
+
+
+void CTransactionThreadTest::DeleteContactL(TInt aCntID) 
+	{
+	// Remove the contact
+    iDB->DeleteContactL(aCntID);
+	}
+
+
+void CTransactionThreadTest::UpdateContactL(TInt aCntID)
+	{
+	CContactItem* cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+	CCntItemModifier* cntModifier = CCntItemModifier::NewLC();
+	
+	cntModifier->SetTextFieldL(KUidContactFieldGivenName, nsPlTransMgr::KName,
+				 *cntItem);
+
+	cntModifier->SetTextFieldL(KUidContactFieldPhoneNumber,
+				KUidContactFieldVCardMapWORK, 
+				KUidContactFieldVCardMapVOICE,
+				KUidContactFieldVCardMapCELL,
+		 		nsPlTransMgr::KNumber, *cntItem);
+
+	cntModifier->SetTextFieldL(KUidContactFieldEMail,
+			    KUidContactFieldVCardMapWORK,
+			    nsPlTransMgr::KEmail, *cntItem);
+
+
+	cntModifier->SetTextFieldL(KUidContactFieldAddress, 
+				nsPlTransMgr::KHomeAdd, *cntItem);
+
+	CleanupStack::PopAndDestroy(cntModifier);
+
+	CContactItem* cntItem2 = iDB->UpdateContactLC(cntItem->Id(), cntItem);
+	CleanupStack::PopAndDestroy(cntItem2);
+	CleanupStack::PopAndDestroy(cntItem);
+	}
+
+
+
+TBool CTransactionThreadTest::CheckChangedFieldL(TInt aCntID)
+	{
+	CContactItem* cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+	CCntItemModifier* cntModifier = CCntItemModifier::NewLC();
+
+	TBool retval = cntModifier->FindTextFieldL(KUidContactFieldGivenName, nsPlTransMgr::KName,
+				 *cntItem) & 
+		cntModifier->FindTextFieldL(KUidContactFieldPhoneNumber,
+				KUidContactFieldVCardMapWORK, 
+				KUidContactFieldVCardMapVOICE,
+				KUidContactFieldVCardMapCELL,
+		 		nsPlTransMgr::KNumber, *cntItem) &
+		cntModifier->FindTextFieldL(KUidContactFieldAddress, 
+				nsPlTransMgr::KHomeAdd, *cntItem)&
+		cntModifier->FindTextFieldL(KUidContactFieldEMail,
+			    KUidContactFieldVCardMapWORK,
+			    nsPlTransMgr::KEmail, *cntItem); 
+
+	CleanupStack::PopAndDestroy(cntModifier);
+	CleanupStack::PopAndDestroy(cntItem);
+	return retval;
+	}
+
+
+
+TBool CTransactionThreadTest::IsContactInDbL(TInt aCntID)
+	{
+	CContactItem* cntItem = NULL;
+	TRAPD(err, cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+		CleanupStack::PopAndDestroy(cntItem);
+		cntItem = NULL;
+		);
+	
+	if (err == KErrNotFound)
+		{
+		return FALSE;	
+		}
+	User::LeaveIfError(err);
+	return TRUE;
+	}
+
+
+void CTransactionThreadTest::ConstructL()
+	{
+	iDB = CContactDatabase::OpenL(); // Default Database.
+	const CContactTemplate& sysTempl(GetSysTemplateL() );
+	iCntItemBldr = CCntItemBuilder::NewLC(sysTempl);
+	CleanupStack::Pop(iCntItemBldr);
+		
+	// Create and name an RTest
+	TPtrC name(RThread().Name());
+	iTest = new(ELeave) RTest(name);
+	}
+
+
+void CTransactionThreadTest::RunTestL()
+	{
+
+	for (int testIndex = 0; testIndex <= EUpdateAndCommitTest; ++testIndex)
+		{
+		switch(testIndex)	
+			{
+			case ECreateAndCommitTest:
+				{
+				CreateAndCommitTestL();
+				break;
+				}
+			case ERollbackAndRecoverTest:
+				{
+				RollbackAndRecoverTestL();
+				break;
+				}
+			case EDeleteAndCommitTest:
+				{
+				DeleteAndCommitTestL();
+				break;
+				}
+			case EUpdateAndCommitTest:
+				{
+				UpdateAndCommitTestL();
+				break;
+				}
+			
+			default:
+				{
+				User::Leave(KErrNotFound);
+				}
+			}
+		}
+	}
+
+
+	
+
+
+
+// Request Timeout test classes
+CTransTimeOutThread* CTransTimeOutThread::NewLC()
+	{
+	CTransTimeOutThread* self = new (ELeave) CTransTimeOutThread();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;					
+	}
+CTransTimeOutThread::~CTransTimeOutThread()
+	{
+	delete iDB;
+	delete iTest;		
+	}
+	
+void CTransTimeOutThread::RunTestL()
+	{
+	// Just wait for TimeOut
+	iDB->DatabaseBeginL(EFalse);
+
+	iTest->Next(_L("Started Transaction & Waiting for 60 seconds...\n"));
+	User::After(KSixtySecondsTimeOut);
+	iTest->Next(_L("Timed Out...\n"));
+
+	TRAP_IGNORE(iDB->DatabaseCommitL(EFalse));
+
+	}
+	
+void CTransTimeOutThread::ConstructL()
+	{
+	iDB = CContactDatabase::OpenL(); // Default Database.
+
+	// Create and name an RTest
+	TPtrC name(RThread().Name());
+	iTest = new(ELeave) RTest(name);	
+	}
+
+
+
+
+	
+	
+	
+
+//
+
+
+
+
+CReqTimeOutThread* CReqTimeOutThread::NewLC()
+	{
+	CReqTimeOutThread* self = new (ELeave) CReqTimeOutThread();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;			
+	}
+
+CReqTimeOutThread::~CReqTimeOutThread()
+	{
+	delete iMatchAll;
+	delete iCntItemBldr;
+	delete iDB;
+	delete iGoldenTemplate;
+	delete iTest;
+	}
+
+void CReqTimeOutThread::RunTestL()
+	{
+	TTime finishTime;
+	TTime now;
+	finishTime.UniversalTime();
+	now.UniversalTime();
+	finishTime +=(KSixtySecondsTimeOut);
+	
+	while (now < finishTime)							
+		{
+		AddContactL(); // Contact the server
+		iTest->Printf(_L("Non TimeOut Thread is maintaining contact with the server\n\r"));
+		User::After(KOneHalfSecondTimeOut);// Every .25 seconds
+		now.UniversalTime();
+		}
+	}
+
+void CReqTimeOutThread::ConstructL()
+	{
+	iDB = CContactDatabase::OpenL(); // Default Database.
+	const CContactTemplate& sysTempl(GetSysTemplateL() );
+	iCntItemBldr = CCntItemBuilder::NewLC(sysTempl);
+	CleanupStack::Pop(iCntItemBldr);
+		
+	// Create and name an RTest
+	TPtrC name(RThread().Name());
+	iTest = new(ELeave) RTest(name);	
+	}
+
+void CReqTimeOutThread::AddContactL()
+	{
+	// Create the contact
+	CContactItem* cntItem = iCntItemBldr->GetCntItemLC();    
+
+    TRAPD(err, iDB->AddNewContactL(*cntItem));
+	if(err != KErrNotReady)
+		{
+		User::LeaveIfError(err); // Propagate the error
+		}
+		
+	CleanupStack::PopAndDestroy(cntItem);
+	cntItem = NULL;
+	}
+
+const CContactTemplate& CReqTimeOutThread::GetSysTemplateL()
+	{
+	if (!iGoldenTemplate)
+		{
+		CContactItemViewDef* matchAll = CContactItemViewDef::NewLC(CContactItemViewDef::EIncludeFields,CContactItemViewDef::EIncludeHiddenFields);
+		matchAll->AddL(KUidContactFieldMatchAll);
+
+		iGoldenTemplate = static_cast<CContactTemplate*>(iDB->ReadContactL(iDB->TemplateId(), *matchAll));
+		CleanupStack::PopAndDestroy(matchAll);
+		}
+	return *iGoldenTemplate;
+	}
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CDBTransTest* CDBTransTest::NewLC()
+	{
+	CDBTransTest* self = new (ELeave) CDBTransTest();
+	CleanupStack::PushL(self);
+
+	self->ConstructL();
+	return self;	
+	}
+
+
+
+void CDBTransTest::ConstructL()
+	{
+	iDB = CContactDatabase::ReplaceL(); // Default Database.
+	const CContactTemplate& sysTempl(GetSysTemplateL() );
+	iCntItemBldr = CCntItemBuilder::NewLC(sysTempl);
+	CleanupStack::Pop(iCntItemBldr);
+	}
+
+
+const CContactTemplate&  CDBTransTest::GetSysTemplateL()
+	{
+	if (!iGoldenTemplate)
+		{
+		CContactItemViewDef* matchAll = CContactItemViewDef::NewLC(CContactItemViewDef::EIncludeFields,CContactItemViewDef::EIncludeHiddenFields);
+		matchAll->AddL(KUidContactFieldMatchAll);
+
+		iGoldenTemplate = static_cast<CContactTemplate*>(iDB->ReadContactL(iDB->TemplateId(), *matchAll));
+		CleanupStack::PopAndDestroy(matchAll);
+		}
+	return *iGoldenTemplate;
+	}
+	
+	
+
+CDBTransTest::~CDBTransTest()
+	{
+	delete iMatchAll;
+	delete iCntItemBldr;
+	delete iDB;
+	delete iGoldenTemplate;
+	}
+
+
+
+void CDBTransTest::RunTestsL()
+	{
+	UpdateAndCommitTestL();
+	CreateAndCommitTestL(); 
+	DeleteAndCommitTestL();
+	RollbackAndRecoverTestL();
+	OutOfMemoryUpdateTestL();
+	OutOfMemoryDeleteTestL();
+	OutOfMemoryAddTestL();
+	}
+
+// ---------- Tests ---------
+
+// Create/commit & Rollback/recover tests.
+
+void CDBTransTest::CreateAndCommitTestL()
+	{
+	test.Next(_L("-> Create Contact and Commit Test"));
+
+	TInt cntID = AddAndCommitContactL();
+	
+	if (IsContactInDbL(cntID))
+		{
+		test.Next(_L("-> TEST SUCCESS - Contact FOUND after commit test"));
+
+		return;
+		}
+	test.Next(_L("-> TEST FAILED - Contact NOT FOUND after commit test"));
+
+	}
+
+void CDBTransTest::RollbackAndRecoverTestL()
+	{
+	test.Next(_L("-> Rollback & Recover Test"));
+
+	iDB->DatabaseBeginLC(EFalse); 
+
+	TInt cntID = AddContactL();
+	
+	iDB->DatabaseRollback();
+	iDB->RecoverL();
+	
+	CleanupStack::Pop();// Need to pop the rollback
+		
+	if (!IsContactInDbL(cntID))
+		{
+		test.Next(_L("-> TEST SUCCESS - Contact was NOT Found after Rollback test"));
+
+		return;
+		}
+	test.Next(_L("-> TEST FAILED - Contact WAS Found after ROLLBACK test"));
+
+	}
+
+void CDBTransTest::UpdateAndCommitTestL()
+	{
+	test.Next(_L("-> Update Contact and Commit Test"));
+
+
+	TInt cntID = AddAndCommitContactL();
+
+	iDB->DatabaseBeginL(EFalse);	
+	UpdateContactL(cntID);
+	iDB->DatabaseCommitL(EFalse);
+	
+	if (CheckChangedFieldL(cntID))
+		{
+		test.Next(_L("-> TEST SUCCESS - Contact FOUND after Update commit test"));
+
+		return;
+		}
+	test.Next(_L("-> TEST FAILED - Contact NOT FOUND after Update commit test"));
+
+	}
+
+
+void CDBTransTest::DeleteAndCommitTestL()
+	{
+	test.Next(_L("-> Contact and Commit Test"));
+
+
+	TInt cntID = AddAndCommitContactL();
+
+	iDB->DatabaseBeginL(EFalse);	
+	DeleteContactL(cntID);
+	iDB->DatabaseCommitL(EFalse);
+	
+	if (!IsContactInDbL(cntID))
+		{
+		test.Next(_L("-> TEST SUCCESS - Contact FOUND after Update commit test"));
+
+		return;
+		}
+	test.Next(_L("-> TEST FAILED - Contact NOT FOUND after Update commit test"));
+
+	}
+
+
+
+// Out Of Memory/Rollback/Recover Tests
+
+void CDBTransTest::OutOfMemoryAddTestL()
+	{
+
+	TInt ret=KErrNoMemory;
+	TInt failAt=0;	  
+	TInt index =0;
+	
+	while (ret!=KErrNone && index < MAX_TRY)
+		{
+		++index;
+		// Add a successful contact, guess the next contact id
+		TInt cntID = AddAndCommitContactL();
+		++cntID;
+		iDB->DatabaseBeginL(EFalse);	
+		++failAt;
+		__UHEAP_SETFAIL(RHeap::EDeterministic,failAt);
+		__UHEAP_MARK;			
+		TRAPD(err, AddContactL());
+		if (err==KErrNone)
+			{
+			iDB->DatabaseCommitL(EFalse);
+			test.Next(_L("-> TEST SUCCESS - Contact committed during OOM Test"));
+
+			__UHEAP_RESET;
+			return;
+			}
+		__UHEAP_RESET;
+		if (err!=KErrNoMemory && err!=KErrNone)
+			{
+			test.Printf(_L("Non standard error: %d\n"),err);
+			}
+		if (err == KErrNoMemory)
+			{
+			iDB->DatabaseRollback();
+			iDB->RecoverL();
+			if (!IsContactInDbL(cntID))
+				{
+				test.Printf(_L(" ->Correct result - Create rollback during OOM - Contact NOT Found... Step: %d \n\r"),failAt); 
+				}
+				else
+				{
+				test.Printf(_L(" ->Error - Delete rollback during OOM - Contact Found... Step: %d \n\r"),failAt);
+				User::Leave(KErrNotFound);
+				}
+			}
+		}
+		if (index == MAX_TRY)
+			{
+			test.Printf(_L(" ->Gave up after %d attempts\n\r"),index); 
+			}
+	}
+
+
+void CDBTransTest::OutOfMemoryDeleteTestL()
+	{
+	TInt ret	= KErrNoMemory;
+	TInt failAt = 0;	  
+	TInt index =0;
+	
+	while (ret!=KErrNone && index < MAX_TRY)
+		{
+		++index;
+		++failAt;
+		TInt cntID = AddAndCommitContactL();
+		iDB->DatabaseBeginL(EFalse);
+		__UHEAP_SETFAIL(RHeap::EDeterministic,failAt);
+		__UHEAP_MARK;			
+		TRAPD(err, DeleteContactL(cntID));
+		
+		if (err==KErrNone)
+			{
+			iDB->DatabaseCommitL(EFalse);
+			test.Next(_L("-> TEST SUCCESS - Delete Contact committed during OOM Test"));
+
+			__UHEAP_RESET;
+			return;
+			}
+		__UHEAP_RESET;
+		if (err!=KErrNoMemory && err!=KErrNone)
+			{
+			test.Printf(_L("Non standard error: %d\n"),err);
+			}
+		if (err == KErrNoMemory)
+			{
+			iDB->DatabaseRollback();
+			iDB->RecoverL();
+		
+			if (IsContactInDbL(cntID))
+				{
+				test.Printf(_L(" ->Correct result - Delete rollback during OOM - Contact Found... Step: %d \n\r"),failAt); 
+				}
+				else
+				{
+				test.Printf(_L(" ->Error - Delete rollback during OOM - Contact NOT Found... Step: %d \n\r"),failAt);
+				User::Leave(KErrNotFound);
+				}
+			}
+		}
+		if (index == MAX_TRY)
+			{
+			test.Printf(_L(" ->Gave up after %d attempts\n\r"),index); 
+			}
+	}
+
+
+void CDBTransTest::OutOfMemoryUpdateTestL()
+	{
+
+	TInt ret=KErrNoMemory;
+	TInt failAt=0;	  
+	TInt index =0;
+	
+	while (ret!=KErrNone && index < MAX_TRY)
+		{
+		++index;
+		TInt cntID = AddAndCommitContactL();
+		iDB->DatabaseBeginL(EFalse);
+		++failAt;
+
+		__UHEAP_SETFAIL(RHeap::EDeterministic,failAt);
+		__UHEAP_MARK;			
+		TRAPD(err, UpdateContactL(cntID));
+		if (err==KErrNone)
+			{
+			iDB->DatabaseCommitL(EFalse);
+			test.Next(_L("-> TEST SUCCESS - Contact committed during OOM Test"));
+
+			__UHEAP_RESET;
+			return;
+			}
+		__UHEAP_RESET;
+		if (err!=KErrNoMemory && err!=KErrNone)
+			{
+			test.Printf(_L("Non standard error: %d\n"),err);
+			}
+		if (err == KErrNoMemory)
+			{
+			iDB->DatabaseRollback();
+			iDB->RecoverL();
+			
+			// Has the contact changed?
+			if (!CheckChangedFieldL(cntID))
+				{
+				test.Printf(_L(" ->Correct result - Update rollback during OOM - Updated Contact NOT Found... Step: %d \n\r"),failAt);			
+				}
+				else
+				{
+				test.Printf(_L(" ->Error - Update rollback during OOM - Updated Contact Found... Step: %d \n\r"),failAt);
+				User::Leave(KErrNotFound);
+				}
+			}
+		}
+		if (index == MAX_TRY)
+			{
+			test.Printf(_L(" ->Gave up after %d attempts\n\r"),index); 
+			}
+
+	}
+
+
+
+// ----------- Helper methods -----------
+
+TInt CDBTransTest::AddContactL()
+	{
+	// Create the contact
+	CContactItem* cntItem = iCntItemBldr->GetCntItemLC();    
+
+    TInt cntID = iDB->AddNewContactL(*cntItem);
+
+	CleanupStack::PopAndDestroy(cntItem);
+	cntItem = NULL;
+	return cntID;
+	}
+
+
+TInt CDBTransTest::AddAndCommitContactL()
+	{
+	iDB->DatabaseBeginL(EFalse);
+	TInt cntID = AddContactL();
+	iDB->DatabaseCommitL(EFalse);
+	return cntID;
+	}
+
+
+void CDBTransTest::DeleteContactL(TInt aCntID) 
+	{
+	// Remove the contact
+    iDB->DeleteContactL(aCntID);
+	}
+
+
+void CDBTransTest::UpdateContactL(TInt aCntID)
+	{
+	CContactItem* cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+	CCntItemModifier* cntModifier = CCntItemModifier::NewLC();
+	
+	cntModifier->SetTextFieldL(KUidContactFieldGivenName, nsPlTransMgr::KName,
+				 *cntItem);
+
+	cntModifier->SetTextFieldL(KUidContactFieldPhoneNumber,
+				KUidContactFieldVCardMapWORK, 
+				KUidContactFieldVCardMapVOICE,
+				KUidContactFieldVCardMapCELL,
+		 		nsPlTransMgr::KNumber, *cntItem);
+
+	cntModifier->SetTextFieldL(KUidContactFieldEMail,
+			    KUidContactFieldVCardMapWORK,
+			    nsPlTransMgr::KEmail, *cntItem);
+
+
+	cntModifier->SetTextFieldL(KUidContactFieldAddress, 
+				nsPlTransMgr::KHomeAdd, *cntItem);
+
+	CleanupStack::PopAndDestroy(cntModifier);
+
+	CContactItem* cntItem2 = iDB->UpdateContactLC(cntItem->Id(), cntItem);
+	CleanupStack::PopAndDestroy(cntItem2);
+	CleanupStack::PopAndDestroy(cntItem);
+	}
+
+
+
+TBool CDBTransTest::CheckChangedFieldL(TInt aCntID)
+	{
+	CContactItem* cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+	CCntItemModifier* cntModifier = CCntItemModifier::NewLC();
+
+	TBool retval = cntModifier->FindTextFieldL(KUidContactFieldGivenName, nsPlTransMgr::KName,
+				 *cntItem) & 
+		cntModifier->FindTextFieldL(KUidContactFieldPhoneNumber,
+				KUidContactFieldVCardMapWORK, 
+				KUidContactFieldVCardMapVOICE,
+				KUidContactFieldVCardMapCELL,
+		 		nsPlTransMgr::KNumber, *cntItem) &
+		cntModifier->FindTextFieldL(KUidContactFieldAddress, 
+				nsPlTransMgr::KHomeAdd, *cntItem)&
+		cntModifier->FindTextFieldL(KUidContactFieldEMail,
+			    KUidContactFieldVCardMapWORK,
+			    nsPlTransMgr::KEmail, *cntItem); 
+
+	CleanupStack::PopAndDestroy(cntModifier);
+	CleanupStack::PopAndDestroy(cntItem);
+	return retval;
+	}
+
+
+
+TBool CDBTransTest::IsContactInDbL(TInt aCntID)
+	{
+	CContactItem* cntItem = NULL;
+	TRAPD(err, cntItem = iDB->ReadContactLC(aCntID, *iMatchAll);
+		CleanupStack::PopAndDestroy(cntItem);
+		cntItem = NULL;
+		);
+	
+	if (err == KErrNotFound)
+		{
+		return FALSE;	
+		}
+	User::LeaveIfError(err);
+	return TRUE;
+	}
+
+/**
+
+@SYMTestCaseID     PIM-T-DBTRANSACTIONTEST-0001
+
+*/
+
+LOCAL_C void DoTestsL()
+	{
+    CleanupClosePushL(test);
+	test.Start(_L("@SYMTESTCaseID:PIM-T-DBTRANSACTIONTEST-0001 ----------- Concurrent tests ----------"));
+
+
+//	CDBTransTest* tranTest = CDBTransTest::NewLC();	
+//	tranTest->RunTestsL();
+	CConcurrentController* testController = CConcurrentController::NewLC();
+	testController->StartTestL(6);
+
+	test.End();
+	CleanupStack::PopAndDestroy(testController);
+//	CleanupStack::PopAndDestroy(tranTest);
+    CleanupStack::Pop(); // test.Close & tranMgrTest
+	}
+
+
+
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+
+	CActiveScheduler* scheduler=new CActiveScheduler;
+	if (scheduler)
+		{
+		CActiveScheduler::Install(scheduler);
+		CTrapCleanup* cleanup = CTrapCleanup::New();
+		if (cleanup)
+			{
+			TRAPD(err,DoTestsL());	
+			__ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("DBDumper Failed"),err) ); 
+			delete cleanup;
+			}
+		delete scheduler;
+		}
+	test.Close();	
+	
+	__UHEAP_MARKEND;
+	return KErrNone;
+	
+	}
+
+
+