// 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);
}