diff -r 000000000000 -r 08ec8eefde2f persistentstorage/store/TFILE/t_storfserr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/store/TFILE/t_storfserr.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,436 @@ +// Copyright (c) 1998-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 + +LOCAL_D RTest test(_L("t_storfserr")); + +#ifdef _DEBUG + +LOCAL_D CTrapCleanup* TheTrapCleanup = NULL; +LOCAL_D RFs TheFs; + +const TInt KTestCleanupStack=0x20; +const TPtrC KTestDir=_L("\\STOR-TST\\T_FSERR\\"); +const TPtrC FileNameA=_L("A.DAT"); +const TPtrC FileNameB=_L("B.DAT"); + +const TPtrC des2(_S("22"),2); +const TPtrC des3(_S("333"),3); +const TPtrC des4(_S("4444"),4); +const TPtrC des5(_S("55555"),5); +LOCAL_D CFileStore* store = NULL; +RStoreWriteStream out; +RStoreReadStream in; + +LOCAL_C void setupCleanup() + {// Initialise the cleanup stack + TheTrapCleanup=CTrapCleanup::New(); + test(TheTrapCleanup!=NULL); + TRAPD(r,\ + {\ + for (TInt i=KTestCleanupStack;i>0;i--)\ + CleanupStack::PushL((TAny*)0);\ + CleanupStack::Pop(KTestCleanupStack);\ + }); + test(r==KErrNone); + } + +LOCAL_C void setupTestDirectory() + {// Prepare the test directory. + TInt r=TheFs.MkDirAll(KTestDir); + test(r==KErrNone||r==KErrAlreadyExists); + r=TheFs.SetSessionPath(KTestDir); + test(r==KErrNone); + } + +LOCAL_D void AlterStoreL(TInt aFail) + { + RStoreWriteStream out2; + RStoreWriteStream out3; + RStoreWriteStream out4; + RStoreReadStream in; + TheFs.SetErrorCondition(KErrNotReady,aFail); + TStreamId id0 = out.CreateLC(*store); + out << _L("012345678901234567890123456789012345678901234567890123456789"); + out.CommitL(); + CleanupStack::PopAndDestroy(); + + TStreamId id2 = out.CreateLC(*store); + out.CommitL(); + CleanupStack::PopAndDestroy(); + + TStreamId id3 = out.CreateLC(*store); + out.CommitL(); + CleanupStack::PopAndDestroy(); + + TStreamId id4 = out.CreateLC(*store); + out << _L("mum"); + out.CommitL(); + CleanupStack::PopAndDestroy(); + + out.ReplaceLC(*store,store->Root()); + out << id2; + out << id3; + out << id4; + out << KNullStreamId; + out << KNullStreamId; + out.CommitL(); + CleanupStack::PopAndDestroy(); + + in.OpenLC(*store,store->Root());// use the root for in and out streams + out.ReplaceLC(*store,store->Root()); + out.WriteL(in); + out.CommitL(); + CleanupStack::PopAndDestroy(2); + + out.ReplaceLC(*store,store->Root());// swap the order + in.OpenLC(*store,store->Root()); + out.WriteL(in); + out << KNullStreamId; + out.CommitL(); + CleanupStack::PopAndDestroy(2); + + store->CommitL(); + + in.OpenLC(*store,store->Root()); + TStreamId idX,idZ; + in >> idX; + in >> idX; + in >> idZ;// id4 "mum" + CleanupStack::PopAndDestroy(); + out.OpenLC(*store,idZ); + in.OpenLC(*store,idZ); + out2.OpenLC(*store,idZ); + out3.OpenLC(*store,idZ); + out4.OpenLC(*store,idZ); + out4.WriteL(in); + out.CommitL(); + CleanupStack::PopAndDestroy(5); + + store->CompactL(); + store->CommitL(); + + store->DeleteL(id0); + store->CommitL(); + + store->CompactL(); + store->CommitL(); + } + +enum TFileQoS + { + ESimple = 0,//File, "write byte" is an atomic operation + EBlockAtomic = 1,//File, "block write" is an atomic operation + ETransactional = 2,//Transactional file system. + ELastQoSType + }; + +const TInt KFailPoints[ELastQoSType][2] = + { + // non-transactional file system + { + 5, 54 + }, + // atomic "block write" + { + 3, 38 + }, + // transactional file system + { + 3, 38 + } + }; + +//The function returns true, if the file system guarantees atomic "block write" operations on aDriveNo. +TBool IsBlockAtomic(TInt aDriveNo) + { + __ASSERT_DEBUG(aDriveNo >= EDriveA && aDriveNo <= EDriveZ, User::Invariant()); + + TVolumeIOParamInfo volInfo; + TInt err = TheFs.VolumeIOParam(aDriveNo, volInfo); + //If VolumeIOParam() succeeds, the media block size is >= 512 bytes and the media block size is power of two - report + //that the media supports atomic "block write" operations. + const TInt KDefaultMediaBlockSize = 512; + return err == KErrNone && volInfo.iBlockSize >= KDefaultMediaBlockSize && (volInfo.iBlockSize & (volInfo.iBlockSize - 1)) == 0; + } + +TFileQoS MediaType(const TDesC& aFilename) + { + TParse p; + TheFs.Parse(aFilename, p); + TDriveInfo dinfo; + TheFs.Drive(dinfo, TDriveUnit(p.Drive())); + TBool transactional = dinfo.iDriveAtt & KDriveAttTransaction; + if(transactional) + { + return ETransactional; + } + if(IsBlockAtomic(TDriveUnit(p.Drive()))) + { + return EBlockAtomic; + } + return ESimple; + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1160 +@SYMTestCaseDesc File server test +@SYMTestPriority High +@SYMTestActions Tests for failure on call to file server +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_D void FailOnEveryFileServerCallL() + { + TheFs.Delete(FileNameA); + + const TFileQoS KMediaType = MediaType(FileNameA); + _LIT(KSimpleText, "Simple"); + _LIT(KAtomicText, "Atomic block \"write\""); + _LIT(KTransactionalText, "Transactional"); + const TPtrC mediaType[ELastQoSType] = {KSimpleText(), KAtomicText(), KTransactionalText()}; + test.Printf(_L("Media type: %S\r\n"), &mediaType[KMediaType]); + + const TInt KStoreCommitted = KFailPoints[KMediaType][0]; + const TInt KLastFail = KFailPoints[KMediaType][1]; + + const TInt KError = KErrNotReady; + const TInt KRootIdSizeBeforeStoreCommit = 0; + const TInt KRootIdSizeAfterStoreCommit = 6*sizeof(TStreamId); + + for (TInt fail=1;fail<=KLastFail+5;++fail) + { + store=CPermanentFileStore::ReplaceLC(TheFs,FileNameA,EFileWrite|EFileRead); + store->SetTypeL(KPermanentFileStoreLayoutUid); + TStreamId rootId = store->ExtendL(); + store->SetRootL(rootId); + store->CommitL(); + TRAPD(r,AlterStoreL(fail)); + TheFs.SetErrorCondition(KErrNone); + if (failRevertL()); + if (r==KErrNotReady) + { + CleanupStack::PopAndDestroy(); + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileWrite|EFileRead); + } + else + test(r==KErrNone); + CleanupStack::PopAndDestroy(); +// + // open read only + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileRead); + RStoreReadStream in; + in.OpenLC(*store,store->Root()); + TInt size=in.Source()->SizeL(); + if (fail=KStoreCommitted + test(size==KRootIdSizeAfterStoreCommit); + CleanupStack::PopAndDestroy(2); +// + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileRead|EFileWrite); + store->ExtendL(); + store->RevertL(); + in.OpenLC(*store,store->Root()); + size=in.Source()->SizeL(); + if (fail=KStoreCommitted + test(size==KRootIdSizeAfterStoreCommit); + CleanupStack::PopAndDestroy(2); + } + } + +LOCAL_D void InitialseStoreWithDataL() + { + TheFs.Delete(FileNameB); + store=CPermanentFileStore::CreateLC(TheFs,FileNameB,EFileWrite|EFileRead); + store->SetTypeL(KPermanentFileStoreLayoutUid); + TStreamId rootId = store->ExtendL(); + store->SetRootL(rootId); + store->CommitL(); + CleanupStack::PopAndDestroy(); + + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead); + TStreamId id2 = out.CreateLC(*store); + out << des2; + out.CommitL(); + CleanupStack::PopAndDestroy(); + + TStreamId id3 = out.CreateLC(*store); + out << des3; + out.CommitL(); + CleanupStack::PopAndDestroy(); + + out.ReplaceLC(*store,store->Root()); + out << id2; + out << id3; + out.CommitL(); + CleanupStack::PopAndDestroy();// out + + store->CommitL(); + CleanupStack::PopAndDestroy();// store + } + +LOCAL_D void AlterStoreDuringFileServerErrorL(TInt aError) + { + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead); + in.OpenLC(*store,store->Root()); + TStreamId id2; + TStreamId id3; + in >> id2; + in >> id3; + CleanupStack::PopAndDestroy();// in + + out.ReplaceLC(*store,id2); + out << des4; + out.CommitL(); + CleanupStack::PopAndDestroy();// out + TheFs.SetErrorCondition(aError); + out.ReplaceLC(*store,id3); + out << des5; + out.CommitL(); + CleanupStack::PopAndDestroy();// out + + store->CommitL(); + CleanupStack::PopAndDestroy();// store + } + +LOCAL_D void TestStreamDataL(TInt aError) + { + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead); + in.OpenLC(*store,store->Root()); + TStreamId id2; + TStreamId id3; + in >> id2; + in >> id3; + CleanupStack::PopAndDestroy();// in + + TBuf<16> buf; + + in.OpenLC(*store,id2); + in >> buf; + if (aError==KErrNone) + test(buf==_L("4444"));// store committed + else + test(buf==_L("22"));// store reverted + + CleanupStack::PopAndDestroy();// in + + in.OpenLC(*store,id3); + in >> buf; + if (aError==KErrNone) + test(buf==_L("55555"));// store committed + else + test(buf==_L("333"));// store reverted + + CleanupStack::PopAndDestroy();// in + + CleanupStack::PopAndDestroy();// store + } + +LOCAL_D void ResetStreamDataL() + { + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead); + in.OpenLC(*store,store->Root()); + TStreamId id2; + TStreamId id3; + in >> id2; + in >> id3; + CleanupStack::PopAndDestroy();// in + + out.ReplaceLC(*store,id2); + out << des2; + out.CommitL(); + CleanupStack::PopAndDestroy();// out + + out.ReplaceLC(*store,id3); + out << des3; + out.CommitL(); + CleanupStack::PopAndDestroy();// out + + store->CommitL(); + CleanupStack::PopAndDestroy();// store + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1161 +@SYMTestCaseDesc Tests for all errors on file server +@SYMTestPriority High +@SYMTestActions Tests for stream data to a store +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_D void TestAllFsErrorL() + { + InitialseStoreWithDataL(); + for (TInt error=0; error >= KErrDied; --error) + { + TRAPD(r,AlterStoreDuringFileServerErrorL(error)); + TheFs.SetErrorCondition(KErrNone); + if (r!=KErrNone) + { + store = CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead); + store->RevertL(); + CleanupStack::PopAndDestroy();// store + } + TestStreamDataL(error); + ResetStreamDataL(); + } + } + +void RunTests() + { + setupTestDirectory(); + __UHEAP_MARK; +// + test.Start(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1160 Random failure on every file server call ")); + TRAPD(r,FailOnEveryFileServerCallL()); + test(r==KErrNone); + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1161 Alter STORE during file server error ")); + TRAP(r,TestAllFsErrorL()); + test(r==KErrNone); + test.End(); + + TheFs.Delete(FileNameA); + TheFs.Delete(FileNameB); +// + __UHEAP_MARKEND; + } + +#endif // _DEBUG + +GLDEF_C TInt E32Main() + {// Test permanent file store. + test.Title(); +#ifdef _DEBUG + TInt r=TheFs.Connect(); + test(r==KErrNone); + setupCleanup(); + RunTests(); + delete TheTrapCleanup; + TheFs.Close(); +#else + test.Start(_L("The tests are not valid in release mode")); + test.End(); +#endif + test.Close(); + return 0; + } +