os/kernelhwsrv/kerneltest/f32test/demandpaging/t_reaper.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-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\demandpaging\t_reaper.cpp
    15 //
    16 // Suite of tests for the Reaper, the reaper is used to clean up files
    17 // which were deleted whilst in use, the delete is delayed until the 
    18 // files are no longer in use and then completed by the reaper.
    19 //
    20 // 001 Loader Reaper/Clamp Tests
    21 // 002 Try deleteing file while Open
    22 // 003 Try deleteing file while Clamped and Open
    23 // 004 Try deleteing while Clamped
    24 // 005 Check moved in sys/del
    25 // 006 Check Can't delete
    26 // 007 Unclamp and Delete
    27 // 008 Copy DLL to drive and delete
    28 // 009 Copy DLL, Load, close and RFs::delete
    29 // 010 Copy DLL, Load, close and Loader::delete
    30 // 011 Copy DLL to drive, load and delete
    31 // 012 Check file deleted on close
    32 // 013 Try deleting something of the same name twice while loaded.
    33 // 
    34 
    35 //! @SYMTestCaseID			KBASE-T_REAPER-0330
    36 //! @SYMTestType			UT
    37 //! @SYMPREQ				PREQ1110
    38 //! @SYMTestCaseDesc		Demand Paging Reaper.
    39 //! @SYMTestActions			001 Loader Reaper/Clamp Tests
    40 //! @SYMTestExpectedResults All tests should pass.
    41 //! @SYMTestPriority        High
    42 //! @SYMTestStatus          Implemented
    43 
    44 #define __E32TEST_EXTENSION__
    45 #include <e32test.h>
    46 #include <e32svr.h>
    47 #include <f32file.h>
    48 #include <e32ldr.h>
    49 #include <u32hal.h>
    50 #include "u32std.h"
    51 
    52 TBool Verbose = EFalse;
    53 RFs TheFs;
    54 RLoader Loader;
    55 TInt DriveNumber=-1;
    56 
    57 class TPagingDriveInfo
    58 	{
    59 public:
    60 	TChar iDriveLetter;
    61 	TDriveInfo iDriveInfo;
    62 	};
    63 
    64 RArray<TPagingDriveInfo> SupportedDrives;
    65 TInt gNumSupportedDrives = 0;
    66 
    67 
    68 LOCAL_D RTest test(_L("T_reaper"));
    69 
    70 _LIT(KFilePath,":\\sys\\bin\\test.txt");
    71 
    72 _LIT(KSysPath,"z:\\sys\\bin\\");
    73 _LIT(KPathDel,":\\sys\\del\\");
    74 _LIT(KDllFile,"t_reaper_test_dll.dll");
    75 const TInt KLibNameLength = 50;
    76 
    77 void CopyDll(const TDesC& aSourceName, const TDesC& aDestName)
    78 	{
    79 	const TInt KBufferSize = 3333;
    80 	TBuf8<KBufferSize> buffer;
    81 	RFile in, out;
    82 	
    83 	test.Printf(_L("  copying %S to %S\n"), &aSourceName, &aDestName);
    84 
    85 	TInt r = TheFs.MkDirAll(aDestName);
    86 	test_Assert(r == KErrNone || r == KErrAlreadyExists, test.Printf(_L("MkDirAll returned %d\n"),r));
    87 
    88 	test_KErrNone(in.Open(TheFs, aSourceName, EFileRead));
    89 	test_KErrNone(out.Replace(TheFs, aDestName, EFileWrite));
    90 
    91 	TInt size;
    92 	test_KErrNone(in.Size(size));
    93 	TInt pos = 0;
    94 	while (pos < size)
    95 		{
    96 		test_KErrNone(in.Read(buffer));
    97 		test_KErrNone(out.Write(buffer));
    98 		pos += buffer.Length();
    99 		}
   100 	
   101 	in.Close();
   102 	out.Close();
   103 	}
   104 
   105 void CopyDllToDrive(const TDesC& aSourceName, TUint8 aDrive, TBuf<KLibNameLength>& aDestName)
   106 	{
   107 		TBuf<KLibNameLength> sourceName;
   108 		sourceName=KSysPath;
   109 		sourceName.Append(aSourceName);
   110 		aDestName=KSysPath;
   111 		aDestName.Append(aSourceName);
   112 		aDestName[0] = aDrive;
   113 		CopyDll(sourceName, aDestName);
   114 	}
   115 
   116 static void CreateTestFile(const TDesC& aTestFile)
   117 /**
   118 	Create an empty file with the supplied name.  This function is used
   119 	to create file which can be deleted with RLoader::Delete.
   120 	
   121 	@param	aFs				Open file server session.
   122 	@param	aTestFile		The test file's name.
   123  */
   124 	{
   125 	TInt r;
   126 	TheFs.MkDirAll(aTestFile);
   127 	RFile f;
   128 	r = f.Replace(TheFs, aTestFile, EFileWrite | EFileStream | EFileShareExclusive);
   129 	test_KErrNone(r);
   130 	TBuf<256> buf(_L("Space is big, I mean its really big.\n"));
   131 	TPtrC8 pBuf((TUint8*)&buf);
   132 	f.Write(pBuf);
   133 	f.Flush();
   134 	f.Close();
   135 	}
   136 
   137 // Get the list of pageable drives
   138 void GetSupportedDrives()
   139 	{
   140 	TChar ch;
   141 	TBuf<256> fileSystemName;
   142 	TDriveList driveList;
   143 	TDriveInfo driveInfo;
   144 
   145 	TInt r = TheFs.DriveList(driveList);
   146     test_KErrNone(r);
   147 
   148 	TBool NandPageableMediaFound = EFalse;
   149 
   150 	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
   151 		{
   152 	    if(!driveList[drvNum])
   153 	        continue;   //-- skip unexisting drive
   154 	
   155 	    test_KErrNone( TheFs.Drive(driveInfo, drvNum) );
   156 		test_KErrNone( TheFs.DriveToChar(drvNum, ch) );
   157 		test_KErrNone( TheFs.FileSystemName(fileSystemName, drvNum) );
   158 
   159 		if (Verbose)
   160 			test.Printf(_L("GetSupportedDrives, Drive %c iType %d iDriveAtt %08x iMediaAtt %08X, fileSystemName %S\n"), 
   161 				(TInt) ch, driveInfo.iType, driveInfo.iDriveAtt, driveInfo.iMediaAtt, &fileSystemName);
   162 	
   163 		if ((driveInfo.iDriveAtt & KDriveAttPageable) && (driveInfo.iType == EMediaNANDFlash))
   164 			NandPageableMediaFound = ETrue;
   165 
   166 		TBool pageable = EFalse;
   167 		if (driveInfo.iDriveAtt & KDriveAttPageable)
   168 			pageable = ETrue;
   169 
   170 		// If we've already found a pageable NAND drive, then assume the Z: drive is pageable too 
   171 		// if it's got a composite file system (fudge)
   172 		_LIT(KCompositeName,"Composite");
   173 		if (fileSystemName == KCompositeName())
   174 			{
   175 			if (NandPageableMediaFound)
   176 				pageable = ETrue;
   177 			driveInfo.iMediaAtt|=KMediaAttWriteProtected;
   178 			}
   179 		if (pageable)
   180 			{
   181 			TPagingDriveInfo pagingDriveInfo;
   182 			pagingDriveInfo.iDriveLetter = ch;
   183 			pagingDriveInfo.iDriveInfo = driveInfo;
   184 
   185 
   186 			test_KErrNone( SupportedDrives.Append(pagingDriveInfo) );
   187 			if (Verbose)
   188 				test.Printf(_L("Drive %c supports paging\n"), (TInt) pagingDriveInfo.iDriveLetter);
   189 			gNumSupportedDrives++;
   190 			}
   191 		}
   192 	}
   193 
   194 
   195 
   196 TInt FindDeletedFile(TUint8 aDrive, TDes& aFile, const TDesC& aExcludedFile=KNullDesC)
   197 	{
   198 	aFile.Zero();
   199 
   200 	_LIT(KSearchPathDel,"?:\\sys\\del\\*");
   201 	TBuf<13> delPath;
   202 	delPath = KSearchPathDel;
   203 	delPath[0] = aDrive;
   204 
   205 	CDir* dir=NULL;
   206 	
   207 	CTrapCleanup* c = CTrapCleanup::New();
   208 	TInt r = TheFs.GetDir(delPath,KEntryAttMatchExclude | KEntryAttDir ,ESortNone,dir);
   209 	delete c;
   210 	if(r==KErrPathNotFound)
   211 		return 0; // no files
   212 	test_KErrNone(r);
   213 
   214 	test.Printf(_L("Files: %d\n"),dir->Count() );
   215 	TInt count = dir->Count();
   216 	TBool found = false;
   217 	for (TInt i=count-1;i>=0;i--)
   218 		{
   219 		TBuf<KLibNameLength> tempPath;
   220 		tempPath.Append(aDrive);
   221 		tempPath.Append(KPathDel);
   222 		tempPath.Append((*dir)[i].iName);
   223 		test.Printf(_L("%S\n"), &tempPath);
   224 		if(!found && tempPath.CompareF(aExcludedFile)!=0)
   225 			{
   226 			found = true;
   227 			aFile = tempPath;
   228 			}
   229 		}
   230 	
   231 	delete dir;
   232 	return count;
   233 	}
   234 
   235 
   236 void TestDlls(TUint8 aDrive)
   237 	{
   238 	TEntry e;
   239 	TBuf<KLibNameLength> libName;
   240 	TBuf<KLibNameLength> delName;
   241 	TBuf<KLibNameLength> delName2;
   242 	TBuf<KLibNameLength> libName2;
   243 
   244 	RLibrary library;
   245 	RLibrary library2;
   246 
   247 	test.Next(_L("Copy DLL to drive and delete"));
   248 	CopyDllToDrive(KDllFile,aDrive,libName);
   249 	test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
   250 	test_KErrNone(Loader.Delete(libName));
   251 	test_Equal(KErrNotFound, TheFs.Entry(libName,e));
   252 	test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
   253 	
   254 	test.Next(_L("Copy DLL, Load, close and RFs::delete"));
   255 	CopyDllToDrive(KDllFile,aDrive,libName);
   256 	test_KErrNone( library.Load(libName));
   257 	test_Equal(KErrInUse, TheFs.Delete(libName));
   258 	CLOSE_AND_WAIT(library);
   259 	test_KErrNone( TheFs.Delete(libName));
   260 	test_Equal(KErrNotFound, TheFs.Entry(libName,e));
   261 	
   262 	test.Next(_L("Copy DLL, Load, close and Loader::delete"));
   263 	CopyDllToDrive(KDllFile,aDrive,libName);
   264 	test_KErrNone( library.Load(libName));
   265 	CLOSE_AND_WAIT(library);
   266 	test_KErrNone( Loader.Delete(libName));
   267 	test_Equal(KErrNotFound, TheFs.Entry(libName,e));
   268 	test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
   269 
   270 	test.Next(_L("Copy DLL to drive, load and delete"));
   271 	CopyDllToDrive(KDllFile,aDrive,libName);
   272 	test_KErrNone( library.Load(libName));
   273 	test_Equal(KErrInUse, TheFs.Delete(libName));
   274 	test_KErrNone( Loader.Delete(libName));
   275 	test_Equal(KErrNotFound, TheFs.Entry(libName,e));
   276 	test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file
   277 	test_Equal(KErrInUse, TheFs.Delete(delName));
   278 	
   279 	test.Next(_L("Check file deleted on close"));
   280 	CLOSE_AND_WAIT(library);
   281 	test_Equal(KErrNotFound, TheFs.Entry(delName,e));	
   282 
   283 	test.Next(_L("Try deleting something of the same name twice while loaded."));
   284 	CopyDllToDrive(KDllFile,aDrive,libName);
   285 	test_KErrNone( library.Load(libName));
   286 	test_KErrNone( Loader.Delete(libName));
   287 	test_Equal(KErrNotFound, TheFs.Entry(libName,e));
   288 	test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file
   289 	
   290 	test.Printf(_L("Load a Secord Copy\n"));
   291 	CopyDllToDrive(KDllFile,aDrive,libName);
   292 	libName2=libName;
   293 	libName2[27]='2';
   294 	test_KErrNone( TheFs.Rename(libName,libName2));
   295 	test_KErrNone( library2.Load(libName2));
   296 	test_KErrNone( TheFs.Rename(libName2,libName));
   297 	
   298 	test.Printf(_L("Try and delete second copy\n"));
   299 	test_KErrNone( Loader.Delete(libName));
   300 	test_Equal(2, FindDeletedFile(aDrive,delName2,delName)); // get name of second 'deleted' file
   301 
   302 	test.Printf(_L("Now close and watch deletions\n"));
   303 	CLOSE_AND_WAIT(library);
   304 	test_Equal(KErrNotFound, TheFs.Entry(delName,e));
   305 		test_KErrNone( TheFs.Entry(delName2,e));
   306 	CLOSE_AND_WAIT(library2);
   307 	test_Equal(KErrNotFound, TheFs.Entry(delName2,e));
   308 	}
   309 
   310 
   311 void BasicTest(TUint8 aDrive)
   312 	{
   313 	TBuf<256> startFileName;	
   314 	TBuf<256> endFileName;
   315 	RFile file;
   316 	RFileClamp fileClamp;
   317 
   318 	startFileName.Append((TChar) aDrive);
   319 	startFileName+=KFilePath;
   320 
   321 	
   322 	CreateTestFile(startFileName);
   323 	
   324 	test.Next(_L("Try deleteing file while Open"));
   325 	test_KErrNone( file.Open(TheFs,startFileName,EFileShareExclusive|EFileWrite));
   326 	test_Equal(KErrInUse, Loader.Delete(startFileName));
   327 
   328 	test.Next(_L("Try deleteing file while Clamped and Open"));
   329 	test_KErrNone( fileClamp.Clamp(file));
   330 	test_Equal(KErrInUse, Loader.Delete(startFileName));
   331 
   332 	test.Next(_L("Try deleteing while Clamped"));
   333 	file.Close(); 
   334 	test_Equal(0, FindDeletedFile(aDrive,endFileName)); // check no files in sys/del
   335 	test_KErrNone( Loader.Delete(startFileName));
   336 
   337 	test.Next(_L("Check moved in sys/del"));
   338 	test_Equal(1, FindDeletedFile(aDrive,endFileName)); // check one file in sys/del
   339 	
   340 	test.Next(_L("Check Can't delete"));
   341 	test_Equal(KErrInUse, TheFs.Delete(endFileName));
   342 
   343 	test.Next(_L("Unclamp and Delete"));
   344 	test_KErrNone( fileClamp.Close(TheFs));
   345 	test_KErrNone( TheFs.Delete(endFileName));
   346 	
   347 	
   348 	}
   349 
   350 
   351 //
   352 // ParseCommandLine reads the arguments and sets globals accordingly.
   353 //
   354 
   355 TInt ParseCommandLine()
   356 	{
   357 	TBuf<32> args;
   358 	User::CommandLine(args);
   359 	TLex lex(args);
   360 	TInt err=KErrNone;
   361 	FOREVER
   362 		{
   363 		TPtrC token=lex.NextToken();
   364 		if(token.Length()!=0)
   365 			{
   366 			if ((token.Length()==1) || ((token.Length()==2) && (token[1]==':')))
   367 				{
   368 				TChar driveLetter = User::UpperCase(token[0]); 
   369 				if ((driveLetter>='A') && (driveLetter<='Z'))
   370 					DriveNumber=driveLetter - (TChar) 'A';
   371 				else 
   372 					err=KErrArgument;
   373 				}
   374 			else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?")))
   375 				{
   376 				test.Printf(_L("\nThis tests the loader's reaper, which is used in code paging to postpone deletions of paged code from disk.\n")); 
   377 				test.Printf(_L("\nIf no drive letter is supplied, then all suitable drives are checked.\n\n"));
   378 				err=KErrCancel;
   379 				}
   380 			else
   381 				err=KErrArgument;
   382 			}
   383 		else
   384 			break;
   385 		
   386 		if (err!=KErrNone)
   387 			{
   388 			if (err==KErrArgument)
   389 				test.Printf(_L("\nUnknown argument '%S'\n"), &token);
   390 			test.Printf(_L("\nUsage:  t_reaper [-h] [<driveletter>]\n\n"));
   391 			test.Getch();
   392 			return err;
   393 			}
   394 		}
   395 	return KErrNone;
   396 	}
   397 
   398 
   399 
   400 GLDEF_C TInt E32Main()
   401 	{
   402 	TInt i;
   403 	test.Title();
   404 	
   405 	if (ParseCommandLine())
   406 		return KErrNone;
   407 	
   408 	TheFs.Connect();
   409 	
   410 	TUint32 memModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
   411 	TUint32 pagingPolicy = E32Loader::PagingPolicy();
   412 	if((memModelAttributes&EMemModelAttrCodePaging)==0 || pagingPolicy==EKernelConfigCodePagingPolicyNoPaging)
   413 		{
   414 		test.Start(_L("TESTS NOT RUN - Code paging not enabled on system."));
   415 		test.End();
   416 		return KErrNone;
   417 		}
   418 
   419 	test.Start(_L("Loader Reaper/Clamp Tests"));
   420 	
   421 	// Turn off evil lazy dll unloading
   422 	RLoader l;
   423 	test(l.Connect()==KErrNone);
   424 	test(l.CancelLazyDllUnload()==KErrNone);
   425 	l.Close();
   426 
   427 	GetSupportedDrives();
   428 	test_Compare(gNumSupportedDrives,>,0);
   429 	test_KErrNone( Loader.Connect());
   430 	test_KErrNone( Loader.CancelLazyDllUnload());
   431 	
   432 	for (i=0;i<gNumSupportedDrives;i++)
   433 		{
   434 		if ((DriveNumber==-1) || (DriveNumber== (TInt) (SupportedDrives[i].iDriveLetter - (TChar) 'A')))
   435 			{
   436 			test.Printf(_L("Testing drive: %c\n"),(TInt) SupportedDrives[i].iDriveLetter);
   437 			if (!(SupportedDrives[i].iDriveInfo.iMediaAtt&KMediaAttWriteProtected))
   438 				{
   439 				TUint8 drive = SupportedDrives[i].iDriveLetter;
   440 				BasicTest(drive);
   441 				TestDlls(drive);
   442 				}
   443 			}
   444 				
   445 		}
   446 		
   447 	Loader.Close();
   448 	TheFs.Close();
   449 	
   450 	test.End();
   451 	
   452 	return KErrNone;
   453 	}