/**
@SYMTestCaseID          PDS-SQL-UT-4161
@SYMTestCaseDesc        SQL server startup file I/O error simulation test
@SYMTestPriority        High
@SYMTestActions         Runs the SQL server startup code in a file I/O error simulation loop.
@SYMTestExpectedResults Test must not fail
@SYMDEF                 DEF144096
*/  
void SqlServerStartupFileIoErrorTest()
    {
    RFs fs;
    TInt err = fs.Connect();
    TEST2(err, KErrNone);
    
    for(TInt fsError=KErrNotFound;fsError>=KErrBadName;--fsError)
        {
        TheTest.Printf(_L("===Simulated error: %d\r\nIteration: "), fsError);
        err = KErrNotFound;
        TInt cnt=0;
        while(err<KErrNone)
            {
            TheTest.Printf(_L("%d "), cnt);
            (void)fs.SetErrorCondition(fsError, cnt);
            TRAP(err, CreateAndDestroySqlServerL());
            (void)fs.SetErrorCondition(KErrNone);
            if(err != KErrNone)
                {
                ++cnt;
                }
            }
        TEST2(err, KErrNone);
        TheTest.Printf(_L("\r\n===File I/O error simulation test succeeded on iteration %d===\r\n"), cnt);
        }

    fs.Close();
    }
/**
@SYMTestCaseID			PDS-SQL-UT-4197
@SYMTestCaseDesc		RFileBuf64::Temp() file I/O error simulation test.
						The test calls RFileBuf64:Temp() in a file I/O error simulation loop.
@SYMTestActions			RFileBuf64::temp() file I/O error simulation test.
@SYMTestExpectedResults Test must not fail
@SYMTestPriority		High
@SYMDEF					DEF145198
*/
void TempFileIoErrTest()
	{
    TInt err = KErrGeneral;
    TInt cnt = 0;
    for(;err<KErrNone;++cnt)
        {
        TheTest.Printf(_L("===Iteration %d. Simulated error:\r\n"), cnt);       
        for (TInt fsError=KErrNotFound;fsError>=KErrBadName;--fsError)
            {
            TheTest.Printf(_L("%d "), fsError);
        	__UHEAP_MARK;
            (void)TheFs.SetErrorCondition(fsError, cnt);
        	RFileBuf64 fbuf(1024);//buffer capacity = 1024 bytes
        	TFileName tmpFileName;
			err = fbuf.Temp(TheFs, KTestDir, tmpFileName, EFileWrite | EFileRead);
            (void)TheFs.SetErrorCondition(KErrNone);
            fbuf.Close();
            __UHEAP_MARKEND;
			TInt err2 = TheFs.Delete(tmpFileName);
			TInt expectedErr = err == KErrNone ? KErrNone : KErrNotFound;
			TEST2(err2, expectedErr);
            }
        TheTest.Printf(_L("\r\n"));
        }
    TheTest.Printf(_L("\r\n===File I/O error simulation test succeeded on iteration %d===\r\n"), cnt);
	}
/**
@SYMTestCaseID			PDS-SQL-UT-4196
@SYMTestCaseDesc		RFileBuf64::Open() file I/O error simulation test.
						The test calls RFileBuf64:Open() in a file I/O error simulation loop.
@SYMTestActions			RFileBuf64::Open() file I/O error simulation test.
@SYMTestExpectedResults Test must not fail
@SYMTestPriority		High
@SYMDEF					DEF145198
*/
void OpenFileIoErrTest()
	{
	RFileBuf64 fbuf(1024);//buffer capacity = 1024 bytes
	TInt err = fbuf.Create(TheFs, KTestFile3, EFileRead | EFileWrite);
	fbuf.Close();
	TEST2(err, KErrNone);
    err = KErrGeneral;
    TInt cnt = 0;
    for(;err<KErrNone;++cnt)
        {
        TheTest.Printf(_L("===Iteration %d. Simulated error:\r\n"), cnt);       
        for (TInt fsError=KErrNotFound;fsError>=KErrBadName;--fsError)
            {
            TheTest.Printf(_L("%d "), fsError);
        	__UHEAP_MARK;
            (void)TheFs.SetErrorCondition(fsError, cnt);
        	err = fbuf.Open(TheFs, KTestFile3, EFileRead | EFileWrite);
            (void)TheFs.SetErrorCondition(KErrNone);
            fbuf.Close();
            __UHEAP_MARKEND;
            }
        TheTest.Printf(_L("\r\n"));
        }
    TheTest.Printf(_L("\r\n===File I/O error simulation test succeeded on iteration %d===\r\n"), cnt);
	(void)TheFs.Delete(KTestFile3);
	}
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);
	}
//sqlite3SymbianLibInit() - 'File I/O error simulation' test
void sqlite3SymbianLibInitFsErrTest()
	{
	sqlite3SymbianLibFinalize();
	
	TInt sysDrive = static_cast<TInt>(RFs::GetSystemDrive());
	TDriveUnit drvUnit(sysDrive);
	TDriveName drvName = drvUnit.Name();
	
	TFileName path;
	TInt err = TheFs.PrivatePath(path);
	TEST2(err, KErrNone);
	
	TParse privDataCage;
	err = privDataCage.Set(drvName, &path, 0);
	TEST2(err, KErrNone);
	
	err = KErrNotFound;
	TInt cnt = 1;
	for(;err<KErrNone;++cnt)
		{
		for (TInt fsError=KErrNotFound;fsError>=KErrDied;--fsError)
			{
			(void)TheFs.RmDir(privDataCage.FullName());
	
			TInt processHandleCnt = 0;
			TInt threadHandleCnt = 0;
			RThread().HandleCount(processHandleCnt, threadHandleCnt);
			TInt allocCellsCnt = User::CountAllocCells();
			
			(void)TheFs.SetErrorCondition(fsError, cnt);
			err = sqlite3SymbianLibInit();
			(void)TheFs.SetErrorCondition(KErrNone);
			
			if(err != KErrNone)
				{
				TInt processHandleCnt2 = 0;
				TInt threadHandleCnt2 = 0;
				RThread().HandleCount(processHandleCnt2, threadHandleCnt2);
				TEST2(processHandleCnt2, processHandleCnt);
				TEST2(threadHandleCnt2, threadHandleCnt);
				TInt allocCellsCnt2 = User::CountAllocCells();
				TEST2(allocCellsCnt2, allocCellsCnt);
				}
			else
				{
				sqlite3SymbianLibFinalize();
				}
			}
		}
	sqlite3SymbianLibFinalize();
	TheTest.Printf(_L("=== sqlite3SymbianLibInit() 'File I/O error simulation' test succeeded at iteration %d\r\n"), cnt);
	}
void CTestContactsPBAPExport::ExportContactsL()
	{
	TInt err = KErrNone;
	// Retrieve the file name to which contact item is to be exported
   	RFs fsSession;
	RFileWriteStream writeStream;

	// connect to file system
	User::LeaveIfError(fsSession.Connect());
	CleanupClosePushL(fsSession);

	GetInputFromIni();

   	// Makes one or more directories.
   	fsSession.MkDirAll(iExportTo);

	// Replaces a single file with another
	User::LeaveIfError(writeStream.Replace(fsSession, iExportTo, EFileWrite));

	INFO_PRINTF1(_L("Exporting Contact....."));

	// Existing database
   	TPtrC databaseFile(_L("C:contactDb.cdb"));

	CContactDatabase* dBase = NULL;
	CContactIdArray* idArray = NULL;

	// Open the existing database
	dBase = CContactDatabase::OpenL(databaseFile);
	CleanupStack::PushL(dBase);

	// Create Utility class object, to export the contact from database
	CTestStep* self = static_cast<CTestStep*>(this);
	iExportObj = new(ELeave) CContactsPBAPExportUtilityClass(self);

	SetFilterL();

	CCntFilter* exportFilter = CCntFilter::NewL();
	CleanupStack::PushL(exportFilter);

	// Get all the contacts from the database to export
	exportFilter->SetContactFilterTypeCard(ETrue);
	dBase->FilterDatabaseL(*exportFilter);
	idArray = exportFilter->iIds;
	CleanupStack::PushL(idArray);

	if(iDamageDb)
		{
		#ifdef _DEBUG
		#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__
		TRAPD(err1,dBase->DamageDatabaseL(0x666));
		if(err1 == KErrNone)
			{
			TRAPD(err,iExportObj->ExportvCardL(dBase, iStandard, idArray, writeStream, iContactFilter));
			INFO_PRINTF2(_L("Err:%d"),err);
			if(err == KErrNotReady)
				{
				SetTestStepResult(EPass);
				}
			else
				{
				SetTestStepResult(EFail);
				}
			if(dBase->IsDamaged())
				{
				dBase->RecoverL();
				}
			}
		else
			{
			INFO_PRINTF2(_L("Could not damage database Err:"),err1);
			}
		#else
			SetTestStepResult(EPass);
		#endif
		#endif
		}
    else
	    {
	    if(iInvalidFileSystem)
		    {
		    #ifdef _DEBUG
		    fsSession.SetErrorCondition(KErrNotReady);
		    TRAPD(err,iExportObj->ExportvCardL(dBase, iStandard, idArray, writeStream, iContactFilter));
			if(err == KErrNotReady)
				{
				SetTestStepResult(EPass);
				}
			else
				{
				SetTestStepResult(EFail);
				}
			fsSession.SetErrorCondition(KErrNone);
			#endif
			}
	    else
			{
			if(!iSetOOM)
				{
				if(idArray->Count() > 0)
					{
					for(TInt i=0; i<idArray->Count() ; i++)
						{
						TInt dCount = dBase->CountL();
						if(i>=dCount)
							{
							break;
							}

						// temporary array used to export one contact at a time
						CContactIdArray* tempIdArray = CContactIdArray::NewL();
						CleanupStack::PushL(tempIdArray);
						tempIdArray->AddL((*idArray)[i]);
						TRAPD(err,iExportObj->ExportvCardL(dBase, iStandard, tempIdArray, writeStream, iContactFilter));

						if(err != KErrNone )
							{
							if(err != KErrNotFound)
								{
								SetTestStepError(err);
								}
							}

						CleanupStack::PopAndDestroy(tempIdArray);
						}
					}
				else
					{
					if(idArray->Count()==0)
						{
						TRAPD(err,iExportObj->ExportvCardL(dBase, iStandard, idArray, writeStream, iContactFilter));
						if(err != KErrNone)
							{
							SetTestStepError(err);
							}
						}
					}

				}
			else
				{
				TInt tryCount = 1;
				for ( ;; )
					{
					__UHEAP_SETFAIL(RHeap::EDeterministic, tryCount);
					TRAP(err, iExportObj->ExportvCardL(dBase, iStandard, idArray, writeStream, iContactFilter));

					if ( err == KErrNone )
						{
						__UHEAP_RESET;
						INFO_PRINTF1(_L("OOM testing of CContactDatabase::ExportSelectedContactsL Api is done"));
						break;
						}
					if ( err != KErrNoMemory )
						{
						INFO_PRINTF2(_L("The unexpected error code is:%d"),err);
						SetTestStepResult(EFail);
						break;
						}
					__UHEAP_SETFAIL(RHeap::ENone, 0);
					tryCount++;
					}
				}
			}
	    }

	CleanupStack::Pop(idArray);
	CleanupStack::PopAndDestroy(exportFilter);

	INFO_PRINTF1(_L("Exported Contact"));
	writeStream.CommitL();
	writeStream.Close();

	INFO_PRINTF2(_L("Total number of contacts in database %d "), dBase->CountL());

	// Cleanup
	CleanupStack::PopAndDestroy(dBase);
    CleanupStack::PopAndDestroy(&fsSession);
	}