persistentstorage/sql/TEST/t_sqlcompact4.cpp
changeset 0 08ec8eefde2f
child 11 211563e4b919
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32test.h>
       
    17 #include <bautils.h>
       
    18 #include <sqldb.h>
       
    19 #include <stdlib.h>
       
    20 #include "sqlite3.h"
       
    21 #include "SqliteSymbian.h"
       
    22 #include "SqlResourceTester.h"
       
    23 
       
    24 ///////////////////////////////////////////////////////////////////////////////////////
       
    25 
       
    26 RTest TheTest(_L("t_sqlcompact4 test"));
       
    27 TParse TheParse;
       
    28 TDriveName TheDrive;
       
    29 
       
    30 RSqlDatabase TheDb;
       
    31 sqlite3* TheSqliteDb = NULL;
       
    32 TBuf<256> TheCmd;
       
    33 
       
    34 const TInt KTextLen = 1000;
       
    35 const TInt KRecLen = 2000;
       
    36 
       
    37 TBuf<KTextLen> TheText;
       
    38 TBuf8<KRecLen> TheSqlQuery;
       
    39 TBuf8<KRecLen> TheSqlFmt;
       
    40 TBuf<KTextLen + 50> TheSqlTexLen;
       
    41 
       
    42 _LIT(KDefaultDriveName, "c:");
       
    43 _LIT(KTestDir, "c:\\test\\");
       
    44 _LIT(KTestDbTemplate8, "c:\\test\\t_sqlcompact4_tmpl8.dat");
       
    45 _LIT(KTestDbTemplate16, "c:\\test\\t_sqlcompact4_tmpl16.dat");
       
    46 _LIT(KDbName, "c:\\test\\t_sqlcompact4_1.db");
       
    47 _LIT(KDbName2, "c:\\test\\t_sqlcompact4_2.db");
       
    48 _LIT(KRoDbName, "z:\\test\\testdb1.db");//Created outside the test app
       
    49 TFileName TheTestDbName;
       
    50 
       
    51 const TInt KMaxThreadCount = 100;
       
    52 TInt32 TheTestThreadCount = 8;
       
    53 
       
    54 const TInt KTestDbPageSize = 1024;
       
    55 
       
    56 TInt TheOriginalDbSize8 = -1;
       
    57 TInt TheCompactedDbSize8 = -1;
       
    58 
       
    59 TInt TheOriginalDbSize16 = -1;
       
    60 TInt TheCompactedDbSize16 = -1;
       
    61 
       
    62 //In order to be able to compile the test, the following variables are defined (used inside the OS porting layer, when _SQLPROFILER macro is defined)
       
    63 #ifdef _SQLPROFILER
       
    64 TInt TheSqlSrvProfilerFileRead = 0;
       
    65 TInt TheSqlSrvProfilerFileWrite = 0;
       
    66 TInt TheSqlSrvProfilerFileSync = 0;
       
    67 TInt TheSqlSrvProfilerFileSetSize = 0;
       
    68 #endif
       
    69 
       
    70 ///////////////////////////////////////////////////////////////////////////////////////
       
    71 
       
    72 void DestroyTestEnv()
       
    73 	{
       
    74 	if(TheSqliteDb)
       
    75 		{
       
    76 		sqlite3_close(TheSqliteDb);
       
    77 		TheSqliteDb = NULL;
       
    78 		}
       
    79 	TheDb.Close();
       
    80 	(void)RSqlDatabase::Delete(KDbName2);
       
    81 	(void)RSqlDatabase::Delete(TheTestDbName);
       
    82 	(void)RSqlDatabase::Delete(KTestDbTemplate16);
       
    83 	(void)RSqlDatabase::Delete(KTestDbTemplate8);
       
    84 	sqlite3SymbianLibFinalize();
       
    85 	CloseSTDLIB();
       
    86 	}
       
    87 
       
    88 ///////////////////////////////////////////////////////////////////////////////////////
       
    89 ///////////////////////////////////////////////////////////////////////////////////////
       
    90 //Test macros and functions
       
    91 void Check(TInt aValue, TInt aLine)
       
    92 	{
       
    93 	if(!aValue)
       
    94 		{
       
    95 		DestroyTestEnv();
       
    96 		RDebug::Print(_L("*** Test failure. Boolean expression evaluates to false.\r\n"));
       
    97 		TheTest(EFalse, aLine);
       
    98 		}
       
    99 	}
       
   100 void Check(TInt aValue, TInt aExpected, TInt aLine)
       
   101 	{
       
   102 	if(aValue != aExpected)
       
   103 		{
       
   104 		DestroyTestEnv();
       
   105 		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
   106 		TheTest(EFalse, aLine);
       
   107 		}
       
   108 	}
       
   109 #define TEST(arg) ::Check((arg), __LINE__)
       
   110 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
   111 
       
   112 ///////////////////////////////////////////////////////////////////////////////////////
       
   113 
       
   114 void CreateTestEnv()
       
   115     {
       
   116     RFs fs;
       
   117 	TInt err = fs.Connect();
       
   118 	TEST2(err, KErrNone);
       
   119 
       
   120 	err = fs.MkDir(KTestDir);
       
   121 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   122 
       
   123 	TheParse.Set(TheDrive, &KTestDir, 0);
       
   124 
       
   125 	err = fs.MkDir(TheParse.DriveAndPath());
       
   126 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   127 
       
   128 	fs.Close();
       
   129 
       
   130 	sqlite3SymbianLibInit();
       
   131 	}
       
   132 
       
   133 ///////////////////////////////////////////////////////////////////////////////////////
       
   134 
       
   135 void CreateTestDatabase8()
       
   136 	{
       
   137 	TheTest.Printf(_L("Create UTF8 test database: %S\r\n"), &KTestDbTemplate8);
       
   138 	(void)RSqlDatabase::Delete(KTestDbTemplate8);
       
   139 	TBuf8<KMaxFileName> fname;
       
   140 	fname.Copy(KTestDbTemplate8);
       
   141 	TheSqliteDb = NULL;
       
   142 	TInt rc = sqlite3_open((const char*)fname.PtrZ(), &TheSqliteDb);
       
   143 	TEST2(rc, SQLITE_OK);
       
   144 	TBuf8<100> sql;
       
   145 	_LIT8(KSql, "PRAGMA page_size=%d\x0");
       
   146 	sql.Format(KSql, KTestDbPageSize);
       
   147 	rc = sqlite3_exec(TheSqliteDb, (const char*)sql.Ptr(), 0, 0, 0);
       
   148 	TEST2(rc, SQLITE_OK);
       
   149 	rc = sqlite3_exec(TheSqliteDb, "CREATE TABLE A(Id INTEGER,Data BLOB)", 0, 0, 0);
       
   150 	TEST2(rc, SQLITE_OK);
       
   151 	//Insert records
       
   152 	rc = sqlite3_exec(TheSqliteDb, "BEGIN", 0, 0, 0);
       
   153 	TEST2(rc, SQLITE_OK);
       
   154 	TheSqlQuery.Copy(_L8("INSERT INTO A VALUES(%d,x'"));
       
   155 	for(TInt j=0;j<(KRecLen-50);++j)
       
   156 		{
       
   157 		TheSqlQuery.Append(_L8("A"));
       
   158 		}
       
   159 	TheSqlQuery.Append(_L8("')"));
       
   160 	const TInt KRecCount = 100;	
       
   161 	for(TInt i=0;i<KRecCount;++i)
       
   162 		{
       
   163 		TheSqlFmt.Format(TheSqlQuery, i + 1);
       
   164 		rc = sqlite3_exec(TheSqliteDb, (const char*)TheSqlFmt.PtrZ(), 0, 0, 0);
       
   165 		TEST2(rc, SQLITE_OK);
       
   166 		}
       
   167 	rc = sqlite3_exec(TheSqliteDb, "COMMIT", 0, 0, 0);
       
   168 	TEST2(rc, SQLITE_OK);
       
   169 	//Free some space
       
   170 	rc = sqlite3_exec(TheSqliteDb, "DELETE FROM A WHERE Id > 10", 0, 0, 0);
       
   171 	TEST2(rc, SQLITE_OK);
       
   172 	sqlite3_close(TheSqliteDb);
       
   173 	TheSqliteDb = NULL;
       
   174 	}
       
   175 
       
   176 void CreateTestDatabase16()
       
   177 	{
       
   178 	TheTest.Printf(_L("Create UTF16 test database: %S\r\n"), &KTestDbTemplate16);
       
   179 	(void)RSqlDatabase::Delete(KTestDbTemplate16);
       
   180 	TBuf<KMaxFileName> fname;
       
   181 	fname.Copy(KTestDbTemplate16);
       
   182 	TheSqliteDb = NULL;
       
   183 	TInt rc = sqlite3_open16(fname.PtrZ(), &TheSqliteDb);
       
   184 	TEST2(rc, SQLITE_OK);
       
   185 	TBuf8<100> sql;
       
   186 	_LIT8(KSql, "PRAGMA page_size=%d\x0");
       
   187 	sql.Format(KSql, KTestDbPageSize);
       
   188 	rc = sqlite3_exec(TheSqliteDb, (const char*)sql.Ptr(), 0, 0, 0);
       
   189 	TEST2(rc, SQLITE_OK);
       
   190 	rc = sqlite3_exec(TheSqliteDb, "CREATE TABLE A(Id INTEGER,Data BLOB)", 0, 0, 0);
       
   191 	TEST2(rc, SQLITE_OK);
       
   192 	//Insert records
       
   193 	rc = sqlite3_exec(TheSqliteDb, "BEGIN", 0, 0, 0);
       
   194 	TEST2(rc, SQLITE_OK);
       
   195 	TheSqlQuery.Copy(_L8("INSERT INTO A VALUES(%d,x'"));
       
   196 	for(TInt j=0;j<(KRecLen-50);++j)
       
   197 		{
       
   198 		TheSqlQuery.Append(_L8("A"));
       
   199 		}
       
   200 	TheSqlQuery.Append(_L8("')"));
       
   201 	const TInt KRecCount = 100;	
       
   202 	for(TInt i=0;i<KRecCount;++i)
       
   203 		{
       
   204 		TheSqlFmt.Format(TheSqlQuery, i + 1);
       
   205 		rc = sqlite3_exec(TheSqliteDb, (const char*)TheSqlFmt.PtrZ(), 0, 0, 0);
       
   206 		TEST2(rc, SQLITE_OK);
       
   207 		}
       
   208 	rc = sqlite3_exec(TheSqliteDb, "COMMIT", 0, 0, 0);
       
   209 	TEST2(rc, SQLITE_OK);
       
   210 	//Free some space
       
   211 	rc = sqlite3_exec(TheSqliteDb, "DELETE FROM A WHERE Id > 10", 0, 0, 0);
       
   212 	TEST2(rc, SQLITE_OK);
       
   213 	sqlite3_close(TheSqliteDb);
       
   214 	TheSqliteDb = NULL;
       
   215 	}
       
   216 	
       
   217 void CreateDatabase8(const TDesC& aTargetDbName)
       
   218 	{
       
   219 	RFs fs;
       
   220 	TInt err = fs.Connect();
       
   221 	TEST2(err, KErrNone);		
       
   222 	CFileMan* fm = NULL;
       
   223 	TRAP(err, fm = CFileMan::NewL(fs));
       
   224 	TEST2(err, KErrNone);
       
   225 	err = fm->Copy(KTestDbTemplate8, aTargetDbName);
       
   226 	delete fm;
       
   227 	fs.Close();
       
   228 	TEST2(err, KErrNone);
       
   229 	}
       
   230 
       
   231 void CreateDatabase16(const TDesC& aTargetDbName)
       
   232 	{
       
   233 	RFs fs;
       
   234 	TInt err = fs.Connect();
       
   235 	TEST2(err, KErrNone);		
       
   236 	CFileMan* fm = NULL;
       
   237 	TRAP(err, fm = CFileMan::NewL(fs));
       
   238 	TEST2(err, KErrNone);
       
   239 	err = fm->Copy(KTestDbTemplate16, aTargetDbName);
       
   240 	delete fm;
       
   241 	fs.Close();
       
   242 	TEST2(err, KErrNone);
       
   243 	}
       
   244 
       
   245 void CalculateMaxCompaction8()
       
   246 	{
       
   247 	TheTest.Printf(_L("UTF8 test database - calculate max compaction\r\n"));
       
   248 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   249 	CreateDatabase8(TheTestDbName);
       
   250 	TInt err = TheDb.Open(TheTestDbName);
       
   251 	TEST2(err, KErrNone);
       
   252 	RSqlDatabase::TSize size1;
       
   253 	err = TheDb.Size(size1);
       
   254 	TEST2(err, KErrNone);
       
   255 	TheTest.Printf(_L("UTF8.Database before compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree);
       
   256 	err = TheDb.Compact(RSqlDatabase::EMaxCompaction);
       
   257 	TEST2(err, size1.iFree);
       
   258 	RSqlDatabase::TSize size2;
       
   259 	err = TheDb.Size(size2);
       
   260 	TEST2(err, KErrNone);
       
   261 	TheTest.Printf(_L("UTF8.Database after compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree);
       
   262 	TheDb.Close();
       
   263 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   264 	TheOriginalDbSize8 = size1.iSize;
       
   265 	TheCompactedDbSize8 = size2.iSize;
       
   266 	TEST(TheOriginalDbSize8 > 0);
       
   267 	TEST(TheCompactedDbSize8 > 0 && TheCompactedDbSize8 < TheOriginalDbSize8);
       
   268 	}
       
   269 
       
   270 void CalculateMaxCompaction16()
       
   271 	{
       
   272 	TheTest.Printf(_L("UTF16 test database - calculate max compaction\r\n"));
       
   273 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   274 	CreateDatabase16(TheTestDbName);
       
   275 	TInt err = TheDb.Open(TheTestDbName);
       
   276 	TEST2(err, KErrNone);
       
   277 	RSqlDatabase::TSize size1;
       
   278 	err = TheDb.Size(size1);
       
   279 	TEST2(err, KErrNone);
       
   280 	TheTest.Printf(_L("UTF16.Database before compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree);
       
   281 	err = TheDb.Compact(RSqlDatabase::EMaxCompaction);
       
   282 	TEST2(err, size1.iFree);
       
   283 	RSqlDatabase::TSize size2;
       
   284 	err = TheDb.Size(size2);
       
   285 	TEST2(err, KErrNone);
       
   286 	TheTest.Printf(_L("UTF16.Database after compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree);
       
   287 	TheDb.Close();
       
   288 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   289 	TheOriginalDbSize16 = size1.iSize;
       
   290 	TheCompactedDbSize16 = size2.iSize;
       
   291 	TEST(TheOriginalDbSize16 > 0);
       
   292 	TEST(TheCompactedDbSize16 > 0 && TheCompactedDbSize16 < TheOriginalDbSize16);
       
   293 	}
       
   294 
       
   295 ///////////////////////////////////////////////////////////////////////////////////////
       
   296 
       
   297 
       
   298 enum TCompactionType {ESyncCompaction, EAsyncCompaction, EMaxCompactionType};
       
   299 
       
   300 TInt DoCompact(TCompactionType aType, TInt aSize, const TDesC& aAttachDbName = KNullDesC)
       
   301 	{
       
   302 	TInt err = KErrGeneral;
       
   303 	switch(aType)
       
   304 		{
       
   305 		case ESyncCompaction:
       
   306 			err = TheDb.Compact(aSize, aAttachDbName);
       
   307 			break;
       
   308 		case EAsyncCompaction:
       
   309 			{
       
   310 			TRequestStatus stat;				
       
   311 			TheDb.Compact(aSize, stat, aAttachDbName);
       
   312 			User::WaitForRequest(stat);
       
   313 			TEST(stat != KRequestPending);
       
   314 			err = stat.Int();
       
   315 			break;
       
   316 			}
       
   317 		default:
       
   318 			TEST(0);
       
   319 			break;	
       
   320 		}
       
   321 	return err;
       
   322 	}
       
   323 
       
   324 TInt DoManualCompaction(TCompactionType aType, const TDesC& aMainDb, TInt aSize, TBool aRoFlag = EFalse)
       
   325 	{
       
   326 	if(!aRoFlag)
       
   327 		{
       
   328 		(void)RSqlDatabase::Delete(aMainDb);
       
   329 		CreateDatabase8(aMainDb);
       
   330 		}
       
   331 
       
   332 	TInt err = TheDb.Open(aMainDb);
       
   333 	TEST2(err, KErrNone);
       
   334 	
       
   335 	err = DoCompact(aType, aSize);
       
   336 		
       
   337 	TheDb.Close();
       
   338 	if(!aRoFlag)
       
   339 		{
       
   340 		(void)RSqlDatabase::Delete(aMainDb);
       
   341 		}
       
   342 	return err;
       
   343 	}
       
   344 
       
   345 TInt DoManualCompaction(TCompactionType aType, TInt aSize, const TDesC& aAttachDbName)
       
   346 	{
       
   347 	return DoCompact(aType, aSize, aAttachDbName);
       
   348 	}
       
   349 
       
   350 void DoManualCompaction(TCompactionType aType, TInt aSize, TInt aCompactedSize)
       
   351 	{
       
   352 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   353 	CreateDatabase8(TheTestDbName);
       
   354 
       
   355 	TInt err = TheDb.Open(TheTestDbName);
       
   356 	TEST2(err, KErrNone);
       
   357 	
       
   358 	err = DoCompact(aType, aSize);
       
   359 	TEST(err >= 0);
       
   360 	
       
   361 	RSqlDatabase::TSize size;
       
   362 	err = TheDb.Size(size);
       
   363 	TEST2(err, KErrNone);
       
   364 	TEST2(size.iSize, aCompactedSize);
       
   365 		
       
   366 	TheDb.Close();
       
   367 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   368 	}
       
   369 
       
   370 void DoManualCompaction(TCompactionType aType, TInt aSize, TInt aCompactedSize, const TDesC& aAttachDbName)
       
   371 	{
       
   372 	TInt err = DoCompact(aType, aSize, aAttachDbName);
       
   373 	TEST(err >= 0);
       
   374 	
       
   375 	RSqlDatabase::TSize size;
       
   376 	err = TheDb.Size(size, aAttachDbName);
       
   377 	TEST2(err, KErrNone);
       
   378 	TEST2(size.iSize, aCompactedSize);
       
   379 	}
       
   380 
       
   381 /**
       
   382 @SYMTestCaseID			SYSLIB-SQL-UT-4064
       
   383 @SYMTestCaseDesc		Manual compaction - negative tests.
       
   384 						The test creates a database with a manual compaction mode.
       
   385 						Then the test executes the following negative tests using both synchronous and
       
   386 						asynchronous Compact() methods:
       
   387 							- RSqlDatabase::Compact() called with aSize parameter value = KMinTInt;
       
   388 							- RSqlDatabase::Compact() called with negative aSize parameter value;
       
   389 							- RSqlDatabase::Compact() called on a read-only database;
       
   390 							- RSqlDatabase::Compact() called on an attached read-only database;
       
   391 							- RSqlDatabase::Compact() called on a nonexisting attached database with very long name;
       
   392 							- RSqlDatabase::Compact() called with aSize = 0;
       
   393 							- RSqlDatabase::Compact() called on a read-only database where the version number of symbian_settings table is 3;
       
   394 @SYMTestPriority		Medium
       
   395 @SYMTestActions			Manual compaction - negative tests.
       
   396 @SYMTestExpectedResults Test must not fail
       
   397 @SYMREQ					REQ10273
       
   398                         REQ10274
       
   399                         REQ10402
       
   400 */
       
   401 void ManualCompactionNegativeTest()
       
   402 	{
       
   403 	for(TInt i=0;i<EMaxCompactionType;++i)
       
   404 		{
       
   405 		//Specifying KMaxTInt as aSize argument value.
       
   406 		TInt err = DoManualCompaction((TCompactionType)i, TheTestDbName, KMaxTInt);
       
   407 		TEST(err > 0);
       
   408 		//Specifying KMinTInt as aSize argument value.
       
   409 		err = DoManualCompaction((TCompactionType)i, TheTestDbName, KMinTInt);
       
   410 		TEST2(err, KErrArgument);
       
   411 		//Specifying another negative value as aSize argument value.
       
   412 		err = DoManualCompaction((TCompactionType)i, TheTestDbName, -357);
       
   413 		TEST2(err, KErrArgument);
       
   414 		//Specifying zero as aSize argument value.
       
   415 		err = DoManualCompaction((TCompactionType)i, TheTestDbName, 0);
       
   416 		TEST2(err, 0);
       
   417 		//Read-only database - old format (version 3 of symbian_settings table)
       
   418 		err = DoManualCompaction((TCompactionType)i, KRoDbName, RSqlDatabase::EMaxCompaction, ETrue);
       
   419 		TEST2(err, KSqlErrReadOnly);
       
   420 		//
       
   421 		(void)RSqlDatabase::Delete(TheTestDbName);
       
   422 		CreateDatabase16(TheTestDbName);
       
   423 		err = TheDb.Open(TheTestDbName);
       
   424 		TEST2(err, KErrNone);
       
   425 		_LIT(KAttachDbName, "Db");
       
   426 		//Attached read-only database
       
   427 		err = TheDb.Attach(KRoDbName, KAttachDbName);
       
   428 		TEST2(err, KErrNone);
       
   429 		err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, KAttachDbName);
       
   430 		TEST2(err, KSqlErrReadOnly);
       
   431 		err = TheDb.Detach(KAttachDbName);
       
   432 		TEST2(err, KErrNone);
       
   433 		//Nonexisting attached database 
       
   434 		err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, _L("aaa"));
       
   435 		TEST2(err, KSqlErrGeneral);
       
   436 		//Very long name of a  nonexisting attached database 
       
   437 		TBuf<KMaxFileName + 10> fname;
       
   438 		fname.SetLength(fname.MaxLength());
       
   439 		fname.Fill(0xDD);
       
   440 		err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, fname);
       
   441 		TEST2(err, KErrBadName);
       
   442 		//
       
   443 		TheDb.Close();
       
   444 		(void)RSqlDatabase::Delete(TheTestDbName);
       
   445 		}
       
   446 	}
       
   447 
       
   448 /**
       
   449 @SYMTestCaseID			SYSLIB-SQL-UT-4065
       
   450 @SYMTestCaseDesc		Manual compaction - functional tests.
       
   451 						The test creates a database with a manual compaction mode.
       
   452 						Then the test executes the following functional tests using both synchronous and
       
   453 						asynchronous Compact() methods:
       
   454 							- RSqlDatabase::Compact() called with aSize parameter value = RSqlDatabase::EMaxCompaction;
       
   455 							- RSqlDatabase::Compact() called with aSize parameter value = 0. No pages should be removed;
       
   456 							- RSqlDatabase::Compact() called with aSize parameter value = 1. 1 page should be removed;
       
   457 							- RSqlDatabase::Compact() called with aSize parameter value = "db page size - 1". 1 page should be removed;
       
   458 							- RSqlDatabase::Compact() called with aSize parameter value = "db page size * <cnt>". <cnt> pages should be removed;
       
   459 							- RSqlDatabase::Compact() called with aSize parameter value > the free db space. All free pages should be removed;
       
   460 						The same functional tests are repeated with an attached database.
       
   461 @SYMTestPriority		Medium
       
   462 @SYMTestActions			Manual compaction - functional tests.
       
   463 @SYMTestExpectedResults Test must not fail
       
   464 @SYMREQ					REQ10273
       
   465                         REQ10274
       
   466                         REQ10402
       
   467 */
       
   468 void ManualCompactionTest()
       
   469 	{
       
   470 	for(TInt i=0;i<EMaxCompactionType;++i)
       
   471 		{
       
   472 		//Calling Compact() with aSize = RSqlDatabase::EMaxCompaction
       
   473 		DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, TheCompactedDbSize8);
       
   474 		//Calling Compact() with aSize = 0. 0 pages expected to be removed
       
   475 		DoManualCompaction((TCompactionType)i, 0, TheOriginalDbSize8);
       
   476 		//Calling Compact() with aSize = 1. 1 page expected to be removed
       
   477 		DoManualCompaction((TCompactionType)i, 1, TheOriginalDbSize8 - KTestDbPageSize);
       
   478 		//Calling Compact() with aSize = KTestDbPageSize - 1. 1 page expected to be removed
       
   479 		DoManualCompaction((TCompactionType)i, KTestDbPageSize - 1, TheOriginalDbSize8 - KTestDbPageSize);
       
   480 		//Calling Compact() with aSize = KTestDbPageSize. 1 page expected to be removed
       
   481 		DoManualCompaction((TCompactionType)i, KTestDbPageSize, TheOriginalDbSize8 - KTestDbPageSize);
       
   482 		const TInt KPagesCnt1 = 17;
       
   483 		//Calling Compact() with aSize = KTestDbPageSize * KPagesCnt1. KPagesCnt1 pages expected to be removed
       
   484 		DoManualCompaction((TCompactionType)i, KTestDbPageSize * KPagesCnt1, TheOriginalDbSize8 - KTestDbPageSize * KPagesCnt1);
       
   485 		//Calling Compact() with aSize > TheOriginalDbSize8. All free pages expected to be removed
       
   486 		DoManualCompaction((TCompactionType)i, TheOriginalDbSize8 + 2000, TheCompactedDbSize8);
       
   487 		//Attached database
       
   488 		(void)RSqlDatabase::Delete(KDbName2);
       
   489 		TInt err = TheDb.Create(KDbName2);
       
   490 		TEST2(err, KErrNone);
       
   491 		(void)RSqlDatabase::Delete(TheTestDbName);
       
   492 		CreateDatabase16(TheTestDbName);
       
   493 		_LIT(KAttachDbName, "Db");
       
   494 		err = TheDb.Attach(TheTestDbName, KAttachDbName);
       
   495 		TEST2(err, KErrNone);
       
   496 		TInt newDatabaseSize = TheOriginalDbSize16;
       
   497 		//Calling Compact() with aSize = 0. 0 pages expected to be removed
       
   498 		DoManualCompaction((TCompactionType)i, 0, newDatabaseSize, KAttachDbName);
       
   499 		//Calling Compact() with aSize = 1. 1 page expected to be removed
       
   500 		DoManualCompaction((TCompactionType)i, 1, TheOriginalDbSize16 - KTestDbPageSize, KAttachDbName);
       
   501 		newDatabaseSize -= KTestDbPageSize;
       
   502 		//Calling Compact() with aSize = KTestDbPageSize - 1. 1 page expected to be removed
       
   503 		DoManualCompaction((TCompactionType)i, KTestDbPageSize - 1, newDatabaseSize - KTestDbPageSize, KAttachDbName);
       
   504 		newDatabaseSize -= KTestDbPageSize;
       
   505 		//Calling Compact() with aSize = KTestDbPageSize. 1 page expected to be removed
       
   506 		DoManualCompaction((TCompactionType)i, KTestDbPageSize, newDatabaseSize - KTestDbPageSize, KAttachDbName);
       
   507 		newDatabaseSize -= KTestDbPageSize;
       
   508 		//Calling Compact() with aSize = KTestDbPageSize * KPagesCnt1. KPagesCnt1 pages expected to be removed
       
   509 		DoManualCompaction((TCompactionType)i, KTestDbPageSize * KPagesCnt1, newDatabaseSize - KTestDbPageSize * KPagesCnt1, KAttachDbName);
       
   510 		newDatabaseSize -= KTestDbPageSize * KPagesCnt1;
       
   511 		//Calling Compact() with aSize > newDatabaseSize. All free pages expected to be removed
       
   512 		DoManualCompaction((TCompactionType)i, newDatabaseSize + 2000, TheCompactedDbSize16, KAttachDbName);
       
   513 		//
       
   514 		err = TheDb.Detach(KAttachDbName);
       
   515 		TEST2(err, KErrNone);
       
   516 		TheDb.Close();
       
   517 		(void)RSqlDatabase::Delete(KDbName2);
       
   518 		}
       
   519 	}
       
   520 
       
   521 
       
   522 enum TSizeTestType {EManualSizeTest, EAutoSizeTest};
       
   523 
       
   524 void DoCompactionDbSizeTest(TSizeTestType aType)
       
   525 	{
       
   526 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   527 	_LIT8(KConfig1, "compaction=manual");
       
   528 	_LIT8(KConfig2, "compaction=auto");
       
   529 	TInt err = TheDb.Create(TheTestDbName, aType == EManualSizeTest ? &KConfig1 : &KConfig2);
       
   530 	TEST2(err, KErrNone);
       
   531 	err = TheDb.Exec(_L("CREATE TABLE A(T TEXT)"));
       
   532 	TEST2(err, 1);
       
   533 	//
       
   534 	RSqlDatabase::TSize size;
       
   535 	err = TheDb.Size(size);
       
   536 	TEST2(err, KErrNone);
       
   537 	TEST2(size.iFree, 0);
       
   538 	//
       
   539 	const TInt KRecCnt = 50;
       
   540 	for(TInt i=0;i<KRecCnt;++i)
       
   541 		{
       
   542 		err = TheDb.Exec(_L("INSERT INTO A VALUES('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaa')"));
       
   543 		TEST2(err, 1);
       
   544 		}
       
   545 	//
       
   546 	err = TheDb.Size(size);
       
   547 	TEST2(err, KErrNone);
       
   548 	TEST2(size.iFree, 0);
       
   549 	//
       
   550 	err = TheDb.Exec(_L("DELETE FROM A WHERE 1"));
       
   551 	TEST2(err, KRecCnt);
       
   552 	//
       
   553 	err = TheDb.Size(size);
       
   554 	TEST2(err, KErrNone);
       
   555 	if(aType == EManualSizeTest)
       
   556 		{
       
   557 		TEST(size.iFree > 0);
       
   558 		}
       
   559 	else
       
   560 		{
       
   561 		TEST2(size.iFree, 0);
       
   562 		}
       
   563 	//
       
   564 	TheDb.Close();
       
   565 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   566 	}
       
   567 
       
   568 /**
       
   569 @SYMTestCaseID			SYSLIB-SQL-UT-4066
       
   570 @SYMTestCaseDesc		RSqlDatabase::Size(TSize&) called on a database with manual compaction mode.
       
   571 						The test creates a database with a manual compaction mode.
       
   572 						Then the test inserts some records and deletes the records making some free database pages.
       
   573 						The test calls RSqlDatabase::Size(TSize&) before and after the delete operation and verifies
       
   574 						that the database file size stays unchanged.
       
   575 @SYMTestPriority		Medium
       
   576 @SYMTestActions			RSqlDatabase::Size(TSize&) called on a database with manual compaction mode.
       
   577 @SYMTestExpectedResults Test must not fail
       
   578 @SYMREQ					REQ10407
       
   579 */
       
   580 void ManualCompactionSizeTest()
       
   581 	{
       
   582 	DoCompactionDbSizeTest(EManualSizeTest);
       
   583 	}
       
   584 
       
   585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   586 //////////////////////////////////         OOM testing        ////////////////////////////////////////////////////////////
       
   587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   588 
       
   589 void PrintEndOfOomTest(TInt aFailingAllocationNo)
       
   590 	{
       
   591 	TheTest.Printf(_L("=== OOM Test succeeded at heap failure rate of %d ===\r\n"), aFailingAllocationNo);
       
   592 	}
       
   593 
       
   594 void SetDbHeapFailure(TInt aFailingAllocationNo)
       
   595 	{
       
   596 	const TInt KDelayedDbHeapFailureMask = 0x1000;
       
   597 	TSqlResourceTester::SetDbHeapFailure(RHeap::EDeterministic | KDelayedDbHeapFailureMask, aFailingAllocationNo);
       
   598 	}
       
   599 	
       
   600 void ResetDbHeapFailure()
       
   601 	{
       
   602 	TSqlResourceTester::SetDbHeapFailure(RHeap::ENone, 0);
       
   603 	}
       
   604 
       
   605 static TInt TheHandleCount1B;
       
   606 static TInt TheHandleCount2B;
       
   607 static TInt TheAllocatedCellsCountB;
       
   608 
       
   609 void MarkHandles()
       
   610 	{
       
   611 	RThread().HandleCount(TheHandleCount1B, TheHandleCount2B);
       
   612 	}
       
   613 
       
   614 void CheckHandles()
       
   615 	{
       
   616 	TInt endHandleCount1E;
       
   617 	TInt endHandleCount2E;
       
   618 
       
   619 	RThread().HandleCount(endHandleCount1E, endHandleCount2E);
       
   620 
       
   621 	TEST(TheHandleCount1B == endHandleCount1E);
       
   622 	TEST(TheHandleCount2B == endHandleCount2E);
       
   623 	}
       
   624 
       
   625 void MarkAllocatedCells()
       
   626 	{
       
   627 	TheAllocatedCellsCountB = User::CountAllocCells();
       
   628 	}
       
   629 
       
   630 void CheckAllocatedCells()
       
   631 	{
       
   632 	TInt allocatedCellsCountE = User::CountAllocCells();
       
   633 	TEST(allocatedCellsCountE == TheAllocatedCellsCountB);
       
   634 	}
       
   635 
       
   636 typedef void (*TDbFuncPtrL)(const TDesC& aDbName);
       
   637 
       
   638 void DoManualCompactionOomTest(TDbFuncPtrL aTestFunctionPtrL, const TDesC& aDbFileName, const TDesC& aAttachDbFileName, const TDesC& aDbName)
       
   639 	{
       
   640 	const TInt KDoDbOomTestAllocLimitServer = 1000;
       
   641 	TInt failingAllocation = 0;
       
   642 	TInt allocation = 0;
       
   643 	TInt err = KErrNoMemory;
       
   644 	while(allocation < KDoDbOomTestAllocLimitServer)
       
   645 		{
       
   646 		MarkHandles();
       
   647 		MarkAllocatedCells();
       
   648 		
       
   649 		__UHEAP_MARK;
       
   650 
       
   651 		SetDbHeapFailure(++allocation);
       
   652 
       
   653 		err = TheDb.Open(aDbFileName);
       
   654 		TEST2(err, KErrNone);
       
   655 		if(aAttachDbFileName != KNullDesC)
       
   656 			{
       
   657 			TEST(aDbName != KNullDesC);
       
   658 			err = TheDb.Attach(aAttachDbFileName, aDbName);
       
   659 			TEST(err == KErrNone || err == KErrNoMemory);
       
   660 			}
       
   661 		if(err == KErrNone)
       
   662 			{
       
   663 			TRAP(err, (*aTestFunctionPtrL)(aDbName));
       
   664 			if(err != KErrNoMemory)
       
   665 				{			
       
   666 				TEST2(err, KErrNone);
       
   667 				}
       
   668 			else
       
   669 				{
       
   670 				failingAllocation = allocation;	
       
   671 				}
       
   672 			}
       
   673 			
       
   674 		ResetDbHeapFailure();
       
   675 
       
   676 		if(aAttachDbFileName != KNullDesC)
       
   677 			{
       
   678 			(void)TheDb.Detach(aDbName);
       
   679 			}
       
   680 		TheDb.Close();
       
   681 
       
   682 		__UHEAP_MARKEND;
       
   683 
       
   684 		CheckAllocatedCells();	    	
       
   685 		CheckHandles();	
       
   686 		}
       
   687 	TEST2(err, KErrNone);
       
   688 	PrintEndOfOomTest(failingAllocation + 1);
       
   689 	}
       
   690 
       
   691 void OomTest1L(const TDesC&)
       
   692 	{
       
   693 	User::LeaveIfError(TheDb.Compact(RSqlDatabase::EMaxCompaction));
       
   694 	}
       
   695 
       
   696 void OomTest2L(const TDesC& aDbName)
       
   697 	{
       
   698 	TEST(aDbName != KNullDesC);
       
   699 	User::LeaveIfError(TheDb.Compact(RSqlDatabase::EMaxCompaction, aDbName));
       
   700 	}
       
   701 
       
   702 /**
       
   703 @SYMTestCaseID			SYSLIB-SQL-UT-4068
       
   704 @SYMTestCaseDesc		RSqlDatabase::Compact() - OOM test.
       
   705 						The test creates a database with a manual compaction mode.
       
   706 						Then the test calls Compact() in an OOM loop.
       
   707 						The same OOM test is repeated for Compact() called an attached database.
       
   708 @SYMTestPriority		Medium
       
   709 @SYMTestActions			RSqlDatabase::Compact() - OOM test.
       
   710 @SYMTestExpectedResults Test must not fail
       
   711 @SYMREQ					REQ10405
       
   712 */
       
   713 void ManualCompactionOomTest()
       
   714 	{
       
   715 	TheTest.Printf(_L("Main database - manual compaction - OOM test\r\n"));
       
   716 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   717 	CreateDatabase8(TheTestDbName);
       
   718 	DoManualCompactionOomTest(&OomTest1L, TheTestDbName, KNullDesC, KNullDesC);
       
   719 	TInt err = TheDb.Open(TheTestDbName);
       
   720 	TEST2(err, KErrNone);
       
   721 	RSqlDatabase::TSize size;
       
   722 	err = TheDb.Size(size);
       
   723 	TEST2(err, KErrNone);
       
   724 	TEST2(size.iSize, TheCompactedDbSize8);
       
   725 	TheDb.Close();
       
   726 
       
   727 	TheTest.Printf(_L("Attached database - manual compaction - OOM test\r\n"));
       
   728 	(void)RSqlDatabase::Delete(KDbName2);
       
   729 	err = TheDb.Create(KDbName2);
       
   730 	TEST2(err, KErrNone);
       
   731 	TheDb.Close();
       
   732 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   733 	CreateDatabase16(TheTestDbName);
       
   734 	DoManualCompactionOomTest(&OomTest2L, KDbName2, TheTestDbName, _L("Db"));
       
   735 	err = TheDb.Open(TheTestDbName);
       
   736 	TEST2(err, KErrNone);
       
   737 	err = TheDb.Size(size);
       
   738 	TEST2(err, KErrNone);
       
   739 	TEST2(size.iSize, TheCompactedDbSize16);
       
   740 	TheDb.Close();
       
   741 
       
   742 	(void)RSqlDatabase::Delete(KDbName2);
       
   743 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   744 	}
       
   745 
       
   746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   747 
       
   748 /**
       
   749 @SYMTestCaseID			SYSLIB-SQL-UT-4067
       
   750 @SYMTestCaseDesc		RSqlDatabase::Size(TSize&) called on a database with auto compaction mode.
       
   751 						The test creates a database with an auto compaction mode.
       
   752 						Then the test inserts some records and deletes the records.
       
   753 						The test calls RSqlDatabase::Size(TSize&) after the delete operation and verifies
       
   754 						that the database file does not contain any free pages.
       
   755 @SYMTestPriority		Medium
       
   756 @SYMTestActions			RSqlDatabase::Size(TSize&) called on a database with auto compaction mode.
       
   757 @SYMTestExpectedResults Test must not fail
       
   758 @SYMREQ					REQ10407
       
   759                         REQ10400
       
   760 */
       
   761 void AutoCompactionSizeTest()
       
   762 	{
       
   763 	DoCompactionDbSizeTest(EAutoSizeTest);
       
   764 	}
       
   765 
       
   766 /**
       
   767 @SYMTestCaseID			SYSLIB-SQL-UT-4069
       
   768 @SYMTestCaseDesc		Background compaction functional test.
       
   769 						The test executes a 10 iterations loop with a "sleep" time 1000000 us at the beginning.
       
   770 						The "sleep" time is divided by 2 on each iteration.
       
   771 						In each iteration the test creates a database with free pages count big enough to kick-off the
       
   772 						background compaction. Then the test executes enough Exec()s in order to kick-off the background compaction.
       
   773 						Then the test "sleeps" the calculated "sleep" time and checks after that the database size and free pages
       
   774 						count and prints them out. After the last iteration the same test is repeated with no "sleep" time.
       
   775 						The test verifies how the client connection activity affects the possibility of the server to run the
       
   776 						background compaction. 
       
   777 @SYMTestPriority		Medium
       
   778 @SYMTestActions			Background compaction functional test.
       
   779 @SYMTestExpectedResults Test must not fail
       
   780 @SYMREQ					REQ10271
       
   781                         REQ10407
       
   782 */
       
   783 void BackgroundCompactionTest()
       
   784 	{
       
   785 	TInt interval = 1000000;//us
       
   786 	const TInt KIterationCnt = 10;
       
   787 	TheTest.Printf(_L("===Sleep after Exec()\r\n"));
       
   788 	for(TInt i=0;i<KIterationCnt;++i)
       
   789 		{
       
   790 		(void)RSqlDatabase::Delete(TheTestDbName);
       
   791 		CreateDatabase8(TheTestDbName);
       
   792 		TInt err = TheDb.Open(TheTestDbName);
       
   793 		TEST2(err, KErrNone);
       
   794 		RSqlDatabase::TSize size1;
       
   795 		err = TheDb.Size(size1);
       
   796 		TEST2(err, KErrNone);
       
   797 		TheTest.Printf(_L("---------------------------------\r\n"));
       
   798 		TheTest.Printf(_L("===Sleep time %d ms. Database before background compaction: size %ld, free space %ld\r\n"), interval / 1000, size1.iSize, size1.iFree);
       
   799 		//Simulate Exec() activities
       
   800 		for(TInt j=0;j<100;++j)
       
   801 			{
       
   802 			err = TheDb.Exec(_L8("SELECT Id FROM A LIMIT 1"));
       
   803 			TEST(err >= 0);
       
   804 			}
       
   805 		User::After(interval);
       
   806 		RSqlDatabase::TSize size2;
       
   807 		err = TheDb.Size(size2);
       
   808 		TEST2(err, KErrNone);
       
   809 		TheTest.Printf(_L("===Database after background compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree);
       
   810 		TEST(size2.iSize <= size1.iSize);
       
   811 		TEST(size2.iFree <= size1.iFree);
       
   812 		interval /= 2;
       
   813 		TheDb.Close();
       
   814 		}
       
   815 	TheTest.Printf(_L("===No sleep\r\n"));
       
   816 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   817 	CreateDatabase8(TheTestDbName);
       
   818 	TInt err = TheDb.Open(TheTestDbName);
       
   819 	TEST2(err, KErrNone);
       
   820 	RSqlDatabase::TSize size1;
       
   821 	err = TheDb.Size(size1);
       
   822 	TEST2(err, KErrNone);
       
   823 	TheTest.Printf(_L("===Database before background compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree);
       
   824 	//Simulate Exec() activities
       
   825 	for(TInt j=0;j<100;++j)
       
   826 		{
       
   827 		err = TheDb.Exec(_L8("SELECT Id FROM A LIMIT 1"));
       
   828 		TEST(err >= 0);
       
   829 		}
       
   830 	RSqlDatabase::TSize size2;
       
   831 	err = TheDb.Size(size2);
       
   832 	TEST2(err, KErrNone);
       
   833 	TheTest.Printf(_L("===Database after background compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree);
       
   834 	TEST(size2.iSize <= size1.iSize);
       
   835 	TEST(size2.iFree <= size1.iFree);
       
   836 	TheDb.Close();
       
   837 	(void)RSqlDatabase::Delete(TheTestDbName);
       
   838 	}
       
   839 
       
   840 struct TThreadData
       
   841 	{
       
   842 	TThreadData(const TDesC& aFileName, TInt aSleepInterval) :
       
   843 		iDbName(aFileName),
       
   844 		iSleepInterval(aSleepInterval)
       
   845 		{
       
   846 		TInt err = iCritSection.CreateLocal();
       
   847 		TEST2(err, KErrNone);
       
   848 		iCritSection.Wait();
       
   849 		Mem::FillZ(&iSize1, sizeof(iSize1));
       
   850 		Mem::FillZ(&iSize2, sizeof(iSize2));
       
   851 		}
       
   852 	TFileName iDbName;	
       
   853 	RCriticalSection iCritSection;
       
   854 	RSqlDatabase::TSize iSize1;
       
   855 	RSqlDatabase::TSize iSize2;
       
   856 	TInt	iSleepInterval;
       
   857 	};
       
   858 
       
   859 TInt ThreadFunc(void* aPrm)
       
   860 	{
       
   861 	TEST(aPrm != NULL);
       
   862 
       
   863 	__UHEAP_MARK;
       
   864 	CTrapCleanup* tc = CTrapCleanup::New();
       
   865 	TheTest(tc != NULL);
       
   866 
       
   867 	//Wait for a signal from the main thread
       
   868 	TThreadData* thrdat = (TThreadData*)aPrm;
       
   869 	thrdat->iCritSection.Wait();
       
   870 
       
   871 	RSqlDatabase db;
       
   872 	TInt err = db.Open(thrdat->iDbName);
       
   873 	TEST2(err, KErrNone);
       
   874 	err = db.Size(thrdat->iSize1);
       
   875 	TEST2(err, KErrNone);
       
   876 	//Simulate Exec() activities
       
   877 	for(TInt j=0;j<100;++j)
       
   878 		{
       
   879 		err = db.Exec(_L8("SELECT Id FROM A LIMIT 1"));
       
   880 		TEST(err >= 0);
       
   881 		if((j % 10) == 0 && thrdat->iSleepInterval > 0)
       
   882 			{
       
   883 			User::After(thrdat->iSleepInterval);
       
   884 			}
       
   885 		}
       
   886 	err = db.Size(thrdat->iSize2);
       
   887 	TEST2(err, KErrNone);
       
   888 	db.Close();
       
   889 
       
   890 	delete tc;	
       
   891 	__UHEAP_MARKEND;
       
   892 	return KErrNone;
       
   893 	}
       
   894 
       
   895 /**
       
   896 @SYMTestCaseID			SYSLIB-SQL-UT-4070
       
   897 @SYMTestCaseDesc		Background compaction load test.
       
   898 						The test runs 8 threads. Each thread connects to a different database.
       
   899 						Each database has space in the free pages above the "free pages" threshold - 
       
   900 						the background compaction will be scheduled at the moment when the database is opened.
       
   901 						Every thread executes some operations on the opened database - that will delay the background compaction.
       
   902 						After every 10 operations the thread sleeps for a specified interval of a time.
       
   903 						After all threads complete, the test checks the database size and free pages count and
       
   904 						prints them out.
       
   905 						The test verifies the ability of the SQL server to run the background compaction under a load.
       
   906 @SYMTestPriority		Medium
       
   907 @SYMTestActions			Background compaction load test.
       
   908 @SYMTestExpectedResults Test must not fail
       
   909 @SYMREQ					REQ10271
       
   910                         REQ10407
       
   911 */
       
   912 void BackgroundCompactionLoadTest()
       
   913 	{
       
   914 	RThread threads[KMaxThreadCount];
       
   915 	TThreadData* thrdata[KMaxThreadCount] = {NULL};
       
   916 	TRequestStatus thrstat[KMaxThreadCount];
       
   917 	
       
   918 	const TInt KSleepInterval[] = {0, 50000, 100000, 300000, 500000, 800000};//us
       
   919 	const TInt KTestCnt = sizeof(KSleepInterval) / sizeof(KSleepInterval[0]);
       
   920 	
       
   921 	for(TInt k=0;k<KTestCnt;++k)
       
   922 		{
       
   923 		TheTest.Printf(_L("=================================================\r\n"));
       
   924 		TheTest.Printf(_L("===Sleep interval %d ms\r\n"), KSleepInterval[k] / 1000);
       
   925 		TheTest.Printf(_L("=================================================\r\n"));
       
   926 		//Create test databases and threads
       
   927 		for(TInt i=0;i<TheTestThreadCount;++i)
       
   928 			{
       
   929 			//Database
       
   930 			TBuf<16> fname;
       
   931 			fname.Copy(_L("\\test\\a"));
       
   932 			fname.AppendNum(i + 1);
       
   933 			fname.Append(_L(".db"));
       
   934 			TheParse.Set(TheDrive, &fname, 0);
       
   935 			(void)RSqlDatabase::Delete(TheParse.FullName());
       
   936 			CreateDatabase8(TheParse.FullName());
       
   937 			//Thread data
       
   938 			thrdata[i] = new TThreadData(TheParse.FullName(), KSleepInterval[k]);
       
   939 			TEST(thrdata[i] != NULL);
       
   940 			//Thread
       
   941 			TBuf<16> thrname;
       
   942 			thrname.Copy(_L("Thread"));
       
   943 			thrname.AppendNum(i + 1);
       
   944 			TInt err = threads[i].Create(thrname, &ThreadFunc, 0x2000, 0x1000, 0x10000, thrdata[i], EOwnerProcess);
       
   945 			TEST2(err, KErrNone);
       
   946 			threads[i].Logon(thrstat[i]);
       
   947 			TEST2(thrstat[i].Int(), KRequestPending);
       
   948 			threads[i].Resume();
       
   949 			}
       
   950 		//Enable the threads
       
   951 		for(TInt i=0;i<TheTestThreadCount;++i)
       
   952 			{
       
   953 			thrdata[i]->iCritSection.Signal();	
       
   954 			}
       
   955 		//Wait for cmpletion
       
   956 		for(TInt i=0;i<TheTestThreadCount;++i)
       
   957 			{
       
   958 			User::WaitForRequest(thrstat[i]);
       
   959 			}
       
   960 		//Report
       
   961 		for(TInt i=0;i<TheTestThreadCount;++i)
       
   962 			{
       
   963 			TheTest.Printf(_L("===Thread %d, database %S\r\n"), i + 1, &(thrdata[i]->iDbName));
       
   964 			TheTest.Printf(_L("===Before background compaction: size %6ld, free space %6ld\r\n"), thrdata[i]->iSize1.iSize, thrdata[i]->iSize1.iFree);
       
   965 			TheTest.Printf(_L("===After background compaction:  size %6ld, free space %6ld\r\n"), thrdata[i]->iSize2.iSize, thrdata[i]->iSize2.iFree);
       
   966 			TEST(thrdata[i]->iSize2.iSize <= thrdata[i]->iSize1.iSize);
       
   967 			TEST(thrdata[i]->iSize2.iFree <= thrdata[i]->iSize1.iFree);
       
   968 			}
       
   969 		//Destroy
       
   970 		for(TInt i=0;i<TheTestThreadCount;++i)
       
   971 			{
       
   972 			(void)RSqlDatabase::Delete(thrdata[i]->iDbName);
       
   973 			thrdata[i]->iCritSection.Close();
       
   974 			delete thrdata[i];
       
   975 			thrdata[i] = NULL;
       
   976 			CLOSE_AND_WAIT(threads[i]);
       
   977 			}
       
   978 		}
       
   979 	}
       
   980 
       
   981 /**
       
   982 @SYMTestCaseID			SYSLIB-SQL-UT-4071
       
   983 @SYMTestCaseDesc		Background compaction in a DDL transaction test.
       
   984 						The test creates a database, begins a transaction that modifies the database structure  
       
   985 						and executes enough operations in order free enough space to kick-off the background compaction. 
       
   986 						The test should not report any failures caused by the fact that the main database connection is
       
   987 						in a DML transaction and at the same time the background connection may try to execute
       
   988 						a "PRAGMA freelist_count" statement.
       
   989 @SYMTestPriority		Medium
       
   990 @SYMTestActions			Background compaction in a DDL transaction test.
       
   991 @SYMTestExpectedResults Test must not fail
       
   992 @SYMREQ					REQ10271
       
   993 */
       
   994 void BackgroundCompactionInDDLTransactionTest()
       
   995 	{
       
   996 	const TInt KOperationCount = 100;
       
   997 	(void)RSqlDatabase::Delete(KDbName);
       
   998 	TInt err = TheDb.Create(KDbName);
       
   999 	TEST2(err, KErrNone);
       
  1000 	err = TheDb.Exec(_L("BEGIN"));
       
  1001 	TEST(err >= 0);
       
  1002 	err = TheDb.Exec(_L("CREATE TABLE A(I INTEGER, T TEXT)"));
       
  1003 	TEST2(err, 1);
       
  1004 	TheText.SetLength(KTextLen);
       
  1005 	TheText.Fill(TChar('A'));
       
  1006 	for(TInt i=0;i<=KOperationCount;++i)	
       
  1007 		{
       
  1008 		TheSqlTexLen.Format(_L("INSERT INTO A VALUES(%d, '%S')"), i + 1, &TheText);
       
  1009 		err = TheDb.Exec(TheSqlTexLen);
       
  1010 		TEST2(err, 1);
       
  1011 		}
       
  1012 	err = TheDb.Exec(_L("COMMIT"));
       
  1013 	TEST(err >= 0);
       
  1014 	TheDb.Close();
       
  1015 	(void)RSqlDatabase::Delete(KDbName);
       
  1016 	}
       
  1017 
       
  1018 void DoTestsL()
       
  1019 	{
       
  1020 	CreateTestDatabase8();
       
  1021 	CalculateMaxCompaction8();
       
  1022 	CreateTestDatabase16();
       
  1023 	CalculateMaxCompaction16();
       
  1024 
       
  1025 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4064 Manual Compact() - negative tests"));	
       
  1026 	ManualCompactionNegativeTest();
       
  1027 
       
  1028 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4065 Manual Compact() tests"));	
       
  1029 	ManualCompactionTest();
       
  1030 
       
  1031 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4066 Manual compaction db size test"));	
       
  1032 	ManualCompactionSizeTest();
       
  1033 
       
  1034 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4068 Manual compaction - OOM test"));	
       
  1035 	ManualCompactionOomTest();
       
  1036 
       
  1037 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4067 Auto compaction db size test"));	
       
  1038 	AutoCompactionSizeTest();
       
  1039 
       
  1040 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4069 Background compaction test"));	
       
  1041 	BackgroundCompactionTest();
       
  1042 
       
  1043 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4070 Background compaction - load test"));	
       
  1044 	BackgroundCompactionLoadTest();
       
  1045 
       
  1046 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4071 Background compaction activated inside a DDL transaction - test"));	
       
  1047 	BackgroundCompactionInDDLTransactionTest();
       
  1048 	}
       
  1049 
       
  1050 TInt E32Main()
       
  1051 	{
       
  1052 	TheTest.Title();
       
  1053 	
       
  1054 	CTrapCleanup* tc = CTrapCleanup::New();
       
  1055 	TheTest(tc != NULL);
       
  1056 	
       
  1057 	TheTest.Printf(_L("Usage:\r\n  t_sqlcompact4 [[drive:] [test thread count]]\r\n"));
       
  1058 	TheDrive.Copy(KDefaultDriveName);
       
  1059 	User::CommandLine(TheCmd);
       
  1060 	TheCmd.TrimAll();
       
  1061 	if(TheCmd.Length() > 0)
       
  1062 		{
       
  1063 		TInt pos = TheCmd.Locate(TChar(' '));
       
  1064 		TheTest(pos > 0);
       
  1065 		TPtrC prm1(TheCmd.Left(pos));
       
  1066 		TPtrC prm2(TheCmd.Mid(pos + 1));
       
  1067 		
       
  1068 		TheDrive.Copy(prm1);
       
  1069 		
       
  1070 		TLex lex(prm2);
       
  1071 		lex.Val(TheTestThreadCount);
       
  1072 		}
       
  1073 	TheParse.Set(TheDrive, &KDbName, 0);
       
  1074 	TheTestDbName.Copy(TheParse.FullName());
       
  1075 	TheTest.Printf(_L("Test database: %S\r\n"), &TheTestDbName);
       
  1076 	
       
  1077 	__UHEAP_MARK;
       
  1078 	
       
  1079 	CreateTestEnv();
       
  1080 	TRAPD(err, DoTestsL());
       
  1081 	DestroyTestEnv();
       
  1082 	TEST2(err, KErrNone);
       
  1083 	
       
  1084 	__UHEAP_MARKEND;
       
  1085 	
       
  1086 	TheTest.End();
       
  1087 	TheTest.Close();
       
  1088 	
       
  1089 	delete tc;
       
  1090 	
       
  1091 	User::Heap().Check();
       
  1092 	return KErrNone;
       
  1093 	}