1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/demandpaging/t_reaper.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,453 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32test\demandpaging\t_reaper.cpp
1.18 +//
1.19 +// Suite of tests for the Reaper, the reaper is used to clean up files
1.20 +// which were deleted whilst in use, the delete is delayed until the
1.21 +// files are no longer in use and then completed by the reaper.
1.22 +//
1.23 +// 001 Loader Reaper/Clamp Tests
1.24 +// 002 Try deleteing file while Open
1.25 +// 003 Try deleteing file while Clamped and Open
1.26 +// 004 Try deleteing while Clamped
1.27 +// 005 Check moved in sys/del
1.28 +// 006 Check Can't delete
1.29 +// 007 Unclamp and Delete
1.30 +// 008 Copy DLL to drive and delete
1.31 +// 009 Copy DLL, Load, close and RFs::delete
1.32 +// 010 Copy DLL, Load, close and Loader::delete
1.33 +// 011 Copy DLL to drive, load and delete
1.34 +// 012 Check file deleted on close
1.35 +// 013 Try deleting something of the same name twice while loaded.
1.36 +//
1.37 +
1.38 +//! @SYMTestCaseID KBASE-T_REAPER-0330
1.39 +//! @SYMTestType UT
1.40 +//! @SYMPREQ PREQ1110
1.41 +//! @SYMTestCaseDesc Demand Paging Reaper.
1.42 +//! @SYMTestActions 001 Loader Reaper/Clamp Tests
1.43 +//! @SYMTestExpectedResults All tests should pass.
1.44 +//! @SYMTestPriority High
1.45 +//! @SYMTestStatus Implemented
1.46 +
1.47 +#define __E32TEST_EXTENSION__
1.48 +#include <e32test.h>
1.49 +#include <e32svr.h>
1.50 +#include <f32file.h>
1.51 +#include <e32ldr.h>
1.52 +#include <u32hal.h>
1.53 +#include "u32std.h"
1.54 +
1.55 +TBool Verbose = EFalse;
1.56 +RFs TheFs;
1.57 +RLoader Loader;
1.58 +TInt DriveNumber=-1;
1.59 +
1.60 +class TPagingDriveInfo
1.61 + {
1.62 +public:
1.63 + TChar iDriveLetter;
1.64 + TDriveInfo iDriveInfo;
1.65 + };
1.66 +
1.67 +RArray<TPagingDriveInfo> SupportedDrives;
1.68 +TInt gNumSupportedDrives = 0;
1.69 +
1.70 +
1.71 +LOCAL_D RTest test(_L("T_reaper"));
1.72 +
1.73 +_LIT(KFilePath,":\\sys\\bin\\test.txt");
1.74 +
1.75 +_LIT(KSysPath,"z:\\sys\\bin\\");
1.76 +_LIT(KPathDel,":\\sys\\del\\");
1.77 +_LIT(KDllFile,"t_reaper_test_dll.dll");
1.78 +const TInt KLibNameLength = 50;
1.79 +
1.80 +void CopyDll(const TDesC& aSourceName, const TDesC& aDestName)
1.81 + {
1.82 + const TInt KBufferSize = 3333;
1.83 + TBuf8<KBufferSize> buffer;
1.84 + RFile in, out;
1.85 +
1.86 + test.Printf(_L(" copying %S to %S\n"), &aSourceName, &aDestName);
1.87 +
1.88 + TInt r = TheFs.MkDirAll(aDestName);
1.89 + test_Assert(r == KErrNone || r == KErrAlreadyExists, test.Printf(_L("MkDirAll returned %d\n"),r));
1.90 +
1.91 + test_KErrNone(in.Open(TheFs, aSourceName, EFileRead));
1.92 + test_KErrNone(out.Replace(TheFs, aDestName, EFileWrite));
1.93 +
1.94 + TInt size;
1.95 + test_KErrNone(in.Size(size));
1.96 + TInt pos = 0;
1.97 + while (pos < size)
1.98 + {
1.99 + test_KErrNone(in.Read(buffer));
1.100 + test_KErrNone(out.Write(buffer));
1.101 + pos += buffer.Length();
1.102 + }
1.103 +
1.104 + in.Close();
1.105 + out.Close();
1.106 + }
1.107 +
1.108 +void CopyDllToDrive(const TDesC& aSourceName, TUint8 aDrive, TBuf<KLibNameLength>& aDestName)
1.109 + {
1.110 + TBuf<KLibNameLength> sourceName;
1.111 + sourceName=KSysPath;
1.112 + sourceName.Append(aSourceName);
1.113 + aDestName=KSysPath;
1.114 + aDestName.Append(aSourceName);
1.115 + aDestName[0] = aDrive;
1.116 + CopyDll(sourceName, aDestName);
1.117 + }
1.118 +
1.119 +static void CreateTestFile(const TDesC& aTestFile)
1.120 +/**
1.121 + Create an empty file with the supplied name. This function is used
1.122 + to create file which can be deleted with RLoader::Delete.
1.123 +
1.124 + @param aFs Open file server session.
1.125 + @param aTestFile The test file's name.
1.126 + */
1.127 + {
1.128 + TInt r;
1.129 + TheFs.MkDirAll(aTestFile);
1.130 + RFile f;
1.131 + r = f.Replace(TheFs, aTestFile, EFileWrite | EFileStream | EFileShareExclusive);
1.132 + test_KErrNone(r);
1.133 + TBuf<256> buf(_L("Space is big, I mean its really big.\n"));
1.134 + TPtrC8 pBuf((TUint8*)&buf);
1.135 + f.Write(pBuf);
1.136 + f.Flush();
1.137 + f.Close();
1.138 + }
1.139 +
1.140 +// Get the list of pageable drives
1.141 +void GetSupportedDrives()
1.142 + {
1.143 + TChar ch;
1.144 + TBuf<256> fileSystemName;
1.145 + TDriveList driveList;
1.146 + TDriveInfo driveInfo;
1.147 +
1.148 + TInt r = TheFs.DriveList(driveList);
1.149 + test_KErrNone(r);
1.150 +
1.151 + TBool NandPageableMediaFound = EFalse;
1.152 +
1.153 + for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
1.154 + {
1.155 + if(!driveList[drvNum])
1.156 + continue; //-- skip unexisting drive
1.157 +
1.158 + test_KErrNone( TheFs.Drive(driveInfo, drvNum) );
1.159 + test_KErrNone( TheFs.DriveToChar(drvNum, ch) );
1.160 + test_KErrNone( TheFs.FileSystemName(fileSystemName, drvNum) );
1.161 +
1.162 + if (Verbose)
1.163 + test.Printf(_L("GetSupportedDrives, Drive %c iType %d iDriveAtt %08x iMediaAtt %08X, fileSystemName %S\n"),
1.164 + (TInt) ch, driveInfo.iType, driveInfo.iDriveAtt, driveInfo.iMediaAtt, &fileSystemName);
1.165 +
1.166 + if ((driveInfo.iDriveAtt & KDriveAttPageable) && (driveInfo.iType == EMediaNANDFlash))
1.167 + NandPageableMediaFound = ETrue;
1.168 +
1.169 + TBool pageable = EFalse;
1.170 + if (driveInfo.iDriveAtt & KDriveAttPageable)
1.171 + pageable = ETrue;
1.172 +
1.173 + // If we've already found a pageable NAND drive, then assume the Z: drive is pageable too
1.174 + // if it's got a composite file system (fudge)
1.175 + _LIT(KCompositeName,"Composite");
1.176 + if (fileSystemName == KCompositeName())
1.177 + {
1.178 + if (NandPageableMediaFound)
1.179 + pageable = ETrue;
1.180 + driveInfo.iMediaAtt|=KMediaAttWriteProtected;
1.181 + }
1.182 + if (pageable)
1.183 + {
1.184 + TPagingDriveInfo pagingDriveInfo;
1.185 + pagingDriveInfo.iDriveLetter = ch;
1.186 + pagingDriveInfo.iDriveInfo = driveInfo;
1.187 +
1.188 +
1.189 + test_KErrNone( SupportedDrives.Append(pagingDriveInfo) );
1.190 + if (Verbose)
1.191 + test.Printf(_L("Drive %c supports paging\n"), (TInt) pagingDriveInfo.iDriveLetter);
1.192 + gNumSupportedDrives++;
1.193 + }
1.194 + }
1.195 + }
1.196 +
1.197 +
1.198 +
1.199 +TInt FindDeletedFile(TUint8 aDrive, TDes& aFile, const TDesC& aExcludedFile=KNullDesC)
1.200 + {
1.201 + aFile.Zero();
1.202 +
1.203 + _LIT(KSearchPathDel,"?:\\sys\\del\\*");
1.204 + TBuf<13> delPath;
1.205 + delPath = KSearchPathDel;
1.206 + delPath[0] = aDrive;
1.207 +
1.208 + CDir* dir=NULL;
1.209 +
1.210 + CTrapCleanup* c = CTrapCleanup::New();
1.211 + TInt r = TheFs.GetDir(delPath,KEntryAttMatchExclude | KEntryAttDir ,ESortNone,dir);
1.212 + delete c;
1.213 + if(r==KErrPathNotFound)
1.214 + return 0; // no files
1.215 + test_KErrNone(r);
1.216 +
1.217 + test.Printf(_L("Files: %d\n"),dir->Count() );
1.218 + TInt count = dir->Count();
1.219 + TBool found = false;
1.220 + for (TInt i=count-1;i>=0;i--)
1.221 + {
1.222 + TBuf<KLibNameLength> tempPath;
1.223 + tempPath.Append(aDrive);
1.224 + tempPath.Append(KPathDel);
1.225 + tempPath.Append((*dir)[i].iName);
1.226 + test.Printf(_L("%S\n"), &tempPath);
1.227 + if(!found && tempPath.CompareF(aExcludedFile)!=0)
1.228 + {
1.229 + found = true;
1.230 + aFile = tempPath;
1.231 + }
1.232 + }
1.233 +
1.234 + delete dir;
1.235 + return count;
1.236 + }
1.237 +
1.238 +
1.239 +void TestDlls(TUint8 aDrive)
1.240 + {
1.241 + TEntry e;
1.242 + TBuf<KLibNameLength> libName;
1.243 + TBuf<KLibNameLength> delName;
1.244 + TBuf<KLibNameLength> delName2;
1.245 + TBuf<KLibNameLength> libName2;
1.246 +
1.247 + RLibrary library;
1.248 + RLibrary library2;
1.249 +
1.250 + test.Next(_L("Copy DLL to drive and delete"));
1.251 + CopyDllToDrive(KDllFile,aDrive,libName);
1.252 + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
1.253 + test_KErrNone(Loader.Delete(libName));
1.254 + test_Equal(KErrNotFound, TheFs.Entry(libName,e));
1.255 + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
1.256 +
1.257 + test.Next(_L("Copy DLL, Load, close and RFs::delete"));
1.258 + CopyDllToDrive(KDllFile,aDrive,libName);
1.259 + test_KErrNone( library.Load(libName));
1.260 + test_Equal(KErrInUse, TheFs.Delete(libName));
1.261 + CLOSE_AND_WAIT(library);
1.262 + test_KErrNone( TheFs.Delete(libName));
1.263 + test_Equal(KErrNotFound, TheFs.Entry(libName,e));
1.264 +
1.265 + test.Next(_L("Copy DLL, Load, close and Loader::delete"));
1.266 + CopyDllToDrive(KDllFile,aDrive,libName);
1.267 + test_KErrNone( library.Load(libName));
1.268 + CLOSE_AND_WAIT(library);
1.269 + test_KErrNone( Loader.Delete(libName));
1.270 + test_Equal(KErrNotFound, TheFs.Entry(libName,e));
1.271 + test_Equal(0, FindDeletedFile(aDrive,delName)); // check no files in sys/del
1.272 +
1.273 + test.Next(_L("Copy DLL to drive, load and delete"));
1.274 + CopyDllToDrive(KDllFile,aDrive,libName);
1.275 + test_KErrNone( library.Load(libName));
1.276 + test_Equal(KErrInUse, TheFs.Delete(libName));
1.277 + test_KErrNone( Loader.Delete(libName));
1.278 + test_Equal(KErrNotFound, TheFs.Entry(libName,e));
1.279 + test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file
1.280 + test_Equal(KErrInUse, TheFs.Delete(delName));
1.281 +
1.282 + test.Next(_L("Check file deleted on close"));
1.283 + CLOSE_AND_WAIT(library);
1.284 + test_Equal(KErrNotFound, TheFs.Entry(delName,e));
1.285 +
1.286 + test.Next(_L("Try deleting something of the same name twice while loaded."));
1.287 + CopyDllToDrive(KDllFile,aDrive,libName);
1.288 + test_KErrNone( library.Load(libName));
1.289 + test_KErrNone( Loader.Delete(libName));
1.290 + test_Equal(KErrNotFound, TheFs.Entry(libName,e));
1.291 + test_Equal(1, FindDeletedFile(aDrive,delName)); // get name of 'deleted' file
1.292 +
1.293 + test.Printf(_L("Load a Secord Copy\n"));
1.294 + CopyDllToDrive(KDllFile,aDrive,libName);
1.295 + libName2=libName;
1.296 + libName2[27]='2';
1.297 + test_KErrNone( TheFs.Rename(libName,libName2));
1.298 + test_KErrNone( library2.Load(libName2));
1.299 + test_KErrNone( TheFs.Rename(libName2,libName));
1.300 +
1.301 + test.Printf(_L("Try and delete second copy\n"));
1.302 + test_KErrNone( Loader.Delete(libName));
1.303 + test_Equal(2, FindDeletedFile(aDrive,delName2,delName)); // get name of second 'deleted' file
1.304 +
1.305 + test.Printf(_L("Now close and watch deletions\n"));
1.306 + CLOSE_AND_WAIT(library);
1.307 + test_Equal(KErrNotFound, TheFs.Entry(delName,e));
1.308 + test_KErrNone( TheFs.Entry(delName2,e));
1.309 + CLOSE_AND_WAIT(library2);
1.310 + test_Equal(KErrNotFound, TheFs.Entry(delName2,e));
1.311 + }
1.312 +
1.313 +
1.314 +void BasicTest(TUint8 aDrive)
1.315 + {
1.316 + TBuf<256> startFileName;
1.317 + TBuf<256> endFileName;
1.318 + RFile file;
1.319 + RFileClamp fileClamp;
1.320 +
1.321 + startFileName.Append((TChar) aDrive);
1.322 + startFileName+=KFilePath;
1.323 +
1.324 +
1.325 + CreateTestFile(startFileName);
1.326 +
1.327 + test.Next(_L("Try deleteing file while Open"));
1.328 + test_KErrNone( file.Open(TheFs,startFileName,EFileShareExclusive|EFileWrite));
1.329 + test_Equal(KErrInUse, Loader.Delete(startFileName));
1.330 +
1.331 + test.Next(_L("Try deleteing file while Clamped and Open"));
1.332 + test_KErrNone( fileClamp.Clamp(file));
1.333 + test_Equal(KErrInUse, Loader.Delete(startFileName));
1.334 +
1.335 + test.Next(_L("Try deleteing while Clamped"));
1.336 + file.Close();
1.337 + test_Equal(0, FindDeletedFile(aDrive,endFileName)); // check no files in sys/del
1.338 + test_KErrNone( Loader.Delete(startFileName));
1.339 +
1.340 + test.Next(_L("Check moved in sys/del"));
1.341 + test_Equal(1, FindDeletedFile(aDrive,endFileName)); // check one file in sys/del
1.342 +
1.343 + test.Next(_L("Check Can't delete"));
1.344 + test_Equal(KErrInUse, TheFs.Delete(endFileName));
1.345 +
1.346 + test.Next(_L("Unclamp and Delete"));
1.347 + test_KErrNone( fileClamp.Close(TheFs));
1.348 + test_KErrNone( TheFs.Delete(endFileName));
1.349 +
1.350 +
1.351 + }
1.352 +
1.353 +
1.354 +//
1.355 +// ParseCommandLine reads the arguments and sets globals accordingly.
1.356 +//
1.357 +
1.358 +TInt ParseCommandLine()
1.359 + {
1.360 + TBuf<32> args;
1.361 + User::CommandLine(args);
1.362 + TLex lex(args);
1.363 + TInt err=KErrNone;
1.364 + FOREVER
1.365 + {
1.366 + TPtrC token=lex.NextToken();
1.367 + if(token.Length()!=0)
1.368 + {
1.369 + if ((token.Length()==1) || ((token.Length()==2) && (token[1]==':')))
1.370 + {
1.371 + TChar driveLetter = User::UpperCase(token[0]);
1.372 + if ((driveLetter>='A') && (driveLetter<='Z'))
1.373 + DriveNumber=driveLetter - (TChar) 'A';
1.374 + else
1.375 + err=KErrArgument;
1.376 + }
1.377 + else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?")))
1.378 + {
1.379 + test.Printf(_L("\nThis tests the loader's reaper, which is used in code paging to postpone deletions of paged code from disk.\n"));
1.380 + test.Printf(_L("\nIf no drive letter is supplied, then all suitable drives are checked.\n\n"));
1.381 + err=KErrCancel;
1.382 + }
1.383 + else
1.384 + err=KErrArgument;
1.385 + }
1.386 + else
1.387 + break;
1.388 +
1.389 + if (err!=KErrNone)
1.390 + {
1.391 + if (err==KErrArgument)
1.392 + test.Printf(_L("\nUnknown argument '%S'\n"), &token);
1.393 + test.Printf(_L("\nUsage: t_reaper [-h] [<driveletter>]\n\n"));
1.394 + test.Getch();
1.395 + return err;
1.396 + }
1.397 + }
1.398 + return KErrNone;
1.399 + }
1.400 +
1.401 +
1.402 +
1.403 +GLDEF_C TInt E32Main()
1.404 + {
1.405 + TInt i;
1.406 + test.Title();
1.407 +
1.408 + if (ParseCommandLine())
1.409 + return KErrNone;
1.410 +
1.411 + TheFs.Connect();
1.412 +
1.413 + TUint32 memModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
1.414 + TUint32 pagingPolicy = E32Loader::PagingPolicy();
1.415 + if((memModelAttributes&EMemModelAttrCodePaging)==0 || pagingPolicy==EKernelConfigCodePagingPolicyNoPaging)
1.416 + {
1.417 + test.Start(_L("TESTS NOT RUN - Code paging not enabled on system."));
1.418 + test.End();
1.419 + return KErrNone;
1.420 + }
1.421 +
1.422 + test.Start(_L("Loader Reaper/Clamp Tests"));
1.423 +
1.424 + // Turn off evil lazy dll unloading
1.425 + RLoader l;
1.426 + test(l.Connect()==KErrNone);
1.427 + test(l.CancelLazyDllUnload()==KErrNone);
1.428 + l.Close();
1.429 +
1.430 + GetSupportedDrives();
1.431 + test_Compare(gNumSupportedDrives,>,0);
1.432 + test_KErrNone( Loader.Connect());
1.433 + test_KErrNone( Loader.CancelLazyDllUnload());
1.434 +
1.435 + for (i=0;i<gNumSupportedDrives;i++)
1.436 + {
1.437 + if ((DriveNumber==-1) || (DriveNumber== (TInt) (SupportedDrives[i].iDriveLetter - (TChar) 'A')))
1.438 + {
1.439 + test.Printf(_L("Testing drive: %c\n"),(TInt) SupportedDrives[i].iDriveLetter);
1.440 + if (!(SupportedDrives[i].iDriveInfo.iMediaAtt&KMediaAttWriteProtected))
1.441 + {
1.442 + TUint8 drive = SupportedDrives[i].iDriveLetter;
1.443 + BasicTest(drive);
1.444 + TestDlls(drive);
1.445 + }
1.446 + }
1.447 +
1.448 + }
1.449 +
1.450 + Loader.Close();
1.451 + TheFs.Close();
1.452 +
1.453 + test.End();
1.454 +
1.455 + return KErrNone;
1.456 + }