persistentstorage/sql/TEST/t_sqlbur.cpp
changeset 0 08ec8eefde2f
child 12 6b6fd149daa2
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2006-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 <e32math.h>
       
    20 
       
    21 #include "SqlBur.h"
       
    22 #include "t_sqlbur.h"
       
    23 
       
    24 ///////////////////////////////////////////////////////////////////////////////////////
       
    25 
       
    26 RTest TheTest(_L("SQL Backup and Restore Test"));
       
    27 
       
    28 _LIT(KPrivateDir, "C:\\private\\10281e17\\");
       
    29 
       
    30 const TUid KClientUid = {0x21212122}; // the data owner's UID
       
    31 
       
    32 _LIT(KBackupDir, "C:\\TEST\\");
       
    33 _LIT(KBackupFile, "C:\\TEST\\Backup.bak");
       
    34 _LIT(KBackupFile2Z, "Z:\\TEST\\t_sqlbur_backup_ver0.bak");
       
    35 _LIT(KBackupFile2, "C:\\TEST\\t_sqlbur_backup_ver0.bak");
       
    36 
       
    37 const TUint KBufferSize = 2048; // used for reading backup files for validation
       
    38 
       
    39 static CActiveScheduler* TheScheduler = NULL;
       
    40 static CSqlBurTestHarness* TheTestHarness = NULL;
       
    41 
       
    42 /////////////////////////////////////
       
    43 
       
    44 const TInt KMaxDbFileSize = 10 * 1024;//The max test db file size
       
    45 const TInt KTestDbFileCnt = 2;
       
    46 
       
    47 //Test db files
       
    48 _LIT(KTestFileName1,"[21212122]AADB2.db");//Created outside this test app
       
    49 _LIT(KTestFileName2,"[21212122]BBDB2.db");//Created outside this test app
       
    50 _LIT(KTestDbFileName1,"C:[21212122]AADB2.db");
       
    51 _LIT(KTestDbFileName2,"C:[21212122]BBDB2.db");
       
    52 
       
    53 const TPtrC KTestFileNames[KTestDbFileCnt] = {KTestFileName1(), KTestFileName2()};
       
    54 
       
    55 static TInt TheDbFileSizes[KTestDbFileCnt];//An array where the real db file size will be stored
       
    56 static TUint8 TheDbFileData[KTestDbFileCnt][KMaxDbFileSize];//An array where the original db file content will be stored
       
    57 static TUint8 TheBuf[KMaxDbFileSize];
       
    58 
       
    59 /////////////////////////////////////
       
    60 
       
    61 ///////////////////////////////////////////////////////////////////////////////////////
       
    62 
       
    63 void TestEnvDestroy()
       
    64 	{
       
    65 	delete TheTestHarness;
       
    66 	TheTestHarness = NULL;		
       
    67 	
       
    68 	delete TheScheduler;
       
    69 	TheScheduler = NULL;
       
    70 	}
       
    71 
       
    72 ////////////////////////////
       
    73 // Test macros and functions
       
    74 ////////////////////////////
       
    75 
       
    76 void Check(TInt aValue, TInt aLine)
       
    77 	{
       
    78 	if(!aValue)
       
    79 		{
       
    80 		TestEnvDestroy();
       
    81 		TheTest(EFalse, aLine);
       
    82 		}
       
    83 	}
       
    84 
       
    85 void Check(TInt aValue, TInt aExpected, TInt aLine)
       
    86 	{
       
    87 	if(aValue != aExpected)
       
    88 		{
       
    89 		TestEnvDestroy();
       
    90 		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
    91 		TheTest(EFalse, aLine);
       
    92 		}
       
    93 	}
       
    94 #define TEST(arg) ::Check((arg), __LINE__)
       
    95 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
    96 
       
    97 ///////////////////////////////////////////////////////////////////////////////////////
       
    98 
       
    99 //CSqlBurTestHarness - test implementation of the MSqlSrvBurInterface, implemented in the production code by the SQL server.
       
   100 CSqlBurTestHarness *CSqlBurTestHarness::New()
       
   101 	{
       
   102 	CSqlBurTestHarness* self = new CSqlBurTestHarness;
       
   103 	TEST(self != NULL);
       
   104 	self->Construct();
       
   105 	return self;
       
   106 	}
       
   107 
       
   108 CSqlBurTestHarness::CSqlBurTestHarness()
       
   109 	{
       
   110 	}
       
   111 
       
   112 void CSqlBurTestHarness::Construct()
       
   113 	{
       
   114 	TInt err = iFs.Connect();
       
   115 	TEST2(err, KErrNone);
       
   116 	err = iFs.MkDir(KBackupDir);
       
   117 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   118 	err = iFs.CreatePrivatePath(EDriveC);
       
   119 	TEST2(err, KErrNone);
       
   120 	}
       
   121 
       
   122 CSqlBurTestHarness::~CSqlBurTestHarness()
       
   123 	{
       
   124 	(void)iFs.Delete(KBackupFile);
       
   125 	iFs.Close();
       
   126 	}
       
   127 
       
   128 //Called by the backup client ot get a list of database files to backup
       
   129 //The array is owned by the caller
       
   130 //The SQL server would have the job to get a list of databases owned by
       
   131 //the given SID and to determine whether the backup flag is set
       
   132 //All databases that satisfy this requirement will be added to the array
       
   133 void CSqlBurTestHarness::GetBackUpListL(TSecureId /*aUid*/, RArray<TParse>& aFileList)
       
   134 	{
       
   135 	//TheTest.Printf(_L("Getting backup file list for SID=%x\r\n"),aUid);
       
   136 	for(TInt i=0;i<KTestDbFileCnt;++i)
       
   137 		{
       
   138 		TParse parse;
       
   139 		parse.Set(KTestFileNames[i], &KPrivateDir, NULL);
       
   140 		aFileList.AppendL(parse);
       
   141 		}
       
   142 	}
       
   143 
       
   144 //Notification that a backup is starting
       
   145 TBool CSqlBurTestHarness::StartBackupL(const RArray<TParse>& /*aFileList*/) 
       
   146 	{
       
   147 	//TheTest.Printf(_L("Start \"backup\". %d files in the list.\r\n"), aFileList.Count());
       
   148 	return ETrue;
       
   149 	}
       
   150 
       
   151 //Notification that a backup has ended
       
   152 void CSqlBurTestHarness::EndBackup(const RArray<TParse>& /*aFileList*/)
       
   153 	{
       
   154 	//TheTest.Printf(_L("End \"backup\". %d files in the list.\r\n"), aFileList.Count());
       
   155 	}
       
   156 
       
   157 //Notification that a restore is starting
       
   158 TBool CSqlBurTestHarness::StartRestoreL(TSecureId /*aUid*/) 
       
   159 	{
       
   160 	//TheTest.Printf(_L("Start \"restore\" for UID=%X\r\n"), aUid);
       
   161 	return ETrue;
       
   162 	}
       
   163 
       
   164 //Notification that a restore has ended
       
   165 void CSqlBurTestHarness::EndRestore(TSecureId /*aUid*/) 
       
   166 	{
       
   167 	//TheTest.Printf(_L("End \"restore\" for UID=%X\r\n"), aUid);
       
   168 	}
       
   169 	
       
   170 //Returns the file system resource handle to the caller.
       
   171 RFs& CSqlBurTestHarness::Fs()
       
   172 	{
       
   173 	return iFs;
       
   174 	}
       
   175 
       
   176 ///////////////////////////////////////////////////////////////////////////////////////
       
   177 ///////////////////////////////////////////////////////////////////////////////////////
       
   178 ///////////////////////////////////////////////////////////////////////////////////////
       
   179 
       
   180 TBool FileExists(RFs& aFs, const TDesC& aFileName)
       
   181 	{
       
   182 	TEntry entry;
       
   183 	return aFs.Entry(aFileName, entry) == KErrNone;
       
   184 	}
       
   185 
       
   186 void TestEnvCreate()
       
   187 	{
       
   188 	TheScheduler = new CActiveScheduler;
       
   189 	TEST(TheScheduler != NULL);
       
   190 	
       
   191 	CActiveScheduler::Install(TheScheduler);
       
   192 
       
   193 	TheTestHarness = CSqlBurTestHarness::New();
       
   194 	TEST(TheTestHarness != NULL);
       
   195 	}
       
   196 
       
   197 //Reads the content of the db files and stores the content to a global memory buffer.
       
   198 //That buffer content will be sued later for  a verification of the restore process.
       
   199 void StoreDbContentToBuf(RFs& aFs)
       
   200 	{
       
   201 	for(TInt i=0;i<KTestDbFileCnt;++i)
       
   202 		{
       
   203 		RFile dbFile;
       
   204 		TInt err = dbFile.Open(aFs, KTestFileNames[i], EFileRead);
       
   205 		TEST2(err, KErrNone);
       
   206 		
       
   207 		TInt fileSize = 0;
       
   208 		err = dbFile.Size(fileSize);
       
   209 		TEST2(err, KErrNone);
       
   210 		TEST(fileSize > 0);
       
   211 
       
   212 		TPtr8 bufptr(TheDbFileData[i], 0, KMaxDbFileSize);
       
   213 		err = dbFile.Read(bufptr, fileSize);
       
   214 		TEST2(err, KErrNone);
       
   215 		TEST(fileSize == bufptr.Length());
       
   216 
       
   217 		TheDbFileSizes[i] = fileSize;
       
   218 		
       
   219 		dbFile.Close();
       
   220 		}
       
   221 	}
       
   222 
       
   223 //At the moment when this function is called, the db files content is already restored.
       
   224 //The function will open the restored db files and compare their content against the content
       
   225 //of the original db files (kept in a global memory buffer).
       
   226 void CompareDbContentWithBuf(RFs& aFs)
       
   227 	{
       
   228 	for(TInt i=0;i<KTestDbFileCnt;++i)
       
   229 		{
       
   230 		TEST(TheDbFileSizes[i] > 0);
       
   231 		
       
   232 		RFile dbFile;
       
   233 		TInt err = dbFile.Open(aFs, KTestFileNames[i], EFileRead);
       
   234 		TEST2(err, KErrNone);
       
   235 		
       
   236 		TInt fileSize = 0;
       
   237 		err = dbFile.Size(fileSize);
       
   238 		TEST2(err, KErrNone);
       
   239 		TEST(fileSize > 0);
       
   240 		TEST(TheDbFileSizes[i] == fileSize);
       
   241 
       
   242 		TPtr8 bufptr(TheBuf, 0, KMaxDbFileSize);
       
   243 		err = dbFile.Read(bufptr, fileSize);
       
   244 		TEST2(err, KErrNone);
       
   245 		TEST(fileSize == bufptr.Length());
       
   246 
       
   247 		err = Mem::Compare(TheBuf, fileSize, TheDbFileData[i], TheDbFileSizes[i]);
       
   248 		TEST2(err, 0);
       
   249 
       
   250 		dbFile.Close();
       
   251 		}
       
   252 	}
       
   253 
       
   254 ////////////////////////////////////////////////////////////////////////////////////////
       
   255 
       
   256 //The backup client will return a series of data chunks representing
       
   257 //one of more databases for the uid of the data owner.
       
   258 //This data is stored in a file on the C drive for the purposes of the test
       
   259 TInt TestBackupL(CSqlBackupClient &aBackupClient, RFs& aFs, TInt aDataChunkSize = KBufferSize)
       
   260 	{
       
   261 	RFile file;
       
   262 	CleanupClosePushL(file);
       
   263 	TInt err = file.Replace(aFs, KBackupFile, EFileWrite | EFileStream | EFileShareExclusive);
       
   264 	User::LeaveIfError(err);
       
   265 	aBackupClient.InitialiseGetProxyBackupDataL(KClientUid, EDriveC);
       
   266 	
       
   267 	TBuf8<KBufferSize> buf;
       
   268 	TPtr8 ptr((TUint8*)buf.Ptr(), aDataChunkSize);
       
   269 	TBool finishedFlag = EFalse;
       
   270 	TInt count = 0;
       
   271 	
       
   272 	do
       
   273 		{
       
   274 		aBackupClient.GetBackupDataSectionL(ptr, finishedFlag);
       
   275 		count += ptr.Length();
       
   276 		err = file.Write(ptr);
       
   277 		User::LeaveIfError(err);
       
   278 		ptr.SetLength(0);
       
   279 		}
       
   280 	while(!finishedFlag);
       
   281 
       
   282 	CleanupStack::PopAndDestroy(&file);
       
   283 	
       
   284 	if(count == 0)
       
   285 		{
       
   286 		User::Leave(KErrEof);
       
   287 		}
       
   288 	if(!FileExists(aFs, KBackupFile))
       
   289 		{
       
   290 		User::Leave(KErrNotFound);
       
   291 		}
       
   292 	TheTest.Printf(_L("Backup complete. %d bytes processed.\r\n"), count);
       
   293 	return count;
       
   294 	}
       
   295 
       
   296 //This sends the data in chunks form back to the BUR client
       
   297 //for nupacking and restoration of the original databases files
       
   298 TInt TestRestoreL(CSqlBackupClient &aRestoreClient, RFs& aFs, TInt aDataChunkSize = KBufferSize)
       
   299 	{
       
   300 	RFile file;
       
   301 	CleanupClosePushL(file);
       
   302 	TInt err = file.Open(aFs, KBackupFile, EFileRead | EFileShareExclusive);
       
   303 	User::LeaveIfError(err);
       
   304 	aRestoreClient.InitialiseRestoreProxyBaseDataL(KClientUid, EDriveC);
       
   305 	
       
   306 	TBuf8<KBufferSize> buf;
       
   307 	TPtr8 ptr((TUint8*)buf.Ptr(), aDataChunkSize);
       
   308 	TBool finishedFlag = EFalse;
       
   309 	
       
   310 	TInt fileSize = 0;
       
   311 	err = file.Size(fileSize);
       
   312 	User::LeaveIfError(err);
       
   313 	TInt count = fileSize;
       
   314 	
       
   315 	do
       
   316 		{
       
   317 		err = file.Read(ptr, aDataChunkSize);
       
   318 		User::LeaveIfError(err);
       
   319 		fileSize -= ptr.Length();
       
   320 		finishedFlag = fileSize == 0;
       
   321 		aRestoreClient.RestoreBaseDataSectionL(ptr, finishedFlag);
       
   322 		ptr.SetLength(0);
       
   323 		} 
       
   324 	while(fileSize > 0);
       
   325 	
       
   326 	CleanupStack::PopAndDestroy(&file);
       
   327 	
       
   328 	aRestoreClient.RestoreComplete(EDriveC);
       
   329 	
       
   330 	if(!finishedFlag)
       
   331 		{
       
   332 		User::Leave(KErrEof);
       
   333 		}
       
   334 	for(TInt i=0;i<KTestDbFileCnt;++i)
       
   335 		{
       
   336 		if(!FileExists(aFs, KTestFileNames[i]))
       
   337 			{
       
   338 			User::Leave(KErrNotFound);
       
   339 			}
       
   340 		}
       
   341 		
       
   342 	TheTest.Printf(_L("Restore complete. %d bytes processed.\r\n"), count);
       
   343 	return count;
       
   344 	}
       
   345 
       
   346 //Verifies the integrity of the backup file.
       
   347 void TestArchiveIntegrityL(CSqlBackupClient &aBackupClient, RFs& aFs)
       
   348 	{
       
   349 	RFile bkpFile;
       
   350 	CleanupClosePushL(bkpFile);
       
   351 	
       
   352 	TInt err = bkpFile.Open(aFs, KBackupFile, EFileRead | EFileShareExclusive);
       
   353 	User::LeaveIfError(err);
       
   354 	
       
   355 	TBuf8<KBufferSize> buf;
       
   356 	TPtr8 ptr((TUint8*)buf.Ptr(), buf.MaxLength());
       
   357 	
       
   358 	TInt bkpFileSize = 0;
       
   359 	err = bkpFile.Size(bkpFileSize);
       
   360 	User::LeaveIfError(err);
       
   361 	
       
   362 	while(bkpFileSize > 0)
       
   363 		{
       
   364 		// get the checksum
       
   365 		err = bkpFile.Read(ptr, 16); // 8 UTF-16 characters
       
   366 		User::LeaveIfError(err);
       
   367 		if(ptr.Length() != 16)
       
   368 			{
       
   369 			User::Leave(KErrCorrupt);
       
   370 			}
       
   371 		TPtr ptr16((TUint16*) ptr.Ptr(), 8, 8);
       
   372 		TLex lex(ptr16);
       
   373 		TUint32 checksum;
       
   374 		lex.SkipSpace();
       
   375 		err = lex.Val(checksum, EHex);
       
   376 		User::LeaveIfError(err);
       
   377 		bkpFileSize -= 16;
       
   378 
       
   379 		// get the old file size
       
   380 		err = bkpFile.Read(ptr, 16); // 8 UTF-16 characters
       
   381 		User::LeaveIfError(err);
       
   382 		if(ptr.Length() != 16)
       
   383 			{
       
   384 			User::Leave(KErrCorrupt);
       
   385 			}
       
   386 		ptr16.Set((TUint16*) ptr.Ptr(), 8, 8);
       
   387 		lex.Assign(ptr16);
       
   388 		TUint32 oldFileSize;
       
   389 		lex.SkipSpace();
       
   390 		err = lex.Val(oldFileSize, EHex);
       
   391 		User::LeaveIfError(err);
       
   392 		bkpFileSize -= 16;
       
   393 
       
   394 		// get the backup file header version
       
   395 		err = bkpFile.Read(ptr, 8); // 4 UTF-16 characters
       
   396 		User::LeaveIfError(err);
       
   397 		ptr16.Set((TUint16*)ptr.Ptr(), 4, 4);
       
   398 		lex.Assign(ptr16);
       
   399 		TUint32 hdrVer;
       
   400 		lex.SkipSpace();
       
   401 		err = lex.Val(hdrVer, EHex);
       
   402 		User::LeaveIfError(err);
       
   403 		bkpFileSize -= 8;
       
   404 
       
   405 		// get the file size
       
   406 		err = bkpFile.Read(ptr, 32); // 16 UTF-16 characters
       
   407 		User::LeaveIfError(err);
       
   408 		if(ptr.Length() != 32)
       
   409 			{
       
   410 			User::Leave(KErrCorrupt);
       
   411 			}
       
   412 		ptr16.Set((TUint16*) ptr.Ptr(), 16, 16);
       
   413 		lex.Assign(ptr16);
       
   414 		TInt64 fileSize;
       
   415 		lex.SkipSpace();
       
   416 		err = lex.Val(fileSize, EHex);
       
   417 		User::LeaveIfError(err);
       
   418 		bkpFileSize -= 32;
       
   419 
       
   420 		// get the filename size
       
   421 		err = bkpFile.Read(ptr, 16); // 8 UTF-16 characters
       
   422 		User::LeaveIfError(err);
       
   423 		ptr16.Set((TUint16*)ptr.Ptr(), 8, 8);
       
   424 		lex.Assign(ptr16);
       
   425 		TUint32 fileNameSize;
       
   426 		lex.SkipSpace();
       
   427 		err = lex.Val(fileNameSize, EHex);
       
   428 		User::LeaveIfError(err);
       
   429 		bkpFileSize -= 16;
       
   430 
       
   431 		// get the filename
       
   432 		err = bkpFile.Read(ptr, fileNameSize * 2); // fileName UTF-16 characters
       
   433 		User::LeaveIfError(err);
       
   434 		if(ptr.Length() != (fileNameSize * 2))
       
   435 			{
       
   436 			User::Leave(KErrCorrupt);
       
   437 			}
       
   438 		ptr16.Set((TUint16*) ptr.Ptr(), fileNameSize, fileNameSize);
       
   439 		lex.Assign(ptr16);
       
   440 		TParse tp;
       
   441 		tp.Set(ptr16, NULL, NULL);
       
   442 		TPtrC dbFileName = tp.Name();
       
   443 		bkpFileSize -= fileNameSize * 2;
       
   444 	
       
   445 		// open a local file - replaces any previous one
       
   446 		RFile64 dbFile;
       
   447 		CleanupClosePushL(dbFile);
       
   448 		err = dbFile.Replace(aFs, dbFileName, EFileWrite | EFileShareExclusive);
       
   449 		User::LeaveIfError(err);
       
   450 	
       
   451 		// copy all the data (file size bytes)
       
   452 		TInt bytesLeftToRead = fileSize;
       
   453 
       
   454 		while(bytesLeftToRead > 0)
       
   455 			{
       
   456 			TInt readSize = bytesLeftToRead > KBufferSize ? KBufferSize : bytesLeftToRead;
       
   457 			err = bkpFile.Read(ptr, readSize);
       
   458 			User::LeaveIfError(err);
       
   459 			if(ptr.Length() != readSize)
       
   460 				{
       
   461 				User::Leave(KErrCorrupt);	
       
   462 				}
       
   463 			bytesLeftToRead -= readSize;
       
   464 			err = dbFile.Write(ptr, readSize);
       
   465 			User::LeaveIfError(err);
       
   466 			}
       
   467 
       
   468 		bkpFileSize -= fileSize;
       
   469 		
       
   470 		// checksum the file
       
   471 		TUint32 dbChecksum = aBackupClient.CheckSumL(dbFile) & 0xFFFFFFFF;
       
   472 		
       
   473 		if(checksum != dbChecksum)
       
   474 			{
       
   475 			User::Leave(KErrCorrupt);
       
   476 			}
       
   477 			
       
   478 		// all done with this file
       
   479 		CleanupStack::PopAndDestroy(&dbFile);
       
   480 		err = aFs.Delete(dbFileName);
       
   481 		User::LeaveIfError(err);
       
   482 		}
       
   483 	
       
   484 	CleanupStack::PopAndDestroy(&bkpFile);
       
   485 	}
       
   486 
       
   487 /**
       
   488 @SYMTestCaseID			SYSLIB-SQL-UT-4002
       
   489 @SYMTestCaseDesc		Test for DEF113598 - "SQL, t_sqlbur unit test needs refactoring"
       
   490 						The test backups 2 test db files, then verifies the backup file integrity,
       
   491 						then restores the test db files content from the backup file.
       
   492 						At the end, the test checks that the restored test db files content is the
       
   493 						same as the content of the original test db file.
       
   494 @SYMTestPriority		High
       
   495 @SYMTestActions			Test for DEF113598 - "SQL, t_sqlbur unit test needs refactoring"
       
   496 @SYMTestExpectedResults Test must not fail
       
   497 @SYMDEF					DEF113598
       
   498 */	
       
   499 void FunctionalTest()
       
   500 	{
       
   501 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4002 Backup: functional test "));
       
   502 	
       
   503 	CSqlBackupClient* backupClient = NULL;
       
   504 	TRAPD(err, backupClient = CSqlBackupClient::NewL(TheTestHarness));
       
   505 	TEST(backupClient != NULL);
       
   506 
       
   507 	////////////////////////////////////////
       
   508 
       
   509 	const TDriveNumber KDrive = EDriveC;
       
   510 	
       
   511 	//Virtual functions - with default implementation
       
   512 	
       
   513 	(void)backupClient->GetExpectedDataSize(KDrive);
       
   514 
       
   515 	(void)backupClient->GetDataChecksum(KDrive);
       
   516 	
       
   517 	TBool finished = EFalse;
       
   518 	TPtr8 ptr(0, 0, 0);
       
   519 	TRAP(err, backupClient->GetSnapshotDataL(KDrive, ptr, finished));
       
   520 	TEST2(err, KErrNotSupported);
       
   521 
       
   522 	TRAP(err, backupClient->InitialiseGetBackupDataL(KDrive));
       
   523 	TEST2(err, KErrNotSupported);
       
   524 
       
   525 	TRAP(err, backupClient->InitialiseRestoreBaseDataL(KDrive));
       
   526 	TEST2(err, KErrNotSupported);
       
   527 
       
   528 	TRAP(err, backupClient->InitialiseRestoreIncrementDataL(KDrive));
       
   529 	TEST2(err, KErrNotSupported);
       
   530 
       
   531 	TPtrC8 ptr2(KNullDesC8);
       
   532 	TRAP(err, backupClient->RestoreIncrementDataSectionL(ptr2, finished));
       
   533 	TEST2(err, KErrNotSupported);
       
   534 
       
   535 	TRAP(err, backupClient->AllSnapshotsSuppliedL());
       
   536 	TEST2(err, KErrNone);
       
   537 
       
   538 	TRAP(err, backupClient->ReceiveSnapshotDataL(KDrive, ptr2, finished));
       
   539 	TEST2(err, KErrNotSupported);
       
   540 
       
   541 	backupClient->TerminateMultiStageOperation();
       
   542 
       
   543 	////////////////////////////////////////
       
   544 
       
   545 	TInt bytesStored = 0;
       
   546 	TRAP(err, bytesStored = TestBackupL(*backupClient, TheTestHarness->Fs()));
       
   547 	TEST2(err, KErrNone);
       
   548 
       
   549 	TheTest.Next(_L("Archive integrity test"));
       
   550 	
       
   551 	TRAP(err, TestArchiveIntegrityL(*backupClient, TheTestHarness->Fs()));
       
   552 	TEST2(err, KErrNone);
       
   553 
       
   554 	delete backupClient;
       
   555 
       
   556 	TheTest.Next(_L("Restore: functional test"));
       
   557 
       
   558 	CSqlBackupClient* restoreClient = NULL;
       
   559 	TRAP(err, restoreClient = CSqlBackupClient::NewL(TheTestHarness));
       
   560 	TEST(restoreClient != NULL);
       
   561 
       
   562 	TInt bytesRestored = 0;
       
   563 	TRAP(err, bytesRestored = TestRestoreL(*restoreClient, TheTestHarness->Fs()));
       
   564 	TEST2(err, KErrNone);
       
   565 	
       
   566 	TEST(bytesRestored == bytesStored);
       
   567 
       
   568 	delete restoreClient;
       
   569 
       
   570 	CompareDbContentWithBuf(TheTestHarness->Fs());
       
   571 	}
       
   572 	
       
   573 TInt DoBackupL()
       
   574 	{
       
   575 	CSqlBackupClient* backupClient = CSqlBackupClient::NewLC(TheTestHarness);
       
   576 	TInt bytesStored = TestBackupL(*backupClient, TheTestHarness->Fs());
       
   577 	CleanupStack::PopAndDestroy(backupClient);
       
   578 	return bytesStored;
       
   579 	}
       
   580 
       
   581 TInt DoRestoreL()
       
   582 	{
       
   583 	CSqlBackupClient* restoreClient = CSqlBackupClient::NewLC(TheTestHarness);
       
   584 	TInt bytesRestored = TestRestoreL(*restoreClient, TheTestHarness->Fs());
       
   585 	CleanupStack::PopAndDestroy(restoreClient);
       
   586 	return bytesRestored;
       
   587 	}
       
   588 
       
   589 /**
       
   590 @SYMTestCaseID			SYSLIB-SQL-UT-4003
       
   591 @SYMTestCaseDesc		Test for DEF113598 - "SQL, t_sqlbur unit test needs refactoring"
       
   592 						Under simulated OOM condition, the test backups 2 test db files, 
       
   593 						then restores the test db files content from the backup file.
       
   594 						At the end, the test checks that the restored test db files content is the
       
   595 						same as the content of the original test db file.
       
   596 @SYMTestPriority		High
       
   597 @SYMTestActions			Test for DEF113598 - "SQL, t_sqlbur unit test needs refactoring"
       
   598 @SYMTestExpectedResults Test must not fail
       
   599 @SYMDEF					DEF113598
       
   600 */	
       
   601 void OomTest()
       
   602 	{
       
   603 	///////////////////////////////////////////////////////////////////////////////
       
   604 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4003 Backup: OOM test "));
       
   605 	TInt err = KErrNoMemory;
       
   606 	TInt bytesStored = 0;
       
   607 	TInt count = 0;
       
   608 	
       
   609 	for(count=1;err==KErrNoMemory;++count)
       
   610 		{
       
   611 		TInt startProcessHandleCount;
       
   612 		TInt startThreadHandleCount;
       
   613 		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   614 		
       
   615 		User::__DbgMarkStart(RHeap::EUser);
       
   616 		User::__DbgSetAllocFail(RHeap::EUser,RHeap::EFailNext, count);
       
   617 		TRAP(err, bytesStored = DoBackupL());
       
   618 		User::__DbgMarkEnd(RHeap::EUser, 0);
       
   619 		
       
   620 		TInt endProcessHandleCount;
       
   621 		TInt endThreadHandleCount;
       
   622 		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   623 		
       
   624 		TEST(startProcessHandleCount == endProcessHandleCount);
       
   625 		TEST(startThreadHandleCount == endThreadHandleCount);
       
   626 		}
       
   627 	TEST2(err, KErrNone);
       
   628 	TheTest.Printf(_L("OOM backup test succeeded at heap failure rate of %d\r\n"), count);
       
   629 
       
   630 	///////////////////////////////////////////////////////////////////////////////
       
   631 	TheTest.Next(_L("Restore: OOM test"));
       
   632 	err = KErrNoMemory;
       
   633 	TInt bytesRestored = 0;
       
   634 	
       
   635 	for(count=1;err==KErrNoMemory;++count)
       
   636 		{
       
   637 		TInt startProcessHandleCount;
       
   638 		TInt startThreadHandleCount;
       
   639 		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);
       
   640 		
       
   641 		User::__DbgMarkStart(RHeap::EUser);
       
   642 		User::__DbgSetAllocFail(RHeap::EUser,RHeap::EFailNext, count);
       
   643 		TRAP(err, bytesRestored = DoRestoreL());
       
   644 		User::__DbgMarkEnd(RHeap::EUser, 0);
       
   645 		
       
   646 		TInt endProcessHandleCount;
       
   647 		TInt endThreadHandleCount;
       
   648 		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
       
   649 		
       
   650 		TEST(startProcessHandleCount == endProcessHandleCount);
       
   651 		TEST(startThreadHandleCount == endThreadHandleCount);
       
   652 		}
       
   653 	TEST2(err, KErrNone);
       
   654 	User::__DbgSetAllocFail(RHeap::EUser, RAllocator::ENone, 0);
       
   655 	TheTest.Printf(_L("OOM restore test succeeded at heap failure rate of %d\r\n"), count);
       
   656 	
       
   657 	TEST(bytesStored == bytesRestored);
       
   658 
       
   659 	CompareDbContentWithBuf(TheTestHarness->Fs());
       
   660 	}
       
   661 
       
   662 /**
       
   663 @SYMTestCaseID			PDS-SQL-UT-4143
       
   664 @SYMTestCaseDesc		SQL Backup&Restore - data chunk size test.
       
   665 						The test uses an integer array of 10 elements with randomly generated data chunk sizes.
       
   666 						Then the test runs 10 backup iterations using each time different data chunk size.
       
   667 						After each backup iteration the test performs a restore operation and checks that the 
       
   668 						data has been backup&restored without errors.
       
   669 @SYMTestActions			SQL Backup&Restore - data chunk size test.
       
   670 @SYMTestExpectedResults Test must not fail
       
   671 @SYMTestPriority		Medium
       
   672 @SYMREQ					REQ12104
       
   673 */
       
   674 void FunctionalTest2()
       
   675 	{
       
   676 	TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4143 Backup&Restore: functional test 2"));
       
   677 	
       
   678 	TTime now;
       
   679 	now.UniversalTime();
       
   680 	TInt64 seed = now.Int64();
       
   681 
       
   682 	const TInt KArraySize = 10;
       
   683 	TInt  dataChunks[10] = {2, 6, 0, 0, 0, 0, 0, 0, 0, 0};
       
   684 	const TInt KMaxDataChunkSize = 50;
       
   685 	
       
   686 	for(TInt i=2;i<KArraySize;)
       
   687 		{
       
   688 		TInt dataChunkSize = Math::Rand(seed) % KMaxDataChunkSize;
       
   689 		if((dataChunkSize % 2) == 0 && dataChunkSize != 0)	//The code works only with data chunks with even sizes!!!
       
   690 			{
       
   691 			dataChunks[i++] = dataChunkSize;
       
   692 			}
       
   693 		}
       
   694 	
       
   695 	for(TInt i=0;i<KArraySize;++i)
       
   696 		{
       
   697 		TheTest.Printf(_L(" === Iteration %d, chunk size %d\r\n"), i + 1, dataChunks[i]);
       
   698 		CSqlBackupClient* backupClient = NULL;
       
   699 		TRAPD(err, backupClient = CSqlBackupClient::NewL(TheTestHarness));
       
   700 		TEST(backupClient != NULL);
       
   701 
       
   702 		TInt bytesStored = 0;
       
   703 		TRAP(err, bytesStored = TestBackupL(*backupClient, TheTestHarness->Fs(), dataChunks[i]));
       
   704 		TEST2(err, KErrNone);
       
   705 
       
   706 		TRAP(err, TestArchiveIntegrityL(*backupClient, TheTestHarness->Fs()));
       
   707 		TEST2(err, KErrNone);
       
   708 
       
   709 		delete backupClient;
       
   710 
       
   711 		CSqlBackupClient* restoreClient = NULL;
       
   712 		TRAP(err, restoreClient = CSqlBackupClient::NewL(TheTestHarness));
       
   713 		TEST(restoreClient != NULL);
       
   714 
       
   715 		TInt bytesRestored = 0;
       
   716 		TRAP(err, bytesRestored = TestRestoreL(*restoreClient, TheTestHarness->Fs(), dataChunks[i]));
       
   717 		TEST2(err, KErrNone);
       
   718 		
       
   719 		TEST(bytesRestored == bytesStored);
       
   720 
       
   721 		delete restoreClient;
       
   722 
       
   723 		CompareDbContentWithBuf(TheTestHarness->Fs());
       
   724 		}
       
   725 	}
       
   726 
       
   727 /**
       
   728 @SYMTestCaseID			PDS-SQL-UT-4144
       
   729 @SYMTestCaseDesc		SQL Backup&Restore - legacy backup file format header test.
       
   730 						The 64-bit file system related changes made in the SQL server required some 
       
   731 						changes to be made in the format of the backup file header.
       
   732 						The test checks that a backup file created with the previous format of the file header
       
   733 						can be restored without errors by the updated Backup&Restore implementation.
       
   734 @SYMTestActions			SQL Backup&Restore - legacy backup file format header test.
       
   735 @SYMTestExpectedResults Test must not fail
       
   736 @SYMTestPriority		Medium
       
   737 @SYMREQ					REQ12104
       
   738 */
       
   739 void LegacyFileFormatTest()
       
   740 	{
       
   741 	TheTest.Next(_L(" @SYMTestCaseID:PDS-SQL-UT-4144 Backup&Restore: legacy file format test"));
       
   742 
       
   743 	//KBackupFile2 is a database backup file with header version 0.
       
   744 	(void)TheTestHarness->Fs().Delete(KBackupFile2);
       
   745 	TInt rc = BaflUtils::CopyFile(TheTestHarness->Fs(), KBackupFile2Z, KBackupFile2);
       
   746 	TEST2(rc, KErrNone);
       
   747 	(void)TheTestHarness->Fs().SetAtt(KBackupFile2, 0, KEntryAttReadOnly);
       
   748 
       
   749 	//Restore the databases from KBackupFile2.
       
   750 	CSqlBackupClient* restoreClient = NULL;
       
   751 	TRAP(rc, restoreClient = CSqlBackupClient::NewL(TheTestHarness));
       
   752 	TEST(restoreClient != NULL);
       
   753 
       
   754 	RFile file;
       
   755 	rc = file.Open(TheTestHarness->Fs(), KBackupFile2, EFileRead | EFileShareExclusive);
       
   756 	TEST2(rc, KErrNone);
       
   757 	
       
   758 	TRAP(rc, restoreClient->InitialiseRestoreProxyBaseDataL(KClientUid, EDriveC));
       
   759 	TEST2(rc, KErrNone);
       
   760 	
       
   761 	TBuf8<KBufferSize> buf;
       
   762 	TPtr8 ptr((TUint8*)buf.Ptr(), buf.MaxSize());
       
   763 	TBool finishedFlag = EFalse;
       
   764 	
       
   765 	TInt fileSize = 0;
       
   766 	rc = file.Size(fileSize);
       
   767 	TEST2(rc, KErrNone);
       
   768 	
       
   769 	do
       
   770 		{
       
   771 		rc = file.Read(ptr);
       
   772 		TEST2(rc, KErrNone);
       
   773 		fileSize -= ptr.Size();
       
   774 		finishedFlag = fileSize == 0;
       
   775 		TRAP(rc, restoreClient->RestoreBaseDataSectionL(ptr, finishedFlag));
       
   776 		ptr.SetLength(0);
       
   777 		} 
       
   778 	while(fileSize > 0);
       
   779 	
       
   780 	file.Close();	
       
   781 	
       
   782 	restoreClient->RestoreComplete(EDriveC);
       
   783 	
       
   784 	TEST(finishedFlag);
       
   785 		
       
   786 	delete restoreClient;
       
   787 
       
   788 	//At this point we have two restored databases: KTestDbFileName1 and KTestDbFileName2.
       
   789 	//The content of the restored file cannot be compared directly, because t_sqlattach uses the same test databases
       
   790 	//and modifies them. The original database content was stored without executing t_sqlattach.
       
   791 	//Hence a simple test is made: open the restored database, check if the database content can be accessed.
       
   792 	
       
   793 	RSqlDatabase db;
       
   794 	rc = db.Open(KTestDbFileName1);
       
   795 	TEST2(rc, KErrNone);
       
   796 	//The database contains this table: "TABLE C(A1 INTEGER, B2 BLOB)". 
       
   797 	rc = db.Exec(_L("INSERT INTO C VALUES(100, 200)"));
       
   798 	TEST2(rc, 1);
       
   799 	RSqlStatement stmt;
       
   800 	rc = stmt.Prepare(db, _L("SELECT * FROM C"));
       
   801 	TEST2(rc, KErrNone);
       
   802 	while((rc = stmt.Next()) == KSqlAtRow)
       
   803 		{
       
   804 		}
       
   805 	stmt.Close();
       
   806 	TEST2(rc, KSqlAtEnd);
       
   807 	db.Close();
       
   808 
       
   809 	rc = db.Open(KTestDbFileName2);
       
   810 	TEST2(rc, KErrNone);
       
   811 	//The database contains this table: "TABLE A1(F1 INTEGER , F2 INTEGER, B1 BLOB)"
       
   812 	rc = db.Exec(_L("INSERT INTO A1 VALUES(100, 200, NULL)"));
       
   813 	TEST2(rc, 1);
       
   814 	rc = stmt.Prepare(db, _L("SELECT * FROM A1"));
       
   815 	TEST2(rc, KErrNone);
       
   816 	while((rc = stmt.Next()) == KSqlAtRow)
       
   817 		{
       
   818 		}
       
   819 	stmt.Close();
       
   820 	TEST2(rc, KSqlAtEnd);
       
   821 	db.Close();
       
   822 
       
   823 	(void)TheTestHarness->Fs().Delete(KBackupFile2);
       
   824 	}
       
   825 			
       
   826 void DoMain()
       
   827 	{
       
   828 	TestEnvCreate();
       
   829 
       
   830 	TheTest.Start(_L("Store db content to memory buffer"));
       
   831 	StoreDbContentToBuf(TheTestHarness->Fs());
       
   832 		
       
   833 	FunctionalTest();
       
   834 
       
   835 	OomTest();
       
   836 
       
   837 	FunctionalTest2();
       
   838 
       
   839 	LegacyFileFormatTest();
       
   840 
       
   841 	TestEnvDestroy();
       
   842 	}
       
   843 
       
   844 TInt E32Main()
       
   845 	{
       
   846 	TheTest.Title();
       
   847 	
       
   848 	CTrapCleanup* tc = CTrapCleanup::New();
       
   849 	TEST(tc != NULL);
       
   850 	
       
   851 	__UHEAP_MARK;
       
   852 	
       
   853 	DoMain();
       
   854 	
       
   855 	__UHEAP_MARKEND;
       
   856 	
       
   857 	TheTest.End();
       
   858 	TheTest.Close();
       
   859 	
       
   860 	delete tc;
       
   861 	
       
   862 	User::Heap().Check();
       
   863 	return KErrNone;
       
   864 	}