os/kernelhwsrv/kerneltest/f32test/server/t_wcache.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-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_wcache.cpp
    15 // This file contains a test for the Write Caching functionality of the File Server
    16 // 
    17 //
    18 
    19 /**
    20  @file
    21  @internalTechnology 
    22 */
    23 
    24 #define __E32TEST_EXTENSION__
    25 #include <f32file.h>
    26 #include <e32test.h>
    27 #include <e32svr.h>
    28 #include <f32dbg.h>
    29 #include "t_server.h"
    30 #include <e32twin.h>
    31 
    32 const TInt KTotalCacheSize = 32 * 1024 * 1024;
    33 const TInt KDefaultCacheSize = (128 + 12) * 1024; 	// This size is the default configuration size
    34 const TInt KFilesNeededToFillCache = (KTotalCacheSize / KDefaultCacheSize) + 2;
    35 const TInt KMinSize = 254; // Boundary minim limit
    36 const TInt KMaxSize = 257; // Boundary max limit
    37 
    38 
    39 
    40 //----------------------------------------------------------------------------------------------
    41 //! @SYMTestCaseID      PBASE-T_WCACHE-0271
    42 //! @SYMTestType        CIT
    43 //! @SYMPREQ            PREQ914
    44 //! @SYMTestCaseDesc    This test case is exercising the Write Caching functionality added to 
    45 //!						the File Server. There are negative and positive tests. 
    46 //! @SYMTestActions     0   setup the environment to execute the tests
    47 //!						1	TestBoundaries writes/reads around the write cache boundaries to
    48 //!							the behaviour of the cache in some common cases. 
    49 //!						2 	TestNegative ensures the integrity of data in the cache gets 
    50 //!							preserved under error conditions
    51 //!						3	TestIntegrity is trying to make sure integrity of the data is preserved
    52 //!						4	TestFillCache fills the cache and then executes TestBoundaries. 
    53 //!						5 	TestFillCacheNegative fills the cache with uncommitted data 
    54 //!
    55 //! @SYMTestExpectedResults finishes if the read cache behaves as expected, panics otherwise
    56 //! @SYMTestPriority        High
    57 //! @SYMTestStatus          Implemented
    58 //----------------------------------------------------------------------------------------------
    59 
    60 
    61 ////////////////////////////////////////////////////////////
    62 // Template functions encapsulating ControlIo magic
    63 //
    64 template <class C>
    65 TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
    66 {
    67     TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
    68 
    69     TInt r = fs.ControlIo(drv, fkn, ptrC);
    70 
    71     return r;
    72 }
    73 
    74 RTest test(_L("T_WCACHE"));
    75 
    76 RFs gTheFs;
    77 TInt gDrive;
    78 TFileName gSessionPath;
    79 TChar gDriveToTest;	
    80 TThreadId gMainThreadId;
    81 TInt gManual = 0;
    82 
    83 HBufC8* gBuf = NULL;
    84 TPtr8 gBufReadPtr(NULL, 0);	
    85 HBufC8* gBufSec = NULL;
    86 TPtr8 gBufWritePtr(NULL, 0);	
    87 
    88 const TInt KOneK = 1024;
    89 const TInt KOneMeg = KOneK * 1024;
    90 const TInt KBlockSize = KOneK;
    91 const TInt KWaitRequestsTableSize = 256;
    92 const TInt KMs = 1000; 
    93 
    94 TInt gSecondFileSize = 0; 
    95 TInt gFirstFileSize = 0;
    96 
    97 TInt64 gMediaSize = 0;
    98 
    99 TTimeIntervalMicroSeconds gTimeTakenBigFile(0);
   100 TBuf16<25> gFirstFile;
   101 TBuf16<25> gSecondFile;
   102 TBuf16<25> gCurrentFile;
   103 
   104 TInt gNextFile = 0;
   105 TTime gTime1;
   106 TTime gTime2;
   107 
   108 
   109 // Concurrent Threads
   110 RThread gThread1;
   111 RSemaphore gClient;
   112 const TInt KHeapSize = 0x4000;
   113 const TInt KMaxHeapSize = 0x100000;
   114 
   115 
   116 /** Formats the drive 
   117 
   118 	@param aDrive 	Drive to be formatted
   119 	@param aFormatMode Mode for the format operation
   120 */
   121 void Formatting(TInt aDrive, TUint aFormatMode )
   122 	{
   123 
   124 	test.Next(_L("Format"));
   125 	TBuf<4> driveBuf = _L("?:\\");
   126 	driveBuf[0]=(TText)(aDrive+'A');
   127 	RFormat format;
   128 	TInt count;
   129 	TInt r = format.Open(gTheFs,driveBuf,aFormatMode,count);
   130 	test_KErrNone(r);
   131 	while(count)
   132 		{
   133 		TInt r = format.Next(count);
   134 		test_KErrNone(r);
   135 		}
   136 	format.Close();
   137 	
   138 	}
   139 
   140 /** Verifies the content of a buffer 
   141 	This function returns KErrNone when all the letters are consecutive in the aBuffer, KErrCorrupt otherwise
   142 
   143 	@param aBuffer  Buffer to be verified
   144 	
   145 	@return KErrNone if all the letters are the same, KErrCorrupt otherwise
   146 */
   147 TInt VerifyBuffer(TDes8& aBuffer)
   148 	{
   149 	TChar c = aBuffer[0];
   150 	
   151 	for(TInt i = 1; i < aBuffer.Length(); i++)
   152 		{
   153 		if(i%32 != 0) 
   154 			{
   155 			if(c != (TChar)(aBuffer[i] - 1)) 
   156 				return KErrCorrupt;
   157 			}
   158 		else
   159 			{
   160 			if(aBuffer[i] != aBuffer[0])		
   161 				return KErrCorrupt;
   162 			}
   163 		c = aBuffer[i];
   164 		}
   165 		
   166 	return KErrNone;
   167 	}
   168 
   169 /**  Fills a buffer with character aC, aC+1, aC+2, ..., aC+0x20, aC, etc 
   170 
   171 	@param aBuffer  Buffer to be filled, output
   172 	@param aLength  Length to be filled
   173 	@param aC		Character to be used to fill the buffer
   174 */
   175 void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
   176 	{
   177 	test (aBuffer.MaxLength() >= aLength);
   178 	for(TInt i = 0; i < aLength; i++)
   179 		{
   180 		aBuffer.Append((i%32) + aC);
   181 		}
   182 	}
   183 
   184 /**  Returns true if fat filesystem present on aDrive
   185 
   186 	@param aFsSession 	Session on the File Server
   187 	@param aDrive 		Drive to be looked at
   188 	
   189 	@return ETrue if FAT, EFalse otherwise
   190 */
   191 TBool IsFSFAT(RFs &aFsSession,TInt aDrive)
   192 	{
   193 	TFileName f;
   194 	TInt r = aFsSession.FileSystemName(f,aDrive);
   195 	
   196 	if (r != KErrNone)
   197 		{
   198 		test.Printf(_L("Unable to get file system name\n"));
   199 		return EFalse;
   200 		}
   201 		
   202 	return (f.CompareF(_L("Fat")) == 0);
   203 	}
   204 
   205 /** Generates a file name of the form FFFFF*<aPos>.TXT (aLong.3)
   206 
   207 	@param aBuffer The filename will be returned here
   208 	@param aLong   Defines the longitude of the file name 
   209 	@param aPos	   Defines the number that will be attached to the filename
   210 */
   211 void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos) 
   212 	{
   213 	TInt padding;
   214 	TInt i = 0;
   215 	TBuf16<10> tempbuf;
   216 	
   217 	_LIT(KNumber,"%d");
   218 	tempbuf.Format(KNumber,aPos);
   219 	padding = aLong-tempbuf.Size()/2;
   220 	aBuffer = _L("");
   221 	while(i < padding)
   222 	{
   223 		aBuffer.Append('F');
   224 		i++;
   225 	}
   226 	aBuffer.Append(tempbuf);
   227 
   228 	_LIT(KExtension1, ".TXT");
   229 	aBuffer.Append(KExtension1);
   230 	}
   231 
   232 /**  Delete content of directory
   233 
   234 	@param aDir	Target directory
   235 	
   236 	@return Error returned if any, otherwise KErrNone
   237 */
   238 TInt DeleteAllL(TDes16& aDir) 
   239 	{
   240 	TBuf16<100> dir;
   241 	CFileMan* fMan = CFileMan::NewL(gTheFs);
   242 	TInt r=0;
   243 	
   244 	dir = aDir;
   245 	dir.Append(_L("F*.*"));
   246 	r = fMan->Delete(dir);	
   247 
   248 	delete fMan;
   249 	return r;
   250 	}
   251 
   252 /**  Waits for all the TRequestStatus in status[] to complete
   253 
   254 	@param status 	Array of TRequestStatus 
   255 	@param aSize  Length to be filled
   256 */
   257 void WaitForAll(TRequestStatus* status, TInt aSize) 
   258 	{
   259 	TInt i = 0;
   260 
   261 	RTest test(_L("T_WCACHE"));
   262 
   263 	while(i < aSize)
   264 		{
   265 		User::WaitForRequest(status[i]);
   266 		if (status[i] != KErrNone)
   267 			{
   268 			test.Printf(_L("status[%d] == %d\n"), i, status[i].Int());
   269 			test(EFalse);
   270 			}
   271 		i++;
   272 		}
   273 
   274 	test.Close();
   275 	}
   276 
   277 /**  Reads the parameters from the comand line 
   278 	 and updates the appropriate variables
   279 */
   280 void parseCommandLine() 
   281 	{
   282 	TBuf<0x100> cmd;
   283 	User::CommandLine(cmd);
   284 	TLex lex(cmd);
   285 	TPtrC token = lex.NextToken();
   286 	TInt r=0;
   287 
   288 	if(token.Length() != 0)		
   289 		{
   290 		gDriveToTest = token[0];
   291 		gDriveToTest.UpperCase();
   292 		}
   293 	else						
   294 		{
   295 		gDriveToTest = 'C';
   296 		}	
   297 		
   298 	r = gTheFs.CharToDrive(gDriveToTest,gDrive);
   299 	test_KErrNone(r);
   300 	
   301 	if(!lex.Eos()) 
   302 		{
   303 		token.Set(lex.NextToken());	
   304 		if(token.Length() != 0)		
   305 			{
   306 				TChar c = token[0];
   307 				c.UpperCase();
   308 				
   309 				gManual = (c == 'M'); 
   310 			}
   311 		}
   312 	
   313 	gSessionPath = _L("?:\\F32-TST\\");
   314 	gSessionPath[0] = (TUint16) gDriveToTest;
   315 	test.Printf(_L("\nCLP=%C\n"),(TInt)gDriveToTest);
   316 	}
   317 
   318 
   319 
   320 /**  Writes a file synchronously in blocks of aBlockSize size
   321 
   322 	@param aFs			RFs object
   323 	@param aFile		File 
   324 	@param aFileName	File name
   325 	@param aSize		Size of the file in bytes
   326 	@param aBlockSize	Size of the blocks to be used in bytes
   327 	@param aBuf			Buffer to be used to write
   328 	@param aMode		Mode in which the file is meant to be opened
   329 						
   330 	@return Returns KErrNone if everything ok, otherwise it panics 
   331 */
   332 TInt WriteFile(RFs& aFs, RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TDes8& aBuf, TInt aMode) 
   333 	{
   334 	RTest test(_L("T_WCACHE"));
   335 
   336 	TInt r = 0;
   337 
   338 	test(aBlockSize > 0);	
   339 
   340 
   341 	r = aFile.Replace(aFs,aFileName,aMode);
   342 	test_KErrNone(r);
   343 
   344 	TInt j = 0;
   345 	while(j < aSize)
   346 		{
   347 			r = aFile.Write(aBuf, aBlockSize);
   348 			test_KErrNone(r);
   349 			j += aBlockSize;
   350 		}					
   351 
   352 	test.Close();
   353 	return KErrNone;	
   354 	}
   355 
   356 /** Write a file that fits in the cache, and dies without proper cleaning
   357 
   358 */
   359 LOCAL_C TInt WriteFileT(TAny* )
   360 	{
   361 	RTest test(_L("T_WCACHE"));
   362 	RFs fs;
   363 	RFile file;
   364 	TInt r = fs.Connect();
   365 	test_KErrNone(r);
   366 
   367 	r = fs.SetSessionPath(gSessionPath);
   368 	test_KErrNone(r);
   369 	
   370 	r = WriteFile(fs, file, gFirstFile, KMinSize * KOneK, KBlockSize, gBufWritePtr, EFileShareAny|EFileWrite|EFileWriteBuffered);
   371 	test_KErrNone(r);
   372 	
   373 	gClient.Signal();
   374 
   375 
   376 	FOREVER
   377 		{
   378 			// waiting for the kill
   379 		}		
   380 	}
   381 
   382 /**  Read File in blocks of size aBlockSize
   383 
   384 	@param aFs			RFs object
   385 	@param aFile		File 
   386 	@param aFileName	File name
   387 	@param aSize		Expected file size
   388 	@param aBlockSize	Size of the blocks to be used in bytes
   389 	@param aMode		Mode in which the file is meant to be opened
   390 						
   391 	@return Returns KErrNone if everything ok, otherwise it panics 
   392 */
   393 TInt ReadFile(RFs& aFs, RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) 
   394 	{
   395 	RTest test(_L("T_WCACHE"));
   396 
   397 	TInt r = 0, size = 0;
   398 	
   399 	test(aBlockSize>0);				// Block size must be greater than 0
   400 
   401 	r = aFile.Open(aFs,aFileName,aMode);
   402 	test_KErrNone(r);
   403 
   404 	// Make sure the size of the file is the right one at this stage
   405 	r = aFile.Size(size);
   406 	test.Printf(_L("size of the file: %d \n"), size/KOneK); 
   407 	test(size == aSize);
   408 	
   409 	TInt j = 0;
   410 	while(j < size) 
   411 	{
   412 		r = aFile.Read(gBufReadPtr, aBlockSize);
   413 		test_KErrNone(r);
   414 		j += aBlockSize;
   415 	}					
   416 
   417 	test.Close();
   418 	return KErrNone;	
   419 	}
   420 
   421 /** Write a file asynchronously in blocks of aBlockSize size
   422 
   423 	@param aFs			RFs object
   424 	@param aFileWrite	RFile object, needs to exist beyond the scope of this function
   425 	@param aFile		File name
   426 	@param aSize		Size of the file in bytes
   427 	@param aMode		Specifies the mode in which the file should be openned
   428 	@param aStatus		TRequestStatus array for all the requests
   429 */
   430 void WriteFileAsync(RFs& aFs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aMode, TRequestStatus aStatus[]) 
   431 	{
   432 	RTest test(_L("T_WCACHE"));
   433 
   434 	TInt r = 0;
   435 	
   436 	r = aFileWrite.Replace(aFs,aFile,aMode);
   437 	test_KErrNone(r);
   438 
   439 	TInt j = 0, i = 0;
   440 	while(j < aSize)
   441 		{
   442 		aFileWrite.Write(gBufWritePtr, KBlockSize, aStatus[i]);
   443 		r = aStatus[i].Int();
   444 		if (r != KErrNone && r != KRequestPending)
   445 			{
   446 			test.Printf(_L("Write %d returned %d\n"), i, r);
   447 			test(0);
   448 			}
   449 		i++;
   450 
   451 		j += KBlockSize;	
   452 		}					
   453 	test.Close();
   454 	}
   455 
   456 /**  Read a file asynchronously in blocks of aBlockSize size
   457 
   458 	@param aFs			RFs object
   459 	@param aFileRead	RFile object, needs to exist beyond the scope of this function
   460 	@param aFile		File name
   461 	@param aFileSize		Size of the file in bytes
   462 	@param aBlockSize	Size of the blocks to be used in bytes
   463 	@param aStatus		TRequestStatus array for all the requests
   464 	@param aMode		Specifies the mode in which the file should be openned
   465 	
   466 	@return KErrNone
   467 */
   468 TInt ReadFileAsync(RFs& aFs,RFile& aFileRead, TDes16& aFile, TInt aFileSize, TInt aBlockSize,TRequestStatus aStatus[],  TInt aMode) 
   469 	{
   470 	RTest test(_L("T_WCACHE"));
   471 
   472 	TInt r = 0;
   473 	TInt size = 0;
   474 	
   475 	test(aBlockSize > 0);			
   476 	
   477 
   478 	r = aFileRead.Open(aFs,aFile, aMode); 
   479 	test_KErrNone(r);
   480 	
   481 	r = aFileRead.Size(size);
   482 	test_KErrNone(r);
   483 
   484 	test.Printf(_L("size of the file %d\n"), size/KOneK);
   485 	test(size == aFileSize);
   486 	
   487 	TInt j = 0, i = 0;
   488 	while(j < size) 
   489 		{
   490 		aFileRead.Read(gBufReadPtr, aBlockSize, aStatus[i]);
   491 		r = aStatus[i].Int();
   492 		if (r != KErrNone && r != KRequestPending)
   493 			{
   494 			test.Printf(_L("Read %d returned %d\n"), i, r);
   495 			test(0);
   496 			}
   497 		i++;
   498 
   499 		j += aBlockSize;
   500 		}					
   501 
   502 	test.Close();
   503 	return KErrNone;	
   504 	}
   505 
   506 /** Measure the time taken for this file to be written synchronously
   507 
   508 	@param aFile 	 	File object
   509 	@param aFileName 	File Name
   510 	@param aSize 		Size in kilobytes
   511 	@param aBlockSize 	Size of the block
   512 	@param aMode 		Mode in which the file is going to be opened
   513 	
   514 	@return time taken to perform the operation in uS
   515 */
   516 TInt WriteTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) 
   517 	{
   518 	RTest test(_L("T_WCACHE"));
   519 
   520 	TTime startTime;
   521 	TTime endTime;
   522 	TInt r = 0;
   523 	
   524 	startTime.HomeTime();
   525 	
   526 	r = WriteFile(gTheFs,aFile, aFileName , aSize * KOneK, aBlockSize, gBufWritePtr, aMode);
   527 	test_KErrNone(r);
   528 	
   529 	endTime.HomeTime();
   530 	
   531 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
   532 	
   533 	test.Close();
   534 	return I64LOW(gTimeTakenBigFile.Int64());
   535 	}
   536 
   537 /** Measure the time taken for this file to be read synchronously
   538 
   539 	@param aFile 	 	File object
   540 	@param aFileName 	File Name
   541 	@param aSize 		Size in kilobytes
   542 	@param aBlockSize 	Size of the block
   543 	@param aMode 		Mode in which the file is going to be opened
   544 
   545 	@return time taken to perform the operation in uS
   546 
   547 */
   548 TInt ReadTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) 
   549 	{
   550 	TTime startTime;
   551 	TTime endTime;
   552 	
   553 	startTime.HomeTime();
   554 	ReadFile(gTheFs,aFile, aFileName, aSize * KOneK, aBlockSize, aMode);
   555 	endTime.HomeTime();
   556 	
   557 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
   558 	
   559 	return I64LOW(gTimeTakenBigFile.Int64()) ;
   560 	}
   561 
   562 /** Read asynchronously the test file from the disc
   563 
   564 	@param aFile 	 	File object
   565 	@param aFileName 	File Name
   566 	@param aSize 		Size in kilobytes
   567 	@param aBlockSize 	Size of the block
   568 	@param aMode 		Mode in which the file is going to be opened
   569 
   570 	@return time taken to perform the operation in uS
   571 */
   572 TInt ReadAsyncTestFile(RFile& file, TDes16& aFile, TInt aSize, TInt aBlockSize, TInt aMode) 
   573 	{
   574 	TTime startTime;
   575 	TTime endTime;
   576 	TRequestStatus status[KWaitRequestsTableSize];
   577 	
   578 	startTime.HomeTime();
   579 	
   580 	ReadFileAsync(gTheFs, file, aFile, aSize * KOneK, aBlockSize, status, aMode);
   581 	WaitForAll(status,  (aSize * KOneK)/KBlockSize);
   582 	
   583 	endTime.HomeTime();
   584 	
   585 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
   586 	
   587 	return I64LOW(gTimeTakenBigFile.Int64());
   588 	}
   589 
   590 /** Read asynchronously the test file from the disc
   591 
   592 	@param aFile 	 	File object
   593 	@param aFileName 	File Name
   594 	@param aSize 		Size in kilobytes
   595 	@param aMode 		Mode in which the file is going to be opened
   596 
   597 	@return time taken to perform the operation in uS
   598 */
   599 TInt WriteAsyncTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aMode) 
   600 	{
   601 	TTime startTime;
   602 	TTime endTime;
   603 	TRequestStatus status[KWaitRequestsTableSize];
   604 	
   605 	startTime.HomeTime();
   606 	
   607 	WriteFileAsync(gTheFs, aFile, aFileName, aSize * KOneK, aMode, status );
   608 	WaitForAll(status, (aSize * KOneK)/KBlockSize);
   609 	
   610 	endTime.HomeTime();
   611 	
   612 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
   613 	
   614 	return I64LOW(gTimeTakenBigFile.Int64());
   615 	}
   616 
   617 /**  Test Boundaries
   618 
   619 	This function is testing the behaviour on the boundaries of the write cache size
   620 */
   621 void TestBoundaries()
   622 	{
   623 	TInt r = 0;
   624 	TInt time = 0;
   625 	TInt rtime = 0;
   626 	TInt tcreate = 0;
   627 	RFile fileWriter;
   628 	RFile fileWriter2;
   629 	RFile fileReader;
   630 
   631 	test.Start(_L("Test Boundaries"));
   632 	
   633 	// Test boundaries from 254K to 256K, synchronous operations 
   634 	TInt i = KMinSize;
   635 	
   636 	
   637 	test.Printf(_L("\n\n\n"));
   638 	
   639 	while(i < KMaxSize) 
   640 		{
   641 		test.Printf(_L("\nSync: Write from 1 K to %d K \n"), i); 
   642 
   643 		tcreate = WriteTestFile(fileWriter, gSecondFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteDirectIO);
   644 		test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs);	
   645 		fileWriter.Close();
   646 
   647 		time =  WriteTestFile(fileWriter2, gFirstFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered);
   648 		test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs);
   649 
   650 		rtime = ReadTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered);
   651 		test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs);
   652 
   653 
   654 		fileReader.Close();	
   655 		fileWriter2.Close();
   656 		
   657 		#if !defined(__WINS__)
   658 			test((tcreate > time) || (tcreate > rtime)); 
   659 		#endif
   660 
   661 		r = gTheFs.Delete(gFirstFile);
   662 		test_KErrNone(r);
   663 		r = gTheFs.Delete(gSecondFile);
   664 		test_KErrNone(r);
   665 		
   666 		i++;
   667 		}
   668 
   669 	test.Printf(_L("\n\n\n"));
   670 	
   671 	// Test boundaries from 254K to 256K, asynchronous operations 
   672 	i = KMinSize;
   673 	
   674 	while(i < KMaxSize) 
   675 		{
   676 		test.Printf(_L("\nAsync: Write from 1 K to %d K \n"), i); 
   677 
   678 		tcreate = WriteAsyncTestFile(fileWriter, gSecondFile, i, EFileShareAny|EFileWrite|EFileWriteDirectIO);
   679 		test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs);	
   680 		fileWriter.Close();
   681 
   682 		time =  WriteAsyncTestFile(fileWriter2, gFirstFile, i,EFileShareAny|EFileWrite|EFileWriteBuffered);
   683 		test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs);
   684 
   685 
   686 		rtime = ReadAsyncTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered);
   687 		test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs);
   688 
   689 		fileReader.Close();	
   690 		fileWriter2.Close();
   691 		
   692 		#if !defined(__WINS__)
   693 			test((tcreate > time) || (tcreate > rtime));  
   694 		#endif
   695 
   696 		r = gTheFs.Delete(gFirstFile);
   697 		test_KErrNone(r);
   698 		r = gTheFs.Delete(gSecondFile);
   699 		test_KErrNone(r);
   700 		
   701 		i++;
   702 		}
   703 
   704 	test.End();
   705 	}
   706 
   707 /**  Test negative cases
   708 
   709 */
   710 void TestNegative()
   711 	{
   712 	TInt r = 0;
   713 	RFile file;
   714 	TInt size =0;
   715 		
   716 	TBuf<20> buf = _L("Write File");
   717 
   718 
   719 	test.Start(_L("Test Negative"));
   720 
   721 	test.Next(_L("Kill a simple operation"));
   722 	
   723 	r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
   724 	test_KErrNone(r);
   725 
   726 	gThread1.Resume();
   727 	gClient.Wait();
   728 
   729 	gThread1.Kill(KErrGeneral);
   730 
   731 	r = file.Open(gTheFs,gFirstFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
   732 	test_KErrNone(r);
   733 
   734 	r = file.Size(size);
   735 	test_KErrNone(r);
   736 	
   737 	test.Printf(_L("The size of the file is %d KB\n\n"), size/KOneK);
   738 	test(size == (KMinSize * KOneK));
   739 	
   740 	file.Close();
   741 
   742 	test.End();
   743 	}
   744 
   745 
   746 /** Read the file verifying content
   747 
   748 	@param aFile file name to verify 
   749 	
   750 	@return returns the time that took to do the verification in mS, fails if the file is not corrupted/modified
   751 */
   752 TInt ReadTestFileVerif(TDes16& aFile)
   753 	{
   754 	TTime startTime;
   755 	TTime endTime;
   756 	TInt r = 0;
   757 	TInt size = 0;
   758 	RFile fileRead;
   759 	TInt corrupt = 0;
   760 	TBool isFat=IsFSFAT(gTheFs,gDrive);
   761 	
   762 	startTime.HomeTime();
   763 	
   764 	r = fileRead.Open(gTheFs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
   765 	test_KErrNone(r);
   766 
   767 	r = fileRead.Size(size);
   768 	test_KErrNone(r);
   769 	
   770 	TInt j = 0;
   771 	
   772 	while(j < size) 
   773 		{
   774 			r = fileRead.Read(gBufReadPtr, KBlockSize);
   775 			if(isFat)
   776 			{
   777 				test_KErrNone(r);
   778 			}
   779 			else 
   780 			{
   781 			if(r == KErrCorrupt) 
   782 				corrupt++;
   783 			}
   784 			
   785 			j += KBlockSize;
   786 			r = VerifyBuffer(gBufReadPtr);
   787 			if(r == KErrCorrupt) 
   788 				corrupt++;
   789 		}					
   790 
   791 	fileRead.Close();
   792 	
   793 	test(corrupt>0); // Ensure the cache returns the changed content 
   794 	
   795 	endTime.HomeTime();
   796 	
   797 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
   798 	
   799 	return I64LOW(gTimeTakenBigFile.Int64()) / KMs;
   800 	}
   801 
   802 /**  Modifies the second file
   803 
   804 */
   805 LOCAL_C TInt CorruptSecondFile()
   806 	{
   807 	TInt r = 0;
   808 	RFile fileWrite;
   809 	HBufC8* dummy = NULL;
   810 	TPtr8 dummyPtr(NULL, 0);	
   811 
   812 	TRAPD(res,dummy = HBufC8::NewL(4));
   813 	test(res == KErrNone && dummy != NULL);
   814 		
   815 	dummyPtr.Set(dummy->Des());
   816 	FillBuffer(dummyPtr, 4, '1');
   817 
   818 	r = fileWrite.Open(gTheFs,gSecondFile,EFileShareAny|EFileWrite|EFileWriteBuffered);
   819 	if(r != KErrNone) 
   820 		return r;
   821 	TInt pos = 30;
   822 	r = fileWrite.Seek(ESeekStart,pos);
   823 	test_KErrNone(r);
   824 	
   825 	r = fileWrite.Write(dummyPtr);
   826 	if(r != KErrNone) 
   827 		return r;
   828 	
   829 	fileWrite.Close();
   830 
   831 	delete dummy;
   832 
   833 	return KErrNone;
   834 	}
   835 
   836 
   837 /** Integrity testing
   838 
   839 */
   840 LOCAL_C void TestIntegrity()
   841 	{
   842 	TInt r = 0;
   843 	TInt time;
   844 	TInt tcreate = 0;
   845 	RFile file;
   846 	
   847 	// Modify file in some position 
   848 	test.Printf(_L("Overwrite partially a file\n"));
   849 	
   850 	test.Printf(_L("\nSync: Write from 1 K to %d K \n"), 255); 
   851 
   852 	tcreate = WriteTestFile(file, gSecondFile, 255, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered);
   853 	test.Printf(_L("Time to write %d K with caching: %d mS\n"), 255, tcreate/KMs);	
   854 	file.Close();
   855 
   856 	test.Printf(_L("Mess the content that is still in the cache\n"));
   857 	CorruptSecondFile(); 
   858 	
   859 	time = ReadTestFileVerif(gSecondFile);	
   860 	test.Printf(_L("Time taken to verify: %d\n"),time);
   861 	
   862 	test.Printf(_L("Integrity verified\n"));
   863 
   864 	r = DeleteAllL(gSessionPath);
   865 	test_KErrNone(r);
   866 	}
   867 
   868 /**  Creates the files to fill the cache with dirty data
   869 	
   870 	@return KErrNone
   871 */
   872 TInt CreateFilesThread(TAny *)
   873 	{
   874 	TInt i = 0;
   875 	TInt r = 0;
   876 	TBuf16<50> directory;
   877 	
   878 	TBuf16<50> path;
   879 	TBuf16<50> buffer(50); 	
   880 	RFile file[KFilesNeededToFillCache];
   881 	
   882 	RTest test(_L("T_WCACHE2"));
   883 	RFs fs;
   884 	
   885 	fs.Connect();
   886 	
   887 	directory = gSessionPath;
   888 	
   889 	test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), KFilesNeededToFillCache, KDefaultCacheSize);
   890 
   891 	// create a big buffer to speed things up
   892 	HBufC8* bigBuf = NULL;
   893 	TInt KBigBifferSize = 32 * KOneK;
   894 	
   895 	TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize));
   896 	test(res == KErrNone && bigBuf != NULL);
   897 		
   898 	TPtr8 bigBufWritePtr(NULL, 0);	
   899 	bigBufWritePtr.Set(bigBuf->Des());
   900 	FillBuffer(bigBufWritePtr, KBigBifferSize, 'A');
   901 	
   902 	i = 0;		
   903 	while(i < KFilesNeededToFillCache) 
   904 		{
   905 		if (i % 10 == 0)
   906 			test.Printf(_L("Creating file %d of %d...\r"), i, KFilesNeededToFillCache);
   907 		FileNameGen(buffer, 8, i+3) ;
   908 		path = directory;
   909 		path.Append(buffer);
   910 
   911 		r = file[i].Create(fs,path,EFileShareAny|EFileWrite|EFileWriteBuffered);
   912 		if(r == KErrAlreadyExists) 
   913 			r = file[i].Open(fs,path,EFileShareAny|EFileWrite|EFileWriteBuffered);
   914 		test_KErrNone(r);
   915 		TInt j = 0;
   916 	
   917 		while(j < KDefaultCacheSize)
   918 			{
   919 			bigBufWritePtr.SetLength(Min(KBigBifferSize, KDefaultCacheSize - j));
   920 			
   921 			r = file[i].Write(bigBufWritePtr);
   922 			test_KErrNone(r);
   923 			j += bigBufWritePtr.Length();
   924 			}					
   925 
   926 		// Not closing the files is done on purpose, as part of the test
   927 
   928 		i++;
   929 		}
   930 	test.Printf(_L("\nFiles created\n"));
   931 	delete bigBuf;
   932 	
   933 	gClient.Signal();
   934 	
   935 	return KErrNone;
   936 	}
   937 
   938 
   939 /**  Creates the files to fill the read cache 
   940 
   941 	@param aFiles 	 Number of files needed to fill the cache
   942 	@param aFileSize The file size
   943 */
   944 void CreateFiles(TInt aFiles, TInt aFileSize)
   945 	{
   946 	TInt i = 0;
   947 	TInt r = 0;
   948 	RFile file;
   949 	TBuf16<50> directory;
   950 	
   951 	TBuf16<50> path;
   952 	TBuf16<50> buffer(50); 	
   953 	
   954 	directory = gSessionPath;
   955 	
   956 	test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), aFiles, aFileSize);
   957 
   958 	// create a big buffer to speed things up
   959 	HBufC8* bigBuf = NULL;
   960 	const TInt KBigBifferSize = 32 * 1024;
   961 	TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize));
   962 	test(res == KErrNone && bigBuf != NULL);
   963 		
   964 	TPtr8 bigBufWritePtr(NULL, 0);	
   965 	bigBufWritePtr.Set(bigBuf->Des());
   966 	FillBuffer(bigBufWritePtr, KBigBifferSize, 'A');
   967 	
   968 	i = 0;		
   969 	while(i < aFiles) 
   970 		{
   971 		if (i % 10 == 0)
   972 			test.Printf(_L("Creating file %d of %d...\r"), i, aFiles);
   973 		FileNameGen(buffer, 8, i+3) ;
   974 		path = directory;
   975 		path.Append(buffer);
   976 
   977 		// delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
   978 		r = gTheFs.Delete(path);
   979 		test_Value(r, r == KErrNone || r == KErrNotFound);
   980 
   981 		r = file.Create(gTheFs,path,EFileShareAny|EFileWrite|EFileWriteDirectIO);
   982 		if(r == KErrAlreadyExists) 
   983 			r = file.Open(gTheFs,path,EFileShareAny|EFileWrite|EFileWriteDirectIO);
   984 		test_KErrNone(r);
   985 		TInt j = 0;
   986 		while(j < aFileSize)
   987 			{
   988 			bigBufWritePtr.SetLength(Min(KBigBifferSize, aFileSize - j));
   989 			r = file.Write(bigBufWritePtr);
   990 			test_KErrNone(r);
   991 			j += bigBufWritePtr.Length();
   992 			}					
   993 
   994 		file.Close();
   995 		i++;
   996 		}
   997 	test.Printf(_L("\nFiles created\n"));
   998 	delete bigBuf;
   999 	}
  1000 
  1001 /**  Fills the read cache 
  1002 
  1003 	@param aFile	 Array of files needed to fill the cache
  1004 	@param aFiles 	 Number of files needed to fill the cache
  1005 	@param aFileSize The file size
  1006 */
  1007 void FillCache(RFile aFile[KFilesNeededToFillCache], TInt aFiles, TInt aFileSize)
  1008 	{
  1009 	TInt i = 0;
  1010 	TInt r = 0;
  1011 	TBuf16<50> directory;
  1012 	
  1013 	TBuf16<50> path;
  1014 	TBuf16<50> buffer(50); 	
  1015 	HBufC8* buf = NULL;
  1016 	TPtr8 bufPtr(NULL, 0);	
  1017 	
  1018 	TRAPD(res,buf = HBufC8::NewL(2));
  1019 	test(res == KErrNone && buf != NULL);
  1020 	bufPtr.Set(buf->Des());
  1021 	
  1022 	directory = gSessionPath;
  1023 	
  1024 	i = 0;		
  1025 	while(i < aFiles) 
  1026 	{
  1027 		FileNameGen(buffer, 8, i+3) ;
  1028 		path = directory;
  1029 		path.Append(buffer);
  1030 		r = aFile[i].Open(gTheFs,path,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
  1031 		test_KErrNone(r);
  1032 		
  1033 		TInt j = 0;
  1034 		while(j < aFileSize)
  1035 			{
  1036 				r = aFile[i].Read(j,bufPtr);
  1037 				test_KErrNone(r);
  1038 				j += 4*KOneK;
  1039 			}					
  1040 
  1041 		i++;
  1042 	}
  1043 	
  1044 	delete buf;
  1045 	test.Printf(_L("Cache filled\n"));
  1046 	}
  1047 
  1048 /** Fills the default cache
  1049 
  1050 */
  1051 void TestFillCache()
  1052 	{	
  1053 	TInt nFiles = KFilesNeededToFillCache;
  1054 	TInt fSize = KDefaultCacheSize;
  1055 	RFile file[KFilesNeededToFillCache];
  1056 	TInt r = 0;
  1057 	
  1058 	if(gMediaSize> ((fSize * nFiles)+gSecondFileSize+gFirstFileSize))
  1059 		{
  1060 		test.Start(_L("Creating files for filling the cache\n"));
  1061 		CreateFiles(nFiles,fSize);
  1062 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1063 		// get number of items on Page Cache
  1064 		TFileCacheStats startPageCacheStats;
  1065 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1066 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1067 		test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount);
  1068 		test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount);
  1069 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1070 #endif
  1071 		FillCache(file,nFiles,fSize); 
  1072 
  1073 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1074 		// get number of items on Page Cache
  1075 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1076 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1077 		test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount);
  1078 		test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount);
  1079 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1080 #endif
  1081 
  1082 	TestBoundaries();
  1083 	
  1084 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1085 		// get number of items on Page Cache
  1086 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1087 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1088 		test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount);
  1089 		test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount);
  1090 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1091 #endif
  1092 
  1093 		TInt i = 0;
  1094 		while( i < KFilesNeededToFillCache )
  1095 			{
  1096 			file[i++].Close();
  1097 			}
  1098 			
  1099 		r = DeleteAllL(gSessionPath);
  1100 		test_KErrNone(r);
  1101 
  1102 		test.End();
  1103 		}
  1104 	else 
  1105 		test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n"));
  1106 	}
  1107 
  1108 /** Fills the cache and generate error situations
  1109 
  1110 */
  1111 void TestFillCacheNegative()
  1112 	{	
  1113 	TInt nFiles = KFilesNeededToFillCache;
  1114 	TInt r = 0;
  1115 
  1116 	if(gMediaSize> ((KDefaultCacheSize * nFiles)+gSecondFileSize+gFirstFileSize))
  1117 		{
  1118 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1119 		// get number of items on Page Cache
  1120 		TFileCacheStats startPageCacheStats;
  1121 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1122 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1123 		test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount);
  1124 		test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount);
  1125 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1126 #endif
  1127 	test.Start(_L("Creating files for filling the cache, with uncommitted data\n"));
  1128 	
  1129 	TBuf<20> buf = _L("FillCache");
  1130 	
  1131 	 r = gThread1.Create(buf,CreateFilesThread,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
  1132 	test_KErrNone(r);
  1133 
  1134 	gThread1.Resume();
  1135 	gClient.Wait();
  1136 
  1137 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1138 		// get number of items on Page Cache
  1139 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1140 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1141 		test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount);
  1142 		test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount);
  1143 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1144 #endif
  1145 
  1146 	TestBoundaries();
  1147 	
  1148 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1149 		// get number of items on Page Cache
  1150 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1151 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1152 		test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount);
  1153 		test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount);
  1154 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1155 		
  1156 		User::After(180000);
  1157 
  1158 		r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
  1159 		test_Value(r, r == KErrNone || r == KErrNotSupported);
  1160 		test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount);
  1161 		test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount);
  1162 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
  1163 
  1164 #endif
  1165 		test.End();
  1166 		
  1167 		r = DeleteAllL(gSessionPath);
  1168 		test_KErrNone(r);
  1169 
  1170 		}
  1171 	else 
  1172 		test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n"));
  1173 	}
  1174 
  1175 
  1176 /** Manual test for card removal
  1177 
  1178 */
  1179 void TestRemoval()
  1180 	{	
  1181 	TInt time = 0, rtime = 0;
  1182 	RFile file1, file2;
  1183 	
  1184 		 	
  1185 	TInt r = gClient.CreateLocal(0);
  1186  	test_KErrNone(r);
  1187  	
  1188 	r = gTheFs.SetSessionPath(gSessionPath);
  1189 	test_KErrNone(r);
  1190 	
  1191 	r = gTheFs.MkDirAll(gSessionPath);
  1192 	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
  1193 
  1194 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1195 	test.Printf(_L("Disabling Lock Fail simulation ...\n"));
  1196 	// turn OFF lock failure mode
  1197 	TBool simulatelockFailureMode = EFalse;
  1198 	r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
  1199 	test_KErrNone(r);
  1200 #endif
  1201 
  1202 	TBuf16<45> dir;
  1203 		
  1204 	// FileNames/File generation
  1205 	test.Start(_L("Preparing the environmnet\n"));
  1206 	FileNameGen(gFirstFile, 8, gNextFile++);
  1207 	FileNameGen(gSecondFile, 8, gNextFile++);
  1208 	dir = gSessionPath;
  1209 	dir.Append(gFirstFile);
  1210 	gFirstFile = dir;
  1211 	dir = gSessionPath;
  1212 	dir.Append(gSecondFile);
  1213 	gSecondFile = dir;
  1214 
  1215 
  1216 	TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1));
  1217 	test(res == KErrNone && gBuf != NULL);
  1218 		
  1219 	gBufWritePtr.Set(gBuf->Des());
  1220 	FillBuffer(gBufWritePtr, KBlockSize, 'A');
  1221 	
  1222 	TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1));
  1223 	test(res2 == KErrNone && gBufSec != NULL);
  1224 	gBufReadPtr.Set(gBufSec->Des());
  1225 
  1226 	
  1227 	test.Printf(_L("\nSync: Write from 1 K to 254 K \n")); 
  1228 
  1229 	time =  WriteTestFile(file1, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered);
  1230 	test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize, time/KMs);
  1231 	test.Printf(_L("Remove MMC card,! and then press a key\n"));
  1232 	test.Getch();
  1233 
  1234 	test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n"));
  1235 	test.Getch();
  1236 
  1237 	rtime = ReadTestFile(file2, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered);
  1238 	test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize, rtime/KMs);
  1239 
  1240 	test.Printf(_L("Remove MMC card! and then press a key\n"));
  1241 	test.Getch();
  1242 
  1243 	test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n"));
  1244 	test.Getch();
  1245 
  1246 
  1247 	test.Printf(_L("\nSync: Write from 1 K to 255 K \n")); 
  1248 
  1249 	time =  WriteTestFile(file1, gFirstFile, KMinSize + 1 , KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered);
  1250 	test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize + 1, time/KMs);
  1251 	test.Printf(_L("Remove MMC card and delete the file //F32-TST//FFFFFFF0.TXT and then press a key\n"));
  1252 	test.Getch();
  1253 
  1254 	test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n"));
  1255 	test.Getch();
  1256 
  1257 	rtime = ReadTestFile(file2, gFirstFile, KMinSize + 1, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered);
  1258 	test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize + 1, rtime/KMs);
  1259 
  1260 	test.Printf(_L("Remove MMC card! and then press a key\n"));
  1261 	test.Getch();
  1262 
  1263 	test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n"));
  1264 	test.Getch();
  1265 	
  1266 		
  1267 	file1.Close();	
  1268 	file2.Close();
  1269 	delete gBuf;
  1270 	delete gBufSec;
  1271 	}
  1272 
  1273 
  1274 /** Main tests function
  1275 */ 
  1276 void CallTestsL()
  1277 	{
  1278 	
  1279 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1280 	test.Printf(_L("Disabling Lock Fail simulation ...\n"));
  1281 	// turn OFF lock failure mode
  1282 	TBool simulatelockFailureMode = EFalse;
  1283 	TInt r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
  1284 	test_KErrNone(r);
  1285 #endif
  1286 
  1287 	TBuf16<45> dir;
  1288 		
  1289 	// FileNames/File generation
  1290 	test.Start(_L("Preparing the environmnet\n"));
  1291 	FileNameGen(gFirstFile, 8, gNextFile++);
  1292 	FileNameGen(gSecondFile, 8, gNextFile++);
  1293 	dir = gSessionPath;
  1294 	dir.Append(gFirstFile);
  1295 	gFirstFile = dir;
  1296 	dir = gSessionPath;
  1297 	dir.Append(gSecondFile);
  1298 	gSecondFile = dir;
  1299 
  1300 
  1301 	TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1));
  1302 	test(res == KErrNone && gBuf != NULL);
  1303 		
  1304 	gBufWritePtr.Set(gBuf->Des());
  1305 	FillBuffer(gBufWritePtr, KBlockSize, 'A');
  1306 	
  1307 	TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1));
  1308 	test(res2 == KErrNone && gBufSec != NULL);
  1309 	gBufReadPtr.Set(gBufSec->Des());
  1310 
  1311 	test.Next(_L("Boundary test"));
  1312 	TestBoundaries();
  1313 	
  1314 	test.Next(_L("Negative test\n"));
  1315 	TestNegative(); 
  1316 
  1317 	test.Next(_L("Integrity test\n"));
  1318 	TestIntegrity(); 
  1319 	
  1320 
  1321 	test.Next(_L("Fill the cache, boundary testing\n"));
  1322 	TestFillCache();
  1323 	
  1324 	test.Next(_L("Fill the cache negative, boundary testing\n"));
  1325 	TestFillCacheNegative();
  1326 	
  1327 	test.End();
  1328 	delete gBuf;
  1329 	delete gBufSec;
  1330 
  1331 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1332 	// turn lock failure mode back ON (if enabled)
  1333 	simulatelockFailureMode = ETrue;
  1334 	r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
  1335 	test_KErrNone(r);
  1336 #endif
  1337 
  1338 	}
  1339 
  1340 /** Initialises semaphores and call the tests
  1341 */ 
  1342 void DoTests()
  1343 	{
  1344 	TInt r = 0;
  1345 	 	
  1346 	r = gClient.CreateLocal(0);
  1347  	test_KErrNone(r);
  1348  	
  1349 	r = gTheFs.SetSessionPath(gSessionPath);
  1350 	test_KErrNone(r);
  1351 	
  1352 	r = gTheFs.MkDirAll(gSessionPath);
  1353 	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
  1354 	gTheFs.ResourceCountMarkStart();
  1355 	
  1356 	TRAP(r,CallTestsL());
  1357 	
  1358 	test_KErrNone(r);
  1359 	gTheFs.ResourceCountMarkEnd();
  1360 	}
  1361 
  1362 /** Determines the space that can be used for the files
  1363 
  1364 */
  1365 TBool CheckForDiskSize()
  1366 	{
  1367 	TVolumeInfo volInfo;
  1368 	TInt r = gTheFs.Volume(volInfo, gDrive);
  1369 	test_KErrNone(r);
  1370 	gMediaSize = volInfo.iSize;
  1371 	
  1372 	test.Printf(_L("\nMedia size: %d MB\n"), gMediaSize/KOneMeg  );
  1373 	
  1374 	return ETrue;
  1375 	}
  1376 
  1377 /** Main function
  1378 
  1379 	@return KErrNone if everything was ok, panics otherwise
  1380 */
  1381 TInt E32Main()
  1382 	{
  1383 	RThread t;
  1384 	gMainThreadId = t.Id();
  1385 	
  1386 	CTrapCleanup* cleanup;
  1387 	cleanup = CTrapCleanup::New();
  1388 
  1389 	__UHEAP_MARK;
  1390 	test.Start(_L("Starting tests... T_WCACHE"));
  1391 	parseCommandLine();
  1392 	
  1393 	TInt r = gTheFs.Connect();
  1394 	test_KErrNone(r);
  1395 	
  1396 	TDriveInfo info;
  1397 	TVolumeInfo volInfo;
  1398 	r = gTheFs.Drive(info,gDrive);
  1399 	test_KErrNone(r);
  1400 	
  1401 	if(info.iMediaAtt&KMediaAttVariableSize)
  1402 		{
  1403 		test.Printf(_L("Tests skipped in RAM drive\n"));
  1404 		goto out;
  1405 		}
  1406 
  1407 	r = gTheFs.Volume(volInfo, gDrive);
  1408 	if (r == KErrNotReady)
  1409 		{
  1410 		if (info.iType == EMediaNotPresent)
  1411 			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
  1412 		else
  1413 			test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType);
  1414 		}
  1415 	else if (r == KErrCorrupt)
  1416 		{
  1417 		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
  1418 		}
  1419 	test_KErrNone(r);	
  1420 
  1421 	if(!(volInfo.iFileCacheFlags & (EFileCacheReadEnabled | EFileCacheReadAheadEnabled))) 
  1422 		{
  1423 		test.Printf(_L("Skipping tests, Read caching not enabled in this drive\n"));
  1424 		goto out;
  1425 		}
  1426 
  1427 	if (((volInfo.iDrive.iMediaAtt & KMediaAttFormattable)))
  1428 		Formatting(gDrive,ESpecialFormat);
  1429 
  1430 	if(!CheckForDiskSize())
  1431 		{
  1432 		test.Printf(_L("Skipping tests due to lack of space to perform them in this drive\n"));
  1433 		}
  1434 	else if(!gManual)
  1435 		{
  1436 		DoTests();
  1437 		}
  1438 	else
  1439 		{
  1440 		TestRemoval();
  1441 		}
  1442 
  1443 out:	
  1444 	test.End();
  1445 
  1446 	gTheFs.Close();
  1447 	test.Close();
  1448 
  1449 	__UHEAP_MARKEND;
  1450 	delete cleanup;
  1451 	return(KErrNone);
  1452     }
  1453