sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_fail.h" sl@0: sl@0: #include "crccheck.h" sl@0: sl@0: #undef __UHEAP_MARK sl@0: #define __UHEAP_MARK sl@0: #undef __UHEAP_MARKEND sl@0: #define __UHEAP_MARKEND sl@0: #undef __UHEAP_CHECK sl@0: #define __UHEAP_CHECK(a) sl@0: sl@0: LOCAL_D TDBMS_CRCChecks TheCrcChecker; sl@0: sl@0: #ifndef __linux__ //No CRC test on LINUX sl@0: #ifdef __TOOLS2__ sl@0: const TPtrC KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_FAIL.CRC"); sl@0: #else sl@0: const TPtrC KCrcRecord=_L("C:\\dbms-tst\\T_FAIL.CRC"); sl@0: #endif sl@0: #endif sl@0: sl@0: #define CRCCHECK (TheCrcChecker.GenerateCrcL(KTestDatabase)) sl@0: sl@0: sl@0: _LIT(KTestTitle,"T_FAIL: DBMS Failure mode test"); sl@0: GLDEF_D RTest test(KTestTitle); sl@0: GLDEF_D RDbs TheDbs; sl@0: GLDEF_D RDbNamedDatabase TheDatabase; sl@0: GLDEF_D TClientHeap KClientHeap; sl@0: GLDEF_D TServerHeap KServerHeap; sl@0: sl@0: sl@0: LOCAL_D CTrapCleanup* TheTrapCleanup; sl@0: LOCAL_D RFs TheFs; sl@0: LOCAL_D RDbView TheView; sl@0: LOCAL_D RDbTable TheTable; sl@0: LOCAL_D RDbRowSet::TAccess Access; sl@0: LOCAL_D CDbColSet* TheColSet; sl@0: LOCAL_D CDbKey* TheKey; sl@0: LOCAL_D const TDesC* TheSql; sl@0: LOCAL_D TBuf<64> TheFormat; sl@0: sl@0: const TInt KTestCleanupStack=0x20; sl@0: sl@0: #ifndef __TOOLS2__ sl@0: const TPtrC KTestDatabase=_L("C:\\dbms-tst\\t_fail.db"); sl@0: #else sl@0: const TPtrC KTestDatabase=_L(".\\dbms-tst\\t_fail.db"); sl@0: #endif sl@0: sl@0: _LIT(TableName,"Table1"); sl@0: _LIT(TableName2,"Table_two"); sl@0: _LIT(TableNameX,"Bad Table Name"); sl@0: _LIT(IndexName,"Index1"); sl@0: _LIT(IndexName2,"Index2"); sl@0: _LIT(Column1,"column_one"); sl@0: _LIT(Column1Fold,"COLUMN_ONE"); sl@0: _LIT(Column2,"column_2"); sl@0: _LIT(Column2X,"column_2%"); sl@0: _LIT(SimpleSql,"select * from Table1"); sl@0: _LIT(UpdateSql,"update Table1 SET column_2='hello'"); sl@0: sl@0: //const TPtrC ComplexSql(_S("select * from Table1 where column_one<0 and not column_one is null or column_2 not like '*fred*' and column_2>'m' order by column_one desc")); sl@0: const TPtrC ComplexSql[]= sl@0: { sl@0: _S("select * from Table1 where column_one<0 and column_one is null"), sl@0: _S("select * from Table1 where column_one<0 and (column_one is null and column_2 like '')"), sl@0: _S("select * from Table1 where (column_one<0 and column_one is null) and column_2 like ''"), sl@0: _S("select * from Table1 where (column_one<0 and column_one is null) and (column_2 like '' and column_one>0)"), sl@0: _S("select * from Table1 where (column_one<0 and column_one is null) and (column_2 like '' and column_one>0 and column_one is null)"), sl@0: _S("select * from Table1 where (column_one<0 and column_one is null and column_one = 10) and (column_2 like '' and column_one>0 and column_one is null)"), sl@0: _S("select * from Table1 where column_one<0 and column_one is null and column_one = 10 and column_2 like '' and column_one>0 and column_one is null") sl@0: }; sl@0: sl@0: struct SSqlErrors sl@0: { sl@0: const TText* iSql; sl@0: TInt iError; sl@0: }; sl@0: sl@0: LOCAL_D SSqlErrors const BadSql[]= sl@0: { sl@0: {_S("sponge"),KErrArgument}, sl@0: {_S("select * from widget"),KErrNotFound}, sl@0: {_S("select * from Table1 where x = 0"),KErrNotFound}, sl@0: {_S("select * from Table1 where x 0 like"),KErrArgument}, sl@0: {_S("select * from Table1 where column_2>'a' and column_one<'z'"),KErrGeneral}, sl@0: {_S("select from Table1"),KErrArgument}, sl@0: {_S("select x, from Table1"),KErrArgument}, sl@0: {_S("select x from Table1"),KErrNotFound}, sl@0: {_S("select column_2 column_one from Table1"),KErrArgument}, sl@0: {_S("select * from Table1 order by x"),KErrNotFound}, sl@0: {_S("select * from Table1 order column_one"),KErrArgument}, sl@0: {_S("select * from Table1 order by column_one down"),KErrArgument} sl@0: }; sl@0: sl@0: GLDEF_C void Connect() sl@0: { sl@0: #ifndef __TOOLS2__ sl@0: TInt r=TheDbs.Connect(); sl@0: test (r==KErrNone); sl@0: TheDbs.ResourceMark(); sl@0: #endif sl@0: } sl@0: sl@0: GLDEF_C void Disconnect() sl@0: { sl@0: #ifndef __TOOLS2__ sl@0: TheDbs.ResourceCheck(); sl@0: TheDbs.Close(); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: //SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version sl@0: LOCAL_C void DbCreateL() sl@0: { sl@0: User::LeaveIfError(TheDatabase.Replace(TheFs,KTestDatabase,TheFormat)); sl@0: } sl@0: sl@0: //SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version sl@0: LOCAL_C void DbOpenL() sl@0: { sl@0: User::LeaveIfError(TheDatabase.Open(TheFs,KTestDatabase,TheFormat)); sl@0: CleanupClosePushL(TheDatabase); sl@0: delete TheDatabase.TableNamesL(); // force a schema load sl@0: CleanupStack::Pop(); sl@0: } sl@0: sl@0: //SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version sl@0: LOCAL_C void DbShareL() sl@0: { sl@0: User::LeaveIfError(TheDatabase.Open(TheDbs,KTestDatabase,TheFormat)); sl@0: CleanupClosePushL(TheDatabase); sl@0: delete TheDatabase.TableNamesL(); // force a schema load sl@0: CleanupStack::Pop(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0612 sl@0: @SYMTestCaseDesc Database validity test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for opening and closing of database sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestOpen() sl@0: { sl@0: _LIT(KFileNotFound,"not a database"); sl@0: TInt r=TheDatabase.Open(TheFs,KFileNotFound); sl@0: test (r==KErrNotFound || r==KErrPathNotFound); sl@0: // sl@0: _LIT(KPathNotFound,"C:\\not a path\\database.db"); sl@0: r=TheDatabase.Open(TheFs,KPathNotFound); sl@0: #ifndef __TOOLS2__ sl@0: test (r==KErrPathNotFound); sl@0: #else sl@0: // Tools2 f32 does not return KErrPathNotFound sl@0: test( (r==KErrPathNotFound) || (r==KErrNotFound)); sl@0: #endif sl@0: // sl@0: _LIT(KNotFormat,"not.a.dbx"); sl@0: r=TheDatabase.Open(TheFs,KFileNotFound,KNotFormat); sl@0: test (r==KErrNotFound || r==KErrPathNotFound); sl@0: // sl@0: DbCreateL(); sl@0: TheDatabase.Close(); sl@0: TInt err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: r=TheDatabase.Open(TheFs,KTestDatabase,TUid::Uid(0x01234567).Name()); sl@0: test (r==KErrNone); // New code has no loadable drivers, it is irrelevant to expect error here sl@0: TheDatabase.Close(); // We have added it here because previous statement does not return error anymore sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: // sl@0: RFile f; sl@0: r=f.Replace(TheFs,KTestDatabase,EFileWrite); sl@0: test (r==KErrNone); sl@0: TCheckedUid type(KDirectFileStoreLayoutUid); sl@0: r=f.Write(type.Des()); sl@0: test (r==KErrNone); sl@0: f.Close(); sl@0: r=TheDatabase.Open(TheFs,KTestDatabase); sl@0: test (r==KErrNotSupported); sl@0: // sl@0: _LIT(KDefaultFormat,"epoc"); sl@0: r=TheDatabase.Open(TheFs,KTestDatabase,KDefaultFormat); sl@0: test (r==KErrNotSupported); // We expect not supported db here sl@0: } sl@0: sl@0: class TClient : public TContext sl@0: { sl@0: public: sl@0: TClient() {} sl@0: private: sl@0: void OpenDbL() const sl@0: {DbOpenL();} sl@0: }; sl@0: class TServer : public TContext sl@0: { sl@0: public: sl@0: TServer() {} sl@0: private: sl@0: void OpenDbL() const sl@0: {DbShareL();} sl@0: }; sl@0: sl@0: const TClient KClient; sl@0: const TServer KServer; sl@0: sl@0: void TFail::Test(const THeapFail& aHeap,const TContext* aContext) sl@0: { sl@0: TInt ii; sl@0: TInt errCode; sl@0: for (ii=1;;++ii) sl@0: { sl@0: if (aContext) sl@0: { sl@0: TRAP(errCode, aContext->OpenDbL()); sl@0: if(errCode != KErrNone) sl@0: return; sl@0: } sl@0: aHeap.Fail(ii); sl@0: aHeap.Mark(); sl@0: TRAPD(r,RunL()); sl@0: aHeap.Reset(); sl@0: if (r==KErrNone) sl@0: break; sl@0: test(r==KErrNoMemory); sl@0: if (aContext) sl@0: { sl@0: TheDatabase.Close(); sl@0: TRAPD(lc, errCode = CRCCHECK); sl@0: test(errCode == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: aHeap.Check(); sl@0: } sl@0: End(); sl@0: if (aContext) sl@0: { sl@0: TheDatabase.Close(); sl@0: TRAPD(lc, errCode = CRCCHECK); sl@0: test(errCode == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: aHeap.Check(); sl@0: } sl@0: sl@0: class TFailCreateDatabase : public TFail sl@0: { sl@0: void RunL() sl@0: {DbCreateL();} sl@0: void End() sl@0: { sl@0: TheDatabase.Close(); sl@0: TInt err; sl@0: TRAPD(lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: }; sl@0: sl@0: class TFailOpenDatabase : public TFail sl@0: { sl@0: void RunL() sl@0: {DbOpenL();} sl@0: void End() sl@0: { sl@0: TheDatabase.Close(); sl@0: TInt err; sl@0: TRAPD(lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: }; sl@0: sl@0: class TFailShareDatabase : public TFail sl@0: { sl@0: void RunL() sl@0: {DbShareL();} sl@0: void End() sl@0: { sl@0: TheDatabase.Close(); sl@0: // Unfortunately it is not possible to generate CRC checks here. The sl@0: // database on a number of occasions is still open by another instance. sl@0: // This causes a KErrInUse in the CRC check code for Symbian, but sl@0: // works on TOOLS2, thus giving probably spurious mismatches. sl@0: // TInt err; sl@0: // TRAPD(lc, err = CRCCHECK); sl@0: // RDebug::Print(_L("ERROR %d\n"), err); sl@0: // test(err == KErrNone); sl@0: // test(lc == KErrNone); sl@0: } sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0613 sl@0: @SYMTestCaseDesc Tests for allocation failures on creating a database sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for allocation failure for differently sourced databases sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void Origins() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0613 Allocation failures on Creating a database ")); sl@0: TFailCreateDatabase t1; sl@0: t1.Test(KClientHeap); sl@0: // sl@0: test.Next(_L("Fail to create existing database")); sl@0: #ifndef __TOOLS2__ sl@0: TUint att; sl@0: TInt r=TheFs.Att(KTestDatabase,att); sl@0: test (r==KErrNone); sl@0: #else sl@0: TInt r; sl@0: #endif sl@0: r=TheDatabase.Create(TheFs,KTestDatabase,TheFormat); sl@0: test (r==KErrAlreadyExists); sl@0: #ifndef __TOOLS2__ sl@0: r=TheFs.Att(KTestDatabase,att); sl@0: test (r==KErrNone); sl@0: #endif sl@0: // sl@0: test.Next(_L("Allocation failures on Open")); sl@0: TFailOpenDatabase t2; sl@0: t2.Test(KClientHeap); sl@0: // sl@0: test.Next(_L("Allocation failures on 1st Share")); sl@0: Connect(); sl@0: TFailShareDatabase t3; sl@0: t3.Test(KClientHeap); sl@0: t3.Test(KServerHeap); sl@0: // sl@0: test.Next(_L("Allocation failures on 2nd Share")); sl@0: DbShareL(); sl@0: RDbNamedDatabase temp=TheDatabase;TheDatabase=RDbNamedDatabase(); sl@0: t3.Test(KClientHeap); sl@0: t3.Test(KServerHeap); sl@0: temp.Close(); sl@0: Disconnect(); sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: class TFailCreateTable : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.CreateTable(TableName,*TheColSet));} sl@0: }; sl@0: sl@0: class TFailAlterTable : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.AlterTable(TableName,*TheColSet));} sl@0: }; sl@0: sl@0: class TFailDropTable : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.DropTable(TableName));} sl@0: }; sl@0: sl@0: class TFailCreateIndex : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.CreateIndex(IndexName,TableName,*TheKey));} sl@0: }; sl@0: sl@0: class TFailDropIndex : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.DropIndex(IndexName,TableName));} sl@0: }; sl@0: sl@0: class TFailGetObject : public TFail sl@0: { sl@0: protected: sl@0: void End() sl@0: {delete iObject;} sl@0: protected: sl@0: CBase* iObject; sl@0: }; sl@0: sl@0: class TFailDatabaseTables : public TFailGetObject sl@0: { sl@0: void RunL() sl@0: {iObject=TheDatabase.TableNamesL();} sl@0: }; sl@0: sl@0: class TFailDatabaseColSet : public TFailGetObject sl@0: { sl@0: void RunL() sl@0: {iObject=TheDatabase.ColSetL(TableName);} sl@0: }; sl@0: sl@0: class TFailDatabaseIndexes : public TFailGetObject sl@0: { sl@0: void RunL() sl@0: {iObject=TheDatabase.IndexNamesL(TableName);} sl@0: }; sl@0: sl@0: class TFailDatabaseKeys : public TFailGetObject sl@0: { sl@0: void RunL() sl@0: {iObject=TheDatabase.KeyL(IndexName,TableName);} sl@0: }; sl@0: sl@0: const TInt KRowCount=60; sl@0: sl@0: LOCAL_C void WriteTableL() sl@0: { sl@0: DbOpenL(); sl@0: TInt r=TheTable.Open(TheDatabase,TableName); sl@0: test (r==KErrNone); sl@0: TheDatabase.Begin(); sl@0: for (TInt ii=0;iiAddL(TDbCol(Column1,EDbColInt32)); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableNameX,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Invalid column name")); sl@0: col->AddL(TDbCol(Column2X,EDbColBit)); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Duplicate column name")); sl@0: col->Remove(Column2X); sl@0: col->AddL(TDbCol(Column1Fold,EDbColBit)); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Invalid column type")); sl@0: col->Remove(Column1); sl@0: col->AddL(TDbCol(Column2,TDbColType(-1))); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Invalid maximum length")); sl@0: col->Remove(Column2); sl@0: col->AddL(TDbCol(Column2,EDbColInt32,0)); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Invalid attributes")); sl@0: col->Remove(Column2); sl@0: TDbCol cc(Column2,EDbColInt32); sl@0: cc.iAttributes=13; sl@0: col->AddL(cc); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Adding/dropping a table name twice")); sl@0: col->Remove(Column2); sl@0: col->AddL(TDbCol(Column2,EDbColText8)); sl@0: __UHEAP_MARK; sl@0: test(TheDatabase.CreateTable(TableName,*col)==KErrNone); sl@0: test(TheDatabase.CreateTable(TableName,*col)==KErrAlreadyExists); sl@0: test(TheDatabase.DropTable(TableNameX)!=KErrNone); sl@0: test(TheDatabase.DropTable(TableName)==KErrNone); sl@0: test(TheDatabase.DropTable(TableName)==KErrNotFound); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Adding and dropping indexes")); sl@0: test(TheDatabase.CreateTable(TableName,*col)==KErrNone); sl@0: TheDatabase.Close(); sl@0: TInt err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: CDbKey *key=CDbKey::NewLC(); sl@0: __UHEAP_MARK; sl@0: DbOpenL(); sl@0: test(TheDatabase.CreateIndex(IndexName,TableName,*key)!=KErrNone); sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: __UHEAP_MARKEND; sl@0: key->AddL(Column2X()); sl@0: __UHEAP_MARK; sl@0: DbOpenL(); sl@0: test(TheDatabase.CreateIndex(IndexName,TableName,*key)!=KErrNone); sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: __UHEAP_MARKEND; sl@0: key->Clear(); sl@0: key->AddL(Column1()); sl@0: __UHEAP_MARK; sl@0: DbOpenL(); sl@0: test(TheDatabase.CreateIndex(TableNameX,TableName,*key)!=KErrNone); sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: __UHEAP_CHECK(0); sl@0: DbOpenL(); sl@0: test(TheDatabase.CreateIndex(IndexName,TableNameX,*key)!=KErrNone); sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: __UHEAP_MARKEND; sl@0: __UHEAP_MARK; sl@0: DbOpenL(); sl@0: test(TheDatabase.CreateIndex(IndexName,TableName,*key)==KErrNone); sl@0: test(TheDatabase.CreateIndex(IndexName,TableName,*key)==KErrAlreadyExists); sl@0: test(TheDatabase.DropIndex(TableNameX,TableName)!=KErrNone); sl@0: test(TheDatabase.DropIndex(IndexName,TableNameX)!=KErrNone); sl@0: test(TheDatabase.DropIndex(IndexName,TableName)==KErrNone); sl@0: test(TheDatabase.DropIndex(IndexName,TableName)==KErrNotFound); sl@0: test(TheDatabase.DropTable(TableName)==KErrNone); sl@0: test(TheDatabase.DropIndex(IndexName,TableName)==KErrNotFound); sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Allocation failure during DDL")); sl@0: TFailCreateTable fct; sl@0: TFailAlterTable fat; sl@0: TFailDropTable fdt; sl@0: TFailCreateIndex fci; sl@0: TFailDropIndex fdi; sl@0: TheColSet=CDbColSet::NewL(); sl@0: TheColSet->AddL(TDbCol(Column1,EDbColUint16)); sl@0: TheKey=CDbKey::NewL(); sl@0: TheKey->AddL(Column1()); sl@0: fct.Test(KClientHeap,KClient); sl@0: WriteTableL(); sl@0: TheColSet->AddL(TDbCol(Column2,EDbColText)); sl@0: fat.Test(KClientHeap,KClient); sl@0: fci.Test(KClientHeap,KClient); sl@0: fdi.Test(KClientHeap,KClient); sl@0: fdt.Test(KClientHeap,KClient); sl@0: // sl@0: test.Next(_L("Allocation failure during server DDL")); sl@0: Connect(); sl@0: TheColSet->Remove(Column2); sl@0: fct.Test(KClientHeap,KServer); sl@0: WriteTableL(); sl@0: TheColSet->AddL(TDbCol(Column2,EDbColText)); sl@0: fat.Test(KClientHeap,KServer); sl@0: fci.Test(KClientHeap,KServer); sl@0: fdi.Test(KClientHeap,KServer); sl@0: fdt.Test(KClientHeap,KServer); sl@0: // sl@0: TheColSet->Remove(Column2); sl@0: fct.Test(KServerHeap,KServer); sl@0: WriteTableL(); sl@0: TheColSet->AddL(TDbCol(Column2,EDbColText)); sl@0: fat.Test(KServerHeap,KServer); sl@0: fci.Test(KServerHeap,KServer); sl@0: fdi.Test(KServerHeap,KServer); sl@0: fdt.Test(KServerHeap,KServer); sl@0: Disconnect(); sl@0: // sl@0: delete TheColSet; sl@0: delete TheKey; sl@0: sl@0: // sl@0: test.Next(_L("Allocation failure on schema enquiry")); sl@0: DbCreateL(); sl@0: test(TheDatabase.CreateTable(TableName,*col)==KErrNone); sl@0: test(TheDatabase.CreateIndex(IndexName,TableName,*key)==KErrNone); sl@0: CleanupStack::PopAndDestroy(2); // columns set and key sl@0: TheDatabase.Close(); sl@0: err = CRCCHECK; sl@0: test(err == KErrNone); sl@0: TFailDatabaseTables t4; sl@0: TFailDatabaseColSet t5; sl@0: TFailDatabaseIndexes t6; sl@0: TFailDatabaseKeys t7; sl@0: t4.Test(KClientHeap,KClient); sl@0: t5.Test(KClientHeap,KClient); sl@0: t6.Test(KClientHeap,KClient); sl@0: t7.Test(KClientHeap,KClient); sl@0: // sl@0: test.Next(_L("Allocation failure on server schema enquiry")); sl@0: Connect(); sl@0: t4.Test(KClientHeap,KServer); sl@0: t4.Test(KServerHeap,KServer); sl@0: t5.Test(KClientHeap,KServer); sl@0: t5.Test(KServerHeap,KServer); sl@0: t6.Test(KClientHeap,KServer); sl@0: t6.Test(KServerHeap,KServer); sl@0: t7.Test(KClientHeap,KServer); sl@0: t7.Test(KServerHeap,KServer); sl@0: Disconnect(); sl@0: test.End(); sl@0: } sl@0: sl@0: class TFailOpenTable : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheTable.Open(TheDatabase,TableName,Access));} sl@0: void End() sl@0: {TheTable.Close();} sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0614 sl@0: @SYMTestCaseDesc Tests for allocation failure on opening and closing of database sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for opening and closing of database sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestTable(const THeapFail& aHeap,const TContext& aContext) sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0614 Allocation failure on Open ")); sl@0: TFailOpenTable fot; sl@0: Access=RDbRowSet::EUpdatable; sl@0: fot.Test(aHeap,aContext); sl@0: Access=RDbRowSet::EReadOnly; sl@0: fot.Test(aHeap,aContext); sl@0: Access=RDbRowSet::EInsertOnly; sl@0: fot.Test(aHeap,aContext); sl@0: // sl@0: test.Next(_L("Open invalid table")); sl@0: aContext.OpenDbL(); sl@0: __UHEAP_MARK; sl@0: TInt r=TheTable.Open(TheDatabase,TableNameX); sl@0: test (r!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Set invalid index")); sl@0: r=TheTable.Open(TheDatabase,TableName); sl@0: test (r==KErrNone); sl@0: __UHEAP_MARK; sl@0: r=TheTable.SetIndex(IndexName2); sl@0: test (r!=KErrNone); sl@0: __UHEAP_MARKEND; sl@0: // sl@0: test.Next(_L("Allocation failure on 2nd Open")); sl@0: RDbTable table(TheTable); sl@0: Access=RDbRowSet::EUpdatable; sl@0: fot.Test(aHeap); sl@0: Access=RDbRowSet::EReadOnly; sl@0: fot.Test(aHeap); sl@0: Access=RDbRowSet::EInsertOnly; sl@0: fot.Test(aHeap); sl@0: table.Close(); sl@0: TheDatabase.Close(); sl@0: r = CRCCHECK; sl@0: test(r == KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void TestTableDDL(const TContext& aContext) sl@0: { sl@0: test.Start(_L("DDL while open")); sl@0: aContext.OpenDbL(); sl@0: TInt r=TheTable.Open(TheDatabase,TableName); sl@0: test (r==KErrNone); sl@0: CDbColSet* set=CDbColSet::NewLC(); sl@0: set->AddL(TDbCol(Column1,EDbColText)); sl@0: r=TheDatabase.CreateTable(TableName2,*set); sl@0: test (r==KErrNone); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrNone); sl@0: TheTable.Close(); sl@0: r=TheTable.Open(TheDatabase,TableName2); sl@0: test (r==KErrNone); sl@0: // sl@0: set->AddL(TDbCol(Column2,EDbColUint32)); sl@0: r=TheDatabase.AlterTable(TableName2,*set); sl@0: test (r==KErrNone); sl@0: CleanupStack::PopAndDestroy(); // set sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrDisconnected); sl@0: TheTable.Reset(); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrDisconnected); sl@0: TheTable.Close(); sl@0: r=TheTable.Open(TheDatabase,TableName2); sl@0: test (r==KErrNone); sl@0: // sl@0: CDbKey* key=CDbKey::NewLC(); sl@0: key->AddL(Column2()); sl@0: r=TheDatabase.CreateIndex(IndexName2,TableName,*key); sl@0: test (r==KErrNone); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrNone); sl@0: r=TheDatabase.DropIndex(IndexName2,TableName); sl@0: test (r==KErrNone); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrNone); sl@0: // sl@0: r=TheDatabase.CreateIndex(IndexName,TableName2,*key); sl@0: test (r==KErrNone); sl@0: CleanupStack::PopAndDestroy(); // key sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrDisconnected); sl@0: TheTable.Close(); sl@0: r=TheTable.Open(TheDatabase,TableName2); sl@0: test (r==KErrNone); sl@0: // sl@0: r=TheDatabase.DropIndex(IndexName,TableName2); sl@0: test (r==KErrNone); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrDisconnected); sl@0: TheTable.Close(); sl@0: r=TheTable.Open(TheDatabase,TableName2); sl@0: test (r==KErrNone); sl@0: // sl@0: r=TheDatabase.DropTable(TableName2); sl@0: test (r==KErrNone); sl@0: TRAP(r,TheTable.CountL(TheTable.EQuick)); sl@0: test (r==KErrDisconnected); sl@0: TheTable.Close(); sl@0: TheDatabase.Close(); sl@0: r = CRCCHECK; sl@0: test(r == KErrNone); sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void Table() sl@0: { sl@0: test.Start(_L("Testing Client-side")); sl@0: TestTable(KClientHeap,KClient); sl@0: TestTableDDL(KClient); sl@0: test.Next(_L("Testing Client-Server")); sl@0: Connect(); sl@0: TestTable(KClientHeap,KServer); sl@0: TestTable(KServerHeap,KServer); sl@0: TestTableDDL(KServer); sl@0: Disconnect(); sl@0: test.End(); sl@0: } sl@0: sl@0: class TFailExecuteSQL : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheDatabase.Execute(*TheSql));} sl@0: void End() sl@0: {} sl@0: }; sl@0: sl@0: class TFailPrepareView : public TFail sl@0: { sl@0: void RunL() sl@0: {User::LeaveIfError(TheView.Prepare(TheDatabase,*TheSql,Access));} sl@0: void End() sl@0: {TheView.Close();} sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0615 sl@0: @SYMTestCaseDesc Tests for allocation failure on prepare sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Tests for error on updating a row set data sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void TestView(const THeapFail& aHeap,const TContext& aContext) sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0615 Allocation failure on Prepare ")); sl@0: TFailPrepareView fpv; sl@0: TheSql=&SimpleSql; sl@0: Access=RDbRowSet::EUpdatable; sl@0: fpv.Test(aHeap,aContext); sl@0: Access=RDbRowSet::EReadOnly; sl@0: fpv.Test(aHeap,aContext); sl@0: Access=RDbRowSet::EInsertOnly; sl@0: fpv.Test(aHeap,aContext); sl@0: // sl@0: test.Next(_L("Allocation failure on Prepare (complex SQL)")); sl@0: for (TUint ii=0;ii 10"))); sl@0: TInt step = 0; sl@0: for(TInt err=1;err>0;++step) sl@0: { sl@0: err = dbUpdate.Next(); sl@0: User::LeaveIfError(err); sl@0: } sl@0: test(step > 1);//just to be sure that the test executes dbUpdate.Next() more than once sl@0: CleanupStack::PopAndDestroy(&dbUpdate); sl@0: } sl@0: virtual void End() sl@0: { sl@0: TheDatabase.Close(); sl@0: TInt err; sl@0: TRAPD( lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-UT-3414 sl@0: @SYMTestCaseDesc "Incremental update" operations - OOM test. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Create a test database with one table and insert some records there (> 100). sl@0: Run an "incremental update" operation in OOM loop. sl@0: @SYMTestExpectedResults The test should not fail or panic. sl@0: @SYMDEF INC101720 sl@0: */ sl@0: LOCAL_C void IncrementalUpdateTest(const THeapFail& aHeap) sl@0: { sl@0: //Create a test shared database with a table sl@0: TheDatabase.Close(); sl@0: TInt err, lc; sl@0: #ifndef __TOOLS2__ sl@0: TheDbs.Close(); sl@0: #endif sl@0: TRAP(lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: #ifndef __TOOLS2__ sl@0: err = TheDbs.Connect(); sl@0: test(err == KErrNone); sl@0: #endif sl@0: err = TheDatabase.Replace(TheFs, KTestDatabase); sl@0: test(err == KErrNone); sl@0: TheDatabase.Close(); sl@0: TRAP(lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: err = TheDatabase.Open(TheDbs, KTestDatabase); sl@0: test(err == KErrNone); sl@0: //Create a test table and fill the table with enough test records (> 100) sl@0: err = TheDatabase.Execute(_L("CREATE TABLE A(Id COUNTER, Id2 INTEGER, Name LONG VARCHAR)")); sl@0: test(err == KErrNone); sl@0: const TInt KTestRecCount = 110; sl@0: err = TheDatabase.Begin(); sl@0: test(err == KErrNone); sl@0: for(TInt i=0;i sql; sl@0: // TUint32 id = Math::Random() % KTestRecCount; sl@0: TUint32 id = (i^0x55555555) % KTestRecCount; sl@0: sql.Format(KSqlFmtStr, id + 1); sl@0: err = TheDatabase.Execute(sql); sl@0: test(err == 1); sl@0: } sl@0: err = TheDatabase.Commit(); sl@0: test(err == KErrNone); sl@0: //The OOM test sl@0: TFailIncrementalUpdate testObj; sl@0: testObj.Test(aHeap); sl@0: //Cleanup sl@0: TheDatabase.Close(); sl@0: #ifndef __TOOLS2__ sl@0: TheDbs.Close(); sl@0: #endif sl@0: TRAP(lc, err = CRCCHECK); sl@0: test(err == KErrNone); sl@0: test(lc == KErrNone); sl@0: } sl@0: sl@0: // sl@0: // Testing the DBMS for failure modes sl@0: // sl@0: LOCAL_C void doMain() sl@0: { sl@0: test.Start(_L("Class RDbNamedDatabase")); sl@0: __UHEAP_MARK; sl@0: Origins(); sl@0: __UHEAP_CHECK(0); sl@0: __UHEAP_MARK; sl@0: // secure shared, not supported on tools2. sl@0: // Origins2(); sl@0: sl@0: __UHEAP_CHECK(0); sl@0: test.Next(_L("Class RDbDatabase")); sl@0: Database(); sl@0: __UHEAP_CHECK(0); sl@0: test.Next(_L("Class RDbTable")); sl@0: Table(); sl@0: __UHEAP_CHECK(0); sl@0: test.Next(_L("Class RDbView")); sl@0: View(); sl@0: __UHEAP_MARKEND; sl@0: test.End(); sl@0: } sl@0: sl@0: // sl@0: // Prepare the test directory. sl@0: // sl@0: LOCAL_C void setupTestDirectory() sl@0: { sl@0: TInt r=TheFs.Connect(); sl@0: test(r==KErrNone); sl@0: // sl@0: r=TheFs.MkDir(KTestDatabase); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: } sl@0: sl@0: // sl@0: // Initialise the cleanup stack. sl@0: // sl@0: LOCAL_C void setupCleanup() sl@0: { sl@0: TheTrapCleanup=CTrapCleanup::New(); sl@0: test(TheTrapCleanup!=NULL); sl@0: TRAPD(r,\ sl@0: {\ sl@0: for (TInt i=KTestCleanupStack;i>0;i--)\ sl@0: CleanupStack::PushL((TAny*)0);\ sl@0: CleanupStack::Pop(KTestCleanupStack);\ sl@0: }); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void DeleteDataFile(const TDesC& aFullName) sl@0: { sl@0: RFs fsSession; sl@0: TInt err = fsSession.Connect(); sl@0: if(err == KErrNone) sl@0: { sl@0: TEntry entry; sl@0: if(fsSession.Entry(aFullName, entry) == KErrNone) sl@0: { sl@0: RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); sl@0: err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); sl@0: } sl@0: err = fsSession.Delete(aFullName); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: fsSession.Close(); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: test.Title(); sl@0: setupTestDirectory(); sl@0: setupCleanup(); sl@0: __UHEAP_MARK; sl@0: // sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0612 Locating a database ")); sl@0: TRAPD(r,TestOpen()); sl@0: test(r==KErrNone); sl@0: sl@0: // These are in t_fail2, secure shared tests, unsupported. sl@0: // PrepareDbFmtString(); sl@0: // TRAP(r,TestOpen2()); sl@0: // test(r==KErrNone); sl@0: sl@0: test.Next(_L("Standard database")); sl@0: TRAP(r,doMain()); sl@0: test(r==KErrNone); sl@0: test.Next(_L("Secure database")); sl@0: TRAP(r,doMain()); sl@0: test(r==KErrNone); sl@0: test.Next(_L("ISAM database")); sl@0: TheFormat=_S("epoc[12345678]"); sl@0: TRAP(r,Origins()); sl@0: test(r==KErrNone); sl@0: sl@0: // TRAP(r,Origins2()); sl@0: // test(r==KErrNone); sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3414 \"Incremental update\" - client test ")); sl@0: IncrementalUpdateTest(KClientHeap); sl@0: test.End(); sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-UT-3414 \"Incremental update\" - client-server test ")); sl@0: IncrementalUpdateTest(KServerHeap); sl@0: test.End(); sl@0: test.Printf(_L("Waiting for server exit\n")); sl@0: const TUint KExitDelay=6*0x100000; // ~6 seconds sl@0: User::After(KExitDelay); sl@0: sl@0: ::DeleteDataFile(KTestDatabase); // clean up data file used by this test - must be done before call to End() - DEF047652 sl@0: sl@0: #ifndef __linux__ sl@0: TInt err; sl@0: #ifndef __TOOLS2__ sl@0: TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord)); sl@0: test(err==KErrNone); sl@0: test(lc==KErrNone); sl@0: #else sl@0: TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord)); sl@0: TPtrC errmsg; sl@0: TheCrcChecker.ErrorReportL(err, errmsg); sl@0: RDebug::Print(errmsg); sl@0: test(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk); sl@0: #endif sl@0: #endif sl@0: sl@0: test.End(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: delete TheTrapCleanup; sl@0: TheFs.Close(); sl@0: test.Close(); sl@0: return 0; sl@0: }