// 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 <e32test.h>
#include <e32base.h>
#include <e32std.h>
#include <f32file.h>
#include <s32file.h>
#include <cntdb.h>
#include <cntitem.h>
#include <cntfield.h>
#include <cntfldst.h>
#include <coreappstest/testserver.h>
#include "T_UTILS.H"
_LIT(KTestName,"T_SEC_CNTDBASE");
#include "testhelpers.h"
LOCAL_C RFs fileServer;
LOCAL_C TDriveList drives;
LOCAL_C const TInt NoDrives = 2;
LOCAL_C TInt driveIdx=0;
LOCAL_C TInt NoDatabases=0;
LOCAL_C TInt NoFileOnPreviousDrive=0;
const TInt KNumTestContacts=20;
LOCAL_C TFileName KNewCntTestFile(_L("Contacts.cbrchar"));
LOCAL_C TDriveUnit driveArray[NoDrives];
LOCAL_C CContactDatabase* db;
_LIT(KNoFiles,"NoFiles");
_LIT(KContactsFilename,"Contacts.cdb");
// These defines and the Local method DrivesOfMediaTypeL should be moved to the
// Agenda Test Library (agntestlibrary)
_LIT(KMediaNotPresent, "MediaNotPresent");
_LIT(KMediaUnknown, "MediaUnknown");
_LIT(KMediaFloppy, "MediaFloppy");
_LIT(KMediaHardDisk, "MediaHardDisk");
_LIT(KMediaCdRom, "MediaCdRom");
_LIT(KMediaRam, "MediaRam");
_LIT(KMediaFlash, "MediaFlash");
_LIT(KMediaRom, "MediaRom");
_LIT(KMediaRemote, "MediaRemote");
_LIT(KMediaNANDFlash, "MediaNANDFlash");
TPtrC MediaTypes[] =
{ KMediaNotPresent(),KMediaUnknown(),KMediaFloppy(),KMediaHardDisk(),KMediaCdRom(),
KMediaRam(),KMediaFlash(),KMediaRom(),KMediaRemote(),KMediaNANDFlash()};
_LIT(KCdbSecure,"c:T_Sec_Cntdbase.cdb");
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
_LIT(KCdbPrivate,"c:\\private\\10003A73\\SQLite__T_Sec_Cntdbase.cdb");
#else
_LIT(KCdbPrivate,"c:\\private\\10003A73\\T_Sec_Cntdbase.cdb");
#endif
_LIT(KCntNameFormat, "NAME #%d");
_LIT(KCntNewNameFormat, "NEW NAME #%d");
LOCAL_C CArrayFix<TInt>* DrivesOfMediaTypeL( TMediaType aMedia, RFs& aFs, TBool aStopAtFirst )
{
TDriveInfo info;
TInt error = KErrNone;
TDriveList driveList;
CArrayFix<TInt>* array = new (ELeave) CArrayFixFlat<TInt>(10);
CleanupStack::PushL( array );
error = aFs.DriveList(driveList);
User::LeaveIfError(error);
for(TInt drive=EDriveA;drive<=EDriveZ;drive++)
{
if( driveList[drive] )
{
error = aFs.Drive(info, drive);
if (error != KErrNone)
{
continue;
}
if ( info.iType == aMedia )
{
array->AppendL( drive );
if( aStopAtFirst )
{ // return if only the first drive of the required type.
break;
}
}
}
}
CleanupStack::Pop( array );
return array;
}
/**
MMCDriveL
Determines a list of drives of type EMediaHardDisk.
The first drive in this list is returned and used
by the rest of the test.
NOTE: if this test is running on ARMv5, an MMC card
must be present otherwise the test fails.
*/
LOCAL_C TDriveUnit MMCDriveL()
{
CArrayFix<TInt>* drives = DrivesOfMediaTypeL(EMediaHardDisk,fileServer,EFalse);
CleanupStack::PushL(drives);
TInt drivesTInt = drives->Count();
if( drivesTInt )
{
test.Printf(_L("Found the following drives of type %S\n"),&MediaTypes[EMediaHardDisk]);
for(TInt i=0;i<drivesTInt;i++)
{
TDriveUnit drv(drives->At(i));
TPtrC drvPtr(drv.Name());
test.Printf(_L("%S\n"),&drvPtr);
}
}
else
{
test.Printf( _L("No drives found of type %S\n"),&MediaTypes[EMediaHardDisk]);
User::LeaveIfError(KErrHardwareNotAvailable);
}
TDriveUnit mmcDrive(drives->At(0));
CleanupStack::PopAndDestroy(drives);
// Use the first drive in the list for the rest of the test.
return mmcDrive;
}
/**
AddNewContactsL
Add KNumTestContacts new contacts with varying numbres of text fields
@param aIdList
*/
LOCAL_C void AddNewContactsL(CArrayFix<TContactItemId>* aIdList)
{
CContactCard* card=CContactCard::NewL();
CleanupStack::PushL(card);
TContactItemId id=KNullContactId;
TContactItemId newId=KNullContactId;
for (TInt ii=0;ii<KNumTestContacts;ii++)
{
TBuf<16> name;
name.Format(KCntNameFormat, ii);
SetNameL(*card,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,name,EFalse);
CContactItemField* field=CContactItemField::NewLC(KStorageTypeText);
card->AddFieldL(*field);
CleanupStack::Pop(); // field
newId=db->AddNewContactL(*card);
id=newId;
aIdList->AppendL(id);
}
CleanupStack::PopAndDestroy(); // card
}
LOCAL_C TPtrC Name(CContactItem& aItem)
{
CContactItemFieldSet& fieldSet=aItem.CardFields();
const TInt pos=fieldSet.Find(KUidContactFieldFamilyName);
if (pos==KErrNotFound)
return _L("");
return fieldSet[pos].TextStorage()->Text();
}
/**
EditContactsL
Check then edit contact names
@param aIdList
*/
LOCAL_C void EditContactsL(CArrayFix<TContactItemId>* aIdList)
{
TInt ii=0;
test.Next(_L("Change all contact names"));
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
for (;ii<aIdList->Count();++ii)
#else
for (;ii<KNumTestContacts;ii++)
#endif
{
const TInt index=(*aIdList)[ii];
// exercise OpenContactLX api, Commit the change and Pop the lock record
CContactItem* item=db->OpenContactLX(index);
CleanupStack::PushL(item);
TBuf<16> name;
name.Format(KCntNameFormat, ii); // "NAME %d"
test(name==Name(*item));
name.Format(KCntNewNameFormat, index); // "NEW NAME %d"
SetNameL(*item,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,name,EFalse);
db->CommitContactL(*item);
CleanupStack::PopAndDestroy(); // item;
CleanupStack::Pop(); // lock record
}
test.Next(_L("Check new contact names"));
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
for (;ii<aIdList->Count();++ii)
#else
for (ii=0;ii<KNumTestContacts;ii++)
#endif
{
const TInt index=(*aIdList)[ii];
CContactItem* item=db->ReadContactL(index);
TBuf<16> name;
name.Format(KCntNewNameFormat, index);
test(name==Name(*item));
delete item;
}
test.Next(_L("Regression test for Contact locking/unlocking (DEF067162)"));
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
for (;ii<aIdList->Count();++ii)
#else
for (ii = 0; ii < KNumTestContacts; ii++)
#endif
{
// open 2 different items
const TInt index1 = (*aIdList)[ii];
const TInt index2 = (*aIdList)[(ii + 1) % KNumTestContacts];
CContactItem* item1 = db->OpenContactLX(index1);
CleanupStack::PushL(item1);
CContactItem* item2 = db->OpenContactLX(index2);
delete item2;
CleanupStack::PopAndDestroy(); // destroy lock = close item2
CleanupStack::PopAndDestroy(item1);
CleanupStack::PopAndDestroy(); // destroy lock = close item1
// re-open 1st item - should not be locked
// OpenContactLX() and PopAndDestroy()
item1 = db->OpenContactLX(index1);
delete item1;
CleanupStack::PopAndDestroy(); // destroy lock = close item1
// re-open 2nd item - should not be locked
// OpenContactL() and CloseContactL()
item2 = db->OpenContactL(index2);
CleanupStack::PushL(item2);
db->CloseContactL(index2); // explicitly close item 2
CleanupStack::PopAndDestroy(item2);
}
// try to read a non-existant contact
TRAPD(err,db->ReadContactL(KNullContactId));
TESTTRUEL(err!=KErrNone);
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
if(aIdList->Count() > 0)
{
#endif
// try to edit a contact that hasn't been opened
CContactItem* item=db->ReadContactLC((*aIdList)[0]);
TRAP(err,db->CommitContactL(*item));
CleanupStack::PopAndDestroy(); // item
TESTTRUEL(err==KErrAccessDenied);
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
}
#endif
// try to close a non-existant contact
TRAP(err,db->CloseContactL(KNullContactId));
TESTTRUEL(err==KErrNone); // test changed from 001 (using DBMS 043) - this test makes more sense anyway
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
if(aIdList->Count() > 0)
{
#endif
// try to close a contact that hasn't been opened
TRAP(err,db->CloseContactL((*aIdList)[0]));
TESTTRUEL(err==KErrNone);
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
}
#endif
}
/**
Gets the list of installed drives and then stores the first 2
in the array drives for use within the test. The second entry
in this array should use method MMCDriveL as used in T_Sec_Tidy
and T_Sec_ListAgendaFile.
*/
LOCAL_C void DrivesL()
{
driveArray[0] = EDriveC;
driveArray[1] = MMCDriveL();
// Tell the user which drive has been chosen.
TPtrC drv( driveArray[1].Name() );
test.Printf(_L("%S chosen for the test.\n"),&drv);
}
/**
Ensure that the filename conforms to the correct form.
The analysis functionality is dependent on the flags:
SYMBIAN_SECURE_DBMS. Unlike Agenda, in contacts as GetDefaultNameL
existed before platsec there is legacy functionality that must
maintained. In not SYMBIAN_SECURE_DBMS the full path must be checked
for. The default filename exits on the current drive.
@param reference to the default file name.
@return ETrue if the default filename is correctly formed.
*/
LOCAL_C TBool CheckDefaultContactsFilename( TFileName& aFilename )
{
_LIT(KDriveFailure, "Incorrect Drive Specified" );
_LIT(KPathFailure, "Incorrect No Path expected" );
_LIT(KFilenameFailure, "Incorrect Filename" );
TDriveUnit lDriveUnit;
// Get the current drive.
CContactDatabase::DatabaseDrive(lDriveUnit);
TParse filename;
filename.Set( aFilename, NULL, NULL);
// Check that the drive letter exists. No drive is an error
// in both modes.
if( filename.Drive() != lDriveUnit.Name())
{
test.Printf(KDriveFailure);
return EFalse;
}
if( filename.Path().Length())
{
test.Printf(KPathFailure);
return EFalse;
}
if( filename.NameAndExt().CompareF(KContactsFilename()))
{
test.Printf(KFilenameFailure);
return EFalse;
}
return ETrue;
}
/**
CheckNotDefaultContactsFiles
Uses all the default database related API's to ensure that
they all return negative, now that the default db has been
removed.
@return ETrue if a default database cannot be found on the
default drive.
*/
LOCAL_C TBool CheckNotDefaultContactsFiles()
{
// The default database on the current default drive.(3)
// The default database on the specific drive. (4)
TBool response = EFalse;
TRAPD(err, response = CContactDatabase::DefaultContactDatabaseExistsL());
if( !(err == KErrNone && !response ))
{
return EFalse;
}
// Use the default database, as we have confirmed previously
// this shouldn't exits. This is dependent upon the Security mode.
TFileName filename;
filename.Copy(driveArray[driveIdx].Name());
filename.Append(KContactsFilename);
// (5)
TRAP(err, response = CContactDatabase::ContactDatabaseExistsL(filename));
if( !(err == KErrNone && !response ))
{
return EFalse;
}
// None of the API return true, no default Contact DB files were detected.
return ETrue;
}
/**
CheckCntFilesL
Ensure that cntFiles contains the list of correct files.
The analysis functionality is dependent on the flags:
_SECURE_DATA_ and _UNSECURE_DATA_
Determines the list of agn files, checks for the existance of aFilename
within the list of aNum names.
@param aNum number of expected files.
@param aFilename a reference to an expected filename.
@return aFileExpectedToExist ETrue if the list contains the expected files.
*/
LOCAL_C TBool CheckCntFilesL( TInt aNum, const TDesC& aFilename , TBool aFileExpectedToExist = ETrue)
{
// Data bases on all drives.
CDesCArray* cntFiles = CContactDatabase::ListDatabasesL();
CleanupStack::PushL(cntFiles);
// Data bases on the specified drive.
CDesCArray* cntFilesFromDrive = CContactDatabase::ListDatabasesL(driveArray[driveIdx]);
CleanupStack::PushL(cntFilesFromDrive);
TInt DriveZCount=0;
// Determine files on drive Z:
if( !cntFiles->Count() && !cntFilesFromDrive->Count() && !aNum )
{
CleanupStack::PopAndDestroy( cntFilesFromDrive );
CleanupStack::PopAndDestroy( cntFiles );
return !aFileExpectedToExist;
}
// Ensure that all drive contents add up.
if( cntFiles->Count() != NoFileOnPreviousDrive + DriveZCount + cntFilesFromDrive->Count() )
{
CleanupStack::PopAndDestroy(cntFilesFromDrive);
CleanupStack::PopAndDestroy(cntFiles);
return !aFileExpectedToExist;
}
TFileName filename;
// In un-secure mode if aFilename contains no path, then
// a backslash must be included between the drive and the
// filename. This because when asked to create filename
// "c:filename" ListDatabasesL returns the name "c:\filename"
// hence a backslash is inserted for comparison purposes.
TParse file;
file.Set(aFilename,NULL,NULL);
filename.Copy(aFilename);
// Check that aFilename is in the list.
TBool retValue = ETrue;
if (!aFileExpectedToExist)
{
// File is not expected to exist. So return EFalse if we find it.
for(TInt i=0;i<cntFilesFromDrive->Count();i++)
{
TFileName driveList_1 = (*cntFilesFromDrive)[i];
if(!driveList_1.CompareF(filename))
{
CleanupStack::PopAndDestroy(cntFilesFromDrive);
CleanupStack::PopAndDestroy(cntFiles);
return !retValue;
}
}
retValue = EFalse;
}
else
{
// File is expected to exist. We should find it in both lists.
// return EFalse if not found in this list.
TBool fileFound = EFalse;
// does file exist in list from drive
for(TInt j=0;j<cntFilesFromDrive->Count();j++)
{
TFileName driveList_2 = (*cntFilesFromDrive)[j];
if(!driveList_2.CompareF(filename))
{
fileFound = ETrue;
break;
}
}
if(!fileFound)
{
CleanupStack::PopAndDestroy(cntFilesFromDrive);
CleanupStack::PopAndDestroy(cntFiles);
return !retValue;
}
}
// We found the file in cntFilesFromDrive
// Does file exist in list from all drives
for(TInt k=0;k<cntFiles->Count();k++)
{
TFileName driveList_3 = (*cntFiles)[k];
if(!driveList_3.CompareF(filename))
{
CleanupStack::PopAndDestroy(cntFilesFromDrive);
CleanupStack::PopAndDestroy(cntFiles);
return retValue;
}
}
CleanupStack::PopAndDestroy(cntFilesFromDrive);
CleanupStack::PopAndDestroy(cntFiles);
// File was not found so return false.
return !retValue;
}
/**
This API uses all the Contacts API's relating to identification
of the default file.
*/
LOCAL_C TBool DefaultDatabaseL()
{
// The default database on the current default drive.
if(!CContactDatabase::DefaultContactDatabaseExistsL())
return EFalse;
// Use the default database, as we have confirmed previously
// this shouldn't exits. This is dependent upon the Security mode.
TFileName filename;
filename.Copy(driveArray[driveIdx].Name());
filename.Append(KContactsFilename);
if(!CContactDatabase::ContactDatabaseExistsL(filename))
return EFalse;
// None of the API return true, no files were detected.
return ETrue;
}
/**
This function uses Five API's available to determine the existance
of database files. These are (1)ListDatabasesL(),(2)ListDatabasesL(TDriveUnit&)
(3)DefaultContactDatabaseExistsL(),(4)DefaultContactDatabaseExistsL(TDriveUnit&)
and (5)ContactDatabaseExistsL(const TDesC&). All five should confirm that there
are no contacts database files.
*/
LOCAL_C TBool CheckNoDatabaseFilesL()
{
TFileName filename;
TBool retVal = EFalse;
filename.Copy(driveArray[driveIdx].Name());
filename.Append(KContactsFilename);
retVal = CheckCntFilesL(NoDatabases, filename , EFalse);
if (retVal == EFalse)
return retVal;
else
return CheckNotDefaultContactsFiles();
}
/**
Tidy
This function removes any files that may exist as a result of a
previous run of the T_Sec_cntdbase test.
The configuration of this operation is dependent upon __SECURE_DATA_
*/
LOCAL_C void Tidy()
{
TFileName addedFile;
CDesCArray* driveFiles = NULL;
for(TInt i =0;i<NoDrives; i++ )
{
addedFile.Copy(driveArray[i].Name());
addedFile.Append(KNewCntTestFile);
TRAPD( err, CContactDatabase::SetDatabaseDriveL(driveArray[i], EFalse));
TRAP( err, CContactDatabase::DeleteDefaultFileL());
TRAP(err, CContactDatabase::DeleteDatabaseL(addedFile));
}
TRAPD(ret, driveFiles = CContactDatabase::ListDatabasesL());
for(TInt j =0;j<driveFiles->Count();j++)
{
CContactDatabase::DeleteDatabaseL((*driveFiles)[j]);
}
if( ret == KErrNone )
{
delete driveFiles;
}
}
// support CreateL and ReplaceL OOM tests
LOCAL_C TInt CheckDatabaseIsAbsentOrOpenable(TBool aDeleteDatabase=EFalse)
{
// CreateL or ReplaceL failed, so database can either be absent or it must Open
TBool exists(EFalse);
TRAPD(err, exists = CContactDatabase::DefaultContactDatabaseExistsL());
if (err)
{
test.Printf(_L("CheckDatabaseIsAbsentOrOpenable - DefaultContactDatabaseExistsL error %d"), err);
}
if(exists)
{
CContactDatabase* dbaseOpen = NULL;
TRAP(err, dbaseOpen = CContactDatabase::OpenL());
if (err)
{
test.Printf(_L("CheckDatabaseIsAbsentOrOpenable - OpenL error %d"), err);
}
if (dbaseOpen != NULL)
{
// database exists, so it should have opened
delete dbaseOpen;
}
if (aDeleteDatabase && (err == KErrNone))
{
// for client side CreateL OOM test
CContactDatabase::DeleteDefaultFileL();
}
}
return err;
}
// Client Side OOM Tests //
LOCAL_C TBool ReplaceLOOM_ClientSideL()
{
test.Next(_L("ReplaceL client side OOM test.\n"));
CContactDatabase* dBase = NULL;
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, dBase = CContactDatabase::ReplaceL());
if( ret == KErrNone )
{
delete dBase;
}
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNone)
{
if(ret != KErrNoMemory)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL(ret == KErrNoMemory);
}
TESTNOERRL(CheckDatabaseIsAbsentOrOpenable());
}
}
// Remove the default database, created by Replace.
CContactDatabase::DeleteDefaultFileL();
test.Printf(_L("\n"));
return ETrue;
}
LOCAL_C TBool ContactDatabaseExistsLOOM_ClientSideL()
{
test.Next(_L("ContactDatabaseExistsL client side OOM test.\n"));
_LIT(KContactDBase,"c:ContactDBase");
TBool dExists = EFalse;
// First create a database to be detected.
CContactDatabase* dBase = NULL;
TRAPD(err, dBase = CContactDatabase::CreateL(KContactDBase));
// need the file to be present to test if it exists
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
delete dBase;
}
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, dExists = CContactDatabase::ContactDatabaseExistsL(KContactDBase));
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
if( ret == KErrNone && dExists )
{
// Remove the database.
CContactDatabase::DeleteDatabaseL(KContactDBase);
}
test.Printf(_L("\n"));
return ETrue;
}
LOCAL_C TBool DefaultContactDatabaseExistsLOOM_ClientSideL()
{
test.Next(_L("DefaultContactDatabaseExistsL client side OOM test.\n"));
TBool dExists = EFalse;
// First create a default database.
CContactDatabase* dBase = NULL;
TRAPD( err, dBase = CContactDatabase::CreateL());
// need the file to be present to test if it exists
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
delete dBase;
}
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, dExists = CContactDatabase::DefaultContactDatabaseExistsL());
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
if( ret == KErrNone && dExists )
{
// Remove the default database
CContactDatabase::DeleteDefaultFileL();
}
test.Printf(_L("\n"));
return ETrue;
}
LOCAL_C TBool GetDefaultNameLOOM_ClientSideL()
{
test.Next(_L("GetDefaultNameL client side OOM test.\n"));
TFileName filename;
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, CContactDatabase::GetDefaultNameL(filename));
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
test.Printf(_L("\n"));
return ETrue;
}
LOCAL_C TBool DeleteDatabaseLOOM_ClientSideL()
{
test.Next(_L("DeleteDatabaseL client side OOM test.\n"));
_LIT(KTestFile,"C:TestFile");
CContactDatabase* dBase = NULL;
// Create a file to delete.
TRAPD(err, dBase = CContactDatabase::CreateL(KTestFile));
// need the file to be present to delete it
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
delete dBase;
}
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, CContactDatabase::DeleteDatabaseL(KTestFile));
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
test.Printf(_L("\n"));
// Check to see that database has been removed.
TBool dExists = EFalse;
TRAP(ret, dExists = CContactDatabase::ContactDatabaseExistsL(KTestFile));
TESTNOERRL(ret);
return !dExists;
}
LOCAL_C TBool DeleteDefaultFileLOOM_ClientSideL()
{
test.Next(_L("DeleteDefaultFileL client side OOM test.\n"));
CContactDatabase* dBase = NULL;
TRAPD( err, dBase = CContactDatabase::CreateL());
// need the file to be present to delete it
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
delete dBase;
}
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, CContactDatabase::DeleteDefaultFileL());
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
test.Printf(_L("\n"));
// Ensure that the default File has been removed.
TBool dExists = EFalse;
TRAP(ret, dExists = CContactDatabase::DefaultContactDatabaseExistsL());
TESTNOERRL(ret);
return !dExists;
}
LOCAL_C TBool CreateLOOM_ClientSideL()
{
test.Next(_L("CreateL client side OOM test.\n"));
TRAPD(err, CContactDatabase::DeleteDefaultFileL());
TESTTRUEL((err == KErrNone) || (err == KErrNotFound));
CContactDatabase* dBase = NULL;
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, dBase = CContactDatabase::CreateL());
if( ret == KErrNone )
{
delete dBase;
dBase=NULL;
}
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNone)
{
if(ret != KErrNoMemory)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL(ret == KErrNoMemory);
}
TESTNOERRL(CheckDatabaseIsAbsentOrOpenable(ETrue));
}
}
//cleanup
if(CContactDatabase::DefaultContactDatabaseExistsL())
{
CContactDatabase::DeleteDefaultFileL();
}
test.Printf(_L("\n"));
return ETrue;
}
LOCAL_C TBool OpenLOOM_ClientSideL()
{
test.Next(_L("OpenL client side OOM test.\n"));
// Create a default database.
CContactDatabase* dBase = NULL;
TRAPD( err, dBase = CContactDatabase::CreateL());
// need the file to be present to open it
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
delete dBase;
}
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, dBase = CContactDatabase::OpenL());
if( ret == KErrNone )
{
delete dBase;
}
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
test.Printf(_L("\n"));
// Remove the default file we just opened.
TRAP( ret, CContactDatabase::DeleteDefaultFileL());
return ETrue;
}
LOCAL_C TBool ListDatabasesLOOM_ClientSideL()
{
test.Next(_L("ListDatabasesL client side OOM test.\n"));
CDesCArray* driveFiles = NULL;
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone )
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
TRAP(ret, driveFiles = CContactDatabase::ListDatabasesL());
if( ret == KErrNone )
{
delete driveFiles;
}
__UHEAP_MARKEND;
__UHEAP_RESET;
if (ret != KErrNoMemory && ret != KErrNone)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
test.Printf(_L("\n"));
return ETrue;
}
#ifdef _DEBUG
LOCAL_C TBool CreateLOOM_ServerSideL()
{
test.Next(_L("CreateL Server side OOM test.\n"));
_LIT(KTemporaryFile,"C:TempFile");
CContactDatabase* dBase = NULL;
CContactDatabase* newDataBase = NULL;
// First create an instance of CContactDatabase to be used to call
// Server side heap methods.
TRAPD( err, dBase = CContactDatabase::ReplaceL(KTemporaryFile));
// need the file to be present for server connection
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TRAP_IGNORE(CContactDatabase::DeleteDefaultFileL());
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("%d,"), failAt);
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, newDataBase = CContactDatabase::CreateL());
if( ret == KErrNone )
{
delete newDataBase;
}
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret != KErrNone)
{
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
if(allocLatest != allocCells -1)
#endif
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
}
else
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
TESTNOERRL(CheckDatabaseIsAbsentOrOpenable(ETrue));
}
}
CleanupStack::PopAndDestroy(dBase);
// This test has created two files; a default and KTemporaryFile
// both must be deleted.
TRAP( ret, CContactDatabase::DeleteDefaultFileL());
TRAP( ret, CContactDatabase::DeleteDatabaseL( KTemporaryFile ));
return ETrue;
}
LOCAL_C TBool DeleteDatabaseLOOM_ServerSideL()
{
test.Next(_L("DeleteDatabaseL Server side OOM test.\n"));
_LIT(KFileToDelete,"c:FileToDelete");
CContactDatabase* dBase = NULL;
CContactDatabase* dBaseForFile = NULL;
//
// create db file for delete test
TRAPD( err, dBaseForFile = CContactDatabase::CreateL(KFileToDelete));
TESTTRUEL((err == KErrNone) || (err == KErrAlreadyExists));
if (err == KErrNone)
{
// Close the file
delete dBaseForFile;
}
// Create Default dBase to be used by ServerSide OOM Calls.
TRAP( err, dBase = CContactDatabase::ReplaceL());
// need the file to be present for server connection
TESTTRUEL(err == KErrNone);
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, CContactDatabase::DeleteDatabaseL(KFileToDelete));
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
CleanupStack::PopAndDestroy(dBase);
// Delete default file.
TRAP(ret, CContactDatabase::DeleteDefaultFileL());
return ETrue;
}
LOCAL_C TBool DefaultContactDatabaseExistsLOOM_ServerSideL()
{
test.Next(_L("DefaultContactDatabaseExistsL Server side OOM test.\n"));
CContactDatabase* dBase = NULL;
TRAPD( err, dBase = CContactDatabase::ReplaceL());
// need the file to be present for server connection
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, CContactDatabase::DefaultContactDatabaseExistsL());
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone)); //Bad leaving code
}
}
CleanupStack::PopAndDestroy(dBase);
// Check to see that database has been removed.
TRAP_IGNORE(CContactDatabase::DeleteDefaultFileL());
return ETrue;
}
LOCAL_C TBool OpenLOOM_ServerSideL()
{
test.Next(_L("OpenL Server side OOM test.\n"));
CContactDatabase* dBase = NULL;
CContactDatabase* dBaseToOpen = NULL;
// Create the default contacts file.
TRAPD(err, dBase = CContactDatabase::ReplaceL());
// need the file to be present for server connection
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, dBaseToOpen = CContactDatabase::OpenL());
if( ret == KErrNone )
{
delete dBaseToOpen;
}
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
if(allocLatest != allocCells + 1)
#endif
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
CleanupStack::PopAndDestroy(dBase);
// Remove the default.
TRAP(ret, CContactDatabase::DeleteDefaultFileL());
return ETrue;
}
LOCAL_C TBool ContactDatabaseExistsLOOM_ServerSideL()
{
test.Next(_L("ContactDatabaseExistsL Server side OOM test.\n"));
_LIT(KCntFileToExist,"C:FileToDetect");
CContactDatabase* dBase = NULL;
// Create the named contacts file.
TRAPD(err, dBase = CContactDatabase::ReplaceL(KCntFileToExist));
// need the file to be present for server connection
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, CContactDatabase::ContactDatabaseExistsL(KCntFileToExist));
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));//Bad leaving code
}
}
CleanupStack::PopAndDestroy(dBase);
// Remove the default.
TRAP(ret, CContactDatabase::DeleteDatabaseL(KCntFileToExist));
return ETrue;
}
LOCAL_C TBool ReplaceLOOM_ServerSideL()
{
test.Next(_L("ReplaceL Server side OOM test.\n"));
_LIT(KCntFileToExist,"C:FileToDetect");
CContactDatabase* dBase = NULL;
CContactDatabase* dBaseReplace = NULL;
// Create the named contacts file.
TRAPD(err, dBase = CContactDatabase::ReplaceL(KCntFileToExist));
// need the file to be present for server connection
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, dBaseReplace = CContactDatabase::ReplaceL());
if(ret == KErrNone)
{
delete dBaseReplace;
}
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret != KErrNone)
{
if(ret != KErrNoMemory)
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
else
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
if(allocLatest != allocCells - 1)
#endif
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
}
TESTNOERRL(CheckDatabaseIsAbsentOrOpenable());
}
}
CleanupStack::PopAndDestroy(dBase);
// Remove the default file associated with the dBase.
TRAP(ret, CContactDatabase::DeleteDatabaseL(KCntFileToExist));
return ETrue;
}
LOCAL_C TBool DeleteDefaultFileLOOM_ServerSideL()
{
test.Next(_L("DeleteDefaultFileL Server side OOM test.\n"));
_LIT(KCntFileToExist,"C:FileToDetect");
CContactDatabase* dBase = NULL;
CContactDatabase* dBaseDefaultFile = NULL;
// ensure default contacts file is created
TRAPD(err, dBaseDefaultFile = CContactDatabase::CreateL());
// need file to be created for delete test
TESTTRUEL( (err == KErrNone) || (err == KErrAlreadyExists))
if (err == KErrNone)
{
delete dBaseDefaultFile;
}
// Create the named contacts file.
TRAP(err, dBase = CContactDatabase::ReplaceL(KCntFileToExist));
// need the file to be present for server connection
TESTTRUEL(err == KErrNone);
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, CContactDatabase::DeleteDefaultFileL());
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone));
}
}
CleanupStack::PopAndDestroy(dBase);
// Remove the default file associated with the dBase.
// Ensure that the default File has been removed.
TBool dExists = EFalse;
TRAP(ret, dExists = CContactDatabase::DefaultContactDatabaseExistsL());
TESTNOERRL(ret);
TRAP_IGNORE(CContactDatabase::DeleteDatabaseL(KCntFileToExist));
return !dExists;
}
LOCAL_C TBool GetDefaultNameLOOM_ServerSideL()
{
test.Next(_L("GetDefaultNameL Server side OOM test.\n"));
CContactDatabase* dBase = NULL;
// Create the default contacts file.
TRAPD(err, dBase = CContactDatabase::ReplaceL());
// need the file to be present
TESTTRUEL((err == KErrNone) && (dBase != NULL));
CleanupStack::PushL(dBase);
TInt allocCells(0);
TInt ret = KErrNoMemory;
TInt failAt = 0;
TFileName filename;
while(ret != KErrNone)
{
failAt++;
if( !(failAt % 5 ))
{
test.Printf(_L("."));
}
dBase->SetCntServerHeapFailure(RHeap::EDeterministic, failAt);
allocCells = dBase->CntServerResourceCount(); //__UHEAP_MARK;
TRAP(ret, CContactDatabase::GetDefaultNameL(filename));
//__SRVHEAP_RESET;
dBase->SetCntServerHeapFailure(RHeap::ENone, 1);
if (ret == KErrNoMemory)
{
TInt allocLatest = dBase->CntServerResourceCount();
if (allocLatest != allocCells)
{
test.Printf(_L("iteraton %d failed - initial alloc cells = %d, alloc Latest = %d\n"),
failAt, allocCells, allocLatest);
TESTVALUEL(allocLatest, allocCells); //__UHEAP_MARKEND;
}
}
else if ( ret != KErrNone )
{
test.Printf(_L("iteration %d failed - non-memory error in OOM test: %d\n"), failAt, ret);
TESTTRUEL((ret == KErrNoMemory || ret == KErrNone)); //Bad leaving code
}
}
CleanupStack::PopAndDestroy(dBase);
TRAP_IGNORE(CContactDatabase::DeleteDefaultFileL());
return ETrue;
}
#endif
LOCAL_C void OOMTestingL()
{
// Client side OOM Testing.
TESTTRUE(ListDatabasesLOOM_ClientSideL());
TESTTRUE(OpenLOOM_ClientSideL());
TESTTRUE(DeleteDatabaseLOOM_ClientSideL());
TESTTRUE(CreateLOOM_ClientSideL());
TESTTRUE(GetDefaultNameLOOM_ClientSideL());
TESTTRUE(DefaultContactDatabaseExistsLOOM_ClientSideL());
TESTTRUE(ContactDatabaseExistsLOOM_ClientSideL());
TESTTRUE(ReplaceLOOM_ClientSideL());
TESTTRUE(DeleteDefaultFileLOOM_ClientSideL());
#ifdef _DEBUG
// Server side OOM testing. Only server side debug method are
// available in debug mode.
TESTTRUE(CreateLOOM_ServerSideL());
TESTTRUE(DeleteDatabaseLOOM_ServerSideL());
TESTTRUE(DefaultContactDatabaseExistsLOOM_ServerSideL());
TESTTRUE(OpenLOOM_ServerSideL());
TESTTRUE(ContactDatabaseExistsLOOM_ServerSideL());
TESTTRUE(ReplaceLOOM_ServerSideL());
TESTTRUE(DeleteDefaultFileLOOM_ServerSideL());
TESTTRUE(GetDefaultNameLOOM_ServerSideL());
#endif
}
/**
NegTestL
Intended to identify the failing cases of the API and ensure that they behave
carefully under these conditions.
This section of the test needs more coverage.
*/
LOCAL_C void NegTestL()
{
TInt err (KErrNone);
test.Next(_L("Test drive Setting and Getting\n"));
{
TBool dbDriveSet;
TDriveUnit driveUnit;
// Set the Current drive to C:
TRAP( err, CContactDatabase::SetDatabaseDriveL(TDriveUnit(2), EFalse));
TESTTRUEL( err == KErrNone );
// Read the current drive back, ensuring it has been changed correctly.
dbDriveSet = CContactDatabase::DatabaseDrive(driveUnit);
TESTTRUEL(dbDriveSet);
TESTTRUEL(driveUnit == 2);
// Create and open an empty contact database
TRAP(err, db = CContactDatabase::ReplaceL());
TESTTRUEL( err == KErrNone && db != NULL);
if( !err )
{
delete db;
db = NULL;
}
err = KErrNone;
TBool exists = EFalse;
TRAP( err, exists = CContactDatabase::DefaultContactDatabaseExistsL());
TESTTRUEL( exists && err == KErrNone );
TRAP(err, CContactDatabase::DeleteDefaultFileL());
TESTTRUEL( err == KErrNone);
TRAP( err, exists = CContactDatabase::DefaultContactDatabaseExistsL());
TESTTRUEL( !exists && err == KErrNone );
// delete again should fail
TRAP(err, CContactDatabase::DeleteDefaultFileL());
TESTTRUEL( err == KErrNotFound );
db = CContactDatabase::CreateL();
TRAP( err, exists = CContactDatabase::DefaultContactDatabaseExistsL());
TESTTRUEL( exists );
delete db;
db = NULL;
TRAP( err, CContactDatabase::SetDatabaseDriveL(TDriveUnit(5), EFalse));
TESTTRUEL( err == KErrNone );
TRAP( err, dbDriveSet = CContactDatabase::DatabaseDrive(driveUnit));
TESTTRUEL( err == KErrNone );
TESTTRUEL( dbDriveSet );
TESTTRUEL( driveUnit == 5 );
TRAP( err, CContactDatabase::SetDatabaseDriveL(TDriveUnit(2), EFalse));
TESTTRUEL( err == KErrNone );
TRAP( err, dbDriveSet = CContactDatabase::DatabaseDrive(driveUnit));
TESTTRUEL( dbDriveSet );
TESTTRUEL( driveUnit == 2 );
}
TRAP( err, db = CContactDatabase::OpenL());
TESTTRUEL( err == KErrNone && db != NULL );
delete db;
db = NULL;
test.Next(_L("Test database opening\n"));
{
// open twice
db = CContactDatabase::OpenL();
TESTTRUEL(db != NULL);
CContactDatabase* db2 = CContactDatabase::OpenL();
TESTTRUEL(db2 != NULL);
TESTTRUEL(db2 != db);
delete db;
db = NULL;
delete db2;
db2 =NULL;
// KNullDesC is used internally, but is not a valid parameter
TRAP(err, db = CContactDatabase::OpenL(KNullDesC));
TESTTRUEL(err == KErrBadName);
TESTTRUEL(db == NULL);
// KNullDesC is used internally, but is not a valid parameter
TRAP(err, db = CContactDatabase::ReplaceL(KNullDesC));
TESTTRUEL(err == KErrBadName);
TESTTRUEL(db == NULL);
// check for Open and Create Failing
CContactDatabase::DeleteDefaultFileL();
TRAP(err, db = CContactDatabase::OpenL());
TESTTRUEL(err == KErrNotFound);
TESTTRUEL(db == NULL);
TRAP(err, db = CContactDatabase::CreateL());
TESTTRUEL(err == KErrNone);
delete db;
db = NULL;
TRAP(err, db = CContactDatabase::CreateL());
TESTTRUEL(err == KErrAlreadyExists);
TESTTRUEL(db == NULL);
// check for Replace replacing!
TRAP(err, db = CContactDatabase::ReplaceL());
TESTTRUEL(err == KErrNone);
TESTTRUEL(db != NULL);
delete db;
db = NULL;
// wait for server to shutdown (6s)
User::After(6000000);
// open twice
db = CContactDatabase::OpenL();
db2 = CContactDatabase::OpenL();
delete db;
db = NULL;
delete db2;
db2 =NULL;
}
}
/**
FunctionTestL
Excersises: ListDatabasesL varients over 2 drives; C & F
SetDatabaseDriveL, DatabaseDrive, GetDefaultNameL,
the varients of DefaultContactDatabaseExistsL, CreateL,
asynchronous OpenL, FindContactFile, DeleteDefaultFileL and
DeleteDatabaseL.
*/
LOCAL_C void FunctionTestL()
{
TFileName addedFile;
test.Next(_L("FunctionTestL CContactDatabase::ListDatabasesL over multiple drives.\n"));
// At this point there should only be 1 file which is the default.
TFileName filename, defaultFilename;
for(driveIdx =0;driveIdx<NoDrives; driveIdx++ )
{
addedFile.Copy(driveArray[driveIdx].Name());
addedFile.Append(KNewCntTestFile);
Tidy();
CDesCArray* cntFiles = NULL;
TRAPD(err, cntFiles = CContactDatabase::ListDatabasesL());
TESTTRUEL(err == KErrNone && cntFiles != NULL);
NoDatabases = 0;
if( !err )
{
NoDatabases = cntFiles->Count();
delete cntFiles;
}
// Check Set and Get default drive.
TPtrC drvName(driveArray[driveIdx].Name());
test.Printf(_L("Testing Drive %S\n"), &drvName);
test.Next(_L("Setting Drive\n"));
TRAP( err, CContactDatabase::SetDatabaseDriveL(driveArray[driveIdx], EFalse));
if( err )
{
test.Printf(_L("CContactDatabase::SetDatabaseDriveL:Leave code:%d"),err);
}
TDriveUnit myDriveUnit;
{
TESTTRUEL(CContactDatabase::DatabaseDrive(myDriveUnit));
}
TESTTRUEL(myDriveUnit == driveArray[driveIdx]);
// Steve. To see if Drive of default filename changes.
TRAP( err, CContactDatabase::GetDefaultNameL( filename ));
if( err )
{
test.Printf(_L("CContactDatabase::GetDefaultNameL:Leave code:%d"),err);
}
test.Next(_L("Checking default filename.\n"));
TESTTRUEL(CheckDefaultContactsFilename(filename));
defaultFilename = filename;
// Exercise all API's the look for Contacts files.
TESTTRUEL(CheckCntFilesL( NoDatabases, KNoFiles, EFalse ));
TESTTRUEL(CheckNoDatabaseFilesL());
// ReplaceL and OpenL //
test.Next(_L("Creating/Replacing default db: ReplaceL.\n"));
TRAP( err, db = CContactDatabase::ReplaceL() );
TESTTRUEL( err == KErrNone && db != NULL );
if ((err != KErrNone) && (db == NULL))
{
test.Printf(_L("CContactDatabase::ReplaceL failed: leave code %d, db pointer %X"), err, db);
}
delete db;
db = NULL;
TESTTRUEL(CheckCntFilesL( NoDatabases + 1, defaultFilename ));
TESTTRUEL(DefaultDatabaseL());
__UHEAP_MARK;
test.Next(_L("Opening Default: OpenL().\n"));
TRAP( err, db = CContactDatabase::OpenL());
if ((err != KErrNone) && (db == NULL))
{
test.Printf(_L("CContactDatabase::OpenL failed: leave code %d, db pointer %X"), err, db);
}
// these tests Leave, as the database needs to be open to continue
TESTTRUEL( db != NULL ); // db should exist..
TESTTRUEL( err == KErrNone);
// Add contacts to the db
CArrayFix<TContactItemId>* idList=new(ELeave) CArrayFixFlat<TContactItemId>(5);
CleanupStack::PushL(idList);
test.Next(_L("Add new contacts"));
TRAP(err,AddNewContactsL(idList));
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
TESTTRUEL( err == KErrNone || err == KErrDiskFull);
#else
TESTTRUEL( err == KErrNone );
#endif
// Read and modify contacts.
test.Next(_L("Read and modify contacts"));
TRAP(err,EditContactsL(idList));
TESTTRUEL( err == KErrNone );
CleanupStack::PopAndDestroy(idList);
delete db;
db = NULL;
__UHEAP_MARKEND;
//Now test opening another database, should succeed
test.Next(_L("Creating addedFile: CreateL(addedFile).\n"));
TRAP( err, db = CContactDatabase::CreateL(addedFile) );
TESTTRUEL( err == KErrNone && db != NULL );
// check that file with name filename exists.
TESTTRUEL(CheckCntFilesL( NoDatabases + 2, addedFile ));
TESTTRUEL(DefaultDatabaseL());
//Add test to check that the db is opened
delete db;
db = NULL;
// Ensure that RecreateSystemTemplateL does not leave
test.Printf(_L("About to recreate template on:"));
test.Printf(addedFile);
test.Next(_L("Testing: RecreateSystemTemplateL( addedFile )"));
err = KErrNone;
TRAP( err, CContactDatabase::RecreateSystemTemplateL( addedFile ));
#ifdef __SYMBIAN_CNTMODEL_USE_SQLITE__
test.Printf(_L("Recieved %d"),err);
TESTTRUEL( err == KErrNone || err == KErrDiskFull);
#else
TESTTRUEL( err == KErrNone );
#endif
test.Next(_L("Opening file addedFile: OpenL( addedFile )\n"));
TRAP( err, db = CContactDatabase::OpenL( addedFile ));
TESTTRUEL( db != NULL );
TESTTRUEL( err == KErrNone);
// Files existing now: Contacts.cdb & Contacts.cdrchar
// File Deletion //
// So at this point we have a default db and another.
// Time to start deleting them ! Start with DeleteDefaultFileL
test.Next(_L("Deleting default file: DeleteDefaultFileL()\n"));
TRAP( err, CContactDatabase::DeleteDefaultFileL());
TESTTRUEL( err == KErrNone );
// only filename should exist.
TESTTRUEL(CheckCntFilesL( NoDatabases + 1, addedFile ));
TESTTRUEL(CheckNotDefaultContactsFiles());
// Check that an open file is cannot be deleted.
// There is one remaining database which we can now remove using DeleteDatabaseL
test.Next(_L("Deleting database addedFile, should fail first time: DeleteDatabaseL(addedFile)\n"));
TRAP(err, CContactDatabase::DeleteDatabaseL(addedFile));
// Given that this file is currently open it DeleteDatabaseL should fail.
TESTTRUEL(err == KErrInUse);
delete db;
db = NULL;
// We have just opened another we can now delete the one that was originally open.
test.Next(_L("Deleting database addedFile, should pass second time: DeleteDatabaseL(addedFile)\n"));
TRAP(err, CContactDatabase::DeleteDatabaseL(addedFile));
TESTTRUEL(err == KErrNone);
// Check that the file "filename" has been deleted and that
// the default file exists.
TESTTRUEL(CheckCntFilesL( NoDatabases, KContactsFilename, EFalse )); // exercise ListDatabasesL
// NoFileOnPreviousDrive is used by CheckCntFilesL as once we start adding files
// to the second drive, so ListDatabasesL() without a parameter returns the total on
// both drives.
CDesCArray* driveFiles = CContactDatabase::ListDatabasesL(driveArray[driveIdx]);
NoFileOnPreviousDrive = driveFiles->Count();
delete driveFiles;
}
}
LOCAL_C TBool EmptyCntDatabaseDeleteL()
{
/**
@SYMTestCaseID PIM-T-SEC-CNTDBASE-DEF049719-0001
@SYMTestType UT
@SYMTestPriority High
@SYMDEF DEF049719
@SYMTestCaseDependencies CntModel CoreAppsTest
@SYMTestCaseDesc Check that a zero length CntDatabase file can be deleted using CContactDatabase::DeleteDatabaseL()
@SYMTestActions Create an empty file where the default contact database should be.
Try to delete it using CContactDatabase::DeleteDefaultFileL().
Check that it has been deleted.
@SYMTestExpectedResults The empty contact database should be deleted.
*/
test.Next(_L("@SYMTestCaseID:PIM-T-SEC-CNTDBASE-DEF049719-0001 Check zero length CntDatabase can be deleted in CContactDatabase::DeleteDatabaseL()"));
TBool result(EFalse);
// Create an empty file
RFs fs;
User::LeaveIfError(fs.Connect());
RFile file;
RPIMTestServer serv;
User::LeaveIfError(serv.Connect());
serv.CreateEmptyFileL(KCdbPrivate);
serv.Close();
const TDesC& datab=KCdbSecure;
file.Close();
fs.Close();
// Delete the contact database
TRAPD(err,CContactDatabase::DeleteDatabaseL(datab));
result = (err == KErrNone);
if(result)
{
// try to open the file
User::LeaveIfError(fs.Connect());
User::LeaveIfError(serv.Connect());
TInt ret(serv.CheckForFile(KCdbPrivate));
serv.Close();
file.Close();
fs.Close();
// if the file is not found then it has been deleted and test is successful
result= (ret == KErrNotFound);
}
return result;
}
LOCAL_C TBool EmptyCntDatabaseOverwriteL()
{
/**
@SYMTestCaseID PIM-T-SEC-CNTDBASE-DEF049719-0002
@SYMTestType UT
@SYMTestPriority High
@SYMDEF DEF049719
@SYMTestCaseDependencies CntModel CoreAppsTest
@SYMTestCaseDesc Check that a zero length CntDatabase file can't be overwritten using CContactDatabase::CreateL()
@SYMTestActions Create an empty file where the default contact database should be.
Try to overwrite it using CContactDatabase::CreateL().
@SYMTestExpectedResults The empty contact database should not be overwritten.
*/
test.Next(_L("@SYMTestCaseID:PIM-T-SEC-CNTDBASE-DEF049719-0002 Check zero length CntDatabase can't be overwritten in CContactDatabase::CreateL()"));
// Create an empty file
RFs fs;
User::LeaveIfError(fs.Connect());
RFile file;
RPIMTestServer serv;
User::LeaveIfError(serv.Connect());
serv.CreateEmptyFileL(KCdbPrivate);
serv.Close();
const TDesC& datab=KCdbSecure;
file.Close();
fs.Close();
CContactDatabase * tData=NULL;
// create the contact database
TRAPD(err,tData=CContactDatabase::CreateL(datab));
CContactDatabase::DeleteDatabaseL(datab); //Delete the test file after use
delete tData;
return (err == KErrAlreadyExists);
}
LOCAL_C void ContactDatabaseZeroL()
{
TESTTRUEL(EmptyCntDatabaseDeleteL());
TESTTRUEL(EmptyCntDatabaseOverwriteL());
}
/**
@SYMTestCaseID PIM-T-SEC-CNTDBASE-0001
*/
LOCAL_C void DoTestsL()
{
test.Start(_L("@SYMTestCaseID:PIM-T-SEC-CNTDBASE-0001 T_Sec_CntDBase\n"));
User::LeaveIfError(fileServer.Connect());
// Before we do anything else check that there is an MMC drive mapped.
DrivesL();
__UHEAP_MARK;
// This test Switches drives and calls CreateL, ListDatabasesL(TDriveUnit)
FunctionTestL();
__UHEAP_MARKEND;
__UHEAP_MARK;
// This test is similar to the previous, but doesn't use ListDatabasesL(TDriveUnit)
// It also makes use of ReplaceL()
NegTestL();
__UHEAP_MARKEND;
__UHEAP_MARK;
OOMTestingL();
__UHEAP_MARKEND;
__UHEAP_MARK;
ContactDatabaseZeroL();
__UHEAP_MARKEND;
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
// The contacts database uses Active Objects to it must
// be provided with an Active Scheduler.
CActiveScheduler* scheduler=new CActiveScheduler;
if (scheduler)
{
CActiveScheduler::Install(scheduler);
CTrapCleanup* cleanup=CTrapCleanup::New();
if (cleanup)
{
TRAPD(err,DoTestsL());
// reset default drive location
TRAP_IGNORE(CContactDatabase::SetDatabaseDriveL(TDriveUnit(EDriveC), EFalse));
test(err == KErrNone);
delete cleanup;
}
delete scheduler;
}
test(__NB_failures == 0);
test.End();
test.Close();
__UHEAP_MARKEND;
return KErrNone;
}