1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/t_sqlitedef.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,515 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +
1.20 +#include <e32test.h>
1.21 +#include <e32uid.h>
1.22 +#include <f32file.h>
1.23 +#include <e32math.h>
1.24 +#include <sqlite3.h>
1.25 +
1.26 +#include "sqliteTestUtl.h"
1.27 +
1.28 +const char* const KTestName = "t_sqlitedef";
1.29 +
1.30 +static RFs TheFs;
1.31 +
1.32 +static sqlite3* TheDb = NULL;
1.33 +static sqlite3* TheDb2 = NULL;
1.34 +
1.35 +const char* KTestDir = "c:\\test\\";
1.36 +const char* KTestDb = "c:\\test\\t_sqlitedef.db";
1.37 +const char* KTestDb2 = "c:\\t_sqlitedef.db";
1.38 +
1.39 +static void DeleteFile(const char* aFileName)
1.40 + {
1.41 + TFileName fname;
1.42 + fname.Copy(TPtrC8((const TUint8*)aFileName));
1.43 + (void)TheFs.Delete(fname);
1.44 + }
1.45 +
1.46 +/**
1.47 + * Creates the database file and the directory that the test file will be stored.
1.48 + */
1.49 +static void CreateTestEnv()
1.50 + {
1.51 + TInt err = TheFs.Connect();
1.52 + TestTestLine(err == KErrNone, __LINE__);
1.53 +
1.54 + err = TheFs.ShareAuto();
1.55 + TestTestLine(err == KErrNone,__LINE__);
1.56 +
1.57 + TFileName testDir;
1.58 + testDir.Copy(TPtrC8((const TUint8*)KTestDir));
1.59 + err = TheFs.MkDir(testDir);
1.60 + TestTestLine(err == KErrNone || err == KErrAlreadyExists, __LINE__);
1.61 +
1.62 + TFileName fname;
1.63 + fname.Copy(TPtrC8((const TUint8*)KTestDb));
1.64 + (void)TheFs.Delete(fname);
1.65 + }
1.66 +/**
1.67 + * Closes the database and erases the database file, but not the directory.
1.68 + */
1.69 +static void DestroyTestEnv()
1.70 + {
1.71 + if(TheDb2)
1.72 + {
1.73 + (void)sqlite3_close(TheDb2);
1.74 + TheDb2 = 0;
1.75 + }
1.76 + if(TheDb)
1.77 + {
1.78 + (void)sqlite3_close(TheDb);
1.79 + TheDb = 0;
1.80 + }
1.81 + if(TheFs.Handle() != KNullHandle)
1.82 + {
1.83 + DeleteFile(KTestDb2);
1.84 + DeleteFile(KTestDb);
1.85 + }
1.86 + TheFs.Close();
1.87 + }
1.88 +
1.89 +
1.90 +///////////////////////////////////////////////////////////////////////////////////////
1.91 +//Test macros and functions
1.92 +
1.93 +static void PrintErrMsg()
1.94 + {
1.95 + TBuf<256> buf;
1.96 + if(TheDb)
1.97 + {
1.98 + const char* msg = sqlite3_errmsg(TheDb);
1.99 + buf.Copy(TPtrC8((const TUint8*)msg));
1.100 + RDebug::Print(_L("*** Db1 err msg: \"%S\"\r\n"), &buf);
1.101 + }
1.102 + if(TheDb2)
1.103 + {
1.104 + const char* msg = sqlite3_errmsg(TheDb2);
1.105 + buf.Copy(TPtrC8((const TUint8*)msg));
1.106 + RDebug::Print(_L("*** Db2 err msg: \"%S\"\r\n"), &buf);
1.107 + }
1.108 + }
1.109 +
1.110 +static void Check(TInt aValue, TInt aLine)
1.111 + {
1.112 + if(!aValue)
1.113 + {
1.114 + PrintErrMsg();
1.115 + DestroyTestEnv();
1.116 + TestTestLine(EFalse, aLine);
1.117 + }
1.118 + }
1.119 +static void Check(TInt aValue, TInt aExpected, TInt aLine)
1.120 + {
1.121 + if(aValue != aExpected)
1.122 + {
1.123 + PrintErrMsg();
1.124 + DestroyTestEnv();
1.125 + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
1.126 + TestTestLine(EFalse, aLine);
1.127 + }
1.128 + }
1.129 +#define TEST(arg) ::Check((arg), __LINE__)
1.130 +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
1.131 +
1.132 +///////////////////////////////////////////////////////////////////////////////////////
1.133 +//
1.134 +
1.135 +TInt ThreadFunc(void*)
1.136 + {
1.137 + User::SetJustInTime(EFalse); // disable debugger panic handling
1.138 +
1.139 + CTrapCleanup* tc = CTrapCleanup::New();
1.140 + TEST(tc != NULL);
1.141 +
1.142 + TInt err = sqlite3_open(KTestDb, &TheDb2);
1.143 + TEST2(err, SQLITE_OK);
1.144 +
1.145 + err = sqlite3_exec(TheDb2, "CREATE TABLE A(Id INTEGER,Name TEXT)", 0, 0, 0);
1.146 + TEST2(err, SQLITE_OK);
1.147 + err = sqlite3_exec(TheDb2, "INSERT INTO A VALUES(1, 'AAA')", 0, 0, 0);
1.148 + TEST2(err, SQLITE_OK);
1.149 +
1.150 + sqlite3_close(TheDb2);
1.151 + TheDb2 = NULL;
1.152 +
1.153 + delete tc;
1.154 +
1.155 + return 0;
1.156 + }
1.157 +
1.158 +/**
1.159 +@SYMTestCaseID PDS-SQLITE3-UT-4029
1.160 +@SYMTestCaseDesc Sqlite file handle test
1.161 + The test verifies that a database can be opened from different threads in the same process,
1.162 + when the shared page cache is enabled. In this case the database file handle is shared between the
1.163 + threads that open the database.
1.164 +@SYMTestPriority High
1.165 +@SYMTestActions Sqlite file handle test
1.166 +@SYMTestExpectedResults Test must not fail
1.167 +@SYMREQ REQ10424
1.168 +*/
1.169 +void FileHandleTest()
1.170 + {
1.171 + DeleteFile(KTestDb);
1.172 + sqlite3_enable_shared_cache(1);//this is a per-process setting (was per-thread in SQLite 3.3.17)
1.173 + TInt err = sqlite3_open(KTestDb, &TheDb);
1.174 + TEST2(err, SQLITE_OK);
1.175 +
1.176 + err = sqlite3_exec(TheDb, "CREATE TABLE B(Id INTEGER,Name TEXT)", 0, 0, 0);
1.177 + TEST2(err, SQLITE_OK);
1.178 + err = sqlite3_exec(TheDb, "INSERT INTO B VALUES(1, 'BBB')", 0, 0, 0);
1.179 + TEST2(err, SQLITE_OK);
1.180 +
1.181 + ////////////////////////////////////////////////////////////
1.182 + // The created thread uses the heap of the creating thread
1.183 + // The same SQLite database can be accessed from different threads in
1.184 + // shared page cache mode only if the threads share the same heap.
1.185 + // The database file handle will be shared between threads.
1.186 + ////////////////////////////////////////////////////////////
1.187 + RDebug::Print(_L("*** Shared heap\r\n"));
1.188 + RThread thr;
1.189 + err = thr.Create(_L("TestThr"), &ThreadFunc, KDefaultStackSize, NULL, NULL);
1.190 + TEST2(err, KErrNone);
1.191 + thr.Resume();
1.192 + TRequestStatus stat;
1.193 + thr.Logon(stat);
1.194 + User::WaitForRequest(stat);
1.195 + User::SetJustInTime(ETrue); // enable debugger panic handling
1.196 +
1.197 + TInt exitType = thr.ExitType();
1.198 + TInt exitReason = thr.ExitReason();
1.199 + thr.Close();
1.200 + TEST2(exitReason, 0);
1.201 + TEST2(exitType, EExitKill);
1.202 + ////////////////////////////////////////////////////////////
1.203 +
1.204 + sqlite3_close(TheDb);
1.205 + TheDb = NULL;
1.206 + }
1.207 +
1.208 +///////////////////////////////////////////////////////////////////////////////////////
1.209 +/////////////// Sqlite3 DLL OOM test ////////////////////////////////
1.210 +///////////////////////////////////////////////////////////////////////////////////////
1.211 +
1.212 +/**
1.213 +@SYMTestCaseID PDS-SQLITE3-CT-4028
1.214 +@SYMTestCaseDesc Sqlite OOM test
1.215 + Precondition: none
1.216 + A standard OOM test checks the sqlite3 DLL for memory leaks documented
1.217 + on the raised defect, to check if the applied fix is working. Before
1.218 + the fix the test was failing with PANIC USER:84 on the second iteration
1.219 + loop on DoTest()
1.220 +@SYMTestPriority Medium
1.221 +@SYMTestActions Sqlite OOM test -
1.222 + Opens the database file.
1.223 + Calls sqlite3_prepare16_v2()
1.224 + Closes database
1.225 + Checks memory leaks
1.226 + Repeats the above indefinitely until SQLITE_OK
1.227 +@SYMTestExpectedResults Test must not fail
1.228 +@SYMDEF DEF121506
1.229 +*/
1.230 +void DEF121506()
1.231 + {
1.232 + RDebug::Print(_L("Iteration: \r\n"));
1.233 + for (TInt it = 1; ; ++it)
1.234 + {
1.235 + RDebug::Print(_L("%d "), it);
1.236 + TInt c1 = User::CountAllocCells();
1.237 + __UHEAP_SETFAIL(RHeap::EDeterministic, it);
1.238 +
1.239 + TInt err = sqlite3_open(KTestDb,&TheDb);
1.240 +
1.241 + if(err == SQLITE_OK)
1.242 + {
1.243 + sqlite3_stmt* stmt = 0;
1.244 + const void* tail = 0;
1.245 + err = sqlite3_prepare16_v2(TheDb,
1.246 + L"CREATE TABLE Sample(Id INTEGER PRIMARY KEY NOT NULL, Name TEXT NOT NULL UNIQUE COLLATE NOCASE);",
1.247 + -1, &stmt, &tail);
1.248 + (void)sqlite3_finalize(stmt);
1.249 + }
1.250 +
1.251 + (void)sqlite3_close(TheDb);
1.252 + TheDb = NULL;
1.253 + __UHEAP_RESET;
1.254 +
1.255 + TInt c2 = User::CountAllocCells();
1.256 + if (c1 != c2)
1.257 + {
1.258 + RDebug::Print(_L("\r\n*** OOM Test failed\r\n"));
1.259 + TEST(EFalse);
1.260 + }
1.261 + else if (err == SQLITE_OK)
1.262 + {
1.263 + RDebug::Print(_L("\r\n*** OOM Test passed\r\n"));
1.264 + break;
1.265 + }
1.266 + TEST2(err, SQLITE_NOMEM);
1.267 + }
1.268 + }
1.269 +
1.270 +/**
1.271 +@SYMTestCaseID PDS-SQLITE3-CT-4046
1.272 +@SYMTestCaseDesc [sqlite3] can't execute sql sequence in transcation.
1.273 +@SYMTestPriority High
1.274 +@SYMTestActions The test deletes the test application private data cage.
1.275 + Then the test creates a database and attempts to execute a set
1.276 + of SQL statements, some of them will need a temporary file to be created.
1.277 + Since the test application private data cage (so the session path) does not exist,
1.278 + the SQLite OS porting layer will fail to create the requested temporary file and
1.279 + will fail with KErrPathNotFound error.
1.280 + The OS porting layer was fixed to create the session path if the temporary file creation error
1.281 + is KErrPathNotFound.
1.282 +@SYMTestExpectedResults Test must not fail
1.283 +@SYMDEF DEF140020
1.284 +*/
1.285 +void DEF140020()
1.286 + {
1.287 + //Remove the private data cage
1.288 + CFileMan* fm = 0;
1.289 + TRAPD(err, fm = CFileMan::NewL(TheFs));
1.290 + TEST(fm != 0);
1.291 +
1.292 + TFileName privatePath;
1.293 + err = TheFs.SessionPath(privatePath);
1.294 + TEST2(err, KErrNone);
1.295 + err = fm->RmDir(privatePath);
1.296 + TEST(err == KErrNone || err == KErrPathNotFound);
1.297 +
1.298 + delete fm;
1.299 + fm = 0;
1.300 +
1.301 + TEST2((TUint)TheDb, 0);
1.302 + err = sqlite3_open(KTestDb2, &TheDb);
1.303 + TEST2(err, SQLITE_OK);
1.304 +
1.305 + const char * stmt[] ={
1.306 + "CREATE TABLE fortest (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, intcol INTEGER NOT NULL, charcol CHAR(255) ) ",
1.307 + "INSERT INTO fortest(intcol, charcol) VALUES(1,'111');",
1.308 + "BEGIN TRANSACTION;",
1.309 + "CREATE TABLE t1_backup(id INTEGER, intcol INTEGER NOT NULL);",
1.310 + "INSERT INTO t1_backup SELECT id, intcol FROM fortest;",
1.311 + "DROP TABLE fortest;",
1.312 + "CREATE TABLE fortest (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, intcol INTEGER NOT NULL);",
1.313 + "INSERT INTO fortest(id, intcol) SELECT id,intcol FROM t1_backup;",
1.314 + "DROP TABLE t1_backup;",
1.315 + "select count(*) from fortest;",
1.316 + "COMMIT;",
1.317 + "select count(*) from fortest;",
1.318 + "CREATE TABLE t1_backup(id INTEGER, intcol INTEGER NOT NULL);",
1.319 + "INSERT INTO t1_backup SELECT id, intcol FROM fortest;",
1.320 + "DROP TABLE fortest;",
1.321 + "CREATE TABLE fortest (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, intcol INTEGER NOT NULL);",
1.322 + "INSERT INTO fortest(id, intcol) SELECT id,intcol FROM t1_backup;",
1.323 + "DROP TABLE t1_backup;",
1.324 + };
1.325 +
1.326 + char* msg = NULL;
1.327 + int i = 0;
1.328 + for (i = 0; i < sizeof(stmt) / sizeof(*stmt); i++)
1.329 + {
1.330 + err = sqlite3_exec(TheDb, stmt[i], NULL, NULL, &msg);
1.331 + TEST2(err, SQLITE_OK);
1.332 + }
1.333 +
1.334 + sqlite3_close(TheDb);
1.335 + TheDb = 0;
1.336 + DeleteFile(KTestDb2);
1.337 + }
1.338 +
1.339 +/**
1.340 +@SYMTestCaseID PDS-SQLITE3-CT-4047
1.341 +@SYMTestCaseDesc Test for DEF143066: SQLITE, "CREATE INDEX" sql crashes the SQLite library.
1.342 + The test creates a database with one empty table and establishes two connections
1.343 + to that database. Then, while the first connection is at the middle of a read
1.344 + transaction, the second connection attempts to create an index.
1.345 + If the defect is not fixed, the SQLite library will crash.
1.346 +@SYMTestPriority High
1.347 +@SYMTestActions DEF143066: SQLITE, "CREATE INDEX" sql crashes the SQLite library.
1.348 +@SYMTestExpectedResults Test must not fail
1.349 +@SYMDEF DEF143066
1.350 +*/
1.351 +void DEF143066()
1.352 + {
1.353 + DeleteFile(KTestDb);
1.354 + sqlite3_enable_shared_cache(1);
1.355 + int err = sqlite3_open(KTestDb, &TheDb);
1.356 + TEST2(err, SQLITE_OK);
1.357 +
1.358 + err = sqlite3_exec(TheDb, "CREATE TABLE T0(Thread INTEGER, LocalIndex INTEGER, Inserts INTEGER, Updates INTEGER, IndexMod8 INTEGER)", 0, 0, 0);
1.359 + TEST2(err, SQLITE_OK);
1.360 +
1.361 + err = sqlite3_open(KTestDb, &TheDb2);
1.362 + TEST2(err, SQLITE_OK);
1.363 +
1.364 + sqlite3_stmt* stmt = 0;
1.365 + const char* tail = 0;
1.366 + err = sqlite3_prepare_v2(TheDb, "SELECT COUNT(Thread) FROM T0 WHERE Thread = 0", -1, &stmt, &tail);
1.367 + TEST2(err, SQLITE_OK);
1.368 +
1.369 + err = sqlite3_step(stmt);
1.370 + TEST2(err, SQLITE_ROW);
1.371 +
1.372 + err = sqlite3_exec(TheDb2, "CREATE INDEX T0INDEX ON T0(Thread,IndexMod8)", 0, 0, 0);
1.373 + TEST2(err, SQLITE_LOCKED);
1.374 +
1.375 + (void)sqlite3_finalize(stmt);
1.376 + sqlite3_close(TheDb2);
1.377 + TheDb2 = NULL;
1.378 + sqlite3_close(TheDb);
1.379 + TheDb = NULL;
1.380 + DeleteFile(KTestDb);
1.381 + }
1.382 +
1.383 +/**
1.384 +@SYMTestCaseID PDS-SQL-CT-4048
1.385 +@SYMTestCaseDesc Test for DEF143151: SQLite, strftime() returns incorrect result.
1.386 + The test takes the current universal time (using TTime)
1.387 + and the current time retrieved from the SQLite library.
1.388 + The test compares the times and expects the difference to be no more than
1.389 + 1 second.
1.390 +@SYMTestPriority High
1.391 +@SYMTestActions DEF143151: SQLite, strftime() returns incorrect result
1.392 +@SYMTestExpectedResults Test must not fail
1.393 +@SYMDEF DEF143151
1.394 +*/
1.395 +void DEF143151()
1.396 + {
1.397 + DeleteFile(KTestDb);
1.398 + int err = sqlite3_open(KTestDb, &TheDb);
1.399 + TEST2(err, SQLITE_OK);
1.400 +
1.401 + //Home date & time
1.402 + TBuf<50> dtstr1;
1.403 + TTime time;
1.404 + time.UniversalTime();
1.405 + TDateTime dt = time.DateTime();
1.406 +
1.407 + sqlite3_stmt* stmt = 0;
1.408 + const char* tail = 0;
1.409 + err = sqlite3_prepare_v2(TheDb, "SELECT strftime('%Y-%m-%d,%H:%M:%S','now')", -1, &stmt, &tail);
1.410 + TEST2(err, SQLITE_OK);
1.411 + err = sqlite3_step(stmt);
1.412 + TEST2(err, SQLITE_ROW);
1.413 +
1.414 + //SQLite date & time
1.415 + const unsigned char* s = sqlite3_column_text(stmt, 0);
1.416 + TEST(s != NULL);
1.417 + TBuf<50> dtstr2;
1.418 + dtstr2.Copy(TPtrC8(s));
1.419 + sqlite3_finalize(stmt);
1.420 +
1.421 + sqlite3_close(TheDb);
1.422 + TheDb = NULL;
1.423 + DeleteFile(KTestDb);
1.424 +
1.425 + dtstr1.Format(_L("%04d-%02d-%02d,%02d:%02d:%02d"), dt.Year(), dt.Month() + 1, dt.Day() + 1, dt.Hour(), dt.Minute(), dt.Second());
1.426 +
1.427 + // For the C-Style printout
1.428 + _LIT8(KUniversalTimeText,"Universal date&time=");
1.429 + _LIT8(KSQLiteTimeText, "SQLite date&time=");
1.430 + TBuf8<96> dtstr1print;
1.431 + TBuf8<96> dtstr2print;
1.432 + dtstr1print.Copy(dtstr1);
1.433 + dtstr2print.Copy(dtstr2);
1.434 + dtstr1print.Insert(0,KUniversalTimeText);
1.435 + dtstr2print.Insert(0,KSQLiteTimeText);
1.436 + TestPrintf((const char*)(dtstr1print.PtrZ()));
1.437 + TestPrintf((const char*)(dtstr2print.PtrZ()));
1.438 +
1.439 + //Comapare and fail if dates are not equal (+- 1 second)
1.440 + TLex lex;
1.441 + lex = dtstr2.Mid(0, 4);
1.442 + TInt sqlyear;
1.443 + err = lex.Val(sqlyear);
1.444 + TEST2(err, KErrNone);
1.445 +
1.446 + lex = dtstr2.Mid(5, 2);
1.447 + TInt sqlmonth;
1.448 + err = lex.Val(sqlmonth);
1.449 + TEST2(err, KErrNone);
1.450 +
1.451 + lex = dtstr2.Mid(8, 2);
1.452 + TInt sqlday;
1.453 + err = lex.Val(sqlday);
1.454 + TEST2(err, KErrNone);
1.455 +
1.456 + lex = dtstr2.Mid(11, 2);
1.457 + TInt sqlhour;
1.458 + err = lex.Val(sqlhour);
1.459 + TEST2(err, KErrNone);
1.460 +
1.461 + lex = dtstr2.Mid(14, 2);
1.462 + TInt sqlminute;
1.463 + err = lex.Val(sqlminute);
1.464 + TEST2(err, KErrNone);
1.465 +
1.466 + lex = dtstr2.Mid(17, 2);
1.467 + TInt sqlsecond;
1.468 + err = lex.Val(sqlsecond);
1.469 + TEST2(err, KErrNone);
1.470 +
1.471 + TDateTime sqldt(sqlyear, (TMonth)(sqlmonth - 1), sqlday - 1, sqlhour, sqlminute, sqlsecond, 0);
1.472 + TTime sqltime(sqldt);
1.473 + TTimeIntervalSeconds diff;
1.474 + err = sqltime.SecondsFrom(time, diff);
1.475 + TEST2(err, KErrNone);
1.476 + TEST(diff.Int() <= 1);
1.477 + }
1.478 +
1.479 +void DoTest()
1.480 + {
1.481 + TestStart("@SYMTestCaseID:PDS-SQLITE3-UT-4029: SQLite file handle test");
1.482 + FileHandleTest();
1.483 +
1.484 + TestNext("@SYMTestCaseID:PDS-SQLITE3-CT-4028: DEF121506 test");
1.485 + DEF121506();
1.486 +
1.487 + TestNext("@SYMTestCaseID:PDS-SQLITE3-CT-4046: DEF140020 test");
1.488 + DEF140020();
1.489 +
1.490 + TestNext("@SYMTestCaseID:PDS-SQLITE3-CT-4047: SQLITE, \"CREATE INDEX\" sql crashes the SQLite library");
1.491 + DEF143066();
1.492 +
1.493 + TestNext(" @SYMTestCaseID:SYSLIB-SQL-CT-4048 DEF143151: SQLite, strftime() returns incorrect result");
1.494 + DEF143151();
1.495 + }
1.496 +
1.497 +///////////////////////////////////////////////////////////////////////////////////////
1.498 +
1.499 +TInt E32Main()
1.500 + {
1.501 + TestOpen(KTestName);
1.502 + TestTitle();
1.503 + CTrapCleanup* tc = CTrapCleanup::New();
1.504 +
1.505 + __UHEAP_MARK;
1.506 +
1.507 + CreateTestEnv();
1.508 + DoTest();
1.509 + DestroyTestEnv();
1.510 +
1.511 + __UHEAP_MARKEND;
1.512 +
1.513 + TestEnd();
1.514 + TestClose();
1.515 + delete tc;
1.516 + User::Heap().Check();
1.517 + return KErrNone;
1.518 + }