--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/t_currentdb.cpp Fri Jun 11 13:29:23 2010 +0300
@@ -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 <e32std.h>
+#include <e32twin.h>
+#include <e32test.h>
+#include <cntdbobs.h>
+#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);
+ }