phonebookengines/contactsmodel/tsrc/Integration/CntPerfTest/src/ContactViewTest.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/Integration/CntPerfTest/src/ContactViewTest.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1526 @@
+// 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 <test/testexecutelog.h>
+#include <cntfldst.h>
+#include <e32panic.h>
+#include <e32cmn.h>
+#include "ClientServer.h"
+#include "ContactViewTest.h"
+#include "ViewObserver.h"
+
+_LIT(KRun1,"EmptyAll");
+_LIT(KRun2,"FullContacts");
+_LIT(KRun3,"FullView");
+_LIT(KRun4,"FullAll");
+_LIT(KRun5,"EmptyFieldset");
+_LIT(KRun6,"EmptyFieldsetView");
+_LIT(KRun7,"MissingFields");
+_LIT(KRun8,"Performance");
+_LIT(KRun9,"CompressRecover");
+_LIT(KRun10,"ConcurrentCNR");
+
+_LIT(KTest1,"Testing Empty contacts and empty view");
+_LIT(KTest2,"Testing Full contacts and empty view");
+_LIT(KTest3,"Testing Empty contacts and Full view");
+_LIT(KTest4,"Testing Full contacts and Full view");
+_LIT(KTest5,"Testing Contacts with empty fieldsets and Full view");
+_LIT(KTest6,"Testing Contacts with empty fieldsets and empty view");
+_LIT(KTest7,"Testing Contacts with 1 or more empty fields and empty view");
+_LIT(KTest8,"***Testing Empty Contacts Views performance***");
+_LIT(KTest81,"***Testing Medium Contacts Views performance***");
+_LIT(KTest82,"***Testing Full Contacts Views performance***");
+_LIT(KTest9,"Compress and recovery test");
+_LIT(KTest10,"Concurrent Compress and recovery test");
+
+static const TInt KManyPerfIters = 1;
+_LIT(KUfield,"field");
+_LIT(KMissingFields, "MissingFields");
+_LIT(KPLView, "PLView");
+_LIT(KRecover, "Recover_" );
+
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+_LIT(KContactsDB,"c:\\private\\10003A73\\Contacts.cdb");
+#else
+_LIT(KContactsDB,"C:\\private\\10003A73\\SQLite__Contacts.cdb");
+#endif
+
+_LIT(KPersistenceDB,"c:\\private\\10273EFB\\Contacts.cdb");
+
+#define ALLPRINT( x )	INFO_PRINTF1( x );\
+						RDebug::Print( x );
+
+#define ALLPRINT2( x, y )	INFO_PRINTF2( x, y );\
+							RDebug::Print( x, y );
+
+
+#ifdef _WINS
+#define KMaxTimeAllowed	500 //seconds, minimum performance
+#else
+#define KMaxTimeAllowed	10000 //hardware is slower
+#endif
+
+_LIT(KStars,"***************");
+_LIT(KStartRecover,"StartRecover");
+_LIT(KEndRecover,"EndRecover");
+_LIT(KStartCompress,"StartCompress");
+_LIT(KEndCompress,"EndCompress");
+
+//Number of contacts
+CContactViewTest::CContactViewTest(CCntPerfServer &aParent):CCntBaseStep(10,aParent),
+															iFullness(EBlank),
+															iPerformanceContacts( EFew )
+	{
+	// Call base class method to set up the human readable name for logging
+	SetTestStepName(SharedConstants::KContactViewTest);
+	}
+
+void CContactViewTest::PreTestL()
+	{
+	iSemaphore.CreateLocal( 0 );
+	iSemaphore2.CreateLocal( 0 );
+	const TDesC &KSection = ConfigSection();
+	iPLView = ( KSection.Find( KPLView ) == 0 ); // section has to start with plview
+	iRecoverFlag = ( KSection.Find( KRecover ) == 0 );
+	}
+
+TVerdict CContactViewTest::doTestStepPostambleL()
+	{
+	iSemaphore.Close();
+	EndRecoverL();
+	EndCompressL();
+	return CCntBaseStep::doTestStepPostambleL();
+	}
+
+void CContactViewTest::CleanupL()
+	{
+	if( iObserver )
+		{
+		iObserver->CleanView();
+		CLEAR( iObserver );
+		}
+
+    CLEAR( iContactsDatabase );
+	CLEAR( iContactsDatabase2 );
+	if( iPLView )
+		{
+		CLEAR(iPersistence);
+		if( iPimServ )
+			{
+			iPimServ->DeleteFileL(KPersistenceDB);
+			iPimServ->Close();
+			CLEAR(iPimServ);
+			}
+		}
+	if( iSortOrder )
+		{
+		iSortOrder->Close();
+		CLEAR(iSortOrder);
+		}
+	CCntBaseStep::Cleanup();
+	}
+
+void CContactViewTest::InitializeL()
+	{
+	CCntBaseStep::InitializeL();
+	if( iPLView )
+		{
+		iPimServ = new(ELeave) RPIMTestServer();
+		User::LeaveIfError(iPimServ->Connect());
+		User::LeaveIfError( iParent->Fs().Connect() );
+		}
+	OpenPersistanceL();//opens iContactsDatabase2
+	iSortOrder = new(ELeave) RContactViewSortOrder();
+	iObserver = CViewObserver::NewLC( *this, &CContactViewTest::AllEmptyTestL );// first test to run
+	CleanupStack::Pop( iObserver );
+	this->Logger().HtmlLogger().ShareAuto();
+	iObserver->Activate();
+	}
+
+TVerdict CContactViewTest::doTestStepL()
+	{
+
+	void (CContactViewTest::*mainFunc)() = NULL;
+
+	const TDesC &run = ConfigSection();
+
+	if( run.Find( KRun1 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::AllEmptyTestL;
+		}
+	else if( run.Find( KRun2 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::ViewEmptyTestL;
+		}
+	else if( run.Find( KRun3 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::ContactEmptyTestL;
+		}
+	else if( run.Find( KRun4 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::AllFullTestL;
+		}
+	else if( run.Find( KRun5 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::EmptyFieldsetTestL;
+		}
+	else if( run.Find( KRun6 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::EmptyFieldsetSortTestL;
+		}
+	else if( run.Find( KRun7 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::MissingFieldTestL;
+		}
+	else if( run.Find( KRun8 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::PerformanceTestL;
+		}
+	else if( run.Find( KRun9 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::RecoverCompressTestL; // this test does not apply to the SQLite version of contacts
+		}
+	else if( run.Find( KRun10 ) > KErrNotFound )
+		{
+		mainFunc = &CContactViewTest::ConcurrentRecoverCompressTestL; // this test does not apply to the SQLite version of contacts
+		}
+	else
+		{
+		MissngTestPanic();
+		}
+
+	__UHEAP_MARK;
+
+	iRemote = EFalse;
+	ALLPRINT(KStars);
+	if( iPLView )
+		{
+		_LIT(KPersistance,"Initialising LocalView on Persistence Layers tests");
+		ALLPRINT(KPersistance);
+		}
+	else
+		{
+		_LIT(KLocalViewCS,"Initialising LocalView on Client/Server tests");
+		ALLPRINT(KLocalViewCS);
+		}
+	ALLPRINT(KStars);
+	InitializeL();
+	iObserver->iMainFunc = mainFunc;
+	CActiveScheduler::Start();
+
+	if( !iPLView )
+		{
+		ALLPRINT(KStars);
+		_LIT(KRemoteViewCS,"Initialising RemoteView on Client/Server tests");
+		ALLPRINT(KRemoteViewCS);
+		ALLPRINT(KStars);
+		iRemote = ETrue;
+        // Ensure that the recover is deleted before another one is created.
+        EndRecoverL();
+		ResetDatabaseL(10);
+		iObserver->iMainFunc = mainFunc;// test to run
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		iObserver->Activate();
+		CActiveScheduler::Start();
+		}
+
+	if( !iPLView )
+		{
+		ALLPRINT(KStars);
+		_LIT(KRemoteViewCS,"Initialising RemoteView on Client/Server tests");
+		ALLPRINT(KRemoteViewCS);
+		ALLPRINT(KStars);
+		iRemote = ETrue;
+		ResetDatabaseL(10);
+		iObserver->iMainFunc = mainFunc;// test to run
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		iObserver->Activate();
+		CActiveScheduler::Start();
+		}
+
+		CleanupL();
+		__UHEAP_MARKEND;
+
+	return TestStepResult();
+	}
+
+/**
+create local view with empty sortorder,
+database is contains ten empty contacts
+*/
+void CContactViewTest::AllEmptyTestL()
+	{
+	ALLPRINT(KTest1);
+	ResetSortL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doAllEmptyTestL;
+	}
+
+/**
+check that local view contains 10 contacts, each containing 1 empty field
+*/
+void CContactViewTest::doAllEmptyTestL(const CContactViewBase &aLView)
+	{
+	ClosePersistanceL(ETrue);
+	TInt length = aLView.CountL();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		manyfields = aLView.ContactAtL(i).FieldCount();
+		INTCOMPARE( manyfields , ==,  1,  i, 0 );
+		SINGLECOMPARE(  CheckViewContact( aLView.ContactAtL(i), KNullDesC ),  i ,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+/**
+create local view with empty sortorder,
+database contains 10 contacts with all fields set to preset values
+*/
+void CContactViewTest::ViewEmptyTestL()
+	{
+	ALLPRINT(KTest2);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	for(TInt i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		OpenL(cid, *iViewAll);
+		SetContactL();
+		CommitL();
+		}
+	ResetSortL();
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doViewEmptyTestL;
+	}
+
+/**
+check that local view contains 10 contacts, each containing 1 empty field
+*/
+void CContactViewTest::doViewEmptyTestL(const CContactViewBase &aLView)
+	{
+	TInt length = aLView.CountL();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+	iIterate->Reset();
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  1,  i, 0 );
+		SINGLECOMPARE(  CheckViewContact( vcontact, GetFieldL(1) ),  i,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+/**
+create local view with sortorder containing all (existing) uids,
+database contains 10 empty contacts
+*/
+void CContactViewTest::ContactEmptyTestL()
+	{
+	ALLPRINT(KTest3);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	ResetSortL();
+
+	TInt length = iExistingUidsArray->Count();
+	TInt i = 0;
+	for( ; i < length ; ++i)
+		{
+		iSortOrder->AppendL( TUid::Uid( (*iExistingUidsArray)[i] ) );
+		}
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doContactEmptyTestL;
+	}
+
+void CContactViewTest::doContactEmptyTestL(const CContactViewBase &aLView)
+	{
+	TInt length = aLView.CountL();
+	TInt arrayLength = iExistingUidsArray->Count();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  arrayLength,  i, 0 );
+		SINGLECOMPARE(  CheckViewContact( vcontact, KNullDesC ),  i ,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+void CContactViewTest::ResetDatabaseL(const TInt aMany)
+	{
+	iIterate->Reset();
+	for(TInt i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		iIterate->RemoveL(cid);
+		}
+	if( aMany > 0 )
+		{
+		iContacts = aMany;
+		}
+	CLEAR( iContactsDatabase );
+	CLEAR( iContactsDatabase2 );
+	iContactsDatabase = CContactDatabase::ReplaceL();
+
+	iContactsDatabase2 = CContactDatabase::OpenL( CContactDatabase::EMultiThread );
+	AddEmptyContactsL(iContacts);
+	iIterate->Reset();
+	}
+
+TBool CContactViewTest::CheckViewContact(const CViewContact &aVContact, const TDesC &aVal)
+	{
+	TBool SingleCheckResult = EFalse;
+	TBool OverallCheckResult = ETrue;
+	TInt length = aVContact.FieldCount();
+	TInt i = 0;
+	for(; i < length; ++i)
+		{
+		SingleCheckResult = STRINGCOMPARE( aVContact.Field(i), ==, aVal, i, 0);
+		OverallCheckResult = OverallCheckResult && SingleCheckResult;
+		}
+	return ( OverallCheckResult && length > 0 );
+	}
+
+/**
+create local view with sortorder containing all (existing) uids,
+database contains 10 contacts with all fields set to preset values
+*/
+void CContactViewTest::AllFullTestL()
+	{
+	ALLPRINT(KTest4);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	TInt i;
+	for(i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		OpenL(cid, *iViewAll);
+		SetContactL();
+		CommitL();
+		}
+
+
+	TInt length = iExistingUidsArray->Count();
+	ResetSortL();
+	for(i = 0 ; i < length ; ++i)
+		{
+		iSortOrder->AppendL( TUid::Uid( (*iExistingUidsArray)[i] ) );
+		}
+
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doAllFullTestL;
+	}
+
+/**
+check that local view contains 10 contacts, each containing as many fields
+as there are uids (114), all field that have a corresponding uid should be
+non-empty
+*/
+void CContactViewTest::doAllFullTestL(const CContactViewBase &aLView)
+	{
+	ClosePersistanceL(ETrue);
+	TInt length = aLView.CountL();
+	TInt arrayLength = iExistingUidsArray->Count();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  arrayLength,  i, 0 );
+		SINGLECOMPARE(  CheckViewContactL( vcontact ),  i ,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+
+void CContactViewTest::SetContactL()
+	{
+	TInt length = iFields->Count();
+	TInt i;
+	for( i = 0; i < length; ++i)
+		{
+		SetFieldL(*iFields, i, (*iFields)[i].Label());
+		}
+	}
+
+/**
+Check that contents of all fields in view contact equal corresponding fields in contact item
+*/
+TBool CContactViewTest::CheckViewContactL(const CViewContact &aVContact)
+	{
+	TBool OverallCheckResult = EFalse;
+
+	//retrieve contact item id of view contact
+	TContactItemId cid = aVContact.Id();
+
+	//open contact item
+	ReadL(cid, *iViewAll);
+	TInt length = aVContact.FieldCount();
+	TInt i = 0;
+	for(; i < length; ++i)
+		{
+		OverallCheckResult = EFalse;
+		//find first field in contact item that equals uid (of view contact field) stored in sort order
+		TInt pos = iFields->Find((*iSortOrder)[i]);
+		TDesC *ContactField = NULL;
+
+		if(pos < 0)
+			{
+			ContactField = const_cast<TDesC *>(&KNullDesC);
+			}
+		else
+			{
+			//converts contents of field - matching the view contact uid - to a string
+			ContactField = FieldStringLC( (*iFields)[pos] );
+			}
+		//check that conents of contact item field equal conents of corresponing view contact field
+		OverallCheckResult = STRINGCOMPARE( aVContact.Field(i), ==, *ContactField, i, 0 );
+
+		if(pos > -1)
+			{
+			CleanupStack::PopAndDestroy( ContactField );
+			}
+
+		//if view contact field doesnt equal contact item field, fail test
+		if( !OverallCheckResult )
+			{
+			break;//test failed
+			}
+		}
+	Close();
+
+	return OverallCheckResult;
+	}
+/**
+cleanup sort order, create new empty sort order
+*/
+void CContactViewTest::ResetSortL()
+	{
+	iSortOrder->Close();
+	CLEAR(iSortOrder);
+	iSortOrder = new(ELeave) RContactViewSortOrder();
+	}
+
+/**
+converts contents of a contact item field to a string
+*/
+HBufC *CContactViewTest::FieldStringLC(const CContactItemField &aField)
+	{
+	HBufC *buf = NULL;
+	if( aField.IsTemplateLabelField() )
+		{
+		buf = HBufC::NewLC(0);
+		return buf;
+		}
+	switch(aField.StorageType())
+		{
+		case KStorageTypeText:
+			{
+			buf = HBufC::NewLC(aField.Label().Length()+2);
+			TPtr ptr = buf->Des();
+			ptr.Append( aField.Label() );
+			}
+		break;
+		case KStorageTypeContactItemId:
+			{
+			buf = HBufC::NewLC(20);//assume cid < 20 digits
+			TContactItemId cid = aField.AgentStorage()->Value();
+			TPtr ptr = buf->Des();
+			ptr.AppendNum(cid);
+			}
+		break;
+		case KStorageTypeStore:
+		case KStorageTypeDateTime:
+			{
+			buf = HBufC::NewLC(0);//views dont care about date/time or binary fields
+			}
+		break;
+		default:
+			{
+			_LIT(KCCVTest,"CCVTest");
+			User::Panic(KCCVTest , EInvariantFalse );
+			}
+		break;
+		}
+	return buf;
+
+	}
+
+/**
+create local view with sortorder containing all (existing) uids,
+database contains 10 contacts with a fieldset containing no fields.
+*/
+void CContactViewTest::EmptyFieldsetTestL()
+	{
+	ALLPRINT(KTest5);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	TInt i;
+	for(i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		OpenL(cid, *iViewAll);
+		iFields->Reset();
+		CommitL();
+		}
+
+
+	TInt length = iExistingUidsArray->Count();
+	ResetSortL();
+	for(i = 0 ; i < length ; ++i)
+		{
+		iSortOrder->AppendL( TUid::Uid( (*iExistingUidsArray)[i] ) );
+		}
+
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doEmptyFieldsetTestL;
+	}
+
+/**
+check that local view contains 10 contacts, each containing as many fields
+as there are uids (114), all field should be empty. create new view with
+empty sortorder
+*/
+void CContactViewTest::doEmptyFieldsetTestL(const CContactViewBase &aLView)
+	{
+	TInt length = aLView.CountL();
+	TInt arrayLength = iExistingUidsArray->Count();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  arrayLength,  i, 0 );
+		SINGLECOMPARE(  CheckViewContact( aLView.ContactAtL(i), KNullDesC ),  i,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+/**
+Delete all fields from all contacts
+*/
+void CContactViewTest::EmptyFieldsetSortTestL()
+	{
+	ALLPRINT(KTest6);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	TInt i;
+	for(i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		OpenL(cid, *iViewAll);
+		//deletes all fields
+		iFields->Reset();
+		CommitL();
+		}
+
+	ResetSortL();
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doEmptyFieldsetSortTestL;
+	}
+
+/**
+Check that view contains 1 field for each contact and that field is null
+*/
+void CContactViewTest::doEmptyFieldsetSortTestL(const CContactViewBase &aLView)
+	{
+	TInt length = aLView.CountL();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  1,  i, 0 );
+		SINGLECOMPARE(  CheckViewContact( aLView.ContactAtL(i), KNullDesC ),  i ,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	}
+
+/**
+Set all fields of all contacts to contain their own label string
+use empty sort order
+*/
+void CContactViewTest::MissingFieldTestL()
+	{
+	ALLPRINT(KTest7);
+	ClosePersistanceL(EFalse);
+	ResetDatabaseL();
+	for(TInt i = 0; i < iContacts; ++i)
+		{
+		const TContactItemId cid = iIterate->NextL();
+		OpenL(cid, *iViewAll);
+		SetContactL();
+		CommitL();
+		}
+	ResetSortL();
+	OpenPersistanceL();
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doMissingFieldTestL;
+	}
+
+/**
+check that a field is generated for each view contact and that field matches list of missing of fields
+remove generated field from contact item and repopulate contact view repeat until view contact field is null
+*/
+void CContactViewTest::doMissingFieldTestL(const CContactViewBase &aLView)
+	{
+	ClosePersistanceL(ETrue);
+	TBool end = ETrue;
+	TInt length = aLView.CountL();
+	TInt manyfields = 0;
+	TInt i;
+	//iterate through ini file, that stores list of expected field in order
+	const TPtrC mfield = GetNextFieldL();
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+	iIterate->Reset();
+
+	for(i = 0; i < length; ++i)
+		{
+		const TInt loc = aLView.FindL(iIterate->NextL());
+		const CViewContact &vcontact = aLView.ContactAtL( loc );
+		manyfields = vcontact.FieldCount();
+		const TPtrC vfield = vcontact.Field(0);
+		INTCOMPARE(  manyfields , ==,  1,  i, 0 );
+		
+		//compare view contact field to field stored in ini file
+		STRINGCOMPARE( vfield, ==, mfield, i, 0 );
+		//if view contact field is null, end test
+		end = end && (vfield == KNullDesC);
+		//find view contact field in contact item and set to null, if field not found, end test
+		end = end || !FindAndClearFieldL( vcontact.Id(), vfield );
+		}
+
+
+	if( end )
+		{
+		iObserver->iMainFunc = NULL;
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		}
+	else
+		{
+		//if test not complete, reset view and repopulate
+		OpenPersistanceL();
+		iObserver->CleanView();
+		iObserver->SetView( CreateViewL() );
+		}
+	}
+
+/**
+populate database with full, medium or empty contacts
+*/
+void CContactViewTest::PerformanceTestL()
+	{
+	ClosePersistanceL( EFalse );
+	ResetDatabaseL(iPerformanceContacts);
+
+	//populate contacts
+	if( EMedium == iFullness )
+		{
+		if( EFew == iPerformanceContacts )
+			{
+			ALLPRINT(KTest81);
+			}
+		TInt i = 0;
+		for(; i < iContacts; ++i)
+			{
+			const TContactItemId cid = iIterate->NextL();
+			OpenL(cid, *iViewAll);
+			SetMediumL();
+			CommitL();
+			}
+		}
+	else if( EFull == iFullness )
+		{
+		if( EFew == iPerformanceContacts )
+			{
+			ALLPRINT(KTest82);
+			}
+		TInt i = 0;
+		for(; i < iContacts; ++i)
+			{
+			const TContactItemId cid = iIterate->NextL();
+			OpenL(cid, *iViewAll);
+			SetFullL();
+			CommitL();
+			}
+		}
+	else
+		{
+		if( EFew == iPerformanceContacts )
+			{
+			ALLPRINT(KTest8);
+			}
+		}
+
+	/**
+	Print the number of contacts used for this test
+	*/
+	switch( iPerformanceContacts )
+		{
+		case EFew:
+			{
+			_LIT(KFewContacts,"Few contacts");
+			ALLPRINT( KFewContacts );
+			iPerformanceContacts = EMid;
+			break;
+			}
+		case EMid:
+			{
+			_LIT(KMidContacts,"Mid contacts");
+			ALLPRINT( KMidContacts );
+			iPerformanceContacts = EMany;
+			break;
+			}
+		case EMany:
+			{
+			_LIT(KManyContacts,"Many contacts");
+			ALLPRINT( KManyContacts );
+			iPerformanceContacts = EMax;
+			break;
+			}
+		case EMax:
+			{
+			_LIT(KMaxContacts,"Max contacts");
+			ALLPRINT( KMaxContacts );
+			iPerformanceContacts = EDone;
+			break;
+			}
+		default:
+			{
+			_LIT(KInvalidContacts,"bad performance contacts");
+			User::Panic(KInvalidContacts, 333 );
+			break;
+			}
+		}
+
+	_LIT(KStartCompact,"Start Compact");
+	ALLPRINT( KStartCompact );
+	iContactsDatabase->CompactL();//to make sure that the server is not busy doing automatic compaction
+	_LIT(KEndCompact,"End Compact");
+	ALLPRINT( KEndCompact );
+
+
+	//Create sortorder with typical uids
+	ResetSortL();
+	iSortOrder->AppendL(KUidContactFieldGivenName);
+	iSortOrder->AppendL(KUidContactFieldAdditionalName);
+	iSortOrder->AppendL(KUidContactFieldFamilyName);
+	iSortOrder->AppendL(KUidContactFieldPhoneNumber);
+
+	OpenPersistanceL();
+	_LIT(KStartView,"Start view creation");
+	ALLPRINT( KStartView );
+	//note time view is created
+	iStartC.UniversalTime();
+	iObserver->SetView( CreateViewL() );
+	//note time vie creat is completed
+	iStartP.UniversalTime();
+	_LIT(KEndView,"End view creation, wait for view to be populated");
+	ALLPRINT( KEndView );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doPerformanceTestL;
+	}
+
+/**
+Calculate/Print time taken to create view
+Calculate/Print time take to populate view
+*/
+void CContactViewTest::doPerformanceTestL(const CContactViewBase &/*aLView*/)
+	{
+	static TInt iters = KManyPerfIters;
+	static TInt64 creation = 0;
+	static TInt64 population = 0;
+
+	_LIT(KIteration,"Iteration: %d");
+	ALLPRINT2(KIteration, iters);
+
+	//note time when view has been populated
+	iFinishP.UniversalTime();
+	//time taken to pupulate view
+	population += ( iFinishP.MicroSecondsFrom( iStartP ).Int64() );
+	//time taken to create view
+	creation += ( iStartP.MicroSecondsFrom( iStartC ).Int64() );
+
+	//if average of many iterations of view population is being measured, wait for last iteration before
+	//calculating average tiem taken to creat/populate a view
+	if(--iters <= 0)
+		{
+		iters = KManyPerfIters;
+
+		TReal creatSec = 0;
+		TReal popSec = 0;
+
+		creatSec =static_cast<TReal>(creation)/(1000000*iters);
+		popSec = static_cast<TReal>(population)/(1000000*iters);
+
+		_LIT(KCreationTime,"Creation Time: %f seconds");
+		ALLPRINT2(KCreationTime, creatSec);
+
+		_LIT(KPopulationTime,"Population time: %f seconds");
+		ALLPRINT2(KPopulationTime, popSec);
+		creation = 0;
+		population = 0;
+
+		if( EFull == iFullness )
+			{
+			iters = KManyPerfIters;
+			}
+
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+
+		//time taken to create and populate view should not exceed defined limit
+		INTCOMPARE( (creatSec + popSec), <, KMaxTimeAllowed, 0, 0 );
+
+		//if empty view, change to medium view performance test
+		if( EBlank == iFullness )
+			{
+			if( EDone == iPerformanceContacts )
+				{
+				iPerformanceContacts = EFew;
+				iFullness = EMedium;
+				}
+			iObserver->iMainFunc = &CContactViewTest::PerformanceTestL;
+			iObserver->Activate();
+			}
+
+		//if medium view, change to full view performance test
+		else if( EMedium == iFullness )
+			{
+			if( EDone == iPerformanceContacts )
+				{
+				iPerformanceContacts = EFew;
+				iFullness = EFull;
+				}
+			iObserver->iMainFunc = &CContactViewTest::PerformanceTestL;
+			iObserver->Activate();
+
+			}
+		//if full view
+		else
+			{
+			//if all contact permuations done, end test
+			if( EDone == iPerformanceContacts )
+				{
+				iPerformanceContacts = EFew;
+				iFullness = EBlank;
+				iObserver->iMainFunc = NULL;
+				iObserver->CleanView();
+				}
+			else
+				{
+				//if other contact permuations availabe for full view, continue testing
+				iObserver->iMainFunc = &CContactViewTest::PerformanceTestL;
+				iObserver->Activate();
+				}
+			}
+
+		}
+	//if not final iteration
+	else
+		{
+		iObserver->iMainFunc = NULL;
+		iObserver->iDoFunc = &CContactViewTest::doPerformanceTestL;
+		//reset view
+		iObserver->CleanView();
+		iStartC.UniversalTime();
+		//recreate view
+		iObserver->SetView( CreateViewL() );
+		iStartP.UniversalTime();
+		}
+	}
+
+/**
+populate contact on first iteration
+reset view and start compress/recover
+*/
+void CContactViewTest::RecoverCompressTestL()
+	{
+	ALLPRINT(KTest9);
+	TInt i;
+	if( !iIteration )
+		{
+		ResetDatabaseL();
+
+		for(i = 0; i < iContacts; ++i)
+			{
+			const TContactItemId cid = iIterate->NextL();
+			OpenL(cid, *iViewAll);
+			SetContactL();
+			CommitL();
+			}
+		}
+
+	//sortorder contains all uids
+	TInt length = iExistingUidsArray->Count();
+	ResetSortL();
+	for(i = 0 ; i < length ; ++i)
+		{
+		iSortOrder->AppendL( TUid::Uid( (*iExistingUidsArray)[i] ) );
+		}
+
+	iObserver->SetView( CreateViewL() );
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = &CContactViewTest::doRecoverCompressTestL;
+
+	//if first iteration start compress/recover
+	if( !iIteration++)
+		{
+		if(iRecoverFlag)
+			{
+			StartRecoverL();
+			}
+		else
+			{
+			StartCompressL();
+			}
+		}
+	}
+
+/**
+if expected error generated, end compress or recover and regenerate view
+otherwise check view is correctly populated
+*/
+void CContactViewTest::doRecoverCompressTestL(const CContactViewBase &aLView)
+	{
+	//check expected generated error 
+	if( ( ( KErrAccessDenied == iObserver->iEvent.iInt && !iRecoverFlag ) ||
+		  ( KErrDisconnected == iObserver->iEvent.iInt && iRecoverFlag ) || iRemote)
+		    && iIteration == 1)
+		{
+		//end recover / compress
+		if(iRecoverFlag)
+			{
+			EndRecoverL();
+			}
+		else
+			{
+			EndCompressL();
+			}
+		//reset view
+		iObserver->iMainFunc = &CContactViewTest::RecoverCompressTestL;
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		iObserver->Activate();
+		iObserver->iEvent = TContactViewEvent();
+		return;
+		}
+
+	//reset iteration
+	iIteration = 0;
+	TInt length = aLView.CountL();
+	TInt arrayLength = iExistingUidsArray->Count();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	//check view correctly populated
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  arrayLength,  i, 0 );
+		SINGLECOMPARE(  CheckViewContactL( vcontact ),  i,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	iObserver->iEvent = TContactViewEvent();
+	}
+
+/**
+start compress / recover before view is created in seperate thread
+create view
+end compress / recover in seperate thread
+*/
+void CContactViewTest::ConcurrentRecoverCompressTestL()
+	{
+	ALLPRINT(KTest10);
+	TInt i;
+	if( !iIteration )
+		{
+		ResetDatabaseL();
+
+		for(i = 0; i < iContacts; ++i)
+			{
+			const TContactItemId cid = iIterate->NextL();
+			OpenL(cid, *iViewAll);
+			SetContactL();
+			CommitL();
+			}
+		}
+
+	TInt length = iExistingUidsArray->Count();
+	ResetSortL();
+	for(i = 0 ; i < length ; ++i)
+		{
+		iSortOrder->AppendL( TUid::Uid( (*iExistingUidsArray)[i] ) );
+		}
+
+	if (iThread.Handle() != RThread().Handle() )
+		{
+		iThread.Close();
+		}
+
+	if( !iIteration )
+		{
+		iThread.Create( KTest10, CContactViewTest::ThreadRunL, KDefaultStackSize, NULL, this, EOwnerThread );
+		iThread.Resume();
+		iThread.SetPriority(EPriorityNormal);
+		iSemaphore.Wait();//wait for recovery compress to be started
+		}
+
+	TRAPD(err, iObserver->SetView(CreateViewL()));
+	if( !iIteration )
+		{
+		iSemaphore2.Signal();// signal that view has been created
+		}
+	if( !iIteration )
+		{
+		iSemaphore.Wait();//wait for recovery/compress to be completed
+		}
+
+	if (err == KErrNotReady)
+ 		{
+		_LIT(KCreateViewResult,"Create view leave with KErrNotReady(-18) in iIteration=%d");
+		ALLPRINT2(KCreateViewResult, iIteration);
+		TEST(iIteration == 0); // expect err=KErrNotReady for iIteration=0 in remote view test
+
+		iObserver->iMainFunc = &CContactViewTest::ConcurrentRecoverCompressTestL;
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		iObserver->Activate();
+		iObserver->iEvent = TContactViewEvent();
+		}
+	else
+		{
+		iObserver->iMainFunc = NULL;
+		iObserver->iDoFunc = &CContactViewTest::doConcurrentRecoverCompressTestL;
+		}
+
+	++iIteration;	
+	}
+
+/**
+on first iteration check that expected error is generated
+on next iteration check that view is correctly populated
+*/
+void CContactViewTest::doConcurrentRecoverCompressTestL(const CContactViewBase &aLView)
+	{
+	//check expected error generated
+	if( ( ( KErrAccessDenied == iObserver->iEvent.iInt && !iRecoverFlag ) ||
+		  ( KErrDisconnected == iObserver->iEvent.iInt && iRecoverFlag ) || iRemote)
+		    && iIteration == 1)
+		{
+		//end recover / compress
+		if(iRecoverFlag)
+			{
+			EndRecoverL();
+			}
+		else
+			{
+			EndCompressL();
+			}
+		//reset view
+		iObserver->iMainFunc = &CContactViewTest::RecoverCompressTestL;
+		iObserver->iDoFunc = NULL;
+		iObserver->CleanView();
+		iObserver->Activate();
+		iObserver->iEvent = TContactViewEvent();
+		return;
+		}
+		
+	iIteration = 0;
+	TInt length = aLView.CountL();
+	TInt arrayLength = iExistingUidsArray->Count();
+	TInt manyfields = 0;
+	TInt i;
+	INTCOMPARE( length , ==,  iContacts, 0, 0 );
+
+	for(i = 0; i < length; ++i)
+		{
+		const CViewContact &vcontact = aLView.ContactAtL(i);
+		manyfields = vcontact.FieldCount();
+		INTCOMPARE( manyfields , ==,  arrayLength,  i, 0 );
+		SINGLECOMPARE(  CheckViewContactL( vcontact ),  i,  0 );
+		}
+	iObserver->iMainFunc = NULL;
+	iObserver->iDoFunc = NULL;
+	iObserver->CleanView();
+	iObserver->iEvent = TContactViewEvent();
+	}
+
+/**
+New thread function, start recovery/compress before view creation and
+completes recovery/compress after view creation
+*/
+void CContactViewTest::RecoverAndCompressThreadTestL()
+	{
+	CContactDatabase *cntdb = CContactDatabase::OpenL();
+	CleanupStack::PushL( cntdb );
+
+	if( iRecoverFlag )
+		{
+		// The views access the database directly and are oblivious of the state of the contacts server.
+		// Therefore they will try and access a corrupt (damaged) database.  This leads to a DBMS panic
+		// It is beleived that 9.1-9.4 the Contacts model has always exhibited this behavior (fixed in 9.5)
+		#ifdef _DEBUG
+			if( !cntdb->IsDamaged() && iDamageCounter == 0 )
+				{
+				cntdb->DamageDatabaseL(0x666);//will give us consistent behaviour on debug builds
+				}
+		#endif
+		++iDamageCounter;
+		CContactActiveRecover *recover = cntdb->CreateRecoverLC();
+		recover->SetObserver( this );
+		iSemaphore.Signal();//signal that recovery has started
+		iSemaphore2.Wait();//wait for view to be created
+
+		ALLPRINT(KStartRecover);
+		while(recover->Step())
+			{
+			User::After( 1000 );
+			}
+		CleanupStack::PopAndDestroy(recover);
+		ALLPRINT(KEndRecover);
+		}
+	else
+		{
+		CContactActiveCompress 	*compress = cntdb->CreateCompressorLC();
+		compress->SetObserver( this );
+		iSemaphore.Signal();//signal that compress has started
+		iSemaphore2.Wait();//wait for view to be created
+		ALLPRINT(KStartCompress);
+		while(compress->Step())
+			{
+			User::After( 1000 );
+			}
+		CleanupStack::PopAndDestroy(compress);
+		ALLPRINT(KEndCompress);
+		}
+	iSemaphore.Signal();//signal that recovery compress is complete
+	CleanupStack::PopAndDestroy( cntdb );
+	}
+
+/**
+Runs thread function, called from thread constructor
+*/
+TInt CContactViewTest::ThreadRunL(TAny *aAny)
+	{
+	TInt ThreadError = KErrNone;
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+
+	CActiveScheduler* sched=NULL;
+	sched=new(ELeave) CActiveScheduler;
+	CActiveScheduler::Install(sched);
+
+	CContactViewTest &test = *static_cast<CContactViewTest *>(aAny);
+	TRAP(ThreadError, test.RecoverAndCompressThreadTestL()	);
+	delete cleanup;
+	delete sched;
+	return ThreadError;
+	}
+
+/**
+Search for a field in contact item acid, that has the same label as aField
+Sets the value of found field to null/empty
+returns true if field found, false otherwise
+*/
+TBool CContactViewTest::FindAndClearFieldL(const TContactItemId aCid, const TDesC &aField)
+	{
+	TBool ret = EFalse;
+	OpenL(aCid,*iViewAll);
+	TInt length = iFields->Count();
+	TInt i;
+	for(i = 0; i < length; ++i)
+		{
+		if( (*iFields)[i].Label() == aField && (*iFields)[i].Storage()->IsFull() )
+			{
+			SetFieldL(*iFields, i, KNullDesC);
+			ret = ETrue;
+			break;
+			}
+		}
+	CommitL();
+	return ret;
+	}
+
+/**
+Iterates through the missing fields list in the ini file,
+retrieves the next field in the list
+*/
+TPtrC CContactViewTest::GetNextFieldL()
+	{
+	static TInt iter = 0;
+	++iter;
+	TPtrC ret = GetFieldL(iter);
+	if( ret == KNullDesC )
+		{
+		iter = 0;
+		}
+	return ret;
+	}
+
+/**
+Retrieves the field at aIndex of under missing fields section in ini file
+*/
+TPtrC CContactViewTest::GetFieldL(const TInt aIndex)
+	{
+	TPtrC ret;
+	TPtrC tfield = KUfield();
+	HBufC *fval=HBufC::NewLC(tfield.Length()+2);//assume #fields < 100
+
+	TPtr fptr=fval->Des();
+	fptr.Append( tfield );
+	fptr.AppendNum( aIndex );
+	GetStringFromConfig( KMissingFields, fptr, ret );
+	CleanupStack::PopAndDestroy( fval );
+	return ret;
+	}
+
+/**
+Creates a persistance layer local view, Client/server local view or remote view
+depending on the type of testing being performed.
+*/
+CContactViewBase* CContactViewTest::CreateViewL()
+	{
+	if( iPLView )
+		{
+		return CContactLocalView::NewL(	*iObserver, *iContactsDatabase,
+										*iSortOrder, EContactsOnly, &iPersistence->FactoryL(), KNullDesC8 );
+		}
+	else
+		{
+		if(iRemote)
+			{
+			return CContactRemoteView::NewL(	*iObserver, *iContactsDatabase,
+											*iSortOrder, EContactsOnly);
+			}
+		else
+			{
+			return CContactLocalView::NewL(	*iObserver, *iContactsDatabase,
+										*iSortOrder, EContactsOnly);
+			}
+		}
+	}
+
+/**
+If performing persistance layer testing, cleanup the persistance layer instance
+if aReOpen, also open sessions to contact server
+*/
+void CContactViewTest::ClosePersistanceL(const TBool aReOpen)
+	{
+	if( iPLView )
+		{
+		if( iPersistence != NULL )
+			{
+			CLEAR( iPersistence );
+			//wait for persistance layer to close, before opening server
+			User::After( 200000 );
+			if( aReOpen )
+				{
+				iContactsDatabase = CContactDatabase::OpenL();
+
+				iContactsDatabase2 = CContactDatabase::OpenL( CContactDatabase::EMultiThread );
+				}
+			}
+		}
+	}
+
+/**
+If performing persistance layer testing, copy database from cntsrv private directory to test server
+private directory using the pim test server. Then open copied db file using persistance layer.
+*/
+void CContactViewTest::OpenPersistanceL()
+	{
+	if( iPLView )
+		{
+		TBuf<190> buf;
+		iContactsDatabase->GetDefaultNameL(buf);
+		CLEAR(iContactsDatabase);
+		CLEAR(iContactsDatabase2);
+		WaitForServerToExitL();
+		iPimServ->CopyFileL(KContactsDB, KPersistenceDB);
+		iPersistence = CPersistenceLayer::NewLC(iParent->Fs());
+		CleanupStack::Pop(iPersistence);
+
+		#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
+		TRAPD( err, iPersistence->ContactsFileL().OpenL( buf ));
+		#else
+		TRAPD( err,
+					while( iPersistence->ContactsFileL().OpenStepL( buf ) ) {}
+		);
+		#endif
+
+		User::LeaveIfError(err);
+		}
+	}
+
+/**
+Set all fields in currently opened contact to a medium length string
+*/
+void CContactViewTest::SetMediumL()
+	{
+
+	for(TInt i = 0; i< 10; ++i)
+		{
+		SetFieldL(*iFields, i, TestConstants::KMediumString);
+		}
+	}
+
+/**
+Set all fields in currently opened contact to a long length string
+*/
+void CContactViewTest::SetFullL()
+	{
+	const TInt count = iFields->Count();
+
+	for(TInt i = 0; i< count; ++i)
+		{
+		SetFieldL(*iFields, i, TestConstants::KLongString);
+		}
+	}
+/**
+damage database and start active recovery
+*/
+void CContactViewTest::StartRecoverL()
+	{
+	ALLPRINT(KStartRecover);
+	#ifdef _DEBUG
+	    #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+		iContactsDatabase2->DamageDatabaseL(0x666);//will give us consistent behaviour on debug builds
+		#endif
+	#endif
+
+    User::After( 200000 );
+
+	iRecover = iContactsDatabase2->CreateRecoverLC();
+	CleanupStack::Pop( iRecover );
+
+	iRecover->SetObserver( this );
+
+	while (iRecover->Step()) {}
+
+	}
+
+/**
+cancel active recovery
+*/
+void CContactViewTest::EndRecoverL()
+	{
+
+	if( iRecover )
+		{
+		ALLPRINT(KEndRecover);
+
+		iRecover->Cancel();//deletes irecover
+		iRecover = NULL;
+		}
+	}
+
+/**
+start active compress
+*/
+void CContactViewTest::StartCompressL()
+	{
+	ALLPRINT(KStartCompress);
+	iCompress = iContactsDatabase2->CreateCompressorLC();
+	iCompress->SetObserver( this );
+	CleanupStack::Pop( iCompress );
+
+	}
+
+/**
+cancels active compress
+*/
+void CContactViewTest::EndCompressL()
+	{
+
+	if( iCompress )
+		{
+        ALLPRINT(KEndCompress);
+
+		iCompress->Cancel();//deletes iCompress
+		iCompress = NULL;
+		}
+	}
+
+/**
+Prints any errors encountered while performing active compress/recover
+*/
+void CContactViewTest::HandleError(TInt aError)
+	{
+	iError = aError;
+	_LIT(KCompressRecoverError,"Error in active compress/recover: %d");
+	ALLPRINT2(KCompressRecoverError, iError);
+	}
+