diff -r fd64c38c277d -r b46a585f6909 phonebookengines_old/contactsmodel/tsrc/t_owncard.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/tsrc/t_owncard.cpp Fri Jun 11 13:29:23 2010 +0300 @@ -0,0 +1,773 @@ +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +// System includes +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include +#include + +// User includes +#include "t_utils2.h" + +// Constant +_LIT(KDatabaseFileName, "c:t_owncard.cdb"); +_LIT(KSemaphoreNameOne, "One"); +_LIT(KSemaphoreNameTwo, "Two"); + +_LIT(KThreadNameOne, "OneThread"); +_LIT(KThreadNameTwo, "TwoThread"); + + +const TInt KDelay = 1000000; + +static RTest TheTest(_L("t_owncard")); + + +// +/* CTestActiveScheduler */ +// This class has been nicked from the t_currentdb.h / .cpp files +class CTestActiveScheduler : public CActiveScheduler + { + public: + void Error (TInt aError) const; + }; +void CTestActiveScheduler::Error(TInt aError) const + { + User::Panic(_L("AScheduler"),aError); + } + + + +// +/* CConcurrentDatabaseAccessBase - Specification */ +// Forms the base class for both threads. +class CConcurrentDatabaseAccessBase : public CActive + { + public: // Data Types + enum TStage + { + EOne_Startup, + ETwo_FirstCheck, + EThree_ChangeOwner, + ENOP_One, + ENOP_Two, + EFour_SecondCheck, + EFive_Cleanup, + EFinished + } ; + public: + CConcurrentDatabaseAccessBase(); + virtual ~CConcurrentDatabaseAccessBase(); + + virtual void ConstructL(const TDesC& aFilename); + + void RunTestL(); + + + public: // data + RThread iThread; + + protected: + void OpenSemaphore(); + void CloseSemaphore(); + void SyncronizeSignal(); + void SyncronizeWait(); + void OpenDatabaseL(); + void CloseDatabase(); + void CloseTest(); + + virtual TBool RunTestImplementationL() = 0; + + protected: // from CActive + void DoCancel() {}; + void RunL(); + TInt RunError(TInt aError); + void CallRunLAgain(); + TBool NextStage(); + + + protected: + CContactDatabase* iDb; + TStage iStage; + TInt iTestError; + + private: + RSemaphore iSemaphoreSignal; + RSemaphore iSemaphoreWait; + TBool iSemaphoreOpen; + HBufC* iDatabaseName; + }; + +// +/* CConcurrentDatabaseAccessBase - Implementation */ +CConcurrentDatabaseAccessBase::CConcurrentDatabaseAccessBase() + : CActive( /*EPriorityStandard*/ EPriorityIdle ) + { + iStage = EOne_Startup; + } + +CConcurrentDatabaseAccessBase::~CConcurrentDatabaseAccessBase() + { + iThread.Close(); + CloseSemaphore(); + delete iDatabaseName; + } + +void CConcurrentDatabaseAccessBase::ConstructL(const TDesC& aFilename) + { + iDatabaseName = aFilename.AllocL(); + } + +void CConcurrentDatabaseAccessBase::OpenDatabaseL() + { + iDb = CContactDatabase::OpenL(*iDatabaseName, CContactDatabase::EMultiThread); + } + +void CConcurrentDatabaseAccessBase::CloseDatabase() + { + delete iDb; + iDb = NULL; + } + +void CConcurrentDatabaseAccessBase::CloseTest() + { + } + +void CConcurrentDatabaseAccessBase::CallRunLAgain() + { + iStatus = KRequestPending; + + TRequestStatus* ptrStatus = &iStatus; + User::RequestComplete( ptrStatus, KErrNone ); + SetActive(); + } + +TBool CConcurrentDatabaseAccessBase::NextStage() + { + TInt stage = static_cast( iStage ); + stage++; + iStage = static_cast( stage ); + return ( iStage == EFinished ); + } + +void CConcurrentDatabaseAccessBase::RunL() + { + TBool stopProcessing = EFalse; + + stopProcessing = RunTestImplementationL(); + + if (stopProcessing) + { + CActiveScheduler::Stop(); + } + } + +TInt CConcurrentDatabaseAccessBase::RunError(TInt aError) + { + // propagate the error + iTestError = aError; + + RDebug::Print(_L("Thread failed at test stage %i, with error %i"), iStage, aError); + + CActiveScheduler::Stop(); + return KErrNone; + } + +void CConcurrentDatabaseAccessBase::RunTestL() + { + // set's up an active scheduler for the thread + // and calls the RunTesImplementation function to actually + // preform the tests. This function should be implemented in the + // child class. + CTestActiveScheduler* scheduler = NULL; + + scheduler = new (ELeave) CTestActiveScheduler; + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + CActiveScheduler::Add( this ); + + OpenDatabaseL(); + + CallRunLAgain(); + CActiveScheduler::Start(); + + CloseDatabase(); + + CleanupStack::PopAndDestroy( scheduler ); + + // propagate error + User::LeaveIfError(iTestError); + } + +void CConcurrentDatabaseAccessBase::OpenSemaphore() + { + TInt success = KErrNone; + + success = iSemaphoreSignal.OpenGlobal( KSemaphoreNameOne ); + if ( success == KErrNotFound ) + { + iSemaphoreSignal.CreateGlobal( KSemaphoreNameOne, 0 ); + success = KErrNone; + } + + + success = iSemaphoreWait.OpenGlobal( KSemaphoreNameTwo ); + if ( success == KErrNotFound ) + { + iSemaphoreWait.CreateGlobal( KSemaphoreNameTwo, 0 ); + } + + iSemaphoreOpen = ETrue; + } + +void CConcurrentDatabaseAccessBase::CloseSemaphore() + { + if (iSemaphoreOpen) + { + iSemaphoreSignal.Close(); + iSemaphoreWait.Close(); + } + + iSemaphoreOpen = EFalse; + } + +void CConcurrentDatabaseAccessBase::SyncronizeSignal() + { + CallRunLAgain(); + iSemaphoreSignal.Signal(); + iSemaphoreWait.Wait(); + } + +void CConcurrentDatabaseAccessBase::SyncronizeWait() + { + CallRunLAgain(); + iSemaphoreSignal.Wait(); + iSemaphoreWait.Signal(); + } + +// +/* CConcurrentOwnerCardModifier - Specification */ +// This class should allow the two threads to compare the owner ID's of there db. +class TOwnerCardCompare + { + public: + enum EThreadName + { + EModifier, + EChecker + }; + public: + TOwnerCardCompare(); + ~TOwnerCardCompare(); + void AssignValuesAndCheckL(TContactItemId aValue, EThreadName aThreadName); + + private: + void CheckValuesL(); + void ClearValues(); + + private: // data + TBool iModifierDataPresent; + TBool iCheckerDataPresent; + TContactItemId iModifierValue; + TContactItemId iCheckerValue; + }; + +// +/* CConcurrentOwnerCardModifier - Implementatio */ +// This class should allow the two threads to compare the owner ID's of there db. +TOwnerCardCompare::TOwnerCardCompare() + { + ClearValues(); + } +TOwnerCardCompare::~TOwnerCardCompare() + { + ClearValues(); + } + +void TOwnerCardCompare::AssignValuesAndCheckL(TContactItemId aValue, EThreadName aThreadName) + { + switch ( aThreadName ) + { + case EModifier: + iModifierDataPresent = ETrue; + iModifierValue = aValue; + break; + + case EChecker: + iCheckerDataPresent = ETrue; + iCheckerValue = aValue; + break; + } + CheckValuesL(); + } + +void TOwnerCardCompare::CheckValuesL() + { + if ( iModifierDataPresent && iCheckerDataPresent ) + { + TheTest( (iCheckerValue == iModifierValue) ); + ClearValues(); + } + } + +void TOwnerCardCompare::ClearValues() + { + iCheckerDataPresent = EFalse; + iModifierDataPresent = EFalse; + iCheckerValue = 0; + iModifierValue = 0xFFFFFFFF; + } + +// +/* CConcurrentOwnerCardModifier - Specification */ +// This class should create the db, and set the owner card. +class CConcurrentOwnerCardModifier : public CConcurrentDatabaseAccessBase + { + public: + CConcurrentOwnerCardModifier(TOwnerCardCompare& aOwnerCardCompare); + ~CConcurrentOwnerCardModifier(); + + static CConcurrentOwnerCardModifier* NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare); + virtual void ConstructL(const TDesC& aFilename); + + static TInt ThreadFunction(TAny* aSelf); + + + protected: + TBool RunTestImplementationL(); + + private: + void AssignAndCompareOwnerCardIdL(TContactItemId aOwner); + + private: + TOwnerCardCompare& iOwnerCardCompare; + }; + +// +/* CConcurrentOwnerCardModifier - Implementation */ + +CConcurrentOwnerCardModifier* CConcurrentOwnerCardModifier::NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare) + { + CConcurrentOwnerCardModifier* self = NULL; + self = new (ELeave) CConcurrentOwnerCardModifier(aOwnerCardCompare); + CleanupStack::PushL( self ); + self->ConstructL(aFilename); + return self; + } + +CConcurrentOwnerCardModifier::CConcurrentOwnerCardModifier(TOwnerCardCompare& aOwnerCardCompare) + : iOwnerCardCompare( aOwnerCardCompare ) + { + } + +CConcurrentOwnerCardModifier::~CConcurrentOwnerCardModifier() + { + } + +TInt CConcurrentOwnerCardModifier::ThreadFunction(TAny* aSelf) + { + CConcurrentOwnerCardModifier* self = STATIC_CAST(CConcurrentOwnerCardModifier*, aSelf); + + // Prepare the stuff required before we start the + // active scheduler. + TInt error = KErrNone; + CTrapCleanup* cleanup = CTrapCleanup::New(); + if (!cleanup) + return KErrNoMemory; + + // Call virtual handler which does anything that needs doing as + // a result of the thread function from being created. + TRAP(error, self->RunTestL()); + + + delete cleanup; + return error; + } + +void CConcurrentOwnerCardModifier::ConstructL(const TDesC& aFilename) + { + CConcurrentDatabaseAccessBase::ConstructL(aFilename); + + iThread.Create( KThreadNameOne, CConcurrentOwnerCardModifier::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread ); + iThread.Resume(); + iThread.SetPriority(/*EPriorityNormal*/EPriorityAbsoluteBackground); + } + +// 1. Set up +// 2. Check current owner card. +// 3. Sync +// 4. modify owner card +// 5. Sync +// 6. Check owner card +// 7. Sync +// 8. Finished. +TBool CConcurrentOwnerCardModifier::RunTestImplementationL() + { + TInt bit = 0; + TContactItemId id; + CRandomContactGenerator* generator = NULL; + CContactItem* item = NULL; + TBool retval = EFalse; + + switch( iStage ) + { + case EOne_Startup: + OpenSemaphore(); + retval = NextStage(); + SyncronizeWait(); // pause until corresponding Searcher thread is ready. + break; + + case ETwo_FirstCheck: + id = iDb->OwnCardId(); + AssignAndCompareOwnerCardIdL( id ); + retval = NextStage(); + SyncronizeWait(); + break; + + case EThree_ChangeOwner: + generator = CRandomContactGenerator::NewL(); + CleanupStack::PushL( generator ); + generator->SetDbL(*iDb); + + bit |= CContactDatabase::ESmsable; + id = generator->AddTypicalContactForFilterL(bit); + item = iDb->ReadContactL( id ); + CleanupStack::PushL( item ); + iDb->SetOwnCardL( *item ); + CleanupStack::PopAndDestroy( item ); + item = NULL; + CleanupStack::PopAndDestroy( generator ); + generator = NULL; + retval = NextStage(); + SyncronizeWait(); // wait here. + break; + + case ENOP_One: + CallRunLAgain(); + retval = NextStage(); + break; + + case ENOP_Two: + CallRunLAgain(); + retval = NextStage(); + break; + + case EFour_SecondCheck: + iDb->CountL(); + id = iDb->OwnCardId(); + AssignAndCompareOwnerCardIdL( id ); + retval = NextStage(); + SyncronizeWait(); + break; + + case EFive_Cleanup: + CloseSemaphore(); + CloseTest(); + retval = ETrue; + break; + + default: + break; + } + + return retval; + } + + +void CConcurrentOwnerCardModifier::AssignAndCompareOwnerCardIdL(TContactItemId aOwner) + { + //SyncronizeWait(); + iOwnerCardCompare.AssignValuesAndCheckL( aOwner, TOwnerCardCompare::EModifier ); + //SyncronizeWait(); + //SyncronizeWait(); + } + +// +/* CConcurrentOwnerCardChecker */ +class CConcurrentOwnerCardChecker : public CConcurrentDatabaseAccessBase + { + public: + CConcurrentOwnerCardChecker(TOwnerCardCompare& aOwnerCardCompare); + ~CConcurrentOwnerCardChecker(); + + static CConcurrentOwnerCardChecker* NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare); + virtual void ConstructL(const TDesC& aFilename); + static TInt ThreadFunction(TAny* aSelf); + static TInt FakeFunction(TAny *aParams); + + + + protected: + TBool RunTestImplementationL(); + + private: + void AssignAndCompareOwnerCardIdL(TContactItemId aOwner); + + private: + TOwnerCardCompare& iOwnerCardCompare; + }; + +CConcurrentOwnerCardChecker* CConcurrentOwnerCardChecker::NewLC(const TDesC& aFilename, TOwnerCardCompare& aOwnerCardCompare) + { + CConcurrentOwnerCardChecker* self = NULL; + self = new (ELeave) CConcurrentOwnerCardChecker(aOwnerCardCompare); + CleanupStack::PushL( self ); + self->ConstructL(aFilename); + return self; + } + +CConcurrentOwnerCardChecker::CConcurrentOwnerCardChecker(TOwnerCardCompare& aOwnerCardCompare) + : iOwnerCardCompare( aOwnerCardCompare ) + { + } + +CConcurrentOwnerCardChecker::~CConcurrentOwnerCardChecker() + { + } + +TInt CConcurrentOwnerCardChecker::ThreadFunction(TAny* aSelf) + { + CConcurrentOwnerCardChecker* self = static_cast(aSelf); + + // Prepare the stuff required before we start the + // active scheduler. + TInt error = KErrNone; + + CTrapCleanup* cleanup = CTrapCleanup::New(); + if (!cleanup) + return KErrNoMemory; + + // Call virtual handler which does anything that needs doing as + // a result of the thread function from being created. + TRAP(error, self->RunTestL()); + + + delete cleanup; + return error; + } + +void CConcurrentOwnerCardChecker::ConstructL(const TDesC& aFilename) + { + CConcurrentDatabaseAccessBase::ConstructL(aFilename); + + iThread.Create( KThreadNameTwo, CConcurrentOwnerCardChecker::ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread ); + iThread.Resume(); + iThread.SetPriority(/*EPriorityNormal*/EPriorityAbsoluteBackground); + + } + + +TInt CConcurrentOwnerCardChecker::FakeFunction(TAny* /*aParams*/) + { + return(KErrNone); + } + +TBool CConcurrentOwnerCardChecker::RunTestImplementationL() + { + // Prep, and get ready to run. Then before starting the search loop + // wait for the other thread. + TContactItemId id; + TBool retval = EFalse; + + switch( iStage ) + { + case EOne_Startup: + //TCallBack callBack(FakeFunction); + OpenSemaphore(); + retval = NextStage(); + SyncronizeSignal(); // wait for the other thread. + break; + + case ETwo_FirstCheck: + id = iDb->OwnCardId(); + AssignAndCompareOwnerCardIdL( id ); + retval = NextStage(); + SyncronizeSignal(); + break; + + case EThree_ChangeOwner: + retval = NextStage(); + SyncronizeSignal(); + break; + + case ENOP_One: + CallRunLAgain(); + retval = NextStage(); + break; + + case ENOP_Two: + CallRunLAgain(); + retval = NextStage(); + break; + + case EFour_SecondCheck: + iDb->CountL(); + id = iDb->OwnCardId(); + AssignAndCompareOwnerCardIdL( id ); + retval = NextStage(); + SyncronizeSignal(); + break; + + case EFive_Cleanup: + CloseSemaphore(); + CloseTest(); + retval = NextStage(); + break; + + default: + break; + } + + return retval; + } + + +void CConcurrentOwnerCardChecker::AssignAndCompareOwnerCardIdL(TContactItemId aOwner) + { + //SyncronizeSignal(); + //SyncronizeSignal(); + iOwnerCardCompare.AssignValuesAndCheckL( aOwner, TOwnerCardCompare::EChecker ); + //SyncronizeSignal(); + } + +// +/* Test Function Prototypes */ +// +void CreateTestDatabaseL(const TDesC& aFilename); +void TestL(); +void doMainL(); + +// +/* Test Function Implementations */ +// +void CreateTestDatabaseL(const TDesC& aFilename ) + { + TInt counter = 0; + TInt bit = 0; + CContactDatabase* database = NULL; + CRandomContactGenerator* generator = NULL; + CContactItem* ownerCardItem = NULL; + TContactItemId ownerCard = 0; + + database = CContactDatabase::ReplaceL(aFilename); + CleanupStack::PushL( database ); + + generator = CRandomContactGenerator::NewL(); + CleanupStack::PushL( generator ); + + generator->SetDbL(*database); + + + bit |= CContactDatabase::ESmsable; + ownerCard = generator->AddTypicalContactForFilterL(bit); + TheTest.Printf(_L("Adding SMS contacts %d\n"), counter); + + + ownerCardItem = database->ReadContactL( ownerCard ); + CleanupStack::PushL( ownerCardItem ); + database->SetOwnCardL( *ownerCardItem ); + CleanupStack::PopAndDestroy( ownerCardItem ); ownerCardItem = NULL; + + CleanupStack::PopAndDestroy( generator ); + CleanupStack::PopAndDestroy( database ); + } + + +void TestL() + { + TRequestStatus thread1; + TRequestStatus thread2; + TOwnerCardCompare compareTool; + CConcurrentOwnerCardChecker* searcher = NULL; + CConcurrentOwnerCardModifier* inserter = NULL; + + CreateTestDatabaseL( KDatabaseFileName ); + + searcher = CConcurrentOwnerCardChecker::NewLC( KDatabaseFileName, compareTool ); + User::After(KDelay); // so that checker thread created first + inserter = CConcurrentOwnerCardModifier::NewLC( KDatabaseFileName, compareTool ); + + searcher->iThread.Logon(thread1); + inserter->iThread.Logon(thread2); + + User::WaitForRequest(thread2); + User::WaitForRequest(thread1); + + CleanupStack::PopAndDestroy( inserter ); + CleanupStack::PopAndDestroy( searcher ); + + // fail if either thread failed + User::LeaveIfError(thread1.Int()); + User::LeaveIfError(thread2.Int()); + } + + +// +// -------> Static global functions (source) +// +void doMainL() + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + CTestRegister * TempFiles = CTestRegister::NewLC(); + TempFiles->RegisterL(KDatabaseFileName, EFileTypeCnt); + + CTestActiveScheduler* scheduler = new (ELeave) CTestActiveScheduler; + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + + + // Delete any existing ini file so that we can be sure this test is ok + TestL(); + + CleanupStack::PopAndDestroy( 3 ); // scheduler, tempfiles, fs + + } + + +/** + +@SYMTestCaseID PIM-T-OWNCARD-0001 + +*/ + +GLDEF_C TInt E32Main() + { + CTrapCleanup* cleanupStack = NULL; + __UHEAP_MARK; + TheTest.Start(_L("@SYMTESTCaseID:PIM-T-OWNCARD-0001 Multi session testcode")); + + TheTest.Title(); + cleanupStack = CTrapCleanup::New(); + TRAPD(ret, doMainL()); + TheTest(ret == KErrNone); + delete cleanupStack; + + TheTest.End(); + TheTest.Close(); + __UHEAP_MARKEND; + return(KErrNone); + }