kerneltest/f32test/server/t_main.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
child 19 4a8fed1c0ef6
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\server\t_main.cpp
// 
//

#define __E32TEST_EXTENSION__

#include <f32file.h>
#include <e32test.h>
#include <e32hal.h>
#include <e32math.h>
#include <f32dbg.h>
#include "t_server.h"
#include "t_chlffs.h"

GLDEF_D	RFs TheFs;
GLDEF_D TFileName gSessionPath;
GLDEF_D TFileName gExeFileName(RProcess().FileName());
GLDEF_D TInt gAllocFailOff=KAllocFailureOff;
GLDEF_D TInt gAllocFailOn=KAllocFailureOff;
GLDEF_D TInt64 gSeed=51703;

GLDEF_D TChar gDriveToTest;
GLDEF_D TVolumeInfo gVolInfo;	// volume info for current drive
GLDEF_D TFileCacheFlags gDriveCacheFlags;

_LIT(KPrivate, "\\Private\\");


////////////////////////////////////////////////////////////
// Template functions encapsulating ControlIo magic
//
GLDEF_D template <class C>
GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
{
    TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));

    TInt r = fs.ControlIo(drv, fkn, ptrC);

    return r;
}

GLDEF_C void CreateShortName(TDes& aFileName,TInt64& aSeed)
//
// Create a random, dos legal 8.3 char name
//
	{

	TInt length=Math::Rand(aSeed)%11;
	if (length==0)
		length=1;
	else if (length==3)	// don't create three letter names like 'AUX' or 'PRN'
		length++;
	else if (length>8)	// end in '.' if no extension
		length++;

	aFileName.SetLength(length);
	for(TInt i=0;i<length;i++)
		{
		if (i==9)
			{
			aFileName[i]='.';
			continue;
			}
		TInt letter=Math::Rand(aSeed)%26;
		aFileName[i]=(TText)('A'+letter);
		}
	}

_LIT(KFatName, "Fat");
_LIT(KFat32Name, "Fat32");

static
TBool isFAT(RFs &aFsSession, TInt aDrive)
{
	TFileName f;
	TInt r = aFsSession.FileSystemName(f, aDrive);
	test_Value(r, r == KErrNone || r == KErrNotFound);
	return (f.CompareF(KFatName) == 0 || f.CompareF(KFat32Name) == 0);
}	

static 
TUint16 getRootEntCnt(RFs &aFsSession, TInt aDrive)
	{
	RRawDisk	rdisk;
	TUint16		rootEntCnt;
	TPtr8		reader((TUint8*)&rootEntCnt, sizeof(rootEntCnt));

	test_KErrNone(rdisk.Open(aFsSession, aDrive));
	test_KErrNone(rdisk.Read(17, reader)); // "BPB_RootEntCnt" field at offset 17
	rdisk.Close();
		
	return rootEntCnt;
	}

GLDEF_C TBool IsFileSystemFAT(RFs &aFsSession,TInt aDrive)
//
// return true if FAT on aDrive
//
	{
	return (isFAT(aFsSession, aDrive) && getRootEntCnt(aFsSession, aDrive) != 0);
	}

GLDEF_C TBool IsFileSystemFAT32(RFs &aFsSession,TInt aDrive)
//
// return true if FAT32 on aDrive
//
	{
	return (isFAT(aFsSession, aDrive) && getRootEntCnt(aFsSession, aDrive) == 0);
	}

GLDEF_C void CreateLongName(TDes& aFileName,TInt64& aSeed,TInt aLength)
//
// Create a random, dos legal 8.3 char name
//
	{

	TInt length;
	if (aLength>0)
		length=aLength;
	else
		{
		length=Math::Rand(aSeed)%128;
		length+=Math::Rand(aSeed)%128;
		length+=Math::Rand(aSeed)%128;
		length+=Math::Rand(aSeed)%128;
		length-=256;
			length=Abs(length);
		if (length==0)
			length=1;
		if (length>220)
			length=31;
		}
	if (length==3)	// don't create three letter names like 'AUX' or 'PRN'
		length++;

	aFileName.SetLength(length);
	TInt spaceChar=-1;
	TInt i;
	for(i=0;i<length;i++)
		{
StartAgain:
		TChar letter=0;
		TBool illegalChar=ETrue;

		while(illegalChar)
			{
#if defined(__WINS__)
			if (gSessionPath[0]=='C')
				letter=(TChar)('A'+Math::Rand(aSeed)%26);
			else
				letter=(TChar)Math::Rand(aSeed)%256;
#else
			letter=(TChar)Math::Rand(aSeed)%256;
#endif
			TBool space=letter.IsSpace();
			if (space && spaceChar==-1)
				spaceChar=i;
			else if (!space && spaceChar!=-1)
				spaceChar=-1;

			switch(letter)
				{
			case '<':
			case '>':
			case ':':
			case '"':
			case '/':
			case '|':
			case '*':
			case '?':
			case '\\':
			case '\0':
				break;
			default:
				illegalChar=EFalse;
				};
			}
		aFileName[i]=(TText)letter;
		}

	if (spaceChar!=-1)
		{
		i=spaceChar;
		goto StartAgain;
		}
	}

GLDEF_C void CheckEntry(const TDesC& aName,TUint anAttributes,const TTime& aModified)
//
// Checks the values associated with an entry
//
	{

	TEntry entry;
	TInt r=TheFs.Entry(aName,entry);
	test_KErrNone(r);
	test(entry.iAtt==anAttributes);
	if (aModified!=TTime(0))
		test(entry.iModified==aModified);
	}

GLDEF_C void CheckDisk()
//
// Do a checkdisk and report failure
//
	{
	test.Next(_L("Check Disk"));
	TInt r=TheFs.CheckDisk(gSessionPath);
	if (r!=KErrNone && r!=KErrNotSupported && r!=KErrPermissionDenied)
		ReportCheckDiskFailure(r);
	}

GLDEF_C void ReportCheckDiskFailure(TInt aRet)
//
// Report the failure of checkdisk
//
	{

	test.Printf(_L("CHECKDISK FAILED: "));
	switch(aRet)
		{
	case 1:	test.Printf(_L("File cluster chain contains a bad value (<2 or >maxCluster)\n")); break;
	case 2:	test.Printf(_L("Two files are linked to the same cluster\n")); break;
	case 3:	test.Printf(_L("Unallocated cluster contains a value != 0\n"));	break;
	case 4:	test.Printf(_L("Size of file != number of clusters in chain\n")); break;
	default: test.Printf(_L("Undefined Error value %d\n"),aRet);
		}
	test(EFalse);
	}

GLDEF_C void TurnAllocFailureOff()
//
// Switch off all allocFailure
//
	{

	test.Printf(_L("Disable Alloc Failure\n"));
	TheFs.SetAllocFailure(gAllocFailOff);
	gAllocFailOn=KAllocFailureOff; // Disable gAllocFailOn
	}

GLDEF_C void TurnAllocFailureOn()
//
// Switch off all allocFailure
//
	{

	test.Printf(_L("Enable Alloc Failure\n"));
	gAllocFailOn=KAllocFailureOn; // Enable gAllocFailOn
	TheFs.SetAllocFailure(gAllocFailOn);
	}

GLDEF_C void MakeFile(const TDesC& aFileName,const TUidType& aUidType,const TDesC8& aFileContents)
//
// Make a file and write uid and data
//
	{

	RFile file;
	TInt r=file.Replace(TheFs,aFileName,0);
	if (r==KErrPathNotFound)
		{
		r=TheFs.MkDirAll(aFileName);
		test_KErrNone(r);
		r=file.Replace(TheFs,aFileName,0);
		}
	test_KErrNone(r);
	TCheckedUid checkedUid(aUidType);
	TPtrC8 uidData((TUint8*)&checkedUid,sizeof(TCheckedUid));
	r=file.Write(uidData);
	test_KErrNone(r);
	r=file.Write(aFileContents);
	test_KErrNone(r);
	file.Close();
	}

GLDEF_C void MakeFile(const TDesC& aFileName,const TDesC8& aFileContents)
//
// Make a file and write something in it
//
	{

	RFile file;
	TInt r=file.Replace(TheFs,aFileName,0);
	if (r==KErrPathNotFound)
		{
		r=TheFs.MkDirAll(aFileName);
		test_KErrNone(r);
		r=file.Replace(TheFs,aFileName,0);
		}
	test_KErrNone(r);
	r=file.Write(aFileContents);
	test_KErrNone(r);
	file.Close();
	}

GLDEF_C void MakeFile(const TDesC& aFileName,TInt anAttributes)
//
// Make a file and write something in it
//
	{

	RFile file;
	TInt r=file.Replace(TheFs,aFileName,0);
	if (r==KErrPathNotFound)
		{
		r=TheFs.MkDirAll(aFileName);
		test_KErrNone(r);
		r=file.Replace(TheFs,aFileName,0);
		}
	test_KErrNone(r);
	file.Close();
	r=TheFs.SetAtt(aFileName,anAttributes,0);
	test_KErrNone(r);
	}

GLDEF_C void SetSessionPath(const TDesC& aPathName)
//
// Set the session path and update gSessionPath
//
	{

	TInt r=TheFs.SetSessionPath(aPathName);
	test_KErrNone(r);
	r=TheFs.SessionPath(gSessionPath);
	test_KErrNone(r);
	}

GLDEF_C void MakeFile(const TDesC& aFileName)
//
// Make a file
//
	{
	
	MakeFile(aFileName,_L8(""));
	}

GLDEF_C void MakeDir(const TDesC& aDirName)
//
// Make a directory
//
	{

	TInt r=TheFs.MkDirAll(aDirName);
	if (r!=KErrNone && r!=KErrAlreadyExists)
		{
		test.Printf(_L("%c: MakeDir Error %d\n"),aDirName[0],r);
		test(0);
		}
	}

GLDEF_C TInt CheckFileExists(const TDesC& aName,TInt aResult,TBool aCompRes/*=ETrue*/)
//
// Check aName exists
//
	{

	TEntry entry;
	TInt r=TheFs.Entry(aName,entry);
	test_Value(r, r == KErrNone || r == aResult);
	if (aResult!=KErrNone)
		return(0);
	TParsePtrC nameParse(aName);
	TParsePtrC entryParse(entry.iName);
	TBool nameMatch=(entryParse.Name()==nameParse.Name());
	TBool extMatch=(entryParse.Ext()==nameParse.Ext()) || (entryParse.Ext().Length()<=1 && nameParse.Ext().Length()<=1);
	test((nameMatch && extMatch)==aCompRes);
	return(entry.iSize);
	}

GLDEF_C void CheckFileContents(const TDesC& aName,const TDesC8& aContents)
//
// Check contents of file
//
	{

	RFile f;
	TInt r=f.Open(TheFs,aName,EFileRead);
	test_KErrNone(r);
	HBufC8* testBuf=HBufC8::NewL(aContents.Length());
	test(testBuf!=NULL);
	TPtr8 bufPtr(testBuf->Des());
	r=f.Read(bufPtr);
	test_KErrNone(r);
	test(bufPtr==aContents);
	r=f.Read(bufPtr);
	test_KErrNone(r);
	test(bufPtr.Length()==0);
	f.Close();
	User::Free(testBuf);
	}

GLDEF_C void DeleteTestDirectory()
//
// Delete the leaf session path directory
//
	{

	TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden"), 0, KEntryAttHidden);
	TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden\\HiddenFile"), 0, KEntryAttHidden);
	TheFs.SetAtt(_L("\\F32-TST\\SCANTEST\\Left\\Dir3\\Dir4\\Hidden\\System"), 0, KEntryAttSystem);
	test.Next(_L("Delete test directory"));
	CFileMan* fMan=CFileMan::NewL(TheFs);
	test(fMan!=NULL);
	TInt r=TheFs.SessionPath(gSessionPath);
	test_KErrNone(r);
	r=TheFs.CheckDisk(gSessionPath);
	if (r!=KErrNone && r!=KErrNotSupported)
		ReportCheckDiskFailure(r);
	r=fMan->RmDir(gSessionPath);
	test_KErrNone(r);
	delete fMan;
	}

GLDEF_C void CreateTestDirectory(const TDesC& aSessionPath)
//
// Create directory for test
//
	{
	TParsePtrC path(aSessionPath);
	test(path.DrivePresent()==EFalse);

	TInt r=TheFs.SetSessionPath(aSessionPath);
	test_KErrNone(r);
	r=TheFs.SessionPath(gSessionPath);
	test_KErrNone(r);
	r=TheFs.MkDirAll(gSessionPath);
	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
	}

GLDEF_C TInt CurrentDrive()
//
// Return the current drive number
//
	{

	TInt driveNum;
	TInt r=TheFs.CharToDrive(gSessionPath[0],driveNum);
	test_KErrNone(r);
	return(driveNum);
	}

GLDEF_C void Format(TInt aDrive)
//
// Format current drive
//
	{

	test.Next(_L("Format"));
	TBuf<4> driveBuf=_L("?:\\");
	driveBuf[0]=(TText)(aDrive+'A');
	RFormat format;
	TInt count;
	TInt r=format.Open(TheFs,driveBuf,EQuickFormat,count);
	test_KErrNone(r);
	while(count)
		{
		TInt r=format.Next(count);
		test_KErrNone(r);
		}
	format.Close();
	}

LOCAL_C void PushLotsL()
//
// Expand the cleanup stack
//
	{
	TInt i;
	for(i=0;i<1000;i++)
		CleanupStack::PushL((CBase*)NULL);
	CleanupStack::Pop(1000);
	}


LOCAL_C void DoTests(TInt aDrive)
//
// Do testing on aDrive
//
	{

	gSessionPath=_L("?:\\F32-TST\\");
	TChar driveLetter;
	TInt r=TheFs.DriveToChar(aDrive,driveLetter);
	test_KErrNone(r);
	gSessionPath[0]=(TText)driveLetter;
	r=TheFs.SetSessionPath(gSessionPath);
	test_KErrNone(r);

// !!! Disable platform security tests until we get the new APIs
//	if(User::Capability() & KCapabilityRoot)
		CheckMountLFFS(TheFs,driveLetter);
	
	User::After(1000000);

//	Format(CurrentDrive());

	test.Printf(_L("Creating session path"));
	r=TheFs.MkDirAll(gSessionPath);
	if(r == KErrCorrupt)
		{
		test.Printf(_L("Attempting to create directory \'%S\' failed, KErrCorrupt\n"), &gSessionPath);
		test.Printf(_L("This could be caused by a previous failing test, or a test media defect\n"));
		test.Printf(_L("Formatting drive, retrying MkDirall\nShould subsequent tests fail with KErrCorrupt (%d) as well, replace test medium !\n"),
			r);
		Format(aDrive);
		r=TheFs.MkDirAll(gSessionPath);
		test_KErrNone(r);
		}
	else if (r == KErrNotReady)
		{
		TDriveInfo d;
		r=TheFs.Drive(d, aDrive);
		test_KErrNone(r);
		if (d.iType == EMediaNotPresent)
			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)driveLetter);
		else
			test.Printf(_L("medium found (type %d) but drive %c: not ready\nPrevious test may have hung; else, check hardware.\n"), (TInt)d.iType, (TUint)driveLetter);
		}
	test_Value(r, r == KErrNone || r == KErrAlreadyExists);
	TheFs.ResourceCountMarkStart();
	test.Printf(_L("Calling main test sequence ...\n"));
	TRAP(r,CallTestsL());
	test_KErrNone(r);
	test.Printf(_L("test sequence completed without error\n"));
	TheFs.ResourceCountMarkEnd();

	CheckDisk();
	TestingLFFS(EFalse);
	}


void ParseCommandArguments()
//
//
//
	{
	TBuf<0x100> cmd;
	User::CommandLine(cmd);
	TLex lex(cmd);
	TPtrC token=lex.NextToken();
	TFileName thisfile=RProcess().FileName();
	if (token.MatchF(thisfile)==0)
		{
		token.Set(lex.NextToken());
		}
	test.Printf(_L("CLP=%S\n"),&token);

	if(token.Length()!=0)		
		{
		gDriveToTest=token[0];
		gDriveToTest.UpperCase();
		}
	else						
		gDriveToTest='C';		
	}

TFullName gExtName;
TBool gPrimaryExtensionExists = EFalse;

GLDEF_C TInt DismountFileSystem(RFs& aFs, const TDesC& aFileSystemName,TInt aDrive)
	{
	//Make note of the first extension if it exists, so that we remount
	//it when the file system is remounted.
	TInt r = aFs.ExtensionName(gExtName, aDrive, 0);
	
	if (r == KErrNone)
		{
		gPrimaryExtensionExists = ETrue;
		}
	return aFs.DismountFileSystem(aFileSystemName, aDrive);
	}

GLDEF_C TInt MountFileSystem(RFs& aFs, const TDesC& aFileSystemName,TInt aDrive, TBool aIsSync)
	{
	TInt r;
	if (gPrimaryExtensionExists)
		{
		r = aFs.MountFileSystem(aFileSystemName, gExtName, aDrive, aIsSync);
		}
	else
		{
		r = aFs. MountFileSystem(aFileSystemName, aDrive, aIsSync);
		}
	return r;
	}

GLDEF_C TInt E32Main()
//
// Test with drive nearly full
//
    {

	CTrapCleanup* cleanup;
	cleanup=CTrapCleanup::New();
	TRAPD(r,PushLotsL());
	__UHEAP_MARK;

	test.Title();
	test.Start(_L("Starting tests..."));


	ParseCommandArguments(); //need this for drive letter to test


	r=TheFs.Connect();
	test_KErrNone(r);
	TheFs.SetAllocFailure(gAllocFailOn);
	TTime timerC;
	timerC.HomeTime();
	TFileName sessionp;
	TheFs.SessionPath(sessionp);

	TBuf<30> privatedir;
	privatedir = KPrivate;

	TUid thisUID = RProcess().Identity();
	privatedir.AppendFormat(_L("%08x"),thisUID.iUid);
	privatedir.Append(_L("\\"));

	test(privatedir == sessionp.Mid(2,sessionp.Length()-2));

	test.Printf(_L("sp=%S\n"),&sessionp);
	sessionp[0]=(TText)gDriveToTest;
	test.Printf(_L("sp1=%S\n"),&sessionp);

	TInt theDrive;
	r=TheFs.CharToDrive(gDriveToTest,theDrive);
	test_KErrNone(r);
	
	// Get the TFileCacheFlags for this drive
	r = TheFs.Volume(gVolInfo, theDrive);
	if (r == KErrNotReady)
		{
		TDriveInfo info;
		TInt err = TheFs.Drive(info,theDrive);
		test_KErrNone(err);
		if (info.iType == EMediaNotPresent)
			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
		else
			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);
		}
	else if (r == KErrCorrupt)
		{
		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
		}
	test_KErrNone(r);
	gDriveCacheFlags = gVolInfo.iFileCacheFlags;
	test.Printf(_L("DriveCacheFlags = %08X\n"), gDriveCacheFlags);

#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
	TPckgBuf<TIOCacheValues> pkgOrgValues;
	TIOCacheValues& orgValues=pkgOrgValues();
	r = controlIo(TheFs,theDrive, KControlIoCacheCount, orgValues);
	test_KErrNone(r);

	test.Printf(_L("\n"));
	test.Printf(_L("Requests on close queue at start=%d\n"),orgValues.iCloseCount);
	test.Printf(_L("Requests on free queue at start=%d\n"),orgValues.iFreeCount);
	test.Printf(_L("Requests dynamically allocated at start=%d\n"),orgValues.iAllocated);
	test.Printf(_L("Requests in total at start=%d\n"),orgValues.iTotalCount);

	// File cache

	// flush closed files queue
	r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles);
	test_KErrNone(r);

	// get number of items on File Cache
	TFileCacheStats startFileCacheStats;
	r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, startFileCacheStats);
	test_Value(r, r == KErrNone || r == KErrNotSupported);
	test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
		startFileCacheStats.iFreeCount, 
		startFileCacheStats.iUsedCount, 
		startFileCacheStats.iAllocatedSegmentCount,
		startFileCacheStats.iLockedSegmentCount,
		startFileCacheStats.iFilesOnClosedQueue);
#endif

	DoTests(theDrive);

	TTime endTimeC;
	endTimeC.HomeTime();
	TTimeIntervalSeconds timeTakenC;
	r=endTimeC.SecondsFrom(timerC,timeTakenC);
	test_KErrNone(r);
	test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int());
	TheFs.SetAllocFailure(gAllocFailOff);
	
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
	TPckgBuf<TIOCacheValues> pkgValues;
	TIOCacheValues& values=pkgValues();
	r = controlIo(TheFs,theDrive, KControlIoCacheCount, values);
	test_KErrNone(r);
	
	test.Printf(_L("Requests on close queue at end=%d\n"),values.iCloseCount);
	test.Printf(_L("Requests on free queue at end=%d\n"),values.iFreeCount);
	test.Printf(_L("Requests dynamically allocated at end=%d\n"),values.iAllocated);
	test.Printf(_L("Requests in total at end=%d\n"),values.iTotalCount);
	
	test(orgValues.iCloseCount==values.iCloseCount);
	test(orgValues.iAllocated == values.iAllocated);
	// The free count can increase if the file server runs out of requests in the RequestAllocator 
	// free pool but this should never decrease - this implies a request leak
	test(orgValues.iFreeCount <= values.iFreeCount);

	// The total number of allocated requests should be equal to :
	// requests on the close queue + requests on free queue 
	// + 1 (because we used one request to issue KControlIoCacheCount)
	// If this doesn't equate then this implies a request leak
	test(values.iTotalCount == values.iCloseCount + values.iFreeCount + 1);

	// File cache
	TFileCacheStats endFileCacheStats;
	r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
	test_Value(r, r == KErrNone || r == KErrNotSupported);

	test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
		endFileCacheStats.iFreeCount, 
		endFileCacheStats.iUsedCount, 
		endFileCacheStats.iAllocatedSegmentCount,
		endFileCacheStats.iLockedSegmentCount,
		endFileCacheStats.iFilesOnClosedQueue);

	// flush closed files queue
	test.Printf(_L("Flushing close queue..."));
	r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles);
	test_KErrNone(r);

	r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
	test_Value(r, r == KErrNone || r == KErrNotSupported);
	test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
		endFileCacheStats.iFreeCount, 
		endFileCacheStats.iUsedCount, 
		endFileCacheStats.iAllocatedSegmentCount,
		endFileCacheStats.iLockedSegmentCount,
		endFileCacheStats.iFilesOnClosedQueue);


	if (r == KErrNone)
		{
		test(startFileCacheStats.iFreeCount == endFileCacheStats.iFreeCount);
		test(startFileCacheStats.iUsedCount == endFileCacheStats.iUsedCount);
		test(startFileCacheStats.iAllocatedSegmentCount == endFileCacheStats.iAllocatedSegmentCount);
		test(startFileCacheStats.iLockedSegmentCount == endFileCacheStats.iLockedSegmentCount);
		test(startFileCacheStats.iFileCount == endFileCacheStats.iFileCount);
		}
#endif

	TheFs.Close();
	test.End();
	test.Close();
	__UHEAP_MARKEND;
	delete cleanup;
	return(KErrNone);
    }