First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\server\t_filecache.cpp
17 #define __E32TEST_EXTENSION__
27 //----------------------------------------------------------------------------------------------
28 //! @SYMTestCaseID PBASE-T_FILECACHE-0189
31 //! @SYMTestCaseDesc Unit tests for fair scheduling, read caching and lazy writing
32 //! @SYMTestActions 0 setup the environment to execute the tests
33 //! 1 Reads a file with different blocksizes
34 //! 2 Write a file with different blocksizes
35 //! 3 Small reads while controlling the cache
36 //! 4 Read operations with and without read ahead
37 //! 5 Write operations with write buffer
38 //! @SYMTestExpectedResults finishes if the implementation of PREQ914 behaves as expected, panics otherwise
39 //! @SYMTestPriority High
40 //! @SYMTestStatus Critical
41 //----------------------------------------------------------------------------------------------
44 //#define SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
47 GLDEF_D RTest test(_L("T_FILECACHE"));
50 GLDEF_D TChar gDriveToTest;
52 GLDEF_D TFileName gSessionPath;
54 GLDEF_D TVolumeInfo gVolInfo; // volume info for current drive
55 GLDEF_D TFileCacheFlags gDriveCacheFlags = TFileCacheFlags(0);
57 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
58 static TFileCacheConfig gFileCacheConfig;
59 static TBool gDisplayCacheFlags = EFalse;
60 static TBool gWriteCacheFlags = EFalse;
61 static TBool gRomPaged = EFalse;
63 static TBool gRunTests = ETrue;
64 static TBool gRunUnitTests = ETrue;
65 static TBool gRunPerformanceTests = EFalse;
66 static TBool gRunManualTests = EFalse;
69 LOCAL_D TInt KMaxFileSize = 768 * 1024;
71 // Chosing a file size of 128K ensures entire file will be cached
72 //LOCAL_D TInt KMaxFileSize = 128 * 1024;
74 LOCAL_D TBuf8<256*1024> DataBuf;
76 const TInt KBufSize = 513 * 1024 - 16;
80 LOCAL_D TPtr8 gBufPtr(NULL, 0);
82 const TReal KOneK = 1024;
83 const TReal KOneMeg = 1024 * KOneK;
85 const TInt KSegmentSize = 4096;
86 const TInt KSegmentSizeMask = (4096-1);
88 GLDEF_D template <class C>
89 GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
91 TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
93 TInt r = fs.ControlIo(drv, fkn, ptrC);
98 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
99 void PrintFileCacheStats(TFileCacheStats& fileCacheStats, TBool aDisplay = ETrue)
101 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
105 test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d) Holes %d Failures (commit %d Lock %d)\n"),
106 fileCacheStats.iFreeCount, fileCacheStats.iUsedCount, fileCacheStats.iAllocatedSegmentCount,fileCacheStats.iLockedSegmentCount,fileCacheStats.iFilesOnClosedQueue, fileCacheStats.iHoleCount, fileCacheStats.iCommitFailureCount, fileCacheStats.iLockFailureCount);
107 test.Printf(_L("File cache: iUncachedPacketsRead %d iUncachedBytesRead %d iUncachedPacketsWritten %d iUncachedBytesWritten %d\n"),
108 fileCacheStats.iUncachedPacketsRead,
109 fileCacheStats.iUncachedBytesRead,
110 fileCacheStats.iUncachedPacketsWritten,
111 fileCacheStats.iUncachedBytesWritten);
114 void PrintFileCacheConfig(TFileCacheConfig& aFileCacheConfig, TBool aDisplay = ETrue)
116 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheConfig, aFileCacheConfig);
117 test (r == KErrNone);
121 test.Printf(_L("File cache:\nDrive %c\nFlags %08X\nFileCacheReadAsync %d\nFairSchedulingLen %d\nCacheSize %d\nMaxReadAheadLen %d\nClosedFileKeepAliveTime %d\nDirtyDataFlushTime %d"),
122 aFileCacheConfig.iDrive + 'A',
123 aFileCacheConfig.iFlags,
124 aFileCacheConfig.iFileCacheReadAsync,
125 aFileCacheConfig.iFairSchedulingLen,
126 aFileCacheConfig.iCacheSize,
127 aFileCacheConfig.iMaxReadAheadLen,
128 aFileCacheConfig.iClosedFileKeepAliveTime,
129 aFileCacheConfig.iDirtyDataFlushTime);
133 void TestDirtyDataWrittenToDisk(TFileCacheStats& fileCacheStats)
135 test.Next(_L("test dirty data has been written to disk"));
136 // wait a maximum of double KDefaultDirtyDataFlushTime for dirty data to be flushed
137 const TInt KWaitTime = 250; // 250 milisecs
138 for (TInt n=0; n<(gFileCacheConfig.iDirtyDataFlushTime/1000)<<1 ; n+= KWaitTime)
140 test.Printf(_L("After %d milisecs : "), n );
141 PrintFileCacheStats(fileCacheStats);
142 User::After(KWaitTime * 1000); // wait 100 ms
143 if (fileCacheStats.iLockedSegmentCount == 0)
146 PrintFileCacheStats(fileCacheStats);
147 test(fileCacheStats.iLockedSegmentCount == 0);
153 gBuf = HBufC8::NewL(KBufSize);
155 gBufPtr.Set(gBuf->Des());
163 LOCAL_C void SetSessionPath(TInt aDrive)
165 gSessionPath=_L("?:\\F32-TST\\");
167 TInt r=TheFs.DriveToChar(aDrive,driveLetter);
169 gSessionPath[0]=(TText)driveLetter;
170 r=TheFs.SetSessionPath(gSessionPath);
174 LOCAL_C void PrintFileMode(TUint aFileMode)
178 buf.Format(_L("FileMode = %08X"), aFileMode);
180 if (aFileMode & EFileWriteBuffered)
181 buf.Append(_L(", EFileWriteBuffered"));
183 if (aFileMode & EFileWriteDirectIO)
184 buf.Append(_L(", EFileWriteDirectIO"));
186 if (aFileMode & EFileReadBuffered)
187 buf.Append(_L(", EFileReadBuffered"));
189 if (aFileMode & EFileReadDirectIO)
190 buf.Append(_L(", EFileReadDirectIO"));
192 if (aFileMode & EFileReadAheadOn)
193 buf.Append(_L(", EFileReadAheadOn"));
195 if (aFileMode & EFileReadAheadOff)
196 buf.Append(_L(", EFileReadAheadOff"));
198 buf.Append(_L("\n"));
202 void FillBuffer(TDes8& aBuffer, TInt aLength)
204 test (aBuffer.MaxLength() >= aLength);
205 for(TInt i=0; i<aLength; i+=2)
207 aBuffer[i]=(TUint8) (i >> 8);
208 aBuffer[i+1]=(TUint8) i;
212 void TestBufferFail(TDes8& aBuffer, TInt aPos, TInt aLength)
214 test.Printf(_L("TestBuffer failed at pos %d len %d\n"), aPos, aLength);
216 #define PRINTCH(ch) ((ch >= 0x20 && ch < 0x7F)?ch:' ')
217 TInt startPos = Max(0, aPos - 64);
218 TInt endPos = startPos + 64;
220 for(TInt n=startPos; n<=endPos; n+=16)
221 RDebug::Print(_L("%08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c]"),
224 aBuffer[n+0], aBuffer[n+1], aBuffer[n+2], aBuffer[n+3], aBuffer[n+4], aBuffer[n+5], aBuffer[n+6], aBuffer[n+7], aBuffer[n+8], aBuffer[n+9], aBuffer[n+10], aBuffer[n+11], aBuffer[n+12], aBuffer[n+13], aBuffer[n+14], aBuffer[n+15],
225 PRINTCH(aBuffer[n+0]), PRINTCH(aBuffer[n+1]), PRINTCH(aBuffer[n+2]), PRINTCH(aBuffer[n+3]), PRINTCH(aBuffer[n+4]), PRINTCH(aBuffer[n+5]), PRINTCH(aBuffer[n+6]), PRINTCH(aBuffer[n+7]), PRINTCH(aBuffer[n+8]), PRINTCH(aBuffer[n+9]), PRINTCH(aBuffer[n+10]), PRINTCH(aBuffer[n+11]), PRINTCH(aBuffer[n+12]), PRINTCH(aBuffer[n+13]), PRINTCH(aBuffer[n+14]), PRINTCH(aBuffer[n+15]));
227 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
229 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheDump, x);
235 void TestBuffer(TDes8& aBuffer, TInt aPos, TInt aLength)
238 for(TInt i=0; i<aLength; i++, pos++)
242 if (aBuffer[pos] != (TUint8) pos-1)
243 TestBufferFail(aBuffer, pos, aLength);
247 if (aBuffer[pos] != (TUint8) (pos >> 8))
248 TestBufferFail(aBuffer, pos, aLength);
254 LOCAL_C void UnitTests()
256 // Test read file handling.
260 test.Start(_L("File cache read and write unit tests"));
262 //TheFs.SetDebugRegister(KCACHE);
270 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
271 TBool simulatelockFailureMode;
272 TFileCacheStats fileCacheStats;
273 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
274 test (r == KErrNone);
275 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
276 test(fileCacheStats.iFilesOnClosedQueue == 0);
279 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
280 // turn OFF lock failure mode
281 simulatelockFailureMode = EFalse;
282 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
283 test (r == KErrNone);
286 TFileName testFile = _L("TEST.BIN");
288 //**********************************
289 // Test Read-Modify-Write
290 //**********************************
291 test.Next(_L("Test read-modify-write"));
292 gBufPtr.SetLength(KBufSize);
293 FillBuffer(gBufPtr, KBufSize);
294 TestBuffer(gBufPtr, 0,KBufSize);
296 TPtr8 readPtr(gBuf->Des());
297 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
298 TInt uncachedBytesRead;
299 TInt uncachedPacketsRead;
302 // create an empty file, so that any writes overlapping segemt boundaries
304 // create a test file using directIO and then re-open it in buffered mode,
305 // so that any writes overlapping segemt boundaries need a read first
306 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO);
308 writePtr.Set(gBuf->Des());
309 r = f.Write(0, writePtr);
312 r = f.Open(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
315 TInt cacheLineLen = 128*1024;
317 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
318 PrintFileCacheStats(fileCacheStats);
319 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
320 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
323 // write 1 partial segment at offset 0 to 7 in segment
324 test.Next(_L("Test read-modify-write #1"));
325 pos = cacheLineLen*0 + KSegmentSize*2 + 0;
327 writePtr.Set(gBuf->Mid(pos, len));
328 r = f.Write(pos, writePtr, len);
330 // read back & verify whole segment
331 pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
332 readPtr.Set(gBufPtr.MidTPtr(pos, len));
333 readPtr.SetLength(len);
335 r = f.Read(pos, readPtr, len);
337 TestBuffer(gBufPtr, pos, len);
339 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
340 PrintFileCacheStats(fileCacheStats);
341 test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
342 test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
343 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
344 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
347 // write 1 partial segment at offset 7 to 4096 in segment
348 test.Next(_L("Test read-modify-write #2"));
349 pos = cacheLineLen*0 + KSegmentSize*3 + 7;
350 len = KSegmentSize - 7;
351 writePtr.Set(gBuf->Mid(pos, len));
352 r = f.Write(pos, writePtr, len);
354 // read back & verify whole segment
355 pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
356 readPtr.Set(gBufPtr.MidTPtr(pos, len));
357 readPtr.SetLength(len);
359 r = f.Read(pos, readPtr, len);
361 TestBuffer(gBufPtr, pos, len);
363 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
364 PrintFileCacheStats(fileCacheStats);
365 test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
366 test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
367 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
368 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
371 // write 1 partial segment at offset 7 to 37 in segment
372 test.Next(_L("Test read-modify-write #3"));
373 pos = cacheLineLen*0 + KSegmentSize*4 + 7;
375 writePtr.Set(gBuf->Mid(pos, len));
376 r = f.Write(pos, writePtr, len);
378 // read back & verify whole segment
379 pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
380 readPtr.Set(gBufPtr.MidTPtr(pos, len));
381 readPtr.SetLength(len);
383 r = f.Read(pos, readPtr, len);
385 TestBuffer(gBufPtr, pos, len);
387 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
388 PrintFileCacheStats(fileCacheStats);
389 test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
390 test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
391 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
392 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
395 // write 2 segments, first and last both partial
396 test.Next(_L("Test read-modify-write #4"));
397 pos = cacheLineLen*1 + KSegmentSize*2 + 3;
398 len = KSegmentSize * 1;
399 writePtr.Set(gBuf->Mid(pos, len));
400 r = f.Write(pos, writePtr, len);
402 // read back & verify whole segment
403 pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
404 readPtr.Set(gBufPtr.MidTPtr(pos, len));
405 readPtr.SetLength(len);
407 r = f.Read(pos, readPtr, len);
409 TestBuffer(gBufPtr, pos, len);
411 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
412 PrintFileCacheStats(fileCacheStats);
413 test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize*2);
414 // should read both segments in one read as they are contiguous
415 test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
416 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
417 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
420 // write 3 segments, first and last both partial
421 test.Next(_L("Test read-modify-write #5"));
422 pos = cacheLineLen*2 + KSegmentSize*2 + 7;
423 len = KSegmentSize * 2;
424 writePtr.Set(gBuf->Mid(pos, len));
425 r = f.Write(pos, writePtr, len);
427 // read back & verify whole segment
428 pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
429 readPtr.Set(gBufPtr.MidTPtr(pos, len));
430 readPtr.SetLength(len);
432 r = f.Read(pos, readPtr, len);
434 TestBuffer(gBufPtr, pos, len);
436 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
437 PrintFileCacheStats(fileCacheStats);
438 test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize*2);
439 test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 2);
440 uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
441 uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
446 //**************************************************************
447 // Test dirty data NOT written to disk if continuously writing to a file which fits in tke cache
448 //**************************************************************
449 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
450 test.Printf(_L("Test dirty data NOT written to disk if continuously writing to a file which fits in tke cache...\n"));
452 // flush closed files queue to empty cache
453 test.Printf(_L("Flushing close queue to empty cache...\n"));
454 r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
457 r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
462 TRequestStatus reqStat;
463 timer.After(reqStat,gFileCacheConfig.iClosedFileKeepAliveTime*3); // write 3 times the flush timer
467 TInt maxLockedSegmentCount = 0;
468 while (reqStat == KRequestPending)
470 bufLen = (bufLen + 1023) & 0x3FFF;
471 len = Min(bufLen, KBufSize - pos);
472 len = Min(len, gFileCacheConfig.iCacheSize-pos);
473 TPtrC8 writePtr = gBuf->Mid(pos, len);
474 r = f.Write(pos, writePtr, len);
477 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
479 // test the locked (i.e. dirty) count always goes up & never down (down would indicate a flush)
480 if (fileCacheStats.iLockedSegmentCount != maxLockedSegmentCount)
481 test.Printf(_L("iLockedSegmentCount %d...\n"), fileCacheStats.iLockedSegmentCount);
483 test(fileCacheStats.iLockedSegmentCount >= maxLockedSegmentCount);
484 maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
485 // wrap to start of file
486 if (pos >= gFileCacheConfig.iCacheSize)
491 test(fileCacheStats.iLockedSegmentCount > 0);
493 if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
494 TestDirtyDataWrittenToDisk(fileCacheStats);
499 //**************************************************************
500 // Test dirty data written to disk
501 //**************************************************************
502 enum {ETestDataWrittenAfterTimeout, ETestDataWrittenAfterFileClose, ETestDataWrittenAfterSessionClose, ETestEnd};
503 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
504 for (testNum = 0; testNum < ETestEnd; testNum++)
506 for (testNum = 0; testNum < 1; testNum++)
511 case ETestDataWrittenAfterTimeout : test.Next(_L("ETestDataWrittenAfterTimeout")); break;
512 case ETestDataWrittenAfterFileClose : test.Next(_L("ETestDataWrittenAfterFileClose")); break;
513 case ETestDataWrittenAfterSessionClose : test.Next(_L("ETestDataWrittenAfterSessionClose")); break;
516 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
517 // flush closed files queue to empty cache
518 test.Printf(_L("Flushing close queue to empty cache...\n"));
519 r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
523 r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
527 gBufPtr.SetLength(KBufSize);
529 test.Printf(_L("writing file in small blocks to test write caching...\n"));
531 FillBuffer(gBufPtr, KBufSize);
532 TestBuffer(gBufPtr, 0,KBufSize);
536 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
537 TInt maxLockedSegmentCount = 0;
538 TInt maxUsedCount = 0;
540 while (pos < KBufSize)
542 bufLen = (bufLen + 1023) & 0x3FFF;
543 len = Min(bufLen, KBufSize - pos);
544 //RDebug::Print(_L("write len %d"), len);
545 TPtrC8 writePtr = gBuf->Mid(pos, len);
546 r = f.Write(pos, writePtr, len);
549 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
550 // PrintFileCacheStats(fileCacheStats);
551 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
553 maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
554 maxUsedCount = Max(maxUsedCount, fileCacheStats.iUsedCount);
557 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
558 test.Next(_L("Test maxiimum locked page and cacheline count is reasonable"));
559 test.Printf(_L("maxLockedSegmentCount %d maxUsedCount %d"), maxLockedSegmentCount, maxUsedCount);
560 test (maxLockedSegmentCount > 0 && maxLockedSegmentCount <= (gFileCacheConfig.iCacheSize * 2) / KSegmentSize );
561 test (maxUsedCount > 0 && maxUsedCount <= 5);
566 if (testNum == ETestDataWrittenAfterTimeout)
568 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
569 if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
570 TestDirtyDataWrittenToDisk(fileCacheStats);
575 if (testNum == ETestDataWrittenAfterFileClose)
578 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
579 test.Next(_L("test dirty data has been written to disk after file close"));
580 PrintFileCacheStats(fileCacheStats);
581 test(fileCacheStats.iLockedSegmentCount == 0);
585 if (testNum == ETestDataWrittenAfterSessionClose)
587 // verify that closing the file server session (i.e. not the file)
588 // flushes the data to disk...
589 // *** NB This is likely to complete sometime AFTER returning from RFs::Close()
590 // *** as the file server doesn't wait for the disconnect thread to complete !!!
594 SetSessionPath(gDrive);
595 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
596 test.Next(_L("Test dirty data is eventually written to disk after session close"));
597 TestDirtyDataWrittenToDisk(fileCacheStats);
598 test(fileCacheStats.iLockedSegmentCount == 0);
602 } // for (TInt testNum = 0; testNum < ETestEnd; testNum++)
605 //#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
606 // PrintFileCacheStats(fileCacheStats);
609 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
610 // flush closed files queue to empty cache
611 test.Printf(_L("Flushing close queue to empty cache...\n"));
612 r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
616 r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileWrite);
621 test (r == KErrNone);
622 test (size = KBufSize);
624 readPtr.Set(gBuf->Des());
626 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
627 // Allocate full cachelines - so we can enable hole testing
628 TBool allocateAllSegmentsInCacheLine = ETrue;
629 r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine);
630 test (r == KErrNone);
631 PrintFileCacheStats(fileCacheStats, EFalse);
632 TInt holesDetected = fileCacheStats.iHoleCount;
633 TInt lockFailures = fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount;
636 test.Next(_L("Test reading a partially filled cacheline"));
637 // create a cacheline with only the first segment filled
638 TInt startPos = KSegmentSize;
641 writePtr.Set(gBuf->Mid(pos, len));
642 r = f.Write(pos, writePtr, len);
645 // read from first & second segments
648 RDebug::Print(_L("+%x, %x\n"), pos, len);
649 readPtr.Set(gBufPtr.MidTPtr(pos, len));
650 readPtr.SetLength(len);
651 r = f.Read(pos, readPtr, len);
653 TestBuffer(gBufPtr, pos, len);
656 test.Next(_L("Test reading an empty segment towards the end of a partially filled cacheline (hole test)"));
657 // read from segment #4 and beyond end of cacheline into next
658 pos = startPos + KSegmentSize * 4;
659 len = KSegmentSize * 33; // 132 K
660 RDebug::Print(_L("+%x, %x\n"), pos, len);
661 readPtr.Set(gBufPtr.MidTPtr(pos, len));
662 readPtr.SetLength(len);
663 r = f.Read(pos, readPtr, len);
665 TestBuffer(gBufPtr, pos, len);
668 test.Next(_L("Test writing to an empty segment towards the end of a partially filled cacheline (hole test)"));
669 // create a cacheline with only the first segment filled
670 startPos = 256 * 1024;
673 writePtr.Set(gBuf->Mid(pos, len));
674 r = f.Write(pos, writePtr, len);
678 // write into segment 3, 4 & 5
679 pos = startPos + KSegmentSize * 2;
680 len = KSegmentSize * 3;
681 writePtr.Set(gBuf->Mid(pos, len));
682 r = f.Write(pos, writePtr, len);
684 // read back whole cacheline & verify
686 len = KSegmentSize * 32; // 128 K
687 RDebug::Print(_L("+%x, %x\n"), pos, len);
688 readPtr.Set(gBufPtr.MidTPtr(pos, len));
689 readPtr.SetLength(len);
690 r = f.Read(pos, readPtr, len);
692 TestBuffer(gBufPtr, pos, len);
694 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
695 PrintFileCacheStats(fileCacheStats);
696 if (fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount != lockFailures)
700 test.Printf(_L("Lock failures detected on paged ROM, abandoning hole test"));
704 test.Printf(_L("Unexpected lock failures detected on unpaged ROM!!!"));
710 test(fileCacheStats.iHoleCount > holesDetected);
712 // Don't allocate full cachelines any more
713 allocateAllSegmentsInCacheLine = EFalse;
714 r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine);
715 test (r == KErrNone);
721 gBufPtr.SetLength(KBufSize);
725 readPtr.SetLength(0);
728 // read from middle of fifth sector to half way thru seventh
729 test.Next(_L("Test read that spans two pages"));
732 RDebug::Print(_L("+%x, %x\n"), pos, len);
733 readPtr.Set(gBufPtr.MidTPtr(pos, len));
734 readPtr.SetLength(len);
735 r = f.Read(pos, readPtr, len);
737 TestBuffer(gBufPtr, pos, len);
741 // read to end of file
742 test.Next(_L("Test reading past end of file"));
743 pos = KBufSize - 0x100; // 0xfb05;
744 len = KBufSize - pos;
745 // pos = KBufSize - 16;
747 // len = Min(len, KBufSize-pos);
748 RDebug::Print(_L("+%x, %x\n"), pos, len);
749 readPtr.Set(gBufPtr.MidTPtr(pos, len));
750 readPtr.SetLength(len);
751 r = f.Read(pos, readPtr, len/* + 0x67*/);
754 test.Next(_L("Test async reads"));
755 // issue 2 async reads
756 pos = KSegmentSize*7 + 16;
758 RDebug::Print(_L("+%x, %x\n"), pos, len);
759 readPtr.Set(gBufPtr.MidTPtr(pos, len));
760 readPtr.SetLength(len);
762 TInt pos2 = pos + len;
763 TInt len2 = KSegmentSize;
764 TPtr8 readPtr2 = gBuf->Des();
765 readPtr2.Set(gBufPtr.MidTPtr(pos2, len2));
766 readPtr2.SetLength(len2);
768 TRequestStatus status1(KRequestPending);
769 TRequestStatus status2(KRequestPending);
771 f.Read(pos, readPtr, len, status1);
772 f.Read(readPtr2, len2, status2);
775 User::WaitForRequest(status1);
776 User::WaitForRequest(status2);
777 test.Printf(_L("status1 %d status2 %d\n"), status1.Int(), status2.Int());
778 TestBuffer(gBufPtr, pos, len);
779 TestBuffer(gBufPtr, pos2, len2);
782 test.Next(_L("Read entire file"));
784 for (pos = 0, len = 1; len <= 1024 && pos < KBufSize; len = (len+1) & 0x3FF)
786 len = Min(len, KBufSize-pos);
787 // RDebug::Print(_L("+%x, %x\n"), pos, len);
788 readPtr.Set(gBufPtr.MidTPtr(pos, len));
789 readPtr.SetLength(len);
791 r = f.Read(pos, readPtr, len);
793 TestBuffer(gBufPtr, pos, len);
798 TestBuffer(gBufPtr, 0, KBufSize);
800 // read from position zero to ensure it's cached
803 readPtr.Set(gBufPtr.MidTPtr(pos, len));
804 readPtr.SetLength(len);
805 r = f.Read(pos, readPtr, len);
807 TestBuffer(gBufPtr, pos, len);
813 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
814 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
815 test (r == KErrNone);
816 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
817 test(fileCacheStats.iFilesOnClosedQueue == 1);
822 //**************************************************************
823 // Test closed file queue
824 //**************************************************************
827 ETestCloseQueueEmptyAfterTimeout,
828 ETestCloseQueueEmptyAfterOpenWithDirectIo,
829 ETestCloseQueueEmptyAfterDelete,
831 for (testNum = 0; testNum < ETestCloseEnd; testNum++)
834 test.Next(_L("Reopen file & verify closed queue is empty"));
836 r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered);
840 readPtr.Set(gBufPtr.MidTPtr(pos, len));
841 readPtr.SetLength(len);
842 r = f.Read(pos, readPtr, len);
844 TestBuffer(gBufPtr, pos, len);
847 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
848 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
849 test (r == KErrNone);
850 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
851 test(fileCacheStats.iFilesOnClosedQueue == 0);
855 test.Next(_L("close & verify file is back on close queue"));
858 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
859 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
860 test (r == KErrNone);
861 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
862 test(fileCacheStats.iFilesOnClosedQueue == 1);
865 if (testNum == ETestCloseQueueEmptyAfterDelete)
867 test.Next(_L("delete file and verify closed queue is empty"));
868 r = TheFs.Delete(testFile);
871 if (testNum == ETestCloseQueueEmptyAfterTimeout)
873 test.Next(_L("wait for a while and verify closed queue is empty"));
874 // wait for closed file queue to empty
875 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
876 User::After(gFileCacheConfig.iClosedFileKeepAliveTime + 1000000);
879 if (testNum == ETestCloseQueueEmptyAfterOpenWithDirectIo)
881 test.Next(_L("Re-open file in directIo mode and then close and verify closed queue is empty"));
882 r = f.Open(TheFs, testFile, EFileRead | EFileReadDirectIO);
887 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
888 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
889 test (r == KErrNone);
890 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
891 test(fileCacheStats.iFilesOnClosedQueue == 0);
895 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
896 // turn lock failure mode back ON (if enabled)
897 simulatelockFailureMode = ETrue;
898 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
899 test (r == KErrNone);
902 //**************************************************************
903 // Test opening a file with a silly open mode flags combinations
904 //**************************************************************
905 test.Next(_L("Open file with illegal cache on/off bits"));
906 r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileReadDirectIO);
907 test_Value(r, r==KErrArgument);
908 r = f.Open(TheFs, testFile, EFileRead | EFileWriteBuffered | EFileWriteDirectIO);
909 test_Value(r, r==KErrArgument);
910 //**********************************
911 // Test that continuously appending to a file yields the correct size...
912 // NB: Must have lock failure more ON in debug mode for this test to pass
913 //**********************************
914 test.Next(_L("Test appending to a file & checking the file size..."));
915 gBufPtr.SetLength(KBufSize);
917 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered);
920 const TInt KWriteLen = KSegmentSize+1;
921 writePtr.Set(gBuf->Des().Ptr(), KWriteLen);
923 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
924 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
925 test (r == KErrNone);
926 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount);
927 TInt writeThroughWithDirtyDataCountOld = fileCacheStats.iWriteThroughWithDirtyDataCount;
928 TInt writeThroughWithDirtyDataCountNew = writeThroughWithDirtyDataCountOld;
932 for (TInt i=0; i<4; i++)
935 r = f.SetSize(fileSize);
936 test (r == KErrNone);
937 for (pos = 0; pos < KMaxFileSize; )
939 r = f.Write(pos, writePtr);
942 test.Printf(_L("Iter #%d, write pos %d size %d, Write() returned %d"), i, pos, fileSize, r);
944 test.Printf(_L("Flush returned %d"), r);
948 pos+= writePtr.Length();
950 r = f.Size(fileSize);
951 test (r == KErrNone);
954 test.Printf(_L("Iter #%d, write pos %d != size %d"), i, pos, fileSize);
956 test.Printf(_L("Flush returned %d"), r);
959 test (fileSize == pos);
961 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
962 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
963 test (r == KErrNone);
964 writeThroughWithDirtyDataCountNew = fileCacheStats.iWriteThroughWithDirtyDataCount;
965 if (writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld)
967 test.Printf(_L("Iter #%d, write pos %d size %d"), i, pos, fileSize);
968 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount);
977 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
978 test(writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld);
985 //TheFs.SetDebugRegister(0);
990 // This thread is used to test what happens if requests are sent to the file server
991 // while the drive thread is hung in the critical notifier server. The requests should
992 // complete immediately with KErrNotReady
993 TInt ReaderThread(TAny* aFileName)
995 RTest test(_L("T_FILECACHE, ReaderThread"));
997 TDesC& fileName = *(TDesC*) aFileName;
1000 TInt r = fs.Connect();
1002 r = fs.SetSessionPath(gSessionPath);
1007 r = file.Open(fs, fileName, EFileRead | EFileReadBuffered | EFileShareReadersOrWriters);
1011 timer.CreateLocal();
1012 TRequestStatus reqStat;
1013 timer.After(reqStat,10000000); // Read for 10 secs
1016 TInt KReadLen = 32768;
1017 TInt retCode = KErrNone;
1019 for (TInt i=0; reqStat == KRequestPending; i++)
1021 r = file.Read(pos, DataBuf, KReadLen);
1022 test_Value(r, r == KErrNone || r == KErrNotReady);
1024 //test.Printf(_L("ReaderThread: iter %d, read at %d ret %d\n"), i, pos, r);
1025 if (r == KErrNotReady)
1027 else if (r == KErrNone)
1028 pos = DataBuf.Length() == 0 ? 0: pos + DataBuf.Length();
1029 if (retCode == KErrNotReady)
1030 test.Printf(_L("ReaderThread: iter %d, read at %d ret %d \n"), i, pos, r);
1045 gBufPtr.SetLength(KBufSize);
1046 FillBuffer(gBufPtr, KBufSize);
1047 TestBuffer(gBufPtr, 0,KBufSize);
1050 writePtr.Set(gBuf->Des());
1052 TFileName testFile = _L("TEST.BIN");
1055 test.Next(_L("Testing writing and then closing with an immediate simulated card eject"));
1056 test.Printf(_L("**********************************************************\n"));
1057 test.Printf(_L("When critical notifier message appears, PRESS RETRY\n"));
1058 test.Printf(_L("**********************************************************\n"));
1060 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
1063 test.Printf(_L("Writing...."));
1064 r = f.Write(0, writePtr);
1065 test.Printf(_L("Write returned %d\n"), r);
1068 r=TheFs.ControlIo(gDrive, KControlIoSimulateFileCacheWriteFailure);
1075 // wait for re-insertion....
1078 r = TheFs.Entry(testFile, entry);
1079 User::After(500000);
1081 while (r == KErrNotReady);
1084 test.Printf(_L("FileSize %d expected %d\n"), entry.iSize, writePtr.Length());
1086 // test all data is written to disk
1087 test (entry.iSize == writePtr.Length());
1091 test.Next(_L("Testing writing and then ejecting card"));
1093 // r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO);
1094 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
1096 writePtr.Set(gBuf->Des());
1099 // set the file size first so that the cluster chain already exists
1100 r = f.SetSize(writePtr.Length());
1101 test.Printf(_L("SetSize returned %d"));
1103 // Create another thread which will attempt to issue reads while this thread is suspended
1104 // These reads should complete with KErrNotReady
1105 const TInt KHeapSize = 32768;
1106 test.Printf(_L("Creating file-reading thread\n"));
1107 RThread readerThread;
1108 readerThread.Create(_L("FileReaderThread"), ReaderThread, KDefaultStackSize, KHeapSize, KHeapSize, &testFile);
1110 test.Printf(_L("Writing...."));
1111 r = f.Write(0, writePtr);
1112 test.Printf(_L("Write returned %d\n"), r);
1115 test.Printf(_L("Waiting 5 seconds.\n"));
1116 test.Printf(_L("**********************************************************\n"));
1117 test.Printf(_L("Please press a key, EJECT MEDIA BEFORE WRITE TIMER EXPIRES,\n"));
1118 test.Printf(_L("wait for critical notifier, replace media and retry\n"));
1119 test.Printf(_L("**********************************************************\n"));
1120 // test.Printf(_L("press any key..."));
1122 test.Printf(_L("\n"));
1124 test.Printf(_L("Writing...."));
1125 r = f.Write(0, writePtr);
1126 test.Printf(_L("Write returned %d\n"), r);
1127 readerThread.Resume();
1129 User::After(5000000);
1133 test.Printf(_L("Flushing....\n"));
1135 test.Printf(_L("Flush returned %d\n"), r);
1137 User::After(5000000);
1139 while (r != KErrNone);
1142 // r = f.Write(0, writePtr);
1143 // test.Printf(_L("Write returned %d"));
1145 // test_KErrNone(r);
1147 test.Next(_L("Testing reader thread completed with KErrNotReady"));
1148 TRequestStatus status;
1149 readerThread.Logon(status);
1150 readerThread.Resume();
1151 User::WaitForRequest(status);
1152 test.Printf(_L("ReaderThread status %d\n"), status.Int());
1153 test (status.Int() == KErrNotReady);
1154 readerThread.Close();
1156 test.Printf(_L("press any key..."));
1158 test.Printf(_L("\n"));
1164 LOCAL_C void DoTestFileRead(TUint aFileMode, TInt aReadBlockSize)
1171 TInt r=file.Open(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
1174 TInt maxReadCount=KMaxFileSize/aReadBlockSize;
1181 timer.CreateLocal();
1182 TRequestStatus reqStat;
1183 timer.After(reqStat,10000000); // After 10 secs
1184 startTime.HomeTime();
1189 file.Seek(ESeekStart,pos);
1190 for(TInt ii=0;ii<maxReadCount;ii++)
1192 r = file.Read(DataBuf,aReadBlockSize);
1195 for(TInt jj=0;jj<DataBuf.Size();jj++)
1197 if (DataBuf[jj] != ((jj+ii*aReadBlockSize)%256))
1199 test.Printf(_L("len %d size %d jj %d ii %d"), DataBuf.Length(), DataBuf.Size(), jj, ii);
1202 // test(DataBuf[jj] == ((jj+ii*aReadBlockSize)%256) );
1205 if (reqStat!=KRequestPending)
1209 TInt functionCalls=loopCount*maxReadCount+ii;
1210 // TReal rate = ( TReal32(functionCalls) * TReal32(aReadBlockSize) ) / 10;
1211 // test.Printf(_L("Read %5d byte blocks:\t%11.3f KBytes/s\n"), aReadBlockSize, rate / (KOneK));
1213 TReal transferRate =
1214 (TReal32(functionCalls) * TReal32(aReadBlockSize)) /
1215 TReal(endTime.MicroSecondsFrom(startTime).Int64()) * TReal(KOneMeg) / TReal(KOneK);
1216 test.Printf(_L("Read %5d byte blocks:\t%11.3f KBytes/s\n"), aReadBlockSize,transferRate);
1228 LOCAL_C void DoTestFileWrite(TUint aFileMode, TInt aWriteBlockSize)
1230 // Do Write benchmark
1233 DataBuf.SetLength(aWriteBlockSize);
1234 TInt maxWriteCount=KMaxFileSize/aWriteBlockSize;
1238 TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
1239 test (r == KErrNone);
1245 timer.CreateLocal();
1246 TRequestStatus reqStat;
1247 timer.After(reqStat,10000000); // After 10 secs
1248 startTime.HomeTime();
1255 file.Seek(ESeekStart,pos);
1256 for(TInt ii=0;ii<maxWriteCount;ii++)
1258 r = file.Write(DataBuf);
1260 if (reqStat!=KRequestPending)
1263 // TReal rate = (TReal32(functionCalls) * TReal32(aWriteBlockSize)) / 10;
1264 // test.Printf(_L("Write %5d byte blocks:\t%11.3f KBytes/s\n"), aWriteBlockSize, rate / (KOneK));
1271 TInt functionCalls=loopCount*maxWriteCount+ii;
1272 TReal transferRate =
1273 (TReal32(functionCalls) * TReal32(aWriteBlockSize)) /
1274 TReal(endTime.MicroSecondsFrom(startTime).Int64()) * TReal(KOneMeg) / TReal(KOneK);
1275 test.Printf(_L("Write %5d byte blocks:\t%11.3f KBytes/s\n"), aWriteBlockSize,transferRate);
1279 TInt r=TheFs.Delete(_L("WRITETST"));
1288 LOCAL_C void TestFileRead(TUint aFileMode)
1290 // Benchmark read method
1294 // ClearSessionDirectory();
1295 test.Next(_L("Benchmark read method"));
1296 // test.Printf(_L("aFileMode %08X\n"), aFileMode);
1297 PrintFileMode(aFileMode);
1300 TBuf8<1024> testdata(1024);
1301 for (TInt i=0;i<testdata.MaxSize();i++)
1302 testdata[i]=TText8(i%256);
1304 // create & fill the file
1306 TInt r=file.Replace(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
1309 test.Printf(_L("Creating test file....."));
1310 TInt count=KMaxFileSize/testdata.Length();
1312 file.Write(testdata);
1314 test.Printf(_L("done.\n"));
1316 #ifdef SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
1318 DoTestFileRead(aFileMode, 1);
1319 DoTestFileRead(aFileMode, 2);
1320 DoTestFileRead(aFileMode, 4);
1321 DoTestFileRead(aFileMode, 8);
1322 DoTestFileRead(aFileMode, 16);
1323 DoTestFileRead(aFileMode, 32);
1324 DoTestFileRead(aFileMode, 64);
1325 DoTestFileRead(aFileMode, 128);
1326 DoTestFileRead(aFileMode, 256);
1327 DoTestFileRead(aFileMode, 512);
1328 DoTestFileRead(aFileMode, 1024);
1329 DoTestFileRead(aFileMode, 2048);
1330 DoTestFileRead(aFileMode, 4096);
1331 DoTestFileRead(aFileMode, 8192);
1332 DoTestFileRead(aFileMode, 16384);
1333 DoTestFileRead(aFileMode, 32768);
1334 DoTestFileRead(aFileMode, 65536);
1335 DoTestFileRead(aFileMode, 131072);
1337 //TheFs.SetDebugRegister(KCACHE);
1338 DoTestFileRead(aFileMode, 1);
1339 DoTestFileRead(aFileMode, 16);
1340 DoTestFileRead(aFileMode, 512);
1341 //TheFs.SetDebugRegister(0);
1342 DoTestFileRead(aFileMode, 4 * 1024);
1343 DoTestFileRead(aFileMode, 32 * 1024);
1344 DoTestFileRead(aFileMode, 64 * 1024);
1345 DoTestFileRead(aFileMode, 128 * 1024);
1346 DoTestFileRead(aFileMode, 256 * 1024);
1349 r=TheFs.Delete(_L("READTEST.XXX"));
1357 LOCAL_C void TestFileWrite(TUint aFileMode)
1359 // Benchmark write method
1362 // ClearSessionDirectory();
1363 test.Next(_L("Benchmark write method"));
1364 // test.Printf(_L("aFileMode %08X\n"), aFileMode);
1365 PrintFileMode(aFileMode);
1369 // TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
1370 // test_KErrNone(r);
1373 #ifdef SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
1374 DoTestFileWrite(aFileMode, 1);
1375 DoTestFileWrite(aFileMode, 2);
1376 DoTestFileWrite(aFileMode, 4);
1377 DoTestFileWrite(aFileMode, 8);
1378 DoTestFileWrite(aFileMode, 16);
1379 DoTestFileWrite(aFileMode, 32);
1380 DoTestFileWrite(aFileMode, 64);
1381 DoTestFileWrite(aFileMode, 128);
1382 DoTestFileWrite(aFileMode, 256);
1383 DoTestFileWrite(aFileMode, 512);
1384 DoTestFileWrite(aFileMode, 1024);
1385 DoTestFileWrite(aFileMode, 2048);
1386 DoTestFileWrite(aFileMode, 4096);
1387 DoTestFileWrite(aFileMode, 8192);
1388 DoTestFileWrite(aFileMode, 16384);
1389 DoTestFileWrite(aFileMode, 32768);
1390 DoTestFileWrite(aFileMode, 65536);
1391 DoTestFileWrite(aFileMode, 131072);
1393 DoTestFileWrite(aFileMode, 1);
1394 DoTestFileWrite(aFileMode, 16);
1395 DoTestFileWrite(aFileMode, 512);
1396 DoTestFileWrite(aFileMode, 4 * 1024);
1397 DoTestFileWrite(aFileMode, 32 * 1024);
1398 DoTestFileWrite(aFileMode, 64 * 1024);
1399 DoTestFileWrite(aFileMode, 128 * 1024);
1400 DoTestFileWrite(aFileMode, 256 * 1024);
1407 CMD_DISPLAY_CACHE_FLAGS,
1408 CMD_WRITE_CACHE_FLAGS,
1409 CMD_PERFORMANCE_TEST,
1414 class CommandLineOption {
1416 CommandLineOption(const TPtrC &s, CommandId i) : str(s), id(i) { }
1422 CommandLineOption() { }
1425 // Lists of command line options
1426 static const CommandLineOption commandList[] = {
1427 CommandLineOption(_L("-help"), CMD_HELP),
1428 CommandLineOption(_L("-h"), CMD_HELP),
1429 CommandLineOption(_L("-?"), CMD_HELP),
1430 CommandLineOption(_L("/?"), CMD_HELP),
1431 CommandLineOption(_L("-d"), CMD_DISPLAY_CACHE_FLAGS),
1432 CommandLineOption(_L("-w"), CMD_WRITE_CACHE_FLAGS),
1433 CommandLineOption(_L("-p"), CMD_PERFORMANCE_TEST),
1434 CommandLineOption(_L("-m"), CMD_MANUAL_TEST),
1439 LOCAL_C void printHelp() {
1440 test.Printf(_L("Option Explanation\r\n"));
1441 test.Printf(_L("-help Print this text\r\n"));
1442 test.Printf(_L("-d Display cache flags\n"));
1443 test.Printf(_L("-p Performance test\n"));
1448 /////////////////////////////////////////////////////////////////////////////
1450 // bool parseCommandLine()
1456 // true if command line options was correct, false if any command was
1460 // Parses the command line
1462 /////////////////////////////////////////////////////////////////////////////
1464 //TBuf<512> commandLine;
1467 LOCAL_C bool ParseCommandLine( const TDesC& aCommand )
1470 TInt tokenCount = 0;
1475 for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
1480 // Search the list of commands for a match.
1482 CommandId commandId = CMD_NO_COMMAND;
1483 for (TUint i = 0; i < sizeof commandList / sizeof commandList[0]; i++)
1485 if (token.CompareF(commandList[i].str) == 0)
1488 // Found a matching string
1490 commandId = commandList[i].id;
1497 case CMD_NO_COMMAND:
1499 TFileName thisfile=RProcess().FileName();
1500 if (token.MatchF(thisfile)==0)
1502 token.Set(lex.NextToken());
1504 test.Printf(_L("CLP=%S\n"),&token);
1506 TChar ch = token[0];
1509 if(token.Length()!=0)
1511 gDriveToTest=token[0];
1512 gDriveToTest.UpperCase();
1526 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1527 case CMD_WRITE_CACHE_FLAGS:
1529 token.Set(lex.NextToken());
1530 if (token.Length() == 0) {
1535 // Extract flags (in hex) from next token.
1537 TPtrC numStr(token);
1539 TInt r = TLex(numStr).Val(val, EHex);
1540 if (r != KErrNone) {
1544 gDriveCacheFlags = TFileCacheFlags(val);
1545 gWriteCacheFlags = ETrue;
1550 case CMD_DISPLAY_CACHE_FLAGS:
1551 gDisplayCacheFlags = ETrue;
1555 case CMD_PERFORMANCE_TEST:
1556 gRunPerformanceTests = ETrue;
1557 gRunUnitTests = EFalse;
1560 case CMD_MANUAL_TEST:
1561 gRunManualTests = ETrue;
1562 gRunUnitTests = EFalse;
1566 test.Printf(_L("Sorry, command option '%S' not implemented\n"),
1576 LOCAL_C TBool parseCommandLine() {
1578 // Loop through all tokens in the command line
1580 TInt cmdLineLen = User::CommandLineLength();
1581 HBufC* cmdLineBuf = HBufC::New( cmdLineLen );
1586 TPtr ptr = cmdLineBuf->Des();
1587 User::CommandLine(ptr);
1589 bool err = ParseCommandLine( *cmdLineBuf );
1594 GLDEF_C void CallTestsL()
1596 // Do tests relative to the session path
1601 TVolumeInfo volInfo;
1602 TInt r = TheFs.Volume(volInfo, gDrive);
1603 test (r == KErrNone);
1606 r = TheFs.ExtensionName(extName,gDrive, 0);
1609 test.Printf(_L("File system extension present (%S)\n"), &extName);
1612 if ((volInfo.iDrive.iType == EMediaRam) ||
1613 ((gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn)) == 0))
1615 if (gRunPerformanceTests)
1617 TestFileRead(EFileReadDirectIO);
1618 TestFileWrite(EFileWriteDirectIO);
1627 if (gRunManualTests)
1632 if (gRunPerformanceTests)
1634 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1635 // turn OFF lock failure mode
1636 TBool simulatelockFailureMode = EFalse;
1637 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
1638 test (r == KErrNone);
1641 TestFileRead(EFileReadDirectIO);
1642 if (gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn))
1644 TestFileRead(EFileReadBuffered | EFileReadAheadOff);
1645 TestFileRead(EFileReadBuffered | EFileReadAheadOn);
1648 TestFileWrite(EFileWriteDirectIO);
1650 if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
1651 TestFileWrite(EFileWriteBuffered);
1654 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1655 // turn lock failure mode back ON (if enabled)
1656 simulatelockFailureMode = ETrue;
1657 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
1658 test (r == KErrNone);
1660 } // if (gRunPerformanceTests)
1667 LOCAL_C void DoTests(TInt aDrive)
1669 // Do testing on aDrive
1673 SetSessionPath(aDrive);
1675 // !!! Disable platform security tests until we get the new APIs
1676 // if(User::Capability() & KCapabilityRoot)
1677 // CheckMountLFFS(TheFs,driveLetter);
1679 User::After(1000000);
1681 TInt r=TheFs.MkDirAll(gSessionPath);
1682 test_Value(r, r == KErrNone || r == KErrAlreadyExists);
1683 TheFs.ResourceCountMarkStart();
1685 TRAP(r,CallTestsL());
1688 TheFs.ResourceCountMarkEnd();
1692 void Format(TInt aDrive)
1694 // Format current drive
1698 test.Next(_L("Format"));
1699 TBuf<4> driveBuf=_L("?:\\");
1700 driveBuf[0]=(TText)(aDrive+'A');
1703 TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
1704 //TInt r=format.Open(TheFs,driveBuf,EFullFormat,count);
1705 test.Printf(_L("RFormat::Open() returned %d\n"), r);
1709 TInt r=format.Next(count);
1715 GLDEF_C TInt E32Main()
1717 // Test with drive nearly full
1721 CTrapCleanup* cleanup;
1722 cleanup=CTrapCleanup::New();
1726 TBool parseOk = parseCommandLine();
1728 User::Leave(KErrNotSupported);
1731 TInt r = TheFs.Connect();
1734 r=TheFs.CharToDrive(gDriveToTest,gDrive);
1737 #if !defined(__WINS__)
1738 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1739 test.Start(_L("Check that the rom is paged"));
1740 TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1741 if (romHeader->iPageableRomStart != NULL)
1743 test.Printf(_L("ROM is paged\n"));
1749 // Get the TFileCacheFlags for this drive
1750 r = TheFs.Volume(gVolInfo, gDrive);
1751 if (r == KErrNotReady)
1754 TInt err = TheFs.Drive(info,gDrive);
1756 if (info.iType == EMediaNotPresent)
1757 test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
1759 test.Printf(_L("medium found (type %d) but drive %c: not ready\nPrevious test may have hung; else, check hardware.\n"), (TInt)info.iType, (TUint)gDriveToTest);
1761 else if (r == KErrCorrupt)
1763 test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
1766 gDriveCacheFlags = gVolInfo.iFileCacheFlags;
1767 test.Printf(_L("DriveCacheFlags for drive %C = %08X\n"), (TInt) gDriveToTest, gDriveCacheFlags);
1769 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1770 PrintFileCacheConfig(gFileCacheConfig, gDrive);
1772 if (gDisplayCacheFlags)
1774 test.Printf(_L("Press any key...\n"));
1778 if (gWriteCacheFlags)
1780 test.Printf(_L("Writing DriveCacheFlags for drive %C = %08X\n"), (TInt) gDriveToTest, gDriveCacheFlags);
1781 r = controlIo(TheFs,gDrive, KControlIoFileCacheFlagsWrite, gDriveCacheFlags);
1782 test (r == KErrNone);
1791 test.Start(_L("Starting tests..."));
1793 if ((gVolInfo.iDrive.iMediaAtt & KMediaAttFormattable))
1796 //TheFs.SetDebugRegister(KCACHE);
1798 //TheFs.SetDebugRegister(0);
1803 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1804 TFileCacheStats fileCacheStats;
1805 PrintFileCacheStats(fileCacheStats);