diff -r 000000000000 -r a41df078684a kerneltest/f32test/demandpaging/t_reaper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/demandpaging/t_reaper.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,452 @@ +// Copyright (c) 2006-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\demandpaging\t_reaper.cpp +// +// Suite of tests for the Reaper, the reaper is used to clean up files +// which were deleted whilst in use, the delete is delayed until the +// files are no longer in use and then completed by the reaper. +// +// 001 Loader Reaper/Clamp Tests +// 002 Try deleteing file while Open +// 003 Try deleteing file while Clamped and Open +// 004 Try deleteing while Clamped +// 005 Check moved in sys/del +// 006 Check Can't delete +// 007 Unclamp and Delete +// 008 Copy DLL to drive and delete +// 009 Copy DLL, Load, close and RFs::delete +// 010 Copy DLL, Load, close and Loader::delete +// 011 Copy DLL to drive, load and delete +// 012 Check file deleted on close +// 013 Try deleting something of the same name twice while loaded. +// + +//! @SYMTestCaseID KBASE-T_REAPER-0330 +//! @SYMTestType UT +//! @SYMPREQ PREQ1110 +//! @SYMTestCaseDesc Demand Paging Reaper. +//! @SYMTestActions 001 Loader Reaper/Clamp Tests +//! @SYMTestExpectedResults All tests should pass. +//! @SYMTestPriority High +//! @SYMTestStatus Implemented + +#define __E32TEST_EXTENSION__ +#include +#include +#include +#include +#include "u32std.h" + +TBool Verbose = EFalse; +RFs TheFs; +RLoader Loader; +TInt DriveNumber=-1; + +class TPagingDriveInfo + { +public: + TChar iDriveLetter; + TDriveInfo iDriveInfo; + }; + +RArray SupportedDrives; +TInt gNumSupportedDrives = 0; + + +LOCAL_D RTest test(_L("T_reaper")); + +_LIT(KFilePath,":\\sys\\bin\\test.txt"); + +_LIT(KSysPath,"z:\\sys\\bin\\"); +_LIT(KPathDel,":\\sys\\del\\"); +_LIT(KDllFile,"t_reaper_test_dll.dll"); +const TInt KLibNameLength = 50; + +void CopyDll(const TDesC& aSourceName, const TDesC& aDestName) + { + const TInt KBufferSize = 3333; + TBuf8 buffer; + RFile in, out; + + test.Printf(_L(" copying %S to %S\n"), &aSourceName, &aDestName); + + TInt r = TheFs.MkDirAll(aDestName); + test_Assert(r == KErrNone || r == KErrAlreadyExists, test.Printf(_L("MkDirAll returned %d\n"),r)); + + test_KErrNone(in.Open(TheFs, aSourceName, EFileRead)); + test_KErrNone(out.Replace(TheFs, aDestName, EFileWrite)); + + TInt size; + test_KErrNone(in.Size(size)); + TInt pos = 0; + while (pos < size) + { + test_KErrNone(in.Read(buffer)); + test_KErrNone(out.Write(buffer)); + pos += buffer.Length(); + } + + in.Close(); + out.Close(); + } + +void CopyDllToDrive(const TDesC& aSourceName, TUint8 aDrive, TBuf& aDestName) + { + TBuf sourceName; + sourceName=KSysPath; + sourceName.Append(aSourceName); + aDestName=KSysPath; + aDestName.Append(aSourceName); + aDestName[0] = aDrive; + CopyDll(sourceName, aDestName); + } + +static void CreateTestFile(const TDesC& aTestFile) +/** + Create an empty file with the supplied name. This function is used + to create file which can be deleted with RLoader::Delete. + + @param aFs Open file server session. + @param aTestFile The test file's name. + */ + { + TInt r; + TheFs.MkDirAll(aTestFile); + RFile f; + r = f.Replace(TheFs, aTestFile, EFileWrite | EFileStream | EFileShareExclusive); + test_KErrNone(r); + TBuf<256> buf(_L("Space is big, I mean its really big.\n")); + TPtrC8 pBuf((TUint8*)&buf); + f.Write(pBuf); + f.Flush(); + f.Close(); + } + +// Get the list of pageable drives +void GetSupportedDrives() + { + TChar ch; + TBuf<256> fileSystemName; + TDriveList driveList; + TDriveInfo driveInfo; + + TInt r = TheFs.DriveList(driveList); + test_KErrNone(r); + + TBool NandPageableMediaFound = EFalse; + + for (TInt drvNum=0; drvNum delPath; + delPath = KSearchPathDel; + delPath[0] = aDrive; + + CDir* dir=NULL; + + CTrapCleanup* c = CTrapCleanup::New(); + TInt r = TheFs.GetDir(delPath,KEntryAttMatchExclude | KEntryAttDir ,ESortNone,dir); + delete c; + if(r==KErrPathNotFound) + return 0; // no files + test_KErrNone(r); + + test.Printf(_L("Files: %d\n"),dir->Count() ); + TInt count = dir->Count(); + TBool found = false; + for (TInt i=count-1;i>=0;i--) + { + TBuf tempPath; + tempPath.Append(aDrive); + tempPath.Append(KPathDel); + tempPath.Append((*dir)[i].iName); + test.Printf(_L("%S\n"), &tempPath); + if(!found && tempPath.CompareF(aExcludedFile)!=0) + { + found = true; + aFile = tempPath; + } + } + + delete dir; + return count; + } + + +void TestDlls(TUint8 aDrive) + { + TEntry e; + TBuf libName; + TBuf delName; + TBuf delName2; + TBuf libName2; + + RLibrary library; + RLibrary library2; + + test.Next(_L("Copy DLL to drive and delete")); + CopyDllToDrive(KDllFile,aDrive,libName); + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del + test_KErrNone(Loader.Delete(libName)); + test_Equal(KErrNotFound, TheFs.Entry(libName,e)); + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del + + test.Next(_L("Copy DLL, Load, close and RFs::delete")); + CopyDllToDrive(KDllFile,aDrive,libName); + test_KErrNone( library.Load(libName)); + test_Equal(KErrInUse, TheFs.Delete(libName)); + CLOSE_AND_WAIT(library); + test_KErrNone( TheFs.Delete(libName)); + test_Equal(KErrNotFound, TheFs.Entry(libName,e)); + + test.Next(_L("Copy DLL, Load, close and Loader::delete")); + CopyDllToDrive(KDllFile,aDrive,libName); + test_KErrNone( library.Load(libName)); + CLOSE_AND_WAIT(library); + test_KErrNone( Loader.Delete(libName)); + test_Equal(KErrNotFound, TheFs.Entry(libName,e)); + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del + + test.Next(_L("Copy DLL to drive, load and delete")); + CopyDllToDrive(KDllFile,aDrive,libName); + test_KErrNone( library.Load(libName)); + test_Equal(KErrInUse, TheFs.Delete(libName)); + test_KErrNone( Loader.Delete(libName)); + test_Equal(KErrNotFound, TheFs.Entry(libName,e)); + test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file + test_Equal(KErrInUse, TheFs.Delete(delName)); + + test.Next(_L("Check file deleted on close")); + CLOSE_AND_WAIT(library); + test_Equal(KErrNotFound, TheFs.Entry(delName,e)); + + test.Next(_L("Try deleting something of the same name twice while loaded.")); + CopyDllToDrive(KDllFile,aDrive,libName); + test_KErrNone( library.Load(libName)); + test_KErrNone( Loader.Delete(libName)); + test_Equal(KErrNotFound, TheFs.Entry(libName,e)); + test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file + + test.Printf(_L("Load a Secord Copy\n")); + CopyDllToDrive(KDllFile,aDrive,libName); + libName2=libName; + libName2[27]='2'; + test_KErrNone( TheFs.Rename(libName,libName2)); + test_KErrNone( library2.Load(libName2)); + test_KErrNone( TheFs.Rename(libName2,libName)); + + test.Printf(_L("Try and delete second copy\n")); + test_KErrNone( Loader.Delete(libName)); + test_Equal(2, FindDeletedFile(aDrive,delName2,delName)); // get name of second 'deleted' file + + test.Printf(_L("Now close and watch deletions\n")); + CLOSE_AND_WAIT(library); + test_Equal(KErrNotFound, TheFs.Entry(delName,e)); + test_KErrNone( TheFs.Entry(delName2,e)); + CLOSE_AND_WAIT(library2); + test_Equal(KErrNotFound, TheFs.Entry(delName2,e)); + } + + +void BasicTest(TUint8 aDrive) + { + TBuf<256> startFileName; + TBuf<256> endFileName; + RFile file; + RFileClamp fileClamp; + + startFileName.Append((TChar) aDrive); + startFileName+=KFilePath; + + + CreateTestFile(startFileName); + + test.Next(_L("Try deleteing file while Open")); + test_KErrNone( file.Open(TheFs,startFileName,EFileShareExclusive|EFileWrite)); + test_Equal(KErrInUse, Loader.Delete(startFileName)); + + test.Next(_L("Try deleteing file while Clamped and Open")); + test_KErrNone( fileClamp.Clamp(file)); + test_Equal(KErrInUse, Loader.Delete(startFileName)); + + test.Next(_L("Try deleteing while Clamped")); + file.Close(); + test_Equal(0, FindDeletedFile(aDrive,endFileName)); // check no files in sys/del + test_KErrNone( Loader.Delete(startFileName)); + + test.Next(_L("Check moved in sys/del")); + test_Equal(1, FindDeletedFile(aDrive,endFileName)); // check one file in sys/del + + test.Next(_L("Check Can't delete")); + test_Equal(KErrInUse, TheFs.Delete(endFileName)); + + test.Next(_L("Unclamp and Delete")); + test_KErrNone( fileClamp.Close(TheFs)); + test_KErrNone( TheFs.Delete(endFileName)); + + + } + + +// +// ParseCommandLine reads the arguments and sets globals accordingly. +// + +TInt ParseCommandLine() + { + TBuf<32> args; + User::CommandLine(args); + TLex lex(args); + TInt err=KErrNone; + FOREVER + { + TPtrC token=lex.NextToken(); + if(token.Length()!=0) + { + if ((token.Length()==1) || ((token.Length()==2) && (token[1]==':'))) + { + TChar driveLetter = User::UpperCase(token[0]); + if ((driveLetter>='A') && (driveLetter<='Z')) + DriveNumber=driveLetter - (TChar) 'A'; + else + err=KErrArgument; + } + else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?"))) + { + test.Printf(_L("\nThis tests the loader's reaper, which is used in code paging to postpone deletions of paged code from disk.\n")); + test.Printf(_L("\nIf no drive letter is supplied, then all suitable drives are checked.\n\n")); + err=KErrCancel; + } + else + err=KErrArgument; + } + else + break; + + if (err!=KErrNone) + { + if (err==KErrArgument) + test.Printf(_L("\nUnknown argument '%S'\n"), &token); + test.Printf(_L("\nUsage: t_reaper [-h] []\n\n")); + test.Getch(); + return err; + } + } + return KErrNone; + } + + + +GLDEF_C TInt E32Main() + { + TInt i; + test.Title(); + + if (ParseCommandLine()) + return KErrNone; + + TheFs.Connect(); + + TUint32 memModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL); + TUint32 pagingPolicy = E32Loader::PagingPolicy(); + if((memModelAttributes&EMemModelAttrCodePaging)==0 || pagingPolicy==EKernelConfigCodePagingPolicyNoPaging) + { + test.Start(_L("TESTS NOT RUN - Code paging not enabled on system.")); + test.End(); + return KErrNone; + } + + test.Start(_L("Loader Reaper/Clamp Tests")); + + // Turn off evil lazy dll unloading + RLoader l; + test(l.Connect()==KErrNone); + test(l.CancelLazyDllUnload()==KErrNone); + l.Close(); + + GetSupportedDrives(); + test_Compare(gNumSupportedDrives,>,0); + test_KErrNone( Loader.Connect()); + test_KErrNone( Loader.CancelLazyDllUnload()); + + for (i=0;i