persistentstorage/sql/TEST/t_sqloslayer.cpp
changeset 31 ba1c4f4a893f
parent 15 3eacc0623088
child 40 b8bdbc8f59c7
--- a/persistentstorage/sql/TEST/t_sqloslayer.cpp	Thu Jul 01 17:02:22 2010 +0100
+++ b/persistentstorage/sql/TEST/t_sqloslayer.cpp	Tue Jul 06 11:54:49 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 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"
@@ -27,6 +27,7 @@
 #ifdef __cplusplus
 }  /* End of the 'extern "C"' block */
 #endif
+#include "SqliteUtil.h"
 
 ///////////////////////////////////////////////////////////////////////////////////////
 
@@ -52,6 +53,9 @@
 TInt TheSqlSrvProfilerFileSetSize = 0;
 #endif
 
+//SQLite panic category.
+_LIT(KSqlitePanicCategory, "Sqlite");
+
 ///////////////////////////////////////////////////////////////////////////////////////
 
 void DeleteTestFiles()
@@ -623,16 +627,24 @@
 	User::Free(osFile);
 	}
 
+TInt DoDeleteTempFiles()
+	{
+    CFileMan* fm = NULL;
+    TRAPD(err, fm = CFileMan::NewL(TheFs));
+    TEST2(err, KErrNone);
+    TFileName path;
+    path.Copy(KPrivateDir);
+    path.Append(_L("temp\\"));
+    path.Append(_L("*.$$$"));
+    err = fm->Delete(path);
+    delete fm;
+    return err;
+	}
+
 void VfsOpenTempFileOomTest()
     {
     //Delete all temp files in this test private data cage.
-    CFileMan* fm = NULL;
-    TRAPD(err, fm = CFileMan::NewL(TheFs));
-    TEST2(err, KErrNone);
-    TBuf<50> path;
-    path.Copy(KPrivateDir);
-    path.Append(_L("*.$$$"));
-    err = fm->Delete(path);
+	TInt err = DoDeleteTempFiles();
     TEST(err == KErrNone || err == KErrNotFound);
     
     sqlite3_vfs* vfs = sqlite3_vfs_find(NULL);
@@ -653,7 +665,9 @@
         err = sqlite3OsOpen(vfs, NULL, osFile, SQLITE_OPEN_READWRITE, &outFlags);
         if(err == SQLITE_OK)
             {
-            err = sqlite3OsClose(osFile);
+			//Since this is a temp file, its creation will be delayed till the first file write operation.
+			err = sqlite3OsWrite(osFile, "1234", 4, 0);
+			(void)sqlite3OsClose(osFile);
             }
         OomPostStep();
         if(err != SQLITE_OK)
@@ -662,16 +676,68 @@
             }
         //If the iteration has failed, then no temp file should exist in the test private data cage.
         //If the iteration has succeeded, then sqlite3OsClose() should have deleted the temp file.
-        TInt err2 = fm->Delete(path);
+        TInt err2 = DoDeleteTempFiles();
         TEST2(err2, KErrNotFound);
         }
     TEST2(err, SQLITE_OK);
     TheTest.Printf(_L("\r\n=== TVfs::Open(<temp file>) OOM test succeeded at allcoation %d\r\n"), failingAllocNum);
     
     User::Free(osFile);
-    delete fm;
     }
 
+void VfsOpenTempFileFileIoErrTest()
+	{
+    //Delete all temp files in this test private data cage.
+	TInt err = DoDeleteTempFiles();
+    TEST(err == KErrNone || err == KErrNotFound);
+    
+    sqlite3_vfs* vfs = sqlite3_vfs_find(NULL);
+    TEST(vfs != NULL);
+
+    sqlite3_file* osFile = (sqlite3_file*)User::Alloc(vfs->szOsFile);
+    TEST(osFile != NULL);
+    
+	err = SQLITE_ERROR;
+	TInt cnt = 1;
+	while(err != SQLITE_OK)
+		{
+		TInt processHandleCnt = 0;
+		TInt threadHandleCnt = 0;
+		RThread().HandleCount(processHandleCnt, threadHandleCnt);
+		TInt allocCellsCnt = User::CountAllocCells();
+
+        TheTest.Printf(_L("%d "), cnt);
+		(void)TheFs.SetErrorCondition(KErrGeneral, cnt);
+        int outFlags = 0;
+        err = sqlite3OsOpen(vfs, NULL, osFile, SQLITE_OPEN_READWRITE, &outFlags);
+        if(err == SQLITE_OK)
+            {
+			//Since this is a temp file, its creation will be delayed till the first file write operation.
+			err = sqlite3OsWrite(osFile, "1234", 4, 0);
+			(void)sqlite3OsClose(osFile);
+            }
+		(void)TheFs.SetErrorCondition(KErrNone);
+		if(err != SQLITE_OK)
+			{
+			TInt processHandleCnt2 = 0;
+			TInt threadHandleCnt2 = 0;
+			RThread().HandleCount(processHandleCnt2, threadHandleCnt2);
+			TEST2(processHandleCnt2, processHandleCnt);
+			TEST2(threadHandleCnt2, threadHandleCnt);
+			TInt allocCellsCnt2 = User::CountAllocCells();
+			TEST2(allocCellsCnt2, allocCellsCnt);
+	        ++cnt;
+			}
+        //If the iteration has failed, then no temp file should exist in the test private data cage.
+        //If the iteration has succeeded, then sqlite3OsClose() should have deleted the temp file.
+        TInt err2 = DoDeleteTempFiles();
+        TEST2(err2, KErrNotFound);
+		}
+    TEST2(err, SQLITE_OK);
+    TheTest.Printf(_L("\r\n=== TVfs::Open(<temp file>) file I/O error simulation test succeeded at iteration %d\r\n"), cnt);
+    User::Free(osFile);
+	}
+
 void VfsCreateDeleteOnCloseFileOomTest()
     {
     sqlite3_vfs* vfs = sqlite3_vfs_find(NULL);
@@ -711,6 +777,71 @@
     User::Free(osFile);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////
+
+//Panic thread function. 
+//It will cast aData parameter to a TFunctor pointer and call it.
+//The expectation is that the called function will panic and kill the panic thread.
+TInt ThreadFunc(void* aData)
+	{
+	CTrapCleanup* tc = CTrapCleanup::New();
+	TEST(tc != NULL);
+	
+	User::SetJustInTime(EFalse);	// disable debugger panic handling
+	
+	TFunctor* obj = reinterpret_cast<TFunctor*> (aData);
+	TEST(obj != NULL);
+	(*obj)();//call the panic function
+	
+	delete tc;
+	
+	return KErrNone;		
+	}
+
+//Panic test.
+//PanicTest function will create a new thread - panic thread, giving it a pointer to the function which has to
+//be executed and the expectation is that the function will panic and kill the panic thread.
+//PanicTest function will check the panic thread exit code, exit category and the panic code.
+void PanicTest(TFunctor& aFunctor, TExitType aExpectedExitType, const TDesC& aExpectedCategory, TInt aExpectedPanicCode)
+	{
+	RThread thread;
+	_LIT(KThreadName,"OsLayerPanicThread");
+	TEST2(thread.Create(KThreadName, &ThreadFunc, 0x2000, 0x1000, 0x10000, (void*)&aFunctor, EOwnerThread), KErrNone);
+	
+	TRequestStatus status;
+	thread.Logon(status);
+	TEST2(status.Int(), KRequestPending);
+	thread.Resume();
+	User::WaitForRequest(status);
+	User::SetJustInTime(ETrue);	// enable debugger panic handling
+
+	TEST2(thread.ExitType(), aExpectedExitType);
+	TEST(thread.ExitCategory() == aExpectedCategory);
+	TEST2(thread.ExitReason(), aExpectedPanicCode);
+	
+	CLOSE_AND_WAIT(thread);
+	}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////     Panic test functions    /////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef _DEBUG    
+
+//Panic when calling COsLayerData::Create() is called and the OS layer data has been already created.
+class TOsLayerDataDuplicated : public TFunctor
+	{
+private:		
+	virtual void operator()()
+		{
+		(void)sqlite3SymbianLibInit();//This should crash the thread in debug mode (because the Os layer
+		                              //data was created already in TestEnvInit()).
+		}
+	};
+static TOsLayerDataDuplicated TheOsLayerDataDuplicated;
+
+#endif //_DEBUG
+
 /**
 @SYMTestCaseID			SYSLIB-SQL-CT-1650
 @SYMTestCaseDesc		SQL, OS porting layer tests.
@@ -740,8 +871,14 @@
 	NegativeTest();
     TheTest.Printf(_L("TVfs::Open(<temp file>) OOM test\r\n"));
     VfsOpenTempFileOomTest();
+    TheTest.Printf(_L("TVfs::Open(<temp file>) file I/O error simulation test\r\n"));
+    VfsOpenTempFileFileIoErrTest();
     TheTest.Printf(_L("TVfs::Open(<'delete on close' file>) OOM test\r\n"));
     VfsCreateDeleteOnCloseFileOomTest();
+#ifdef _DEBUG    
+	TheTest.Printf(_L("'An attempt to create the OS layer data again' panic\r\n"));
+	PanicTest(TheOsLayerDataDuplicated, EExitPanic, KSqlitePanicCategory, ESqliteOsPanicOsLayerDataExists);
+#endif //_DEBUG	
 	}
 
 TInt E32Main()