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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\demandpaging\t_reaper.cpp
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.
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.
35 //! @SYMTestCaseID KBASE-T_REAPER-0330
38 //! @SYMTestCaseDesc Demand Paging Reaper.
39 //! @SYMTestActions 001 Loader Reaper/Clamp Tests
40 //! @SYMTestExpectedResults All tests should pass.
41 //! @SYMTestPriority High
42 //! @SYMTestStatus Implemented
44 #define __E32TEST_EXTENSION__
52 TBool Verbose = EFalse;
57 class TPagingDriveInfo
61 TDriveInfo iDriveInfo;
64 RArray<TPagingDriveInfo> SupportedDrives;
65 TInt gNumSupportedDrives = 0;
68 LOCAL_D RTest test(_L("T_reaper"));
70 _LIT(KFilePath,":\\sys\\bin\\test.txt");
72 _LIT(KSysPath,"z:\\sys\\bin\\");
73 _LIT(KPathDel,":\\sys\\del\\");
74 _LIT(KDllFile,"t_reaper_test_dll.dll");
75 const TInt KLibNameLength = 50;
77 void CopyDll(const TDesC& aSourceName, const TDesC& aDestName)
79 const TInt KBufferSize = 3333;
80 TBuf8<KBufferSize> buffer;
83 test.Printf(_L(" copying %S to %S\n"), &aSourceName, &aDestName);
85 TInt r = TheFs.MkDirAll(aDestName);
86 test_Assert(r == KErrNone || r == KErrAlreadyExists, test.Printf(_L("MkDirAll returned %d\n"),r));
88 test_KErrNone(in.Open(TheFs, aSourceName, EFileRead));
89 test_KErrNone(out.Replace(TheFs, aDestName, EFileWrite));
92 test_KErrNone(in.Size(size));
96 test_KErrNone(in.Read(buffer));
97 test_KErrNone(out.Write(buffer));
98 pos += buffer.Length();
105 void CopyDllToDrive(const TDesC& aSourceName, TUint8 aDrive, TBuf<KLibNameLength>& aDestName)
107 TBuf<KLibNameLength> sourceName;
109 sourceName.Append(aSourceName);
111 aDestName.Append(aSourceName);
112 aDestName[0] = aDrive;
113 CopyDll(sourceName, aDestName);
116 static void CreateTestFile(const TDesC& aTestFile)
118 Create an empty file with the supplied name. This function is used
119 to create file which can be deleted with RLoader::Delete.
121 @param aFs Open file server session.
122 @param aTestFile The test file's name.
126 TheFs.MkDirAll(aTestFile);
128 r = f.Replace(TheFs, aTestFile, EFileWrite | EFileStream | EFileShareExclusive);
130 TBuf<256> buf(_L("Space is big, I mean its really big.\n"));
131 TPtrC8 pBuf((TUint8*)&buf);
137 // Get the list of pageable drives
138 void GetSupportedDrives()
141 TBuf<256> fileSystemName;
142 TDriveList driveList;
143 TDriveInfo driveInfo;
145 TInt r = TheFs.DriveList(driveList);
148 TBool NandPageableMediaFound = EFalse;
150 for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
152 if(!driveList[drvNum])
153 continue; //-- skip unexisting drive
155 test_KErrNone( TheFs.Drive(driveInfo, drvNum) );
156 test_KErrNone( TheFs.DriveToChar(drvNum, ch) );
157 test_KErrNone( TheFs.FileSystemName(fileSystemName, drvNum) );
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);
163 if ((driveInfo.iDriveAtt & KDriveAttPageable) && (driveInfo.iType == EMediaNANDFlash))
164 NandPageableMediaFound = ETrue;
166 TBool pageable = EFalse;
167 if (driveInfo.iDriveAtt & KDriveAttPageable)
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())
175 if (NandPageableMediaFound)
177 driveInfo.iMediaAtt|=KMediaAttWriteProtected;
181 TPagingDriveInfo pagingDriveInfo;
182 pagingDriveInfo.iDriveLetter = ch;
183 pagingDriveInfo.iDriveInfo = driveInfo;
186 test_KErrNone( SupportedDrives.Append(pagingDriveInfo) );
188 test.Printf(_L("Drive %c supports paging\n"), (TInt) pagingDriveInfo.iDriveLetter);
189 gNumSupportedDrives++;
196 TInt FindDeletedFile(TUint8 aDrive, TDes& aFile, const TDesC& aExcludedFile=KNullDesC)
200 _LIT(KSearchPathDel,"?:\\sys\\del\\*");
202 delPath = KSearchPathDel;
207 CTrapCleanup* c = CTrapCleanup::New();
208 TInt r = TheFs.GetDir(delPath,KEntryAttMatchExclude | KEntryAttDir ,ESortNone,dir);
210 if(r==KErrPathNotFound)
211 return 0; // no files
214 test.Printf(_L("Files: %d\n"),dir->Count() );
215 TInt count = dir->Count();
217 for (TInt i=count-1;i>=0;i--)
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)
236 void TestDlls(TUint8 aDrive)
239 TBuf<KLibNameLength> libName;
240 TBuf<KLibNameLength> delName;
241 TBuf<KLibNameLength> delName2;
242 TBuf<KLibNameLength> libName2;
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
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));
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
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));
279 test.Next(_L("Check file deleted on close"));
280 CLOSE_AND_WAIT(library);
281 test_Equal(KErrNotFound, TheFs.Entry(delName,e));
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
290 test.Printf(_L("Load a Secord Copy\n"));
291 CopyDllToDrive(KDllFile,aDrive,libName);
294 test_KErrNone( TheFs.Rename(libName,libName2));
295 test_KErrNone( library2.Load(libName2));
296 test_KErrNone( TheFs.Rename(libName2,libName));
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
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));
311 void BasicTest(TUint8 aDrive)
313 TBuf<256> startFileName;
314 TBuf<256> endFileName;
316 RFileClamp fileClamp;
318 startFileName.Append((TChar) aDrive);
319 startFileName+=KFilePath;
322 CreateTestFile(startFileName);
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));
328 test.Next(_L("Try deleteing file while Clamped and Open"));
329 test_KErrNone( fileClamp.Clamp(file));
330 test_Equal(KErrInUse, Loader.Delete(startFileName));
332 test.Next(_L("Try deleteing while Clamped"));
334 test_Equal(0, FindDeletedFile(aDrive,endFileName)); // check no files in sys/del
335 test_KErrNone( Loader.Delete(startFileName));
337 test.Next(_L("Check moved in sys/del"));
338 test_Equal(1, FindDeletedFile(aDrive,endFileName)); // check one file in sys/del
340 test.Next(_L("Check Can't delete"));
341 test_Equal(KErrInUse, TheFs.Delete(endFileName));
343 test.Next(_L("Unclamp and Delete"));
344 test_KErrNone( fileClamp.Close(TheFs));
345 test_KErrNone( TheFs.Delete(endFileName));
352 // ParseCommandLine reads the arguments and sets globals accordingly.
355 TInt ParseCommandLine()
358 User::CommandLine(args);
363 TPtrC token=lex.NextToken();
364 if(token.Length()!=0)
366 if ((token.Length()==1) || ((token.Length()==2) && (token[1]==':')))
368 TChar driveLetter = User::UpperCase(token[0]);
369 if ((driveLetter>='A') && (driveLetter<='Z'))
370 DriveNumber=driveLetter - (TChar) 'A';
374 else if ((token==_L("help")) || (token==_L("-h")) || (token==_L("-?")))
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"));
388 if (err==KErrArgument)
389 test.Printf(_L("\nUnknown argument '%S'\n"), &token);
390 test.Printf(_L("\nUsage: t_reaper [-h] [<driveletter>]\n\n"));
400 GLDEF_C TInt E32Main()
405 if (ParseCommandLine())
410 TUint32 memModelAttributes=UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
411 TUint32 pagingPolicy = E32Loader::PagingPolicy();
412 if((memModelAttributes&EMemModelAttrCodePaging)==0 || pagingPolicy==EKernelConfigCodePagingPolicyNoPaging)
414 test.Start(_L("TESTS NOT RUN - Code paging not enabled on system."));
419 test.Start(_L("Loader Reaper/Clamp Tests"));
421 // Turn off evil lazy dll unloading
423 test(l.Connect()==KErrNone);
424 test(l.CancelLazyDllUnload()==KErrNone);
427 GetSupportedDrives();
428 test_Compare(gNumSupportedDrives,>,0);
429 test_KErrNone( Loader.Connect());
430 test_KErrNone( Loader.CancelLazyDllUnload());
432 for (i=0;i<gNumSupportedDrives;i++)
434 if ((DriveNumber==-1) || (DriveNumber== (TInt) (SupportedDrives[i].iDriveLetter - (TChar) 'A')))
436 test.Printf(_L("Testing drive: %c\n"),(TInt) SupportedDrives[i].iDriveLetter);
437 if (!(SupportedDrives[i].iDriveInfo.iMediaAtt&KMediaAttWriteProtected))
439 TUint8 drive = SupportedDrives[i].iDriveLetter;