|
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_clamp.cpp |
|
15 // Test suite for file clamping, file clamping is used to prevent files |
|
16 // (exes or dlls) from being deleted whilst in use. |
|
17 // 002 GetDriveLetters() |
|
18 // 003 Test1() Basic clamp operation |
|
19 // 004 Test2() Invalid clamp requests |
|
20 // 005 Test3() Denied FS requests when file(s) are clamped |
|
21 // 006 Test3Operations() Test other RFile, RFs operations |
|
22 // 007 Test3Operations() Increase number of clamps to MY_N |
|
23 // 008 Test3Operations() Decrease number of clamps by MY_M |
|
24 // 009 Test3Operations() Increase number of clamps by MY_M |
|
25 // 010 TestDeferredDismount() Open and clamp file, register for dismount |
|
26 // notification, then issue dismount instruction. |
|
27 // 011 Test4() Clamp tests for non-writable file system |
|
28 // 012 Test5() Clamp requests on non-clamping file systems |
|
29 // |
|
30 // |
|
31 |
|
32 //! @SYMTestCaseID KBASE-T_CLAMP-0328 |
|
33 //! @SYMTestType UT |
|
34 //! @SYMPREQ PREQ1110 |
|
35 //! @SYMTestCaseDesc Demand Paging File Clamp tests |
|
36 //! @SYMTestActions 001 Starting T_CLAMP |
|
37 //! @SYMTestExpectedResults All tests should pass. |
|
38 //! @SYMTestPriority High |
|
39 //! @SYMTestStatus Implemented |
|
40 |
|
41 #define __E32TEST_EXTENSION__ |
|
42 |
|
43 #include <e32test.h> |
|
44 RTest test(_L("T_CLAMP")); |
|
45 |
|
46 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
47 |
|
48 #include <f32file.h> |
|
49 #include <f32dbg.h> |
|
50 RFs TheFs; |
|
51 |
|
52 _LIT(KFATName,"FAT"); |
|
53 //_LIT(KFAT32Name,"FAT32"); |
|
54 _LIT(KROFSName,"ROFS"); |
|
55 _LIT(KLFFSName,"LFFS"); |
|
56 _LIT(KCOMPName,"COMPOSITE"); // Z: name if Composite File System |
|
57 //#ifdef __WINS__ |
|
58 //_LIT(KROMName,"WIN32"); // Clamping is not supported for non-composite filing system on Z: |
|
59 //#else |
|
60 _LIT(KROMName,"ROM"); // Z: name if ROMFS (on hardware, not emulator) |
|
61 //#endif |
|
62 |
|
63 TChar NandFatDrv='?'; |
|
64 TChar RofsDrv='?'; |
|
65 TChar LffsDrv='?'; |
|
66 TChar CompDrv='?'; |
|
67 |
|
68 |
|
69 LOCAL_C void Test1() |
|
70 { |
|
71 // Basic clamp operation |
|
72 test.Next(_L("T_Clamp - Test1()")); |
|
73 |
|
74 TBuf<256> fileName; |
|
75 TBuf<256> buf(_L("buffer for file used")); |
|
76 |
|
77 fileName = _L("clampFile.tst"); |
|
78 RFile testFile; |
|
79 TInt r=testFile.Replace(TheFs,fileName,EFileWrite); |
|
80 test(r==KErrNone); |
|
81 TPtrC8 pBuf((TUint8*)&buf); |
|
82 testFile.Write(pBuf); |
|
83 testFile.Flush(); |
|
84 |
|
85 // Clamp file |
|
86 RFileClamp handle; |
|
87 r=handle.Clamp(testFile); |
|
88 test(r==KErrNone); |
|
89 TInt64 storedCookie_0=handle.iCookie[0]; |
|
90 TInt64 storedCookie_1=handle.iCookie[1]; |
|
91 |
|
92 // Try to clamp previously-clamped file |
|
93 RFileClamp handle1; |
|
94 r=handle1.Clamp(testFile); |
|
95 test(r==KErrNone); |
|
96 |
|
97 // Unclamp file |
|
98 r=handle.Close(TheFs); |
|
99 test (r==KErrNone); |
|
100 // Check cookie content has been re-initialised |
|
101 test((0==handle.iCookie[0])&&(0==handle.iCookie[1])); |
|
102 |
|
103 // Try to unclamp a file that is not clamped |
|
104 handle.iCookie[0]=storedCookie_0; |
|
105 handle.iCookie[1]=storedCookie_1; |
|
106 r=handle.Close(TheFs); |
|
107 test (r==KErrNotFound); |
|
108 |
|
109 // Check that attempting to unclamp with a zero-content cookie |
|
110 // yields no error |
|
111 handle.iCookie[0]=0; |
|
112 handle.iCookie[1]=0; |
|
113 r=handle.Close(TheFs); |
|
114 test (r==KErrNone); |
|
115 |
|
116 // Clamp the file (again) |
|
117 r=handle.Clamp(testFile); |
|
118 test(r==KErrNone); |
|
119 |
|
120 // Create and clamp a second file ... |
|
121 fileName = _L("clampFile2.tst"); |
|
122 RFile testFile2; |
|
123 r=testFile2.Replace(TheFs,fileName,EFileWrite); |
|
124 test(r==KErrNone); |
|
125 buf=_L("buffer for file 2"); |
|
126 testFile2.Write(pBuf); |
|
127 testFile2.Flush(); |
|
128 RFileClamp handle2; |
|
129 r=handle2.Clamp(testFile2); |
|
130 test(r==KErrNone); |
|
131 |
|
132 // Create and clamp a third file ... |
|
133 RFileClamp handle3; |
|
134 fileName = _L("clampFile3.tst"); |
|
135 RFile testFile3; |
|
136 r=testFile3.Replace(TheFs,fileName,EFileWrite); |
|
137 test(r==KErrNone); |
|
138 buf=_L("buffer for file 3"); |
|
139 testFile3.Write(pBuf); |
|
140 testFile3.Flush(); |
|
141 r=handle3.Clamp(testFile3); |
|
142 test(r==KErrNone); |
|
143 |
|
144 // Test can unclamp then reclamp first file |
|
145 // then repeat for the third file |
|
146 r=handle.Close(TheFs); |
|
147 test (r==KErrNone); |
|
148 r=handle.Clamp(testFile); |
|
149 test(r==KErrNone); |
|
150 r=handle3.Close(TheFs); |
|
151 test (r==KErrNone); |
|
152 r=handle3.Clamp(testFile3); |
|
153 test(r==KErrNone); |
|
154 |
|
155 // Tidy up |
|
156 r=handle.Close(TheFs); |
|
157 test (r==KErrNone); |
|
158 r=handle1.Close(TheFs); |
|
159 test (r==KErrNone); |
|
160 testFile.Close(); |
|
161 r=TheFs.Delete(_L("clampFile.tst")); |
|
162 test (r==KErrNone); |
|
163 |
|
164 r=handle2.Close(TheFs); |
|
165 test (r==KErrNone); |
|
166 testFile2.Close(); |
|
167 r=TheFs.Delete(_L("clampFile2.tst")); |
|
168 test (r==KErrNone); |
|
169 |
|
170 r=handle3.Close(TheFs); |
|
171 test (r==KErrNone); |
|
172 testFile3.Close(); |
|
173 r=TheFs.Delete(_L("clampFile3.tst")); |
|
174 test (r==KErrNone); |
|
175 } |
|
176 |
|
177 |
|
178 LOCAL_C void Test2() |
|
179 { |
|
180 // Invalid clamp requests |
|
181 test.Next(_L("T_Clamp - Test2()")); |
|
182 |
|
183 // Test attempt to clamp empty file is rejected |
|
184 RFileClamp handle4; |
|
185 TBuf<256> file4Name; |
|
186 file4Name = _L("clampFile4.tst"); |
|
187 RFile testFile4; |
|
188 TInt r=testFile4.Replace(TheFs,file4Name,EFileWrite); |
|
189 test(r==KErrNone); |
|
190 r=handle4.Clamp(testFile4); |
|
191 test(r==KErrEof); |
|
192 |
|
193 // Preparation for next test - create a valid clamp handle |
|
194 TBuf<256> buf4(_L("buffer for file 4")); |
|
195 TPtrC8 pBuf4((TUint8*)&buf4); |
|
196 testFile4.Write(pBuf4); |
|
197 testFile4.Flush(); |
|
198 r=handle4.Clamp(testFile4); |
|
199 test(r==KErrNone); |
|
200 |
|
201 // Try to unclamp non-existant file |
|
202 RFileClamp handle5; |
|
203 memcpy((TAny*)&handle5,(TAny*)&handle4,sizeof(RFileClamp)); |
|
204 handle5.iCookie[0] = MAKE_TINT64(-1,-1); // iCookie[0] holds the unique ID |
|
205 r=handle5.Close(TheFs); |
|
206 test (r==KErrNotFound); |
|
207 |
|
208 // Tidy up |
|
209 r=handle4.Close(TheFs); |
|
210 test (r==KErrNone); |
|
211 testFile4.Close(); |
|
212 r=TheFs.Delete(_L("clampFile4.tst")); |
|
213 test (r==KErrNone); |
|
214 } |
|
215 |
|
216 |
|
217 |
|
218 LOCAL_C void TestDeferredDismount(TDesC& aRoot, TDesC& aFileName, RFileClamp* handlePtr) |
|
219 { |
|
220 // Open and clamp file, register for dismount notification, then issue |
|
221 // dismount instruction. |
|
222 // Since there are no other clients registered for dismount notification, |
|
223 // this would normally lead too dismount being instigated. However, since |
|
224 // the file is clamped, dismount should be deferred |
|
225 test.Next(_L("T_Clamp - TestDeferredDismount()")); |
|
226 |
|
227 // File system details required for clean-up |
|
228 const TInt KMaxFileSystemNameLength=100; // Arbitrary length |
|
229 const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length |
|
230 TBuf<KMaxFileSystemNameLength> fsName; |
|
231 TBuf<KMaxFileSystemExtNameLength> fsExtName_0; |
|
232 TBuf<KMaxFileSystemExtNameLength> fsExtName_1; |
|
233 TBool fsExt0Present=EFalse; |
|
234 TBool fsExt1Present=EFalse; |
|
235 TInt driveNo, r; |
|
236 r=TheFs.CharToDrive(aRoot[0], driveNo); |
|
237 test(r==KErrNone); |
|
238 r=TheFs.FileSystemName(fsName, driveNo); |
|
239 test(r==KErrNone); |
|
240 r=TheFs.ExtensionName(fsExtName_0,driveNo,0); |
|
241 if(r==KErrNone) |
|
242 fsExt0Present=ETrue; |
|
243 r=TheFs.ExtensionName(fsExtName_1,driveNo,1); |
|
244 if(r==KErrNone) |
|
245 fsExt1Present=ETrue; |
|
246 |
|
247 // Create a file & write to it so that we can test whether dismounting works correctly with dirty data |
|
248 TDriveInfo driveInfo; |
|
249 test(TheFs.Drive(driveInfo, driveNo) == KErrNone); |
|
250 TFileName dirtyFileName(_L("dirtyFile.tst")); |
|
251 RFile dirtyFile; |
|
252 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
|
253 { |
|
254 r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite); |
|
255 test(r==KErrNone); |
|
256 r=dirtyFile.Write(_L8("My name is Michael Caine")); |
|
257 test(r==KErrNone); |
|
258 } |
|
259 |
|
260 |
|
261 RFile testFile; |
|
262 r=testFile.Open(TheFs,aFileName,EFileRead); |
|
263 test(r==KErrNone); |
|
264 r=handlePtr->Clamp(testFile); |
|
265 test(r==KErrNone); |
|
266 testFile.Close(); |
|
267 |
|
268 TRequestStatus clientNotify=KErrNone; |
|
269 TRequestStatus clientDismount=KErrNone; |
|
270 TheFs.NotifyDismount(driveNo, clientNotify); // Register for notification |
|
271 test(clientNotify == KRequestPending); |
|
272 |
|
273 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
|
274 test(clientDismount == KRequestPending); |
|
275 User::WaitForRequest(clientNotify); |
|
276 test(clientNotify == KErrNone); |
|
277 |
|
278 r=TheFs.AllowDismount(driveNo); // Respond to dismount notification |
|
279 test(r == KErrNone); |
|
280 test(clientDismount == KRequestPending); // Dismount is deferred |
|
281 |
|
282 // |
|
283 // Now unclamp the file, and check that the deferred dismount is performed. |
|
284 r=handlePtr->Close(TheFs); |
|
285 test(r==KErrNone); |
|
286 User::WaitForRequest(clientDismount); |
|
287 test(clientDismount == KErrNone); |
|
288 |
|
289 // Try to write to the opened file: this should return KErrNotReady as there is no drive thread |
|
290 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
|
291 { |
|
292 r=dirtyFile.Write(_L8("My name isn't really Michael Caine")); |
|
293 test(r==KErrNotReady); |
|
294 } |
|
295 |
|
296 // Re-mount the file system |
|
297 if(fsExt0Present) |
|
298 { |
|
299 r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); |
|
300 test(r==KErrNone); |
|
301 } |
|
302 else if(fsExt1Present) // untested ! |
|
303 { |
|
304 r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); |
|
305 test(r==KErrNone); |
|
306 } |
|
307 else |
|
308 { |
|
309 r=TheFs.MountFileSystem(fsName,driveNo); |
|
310 test_KErrNone(r); |
|
311 } |
|
312 |
|
313 // create some more dirty data to verify that the file server can cope with the drive thread |
|
314 // having gone & come back again |
|
315 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
|
316 { |
|
317 r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish.")); |
|
318 test(r==KErrDisMounted); |
|
319 |
|
320 dirtyFile.Close(); |
|
321 r = TheFs.Delete(dirtyFileName); |
|
322 test(r == KErrNone); |
|
323 } |
|
324 |
|
325 // Issue a EFsDismountNotifyClients with no clients but with files clamped |
|
326 // & verify that the dismount request completes when clamps are removed |
|
327 r=testFile.Open(TheFs,aFileName,EFileRead); |
|
328 test(r==KErrNone); |
|
329 r=handlePtr->Clamp(testFile); |
|
330 test(r==KErrNone); |
|
331 testFile.Close(); |
|
332 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
|
333 |
|
334 test(clientDismount == KRequestPending); |
|
335 r=handlePtr->Close(TheFs); |
|
336 test(r==KErrNone); |
|
337 User::WaitForRequest(clientDismount); |
|
338 test(clientDismount == KErrNone); |
|
339 // Re-mount the file system again |
|
340 if(fsExt0Present) |
|
341 { |
|
342 r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); |
|
343 test(r==KErrNone); |
|
344 } |
|
345 else if(fsExt1Present) // untested ! |
|
346 { |
|
347 r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); |
|
348 test(r==KErrNone); |
|
349 } |
|
350 else |
|
351 { |
|
352 r=TheFs.MountFileSystem(fsName,driveNo); |
|
353 test_KErrNone(r); |
|
354 } |
|
355 |
|
356 |
|
357 // Issue a EFsDismountForceDismount with no clients but with files clamped |
|
358 // & verify that the dismount request completes when clamps are removed |
|
359 r=testFile.Open(TheFs,aFileName,EFileRead); |
|
360 test(r==KErrNone); |
|
361 r=handlePtr->Clamp(testFile); |
|
362 test(r==KErrNone); |
|
363 testFile.Close(); |
|
364 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountForceDismount); |
|
365 |
|
366 test(clientDismount == KRequestPending); |
|
367 r=handlePtr->Close(TheFs); |
|
368 test(r==KErrNone); |
|
369 User::WaitForRequest(clientDismount); |
|
370 test(clientDismount == KErrNone); |
|
371 // Re-mount the file system again |
|
372 if(fsExt0Present) |
|
373 { |
|
374 r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); |
|
375 test(r==KErrNone); |
|
376 } |
|
377 else if(fsExt1Present) // untested ! |
|
378 { |
|
379 r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); |
|
380 test(r==KErrNone); |
|
381 } |
|
382 else |
|
383 { |
|
384 r=TheFs.MountFileSystem(fsName,driveNo); |
|
385 test_KErrNone(r); |
|
386 } |
|
387 |
|
388 } |
|
389 |
|
390 |
|
391 |
|
392 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName) |
|
393 { |
|
394 test.Next(_L("T_Clamp - Test3Operations()")); |
|
395 // RFormat::Open |
|
396 #ifdef __WINS__ |
|
397 if (User::UpperCase(aRoot[0]) != 'C') |
|
398 #endif |
|
399 { |
|
400 TBuf<4> driveBuf=_L("?:\\"); |
|
401 driveBuf[0] = aRoot[0]; |
|
402 RFormat format; |
|
403 TInt count; |
|
404 TInt r=format.Open(TheFs,driveBuf,EFullFormat,count); |
|
405 test(r==KErrInUse); |
|
406 format.Close(); |
|
407 } |
|
408 |
|
409 // Dismount: synchronous requests |
|
410 // RFs::DismountFileSystem, RFs::SwapFileSystem |
|
411 const TInt KMaxFileSystemNameLength=100; // Arbitrary length |
|
412 TBuf<KMaxFileSystemNameLength> fileSysName; |
|
413 TInt driveNo, r; |
|
414 r=TheFs.CharToDrive(aRoot[0], driveNo); |
|
415 test(r==KErrNone); |
|
416 r=TheFs.FileSystemName(fileSysName,driveNo); |
|
417 test(r==KErrNone); |
|
418 |
|
419 r=TheFs.DismountFileSystem(fileSysName,driveNo); |
|
420 test(r==KErrInUse); |
|
421 |
|
422 r=TheFs.SwapFileSystem(fileSysName,fileSysName,driveNo); |
|
423 test(r==KErrInUse); |
|
424 |
|
425 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
426 // The cancellation of deferred dismounts requires controlIO |
|
427 // functionality available in debug versions of the code. |
|
428 |
|
429 // Dismount: asynchronous requests |
|
430 // RFs::NotifyDismount, RFs::AllowDismount |
|
431 const TInt KNumClients = 5; |
|
432 RFs clientFs[KNumClients]; |
|
433 TRequestStatus clientNotify[KNumClients]; |
|
434 TRequestStatus clientComplete; |
|
435 TInt i=0; |
|
436 for(i=0; i< KNumClients; i++) |
|
437 { |
|
438 r=clientFs[i].Connect(); |
|
439 test(r==KErrNone); |
|
440 } |
|
441 // Cancel any deferred dismount in preparation for the next test |
|
442 r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); |
|
443 test(r==KErrNone); |
|
444 |
|
445 // Use case 1: Orderly dismount |
|
446 // All clients register for dismount notification |
|
447 for(i=0; i< KNumClients; i++) |
|
448 { |
|
449 clientNotify[i] = KErrNone; |
|
450 clientFs[i].NotifyDismount(driveNo, clientNotify[i]); |
|
451 test(clientNotify[i] == KRequestPending); |
|
452 } |
|
453 // First client notifies intent to dismount |
|
454 clientComplete = KErrNone; |
|
455 clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); |
|
456 test(clientComplete == KRequestPending); |
|
457 // Check all clients have received the notification |
|
458 for(i=0; i< KNumClients; i++) |
|
459 { |
|
460 test(clientNotify[i] == KErrNone); |
|
461 } |
|
462 // All clients invoke AllowDismount |
|
463 for(i=0; i< KNumClients; i++) |
|
464 { |
|
465 r=clientFs[i].AllowDismount(driveNo); |
|
466 test(r==KErrNone); |
|
467 } |
|
468 // Dismount is deferred |
|
469 test(clientComplete == KRequestPending); |
|
470 |
|
471 |
|
472 // Cancel the deferred dismount in preparation for the next test |
|
473 clientFs[0].NotifyDismountCancel(clientComplete); |
|
474 test(clientComplete == KErrCancel); |
|
475 r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); |
|
476 test(r==KErrNone); |
|
477 clientComplete=KErrNone; // Re-initialise the TRequestStatus |
|
478 |
|
479 |
|
480 // Use case 2: Forced dismount |
|
481 // All clients register for dismount notification |
|
482 for(i=0; i< KNumClients; i++) |
|
483 { |
|
484 clientFs[i].NotifyDismount(driveNo, clientNotify[i]); |
|
485 test(clientNotify[i] == KRequestPending); |
|
486 } |
|
487 // First client notifies intent to dismount |
|
488 clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); |
|
489 test(clientComplete == KRequestPending); |
|
490 // Check all clients have received the notification |
|
491 for(i=0; i< KNumClients; i++) |
|
492 { |
|
493 test(clientNotify[i] == KErrNone); |
|
494 } |
|
495 // Not all other clients invoke AllowDismount |
|
496 for(i=0; i< KNumClients-1; i++) |
|
497 { |
|
498 clientFs[i].AllowDismount(driveNo); |
|
499 } |
|
500 // First client attempts forced dismount |
|
501 test(clientComplete == KRequestPending); |
|
502 clientFs[0].NotifyDismount(driveNo, clientComplete, EFsDismountForceDismount); |
|
503 // Dismount is deferred |
|
504 test(clientComplete == KRequestPending); |
|
505 |
|
506 // Cancel the deferred dismount in preparation for the next test |
|
507 // Also cancel the 'un-Allowed' notification request |
|
508 clientFs[0].NotifyDismountCancel(clientComplete); |
|
509 test(clientComplete == KErrCancel); |
|
510 r=TheFs.ControlIo(driveNo,KControlIoCancelDeferredDismount); |
|
511 test(r==KErrNone); |
|
512 clientComplete=KErrNone; // Re-initialise the TRequestStatus |
|
513 #endif |
|
514 |
|
515 // RFile::Open with EFileWrite |
|
516 RFile testFile; |
|
517 r=testFile.Open(TheFs,aFileName,EFileWrite|EFileShareReadersOrWriters); |
|
518 test(r==KErrInUse); |
|
519 |
|
520 // RFile::Replace |
|
521 RFile testFile2; |
|
522 r=testFile2.Replace(TheFs,aFileName,EFileRead); |
|
523 test(r==KErrInUse); |
|
524 testFile2.Close(); |
|
525 |
|
526 // RFile::Set - this should not be prevented by clamping |
|
527 r=testFile.Open(TheFs,aFileName,EFileRead|EFileShareAny); |
|
528 test(r == KErrNone); |
|
529 |
|
530 TTime origTime; |
|
531 TUint origAtt; |
|
532 r=testFile.Att(origAtt); |
|
533 test(r==KErrNone); |
|
534 r=testFile.Modified(origTime); |
|
535 test(r==KErrNone); |
|
536 |
|
537 TTime time; // Arbitrary value |
|
538 TUint setMask=0xA5A5&~KEntryAttReadOnly; // Not read-only, otherwise arbitrary value |
|
539 TUint clearMask=0x5A5A & KEntryAttReadOnly; // Not read-only, otherwise arbitrary value |
|
540 r=testFile.Set(time,setMask,clearMask); |
|
541 test(r==KErrNone); |
|
542 |
|
543 r=testFile.Set(origTime,origAtt,~origAtt); // restore original values |
|
544 test(r==KErrNone); |
|
545 testFile.Close(); |
|
546 |
|
547 // RFs::Rename - this should not be prevented by clamping |
|
548 r=TheFs.Rename(aFileName,_L("aDummyName")); |
|
549 test(r==KErrNone); |
|
550 r=TheFs.Rename(_L("aDummyName"),aFileName); // restore original name |
|
551 test(r==KErrNone); |
|
552 |
|
553 // RFs::Replace |
|
554 r=TheFs.Replace(aFileName,_L("aDummyName")); |
|
555 test(r==KErrInUse); |
|
556 |
|
557 // RFs::SetEntry - this should not be prevented by clamping |
|
558 r=TheFs.SetEntry(aFileName,time,setMask,clearMask); |
|
559 test(r==KErrNone); |
|
560 r=TheFs.SetEntry(aFileName,origTime,origAtt,~origAtt); // restore original values |
|
561 test(r==KErrNone); |
|
562 |
|
563 // RFs::Delete |
|
564 r=TheFs.Delete(aFileName); |
|
565 test(r==KErrInUse); |
|
566 |
|
567 // RRawDisk::Open (*** no longer required ***) |
|
568 } |
|
569 |
|
570 LOCAL_C void Test3(TDesC& aRoot) |
|
571 { |
|
572 // Denied FS requests when file(s) are clamped. |
|
573 test.Next(_L("T_Clamp - Test3()")); |
|
574 |
|
575 // Clamping is reference counted, so we need a test to check that |
|
576 // a file clamped N times cannot be modified until it has been unclamped N times. |
|
577 // Should also check |
|
578 // - Clamp N times |
|
579 // - Unclamp M times (M<N) |
|
580 // - Clamp M times. |
|
581 // - Unclamp N times |
|
582 |
|
583 #define MY_N 16 |
|
584 #define MY_M 12 |
|
585 |
|
586 // Create a file for use |
|
587 TBuf<256> fileName; |
|
588 TBuf<256> buf(_L("buffer for file used")); |
|
589 fileName = _L("clampFile.tst"); |
|
590 RFile testFile; |
|
591 TInt r=testFile.Replace(TheFs,fileName,EFileWrite); |
|
592 test(r==KErrNone); |
|
593 TPtrC8 pBuf((TUint8*)&buf); |
|
594 testFile.Write(pBuf); |
|
595 testFile.Flush(); |
|
596 // Close file,then re-open (to support clamping) in sharable mode |
|
597 // (to allow testing of RFile::Open with EFileWrite) |
|
598 testFile.Close(); |
|
599 r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); |
|
600 test(r==KErrNone); |
|
601 // Show, prior to clamping, that the file can be opened with EFileWrite |
|
602 RFile testFile2; |
|
603 r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); |
|
604 test(r==KErrNone); |
|
605 // Close the second RFile instance |
|
606 testFile2.Close(); |
|
607 |
|
608 // Clamp and unclamp a number of times, and invoke the |
|
609 // operations to test |
|
610 RFileClamp myHandles[MY_N]; |
|
611 RFileClamp *handlePtr = myHandles; |
|
612 TInt i = 0; |
|
613 |
|
614 // Clamp once |
|
615 r=handlePtr->Clamp(testFile); |
|
616 test(r==KErrNone); |
|
617 i++; |
|
618 |
|
619 // RFile::SetAtt - this should not be prevented by clamping |
|
620 TTime origTime; |
|
621 TUint origAtt; |
|
622 r=testFile.Att(origAtt); |
|
623 test(r==KErrNone); |
|
624 r=testFile.Modified(origTime); |
|
625 test(r==KErrNone); |
|
626 TTime time; // Arbitrary value |
|
627 TUint setMask=0xA5A5&~KEntryAttReadOnly; // Not read-only, otherwise arbitrary value |
|
628 TUint clearMask=0x5A5A & KEntryAttReadOnly; // Not read-only, otherwise arbitrary value |
|
629 r=testFile.Att(origAtt); |
|
630 test(r==KErrNone); |
|
631 r=testFile.SetAtt(setMask,clearMask); |
|
632 test(r==KErrNone); |
|
633 r=testFile.Set(origTime,origAtt,~origAtt); // restore original values |
|
634 test(r==KErrNone); |
|
635 |
|
636 // RFile::SetModified - this should not be prevented by clamping |
|
637 r=testFile.Modified(origTime); |
|
638 test(r==KErrNone); |
|
639 r=testFile.SetModified(time); |
|
640 test(r==KErrNone); |
|
641 r=testFile.SetModified(origTime); // restore original value |
|
642 test(r==KErrNone); |
|
643 |
|
644 // RFile::Rename - this should not be prevented by clamping |
|
645 // Need file to be opened in EFileShareExclusive sharing mode, |
|
646 // so close, unclamp, re-open appropriately and re-clamp |
|
647 testFile.Close(); |
|
648 r=handlePtr->Close(TheFs); |
|
649 test(r==KErrNone); |
|
650 i--; |
|
651 r=testFile.Open(TheFs,fileName,EFileWrite|EFileShareExclusive); |
|
652 test(r==KErrNone); |
|
653 r=handlePtr->Clamp(testFile); |
|
654 test(r==KErrNone); |
|
655 i++; |
|
656 r=testFile.Rename(_L("aDummyName")); |
|
657 test(r==KErrNone); |
|
658 r=testFile.Rename(fileName); |
|
659 test(r==KErrNone); |
|
660 |
|
661 // RFile::SetSize |
|
662 r=testFile.SetSize(1000); // Arbitrary value |
|
663 test(r==KErrInUse); |
|
664 |
|
665 // Test other RFile, RFs operations |
|
666 testFile.Close(); |
|
667 Test3Operations(aRoot,fileName); |
|
668 |
|
669 // Increase number of clamps to MY_N |
|
670 r=testFile.Open(TheFs,fileName,EFileRead); |
|
671 test(r==KErrNone); |
|
672 for(; i < MY_N; i++) |
|
673 { |
|
674 handlePtr++; |
|
675 r=handlePtr->Clamp(testFile); |
|
676 test(r==KErrNone); |
|
677 } |
|
678 testFile.Close(); |
|
679 Test3Operations(aRoot,fileName); |
|
680 |
|
681 // Decrease number of clamps by MY_M |
|
682 for(;i > (MY_N - MY_M); i--) |
|
683 { |
|
684 r=handlePtr->Close(TheFs); |
|
685 test(r==KErrNone); |
|
686 if(handlePtr!=myHandles) |
|
687 handlePtr--; |
|
688 else |
|
689 break; |
|
690 } |
|
691 Test3Operations(aRoot,fileName); |
|
692 |
|
693 // Increase number of clamps by MY_M |
|
694 r=testFile.Open(TheFs,fileName,EFileRead); |
|
695 test(r == KErrNone); |
|
696 TInt j=0; |
|
697 for(;j < MY_M; j++) |
|
698 { |
|
699 handlePtr++; |
|
700 r=handlePtr->Clamp(testFile); |
|
701 test(r==KErrNone); |
|
702 i++; |
|
703 } |
|
704 testFile.Close(); |
|
705 Test3Operations(aRoot,fileName); |
|
706 |
|
707 // Decrease number of clamps by MY_N |
|
708 for(;i > 0; i--) |
|
709 { |
|
710 r=handlePtr->Close(TheFs); |
|
711 test(r==KErrNone); |
|
712 if(handlePtr!=myHandles) |
|
713 handlePtr--; |
|
714 else |
|
715 break; |
|
716 } |
|
717 |
|
718 // Test deferred dismount - use next free handle |
|
719 TestDeferredDismount(aRoot,fileName,handlePtr); |
|
720 |
|
721 // Re-create the test directory |
|
722 r=TheFs.MkDirAll(aRoot); |
|
723 test(r==KErrNone || r== KErrAlreadyExists); |
|
724 TheFs.SetSessionPath(aRoot); |
|
725 |
|
726 // No clamps remain - prove RFile::Open with EFileWrite |
|
727 r=testFile2.Open(TheFs,fileName,EFileWrite|EFileShareReadersOrWriters); |
|
728 test(r==KErrNone); |
|
729 testFile2.Close(); |
|
730 |
|
731 // No clamps remain - prove that file can now be deleted |
|
732 r=TheFs.Delete(_L("clampFile.tst")); |
|
733 test (r==KErrNone); |
|
734 } |
|
735 |
|
736 |
|
737 LOCAL_C void Test4(TDesC& aRoot) |
|
738 { |
|
739 // Clamp tests for non-writable file system |
|
740 test.Next(_L("T_Clamp - Test4()")); |
|
741 |
|
742 // Tests are limited to clamp, unclamp and denied requests |
|
743 // when clamps are present. |
|
744 TBuf<256> pathName; |
|
745 #ifdef __WINS__ |
|
746 if((aRoot[0]=='Z')||(aRoot[0]=='z')) |
|
747 pathName=_L("clean.txt"); |
|
748 else |
|
749 pathName=_L("root.txt"); |
|
750 #else |
|
751 if((aRoot[0]=='Z')||(aRoot[0]=='z')) |
|
752 pathName=_L("UnicodeData.txt"); |
|
753 else |
|
754 pathName=_L("\\Test\\clamp.txt"); // For (non-composite) ROFS drive |
|
755 #endif |
|
756 RFile testFile; |
|
757 TInt r=testFile.Open(TheFs, pathName, EFileRead); |
|
758 test(r==KErrNone); |
|
759 |
|
760 // Clamp file |
|
761 RFileClamp handle; |
|
762 r=handle.Clamp(testFile); |
|
763 test(r==KErrNone); |
|
764 TInt64 storedCookie_0=handle.iCookie[0]; |
|
765 TInt64 storedCookie_1=handle.iCookie[1]; |
|
766 |
|
767 // Try to clamp previously-clamped file |
|
768 RFileClamp handle1; |
|
769 r=handle1.Clamp(testFile); |
|
770 test(r==KErrNone); |
|
771 |
|
772 // Unclamp file |
|
773 r=handle.Close(TheFs); |
|
774 test (r==KErrNone); |
|
775 // Check cookie content has been re-initialised |
|
776 test((0==handle.iCookie[0])&&(0==handle.iCookie[1])); |
|
777 |
|
778 // Try to unclamp a file that is not clamped |
|
779 handle.iCookie[0]=storedCookie_0; |
|
780 handle.iCookie[1]=storedCookie_1; |
|
781 r=handle.Close(TheFs); |
|
782 test (r==KErrNotFound); |
|
783 // Remove remaining clamp |
|
784 r=handle1.Close(TheFs); |
|
785 test (r==KErrNone); |
|
786 |
|
787 testFile.Close(); |
|
788 |
|
789 if((aRoot[0]!='Z')&&(aRoot[0]!='z')) // Can not dismount Z: |
|
790 TestDeferredDismount(aRoot,pathName,&handle); |
|
791 } |
|
792 |
|
793 |
|
794 LOCAL_C void Test5() |
|
795 { |
|
796 // Clamp requests on non-clamping file systems |
|
797 test.Next(_L("T_Clamp - Test5()")); |
|
798 |
|
799 TBuf<256> unsuppFile; |
|
800 unsuppFile = _L("unsuppFile.tst"); |
|
801 RFile testFile; |
|
802 TInt r=testFile.Replace(TheFs,unsuppFile,EFileWrite); |
|
803 test(r==KErrNone); |
|
804 |
|
805 // Try to clamp a file on a file system that does |
|
806 // not support clamping |
|
807 RFileClamp handle; |
|
808 r=handle.Clamp(testFile); |
|
809 test(r==KErrNotSupported); |
|
810 |
|
811 // Tidy up |
|
812 testFile.Close(); |
|
813 r=TheFs.Delete(_L("unsuppFile.tst")); |
|
814 test (r==KErrNone); |
|
815 } |
|
816 |
|
817 |
|
818 LOCAL_C void GetDriveLetters() |
|
819 { |
|
820 // Assign the first drive that matches the required criteria |
|
821 test.Next(_L("T_Clamp - GetDriveLetters()")); |
|
822 |
|
823 TDriveList driveList; |
|
824 TDriveInfo driveInfo; |
|
825 TInt r=TheFs.DriveList(driveList); |
|
826 test(r==KErrNone); |
|
827 TInt drvNum; |
|
828 TBool drivesFound = EFalse; |
|
829 for(drvNum=0; (drvNum<KMaxDrives) && !drivesFound; drvNum++) |
|
830 { |
|
831 TChar drvLetter='?'; |
|
832 TFileName fileSystem; |
|
833 if(!driveList[drvNum]) |
|
834 continue; |
|
835 test(TheFs.Drive(driveInfo, drvNum) == KErrNone); |
|
836 test(TheFs.DriveToChar(drvNum,drvLetter) == KErrNone); |
|
837 r=TheFs.FileSystemName(fileSystem,drvNum); |
|
838 fileSystem.UpperCase(); |
|
839 test((r==KErrNone)||(r==KErrNotFound)); |
|
840 if (!(driveInfo.iDriveAtt & KDriveAttInternal)) |
|
841 continue; |
|
842 // Check for FAT on NAND |
|
843 if(NandFatDrv=='?') |
|
844 { |
|
845 if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KFATName)==0)) |
|
846 NandFatDrv=drvLetter; |
|
847 } |
|
848 // Check for ROFS |
|
849 if(RofsDrv=='?') |
|
850 { |
|
851 if((driveInfo.iType==EMediaNANDFlash) && (fileSystem.Compare(KROFSName)==0)) |
|
852 RofsDrv=drvLetter; |
|
853 } |
|
854 // Check for LFFS |
|
855 if(LffsDrv=='?') |
|
856 { |
|
857 if((driveInfo.iType==EMediaFlash) && (fileSystem.Compare(KLFFSName)==0)) |
|
858 LffsDrv=drvLetter; |
|
859 } |
|
860 // Check for CompFSys |
|
861 if(CompDrv=='?') |
|
862 { |
|
863 if((driveInfo.iType==EMediaRom) && ((fileSystem.Compare(KROMName)==0)||(fileSystem.Compare(KCOMPName)==0))) |
|
864 CompDrv=drvLetter; |
|
865 } |
|
866 drivesFound=((NandFatDrv!='?')&&(RofsDrv!='?')&&(LffsDrv!='?')&&(CompDrv!='?')); |
|
867 } |
|
868 if(NandFatDrv!='?') |
|
869 test((NandFatDrv!=RofsDrv)&&(NandFatDrv!=LffsDrv)&&(NandFatDrv!=CompDrv)); |
|
870 if(RofsDrv!='?') |
|
871 test((RofsDrv!=LffsDrv)&&(RofsDrv!=CompDrv)); |
|
872 if(LffsDrv!='?') |
|
873 test(LffsDrv!=CompDrv); |
|
874 |
|
875 RDebug::Printf("T_CLAMP: FAT drive=%C, ROFS drive=%C, LFFS drive=%C, ROM-COMP drive=%C \n",(TText)NandFatDrv,(TText)RofsDrv,(TText)LffsDrv,(TText)CompDrv); |
|
876 return; |
|
877 } |
|
878 |
|
879 |
|
880 // |
|
881 // E32Main |
|
882 // |
|
883 |
|
884 TInt E32Main() |
|
885 { |
|
886 TInt r; |
|
887 test.Title(); |
|
888 test.Start(_L("Starting T_CLAMP ...")); |
|
889 test(TheFs.Connect()==KErrNone); |
|
890 |
|
891 GetDriveLetters(); |
|
892 TBuf<256> pathName; |
|
893 |
|
894 //************************************************************************ |
|
895 // |
|
896 // Test on FAT (writable file system) |
|
897 // |
|
898 //************************************************************************ |
|
899 if(NandFatDrv!='?') |
|
900 { |
|
901 pathName=_L("?:\\CLAMP-TST\\"); // FAT on NAND |
|
902 pathName[0]=(TText)NandFatDrv; |
|
903 r=TheFs.MkDirAll(pathName); |
|
904 test(r==KErrNone || r== KErrAlreadyExists); |
|
905 TheFs.SetSessionPath(pathName); |
|
906 test.Printf( _L("T_CLAMP: testing FAT drive on %C\n"),(TText)NandFatDrv); |
|
907 |
|
908 Test1(); // Basic clamp operation |
|
909 Test2(); // Invalid clamp requests |
|
910 Test3(pathName);// Denied FS requests when files are clamped |
|
911 |
|
912 r=TheFs.RmDir(pathName); |
|
913 test(r==KErrNone); |
|
914 } |
|
915 else |
|
916 test.Printf( _L("T_CLAMP: FAT drive not tested\n")); |
|
917 |
|
918 //************************************************************************ |
|
919 // |
|
920 // Test on ROFS (non-writable file system) |
|
921 // |
|
922 //************************************************************************ |
|
923 if(RofsDrv!='?') |
|
924 { |
|
925 pathName=_L("?:\\"); |
|
926 pathName[0]=(TText)RofsDrv; |
|
927 TheFs.SetSessionPath(pathName); |
|
928 test.Printf( _L("T_CLAMP: testing ROFS drive on %C\n"),(TText)RofsDrv); |
|
929 |
|
930 Test4(pathName); // Clamp tests for non-writable file system |
|
931 } |
|
932 else |
|
933 test.Printf( _L("T_CLAMP: ROFS drive not tested\n")); |
|
934 |
|
935 //************************************************************************ |
|
936 // |
|
937 // Test on Z: - Composite File System, or ROMFS (non-writable file system) |
|
938 // |
|
939 //************************************************************************ |
|
940 if(CompDrv!='?') |
|
941 { |
|
942 pathName=_L("?:\\TEST\\"); |
|
943 pathName[0]=(TText)CompDrv; |
|
944 TheFs.SetSessionPath(pathName); |
|
945 test.Printf( _L("T_CLAMP: testing Z drive (on %C)\n"),(TText)CompDrv); |
|
946 |
|
947 Test4(pathName); // Clamp tests for non-writable file system |
|
948 } |
|
949 else |
|
950 test.Printf( _L("T_CLAMP: Z drive not tested\n")); |
|
951 |
|
952 //************************************************************************ |
|
953 // |
|
954 // Test on LFFS (non-clampable file system) |
|
955 // |
|
956 //************************************************************************ |
|
957 if(LffsDrv!='?') |
|
958 { |
|
959 TBuf<256> unsuppPath; |
|
960 unsuppPath=_L("?:\\CLAMP-TST\\"); |
|
961 unsuppPath[0]=(TText)LffsDrv; |
|
962 r=TheFs.MkDirAll(unsuppPath); |
|
963 test(r==KErrNone || r== KErrAlreadyExists); |
|
964 TheFs.SetSessionPath(unsuppPath); |
|
965 test.Printf( _L("T_CLAMP: testing LFFS drive on %C\n"),(TText)LffsDrv); |
|
966 |
|
967 Test5(); // Clamp requests on non-clamping file systems |
|
968 } |
|
969 else |
|
970 test.Printf( _L("T_CLAMP: LFFS drive not tested\n")); |
|
971 |
|
972 test.End(); |
|
973 return 0; |
|
974 } |
|
975 |
|
976 #else |
|
977 |
|
978 TInt E32Main() |
|
979 { |
|
980 test.Title(); |
|
981 test.Start(_L("Test does not run on UREL builds.")); |
|
982 test.End(); |
|
983 return 0; |
|
984 } |
|
985 #endif |