/*
* Copyright (c) 2005 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:
* ?description_line
*
*/
// INCLUDES
#include "FT_CPosTp127.h"
#include <Lbs.h>
#include <EPos_CPosLmDatabaseManager.h>
#include <EPos_CPosLandmarkParser.h>
#include <EPos_CPosLandmarkEncoder.h>
#include <EPos_CPosLandmark.h>
#include <EPos_CPosLmMultiDbSearch.h>
#include <EPos_CPosLmCatNameCriteria.h>
#include <EPos_CPosLmTextCriteria.h>
#include <EPos_CPosLmCategoryCriteria.h>
#include "FT_LandmarkConstants.h"
// CONSTANTS
const TInt KShortExecutionTimeInSeconds = 15;
const TInt KLongExecutionTimeInSeconds = 5 * 60; // Five minutes. The longer the more errors seem appear...
const TInt KNrOfDatabases = 5;
const TInt KLockedDbIndex = 2;
const TInt KMaxNrOfLms = 20;
const TInt KLockThreadStartupTime = 500000;
_LIT(KCreateThreadErr, "Creating thread failed with %d");
_LIT(KLockThreadSearchPattern, "*TP127_LockThread*");
_LIT(KTestDbUri, "TestDatabase.ldb");
_LIT(KTestDbUriUC, "TESTDATABASE.LDB");
// ================= LOCAL FUNCTIONS =======================
// ---------------------------------------------------------
// LOCAL_C ThreadFunction
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C TInt ThreadFunction(TAny* aData)
{
CTrapCleanup* cleanup = CTrapCleanup::New();
CActiveScheduler* actSch = new (ELeave) CActiveScheduler;
CActiveScheduler::Install(actSch);
TThreadParam* params = reinterpret_cast<TThreadParam*> (aData);
TRAPD(err, (*params->iTestFunction)(params->iMessage));
delete actSch;
delete cleanup;
return err;
}
// ---------------------------------------------------------
// LOCAL_C AssertTrueL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C void AssertTrueL(
TBool aCondition,
const TDesC& aBuf,
TDes* aMessage,
TInt aError = KErrGeneral)
{
if (!aCondition)
{
_LIT(KFormat, "%S, error = %d");
aMessage->Format(KFormat, &aBuf, aError);
aError == KErrNone ? User::Leave(KErrGeneral) : User::Leave(aError);
}
}
// ---------------------------------------------------------
// LOCAL_C ThreadExistsL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C TBool ThreadExistsL(const TDesC& aSearchPattern)
{
TFindThread threadSearcher;
threadSearcher.Find(aSearchPattern);
TFullName fullName;
return (threadSearcher.Next(fullName) == KErrNone);
}
// ---------------------------------------------------------
// LOCAL_C VerifyResultL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C void VerifyResultL(
TBool aLockThreadExists,
CPosLmMultiDbSearch* aMultiDbSearcher,
TDes* aDes)
{
TInt nrOfErrors = aMultiDbSearcher->NumOfSearchErrors();
if (aLockThreadExists)
{
// Reading locked db should result in KErrLocked
AssertTrueL(nrOfErrors == 1, _L("Not one error as expected"), aDes);
CPosLmMultiDbSearch::TSearchError error;
aMultiDbSearcher->GetSearchError(0, error);
AssertTrueL(error.iDatabaseIndex == KLockedDbIndex, _L("Error in wrong db"), aDes);
AssertTrueL(error.iErrorCode == KErrLocked, _L("Wrong error"), aDes, error.iErrorCode);
}
else
{
AssertTrueL(nrOfErrors == 0, _L("Search failed with errors"), aDes);
}
aDes->Zero();
}
// ================= CThreadMonitor MEMBER FUNCTIONS =======================
// Constructor
CThreadMonitor::CThreadMonitor(RThread* aThread)
: CActive(CActive::EPriorityStandard), iThread(aThread)
{
CActiveScheduler::Add(this);
}
// Destructor
CThreadMonitor::~CThreadMonitor()
{
Cancel();
}
// ---------------------------------------------------------
// CThreadMonitor::NewL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
CThreadMonitor* CThreadMonitor::NewL(RThread* aThread)
{
CThreadMonitor* self = new (ELeave) CThreadMonitor(aThread);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
// ---------------------------------------------------------
// CThreadMonitor::ConstructL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CThreadMonitor::ConstructL()
{
iThread->Resume();
iThread->Logon(iStatus);
SetActive();
}
// ---------------------------------------------------------
// CThreadMonitor::DoCancel
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CThreadMonitor::DoCancel()
{
iThread->LogonCancel(iStatus);
// Kill thread
TRequestStatus status;
iThread->Logon(status);
iThread->Kill(KErrCancel);
User::WaitForRequest(status);
}
// ---------------------------------------------------------
// CThreadMonitor::RunL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CThreadMonitor::RunL()
{
CActiveScheduler::Stop();
}
// ================= CPosTp127 MEMBER FUNCTIONS =======================
// ---------------------------------------------------------
// CPosTp127::GetName
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::GetName(TDes& aName) const
{
_LIT(KTestName, "TP127 - Multiple databases, multiple clients");
aName = KTestName;
}
// ---------------------------------------------------------
// CPosTp127::InitTestL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::InitTestL()
{
MakeSurePanicDebugFileExistsL();
// PrepareDatabases
RemoveAllLmDatabasesL();
CopyTestDbFileL(KDb20);
CopyTestDbFileL(KDb40);
CopyTestDbFileL(KDb60);
CopyTestDbFileL(KDb80);
CopyTestDbFileL(KDb105);
// Initialize databases - is this really needed?
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
for (TInt i = 0; i < KNrOfDatabases; i++)
{
CPosLandmarkDatabase* db = CPosLandmarkDatabase::OpenL(dbList->operator[](i));
CleanupStack::PushL(db);
ExecuteAndDeleteLD(db->InitializeL());
CleanupStack::PopAndDestroy(db);
}
// Remove the last 5 lms of the the last db
CPosLandmarkDatabase* db = CPosLandmarkDatabase::OpenL(KDb105);
CleanupStack::PushL(db);
CPosLmItemIterator* iter = db->LandmarkIteratorL();
CleanupStack::PushL(iter);
RIdArray idArray;
CleanupClosePushL(idArray);
iter->GetItemIdsL(idArray, 20, iter->NumOfItemsL() - 20);
ExecuteAndDeleteLD(db->RemoveLandmarksL(idArray));
CleanupStack::PopAndDestroy(3, db);
CleanupStack::PopAndDestroy(2, dbMan);
}
// ---------------------------------------------------------
// CPosTp127::CloseTest
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::CloseTest()
{
}
// ---------------------------------------------------------
// CPosTp127::StartL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::StartL()
{
// 1. Create multiple db search threads
iLog->Put(_L("<<<< 1. Create multiple db search threads >>>>"));
TBool lockDb = ETrue;
TBool successful = MultipleDbSearchClientsL(!lockDb);
//TBool successful = MultipleDbSearchClientsL(lockDb);
// Sometimes error ESLI-69LDJD DBMS - Error occurs
// 2. One of the databases is locked
iLog->Put(_L("<<<< 2. One of the databases is locked >>>>"));
User::After(KLockThreadStartupTime); // Let previous thread instances really die
if (!MultipleDbSearchClientsL(lockDb))
{
successful = EFalse;
}
// 3. Copy database in use
iLog->Put(_L("<<<< 3. Copy database in use >>>>"));
if (!VerifyInUseWhenCopyL())
{
successful = EFalse;
}
// 4. Copy databases continuously in parallel
iLog->Put(_L("<<<< 4. Copy databases continuously in parallel >>>>"));
if (!VerifyCopyStressL())
{
successful = EFalse;
}
// 5. Use all LM APIs
iLog->Put(_L("<<<< 5. Use all LM APIs simultaneously >>>>"));
if (!MultipleLmClientsL())
{
successful = EFalse;
}
// Leave if error
if (!successful)
{
User::Leave(KErrGeneral);
}
}
// ---------------------------------------------------------
// CPosTp127::MultipleDbSearchClientsL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp127::MultipleDbSearchClientsL(TBool aLockDb)
{
RThread searchThread1, searchThread2, searchThread3, lockThread;
TThreadParam params1, params2, params3, params4;
TBuf<200> threadMsg1, threadMsg2, threadMsg3, threadMsg4;
RArray<TThreadParam> threadArray;
CleanupClosePushL(threadArray);
// Create search thread 1
_LIT(KSearchThread1, "TP127 - Search thread 1");
TInt err = searchThread1.Create(KSearchThread1, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms1);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(searchThread1);
params1.iMessage = &threadMsg1;
params1.iTestFunction = MultipleDbCategorySearchL;
params1.iThread = &searchThread1;
threadArray.AppendL(params1);
// Create search thread 2
_LIT(KSearchThread2, "TP127 - Search thread 2");
err = searchThread2.Create(KSearchThread2, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms2);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(searchThread2);
params2.iMessage = &threadMsg2;
params2.iTestFunction = MultipleDbLandmarkSearchL;
params2.iThread = &searchThread2;
threadArray.AppendL(params2);
// Create search thread 3
_LIT(KSearchThread3, "TP127 - Search thread 3");
err = searchThread3.Create(KSearchThread3, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms3);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(searchThread3);
params3.iMessage = &threadMsg3;
params3.iTestFunction = MultipleDbLandmarkWithoutCategorySearchL;
params3.iThread = &searchThread3;
threadArray.AppendL(params3);
if (aLockDb)
{
// Create db lock thread
_LIT(KLockThread, "TP127 - TP127_LockThread");
err = lockThread.Create(KLockThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms4);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(lockThread);
params4.iMessage = &threadMsg4;
params4.iTestFunction = LockDatabaseL;
params4.iThread = &lockThread;
threadArray.AppendL(params4);
}
TBool successful = ResumeThreadsAndVerifyExitL(threadArray);
if (aLockDb)
{
CleanupStack::PopAndDestroy(&lockThread);
}
CleanupStack::PopAndDestroy(4, &threadArray);
return successful;
}
// ---------------------------------------------------------
// CPosTp127::MultipleLmClientsL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp127::MultipleLmClientsL()
{
// Set default db
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
HPosLmDatabaseInfo* dbInfo = HPosLmDatabaseInfo::NewLC(KTestDbUri);
dbMan->CreateDatabaseL(*dbInfo);
CleanupStack::PopAndDestroy(dbInfo);
dbMan->SetDefaultDatabaseUriL(KTestDbUri);
CleanupStack::PopAndDestroy(dbMan);
RThread dbManThread, multiSearchThread, dbThread, singleSearchThread;
TThreadParam params1, params2, params3, params4;
TBuf<200> threadMsg1, threadMsg2, threadMsg3, threadMsg4;
RArray<TThreadParam> threadArray;
CleanupClosePushL(threadArray);
// Create db management thread
_LIT(KDbManThread, "TP127 - Db manager thread");
TInt err = dbManThread.Create(KDbManThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms1);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(dbManThread);
params1.iMessage = &threadMsg1;
params1.iTestFunction = DbManagementL;
params1.iThread = &dbManThread;
threadArray.AppendL(params1);
// Create multi db search thread
_LIT(KMultiSearchThread, "TP127 - Multi search thread");
err = multiSearchThread.Create(KMultiSearchThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms2);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(multiSearchThread);
params2.iMessage = &threadMsg2;
params2.iTestFunction = MultipleDbSearchL;
params2.iThread = &multiSearchThread;
threadArray.AppendL(params2);
// Create LM API thread
_LIT(KDbThread, "TP127 - db thread");
err = dbThread.Create(KDbThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms3);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(dbThread);
params3.iMessage = &threadMsg3;
params3.iTestFunction = DbAccessL;
params3.iThread = &dbThread;
threadArray.AppendL(params3);
// Create single db search thread
_LIT(KSingleSearchThread, "TP127 - Single search thread");
err = singleSearchThread.Create(KSingleSearchThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms4);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(singleSearchThread);
params4.iMessage = &threadMsg4;
params4.iTestFunction = SingleDbSearchL;
params4.iThread = &singleSearchThread;
threadArray.AppendL(params4);
TBool successful = ResumeThreadsAndVerifyExitL(threadArray);
CleanupStack::PopAndDestroy(5, &threadArray);
return successful;
}
// ---------------------------------------------------------
// CPosTp127::VerifyInUseWhenCopyL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp127::VerifyInUseWhenCopyL()
{
RThread copyThread, lockThread;
TThreadParam params1, params2;
TBuf<200> threadMsg1, threadMsg2;
RArray<TThreadParam> threadArray;
CleanupClosePushL(threadArray);
// Create copy thread
_LIT(KCopyThread, "TP127 - Copy thread");
TInt err = copyThread.Create(KCopyThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms1);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread);
params1.iMessage = &threadMsg1;
params1.iTestFunction = CopyLockedDatabaseL;
params1.iThread = ©Thread;
threadArray.AppendL(params1);
// Create db lock thread
_LIT(KLockThread, "TP127 - TP127_LockThread");
err = KErrAlreadyExists;
while (err == KErrAlreadyExists)
{
err = lockThread.Create(KLockThread, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms2);
}
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(lockThread);
params2.iMessage = &threadMsg2;
params2.iTestFunction = LockDatabaseL;
params2.iThread = &lockThread;
threadArray.AppendL(params2);
TBool successful = ResumeThreadsAndVerifyExitL(threadArray);
CleanupStack::PopAndDestroy(3, &threadArray);
return successful;
}
// ---------------------------------------------------------
// CPosTp127::VerifyCopyStressL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp127::VerifyCopyStressL()
{
RThread copyThread1, copyThread2, copyThread3, copyThread4, copyThread5;
TThreadParam params1, params2, params3, params4, params5;
TBuf<200> threadMsg1, threadMsg2, threadMsg3, threadMsg4, threadMsg5;
RArray<TThreadParam> threadArray;
CleanupClosePushL(threadArray);
// Create copy thread1
_LIT(KCopyThread1, "TP127 - Copy thread1");
TInt err = copyThread1.Create(KCopyThread1, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms1);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread1);
params1.iMessage = &threadMsg1;
params1.iTestFunction = CopyDatabaseL;
params1.iThread = ©Thread1;
threadArray.AppendL(params1);
// Create copy thread2
_LIT(KCopyThread2, "TP127 - Copy thread2");
err = copyThread2.Create(KCopyThread2, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms2);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread2);
params2.iMessage = &threadMsg2;
params2.iTestFunction = CopyDatabaseL;
params2.iThread = ©Thread2;
threadArray.AppendL(params2);
// Create copy thread3
_LIT(KCopyThread3, "TP127 - Copy thread3");
err = copyThread3.Create(KCopyThread3, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms3);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread3);
params3.iMessage = &threadMsg3;
params3.iTestFunction = CopyDatabaseL;
params3.iThread = ©Thread3;
threadArray.AppendL(params3);
// Create copy thread4
_LIT(KCopyThread4, "TP127 - Copy thread4");
err = copyThread4.Create(KCopyThread4, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms4);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread4);
params4.iMessage = &threadMsg4;
params4.iTestFunction = CopyDatabaseL;
params4.iThread = ©Thread4;
threadArray.AppendL(params4);
// Create copy thread5
_LIT(KCopyThread5, "TP127 - Copy thread5");
err = copyThread5.Create(KCopyThread5, ThreadFunction,
KDefaultStackSize, KMinHeapSize, KMaxHeapSize, ¶ms5);
AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);
CleanupClosePushL(copyThread5);
params5.iMessage = &threadMsg5;
params5.iTestFunction = CopyDatabaseL;
params5.iThread = ©Thread5;
threadArray.AppendL(params5);
TBool successful = ResumeThreadsAndVerifyExitL(threadArray);
CleanupStack::PopAndDestroy(6, &threadArray);
return successful;
}
// ---------------------------------------------------------
// CPosTp127::ResumeThreadsAndVerifyExitL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp127::ResumeThreadsAndVerifyExitL(const RArray<TThreadParam>& aThreadParams)
{
// Start threads.
RPointerArray<CThreadMonitor> threadMonitors;
CleanupClosePushL(threadMonitors);
TInt nrOfThreads = aThreadParams.Count();
for (TInt j = 0; j < nrOfThreads; j++)
{
threadMonitors.AppendL(CThreadMonitor::NewL(aThreadParams[j].iThread));
}
// <<<< Commented code below can be enabled for immediate interruption when any thread fails >>>>
// Wait until any of the threads exits.
TInt error = KErrNone;
TBool allThreadsTerminated = EFalse;
while (!allThreadsTerminated
/* && error == KErrNone*/)
{
CActiveScheduler::Start();
// Assume all threads are terminated
allThreadsTerminated = ETrue;
for (TInt i = 0; i < nrOfThreads
/* && error == KErrNone*/; i++)
{
if (threadMonitors[i]->IsActive())
{
// Thread is still alive
allThreadsTerminated = EFalse;
}
else
{
/* if (aThreadParams[i].iThread->ExitType() != EExitKill)
{
error = KErrGeneral;
}
else if (aThreadParams[i].iThread->ExitReason())
{
error = aThreadParams[i].iThread->ExitReason();
}
*/ }
}
}
// <<<< Commented code above can be enabled for immediate interruption when any thread fails >>>>
// Terminate all remaining threads (in case of errors)
threadMonitors.ResetAndDestroy();
CleanupStack::PopAndDestroy(&threadMonitors);
// Log summary
for (TInt i = 0; i < nrOfThreads; i++)
{
if (*aThreadParams[i].iMessage != KNullDesC)
{
iLog->Put(*aThreadParams[i].iMessage);
}
TName threadName = aThreadParams[i].iThread->Name();
if (aThreadParams[i].iThread->ExitType() != EExitKill)
{
iBuf.Format(_L("%S was not killed!"), &threadName);
iLog->PutError(iBuf);
TExitCategoryName category = aThreadParams[i].iThread->ExitCategory();
iBuf.Format(_L("Exit Category = %S %d"), &category, aThreadParams[i].iThread->ExitReason());
iLog->Put(iBuf);
error = KErrGeneral;
}
else
{
TInt exitReason = aThreadParams[i].iThread->ExitReason();
if (exitReason != 0)
{
iBuf.Format(_L("%S's exit reason wasn't 0 but %d."), &threadName, exitReason);
iLog->PutError(iBuf);
error = exitReason;
}
}
}
return (error == KErrNone);
}
// ================= STATIC THREAD FUNCTIONS =======================
// ---------------------------------------------------------
// CPosTp127::MultipleDbCategorySearchL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::MultipleDbCategorySearchL(TDes* aMessage)
{
TBool lockThreadExists = ThreadExistsL(KLockThreadSearchPattern);
if (lockThreadExists)
{
// Let lock thread launch first
User::After(KLockThreadStartupTime);
}
// Search multiple databases for some seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
while (executionTime.Int() < KShortExecutionTimeInSeconds)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
AssertTrueL(dbList->Count() == KNrOfDatabases, _L("MultipleDbCategorySearchL: Wrong number of databases"), aMessage);
CPosLmMultiDbSearch* dbSearcher = CPosLmMultiDbSearch::NewL(*dbList);
CleanupStack::PushL(dbSearcher);
// Search for categories containing a specific string
CPosLmCatNameCriteria* criteria = CPosLmCatNameCriteria::NewLC();
criteria->SetSearchPatternL(_L("*Log*"));
CPosLmOperation* operation = dbSearcher->StartCategorySearchL(*criteria, CPosLmCategoryManager::ECategorySortOrderNone);
ExecuteAndDeleteLD(operation);
aMessage->Copy(_L("MultipleDbCategorySearchL: "));
VerifyResultL(lockThreadExists, dbSearcher, aMessage);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
CleanupStack::PopAndDestroy(4, dbMan);
}
}
// ---------------------------------------------------------
// CPosTp127::MultipleDbLandmarkSearchL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::MultipleDbLandmarkSearchL(TDes* aMessage)
{
TBool lockThreadExists = ThreadExistsL(KLockThreadSearchPattern);
if (lockThreadExists)
{
// Let lock thread launch first
User::After(KLockThreadStartupTime);
}
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
while (executionTime.Int() < KShortExecutionTimeInSeconds)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
CPosLmMultiDbSearch* dbSearcher = CPosLmMultiDbSearch::NewL(*dbList);
CleanupStack::PushL(dbSearcher);
// Search for landmarks containing a specific string
CPosLmTextCriteria* criteria = CPosLmTextCriteria::NewLC();
criteria->SetTextL(_L("*as*"));
CPosLmOperation* operation = dbSearcher->StartLandmarkSearchL(*criteria);
ExecuteAndDeleteLD(operation);
aMessage->Copy(_L("MultipleDbLandmarkSearchL: "));
VerifyResultL(lockThreadExists, dbSearcher, aMessage);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
CleanupStack::PopAndDestroy(4, dbMan);
}
}
// ---------------------------------------------------------
// CPosTp127::MultipleDbLandmarkWithoutCategorySearchL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::MultipleDbLandmarkWithoutCategorySearchL(TDes* aMessage)
{
TBool lockThreadExists = ThreadExistsL(KLockThreadSearchPattern);
if (lockThreadExists)
{
// Let lock thread launch first
User::After(KLockThreadStartupTime);
}
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
while (executionTime.Int() < KShortExecutionTimeInSeconds)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
AssertTrueL(dbList->Count() == KNrOfDatabases, _L("MultipleDbLandmarkWithoutCategorySearchL: Wrong number of databases"), aMessage);
CPosLmMultiDbSearch* dbSearcher = CPosLmMultiDbSearch::NewL(*dbList);
CleanupStack::PushL(dbSearcher);
// Search for uncategorized landmarks
CPosLmCategoryCriteria* criteria = CPosLmCategoryCriteria::NewLC();
CPosLmOperation* operation = dbSearcher->StartLandmarkSearchL(*criteria);
ExecuteAndDeleteLD(operation);
aMessage->Copy(_L("MultipleDbLandmarkWithoutCategorySearchL: "));
VerifyResultL(lockThreadExists, dbSearcher, aMessage);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
CleanupStack::PopAndDestroy(4, dbMan);
}
}
// ---------------------------------------------------------
// CPosTp127::LockDatabaseL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::LockDatabaseL(TDes* aMessage)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
AssertTrueL(dbList->Count() == KNrOfDatabases, _L("MultipleDbLandmarkWithoutCategorySearchL: Wrong number of databases"), aMessage);
CPosLandmarkDatabase* db = CPosLandmarkDatabase::OpenL((*dbList)[KLockedDbIndex]);
CleanupStack::PushL(db);
CPosLmOperation* operation = db->RemoveAllLandmarksL();
User::After((KShortExecutionTimeInSeconds + 1) * 1000000);
delete operation;
CleanupStack::PopAndDestroy(3, dbMan);
}
// ---------------------------------------------------------
// CPosTp127::DbManagementL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::DbManagementL(TDes* aMessage)
{
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
TInt i(0);
TBool errorsFound = EFalse;
while (executionTime.Int() < KLongExecutionTimeInSeconds)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
// List dbs
CDesCArray* dbList = dbMan->ListDatabasesLC();
// Create db
HPosLmDatabaseInfo* dbInfo = HPosLmDatabaseInfo::NewLC(KTestDbUri);
TRAPD(err, dbMan->CreateDatabaseL(*dbInfo));
CleanupStack::PopAndDestroy(dbInfo);
if (err != KErrAlreadyExists)
{
AssertTrueL(dbMan->DatabaseExistsL(KTestDbUri), _L("DbManagementL: Created database does not exist"), aMessage);
}
// Try to read default URI
HBufC* defaultDb = dbMan->DefaultDatabaseUriLC();
// Set default db to the created one
dbMan->SetDefaultDatabaseUriL(KTestDbUri);
// Remove default db
TRAP(err, dbMan->DeleteDatabaseL(KTestDbUri));
AssertTrueL(err == KErrNone || err == KErrInUse, _L("DbManagementL: Wrong error code when removing created database"), aMessage, err);
if (err == KErrNone)
{
AssertTrueL(!dbMan->DatabaseExistsL(KTestDbUri), _L("DbManagementL: Removed database exists"), aMessage);
}
// Create a copy of a db
if (dbList->Count() > 0)
{
TRAP(err, dbMan->CopyDatabaseL((*dbList)[0], KTestDbUri));
// TBD: How can err == KErrLocked happen? Refer to ESLI-68HKE6
// TBD: Sometimes KErrDied is returned from this function. Why? Write error report?
AssertTrueL(err == KErrNone || err == KErrAlreadyExists || err == KErrInUse || err == KErrLocked, _L("DbManagementL: Wrong error code when copying database"), aMessage, err);
if (err == KErrNone || err == KErrAlreadyExists)
{
AssertTrueL(dbMan->DatabaseExistsL(KTestDbUri), _L("DbManagementL: Copied database does not exist"), aMessage);
// Remove copy
TRAP(err, dbMan->DeleteDatabaseL(KTestDbUri));
AssertTrueL(err == KErrNone || err == KErrInUse, _L("DbManagementL: Wrong error code when removing copied database"), aMessage, err);
if (err == KErrNone)
{
AssertTrueL(!dbMan->DatabaseExistsL(KTestDbUri), _L("DbManagementL: Removed database exists"), aMessage);
}
}
else if (err == KErrLocked) // To be removed when ESLI-68HKE6 is solved
{
aMessage->Copy(_L("DbManagementL: CPosLmDatabaseManager::CopyDatabaseL() left with KErrLocked - check ESLI-68HKE6"));
errorsFound = ETrue;
}
}
// Set default db to another uri
dbMan->SetDefaultDatabaseUriL((*dbList)[i]);
if (++i == 5)
{
i = 0;
}
// Increase probability that (*dbList)[i] and not KTestDbUri is default db most of the time
User::After(10000);
CleanupStack::PopAndDestroy(3, dbMan);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
}
if (errorsFound)
{
User::Leave(KErrGeneral);
}
}
// ---------------------------------------------------------
// CPosTp127::DbAccessL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::DbAccessL(TDes* aMessage)
{
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
TBool errorsFound = EFalse;
while (executionTime.Int() < KLongExecutionTimeInSeconds)
{
CPosLandmarkDatabase* db = NULL;
TRAPD(err, db = CPosLandmarkDatabase::OpenL());
// TBD: How can KErrNotFound happen? Refer to ESLI-68HE4P
if (err == KErrLocked || err == KErrInUse || err == KErrNotFound)
{
if (err == KErrNotFound) // To be removed when ESLI-68HE4P is solved
{
aMessage->Copy(_L("DbAccessL: CPosLandmarkDatabase::OpenL() left with KErrNotFound - check ESLI-68HE4P"));
errorsFound = ETrue;
}
// Some client is writing(KErrLocked)/deleting(KErrInUse) the db. Try again.
continue;
}
AssertTrueL(err == KErrNone, _L("DbAccessL: Wrong error code when opening db"), aMessage, err);
CleanupStack::PushL(db);
// We don't want to use the empty test database
HBufC* dbUri = db->DatabaseUriLC();
// TBD: Both UC and original case need to be checked here due to SDK bug! To be updated. (refer to INC053631 in teamtrack and ESLI-68HK3W in TSW)
if (dbUri->Find(KTestDbUriUC) != KErrNotFound || dbUri->Find(KTestDbUri) != KErrNotFound)
{
if (dbUri->Find(KTestDbUriUC) != KErrNotFound) // To be removed when ESLI-68HK3W is solved
{
aMessage->Copy(_L("DbAccessL: UPPER CASE of db URI found - check ESLI-68HK3W"));
errorsFound = ETrue;
}
CleanupStack::PopAndDestroy(2, db);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
continue;
}
// Fetch db iterator
CPosLmItemIterator* iterator = NULL;
TRAP(err, iterator = db->LandmarkIteratorL());
// TBD: KErrPosLmNotInitialized should not be accepted. Refer to ESLI-68JAMD
if (err == KErrCorrupt || err == KErrPosLmNotInitialized)
{
if (err == KErrPosLmNotInitialized) // To be removed when ESLI-68JAMD is solved
{
aMessage->Copy(_L("DbAccessL: CPosLandmarkDatabase::LandmarkIteratorL() left with KErrPosLmNotInitialized - check ESLI-68JAMD"));
errorsFound = ETrue;
}
// TBD: Databases need to be re-initialized, because they haved been damaged. Why do they become damaged?
err = KErrLocked;
while (err == KErrLocked && db->IsInitializingNeeded())
{
TRAP(err, ExecuteAndDeleteLD(db->InitializeL()));
AssertTrueL(err == KErrNone || err == KErrLocked, _L("DbAccessL: Wrong error code when initializing"), aMessage, err);
}
TRAP(err, iterator = db->LandmarkIteratorL());
}
TBuf<100> buf;
_LIT(KFormat, "DbAccessL: Wrong error code when creating iterator for db %S");
buf.Format(KFormat, dbUri);
AssertTrueL(err == KErrNone, buf, aMessage, err);
CleanupStack::PopAndDestroy(dbUri);
CleanupStack::PushL(iterator);
// Add, read and update a landmark
CPosLandmark* lm = CPosLandmark::NewLC();
TPosLmItemId id = KPosLmNullItemId;
TRAP(err, id = db->AddLandmarkL(*lm));
CleanupStack::PopAndDestroy(lm);
if (err == KErrNone)
{
TRAP(err, CleanupStack::Pop(lm = db->ReadLandmarkLC(id)));
CleanupStack::PushL(lm);
AssertTrueL(err == KErrNone, _L("DbAccessL: Wrong error code when reading created landmark"), aMessage, err);
lm->SetLandmarkNameL(_L("A landmark"));
TRAP(err, db->UpdateLandmarkL(*lm));
AssertTrueL(err == KErrNone || err == KErrLocked, _L("DbAccessL: Wrong error code when updating lm"), aMessage, err);
CleanupStack::PopAndDestroy(lm);
}
else
{
AssertTrueL(err == KErrLocked, _L("DbAccessL: Wrong error code when adding lm"), aMessage, err);
}
// Remove possible added landmarks
TInt nrOfItems = iterator->NumOfItemsL();
if (nrOfItems > KMaxNrOfLms)
{
RIdArray idArray;
CleanupClosePushL(idArray);
iterator->GetItemIdsL(idArray, KMaxNrOfLms, nrOfItems - KMaxNrOfLms);
err = KErrLocked;
while (err != KErrNone)
{
TRAP(err, ExecuteAndDeleteLD(db->RemoveLandmarksL(idArray)));
AssertTrueL(err == KErrNone || err == KErrLocked, _L("DbAccessL: Wrong error code when removing lm"), aMessage, err);
}
CleanupStack::PopAndDestroy(&idArray);
}
CleanupStack::PopAndDestroy(2, db);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
}
if (errorsFound)
{
User::Leave(KErrGeneral);
}
}
// ---------------------------------------------------------
// CPosTp127::SingleDbSearchL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::SingleDbSearchL(TDes* aMessage)
{
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
TInt64 seed = startTime.Int64();
TBool errorsFound = EFalse;
while (executionTime.Int() < KLongExecutionTimeInSeconds)
{
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
// Open one of the pre-defined databases
TInt index = (TInt) (Math::FRand(seed) * dbList->Count());
TPtrC uri = (*dbList)[index];
// TBD: Both UC and original case need to be checked here due to SDK bug! To be updated. (refer to INC053631 in teamtrack and ESLI-68HK3W in TSW)
if (uri.Find(KTestDbUriUC) != KErrNotFound || uri.Find(KTestDbUri) != KErrNotFound)
{
if (uri.Find(KTestDbUriUC) != KErrNotFound) // To be removed when ESLI-68HK3W is solved
{
aMessage->Copy(_L("SingleDbSearchL: UPPER CASE of db URI found - check ESLI-68HK3W"));
errorsFound = ETrue;
}
// We don't want to search the empty test database
CleanupStack::PopAndDestroy(2, dbMan);
continue;
}
CPosLandmarkDatabase* db = NULL;
TRAPD(err, db = CPosLandmarkDatabase::OpenL(uri));
if (err == KErrLocked)
{
// Some client is writing to the db. Try again.
CleanupStack::PopAndDestroy(2, dbMan);
continue;
}
_LIT(KFormat, "SingleDbSearchL: Wrong error code when opening db %S");
TBuf<100> buf;
buf.Format(KFormat, &uri);
AssertTrueL(err == KErrNone, buf, aMessage, err);
CleanupStack::PushL(db);
CPosLandmarkSearch* dbSearcher = NULL;
TRAP(err, dbSearcher = CPosLandmarkSearch::NewL(*db));
AssertTrueL(err == KErrNone, _L("SingleDbSearchL: Wrong error code when calling CPosLandmarkSearch::NewL"), aMessage, err);
CleanupStack::PushL(dbSearcher);
// Search for landmarks containing a specific string
CPosLmTextCriteria* criteria = CPosLmTextCriteria::NewLC();
criteria->SetTextL(_L("*as*"));
CPosLmOperation* operation = NULL;
TRAP(err, operation = dbSearcher->StartLandmarkSearchL(*criteria));
AssertTrueL(err == KErrNone || err == KErrLocked, _L("SingleDbSearchL: Wrong error code when creating search op"), aMessage, err);
if (operation)
{
CleanupStack::PushL(operation);
TRAP(err, operation->ExecuteL());
AssertTrueL(err == KErrNone || err == KErrLocked, _L("SingleDbSearchL: Wrong error code when executing search op"), aMessage, err);
CleanupStack::PopAndDestroy(operation);
}
CleanupStack::PopAndDestroy(5, dbMan);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
}
if (errorsFound)
{
User::Leave(KErrGeneral);
}
}
// ---------------------------------------------------------
// CPosTp127::MultipleDbSearchL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::MultipleDbSearchL(TDes* aMessage)
{
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
/*
RArray<RIdArray> expectedResult; // contains expected matches when search patern is *e*
CleanupClosePushL(expectedResult);
RIdArray array1;
CleanupClosePushL(array1);
array1.AppendL(4); // vegetariskt
array1.AppendL(5); // Inte sa bra
array1.AppendL(8); // Medel
array1.AppendL(9); // Medel2
array1.AppendL(12); // GatesB
array1.AppendL(13); // Text"'1
array1.AppendL(14); // GatesF
array1.AppendL(15); // xStekt
array1.AppendL(18); // enat?r
array1.AppendL(19); // enator
expectedResult.AppendL(array1);
RIdArray array2;
CleanupClosePushL(array2);
for (TInt i = 29; i <= 40; i++)
{
array2.AppendL(i); // Unique - Text10
}
expectedResult.AppendL(array2);
RIdArray array3;
CleanupClosePushL(array3);
array3.AppendL(45); // Several
array3.AppendL(51); // PellesPizza
array3.AppendL(52); // Kalles Hundgård
for (TInt i = 54; i <= 60; i++)
{
array3.AppendL(i); // TE, Gårda - TE, Oulu
}
expectedResult.AppendL(array3);
RIdArray array4;
CleanupClosePushL(array4);
array4.AppendL(61); // TE, Tampere
array4.AppendL(62); // Nokia, Köpenhamn
array4.AppendL(65); // Tampere
array4.AppendL(66); // Helsinki
array4.AppendL(67); // Bengtfors
array4.AppendL(70); // Göteborg
array4.AppendL(71); // PallesPalör
array4.AppendL(72); // Läkare utan gränser
array4.AppendL(74); // Läkargruppen
array4.AppendL(75); // Läkarhuset
array4.AppendL(76); // Sahlgrenska
array4.AppendL(77); // östra sjukhuset
array4.AppendL(80); // GöteborgsTaxi
expectedResult.AppendL(array4);
RIdArray array5;
CleanupClosePushL(array5);
array5.AppendL(81); // LandvetterTaxi
array5.AppendL(84); // Länsmuseumet
array5.AppendL(85); // Sjöfartsmuseumet
array5.AppendL(86); // KinaMuseumet
array5.AppendL(88); // Etnogfrafiska
array5.AppendL(89); // TekniskaMuseumet
array5.AppendL(91); // Centrum dagiset
array5.AppendL(93); // Lackarbäcks daghem
for (TInt i = 95; i <= 100; i++)
{
array5.AppendL(i); // TE dagis - krokslätts frisörerna
}
expectedResult.AppendL(array5);
*/
RArray<TInt> nrOfExpectedMatches; // contains the number of matches for each db when search pattern is *e*
CleanupClosePushL(nrOfExpectedMatches);
nrOfExpectedMatches.AppendL(10);
nrOfExpectedMatches.AppendL(12);
nrOfExpectedMatches.AppendL(10);
nrOfExpectedMatches.AppendL(13);
nrOfExpectedMatches.AppendL(14);
while (executionTime.Int() < KLongExecutionTimeInSeconds)
{
CDesCArray* dbList = new (ELeave) CDesCArrayFlat(5);
CleanupStack::PushL(dbList);
dbList->AppendL(KDb20);
dbList->AppendL(KDb40);
dbList->AppendL(KDb60);
dbList->AppendL(KDb80);
dbList->AppendL(KDb105);
CPosLmMultiDbSearch* dbSearcher = CPosLmMultiDbSearch::NewL(*dbList);
CleanupStack::PushL(dbSearcher);
// Search for landmarks containing a specific string in name
CPosLmTextCriteria* criteria = CPosLmTextCriteria::NewLC();
criteria->SetTextL(_L("*e*"));
criteria->SetAttributesToSearch(CPosLandmark::ELandmarkName);
CPosLmOperation* operation = NULL;
TRAPD(err, operation = dbSearcher->StartLandmarkSearchL(*criteria))
AssertTrueL(err == KErrNone || err == KErrLocked, _L("MultipleDbSearchL: Wrong error code when creating search op"), aMessage, err);
if (operation)
{
CleanupStack::PushL(operation);
TRAP(err, operation->ExecuteL());
AssertTrueL(err == KErrNone || err == KErrLocked, _L("MultipleDbSearchL: Wrong error code when executing search op"), aMessage, err);
CleanupStack::PopAndDestroy(operation);
}
// Check errors
RArray<TInt> dbsWithErrors;
CleanupClosePushL(dbsWithErrors);
TUint nrOfSearchErrors = dbSearcher->NumOfSearchErrors();
for (TUint i = 0; i < nrOfSearchErrors; i++)
{
CPosLmMultiDbSearch::TSearchError error;
dbSearcher->GetSearchError(i, error);
AssertTrueL(error.iErrorCode == KErrLocked, _L("MultipleDbSearchL: Wrong error code when searching"), aMessage, error.iErrorCode);
dbsWithErrors.AppendL(error.iDatabaseIndex);
}
// Check number of matches
for (TInt i = 0; i < dbList->Count(); i++)
{
if (dbsWithErrors.Find(i) == KErrNotFound)
{
TInt nrOfMatches = dbSearcher->NumOfMatches(i);
TInt expectedResult = nrOfExpectedMatches[i];
AssertTrueL(nrOfMatches == expectedResult, _L("MultipleDbSearchL: Wrong number of matches"), aMessage);
}
}
CleanupStack::PopAndDestroy(4, dbList);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
}
CleanupStack::PopAndDestroy(&nrOfExpectedMatches);
}
// ---------------------------------------------------------
// CPosTp127::CopyLockedDatabaseL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::CopyLockedDatabaseL(TDes* aMessage)
{
TBool lockThreadExists = ThreadExistsL(KLockThreadSearchPattern);
if (lockThreadExists)
{
// Let lock thread launch first
User::After(KLockThreadStartupTime);
}
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
CDesCArray* dbList = dbMan->ListDatabasesLC();
AssertTrueL(dbList->Count() == KNrOfDatabases, _L("CopyLockedDatabaseL: Wrong number of databases"), aMessage);
// Try to copy database. Should result in KErrInUse
TRAPD(err, dbMan->CopyDatabaseL((*dbList)[KLockedDbIndex], KTestDbUri));
// TBD: KErrLocked should not be accepted. Refer to ESLI-68HKE6
AssertTrueL(err != KErrLocked, _L("CopyLockedDatabaseL: Wrong error code when copying database - check ESLI-68HKE6"), aMessage, err);
AssertTrueL(err == KErrInUse , _L("CopyLockedDatabaseL: Wrong error code when copying database"), aMessage, err);
CleanupStack::PopAndDestroy(2, dbMan);
}
// ---------------------------------------------------------
// CPosTp127::CopyDatabaseL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp127::CopyDatabaseL(TDes* aMessage)
{
// Execute thread for a number of seconds
TTime startTime, stopTime;
startTime.HomeTime();
stopTime.HomeTime();
TTimeIntervalSeconds executionTime;
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
TInt64 seed = startTime.Int64();
TBool errorsFound = EFalse;
CPosLmDatabaseManager* dbMan = CPosLmDatabaseManager::NewL();
CleanupStack::PushL(dbMan);
while (executionTime.Int() < KShortExecutionTimeInSeconds)
{
CDesCArray* dbList = dbMan->ListDatabasesLC();
// Create a source and a target URI
_LIT(KCopy, "_copy");
TInt copyLength = KCopy().Length();
TInt index = (TInt) (Math::FRand(seed) * dbList->Count());
TPtrC sourceUri = (*dbList)[index];
HBufC* targetUriBuffer = HBufC::NewLC(sourceUri.Length() + copyLength);
TPtr targetUri = targetUriBuffer->Des();
targetUri.Copy(sourceUri);
targetUri.Insert(targetUri.Length() - 4, KCopy); // 4 == length of ".ldb"
// Try to copy database. Should result in KErrInUse if locked, KErrNone otherwise
TRAPD(err, dbMan->CopyDatabaseL(sourceUri, targetUri));
AssertTrueL(err == KErrNone || err == KErrAlreadyExists, _L("CopyDatabaseL: Wrong error code when copying database"), aMessage, err);
// Set default database to the created one
TRAP(err, dbMan->SetDefaultDatabaseUriL(targetUri));
AssertTrueL(err == KErrNone || err == KErrNotFound, _L("CopyDatabaseL: Wrong error code when setting default db to target"), aMessage, err);
// Remove the created database
err = KErrLocked;
while (err != KErrNone && err != KErrNotFound)
{
TRAP(err, dbMan->DeleteDatabaseL(targetUri));
}
// Set default database to the source
TRAP(err, dbMan->SetDefaultDatabaseUriL(sourceUri));
AssertTrueL(err == KErrNone, _L("CopyDatabaseL: Wrong error code when setting default db to source"), aMessage, err);
CleanupStack::PopAndDestroy(2, dbList);
stopTime.HomeTime();
User::LeaveIfError(stopTime.SecondsFrom(startTime, executionTime));
}
if (errorsFound)
{
User::Leave(KErrGeneral);
}
CleanupStack::PopAndDestroy(dbMan);
}
// End of File