--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/TEST/t_sqloom3.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,401 @@
+// Copyright (c) 2005-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 "t_sqloom.h"
+
+RTest TheTest(_L("t_sqloom3 test"));
+
+///////////////////////////////////////////////////////////////////////////////////////
+/////////////// RSqlDatabase OOM tests ////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+
+/**
+@SYMTestCaseID SYSLIB-SQL-CT-1615, SYSLIB-SQL-CT-1639
+@SYMTestCaseDesc RSqlDatabase::Create() OOM test - secure and non-secure databases.
+ Precondition: the database does not exist.
+ The test calls RSqlDatabase::Create() while simulating OOM failures and checks
+ that there are no memory and resource leaks.
+ Note: It's possible for a database to be created even after memory allocation
+ has failed. This is because SQLITE reuses some pages of the page cache which
+ have been allocated but are curently not in use. This means it is necessary
+ to delete the database and continue checking for memory and resource leaks
+ even after a database has been created successfully.
+@SYMTestPriority High
+@SYMTestActions RSqlDatabase::Create() OOM test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ5792
+ REQ5793
+ REQ10271
+ REQ10273
+ REQ10274
+*/
+void DoCreateDatabaseOomTest(const TDesC& aDbFileName, TDbType aDbType, TInt aExpectedError, const TDesC8* aConfigStr = NULL)
+ {
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1639 RSqlDatabase::Create() - OOM test"));
+ RSqlSecurityPolicy securityPolicy;
+ CreateTestSecurityPolicy(securityPolicy);
+ enum TMethodType {ENonLeavingMethod, ELeavingMethod};
+ const TMethodType KMethodType[] = {ENonLeavingMethod, ELeavingMethod};
+ for(TInt j=0;j<sizeof(KMethodType)/sizeof(KMethodType[0]);++j)
+ {
+ for(TInt i=0;i<(TInt)(sizeof(TheOomTestType)/sizeof(TheOomTestType[0]));++i)
+ {
+ if(aExpectedError != KErrAlreadyExists)
+ {
+ (void)RSqlDatabase::Delete(aDbFileName);
+ }
+ TInt err = KErrNone;
+ TInt failingAllocationNo = 0;
+ TInt allocationNo = 0;
+ TInt maxAllocationNo = TheOomTestType[i] == EServerSideTest ? KDoCreateDatabaseOomTestAllocLimitServer : KDoCreateDatabaseOomTestAllocLimitClient;
+ while(allocationNo < maxAllocationNo)
+ {
+ MarkHandles();
+ MarkAllocatedCells();
+
+ __UHEAP_MARK;
+
+ RSqlDatabase db;
+
+ SetDbHeapFailure(TheOomTestType[i], ++allocationNo);
+
+ if(KMethodType[j] == ENonLeavingMethod)
+ {
+ err = aDbType == ESecureDb ? db.Create(aDbFileName, securityPolicy, aConfigStr) : db.Create(aDbFileName, aConfigStr);
+ }
+ else
+ {
+ TRAP(err, aDbType == ESecureDb ? db.CreateL(aDbFileName, securityPolicy, aConfigStr) : db.CreateL(aDbFileName, aConfigStr));
+ }
+
+ db.Close();
+ if(err != KErrNoMemory)
+ {
+ TEST2(err, aExpectedError);
+ }
+ else
+ {
+ failingAllocationNo = allocationNo;
+ }
+
+ ResetDbHeapFailure(TheOomTestType[i]);
+
+ if(err == KErrNone && aExpectedError != KErrAlreadyExists)
+ {
+ err = db.Delete(aDbFileName);
+ TEST2(err, KErrNone);
+ }
+
+ __UHEAP_MARKEND;
+
+ CheckAllocatedCells();
+ CheckHandles();
+ }
+ TEST2(err, aExpectedError);
+ PrintEndOfOomTest(TheOomTestType[i], failingAllocationNo + 1);
+ }
+ }
+ RSqlDatabase::Delete(aDbFileName);
+ securityPolicy.Close();
+ }
+
+//"RSqlDatabase::Open()" OOM test
+void OpenDatabaseL(RSqlDatabase& aDb, const TDesC& aDbFileName, TDbType)
+ {
+ TInt err = aDb.Open(aDbFileName);
+ User::LeaveIfError(err);
+ }
+
+//"RSqlDatabase::Exec()" OOM test (8-bit SQL statements), syntax error
+void ExecBadStatement8L(RSqlDatabase& aDb, const TDesC&, TDbType)
+ {
+ _LIT8(KSqlString, "CREATE TABL BBB(Fld1 INTEGER, Fld2 BIGINT, Fld3 DOUBLE, Fld4 TEXT)");
+ TInt err = aDb.Exec(KSqlString);
+ User::LeaveIfError(err);
+ }
+
+//"RSqlDatabase::Exec()" OOM test (16-bit SQL statements), syntax error
+void ExecBadStatement16L(RSqlDatabase& aDb, const TDesC&, TDbType)
+ {
+ _LIT(KSqlString, "CREATE TABLE B!B!B(Fld1 INTEGER, Fld2 BIGINT, Fld3 DOUBLE, Fld4 TEXT)");
+ TInt err = aDb.Exec(KSqlString);
+ User::LeaveIfError(err);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-CT-1813
+@SYMTestCaseDesc RSqlDatabase methods - negative OOM test
+ Precondition: the database exists.
+ The test calls the given as an argument function while simulating OOM failures
+ and checks that there are no memory and resource leaks. The calling function is expected to fail
+ with aExpectedError error.
+@SYMTestPriority High
+@SYMTestActions RSqlDatabase methods - negative OOM tests
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ5792
+ REQ5793
+*/
+void DoDbOomNegativeTest(TDbFuncPtrL aTestFunctionPtrL, const TDesC& aDbFileName, TDbAction aDbAction, TInt aExpectedError)
+ {
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1813 RSqlDatabase - negative OOM test"));
+ for(TInt i=0;i<(TInt)(sizeof(TheOomTestType)/sizeof(TheOomTestType[0]));++i)
+ {
+ TInt err = KErrNoMemory;
+ TInt failingAllocationNo = 0;
+ while(err == KErrNoMemory)
+ {
+ MarkHandles();
+ MarkAllocatedCells();
+
+ __UHEAP_MARK;
+
+ if(TheOomTestType[i] == EServerSideTest)
+ {//If aDbAction is EOpenDb, then we will delay the heap failure simulation, until the database is opened
+ SetDbHeapFailure(TheOomTestType[i], ++failingAllocationNo, aDbAction == EOpenDb);
+ }
+
+ RSqlDatabase db;
+ //if aDbAction is EOpenDb then this is a OOM test different than a test for RSqlDatabase::Open
+ if(aDbAction == EOpenDb)
+ {
+ err = db.Open(aDbFileName);
+ TEST2(err, KErrNone);
+ }
+
+ if(TheOomTestType[i] == EClientSideTest)
+ {
+ SetDbHeapFailure(TheOomTestType[i], ++failingAllocationNo);
+ }
+
+ TRAP(err, (*aTestFunctionPtrL)(db, aDbFileName, ENonSecureDb));
+ db.Close();
+ if(err != KErrNoMemory)
+ {
+ TEST2(err, aExpectedError);
+ }
+
+ ResetDbHeapFailure(TheOomTestType[i]);
+
+ __UHEAP_MARKEND;
+
+ CheckAllocatedCells();
+ CheckHandles();
+ }
+ TEST2(err, aExpectedError);
+ PrintEndOfOomTest(TheOomTestType[i], failingAllocationNo);
+ }
+ RSqlDatabase::Delete(aDbFileName);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+
+//RSqlDatabase - negative OOM tests
+void DbOomNegativeTestsL()
+ {
+ TheTest.Printf(_L("===RSqlDatabase::Open(), non-existing drive\r\n"));
+ _LIT(KDbName1, "A:[1111CCCC]db1.db");
+ DoDbOomNegativeTest(&OpenDatabaseL, KDbName1, ENotOpenDb, KErrNotReady);
+
+ TheTest.Printf(_L("===RSqlDatabase::Open(), non-existing file\r\n"));
+ _LIT(KDbName2, "c:\\test\\nofile.db");
+ DoDbOomNegativeTest(&OpenDatabaseL, KDbName2, ENotOpenDb, KErrNotFound);
+
+ TheTest.Printf(_L("===RSqlDatabase::Open(), zero-length name\r\n"));
+ _LIT(KDbName3, "");
+ DoDbOomNegativeTest(&OpenDatabaseL, KDbName3, ENotOpenDb, KErrBadName);
+
+ TheTest.Printf(_L("===RSqlDatabase::Open(), directory name\r\n"));
+ _LIT(KDbName4, "C:\\TEST\\");
+ DoDbOomNegativeTest(&OpenDatabaseL, KDbName4, ENotOpenDb, KErrBadName);
+
+ TheTest.Printf(_L("===RSqlDatabase::Create(), secure database already exists\r\n"));
+ RSqlSecurityPolicy securityPolicy;
+ CreateTestSecurityPolicy(securityPolicy);
+ RSqlDatabase db;
+ TInt err = db.Create(KSecureDb2, securityPolicy);
+ TEST2(err, KErrNone);
+ db.Close();
+ securityPolicy.Close();
+ DoCreateDatabaseOomTest(KSecureDb2, ESecureDb, KErrAlreadyExists);
+
+ TheTest.Printf(_L("===RSqlDatabase::Create(), database already exists\r\n"));
+ err = db.Create(KTestDb2);
+ TEST2(err, KErrNone);
+ db.Close();
+ DoCreateDatabaseOomTest(KTestDb2, ENonSecureDb, KErrAlreadyExists);
+
+ TheTest.Printf(_L("===RSqlDatabase::Exec(), 8-bit SQL, syntax error\r\n"));
+ err = db.Create(KTestDb);
+ TEST2(err, KErrNone);
+ db.Close();
+ DoDbOomNegativeTest(&ExecBadStatement8L, KTestDb, EOpenDb, KSqlErrGeneral);
+
+ TheTest.Printf(_L("===RSqlDatabase::Exec(), 16-bit SQL, syntax error\r\n"));
+ err = db.Create(KTestDb);
+ TEST2(err, KErrNone);
+ db.Close();
+ DoDbOomNegativeTest(&ExecBadStatement16L, KTestDb, EOpenDb, KSqlErrGeneral);
+ }
+
+void DEF114297PrepareStmtL(RSqlDatabase& aDb, RSqlStatement& aStmt)
+ {
+ _LIT(KSelectSql, "SELECT e.* FROM edge AS e, node AS n1, node AS n2 WHERE n1.name = 'alice' AND n2.name = 'bob' AND e.orig = n1.id AND e.dest = n2.id ORDER BY n2.name DESC");
+ TInt err = aStmt.Prepare(aDb, KSelectSql);
+ User::LeaveIfError(err);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-4004
+@SYMTestCaseDesc Test for DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL.
+ The test does an OOM test for RSqlStatement::Prepare() using a specific SELECT SQL statement.
+@SYMTestPriority High
+@SYMTestActions Test for DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF DEF114297
+*/
+void DEF114297()
+ {
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4004 ===DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL "));
+ (void)RSqlDatabase::Delete(KTestDb);
+ RSqlDatabase db;
+ TInt err = db.Create(KTestDb);
+ TEST2(err, KErrNone);
+ err = db.Exec(_L("CREATE TABLE node(id INTEGER PRIMARY KEY,name TEXT)"));
+ TEST2(err, 1);
+ err = db.Exec(_L("CREATE INDEX node_idx ON node(name)"));
+ TEST2(err, 1);
+ err = db.Exec(_L("CREATE TABLE edge(orig INTEGER REFERENCES node,dest INTEGER REFERENCES node,PRIMARY KEY(orig, dest))"));
+ TEST2(err, 1);
+ err = db.Exec(_L("CREATE INDEX edge_idx ON edge(dest,orig)"));
+ TEST2(err, 1);
+ err = db.Exec(_L("INSERT INTO node(id,name) VALUES(1,'alice')"));
+ TEST2(err, 1);
+ err = db.Exec(_L("INSERT INTO node(id,name) VALUES(2,'bob')"));
+ TEST2(err, 1);
+ err = KErrNoMemory;
+ TInt failingAllocationNo = 0;
+ while(err == KErrNoMemory)
+ {
+ MarkHandles();
+ MarkAllocatedCells();
+
+ __UHEAP_MARK;
+
+ SetHeapFailure(EServerSideTest, ++failingAllocationNo);
+
+ RSqlStatement stmt;
+ TRAP(err, DEF114297PrepareStmtL(db, stmt));
+ stmt.Close();
+ if(err != KErrNoMemory)
+ {
+ TEST2(err, KErrNone);
+ }
+
+ ResetHeapFailure(EServerSideTest);
+
+ __UHEAP_MARKEND;
+
+ CheckAllocatedCells();
+ CheckHandles();
+ }
+ db.Close();
+ (void)RSqlDatabase::Delete(KTestDb);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-4011
+@SYMTestCaseDesc Test for DEF115815 - SELECT random()&1==-1 causes sql server to crash.
+ The test does an OOM test for RSqlStatement::Prepare() using a specific SELECT SQL statement.
+@SYMTestPriority High
+@SYMTestActions Test for DEF115815 - SELECT random()&1==-1 causes sql server to crash.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF DEF115815
+*/
+void DEF115815()
+ {
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4011 ===DEF115815 - SELECT random()&1==-1 causes sql server to crash "));
+ (void)RSqlDatabase::Delete(KTestDb);
+ RSqlDatabase db;
+ TInt err = db.Create(KTestDb);
+ TEST2(err, KErrNone);
+ err = db.Exec(_L("CREATE TABLE node(id INTEGER)"));
+ TEST2(err, 1);
+ err = KErrNoMemory;
+ TInt failingAllocationNo = 0;
+ while(err == KErrNoMemory)
+ {
+ MarkHandles();
+ MarkAllocatedCells();
+
+ __UHEAP_MARK;
+
+ SetHeapFailure(EServerSideTest, ++failingAllocationNo);
+
+ RSqlStatement stmt;
+ err = stmt.Prepare(db, _L("SELECT random()&1==-1"));
+ stmt.Close();
+ if(err != KErrNoMemory)
+ {
+ TEST2(err, KErrNone);
+ }
+
+ ResetHeapFailure(EServerSideTest);
+
+ __UHEAP_MARKEND;
+
+ CheckAllocatedCells();
+ CheckHandles();
+ }
+ db.Close();
+ (void)RSqlDatabase::Delete(KTestDb);
+ }
+
+void DoTestsL()
+ {
+ TheTest.Start(_L("SQL OOM-3 tests"));
+
+ DbOomNegativeTestsL();
+
+ DEF114297();
+
+ DEF115815();
+ }
+
+TInt E32Main()
+ {
+ TheTest.Title();
+
+ CTrapCleanup* tc = CTrapCleanup::New();
+
+ __UHEAP_MARK;
+
+ CreateTestDir();
+ DeleteTestFiles();
+
+ TRAPD(err, DoTestsL());
+ DeleteTestFiles();
+ TEST2(err, KErrNone);
+
+ __UHEAP_MARKEND;
+
+ TheTest.End();
+ TheTest.Close();
+
+ delete tc;
+
+ User::Heap().Check();
+ return KErrNone;
+ }