os/kernelhwsrv/kerneltest/f32test/server/t_filecache.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32test\server\t_filecache.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
#define __E32TEST_EXTENSION__
sl@0
    18
#include <f32file.h>
sl@0
    19
#include <e32test.h>
sl@0
    20
#include <e32svr.h> 
sl@0
    21
#include <f32dbg.h>
sl@0
    22
#include "t_server.h"
sl@0
    23
#include <e32twin.h>
sl@0
    24
#include <e32rom.h>
sl@0
    25
sl@0
    26
sl@0
    27
//----------------------------------------------------------------------------------------------
sl@0
    28
//! @SYMTestCaseID      PBASE-T_FILECACHE-0189
sl@0
    29
//! @SYMTestType        UT
sl@0
    30
//! @SYMPREQ            PREQ914
sl@0
    31
//! @SYMTestCaseDesc    Unit tests for fair scheduling, read caching and lazy writing
sl@0
    32
//! @SYMTestActions     0   setup the environment to execute the tests 
sl@0
    33
//!						1 	Reads a file with different blocksizes
sl@0
    34
//!						2	Write a file with different blocksizes
sl@0
    35
//!						3	Small reads while controlling the cache 
sl@0
    36
//!						4	Read operations with and without read ahead
sl@0
    37
//!						5 	Write operations with write buffer
sl@0
    38
//! @SYMTestExpectedResults finishes if the implementation of PREQ914 behaves as expected, panics otherwise
sl@0
    39
//! @SYMTestPriority        High
sl@0
    40
//! @SYMTestStatus          Critical
sl@0
    41
//----------------------------------------------------------------------------------------------
sl@0
    42
sl@0
    43
sl@0
    44
//#define SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
sl@0
    45
sl@0
    46
sl@0
    47
GLDEF_D RTest test(_L("T_FILECACHE"));
sl@0
    48
sl@0
    49
GLDEF_D	RFs TheFs;
sl@0
    50
GLDEF_D TChar gDriveToTest;
sl@0
    51
GLDEF_D TInt gDrive;
sl@0
    52
GLDEF_D TFileName gSessionPath;
sl@0
    53
sl@0
    54
GLDEF_D TVolumeInfo gVolInfo;	// volume info for current drive
sl@0
    55
GLDEF_D TFileCacheFlags gDriveCacheFlags = TFileCacheFlags(0);
sl@0
    56
sl@0
    57
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
    58
static TFileCacheConfig gFileCacheConfig;
sl@0
    59
static TBool gDisplayCacheFlags = EFalse;
sl@0
    60
static TBool gWriteCacheFlags = EFalse;
sl@0
    61
static TBool gRomPaged = EFalse;
sl@0
    62
#endif
sl@0
    63
static TBool gRunTests = ETrue;
sl@0
    64
static TBool gRunUnitTests = ETrue;
sl@0
    65
static TBool gRunPerformanceTests = EFalse;
sl@0
    66
static TBool gRunManualTests = EFalse;
sl@0
    67
sl@0
    68
sl@0
    69
LOCAL_D TInt KMaxFileSize = 768 * 1024;
sl@0
    70
sl@0
    71
// Chosing a file size of 128K ensures entire file will be cached
sl@0
    72
//LOCAL_D TInt KMaxFileSize = 128 * 1024;
sl@0
    73
sl@0
    74
LOCAL_D TBuf8<256*1024> DataBuf;
sl@0
    75
sl@0
    76
const TInt KBufSize = 513 * 1024 - 16;
sl@0
    77
HBufC8* gBuf = NULL;
sl@0
    78
sl@0
    79
sl@0
    80
LOCAL_D TPtr8 gBufPtr(NULL, 0);
sl@0
    81
sl@0
    82
const TReal KOneK = 1024;
sl@0
    83
const TReal KOneMeg = 1024 * KOneK;
sl@0
    84
sl@0
    85
const TInt KSegmentSize = 4096;
sl@0
    86
const TInt KSegmentSizeMask = (4096-1);
sl@0
    87
sl@0
    88
GLDEF_D template <class C>
sl@0
    89
GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
sl@0
    90
{
sl@0
    91
    TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
sl@0
    92
sl@0
    93
    TInt r = fs.ControlIo(drv, fkn, ptrC);
sl@0
    94
sl@0
    95
    return r;
sl@0
    96
}
sl@0
    97
sl@0
    98
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
    99
void PrintFileCacheStats(TFileCacheStats& fileCacheStats, TBool aDisplay = ETrue)
sl@0
   100
	{
sl@0
   101
	TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   102
	test_KErrNone(r);
sl@0
   103
	if (!aDisplay)
sl@0
   104
		return;
sl@0
   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"), 
sl@0
   106
		fileCacheStats.iFreeCount, fileCacheStats.iUsedCount, fileCacheStats.iAllocatedSegmentCount,fileCacheStats.iLockedSegmentCount,fileCacheStats.iFilesOnClosedQueue, fileCacheStats.iHoleCount, fileCacheStats.iCommitFailureCount, fileCacheStats.iLockFailureCount);
sl@0
   107
	test.Printf(_L("File cache: iUncachedPacketsRead %d iUncachedBytesRead %d iUncachedPacketsWritten %d iUncachedBytesWritten %d\n"), 
sl@0
   108
		fileCacheStats.iUncachedPacketsRead,
sl@0
   109
		fileCacheStats.iUncachedBytesRead,
sl@0
   110
		fileCacheStats.iUncachedPacketsWritten,
sl@0
   111
		fileCacheStats.iUncachedBytesWritten);
sl@0
   112
	}
sl@0
   113
sl@0
   114
void PrintFileCacheConfig(TFileCacheConfig& aFileCacheConfig, TBool aDisplay = ETrue)
sl@0
   115
	{
sl@0
   116
	TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheConfig, aFileCacheConfig);
sl@0
   117
	test (r == KErrNone);
sl@0
   118
	if (!aDisplay)
sl@0
   119
		return;
sl@0
   120
	
sl@0
   121
	test.Printf(_L("File cache:\nDrive %c\nFlags %08X\nFileCacheReadAsync %d\nFairSchedulingLen %d\nCacheSize %d\nMaxReadAheadLen %d\nClosedFileKeepAliveTime %d\nDirtyDataFlushTime %d"), 
sl@0
   122
		aFileCacheConfig.iDrive + 'A',
sl@0
   123
		aFileCacheConfig.iFlags,
sl@0
   124
		aFileCacheConfig.iFileCacheReadAsync,
sl@0
   125
		aFileCacheConfig.iFairSchedulingLen,
sl@0
   126
		aFileCacheConfig.iCacheSize,
sl@0
   127
		aFileCacheConfig.iMaxReadAheadLen,
sl@0
   128
		aFileCacheConfig.iClosedFileKeepAliveTime,
sl@0
   129
		aFileCacheConfig.iDirtyDataFlushTime);
sl@0
   130
	
sl@0
   131
	}
sl@0
   132
sl@0
   133
void TestDirtyDataWrittenToDisk(TFileCacheStats& fileCacheStats)
sl@0
   134
	{
sl@0
   135
	test.Next(_L("test dirty data has been written to disk"));
sl@0
   136
	// wait a maximum of double KDefaultDirtyDataFlushTime for dirty data to be flushed
sl@0
   137
	const TInt KWaitTime = 250;	// 250 milisecs
sl@0
   138
	for (TInt n=0; n<(gFileCacheConfig.iDirtyDataFlushTime/1000)<<1 ; n+= KWaitTime)
sl@0
   139
		{
sl@0
   140
		test.Printf(_L("After %d milisecs : "), n );
sl@0
   141
		PrintFileCacheStats(fileCacheStats);
sl@0
   142
		User::After(KWaitTime * 1000);		// wait 100 ms
sl@0
   143
		if (fileCacheStats.iLockedSegmentCount == 0)
sl@0
   144
			break;
sl@0
   145
		}
sl@0
   146
	PrintFileCacheStats(fileCacheStats);
sl@0
   147
	test(fileCacheStats.iLockedSegmentCount == 0);
sl@0
   148
	}
sl@0
   149
#endif 
sl@0
   150
sl@0
   151
void TestsInit()
sl@0
   152
	{
sl@0
   153
	gBuf = HBufC8::NewL(KBufSize);
sl@0
   154
	test(gBuf!=NULL);
sl@0
   155
	gBufPtr.Set(gBuf->Des());
sl@0
   156
	}
sl@0
   157
void TestsEnd()
sl@0
   158
	{
sl@0
   159
	delete gBuf;
sl@0
   160
	gBuf = NULL;
sl@0
   161
	}
sl@0
   162
sl@0
   163
LOCAL_C void SetSessionPath(TInt aDrive)
sl@0
   164
	{
sl@0
   165
	gSessionPath=_L("?:\\F32-TST\\");
sl@0
   166
	TChar driveLetter;
sl@0
   167
	TInt r=TheFs.DriveToChar(aDrive,driveLetter);
sl@0
   168
	test_KErrNone(r);
sl@0
   169
	gSessionPath[0]=(TText)driveLetter;
sl@0
   170
	r=TheFs.SetSessionPath(gSessionPath);
sl@0
   171
	test_KErrNone(r);
sl@0
   172
	}
sl@0
   173
sl@0
   174
LOCAL_C void PrintFileMode(TUint aFileMode)
sl@0
   175
	{
sl@0
   176
	TBuf<80> buf;
sl@0
   177
sl@0
   178
	buf.Format(_L("FileMode = %08X"), aFileMode);
sl@0
   179
sl@0
   180
	if (aFileMode & EFileWriteBuffered)
sl@0
   181
		buf.Append(_L(", EFileWriteBuffered"));
sl@0
   182
sl@0
   183
	if (aFileMode & EFileWriteDirectIO)
sl@0
   184
		buf.Append(_L(", EFileWriteDirectIO"));
sl@0
   185
sl@0
   186
	if (aFileMode & EFileReadBuffered)
sl@0
   187
		buf.Append(_L(", EFileReadBuffered"));
sl@0
   188
sl@0
   189
	if (aFileMode & EFileReadDirectIO)
sl@0
   190
		buf.Append(_L(", EFileReadDirectIO"));
sl@0
   191
sl@0
   192
	if (aFileMode & EFileReadAheadOn)
sl@0
   193
		buf.Append(_L(", EFileReadAheadOn"));
sl@0
   194
sl@0
   195
	if (aFileMode & EFileReadAheadOff)
sl@0
   196
		buf.Append(_L(", EFileReadAheadOff"));
sl@0
   197
sl@0
   198
	buf.Append(_L("\n"));
sl@0
   199
	test.Printf(buf);
sl@0
   200
	}
sl@0
   201
sl@0
   202
void FillBuffer(TDes8& aBuffer, TInt aLength)
sl@0
   203
	{
sl@0
   204
	test (aBuffer.MaxLength() >= aLength);
sl@0
   205
	for(TInt i=0; i<aLength; i+=2)
sl@0
   206
		{
sl@0
   207
		aBuffer[i]=(TUint8) (i >> 8);
sl@0
   208
		aBuffer[i+1]=(TUint8) i;
sl@0
   209
		}
sl@0
   210
	}
sl@0
   211
sl@0
   212
void TestBufferFail(TDes8& aBuffer, TInt aPos, TInt aLength)
sl@0
   213
	{
sl@0
   214
	test.Printf(_L("TestBuffer failed at pos %d len %d\n"), aPos, aLength);
sl@0
   215
sl@0
   216
	#define PRINTCH(ch) ((ch >= 0x20 && ch < 0x7F)?ch:' ')
sl@0
   217
	TInt startPos = Max(0, aPos - 64);
sl@0
   218
	TInt endPos = startPos + 64;
sl@0
   219
sl@0
   220
	for(TInt n=startPos; n<=endPos; n+=16)
sl@0
   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]"), 
sl@0
   222
			//&aBuffer[aPos+n],
sl@0
   223
			n,
sl@0
   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],
sl@0
   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]));
sl@0
   226
sl@0
   227
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   228
		TInt x;
sl@0
   229
		TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheDump, x);
sl@0
   230
		test_KErrNone(r);
sl@0
   231
#endif
sl@0
   232
	test (0);
sl@0
   233
	}
sl@0
   234
sl@0
   235
void TestBuffer(TDes8& aBuffer, TInt aPos, TInt aLength)
sl@0
   236
	{
sl@0
   237
	TInt pos = aPos;
sl@0
   238
	for(TInt i=0; i<aLength; i++, pos++)
sl@0
   239
		{
sl@0
   240
		if (pos & 1)
sl@0
   241
			{
sl@0
   242
			if (aBuffer[pos] != (TUint8) pos-1)
sl@0
   243
				TestBufferFail(aBuffer, pos, aLength);
sl@0
   244
			}
sl@0
   245
		else
sl@0
   246
			{
sl@0
   247
			if (aBuffer[pos] != (TUint8) (pos >> 8))
sl@0
   248
				TestBufferFail(aBuffer, pos, aLength);
sl@0
   249
			}
sl@0
   250
		}
sl@0
   251
	}
sl@0
   252
sl@0
   253
sl@0
   254
LOCAL_C void UnitTests()
sl@0
   255
//
sl@0
   256
// Test read file handling.
sl@0
   257
//
sl@0
   258
	{
sl@0
   259
sl@0
   260
	test.Start(_L("File cache read and write unit tests"));
sl@0
   261
	
sl@0
   262
//TheFs.SetDebugRegister(KCACHE);
sl@0
   263
	
sl@0
   264
	RFile f;
sl@0
   265
	TInt r;
sl@0
   266
	TInt pos;
sl@0
   267
	TInt len;
sl@0
   268
	TInt testNum;
sl@0
   269
sl@0
   270
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   271
	TBool simulatelockFailureMode;
sl@0
   272
	TFileCacheStats fileCacheStats;
sl@0
   273
	r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   274
	test (r == KErrNone);
sl@0
   275
	test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
sl@0
   276
	test(fileCacheStats.iFilesOnClosedQueue == 0);
sl@0
   277
#endif
sl@0
   278
sl@0
   279
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   280
	// turn OFF lock failure mode 
sl@0
   281
	simulatelockFailureMode = EFalse;
sl@0
   282
	r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
   283
	test (r == KErrNone);
sl@0
   284
#endif
sl@0
   285
sl@0
   286
	TFileName testFile   = _L("TEST.BIN");
sl@0
   287
sl@0
   288
	//**********************************
sl@0
   289
	// Test Read-Modify-Write
sl@0
   290
	//**********************************
sl@0
   291
	test.Next(_L("Test read-modify-write"));
sl@0
   292
	gBufPtr.SetLength(KBufSize);
sl@0
   293
	FillBuffer(gBufPtr, KBufSize);
sl@0
   294
	TestBuffer(gBufPtr, 0,KBufSize);
sl@0
   295
	TPtrC8 writePtr;
sl@0
   296
	TPtr8 readPtr(gBuf->Des());
sl@0
   297
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   298
	TInt uncachedBytesRead;
sl@0
   299
	TInt uncachedPacketsRead;
sl@0
   300
#endif
sl@0
   301
sl@0
   302
	// create an empty file, so that any writes overlapping segemt boundaries
sl@0
   303
	// need a read first
sl@0
   304
	// create a test file using directIO and then re-open it in buffered mode, 
sl@0
   305
	// so that any writes overlapping segemt boundaries need a read first
sl@0
   306
	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO);
sl@0
   307
	test_KErrNone(r);
sl@0
   308
	writePtr.Set(gBuf->Des());
sl@0
   309
	r = f.Write(0, writePtr);
sl@0
   310
	test_KErrNone(r);
sl@0
   311
	f.Close();
sl@0
   312
	r = f.Open(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
sl@0
   313
	test_KErrNone(r);
sl@0
   314
sl@0
   315
	TInt cacheLineLen = 128*1024;
sl@0
   316
sl@0
   317
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   318
	PrintFileCacheStats(fileCacheStats);
sl@0
   319
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   320
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   321
#endif
sl@0
   322
sl@0
   323
	// write 1 partial segment at offset 0 to 7 in segment
sl@0
   324
	test.Next(_L("Test read-modify-write #1"));
sl@0
   325
	pos = cacheLineLen*0 + KSegmentSize*2 + 0;
sl@0
   326
	len = 7;
sl@0
   327
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   328
	r = f.Write(pos, writePtr, len);
sl@0
   329
	test_KErrNone(r);
sl@0
   330
	// read back & verify whole segment
sl@0
   331
	pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
sl@0
   332
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   333
	readPtr.SetLength(len);
sl@0
   334
	readPtr.FillZ();
sl@0
   335
	r = f.Read(pos, readPtr, len);
sl@0
   336
	test_KErrNone(r);
sl@0
   337
	TestBuffer(gBufPtr, pos, len);
sl@0
   338
	test_KErrNone(r);
sl@0
   339
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   340
	PrintFileCacheStats(fileCacheStats);
sl@0
   341
	test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
sl@0
   342
	test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
sl@0
   343
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   344
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   345
#endif
sl@0
   346
sl@0
   347
	// write 1 partial segment at offset 7 to 4096 in segment
sl@0
   348
	test.Next(_L("Test read-modify-write #2"));
sl@0
   349
	pos = cacheLineLen*0 + KSegmentSize*3 + 7;
sl@0
   350
	len = KSegmentSize - 7;
sl@0
   351
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   352
	r = f.Write(pos, writePtr, len);
sl@0
   353
	test_KErrNone(r);
sl@0
   354
	// read back & verify whole segment
sl@0
   355
	pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
sl@0
   356
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   357
	readPtr.SetLength(len);
sl@0
   358
	readPtr.FillZ();
sl@0
   359
	r = f.Read(pos, readPtr, len);
sl@0
   360
	test_KErrNone(r);
sl@0
   361
	TestBuffer(gBufPtr, pos, len);
sl@0
   362
	test_KErrNone(r);
sl@0
   363
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   364
	PrintFileCacheStats(fileCacheStats);
sl@0
   365
	test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
sl@0
   366
	test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
sl@0
   367
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   368
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   369
#endif
sl@0
   370
sl@0
   371
	// write 1 partial segment at offset 7 to 37 in segment
sl@0
   372
	test.Next(_L("Test read-modify-write #3"));
sl@0
   373
	pos = cacheLineLen*0 + KSegmentSize*4 + 7;
sl@0
   374
	len = 30;
sl@0
   375
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   376
	r = f.Write(pos, writePtr, len);
sl@0
   377
	test_KErrNone(r);
sl@0
   378
	// read back & verify whole segment
sl@0
   379
	pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
sl@0
   380
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   381
	readPtr.SetLength(len);
sl@0
   382
	readPtr.FillZ();
sl@0
   383
	r = f.Read(pos, readPtr, len);
sl@0
   384
	test_KErrNone(r);
sl@0
   385
	TestBuffer(gBufPtr, pos, len);
sl@0
   386
	test_KErrNone(r);
sl@0
   387
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   388
	PrintFileCacheStats(fileCacheStats);
sl@0
   389
	test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize);
sl@0
   390
	test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);
sl@0
   391
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   392
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   393
#endif
sl@0
   394
sl@0
   395
	// write 2 segments, first and last both partial
sl@0
   396
	test.Next(_L("Test read-modify-write #4"));
sl@0
   397
	pos = cacheLineLen*1 + KSegmentSize*2 + 3;
sl@0
   398
	len = KSegmentSize * 1;
sl@0
   399
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   400
	r = f.Write(pos, writePtr, len);
sl@0
   401
	test_KErrNone(r);
sl@0
   402
	// read back & verify whole segment
sl@0
   403
	pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
sl@0
   404
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   405
	readPtr.SetLength(len);
sl@0
   406
	readPtr.FillZ();
sl@0
   407
	r = f.Read(pos, readPtr, len);
sl@0
   408
	test_KErrNone(r);
sl@0
   409
	TestBuffer(gBufPtr, pos, len);
sl@0
   410
	test_KErrNone(r);
sl@0
   411
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   412
	PrintFileCacheStats(fileCacheStats);
sl@0
   413
	test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize*2);
sl@0
   414
	// should read both segments in one read as they are contiguous
sl@0
   415
	test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 1);	
sl@0
   416
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   417
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   418
#endif
sl@0
   419
sl@0
   420
	// write 3 segments, first and last both partial
sl@0
   421
	test.Next(_L("Test read-modify-write #5"));
sl@0
   422
	pos = cacheLineLen*2 + KSegmentSize*2 + 7;
sl@0
   423
	len = KSegmentSize * 2;
sl@0
   424
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   425
	r = f.Write(pos, writePtr, len);
sl@0
   426
	test_KErrNone(r);
sl@0
   427
	// read back & verify whole segment
sl@0
   428
	pos&= ~KSegmentSizeMask; len = (len + KSegmentSize-1) & ~KSegmentSizeMask;
sl@0
   429
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   430
	readPtr.SetLength(len);
sl@0
   431
	readPtr.FillZ();
sl@0
   432
	r = f.Read(pos, readPtr, len);
sl@0
   433
	test_KErrNone(r);
sl@0
   434
	TestBuffer(gBufPtr, pos, len);
sl@0
   435
	test_KErrNone(r);
sl@0
   436
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   437
	PrintFileCacheStats(fileCacheStats);
sl@0
   438
	test (fileCacheStats.iUncachedBytesRead - uncachedBytesRead == KSegmentSize*2);
sl@0
   439
	test (fileCacheStats.iUncachedPacketsRead - uncachedPacketsRead == 2);
sl@0
   440
	uncachedBytesRead = fileCacheStats.iUncachedBytesRead;
sl@0
   441
	uncachedPacketsRead = fileCacheStats.iUncachedPacketsRead;
sl@0
   442
#endif
sl@0
   443
sl@0
   444
	f.Close();
sl@0
   445
sl@0
   446
	//**************************************************************
sl@0
   447
	// Test dirty data NOT written to disk if continuously writing to a file which fits in tke cache
sl@0
   448
	//**************************************************************
sl@0
   449
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   450
	test.Printf(_L("Test dirty data NOT written to disk if continuously writing to a file which fits in tke cache...\n"));
sl@0
   451
sl@0
   452
	// flush closed files queue to empty cache 
sl@0
   453
	test.Printf(_L("Flushing close queue to empty cache...\n"));
sl@0
   454
	r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
sl@0
   455
	test_KErrNone(r);
sl@0
   456
sl@0
   457
	r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
sl@0
   458
	test_KErrNone(r);
sl@0
   459
sl@0
   460
	RTimer timer;
sl@0
   461
	timer.CreateLocal();
sl@0
   462
	TRequestStatus reqStat;
sl@0
   463
	timer.After(reqStat,gFileCacheConfig.iClosedFileKeepAliveTime*3); // write 3 times the flush timer
sl@0
   464
sl@0
   465
	pos = 0;
sl@0
   466
	TInt bufLen = 7;
sl@0
   467
	TInt maxLockedSegmentCount = 0;
sl@0
   468
	while (reqStat == KRequestPending)
sl@0
   469
		{
sl@0
   470
		bufLen = (bufLen + 1023) & 0x3FFF;
sl@0
   471
		len = Min(bufLen, KBufSize - pos);
sl@0
   472
		len = Min(len, gFileCacheConfig.iCacheSize-pos);
sl@0
   473
		TPtrC8 writePtr = gBuf->Mid(pos, len);
sl@0
   474
		r = f.Write(pos, writePtr, len);
sl@0
   475
		test_KErrNone(r);
sl@0
   476
		pos+= len;
sl@0
   477
		TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   478
		test_KErrNone(r);
sl@0
   479
		// test the locked (i.e. dirty) count always goes up & never down (down would indicate a flush)
sl@0
   480
		if (fileCacheStats.iLockedSegmentCount != maxLockedSegmentCount)
sl@0
   481
			test.Printf(_L("iLockedSegmentCount %d...\n"), fileCacheStats.iLockedSegmentCount);
sl@0
   482
sl@0
   483
		test(fileCacheStats.iLockedSegmentCount >= maxLockedSegmentCount);
sl@0
   484
		maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
sl@0
   485
		// wrap to start of file
sl@0
   486
		if (pos >= gFileCacheConfig.iCacheSize)	
sl@0
   487
			pos = 0;
sl@0
   488
		}
sl@0
   489
	timer.Close();
sl@0
   490
sl@0
   491
	test(fileCacheStats.iLockedSegmentCount > 0);
sl@0
   492
sl@0
   493
	if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
sl@0
   494
		TestDirtyDataWrittenToDisk(fileCacheStats);
sl@0
   495
	f.Close();
sl@0
   496
#endif
sl@0
   497
sl@0
   498
sl@0
   499
	//**************************************************************
sl@0
   500
	// Test dirty data written to disk
sl@0
   501
	//**************************************************************
sl@0
   502
	enum {ETestDataWrittenAfterTimeout, ETestDataWrittenAfterFileClose, ETestDataWrittenAfterSessionClose, ETestEnd};
sl@0
   503
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   504
	for (testNum = 0; testNum < ETestEnd; testNum++)
sl@0
   505
#else
sl@0
   506
	for (testNum = 0; testNum < 1; testNum++)
sl@0
   507
#endif
sl@0
   508
		{
sl@0
   509
		switch(testNum)
sl@0
   510
			{
sl@0
   511
			case ETestDataWrittenAfterTimeout		: test.Next(_L("ETestDataWrittenAfterTimeout"));		break;
sl@0
   512
			case ETestDataWrittenAfterFileClose		: test.Next(_L("ETestDataWrittenAfterFileClose"));		break;
sl@0
   513
			case ETestDataWrittenAfterSessionClose	: test.Next(_L("ETestDataWrittenAfterSessionClose"));	break;
sl@0
   514
			};
sl@0
   515
sl@0
   516
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   517
		// flush closed files queue to empty cache 
sl@0
   518
		test.Printf(_L("Flushing close queue to empty cache...\n"));
sl@0
   519
		r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
sl@0
   520
		test_KErrNone(r);
sl@0
   521
#endif
sl@0
   522
sl@0
   523
		r = f.Replace(TheFs, testFile, EFileReadBuffered | EFileWrite | EFileWriteBuffered);
sl@0
   524
		test_KErrNone(r);
sl@0
   525
sl@0
   526
sl@0
   527
		gBufPtr.SetLength(KBufSize);
sl@0
   528
		
sl@0
   529
		test.Printf(_L("writing file in small blocks to test write caching...\n"));
sl@0
   530
sl@0
   531
		FillBuffer(gBufPtr, KBufSize);
sl@0
   532
		TestBuffer(gBufPtr, 0,KBufSize);
sl@0
   533
sl@0
   534
		pos = 0;
sl@0
   535
		TInt bufLen = 7;
sl@0
   536
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   537
		TInt maxLockedSegmentCount = 0;
sl@0
   538
		TInt maxUsedCount = 0;
sl@0
   539
#endif
sl@0
   540
		while (pos < KBufSize) 
sl@0
   541
			{
sl@0
   542
			bufLen = (bufLen + 1023) & 0x3FFF;
sl@0
   543
			len = Min(bufLen, KBufSize - pos);
sl@0
   544
//RDebug::Print(_L("write len %d"), len);
sl@0
   545
			TPtrC8 writePtr = gBuf->Mid(pos, len);
sl@0
   546
			r = f.Write(pos, writePtr, len);
sl@0
   547
			test_KErrNone(r);
sl@0
   548
			pos+= len;
sl@0
   549
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   550
//			PrintFileCacheStats(fileCacheStats);
sl@0
   551
			TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   552
			test_KErrNone(r);
sl@0
   553
			maxLockedSegmentCount = Max(maxLockedSegmentCount, fileCacheStats.iLockedSegmentCount);
sl@0
   554
			maxUsedCount = Max(maxUsedCount, fileCacheStats.iUsedCount);
sl@0
   555
#endif
sl@0
   556
			}
sl@0
   557
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   558
		test.Next(_L("Test maxiimum locked page and cacheline count is reasonable"));
sl@0
   559
		test.Printf(_L("maxLockedSegmentCount %d maxUsedCount %d"), maxLockedSegmentCount, maxUsedCount);
sl@0
   560
		test (maxLockedSegmentCount > 0 && maxLockedSegmentCount <= (gFileCacheConfig.iCacheSize * 2) / KSegmentSize );
sl@0
   561
		test (maxUsedCount > 0 && maxUsedCount <= 5);
sl@0
   562
#endif
sl@0
   563
sl@0
   564
sl@0
   565
sl@0
   566
		if (testNum == ETestDataWrittenAfterTimeout)
sl@0
   567
			{
sl@0
   568
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   569
			if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
sl@0
   570
				TestDirtyDataWrittenToDisk(fileCacheStats);
sl@0
   571
#endif
sl@0
   572
			f.Close();
sl@0
   573
			}
sl@0
   574
sl@0
   575
		if (testNum == ETestDataWrittenAfterFileClose)
sl@0
   576
			{
sl@0
   577
			f.Close();
sl@0
   578
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   579
			test.Next(_L("test dirty data has been written to disk after file close"));
sl@0
   580
			PrintFileCacheStats(fileCacheStats);
sl@0
   581
			test(fileCacheStats.iLockedSegmentCount == 0);
sl@0
   582
#endif
sl@0
   583
			}
sl@0
   584
sl@0
   585
		if (testNum == ETestDataWrittenAfterSessionClose)
sl@0
   586
			{
sl@0
   587
			// verify that closing the file server session (i.e. not the file)
sl@0
   588
			// flushes the data to disk...
sl@0
   589
			// *** NB This is likely to complete sometime AFTER returning from RFs::Close()
sl@0
   590
			// *** as  the file server doesn't wait for the disconnect thread to complete !!! 
sl@0
   591
sl@0
   592
			TheFs.Close();
sl@0
   593
			TheFs.Connect();
sl@0
   594
			SetSessionPath(gDrive);
sl@0
   595
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   596
			test.Next(_L("Test dirty data is eventually written to disk after session close"));
sl@0
   597
			TestDirtyDataWrittenToDisk(fileCacheStats);
sl@0
   598
			test(fileCacheStats.iLockedSegmentCount == 0);
sl@0
   599
#endif
sl@0
   600
			}
sl@0
   601
sl@0
   602
		}	// for (TInt testNum = 0; testNum < ETestEnd; testNum++)
sl@0
   603
sl@0
   604
sl@0
   605
//#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   606
//	PrintFileCacheStats(fileCacheStats);
sl@0
   607
//#endif
sl@0
   608
sl@0
   609
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   610
	// flush closed files queue to empty cache 
sl@0
   611
	test.Printf(_L("Flushing close queue to empty cache...\n"));
sl@0
   612
	r = TheFs.ControlIo(gDrive, KControlIoFlushClosedFiles);
sl@0
   613
	test_KErrNone(r);
sl@0
   614
#endif
sl@0
   615
sl@0
   616
	r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileWrite);
sl@0
   617
	test_KErrNone(r);
sl@0
   618
sl@0
   619
	TInt size;
sl@0
   620
	r = f.Size(size);
sl@0
   621
	test (r == KErrNone);
sl@0
   622
	test (size = KBufSize);
sl@0
   623
sl@0
   624
	readPtr.Set(gBuf->Des());
sl@0
   625
sl@0
   626
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   627
	// Allocate full cachelines - so we can enable hole testing
sl@0
   628
	TBool allocateAllSegmentsInCacheLine = ETrue;
sl@0
   629
	r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine);
sl@0
   630
	test (r == KErrNone);
sl@0
   631
	PrintFileCacheStats(fileCacheStats, EFalse);
sl@0
   632
	TInt holesDetected = fileCacheStats.iHoleCount;
sl@0
   633
	TInt lockFailures = fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount;
sl@0
   634
#endif
sl@0
   635
sl@0
   636
	test.Next(_L("Test reading a partially filled cacheline"));
sl@0
   637
	// create a cacheline with only the first segment filled
sl@0
   638
	TInt startPos = KSegmentSize;
sl@0
   639
	pos = startPos;
sl@0
   640
	len = KSegmentSize;
sl@0
   641
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   642
	r = f.Write(pos, writePtr, len);
sl@0
   643
	test_KErrNone(r);
sl@0
   644
sl@0
   645
	// read from first & second segments
sl@0
   646
	pos = startPos;
sl@0
   647
	len = 8192;
sl@0
   648
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   649
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   650
	readPtr.SetLength(len);
sl@0
   651
	r = f.Read(pos, readPtr, len);
sl@0
   652
	test_KErrNone(r);
sl@0
   653
	TestBuffer(gBufPtr, pos, len);
sl@0
   654
sl@0
   655
	
sl@0
   656
	test.Next(_L("Test reading an empty segment towards the end of a partially filled cacheline (hole test)"));
sl@0
   657
	// read from segment #4 and beyond end of cacheline into next
sl@0
   658
	pos = startPos + KSegmentSize * 4;
sl@0
   659
	len = KSegmentSize * 33;	// 132 K
sl@0
   660
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   661
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   662
	readPtr.SetLength(len);
sl@0
   663
	r = f.Read(pos, readPtr, len);
sl@0
   664
	test_KErrNone(r);
sl@0
   665
	TestBuffer(gBufPtr, pos, len);
sl@0
   666
sl@0
   667
sl@0
   668
	test.Next(_L("Test writing to an empty segment towards the end of a partially filled cacheline (hole test)"));
sl@0
   669
	// create a cacheline with only the first segment filled
sl@0
   670
	startPos = 256 * 1024;			
sl@0
   671
	pos = startPos;
sl@0
   672
	len = KSegmentSize;
sl@0
   673
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   674
	r = f.Write(pos, writePtr, len);
sl@0
   675
	test_KErrNone(r);
sl@0
   676
sl@0
   677
sl@0
   678
	// write into segment 3, 4 & 5
sl@0
   679
	pos = startPos + KSegmentSize * 2;
sl@0
   680
	len = KSegmentSize * 3;
sl@0
   681
	writePtr.Set(gBuf->Mid(pos, len));
sl@0
   682
	r = f.Write(pos, writePtr, len);
sl@0
   683
	test_KErrNone(r);
sl@0
   684
	// read back whole cacheline & verify
sl@0
   685
	pos = startPos;
sl@0
   686
	len = KSegmentSize * 32;	// 128 K
sl@0
   687
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   688
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   689
	readPtr.SetLength(len);
sl@0
   690
	r = f.Read(pos, readPtr, len);
sl@0
   691
	test_KErrNone(r);
sl@0
   692
	TestBuffer(gBufPtr, pos, len);
sl@0
   693
sl@0
   694
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   695
	PrintFileCacheStats(fileCacheStats);
sl@0
   696
	if (fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount != lockFailures)
sl@0
   697
		{
sl@0
   698
		if (gRomPaged)
sl@0
   699
			{
sl@0
   700
			test.Printf(_L("Lock failures detected on paged ROM, abandoning hole test"));
sl@0
   701
			}
sl@0
   702
		else
sl@0
   703
			{
sl@0
   704
			test.Printf(_L("Unexpected lock failures detected on unpaged ROM!!!"));
sl@0
   705
			test(0);
sl@0
   706
			}
sl@0
   707
		}
sl@0
   708
	else
sl@0
   709
		{
sl@0
   710
		test(fileCacheStats.iHoleCount > holesDetected);
sl@0
   711
		}
sl@0
   712
	// Don't allocate full cachelines any more
sl@0
   713
	allocateAllSegmentsInCacheLine = EFalse;
sl@0
   714
	r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine);
sl@0
   715
	test (r == KErrNone);
sl@0
   716
#endif
sl@0
   717
sl@0
   718
sl@0
   719
sl@0
   720
	gBufPtr.FillZ();
sl@0
   721
	gBufPtr.SetLength(KBufSize);
sl@0
   722
sl@0
   723
	
sl@0
   724
sl@0
   725
	readPtr.SetLength(0);
sl@0
   726
sl@0
   727
sl@0
   728
	// read from middle of fifth sector to half way thru seventh
sl@0
   729
	test.Next(_L("Test read that spans two pages"));
sl@0
   730
	pos = 512*4 + 16;
sl@0
   731
	len = 512*2;
sl@0
   732
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   733
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   734
	readPtr.SetLength(len);
sl@0
   735
	r = f.Read(pos, readPtr, len);
sl@0
   736
	test_KErrNone(r);
sl@0
   737
	TestBuffer(gBufPtr, pos, len);
sl@0
   738
sl@0
   739
sl@0
   740
sl@0
   741
	// read to end of file
sl@0
   742
	test.Next(_L("Test reading past end of file"));
sl@0
   743
    pos = KBufSize - 0x100;			// 0xfb05;
sl@0
   744
	len = KBufSize - pos;
sl@0
   745
//	pos = KBufSize - 16;
sl@0
   746
//	len = 512;;
sl@0
   747
//	len = Min(len, KBufSize-pos);
sl@0
   748
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   749
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   750
	readPtr.SetLength(len);
sl@0
   751
	r = f.Read(pos, readPtr, len/* + 0x67*/);
sl@0
   752
	test_KErrNone(r);
sl@0
   753
sl@0
   754
	test.Next(_L("Test async reads"));
sl@0
   755
	// issue 2 async reads
sl@0
   756
	pos = KSegmentSize*7 + 16;
sl@0
   757
	len = KSegmentSize;
sl@0
   758
	RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   759
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   760
	readPtr.SetLength(len);
sl@0
   761
sl@0
   762
	TInt pos2 = pos + len;
sl@0
   763
	TInt len2 = KSegmentSize;
sl@0
   764
	TPtr8 readPtr2 = gBuf->Des();
sl@0
   765
	readPtr2.Set(gBufPtr.MidTPtr(pos2, len2));
sl@0
   766
	readPtr2.SetLength(len2);
sl@0
   767
	
sl@0
   768
	TRequestStatus status1(KRequestPending);
sl@0
   769
	TRequestStatus status2(KRequestPending);
sl@0
   770
	
sl@0
   771
	f.Read(pos, readPtr, len, status1);
sl@0
   772
	f.Read(readPtr2, len2, status2);
sl@0
   773
sl@0
   774
sl@0
   775
	User::WaitForRequest(status1);
sl@0
   776
	User::WaitForRequest(status2);
sl@0
   777
	test.Printf(_L("status1 %d status2 %d\n"), status1.Int(), status2.Int());
sl@0
   778
	TestBuffer(gBufPtr, pos, len);
sl@0
   779
	TestBuffer(gBufPtr, pos2, len2);
sl@0
   780
sl@0
   781
sl@0
   782
	test.Next(_L("Read entire file"));
sl@0
   783
sl@0
   784
	for (pos = 0, len = 1; len <= 1024 && pos < KBufSize; len = (len+1) & 0x3FF)
sl@0
   785
		{
sl@0
   786
		len = Min(len, KBufSize-pos);
sl@0
   787
//		RDebug::Print(_L("+%x, %x\n"), pos, len);
sl@0
   788
		readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   789
		readPtr.SetLength(len);
sl@0
   790
sl@0
   791
		r = f.Read(pos, readPtr, len);
sl@0
   792
		test_KErrNone(r);
sl@0
   793
		TestBuffer(gBufPtr, pos, len);
sl@0
   794
		test_KErrNone(r);
sl@0
   795
		pos+= len;
sl@0
   796
		}
sl@0
   797
	
sl@0
   798
	TestBuffer(gBufPtr, 0, KBufSize);
sl@0
   799
sl@0
   800
	// read from position zero to ensure it's cached
sl@0
   801
	pos = 0;
sl@0
   802
	len = 512;
sl@0
   803
	readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   804
	readPtr.SetLength(len);
sl@0
   805
	r = f.Read(pos, readPtr, len);
sl@0
   806
	test_KErrNone(r);
sl@0
   807
	TestBuffer(gBufPtr, pos, len);
sl@0
   808
	test_KErrNone(r);
sl@0
   809
sl@0
   810
	f.Close();
sl@0
   811
sl@0
   812
sl@0
   813
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   814
	r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   815
	test (r == KErrNone);
sl@0
   816
	test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
sl@0
   817
	test(fileCacheStats.iFilesOnClosedQueue == 1);
sl@0
   818
#endif
sl@0
   819
	//
sl@0
   820
sl@0
   821
	
sl@0
   822
	//**************************************************************
sl@0
   823
	// Test closed file queue 
sl@0
   824
	//**************************************************************
sl@0
   825
	enum 
sl@0
   826
		{
sl@0
   827
		ETestCloseQueueEmptyAfterTimeout, 
sl@0
   828
		ETestCloseQueueEmptyAfterOpenWithDirectIo, 
sl@0
   829
		ETestCloseQueueEmptyAfterDelete, 
sl@0
   830
		ETestCloseEnd};
sl@0
   831
	for (testNum = 0; testNum < ETestCloseEnd; testNum++)
sl@0
   832
		{
sl@0
   833
	
sl@0
   834
		test.Next(_L("Reopen file & verify closed queue is empty"));
sl@0
   835
sl@0
   836
		r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered);
sl@0
   837
		test_KErrNone(r);
sl@0
   838
		pos = 0;
sl@0
   839
		len = 512;
sl@0
   840
		readPtr.Set(gBufPtr.MidTPtr(pos, len));
sl@0
   841
		readPtr.SetLength(len);
sl@0
   842
		r = f.Read(pos, readPtr, len);
sl@0
   843
		test_KErrNone(r);
sl@0
   844
		TestBuffer(gBufPtr, pos, len);
sl@0
   845
		test_KErrNone(r);
sl@0
   846
sl@0
   847
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   848
		r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   849
		test (r == KErrNone);
sl@0
   850
		test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
sl@0
   851
		test(fileCacheStats.iFilesOnClosedQueue == 0);
sl@0
   852
#endif
sl@0
   853
		f.Close();
sl@0
   854
sl@0
   855
		test.Next(_L("close & verify file is back on close queue"));
sl@0
   856
sl@0
   857
sl@0
   858
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   859
		r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   860
		test (r == KErrNone);
sl@0
   861
		test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
sl@0
   862
		test(fileCacheStats.iFilesOnClosedQueue == 1);
sl@0
   863
#endif
sl@0
   864
sl@0
   865
		if (testNum == ETestCloseQueueEmptyAfterDelete)
sl@0
   866
			{
sl@0
   867
			test.Next(_L("delete file and verify closed queue is empty"));
sl@0
   868
			r = TheFs.Delete(testFile);
sl@0
   869
			test_KErrNone(r);
sl@0
   870
			}
sl@0
   871
		if (testNum == ETestCloseQueueEmptyAfterTimeout)
sl@0
   872
			{
sl@0
   873
			test.Next(_L("wait for a while and verify closed queue is empty"));
sl@0
   874
			// wait for closed file queue to empty
sl@0
   875
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   876
			User::After(gFileCacheConfig.iClosedFileKeepAliveTime + 1000000);
sl@0
   877
#endif
sl@0
   878
			}
sl@0
   879
		if (testNum == ETestCloseQueueEmptyAfterOpenWithDirectIo)
sl@0
   880
			{
sl@0
   881
			test.Next(_L("Re-open file in directIo mode and then close and verify closed queue is empty"));
sl@0
   882
			r = f.Open(TheFs, testFile, EFileRead | EFileReadDirectIO);
sl@0
   883
			test_KErrNone(r);
sl@0
   884
			f.Close();
sl@0
   885
			}
sl@0
   886
sl@0
   887
	#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   888
		r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   889
		test (r == KErrNone);
sl@0
   890
		test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue);
sl@0
   891
		test(fileCacheStats.iFilesOnClosedQueue == 0);
sl@0
   892
	#endif
sl@0
   893
		}
sl@0
   894
sl@0
   895
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   896
	// turn lock failure mode back ON (if enabled)
sl@0
   897
	simulatelockFailureMode = ETrue;
sl@0
   898
	r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
   899
	test (r == KErrNone);
sl@0
   900
#endif
sl@0
   901
sl@0
   902
	//**************************************************************
sl@0
   903
	// Test opening a file with a silly open mode flags combinations 
sl@0
   904
	//**************************************************************
sl@0
   905
	test.Next(_L("Open file with illegal cache on/off bits"));
sl@0
   906
	r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileReadDirectIO);
sl@0
   907
	test_Value(r, r==KErrArgument);
sl@0
   908
	r = f.Open(TheFs, testFile, EFileRead | EFileWriteBuffered | EFileWriteDirectIO);
sl@0
   909
	test_Value(r, r==KErrArgument);
sl@0
   910
	//**********************************
sl@0
   911
	// Test that continuously appending to a file yields the correct size...
sl@0
   912
	// NB: Must have lock failure more ON in debug mode for this test to pass
sl@0
   913
	//**********************************
sl@0
   914
	test.Next(_L("Test appending to a file & checking the file size..."));
sl@0
   915
	gBufPtr.SetLength(KBufSize);
sl@0
   916
sl@0
   917
	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered);
sl@0
   918
	test_KErrNone(r);
sl@0
   919
sl@0
   920
	const TInt KWriteLen = KSegmentSize+1;
sl@0
   921
	writePtr.Set(gBuf->Des().Ptr(), KWriteLen);
sl@0
   922
sl@0
   923
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   924
	r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   925
	test (r == KErrNone);
sl@0
   926
	test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount);
sl@0
   927
	TInt writeThroughWithDirtyDataCountOld = fileCacheStats.iWriteThroughWithDirtyDataCount;
sl@0
   928
	TInt writeThroughWithDirtyDataCountNew = writeThroughWithDirtyDataCountOld;
sl@0
   929
#endif
sl@0
   930
sl@0
   931
	TInt fileSize = 0;
sl@0
   932
	for (TInt i=0; i<4; i++)
sl@0
   933
		{
sl@0
   934
		fileSize = 0;
sl@0
   935
		r = f.SetSize(fileSize);
sl@0
   936
		test (r == KErrNone);
sl@0
   937
		for (pos = 0; pos < KMaxFileSize; )
sl@0
   938
			{
sl@0
   939
			r = f.Write(pos, writePtr);
sl@0
   940
			if (r != KErrNone)
sl@0
   941
				{
sl@0
   942
				test.Printf(_L("Iter #%d, write pos %d size %d, Write() returned %d"), i, pos, fileSize, r);
sl@0
   943
				r = f.Flush();
sl@0
   944
				test.Printf(_L("Flush returned %d"), r);
sl@0
   945
				test(0);
sl@0
   946
				}
sl@0
   947
			test(r == KErrNone);
sl@0
   948
			pos+= writePtr.Length();
sl@0
   949
sl@0
   950
			r = f.Size(fileSize);
sl@0
   951
			test (r == KErrNone);
sl@0
   952
			if (fileSize != pos)
sl@0
   953
				{
sl@0
   954
				test.Printf(_L("Iter #%d, write pos %d != size %d"), i, pos, fileSize);
sl@0
   955
				r = f.Flush();
sl@0
   956
				test.Printf(_L("Flush returned %d"), r);
sl@0
   957
				test(0);
sl@0
   958
				}
sl@0
   959
			test (fileSize == pos);
sl@0
   960
sl@0
   961
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   962
			r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats);
sl@0
   963
			test (r == KErrNone);
sl@0
   964
			writeThroughWithDirtyDataCountNew = fileCacheStats.iWriteThroughWithDirtyDataCount;
sl@0
   965
			if (writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld)
sl@0
   966
				{
sl@0
   967
				test.Printf(_L("Iter #%d, write pos %d size %d"), i, pos, fileSize);
sl@0
   968
				test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount);
sl@0
   969
				i = 4;
sl@0
   970
				break;
sl@0
   971
				}
sl@0
   972
#endif
sl@0
   973
sl@0
   974
			}
sl@0
   975
		}
sl@0
   976
sl@0
   977
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
   978
	test(writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld);
sl@0
   979
#endif
sl@0
   980
sl@0
   981
sl@0
   982
	f.Close();
sl@0
   983
sl@0
   984
sl@0
   985
//TheFs.SetDebugRegister(0);
sl@0
   986
	test.End();
sl@0
   987
	}
sl@0
   988
sl@0
   989
sl@0
   990
// This thread is used to test what happens if requests are sent to the file server
sl@0
   991
// while the drive thread is hung in the critical notifier server. The requests should
sl@0
   992
// complete immediately with KErrNotReady
sl@0
   993
TInt ReaderThread(TAny* aFileName)
sl@0
   994
	{
sl@0
   995
	RTest test(_L("T_FILECACHE, ReaderThread"));
sl@0
   996
	
sl@0
   997
	TDesC& fileName = *(TDesC*) aFileName;
sl@0
   998
sl@0
   999
	RFs fs;
sl@0
  1000
	TInt r = fs.Connect();
sl@0
  1001
	test (r==KErrNone);
sl@0
  1002
	r = fs.SetSessionPath(gSessionPath);
sl@0
  1003
	test (r==KErrNone);
sl@0
  1004
sl@0
  1005
sl@0
  1006
	RFile file;
sl@0
  1007
	r = file.Open(fs, fileName, EFileRead | EFileReadBuffered | EFileShareReadersOrWriters);
sl@0
  1008
	test_KErrNone(r);
sl@0
  1009
sl@0
  1010
	RTimer timer;
sl@0
  1011
	timer.CreateLocal();
sl@0
  1012
	TRequestStatus reqStat;
sl@0
  1013
	timer.After(reqStat,10000000); // Read for 10 secs
sl@0
  1014
sl@0
  1015
	TInt pos=0;
sl@0
  1016
	TInt KReadLen = 32768;
sl@0
  1017
	TInt retCode = KErrNone;
sl@0
  1018
		
sl@0
  1019
	for (TInt i=0; reqStat == KRequestPending; i++)
sl@0
  1020
		{
sl@0
  1021
		r = file.Read(pos, DataBuf, KReadLen);
sl@0
  1022
		test_Value(r, r == KErrNone || r == KErrNotReady);
sl@0
  1023
sl@0
  1024
		//test.Printf(_L("ReaderThread: iter %d, read at %d ret %d\n"), i, pos, r);
sl@0
  1025
		if (r == KErrNotReady)
sl@0
  1026
			retCode = r;
sl@0
  1027
		else if (r == KErrNone)
sl@0
  1028
			pos = DataBuf.Length() == 0 ? 0: pos + DataBuf.Length();
sl@0
  1029
		if (retCode == KErrNotReady)
sl@0
  1030
			test.Printf(_L("ReaderThread: iter %d, read at %d ret %d \n"), i, pos, r);
sl@0
  1031
		}
sl@0
  1032
sl@0
  1033
	timer.Close();
sl@0
  1034
	file.Close();
sl@0
  1035
	fs.Close();
sl@0
  1036
sl@0
  1037
	return retCode;
sl@0
  1038
	}
sl@0
  1039
sl@0
  1040
sl@0
  1041
void ManualTests()
sl@0
  1042
	{
sl@0
  1043
	RFile f;
sl@0
  1044
	TInt r;
sl@0
  1045
	gBufPtr.SetLength(KBufSize);
sl@0
  1046
	FillBuffer(gBufPtr, KBufSize);
sl@0
  1047
	TestBuffer(gBufPtr, 0,KBufSize);
sl@0
  1048
sl@0
  1049
	TPtrC8 writePtr;
sl@0
  1050
	writePtr.Set(gBuf->Des());
sl@0
  1051
	
sl@0
  1052
	TFileName testFile   = _L("TEST.BIN");
sl@0
  1053
	
sl@0
  1054
#if defined(_DEBUG)
sl@0
  1055
	test.Next(_L("Testing writing and then closing with an immediate simulated card eject"));
sl@0
  1056
	test.Printf(_L("**********************************************************\n"));
sl@0
  1057
	test.Printf(_L("When critical notifier message appears, PRESS RETRY\n"));
sl@0
  1058
	test.Printf(_L("**********************************************************\n"));
sl@0
  1059
sl@0
  1060
	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
sl@0
  1061
	test_KErrNone(r);
sl@0
  1062
sl@0
  1063
	test.Printf(_L("Writing...."));
sl@0
  1064
	r = f.Write(0, writePtr);
sl@0
  1065
	test.Printf(_L("Write returned %d\n"), r);
sl@0
  1066
	test_KErrNone(r);
sl@0
  1067
sl@0
  1068
	r=TheFs.ControlIo(gDrive, KControlIoSimulateFileCacheWriteFailure);
sl@0
  1069
	test_KErrNone(r);
sl@0
  1070
sl@0
  1071
	f.Close();
sl@0
  1072
sl@0
  1073
	TEntry entry;
sl@0
  1074
sl@0
  1075
	// wait for re-insertion....
sl@0
  1076
	do
sl@0
  1077
		{
sl@0
  1078
		r = TheFs.Entry(testFile, entry);
sl@0
  1079
		User::After(500000);
sl@0
  1080
		}
sl@0
  1081
	while (r == KErrNotReady);
sl@0
  1082
	test_KErrNone(r);
sl@0
  1083
sl@0
  1084
	test.Printf(_L("FileSize %d expected %d\n"), entry.iSize, writePtr.Length());
sl@0
  1085
sl@0
  1086
	// test all data is written to disk 
sl@0
  1087
	test (entry.iSize == writePtr.Length());
sl@0
  1088
#endif
sl@0
  1089
sl@0
  1090
sl@0
  1091
	test.Next(_L("Testing writing and then ejecting card"));
sl@0
  1092
sl@0
  1093
//	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO);
sl@0
  1094
	r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered | EFileShareReadersOrWriters);
sl@0
  1095
	test_KErrNone(r);
sl@0
  1096
	writePtr.Set(gBuf->Des());
sl@0
  1097
sl@0
  1098
sl@0
  1099
	// set the file size first so that the cluster chain already exists
sl@0
  1100
	r = f.SetSize(writePtr.Length());
sl@0
  1101
	test.Printf(_L("SetSize returned %d"));
sl@0
  1102
sl@0
  1103
	// Create another thread which will attempt to issue reads while this thread is suspended
sl@0
  1104
	// These reads should complete with KErrNotReady
sl@0
  1105
	const TInt KHeapSize = 32768;
sl@0
  1106
	test.Printf(_L("Creating file-reading thread\n"));
sl@0
  1107
	RThread readerThread;
sl@0
  1108
	readerThread.Create(_L("FileReaderThread"), ReaderThread, KDefaultStackSize, KHeapSize, KHeapSize, &testFile);
sl@0
  1109
sl@0
  1110
	test.Printf(_L("Writing...."));
sl@0
  1111
	r = f.Write(0, writePtr);
sl@0
  1112
	test.Printf(_L("Write returned %d\n"), r);
sl@0
  1113
sl@0
  1114
sl@0
  1115
	test.Printf(_L("Waiting 5 seconds.\n"));
sl@0
  1116
	test.Printf(_L("**********************************************************\n"));
sl@0
  1117
	test.Printf(_L("Please press a key, EJECT MEDIA BEFORE WRITE TIMER EXPIRES,\n"));
sl@0
  1118
	test.Printf(_L("wait for critical notifier, replace media and retry\n"));
sl@0
  1119
	test.Printf(_L("**********************************************************\n"));
sl@0
  1120
//	test.Printf(_L("press any key..."));
sl@0
  1121
	test.Getch();
sl@0
  1122
	test.Printf(_L("\n"));
sl@0
  1123
sl@0
  1124
	test.Printf(_L("Writing...."));
sl@0
  1125
	r = f.Write(0, writePtr);
sl@0
  1126
	test.Printf(_L("Write returned %d\n"), r);
sl@0
  1127
	readerThread.Resume();
sl@0
  1128
sl@0
  1129
	User::After(5000000);
sl@0
  1130
sl@0
  1131
	do
sl@0
  1132
		{
sl@0
  1133
		test.Printf(_L("Flushing....\n"));
sl@0
  1134
		r = f.Flush();
sl@0
  1135
		test.Printf(_L("Flush returned %d\n"), r);
sl@0
  1136
		if (r != KErrNone)
sl@0
  1137
			User::After(5000000);
sl@0
  1138
		}
sl@0
  1139
	while (r != KErrNone);
sl@0
  1140
sl@0
  1141
sl@0
  1142
//	r = f.Write(0, writePtr);
sl@0
  1143
//	test.Printf(_L("Write returned %d"));
sl@0
  1144
sl@0
  1145
//	test_KErrNone(r);
sl@0
  1146
sl@0
  1147
	test.Next(_L("Testing reader thread completed with KErrNotReady"));
sl@0
  1148
	TRequestStatus status;
sl@0
  1149
	readerThread.Logon(status);
sl@0
  1150
	readerThread.Resume();
sl@0
  1151
	User::WaitForRequest(status);
sl@0
  1152
	test.Printf(_L("ReaderThread status  %d\n"), status.Int());
sl@0
  1153
	test (status.Int() == KErrNotReady);
sl@0
  1154
	readerThread.Close();
sl@0
  1155
sl@0
  1156
	test.Printf(_L("press any key..."));
sl@0
  1157
	test.Getch();
sl@0
  1158
	test.Printf(_L("\n"));
sl@0
  1159
sl@0
  1160
	f.Close();
sl@0
  1161
	}
sl@0
  1162
sl@0
  1163
sl@0
  1164
LOCAL_C void DoTestFileRead(TUint aFileMode, TInt aReadBlockSize)
sl@0
  1165
//
sl@0
  1166
// Do Read Test
sl@0
  1167
//
sl@0
  1168
	{
sl@0
  1169
sl@0
  1170
	RFile file;
sl@0
  1171
	TInt r=file.Open(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
sl@0
  1172
	test_KErrNone(r);
sl@0
  1173
sl@0
  1174
	TInt maxReadCount=KMaxFileSize/aReadBlockSize;
sl@0
  1175
	TInt loopCount=0;
sl@0
  1176
sl@0
  1177
	TTime startTime;
sl@0
  1178
	TTime endTime;
sl@0
  1179
sl@0
  1180
	RTimer timer;
sl@0
  1181
	timer.CreateLocal();
sl@0
  1182
	TRequestStatus reqStat;
sl@0
  1183
	timer.After(reqStat,10000000); // After 10 secs
sl@0
  1184
	startTime.HomeTime();
sl@0
  1185
sl@0
  1186
	FOREVER
sl@0
  1187
		{
sl@0
  1188
		TInt pos=0;
sl@0
  1189
		file.Seek(ESeekStart,pos);
sl@0
  1190
		for(TInt ii=0;ii<maxReadCount;ii++)
sl@0
  1191
			{
sl@0
  1192
			r = file.Read(DataBuf,aReadBlockSize);
sl@0
  1193
			test_KErrNone(r);
sl@0
  1194
#if defined(_DEBUG)
sl@0
  1195
			for(TInt jj=0;jj<DataBuf.Size();jj++)
sl@0
  1196
				{
sl@0
  1197
				if (DataBuf[jj] != ((jj+ii*aReadBlockSize)%256))
sl@0
  1198
					{
sl@0
  1199
					test.Printf(_L("len %d size %d jj %d ii %d"), DataBuf.Length(), DataBuf.Size(), jj, ii);
sl@0
  1200
					test(0);
sl@0
  1201
					}
sl@0
  1202
//				test(DataBuf[jj] == ((jj+ii*aReadBlockSize)%256) );
sl@0
  1203
				}
sl@0
  1204
#endif
sl@0
  1205
			if (reqStat!=KRequestPending)
sl@0
  1206
				{
sl@0
  1207
				endTime.HomeTime();
sl@0
  1208
sl@0
  1209
				TInt functionCalls=loopCount*maxReadCount+ii;
sl@0
  1210
//				TReal rate = ( TReal32(functionCalls) * TReal32(aReadBlockSize) ) / 10;
sl@0
  1211
//				test.Printf(_L("Read %5d byte blocks:\t%11.3f KBytes/s\n"), aReadBlockSize, rate / (KOneK));
sl@0
  1212
				
sl@0
  1213
				TReal transferRate = 
sl@0
  1214
					(TReal32(functionCalls) * TReal32(aReadBlockSize)) / 
sl@0
  1215
					TReal(endTime.MicroSecondsFrom(startTime).Int64()) * TReal(KOneMeg) / TReal(KOneK);
sl@0
  1216
				test.Printf(_L("Read %5d byte blocks:\t%11.3f KBytes/s\n"), aReadBlockSize,transferRate);
sl@0
  1217
sl@0
  1218
				timer.Close();
sl@0
  1219
				file.Close();
sl@0
  1220
sl@0
  1221
				return;
sl@0
  1222
				}
sl@0
  1223
			}
sl@0
  1224
		loopCount++;
sl@0
  1225
		}
sl@0
  1226
	}
sl@0
  1227
sl@0
  1228
LOCAL_C void DoTestFileWrite(TUint aFileMode, TInt aWriteBlockSize)
sl@0
  1229
//
sl@0
  1230
// Do Write benchmark
sl@0
  1231
//
sl@0
  1232
	{
sl@0
  1233
	DataBuf.SetLength(aWriteBlockSize);
sl@0
  1234
	TInt maxWriteCount=KMaxFileSize/aWriteBlockSize;
sl@0
  1235
	TInt loopCount=0;
sl@0
  1236
sl@0
  1237
	RFile file;
sl@0
  1238
	TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
sl@0
  1239
	test (r == KErrNone);
sl@0
  1240
sl@0
  1241
	TTime startTime;
sl@0
  1242
	TTime endTime;
sl@0
  1243
sl@0
  1244
	RTimer timer;
sl@0
  1245
	timer.CreateLocal();
sl@0
  1246
	TRequestStatus reqStat;
sl@0
  1247
	timer.After(reqStat,10000000); // After 10 secs
sl@0
  1248
	startTime.HomeTime();
sl@0
  1249
sl@0
  1250
	
sl@0
  1251
sl@0
  1252
	FOREVER
sl@0
  1253
		{
sl@0
  1254
		TInt pos=0;
sl@0
  1255
		file.Seek(ESeekStart,pos);
sl@0
  1256
		for(TInt ii=0;ii<maxWriteCount;ii++)
sl@0
  1257
			{
sl@0
  1258
			r = file.Write(DataBuf);
sl@0
  1259
			test_KErrNone(r);
sl@0
  1260
			if (reqStat!=KRequestPending)
sl@0
  1261
				{
sl@0
  1262
				
sl@0
  1263
//				TReal rate = (TReal32(functionCalls) * TReal32(aWriteBlockSize)) / 10;
sl@0
  1264
//				test.Printf(_L("Write %5d byte blocks:\t%11.3f KBytes/s\n"), aWriteBlockSize, rate / (KOneK));
sl@0
  1265
sl@0
  1266
				r = file.Flush();
sl@0
  1267
				test_KErrNone(r);
sl@0
  1268
sl@0
  1269
				endTime.HomeTime();
sl@0
  1270
sl@0
  1271
				TInt functionCalls=loopCount*maxWriteCount+ii;
sl@0
  1272
				TReal transferRate = 
sl@0
  1273
					(TReal32(functionCalls) * TReal32(aWriteBlockSize)) / 
sl@0
  1274
					TReal(endTime.MicroSecondsFrom(startTime).Int64()) * TReal(KOneMeg) / TReal(KOneK);
sl@0
  1275
				test.Printf(_L("Write %5d byte blocks:\t%11.3f KBytes/s\n"), aWriteBlockSize,transferRate);
sl@0
  1276
sl@0
  1277
				file.Close();
sl@0
  1278
				timer.Close();
sl@0
  1279
				TInt r=TheFs.Delete(_L("WRITETST"));
sl@0
  1280
				test_KErrNone(r);
sl@0
  1281
				return;
sl@0
  1282
				}
sl@0
  1283
			}
sl@0
  1284
		loopCount++;
sl@0
  1285
		}
sl@0
  1286
	}
sl@0
  1287
sl@0
  1288
LOCAL_C void TestFileRead(TUint aFileMode)
sl@0
  1289
//
sl@0
  1290
// Benchmark read method
sl@0
  1291
//
sl@0
  1292
	{
sl@0
  1293
sl@0
  1294
//	ClearSessionDirectory();
sl@0
  1295
	test.Next(_L("Benchmark read method"));
sl@0
  1296
//	test.Printf(_L("aFileMode %08X\n"), aFileMode);
sl@0
  1297
	PrintFileMode(aFileMode);
sl@0
  1298
sl@0
  1299
// Create test data
sl@0
  1300
	TBuf8<1024> testdata(1024);
sl@0
  1301
	for (TInt i=0;i<testdata.MaxSize();i++)
sl@0
  1302
		testdata[i]=TText8(i%256);		
sl@0
  1303
	
sl@0
  1304
	// create & fill the file
sl@0
  1305
	RFile file;
sl@0
  1306
	TInt r=file.Replace(TheFs,_L("READTEST.XXX"),EFileStream | aFileMode);
sl@0
  1307
	test_KErrNone(r);
sl@0
  1308
sl@0
  1309
	test.Printf(_L("Creating test file....."));
sl@0
  1310
	TInt count=KMaxFileSize/testdata.Length();
sl@0
  1311
	while (count--)
sl@0
  1312
		file.Write(testdata);
sl@0
  1313
	file.Close();
sl@0
  1314
	test.Printf(_L("done.\n"));
sl@0
  1315
sl@0
  1316
#ifdef SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
sl@0
  1317
sl@0
  1318
	DoTestFileRead(aFileMode, 1);
sl@0
  1319
	DoTestFileRead(aFileMode, 2);
sl@0
  1320
	DoTestFileRead(aFileMode, 4);
sl@0
  1321
	DoTestFileRead(aFileMode, 8);
sl@0
  1322
	DoTestFileRead(aFileMode, 16);
sl@0
  1323
	DoTestFileRead(aFileMode, 32);
sl@0
  1324
	DoTestFileRead(aFileMode, 64);
sl@0
  1325
	DoTestFileRead(aFileMode, 128);
sl@0
  1326
	DoTestFileRead(aFileMode, 256);
sl@0
  1327
	DoTestFileRead(aFileMode, 512);
sl@0
  1328
	DoTestFileRead(aFileMode, 1024);
sl@0
  1329
	DoTestFileRead(aFileMode, 2048);
sl@0
  1330
	DoTestFileRead(aFileMode, 4096);
sl@0
  1331
	DoTestFileRead(aFileMode, 8192);
sl@0
  1332
	DoTestFileRead(aFileMode, 16384);
sl@0
  1333
	DoTestFileRead(aFileMode, 32768);
sl@0
  1334
	DoTestFileRead(aFileMode, 65536);
sl@0
  1335
	DoTestFileRead(aFileMode, 131072);
sl@0
  1336
#else
sl@0
  1337
//TheFs.SetDebugRegister(KCACHE);
sl@0
  1338
	DoTestFileRead(aFileMode, 1);
sl@0
  1339
	DoTestFileRead(aFileMode, 16);
sl@0
  1340
	DoTestFileRead(aFileMode, 512);
sl@0
  1341
//TheFs.SetDebugRegister(0);
sl@0
  1342
	DoTestFileRead(aFileMode, 4 * 1024);
sl@0
  1343
	DoTestFileRead(aFileMode, 32 * 1024);
sl@0
  1344
	DoTestFileRead(aFileMode, 64 * 1024);
sl@0
  1345
	DoTestFileRead(aFileMode, 128 * 1024);
sl@0
  1346
	DoTestFileRead(aFileMode, 256 * 1024);
sl@0
  1347
#endif
sl@0
  1348
sl@0
  1349
	r=TheFs.Delete(_L("READTEST.XXX"));
sl@0
  1350
sl@0
  1351
sl@0
  1352
sl@0
  1353
	test_KErrNone(r);
sl@0
  1354
	}
sl@0
  1355
sl@0
  1356
sl@0
  1357
LOCAL_C void TestFileWrite(TUint aFileMode)
sl@0
  1358
//
sl@0
  1359
// Benchmark write method
sl@0
  1360
//
sl@0
  1361
	{
sl@0
  1362
//	ClearSessionDirectory();
sl@0
  1363
	test.Next(_L("Benchmark write method"));
sl@0
  1364
//	test.Printf(_L("aFileMode %08X\n"), aFileMode);
sl@0
  1365
	PrintFileMode(aFileMode);
sl@0
  1366
sl@0
  1367
	
sl@0
  1368
//	RFile file;
sl@0
  1369
//	TInt r = file.Replace(TheFs,_L("WRITETST"),EFileStream | aFileMode);
sl@0
  1370
//	test_KErrNone(r);
sl@0
  1371
sl@0
  1372
sl@0
  1373
#ifdef SYMBIAN_TEST_EXTENDED_BUFFER_SIZES
sl@0
  1374
	DoTestFileWrite(aFileMode, 1);
sl@0
  1375
	DoTestFileWrite(aFileMode, 2);
sl@0
  1376
	DoTestFileWrite(aFileMode, 4);
sl@0
  1377
	DoTestFileWrite(aFileMode, 8);
sl@0
  1378
	DoTestFileWrite(aFileMode, 16);
sl@0
  1379
	DoTestFileWrite(aFileMode, 32);
sl@0
  1380
	DoTestFileWrite(aFileMode, 64);
sl@0
  1381
	DoTestFileWrite(aFileMode, 128);
sl@0
  1382
	DoTestFileWrite(aFileMode, 256);
sl@0
  1383
	DoTestFileWrite(aFileMode, 512);
sl@0
  1384
	DoTestFileWrite(aFileMode, 1024);
sl@0
  1385
	DoTestFileWrite(aFileMode, 2048);
sl@0
  1386
	DoTestFileWrite(aFileMode, 4096);
sl@0
  1387
	DoTestFileWrite(aFileMode, 8192);
sl@0
  1388
	DoTestFileWrite(aFileMode, 16384);
sl@0
  1389
	DoTestFileWrite(aFileMode, 32768);
sl@0
  1390
	DoTestFileWrite(aFileMode, 65536);
sl@0
  1391
	DoTestFileWrite(aFileMode, 131072);
sl@0
  1392
#else
sl@0
  1393
	DoTestFileWrite(aFileMode, 1);
sl@0
  1394
	DoTestFileWrite(aFileMode, 16);
sl@0
  1395
	DoTestFileWrite(aFileMode, 512);
sl@0
  1396
	DoTestFileWrite(aFileMode, 4 * 1024);
sl@0
  1397
	DoTestFileWrite(aFileMode, 32 * 1024);
sl@0
  1398
	DoTestFileWrite(aFileMode, 64 * 1024);
sl@0
  1399
	DoTestFileWrite(aFileMode, 128 * 1024);
sl@0
  1400
	DoTestFileWrite(aFileMode, 256 * 1024);
sl@0
  1401
#endif
sl@0
  1402
	}
sl@0
  1403
sl@0
  1404
enum CommandId {
sl@0
  1405
    CMD_NO_COMMAND,
sl@0
  1406
    CMD_HELP,
sl@0
  1407
	CMD_DISPLAY_CACHE_FLAGS,
sl@0
  1408
	CMD_WRITE_CACHE_FLAGS,
sl@0
  1409
	CMD_PERFORMANCE_TEST,
sl@0
  1410
	CMD_MANUAL_TEST
sl@0
  1411
};
sl@0
  1412
sl@0
  1413
sl@0
  1414
class CommandLineOption { 
sl@0
  1415
public:
sl@0
  1416
    CommandLineOption(const TPtrC &s, CommandId i) : str(s), id(i) { }
sl@0
  1417
    
sl@0
  1418
    const TPtrC str;
sl@0
  1419
    CommandId   id;
sl@0
  1420
    
sl@0
  1421
private:
sl@0
  1422
    CommandLineOption() { }
sl@0
  1423
};
sl@0
  1424
sl@0
  1425
// Lists of command line options
sl@0
  1426
static const CommandLineOption commandList[] = {
sl@0
  1427
    CommandLineOption(_L("-help"), CMD_HELP),
sl@0
  1428
    CommandLineOption(_L("-h"), CMD_HELP),
sl@0
  1429
    CommandLineOption(_L("-?"), CMD_HELP),
sl@0
  1430
    CommandLineOption(_L("/?"), CMD_HELP),
sl@0
  1431
    CommandLineOption(_L("-d"), CMD_DISPLAY_CACHE_FLAGS),
sl@0
  1432
    CommandLineOption(_L("-w"), CMD_WRITE_CACHE_FLAGS),
sl@0
  1433
    CommandLineOption(_L("-p"), CMD_PERFORMANCE_TEST),
sl@0
  1434
    CommandLineOption(_L("-m"), CMD_MANUAL_TEST),
sl@0
  1435
};
sl@0
  1436
sl@0
  1437
sl@0
  1438
sl@0
  1439
LOCAL_C void printHelp() {
sl@0
  1440
    test.Printf(_L("Option          Explanation\r\n"));
sl@0
  1441
    test.Printf(_L("-help           Print this text\r\n"));
sl@0
  1442
    test.Printf(_L("-d				Display cache flags\n"));
sl@0
  1443
    test.Printf(_L("-p				Performance test\n"));
sl@0
  1444
}
sl@0
  1445
sl@0
  1446
sl@0
  1447
sl@0
  1448
/////////////////////////////////////////////////////////////////////////////
sl@0
  1449
// Function: 
sl@0
  1450
//		bool parseCommandLine()
sl@0
  1451
//
sl@0
  1452
// Parameters:
sl@0
  1453
//		-
sl@0
  1454
//
sl@0
  1455
// Return value:
sl@0
  1456
//		true if command line options was correct, false if any command was
sl@0
  1457
//      invalid
sl@0
  1458
//
sl@0
  1459
// Purpose:
sl@0
  1460
//		Parses the command line
sl@0
  1461
//
sl@0
  1462
/////////////////////////////////////////////////////////////////////////////
sl@0
  1463
sl@0
  1464
//TBuf<512> commandLine;
sl@0
  1465
sl@0
  1466
sl@0
  1467
LOCAL_C bool ParseCommandLine( const TDesC& aCommand )
sl@0
  1468
	{
sl@0
  1469
    TLex lex(aCommand);
sl@0
  1470
    TInt tokenCount = 0;
sl@0
  1471
sl@0
  1472
	gDriveToTest='C';		
sl@0
  1473
	gRunTests = ETrue;
sl@0
  1474
sl@0
  1475
    for (TPtrC token=lex.NextToken(); token.Length() != 0;token.Set(lex.NextToken()))
sl@0
  1476
		{
sl@0
  1477
        tokenCount++;
sl@0
  1478
sl@0
  1479
        //
sl@0
  1480
        // Search the list of commands for a match.
sl@0
  1481
        //
sl@0
  1482
        CommandId commandId = CMD_NO_COMMAND;
sl@0
  1483
        for (TUint i = 0; i < sizeof commandList / sizeof commandList[0]; i++) 
sl@0
  1484
			{
sl@0
  1485
            if (token.CompareF(commandList[i].str) == 0) 
sl@0
  1486
				{
sl@0
  1487
                //
sl@0
  1488
                // Found a matching string
sl@0
  1489
                //
sl@0
  1490
                commandId = commandList[i].id;
sl@0
  1491
                break;
sl@0
  1492
				}
sl@0
  1493
			}
sl@0
  1494
sl@0
  1495
        switch (commandId) 
sl@0
  1496
			{
sl@0
  1497
			case CMD_NO_COMMAND:
sl@0
  1498
				{
sl@0
  1499
				TFileName thisfile=RProcess().FileName();
sl@0
  1500
				if (token.MatchF(thisfile)==0)
sl@0
  1501
					{
sl@0
  1502
					token.Set(lex.NextToken());
sl@0
  1503
					}
sl@0
  1504
				test.Printf(_L("CLP=%S\n"),&token);
sl@0
  1505
sl@0
  1506
				TChar ch = token[0];
sl@0
  1507
				if (ch.IsAlpha())
sl@0
  1508
					{
sl@0
  1509
					if(token.Length()!=0)		
sl@0
  1510
						{
sl@0
  1511
						gDriveToTest=token[0];
sl@0
  1512
						gDriveToTest.UpperCase();
sl@0
  1513
						}
sl@0
  1514
					else						
sl@0
  1515
						gDriveToTest='C';		
sl@0
  1516
					lex.NextToken();
sl@0
  1517
					}
sl@0
  1518
				}
sl@0
  1519
				break;
sl@0
  1520
sl@0
  1521
			case CMD_HELP:
sl@0
  1522
				printHelp();
sl@0
  1523
				gRunTests = EFalse;
sl@0
  1524
				break;
sl@0
  1525
sl@0
  1526
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1527
			case CMD_WRITE_CACHE_FLAGS:
sl@0
  1528
				{         
sl@0
  1529
					token.Set(lex.NextToken());
sl@0
  1530
					if (token.Length() == 0) {
sl@0
  1531
						printHelp();
sl@0
  1532
						return false;
sl@0
  1533
					}
sl@0
  1534
					//
sl@0
  1535
					// Extract flags (in hex) from next token.
sl@0
  1536
					//
sl@0
  1537
					TPtrC numStr(token);
sl@0
  1538
					TUint val;
sl@0
  1539
					TInt r = TLex(numStr).Val(val, EHex);
sl@0
  1540
					if (r != KErrNone) {
sl@0
  1541
						printHelp();
sl@0
  1542
						return false;
sl@0
  1543
					}
sl@0
  1544
					gDriveCacheFlags = TFileCacheFlags(val);
sl@0
  1545
					gWriteCacheFlags = ETrue;
sl@0
  1546
					gRunTests = EFalse;
sl@0
  1547
					break;
sl@0
  1548
				}
sl@0
  1549
sl@0
  1550
			case CMD_DISPLAY_CACHE_FLAGS:
sl@0
  1551
				gDisplayCacheFlags = ETrue;
sl@0
  1552
				gRunTests = EFalse;
sl@0
  1553
				break;
sl@0
  1554
#endif
sl@0
  1555
			case CMD_PERFORMANCE_TEST:
sl@0
  1556
				gRunPerformanceTests = ETrue;
sl@0
  1557
				gRunUnitTests = EFalse;
sl@0
  1558
				break;
sl@0
  1559
sl@0
  1560
			case CMD_MANUAL_TEST:
sl@0
  1561
				gRunManualTests = ETrue;
sl@0
  1562
				gRunUnitTests = EFalse;
sl@0
  1563
				break;
sl@0
  1564
sl@0
  1565
			default:
sl@0
  1566
				test.Printf(_L("Sorry, command option '%S' not implemented\n"),
sl@0
  1567
					&token);
sl@0
  1568
				break;
sl@0
  1569
			}
sl@0
  1570
sl@0
  1571
		}
sl@0
  1572
    return true;
sl@0
  1573
}
sl@0
  1574
sl@0
  1575
sl@0
  1576
LOCAL_C TBool parseCommandLine() {
sl@0
  1577
    //
sl@0
  1578
    // Loop through all tokens in the command line
sl@0
  1579
    //
sl@0
  1580
	TInt cmdLineLen = User::CommandLineLength();
sl@0
  1581
	HBufC* cmdLineBuf = HBufC::New( cmdLineLen );
sl@0
  1582
    if( !cmdLineBuf )
sl@0
  1583
		{
sl@0
  1584
		return false;
sl@0
  1585
		}
sl@0
  1586
	TPtr ptr = cmdLineBuf->Des();
sl@0
  1587
	User::CommandLine(ptr);
sl@0
  1588
sl@0
  1589
	bool err = ParseCommandLine( *cmdLineBuf );
sl@0
  1590
	delete cmdLineBuf;
sl@0
  1591
	return err;
sl@0
  1592
	}
sl@0
  1593
sl@0
  1594
GLDEF_C void CallTestsL()
sl@0
  1595
//
sl@0
  1596
// Do tests relative to the session path
sl@0
  1597
//
sl@0
  1598
	{
sl@0
  1599
	TestsInit();
sl@0
  1600
sl@0
  1601
	TVolumeInfo volInfo;
sl@0
  1602
	TInt r = TheFs.Volume(volInfo, gDrive);
sl@0
  1603
	test (r == KErrNone);
sl@0
  1604
sl@0
  1605
	TFullName extName;
sl@0
  1606
	r = TheFs.ExtensionName(extName,gDrive, 0);
sl@0
  1607
	if (r == KErrNone)
sl@0
  1608
		{
sl@0
  1609
		test.Printf(_L("File system extension present (%S)\n"), &extName);
sl@0
  1610
		}
sl@0
  1611
sl@0
  1612
	if ((volInfo.iDrive.iType == EMediaRam) ||
sl@0
  1613
		((gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn)) == 0))
sl@0
  1614
		{
sl@0
  1615
		if (gRunPerformanceTests)
sl@0
  1616
			{
sl@0
  1617
			TestFileRead(EFileReadDirectIO);
sl@0
  1618
			TestFileWrite(EFileWriteDirectIO);
sl@0
  1619
			}
sl@0
  1620
		TestsEnd();
sl@0
  1621
		return;
sl@0
  1622
		}
sl@0
  1623
sl@0
  1624
	if (gRunUnitTests)
sl@0
  1625
		UnitTests();
sl@0
  1626
sl@0
  1627
	if (gRunManualTests)
sl@0
  1628
		{		
sl@0
  1629
		ManualTests();
sl@0
  1630
		}
sl@0
  1631
sl@0
  1632
	if (gRunPerformanceTests)
sl@0
  1633
		{
sl@0
  1634
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1635
		// turn OFF lock failure mode
sl@0
  1636
		TBool simulatelockFailureMode = EFalse;
sl@0
  1637
		r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
  1638
		test (r == KErrNone);
sl@0
  1639
#endif
sl@0
  1640
sl@0
  1641
		TestFileRead(EFileReadDirectIO);
sl@0
  1642
		if (gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn))
sl@0
  1643
			{
sl@0
  1644
			TestFileRead(EFileReadBuffered | EFileReadAheadOff);
sl@0
  1645
			TestFileRead(EFileReadBuffered | EFileReadAheadOn);
sl@0
  1646
			}
sl@0
  1647
sl@0
  1648
		TestFileWrite(EFileWriteDirectIO);
sl@0
  1649
sl@0
  1650
		if (gDriveCacheFlags & (EFileCacheWriteEnabled | EFileCacheWriteOn))
sl@0
  1651
			TestFileWrite(EFileWriteBuffered);
sl@0
  1652
sl@0
  1653
sl@0
  1654
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1655
		// turn lock failure mode back ON (if enabled)
sl@0
  1656
		simulatelockFailureMode = ETrue;
sl@0
  1657
		r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
  1658
		test (r == KErrNone);
sl@0
  1659
#endif
sl@0
  1660
		}	// if (gRunPerformanceTests)
sl@0
  1661
sl@0
  1662
	TestsEnd();
sl@0
  1663
	}
sl@0
  1664
sl@0
  1665
sl@0
  1666
sl@0
  1667
LOCAL_C void DoTests(TInt aDrive)
sl@0
  1668
//
sl@0
  1669
// Do testing on aDrive
sl@0
  1670
//
sl@0
  1671
	{
sl@0
  1672
sl@0
  1673
	SetSessionPath(aDrive);
sl@0
  1674
sl@0
  1675
// !!! Disable platform security tests until we get the new APIs
sl@0
  1676
//	if(User::Capability() & KCapabilityRoot)
sl@0
  1677
//		CheckMountLFFS(TheFs,driveLetter);
sl@0
  1678
	
sl@0
  1679
	User::After(1000000);
sl@0
  1680
sl@0
  1681
	TInt r=TheFs.MkDirAll(gSessionPath);
sl@0
  1682
	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
sl@0
  1683
	TheFs.ResourceCountMarkStart();
sl@0
  1684
sl@0
  1685
	TRAP(r,CallTestsL());
sl@0
  1686
	test_KErrNone(r);
sl@0
  1687
sl@0
  1688
	TheFs.ResourceCountMarkEnd();
sl@0
  1689
	}
sl@0
  1690
sl@0
  1691
sl@0
  1692
void Format(TInt aDrive)
sl@0
  1693
//
sl@0
  1694
// Format current drive
sl@0
  1695
//
sl@0
  1696
	{
sl@0
  1697
sl@0
  1698
	test.Next(_L("Format"));
sl@0
  1699
	TBuf<4> driveBuf=_L("?:\\");
sl@0
  1700
	driveBuf[0]=(TText)(aDrive+'A');
sl@0
  1701
	RFormat format;
sl@0
  1702
	TInt count;
sl@0
  1703
	TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
sl@0
  1704
	//TInt r=format.Open(TheFs,driveBuf,EFullFormat,count);
sl@0
  1705
	test.Printf(_L("RFormat::Open() returned %d\n"), r);
sl@0
  1706
	test_KErrNone(r);
sl@0
  1707
	while(count)
sl@0
  1708
		{
sl@0
  1709
		TInt r=format.Next(count);
sl@0
  1710
		test_KErrNone(r);
sl@0
  1711
		}
sl@0
  1712
	format.Close();
sl@0
  1713
	}
sl@0
  1714
sl@0
  1715
GLDEF_C TInt E32Main()
sl@0
  1716
//
sl@0
  1717
// Test with drive nearly full
sl@0
  1718
//
sl@0
  1719
	{
sl@0
  1720
sl@0
  1721
	CTrapCleanup* cleanup;
sl@0
  1722
	cleanup=CTrapCleanup::New();
sl@0
  1723
sl@0
  1724
	__UHEAP_MARK;
sl@0
  1725
sl@0
  1726
	TBool parseOk = parseCommandLine();
sl@0
  1727
	if (!parseOk)
sl@0
  1728
		User::Leave(KErrNotSupported);
sl@0
  1729
sl@0
  1730
sl@0
  1731
	TInt r = TheFs.Connect();
sl@0
  1732
	test_KErrNone(r);
sl@0
  1733
sl@0
  1734
	r=TheFs.CharToDrive(gDriveToTest,gDrive);
sl@0
  1735
	test_KErrNone(r);
sl@0
  1736
sl@0
  1737
#if !defined(__WINS__)
sl@0
  1738
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1739
	test.Start(_L("Check that the rom is paged"));
sl@0
  1740
	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
  1741
	if (romHeader->iPageableRomStart != NULL)
sl@0
  1742
		{
sl@0
  1743
		test.Printf(_L("ROM is paged\n"));
sl@0
  1744
		gRomPaged = ETrue;
sl@0
  1745
		}
sl@0
  1746
#endif
sl@0
  1747
#endif
sl@0
  1748
sl@0
  1749
	// Get the TFileCacheFlags for this drive
sl@0
  1750
	r = TheFs.Volume(gVolInfo, gDrive);
sl@0
  1751
	if (r == KErrNotReady)
sl@0
  1752
		{
sl@0
  1753
		TDriveInfo info;
sl@0
  1754
		TInt err = TheFs.Drive(info,gDrive);
sl@0
  1755
		test_KErrNone(err);
sl@0
  1756
		if (info.iType == EMediaNotPresent)
sl@0
  1757
			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
sl@0
  1758
		else
sl@0
  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);
sl@0
  1760
		}
sl@0
  1761
	else if (r == KErrCorrupt)
sl@0
  1762
		{
sl@0
  1763
		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
sl@0
  1764
		}
sl@0
  1765
	test_KErrNone(r);
sl@0
  1766
	gDriveCacheFlags = gVolInfo.iFileCacheFlags;
sl@0
  1767
	test.Printf(_L("DriveCacheFlags for drive %C = %08X\n"), (TInt) gDriveToTest, gDriveCacheFlags);
sl@0
  1768
sl@0
  1769
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1770
	PrintFileCacheConfig(gFileCacheConfig, gDrive);
sl@0
  1771
	
sl@0
  1772
	if (gDisplayCacheFlags)
sl@0
  1773
		{
sl@0
  1774
		test.Printf(_L("Press any key...\n"));
sl@0
  1775
		test.Getch();
sl@0
  1776
		}
sl@0
  1777
sl@0
  1778
	if (gWriteCacheFlags)
sl@0
  1779
		{
sl@0
  1780
		test.Printf(_L("Writing DriveCacheFlags for drive %C = %08X\n"), (TInt) gDriveToTest, gDriveCacheFlags);
sl@0
  1781
		r = controlIo(TheFs,gDrive, KControlIoFileCacheFlagsWrite, gDriveCacheFlags);
sl@0
  1782
		test (r == KErrNone);
sl@0
  1783
		}
sl@0
  1784
#endif
sl@0
  1785
sl@0
  1786
	if (gRunTests)
sl@0
  1787
		{
sl@0
  1788
		test.Title();
sl@0
  1789
sl@0
  1790
sl@0
  1791
		test.Start(_L("Starting tests..."));
sl@0
  1792
sl@0
  1793
		if ((gVolInfo.iDrive.iMediaAtt & KMediaAttFormattable))
sl@0
  1794
			Format(gDrive);
sl@0
  1795
sl@0
  1796
//TheFs.SetDebugRegister(KCACHE);
sl@0
  1797
			DoTests(gDrive);
sl@0
  1798
//TheFs.SetDebugRegister(0);
sl@0
  1799
			test.End();
sl@0
  1800
//			}
sl@0
  1801
		}
sl@0
  1802
sl@0
  1803
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1804
	TFileCacheStats fileCacheStats;
sl@0
  1805
	PrintFileCacheStats(fileCacheStats);
sl@0
  1806
#endif
sl@0
  1807
sl@0
  1808
	TheFs.Close();
sl@0
  1809
	test.Close();
sl@0
  1810
	__UHEAP_MARKEND;
sl@0
  1811
	delete cleanup;
sl@0
  1812
	return(KErrNone);
sl@0
  1813
    }