kerneltest/f32test/server/t_filecache.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
child 131 e880629062dd
child 248 0ffb4e86fcc9
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // f32test\server\t_filecache.cpp
       
    15 // 
       
    16 //
       
    17 #define __E32TEST_EXTENSION__
       
    18 #include <f32file.h>
       
    19 #include <e32test.h>
       
    20 #include <e32svr.h> 
       
    21 #include <f32dbg.h>
       
    22 #include "t_server.h"
       
    23 #include <e32twin.h>
       
    24 #include <e32rom.h>
       
    25 
       
    26 
       
    27 //----------------------------------------------------------------------------------------------
       
    28 //! @SYMTestCaseID      PBASE-T_FILECACHE-0189
       
    29 //! @SYMTestType        UT
       
    30 //! @SYMPREQ            PREQ914
       
    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 //----------------------------------------------------------------------------------------------
       
    42 
       
    43 
       
    44 //#define SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
       
    45 
       
    46 
       
    47 GLDEF_D RTest test(_L("T_FILECACHE"));
       
    48 
       
    49 GLDEF_D	RFs TheFs;
       
    50 GLDEF_D TChar gDriveToTest;
       
    51 GLDEF_D TInt gDrive;
       
    52 GLDEF_D TFileName gSessionPath;
       
    53 
       
    54 GLDEF_D TVolumeInfo gVolInfo;	// volume info for current drive
       
    55 GLDEF_D TFileCacheFlags gDriveCacheFlags = TFileCacheFlags(0);
       
    56 
       
    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;
       
    62 #endif
       
    63 static TBool gRunTests = ETrue;
       
    64 static TBool gRunUnitTests = ETrue;
       
    65 static TBool gRunPerformanceTests = EFalse;
       
    66 static TBool gRunManualTests = EFalse;
       
    67 
       
    68 
       
    69 LOCAL_D TInt KMaxFileSize = 768 * 1024;
       
    70 
       
    71 // Chosing a file size of 128K ensures entire file will be cached
       
    72 //LOCAL_D TInt KMaxFileSize = 128 * 1024;
       
    73 
       
    74 LOCAL_D TBuf8<256*1024> DataBuf;
       
    75 
       
    76 const TInt KBufSize = 513 * 1024 - 16;
       
    77 HBufC8* gBuf = NULL;
       
    78 
       
    79 
       
    80 LOCAL_D TPtr8 gBufPtr(NULL, 0);
       
    81 
       
    82 const TReal KOneK = 1024;
       
    83 const TReal KOneMeg = 1024 * KOneK;
       
    84 
       
    85 const TInt KSegmentSize = 4096;
       
    86 const TInt KSegmentSizeMask = (4096-1);
       
    87 
       
    88 GLDEF_D template <class C>
       
    89 GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
       
    90 {
       
    91     TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
       
    92 
       
    93     TInt r = fs.ControlIo(drv, fkn, ptrC);
       
    94 
       
    95     return r;
       
    96 }
       
    97 
       
    98 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
    99 void PrintFileCacheStats(TFileCacheStats& fileCacheStats, TBool aDisplay = ETrue)
       
   100 	{
       
   101 	TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
       
   102 	test_KErrNone(r);
       
   103 	if (!aDisplay)
       
   104 		return;
       
   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);
       
   112 	}
       
   113 
       
   114 void PrintFileCacheConfig(TFileCacheConfig& aFileCacheConfig, TBool aDisplay = ETrue)
       
   115 	{
       
   116 	TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheConfig, aFileCacheConfig);
       
   117 	test (r == KErrNone);
       
   118 	if (!aDisplay)
       
   119 		return;
       
   120 	
       
   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);
       
   130 	
       
   131 	}
       
   132 
       
   133 void TestDirtyDataWrittenToDisk(TFileCacheStats& fileCacheStats)
       
   134 	{
       
   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)
       
   139 		{
       
   140 		test.Printf(_L("After %d milisecs : "), n );
       
   141 		PrintFileCacheStats(fileCacheStats);
       
   142 		User::After(KWaitTime * 1000);		// wait 100 ms
       
   143 		if (fileCacheStats.iLockedSegmentCount == 0)
       
   144 			break;
       
   145 		}
       
   146 	PrintFileCacheStats(fileCacheStats);
       
   147 	test(fileCacheStats.iLockedSegmentCount == 0);
       
   148 	}
       
   149 #endif 
       
   150 
       
   151 void TestsInit()
       
   152 	{
       
   153 	gBuf = HBufC8::NewL(KBufSize);
       
   154 	test(gBuf!=NULL);
       
   155 	gBufPtr.Set(gBuf->Des());
       
   156 	}
       
   157 void TestsEnd()
       
   158 	{
       
   159 	delete gBuf;
       
   160 	gBuf = NULL;
       
   161 	}
       
   162 
       
   163 LOCAL_C void SetSessionPath(TInt aDrive)
       
   164 	{
       
   165 	gSessionPath=_L("?:\\F32-TST\\");
       
   166 	TChar driveLetter;
       
   167 	TInt r=TheFs.DriveToChar(aDrive,driveLetter);
       
   168 	test_KErrNone(r);
       
   169 	gSessionPath[0]=(TText)driveLetter;
       
   170 	r=TheFs.SetSessionPath(gSessionPath);
       
   171 	test_KErrNone(r);
       
   172 	}
       
   173 
       
   174 LOCAL_C void PrintFileMode(TUint aFileMode)
       
   175 	{
       
   176 	TBuf<80> buf;
       
   177 
       
   178 	buf.Format(_L("FileMode = %08X"), aFileMode);
       
   179 
       
   180 	if (aFileMode & EFileWriteBuffered)
       
   181 		buf.Append(_L(", EFileWriteBuffered"));
       
   182 
       
   183 	if (aFileMode & EFileWriteDirectIO)
       
   184 		buf.Append(_L(", EFileWriteDirectIO"));
       
   185 
       
   186 	if (aFileMode & EFileReadBuffered)
       
   187 		buf.Append(_L(", EFileReadBuffered"));
       
   188 
       
   189 	if (aFileMode & EFileReadDirectIO)
       
   190 		buf.Append(_L(", EFileReadDirectIO"));
       
   191 
       
   192 	if (aFileMode & EFileReadAheadOn)
       
   193 		buf.Append(_L(", EFileReadAheadOn"));
       
   194 
       
   195 	if (aFileMode & EFileReadAheadOff)
       
   196 		buf.Append(_L(", EFileReadAheadOff"));
       
   197 
       
   198 	buf.Append(_L("\n"));
       
   199 	test.Printf(buf);
       
   200 	}
       
   201 
       
   202 void FillBuffer(TDes8& aBuffer, TInt aLength)
       
   203 	{
       
   204 	test (aBuffer.MaxLength() >= aLength);
       
   205 	for(TInt i=0; i<aLength; i+=2)
       
   206 		{
       
   207 		aBuffer[i]=(TUint8) (i >> 8);
       
   208 		aBuffer[i+1]=(TUint8) i;
       
   209 		}
       
   210 	}
       
   211 
       
   212 void TestBufferFail(TDes8& aBuffer, TInt aPos, TInt aLength)
       
   213 	{
       
   214 	test.Printf(_L("TestBuffer failed at pos %d len %d\n"), aPos, aLength);
       
   215 
       
   216 	#define PRINTCH(ch) ((ch >= 0x20 && ch < 0x7F)?ch:' ')
       
   217 	TInt startPos = Max(0, aPos - 64);
       
   218 	TInt endPos = startPos + 64;
       
   219 
       
   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]"), 
       
   222 			//&aBuffer[aPos+n],
       
   223 			n,
       
   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]));
       
   226 
       
   227 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   228 		TInt x;
       
   229 		TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheDump, x);
       
   230 		test_KErrNone(r);
       
   231 #endif
       
   232 	test (0);
       
   233 	}
       
   234 
       
   235 void TestBuffer(TDes8& aBuffer, TInt aPos, TInt aLength)
       
   236 	{
       
   237 	TInt pos = aPos;
       
   238 	for(TInt i=0; i<aLength; i++, pos++)
       
   239 		{
       
   240 		if (pos & 1)
       
   241 			{
       
   242 			if (aBuffer[pos] != (TUint8) pos-1)
       
   243 				TestBufferFail(aBuffer, pos, aLength);
       
   244 			}
       
   245 		else
       
   246 			{
       
   247 			if (aBuffer[pos] != (TUint8) (pos >> 8))
       
   248 				TestBufferFail(aBuffer, pos, aLength);
       
   249 			}
       
   250 		}
       
   251 	}
       
   252 
       
   253 
       
   254 LOCAL_C void UnitTests()
       
   255 //
       
   256 // Test read file handling.
       
   257 //
       
   258 	{
       
   259 
       
   260 	test.Start(_L("File cache read and write unit tests"));
       
   261 	
       
   262 //TheFs.SetDebugRegister(KCACHE);
       
   263 	
       
   264 	RFile f;
       
   265 	TInt r;
       
   266 	TInt pos;
       
   267 	TInt len;
       
   268 	TInt testNum;
       
   269 
       
   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);
       
   277 #endif
       
   278 
       
   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);
       
   284 #endif
       
   285 
       
   286 	TFileName testFile   = _L("TEST.BIN");
       
   287 
       
   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);
       
   295 	TPtrC8 writePtr;
       
   296 	TPtr8 readPtr(gBuf->Des());
       
   297 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   298 	TInt uncachedBytesRead;
       
   299 	TInt uncachedPacketsRead;
       
   300 #endif
       
   301 
       
   302 	// create an empty file, so that any writes overlapping segemt boundaries
       
   303 	// need a read first
       
   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);
       
   307 	test_KErrNone(r);
       
   308 	writePtr.Set(gBuf->Des());
       
   309 	r = f.Write(0, writePtr);
       
   310 	test_KErrNone(r);
       
   311 	f.Close();
       
   312 	r = f.Open(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
       
   313 	test_KErrNone(r);
       
   314 
       
   315 	TInt cacheLineLen = 128*1024;
       
   316 
       
   317 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   318 	PrintFileCacheStats(fileCacheStats);
       
   319 	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
       
   320 	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
       
   321 #endif
       
   322 
       
   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;
       
   326 	len = 7;
       
   327 	writePtr.Set(gBuf->Mid(pos, len));
       
   328 	r = f.Write(pos, writePtr, len);
       
   329 	test_KErrNone(r);
       
   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);
       
   334 	readPtr.FillZ();
       
   335 	r = f.Read(pos, readPtr, len);
       
   336 	test_KErrNone(r);
       
   337 	TestBuffer(gBufPtr, pos, len);
       
   338 	test_KErrNone(r);
       
   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;
       
   345 #endif
       
   346 
       
   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);
       
   353 	test_KErrNone(r);
       
   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);
       
   358 	readPtr.FillZ();
       
   359 	r = f.Read(pos, readPtr, len);
       
   360 	test_KErrNone(r);
       
   361 	TestBuffer(gBufPtr, pos, len);
       
   362 	test_KErrNone(r);
       
   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;
       
   369 #endif
       
   370 
       
   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;
       
   374 	len = 30;
       
   375 	writePtr.Set(gBuf->Mid(pos, len));
       
   376 	r = f.Write(pos, writePtr, len);
       
   377 	test_KErrNone(r);
       
   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);
       
   382 	readPtr.FillZ();
       
   383 	r = f.Read(pos, readPtr, len);
       
   384 	test_KErrNone(r);
       
   385 	TestBuffer(gBufPtr, pos, len);
       
   386 	test_KErrNone(r);
       
   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;
       
   393 #endif
       
   394 
       
   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);
       
   401 	test_KErrNone(r);
       
   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);
       
   406 	readPtr.FillZ();
       
   407 	r = f.Read(pos, readPtr, len);
       
   408 	test_KErrNone(r);
       
   409 	TestBuffer(gBufPtr, pos, len);
       
   410 	test_KErrNone(r);
       
   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;
       
   418 #endif
       
   419 
       
   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);
       
   426 	test_KErrNone(r);
       
   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);
       
   431 	readPtr.FillZ();
       
   432 	r = f.Read(pos, readPtr, len);
       
   433 	test_KErrNone(r);
       
   434 	TestBuffer(gBufPtr, pos, len);
       
   435 	test_KErrNone(r);
       
   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;
       
   442 #endif
       
   443 
       
   444 	f.Close();
       
   445 
       
   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"));
       
   451 
       
   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);
       
   455 	test_KErrNone(r);
       
   456 
       
   457 	r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
       
   458 	test_KErrNone(r);
       
   459 
       
   460 	RTimer timer;
       
   461 	timer.CreateLocal();
       
   462 	TRequestStatus reqStat;
       
   463 	timer.After(reqStat,gFileCacheConfig.iClosedFileKeepAliveTime*3); // write 3 times the flush timer
       
   464 
       
   465 	pos = 0;
       
   466 	TInt bufLen = 7;
       
   467 	TInt maxLockedSegmentCount = 0;
       
   468 	while (reqStat == KRequestPending)
       
   469 		{
       
   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);
       
   475 		test_KErrNone(r);
       
   476 		pos+= len;
       
   477 		TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
       
   478 		test_KErrNone(r);
       
   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);
       
   482 
       
   483 		test(fileCacheStats.iLockedSegmentCount >= maxLockedSegmentCount);
       
   484 		maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
       
   485 		// wrap to start of file
       
   486 		if (pos >= gFileCacheConfig.iCacheSize)	
       
   487 			pos = 0;
       
   488 		}
       
   489 	timer.Close();
       
   490 
       
   491 	test(fileCacheStats.iLockedSegmentCount > 0);
       
   492 
       
   493 	if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
       
   494 		TestDirtyDataWrittenToDisk(fileCacheStats);
       
   495 	f.Close();
       
   496 #endif
       
   497 
       
   498 
       
   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++)
       
   505 #else
       
   506 	for (testNum = 0; testNum < 1; testNum++)
       
   507 #endif
       
   508 		{
       
   509 		switch(testNum)
       
   510 			{
       
   511 			case ETestDataWrittenAfterTimeout		: test.Next(_L("ETestDataWrittenAfterTimeout"));		break;
       
   512 			case ETestDataWrittenAfterFileClose		: test.Next(_L("ETestDataWrittenAfterFileClose"));		break;
       
   513 			case ETestDataWrittenAfterSessionClose	: test.Next(_L("ETestDataWrittenAfterSessionClose"));	break;
       
   514 			};
       
   515 
       
   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);
       
   520 		test_KErrNone(r);
       
   521 #endif
       
   522 
       
   523 		r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
       
   524 		test_KErrNone(r);
       
   525 
       
   526 
       
   527 		gBufPtr.SetLength(KBufSize);
       
   528 		
       
   529 		test.Printf(_L("writing file in small blocks to test write caching...\n"));
       
   530 
       
   531 		FillBuffer(gBufPtr, KBufSize);
       
   532 		TestBuffer(gBufPtr, 0,KBufSize);
       
   533 
       
   534 		pos = 0;
       
   535 		TInt bufLen = 7;
       
   536 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   537 		TInt maxLockedSegmentCount = 0;
       
   538 		TInt maxUsedCount = 0;
       
   539 #endif
       
   540 		while (pos < KBufSize) 
       
   541 			{
       
   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);
       
   547 			test_KErrNone(r);
       
   548 			pos+= len;
       
   549 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   550 //			PrintFileCacheStats(fileCacheStats);
       
   551 			TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
       
   552 			test_KErrNone(r);
       
   553 			maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
       
   554 			maxUsedCount = Max(maxUsedCount, fileCacheStats.iUsedCount);
       
   555 #endif
       
   556 			}
       
   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);
       
   562 #endif
       
   563 
       
   564 
       
   565 
       
   566 		if (testNum == ETestDataWrittenAfterTimeout)
       
   567 			{
       
   568 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   569 			if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
       
   570 				TestDirtyDataWrittenToDisk(fileCacheStats);
       
   571 #endif
       
   572 			f.Close();
       
   573 			}
       
   574 
       
   575 		if (testNum == ETestDataWrittenAfterFileClose)
       
   576 			{
       
   577 			f.Close();
       
   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);
       
   582 #endif
       
   583 			}
       
   584 
       
   585 		if (testNum == ETestDataWrittenAfterSessionClose)
       
   586 			{
       
   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 !!! 
       
   591 
       
   592 			TheFs.Close();
       
   593 			TheFs.Connect();
       
   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);
       
   599 #endif
       
   600 			}
       
   601 
       
   602 		}	// for (TInt testNum = 0; testNum < ETestEnd; testNum++)
       
   603 
       
   604 
       
   605 //#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   606 //	PrintFileCacheStats(fileCacheStats);
       
   607 //#endif
       
   608 
       
   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);
       
   613 	test_KErrNone(r);
       
   614 #endif
       
   615 
       
   616 	r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileWrite);
       
   617 	test_KErrNone(r);
       
   618 
       
   619 	TInt size;
       
   620 	r = f.Size(size);
       
   621 	test (r == KErrNone);
       
   622 	test (size = KBufSize);
       
   623 
       
   624 	readPtr.Set(gBuf->Des());
       
   625 
       
   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;
       
   634 #endif
       
   635 
       
   636 	test.Next(_L("Test reading a partially filled cacheline"));
       
   637 	// create a cacheline with only the first segment filled
       
   638 	TInt startPos = KSegmentSize;
       
   639 	pos = startPos;
       
   640 	len = KSegmentSize;
       
   641 	writePtr.Set(gBuf->Mid(pos, len));
       
   642 	r = f.Write(pos, writePtr, len);
       
   643 	test_KErrNone(r);
       
   644 
       
   645 	// read from first & second segments
       
   646 	pos = startPos;
       
   647 	len = 8192;
       
   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);
       
   652 	test_KErrNone(r);
       
   653 	TestBuffer(gBufPtr, pos, len);
       
   654 
       
   655 	
       
   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);
       
   664 	test_KErrNone(r);
       
   665 	TestBuffer(gBufPtr, pos, len);
       
   666 
       
   667 
       
   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;			
       
   671 	pos = startPos;
       
   672 	len = KSegmentSize;
       
   673 	writePtr.Set(gBuf->Mid(pos, len));
       
   674 	r = f.Write(pos, writePtr, len);
       
   675 	test_KErrNone(r);
       
   676 
       
   677 
       
   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);
       
   683 	test_KErrNone(r);
       
   684 	// read back whole cacheline & verify
       
   685 	pos = startPos;
       
   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);
       
   691 	test_KErrNone(r);
       
   692 	TestBuffer(gBufPtr, pos, len);
       
   693 
       
   694 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   695 	PrintFileCacheStats(fileCacheStats);
       
   696 	if (fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount != lockFailures)
       
   697 		{
       
   698 		if (gRomPaged)
       
   699 			{
       
   700 			test.Printf(_L("Lock failures detected on paged ROM, abandoning hole test"));
       
   701 			}
       
   702 		else
       
   703 			{
       
   704 			test.Printf(_L("Unexpected lock failures detected on unpaged ROM!!!"));
       
   705 			test(0);
       
   706 			}
       
   707 		}
       
   708 	else
       
   709 		{
       
   710 		test(fileCacheStats.iHoleCount > holesDetected);
       
   711 		}
       
   712 	// Don't allocate full cachelines any more
       
   713 	allocateAllSegmentsInCacheLine = EFalse;
       
   714 	r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine);
       
   715 	test (r == KErrNone);
       
   716 #endif
       
   717 
       
   718 
       
   719 
       
   720 	gBufPtr.FillZ();
       
   721 	gBufPtr.SetLength(KBufSize);
       
   722 
       
   723 	
       
   724 
       
   725 	readPtr.SetLength(0);
       
   726 
       
   727 
       
   728 	// read from middle of fifth sector to half way thru seventh
       
   729 	test.Next(_L("Test read that spans two pages"));
       
   730 	pos = 512*4 + 16;
       
   731 	len = 512*2;
       
   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);
       
   736 	test_KErrNone(r);
       
   737 	TestBuffer(gBufPtr, pos, len);
       
   738 
       
   739 
       
   740 
       
   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;
       
   746 //	len = 512;;
       
   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*/);
       
   752 	test_KErrNone(r);
       
   753 
       
   754 	test.Next(_L("Test async reads"));
       
   755 	// issue 2 async reads
       
   756 	pos = KSegmentSize*7 + 16;
       
   757 	len = KSegmentSize;
       
   758 	RDebug::Print(_L("+%x, %x\n"), pos, len);
       
   759 	readPtr.Set(gBufPtr.MidTPtr(pos, len));
       
   760 	readPtr.SetLength(len);
       
   761 
       
   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);
       
   767 	
       
   768 	TRequestStatus status1(KRequestPending);
       
   769 	TRequestStatus status2(KRequestPending);
       
   770 	
       
   771 	f.Read(pos, readPtr, len, status1);
       
   772 	f.Read(readPtr2, len2, status2);
       
   773 
       
   774 
       
   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);
       
   780 
       
   781 
       
   782 	test.Next(_L("Read entire file"));
       
   783 
       
   784 	for (pos = 0, len = 1; len <= 1024 && pos < KBufSize; len = (len+1) & 0x3FF)
       
   785 		{
       
   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);
       
   790 
       
   791 		r = f.Read(pos, readPtr, len);
       
   792 		test_KErrNone(r);
       
   793 		TestBuffer(gBufPtr, pos, len);
       
   794 		test_KErrNone(r);
       
   795 		pos+= len;
       
   796 		}
       
   797 	
       
   798 	TestBuffer(gBufPtr, 0, KBufSize);
       
   799 
       
   800 	// read from position zero to ensure it's cached
       
   801 	pos = 0;
       
   802 	len = 512;
       
   803 	readPtr.Set(gBufPtr.MidTPtr(pos, len));
       
   804 	readPtr.SetLength(len);
       
   805 	r = f.Read(pos, readPtr, len);
       
   806 	test_KErrNone(r);
       
   807 	TestBuffer(gBufPtr, pos, len);
       
   808 	test_KErrNone(r);
       
   809 
       
   810 	f.Close();
       
   811 
       
   812 
       
   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);
       
   818 #endif
       
   819 	//
       
   820 
       
   821 	
       
   822 	//**************************************************************
       
   823 	// Test closed file queue 
       
   824 	//**************************************************************
       
   825 	enum 
       
   826 		{
       
   827 		ETestCloseQueueEmptyAfterTimeout, 
       
   828 		ETestCloseQueueEmptyAfterOpenWithDirectIo, 
       
   829 		ETestCloseQueueEmptyAfterDelete, 
       
   830 		ETestCloseEnd};
       
   831 	for (testNum = 0; testNum < ETestCloseEnd; testNum++)
       
   832 		{
       
   833 	
       
   834 		test.Next(_L("Reopen file & verify closed queue is empty"));
       
   835 
       
   836 		r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered);
       
   837 		test_KErrNone(r);
       
   838 		pos = 0;
       
   839 		len = 512;
       
   840 		readPtr.Set(gBufPtr.MidTPtr(pos, len));
       
   841 		readPtr.SetLength(len);
       
   842 		r = f.Read(pos, readPtr, len);
       
   843 		test_KErrNone(r);
       
   844 		TestBuffer(gBufPtr, pos, len);
       
   845 		test_KErrNone(r);
       
   846 
       
   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);
       
   852 #endif
       
   853 		f.Close();
       
   854 
       
   855 		test.Next(_L("close & verify file is back on close queue"));
       
   856 
       
   857 
       
   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);
       
   863 #endif
       
   864 
       
   865 		if (testNum == ETestCloseQueueEmptyAfterDelete)
       
   866 			{
       
   867 			test.Next(_L("delete file and verify closed queue is empty"));
       
   868 			r = TheFs.Delete(testFile);
       
   869 			test_KErrNone(r);
       
   870 			}
       
   871 		if (testNum == ETestCloseQueueEmptyAfterTimeout)
       
   872 			{
       
   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);
       
   877 #endif
       
   878 			}
       
   879 		if (testNum == ETestCloseQueueEmptyAfterOpenWithDirectIo)
       
   880 			{
       
   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);
       
   883 			test_KErrNone(r);
       
   884 			f.Close();
       
   885 			}
       
   886 
       
   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);
       
   892 	#endif
       
   893 		}
       
   894 
       
   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);
       
   900 #endif
       
   901 
       
   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);
       
   916 
       
   917 	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered);
       
   918 	test_KErrNone(r);
       
   919 
       
   920 	const TInt KWriteLen = KSegmentSize+1;
       
   921 	writePtr.Set(gBuf->Des().Ptr(), KWriteLen);
       
   922 
       
   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;
       
   929 #endif
       
   930 
       
   931 	TInt fileSize = 0;
       
   932 	for (TInt i=0; i<4; i++)
       
   933 		{
       
   934 		fileSize = 0;
       
   935 		r = f.SetSize(fileSize);
       
   936 		test (r == KErrNone);
       
   937 		for (pos = 0; pos < KMaxFileSize; )
       
   938 			{
       
   939 			r = f.Write(pos, writePtr);
       
   940 			if (r != KErrNone)
       
   941 				{
       
   942 				test.Printf(_L("Iter #%d, write pos %d size %d, Write() returned %d"), i, pos, fileSize, r);
       
   943 				r = f.Flush();
       
   944 				test.Printf(_L("Flush returned %d"), r);
       
   945 				test(0);
       
   946 				}
       
   947 			test(r == KErrNone);
       
   948 			pos+= writePtr.Length();
       
   949 
       
   950 			r = f.Size(fileSize);
       
   951 			test (r == KErrNone);
       
   952 			if (fileSize != pos)
       
   953 				{
       
   954 				test.Printf(_L("Iter #%d, write pos %d != size %d"), i, pos, fileSize);
       
   955 				r = f.Flush();
       
   956 				test.Printf(_L("Flush returned %d"), r);
       
   957 				test(0);
       
   958 				}
       
   959 			test (fileSize == pos);
       
   960 
       
   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)
       
   966 				{
       
   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);
       
   969 				i = 4;
       
   970 				break;
       
   971 				}
       
   972 #endif
       
   973 
       
   974 			}
       
   975 		}
       
   976 
       
   977 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
   978 	test(writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld);
       
   979 #endif
       
   980 
       
   981 
       
   982 	f.Close();
       
   983 
       
   984 
       
   985 //TheFs.SetDebugRegister(0);
       
   986 	test.End();
       
   987 	}
       
   988 
       
   989 
       
   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)
       
   994 	{
       
   995 	RTest test(_L("T_FILECACHE, ReaderThread"));
       
   996 	
       
   997 	TDesC& fileName = *(TDesC*) aFileName;
       
   998 
       
   999 	RFs fs;
       
  1000 	TInt r = fs.Connect();
       
  1001 	test (r==KErrNone);
       
  1002 	r = fs.SetSessionPath(gSessionPath);
       
  1003 	test (r==KErrNone);
       
  1004 
       
  1005 
       
  1006 	RFile file;
       
  1007 	r = file.Open(fs, fileName, EFileRead | EFileReadBuffered | EFileShareReadersOrWriters);
       
  1008 	test_KErrNone(r);
       
  1009 
       
  1010 	RTimer timer;
       
  1011 	timer.CreateLocal();
       
  1012 	TRequestStatus reqStat;
       
  1013 	timer.After(reqStat,10000000); // Read for 10 secs
       
  1014 
       
  1015 	TInt pos=0;
       
  1016 	TInt KReadLen = 32768;
       
  1017 	TInt retCode = KErrNone;
       
  1018 		
       
  1019 	for (TInt i=0; reqStat == KRequestPending; i++)
       
  1020 		{
       
  1021 		r = file.Read(pos, DataBuf, KReadLen);
       
  1022 		test_Value(r, r == KErrNone || r == KErrNotReady);
       
  1023 
       
  1024 		//test.Printf(_L("ReaderThread: iter %d, read at %d ret %d\n"), i, pos, r);
       
  1025 		if (r == KErrNotReady)
       
  1026 			retCode = r;
       
  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);
       
  1031 		}
       
  1032 
       
  1033 	timer.Close();
       
  1034 	file.Close();
       
  1035 	fs.Close();
       
  1036 
       
  1037 	return retCode;
       
  1038 	}
       
  1039 
       
  1040 
       
  1041 void ManualTests()
       
  1042 	{
       
  1043 	RFile f;
       
  1044 	TInt r;
       
  1045 	gBufPtr.SetLength(KBufSize);
       
  1046 	FillBuffer(gBufPtr, KBufSize);
       
  1047 	TestBuffer(gBufPtr, 0,KBufSize);
       
  1048 
       
  1049 	TPtrC8 writePtr;
       
  1050 	writePtr.Set(gBuf->Des());
       
  1051 	
       
  1052 	TFileName testFile   = _L("TEST.BIN");
       
  1053 	
       
  1054 #if defined(_DEBUG)
       
  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"));
       
  1059 
       
  1060 	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
       
  1061 	test_KErrNone(r);
       
  1062 
       
  1063 	test.Printf(_L("Writing...."));
       
  1064 	r = f.Write(0, writePtr);
       
  1065 	test.Printf(_L("Write returned %d\n"), r);
       
  1066 	test_KErrNone(r);
       
  1067 
       
  1068 	r=TheFs.ControlIo(gDrive, KControlIoSimulateFileCacheWriteFailure);
       
  1069 	test_KErrNone(r);
       
  1070 
       
  1071 	f.Close();
       
  1072 
       
  1073 	TEntry entry;
       
  1074 
       
  1075 	// wait for re-insertion....
       
  1076 	do
       
  1077 		{
       
  1078 		r = TheFs.Entry(testFile, entry);
       
  1079 		User::After(500000);
       
  1080 		}
       
  1081 	while (r == KErrNotReady);
       
  1082 	test_KErrNone(r);
       
  1083 
       
  1084 	test.Printf(_L("FileSize %d expected %d\n"), entry.iSize, writePtr.Length());
       
  1085 
       
  1086 	// test all data is written to disk 
       
  1087 	test (entry.iSize == writePtr.Length());
       
  1088 #endif
       
  1089 
       
  1090 
       
  1091 	test.Next(_L("Testing writing and then ejecting card"));
       
  1092 
       
  1093 //	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO);
       
  1094 	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
       
  1095 	test_KErrNone(r);
       
  1096 	writePtr.Set(gBuf->Des());
       
  1097 
       
  1098 
       
  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"));
       
  1102 
       
  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);
       
  1109 
       
  1110 	test.Printf(_L("Writing...."));
       
  1111 	r = f.Write(0, writePtr);
       
  1112 	test.Printf(_L("Write returned %d\n"), r);
       
  1113 
       
  1114 
       
  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..."));
       
  1121 	test.Getch();
       
  1122 	test.Printf(_L("\n"));
       
  1123 
       
  1124 	test.Printf(_L("Writing...."));
       
  1125 	r = f.Write(0, writePtr);
       
  1126 	test.Printf(_L("Write returned %d\n"), r);
       
  1127 	readerThread.Resume();
       
  1128 
       
  1129 	User::After(5000000);
       
  1130 
       
  1131 	do
       
  1132 		{
       
  1133 		test.Printf(_L("Flushing....\n"));
       
  1134 		r = f.Flush();
       
  1135 		test.Printf(_L("Flush returned %d\n"), r);
       
  1136 		if (r != KErrNone)
       
  1137 			User::After(5000000);
       
  1138 		}
       
  1139 	while (r != KErrNone);
       
  1140 
       
  1141 
       
  1142 //	r = f.Write(0, writePtr);
       
  1143 //	test.Printf(_L("Write returned %d"));
       
  1144 
       
  1145 //	test_KErrNone(r);
       
  1146 
       
  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();
       
  1155 
       
  1156 	test.Printf(_L("press any key..."));
       
  1157 	test.Getch();
       
  1158 	test.Printf(_L("\n"));
       
  1159 
       
  1160 	f.Close();
       
  1161 	}
       
  1162 
       
  1163 
       
  1164 LOCAL_C void DoTestFileRead(TUint aFileMode, TInt aReadBlockSize)
       
  1165 //
       
  1166 // Do Read Test
       
  1167 //
       
  1168 	{
       
  1169 
       
  1170 	RFile file;
       
  1171 	TInt r=file.Open(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
       
  1172 	test_KErrNone(r);
       
  1173 
       
  1174 	TInt maxReadCount=KMaxFileSize/aReadBlockSize;
       
  1175 	TInt loopCount=0;
       
  1176 
       
  1177 	TTime startTime;
       
  1178 	TTime endTime;
       
  1179 
       
  1180 	RTimer timer;
       
  1181 	timer.CreateLocal();
       
  1182 	TRequestStatus reqStat;
       
  1183 	timer.After(reqStat,10000000); // After 10 secs
       
  1184 	startTime.HomeTime();
       
  1185 
       
  1186 	FOREVER
       
  1187 		{
       
  1188 		TInt pos=0;
       
  1189 		file.Seek(ESeekStart,pos);
       
  1190 		for(TInt ii=0;ii<maxReadCount;ii++)
       
  1191 			{
       
  1192 			r = file.Read(DataBuf,aReadBlockSize);
       
  1193 			test_KErrNone(r);
       
  1194 #if defined(_DEBUG)
       
  1195 			for(TInt jj=0;jj<DataBuf.Size();jj++)
       
  1196 				{
       
  1197 				if (DataBuf[jj] != ((jj+ii*aReadBlockSize)%256))
       
  1198 					{
       
  1199 					test.Printf(_L("len %d size %d jj %d ii %d"), DataBuf.Length(), DataBuf.Size(), jj, ii);
       
  1200 					test(0);
       
  1201 					}
       
  1202 //				test(DataBuf[jj] == ((jj+ii*aReadBlockSize)%256) );
       
  1203 				}
       
  1204 #endif
       
  1205 			if (reqStat!=KRequestPending)
       
  1206 				{
       
  1207 				endTime.HomeTime();
       
  1208 
       
  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));
       
  1212 				
       
  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);
       
  1217 
       
  1218 				timer.Close();
       
  1219 				file.Close();
       
  1220 
       
  1221 				return;
       
  1222 				}
       
  1223 			}
       
  1224 		loopCount++;
       
  1225 		}
       
  1226 	}
       
  1227 
       
  1228 LOCAL_C void DoTestFileWrite(TUint aFileMode, TInt aWriteBlockSize)
       
  1229 //
       
  1230 // Do Write benchmark
       
  1231 //
       
  1232 	{
       
  1233 	DataBuf.SetLength(aWriteBlockSize);
       
  1234 	TInt maxWriteCount=KMaxFileSize/aWriteBlockSize;
       
  1235 	TInt loopCount=0;
       
  1236 
       
  1237 	RFile file;
       
  1238 	TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
       
  1239 	test (r == KErrNone);
       
  1240 
       
  1241 	TTime startTime;
       
  1242 	TTime endTime;
       
  1243 
       
  1244 	RTimer timer;
       
  1245 	timer.CreateLocal();
       
  1246 	TRequestStatus reqStat;
       
  1247 	timer.After(reqStat,10000000); // After 10 secs
       
  1248 	startTime.HomeTime();
       
  1249 
       
  1250 	
       
  1251 
       
  1252 	FOREVER
       
  1253 		{
       
  1254 		TInt pos=0;
       
  1255 		file.Seek(ESeekStart,pos);
       
  1256 		for(TInt ii=0;ii<maxWriteCount;ii++)
       
  1257 			{
       
  1258 			r = file.Write(DataBuf);
       
  1259 			test_KErrNone(r);
       
  1260 			if (reqStat!=KRequestPending)
       
  1261 				{
       
  1262 				
       
  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));
       
  1265 
       
  1266 				r = file.Flush();
       
  1267 				test_KErrNone(r);
       
  1268 
       
  1269 				endTime.HomeTime();
       
  1270 
       
  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);
       
  1276 
       
  1277 				file.Close();
       
  1278 				timer.Close();
       
  1279 				TInt r=TheFs.Delete(_L("WRITETST"));
       
  1280 				test_KErrNone(r);
       
  1281 				return;
       
  1282 				}
       
  1283 			}
       
  1284 		loopCount++;
       
  1285 		}
       
  1286 	}
       
  1287 
       
  1288 LOCAL_C void TestFileRead(TUint aFileMode)
       
  1289 //
       
  1290 // Benchmark read method
       
  1291 //
       
  1292 	{
       
  1293 
       
  1294 //	ClearSessionDirectory();
       
  1295 	test.Next(_L("Benchmark read method"));
       
  1296 //	test.Printf(_L("aFileMode %08X\n"), aFileMode);
       
  1297 	PrintFileMode(aFileMode);
       
  1298 
       
  1299 // Create test data
       
  1300 	TBuf8<1024> testdata(1024);
       
  1301 	for (TInt i=0;i<testdata.MaxSize();i++)
       
  1302 		testdata[i]=TText8(i%256);		
       
  1303 	
       
  1304 	// create & fill the file
       
  1305 	RFile file;
       
  1306 	TInt r=file.Replace(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
       
  1307 	test_KErrNone(r);
       
  1308 
       
  1309 	test.Printf(_L("Creating test file....."));
       
  1310 	TInt count=KMaxFileSize/testdata.Length();
       
  1311 	while (count--)
       
  1312 		file.Write(testdata);
       
  1313 	file.Close();
       
  1314 	test.Printf(_L("done.\n"));
       
  1315 
       
  1316 #ifdef SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
       
  1317 
       
  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);
       
  1336 #else
       
  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);
       
  1347 #endif
       
  1348 
       
  1349 	r=TheFs.Delete(_L("READTEST.XXX"));
       
  1350 
       
  1351 
       
  1352 
       
  1353 	test_KErrNone(r);
       
  1354 	}
       
  1355 
       
  1356 
       
  1357 LOCAL_C void TestFileWrite(TUint aFileMode)
       
  1358 //
       
  1359 // Benchmark write method
       
  1360 //
       
  1361 	{
       
  1362 //	ClearSessionDirectory();
       
  1363 	test.Next(_L("Benchmark write method"));
       
  1364 //	test.Printf(_L("aFileMode %08X\n"), aFileMode);
       
  1365 	PrintFileMode(aFileMode);
       
  1366 
       
  1367 	
       
  1368 //	RFile file;
       
  1369 //	TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
       
  1370 //	test_KErrNone(r);
       
  1371 
       
  1372 
       
  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);
       
  1392 #else
       
  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);
       
  1401 #endif
       
  1402 	}
       
  1403 
       
  1404 enum CommandId {
       
  1405     CMD_NO_COMMAND,
       
  1406     CMD_HELP,
       
  1407 	CMD_DISPLAY_CACHE_FLAGS,
       
  1408 	CMD_WRITE_CACHE_FLAGS,
       
  1409 	CMD_PERFORMANCE_TEST,
       
  1410 	CMD_MANUAL_TEST
       
  1411 };
       
  1412 
       
  1413 
       
  1414 class CommandLineOption { 
       
  1415 public:
       
  1416     CommandLineOption(const TPtrC &s, CommandId i) : str(s), id(i) { }
       
  1417     
       
  1418     const TPtrC str;
       
  1419     CommandId   id;
       
  1420     
       
  1421 private:
       
  1422     CommandLineOption() { }
       
  1423 };
       
  1424 
       
  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),
       
  1435 };
       
  1436 
       
  1437 
       
  1438 
       
  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"));
       
  1444 }
       
  1445 
       
  1446 
       
  1447 
       
  1448 /////////////////////////////////////////////////////////////////////////////
       
  1449 // Function: 
       
  1450 //		bool parseCommandLine()
       
  1451 //
       
  1452 // Parameters:
       
  1453 //		-
       
  1454 //
       
  1455 // Return value:
       
  1456 //		true if command line options was correct, false if any command was
       
  1457 //      invalid
       
  1458 //
       
  1459 // Purpose:
       
  1460 //		Parses the command line
       
  1461 //
       
  1462 /////////////////////////////////////////////////////////////////////////////
       
  1463 
       
  1464 //TBuf<512> commandLine;
       
  1465 
       
  1466 
       
  1467 LOCAL_C bool ParseCommandLine( const TDesC& aCommand )
       
  1468 	{
       
  1469     TLex lex(aCommand);
       
  1470     TInt tokenCount = 0;
       
  1471 
       
  1472 	gDriveToTest='C';		
       
  1473 	gRunTests = ETrue;
       
  1474 
       
  1475     for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
       
  1476 		{
       
  1477         tokenCount++;
       
  1478 
       
  1479         //
       
  1480         // Search the list of commands for a match.
       
  1481         //
       
  1482         CommandId commandId = CMD_NO_COMMAND;
       
  1483         for (TUint i = 0; i < sizeof commandList / sizeof commandList[0]; i++) 
       
  1484 			{
       
  1485             if (token.CompareF(commandList[i].str) == 0) 
       
  1486 				{
       
  1487                 //
       
  1488                 // Found a matching string
       
  1489                 //
       
  1490                 commandId = commandList[i].id;
       
  1491                 break;
       
  1492 				}
       
  1493 			}
       
  1494 
       
  1495         switch (commandId) 
       
  1496 			{
       
  1497 			case CMD_NO_COMMAND:
       
  1498 				{
       
  1499 				TFileName thisfile=RProcess().FileName();
       
  1500 				if (token.MatchF(thisfile)==0)
       
  1501 					{
       
  1502 					token.Set(lex.NextToken());
       
  1503 					}
       
  1504 				test.Printf(_L("CLP=%S\n"),&token);
       
  1505 
       
  1506 				TChar ch = token[0];
       
  1507 				if (ch.IsAlpha())
       
  1508 					{
       
  1509 					if(token.Length()!=0)		
       
  1510 						{
       
  1511 						gDriveToTest=token[0];
       
  1512 						gDriveToTest.UpperCase();
       
  1513 						}
       
  1514 					else						
       
  1515 						gDriveToTest='C';		
       
  1516 					lex.NextToken();
       
  1517 					}
       
  1518 				}
       
  1519 				break;
       
  1520 
       
  1521 			case CMD_HELP:
       
  1522 				printHelp();
       
  1523 				gRunTests = EFalse;
       
  1524 				break;
       
  1525 
       
  1526 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1527 			case CMD_WRITE_CACHE_FLAGS:
       
  1528 				{         
       
  1529 					token.Set(lex.NextToken());
       
  1530 					if (token.Length() == 0) {
       
  1531 						printHelp();
       
  1532 						return false;
       
  1533 					}
       
  1534 					//
       
  1535 					// Extract flags (in hex) from next token.
       
  1536 					//
       
  1537 					TPtrC numStr(token);
       
  1538 					TUint val;
       
  1539 					TInt r = TLex(numStr).Val(val, EHex);
       
  1540 					if (r != KErrNone) {
       
  1541 						printHelp();
       
  1542 						return false;
       
  1543 					}
       
  1544 					gDriveCacheFlags = TFileCacheFlags(val);
       
  1545 					gWriteCacheFlags = ETrue;
       
  1546 					gRunTests = EFalse;
       
  1547 					break;
       
  1548 				}
       
  1549 
       
  1550 			case CMD_DISPLAY_CACHE_FLAGS:
       
  1551 				gDisplayCacheFlags = ETrue;
       
  1552 				gRunTests = EFalse;
       
  1553 				break;
       
  1554 #endif
       
  1555 			case CMD_PERFORMANCE_TEST:
       
  1556 				gRunPerformanceTests = ETrue;
       
  1557 				gRunUnitTests = EFalse;
       
  1558 				break;
       
  1559 
       
  1560 			case CMD_MANUAL_TEST:
       
  1561 				gRunManualTests = ETrue;
       
  1562 				gRunUnitTests = EFalse;
       
  1563 				break;
       
  1564 
       
  1565 			default:
       
  1566 				test.Printf(_L("Sorry, command option '%S' not implemented\n"),
       
  1567 					&token);
       
  1568 				break;
       
  1569 			}
       
  1570 
       
  1571 		}
       
  1572     return true;
       
  1573 }
       
  1574 
       
  1575 
       
  1576 LOCAL_C TBool parseCommandLine() {
       
  1577     //
       
  1578     // Loop through all tokens in the command line
       
  1579     //
       
  1580 	TInt cmdLineLen = User::CommandLineLength();
       
  1581 	HBufC* cmdLineBuf = HBufC::New( cmdLineLen );
       
  1582     if( !cmdLineBuf )
       
  1583 		{
       
  1584 		return false;
       
  1585 		}
       
  1586 	TPtr ptr = cmdLineBuf->Des();
       
  1587 	User::CommandLine(ptr);
       
  1588 
       
  1589 	bool err = ParseCommandLine( *cmdLineBuf );
       
  1590 	delete cmdLineBuf;
       
  1591 	return err;
       
  1592 	}
       
  1593 
       
  1594 GLDEF_C void CallTestsL()
       
  1595 //
       
  1596 // Do tests relative to the session path
       
  1597 //
       
  1598 	{
       
  1599 	TestsInit();
       
  1600 
       
  1601 	TVolumeInfo volInfo;
       
  1602 	TInt r = TheFs.Volume(volInfo, gDrive);
       
  1603 	test (r == KErrNone);
       
  1604 
       
  1605 	TFullName extName;
       
  1606 	r = TheFs.ExtensionName(extName,gDrive, 0);
       
  1607 	if (r == KErrNone)
       
  1608 		{
       
  1609 		test.Printf(_L("File system extension present (%S)\n"), &extName);
       
  1610 		}
       
  1611 
       
  1612 	if ((volInfo.iDrive.iType == EMediaRam) ||
       
  1613 		((gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn)) == 0))
       
  1614 		{
       
  1615 		if (gRunPerformanceTests)
       
  1616 			{
       
  1617 			TestFileRead(EFileReadDirectIO);
       
  1618 			TestFileWrite(EFileWriteDirectIO);
       
  1619 			}
       
  1620 		TestsEnd();
       
  1621 		return;
       
  1622 		}
       
  1623 
       
  1624 	if (gRunUnitTests)
       
  1625 		UnitTests();
       
  1626 
       
  1627 	if (gRunManualTests)
       
  1628 		{		
       
  1629 		ManualTests();
       
  1630 		}
       
  1631 
       
  1632 	if (gRunPerformanceTests)
       
  1633 		{
       
  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);
       
  1639 #endif
       
  1640 
       
  1641 		TestFileRead(EFileReadDirectIO);
       
  1642 		if (gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn))
       
  1643 			{
       
  1644 			TestFileRead(EFileReadBuffered | EFileReadAheadOff);
       
  1645 			TestFileRead(EFileReadBuffered | EFileReadAheadOn);
       
  1646 			}
       
  1647 
       
  1648 		TestFileWrite(EFileWriteDirectIO);
       
  1649 
       
  1650 		if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
       
  1651 			TestFileWrite(EFileWriteBuffered);
       
  1652 
       
  1653 
       
  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);
       
  1659 #endif
       
  1660 		}	// if (gRunPerformanceTests)
       
  1661 
       
  1662 	TestsEnd();
       
  1663 	}
       
  1664 
       
  1665 
       
  1666 
       
  1667 LOCAL_C void DoTests(TInt aDrive)
       
  1668 //
       
  1669 // Do testing on aDrive
       
  1670 //
       
  1671 	{
       
  1672 
       
  1673 	SetSessionPath(aDrive);
       
  1674 
       
  1675 // !!! Disable platform security tests until we get the new APIs
       
  1676 //	if(User::Capability() & KCapabilityRoot)
       
  1677 //		CheckMountLFFS(TheFs,driveLetter);
       
  1678 	
       
  1679 	User::After(1000000);
       
  1680 
       
  1681 	TInt r=TheFs.MkDirAll(gSessionPath);
       
  1682 	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
       
  1683 	TheFs.ResourceCountMarkStart();
       
  1684 
       
  1685 	TRAP(r,CallTestsL());
       
  1686 	test_KErrNone(r);
       
  1687 
       
  1688 	TheFs.ResourceCountMarkEnd();
       
  1689 	}
       
  1690 
       
  1691 
       
  1692 void Format(TInt aDrive)
       
  1693 //
       
  1694 // Format current drive
       
  1695 //
       
  1696 	{
       
  1697 
       
  1698 	test.Next(_L("Format"));
       
  1699 	TBuf<4> driveBuf=_L("?:\\");
       
  1700 	driveBuf[0]=(TText)(aDrive+'A');
       
  1701 	RFormat format;
       
  1702 	TInt count;
       
  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);
       
  1706 	test_KErrNone(r);
       
  1707 	while(count)
       
  1708 		{
       
  1709 		TInt r=format.Next(count);
       
  1710 		test_KErrNone(r);
       
  1711 		}
       
  1712 	format.Close();
       
  1713 	}
       
  1714 
       
  1715 GLDEF_C TInt E32Main()
       
  1716 //
       
  1717 // Test with drive nearly full
       
  1718 //
       
  1719 	{
       
  1720 
       
  1721 	CTrapCleanup* cleanup;
       
  1722 	cleanup=CTrapCleanup::New();
       
  1723 
       
  1724 	__UHEAP_MARK;
       
  1725 
       
  1726 	TBool parseOk = parseCommandLine();
       
  1727 	if (!parseOk)
       
  1728 		User::Leave(KErrNotSupported);
       
  1729 
       
  1730 
       
  1731 	TInt r = TheFs.Connect();
       
  1732 	test_KErrNone(r);
       
  1733 
       
  1734 	r=TheFs.CharToDrive(gDriveToTest,gDrive);
       
  1735 	test_KErrNone(r);
       
  1736 
       
  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)
       
  1742 		{
       
  1743 		test.Printf(_L("ROM is paged\n"));
       
  1744 		gRomPaged = ETrue;
       
  1745 		}
       
  1746 #endif
       
  1747 #endif
       
  1748 
       
  1749 	// Get the TFileCacheFlags for this drive
       
  1750 	r = TheFs.Volume(gVolInfo, gDrive);
       
  1751 	if (r == KErrNotReady)
       
  1752 		{
       
  1753 		TDriveInfo info;
       
  1754 		TInt err = TheFs.Drive(info,gDrive);
       
  1755 		test_KErrNone(err);
       
  1756 		if (info.iType == EMediaNotPresent)
       
  1757 			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
       
  1758 		else
       
  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);
       
  1760 		}
       
  1761 	else if (r == KErrCorrupt)
       
  1762 		{
       
  1763 		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
       
  1764 		}
       
  1765 	test_KErrNone(r);
       
  1766 	gDriveCacheFlags = gVolInfo.iFileCacheFlags;
       
  1767 	test.Printf(_L("DriveCacheFlags for drive %C = %08X\n"), (TInt) gDriveToTest, gDriveCacheFlags);
       
  1768 
       
  1769 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1770 	PrintFileCacheConfig(gFileCacheConfig, gDrive);
       
  1771 	
       
  1772 	if (gDisplayCacheFlags)
       
  1773 		{
       
  1774 		test.Printf(_L("Press any key...\n"));
       
  1775 		test.Getch();
       
  1776 		}
       
  1777 
       
  1778 	if (gWriteCacheFlags)
       
  1779 		{
       
  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);
       
  1783 		}
       
  1784 #endif
       
  1785 
       
  1786 	if (gRunTests)
       
  1787 		{
       
  1788 		test.Title();
       
  1789 
       
  1790 
       
  1791 		test.Start(_L("Starting tests..."));
       
  1792 
       
  1793 		if ((gVolInfo.iDrive.iMediaAtt & KMediaAttFormattable))
       
  1794 			Format(gDrive);
       
  1795 
       
  1796 //TheFs.SetDebugRegister(KCACHE);
       
  1797 			DoTests(gDrive);
       
  1798 //TheFs.SetDebugRegister(0);
       
  1799 			test.End();
       
  1800 //			}
       
  1801 		}
       
  1802 
       
  1803 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1804 	TFileCacheStats fileCacheStats;
       
  1805 	PrintFileCacheStats(fileCacheStats);
       
  1806 #endif
       
  1807 
       
  1808 	TheFs.Close();
       
  1809 	test.Close();
       
  1810 	__UHEAP_MARKEND;
       
  1811 	delete cleanup;
       
  1812 	return(KErrNone);
       
  1813     }