persistentstorage/sql/TEST/t_sqlconfigfile.cpp
changeset 0 08ec8eefde2f
child 12 6b6fd149daa2
--- /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;
+	}