diff -r 000000000000 -r 08ec8eefde2f persistentstorage/store/TFILE/t_storfperm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/store/TFILE/t_storfperm.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,587 @@ +// 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 + +const TInt KTestCleanupStack=0x20; + +// This is a path specification and should not be used as is +_LIT(KFileLocationSpec, "Z:\\STOR-TST\\T_FPERM.DAT"); +const TUint8* KTestData=_S8("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); +const TInt KTestLength=36; +const TInt KTestTotal=KTestLength*(KTestLength+1); +const TPtrC8 KTestDes(KTestData,KTestLength); + +LOCAL_D CTrapCleanup* TheTrapCleanup; +LOCAL_D RTest test(_L("t_storfperm")); +LOCAL_D RFs TheFs; +LOCAL_D TFileName TheTempFile; +LOCAL_D TBuf8 TheBuf; +/** +@SYMTestCaseID SYSLIB-STORE-CT-1152 +@SYMTestCaseDesc Tests empty streams +@SYMTestPriority High +@SYMTestActions Tests for empty stream buffers.Check for end of file error,overflow error flags +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testEmptyL(CStreamStore& aStore) + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1152 Stream created using 'extend' ")); + TStreamId empty=aStore.ExtendL(); + RStoreReadStream in; + in.OpenL(aStore,empty); + TUint8 b; + test(in.Source()->ReadL(&b,1)==0); + in.Source()->SeekL(0,KStreamBeginning); + test(in.Source()->SeekL(MStreamBuf::ERead,EStreamMark)==KStreamBeginning); + test(in.Source()->SizeL()==0); + TRAPD(r,in.Source()->SeekL(MStreamBuf::ERead,EStreamBeginning,1)); + test(r==KErrEof); + TRAP(r,in.Source()->SeekL(MStreamBuf::ERead,EStreamEnd,-1)); + test(r==KErrEof); + in.Close(); + RStoreWriteStream out; + out.OpenL(aStore,empty); + out.Sink()->SeekL(0,KStreamBeginning); + test(out.Sink()->SeekL(MStreamBuf::EWrite,EStreamMark)==KStreamBeginning); + test(out.Sink()->SizeL()==0); + TRAP(r,out.Sink()->SeekL(MStreamBuf::EWrite,EStreamBeginning,1)); + test(r==KErrEof); + TRAP(r,out.Sink()->SeekL(MStreamBuf::EWrite,EStreamEnd,-1)); + test(r==KErrEof); + TRAP(r,out.WriteUint8L(0)); + test(r==KErrOverflow); + out.Close(); +// + test.Next(_L("Replacing empty with empty")); + out.ReplaceL(aStore,empty); + out.CommitL(); + out.Release(); + in.OpenL(aStore,empty); + test(in.Source()->ReadL(&b,1)==0); + in.Source()->SeekL(0,KStreamBeginning); + test(in.Source()->SeekL(MStreamBuf::ERead,EStreamMark)==KStreamBeginning); + test(in.Source()->SizeL()==0); + TRAP(r,in.Source()->SeekL(MStreamBuf::ERead,EStreamBeginning,1)); + test(r==KErrEof); + TRAP(r,in.Source()->SeekL(MStreamBuf::ERead,EStreamEnd,-1)); + test(r==KErrEof); + in.Close(); + out.OpenL(aStore,empty); + out.Sink()->SeekL(0,KStreamBeginning); + test(out.Sink()->SeekL(MStreamBuf::EWrite,EStreamMark)==KStreamBeginning); + test(out.Sink()->SizeL()==0); + TRAP(r,out.Sink()->SeekL(MStreamBuf::EWrite,EStreamBeginning,1)); + test(r==KErrEof); + TRAP(r,out.Sink()->SeekL(MStreamBuf::EWrite,EStreamEnd,-1)); + test(r==KErrEof); + TRAP(r,out.WriteUint8L(0)); + test(r==KErrOverflow); + out.Close(); + } + +// +// Test writing to a store +// +LOCAL_C void testWriteL(CPersistentStore& aStore) + { + test.Next(_L("Writing...")); + RStoreWriteStream out; + TStreamId id=out.CreateLC(aStore); + TStreamPos end=KStreamBeginning; //* + for (TInt i=0;i<=KTestLength;++i) + { + test(out.Sink()->SeekL(MStreamBuf::EWrite,EStreamMark)==end); //* + out.WriteL(KTestDes,i); + test(out.Sink()->SeekL(0,EStreamEnd,-i)==end); //* + out.WriteL(&KTestData[i],KTestLength-i); + end+=KTestLength; //* + } +//* test(out.Sink()->SizeL()==end.Offset()); +//* out.WriteL(KTestDes,12); +//* end+=12; + test(out.Sink()->SizeL()==end.Offset()); //* + out.CommitL(); + test(out.Sink()->SizeL()==end.Offset()); //* + out.Close(); + aStore.SetRootL(out.CreateL(aStore)); + out<=0;--i) + { + aStream.ReadL(TheBuf,i); + test(TheBuf.Length()==i); + TheBuf.SetMax(); + aStream.ReadL(&TheBuf[i],KTestLength-i); + TheBuf.SetLength(KTestLength); + test(TheBuf==KTestDes); + } + } + +// +// Test reading from a store +// +LOCAL_C void testReadL(const CPersistentStore& aStore) + { + test.Next(_L("Reading...")); + RStoreReadStream in; + in.OpenLC(aStore,aStore.Root()); + in>>TheBuf; + TStreamId id; + in>>id; + in.Close(); + in.OpenL(aStore,id); + testReadL(in); + CleanupStack::PopAndDestroy(); + } + +// +// Test copying from one stream to another. +// +LOCAL_C void testCopyL(RWriteStream& aWriteStream,RReadStream& aReadStream) + { + test.Next(_L("Copying")); + for (TInt i=KTestLength;i>=0;--i) + { + aWriteStream.WriteL(aReadStream,i); + aReadStream.ReadL(aWriteStream,KTestLength-i); + } + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1153 +@SYMTestCaseDesc Tests for writing using a permanent file store +@SYMTestPriority High +@SYMTestActions Tests for memory and end of file error while creating the store. + Tests for writing to replaced,temporary,opened,created file. + Tests for creating an already existing file. + Tests for panic while deleting a file. +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testWriteL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1153 Creating and failing to open 'ghost' file ")); + + TDriveUnit drive(static_cast(RFs::GetSystemDrive())); + TParse parse; + parse.Set(drive.Name(), &KFileLocationSpec, NULL); + + TheFs.Delete(parse.NameAndExt()); + CFileStore* store=CPermanentFileStore::CreateLC(TheFs,parse.NameAndExt(),EFileWrite); + CleanupStack::PopAndDestroy(); + store=NULL; + TRAPD(r,store=CPermanentFileStore::OpenL(TheFs,parse.NameAndExt(),EFileRead|EFileWrite)); + test(store==NULL&&r==KErrEof); +// + test.Next(_L("Empty tests on replaced file")); + store=CPermanentFileStore::ReplaceLC(TheFs,parse.NameAndExt(),EFileWrite); + store->SetTypeL(TUidType(KPermanentFileStoreLayoutUid,KPermanentFileStoreLayoutUid)); + testEmptyL(*store); + CleanupStack::PopAndDestroy(); +// + test.Next(_L("Writing to temp file")); + store=CPermanentFileStore::TempLC(TheFs,parse.DriveAndPath(),TheTempFile,EFileWrite); + store->SetTypeL(TUidType(store->Layout(),KNullUid,KPermanentFileStoreLayoutUid)); + testWriteL(*store); + store->CommitL(); + CleanupStack::PopAndDestroy(); +// + test.Next(_L("Writing to opened file")); + store=CPermanentFileStore::OpenLC(TheFs,parse.NameAndExt(),EFileRead|EFileWrite); + testWriteL(*store); + store->CommitL(); + CleanupStack::PopAndDestroy(); +// + test.Next(_L("Failing to create existing file")); + store=NULL; + TRAP(r,store=CPermanentFileStore::CreateL(TheFs,TheTempFile,EFileWrite)); + test(store==NULL&&r==KErrAlreadyExists); + if (TheFs.Delete(parse.NameAndExt())!=KErrNone) + test.Panic(_L("Deleting file")); +// + test.Next(_L("Writing to created file")); + RFile file; + test(file.Create(TheFs,parse.NameAndExt(),EFileWrite)==KErrNone); + store=CPermanentFileStore::NewLC(file); + store->SetTypeL(KPermanentFileStoreLayoutUid); + testWriteL(*store); + store->CommitL(); + CleanupStack::PopAndDestroy(); + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1154 +@SYMTestCaseDesc Tests for reading using a permanent file store. +@SYMTestPriority High +@SYMTestActions Read data from a stream +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testReadL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1154 Reading from opened file ")); + + TParsePtrC parse(KFileLocationSpec); + + RFile file; + test(file.Open(TheFs,parse.NameAndExt(),EFileRead)==KErrNone); + CFileStore* store=CFileStore::FromLC(file); + testReadL(*store); + store->CommitL(); + CleanupStack::PopAndDestroy(); +// + test.Next(_L("Reading from temp file")); + test(file.Open(TheFs,TheTempFile,EFileRead)==KErrNone); + store=CPermanentFileStore::FromLC(file); + testReadL(*store); + CleanupStack::PopAndDestroy(); + } + +LOCAL_C void testRootL(CPersistentStore& aStore) + { + aStore.SetRootL(aStore.ExtendL()); + aStore.CommitL(); + } + +LOCAL_C void testDummyL(CFileStore& aStore) + { + aStore.SetTypeL(aStore.Layout()); + aStore.CommitL(); + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1155 +@SYMTestCaseDesc Tests for recovery from write failures +@SYMTestPriority High +@SYMTestActions Tests for access denied error during writing,commit and update process +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testRecoveryL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1155 Recovering from write failures ")); + TParsePtrC parse(KFileLocationSpec); + + CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,parse.NameAndExt(),EFileWrite); + store->SetTypeL(KPermanentFileStoreLayoutUid); + testWriteL(*store); + store->CommitL(); +// + store->File().Close(); + test(store->File().Open(TheFs,parse.NameAndExt(),EFileRead)==KErrNone); +// fail during writing + TRAPD(r,store->SetTypeL(store->Type());testWriteL(*store)); + test(r==KErrAccessDenied); + store->Revert(); + testReadL(*store); +// fail during commit + TRAP(r,testRootL(*store)); + test(r==KErrAccessDenied); + store->Revert(); + testReadL(*store); +// fail during dummy update + TRAP(r,testDummyL(*store)); + test(r==KErrAccessDenied); + store->Revert(); + testReadL(*store); + CleanupStack::PopAndDestroy(); + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1156 +@SYMTestCaseDesc Tests copying in a single file store. +@SYMTestPriority High +@SYMTestActions Tests for copying using different buffer sizes +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testCopyL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1156 Copying using small transfers ")); + TParsePtrC parse(KFileLocationSpec); + + CFileStore* store=CFileStore::OpenLC(TheFs,parse.NameAndExt(),EFileRead|EFileWrite); + RStoreReadStream in; + in.OpenLC(*store,store->Root()); + in>>TheBuf; + TStreamId copyId; + in>>copyId; + in.Close(); + in.OpenL(*store,copyId); + RStoreWriteStream out; + TStreamId id=out.CreateLC(*store); + testCopyL(out,in); + out.CommitL(); + out.Close(); + in.Close(); + in.OpenL(*store,id); + testReadL(in); + in.Close(); +// + test.Next(_L("Copying using a single big transfer")); + in.OpenL(*store,copyId); + id=out.CreateL(*store); + in.ReadL(out,KTestTotal); + out.CommitL(); + out.Close(); + in.Close(); + in.OpenL(*store,id); + testReadL(in); + in.Close(); + in.OpenL(*store,copyId); + id=out.CreateL(*store); + out.WriteL(in,KTestTotal); + out.CommitL(); + out.Close(); + in.Close(); + in.OpenL(*store,id); + testReadL(in); +// + CleanupStack::PopAndDestroy(3); + } + +// +// Test empty streams. +// +LOCAL_C void testEmptyL() + { + test.Next(_L("Empty tests on existing file")); + TParsePtrC parse(KFileLocationSpec); + CFileStore* store=CFileStore::OpenLC(TheFs,parse.NameAndExt(),EFileRead|EFileWrite); + testEmptyL(*store); +// + CleanupStack::PopAndDestroy(); + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1157 +@SYMTestCaseDesc Tests for detaching file from store +@SYMTestPriority High +@SYMTestActions Detach the file and discard the store +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testDetachL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1157 Writing a file store ")); + TParsePtrC parse(KFileLocationSpec); + + CFileStore* store=CPermanentFileStore::ReplaceLC(TheFs,parse.NameAndExt(),EFileWrite|EFileRead); + store->SetTypeL(KPermanentFileStoreLayoutUid); + testWriteL(*store); + store->CommitL(); +// + test.Next(_L("Detach the file and discard the store")); + RFile file=store->File(); + store->Detach(); + CleanupStack::PopAndDestroy(); +// + test.Next(_L("Re-construct the store and check the contents")); + store=CFileStore::FromLC(file); + testReadL(*store); + CleanupStack::PopAndDestroy(); + } +/** +@SYMTestCaseID SYSLIB-STORE-CT-1158 +@SYMTestCaseDesc Tests for defect No 039456 + Permanent File Store allows code to open and read from deleted streams +@SYMTestPriority High +@SYMTestActions Create four streams,delete last three and close the store. + Open the store and test for reading the first stream. +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void testDef039456L() +{ + _LIT(KMsvDrivelessTestPath, ":\\t_storperm.dat"); + TFileName msvTestPath; + msvTestPath.Append(RFs::GetSystemDriveChar()); + msvTestPath.Append(KMsvDrivelessTestPath); + + _LIT(KStringOne, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); + _LIT(KStringTwo, "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); + + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1158 ")); + TheFs.Delete(msvTestPath); + CPermanentFileStore* testStore = CPermanentFileStore::CreateLC(TheFs, msvTestPath, EFileWrite|EFileShareAny); + testStore->SetTypeL(KPermanentFileStoreLayoutUid); + + // create four streams, + RStoreWriteStream wstream; + TStreamId stream_one=wstream.CreateLC(*testStore); + wstream << KStringOne; + wstream.CommitL(); + CleanupStack::PopAndDestroy(&wstream); + testStore->CommitL(); + TStreamId stream_two=wstream.CreateLC(*testStore); + wstream << KStringTwo; + wstream.CommitL(); + CleanupStack::PopAndDestroy(&wstream); + testStore->CommitL(); + TStreamId stream_three=wstream.CreateLC(*testStore); + wstream << KStringOne; + wstream.CommitL(); + CleanupStack::PopAndDestroy(&wstream); + testStore->CommitL(); + TStreamId stream_four=wstream.CreateLC(*testStore); + wstream << KStringOne; + wstream.CommitL(); + CleanupStack::PopAndDestroy(&wstream); + testStore->CommitL(); + + // delete last three streams added (not in the order added) + testStore->DeleteL(stream_four); + testStore->CommitL(); + testStore->DeleteL(stream_three); + testStore->CommitL(); + testStore->DeleteL(stream_two); + testStore->CommitL(); + + // close the store + CleanupStack::PopAndDestroy(testStore); + + // open store, try and read each of the streams, only stream_one should be present + testStore = CPermanentFileStore::OpenLC(TheFs, msvTestPath, EFileWrite|EFileShareAny); + RStoreReadStream rstream1, rstream2; + + // check stream_one ok + TRAPD(error_stream_one,rstream1.OpenL(*testStore,stream_one)); + test(error_stream_one==KErrNone); + rstream1.Close(); + + // shouldn't be able to open this stream as we deleted it.... + TRAPD(error_stream_two,rstream2.OpenL(*testStore,stream_two)); + test(error_stream_two==KErrNotFound); + + CleanupStack::PopAndDestroy(testStore); + + (void)TheFs.Delete(msvTestPath); + } + + +// +// Prepare the test directory. +// +LOCAL_C void setupTestDirectory() + { + TInt r=TheFs.Connect(); + test(r==KErrNone); +// + TDriveUnit drive(static_cast(RFs::GetSystemDrive())); + TParse parse; + parse.Set(drive.Name(), &KFileLocationSpec, NULL); + + r=TheFs.MkDir(parse.DriveAndPath()); + test(r==KErrNone||r==KErrAlreadyExists); + r=TheFs.SetSessionPath(parse.DriveAndPath()); + test(r==KErrNone); + } + +// +// Initialise the cleanup stack. +// +LOCAL_C void setupCleanup() + { + 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 DeleteDataFile(const TDesC& aFullName) + { + RFs fsSession; + TInt err = fsSession.Connect(); + if(err == KErrNone) + { + TEntry entry; + if(fsSession.Entry(aFullName, entry) == KErrNone) + { + RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); + if(err != KErrNone) + { + RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); + } + err = fsSession.Delete(aFullName); + if(err != KErrNone) + { + RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); + } + } + fsSession.Close(); + } + else + { + RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); + } + } + +// +// Test permanent file store. +// +GLDEF_C TInt E32Main() + { + test.Title(); + setupTestDirectory(); + setupCleanup(); + __UHEAP_MARK; +// + test.Start(_L("Test permanent file store")); + TRAPD(r,testWriteL()); + test(r==KErrNone); + TRAP(r,testReadL()); + test(r==KErrNone); + TRAP(r,testRecoveryL()); + test(r==KErrNone); + TRAP(r,testCopyL()); + test(r==KErrNone); + TRAP(r,testEmptyL()); + test(r==KErrNone); + TRAP(r,testDetachL()); + test(r==KErrNone); + TRAP(r,testDef039456L()); + test(r==KErrNone); + + //deletion of data files must be before call to .End() - DEF047652 + TDriveUnit drive(static_cast(RFs::GetSystemDrive())); + TParse parse; + parse.Set(drive.Name(), &KFileLocationSpec, NULL); + ::DeleteDataFile(parse.FullName()); + + test.End(); +// + __UHEAP_MARKEND; + + delete TheTrapCleanup; + if (TheFs.Delete(TheTempFile)!=KErrNone) + test.Panic(_L("Deleting temp file")); + TheFs.Close(); + test.Close(); + return 0; + } +