// Copyright (c) 2004-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 <e32std.h>
#include <e32test.h>
#include <cntdb.h>
#include "T_Sec_AsyncOpen.h"
#include <coreappstest/testserver.h>
//
// Constants.
//
_LIT(KTestName,"T_Sec_AsyncOpen");
_LIT(KDbFileName,"c:T_Sec_AsyncOpen.cdb");
#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
//That file is a contact model database from a Calypso device
_LIT(KDatabaseV4, "Z:\\Core-Apps\\App-Engines\\CntModel\\Databases\\FormatV4.cdb");
_LIT(KDbOldVersionFilePath,"C:\\private\\10003A73\\OLDVERSION.CDB");
#else
//Just use a SQlite file - this still tests async and sync openings of the file
_LIT(KDatabaseV4, "Z:\\Core-Apps\\App-Engines\\CntModel\\Databases\\SQLite__Contacts.cdb");
_LIT(KDbOldVersionFilePath,"C:\\private\\10003A73\\SQLite__OLDVERSION.CDB");
#endif //__SYMBIAN_CNTMODEL_USE_SQLITE__
_LIT(KDbOldVersionFileName,"C:OldVersion.cdb");
_LIT(KDbDamaged,"c:Damaged.cdb");
_LIT(KDefaultDb,"c:Contacts.cdb");
_LIT(KDbFileNameNotExist,"c:NotHere.cdb");
_LIT(KThreadOpenAsync,"OpenAsync");
_LIT(KThreadOpenSync,"OpenSync");
const TInt KNumWaitLoops = 3;
LOCAL_D RTest test(KTestName);
//
// CTestConductor.
//
CTestConductor* CTestConductor::NewL()
{
CTestConductor* self = new(ELeave) CTestConductor();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CTestConductor::~CTestConductor()
{
//state deleted during tests
}
CTestConductor::CTestConductor() : CActive(EPriorityStandard),iCurrentTestNumber(-1),iWaitCounter(0)
{
CActiveScheduler::Add(this);
}
void CTestConductor::ConstructL()
{
// Create the db files used in the tests
iDb = CContactDatabase::ReplaceL(KDbDamaged);
CleanupStack::PushL(iDb);
iDb->DamageDatabaseL(0x666);
CleanupStack::PopAndDestroy(iDb);
iDb = CContactDatabase::ReplaceL(KDbFileName);
delete iDb;
iDb = CContactDatabase::ReplaceL(KDefaultDb);
delete iDb;
CopyCdbFileL(KDatabaseV4,KDbOldVersionFilePath);
iDb = NULL;
iTestError = KErrNone;
NextTest();
CActiveScheduler::Start();
User::LeaveIfError(iTestError);
}
void CTestConductor::NextTest()
{
++iCurrentTestNumber;
TRequestStatus *pS = &iStatus;
User::RequestComplete(pS,KErrNone);
SetActive();
}
void CTestConductor::RunL()
{
User::After(1000);
switch (iCurrentTestNumber)
{
// Test One - Async Open of a Named Database
case EAsyncOpenNamed:
test.Next(_L("=== Async Open of Named Db"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbFileName,iStatus);
++iCurrentTestNumber;
break;
// Check Test One Results
case EAsyncOpenedNamed:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened Async\n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// Test Two - Async Open of the Default Database
case EAsyncOpenDefault:
test.Next(_L("=== Async Open Default"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(iStatus);
++iCurrentTestNumber;
break;
// Check Test Two Results
case EAsyncOpenedDefault:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened Async Default \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// Test Three - Attempted Async Open of a Non-Existent File
case EAsyncOpenNonExistent:
test.Next(_L("=== Attempted Open of Non-Existent File"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbFileNameNotExist,iStatus);
++iCurrentTestNumber;
break;
// Check Test Three Results
case EAsyncOpenedNonExistent:
test.Printf(_L("=== Opened Non Existent Response\n"));
test(iStatus.Int() == KErrNotFound);
delete iContactOpenOperation;
NextTest();
break;
// Test Four - Cancel the Async Open
case EAsyncCancelOpenDefault:
test.Next(_L("=== Cancel Async Open"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(iStatus);
++iCurrentTestNumber;
// Cancel the request
delete iContactOpenOperation;
break;
// Check Test Four Results
case EAsyncCanceledOpenedDefault:
test.Printf(_L("=== Cancelled Async Open\n"));
test(iStatus.Int() == KErrCancel);
NextTest();
break;
// Test Five - Async Open of a damaged Database
case EAsyncOpenDamaged:
test.Next(_L("Open a damaged database"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbDamaged,iStatus);
++iCurrentTestNumber;
break;
// Check Test Five Results
case EAsyncOpenedDamaged:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened Damaged Db \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// Test Six - Async Open of a Previous version of the Database
case EAsyncOpenPreviousVersion:
test.Next(_L("Open an old version database"));
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbOldVersionFileName,iStatus);
++iCurrentTestNumber;
break;
// Check Test Six Results
case EAsyncOpenedPreviousVersion:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened Previoius Version Db \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// Test Seven - Async Open of a Previous version of the Database, and an Async
// call open of the same database in a different thread.
case EOpenAsyncAndAsync:
test.Next(_L("Open Async Then Sync"));
// Copy Version 4 Db
CopyCdbFileL(KDatabaseV4,KDbOldVersionFilePath);
// Open Async
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbOldVersionFileName,iStatus);
++iCurrentTestNumber;
// Lauch Thread to Open Db Asynchronously
CDbOpenLauncher::Create(KThreadOpenAsync, KThreadOpenAsync);
break;
// Check Test Seven Results
case EOpenedAsyncAndAsync:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened After Async Open Db \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// Iterate through these states (allowing other thread to open asynchronously)
case EWaitState:
test.Printf(_L("=== Waiting in first thread \n"));
iCurrentTestNumber = EWaitedState;
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbOldVersionFileName,iStatus);
break;
case EWaitedState:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened After Wait Db \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
if (iWaitCounter < KNumWaitLoops)
{
iCurrentTestNumber = EWaitState - 1;
iWaitCounter++;
}
else
{
// move onto next test
iCurrentTestNumber = EWaitedState;
}
NextTest();
break;
// Test Eight - Async Open of a Previous version of the Database, and a Sync
// open of the same database in a different thread.
case EOpenAsyncAndSync:
test.Next(_L("Open Async Then Sync"));
// Copy Version 4 Db
CopyCdbFileL(KDatabaseV4,KDbOldVersionFilePath);
// Open Async
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbOldVersionFileName,iStatus);
++iCurrentTestNumber;
// Lauch Thread to Open Db Synchronously
CDbOpenLauncher::Create(KThreadOpenSync, KThreadOpenSync);
break;
// Check Test Eight Results
case EOpenedAsyncAndSync:
test(iStatus.Int() == KErrNone);
test.Printf(_L("=== Opened After Sync Open Db \n"));
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
NextTest();
break;
// End of Tests
case ENumTests:
{
test.Printf(_L("=== Main Tests Complete\n"));
RThread thread;
test(thread.RequestCount()==0);
// tidy up files
CContactDatabase::DeleteDatabaseL(KDbDamaged);
CContactDatabase::DeleteDatabaseL(KDefaultDb);
CContactDatabase::DeleteDatabaseL(KDbOldVersionFileName);
CContactDatabase::DeleteDatabaseL(KDbFileName);
CActiveScheduler::Stop();
}
break;
default:
ASSERT(EFalse);
break;
}
}
void CTestConductor::DoCancel()
{
}
TInt CTestConductor::RunError(TInt aError)
{
// (only a few steps call leaving methods but we have case statements for each)
// propagate aError back to caller
iTestError = aError;
switch (iCurrentTestNumber)
{
case EAsyncOpenNamed: test.Printf(_L("Failed at test step AsyncOpenNamed (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenedNamed: test.Printf(_L("Failed at test step AsyncOpenedNamed (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenDefault: test.Printf(_L("Failed at test step AsyncOpenDefault (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenedDefault: test.Printf(_L("Failed at test step AsyncOpenedDefault (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenNonExistent: test.Printf(_L("Failed at test step AsyncOpenNonExistent (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenedNonExistent: test.Printf(_L("Failed at test step AsyncOpenedNonExistent (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncCancelOpenDefault: test.Printf(_L("Failed at test step AsyncCancelOpenDefault (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncCanceledOpenedDefault: test.Printf(_L("Failed at test step AsyncCanceledOpenedDefault (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenDamaged: test.Printf(_L("Failed at test step AsyncOpenDamaged (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenedDamaged: test.Printf(_L("Failed at test step AsyncOpenedDamaged (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenPreviousVersion: test.Printf(_L("Failed at test step AsyncOpenPreviousVersion (%i), with error %i"), iCurrentTestNumber, aError); break;
case EAsyncOpenedPreviousVersion: test.Printf(_L("Failed at test step AsyncOpenedPreviousVersion (%i), with error %i"), iCurrentTestNumber, aError); break;
case EOpenAsyncAndAsync: test.Printf(_L("Failed at test step OpenAsyncAndAsync (%i), with error %i"), iCurrentTestNumber, aError); break;
case EOpenedAsyncAndAsync: test.Printf(_L("Failed at test step OpenedAsyncAndAsync (%i), with error %i"), iCurrentTestNumber, aError); break;
case EWaitState: test.Printf(_L("Failed at test step WaitState (%i), with error %i"), iCurrentTestNumber, aError); break;
case EWaitedState: test.Printf(_L("Failed at test step WaitedState (%i), with error %i"), iCurrentTestNumber, aError); break;
case EOpenAsyncAndSync: test.Printf(_L("Failed at test step OpenAsyncAndSync (%i), with error %i"), iCurrentTestNumber, aError); break;
case EOpenedAsyncAndSync: test.Printf(_L("Failed at test step OpenedAsyncAndSync (%i), with error %i"), iCurrentTestNumber, aError); break;
case ENumTests: test.Printf(_L("Failed at test step NumTests (%i), with error %i"), iCurrentTestNumber, aError); break;
default: test.Printf(_L("Failed at test step %i, with error %i"), iCurrentTestNumber, aError); break;
}
CActiveScheduler::Stop();
return KErrNone;
}
void CTestConductor::CopyCdbFileL(const TDesC& aFileName, const TDesC& aToFileName)
{
RPIMTestServer serv;
User::LeaveIfError(serv.Connect());
serv.CopyFileL(aFileName, aToFileName);
serv.Close();
}
//
// Separate Thread to Open Database
//
CDbOpenLauncher::CViewer* CDbOpenLauncher::CViewer::NewL(const TDesC& aViewName)
{
CViewer* self = new(ELeave) CViewer;
CleanupStack::PushL(self);
self->ConstructL(aViewName);
CleanupStack::Pop(self);
return(self);
}
CDbOpenLauncher::CViewer::~CViewer()
{
delete iDatabase;
}
void CDbOpenLauncher::CViewer::ConstructL(const TDesC& aViewName)
{
if(aViewName.Compare(KThreadOpenAsync) == 0)
{
// Create Async Open
tester=CTester::NewL();
}
else if (aViewName.Compare(KThreadOpenSync) == 0)
{
//Open the database Synchronously
iDatabase = CContactDatabase::OpenL(KDbOldVersionFileName);
test(iDatabase != NULL);
delete iDatabase;
}
}
void CDbOpenLauncher::DoMainL(const TDesC& aName)
{
CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
CActiveScheduler::Install(scheduler);
CViewer* view = CViewer::NewL(aName);
CleanupStack::PushL(view);
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(view);
}
// This is the only thing one needs to call in order to set the view in motion.
void CDbOpenLauncher::Create(const TDesC& aName, const TDesC& aViewName)
{
RThread thread;
thread.Create( aName, CDbOpenLauncher::LaunchThread, KDefaultStackSize, 0x2000, 0x20000, (void*) &aViewName, EOwnerThread );
thread.Resume();
thread.SetPriority(EPriorityNormal);
thread.Close();
}
TInt CDbOpenLauncher::LaunchThread(TAny* aAny)
{
__UHEAP_MARK;
CTrapCleanup* cleanUpStack=CTrapCleanup::New();
if (!cleanUpStack)
{
return KErrNoMemory;
}
TRAPD(r,DoMainL(*((TDesC*) aAny)));
delete CActiveScheduler::Current();
delete cleanUpStack;
__UHEAP_MARKEND;
return r;
}
//
// CTester Active Object to test Async Open in thread whilst async open is going on in other thread
//
CTester* CTester::NewL()
{
CTester* self = new(ELeave) CTester();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
void CTester::DoCancel()
{
}
CTester::~CTester()
{
//state deleted during tests
}
CTester::CTester() : CActive(EPriorityIdle),iCurrentTestNumber(0)
{
CActiveScheduler::Add(this);
}
void CTester::ConstructL()
{
NextTest();
CActiveScheduler::Start();
}
void CTester::NextTest()
{
TRequestStatus *pS = &iStatus;
User::RequestComplete(pS,KErrNone);
SetActive();
}
void CTester::RunL()
{
if (iCurrentTestNumber == EAsyncOpenNamed)
{
SetActive();
iContactOpenOperation = CContactDatabase::Open(KDbFileName,iStatus);
++iCurrentTestNumber;
}
else if(iCurrentTestNumber == EAsyncOpenedNamed)
{
test(iStatus.Int() == KErrNone);
iDb = iContactOpenOperation->TakeDatabase();
test(iDb != NULL);
delete iContactOpenOperation;
delete iDb;
CActiveScheduler::Stop();
}
}
//
// Main.
//
/**
@SYMTestCaseID PIM-T-SEC-ASYNCOPEN-0001
*/
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
test.Start(_L("@SYMTESTCaseID:PIM-T-SEC-ASYNCOPEN-0001 Async Open Testing"));
CActiveScheduler* scheduler=new CActiveScheduler;
if (scheduler)
{
CActiveScheduler::Install(scheduler);
CTrapCleanup* cleanup=CTrapCleanup::New();
if (cleanup)
{
CTestConductor* tester=NULL;
TRAPD(err,tester=CTestConductor::NewL());
test(err == KErrNone);
delete tester;
delete cleanup;
}
delete scheduler;
}
test.End();
test.Close();
__UHEAP_MARKEND;
return KErrNone;
}