sl@0: // Copyright (c) 2007-2010 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 //MStreamBuf sl@0: #include sl@0: #include "SqlResourceProfiler.h" sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: RTest TheTest(_L("t_sqlapi2 test")); sl@0: RSqlDatabase TheDb; sl@0: RSqlStatement TheStmt; sl@0: sl@0: _LIT(KTestDir, "c:\\test\\"); sl@0: _LIT(KTestDbName1, "c:\\test\\t_sqlapi2_1.db"); sl@0: _LIT(KTestDbName2, "c:\\private\\1111C1EF\\t_sqlapi2_2.db");//t_sqlapi2 app - private database sl@0: sl@0: _LIT(KDbInjectedName1, "DELETE FROM symbian_settings;c:\\test\\A.db"); sl@0: _LIT(KDbInjectedName2, "c:\\test\\A.db;DELETE FROM symbian_settings;"); sl@0: sl@0: const TInt KBufLen = 8192; sl@0: TBuf TheBuf; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void DeleteTestFiles() sl@0: { sl@0: TheStmt.Close(); sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KDbInjectedName2); sl@0: (void)RSqlDatabase::Delete(KDbInjectedName1); sl@0: (void)RSqlDatabase::Delete(KTestDbName2); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: //Test macros and functions sl@0: void Check(TInt aValue, TInt aLine) sl@0: { sl@0: if(!aValue) sl@0: { sl@0: DeleteTestFiles(); sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: void Check(TInt aValue, TInt aExpected, TInt aLine) sl@0: { sl@0: if(aValue != aExpected) sl@0: { sl@0: DeleteTestFiles(); sl@0: RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); sl@0: TheTest(EFalse, aLine); sl@0: } sl@0: } sl@0: #define TEST(arg) ::Check((arg), __LINE__) sl@0: #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CreateTestEnv() sl@0: { sl@0: RFs fs; sl@0: TInt err = fs.Connect(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: err = fs.MkDir(KTestDir); sl@0: TEST(err == KErrNone || err == KErrAlreadyExists); sl@0: sl@0: err = fs.CreatePrivatePath(EDriveC); sl@0: TEST(err == KErrNone || err == KErrAlreadyExists); sl@0: sl@0: fs.Close(); sl@0: } sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-3512 sl@0: @SYMTestCaseDesc RSqlStatement::ColumnCount() - SELECT statements test sl@0: The test creates a database with a table and then checks the ColumnCount() sl@0: return result for the following statements: sl@0: - select all columns; sl@0: - select a subset; sl@0: - select an expression; sl@0: - select a constant; sl@0: - multi-table select; sl@0: - select a function; sl@0: - select plus sub-query; sl@0: @SYMTestPriority High sl@0: @SYMTestActions RSqlStatement::ColumnCount() test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ8035 sl@0: */ sl@0: void ColumnCountTest() sl@0: { sl@0: sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: //Create table 1 sl@0: err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT,Id2 INTEGER,Data BLOB)")); sl@0: TEST(err >= 0); sl@0: sl@0: err = TheDb.Exec(_L("INSERT INTO A VALUES(1,'AAA',6234567890,x'11AAFD0C771188')")); sl@0: TEST2(err, 1); sl@0: sl@0: //Select all columns (SELECT *) sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: TInt cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 4); sl@0: TheStmt.Close(); sl@0: //Select all columns (SELECT a,b,c...) sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT Id,Name,Id2,Data FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 4); sl@0: TheStmt.Close(); sl@0: //Select column subset sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT Id,Name,Data FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 3); sl@0: TheStmt.Close(); sl@0: //Select column subset + expression sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT Id,Id+Id2 FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 2); sl@0: TheStmt.Close(); sl@0: //Select column subset + constant sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT Id,Id2,345.78 FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 3); sl@0: TheStmt.Close(); sl@0: //Select SQL function sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT COUNT(*) FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 1); sl@0: TheStmt.Close(); sl@0: //Create table 2 sl@0: err = TheDb.Exec(_L("CREATE TABLE B(Id INTEGER, S INTEGER)")); sl@0: TEST(err >= 0); sl@0: err = TheDb.Exec(_L("INSERT INTO B VALUES(1,25)")); sl@0: TEST2(err, 1); sl@0: //Multitable select sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT A.Id,B.S FROM A,B WHERE A.Id = B.Id")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 2); sl@0: TheStmt.Close(); sl@0: //Select + Subquery sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT Id FROM A WHERE (SELECT S FROM B WHERE A.Id = B.Id) > 10")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 1); sl@0: TheStmt.Close(); sl@0: //Cleanup sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-3513 sl@0: @SYMTestCaseDesc RSqlStatement::ColumnCount() - DDL and DML statements test sl@0: The test creates a database with a table and then checks the ColumnCount() return result for sl@0: DML statements (INSERT/UPDATE/DELETE) and DDL statements (CREATE TABLE/INDEX, DROP TABLE?INDEX). sl@0: The column count for DML and DDL statements should be 0. sl@0: @SYMTestPriority High sl@0: @SYMTestActions RSqlStatement::ColumnCount() test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ8035 sl@0: */ sl@0: void ColumnCountTest2() sl@0: { sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: //Create table sl@0: err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT,Id2 INTEGER,Data BLOB)")); sl@0: TEST(err >= 0); sl@0: err = TheDb.Exec(_L("INSERT INTO A VALUES(1,'AAA',6234567890,x'11AAFD0C771188')")); sl@0: TEST2(err, 1); sl@0: //INSERT statement sl@0: err = TheStmt.Prepare(TheDb, _L("INSERT INTO A(Id,Id2) VALUES(:P1,:P2)")); sl@0: TEST2(err, KErrNone); sl@0: TInt cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //UPDATE statement sl@0: err = TheStmt.Prepare(TheDb, _L("UPDATE A SET Id2=100 WHERE Id=:P1")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //DELETE statement sl@0: err = TheStmt.Prepare(TheDb, _L("DELETE FROM A WHERE Id=:P1")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //CREATE TABLE statement sl@0: err = TheStmt.Prepare(TheDb, _L("CREATE TABLE B AS SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //DROP TABLE statement sl@0: err = TheStmt.Prepare(TheDb, _L("DROP TABLE A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //CREATE INDEX statement sl@0: err = TheStmt.Prepare(TheDb, _L("CREATE INDEX I ON A(Id)")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: err = TheStmt.Exec(); sl@0: TEST(err >= 0); sl@0: TheStmt.Close(); sl@0: //DROP INDEX statement sl@0: err = TheStmt.Prepare(TheDb, _L("DROP INDEX I")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //CREATE TRIGGER statement sl@0: err = TheStmt.Prepare(TheDb, sl@0: _L("CREATE TRIGGER Trg BEFORE DELETE ON A \ sl@0: BEGIN \ sl@0: SELECT CASE WHEN ((SELECT Id2 FROM A WHERE A.Id = old.Id) > 0) \ sl@0: THEN RAISE (ABORT, 'Id2 > 0') \ sl@0: END;\ sl@0: END;")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //CREATE VIEW statement sl@0: err = TheStmt.Prepare(TheDb, _L("CREATE VIEW V AS SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: err = TheStmt.Exec(); sl@0: TEST(err >= 0); sl@0: TheStmt.Close(); sl@0: //DROP VIEW statement sl@0: err = TheStmt.Prepare(TheDb, _L("DROP VIEW V")); sl@0: TEST2(err, KErrNone); sl@0: cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, 0); sl@0: TheStmt.Close(); sl@0: //Cleanup sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-3514 sl@0: @SYMTestCaseDesc RSqlStatement::DeclaredColumnType() test sl@0: The test creates a database with a table and then checks the DeclaredColumnType() return result for: sl@0: - select all column from the table and check their types; sl@0: - multi-table select plus column type checks; sl@0: - select expression - the expected column type is ESqlInt; sl@0: - select constant - the expected column type is ESqlInt; sl@0: @SYMTestPriority High sl@0: @SYMTestActions RSqlStatement::ColumnCount() test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ8035 sl@0: */ sl@0: void DeclaredColumnTypeTest() sl@0: { sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: const char* KColTypeNames[] = sl@0: {"INTEGER", "LONG INTEGER", "INT", "SHORT INT", "SMALL INT", "TINY INT", "SHORT", "INT64", sl@0: "TEXT", "LONGTEXT", "CLOB", "CHAR", "CHARACTER(20)", "LONG TEXT", sl@0: "BINARY", "LONG BINARY", "LONGBINARY", "BLOB", "LONGBLOB", "LONG BLOB", sl@0: "REAL", "FLOAT", "DOUBLE", "LONG DOUBLE", sl@0: "LONG LONG", "BOO HOO"}; sl@0: const TSqlColumnType KColTypes[] = sl@0: {ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt, sl@0: ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,ESqlText, sl@0: ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary, sl@0: ESqlReal,ESqlReal,ESqlReal,ESqlReal, sl@0: ESqlInt,ESqlInt}; sl@0: const TInt KColTypeCnt = sizeof(KColTypes) / sizeof(KColTypes[0]); sl@0: TEST2(sizeof(KColTypeNames) / sizeof(KColTypeNames[0]), KColTypeCnt); sl@0: //Create table 1 sl@0: TBuf8<512> sql; sl@0: sql.Copy(_L8("CREATE TABLE T(")); sl@0: for(TInt i=0;i= 0); sl@0: //Select all columns (SELECT *) sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT * FROM T")); sl@0: TEST2(err, KErrNone); sl@0: TInt cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, KColTypeCnt); sl@0: TSqlColumnType colType; sl@0: for(TInt i=0;i= 0); sl@0: //Multi-table select sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT T.A1,T2.Id,T.A9,T2.Data FROM T,T2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.DeclaredColumnType(0, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlInt); sl@0: err = TheStmt.DeclaredColumnType(1, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlInt); sl@0: err = TheStmt.DeclaredColumnType(2, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlText); sl@0: err = TheStmt.DeclaredColumnType(3, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlBinary); sl@0: TheStmt.Close(); sl@0: //Select expression sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES FROM t2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.DeclaredColumnType(0, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlInt); sl@0: TheStmt.Close(); sl@0: //Select constant sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES, 55.89 FROM t2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.DeclaredColumnType(1, colType); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colType, ESqlInt); sl@0: TheStmt.Close(); sl@0: //Cleanup sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4017 sl@0: @SYMTestCaseDesc RSqlStatement::ColumnName(TInt, TPtrC&) test sl@0: The test creates a database with a table and then checks the ColumnName() return result for: sl@0: - select all column from the table and check their names; sl@0: - multi-table select plus column name checks; sl@0: - select expression - the expected column name is RES sl@0: - select constant - the expected column type is 55.89 sl@0: @SYMTestPriority High sl@0: @SYMTestActions RSqlStatement::ColumnName() test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMCR RMAD-7B7EV5 sl@0: Add SQL Server APIs to retrieve column and parameter names sl@0: */ sl@0: void ColumnNameTest() sl@0: { sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: const char* KColTypeNames[] = sl@0: {"INTEGER", "LONG INTEGER", "INT", "SHORT INT", "SMALL INT", "TINY INT", "SHORT", "INT64", sl@0: "TEXT", "LONGTEXT", "CLOB", "CHAR", "CHARACTER(20)", "LONG TEXT", sl@0: "BINARY", "LONG BINARY", "LONGBINARY", "BLOB", "LONGBLOB", "LONG BLOB", sl@0: "REAL", "FLOAT", "DOUBLE", "LONG DOUBLE", sl@0: "LONG LONG", "BOO HOO"}; sl@0: const TSqlColumnType KColTypes[] = sl@0: {ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt, sl@0: ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,ESqlText, sl@0: ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary, sl@0: ESqlReal,ESqlReal,ESqlReal,ESqlReal, sl@0: ESqlInt,ESqlInt}; sl@0: const TInt KColTypeCnt = sizeof(KColTypes) / sizeof(KColTypes[0]); sl@0: TEST2(sizeof(KColTypeNames) / sizeof(KColTypeNames[0]), KColTypeCnt); sl@0: //Create table 1 sl@0: TBuf8<512> sql; sl@0: sql.Copy(_L8("CREATE TABLE T(")); sl@0: for(TInt i=0;i= 0); sl@0: //Select all columns (SELECT *) sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT * FROM T")); sl@0: TEST2(err, KErrNone); sl@0: TInt cnt = TheStmt.ColumnCount(); sl@0: TEST2(cnt, KColTypeCnt); sl@0: TPtrC colName; sl@0: TBuf<128> expectedColName; sl@0: for(TInt i=0;i= 0); sl@0: //Multi-table select sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT T.A1,T2.Id,T.A9,T2.DATA FROM T,T2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.ColumnName(0, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("A1")), 0); sl@0: err = TheStmt.ColumnName(1, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("Id")), 0); sl@0: err = TheStmt.ColumnName(2, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("A9")), 0); sl@0: err = TheStmt.ColumnName(3, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("DATA")), 0); sl@0: TheStmt.Close(); sl@0: //Select expression sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES FROM t2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.ColumnName(0, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("RES")), 0); sl@0: //Too big column index sl@0: err = TheStmt.ColumnName(1323, colName); sl@0: TEST2(err, KErrNotFound); sl@0: //Negative column index sl@0: err = TheStmt.ColumnName(-100, colName); sl@0: TEST2(err, KErrNotFound); sl@0: TheStmt.Close(); sl@0: //Select constant sl@0: err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES, 55.89 FROM t2")); sl@0: TEST2(err, KErrNone); sl@0: err = TheStmt.ColumnName(1, colName); sl@0: TEST2(err, KErrNone); sl@0: TEST2(colName.Compare(_L("55.89")), 0); sl@0: TheStmt.Close(); sl@0: //Cleanup sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4018 sl@0: @SYMTestCaseDesc RSqlStatement::ParameterName(TInt, TPtrC&) and RSqlStatement::ParamName(TInt, TPtrC&) test sl@0: DML test: sl@0: The test creates a database with a table and prepares an insert query. sl@0: The test then checks the ParameterName() and ParamName() return result for: sl@0: - Named parameters - return the named param sl@0: - Unnamed parameters - return ? sl@0: @SYMTestPriority High sl@0: @SYMTestActions RSqlStatement::ParameterName() and RSqlStatement::ParamName() test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMCR RMAD-7B7EV5 sl@0: Add SQL Server APIs to retrieve column and parameter names sl@0: */ sl@0: void ParamNameTest() sl@0: { sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: const char* KColTypeNames[] = sl@0: {"INTEGER", "TEXT"}; sl@0: const TInt KColTypeCnt = sizeof(KColTypeNames) / sizeof(KColTypeNames[0]); sl@0: //Create table 1 sl@0: TBuf8<256> sql; sl@0: sql.Copy(_L8("CREATE TABLE T(")); sl@0: for(TInt i=0;i= 0); sl@0: TheStmt.Close(); sl@0: sl@0: // Create insert statement, then check param names sl@0: err = TheStmt.Prepare(TheDb, _L("INSERT INTO T (A1, A2) VALUES (:prm1, :prm2)")); sl@0: TEST2(err, KErrNone); sl@0: TPtrC paramName; sl@0: TBuf<128> expectedParamName; sl@0: for(TInt i=0;i= 0); sl@0: err = db1.Exec(_L("INSERT INTO A VALUES(2)")); sl@0: TEST2(err, 1); sl@0: err = db2.Open(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = db1.Exec(_L("COMMIT TRANSACTION")); sl@0: TEST(err >= 0); sl@0: db2.Close(); sl@0: db1.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: TInt StackOverflowThreadFunc(void* aData) sl@0: { sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: TEST(tc != NULL); sl@0: sl@0: User::SetJustInTime(EFalse); // disable debugger panic handling sl@0: sl@0: TInt* cntptr = reinterpret_cast (aData); sl@0: TEST(cntptr != NULL); sl@0: TInt cnt = *cntptr; sl@0: sl@0: HBufC* buf = HBufC::New(cnt * 12 + 32);//enough for the "SELECT Id FROM A WHERE Id=v1 OR Id=v2 OR ..." string sl@0: if(!buf) sl@0: { sl@0: delete tc; sl@0: return KErrNoMemory; sl@0: } sl@0: TPtr sql = buf->Des(); sl@0: sl@0: TInt err = TheDb.Open(KTestDbName1); sl@0: if(err != KErrNone) sl@0: { sl@0: delete buf; sl@0: delete tc; sl@0: return err; sl@0: } sl@0: sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: TInt64 seed = now.Int64(); sl@0: sl@0: sql.Copy(_L("SELECT Id FROM A WHERE ")); sl@0: for(TInt i=0;i 0) sl@0: { sl@0: TInt count = next; sl@0: TheTest.Printf(_L("'OR' expr. count: %d\r\n"), count); sl@0: RThread thread; sl@0: _LIT(KThreadName,"ORThread"); //stack minheap maxheap sl@0: err = thread.Create(KThreadName, &StackOverflowThreadFunc, 0x2000, 0x00100000, 0x02000000, &count); sl@0: TEST2(err, KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: TEST2(status.Int(), KRequestPending); sl@0: thread.Resume(); sl@0: User::WaitForRequest(status); sl@0: User::SetJustInTime(ETrue); // enable debugger panic handling sl@0: sl@0: TInt exitType = thread.ExitType(); sl@0: const TDesC& exitCategory = thread.ExitCategory(); sl@0: TInt exitReason = thread.ExitReason(); sl@0: TheTest.Printf(_L("Exit type: %d, exit reason: %d, exit category: %S\r\n"), exitType, exitReason, &exitCategory); sl@0: thread.Close(); sl@0: TEST(exitReason != KErrServerTerminated); sl@0: TEST(exitType != EExitPanic); sl@0: sl@0: TInt tmp = next; sl@0: if(status.Int() != KErrNone) sl@0: {//The number of the OR subexpressions is too big and cannot be parsed. Decrease the number, repeat the test. sl@0: next -= Abs(next - prev) / 2; sl@0: } sl@0: else sl@0: {//KErrNone: The number of the OR subexpressions has been successfully parsed. Increase the number, repeat the test. sl@0: next += Abs(next - prev) / 2; sl@0: } sl@0: prev = tmp; sl@0: } sl@0: TheTest.Printf(_L("The test has succeeded with an expression with %d ORs\r\n"), prev); sl@0: } sl@0: sl@0: void AssertSettingsTable() sl@0: { sl@0: TSqlScalarFullSelectQuery query(TheDb); sl@0: TInt recCount = 0; sl@0: TRAPD(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings"))); sl@0: TEST2(err, KErrNone); sl@0: TEST2(recCount, 1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4086 sl@0: @SYMTestCaseDesc RSqlBlobWriteStream::OpenL() and RSqlBlobReadStream::OpenL() - injection test sl@0: The test attempts to open a blob stream with an attached database name containing sl@0: "DELETE FROM symbian_settings" statement. The test should not delete the content of the sl@0: "symbian_settings" table. sl@0: The test also attempts to open a blob stream with a set of very long database/table/column names. sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions RSqlBlobWriteStream::OpenL() and RSqlBlobReadStream::OpenL() - injection test sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ5792 sl@0: REQ10410 sl@0: REQ10411 sl@0: REQ10418 sl@0: */ sl@0: void BlobStreamInjectionTest() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Data BLOB)")); sl@0: TEST2(err, 1); sl@0: err = TheDb.Exec(_L("INSERT INTO A VALUES(1, x'11223344556677889900')")); sl@0: TEST2(err, 1); sl@0: _LIT(KAttachDb, "AttachDb"); sl@0: err = TheDb.Attach(KTestDbName1, KAttachDb); sl@0: TEST2(err, KErrNone); sl@0: //RSqlBlobWriteStream::OpenL() - attached database name injected sl@0: RSqlBlobWriteStream strm1; sl@0: TRAP(err, strm1.OpenL(TheDb, _L("A"), _L("Data"), 1, _L("Id;DELETE FROM symbian_settings;"))); sl@0: TEST(err != KErrNone); sl@0: AssertSettingsTable(); sl@0: //RSqlBlobReadStream::OpenL() - attached database name injected sl@0: RSqlBlobReadStream strm2; sl@0: TRAP(err, strm2.OpenL(TheDb, _L("A"), _L("Data"), 1, _L("Id;DELETE FROM symbian_settings;"))); sl@0: TEST(err != KErrNone); sl@0: AssertSettingsTable(); sl@0: //Attempt to open a write blob stream with a set of very long database/table/column names. sl@0: TBuf longName; sl@0: longName.SetLength(longName.MaxLength()); sl@0: RSqlBlobWriteStream strm3; sl@0: TRAP(err, strm3.OpenL(TheDb, longName, longName, 1, longName)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a read blob stream with a set of very long database/table/column names. sl@0: RSqlBlobReadStream strm4; sl@0: TRAP(err, strm4.OpenL(TheDb, longName, longName, 1, longName)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a write blob stream with a set of KNullDesC database/table/column names. sl@0: RSqlBlobWriteStream strm5; sl@0: TRAP(err, strm5.OpenL(TheDb, KNullDesC, KNullDesC, 1, KNullDesC)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a read blob stream with a set of KNullDesC database/table/column names. sl@0: RSqlBlobReadStream strm6; sl@0: TRAP(err, strm6.OpenL(TheDb, KNullDesC, KNullDesC, 1, KNullDesC)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a read blob stream, where the blob column name is invalid and contains non-convertible characters. sl@0: TBuf<3> invName; sl@0: invName.SetLength(3); sl@0: invName[0] = TChar(0xD800); sl@0: invName[1] = TChar(0xFC00); sl@0: invName[2] = TChar(0x0000); sl@0: RSqlBlobReadStream strm7; sl@0: TRAP(err, strm7.OpenL(TheDb, _L("A"), invName, 1, KNullDesC)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a read blob stream, where the table name is invalid and contains non-convertible characters. sl@0: RSqlBlobReadStream strm8; sl@0: TRAP(err, strm8.OpenL(TheDb, invName, _L("Data"), 1, KNullDesC)); sl@0: TEST(err != KErrNone); sl@0: //Attempt to open a read blob stream, where the attached db name is invalid and contains non-convertible characters. sl@0: RSqlBlobReadStream strm9; sl@0: TRAP(err, strm9.OpenL(TheDb, _L("A"), _L("Data"), 1, invName)); sl@0: TEST(err != KErrNone); sl@0: // sl@0: err = TheDb.Detach(KAttachDb); sl@0: TEST2(err, KErrNone); sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4087 sl@0: @SYMTestCaseDesc Bound parameter values test. sl@0: The test verifies that bound parameters with big text/binary values retain their values after sl@0: the RSqlStatement::Reset() call. The old bound paramegter values can be used for the next sl@0: RSqlStatement::Exec() call. sl@0: @SYMTestActions Bound parameter values test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void BoundParameterValuesTest() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: err = TheDb.Exec(_L("CREATE TABLE A2(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: RSqlStatement stmt1, stmt2; sl@0: err = stmt1.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt2.Prepare(TheDb, _L("INSERT INTO A2 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: //Insert 1 record into table "A1". T2 = "ZZZZ.....". sl@0: TheBuf.SetLength(KBufLen - 100); sl@0: TheBuf.Fill(TChar('Z')); sl@0: err = stmt1.BindText(0, TheBuf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt1.BindText(1, TheBuf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt1.Exec(); sl@0: TEST2(err, 1); sl@0: err = stmt1.Reset(); sl@0: TEST2(err, KErrNone); sl@0: //Insert 1 record into table "A2". T2 = "AAAAAAA.....". sl@0: TheBuf.SetLength(KBufLen); sl@0: TheBuf.Fill(TChar('A')); sl@0: err = stmt2.BindText(0, TheBuf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt2.BindText(1, TheBuf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt2.Exec(); sl@0: TEST2(err, 1); sl@0: err = stmt2.Reset(); sl@0: TEST2(err, KErrNone); sl@0: //Insert 1 record into table "A1". T2 not set. T2 should be initialized with the previous bound value - "ZZZZZZ....". sl@0: //If the problem is not fixed, the SQLITE will attempt to access an already deleted region of memory. sl@0: TheBuf.SetLength(KBufLen - 100); sl@0: TheBuf.Fill(TChar('B')); sl@0: err = stmt1.BindText(0, TheBuf); sl@0: TEST2(err, KErrNone); sl@0: err = stmt1.Exec(); sl@0: TEST2(err, 1); sl@0: err = stmt1.Reset(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: stmt2.Close(); sl@0: stmt1.Close(); sl@0: sl@0: //Check the inserted records. sl@0: TSqlScalarFullSelectQuery q(TheDb); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=1"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST2(TheBuf.Length(), (KBufLen - 100)); sl@0: for(TInt i1=0;i1<(KBufLen - 100);++i1) sl@0: { sl@0: TEST2(TheBuf[i1], TChar('Z')); sl@0: } sl@0: TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=2"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST2(TheBuf.Length(), (KBufLen - 100)); sl@0: for(TInt i2=0;i2<(KBufLen - 100);++i2) sl@0: { sl@0: TEST2(TheBuf[i2], TChar('Z')); sl@0: } sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4076 sl@0: @SYMTestCaseDesc Bound parameter values test. sl@0: The test verifies that when a RSqlParamWriteStream object is used for binding parameter values, sl@0: it is safe to erverse the order of RSqlParamWriteStream::Close() and RSqlStatement::Close() calls. sl@0: @SYMTestActions Bound parameter values test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void BoundParameterValuesTest2() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: RSqlParamWriteStream strm; sl@0: err = strm.BindText(stmt, 0); sl@0: TEST2(err, KErrNone); sl@0: err = stmt.Exec(); sl@0: TEST2(err, 1); sl@0: stmt.Close(); sl@0: strm.Close(); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4077 sl@0: @SYMTestCaseDesc Bound parameter values test. sl@0: The test verifies that when a RSqlParamWriteStream object is used for binding parameter values, sl@0: it is possible to write the parameter value, then call RSqlParamWriteStream::Close() and finally - sl@0: RSqlStatement::Exec() to execute the operation (an INSERT statement). The test verifies that the record sl@0: has really been inserted and the column value is equal to the bound parameter value sl@0: @SYMTestActions Bound parameter values test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void BoundParameterValuesTest3() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: RSqlParamWriteStream strm; sl@0: err = strm.BindText(stmt, 0); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText, "AAAA"); sl@0: TRAP(err, strm.WriteL(KText)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: strm.Close(); sl@0: err = stmt.Exec(); sl@0: TEST2(err, 1); sl@0: stmt.Close(); sl@0: sl@0: TSqlScalarFullSelectQuery q(TheDb); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText() == TheBuf); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4083 sl@0: @SYMTestCaseDesc Bound parameter values test. sl@0: The test prepares an INSERT sql statement and inserts two records using streams to bind the parameter values. sl@0: For the second INSERT no parameter value is bound to the first parameter. The expectation is that the value sl@0: that has been bound for the first record will be used for the second record also. sl@0: @SYMTestActions Bound parameter values test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void BoundParameterValuesTest4() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: sl@0: RSqlParamWriteStream strm; sl@0: err = strm.BindText(stmt, 0); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText1, "AAAA"); sl@0: TRAP(err, strm.WriteL(KText1)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: strm.Close(); sl@0: sl@0: err = strm.BindText(stmt, 1); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText2, "BBBBBBBBBB"); sl@0: TRAP(err, strm.WriteL(KText2)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: strm.Close(); sl@0: sl@0: err = stmt.Exec(); sl@0: TEST2(err, 1); sl@0: err = stmt.Reset(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: err = strm.BindText(stmt, 1); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText3, "CCCCCCCCCCC"); sl@0: TRAP(err, strm.WriteL(KText3)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: strm.Close(); sl@0: sl@0: err = stmt.Exec(); sl@0: TEST2(err, 1); sl@0: sl@0: stmt.Close(); sl@0: sl@0: TSqlScalarFullSelectQuery q(TheDb); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=1"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText1() == TheBuf); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=1"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText2() == TheBuf); sl@0: sl@0: TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=2"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText1() == TheBuf); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=2"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText3() == TheBuf); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4105 sl@0: @SYMTestCaseDesc Bound parameter values test. sl@0: BC test. Even though it is correct to execute only one CommitL() on a parameter stream, sl@0: it should be possible to execute more than one CommitL(). It should be possible also sl@0: the stream data to be updated after the first commit operation and the expectation is that sl@0: the updated parameter data should be used for the column value. sl@0: @SYMTestActions Bound parameter values test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void BoundParameterValuesTest5() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: RSqlStatement stmt; sl@0: err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)")); sl@0: TEST2(err, KErrNone); sl@0: sl@0: RSqlParamWriteStream strm; sl@0: err = strm.BindText(stmt, 0); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText1, "AAAA"); sl@0: TRAP(err, strm.WriteL(KText1)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.Sink()->SeekL(MStreamBuf::EWrite, EStreamBeginning, 0)); sl@0: TEST2(err, KErrNone); sl@0: _LIT(KText2, "DTAA"); sl@0: TRAP(err, strm.WriteL(KText2)); sl@0: TEST2(err, KErrNone); sl@0: TRAP(err, strm.CommitL()); sl@0: TEST2(err, KErrNone); sl@0: strm.Close(); sl@0: sl@0: err = stmt.Exec(); sl@0: TEST2(err, 1); sl@0: sl@0: stmt.Close(); sl@0: sl@0: TSqlScalarFullSelectQuery q(TheDb); sl@0: TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=1"), TheBuf)); sl@0: TEST2(err, KErrNone); sl@0: TEST(KText2() == TheBuf); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: void PrintConfig(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<128> config; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterConfig, config) == KErrNone) sl@0: { sl@0: _LIT(KCacheSize, "Cache size: %S pages\r\n"); sl@0: _LIT(KPageSize, "Page size: %S bytes\r\n"); sl@0: _LIT(KEncoding, "Encoding: %S\r\n"); sl@0: _LIT(KDefaultSoftHeapLimit, "Default soft heap limit: %S Kb\r\n"); sl@0: _LIT(KVacuumMode, "Vacuum mode: %S\r\n"); sl@0: sl@0: TPtrC KText[] = {KCacheSize(), KPageSize(), KEncoding(), KDefaultSoftHeapLimit(), KVacuumMode()}; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void PrintFileIo(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<300> countersValues; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterFileIO, countersValues) == KErrNone) sl@0: { sl@0: TheTest.Printf(_L("=========================\r\n")); sl@0: _LIT(KFileCreate, "File Create"); sl@0: _LIT(KFileOpen, "File Open"); sl@0: _LIT(KFileClose, "File Close"); sl@0: _LIT(KFileDelete, "File Delete"); sl@0: _LIT(KFileRead, "File Read"); sl@0: _LIT(KFileWrite, "File Write"); sl@0: _LIT(KFileSeek, "File Seek"); sl@0: _LIT(KFileSize, "File Size"); sl@0: _LIT(KFileSetSize, "File SetSize"); sl@0: _LIT(KFileSync, "File Sync"); sl@0: _LIT(KFileDrive, "File Drive"); sl@0: _LIT(KFileAdopt, "File Adopt"); sl@0: _LIT(KFsClose, "Fs Close"); sl@0: _LIT(KFsConnect, "Fs Connect"); sl@0: _LIT(KFsGetSystemDrive, "Fs GetSystemDrive"); sl@0: _LIT(KFsCreatePrivatePath, "Fs CreatePrivatePath"); sl@0: _LIT(KFsPrivatePath, "Fs PrivatePath"); sl@0: _LIT(KFsVolumeIoParam, "Fs VolumeIoParam"); sl@0: _LIT(KFsEntry, "Fs Entry"); sl@0: _LIT(KFsAtt, "Fs Att"); sl@0: _LIT(KFileCreateTemp, "File CreateTemp"); sl@0: _LIT(KFileAttach, "File Attach"); sl@0: _LIT(KBytesWritten, "File Bytes Written"); sl@0: _LIT(KBytesRead, "File Bytes Read"); sl@0: TPtrC KText[] = sl@0: { sl@0: KFileCreate(), KFileOpen(), KFileClose(), KFileDelete(), KFileRead(), KFileWrite(), KFileSeek(), KFileSize(), sl@0: KFileSetSize(), KFileSync(), KFileDrive(), KFileAdopt(), KFsClose(), KFsConnect(), KFsGetSystemDrive(), sl@0: KFsCreatePrivatePath(), KFsPrivatePath(), KFsVolumeIoParam(), KFsEntry(), KFsAtt(), KFileCreateTemp(), sl@0: KFileAttach(), KBytesWritten(), KBytesRead() sl@0: }; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void PrintOsCall(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<300> countersValues; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterOsCall, countersValues) == KErrNone) sl@0: { sl@0: TheTest.Printf(_L("=========================\r\n")); sl@0: _LIT(KEOsFileClose, "FileClose"); sl@0: _LIT(KEOsFileRead, "FileRead"); sl@0: _LIT(KEOsFileWrite, "FileWrite"); sl@0: _LIT(KEOsFileTruncate, "FileTruncate"); sl@0: _LIT(KEOsFileSync, "FileSync"); sl@0: _LIT(KEOsFileFileSize, "FileSize"); sl@0: _LIT(KEOsFileLock, "FileLock"); sl@0: _LIT(KEOsFileUnlock, "FileUnlock"); sl@0: _LIT(KEOsFileCheckReservedLock, "FileCheckReservedLock"); sl@0: _LIT(KEOsFileFileControl, "FileIoControl"); sl@0: _LIT(KEOsFileSectorSize, "FileSectorSize"); sl@0: _LIT(KEOsFileDeviceCharacteristics, "FileDeviceCharacteristics"); sl@0: _LIT(KEOsVfsOpen, "VfsOpen"); sl@0: _LIT(KEOsVfsDelete, "VfsDelete"); sl@0: _LIT(KEOsVfsAccess, "VfsAccess"); sl@0: _LIT(KEOsVfsFullPathName, "VfsFullPathName"); sl@0: _LIT(KEOsVfsRandomness, "VfsRandomnes"); sl@0: _LIT(KEOsVfsSleep, "VfsSleep"); sl@0: _LIT(KEOsVfsCurrentTime, "VfsCurrentTime"); sl@0: _LIT(KEOsVfsGetLastError, "VfsGetLastError"); sl@0: TPtrC KText[] = sl@0: { sl@0: KEOsFileClose(), KEOsFileRead(), KEOsFileWrite(), KEOsFileTruncate(), KEOsFileSync(), sl@0: KEOsFileFileSize(), KEOsFileLock(), KEOsFileUnlock(), KEOsFileCheckReservedLock(), KEOsFileFileControl(), sl@0: KEOsFileSectorSize(), KEOsFileDeviceCharacteristics(), sl@0: KEOsVfsOpen(), KEOsVfsDelete(), KEOsVfsAccess(), KEOsVfsFullPathName(), KEOsVfsRandomness(), KEOsVfsSleep(), sl@0: KEOsVfsCurrentTime(), KEOsVfsGetLastError()}; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void PrintOsCallTime(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<300> callTimes; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterOsCallTime, callTimes) == KErrNone) sl@0: { sl@0: TheTest.Printf(_L("=========================\r\n")); sl@0: _LIT(KEOsFileClose, "FileClose"); sl@0: _LIT(KEOsFileRead, "FileRead"); sl@0: _LIT(KEOsFileWrite, "FileWrite"); sl@0: _LIT(KEOsFileTruncate, "FileTruncate"); sl@0: _LIT(KEOsFileSync, "FileSync"); sl@0: _LIT(KEOsFileFileSize, "FileSize"); sl@0: _LIT(KEOsFileLock, "FileLock"); sl@0: _LIT(KEOsFileUnlock, "FileUnlock"); sl@0: _LIT(KEOsFileCheckReservedLock, "FileCheckReservedLock"); sl@0: _LIT(KEOsFileFileControl, "FileIoControl"); sl@0: _LIT(KEOsFileSectorSize, "FileSectorSize"); sl@0: _LIT(KEOsFileDeviceCharacteristics, "FileDeviceCharacteristics"); sl@0: _LIT(KEOsVfsOpen, "VfsOpen"); sl@0: _LIT(KEOsVfsDelete, "VfsDelete"); sl@0: _LIT(KEOsVfsAccess, "VfsAccess"); sl@0: _LIT(KEOsVfsFullPathName, "VfsFullPathName"); sl@0: _LIT(KEOsVfsRandomness, "VfsRandomnes"); sl@0: _LIT(KEOsVfsSleep, "VfsSleep"); sl@0: _LIT(KEOsVfsCurrentTime, "VfsCurrentTime"); sl@0: _LIT(KEOsVfsGetLastError, "VfsGetLastError"); sl@0: TPtrC KText[] = sl@0: { sl@0: KEOsFileClose(), KEOsFileRead(), KEOsFileWrite(), KEOsFileTruncate(), KEOsFileSync(), sl@0: KEOsFileFileSize(), KEOsFileLock(), KEOsFileUnlock(), KEOsFileCheckReservedLock(), KEOsFileFileControl(), sl@0: KEOsFileSectorSize(), KEOsFileDeviceCharacteristics(), sl@0: KEOsVfsOpen(), KEOsVfsDelete(), KEOsVfsAccess(), KEOsVfsFullPathName(), KEOsVfsRandomness(), KEOsVfsSleep(), sl@0: KEOsVfsCurrentTime(), KEOsVfsGetLastError()}; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(_L("==Operation %S, time %S us\r\n"), &KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void PrintIpc(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<300> countersValues; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterIpc, countersValues) == KErrNone) sl@0: { sl@0: TheTest.Printf(_L("=========================\r\n")); sl@0: _LIT(KIpcRq, "IPC requests"); sl@0: _LIT(KIpcRead, "IPC read"); sl@0: _LIT(KIpcWrite, "IPC write"); sl@0: _LIT(KIpcReadBytes, "IPC read bytes"); sl@0: _LIT(KIpcWriteBytes, "IPC write bytes"); sl@0: TPtrC KText[] = sl@0: { sl@0: KIpcRq(), KIpcRead(), KIpcWrite(), KIpcReadBytes(), KIpcWriteBytes() sl@0: }; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void PrintMemory(TSqlResourceProfiler& aProfiler) sl@0: { sl@0: TBuf8<300> countersValues; sl@0: if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterMemory, countersValues) == KErrNone) sl@0: { sl@0: TheTest.Printf(_L("=========================\r\n")); sl@0: _LIT(KMemorySrvAllocatedCnt, "Server allocated cnt"); sl@0: _LIT(KMemorySrvAllocatedSize, "Server allocated size"); sl@0: _LIT(KMemorySrvFreeSpace, "Server free space"); sl@0: _LIT(KMemorySrvLargestBlockSize, "Server larges block size"); sl@0: _LIT(KMemorySQLiteAllocatedCnt, "SQLite allocated cnt"); sl@0: _LIT(KMemorySQLiteReallocatedCnt, "SQLite reallocated cnt"); sl@0: _LIT(KMemorySQLiteFreedCnt, "SQLite freed cnt"); sl@0: _LIT(KMemorySQLiteAllocatedBytes, "SQLite allocated bytes"); sl@0: _LIT(KMemorySQLiteFreedBytes, "SQLite freed bytes"); sl@0: _LIT(KMemorySQLiteAllocTime, "SQLite alloc, us"); sl@0: _LIT(KMemorySQLiteReallocTime, "SQLite realloc, us"); sl@0: _LIT(KMemorySQLiteFreeTime, "SQLite free, us"); sl@0: TPtrC KText[] = sl@0: { sl@0: KMemorySrvAllocatedCnt(), KMemorySrvAllocatedSize(), KMemorySrvFreeSpace(), KMemorySrvLargestBlockSize(), sl@0: KMemorySQLiteAllocatedCnt(), KMemorySQLiteReallocatedCnt(), KMemorySQLiteFreedCnt(), sl@0: KMemorySQLiteAllocatedBytes(), KMemorySQLiteFreedBytes(), sl@0: KMemorySQLiteAllocTime(), KMemorySQLiteReallocTime(), KMemorySQLiteFreeTime() sl@0: }; sl@0: sl@0: for(TInt i=0;i num; sl@0: num.Copy(num8); sl@0: TheTest.Printf(_L("==%S=%S\r\n"), &KText[idx], &num); sl@0: ++idx; sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SQL-UT-4088 sl@0: @SYMTestCaseDesc TSqlResouceProfiler - file I/O and configuration test. sl@0: The test enables the file I/O profiling and then executes a simple INSERT statement sl@0: and prints out the profiling results. The test also prints the current database configuration. sl@0: @SYMTestActions TSqlResouceProfiler - file I/O and configuration test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority Medium sl@0: @SYMREQ REQ5792 sl@0: */ sl@0: void ProfilerTest() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER, T TEXT)")); sl@0: TEST2(err, 1); sl@0: sl@0: TSqlResourceProfiler profiler(TheDb); sl@0: sl@0: PrintConfig(profiler); sl@0: sl@0: (void)profiler.Start(TSqlResourceProfiler::ESqlCounterFileIO); sl@0: (void)profiler.Start(TSqlResourceProfiler::ESqlCounterOsCall); sl@0: (void)profiler.Start(TSqlResourceProfiler::ESqlCounterOsCallTime); sl@0: (void)profiler.Start(TSqlResourceProfiler::ESqlCounterIpc); sl@0: (void)profiler.Start(TSqlResourceProfiler::ESqlCounterMemory); sl@0: sl@0: (void)profiler.Reset(TSqlResourceProfiler::ESqlCounterFileIO); sl@0: (void)profiler.Reset(TSqlResourceProfiler::ESqlCounterOsCall); sl@0: (void)profiler.Reset(TSqlResourceProfiler::ESqlCounterOsCallTime); sl@0: (void)profiler.Reset(TSqlResourceProfiler::ESqlCounterIpc); sl@0: (void)profiler.Reset(TSqlResourceProfiler::ESqlCounterMemory); sl@0: sl@0: err = TheDb.Exec(_L("INSERT INTO A VALUES(1, 'ABCDEEFGH')")); sl@0: TEST2(err, 1); sl@0: sl@0: PrintFileIo(profiler); sl@0: PrintOsCall(profiler); sl@0: PrintOsCallTime(profiler); sl@0: PrintIpc(profiler); sl@0: PrintMemory(profiler); sl@0: sl@0: (void)profiler.Stop(TSqlResourceProfiler::ESqlCounterIpc); sl@0: (void)profiler.Stop(TSqlResourceProfiler::ESqlCounterOsCallTime); sl@0: (void)profiler.Stop(TSqlResourceProfiler::ESqlCounterOsCall); sl@0: (void)profiler.Stop(TSqlResourceProfiler::ESqlCounterFileIO); sl@0: (void)profiler.Stop(TSqlResourceProfiler::ESqlCounterMemory); sl@0: sl@0: TheDb.Close(); sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: } sl@0: sl@0: TInt CompoundSelectStackOverflowThreadFunc(void* aData) sl@0: { sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: TEST(tc != NULL); sl@0: sl@0: User::SetJustInTime(EFalse); // disable debugger panic handling sl@0: sl@0: TInt* cntptr = reinterpret_cast (aData); sl@0: TEST(cntptr != NULL); sl@0: const TInt KSelectStmtCnt = *cntptr; sl@0: sl@0: HBufC* buf = HBufC::New(KSelectStmtCnt * 25 + 32);//enough for the "SELECT I FROM A UNION SELECT I FROM A..." string sl@0: if(!buf) sl@0: { sl@0: delete tc; sl@0: return KErrNoMemory; sl@0: } sl@0: TPtr sql = buf->Des(); sl@0: sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: RSqlDatabase db; sl@0: TInt err = db.Create(KTestDbName1); sl@0: if(err != KErrNone) sl@0: { sl@0: delete buf; sl@0: return err; sl@0: } sl@0: err = db.Exec(_L("CREATE TABLE A(I INTEGER);INSERT INTO A VALUES(1);")); sl@0: if(err < 1) sl@0: { sl@0: delete buf; sl@0: return err; sl@0: } sl@0: sl@0: for(TInt i=0;i0;--cnt) sl@0: { sl@0: TheTest.Printf(_L("SELECT statement count: %d\r\n"), cnt); sl@0: RThread thread; sl@0: _LIT(KThreadName,"S2Thread"); //stack minheap maxheap sl@0: TInt err = thread.Create(KThreadName, &CompoundSelectStackOverflowThreadFunc, 0x2000, 0x00100000, 0x02000000, &cnt); sl@0: TEST2(err, KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: thread.Logon(status); sl@0: TEST2(status.Int(), KRequestPending); sl@0: thread.Resume(); sl@0: User::WaitForRequest(status); sl@0: User::SetJustInTime(ETrue); // enable debugger panic handling sl@0: sl@0: TInt exitType = thread.ExitType(); sl@0: const TDesC& exitCategory = thread.ExitCategory(); sl@0: TInt exitReason = thread.ExitReason(); sl@0: TheTest.Printf(_L("Exit type: %d, exit reason: %d, exit category: %S\r\n"), exitType, exitReason, &exitCategory); sl@0: thread.Close(); sl@0: if(exitReason == KErrServerTerminated) //SQL server --> stack overflow sl@0: { sl@0: continue; sl@0: } sl@0: TEST2(exitReason, KErrNone); sl@0: TheTest.Printf(_L(" The test has succeeded with SELECT statement count=%d\r\n"), cnt); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID PDS-SQL-CT-4198 sl@0: @SYMTestCaseDesc Expired SQL statements test. sl@0: The test creates a database and opens 2 connections to that database. sl@0: Connection 2 prepares couple of SELECT and INSERT statements (8-bit and 16-bit). sl@0: Then connection 1 renames the table used in the already prepared statements. sl@0: Connection 2 attempts to execute the prepared statements. The execution should fail sl@0: because the database schema has changed after they were prepared. sl@0: @SYMTestActions Expired SQL statements test. sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMTestPriority High sl@0: @SYMDEF DEF145236 sl@0: */ sl@0: void ExpiredStmtTest() sl@0: { sl@0: (void)RSqlDatabase::Delete(KTestDbName1); sl@0: //Create a database and create db connection 1. sl@0: TInt err = TheDb.Create(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: err = TheDb.Exec(_L("CREATE TABLE A(C1 INTEGER)")); sl@0: TEST(err >= 0); sl@0: err = TheDb.Exec(_L("INSERT INTO A(C1) VALUES(1)")); sl@0: TEST2(err, 1); sl@0: sl@0: //Create db connection 2 to the same database, as db connection 1. sl@0: RSqlDatabase db2; sl@0: err = db2.Open(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: sl@0: //Db connection 2. Prepare SELECT and INSERT, 8-bit and 16-bit statements. sl@0: RSqlStatement stmt1, stmt2, stmt3, stmt4; sl@0: err = stmt1.Prepare(db2, _L("SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt2.Prepare(db2, _L8("SELECT * FROM A")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt3.Prepare(db2, _L("INSERT INTO A(C1) VALUES(2)")); sl@0: TEST2(err, KErrNone); sl@0: err = stmt4.Prepare(db2, _L8("INSERT INTO A(C1) VALUES(3)")); sl@0: TEST2(err, KErrNone); sl@0: sl@0: //Modify the A table structure from the other connection sl@0: //err = TheDb.Exec(_L("ALTER TABLE A ADD C2 INTEGER")); sl@0: err = TheDb.Exec(_L("ALTER TABLE A RENAME TO B")); sl@0: TEST(err >= 0); sl@0: sl@0: //Try to execute the already prepared statements. sl@0: err = stmt1.Next(); sl@0: TEST2(err, KSqlErrSchema); sl@0: err = stmt1.Next(); sl@0: TEST(err != KSqlAtRow); sl@0: err = stmt2.Next(); sl@0: TEST(err != KSqlAtRow); sl@0: err = stmt3.Exec(); sl@0: TEST(err < 0); sl@0: err = stmt4.Exec(); sl@0: TEST(err < 0); sl@0: // sl@0: stmt4.Close(); sl@0: stmt3.Close(); sl@0: stmt2.Close(); sl@0: stmt1.Close(); sl@0: db2.Close(); sl@0: TheDb.Close(); sl@0: err = RSqlDatabase::Delete(KTestDbName1); sl@0: TEST2(err, KErrNone); sl@0: } sl@0: sl@0: void DoTestsL() sl@0: { sl@0: TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3512 RSqlStatement::ColumnCount() tests ")); sl@0: ColumnCountTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3513 RSqlStatement::ColumnCount(), non-SELECT tests ")); sl@0: ColumnCountTest2(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3514 RSqlStatement::DeclaredColumnType() tests ")); sl@0: DeclaredColumnTypeTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4017 RSqlStatement::ColumnName() tests")); sl@0: ColumnNameTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4018 RSqlStatement::ParameterName() and RSqlStatement::ParamName() tests")); sl@0: ParamNameTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4006 DEF115300 - SqlSrv.EXE::!SQL Server when preparing invalid LEFT JOIN sql query ")); sl@0: DEF115300(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4007 DEF115331 - SQL, bad code coverage for db reindexing if default collation has changed ")); sl@0: DEF115331L(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4079 RSqlDatabase::Create() and RSqlDatabase::Open() - injection tests")); sl@0: InjectionTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4038 Two connections test")); sl@0: TwoConnectionsTest(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4080 SQL server stack overflow test")); sl@0: SqlServerStackOverflowTest(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4086 RSqlBlobWriteStream/RSqlBlobReadStream injection test")); sl@0: BlobStreamInjectionTest(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4087 Bound parameter values test 1")); sl@0: BoundParameterValuesTest(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4076 Bound parameter values test 2")); sl@0: BoundParameterValuesTest2(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4077 Bound parameter values test 3")); sl@0: BoundParameterValuesTest3(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4083 Bound parameter values test 4")); sl@0: BoundParameterValuesTest4(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4105 Bound parameter values test 5")); sl@0: BoundParameterValuesTest5(); sl@0: TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4088 TSqlResourceProfiler - file I/O and configuration test")); sl@0: ProfilerTest(); sl@0: TheTest.Next( _L(" Compound SELECT, stack overflow test")); sl@0: CompoundSelectStackOverflowTest(); sl@0: TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-CT-4198 Expired statements test")); sl@0: ExpiredStmtTest(); sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: TheTest.Title(); sl@0: sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: CreateTestEnv(); sl@0: DeleteTestFiles(); sl@0: TRAPD(err, DoTestsL()); sl@0: DeleteTestFiles(); sl@0: TEST2(err, KErrNone); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: TheTest.End(); sl@0: TheTest.Close(); sl@0: sl@0: delete tc; sl@0: sl@0: User::Heap().Check(); sl@0: return KErrNone; sl@0: }