--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/Integration/PerfFuncSuite/src/StateMachineStep.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,714 @@
+// 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 "StateMachineStep.h"
+#include "PerformanceFunctionalityDefs.h"
+#include <cntfilt.h>
+
+const static TInt KNumberOfContacts = 10;
+
+_LIT(KTestCase1,"OpeningRecovery");
+_LIT(KTestCase2,"OpeningAsync");
+_LIT(KTestCase3,"Writable");
+_LIT(KTestCase4,"DefaultRecovery");
+_LIT(KTestCase5,"DefaultCompress");
+_LIT(KTestCase6,"AsyncInteg");
+_LIT(KTestCase7,"TablesClosed");
+_LIT(KTestCase8,"WritableSpeed");
+
+_LIT(KTestCasePrint1, "Opening State statemachine Recovery tests");
+_LIT(KTestCasePrint2, "Opening State statemachine Asynchronous open tests");
+_LIT(KTestCasePrint3, "Writable State statemachine tests");
+_LIT(KTestCasePrint4, "Default State recovery statemachine tests");
+_LIT(KTestCasePrint5, "Default State compression statemachine tests");
+_LIT(KTestCasePrint6, "Asynchronous Integrity tests");
+_LIT(KTestCasePrint7, "Tables Closed State statemachine tests");
+_LIT(KTestCasePrint8, "Writable State statemachine speed dial tests");
+
+/**
+ * This class tests the internal implementation of the contact model server
+ * specifically it is designed to stress test the state machine
+ * so that all the major functionality of the state machine is exercised
+ * each test function usually encompasses one test case, the description for
+ * the test case is defined in the related test script file (StateMachineStep.script)
+ * each test step in the test script file usually call this test class with a non
+ * existent ini file section name, the section name correspond to the test case
+ * name stored within this class. The reasoning behind this is that each test case
+ * does not need to store any additional data within the ini file and as such a reference
+ * to an actual ini file section would be redundent.
+ */
+CStateMachineStep::CStateMachineStep()
+ : CPerformanceFunctionalityBase( KNumberOfContacts )
+ {
+ SetTestStepName(KStateMachineStep);
+ }
+
+TVerdict CStateMachineStep::doTestStepPostambleL()
+ {
+ return CPerformanceFunctionalityBase::doTestStepPostambleL();
+ }
+
+void CStateMachineStep::InitializeL()
+ {
+ CPerformanceFunctionalityBase::InitializeL();
+ //set timeout to 0, to minimize waits within the test
+ iContactsDatabase->SetOperationTimeOutL(0);
+ }
+
+void CStateMachineStep::Cleanup()
+ {
+ //unload async opens
+ CLEAR( iContactOpenOperation1 );
+ CLEAR( iContactOpenOperation2 );
+ CPerformanceFunctionalityBase::Cleanup();
+ }
+
+void CStateMachineStep::PreTestL()
+ {
+ //does nothing
+ }
+
+TVerdict CStateMachineStep::doTestStepL()
+ {
+ __UHEAP_MARK;
+ InitializeL();
+ _LIT(KPrintStart, "CStateMachineStep::doTestStepL()");
+ INFO_PRINTF1(KPrintStart); //Block start
+ iIterate->Reset();
+
+ const TDesC &KSection = ConfigSection();
+
+ if( KSection == KTestCase1 )
+ {
+ INFO_PRINTF1( KTestCasePrint1 );
+ OpeningStateRecoverTestsL();
+ }
+ else if( KSection == KTestCase2 )
+ {
+ INFO_PRINTF1( KTestCasePrint2 );
+ OpeningStateAsyncOpenTestsL();
+ }
+ else if( KSection == KTestCase3 )
+ {
+ INFO_PRINTF1( KTestCasePrint3 );
+ WritableStateTestsL();
+ }
+ else if( KSection == KTestCase4 )
+ {
+ INFO_PRINTF1( KTestCasePrint4 );
+ DefaultStateCompressionTestsL();
+ }
+ else if( KSection == KTestCase5 )
+ {
+ INFO_PRINTF1( KTestCasePrint5 );
+ DefaultStateRecoveryTestsL();
+ }
+ else if( KSection == KTestCase6 )
+ {
+ INFO_PRINTF1( KTestCasePrint6 );
+ AsynchronousIntegrityTestL();
+ }
+ else if( KSection == KTestCase7 )
+ {
+ INFO_PRINTF1( KTestCasePrint7 );
+ TablesClosedStateTestsL();
+ }
+ else if( KSection == KTestCase8 )
+ {
+ INFO_PRINTF1( KTestCasePrint8 );
+ WritableStateSpeedDialTestsL();
+ }
+ else
+ {
+ MissingTestPanic();
+ }
+
+ Cleanup();
+ __UHEAP_MARKEND;
+
+ return TestStepResult();
+
+ }
+
+void CStateMachineStep::OpeningStateRecoverTestsL()
+ {
+ TContactItemId con1 = iIterate->NextL();
+ CContactDatabase *database = CContactDatabase::OpenL();
+
+ iCompleteSteps = ETrue;
+ TInt error = KErrNone;
+
+ //transition to opening state
+ TRAP( error, StartRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+
+ //open tables while in opening state
+ TRAP( error, database->OpenTablesL() );
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #endif
+
+ //transition out of opening state
+ TRAP( error, EndRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+ CLEAR( database );
+
+ iCompleteSteps = ETrue;
+ //transition to opening state
+ TRAP( error, StartRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ //transition out of opening state, completing all recovery steps
+ TRAP( error, EndRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ iCompleteSteps = EFalse;
+ //transition to opening state
+ TRAP( error, StartRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ //transition out of opening state, cancelling recovery
+ TRAP( error, EndRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ iCompleteSteps = EFalse;
+ //transition to opening state
+ TRAP( error, StartRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ //can't access contacts as database is in recovery state
+ TRAP( error,
+ ReadL(con1);
+ CloseL( EFalse );
+ );
+
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+
+ TRAP( error,
+ OpenL(con1);
+ CloseL( ETrue );
+ );
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+
+ //transition out of opening state, cancelling recovery
+ TRAP( error, EndRecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ //after recovery is complete it should be possible to access contact normally
+ TRAP( error,
+ ReadL(con1);
+ CloseL( EFalse );
+ );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ TRAP( error,
+ OpenL(con1);
+ CloseL( ETrue );
+ );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+
+ }
+
+void CStateMachineStep::OpeningStateAsyncOpenTestsL()
+ {
+ CContactDatabase *database1 = NULL;
+ CContactDatabase *database2 = NULL;
+
+ CLEAR( iContactsDatabase );
+ WaitForServerToExitL();
+
+ //open databases asynchronously *2
+ iContactOpenOperation1 = CContactDatabase::Open(iStatus1);
+ iContactOpenOperation2 = CContactDatabase::Open(iStatus2);
+ //cancel second async open first
+ CLEAR( iContactOpenOperation2 );
+ CLEAR( iContactOpenOperation1 );
+ //check that async opens were cancelled
+ if( iStatus1.Int() != KErrNone )
+ {
+ INTCOMPARE( KErrCancel, ==, iStatus1.Int(), 0, 0 );
+ }
+ if( iStatus2.Int() != KErrNone )
+ {
+ INTCOMPARE( KErrCancel, ==, iStatus2.Int(), 0, 0 );
+ }
+
+ //open databases asynchronously *2
+ iContactOpenOperation1 = CContactDatabase::Open(iStatus1);
+ iContactOpenOperation2 = CContactDatabase::Open(iStatus2);
+ //cancel first async open
+ CLEAR( iContactOpenOperation1 );
+ User::WaitForRequest(iStatus2);
+ //get opened database sessions
+ database1 = iContactOpenOperation2->TakeDatabase();
+ //check that databases have been opened
+ INTCOMPARE( reinterpret_cast<TInt>(database1), !=, NULL, 0, 0 );
+ //check that first async open was cancelled
+ INTCOMPARE( KErrCancel, ==, iStatus1.Int(), 0, 0 );
+ //check that second async opened was successful
+ INTCOMPARE( KErrNone, ==, iStatus2.Int(), 0, 0 );
+ //unload opened database sessions
+ CLEAR( database1 );
+ CLEAR( iContactOpenOperation2 );
+
+ WaitForServerToExitL();
+ //open databases asynchronously *2
+ iContactOpenOperation1 = CContactDatabase::Open(iStatus1);
+ iContactOpenOperation2 = CContactDatabase::Open(iStatus2);
+ //wait for async opens to complete
+ User::WaitForRequest(iStatus1);
+ User::WaitForRequest(iStatus2);
+
+ //get opened database sessions
+ database1 = iContactOpenOperation1->TakeDatabase();
+ database2 = iContactOpenOperation2->TakeDatabase();
+
+ //check that databases have been opened
+ INTCOMPARE( reinterpret_cast<TInt>(database1), !=, NULL, 0, 0 );
+ INTCOMPARE( reinterpret_cast<TInt>(database2), !=, NULL, 0, 0 );
+ //unload async opens
+ CLEAR( iContactOpenOperation1 );
+ CLEAR( iContactOpenOperation2 );
+ //unload opened database sessions
+ CLEAR( database1 );
+ CLEAR( database2 );
+ //check that async opens completed successfully
+ INTCOMPARE( KErrNone, ==, iStatus1.Int(), 0, 0 );
+ INTCOMPARE( KErrNone, ==, iStatus2.Int(), 0, 0 );
+
+
+ iContactsDatabase = CContactDatabase::OpenL();
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ iContactsDatabase->DamageDatabaseL(0x666);
+ #endif
+ CLEAR( iContactsDatabase );
+
+ WaitForServerToExitL();
+ iActiveRecoverObserver.iCompressOrRecoverError = KErrNone;
+
+ //open databases asynchronously
+ iContactOpenOperation1 = CContactDatabase::Open(iStatus1);
+ //get partially opened database session
+ database1= iContactOpenOperation1->TakeDatabase();
+ //start async recovery
+ CContactActiveRecover* recover = database1->CreateRecoverLC();
+ recover->SetObserver( &iActiveRecoverObserver );
+ //complete async recovery
+ while(recover->Step()){}
+ CleanupStack::PopAndDestroy( recover );
+ recover = NULL;
+
+ //unload async opens
+ CLEAR( iContactOpenOperation1 );
+ //unload opened database sessions
+ CLEAR( database1 );
+
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ iContactsDatabase = CContactDatabase::OpenL();
+ }
+
+void CStateMachineStep::WritableStateTestsL()
+ {
+ const TContactItemId KContactId = iIterate->NextL();
+ const TContactItemId KContactId2 = iIterate->NextL();
+ TInt error = KErrNone;
+
+ //set contact as own card
+ OpenL( KContactId );
+ TRAP( error, iContactsDatabase->SetOwnCardL( *iContactItem ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CommitL( ETrue );
+ //check contact is set as own card
+ INTCOMPARE( iContactsDatabase->OwnCardId(), ==, KContactId, 0, 0 );
+
+ //set contact as own card again, to test internal functionality of state machine
+ OpenL( KContactId );
+ TRAP( error, iContactsDatabase->SetOwnCardL( *iContactItem ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CommitL( ETrue );
+ //contact is still marked as own card
+ INTCOMPARE( iContactsDatabase->OwnCardId(), ==, KContactId, 0, 0 );
+
+ //read contact
+ ReadL( KContactId2 );
+ //set contact as own card using read contact
+ TRAP( error, iContactsDatabase->SetOwnCardL( *iContactItem ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CloseL( EFalse );
+ //check that contact is set as own card
+ INTCOMPARE( iContactsDatabase->OwnCardId(), ==, KContactId2, 0, 0 );
+
+ //Perform recovery while in writeable state and database not damaged
+ TRAP( error,
+ //start async recovery
+ CContactActiveRecover* recover = iContactsDatabase->CreateRecoverLC();
+ recover->SetObserver( &iActiveRecoverObserver );
+ //complete async recovery
+ while(recover->Step()){}
+ CleanupStack::PopAndDestroy( recover );
+ recover = NULL;
+ );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ TRAP( error, iContactsDatabase->RecoverL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ }
+
+void CStateMachineStep::WritableStateSpeedDialTestsL()
+ {
+ _LIT(KFieldValue, "FieldValue");
+ const TContactItemId KContactId = iIterate->NextL();
+ TInt error = KErrNone;
+ iActiveRecoverObserver.iCompressOrRecoverError = KErrNone;
+
+ OpenL( KContactId );
+ const TInt KFieldCount = iFields->Count();
+ CloseL( ETrue );
+
+
+ OpenL( KContactId );
+
+ //try setting an empty field as a SpeedDial
+ //no error should ensue
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*iContactItem, 1, 1) );
+
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+
+ //write some test data into all fields of the contact item
+ //parameter is used only for Text and Store type fields - others are created on the fly
+ SetAllFieldsL(KFieldValue);
+ CommitL( EFalse );
+
+ for( TInt i = 0; i < KFieldCount; ++i)
+ {
+ OpenL( KContactId );
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*iContactItem, i, 1) );
+
+ //if field is text, set speed dial should be successful
+ if( (*iFields)[i].StorageType() == KStorageTypeText)
+ {
+ CloseL( ETrue );
+ INTCOMPARE( KErrNone, ==, error, i, 0 );
+ ReadL( KContactId );
+ TESTPRINTI( (*iFields)[i].IsSpeedDial(), i );
+ CloseL( EFalse );
+ }
+ //if field not text, set speed dial should fail
+ else
+ {
+ CloseL( ETrue );
+ INTCOMPARE( KErrArgument, ==, error, i, 0 );
+ ReadL( KContactId );
+ TESTPRINTI( !(*iFields)[i].IsSpeedDial(), i );
+ CloseL( EFalse );
+ }
+ }
+
+ ReadL( KContactId );
+ //set speed dial for unopened/read contact
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*iContactItem, 1, 1) );
+ CloseL( EFalse );
+ //set speed dial should fail
+ INTCOMPARE( KErrAccessDenied, ==, error, 0, 0 );
+ ReadL( KContactId );
+ TESTPRINT( !(*iFields)[1].IsSpeedDial() );
+ CloseL( EFalse );
+
+ //set speed dial for system template - expect error here
+ CContactCard* contact = CContactCard::NewLC( iTemplate );
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*contact, 1, 1) );
+ INTCOMPARE( KErrArgument, ==, error, 0, 0 );
+ CleanupStack::PopAndDestroy(contact);
+
+ //set speed dial for contact with empty field set - expect error here too
+ contact = CContactCard::NewLC();
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*contact, 1, 1) );
+ INTCOMPARE( KErrArgument, ==, error, 0, 0 );
+ CleanupStack::PopAndDestroy(contact);
+ }
+
+/**
+Perform operations that are not supported by current state, so that default state is used
+all operations should be unsuccessfull
+*/
+void CStateMachineStep::DefaultStateCompressionTestsL()
+ {
+ const TContactItemId KContactId = iIterate->NextL();
+ TInt error = KErrNone;
+
+ OpenL( KContactId );
+ //transition into compress state
+ StartCompressL();
+
+ //perform unsupported operations
+ TRAP( error, iContactsDatabase->CloseTables() );//non leaving function
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+
+ TRAP( error, iContactsDatabase->OpenTablesL() );
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+#endif
+
+ TRAP( error, iContactsDatabase->RecoverL() );
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+#endif
+
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ // only do this with the DBMS version of the contacts model as DamageDatabaseL
+ // doesn't do anything in the SQLite version and so the test will always fail.
+ TRAP( error, iContactsDatabase->DamageDatabaseL(0x666); );
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#endif
+
+ TRAP( error,
+ CContactActiveRecover* recover = iContactsDatabase->CreateRecoverLC();
+ CleanupStack::PopAndDestroy(recover);
+ );
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+#endif
+
+ TRAP( error, iContactsDatabase->SetOwnCardL( *iContactItem ) );
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+#endif
+
+ TRAP( error, iContactsDatabase->SetFieldAsSpeedDialL(*iContactItem, 1, 1) );
+#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrInUse, ==, error, 0, 0 );
+#endif
+
+ EndCompressL();
+ //end compress state
+
+ CloseL( ETrue );
+
+
+ }
+
+/**
+Perform operations that are not supported by current state, so that default state is used
+all operations should be unsuccessfull
+*/
+void CStateMachineStep::DefaultStateRecoveryTestsL()
+ {
+ TInt error = KErrNone;
+
+ //transition into opening state
+ StartRecoverL();
+
+ //perform usupported operations
+ TRAP( error, iContactsDatabase->CompactL() );
+
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+
+
+ TRAP( error,
+ CContactActiveCompress* compress = iContactsDatabase->CreateCompressorLC();
+ CleanupStack::PopAndDestroy( compress );
+ );
+
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+
+ EndRecoverL();
+ //end opening stat
+ }
+
+void CStateMachineStep::AsynchronousIntegrityTestL()
+ {
+ const TContactItemId KContactId = iIterate->NextL();
+ TInt error = KErrNone;
+
+ //test that it is possible to create multiple active compressor
+ iActiveRecoverObserver.iCompressOrRecoverError = KErrNone;
+ CContactActiveCompress* compress1 = iContactsDatabase->CreateCompressorLC();
+ compress1->SetObserver( &iActiveRecoverObserver );
+ CContactActiveCompress* compress2 = iContactsDatabase->CreateCompressorLC();
+ compress2->SetObserver( &iActiveRecoverObserver );
+ while(compress1->Step()){}
+ while(compress2->Step()){}
+ CleanupStack::PopAndDestroy( compress2 );
+ CleanupStack::PopAndDestroy( compress1 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+
+ //test that it is possible to create multiple active recoverers
+ iActiveRecoverObserver.iCompressOrRecoverError = KErrNone;
+ CContactActiveRecover* recover1 = iContactsDatabase->CreateRecoverLC();
+ recover1->SetObserver( &iActiveRecoverObserver );
+ CContactActiveRecover* recover2 = iContactsDatabase->CreateRecoverLC();
+ recover2->SetObserver( &iActiveRecoverObserver );
+ while(recover1->Step()){}
+ while(recover2->Step()){}
+ CleanupStack::PopAndDestroy( recover2 );
+ CleanupStack::PopAndDestroy( recover1 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ //transition into compress state
+
+ iCompleteSteps = EFalse;
+ StartCompressL();
+ TRAP( error,
+ CContactActiveRecover* recover = iContactsDatabase->CreateRecoverLC();
+ CleanupStack::PopAndDestroy( recover );
+ );
+#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+#else
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+#endif
+
+ EndCompressL();
+ //end compress state
+
+ //test that we have transitioned out of compress state
+ TRAP( error, ReadL( KContactId ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CloseL( EFalse );
+
+ iCompleteSteps = EFalse;
+ //transition into opening state
+ StartRecoverL();
+ TRAP( error,
+ CContactActiveCompress* compress = iContactsDatabase->CreateCompressorLC();
+ CleanupStack::PopAndDestroy( compress );
+ );
+
+ #ifdef _DEBUG
+ #ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+ #else
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ #endif
+
+ EndRecoverL();
+ //transition out of opening state
+
+ //test that we have transitioned out of compress state
+ TRAP( error, ReadL( KContactId ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CloseL( EFalse );
+ }
+
+void CStateMachineStep::TablesClosedStateTestsL()
+ {
+ const TContactItemId KContactId = iIterate->NextL();
+ TInt error = KErrNone;
+
+ iActiveRecoverObserver.iCompressOrRecoverError = KErrNone;
+ //transition to tables closed state
+ iContactsDatabase->CloseTables();
+
+
+ TRAP( error,
+ CContactActiveCompress* compress = iContactsDatabase->CreateCompressorLC();
+ compress->SetObserver( &iActiveRecoverObserver );
+ CleanupStack::PopAndDestroy( compress );//dont complete all steps
+ );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ //test that we are still in tables closed state
+ TRAP( error, ReadL( KContactId ) );
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ CloseL( EFalse );
+
+ TRAP( error,
+ CContactActiveCompress* compress = iContactsDatabase->CreateCompressorLC();
+ compress->SetObserver( &iActiveRecoverObserver );
+ while(compress->Step()){}//complete all steps
+ CleanupStack::PopAndDestroy( compress );
+ );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ INTCOMPARE( KErrNone, ==, iActiveRecoverObserver.iCompressOrRecoverError, 0, 0 );
+
+ //test that we are still in tables closed state
+ TRAP( error, ReadL( KContactId ) );
+ INTCOMPARE( KErrNotReady, ==, error, 0, 0 );
+ CloseL( EFalse );
+
+ //transition to writeable state
+ CContactDatabase *database = NULL;
+ TRAP( error, database = CContactDatabase::OpenL() );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+
+ //test that we have transitioned out of tables closed state
+ TRAP( error, ReadL( KContactId ) );
+ INTCOMPARE( KErrNone, ==, error, 0, 0 );
+ CloseL( EFalse );
+
+ CLEAR( database );
+
+ }