1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/store/TFILE/t_storfserr.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,436 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <s32file.h>
1.20 +#include <e32test.h>
1.21 +
1.22 +LOCAL_D RTest test(_L("t_storfserr"));
1.23 +
1.24 +#ifdef _DEBUG
1.25 +
1.26 +LOCAL_D CTrapCleanup* TheTrapCleanup = NULL;
1.27 +LOCAL_D RFs TheFs;
1.28 +
1.29 +const TInt KTestCleanupStack=0x20;
1.30 +const TPtrC KTestDir=_L("\\STOR-TST\\T_FSERR\\");
1.31 +const TPtrC FileNameA=_L("A.DAT");
1.32 +const TPtrC FileNameB=_L("B.DAT");
1.33 +
1.34 +const TPtrC des2(_S("22"),2);
1.35 +const TPtrC des3(_S("333"),3);
1.36 +const TPtrC des4(_S("4444"),4);
1.37 +const TPtrC des5(_S("55555"),5);
1.38 +LOCAL_D CFileStore* store = NULL;
1.39 +RStoreWriteStream out;
1.40 +RStoreReadStream in;
1.41 +
1.42 +LOCAL_C void setupCleanup()
1.43 + {// Initialise the cleanup stack
1.44 + TheTrapCleanup=CTrapCleanup::New();
1.45 + test(TheTrapCleanup!=NULL);
1.46 + TRAPD(r,\
1.47 + {\
1.48 + for (TInt i=KTestCleanupStack;i>0;i--)\
1.49 + CleanupStack::PushL((TAny*)0);\
1.50 + CleanupStack::Pop(KTestCleanupStack);\
1.51 + });
1.52 + test(r==KErrNone);
1.53 + }
1.54 +
1.55 +LOCAL_C void setupTestDirectory()
1.56 + {// Prepare the test directory.
1.57 + TInt r=TheFs.MkDirAll(KTestDir);
1.58 + test(r==KErrNone||r==KErrAlreadyExists);
1.59 + r=TheFs.SetSessionPath(KTestDir);
1.60 + test(r==KErrNone);
1.61 + }
1.62 +
1.63 +LOCAL_D void AlterStoreL(TInt aFail)
1.64 + {
1.65 + RStoreWriteStream out2;
1.66 + RStoreWriteStream out3;
1.67 + RStoreWriteStream out4;
1.68 + RStoreReadStream in;
1.69 + TheFs.SetErrorCondition(KErrNotReady,aFail);
1.70 + TStreamId id0 = out.CreateLC(*store);
1.71 + out << _L("012345678901234567890123456789012345678901234567890123456789");
1.72 + out.CommitL();
1.73 + CleanupStack::PopAndDestroy();
1.74 +
1.75 + TStreamId id2 = out.CreateLC(*store);
1.76 + out.CommitL();
1.77 + CleanupStack::PopAndDestroy();
1.78 +
1.79 + TStreamId id3 = out.CreateLC(*store);
1.80 + out.CommitL();
1.81 + CleanupStack::PopAndDestroy();
1.82 +
1.83 + TStreamId id4 = out.CreateLC(*store);
1.84 + out << _L("mum");
1.85 + out.CommitL();
1.86 + CleanupStack::PopAndDestroy();
1.87 +
1.88 + out.ReplaceLC(*store,store->Root());
1.89 + out << id2;
1.90 + out << id3;
1.91 + out << id4;
1.92 + out << KNullStreamId;
1.93 + out << KNullStreamId;
1.94 + out.CommitL();
1.95 + CleanupStack::PopAndDestroy();
1.96 +
1.97 + in.OpenLC(*store,store->Root());// use the root for in and out streams
1.98 + out.ReplaceLC(*store,store->Root());
1.99 + out.WriteL(in);
1.100 + out.CommitL();
1.101 + CleanupStack::PopAndDestroy(2);
1.102 +
1.103 + out.ReplaceLC(*store,store->Root());// swap the order
1.104 + in.OpenLC(*store,store->Root());
1.105 + out.WriteL(in);
1.106 + out << KNullStreamId;
1.107 + out.CommitL();
1.108 + CleanupStack::PopAndDestroy(2);
1.109 +
1.110 + store->CommitL();
1.111 +
1.112 + in.OpenLC(*store,store->Root());
1.113 + TStreamId idX,idZ;
1.114 + in >> idX;
1.115 + in >> idX;
1.116 + in >> idZ;// id4 "mum"
1.117 + CleanupStack::PopAndDestroy();
1.118 + out.OpenLC(*store,idZ);
1.119 + in.OpenLC(*store,idZ);
1.120 + out2.OpenLC(*store,idZ);
1.121 + out3.OpenLC(*store,idZ);
1.122 + out4.OpenLC(*store,idZ);
1.123 + out4.WriteL(in);
1.124 + out.CommitL();
1.125 + CleanupStack::PopAndDestroy(5);
1.126 +
1.127 + store->CompactL();
1.128 + store->CommitL();
1.129 +
1.130 + store->DeleteL(id0);
1.131 + store->CommitL();
1.132 +
1.133 + store->CompactL();
1.134 + store->CommitL();
1.135 + }
1.136 +
1.137 +enum TFileQoS
1.138 + {
1.139 + ESimple = 0,//File, "write byte" is an atomic operation
1.140 + EBlockAtomic = 1,//File, "block write" is an atomic operation
1.141 + ETransactional = 2,//Transactional file system.
1.142 + ELastQoSType
1.143 + };
1.144 +
1.145 +const TInt KFailPoints[ELastQoSType][2] =
1.146 + {
1.147 + // non-transactional file system
1.148 + {
1.149 + 5, 54
1.150 + },
1.151 + // atomic "block write"
1.152 + {
1.153 + 3, 38
1.154 + },
1.155 + // transactional file system
1.156 + {
1.157 + 3, 38
1.158 + }
1.159 + };
1.160 +
1.161 +//The function returns true, if the file system guarantees atomic "block write" operations on aDriveNo.
1.162 +TBool IsBlockAtomic(TInt aDriveNo)
1.163 + {
1.164 + __ASSERT_DEBUG(aDriveNo >= EDriveA && aDriveNo <= EDriveZ, User::Invariant());
1.165 +
1.166 + TVolumeIOParamInfo volInfo;
1.167 + TInt err = TheFs.VolumeIOParam(aDriveNo, volInfo);
1.168 + //If VolumeIOParam() succeeds, the media block size is >= 512 bytes and the media block size is power of two - report
1.169 + //that the media supports atomic "block write" operations.
1.170 + const TInt KDefaultMediaBlockSize = 512;
1.171 + return err == KErrNone && volInfo.iBlockSize >= KDefaultMediaBlockSize && (volInfo.iBlockSize & (volInfo.iBlockSize - 1)) == 0;
1.172 + }
1.173 +
1.174 +TFileQoS MediaType(const TDesC& aFilename)
1.175 + {
1.176 + TParse p;
1.177 + TheFs.Parse(aFilename, p);
1.178 + TDriveInfo dinfo;
1.179 + TheFs.Drive(dinfo, TDriveUnit(p.Drive()));
1.180 + TBool transactional = dinfo.iDriveAtt & KDriveAttTransaction;
1.181 + if(transactional)
1.182 + {
1.183 + return ETransactional;
1.184 + }
1.185 + if(IsBlockAtomic(TDriveUnit(p.Drive())))
1.186 + {
1.187 + return EBlockAtomic;
1.188 + }
1.189 + return ESimple;
1.190 + }
1.191 +/**
1.192 +@SYMTestCaseID SYSLIB-STORE-CT-1160
1.193 +@SYMTestCaseDesc File server test
1.194 +@SYMTestPriority High
1.195 +@SYMTestActions Tests for failure on call to file server
1.196 +@SYMTestExpectedResults Test must not fail
1.197 +@SYMREQ REQ0000
1.198 +*/
1.199 +LOCAL_D void FailOnEveryFileServerCallL()
1.200 + {
1.201 + TheFs.Delete(FileNameA);
1.202 +
1.203 + const TFileQoS KMediaType = MediaType(FileNameA);
1.204 + _LIT(KSimpleText, "Simple");
1.205 + _LIT(KAtomicText, "Atomic block \"write\"");
1.206 + _LIT(KTransactionalText, "Transactional");
1.207 + const TPtrC mediaType[ELastQoSType] = {KSimpleText(), KAtomicText(), KTransactionalText()};
1.208 + test.Printf(_L("Media type: %S\r\n"), &mediaType[KMediaType]);
1.209 +
1.210 + const TInt KStoreCommitted = KFailPoints[KMediaType][0];
1.211 + const TInt KLastFail = KFailPoints[KMediaType][1];
1.212 +
1.213 + const TInt KError = KErrNotReady;
1.214 + const TInt KRootIdSizeBeforeStoreCommit = 0;
1.215 + const TInt KRootIdSizeAfterStoreCommit = 6*sizeof(TStreamId);
1.216 +
1.217 + for (TInt fail=1;fail<=KLastFail+5;++fail)
1.218 + {
1.219 + store=CPermanentFileStore::ReplaceLC(TheFs,FileNameA,EFileWrite|EFileRead);
1.220 + store->SetTypeL(KPermanentFileStoreLayoutUid);
1.221 + TStreamId rootId = store->ExtendL();
1.222 + store->SetRootL(rootId);
1.223 + store->CommitL();
1.224 + TRAPD(r,AlterStoreL(fail));
1.225 + TheFs.SetErrorCondition(KErrNone);
1.226 + if (fail<KLastFail)
1.227 + test(r==KError);
1.228 + else
1.229 + test(r==KErrNone);
1.230 + TRAP(r,store->RevertL());
1.231 + if (r==KErrNotReady)
1.232 + {
1.233 + CleanupStack::PopAndDestroy();
1.234 + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileWrite|EFileRead);
1.235 + }
1.236 + else
1.237 + test(r==KErrNone);
1.238 + CleanupStack::PopAndDestroy();
1.239 +//
1.240 + // open read only
1.241 + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileRead);
1.242 + RStoreReadStream in;
1.243 + in.OpenLC(*store,store->Root());
1.244 + TInt size=in.Source()->SizeL();
1.245 + if (fail<KStoreCommitted)
1.246 + test(size==KRootIdSizeBeforeStoreCommit);
1.247 + else //fail>=KStoreCommitted
1.248 + test(size==KRootIdSizeAfterStoreCommit);
1.249 + CleanupStack::PopAndDestroy(2);
1.250 +//
1.251 + store=CPermanentFileStore::OpenLC(TheFs,FileNameA,EFileRead|EFileWrite);
1.252 + store->ExtendL();
1.253 + store->RevertL();
1.254 + in.OpenLC(*store,store->Root());
1.255 + size=in.Source()->SizeL();
1.256 + if (fail<KStoreCommitted)
1.257 + test(size==KRootIdSizeBeforeStoreCommit);
1.258 + else //fail>=KStoreCommitted
1.259 + test(size==KRootIdSizeAfterStoreCommit);
1.260 + CleanupStack::PopAndDestroy(2);
1.261 + }
1.262 + }
1.263 +
1.264 +LOCAL_D void InitialseStoreWithDataL()
1.265 + {
1.266 + TheFs.Delete(FileNameB);
1.267 + store=CPermanentFileStore::CreateLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.268 + store->SetTypeL(KPermanentFileStoreLayoutUid);
1.269 + TStreamId rootId = store->ExtendL();
1.270 + store->SetRootL(rootId);
1.271 + store->CommitL();
1.272 + CleanupStack::PopAndDestroy();
1.273 +
1.274 + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.275 + TStreamId id2 = out.CreateLC(*store);
1.276 + out << des2;
1.277 + out.CommitL();
1.278 + CleanupStack::PopAndDestroy();
1.279 +
1.280 + TStreamId id3 = out.CreateLC(*store);
1.281 + out << des3;
1.282 + out.CommitL();
1.283 + CleanupStack::PopAndDestroy();
1.284 +
1.285 + out.ReplaceLC(*store,store->Root());
1.286 + out << id2;
1.287 + out << id3;
1.288 + out.CommitL();
1.289 + CleanupStack::PopAndDestroy();// out
1.290 +
1.291 + store->CommitL();
1.292 + CleanupStack::PopAndDestroy();// store
1.293 + }
1.294 +
1.295 +LOCAL_D void AlterStoreDuringFileServerErrorL(TInt aError)
1.296 + {
1.297 + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.298 + in.OpenLC(*store,store->Root());
1.299 + TStreamId id2;
1.300 + TStreamId id3;
1.301 + in >> id2;
1.302 + in >> id3;
1.303 + CleanupStack::PopAndDestroy();// in
1.304 +
1.305 + out.ReplaceLC(*store,id2);
1.306 + out << des4;
1.307 + out.CommitL();
1.308 + CleanupStack::PopAndDestroy();// out
1.309 + TheFs.SetErrorCondition(aError);
1.310 + out.ReplaceLC(*store,id3);
1.311 + out << des5;
1.312 + out.CommitL();
1.313 + CleanupStack::PopAndDestroy();// out
1.314 +
1.315 + store->CommitL();
1.316 + CleanupStack::PopAndDestroy();// store
1.317 + }
1.318 +
1.319 +LOCAL_D void TestStreamDataL(TInt aError)
1.320 + {
1.321 + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.322 + in.OpenLC(*store,store->Root());
1.323 + TStreamId id2;
1.324 + TStreamId id3;
1.325 + in >> id2;
1.326 + in >> id3;
1.327 + CleanupStack::PopAndDestroy();// in
1.328 +
1.329 + TBuf<16> buf;
1.330 +
1.331 + in.OpenLC(*store,id2);
1.332 + in >> buf;
1.333 + if (aError==KErrNone)
1.334 + test(buf==_L("4444"));// store committed
1.335 + else
1.336 + test(buf==_L("22"));// store reverted
1.337 +
1.338 + CleanupStack::PopAndDestroy();// in
1.339 +
1.340 + in.OpenLC(*store,id3);
1.341 + in >> buf;
1.342 + if (aError==KErrNone)
1.343 + test(buf==_L("55555"));// store committed
1.344 + else
1.345 + test(buf==_L("333"));// store reverted
1.346 +
1.347 + CleanupStack::PopAndDestroy();// in
1.348 +
1.349 + CleanupStack::PopAndDestroy();// store
1.350 + }
1.351 +
1.352 +LOCAL_D void ResetStreamDataL()
1.353 + {
1.354 + store=CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.355 + in.OpenLC(*store,store->Root());
1.356 + TStreamId id2;
1.357 + TStreamId id3;
1.358 + in >> id2;
1.359 + in >> id3;
1.360 + CleanupStack::PopAndDestroy();// in
1.361 +
1.362 + out.ReplaceLC(*store,id2);
1.363 + out << des2;
1.364 + out.CommitL();
1.365 + CleanupStack::PopAndDestroy();// out
1.366 +
1.367 + out.ReplaceLC(*store,id3);
1.368 + out << des3;
1.369 + out.CommitL();
1.370 + CleanupStack::PopAndDestroy();// out
1.371 +
1.372 + store->CommitL();
1.373 + CleanupStack::PopAndDestroy();// store
1.374 + }
1.375 +/**
1.376 +@SYMTestCaseID SYSLIB-STORE-CT-1161
1.377 +@SYMTestCaseDesc Tests for all errors on file server
1.378 +@SYMTestPriority High
1.379 +@SYMTestActions Tests for stream data to a store
1.380 +@SYMTestExpectedResults Test must not fail
1.381 +@SYMREQ REQ0000
1.382 +*/
1.383 +LOCAL_D void TestAllFsErrorL()
1.384 + {
1.385 + InitialseStoreWithDataL();
1.386 + for (TInt error=0; error >= KErrDied; --error)
1.387 + {
1.388 + TRAPD(r,AlterStoreDuringFileServerErrorL(error));
1.389 + TheFs.SetErrorCondition(KErrNone);
1.390 + if (r!=KErrNone)
1.391 + {
1.392 + store = CPermanentFileStore::OpenLC(TheFs,FileNameB,EFileWrite|EFileRead);
1.393 + store->RevertL();
1.394 + CleanupStack::PopAndDestroy();// store
1.395 + }
1.396 + TestStreamDataL(error);
1.397 + ResetStreamDataL();
1.398 + }
1.399 + }
1.400 +
1.401 +void RunTests()
1.402 + {
1.403 + setupTestDirectory();
1.404 + __UHEAP_MARK;
1.405 +//
1.406 + test.Start(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1160 Random failure on every file server call "));
1.407 + TRAPD(r,FailOnEveryFileServerCallL());
1.408 + test(r==KErrNone);
1.409 + test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1161 Alter STORE during file server error "));
1.410 + TRAP(r,TestAllFsErrorL());
1.411 + test(r==KErrNone);
1.412 + test.End();
1.413 +
1.414 + TheFs.Delete(FileNameA);
1.415 + TheFs.Delete(FileNameB);
1.416 +//
1.417 + __UHEAP_MARKEND;
1.418 + }
1.419 +
1.420 +#endif // _DEBUG
1.421 +
1.422 +GLDEF_C TInt E32Main()
1.423 + {// Test permanent file store.
1.424 + test.Title();
1.425 +#ifdef _DEBUG
1.426 + TInt r=TheFs.Connect();
1.427 + test(r==KErrNone);
1.428 + setupCleanup();
1.429 + RunTests();
1.430 + delete TheTrapCleanup;
1.431 + TheFs.Close();
1.432 +#else
1.433 + test.Start(_L("The tests are not valid in release mode"));
1.434 + test.End();
1.435 +#endif
1.436 + test.Close();
1.437 + return 0;
1.438 + }
1.439 +