diff -r 000000000000 -r e686773b3f54 phonebookengines/contactsmodel/tsrc/t_currentdb.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/contactsmodel/tsrc/t_currentdb.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,1590 @@ +// Copyright (c) 1997-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_currentdb.h" + +// System includes +#include +#include +#include +#include +#include "coreappstest/testserver.h" + +// User includes +#include "T_UTILS.H" + +// Globals +static RTest TheTest(_L("T_CURRENTDB - Test CntModel current DB support")); +static CTrapCleanup* TheCleanup; + +// Constants (literal) +_LIT(KThreadTestFormat, "\nThread %d running test %d\n"); +_LIT(KThreadTestOkFormat, "\nThread %d completed test %d OK\n"); + +// Configure database location +_LIT(KTestDatabaseFile, "C:Contacts.cdb"); +_LIT(KTestDatabaseFile2, "C:LotsOfContacts.cdb"); + +// Configure .ini file location +_LIT(KContactsModelIniFile, "c:\\private\\10003A73\\CntModel.ini"); + +_LIT(KTestSemaphoreOne, "T_CURRENTDB_SEMAPHORE_ONE"); +_LIT(KTestSemaphoreTwo, "T_CURRENTDB_SEMAPHORE_TWO"); +_LIT(KSpeedDialPhoneNumber, "020 11111111"); +_LIT(KSpeedDialPhoneNumber2, "020 22222222"); +const TInt KSpeedDialPositionOne = 1; +const TInt KSpeedDialPositionTwo = 2; + +const TInt KTestSteps = 100; + +// +// -------> CTestActiveScheduler (header) +// +class CTestActiveScheduler : public CActiveScheduler + { +// +public: +// + void Error (TInt aError) const; + }; + + +// +// -------> CTestActiveScheduler (source) +// +void CTestActiveScheduler::Error(TInt aError) const + { + User::Panic(_L("AScheduler"),aError); + } + + +// +// -------> CTestBase (source) +// +CTestBase::CTestBase(CTestManager& aTester, TInt aClientNumber, TThreadPriority aThreadPriority, TInt aPriority) +: CActive(aPriority), iTestCoordinator(aTester), iClientNumber(aClientNumber), iThreadPriority(aThreadPriority) + { + } + +CTestBase::~CTestBase() + { + Cancel(); + iThread.Close(); + } + +void CTestBase::ConstructL(const TDesC& aName) + { + User::LeaveIfError(iThread.Create(aName, ThreadFunction, KDefaultStackSize, 0x2000, 0x20000, this, EOwnerThread)); + iThread.Resume(); + iThread.SetPriority(iThreadPriority); + } + +// +// +// + +void CTestBase::Complete(TInt aReason) + { + // Complete the request with the specified reason. + __ASSERT_ALWAYS(IsActive() && iStatus.Int() == KRequestPending, User::Invariant()); + TRequestStatus* status = &iStatus; + iThread.RequestComplete(status, aReason); + } + +// +// +// + +void CTestBase::RunL() + { + _LIT(KThreadTestCompleteFormat, "Thread %d finished tests"); + + if (iWaiting || iWaitingForAnyEvent) + { + CActiveScheduler::Stop(); // stop nested scheduler + iWaiting = iWaitingForAnyEvent = EFalse; + return; + } + + // Increment test number + ++iCurrentTest; + + if (iStatus.Int() < KErrNone) // Can this happen? + { + User::Invariant(); + } + + switch(iStatus.Int()) + { + case EEndTests: + { + TBuf<50> buf; + buf.Format(KThreadTestCompleteFormat, iClientNumber); + iTest->Next(buf); + CActiveScheduler::Stop(); + break; + } + default: + { + // Call the framework to handle the specific test number + DoTestL(iStatus.Int()); + + TBuf<200> buf; + buf.Format(KThreadTestOkFormat, iClientNumber, iStatus.Int()); + iTest->Printf(buf); + + // Re issue another asynch request + ReadyForNextTest(); + break; + } + } + } + +void CTestBase::DoCancel() + { + iWaitTimer.Cancel(); + + // Cancel any outstanding request + if (!(iWaiting || iWaitingForAnyEvent)) + { + Complete(KErrCancel); + } + } + +// +// +// + +TInt CTestBase::ThreadFunction(TAny* aParam) + { + CTestBase* self = STATIC_CAST(CTestBase*, aParam); + + // Prepare the stuff required before we start the + // active scheduler. + 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. + TRAPD(err, self->RunTestsL()); + + delete cleanup; + return err; + } + +void CTestBase::RunTestsL() + { + User::LeaveIfError(iWaitTimer.CreateLocal()); + + OpenSemaphoreL(); + + HandleThreadCreationL(); + ReadyForNextTest(); + CActiveScheduler::Start(); + HandleThreadDeletionL(); + + CloseSemaphore(); + + iWaitTimer.Cancel(); + iWaitTimer.Close(); + } + +TInt CTestBase::HandleThreadCreationL() + { + // Create and name an RTest + TBuf<100> threadName; + threadName.Format(_L("Test thread %d"), iClientNumber); + iTest = new(ELeave) RTest(threadName); + iTest->Start(_L("Starting test")); + + // Position our console window + TSize size = iTest->Console()->ScreenSize(); + size.iWidth = size.iWidth - 4; + size.iHeight = (size.iHeight / 2) - 3; + + iConsole = Console::NewL(threadName, size); + delete (CONST_CAST(RTest*, iTest)->Console()); + iTest->SetConsole(iConsole); + iConsole->ClearScreen(); + + // Create contacts db session + iTest->Next(_L("Creating contacts test utility")); + iContactsTest = new(ELeave) CCntTest(); + OpenDatabaseL(); + + // Add the CTestBase object + // to it. Has to be done in this function, otherwise the AO can + // end up being added to the wrong active scheduler + CActiveScheduler::Add(this); + + return KErrNone; + } + +void CTestBase::HandleThreadDeletionL() + { + iContactsTest->EndTestLib(KErrNone); + } + +// +// +// + +void CTestBase::ReadyForNextTest() +// +// Requests another test be executed +// + { + __ASSERT_ALWAYS(!iWaiting && !iWaitingForAnyEvent, User::Invariant()); + SetActive(); + iStatus = KRequestPending; + } + +void CTestBase::WaitForContactsEvent(TContactDbObserverEventType aEvent, TInt aTimeInSecondsToWaitFor) + { + iWaiting = ETrue; + iEvent = aEvent; + TTimeIntervalMicroSeconds32 time(aTimeInSecondsToWaitFor * 1000000); + iWaitTimer.After(iStatus, time); + SetActive(); + CActiveScheduler::Start(); + } + +void CTestBase::WaitForAnyContactsEvent(TInt aTimeInSecondsToWaitFor) + { + iWaitingForAnyEvent = ETrue; + TTimeIntervalMicroSeconds32 time(aTimeInSecondsToWaitFor * 1000000); + iWaitTimer.After(iStatus, time); + SetActive(); + CActiveScheduler::Start(); + } + +void CTestBase::HandleDatabaseEventL(TContactDbObserverEvent aEvent) + { + __ASSERT_ALWAYS(iWaiting || iWaitingForAnyEvent, User::Invariant()); + + iLastEvent=aEvent; + switch(aEvent.iType) + { + case EContactDbObserverEventNull: + iTest->Printf(_L("Event: EContactDbObserverEventNull\n")); + break; + case EContactDbObserverEventUnused: + iTest->Printf(_L("Event: EContactDbObserverEventUnused\n")); + break; + case EContactDbObserverEventContactChanged: + iTest->Printf(_L("Event: EContactDbObserverEventContactChanged\n")); + break; + case EContactDbObserverEventContactDeleted: + iTest->Printf(_L("Event: EContactDbObserverEventContactDeleted\n")); + break; + case EContactDbObserverEventContactAdded: + iTest->Printf(_L("Event: EContactDbObserverEventContactAdded\n")); + break; + case EContactDbObserverEventUnknownChanges: + iTest->Printf(_L("Event: EContactDbObserverEventUnknownChanges\n")); + break; + case EContactDbObserverEventRecover: + iTest->Printf(_L("Event: EContactDbObserverEventRecover\n")); + break; + case EContactDbObserverEventRollback: + iTest->Printf(_L("Event: EContactDbObserverEventRollback\n")); + break; + case EContactDbObserverEventTablesClosed: + iTest->Printf(_L("Event: EContactDbObserverEventTablesClosed\n")); + break; + case EContactDbObserverEventTablesOpened: + iTest->Printf(_L("Event: EContactDbObserverEventTablesOpened\n")); + break; + case EContactDbObserverEventTemplateChanged: + iTest->Printf(_L("Event: EContactDbObserverEventTemplateChanged\n")); + break; + case EContactDbObserverEventTemplateDeleted: + iTest->Printf(_L("Event: EContactDbObserverEventTemplateDeleted\n")); + break; + case EContactDbObserverEventTemplateAdded: + iTest->Printf(_L("Event: EContactDbObserverEventTemplateAdded\n")); + break; + case EContactDbObserverEventCurrentItemDeleted: + iTest->Printf(_L("Event: EContactDbObserverEventCurrentItemDeleted\n")); + break; + case EContactDbObserverEventCurrentItemChanged: + (*iTest)(aEvent.iContactId != KNullContactId); + iTest->Printf(_L("Event: EContactDbObserverEventCurrentItemChanged\n")); + break; + case EContactDbObserverEventOwnCardChanged: + iTest->Printf(_L("Event: EContactDbObserverEventOwnCardChanged\n")); + break; + case EContactDbObserverEventPreferredTemplateChanged: + iTest->Printf(_L("Event: EContactDbObserverEventPreferredTemplateChanged\n")); + break; + case EContactDbObserverEventOwnCardDeleted: + iTest->Printf(_L("Event: EContactDbObserverEventOwnCardDeleted\n")); + break; + case EContactDbObserverEventGroupAdded: + iTest->Printf(_L("Event: EContactDbObserverEventGroupAdded\n")); + break; + case EContactDbObserverEventGroupChanged: + iTest->Printf(_L("Event: EContactDbObserverEventGroupChanged\n")); + break; + case EContactDbObserverEventGroupDeleted: + iTest->Printf(_L("Event: EContactDbObserverEventGroupDeleted\n")); + break; + case EContactDbObserverEventCurrentDatabaseChanged: + iTest->Printf(_L("Event: EContactDbObserverEventCurrentDatabaseChanged\n")); + break; + case EContactDbObserverEventSpeedDialsChanged: + iTest->Printf(_L("Event: EContactDbObserverEventSpeedDialsChanged\n")); + break; + default: + iTest->Printf(_L("Unhandled Event\n")); + User::Invariant(); + } + + if ((aEvent.iType == iEvent) || iWaitingForAnyEvent) + { + Cancel(); + iWaiting = iWaitingForAnyEvent = EFalse; + CActiveScheduler::Stop(); + return; + } + else if (aEvent.iType != iEvent) + { + iTest->Printf(_L("Got an Unexpected Event.\n")); + } + + + } + +void CTestBase::OpenSemaphoreL() + { + TInt error = iSemaphoreOne.CreateGlobal(KTestSemaphoreOne(), 0); + if (error == KErrAlreadyExists || error == KErrNone) + { + iSemaphoreOne.OpenGlobal(KTestSemaphoreOne()); + } + else + { + User::Leave(error); + } + + error = iSemaphoreTwo.CreateGlobal(KTestSemaphoreTwo(), 0); + if (error == KErrAlreadyExists || error == KErrNone) + { + iSemaphoreTwo.OpenGlobal(KTestSemaphoreTwo()); + } + else + { + User::Leave(error); + } + } + +void CTestBase::CloseSemaphore() + { + iSemaphoreOne.Close(); + iSemaphoreTwo.Close(); + } + + +// +// -------> CTestThreadOne (source) +// +CTestThreadOne::CTestThreadOne(CTestManager& aTester, TInt aClientNumber, TThreadPriority aThreadPriority, TInt aPriority) +: CTestBase(aTester, aClientNumber, aThreadPriority, aPriority) + { + } + +CTestThreadOne* CTestThreadOne::NewL(TInt aClientNumber, const TDesC& aName, CTestManager& aTester, TThreadPriority aThreadPriority, TInt aPriority) + { + CTestThreadOne* self = new(ELeave) CTestThreadOne(aTester, aClientNumber, aThreadPriority, aPriority); + CleanupStack::PushL(self); + self->ConstructL(aName); + CleanupStack::Pop(); // self + return self; + } + +void CTestThreadOne::OpenDatabaseL() + { + TBuf<200> buf; + buf.Format(_L("Constructing test utilities with database set as %S"), &KTestDatabaseFile); + iTest->Next(buf); + iContactsTest->ConstructL(*iTest, KTestDatabaseFile); + } + +// +// +// + +void CTestThreadOne::DoTestL(TInt aTestNumber) + { + TBuf<50> buf; + buf.Format(KThreadTestFormat, iClientNumber, aTestNumber); + iTest->Next(buf); + + switch(aTestNumber) + { + case ETest1: + DoTest1L(); + break; + case ETest2: + DoTest2L(); + break; + case ETest3: + DoTest3L(); + break; + case ETest4: + DoTest4L(); + break; + case ETest5: + DoTest5L(); + break; + case ETest6: + DoTest6L(); + break; + case ETest7: + DoTest7L(); + break; + case ETest8: + DoTest8L(); + break; + case ETest9: + DoTest9L(); + break; + default: + User::Invariant(); + } + } + +// +// +// + +void CTestThreadOne::DoTest1L() + { + // This thread has a higher priority than thread 2 so it should run first, + // hence this test should work. + iSemaphoreOne.Wait(); + + iTest->Next(_L("Opening the database and check the current db is null\n")); + iContactsTest->OpenDatabaseL(); + + iTest->Printf(_L("Fetching the current database...\n")); + TFileName currentDb; + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("Current database reported as %S\n"), ¤tDb); + (*iTest)(currentDb.CompareF(KNullDesC) == 0); + + // Because there was no ini file found, we now set this database to be the + // current. + iTest->Printf(_L("\tSetting thread one's database as the current db\n")); + User::LeaveIfError(iContactsTest->Db()->SetCurrentDatabase(KTestDatabaseFile)); + + // Check that it is the current db now + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("Current database reported as %S\n"), ¤tDb); + (*iTest)(currentDb.CompareF(KTestDatabaseFile) == 0); + iSemaphoreTwo.Signal(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +void CTestThreadOne::DoTest2L() + { + iSemaphoreOne.Wait(); + iSemaphoreTwo.Signal(); + iTest->Next(_L("\tWaiting for thread 2 to change current db\n")); + // Thread two is going to change the current database to 'it's' db. + // Wait for notification... + + // !! Why on Earth do we need one of these? Talk about bad design. + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*iContactsTest->Db(), this); + CleanupStack::PushL(changeNotifier); + WaitForContactsEvent(EContactDbObserverEventCurrentDatabaseChanged); + CleanupStack::PopAndDestroy(); // changeNotifier + iTest->Printf(_L("\tCurrent database change was reported correctly\n")); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +void CTestThreadOne::DoTest3L() + { + iSemaphoreOne.Wait(); + + iTest->Next(_L("Setting the current db a lot of times\n")); + for(TInt i = 0; i < KTestSteps; ++i) + { + // Open and close our database setting it as the default + iTest->Printf(_L("\tClosing thread one's database\n")); + iContactsTest->CloseDatabase(); + + iTest->Printf(_L("\tOpening thread one's database\n")); + iContactsTest->OpenDatabaseL(); + + // Set our db + iTest->Printf(_L("\tSetting thread one's database as the current db\n")); + User::LeaveIfError(iContactsTest->Db()->SetCurrentDatabase(KTestDatabaseFile)); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + + iSemaphoreOne.Wait(); + // Check that the current db is KTestDatabaseFile2 (because thread two has just closed the + // previous current db, which was KTestDatabaseFile2). + TFileName currentDb; + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("Current database reported as %S\n"), ¤tDb); + (*iTest)(currentDb.CompareF(KTestDatabaseFile2) == 0); + + iTest->Printf(_L("\tClosing thread one's database\n")); + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +void CTestThreadOne::DoTest4L() + { + iSemaphoreOne.Wait(); + + iTest->Next(_L("Checking that after closing all sessions, the current database is remembered\n")); + + iTest->Printf(_L("\tOpening thread one's database\n")); + iContactsTest->OpenDatabaseL(); + + iTest->Printf(_L("\tClosing thread one's database\n")); + iContactsTest->CloseDatabase(); + + iTest->Printf(_L("\tDeleting CntModel.ini and checking server still able to cope\n")); + // Secure Server waits 5s from last connection + // to write the .ini file and close + User::After(6000000); + + RPIMTestServer serv; + User::LeaveIfError(serv.Connect()); + TRAPD(err,serv.DeleteFileL(KContactsModelIniFile)); + if (err != KErrNotFound) + { + User::LeaveIfError(err); + } + serv.Close(); + + iTest->Printf(_L("\tAttempt to re-open thread one's database\n")); + iContactsTest->OpenDatabaseL(); + + iTest->Printf(_L("\tCheck that the current database is null in this instance\n")); + TFileName currentDb; + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("\tCurrent database reported as %S\n"), ¤tDb); + + iTest->Printf(_L("\tSet the current db again\n")); + User::LeaveIfError(iContactsTest->Db()->SetCurrentDatabase(KTestDatabaseFile)); + + iTest->Printf(_L("\tWait for change notification\n")); + iTest->Printf(_L("\tClosing thread one's database\n")); + iContactsTest->CloseDatabase(); + + iTest->Printf(_L("\tOpening thread one's database again to check correct restoration of current db\n")); + iContactsTest->OpenDatabaseL(); + + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("Current database reported as %S\n"), ¤tDb); + (*iTest)(currentDb.CompareF(KTestDatabaseFile) == 0); + + iTest->Printf(_L("\tClosing thread one's database\n")); + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + + +/** + * Speeddial test + * Open contacts database + * Wait for notification that the other client has opened the database + * Add a new speeddial + * Wait for confirmation the update was received + */ +void CTestThreadOne::DoTest5L() + { + iSemaphoreOne.Wait(); + + iContactsTest->OpenDatabaseL(); + + iTest->Printf(_L("we've both got the database open")); + + // Add a contact and set the speeddial + CContactItem* item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Given"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber, ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, _L("020 22222222"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapCELL, _L("07747 065000"), ETrue); + TContactItemId id = iContactsTest->Db()->AddNewContactL(*item); + iContactsTest->Db()->SetCurrentItem(id); + CleanupStack::PopAndDestroy(item); + + // Set speeddial + TInt fieldId=1; + const CContactIdArray* sortedItems = iContactsTest->Db()->SortedItemsL(); + + // First item in position 1 + CContactItem* firstItem = iContactsTest->Db()->OpenContactL((*sortedItems)[0]); + CleanupStack::PushL(firstItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, KSpeedDialPositionOne); + CleanupStack::PopAndDestroy(firstItem); + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + TBuf<32> phoneNumber; + TContactItemId id2 = iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id2 == id); + iTest->Printf(_L("ThreadOne : set contact with speed dial at position 1, awaiting notification.\n")); + + iContactsTest->Db()->DeleteContactL(id); + iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + iTest->Printf(_L("ThreadOne : deleted contact, waiting for notification\n")); + + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +/** + * Speeddial test + * Open contacts database + * Wait for notification that the other client has opened the database + * Remove a speeddial + * Wait for confirmation the update was received + */ +void CTestThreadOne::DoTest6L() + { + iSemaphoreOne.Wait(); + + iContactsTest->OpenDatabaseL(); + iTest->Printf(_L("we've both got the database open")); + + // Add a contact and set the speeddial + CContactItem* item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Given"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber, ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, _L("020 22222222"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapCELL, _L("07747 065000"), ETrue); + TContactItemId id = iContactsTest->Db()->AddNewContactL(*item); + iContactsTest->Db()->SetCurrentItem(id); + CleanupStack::PopAndDestroy(item); + + // Set speeddial + TInt fieldId=1; + const CContactIdArray* sortedItems = iContactsTest->Db()->SortedItemsL(); + + // First item in position 1 + CContactItem* firstItem = iContactsTest->Db()->OpenContactL((*sortedItems)[0]); + CleanupStack::PushL(firstItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, KSpeedDialPositionOne); + CleanupStack::PopAndDestroy(firstItem); + + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + TBuf<32> phoneNumber; + TContactItemId id2= iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id2==id); + iTest->Printf(_L("ThreadOne : set contact with speed dial at position 1, awaiting notification.\n")); + + iTest->Printf(_L("ThreadOne : removing speed dial that was just added.... ")); + iContactsTest->Db()->RemoveSpeedDialFieldL(id, KSpeedDialPositionOne); + iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + iTest->Printf(_L("done\n")); + + iSemaphoreTwo.Signal(); + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +/** + * Group add test + * Open contacts database + * Wait for notification that the other client has opened the database + * Add a new group + * Wait for confirmation the update was received + * Delete the new group + * Wait for confirmation the update was received + */ +void CTestThreadOne::DoTest7L() + { + iSemaphoreOne.Wait(); + + iContactsTest->OpenDatabaseL(); + iTest->Printf(_L("we've both got the database open")); + + CContactItem* tempGroup = iContactsTest->Db()->CreateContactGroupL(_L("NEW GROUP")); + delete tempGroup; + + CContactIdArray* groupIdList = iContactsTest->Db()->GetGroupIdListL(); + CleanupStack::PushL(groupIdList); + iContactsTest->Db()->DeleteContactL((*groupIdList)[0]); + CleanupStack::PopAndDestroy(groupIdList); + iContactsTest->CloseDatabase(); + iSemaphoreTwo.Signal(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +void CTestThreadOne::DoTest8L() + { + iSemaphoreOne.Wait(); + + iContactsTest->OpenDatabaseL(); + iTest->Printf(_L("we've both got the database open")); + + // Add a contact and set the speeddial + CContactItem* item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Given"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber, ETrue); + TContactItemId id = iContactsTest->Db()->AddNewContactL(*item); + CleanupStack::PopAndDestroy(item); + + // Set speeddial - Case:1 + TInt fieldId=1; + CContactItem* firstItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(firstItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, KSpeedDialPositionOne); + CleanupStack::PopAndDestroy(firstItem); + + TBuf<32> phoneNumber; + TContactItemId id2= iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id2==id); + iTest->Printf(_L("ThreadOne : set contact with speed dial at position 1, awaiting notification.\n")); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + // changing the name to see the type of notifications emitted. - Case:2 + CContactItem* editItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(editItem); + SetNameL(*editItem, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("changed"), EFalse); + iContactsTest->Db()->CommitContactL(*editItem); + CleanupStack::PopAndDestroy(editItem); + iTest->Printf(_L("ThreadOne : Changing name of contact at position 1, awaiting notification.\n")); + + // changing the name & phone number, to see the type of notifications emitted. - Case:3 + editItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(editItem); + SetNameL(*editItem, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("changed"), EFalse); + SetNameL(*editItem, KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, _L("020 88888888"), EFalse); + iContactsTest->Db()->CommitContactL(*editItem); + CleanupStack::PopAndDestroy(editItem); + iTest->Printf(_L("ThreadOne : Changing name & phone no. of contact at position 1, awaiting notification.\n")); + + iContactsTest->Db()->DeleteContactL(id); + iTest->Printf(_L("ThreadOne : deleted contact, waiting for notification\n")); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + //add 2 contacts, set them to speed dail, change details & commit, and check notifications, + // & delete - Case:4 + item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Contact-1"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber, ETrue); + id = iContactsTest->Db()->AddNewContactL(*item); + CleanupStack::PopAndDestroy(item); + + item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Contact-2"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber2, ETrue); + id2 = iContactsTest->Db()->AddNewContactL(*item); + CleanupStack::PopAndDestroy(item); + + // speeddial for the both the contacts, + firstItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(firstItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, KSpeedDialPositionOne); + CleanupStack::PopAndDestroy(firstItem); + + CContactItem* secondItem = iContactsTest->Db()->OpenContactL(id2); + CleanupStack::PushL(secondItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*secondItem, fieldId, KSpeedDialPositionTwo); + CleanupStack::PopAndDestroy(secondItem); + + //change details, for second contact 1st and then the first contact. + editItem = iContactsTest->Db()->OpenContactL(id2); + CleanupStack::PushL(editItem); + SetNameL(*editItem, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("changed second"), EFalse); + SetNameL(*editItem, KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, _L("020 77777777"), EFalse); + iContactsTest->Db()->CommitContactL(*editItem); + CleanupStack::PopAndDestroy(editItem); + + editItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(editItem); + SetNameL(*editItem, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("changed first"), EFalse); + SetNameL(*editItem, KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, _L("020 66666666"), EFalse); + iContactsTest->Db()->CommitContactL(*editItem); + CleanupStack::PopAndDestroy(editItem); + + iContactsTest->Db()->DeleteContactL(id); + iContactsTest->Db()->DeleteContactL(id2); + iTest->Printf(_L("ThreadOne : Added 2 contacts, set speed dail for both, changed contact details for both & deleted both the contacts, waiting for notification\n")); + + //Case:5, Add contact, set speed dail, remove speed dail, delete contact + // Add a contact and set the speeddial + item=CContactCard::NewLC(); + SetNameL(*item,KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, _L("Given"), ETrue); + SetNameL(*item,KUidContactFieldPhoneNumber, KUidContactFieldVCardMapTEL, KSpeedDialPhoneNumber, ETrue); + id = iContactsTest->Db()->AddNewContactL(*item); + CleanupStack::PopAndDestroy(item); + + // Set speeddial + firstItem = iContactsTest->Db()->OpenContactL(id); + CleanupStack::PushL(firstItem); + iContactsTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, KSpeedDialPositionOne); + CleanupStack::PopAndDestroy(firstItem); + + iSemaphoreTwo.Signal(); + + // Remove speed dail + id2= iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id2==id); + + iContactsTest->Db()->RemoveSpeedDialFieldL(id, KSpeedDialPositionOne); + iContactsTest->Db()->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KNullDesC); + iContactsTest->Db()->DeleteContactL(id); + iTest->Printf(_L("ThreadOne : Add contacts, set speed dail, remove speed dial, and delete, waiting for notification\n")); + + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + } + +/* +Teststep to test fix for INC116664 +1)Add contact items to database +2)Add contact template to database +3)Delete contact template from database +Result:Contact template should be deleted without any panic. +*/ + +void CTestThreadOne::DoTest9L() + { + iSemaphoreOne.Wait(); + + iContactsTest->OpenDatabaseL(); + iTest->Printf(_L("we've both got the database open")); + + iTest->Printf(_L("Add new contact data\n")); + + CContactDatabase* db = iContactsTest->Db(); + + TContactItemId id = AddContactL(db, KUidContactFieldFamilyName, KUidContactFieldVCardMapUnusedN, _L("3333")); + iTest->Printf(_L("Contact Added with Id = %d\n"), id); + + id = AddContactL(db, KUidContactFieldFamilyName, KUidContactFieldVCardMapUnusedN, _L("2222")); + iTest->Printf(_L("Contact Added with Id = %d\n"), id); + + id = AddContactL(db, KUidContactFieldFamilyName, KUidContactFieldVCardMapUnusedN, _L("1111")); + iTest->Printf(_L("Contact Added with Id = %d\n"), id); + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + CContactItem* contactTemplate = iContactsTest->Db()->CreateContactCardTemplateLC(_L("TestINC116664")); + id = contactTemplate->Id(); + iTest->Printf(_L("Contact Template Created with Id = %d\n"),id); + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + + iContactsTest->Db()->AddNewContactL(*contactTemplate); + iSemaphoreTwo.Signal(); + iSemaphoreOne.Wait(); + CleanupStack::PopAndDestroy(contactTemplate); + + iTest->Printf(_L("Deleting Contact Template now\n")); + iContactsTest->Db()->DeleteContactL(id); + iSemaphoreTwo.Signal(); + + iContactsTest->CloseDatabase(); + } + +// +// -------> CTestThreadTwo (source) +// +CTestThreadTwo::CTestThreadTwo(CTestManager& aTester, TInt aClientNumber, TThreadPriority aThreadPriority, TInt aPriority) +: CTestBase(aTester, aClientNumber, aThreadPriority, aPriority) + { + } + +CTestThreadTwo* CTestThreadTwo::NewL(TInt aClientNumber, const TDesC& aName, CTestManager& aTester, TThreadPriority aThreadPriority, TInt aPriority) + { + CTestThreadTwo* self = new(ELeave) CTestThreadTwo(aTester, aClientNumber, aThreadPriority, aPriority); + CleanupStack::PushL(self); + self->ConstructL(aName); + CleanupStack::Pop(); // self + return self; + } + +void CTestThreadTwo::OpenDatabaseL() + { + TBuf<200> buf; + buf.Format(_L("Constructing test utilities with database set as %S"), &KTestDatabaseFile); + iTest->Next(buf); + iContactsTest->ConstructL(*iTest, KTestDatabaseFile2); + } + +// +// +// + +void CTestThreadTwo::DoTestL(TInt aTestNumber) + { + TBuf<50> buf; + buf.Format(KThreadTestFormat, iClientNumber, aTestNumber); + iTest->Next(buf); + + switch(aTestNumber) + { + case ETest1: + DoTest1L(); + break; + case ETest2: + DoTest2L(); + break; + case ETest3: + DoTest3L(); + break; + case ETest4: + DoTest4L(); + break; + case ETest5: + DoTest5L(); + break; + case ETest6: + DoTest6L(); + break; + case ETest7: + DoTest7L(); + break; + case ETest8: + DoTest8L(); + break; + case ETest9: + DoTest9L(); + break; + default: + User::Invariant(); + } + } + +// +// +// + +void CTestThreadTwo::DoTest1L() + { + iSemaphoreOne.Signal(); + // This thread has a lower priority than thread 1 so it should run second, + // hence this test should work. + iSemaphoreTwo.Wait(); + iTest->Next(_L("Opening the database and check it is not made the current db\n")); + iContactsTest->OpenDatabaseL(); + + iTest->Printf(_L("\tFetching the current database...\n")); + TFileName currentDb; + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("\tCurrent database reported as %S\n"), ¤tDb); + + // The current database should still be the normal 'contacts.cdb' + (*iTest)(currentDb.CompareF(KTestDatabaseFile) == 0); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + +void CTestThreadTwo::DoTest2L() + { + iSemaphoreOne.Signal(); + + iTest->Next(_L("Setting the current database and check...")); + + // Set our database as the current (it was thread 1's)... + User::LeaveIfError(iContactsTest->Db()->SetCurrentDatabase(KTestDatabaseFile2)); + + // Check it's been changed... + iTest->Printf(_L("\tFetching the current database...\n")); + TFileName currentDb; + User::LeaveIfError(iContactsTest->Db()->GetCurrentDatabase(currentDb)); + iTest->Printf(_L("\tCurrent database reported as %S\n"), ¤tDb); + (*iTest)(currentDb.CompareF(KTestDatabaseFile2) == 0); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + +void CTestThreadTwo::DoTest3L() + { + iSemaphoreOne.Signal(); + + iTest->Next(_L("Waiting for thread 1 to set the current db a lot of times\n")); + for(TInt i = 0; i < KTestSteps; ++i) + { + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*iContactsTest->Db(), this); + CleanupStack::PushL(changeNotifier); + + // This will wait for it + iTest->Printf(_L("\tWaiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventCurrentDatabaseChanged); + iTest->Printf(_L("\tNotification complete...\n")); + CleanupStack::PopAndDestroy(); // changeNotifier + + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + + // Set our database as the current (it was thread 1's)... + User::LeaveIfError(iContactsTest->Db()->SetCurrentDatabase(KTestDatabaseFile2)); + + // Now close our db + iTest->Printf(_L("\tClosing thread two's database\n")); + iContactsTest->CloseDatabase(); + iSemaphoreOne.Signal(); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + +void CTestThreadTwo::DoTest4L() + { + iSemaphoreOne.Signal(); + iTest->Next(_L("Thread two, simple wait for notification to aid thread one\n")); + + iTest->Printf(_L("\tOpening thread two's database\n")); + iContactsTest->OpenDatabaseL(); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*iContactsTest->Db(), this); + CleanupStack::PushL(changeNotifier); + iTest->Printf(_L("\tWaiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventCurrentDatabaseChanged); + iTest->Printf(_L("\tNotification complete...\n")); + CleanupStack::PopAndDestroy(); // changeNotifier + + // Close our db + iTest->Printf(_L("\tClosing thread two's database\n")); + iContactsTest->CloseDatabase(); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + + +/** + * Speeddial test + * Open thread one's contacts database + * Wait for notification that the other client added a speeddial + * Check that it is possible to read the speeddial + */ +void CTestThreadTwo::DoTest5L() + { + iTest->Printf(_L("\tOpening thread one's database\n")); + CContactDatabase* threadTwoDb = iContactsTest->Db()->OpenL(KTestDatabaseFile); + CleanupStack::PushL(threadTwoDb); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*threadTwoDb, this); + CleanupStack::PushL(changeNotifier); + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + iSemaphoreTwo.Wait(); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + WaitForContactsEvent(EContactDbObserverEventCurrentItemChanged); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + iTest->Printf(_L("\tThreadTwo : We expect a speed dial to have been added... ")); + TheTest(iLastEvent.iContactId==1); + iTest->Printf(_L("correct.\n")); + + TBuf<32> phoneNumber; + TContactItemId id = threadTwoDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber == KSpeedDialPhoneNumber); + TheTest(id == 1); + + iSemaphoreOne.Signal(); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + iTest->Printf(_L("\tThreadTwo : We expect the contact owning the speed dial to have been deleted... ")); + TheTest(iLastEvent.iContactId == id); // Speed dial has been deleted by CTestThreadOne::DoTest5L(), + //event returns ID on deletion + iTest->Printf(_L("\n\tSpeed dial contact has been deleted by CTestThreadOne::DoTest5L(),.\n")); + iTest->Printf(_L("correct.\n")); + CleanupStack::PopAndDestroy(); // changeNotifier + + id = threadTwoDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber == KNullDesC); + TheTest(id==-1); + + CleanupStack::PopAndDestroy(); + + // Signal thread 1 + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + + +/** + * Speeddial test + * Open thread one's contacts database + * Wait for notification that the other client removed a speeddial + * Check that it is possible to read the speeddial + */ +void CTestThreadTwo::DoTest6L() + { + iTest->Printf(_L("\tOpening thread one's database\n")); + CContactDatabase* threadOneDb = iContactsTest->Db()->OpenL(KTestDatabaseFile); + CleanupStack::PushL(threadOneDb); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*threadOneDb, this); + CleanupStack::PushL(changeNotifier); + + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + + iTest->Printf(_L("\tWaiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + WaitForContactsEvent(EContactDbObserverEventCurrentItemChanged); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + iTest->Printf(_L("\tSpeedDial Notification complete\n")); + TheTest(iLastEvent.iContactId==2); // we deleted contact 1 + + TBuf<32> phoneNumber; + TContactItemId id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id==2); + + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + + WaitForContactsEvent(EContactDbObserverEventContactChanged); + TheTest(iLastEvent.iContactId==id); //speed dial has been removed by CTestThreadOne::DoTest6L(), + // event returns ID on removal + iTest->Printf(_L("\n\tspeed dial has been removed by CTestThreadOne::DoTest6L(), \n")); + CleanupStack::PopAndDestroy(); // changeNotifier + + id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KNullDesC); + TheTest(id==-1); + + CleanupStack::PopAndDestroy(); // threadOneDb + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + +/** + * Group test + * Open thread one's contacts database + * Wait for notification that the other client added a contact group + * and acknowledge the same + * Wait for notification that the other client deleted a contact group + * and acknowledge the same + */ +void CTestThreadTwo::DoTest7L() + { + iTest->Printf(_L("\tOpening thread one's database\n")); + CContactDatabase* threadOneDb = iContactsTest->Db()->OpenL(KTestDatabaseFile); + CleanupStack::PushL(threadOneDb); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*threadOneDb, this); + CleanupStack::PushL(changeNotifier); + + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + + + WaitForContactsEvent(EContactDbObserverEventGroupAdded); + TheTest(threadOneDb->GroupCount()==1); + + WaitForContactsEvent(EContactDbObserverEventGroupDeleted); + TheTest(threadOneDb->GroupCount()==0); + + CleanupStack::PopAndDestroy(2); // threadOneDb, changeNotifier + + // Signal thread 1 + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + +void CTestThreadTwo::DoTest8L() + { + iTest->Printf(_L("\tOpening thread one's database\n")); + CContactDatabase* threadOneDb = iContactsTest->Db()->OpenL(KTestDatabaseFile); + CleanupStack::PushL(threadOneDb); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*threadOneDb, this); + CleanupStack::PushL(changeNotifier); + + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + iTest->Printf(_L("\tThreadTwo : We expect a speed dial to have been added... ")); + TheTest(iLastEvent.iContactId == 4); + iTest->Printf(_L("correct.\n")); + + TBuf<32> phoneNumber; + TContactItemId id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KSpeedDialPhoneNumber); + TheTest(id == 4); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactChanged); + iTest->Printf(_L("\tThreadTwo : We expect a contact having speed dial to have been modified... ")); + TheTest(iLastEvent.iContactId == 4); + iTest->Printf(_L("correct.\n")); + + //changed both name & phone no. of contact with speed dial + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactChanged); + iTest->Printf(_L("\tThreadTwo : Both contact having speed dial have been modified ... ")); + TheTest(iLastEvent.iContactId == 4); + iTest->Printf(_L("correct.\n")); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactDeleted); + iTest->Printf(_L("\tThreadTwo : We expect the contact owning the speed dial to have been deleted... ")); + TheTest(iLastEvent.iContactId==id); // Speed dial has been deleted by CTestThreadOne::DoTest5L(), + //event returns ID on deletion + iTest->Printf(_L("\n\tSpeed dial contact has been deleted by CTestThreadOne::DoTest8L(),.\n")); + id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KNullDesC); + TheTest(id==-1); + iTest->Printf(_L("correct.\n")); + + // Pause this thread + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + + //case-4 + iTest->Printf(_L("\tThreadTwo : Waiting for change notification for case-4...\n")); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + TheTest(iLastEvent.iContactId==5); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + iTest->Printf(_L("\tThreadTwo : We expect a 2 contacts to have been added... ")); + TheTest(iLastEvent.iContactId==6); + iTest->Printf(_L("correct.\n")); + + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + TheTest(iLastEvent.iContactId==5); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + iTest->Printf(_L("\tThreadTwo : We expect a speed dial to have been set for both the contacts... ")); + TheTest(iLastEvent.iContactId==6); + iTest->Printf(_L("correct.\n")); + + //changed name & phone no. of both the contact with speed dial + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactChanged); + TheTest(iLastEvent.iContactId == 6); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactChanged); + iTest->Printf(_L("\tThreadTwo : Both contacts having speed dial have been modified ... ")); + TheTest(iLastEvent.iContactId == 5); + iTest->Printf(_L("correct.\n")); + + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactDeleted); + TheTest(iLastEvent.iContactId==5); // Speed dial has been deleted + iTest->Printf(_L("\tSpeed dial for contact-1 has been deleted by CTestThreadOne::DoTest8L(),.\n")); + id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionOne, phoneNumber); + TheTest(phoneNumber==KNullDesC); + TheTest(id==-1); + iTest->Printf(_L("correct.\n")); + + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactDeleted); + id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionTwo, phoneNumber); + TheTest(iLastEvent.iContactId==6); // Speed dial has been deleted + iTest->Printf(_L("\tSpeed dial for contact-2 has been deleted by CTestThreadOne::DoTest8L(),.\n")); + id = threadOneDb->GetSpeedDialFieldL(KSpeedDialPositionTwo, phoneNumber); + TheTest(phoneNumber==KNullDesC); + TheTest(id==-1); + iTest->Printf(_L("correct.\n")); + iTest->Printf(_L("\tThreadTwo : We expect the contact owning the speed dial to have been deleted... ")); + + iTest->Printf(_L("\tThreadTwo : Waiting for change notification...\n")); + WaitForContactsEvent(EContactDbObserverEventContactAdded); + WaitForContactsEvent(EContactDbObserverEventSpeedDialsChanged); + WaitForContactsEvent(EContactDbObserverEventContactChanged); + WaitForContactsEvent(EContactDbObserverEventContactDeleted); + iTest->Printf(_L("\tThreadTwo : We expect a speed dial to have been added and removed... ")); + TheTest(iLastEvent.iContactId == 7); + iTest->Printf(_L("correct.\n")); + + CleanupStack::PopAndDestroy(); // changeNotifier, + CleanupStack::PopAndDestroy(); // threadOneDb + + // Signal thread 1 + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + } + + +/* +Teststep to test fix for INC116664 +1)Open database and wait for notifications +Result: Notifications for contact and template addition along with template deletion should be recieved. +*/ +void CTestThreadTwo::DoTest9L() + { + iTest->Printf(_L("\tOpening thread one's database\n")); + CContactDatabase* threadOneDb = iContactsTest->Db()->OpenL(KTestDatabaseFile); + CleanupStack::PushL(threadOneDb); + + // This will wait notification + CContactChangeNotifier* changeNotifier = CContactChangeNotifier::NewL(*threadOneDb, this); + CleanupStack::PushL(changeNotifier); + iSemaphoreOne.Signal(); // indicate we've got the same database open + iSemaphoreTwo.Wait(); + + WaitForContactsEvent(EContactDbObserverEventContactAdded); + + WaitForContactsEvent(EContactDbObserverEventContactAdded); + + WaitForContactsEvent(EContactDbObserverEventContactAdded); + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + + WaitForContactsEvent(EContactDbObserverEventTemplateAdded); + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + + WaitForContactsEvent(EContactDbObserverEventTemplateAdded); + iSemaphoreOne.Signal(); + iSemaphoreTwo.Wait(); + + WaitForContactsEvent(EContactDbObserverEventTemplateDeleted); + iSemaphoreOne.Signal(); + + CleanupStack::PopAndDestroy(2); // threadOneDb, changeNotifier + } + +// +// -------> CTestManager (source) +// +CTestManager::CTestManager(TInt aPriority) +: CTimer(aPriority) + { + CActiveScheduler::Add(this); + } + +CTestManager::~CTestManager() + { + Cancel(); + delete iClient1; + delete iClient2; + } + +void CTestManager::ConstructL() + { + CTimer::ConstructL(); + + iClient2 = CTestThreadTwo::NewL(2, _L("Client-2"), *this, EPriorityLess); // lower + iClient1 = CTestThreadOne::NewL(1, _L("Client-1"), *this, EPriorityMore); + + IssueTimerRequest(); + CActiveScheduler::Start(); + } + +CTestManager* CTestManager::NewL() + { + CTestManager* self = NewLC(); + CleanupStack::Pop(); // self + return self; + } + +CTestManager* CTestManager::NewLC() + { + CTestManager* self = new (ELeave) CTestManager(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// +// +// + +void CTestManager::RunL() + { + if ( iClient1->IsActive() && iClient2->IsActive() + && iClient1->CurrentTest() == iClient2->CurrentTest() + && !(iClient1->Waiting() || iClient2->Waiting()) + ) + // We can only complete a request if the active objects are ready. This is + // determined using IsActive() + { + if (iTestNumber >= CTestBase::EEndTests) + // Have we run all the tests? + { + TRequestStatus thread1, thread2; + + // Log on to the threads so that we'll be notified when they die + // Must do this before telling threads to end! + iClient1->Thread().Logon(thread1); + iClient2->Thread().Logon(thread2); + + iClient1->Complete(CTestBase::EEndTests); + iClient2->Complete(CTestBase::EEndTests); + + // Wait for them both to die... + User::WaitForRequest(thread2); + User::WaitForRequest(thread1); + + CActiveScheduler::Stop(); + return; // prevent from starting timer again + } + + _LIT(KNextTestFormatTitle, "Test %d"); + TBuf<20> testBuf; + testBuf.Format(KNextTestFormatTitle, iTestNumber); + + TheTest.Next(_L(" ")); + + iClient1->Complete(iTestNumber); + iClient2->Complete(iTestNumber); + + // We've just requested a test be completed, so we have to increment this + // so that it's ready for the next test... + iTestNumber++; + } + + // Re-issue the asynchronous request to the CTimer + IssueTimerRequest(); + } + +// +// +// + +void CTestManager::IssueTimerRequest() + { + const TInt KOneSecond = 1000000; + After(KOneSecond); + } + + +// +// -------> Static global functions (source) +// +static void doMainL() + { + CTestActiveScheduler* scheduler = new (ELeave) CTestActiveScheduler; + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + RPIMTestServer serv; + User::LeaveIfError(serv.Connect()); + CleanupClosePushL(serv); + + RFs fsSession; + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + + CTestRegister* TempFiles = CTestRegister::NewLC(); + TempFiles->RegisterL(KTestDatabaseFile2, EFileTypeCnt); + + // Create two contacts databases - ignore return value + CContactDatabase* db1 = CContactDatabase::ReplaceL(KTestDatabaseFile); + delete db1; + CContactDatabase* db2 = CContactDatabase::ReplaceL(KTestDatabaseFile2); + delete db2; + + // Secure Server waits 5s from last connection + // to write the .ini file and close + User::After(6000000); + + // Delete any existing ini file so that we can be sure this test is ok + serv.DeleteFileL(KContactsModelIniFile); + serv.Close(); + + CTestManager::NewLC(); + CleanupStack::PopAndDestroy(5, scheduler); // tester, TempFiles, fsSession + } + + +/** + +@SYMTestCaseID PIM-T-CURRENTDB-0001 + +*/ + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + TheTest.Start(_L("@SYMTESTCaseID:PIM-T-CURRENTDB-0001 Multi session testcode")); + + TheTest.Title(); + TheCleanup = CTrapCleanup::New(); + TRAPD(ret, doMainL()); + TheTest(ret == KErrNone); + delete TheCleanup; + + TheTest.End(); + TheTest.Close(); + __UHEAP_MARKEND; + return(KErrNone); + }