1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/TEST/t_sqldbconfigfile.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1340 @@
1.4 +// Copyright (c) 2008-2010 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 +#include <e32test.h>
1.20 +#include <stdlib.h>
1.21 +#include <bautils.h>
1.22 +#include <hal.h>
1.23 +#include <sqldb.h>
1.24 +#include "sqlite3.h"
1.25 +#include "SqliteSymbian.h"
1.26 +#include "SqlResourceTester.h"
1.27 +
1.28 +//In order to be able to compile the test, the following variables are defined (used inside the OS porting layer,
1.29 +//when _SQLPROFILER macro is defined)
1.30 +#ifdef _SQLPROFILER
1.31 +TInt TheSqlSrvProfilerFileRead = 0;
1.32 +TInt TheSqlSrvProfilerFileWrite = 0;
1.33 +TInt TheSqlSrvProfilerFileSync = 0;
1.34 +TInt TheSqlSrvProfilerFileSetSize = 0;
1.35 +#endif
1.36 +
1.37 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.38 +/// This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined! ///
1.39 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.40 +
1.41 +RTest TheTest(_L("t_sqldbconfigfile test"));
1.42 +
1.43 +#ifdef SYSLIBS_TEST
1.44 +
1.45 +extern TBool IsStatementSupported(const TDesC& aStatementIn, const TDesC& aDbName, TDes& aStatementOut);
1.46 +
1.47 +RFs TheFs;
1.48 +RSqlDatabase TheDb;
1.49 +sqlite3 *TheDbHandle = NULL;
1.50 +
1.51 +_LIT(KCfgDb1, "c:[1111C1C1]a.db"); // shared, secure db
1.52 +_LIT(KCfgDb2, "c:[1111C1C1]b.db"); // shared, secure db (no config file for it)
1.53 +_LIT(KCfgDb3, "c:\\private\\1111C1C1\\c.db"); // private, secure db
1.54 +_LIT(KCfgDb4, "c:\\test\\d.db"); // public db
1.55 +_LIT(KCfgDb5, "c:[1111C1C1]e.db"); // shared, secure db (config file created before db is created)
1.56 +
1.57 +_LIT(KCfgDb1ConfigFilePath, "c:\\private\\10281e17\\cfg[1111C1C1]a.db.0%d"); // config file version %d for a.db
1.58 +_LIT(KCfgDb3ConfigFileV01Path, "c:\\private\\10281e17\\cfgc.db.01"); // config file v01 for c.db (unsupported)
1.59 +_LIT(KCfgDb4ConfigFileV01Path, "c:\\private\\10281e17\\cfgd.db.01"); // config file v01 for d.db (unsupported)
1.60 +_LIT(KCfgDb5ConfigFileV01Path, "c:\\private\\10281e17\\cfg[1111C1C1]e.db.01"); // config file v01 for e.db
1.61 +_LIT(KCfgDb1CorruptConfigFilePath, "c:\\private\\10281e17\\cfg[1111C1C1]a.db.invalidextension"); // invalid config file name syntax
1.62 +
1.63 +// config file valid contents (used for v02 and others)
1.64 +_LIT8(KCfgConfigFileValidStmt, "CREATE INDEX newIdx ON table1(i3) ;");
1.65 +// config file v03 empty contents
1.66 +_LIT8(KCfgDb1ConfigFileV03EmptyStmt, "");
1.67 +// config file v04 unsupported contents
1.68 +_LIT8(KCfgDb1ConfigFileV04UnsupportedStmt, "DELETE FROM table1");
1.69 +// config file v05 only whitespace contents
1.70 +_LIT8(KCfgDb1ConfigFileV05OnlyWhitespaceStmt, " \r\n \r\n");
1.71 +// config file v06 invalid schema contents
1.72 +_LIT8(KCfgDb1ConfigFileV06InvalidSchemaStmt, "CREATE INDEX thisIdx ON table999(i3)");
1.73 +// config file v07 unsupported comment style
1.74 +_LIT8(KCfgDb1ConfigFileV07InvalidCommentedStmt, "CREATE INDEX ind1 ON table1(i2) // create an index");
1.75 +// config file v08 sequence of different statements
1.76 +_LIT8(KCfgDb1ConfigFileV08SeqStmt, "; CREATE INDEX IdxFirst ON table1(i3)\r\n; DELETE FROM table1;INSERT INTO table1 (i1,i2,i3) values(6,7,8);;CREATE INDEX IdxSecond ON table1(i1);");
1.77 +// config file v09 whitespace before and after statement
1.78 +_LIT8(KCfgDb1ConfigFileV09WhitespacePreAndPostStmt, " CREATE INDEX intIdx ON table1(i1) ");
1.79 +// config file v10 valid contents
1.80 +_LIT8(KCfgDb1ConfigFileV10ValidStmt, "CREATE INDEX i3Index ON table1(i3)\n");
1.81 +// config file v11 valid contents (also tests that any amount spaces and tabs are allowed between 'CREATE' and 'INDEX')
1.82 +_LIT8(KCfgDb1ConfigFileV11ValidStmt, "CREATE INDEX i1Index ON table1(i1);\nCREATE INDEX i2Index ON table1(i2)");
1.83 +// config file v12 invalid stmt plus valid stmt
1.84 +_LIT8(KCfgDb1ConfigFileV12InvalidPlusValidStmt, "CREATE UNIQUE INDEX uniqueIdx ON table1(i1);CREATE INDEX v12Idx ON table1(i2)");
1.85 +// config file v13 supported SQL comment style
1.86 +_LIT8(KCfgDb1ConfigFileV13SQLCommentStmt, "CREATE INDEX v13Idx ON table1(i1) -- this is an SQL comment");
1.87 +// config file v14 supported 'C' comment style
1.88 +_LIT8(KCfgDb1ConfigFileV14CCommentStmt, "CREATE INDEX v14Idx ON table1(i3) /* this is a C comment */;");
1.89 +
1.90 +//KLongDbName1 is "long" enough to allow "-journal" to be added at the end.
1.91 +//Also, on simulators/emulators the file names have a prefix with length of about 30 characters
1.92 +//(something like \epoc\winscw\c\....)
1.93 +_LIT(KLongDbName1, "c:[1111C1C1]a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a.db");
1.94 +_LIT(KLongCfgName1, "c:\\private\\10281e17\\cfg[1111C1C1]a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a.db.01");
1.95 +
1.96 +_LIT(KSqlSrvPrivatePath, "\\private\\10281e17\\");
1.97 +_LIT(KResetCollationDllSql, "UPDATE symbian_settings SET CollationDllName='hjagafsff'");
1.98 +
1.99 +_LIT(KAttachDb1, "Db1");
1.100 +_LIT(KAttachDb2, "Db2");
1.101 +_LIT(KAttachDb5, "Db5");
1.102 +
1.103 +///////////////////////////////////////////////////////////////////////////////////////
1.104 +// Destroy functions
1.105 +
1.106 +void KillSqlServer()
1.107 + {
1.108 + _LIT(KSqlSrvName, "sqlsrv.exe");
1.109 + TFullName name;
1.110 + //RDebug::Print(_L("Find and kill \"%S\" process.\n"), &aProcessName);
1.111 + TBuf<64> pattern(KSqlSrvName);
1.112 + TInt length = pattern.Length();
1.113 + pattern += _L("*");
1.114 + TFindProcess procFinder(pattern);
1.115 +
1.116 + while (procFinder.Next(name) == KErrNone)
1.117 + {
1.118 + if (name.Length() > length)
1.119 + {//If found name is a string containing aProcessName string.
1.120 + TChar c(name[length]);
1.121 + if (c.IsAlphaDigit() ||
1.122 + c == TChar('_') ||
1.123 + c == TChar('-'))
1.124 + {
1.125 + // If the found name is other valid application name
1.126 + // starting with aProcessName string.
1.127 + //RDebug::Print(_L(":: Process name: \"%S\".\n"), &name);
1.128 + continue;
1.129 + }
1.130 + }
1.131 + RProcess proc;
1.132 + if (proc.Open(name) == KErrNone)
1.133 + {
1.134 + proc.Kill(0);
1.135 + //RDebug::Print(_L("\"%S\" process killed.\n"), &name);
1.136 + }
1.137 + proc.Close();
1.138 + }
1.139 + }
1.140 +
1.141 +void DeleteCfgFilesAndDbs()
1.142 + {
1.143 + (void)RSqlDatabase::Delete(KLongDbName1);
1.144 + (void)RSqlDatabase::Delete(KCfgDb1);
1.145 + (void)RSqlDatabase::Delete(KCfgDb2);
1.146 + (void)RSqlDatabase::Delete(KCfgDb3);
1.147 + (void)RSqlDatabase::Delete(KCfgDb4);
1.148 + (void)RSqlDatabase::Delete(KCfgDb5);
1.149 + (void)TheFs.Delete(KLongCfgName1);
1.150 + (void)TheFs.Delete(KCfgDb3ConfigFileV01Path);
1.151 + (void)TheFs.Delete(KCfgDb4ConfigFileV01Path);
1.152 + (void)TheFs.Delete(KCfgDb5ConfigFileV01Path);
1.153 + CFileMan* fileMan = 0;
1.154 + TRAPD(err, fileMan = CFileMan::NewL(TheFs));
1.155 + if(KErrNone == err)
1.156 + {
1.157 + (void)fileMan->Delete(_L("c:\\private\\10281e17\\cfg[1111C1C1]a.db.*"));
1.158 + delete fileMan;
1.159 + }
1.160 + }
1.161 +
1.162 +void DestroyTestEnv()
1.163 + {
1.164 + if(TheDbHandle)
1.165 + {
1.166 + sqlite3_close(TheDbHandle);
1.167 + TheDbHandle = NULL;
1.168 + }
1.169 + TheDb.Close();
1.170 + KillSqlServer();
1.171 + DeleteCfgFilesAndDbs();
1.172 + TheFs.Close();
1.173 + }
1.174 +
1.175 +///////////////////////////////////////////////////////////////////////////////////////
1.176 +// Test macros and functions
1.177 +
1.178 +void Check(TInt aValue, TInt aLine)
1.179 + {
1.180 + if(!aValue)
1.181 + {
1.182 + DestroyTestEnv();
1.183 + TheTest(EFalse, aLine);
1.184 + }
1.185 + }
1.186 +void Check(TInt aValue, TInt aExpected, TInt aLine)
1.187 + {
1.188 + if(aValue != aExpected)
1.189 + {
1.190 + DestroyTestEnv();
1.191 + TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
1.192 + TheTest(EFalse, aLine);
1.193 + }
1.194 + }
1.195 +#define TEST(arg) ::Check((arg), __LINE__)
1.196 +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
1.197 +
1.198 +// OOM test functions
1.199 +
1.200 +static TInt TheHandleCount1;
1.201 +static TInt TheHandleCount2;
1.202 +static TInt TheAllocatedCellsCount;
1.203 +
1.204 +void MarkHandles()
1.205 + {
1.206 + RThread().HandleCount(TheHandleCount1, TheHandleCount2);
1.207 + }
1.208 +
1.209 +void CheckHandles()
1.210 + {
1.211 + TInt endHandleCount1;
1.212 + TInt endHandleCount2;
1.213 +
1.214 + RThread().HandleCount(endHandleCount1, endHandleCount2);
1.215 +
1.216 + TEST2(TheHandleCount1, endHandleCount1);
1.217 + TEST2(TheHandleCount2, endHandleCount2);
1.218 + }
1.219 +
1.220 +void MarkAllocatedCells()
1.221 + {
1.222 + TheAllocatedCellsCount = User::CountAllocCells();
1.223 + }
1.224 +
1.225 +void CheckAllocatedCells()
1.226 + {
1.227 + TInt allocatedCellsCount = User::CountAllocCells();
1.228 + TEST2(allocatedCellsCount, TheAllocatedCellsCount);
1.229 + }
1.230 +
1.231 +///////////////////////////////////////////////////////////////////////////////////////
1.232 +// Set up functions
1.233 +
1.234 +RSqlSecurityPolicy CreateSecurityPolicy()
1.235 + {
1.236 + const TSecurityPolicy KDefaultPolicy(TSecurityPolicy::EAlwaysPass);
1.237 + RSqlSecurityPolicy policy;
1.238 + TInt err = policy.Create(KDefaultPolicy);
1.239 + TEST2(err, KErrNone);
1.240 + err = policy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, KDefaultPolicy);
1.241 + TEST2(err, KErrNone);
1.242 + err = policy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, KDefaultPolicy);
1.243 + TEST2(err, KErrNone);
1.244 + err = policy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, KDefaultPolicy);
1.245 + TEST2(err, KErrNone);
1.246 + return policy;
1.247 + }
1.248 +
1.249 +void DoCreateCfgFile(const TDesC& aFileName, const TDesC8& aData)
1.250 + {
1.251 + RFile file;
1.252 + TInt err = file.Create(TheFs, aFileName, EFileRead | EFileWrite);
1.253 + TEST2(err, KErrNone);
1.254 + err = file.Write(aData);
1.255 + file.Close();
1.256 + TEST2(err, KErrNone);
1.257 + }
1.258 +
1.259 +// Create v01 of the test config files
1.260 +void CreateCfgFiles()
1.261 + {
1.262 + TFileName fileName;
1.263 + TInt v1 = 1;
1.264 + fileName.Format(KCfgDb1ConfigFilePath, v1);
1.265 +
1.266 + // config file v01 contents for db1 (also tests that upper and lower case statements are both supported)
1.267 + _LIT8(KCfgDb1ConfigFile01Stmts, "CREATE INDEX idx ON table1(i1);CREATE INDEX idx2 ON table1(i2);INSERT INTO table1 (i1,i2,i3) values(5,8,9);DELETE FROM table1;create index multiidx ON TABLE1(i2,i3)");
1.268 + DoCreateCfgFile(fileName, KCfgDb1ConfigFile01Stmts);
1.269 +
1.270 + // config file v01 contents for db3 (will not be processed as db3 is not a shared, secure db)
1.271 + _LIT8(KCfgDb3ConfigFile01Stmts, "CREATE INDEX idx ON table3(i1)");
1.272 + DoCreateCfgFile(KCfgDb3ConfigFileV01Path, KCfgDb3ConfigFile01Stmts);
1.273 +
1.274 + // config file v01 contents for db4 (will not be processed as db4 is not a shared, secure db)
1.275 + _LIT8(KCfgDb4ConfigFile01Stmts, "CREATE INDEX idx ON table4(i1)");
1.276 + DoCreateCfgFile(KCfgDb4ConfigFileV01Path, KCfgDb4ConfigFile01Stmts);
1.277 +
1.278 + // create the config file for Db5 before the database has been created
1.279 + // config file v01 contents for db5 (will eventually be processed after db5 itself is created)
1.280 + _LIT8(KCfgDb5ConfigFile01Stmts, "CREATE INDEX idx ON table5(i1);\r\n");
1.281 + DoCreateCfgFile(KCfgDb5ConfigFileV01Path, KCfgDb5ConfigFile01Stmts);
1.282 + }
1.283 +
1.284 +void DoCreateCfgDb(const TDesC& aFileName, const TDesC& aCreateTblSql, const TDesC& aInsertSql,
1.285 + RSqlSecurityPolicy* aPolicy = NULL)
1.286 + {
1.287 + TInt err = aPolicy ? TheDb.Create(aFileName, *aPolicy) : TheDb.Create(aFileName);
1.288 + TEST2(err, KErrNone);
1.289 + err = TheDb.Exec(aCreateTblSql);
1.290 + TEST(err >= 0);
1.291 + err = TheDb.Exec(aInsertSql);
1.292 + TEST(err == 1);
1.293 + TheDb.Close();
1.294 + }
1.295 +
1.296 +// Create the test databases
1.297 +void CreateCfgDbs()
1.298 + {
1.299 + RSqlSecurityPolicy securityPolicy = CreateSecurityPolicy();
1.300 + DoCreateCfgDb(KCfgDb1, _L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"),
1.301 + _L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"), &securityPolicy);
1.302 + DoCreateCfgDb(KCfgDb2, _L("CREATE TABLE table2(i1 INTEGER, i2 INTEGER, i3 INTEGER)"),
1.303 + _L("INSERT INTO table2 (i1,i2,i3) values(4,5,6)"), &securityPolicy);
1.304 + securityPolicy.Close();
1.305 + DoCreateCfgDb(KCfgDb3, _L("CREATE TABLE table3(i1 INTEGER, i2 INTEGER)"),
1.306 + _L("INSERT INTO table3 (i1,i2) values(7,8)"));
1.307 + DoCreateCfgDb(KCfgDb4, _L("CREATE TABLE table4(i1 INTEGER, i2 INTEGER, i3 INTEGER)"),
1.308 + _L("INSERT INTO table4 (i1,i2,i3) values(9,10,11)"));
1.309 + }
1.310 +
1.311 +void CreateCfgFilesAndDbs()
1.312 + {
1.313 + CreateCfgFiles();
1.314 + CreateCfgDbs();
1.315 +
1.316 + // Must now kill the SQL Server so that the config files
1.317 + // created above are found and processed when it restarts
1.318 + KillSqlServer();
1.319 + }
1.320 +
1.321 +// Create the Db5 test database (a config file for it already exists)
1.322 + void CreateDb5()
1.323 + {
1.324 + RSqlSecurityPolicy securityPolicy = CreateSecurityPolicy();
1.325 + DoCreateCfgDb(KCfgDb5, _L("CREATE TABLE table5(i1 INTEGER, i2 INTEGER, i3 INTEGER)"),
1.326 + _L("INSERT INTO table5 (i1,i2,i3) values(1,2,3)"), &securityPolicy);
1.327 + securityPolicy.Close();
1.328 + }
1.329 +
1.330 +void SetupTestEnv()
1.331 + {
1.332 + TInt err = TheFs.Connect();
1.333 + TEST2(err, KErrNone);
1.334 +
1.335 + _LIT(KTestDir, "c:\\test\\");
1.336 + err = TheFs.MkDir(KTestDir);
1.337 + TEST(err == KErrNone || err == KErrAlreadyExists);
1.338 +
1.339 + err = TheFs.CreatePrivatePath(EDriveC);
1.340 + TEST(err == KErrNone || err == KErrAlreadyExists);
1.341 +
1.342 + // Create the cfg dbs and config files
1.343 + DeleteCfgFilesAndDbs(); // just incase any previous files are lingering
1.344 + CreateCfgFilesAndDbs();
1.345 + }
1.346 +
1.347 +///////////////////////////////////////////////////////////////////////////////////////
1.348 +//
1.349 +TInt CalcTimeMs(TUint32 aStartTicks, TUint32 aEndTicks)
1.350 + {
1.351 + static TInt freq = 0;
1.352 + if(freq == 0)
1.353 + {
1.354 + TEST2(HAL::Get(HAL::EFastCounterFrequency, freq), KErrNone);
1.355 + }
1.356 + TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
1.357 + if(diffTicks < 0)
1.358 + {
1.359 + diffTicks = KMaxTUint32 + diffTicks + 1;
1.360 + }
1.361 + const TInt KMicroSecIn1Sec = 1000000;
1.362 + TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq;
1.363 + return us / 1000;
1.364 + }
1.365 +
1.366 +///////////////////////////////////////////////////////////////////////////////////////
1.367 +// Config file replacement functions
1.368 +
1.369 +void UpgradeDbConfigFile(TInt aCurrentVersion)
1.370 + {
1.371 + TInt newVersion = aCurrentVersion + 1;
1.372 + TEST(newVersion != 0 && newVersion != 1 && newVersion != 10 && newVersion != 11 && newVersion < 15);
1.373 +
1.374 + KillSqlServer();
1.375 +
1.376 + TFileName fname;
1.377 + fname.Format(KCfgDb1ConfigFilePath, aCurrentVersion);
1.378 + TInt err = TheFs.Delete(fname);
1.379 + TEST2(err, KErrNone);
1.380 +
1.381 + if(newVersion == 12)
1.382 + {
1.383 + // also delete version 10 of file
1.384 + fname.Format(KCfgDb1ConfigFilePath, 10);
1.385 + err = TheFs.Delete(fname);
1.386 + TEST2(err, KErrNone);
1.387 + }
1.388 +
1.389 + const TPtrC8 stmts[] = {KNullDesC8(), KNullDesC8(),
1.390 + KCfgConfigFileValidStmt(),
1.391 + KCfgDb1ConfigFileV03EmptyStmt(),
1.392 + KCfgDb1ConfigFileV04UnsupportedStmt(),
1.393 + KCfgDb1ConfigFileV05OnlyWhitespaceStmt(),
1.394 + KCfgDb1ConfigFileV06InvalidSchemaStmt(),
1.395 + KCfgDb1ConfigFileV07InvalidCommentedStmt(),
1.396 + KCfgDb1ConfigFileV08SeqStmt(),
1.397 + KCfgDb1ConfigFileV09WhitespacePreAndPostStmt(),
1.398 + KNullDesC8(), KNullDesC8(),
1.399 + KCfgDb1ConfigFileV12InvalidPlusValidStmt(),
1.400 + KCfgDb1ConfigFileV13SQLCommentStmt(),
1.401 + KCfgDb1ConfigFileV14CCommentStmt()};
1.402 +
1.403 + fname.Format(KCfgDb1ConfigFilePath, newVersion);
1.404 + DoCreateCfgFile(fname, stmts[newVersion]);
1.405 + }
1.406 +
1.407 +void DowngradeDbConfigFile(TInt aCurrentVersion)
1.408 + {
1.409 + TEST(aCurrentVersion > 1);
1.410 +
1.411 + KillSqlServer();
1.412 +
1.413 + TFileName fname;
1.414 + fname.Format(KCfgDb1ConfigFilePath, aCurrentVersion);
1.415 + TInt err = TheFs.Delete(fname);
1.416 + TEST2(err, KErrNone);
1.417 +
1.418 + fname.Format(KCfgDb1ConfigFilePath, aCurrentVersion - 1);
1.419 + DoCreateCfgFile(fname, KCfgConfigFileValidStmt);
1.420 + }
1.421 +
1.422 +void CreateCorruptDbConfigFile(TInt aCurrentVersion)
1.423 + {
1.424 + KillSqlServer();
1.425 +
1.426 + TFileName fname;
1.427 + fname.Format(KCfgDb1ConfigFilePath, aCurrentVersion);
1.428 + TInt err = TheFs.Delete(fname);
1.429 + TEST2(err, KErrNone);
1.430 +
1.431 + DoCreateCfgFile(KCfgDb1CorruptConfigFilePath, KCfgConfigFileValidStmt);
1.432 + }
1.433 +
1.434 +void CreateTwoVersionsOfConfigFile()
1.435 + {
1.436 + KillSqlServer();
1.437 +
1.438 + TInt err = TheFs.Delete(KCfgDb1CorruptConfigFilePath);
1.439 + TEST2(err, KErrNone);
1.440 +
1.441 + TInt nextVersion = 10;
1.442 + TFileName fname;
1.443 + fname.Format(KCfgDb1ConfigFilePath, nextVersion);
1.444 + DoCreateCfgFile(fname, KCfgDb1ConfigFileV10ValidStmt);
1.445 +
1.446 + ++nextVersion;
1.447 + fname.Format(KCfgDb1ConfigFilePath, nextVersion);
1.448 + DoCreateCfgFile(fname, KCfgDb1ConfigFileV11ValidStmt);
1.449 + }
1.450 +
1.451 +///////////////////////////////////////////////////////////////////////////////////////
1.452 +// DoDbCfgTests() functions
1.453 +
1.454 +TInt GetDbCfgVersion(const TDesC& aDbName)
1.455 + {
1.456 + // Note: We have to use SQLite directly to access the settings
1.457 + // table as the SQL Server denies permission to access this table
1.458 + // as it is in a shared, secure database
1.459 +
1.460 + TParse parse;
1.461 + TInt err = parse.Set(aDbName, &KSqlSrvPrivatePath, 0);
1.462 + TEST2(err, KErrNone);
1.463 +
1.464 + TBuf8<KMaxFileName + 1> dbFileName;
1.465 + dbFileName.Copy(parse.FullName());
1.466 +
1.467 + sqlite3 *dbHandle = NULL;
1.468 + TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
1.469 + TEST2(rc, SQLITE_OK);
1.470 +
1.471 + _LIT(KGetDbCfgVersionSql, "SELECT Reserved AS DbCfgVersion FROM symbian_settings");
1.472 + TBuf<100> queryBuf;
1.473 + queryBuf.Copy(KGetDbCfgVersionSql);
1.474 +
1.475 + sqlite3_stmt* stmtHandle = NULL;
1.476 + const void* stmtTailZ = NULL;
1.477 + rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
1.478 + TEST2(rc, SQLITE_OK);
1.479 +
1.480 + rc = sqlite3_step(stmtHandle);
1.481 + TEST2(rc, SQLITE_ROW);
1.482 +
1.483 + TInt version = sqlite3_column_int(stmtHandle, 0);
1.484 +
1.485 + rc = sqlite3_step(stmtHandle);
1.486 + TEST2(rc, SQLITE_DONE);
1.487 +
1.488 + sqlite3_finalize(stmtHandle);
1.489 + sqlite3_close(dbHandle);
1.490 +
1.491 + return version;
1.492 + }
1.493 +
1.494 +TBool GuessSystemSettingsTable(const TDesC& aDbName, TInt aVersion)
1.495 + {
1.496 + TInt dbCfgVersion = GetDbCfgVersion(aDbName);
1.497 + return dbCfgVersion == aVersion;
1.498 + }
1.499 +
1.500 +void CheckSystemSettingsTable(const TDesC& aDbName, TInt aVersion)
1.501 + {
1.502 + TInt dbCfgVersion = GetDbCfgVersion(aDbName);
1.503 + TEST2(dbCfgVersion, aVersion);
1.504 + }
1.505 +
1.506 +void CheckRecordCount(const TDesC& aTable)
1.507 + {
1.508 + // There should always be only 1 record in the table
1.509 + // in each database as INSERT and DELETE statements are
1.510 + // not supported in the config files
1.511 + TBuf<50> sql;
1.512 + sql.Format(_L("SELECT COUNT(*) FROM %S"), &aTable);
1.513 + TSqlScalarFullSelectQuery q(TheDb);
1.514 + TInt count = 0;
1.515 + TRAPD(err, count = q.SelectIntL(sql));
1.516 + TEST2(err, KErrNone);
1.517 + TEST2(count, 1);
1.518 + }
1.519 +
1.520 +TInt ExpectedDb1IndexCount(TInt aExpectedStoredVersion)
1.521 + {
1.522 + TEST(aExpectedStoredVersion >= 0 && aExpectedStoredVersion < 15);
1.523 + const TInt KIdxCnt[] = {
1.524 + -1,
1.525 + 3, // Only files 01 - 04, 09 and 11 will be successfully processed and so stored in the settings table
1.526 + 4, // 1 more index should be added to db1 based on config file 02
1.527 + 4, 4, 4, 4, 4, // no more indices should be added to db1 based on config file 03 - 07
1.528 + 6, // 2 more indices should be added to db1 based on config file 08
1.529 + 7, // 1 more index should be added to db1 based on config file 09
1.530 + -1,
1.531 + 9, // 2 more indices should be added to db1 based on config file 11
1.532 + 10, // 1 more index should be added to db1 based on config file 12
1.533 + 11, // 1 more index should be added to db1 based on config file 13
1.534 + 12}; // 1 more index should be added to db1 based on config file 14
1.535 + return KIdxCnt[aExpectedStoredVersion];
1.536 + }
1.537 +
1.538 +void CheckIndexCount(TInt aExpectedIndexCount)
1.539 + {
1.540 + _LIT(KDbCheckNumIndices, "SELECT COUNT(*) FROM sqlite_master WHERE type = 'index'");
1.541 + TSqlScalarFullSelectQuery q(TheDb);
1.542 + TInt count = 0;
1.543 + TRAPD(err, count = q.SelectIntL(KDbCheckNumIndices));
1.544 + TEST2(err, KErrNone);
1.545 + TEST2(count, aExpectedIndexCount);
1.546 + }
1.547 +
1.548 +void DoCfgOpenTest(TInt aExpectedStoredVersion, const TDesC& aDbFileName, const TDesC& aTblName, TInt aExpectedIndexCnt)
1.549 + {
1.550 + TInt err = TheDb.Open(aDbFileName);
1.551 + TEST2(err, KErrNone);
1.552 + CheckRecordCount(aTblName);
1.553 + CheckIndexCount(aExpectedIndexCnt);
1.554 + TheDb.Close();
1.555 + // Check that the ops in the specified config file have been applied.
1.556 + CheckSystemSettingsTable(aDbFileName, aExpectedStoredVersion);
1.557 + }
1.558 +
1.559 +void DoCfgOpenTests(TInt aExpectedStoredVersion)
1.560 + {
1.561 + // Open a shared, secure database - config ops should be applied on it.
1.562 + // There should still be only 1 record and 3 indices in the table.
1.563 + TheTest.Printf(_L("===CfgOpen: Open shared, secure database\r\n"));
1.564 + DoCfgOpenTest(aExpectedStoredVersion, KCfgDb1, _L("table1"), ExpectedDb1IndexCount(aExpectedStoredVersion));
1.565 +
1.566 + // Open again the same shared, secure database - no config should occur (it has already been done).
1.567 + TheTest.Printf(_L("===CfgOpen: Open shared, secure database again\r\n"));
1.568 + DoCfgOpenTest(aExpectedStoredVersion, KCfgDb1, _L("table1"), ExpectedDb1IndexCount(aExpectedStoredVersion));
1.569 +
1.570 + // Open a shared, secure database - no config should occur (there is no config file for this database)
1.571 + TheTest.Printf(_L("===CfgOpen: Open shared, secure database (that has no config file)\r\n"));
1.572 + DoCfgOpenTest(0, KCfgDb2, _L("table2"), 0);
1.573 +
1.574 + // Open a private, secure database - no config should occur
1.575 + TheTest.Printf(_L("===CfgOpen: Open private, secure database\r\n"));
1.576 + DoCfgOpenTest(0, KCfgDb3, _L("table3"), 0);
1.577 +
1.578 + // Open a public database - no config should occur
1.579 + TheTest.Printf(_L("===CfgOpen: Open public database\r\n"));
1.580 + DoCfgOpenTest(0, KCfgDb4, _L("table4"), 0);
1.581 + }
1.582 +
1.583 +void DoUpgradedCfgOpenTest()
1.584 + {
1.585 + // Upgrade the config file for KCfgDb1, i.e. replace v1 file with v2 file
1.586 + UpgradeDbConfigFile(1);
1.587 + DoCfgOpenTests(2);
1.588 + }
1.589 +
1.590 +void DoBadCfgOpenTests()
1.591 + {
1.592 + // Test an empty config file
1.593 + UpgradeDbConfigFile(2); // the current file version is 02, replace it with 03
1.594 + DoCfgOpenTests(3); // version 03 will be successfully processed and stored in the settings table
1.595 +
1.596 + // Test a config file with unsupported operations (these will be ignored)
1.597 + UpgradeDbConfigFile(3); // the current file version is 03, replace it with 04
1.598 + DoCfgOpenTests(4); // version 04 will be successfully processed (the unsupported operations are ignored) and stored in the settings table
1.599 +
1.600 + // Test a config file with only whitespace in it
1.601 + UpgradeDbConfigFile(4); // the current file version is 04, replace it with 05
1.602 + DoCfgOpenTests(5); // version 05 will be successfully processed (the whitespace is ignored) and stored in the settings table
1.603 +
1.604 + // Test a config file with operations on an invalid table
1.605 + UpgradeDbConfigFile(5); // the current file version is 05, replace it with 06
1.606 + DoCfgOpenTests(6); // version 06 will be successfully processed (the failed-to-execute operation will be ignored) and stored in the settings table
1.607 +
1.608 + // Test a config file that contains an invalid comment style
1.609 + UpgradeDbConfigFile(6); // the current file version is 06, replace it with 07
1.610 + DoCfgOpenTests(7); // version 07 will be successfully processed (the line with invalid comment syntax will be ignored) and stored in the settings table
1.611 +
1.612 + // Test a config file that contains a sequence of statements as one statement (this is currently unsupported)
1.613 + UpgradeDbConfigFile(7); // the current file version is 07, replace it with 08
1.614 + DoCfgOpenTests(8); // version 08 will be successfully processed (the line with a sequence of statements is ignored) and stored in the settings table
1.615 +
1.616 + // Test a config file that contains whitespace before and after the SQL statement
1.617 + UpgradeDbConfigFile(8); // the current file version is 08, replace it with 09
1.618 + DoCfgOpenTests(9); // version 09 will be successfully processed and stored in the settings table
1.619 +
1.620 + // Test a config file that has a lower extension number
1.621 + DowngradeDbConfigFile(9); // the current file version is 09, replace it with 08
1.622 + DoCfgOpenTests(9); // version 08 will NOT be processed (as it is a lower version than that stored), and 09 will remain stored in the settings table
1.623 +
1.624 + // Test a config file that has an invalid extension
1.625 + CreateCorruptDbConfigFile(8); // the current file version is 08, replace it with a file with an invalid extension
1.626 + DoCfgOpenTests(9); // the invalid file will NOT be processed, and 09 will remain stored in the settings table
1.627 +
1.628 + // Test two versions of the config file (two versions should not be present at the same time)
1.629 + CreateTwoVersionsOfConfigFile(); // the current file has an invalid extension, delete it and create version 10 and version 11
1.630 + DoCfgOpenTests(11); // only version 11 will be processed (as it is the highest version), and 11 will be stored in the settings table
1.631 +
1.632 + // Test a config file that contains an invalid statement and a valid statement
1.633 + UpgradeDbConfigFile(11); // the current file versions are 10 and 11, replace them with 12
1.634 + DoCfgOpenTests(12); // version 12 will be successfully processed (the invalid statement will be ignored and the valid statement executed) and stored in the settings table
1.635 +
1.636 + // Test a config file that contains a SQL style comment
1.637 + UpgradeDbConfigFile(12); // the current file version is 12, replace it with 13
1.638 + DoCfgOpenTests(13); // version 13 will be successfully processed (the SQL style comment will be ignored) and stored in the settings table
1.639 +
1.640 + // Test a config file that contains a 'C' style comment
1.641 + UpgradeDbConfigFile(13); // the current file version is 13, replace it with 14
1.642 + DoCfgOpenTests(14); // version 14 will be successfully processed (the 'C' style comment will be ignored) and stored in the settings table
1.643 + }
1.644 +
1.645 +void DoNewDbCfgOpenTest()
1.646 + {
1.647 + // Create Db5 - a config file already exists for this database
1.648 + CreateDb5();
1.649 +
1.650 + // Open the shared, secure database Db5 - config ops should be applied on it.
1.651 + // There should now be 1 index in the table.
1.652 + TheTest.Printf(_L("===NewDbCfg: Open shared, secure database\r\n"));
1.653 + DoCfgOpenTest(1, KCfgDb5, _L("table5"), 1);
1.654 +
1.655 + // Open again the same shared, secure database - no config should occur (it has already been done)
1.656 + TheTest.Printf(_L("===NewDbCfg: Open shared, secure database again\r\n"));
1.657 + DoCfgOpenTest(1, KCfgDb5, _L("table5"), 1);
1.658 + }
1.659 +
1.660 +void DoCfgAttachTests(TInt aExpectedStoredVersion = 0)
1.661 + {
1.662 + // Open a private, secure database - no config should occur
1.663 + TheTest.Printf(_L("===CfgAttach: Open private, secure database\r\n"));
1.664 + TInt err = TheDb.Open(KCfgDb3);
1.665 + TEST2(err, KErrNone);
1.666 + // Attach a shared, secure database - the db1 config file should not be processed
1.667 + TheTest.Printf(_L("===CfgAttach: Attach shared, secure database\r\n"));
1.668 + err = TheDb.Attach(KCfgDb1, KAttachDb1);
1.669 + TEST2(err, KErrNone);
1.670 + TheDb.Close();
1.671 + CheckSystemSettingsTable(KCfgDb1, aExpectedStoredVersion); // check that the config file has not been processed for db1
1.672 + CheckSystemSettingsTable(KCfgDb3, 0);
1.673 +
1.674 + // Open a public database - no config should occur
1.675 + TheTest.Printf(_L("===CfgAttach: Open public database\r\n"));
1.676 + err = TheDb.Open(KCfgDb4);
1.677 + TEST2(err, KErrNone);
1.678 + // Attach a shared, secure database - no config should occur (there is no config file for this database)
1.679 + TheTest.Printf(_L("===CfgAttach: Attach shared, secure database (that has no config file)\r\n"));
1.680 + err = TheDb.Attach(KCfgDb2, KAttachDb2);
1.681 + TEST2(err, KErrNone);
1.682 + TheDb.Close();
1.683 + CheckSystemSettingsTable(KCfgDb2, 0);
1.684 + CheckSystemSettingsTable(KCfgDb4, 0);
1.685 + }
1.686 +
1.687 +void DoUpgradedCfgAttachTest()
1.688 + {
1.689 + // Upgrade the config file for KCfgDb1, i.e. replace v1 file with v2 file
1.690 + UpgradeDbConfigFile(1);
1.691 + DoCfgAttachTests(2);
1.692 + }
1.693 +
1.694 +void DoBadCfgAttachTests()
1.695 + {
1.696 + // Test an empty config file
1.697 + UpgradeDbConfigFile(2); // the current file version is 02, replace it with 03
1.698 + DoCfgAttachTests(3); // version 03 will not be processed so no update to settings table
1.699 +
1.700 + // Test a config file with unsupported operations
1.701 + UpgradeDbConfigFile(3); // the current file version is 03, replace it with 04
1.702 + DoCfgAttachTests(4); // version 04 will not be processed so no update to settings table
1.703 +
1.704 + // Test a config file with only whitespace in it
1.705 + UpgradeDbConfigFile(4); // the current file version is 04, replace it with 05
1.706 + DoCfgAttachTests(5); // version 05 will not be processed so no update to settings table
1.707 +
1.708 + // Test a config file with operations on an invalid table
1.709 + UpgradeDbConfigFile(5); // the current file version is 05, replace it with 06
1.710 + DoCfgAttachTests(6); // version 06 will not be processed so no update to settings table
1.711 +
1.712 + // Test a config file that contains an invalid comment style
1.713 + UpgradeDbConfigFile(6); // the current file version is 06, replace it with 07
1.714 + DoCfgAttachTests(7); // version 07 will not be processed so no update to settings table
1.715 +
1.716 + // Test a config file that contains a sequence of statements as one statement (this is currently unsupported)
1.717 + UpgradeDbConfigFile(7); // the current file version is 07, replace it with 08
1.718 + DoCfgAttachTests(8); // version 08 will not be processed so no update to settings table
1.719 +
1.720 + // Test a config file that contains whitespace before and after the SQL statement
1.721 + UpgradeDbConfigFile(8); // the current file version is 08, replace it with 09
1.722 + DoCfgAttachTests(9); // version 09 will not be processed so no update to settings table
1.723 +
1.724 + // Test a config file that has a lower extension number
1.725 + DowngradeDbConfigFile(9); // the current file version is 09, replace it with 08
1.726 + DoCfgAttachTests(9); // version 08 will not be processed so no update to settings table
1.727 +
1.728 + // Test a config file that has an invalid extension
1.729 + CreateCorruptDbConfigFile(8); // the current file version is 08, replace it with a file with an invalid extension
1.730 + DoCfgAttachTests(9); // the invalid file will not be processed so no update to settings table
1.731 +
1.732 + // Test two versions of the config file (two versions should not be present at the same time)
1.733 + CreateTwoVersionsOfConfigFile(); // the current file has an invalid extension, delete it and create version 10 and version 11
1.734 + DoCfgAttachTests(11); // neither version 10 or 11 will be processed so no update to settings table
1.735 +
1.736 + // Test a config file that contains an invalid statement and a valid statement
1.737 + UpgradeDbConfigFile(11); // the current file versions are 10 and 11, replace them with 12
1.738 + DoCfgAttachTests(12); // version 12 will not be processed so no update to settings table
1.739 +
1.740 + // Test a config file that contains a SQL style comment
1.741 + UpgradeDbConfigFile(12); // the current file version is 12, replace it with 13
1.742 + DoCfgAttachTests(13); // version 13 will not be processed so no update to settings table
1.743 +
1.744 + // Test a config file that contains a 'C' style comment
1.745 + UpgradeDbConfigFile(13); // the current file version is 13, replace it with 14
1.746 + DoCfgAttachTests(14); // version 14 will not be processed so no update to settings table
1.747 + }
1.748 +
1.749 +void DoNewDbCfgAttachTest()
1.750 + {
1.751 + // Create Db5 - a config file already exists for this
1.752 + CreateDb5();
1.753 +
1.754 + // Open a private, secure database - no config should occur
1.755 + TheTest.Printf(_L("===NewDbCfgAttach: Open private, secure database\r\n"));
1.756 + TInt err = TheDb.Open(KCfgDb3);
1.757 + TEST2(err, KErrNone);
1.758 + CheckRecordCount(_L("table3"));
1.759 + CheckIndexCount(0);
1.760 +
1.761 + // Attach a shared, secure database - the db5 config file should not be processed
1.762 + TheTest.Printf(_L("===NewDbCfgAttach: Attach shared, secure database\r\n"));
1.763 + err = TheDb.Attach(KCfgDb5, KAttachDb5);
1.764 + TEST2(err, KErrNone);
1.765 + CheckRecordCount(_L("table5"));
1.766 + CheckIndexCount(0); // there should still be no indices in the table
1.767 + TheDb.Close();
1.768 + CheckSystemSettingsTable(KCfgDb5, 1); // check that the config file has been processed for db1
1.769 + CheckSystemSettingsTable(KCfgDb3, 0);
1.770 + }
1.771 +
1.772 +void ResetStoredCollationDll()
1.773 + {
1.774 + // Note: We have to use SQLite directly to access the settings
1.775 + // table as the SQL Server denies permission to access this table
1.776 + // as it is in a shared, secure database
1.777 +
1.778 + TParse parse;
1.779 + parse.Set(KCfgDb1, &KSqlSrvPrivatePath, 0);
1.780 +
1.781 + TBuf8<KMaxFileName + 1> dbFileName;
1.782 + dbFileName.Copy(parse.FullName());
1.783 +
1.784 + sqlite3 *dbHandle = NULL;
1.785 + TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
1.786 + TEST2(rc, SQLITE_OK);
1.787 +
1.788 + TBuf<100> queryBuf;
1.789 + queryBuf.Append(KResetCollationDllSql());
1.790 +
1.791 + sqlite3_stmt* stmtHandle = NULL;
1.792 + const void* stmtTailZ = NULL;
1.793 + rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
1.794 + TEST2(rc, SQLITE_OK);
1.795 +
1.796 + rc = sqlite3_step(stmtHandle);
1.797 + TEST2(rc, SQLITE_DONE);
1.798 +
1.799 + sqlite3_finalize(stmtHandle);
1.800 + sqlite3_close(dbHandle);
1.801 + }
1.802 +
1.803 +void CheckCollationDllUpdated()
1.804 + {
1.805 + // Note: We have to use SQLite directly to access the settings
1.806 + // table as the SQL Server denies permission to access this table
1.807 + // as it is in a shared, secure database
1.808 +
1.809 + TParse parse;
1.810 + parse.Set(KCfgDb1, &KSqlSrvPrivatePath, 0);
1.811 +
1.812 + TBuf8<KMaxFileName + 1> dbFileName;
1.813 + dbFileName.Copy(parse.FullName());
1.814 +
1.815 + sqlite3 *dbHandle = NULL;
1.816 + TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
1.817 + TEST2(rc, SQLITE_OK);
1.818 +
1.819 + _LIT(KGetCollationDllSql, "SELECT CollationDllName FROM symbian_settings");
1.820 + TBuf<100> queryBuf;
1.821 + queryBuf.Append(KGetCollationDllSql());
1.822 +
1.823 + sqlite3_stmt* stmtHandle = NULL;
1.824 + const void* stmtTailZ = NULL;
1.825 + rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
1.826 + TEST2(rc, SQLITE_OK);
1.827 +
1.828 + rc = sqlite3_step(stmtHandle);
1.829 + TEST2(rc, SQLITE_ROW);
1.830 +
1.831 + const TUint16* collationDllName = (const TUint16*)sqlite3_column_text16(stmtHandle, 0);
1.832 + TInt collationDllNameLen = sqlite3_column_bytes(stmtHandle, 0) / sizeof(TUint16);
1.833 + TPtrC ptr(collationDllName, collationDllNameLen);
1.834 +
1.835 + rc = sqlite3_step(stmtHandle);
1.836 + TEST2(rc, SQLITE_DONE);
1.837 +
1.838 + sqlite3_finalize(stmtHandle);
1.839 + sqlite3_close(dbHandle);
1.840 +
1.841 + _LIT(KTestCollationDllName, "hjagafsff");//The same as the used in KResetCollationDllSql statement
1.842 + TEST(ptr != KTestCollationDllName);
1.843 + }
1.844 +
1.845 +/**
1.846 +@SYMTestCaseID SYSLIB-SQL-UT-4010
1.847 +@SYMTestCaseDesc New database configuration files feature - unit test.
1.848 + The test opens several test databases, and the database configuration
1.849 + file for one of the shared, secure databases is processed. This is
1.850 + repeated for a variety of versions of the database configuration file,
1.851 + both valid and invalid. The same tests are repeated for when attaching,
1.852 + rather than opening, the test databases. The test also verifies that
1.853 + reindexing occurs if necessary when a database is opened or attached,
1.854 + regardless of whether or not database configuration is also required.
1.855 + Finally, the test also verifies that a config file that exists before
1.856 + the database itself is created will be processed when the database is
1.857 + opened for the first time.
1.858 +@SYMTestPriority High
1.859 +@SYMTestActions New database configuration files feature - unit test.
1.860 +@SYMTestExpectedResults The test must not fail
1.861 +@SYMCR LMAN-79SJ7L
1.862 +*/
1.863 +void DoDbCfgTests()
1.864 + {
1.865 + // Do 'open' tests for new db config file feature
1.866 + DoCfgOpenTests(1); // open the test databases
1.867 + DoUpgradedCfgOpenTest(); // upgrade the config file for db1 and reopen the test databases
1.868 + DoBadCfgOpenTests(); // corrupt the config file for db1 (in a variety of ways) and reopen the test databases
1.869 + DoNewDbCfgOpenTest(); // create a db for which a config file already exists and then open the db
1.870 +
1.871 + // Recreate the original dbs and config files
1.872 + DeleteCfgFilesAndDbs();
1.873 + CreateCfgFilesAndDbs();
1.874 +
1.875 + // Do 'attach' tests for new db config file feature
1.876 + DoCfgAttachTests(1); // attach the test databases
1.877 + DoUpgradedCfgAttachTest(); // upgrade the config file for db1 and reattach the test databases
1.878 + DoBadCfgAttachTests(); // corrupt the config file for db1 (in a variety of ways) and reattach the test databases
1.879 + DoNewDbCfgAttachTest(); // create a db for which a config file already exists and then attach the db
1.880 +
1.881 + // Recreate the original dbs and config files
1.882 + DeleteCfgFilesAndDbs();
1.883 + CreateCfgFilesAndDbs();
1.884 +
1.885 + // Do the test that causes both reindexing and db configuration to occur when db1 is opened
1.886 + ResetStoredCollationDll();
1.887 + DoCfgOpenTests(1);
1.888 + CheckCollationDllUpdated();
1.889 +
1.890 + // Recreate the original dbs and config files
1.891 + DeleteCfgFilesAndDbs();
1.892 + CreateCfgFilesAndDbs();
1.893 +
1.894 + // Do the test that causes reindexing to occur when db1 is attached (no db configuration occurs for attach)
1.895 + ResetStoredCollationDll();
1.896 + DoCfgAttachTests(1);
1.897 + CheckCollationDllUpdated(); // db1's stored collation dll name should now match db3's (to which Db1 is attached) stored collation name
1.898 + }
1.899 +
1.900 +/**
1.901 +@SYMTestCaseID SYSLIB-SQL-UT-4013
1.902 +@SYMTestCaseDesc New database configuration files feature - OOM test.
1.903 + The test opens a shared secure database for which there
1.904 + exists a database configuration file that is to be processed.
1.905 + The open call is executed within an OOM loop, which causes
1.906 + an OOM error to occur at different stages of the open call.
1.907 + The test verifies that OOM errors are handled correctly and
1.908 + that on the final loop - when no OOM errors occur - the database is
1.909 + successfully opened and the database configuration file is processed.
1.910 +@SYMTestPriority High
1.911 +@SYMTestActions New database configuration files feature - OOM test.
1.912 +@SYMTestExpectedResults The test must not fail
1.913 +@SYMCR LMAN-79SJ7L
1.914 +*/
1.915 +void DoDbCfgOOMTests()
1.916 + {
1.917 + // Recreate the original dbs and config files
1.918 + DeleteCfgFilesAndDbs();
1.919 + CreateCfgFilesAndDbs();
1.920 +
1.921 + // The server is stopped at the end of CreateCfgFilesAndDbs().
1.922 + // Before the test loop below begins we attach Db1 so that the
1.923 + // server starts up again and stores Db1's security policy in
1.924 + // CSqlServer::iSecurityMap. Otherwise there will be unmatching
1.925 + // allocated cells in the test below. Do not call Detach() before
1.926 + // Close(). We 'attach' Db1 here rather than 'open' it because
1.927 + // open is the API that we want to test in the while loop
1.928 + TInt err = TheDb.Open(KCfgDb3);
1.929 + TEST2(err, KErrNone);
1.930 + err = TheDb.Attach(KCfgDb1, KAttachDb1);
1.931 + TEST2(err, KErrNone);
1.932 + TheDb.Close();
1.933 +
1.934 + err = KErrNoMemory;
1.935 + TInt failingAllocationNo = 0;
1.936 + while(err == KErrNoMemory)
1.937 + {
1.938 + MarkHandles();
1.939 + MarkAllocatedCells();
1.940 +
1.941 + __UHEAP_MARK;
1.942 +
1.943 + TheTest.Printf(_L("%d\r"), failingAllocationNo + 1);
1.944 +
1.945 + // Set failure rate
1.946 + TSqlResourceTester::SetDbHeapFailure(RHeap::EDeterministic, ++failingAllocationNo);
1.947 + err = TheDb.Open(KCfgDb1);
1.948 + if(err != KErrNoMemory)
1.949 + {
1.950 + TEST2(err, KErrNone);
1.951 + TheDb.Close();
1.952 + if(GuessSystemSettingsTable(KCfgDb1, 0))
1.953 + {
1.954 + err = KErrNoMemory;
1.955 + }
1.956 + }
1.957 +
1.958 + // Reset failure rate
1.959 + TSqlResourceTester::SetDbHeapFailure(RHeap::ENone, 0);
1.960 +
1.961 + TheDb.Close();
1.962 +
1.963 + __UHEAP_MARKEND;
1.964 +
1.965 + CheckAllocatedCells();
1.966 + CheckHandles();
1.967 + }
1.968 + TEST2(err, KErrNone);
1.969 + TheTest.Printf(_L("\r\n"));
1.970 + CheckSystemSettingsTable(KCfgDb1, 1); // check that the settings table has been updated with v01 of the config file
1.971 + }
1.972 +
1.973 +/**
1.974 +@SYMTestCaseID SYSLIB-SQL-UT-4014
1.975 +@SYMTestCaseDesc New database configuration files feature - File I/O failures test.
1.976 + The test opens a shared secure database for which there
1.977 + exists a database configuration file that is to be processed.
1.978 + The open call is executed within a file I/O failure loop, which
1.979 + causes a selection of file I/O errors to occur at different stages
1.980 + of the open call.
1.981 + The test verifies that file I/O errors are handled correctly and
1.982 + that on the final loop - when no file I/O errors occur - the database
1.983 + is successfully opened and the database configuration file is processed.
1.984 + NOTE: This test also acts as the test case for defect DEF116688.
1.985 +@SYMTestPriority High
1.986 +@SYMTestActions New database configuration files feature - File I/O failures test.
1.987 +@SYMTestExpectedResults The test must not fail
1.988 +@SYMCR LMAN-79SJ7L
1.989 +*/
1.990 +void DoDbCfgFileIOFailuresTests()
1.991 + {
1.992 + // Recreate the original dbs and config files
1.993 + DeleteCfgFilesAndDbs();
1.994 + CreateCfgFilesAndDbs();
1.995 +
1.996 + // The server is stopped at the end of CreateCfgFilesAndDbs().
1.997 + // Before the test loop below begins we start the server again
1.998 + // by opening Db3) so that any server start up file i/o ops will
1.999 + // succeed. We don't open Db1 here because opening Db1 is what
1.1000 + // we want to test in the while loop
1.1001 + TInt err = TheDb.Open(KCfgDb3);
1.1002 + TEST2(err, KErrNone);
1.1003 + TheDb.Close();
1.1004 +
1.1005 + TBool isFinished = EFalse;
1.1006 + err = KErrNotFound;
1.1007 + TInt iter = 0;
1.1008 + TheTest.Printf(_L("Iteration\r\n"));
1.1009 + for(TInt cnt = 0; !isFinished; ++cnt)
1.1010 + {
1.1011 + for(TInt fsError = KErrNotFound; fsError >= KErrUnderflow; --fsError) // errors -1 to -10 will be generated
1.1012 + {
1.1013 + TheTest.Printf(_L("%d/%d \r"), ++iter, fsError);
1.1014 + (void)TheFs.SetErrorCondition(fsError, cnt); // set error code and how soon it is to occur
1.1015 + err = TheDb.Open(KCfgDb1);
1.1016 + (void)TheFs.SetErrorCondition(KErrNone);
1.1017 + TheDb.Close();
1.1018 + if(err != KErrNone)
1.1019 + {
1.1020 + // An error has occured. We know that this means that the database
1.1021 + // configuration part of the open call wasn't reached (because the
1.1022 + // database configuration part returns KErrNone even if it fails).
1.1023 + // But check anyway that the database content is still the same as
1.1024 + // before, i.e. the settings table has not been updated
1.1025 + CheckSystemSettingsTable(KCfgDb1, 0);
1.1026 + }
1.1027 + else
1.1028 + {
1.1029 + // Either the database configuration file for Db1 has been successfully
1.1030 + // processed or it failed part-way through being processed (KErrNone is
1.1031 + // returned in this case too).
1.1032 + // If it was the former then the the settings table will have
1.1033 + // been updated to store v01 of the config file
1.1034 + if(GuessSystemSettingsTable(KCfgDb1, 1))
1.1035 + {
1.1036 + isFinished = ETrue;
1.1037 + break;
1.1038 + }
1.1039 + }
1.1040 + }
1.1041 + }
1.1042 + TheTest.Printf(_L("\r\n"));
1.1043 + TEST2(err, KErrNone);
1.1044 + // Check that the database configuration was allowed to be successfully applied in one of the loops
1.1045 + CheckSystemSettingsTable(KCfgDb1, 1); // check that the settings table has been updated with v01 of the config file
1.1046 + }
1.1047 +
1.1048 +/**
1.1049 +@SYMTestCaseID SYSLIB-SQL-UT-4015
1.1050 +@SYMTestCaseDesc New database configuration files feature - Performance test.
1.1051 + The test measures:
1.1052 + - the startup time of the SQL Server when 0 and 4 database
1.1053 + configuration files exist
1.1054 + - the time taken to open a shared, secure database when a
1.1055 + database configuration file does and does not exist for it
1.1056 + - the time taken to open a shared, secure database when a
1.1057 + database configuration file exists for it but it has already
1.1058 + been processed
1.1059 + - the time taken to attach a shared, secure database when a
1.1060 + database configuration file does and does not exist for it
1.1061 +@SYMTestPriority High
1.1062 +@SYMTestActions New database configuration files feature - Performance test.
1.1063 +@SYMTestExpectedResults The test must not fail
1.1064 +@SYMCR LMAN-79SJ7L
1.1065 +*/
1.1066 +void DoDbCfgPerfTests()
1.1067 + {
1.1068 + // Recreate the original dbs
1.1069 + DeleteCfgFilesAndDbs();
1.1070 + CreateCfgDbs();
1.1071 + KillSqlServer();
1.1072 +
1.1073 + // Measure the start up time of the server when
1.1074 + // there are no database configuration files to be cached.
1.1075 + // Open Db4 (public db):
1.1076 + // No reindexing required
1.1077 + // Database configuration is not considered
1.1078 + TUint32 start = User::FastCounter();
1.1079 + TInt err = TheDb.Open(KCfgDb4);
1.1080 + TUint32 end = User::FastCounter();
1.1081 + TEST2(err, KErrNone);
1.1082 + CheckRecordCount(_L("table4"));
1.1083 + CheckIndexCount(0);
1.1084 + TheDb.Close();
1.1085 + CheckSystemSettingsTable(KCfgDb4, 0);
1.1086 + TInt ms = CalcTimeMs(start, end);
1.1087 + TheTest.Printf(_L("Execution time: Server startup (via Open call) - no database config files to cache: %d ms\r\n"), ms);
1.1088 +
1.1089 + // Measure the time to open Db1 when no database
1.1090 + // configuration file exists for it.
1.1091 + // Open Db1 (shared, secure db):
1.1092 + // No reindexing required
1.1093 + // Database configuration is considered but no config file is found
1.1094 + start = User::FastCounter();
1.1095 + err = TheDb.Open(KCfgDb1);
1.1096 + end = User::FastCounter();
1.1097 + TEST2(err, KErrNone);
1.1098 + CheckRecordCount(_L("table1"));
1.1099 + CheckIndexCount(0);
1.1100 + TheDb.Close();
1.1101 + CheckSystemSettingsTable(KCfgDb1, 0);
1.1102 + ms = CalcTimeMs(start, end);
1.1103 + TheTest.Printf(_L("Execution time: Open shared, secure Db1 - no config file is found: %d ms\r\n"), ms);
1.1104 +
1.1105 + // Measure the time to attach Db1 (database configuration will not be considered).
1.1106 + // Attach Db1 (shared, secure db):
1.1107 + // No reindexing required
1.1108 + // Database configuration is not considered
1.1109 + TheDb.Open(KCfgDb3);
1.1110 + TEST2(err, KErrNone);
1.1111 + start = User::FastCounter();
1.1112 + err = TheDb.Attach(KCfgDb1, KAttachDb1);
1.1113 + end = User::FastCounter();
1.1114 + TEST2(err, KErrNone);
1.1115 + TheDb.Close();
1.1116 + CheckSystemSettingsTable(KCfgDb3, 0);
1.1117 + CheckSystemSettingsTable(KCfgDb1, 0);
1.1118 + ms = CalcTimeMs(start, end);
1.1119 + TheTest.Printf(_L("Execution time: Attach shared, secure Db1 - database config is not considered: %d ms\r\n"), ms);
1.1120 +
1.1121 + // Create the 4 version 01 config files now
1.1122 + CreateCfgFiles();
1.1123 + KillSqlServer(); // stop the server so that the files are found when it is restarted
1.1124 +
1.1125 + // Measure the start up time of the server when
1.1126 + // there are 4 database configuration files to be cached.
1.1127 + // Open Db4 (public db):
1.1128 + // No reindexing required
1.1129 + // Database configuration is not considered
1.1130 + start = User::FastCounter();
1.1131 + err = TheDb.Open(KCfgDb4);
1.1132 + end = User::FastCounter();
1.1133 + TEST2(err, KErrNone);
1.1134 + CheckRecordCount(_L("table4"));
1.1135 + CheckIndexCount(0);
1.1136 + TheDb.Close();
1.1137 + CheckSystemSettingsTable(KCfgDb4, 0);
1.1138 + ms = CalcTimeMs(start, end);
1.1139 + TheTest.Printf(_L("Execution time: Server startup (via Open call) - 4 database config files to cache: %d ms\r\n"), ms);
1.1140 +
1.1141 + // Measure the time to open Db1 when a database
1.1142 + // configuration file exists for it.
1.1143 + // Open Db1 (shared, secure db):
1.1144 + // No reindexing required
1.1145 + // Database configuration is considered, a file is found and config is applied (3 indices are created)
1.1146 + start = User::FastCounter();
1.1147 + err = TheDb.Open(KCfgDb1);
1.1148 + end = User::FastCounter();
1.1149 + TEST2(err, KErrNone);
1.1150 + CheckRecordCount(_L("table1"));
1.1151 + CheckIndexCount(3);
1.1152 + TheDb.Close();
1.1153 + CheckSystemSettingsTable(KCfgDb1, 1);
1.1154 + ms = CalcTimeMs(start, end);
1.1155 + TheTest.Printf(_L("Execution time: Open shared, secure Db1 - config file is found and applied: %d ms\r\n"), ms);
1.1156 +
1.1157 + // Measure the time to open Db1 when a database
1.1158 + // configuration file exists for it but is has already been processed.
1.1159 + // Open Db1 (shared, secure db):
1.1160 + // No reindexing required
1.1161 + // Database configuration is considered, a file is found but it has already been processed
1.1162 + start = User::FastCounter();
1.1163 + err = TheDb.Open(KCfgDb1);
1.1164 + end = User::FastCounter();
1.1165 + TEST2(err, KErrNone);
1.1166 + CheckRecordCount(_L("table1"));
1.1167 + CheckIndexCount(3);
1.1168 + TheDb.Close();
1.1169 + CheckSystemSettingsTable(KCfgDb1, 1);
1.1170 + ms = CalcTimeMs(start, end);
1.1171 + TheTest.Printf(_L("Execution time: Open shared, secure Db1 - config file is found but already processed: %d ms\r\n"), ms);
1.1172 +
1.1173 + // Measure the time to attach Db1 (database configuration will not be considered).
1.1174 + // Attach Db1 (shared, secure db):
1.1175 + // No reindexing required
1.1176 + // Database configuration is not considered
1.1177 + TheDb.Open(KCfgDb3);
1.1178 + TEST2(err, KErrNone);
1.1179 + start = User::FastCounter();
1.1180 + err = TheDb.Attach(KCfgDb1, KAttachDb1);
1.1181 + end = User::FastCounter();
1.1182 + TEST2(err, KErrNone);
1.1183 + TheDb.Close();
1.1184 + CheckSystemSettingsTable(KCfgDb3, 0);
1.1185 + CheckSystemSettingsTable(KCfgDb1, 1);
1.1186 + ms = CalcTimeMs(start, end);
1.1187 + TheTest.Printf(_L("Execution time: Attach shared, secure Db1 - database config is not considered: %d ms\r\n"), ms);
1.1188 + }
1.1189 +
1.1190 +void TestStatements()
1.1191 + {
1.1192 + _LIT(KDbName, "attachDb");
1.1193 + TBuf<200> buf;
1.1194 +
1.1195 + // supported statements
1.1196 + TBool rc = IsStatementSupported(_L("CREATE INDEX idx ON tbl(ColA)"), KDbName, buf);
1.1197 + TEST(rc);
1.1198 + rc = IsStatementSupported(_L("CREATE INDEX IF NOT EXISTS idx ON tbl(ColA)"), KDbName, buf);
1.1199 + TEST(rc);
1.1200 +
1.1201 + // unsupported statements
1.1202 + rc = IsStatementSupported(_L("CREATE UNIQUE INDEX idx ON tbl(ColA)"), KDbName, buf);
1.1203 + TEST(!rc);
1.1204 + rc = IsStatementSupported(_L("CREATE idx ON tbl(ColA)"), KDbName, buf);
1.1205 + TEST(!rc);
1.1206 + }
1.1207 +
1.1208 +/**
1.1209 +@SYMTestCaseID SYSLIB-SQL-UT-4030
1.1210 +@SYMTestCaseDesc Test IsStatementSupportedLC function.
1.1211 + This function checks either SQL statement from DB configuration file is supported or not.
1.1212 + In the case of supported statement, function allocates buffer and copies statement into that buffer.
1.1213 + Call IsStatementSupportedLC on several supported and unsupported SQL statements.
1.1214 +@SYMTestPriority High
1.1215 +@SYMTestActions Test IsStatementSupportedLC function.
1.1216 +@SYMTestExpectedResults The test must not fail
1.1217 +@SYMDEF DEF118058
1.1218 +*/
1.1219 +void DoIsStatementSupportedTests()
1.1220 + {
1.1221 + TestStatements();
1.1222 + }
1.1223 +
1.1224 +void DoLongDbNameTest()
1.1225 + {
1.1226 + //Create the database
1.1227 + RSqlSecurityPolicy securityPolicy = CreateSecurityPolicy();
1.1228 +
1.1229 + TInt err = TheDb.Create(KLongDbName1, securityPolicy);
1.1230 + TEST2(err, KErrNone);
1.1231 + err = TheDb.Exec(_L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
1.1232 + TEST(err >= 0);
1.1233 + err = TheDb.Exec(_L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"));
1.1234 + TEST(err == 1);
1.1235 + TheDb.Close();
1.1236 + //Kill the server (to reload config file names at the server startup)
1.1237 + KillSqlServer();
1.1238 + ///////////////////////////////////////////////////////////////////////
1.1239 + TheTest.Printf(_L("Open a database with a long name\r\n"));
1.1240 + //Create cfg file
1.1241 + RFile file;
1.1242 + TFileName fileName;
1.1243 + err = file.Create(TheFs, KLongCfgName1, EFileRead | EFileWrite);
1.1244 + TEST2(err, KErrNone);
1.1245 + TPtrC8 pDb1((const TUint8*)KCfgConfigFileValidStmt().Ptr(), KCfgConfigFileValidStmt().Length());
1.1246 + err = file.Write(pDb1);
1.1247 + file.Close();
1.1248 + TEST2(err, KErrNone);
1.1249 + //Open the database
1.1250 + err = TheDb.Open(KLongDbName1);
1.1251 + TEST2(err, KErrNone);
1.1252 + CheckRecordCount(_L("table1"));
1.1253 + CheckIndexCount(1); // there should now be 1 index in the table
1.1254 + TheDb.Close();
1.1255 + const TInt KVersion = 1;
1.1256 + CheckSystemSettingsTable(KLongDbName1, KVersion); // check that the ops in the specified config file have been applied
1.1257 + ///////////////////////////////////////////////////////////////////////
1.1258 + TheTest.Printf(_L("Attach a database with a long logical name\r\n"));
1.1259 + //Attached database test
1.1260 + //Recreate the database
1.1261 + (void)RSqlDatabase::Delete(KLongDbName1);
1.1262 + err = TheDb.Create(KLongDbName1, securityPolicy);
1.1263 + TEST2(err, KErrNone);
1.1264 + err = TheDb.Exec(_L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
1.1265 + TEST(err >= 0);
1.1266 + err = TheDb.Exec(_L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"));
1.1267 + TEST(err == 1);
1.1268 + TheDb.Close();
1.1269 + //Kill the server (to reload config file names at the server startup)
1.1270 + KillSqlServer();
1.1271 + //Open the main database
1.1272 + err = TheDb.Open(KCfgDb1);
1.1273 + securityPolicy.Close();
1.1274 + TEST2(err, KErrNone);
1.1275 + //Attach a database with a very long logical name
1.1276 + TFileName attachDbName;
1.1277 + attachDbName.SetLength(KMaxFileName);
1.1278 + attachDbName.Fill(TChar('A'));
1.1279 + err = TheDb.Attach(KLongDbName1, attachDbName);
1.1280 + TEST2(err, KErrNone);
1.1281 + err = TheDb.Detach(attachDbName);
1.1282 + TEST2(err, KErrNone);
1.1283 + TheDb.Close();
1.1284 + CheckSystemSettingsTable(KLongDbName1, KVersion); // check that the ops in the specified config file have been applied
1.1285 + //Cleanup
1.1286 + (void)RSqlDatabase::Delete(KLongDbName1);
1.1287 + }
1.1288 +
1.1289 +void DoTests()
1.1290 + {
1.1291 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4010 Database config files test"));
1.1292 + DoDbCfgTests();
1.1293 +
1.1294 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4013 Database config files OOM test"));
1.1295 + DoDbCfgOOMTests();
1.1296 +
1.1297 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4014 Database config files file I/O error simulation test"));
1.1298 + DoDbCfgFileIOFailuresTests();
1.1299 +
1.1300 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4015 Database config files performance test"));
1.1301 + DoDbCfgPerfTests();
1.1302 +
1.1303 + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4030 Database config files - supported SQl statements test"));
1.1304 + DoIsStatementSupportedTests();
1.1305 +
1.1306 + TheTest.Next(_L("'Long database name' tests"));
1.1307 + DoLongDbNameTest();
1.1308 + }
1.1309 +
1.1310 +#endif //SYSLIBS_TEST
1.1311 +
1.1312 +TInt E32Main()
1.1313 + {
1.1314 + TheTest.Title();
1.1315 +
1.1316 + CTrapCleanup* tc = CTrapCleanup::New();
1.1317 + TheTest(tc != NULL);
1.1318 +
1.1319 + __UHEAP_MARK;
1.1320 +
1.1321 +#ifdef SYSLIBS_TEST
1.1322 + TheTest.Start(_L("Setting up the test environment"));
1.1323 + SetupTestEnv();
1.1324 + sqlite3SymbianLibInit();
1.1325 + DoTests();
1.1326 + DestroyTestEnv();
1.1327 + sqlite3SymbianLibFinalize();
1.1328 + CloseSTDLIB();
1.1329 + TheTest.End();
1.1330 +#else
1.1331 + TheTest.Start(_L("This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined!"));
1.1332 + TheTest.End();
1.1333 +#endif
1.1334 +
1.1335 + __UHEAP_MARKEND;
1.1336 +
1.1337 + TheTest.Close();
1.1338 +
1.1339 + delete tc;
1.1340 +
1.1341 + User::Heap().Check();
1.1342 + return KErrNone;
1.1343 + }