kerneltest/f32test/server/t_wcache.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
child 256 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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