// Copyright (c) 2001-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:
// This contains CTestCase which is the base class for all the TestCase DLLs
//
//
// EPOC includes
#include <e32base.h>
#include <commdb.h>
#include <f32file.h>
// Test system includes
#ifdef SYMBIAN_OLD_EXPORT_LOCATION
#include <comms-infras/commdb/protection/protectdb.h>
#include <comms-infras/commdb/protection/protectcpdb.h>
#else
//these headers are user includes in the new env.
#include "protectdb.h"
#include "protectcpdb.h"
#endif
#include <cdbpreftable.h>
#include "CDBSTD.H"
#include <networking/log.h>
#include <networking/teststep.h>
#include "Teststepcommdb.h"
#include <networking/testsuite.h>
#include "TestSuiteCommdb.h"
// constructor
CTestStepCommDb::CTestStepCommDb()
{
iRemoteObjects = EFalse;
}
// destructor
CTestStepCommDb::~CTestStepCommDb()
{
popAndDestroyDatabaseObjects();
}
// file copy
void CTestStepCommDb::copyFileL(const TDesC& anOld,const TDesC& aNew)
{
// create a fileserver
RFs fileSystem;
// connect to file server
User::LeaveIfError(fileSystem.Connect());
CleanupClosePushL(fileSystem);
// create a file manager
CFileMan * fileMan = CFileMan::NewL(fileSystem);
CleanupStack::PushL(fileMan);
// parse the filenames
TParse source;
User::LeaveIfError(source.Set(anOld, NULL, NULL));
// parse the filenames
TParse target;
User::LeaveIfError(target.Set(aNew, NULL, NULL));
// do the copy
User::LeaveIfError(fileMan->Copy(source.FullName(), target.FullName(), CFileMan::EOverWrite));
// make read/write
User::LeaveIfError(fileSystem.SetAtt(source.FullName(),NULL, KEntryAttReadOnly));
// clean up
CleanupStack::PopAndDestroy(fileMan);
CleanupStack::PopAndDestroy(&fileSystem);
}
void CTestStepCommDb::deleteFileL(const TDesC& aFileName)
{
// create a fileserver
RFs fileSystem;
User::LeaveIfError(fileSystem.Connect());
CleanupClosePushL(fileSystem);
Log(_L("Set file to read-write in order to delete"));
// Remove read only flag
TInt ret = fileSystem.SetAtt(aFileName, 0, KEntryAttReadOnly);
if (ret == KErrNotFound)
{
// If file already removed then no need to delete it
Log(_L("File not found"));
CleanupStack::PopAndDestroy(&fileSystem);
return;
}
User::LeaveIfError(ret);
// Delete file
User::LeaveIfError(fileSystem.Delete(aFileName));
Log(_L("deleted file"));
// clean up
CleanupStack::PopAndDestroy(&fileSystem);
}
void CTestStepCommDb::DeleteCurrentDatabaseL()
{
RDbs rDbs;
// User::LeaveIfError(rDbs.Connect());
TInt ret(KErrNone);
ret = rDbs.Connect();
if(ret!=KErrNone)
{
Log(_L("CTestStepCommDb::DeleteCurrentDatabaseL : rDbs.Connect FAILED with %d"),ret );
User::Leave(ret);
}
CleanupClosePushL(rDbs);
TName commDb(KCDrive);
commDb.Append(KDbBaseName);
TUid KCommsDbFileUid = { 0x10004e1d };
// May need to make several
// attempts if it is transiently locked; report these and if
// not successful after a number of attempts report this and abort
TInt remainingTries = 5;
// TInt ret (KErrNone);
while(remainingTries-- > 0)
{
ret = rDbs.DeleteDatabase(commDb, KCommsDbFileUid);
if(ret == KErrNone || ret == KErrPathNotFound || ret == KErrNotFound)
{
ret = KErrNone;
break;
}
else
{
Log(_L("CTestStepCommDb::DeleteCurrentDatabaseL : rDbs.DeleteDatabase FAILED to delete %S %S with %d"),&KCDrive,&KDbBaseName,ret);
}
}
User::LeaveIfError(ret);
CleanupStack::PopAndDestroy(&rDbs);
}
void CTestStepCommDb::CopyDatabaseL(const TDesC& aSource)
{
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
RDbs rDbs;
User::LeaveIfError(rDbs.Connect());
CleanupClosePushL(rDbs);
const TUid KCommsDbFileUid = {0x10004e1d};
TInt remainingTries = 5;
TInt ret (KErrNone);
DeleteCurrentDatabaseL();
while(remainingTries-- > 0)
{
ret = rDbs.CopyDatabase(aSource, KDbFileName, KCommsDbFileUid);
if(ret == KErrNone || ret == KErrPathNotFound || ret == KErrNotFound)
{
break;
}
}
User::LeaveIfError(ret);
CleanupStack::PopAndDestroy(&rDbs);
CleanupStack::PopAndDestroy(&fs);
}
TInt CTestStepCommDb::copyTestDatabase( TDatabaseNumber aDbNumber )
{
(void)aDbNumber;
return KErrNone;
}
TInt CTestStepCommDb::copyDatabaseToDefault( TDatabaseNumber aDbNumber )
{
(void)aDbNumber;
return KErrNone;
}
TBool CTestStepCommDb::openDbAndViewL( const TDesC16& aTable )
{
TBool created = EFalse;
//Only create Db and view objects if they're not already created
if ( ! iTheDb )
{
iTheDb=CCommsDatabase::NewL();
created = ETrue;
}
if ( !iTheView )
{
iTheView=iTheDb->OpenTableLC( aTable );
CleanupStack::Pop(); //no need to put it on the cleanup stack
}
return created;
}
TVerdict CTestStepCommDb::doTestStepPostambleL()
{
if ( iTheView )
{
delete iTheView;
iTheView = 0;
}
if ( iTheDb )
{
delete iTheDb;
iTheDb = 0;
}
return EPass;
}
void CTestStepCommDb::popAndDestroyDatabaseObjects()
{
// doTestStepPostambleL();
}
TBool CTestStepCommDb::openDbL()
{
TBool created = EFalse;
if ( !iTheDb )
{
//Only open the Db if its not already open
TRAPD(ret,iTheDb=CCommsDatabase::NewL());
if(ret!=KErrNone)
{
Log(_L("CTestStepCommDb::openDbL : CCommsDatabase::NewL LEFT with %d"),ret);
User::Leave(ret);
}
created = ETrue;
}
return created;
}
void CTestStepCommDb::setRemoteDatabaseObjects( CCommsDatabase* aDb, CCommsDbTableView* aDbView )
{
if ( !iTheDb )
{
//make sure that no-one else has already set the objects
iTheDb = aDb;
iTheView = aDbView;
iRemoteObjects = ETrue;
}
}
void CTestStepCommDb::clearRemoteDatabaseObjects()
{
if( iRemoteObjects )
{
//Only clear objects if they were previously set remotly
iTheDb = 0;
iTheView = 0;
}
}
TInt CTestStepCommDb::executeStepL()
{
return KErrGeneral;
}
TInt CTestStepCommDb::executeStep(CTestStepCommDb& aTestStep)
{
TInt r,ret= KErrNone;
TRAP( r, ret = aTestStep.executeStepL() );
if ( r != KErrNone )
ret = r;
return ret;
}
TInt CTestStepCommDb::executeStep( )
{
TInt ret=0;
TRAPD( r, ret = executeStepL() );
if ( r != KErrNone )
ret = r;
return ret;
}
//
//This heap failure member function is used when a test step needs a Database and a View
//object.
//
TInt CTestStepCommDb::doTestStepWithHeapFailureL( CTestStepCommDb& aTestStep, TInt aReturnValue)
{
TInt ret=0;
for (TInt i=1; i< KHeapFailure ; i++)
{
aTestStep.doTestStepPreambleL();
__UHEAP_FAILNEXT(i);
ret = aTestStep.executeStep();
__UHEAP_RESET;
aTestStep.doTestStepPostambleL();
if ( ret == KErrNoMemory )
{
//The heap failure has been trapped correctly
continue;
}
else if ( ret == aReturnValue )
{
//Test step normal behaviour
TPtrC ExpectedErrortxt = CLog::EpocErrorToText(ret);
Log(_L("%s PASSED heap failure test, i = %d return code==%S"),
aTestStep.iTestStepName.PtrZ(), i, &ExpectedErrortxt );
break;
}
else
{
// test step has not returned the exepected error value ( which was either KErrNoMemory or aReturnValue )
TPtrC unexpectedErrortxt = CLog::EpocErrorToText(ret);
TPtrC Error = CLog::EpocErrorToText(aReturnValue);
Log(_L("%s *FAILED* heap failure test, i=%d return code:%S expected:%S"),
aTestStep.iTestStepName.PtrZ(), i, &unexpectedErrortxt, &Error );
iTestStepResult = EFail;
break;
}
}
return KErrNone;
}
void CTestStepCommDb::CheckTableIsProtectedL(CCommsDbProtectTableView* aTable)
{
TESTL(iTheDb->BeginTransaction()==KErrNone);
if(aTable->GotoFirstRecord()==KErrNone)
{
// Check settings on Record
RDbRowSet::TAccess tableAccess = RDbRowSet::EUpdatable;
TInt ret = aTable->GetTableAccess(tableAccess);
TESTL(ret == KErrNone);
TESTL(tableAccess == RDbRowSet::EReadOnly);
// Test that first record cannot be updated
TRAP(ret,UpdateRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
// Test that cannot delete first record
TRAP(ret,DeleteRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
// Test that cannot insert new record
TRAP(ret,InsertRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
aTable->GotoFirstRecord();
}
TESTL(iTheDb->CommitTransaction()==KErrNone);
}
void CTestStepCommDb::CheckTableIsProtectedL(CCommsDbProtectConnectPrefTableView* aTable)
{
TESTL(iTheDb->BeginTransaction()==KErrNone);
if(aTable->GotoFirstRecord()==KErrNone)
{
// Check settings on Record
RDbRowSet::TAccess tableAccess = RDbRowSet::EUpdatable;
TInt ret = aTable->GetTableAccess(tableAccess);
TESTL(ret == KErrNone);
TESTL(tableAccess == RDbRowSet::EReadOnly);
// Test that first record cannot be updated
TRAP(ret,UpdateRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
// Test that cannot delete first record
TRAP(ret,DeleteRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
// Test that cannot insert new record
TRAP(ret,InsertRecordL(aTable,KErrAccessDenied));
TESTL(ret == KErrNone);
aTable->GotoFirstRecord();
}
TESTL(iTheDb->CommitTransaction()==KErrNone);
}
void CTestStepCommDb::CheckTableIsNotProtectedL(CCommsDbProtectTableView* aTable)
{
TESTL(iTheDb->BeginTransaction()==KErrNone);
if(aTable->GotoFirstRecord()==KErrNone)
{
// Check settings on Table
RDbRowSet::TAccess tableAccess = RDbRowSet::EReadOnly;
TInt ret = aTable->GetTableAccess(tableAccess);
TESTL(ret == KErrNone);
TESTL(tableAccess == RDbRowSet::EUpdatable);
// Test can update first record
TRAP(ret,UpdateRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
// Test that can delete record
TRAP(ret,DeleteRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
// Test that can insert new record
TRAP(ret,InsertRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
aTable->GotoFirstRecord();
}
TESTL(iTheDb->CommitTransaction()==KErrNone);
}
void CTestStepCommDb::CheckTableIsNotProtectedL(CCommsDbProtectConnectPrefTableView* aTable)
{
TESTL(iTheDb->BeginTransaction()==KErrNone);
if(aTable->GotoFirstRecord()==KErrNone)
{
// Check settings on Table
RDbRowSet::TAccess tableAccess = RDbRowSet::EReadOnly;
TInt ret = aTable->GetTableAccess(tableAccess);
TESTL(ret == KErrNone);
TESTL(tableAccess == RDbRowSet::EUpdatable);
// Test can update first record
TRAP(ret,UpdateRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
// Test that can delete record
TRAP(ret,DeleteRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
// Test that can insert new record
TRAP(ret,InsertRecordL(aTable,KErrNone));
TESTL(ret == KErrNone);
aTable->GotoFirstRecord();
}
TESTL(iTheDb->CommitTransaction()==KErrNone);
}
void CTestStepCommDb::GoToPositionL(CCommsDbProtectTableView* aTable,TInt aPos)
{
TESTL(aTable->GotoFirstRecord()==KErrNone);
for (TInt i = 0; i < aPos; i++)
{
TESTL(aTable->GotoNextRecord()==KErrNone);
}
}
void CTestStepCommDb::ProtectRecordL(CCommsDbProtectTableView* aTable, TInt aResult)
{
TESTL(aTable->ProtectRecord()==aResult);
}
void CTestStepCommDb::ProtectRecordL(CCommsDbProtectConnectPrefTableView* aTable, TInt aResult)
{
TESTL(aTable->ProtectRecord()==aResult);
}
void CTestStepCommDb::UnprotectRecordL(CCommsDbProtectTableView* aTable, TInt aResult)
{
TESTL(aTable->UnprotectRecord()==aResult);
}
void CTestStepCommDb::UnprotectRecordL(CCommsDbProtectConnectPrefTableView* aTable, TInt aResult)
{
TESTL(aTable->UnprotectRecord()==aResult);
}
void CTestStepCommDb::UpdateRecordL(CCommsDbProtectTableView* aTable, TInt aResult)
{
TESTL(aTable->UpdateRecord()==aResult);
if (aResult == KErrNone)
{
ModifyRecordL(aTable);
TESTL(aTable->PutRecordChanges()==KErrNone);
}
}
void CTestStepCommDb::UpdateRecordL(CCommsDbProtectConnectPrefTableView* aTable, TInt aExpectedResult)
{
TUint32 Ranking;
CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref RecordData;
TInt ErrVal = ChangeCPRankingL(aTable, Ranking); // Try modifying a field.
TESTL(ErrVal == aExpectedResult);
if (ErrVal == KErrNone)
{
// The change was allowed, so check it actually happened.
aTable->ReadConnectionPreferenceL(RecordData);
TESTL(Ranking == RecordData.iRanking);
}
}
void CTestStepCommDb::DeleteRecordL(CCommsDbProtectTableView* aTable, TInt aResult)
{
TESTL(aTable->DeleteRecord()==aResult);
}
void CTestStepCommDb::DeleteRecordL(CCommsDbProtectConnectPrefTableView* aTable, TInt aExpectedResult)
{
TRAPD(ErrVal, aTable->DeleteConnectionPreferenceL());
TESTL(ErrVal == aExpectedResult);
}
void CTestStepCommDb::InsertRecordL(CCommsDbProtectTableView* aTable, TInt aExpectedResult)
{
TUint32 recordId;
TInt ret = aTable->InsertRecord(recordId);
TESTL(ret==aExpectedResult||ret==KErrAlreadyExists); //for some tables insertion fails
//because they can only have
//one record (i.e. DEFAULT_GPRS)
if (ret == KErrNone)
{
PopulateInsertedRecordL(aTable);
TESTL(aTable->PutRecordChanges()==KErrNone);
}
}
void CTestStepCommDb::InsertRecordL(CCommsDbProtectConnectPrefTableView* aTable, TInt aExpectedResult)
{
CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref PrefData1, PrefData2;
PrefData1.iRanking = 0;
PrefData1.iDirection = ECommDbConnectionDirectionOutgoing;
PrefData1.iDialogPref = ECommDbDialogPrefWarn;
PrefData1.iBearer.iBearerSet = ECommDbBearerCSD;
PrefData1.iBearer.iIapId = 1;
TRAPD(ErrVal, aTable->InsertConnectionPreferenceL(PrefData1));
TESTL(ErrVal==aExpectedResult); //for some tables insertion fails
//because they can only have
//one record (i.e. DEFAULT_GPRS)
if (ErrVal == KErrNone)
{
aTable->ReadConnectionPreferenceL(PrefData2);
TESTL(PrefData1 == PrefData2);
}
}
#define TEST_FCN(_F_) {TRAPD(ret,_F_); TESTL(ret == KErrNone);}
void CTestStepCommDb::ModifyRecordL(CCommsDbProtectTableView* aTable)
//
// Modify some field in current record
//
{
TEST_FCN(aTable->WriteTextL(TPtrC(COMMDB_NAME),_L("test")));
}
// Extract the protection state for the current record,
// and leave if it's not the state expected
void CTestStepCommDb::CheckRecordAccessL(CCommsDbProtectConnectPrefTableView* aTable, TInt aExpectedAccess)
{
TInt FoundAccess;
// Set the state to one not expected, so it will fail if not explicitly changed
if (aExpectedAccess == RDbRowSet::EUpdatable)
FoundAccess = RDbRowSet::EReadOnly;
else
FoundAccess = RDbRowSet::EUpdatable;
TESTL(aTable->GetRecordAccess(FoundAccess) == KErrNone);
TESTL(aExpectedAccess == FoundAccess);
}
void CTestStepCommDb::PopulateInsertedRecordL(CCommsDbProtectTableView* aTable)
//
// Populate minimal set of fields in current newly inserted record.
//
{
TBuf<50> tableName;
aTable->GetTableName(tableName);
if (tableName == TPtrC(DIAL_OUT_ISP))
{
TEST_FCN(aTable->WriteTextL(TPtrC(COMMDB_NAME),_L("Inserted Service")));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_DIAL_RESOLUTION),ETrue));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_USE_LOGIN_SCRIPT),EFalse));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_PROMPT_FOR_LOGIN),ETrue));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_IF_PROMPT_FOR_AUTH),ETrue));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_IP_ADDR_FROM_SERVER),ETrue));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_IP_DNS_ADDR_FROM_SERVER),ETrue));
TEST_FCN(aTable->WriteBoolL(TPtrC(ISP_IP6_DNS_ADDR_FROM_SERVER),ETrue));
}
// EXTEND OR MODIFY this function if want to use different table
}
// Just a utility function - for checking the protection of the Connection Preferences
// table and its records, we just try changing the ranking field of the first one.
TInt CTestStepCommDb::ChangeCPRankingL(CCommsDbProtectConnectPrefTableView* aTable, TUint32& Ranking)
{
CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref RecordData;
aTable->ReadConnectionPreferenceL(RecordData);
if(RecordData.iRanking == 1)
Ranking = 0;
else
Ranking = 1;
TRAPD(ErrVal, aTable->ChangeConnectionPreferenceRankL(Ranking));
return(ErrVal);
}
#undef TEST_FCN