diff -r d4f567ce2e7c -r 5b6f26637ad3 phonebookengines_old/contactsmodel/tsrc/T_FERROR.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/tsrc/T_FERROR.CPP Tue Aug 31 15:05:21 2010 +0300 @@ -0,0 +1,541 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include "T_UTILS.H" + +// Type definitions +CCntTest* CntTest=NULL; +LOCAL_D RTest test(_L("T_FERROR")); +LOCAL_D RFile logFile; +LOCAL_D RFile threadLogFile; + +const TPtrC KDatabaseFileName=_L("C:T_FERROR"); +const TPtrC KDatabaseRemoveableFileName=_L("D:T_FERROR2"); + +const TPtrC KLogFileName=_L("C:\\T_FERROR.LOG"); +const TPtrC KThreadLogFileName=_L("C:\\T_FERROR2.LOG"); +const TInt KNumTestContacts=5; + +class CFred2 : public CBase + { +public: + ~CFred2(); + void ConstructL(); + void WaitForLogon(); + void Kill(); + void DoDamageL(); +protected: + RThread iThread; + TRequestStatus iLogonStatus; + }; + +class CContactReadWriter : public CIdle, public MContactDbObserver + { +public: + static CContactReadWriter *NewLC(); + static TInt CallbackL(TAny *xThis); +private: + TInt DoWorkL(); + CContactReadWriter(); + ~CContactReadWriter(); + void SetNameL(CContactItem& aItem,TUid aVcardType,const TDesC& aName); + TPtrC Name(CContactItem& aItem); + TBool AddNewContactsL(); + TBool EditContactsL(); + TBool DeleteContactsL(); + void PrintRecovering() const; + void PrintErr(TInt aErr) const; +public: // from MContactDbObserver + void HandleDatabaseEventL(TContactDbObserverEvent aEvent); +private: + TBool iSuspendWork; + TInt iSubState; + TInt iState; + CContactDatabase* iDb; + CArrayFix* iIdList; + CContactChangeNotifier *iNotify; + }; + +LOCAL_C void doWriteToLogL(RFile &aFile, const TDesC &aLog, TInt aParam, TInt aParam2) + { + TBuf<128> buf; + TTime time; + time.UniversalTime(); + time.FormatL(buf,_L("%T:%S.%*C3-")); + TFileText textFile; + textFile.Set(aFile); + User::LeaveIfError(textFile.Write(buf)); + buf.Format(aLog,aParam,aParam2); + User::LeaveIfError(textFile.Write(buf)); + aFile.Flush(); + } + +LOCAL_C void WriteToLogL(const TDesC &aLog, TInt aParam=0, TInt aParam2=0) + { + doWriteToLogL(logFile,aLog,aParam,aParam2); + } + +LOCAL_C void WriteToThreadLogL(const TDesC &aLog, TInt aParam=0, TInt aParam2=0) + { + doWriteToLogL(threadLogFile,aLog,aParam,aParam2); + } + +// +// CContactReadWriter +// + +void CContactReadWriter::HandleDatabaseEventL(TContactDbObserverEvent aEvent) + { + if (aEvent.iType==EContactDbObserverEventTablesClosed) + iSuspendWork=ETrue; + else if (aEvent.iType==EContactDbObserverEventTablesOpened) + iSuspendWork=EFalse; + else if (aEvent.iType==EContactDbObserverEventRollback) + { + PrintRecovering(); + TRAP_IGNORE(iDb->RecoverL()); + } + WriteToLogL(_L("Event(%d,%d)"),aEvent.iType,aEvent.iContactId); + } + +void CContactReadWriter::SetNameL(CContactItem& aItem,TUid aVcardType,const TDesC& aName) +// +// Set the contents of a text field, creating the field if required +// + { + CContactItemFieldSet& fieldSet=aItem.CardFields(); + const TInt pos=fieldSet.Find(KUidContactFieldFamilyName); + if (pos!=KErrNotFound) + fieldSet[pos].TextStorage()->SetTextL(aName); + else + { + CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,KUidContactFieldFamilyName); + field->SetMapping(aVcardType); + field->TextStorage()->SetTextL(aName); + aItem.AddFieldL(*field); + CleanupStack::Pop(); // item + } + } + +TPtrC CContactReadWriter::Name(CContactItem& aItem) + { + CContactItemFieldSet& fieldSet=aItem.CardFields(); + const TInt pos=fieldSet.Find(KUidContactFieldFamilyName); + if (pos==KErrNotFound) + return _L(""); + return fieldSet[pos].TextStorage()->Text(); + } + +TBool CContactReadWriter::AddNewContactsL() + { + CContactCard* card=CContactCard::NewL(); + CleanupStack::PushL(card); + TBuf<16> name; + name.Format(_L("NAME #%d"),iSubState); + SetNameL(*card,KUidContactFieldVCardMapUnusedN,name); + CContactItemField* field=CContactItemField::NewLC(KStorageTypeText); + card->AddFieldL(*field); + CleanupStack::Pop(); // field + iIdList->AppendL(iDb->AddNewContactL(*card)); + CleanupStack::PopAndDestroy(); // card + iSubState++; + return(iSubState==KNumTestContacts); + } + +TBool CContactReadWriter::EditContactsL() +// +// Check then edit contact names +// + { + if (iSubStateOpenContactLX(index); + CleanupStack::PushL(item); + TBuf<16> name; + name.Format(_L("NAME #%d"),iSubState); + test(name==Name(*item)); + name.Format(_L("NEW NAME #%d"),index); + SetNameL(*item,KUidContactFieldVCardMapUnusedN,name); + iDb->CommitContactL(*item); + CleanupStack::PopAndDestroy(); // item; + CleanupStack::Pop(); // Close from OpenContactLX + } + else if (iSubState<(2*KNumTestContacts)) + { + const TInt index=(*iIdList)[iSubState-KNumTestContacts]; + CContactItem* item=iDb->ReadContactL(index); + TBuf<16> name; + name.Format(_L("NEW NAME #%d"),index); + test(name==Name(*item)); + delete item; + } + return(++iSubState==2*KNumTestContacts); + } + +TBool CContactReadWriter::DeleteContactsL() +// +// Delete all contacts +// + { + if (iDb->CountL()==0) + return(ETrue); + iDb->DeleteContactL((*iDb->SortedItemsL())[0]); + return(EFalse); + } + +// + +CContactReadWriter::CContactReadWriter() : CIdle(CActive::EPriorityIdle) + { + } + +CContactReadWriter *CContactReadWriter::NewLC() + { + CContactReadWriter *rw=new(ELeave) CContactReadWriter(); + CleanupStack::PushL(rw); + CActiveScheduler::Add(rw); + rw->Start(TCallBack(CContactReadWriter::CallbackL,rw)); + return(rw); + } + +CContactReadWriter::~CContactReadWriter() + { + delete iNotify; + delete iIdList; + delete iDb; + } + +TInt CContactReadWriter::DoWorkL() + { + if (iSuspendWork) + { + WriteToLogL(_L("Suspended")); + User::After(100000); + return(ETrue); + } + WriteToLogL(_L("DoWork(%d,%d)"),iState,iSubState); + TBool moveToNextState=ETrue; + switch(iState) + { + case 0: + test(iDb==NULL); + User::After(200000); // Increase the chance of a damage hit here + iDb=CContactDatabase::OpenL(KDatabaseFileName); + while(iDb->IsDamaged()) + { + WriteToLogL(_L("Recovering")); + TRAP_IGNORE(iDb->RecoverL()); + } + iNotify=CContactChangeNotifier::NewL(*iDb,this); + iIdList=new(ELeave) CArrayFixFlat(5); + break; + case 1: + moveToNextState=AddNewContactsL(); + break; + case 2: + moveToNextState=EditContactsL(); + break; + case 3: + moveToNextState=DeleteContactsL(); + break; + case 4: + CActiveScheduler::Stop(); + return(EFalse); + } + if (moveToNextState) + { + iState++; + iSubState=0; + } + return(ETrue); + } + +void CContactReadWriter::PrintRecovering() const + { + test.Printf(_L("Recovering:")); + } + +void CContactReadWriter::PrintErr(TInt aErr) const + { + TBuf<64> errText; + errText.Format(_L("Err %d:"),aErr); + test.Printf(errText); + } + +TInt CContactReadWriter::CallbackL(TAny *aThis) + { + CContactReadWriter *xthis=(CContactReadWriter *)aThis; + TInt ret=ETrue; + TRAPD(err,ret=xthis->DoWorkL()); + if (err!=KErrNone) + { + xthis->PrintErr(err); +/* if (xthis->iDb) + { + TRAP_IGNORE(xthis->iDb->RecoverL()); + }*/ + } + return(ret); + } + +// + +LOCAL_C void CreateDatabaseL() +// +// Create a database in a store +// + { + CntTest->CreateDatabaseL(); + CntTest->DeleteAllTemplateFieldsL(); + CntTest->CloseDatabase(); + } + +void TestLoop(TInt aNumLoops) + { + CFred2 *fred2=new(ELeave) CFred2; + CleanupStack::PushL(fred2); + fred2->ConstructL(); + for(TInt loop=0;loopRecoverL()); + test.Printf(_L("Recover error %d"),addErr); + TRAP(addErr,remDb->OpenTablesL()); + test.Printf(_L("Open tables error %d\n"),addErr); + test.Printf(_L("Press a key to try again\n")); + test.Getch(); + } + if (addErr==KErrNone) + { + TRAP(addErr,AddContactL(remDb,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("x"))); + } + } while(addErr!=KErrNone); + CleanupStack::PopAndDestroy(); // remDb + } + } + } + +/** + +@SYMTestCaseID PIM-T-FERROR-0001 + +*/ + +void DoTestsL() + { + test.Start(_L("@SYMTESTCaseID:PIM-T-FERROR-0001 Remove pack test")); + + RemovePackTestL(); + + test.Next(_L("File error tests")); + + User::LeaveIfError(logFile.Replace(CntTest->Fs(),KLogFileName,EFileStreamText|EFileWrite)); + CleanupClosePushL(logFile); +// + test.Next(_L("Create new database")); + + WriteToLogL(_L("Starting Logging")); + TRAPD(ret,CreateDatabaseL()); + test(ret==KErrNone); + test.Next(_L("Starting fail loop")); + + TestLoop(50); + test.Next(_L("Delete database")); + + TInt retDel=KErrNone; + do + { + TRAP(retDel,CntTest->DeleteDatabaseL()); + if (retDel==KErrInUse) + { + User::After(200000); + } + else + { + test(retDel==KErrNone); + } + } while(retDel!=KErrNone); + WriteToLogL(_L("Close log")); + CleanupStack::PopAndDestroy(); // logfile + } + +GLDEF_C TInt E32Main() + { + CntTest=new(ELeave) CCntTest; + CntTest->ConstructL(test,KDatabaseFileName); + TRAPD(err,DoTestsL()); + CntTest->EndTestLib(err); + return KErrNone; + } + +// +// CFred2 +// + +LOCAL_C TInt FredIIFunc(TAny *aParam); + +CFred2::~CFred2() + { + Kill(); + iThread.Close(); + } + +void CFred2::ConstructL() + { + User::LeaveIfError(iThread.Create(_L("FredII"),FredIIFunc,KDefaultStackSize,0x2000,0x20000,this,EOwnerThread)); + iThread.Logon(iLogonStatus); + iThread.Resume(); + } + +void CFred2::Kill() + { + iThread.Kill(0); + } + +void CFred2::WaitForLogon() + { + User::WaitForRequest(iLogonStatus); + test(iLogonStatus.Int()==KErrNone); + } + +// +// Fred II from here on +// + +LOCAL_C TInt FredIIFunc(TAny *aParam) + { + CActiveScheduler::Install(new(ELeave) CActiveScheduler); + CTrapCleanup* cleanup=CTrapCleanup::New(); + TRAPD(err,((CFred2 *)aParam)->DoDamageL()); + test(EFalse); + delete cleanup; + delete CActiveScheduler::Current(); + return(err); + } + +#if defined(__WINS__) + const TInt KMaxDamageWait=500000; // up to a half a second +#else +# if defined(_UNICODE) + const TInt KMaxDamageWait=1500000; // up to a one second +# else + const TInt KMaxDamageWait=1000000; // up to one and a half a second +# endif +#endif + +void CFred2::DoDamageL() + { + RFs fs; + test(fs.Connect()==KErrNone); + CleanupClosePushL(fs); + User::LeaveIfError(threadLogFile.Replace(fs,KThreadLogFileName,EFileStreamText|EFileWrite)); + CleanupClosePushL(threadLogFile); + WriteToThreadLogL(_L("test1")); +// + WriteToThreadLogL(_L("test2")); + CContactDatabase* db=CContactDatabase::OpenL(KDatabaseFileName); + WriteToThreadLogL(_L("test3")); + CleanupStack::PushL(db); + TBool doRecover=EFalse; + TInt64 seed=0; + User::After(1000000); + TInt damageCount=0; + TInt error1=KErrNone; + TInt error2=KErrNone; + WriteToThreadLogL(_L("test4")); + FOREVER + { + TInt after=(Math::Rand(seed)%KMaxDamageWait); + User::After(after); + WriteToThreadLogL(_L("Doing damage")); + TRAP(error1,db->DamageDatabaseL(0x666)); + damageCount++; + FOREVER + { + if (doRecover) + { + WriteToThreadLogL(_L("Start Recover")); + TRAP(error2,db->RecoverL()); + WriteToThreadLogL(_L("Finished Recover")); + } + else + { + WriteToThreadLogL(_L("Close tables")); + db->CloseTables(); + TRAP(error2,db->OpenTablesL()); + WriteToThreadLogL(_L("Open tables %d"),error2); + } + if (error2==KErrNone) + break; + User::After(100000); + } + doRecover=!doRecover; + } +//unreachable at the mo' CleanupStack::PopAndDestroy(3); // db, log file, fs + }