--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/TEST/t_sqlconfigfile.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1013 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32test.h>
+#include <sqldb.h>
+//#include "SqlUtil.h"
+#include "SqlSrvConfig.h"
+#include "SqlResourceTester.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+/// This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined! ///
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+RTest TheTest(_L("t_sqlconfigfile test"));
+
+#ifdef SYSLIBS_TEST
+
+RFs TheFs;
+RSqlDatabase TheDb;
+
+_LIT(KTestDir, "c:\\test\\");
+_LIT(KTestDbName, "c:\\test\\t_sqlconfigfile.db");
+_LIT(KSqlSrvConfigFile, "c:\\test\\t_sqlserver.cfg");
+_LIT(KSqlSrvName, "sqlsrv.exe");
+
+enum TConfigParamType {EPrmCacheSize, EPrmPageSize, EPrmDbEncoding};
+
+//Default configuration parameter values, defined in ../test/sqlserver.cfg file
+//(the same as the build-time configuration parameter values)
+const TInt KDefaultPageSize = 1024;
+const TInt KDefaultCacheSize = (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / KDefaultPageSize;
+const TSqlSrvConfigParams::TDbEncoding KDefaultEncoding = TSqlSrvConfigParams::EEncUtf16;
+
+TInt KillProcess(const TDesC& aProcessName);
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Destroy functions
+
+TInt KillProcess(const TDesC& aProcessName)
+ {
+ TFullName name;
+ //RDebug::Print(_L("Find and kill \"%S\" process.\n"), &aProcessName);
+ TBuf<64> pattern(aProcessName);
+ TInt length = pattern.Length();
+ pattern += _L("*");
+ TFindProcess procFinder(pattern);
+
+ while (procFinder.Next(name) == KErrNone)
+ {
+ if (name.Length() > length)
+ {//If found name is a string containing aProcessName string.
+ TChar c(name[length]);
+ if (c.IsAlphaDigit() ||
+ c == TChar('_') ||
+ c == TChar('-'))
+ {
+ // If the found name is other valid application name
+ // starting with aProcessName string.
+ //RDebug::Print(_L(":: Process name: \"%S\".\n"), &name);
+ continue;
+ }
+ }
+ RProcess proc;
+ if (proc.Open(name) == KErrNone)
+ {
+ proc.Kill(0);
+ //RDebug::Print(_L("\"%S\" process killed.\n"), &name);
+ }
+ proc.Close();
+ }
+ return KErrNone;
+ }
+
+void DestroyTestEnv()
+ {
+ TheDb.Close();
+ (void)KillProcess(KSqlSrvName);
+ (void)TheFs.Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ TheFs.Close();
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Test macros and functions
+
+void Check(TInt aValue, TInt aLine)
+ {
+ if(!aValue)
+ {
+ DestroyTestEnv();
+ TheTest(EFalse, aLine);
+ }
+ }
+void Check(TInt aValue, TInt aExpected, TInt aLine)
+ {
+ if(aValue != aExpected)
+ {
+ DestroyTestEnv();
+ RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
+ TheTest(EFalse, aLine);
+ }
+ }
+#define TEST(arg) ::Check((arg), __LINE__)
+#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
+
+// OOM test functions
+
+static TInt TheHandleCount1;
+static TInt TheHandleCount2;
+static TInt TheAllocatedCellsCount;
+
+void MarkHandles()
+ {
+ RThread().HandleCount(TheHandleCount1, TheHandleCount2);
+ }
+
+void CheckHandles()
+ {
+ TInt endHandleCount1;
+ TInt endHandleCount2;
+
+ RThread().HandleCount(endHandleCount1, endHandleCount2);
+
+ TEST(TheHandleCount1 == endHandleCount1);
+ TEST(TheHandleCount2 == endHandleCount2);
+ }
+
+void MarkAllocatedCells()
+ {
+ TheAllocatedCellsCount = User::CountAllocCells();
+ }
+
+void CheckAllocatedCells()
+ {
+ TInt allocatedCellsCount = User::CountAllocCells();
+ TEST(allocatedCellsCount == TheAllocatedCellsCount);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Set up functions
+
+TInt DoCreateSecurityPolicy(RSqlSecurityPolicy& securityPolicy)
+ {
+ const TSecurityPolicy KDefaultPolicy(TSecurityPolicy::EAlwaysPass);
+ if((KErrNone != securityPolicy.Create(KDefaultPolicy))
+ ||
+ (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, KDefaultPolicy))
+ ||
+ (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, KDefaultPolicy))
+ ||
+ (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, KDefaultPolicy)))
+ {
+ return KErrGeneral;
+ }
+
+ return KErrNone;
+ }
+
+void SetupTestEnv()
+ {
+ TInt err = TheFs.Connect();
+ TEST2(err, KErrNone);
+
+ err = TheFs.MkDir(KTestDir);
+ TEST(err == KErrNone || err == KErrAlreadyExists);
+
+ err = TheFs.CreatePrivatePath(EDriveC);
+ TEST(err == KErrNone || err == KErrAlreadyExists);
+
+ (void)TheFs.Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Parameter check functions
+
+TInt DoGetConfigParamValueL(RSqlDatabase& aDb, TConfigParamType aPrmType)
+ {
+ TSqlScalarFullSelectQuery q(aDb);
+ TInt res = 0;
+ switch(aPrmType)
+ {
+ case EPrmCacheSize:
+ res = q.SelectIntL(_L8("PRAGMA cache_size"));
+ break;
+ case EPrmPageSize:
+ res = q.SelectIntL(_L8("PRAGMA page_size"));
+ break;
+ case EPrmDbEncoding:
+ {
+ TBuf<20> dbEncodingText;
+ res = q.SelectTextL(_L8("PRAGMA encoding"), dbEncodingText);
+ TEST2(res, KErrNone);
+ if(dbEncodingText.FindF(_L("UTF-16")) >= 0)
+ {
+ res = TSqlSrvConfigParams::EEncUtf16;
+ }
+ else if(dbEncodingText.FindF(_L("UTF-8")) >= 0)
+ {
+ res = TSqlSrvConfigParams::EEncUtf8;
+ }
+ else
+ {
+ TEST2(0, 1);
+ }
+ }
+ break;
+ default:
+ TEST2(0, 1);
+ break;
+ }
+ return res;
+ }
+
+TInt GetConfigParamValue(RSqlDatabase& aDb, TConfigParamType aPrmType)
+ {
+ TInt res = 0;
+ TRAPD(err, res = DoGetConfigParamValueL(aDb, aPrmType));
+ TEST2(err, KErrNone);
+ return res;
+ }
+
+void AssertConfigPrmValues(RSqlDatabase& aDb, TInt aExpectedCacheSize, TInt aExpectedPageSize, TInt aExpectedDbEncoding)
+ {
+ TInt cacheSize = GetConfigParamValue(aDb, EPrmCacheSize);
+ TInt pageSize = GetConfigParamValue(aDb, EPrmPageSize);
+ TInt dbEncoding = GetConfigParamValue(aDb, EPrmDbEncoding);
+ TEST2(cacheSize, aExpectedCacheSize);
+ TEST2(pageSize, aExpectedPageSize);
+ TEST2(dbEncoding, aExpectedDbEncoding);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Config file replacement functions
+
+// File config strings are 16-bit.
+void ReplaceConfigFile(const TDesC16& aConfig)
+ {
+ (void)KillProcess(KSqlSrvName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ RFile file;
+ TInt err = file.Create(TheFs, KSqlSrvConfigFile, EFileRead | EFileWrite);
+ TEST2(err, KErrNone);
+ TPtrC8 p((const TUint8*)aConfig.Ptr(), aConfig.Length() * sizeof(TUint16));
+ err = file.Write(p);
+ file.Close();
+ TEST2(err, KErrNone);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+//
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3603
+@SYMTestCaseDesc Bad config file test
+ The test creates bad config files like:
+ - empty config file;
+ - "\n" config file;
+ - "\r\n" config file;
+ - config file with comment lines only;
+ Then the test restarts the SQL server and checks that the bad config file is detected and
+ appropriate error code - returned to the caller (during "database create" operation).
+@SYMTestPriority High
+@SYMTestActions Bad config file test
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+*/
+void BadCfgFileTest()
+ {
+ //Empty config file
+ ReplaceConfigFile(_L(""));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrEof);//BC kept - an empty config file is treated as invalid
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"\n" config file
+ ReplaceConfigFile(_L("\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrEof);//BC compatible
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"\r\n" config file
+ ReplaceConfigFile(_L("\r\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrEof);//BC compatible
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //" \r\n" config file
+ ReplaceConfigFile(_L(" \r\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrEof);//BC compatible
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //" # \r\n" config file
+ ReplaceConfigFile(_L(" # \r\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrEof);//BC compatible
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //" # \r\na=b\r\n" config file
+ ReplaceConfigFile(_L(" # \r\na=b\r\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //" # \r\n a=b \r\n" config file
+ ReplaceConfigFile(_L(" # \r\n a=b \r\n"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //" # \r\n a=b " config file
+ ReplaceConfigFile(_L(" # \r\n a=b "));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3604
+@SYMTestCaseDesc Config file with bad parameters test
+ The test creates config files with bad parameters like:
+ - negative cache size;
+ - non-numeric cache size value;
+ - empty cache size value;
+ - negative page size;
+ - non-numeric page size value;
+ - empty page size value;
+ - negative soft heap limit size;
+ - non-numeric soft heap limit value;
+ - empty soft heap limit value;
+ - too small soft heap limit value;
+ - too big soft heap limit value;
+ - negative free page threshold value;
+ - empty free page threshold value;
+ - non-numeric free page threshold value;
+ Then the test restarts the SQL server and checks that the bad config file is detected and
+ appropriate error code - returned to the caller (during "database create" operation).
+@SYMTestPriority High
+@SYMTestActions Config file with bad parameters test
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+ REQ10271
+*/
+void BadCfgFileParametersTest()
+ {
+ /////////////// cache_size ////////////////
+ //"cache_size=-20;" config file
+ ReplaceConfigFile(_L("cache_size=-20;"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"cache_size=456.90" config file
+ ReplaceConfigFile(_L("cache_size=456.90"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"cache_size='dfjkhdfjk';" config file
+ ReplaceConfigFile(_L("cache_size='dfjkhdfjk';"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"cache_size=;" config file
+ ReplaceConfigFile(_L("cache_size=;"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ /////////////// page_size ////////////////
+ //"page_size=-55" config file
+ ReplaceConfigFile(_L("page_size=-55"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"page_size=25.89" config file
+ ReplaceConfigFile(_L("page_size=25.89"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);//BC compatible
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"page_size=gffgrtj" config file
+ ReplaceConfigFile(_L("page_size=gffgrtj"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"page_size=" config file
+ ReplaceConfigFile(_L("page_size="));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //////// soft_heap_limit_kb ///////////
+ //"soft_heap_limit_kb=-10" config file
+ ReplaceConfigFile(_L("soft_heap_limit_kb=-10"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=5" config file (bellow min limit - 8Kb when SYSLIBS_TEST macro is defined)
+ ReplaceConfigFile(_L("soft_heap_limit_kb=5"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=8" config file (the min limit - 8Kb when SYSLIBS_TEST macro is defined)
+ ReplaceConfigFile(_L("soft_heap_limit_kb=8"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=2000000000" config file (above max limit)
+ ReplaceConfigFile(_L("soft_heap_limit_kb=2000000000"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=KMaxTInt/1024" config file (the max limit)
+ TBuf<32> configBuf;
+ configBuf.Copy(_L("soft_heap_limit_kb="));
+ TInt maxSoftHeapLimit = KMaxTInt / 1024;
+ configBuf.AppendNum(maxSoftHeapLimit);
+ ReplaceConfigFile(configBuf);
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=sdfcvyua" config file
+ ReplaceConfigFile(_L("soft_heap_limit_kb=sdfcvyua"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=" config file
+ ReplaceConfigFile(_L("soft_heap_limit_kb="));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=1023.456" config file
+ ReplaceConfigFile(_L("soft_heap_limit_kb=1023.456"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //////// free_space_threshold_kb ///////////
+ //"free_space_threshold_kb=-10" config file
+ ReplaceConfigFile(_L("free_space_threshold_kb=-10"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"free_space_threshold_kb=0" config file
+ ReplaceConfigFile(_L("free_space_threshold_kb=0"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"free_space_threshold_kb=" config file
+ ReplaceConfigFile(_L("free_space_threshold_kb="));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"free_space_threshold_kb=34.56" config file
+ ReplaceConfigFile(_L("free_space_threshold_kb=34.56"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"free_space_threshold_kb=gfghfg" config file
+ ReplaceConfigFile(_L("free_space_threshold_kb=gfghfg"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ /////////////////////////////////////////////
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3605
+@SYMTestCaseDesc Config parameters conflict test.
+ 1) The test creates a database with cache size parameter value specified in both the config file and the
+ config string. The expectation is that the config string parameter will be used.
+ 2) The test creates a database with page size parameter value specified in both the config file and the
+ config string. The expectation is that the config string parameter will be used.
+ 3) The test creates a database with encoding parameter value specified in both the config file and the
+ config string. The expectation is that the config string parameter will be used.
+ 4) The test creates a database with soft heap limit value specified in both the config file and the
+ config string. The expectation is that the database creation will fail (the soft heap limit
+ cannot be configured using a config string).
+ 5) The test creates a database with free page threshold value specified in both the config file and the
+ config string. The expectation is that the database creation will succeeds. The free page threshold
+ value from the config file will be used.
+@SYMTestPriority High
+@SYMTestActions Config parameters conflict test
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+ REQ10271
+*/
+void CfgFileConflictTest()
+ {
+ //"cache_size=200" config file
+ //"cache_size=100" client config string
+ ReplaceConfigFile(_L("cache_size=200"));
+ _LIT8(KConfigStr1, "cache_size=100");
+ TInt err = TheDb.Create(KTestDbName, &KConfigStr1);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, 100, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"page_size=512" config file
+ //"page_size=8192" client config string
+ ReplaceConfigFile(_L("page_size=512"));
+ _LIT8(KConfigStr2, "page_size=8192");
+ err = TheDb.Create(KTestDbName, &KConfigStr2);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (TSqlSrvConfigParams::KDefaultSoftHeapLimitKb * 1024) / 8192, 8192, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"encoding=UTF-16" config file
+ //"encoding=UTF-8" client config string
+ ReplaceConfigFile(_L("encoding=UTF-16"));
+ _LIT8(KConfigStr3, "encoding=UTF-8");
+ err = TheDb.Create(KTestDbName, &KConfigStr3);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, KDefaultCacheSize, KDefaultPageSize, TSqlSrvConfigParams::EEncUtf8);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=900" config file
+ //"soft_heap_limit_kb=800" client config string
+ ReplaceConfigFile(_L("soft_heap_limit_kb=900"));
+ _LIT8(KConfigStr4, "soft_heap_limit_kb=800");
+ err = TheDb.Create(KTestDbName, &KConfigStr4);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"free_space_threshold_kb=100" config file
+ //"free_space_threshold_kb=200" client config string
+ ReplaceConfigFile(_L("free_space_threshold_kb=100"));
+ _LIT8(KConfigStr5, "free_space_threshold_kb=200");
+ err = TheDb.Create(KTestDbName, &KConfigStr5);
+ TEST2(err, KErrArgument);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3606
+@SYMTestCaseDesc Soft Heap Limit - functional test.
+ The test attempts to create a database with the soft heap limit value specified in the config file
+ and different combinations of the page size and cache size parameters in both config file and client
+ config string. The expectation is that when the cache size parameter value is not specified explicitly
+ in the config file or in the config string, the cache size value will be calculated, using the soft
+ heap limit and the database page size.
+@SYMTestPriority High
+@SYMTestActions Soft Heap Limit - functional test.
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+*/
+void SoftHeapLimitFunctionalTest1()
+ {
+ ///////////////////// CREATE DATABASE /////////////////////////////////////////////////////////
+ //"soft_heap_limit_kb=512" config file. (512 is the min soft heap limit value)
+ //Expected result: the database cache size will be (512 * 1024)/page_size;
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / KDefaultPageSize, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=KMaxTInt/1024" config file. (KMaxTInt / 1024 is the max soft heap limit value)
+ //Expected result: the database cache size will be KMaxTInt/page_size;
+ TBuf<32> configBuf;
+ configBuf.Copy(_L("soft_heap_limit_kb="));
+ TInt maxSoftHeapLimit = KMaxTInt / 1024;
+ configBuf.AppendNum(maxSoftHeapLimit);
+ ReplaceConfigFile(configBuf);
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, KMaxTInt / KDefaultPageSize, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512;page_size=2048" config file.
+ //Expected result: the database cache size will be (512 * 1024)/2048. The page size value from the config file is used.
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512;page_size=2048"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / 2048, 2048, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512" config file.
+ //"page_size=4096" client config string.
+ //Expected result: the database cache size will be (512 * 1024)/4096. The page size value from the client config string is used.
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512;"));
+ _LIT8(KConfigStr1, "page_size=4096");
+ err = TheDb.Create(KTestDbName, &KConfigStr1);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / 4096, 4096, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512;page_size=8192" config file.
+ //"page_size=2048" client config string.
+ //Expected result: the database cache size will be (512 * 1024)/2048. The page size value from the client config string is used.
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512;page_size=8192"));
+ _LIT8(KConfigStr2, "page_size=2048");
+ err = TheDb.Create(KTestDbName, &KConfigStr2);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / 2048, 2048, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512;page_size=2048;encoding=UTF-8" config file.
+ //"cache_size=100" client config string.
+ //Expected result: the database cache size will be 100. The soft heap limit is not used for the cache size calculation.
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512;page_size=2048;encoding=UTF-8"));
+ _LIT8(KConfigStr3, "cache_size=100");
+ err = TheDb.Create(KTestDbName, &KConfigStr3);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, 100, 2048, TSqlSrvConfigParams::EEncUtf8);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3607
+@SYMTestCaseDesc Soft Heap Limit - functional test.
+ The test attempts to open a database with the soft heap limit value specified in the config file
+ and different combinations of the page size and cache size parameters in both config file and client
+ config string. The expectation is that when the cache size parameter value is not specified explicitly
+ in the config file or in the config string, the cache size value will be calculated, using the soft
+ heap limit and the database page size (read from the database, not from the config file or string).
+@SYMTestPriority High
+@SYMTestActions Soft Heap Limit - functional test.
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+*/
+void SoftHeapLimitFunctionalTest2()
+ {
+ ///////////////////// OPEN DATABASE /////////////////////////////////////////////////////////
+ //"soft_heap_limit_kb=512;page_size=2048" config file.
+ //Expected result: the database cache size will be (512 * 1024)/2048. The database page size value is used (not the built-time one).
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512;page_size=2048"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / 2048, 2048, KDefaultEncoding);
+ TheDb.Close();
+ ReplaceConfigFile(_L("soft_heap_limit_kb=1024;page_size=8192"));
+ err = TheDb.Open(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (1024 * 1024) / 2048, 2048, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512" config file.
+ //"page_size=4096" client config string.
+ //Expected result: the database cache size will be (512 * 1024)/4096. The database page size value is used (not the built-time one).
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512"));
+ _LIT8(KConfigStr1, "page_size=4096");
+ err = TheDb.Create(KTestDbName, &KConfigStr1);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (512 * 1024) / 4096, 4096, KDefaultEncoding);
+ TheDb.Close();
+ ReplaceConfigFile(_L("soft_heap_limit_kb=1024;page_size=8192"));
+ err = TheDb.Open(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (1024 * 1024) / 4096, 4096, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ //"soft_heap_limit_kb=512" config file.
+ //"page_size=4096" client config string when openning the database.
+ //Expected result: the database cache size will be 512. The database page size value is used (the built-time one).
+ ReplaceConfigFile(_L("soft_heap_limit_kb=512"));
+ err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, 512, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ ReplaceConfigFile(_L("soft_heap_limit_kb=1024;page_size=512"));
+ _LIT8(KConfigStr2, "page_size=4096");
+ err = TheDb.Open(KTestDbName, &KConfigStr2);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, 1024, KDefaultPageSize, KDefaultEncoding);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3608
+@SYMTestCaseDesc Soft Heap Limit - file I/O failure simulation test.
+ The test creates a database with very small soft heap limit value (8Kb).
+ Then the test attempts to insert a record in an explicit transaction while doing
+ file I/O failure simulation.
+@SYMTestPriority High
+@SYMTestActions Soft Heap Limit - file I/O failure simulation test.
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+ REQ10271
+*/
+void FileIOFailureTest()
+ {
+ (void)RSqlDatabase::Delete(KTestDbName);
+ ReplaceConfigFile(_L("soft_heap_limit_kb=8;cache_size=16;page_size=512;free_space_threshold_kb=100"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT)"));
+ TEST(err >= 0);
+ TheDb.Close();
+ err = -1;
+ const TInt KTestRecCnt = 100;
+ for(TInt cnt=1;err<KErrNone;++cnt)
+ {
+ TheTest.Printf(_L("%d \r"), cnt);
+ err = TheDb.Open(KTestDbName);
+ TEST2(err, KErrNone);
+ TInt recCntBegin = 0;
+ TSqlScalarFullSelectQuery q1(TheDb);
+ TRAP(err, recCntBegin = q1.SelectIntL(_L("SELECT COUNT (*) FROM A")));
+ TEST2(err, KErrNone);
+ (void)TheFs.SetErrorCondition(KErrGeneral, cnt);
+ err = TheDb.Exec(_L("BEGIN TRANSACTION"));
+ if(err == KErrNone)
+ {
+ for(TInt i=0;i<KTestRecCnt;++i)
+ {
+ TBuf<300> sql;
+ sql.Format(_L("INSERT INTO A(Id,Name) VALUES(%d, 'A1234567890B1234567890C1234567890D1234567890E1234567890F1234567890G1234567890H1234567890I1234567890J1234567890K1234567890L1234567890M1234567890N1234567890O1234567890P1234567890Q1234567890R1234567890')"), cnt);
+ err = TheDb.Exec(sql);
+ TEST(err == 1 || err < 0);
+ if(err < 0)
+ {
+ break;
+ }
+ }
+ if(err == 1)
+ {
+ err = TheDb.Exec(_L("COMMIT TRANSACTION"));
+ }
+ else if(TheDb.InTransaction()) //the transaction may have been rolled back automatically
+ {
+ err = TheDb.Exec(_L("ROLLBACK TRANSACTION"));
+ }
+ if(err == 0)
+ {
+ err = 1;
+ }
+ }
+ (void)TheFs.SetErrorCondition(KErrNone);
+ if(err < 1)
+ {
+ TheDb.Close();//close the database to recover from the last error
+ TInt err2 = TheDb.Open(KTestDbName);
+ TEST2(err2, KErrNone);
+ }
+ TSqlScalarFullSelectQuery q2(TheDb);
+ TInt recCntEnd = 0;
+ TRAPD(err3, recCntEnd = q2.SelectIntL(_L("SELECT COUNT (*) FROM A")));
+ TheDb.Close();
+ TEST2(err3, KErrNone);
+ //check the database content - all bets are off in a case of an I/O error.
+ //The new records may have actually been inserted.
+ TEST(recCntEnd == recCntBegin || recCntEnd == (recCntBegin + KTestRecCnt));
+ }
+ (void)TheFs.SetErrorCondition(KErrNone);
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-3609
+@SYMTestCaseDesc Soft Heap Limit - OOM test.
+ The test creates a database with very small soft heap limit value (8Kb).
+ The the test attempts to insert a record in an explicit transaction while doing
+ OOM simulation.
+@SYMTestPriority High
+@SYMTestActions Soft Heap Limit - OOM test.
+@SYMTestExpectedResults The test must not fail
+@SYMREQ REQ8162
+ REQ10271
+*/
+void OOMtest()
+ {
+ (void)RSqlDatabase::Delete(KTestDbName);
+ ReplaceConfigFile(_L("soft_heap_limit_kb=8;cache_size=16;page_size=512;free_space_threshold_kb=150"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT)"));
+ TEST(err >= 0);
+ TheDb.Close();
+
+ const TInt KOomIterationCount = 1000;//Instead fo doing the OOM test while "err == KErrNoMemory", the test is
+ //performed KOomIterationCount times, because the "soft heap limit" will
+ //force the SQLite library to reuse some of the already allocated but not used pages.
+ TInt failingAllocationNo = 0;
+ while(failingAllocationNo < KOomIterationCount)
+ {
+ __UHEAP_MARK;
+
+ const TInt KDelayedDbHeapFailureMask = 0x1000;
+ TSqlResourceTester::SetDbHeapFailure(RHeap::EFailNext | KDelayedDbHeapFailureMask, ++failingAllocationNo);
+
+ err = TheDb.Open(KTestDbName);
+ TEST2(err, KErrNone);
+
+ err = TheDb.Exec(_L("BEGIN TRANSACTION"));
+ if(err == KErrNone)
+ {
+ const TInt KTestRecCnt = 4;
+ for(TInt i=0;i<KTestRecCnt;++i)
+ {
+ err = TheDb.Exec(_L("INSERT INTO A(Id,Name) VALUES(1, 'A1234567890B1234567890C1234567890D1234567890E1234567890F1234567890G1234567890H1234567890I1234567890J1234567890K1234567890L1234567890M1234567890N1234567890O1234567890P1234567890Q1234567890R1234567890')"));
+ if(err < 1)
+ {
+ break;
+ }
+ }
+ if(err == 1)
+ {
+ err = TheDb.Exec(_L("COMMIT TRANSACTION"));
+ }
+ else if(TheDb.InTransaction()) //the transaction may have been rolled back automatically
+ {
+ err = TheDb.Exec(_L("ROLLBACK TRANSACTION"));
+ }
+ }
+
+ TSqlResourceTester::SetDbHeapFailure(RHeap::ENone, 0);
+
+ TheDb.Close();
+
+ TheTest.Printf(_L("%d/%d \r"), failingAllocationNo, err);
+
+ __UHEAP_MARKEND;
+
+ TEST(err >= 0 || err == KErrNoMemory);
+ }
+ TEST(err >= 0);
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-4081
+@SYMTestCaseDesc Background compaction, free page threshold - functional test.
+ The test creates a server config file, where the free page threshold is set to be 20 Kb.
+ Then the test creates a database. The test inserts 40 pages (40 Kb) into the database, closes and
+ reopens the database. Then the test deletes some records from the database.
+ But the space in the free pages is not big enough to kick-off the background compaction.
+ The test checks that no compaction has occurred after the deletions.
+ The test deletes more records and the free page threshold is reached.
+ The test checks that after the last deletion the database really has been compacted.
+@SYMTestPriority Medium
+@SYMTestActions Background compaction, free page threshold - functional test.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ10271
+*/
+void FreePageThresholdTest()
+ {
+ const TInt KFreePageThresholdSrvCfgKb = 20;
+ TBuf<50> cfgBuf1;
+ cfgBuf1.Format(_L("free_space_threshold_kb=%d"), KFreePageThresholdSrvCfgKb);
+ ReplaceConfigFile(cfgBuf1);
+
+ const TInt KPageSize = 1024;
+ TBuf8<50> cfgBuf2;
+ cfgBuf2.Format(_L8("page_size=%d;"), KPageSize);
+ //Create a database and insert some records. At the end the database size is bigger than the free pages threshold.
+ (void)RSqlDatabase::Delete(KTestDbName);
+ TInt err = TheDb.Create(KTestDbName, &cfgBuf2);
+ TEST2(err, KErrNone);
+ err = TheDb.Exec(_L("CREATE TABLE A(B BLOB)"));
+ TEST2(err, 1);
+ TBuf8<(KPageSize - 150) * 2> blob;
+ blob.SetLength((KPageSize - 150) * 2);
+ blob.Fill(TChar('A'));
+ for(TInt i=0;i<KFreePageThresholdSrvCfgKb*2;++i)
+ {
+ TBuf8<KPageSize * 2> sql;
+ sql.Format(_L8("INSERT INTO A VALUES(x'%S')"), &blob);
+ err = TheDb.Exec(sql);
+ TEST2(err, 1);
+ }
+ TheDb.Close();
+ //Reopen the database and delete some records. The free spave is not big enough to kick-off the background compaction.
+ err = TheDb.Open(KTestDbName);
+ TEST2(err, KErrNone);
+ for(TInt i=0;i<10;++i)
+ {
+ TBuf8<50> sql;
+ sql.Format(_L8("DELETE FROM A WHERE ROWID=%d"), i + 1);
+ err = TheDb.Exec(sql);
+ TEST2(err, 1);
+ }
+ User::After(1000000);
+ RSqlDatabase::TSize size;
+ err = TheDb.Size(size);
+ TEST2(err, KErrNone);
+ TEST(size.iFree > 0);
+ //Delete more records, the free page threshold is reached, the background compaction - kicked-off.
+ for(TInt i=10;i<20;++i)
+ {
+ TBuf8<50> sql;
+ sql.Format(_L8("DELETE FROM A WHERE ROWID=%d"), i + 1);
+ err = TheDb.Exec(sql);
+ TEST2(err, 1);
+ }
+ User::After(1000000);
+ err = TheDb.Size(size);
+ TEST2(err, KErrNone);
+ TEST2(size.iFree, 0);
+ //
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ (void)TheFs.Delete(KSqlSrvConfigFile);
+ }
+
+/**
+@SYMTestCaseID SYSLIB-SQL-UT-4075
+@SYMTestCaseDesc Server configuration file, large string test.
+ The test creates a server config file, where all parameters are used
+ and checks the the parameter values are processed normally.
+@SYMTestPriority Medium
+@SYMTestActions Server configuration file, large string test.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ10271
+*/
+void LargeStringTest()
+ {
+ ReplaceConfigFile(_L("page_size=32768;cache_size=2048;encoding=UTF-16;soft_heap_limit_kb=2048;free_space_threshold_kb=100000000;compaction=background"));
+ TInt err = TheDb.Create(KTestDbName);
+ TEST2(err, KErrNone);
+ AssertConfigPrmValues(TheDb, (2048 * 1024) / 32768, 32768, TSqlSrvConfigParams::EEncUtf16);
+ TheDb.Close();
+ (void)RSqlDatabase::Delete(KTestDbName);
+ }
+
+void DoTests()
+ {
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3603 Bad config file "));
+ BadCfgFileTest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3604 Config file - bad parameters "));
+ BadCfgFileParametersTest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3605 Config file - conflict test "));
+ CfgFileConflictTest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3606 Soft heap limit - functional test (\"create database\") "));
+ SoftHeapLimitFunctionalTest1();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3607 Soft heap limit - functional test (\"open database\") "));
+ SoftHeapLimitFunctionalTest2();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3608 Soft heap limit - file I/O failure "));
+ FileIOFailureTest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3609 Soft heap limit - OOM failure "));
+ OOMtest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4081 SQL server configuration file + free page threshold - functional test "));
+ FreePageThresholdTest();
+ TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4075 SQL server configuration file + large string "));
+ LargeStringTest();
+ }
+
+#endif //SYSLIBS_TEST
+
+TInt E32Main()
+ {
+ TheTest.Title();
+
+ CTrapCleanup* tc = CTrapCleanup::New();
+ TheTest(tc != NULL);
+
+ __UHEAP_MARK;
+
+#ifdef SYSLIBS_TEST
+ TheTest.Start(_L("t_sqlconfigfile tests"));
+
+ SetupTestEnv();
+ DoTests();
+ DestroyTestEnv();
+
+ TheTest.End();
+#else
+ TheTest.Start(_L("This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined!"));
+ TheTest.End();
+#endif
+
+ __UHEAP_MARKEND;
+
+ TheTest.Close();
+
+ delete tc;
+
+ User::Heap().Check();
+ return KErrNone;
+ }