229 const TInt KMaxFileSystemNameLength=100; // Arbitrary length |
249 const TInt KMaxFileSystemNameLength=100; // Arbitrary length |
230 const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length |
250 const TInt KMaxFileSystemExtNameLength=100; // Arbitrary length |
231 TBuf<KMaxFileSystemNameLength> fsName; |
251 TBuf<KMaxFileSystemNameLength> fsName; |
232 TBuf<KMaxFileSystemExtNameLength> fsExtName_0; |
252 TBuf<KMaxFileSystemExtNameLength> fsExtName_0; |
233 TBuf<KMaxFileSystemExtNameLength> fsExtName_1; |
253 TBuf<KMaxFileSystemExtNameLength> fsExtName_1; |
234 TBool fsExt0Present=EFalse; |
|
235 TBool fsExt1Present=EFalse; |
|
236 TInt driveNo, r; |
254 TInt driveNo, r; |
237 r=TheFs.CharToDrive(aRoot[0], driveNo); |
255 r=TheFs.CharToDrive(aRoot[0], driveNo); |
238 test(r==KErrNone); |
256 test(r==KErrNone); |
239 r=TheFs.FileSystemName(fsName, driveNo); |
257 r=TheFs.FileSystemName(fsName, driveNo); |
240 test(r==KErrNone); |
258 test(r==KErrNone); |
241 r=TheFs.ExtensionName(fsExtName_0,driveNo,0); |
259 |
242 if(r==KErrNone) |
260 //******************************************************************************************************* |
243 fsExt0Present=ETrue; |
|
244 r=TheFs.ExtensionName(fsExtName_1,driveNo,1); |
|
245 if(r==KErrNone) |
|
246 fsExt1Present=ETrue; |
|
247 |
|
248 // Create a file & write to it so that we can test whether dismounting works correctly with dirty data |
261 // Create a file & write to it so that we can test whether dismounting works correctly with dirty data |
|
262 //******************************************************************************************************* |
|
263 test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with dirty data, registered clients & clamped files")); |
|
264 |
249 TDriveInfo driveInfo; |
265 TDriveInfo driveInfo; |
250 test(TheFs.Drive(driveInfo, driveNo) == KErrNone); |
266 test(TheFs.Drive(driveInfo, driveNo) == KErrNone); |
251 TFileName dirtyFileName(_L("dirtyFile.tst")); |
267 TFileName dirtyFileName(_L("dirtyFile.tst")); |
252 RFile dirtyFile; |
268 RFile dirtyFile; |
253 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
269 TBool writeProtectedMedia = driveInfo.iMediaAtt & KMediaAttWriteProtected; |
|
270 if (!writeProtectedMedia) |
254 { |
271 { |
255 r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite); |
272 r=dirtyFile.Replace(TheFs, dirtyFileName, EFileWrite); |
256 test(r==KErrNone); |
273 test(r==KErrNone); |
257 r=dirtyFile.Write(_L8("My name is Michael Caine")); |
274 r=dirtyFile.Write(_L8("My name is Michael Caine")); |
258 test(r==KErrNone); |
275 test(r==KErrNone); |
266 test(r==KErrNone); |
283 test(r==KErrNone); |
267 testFile.Close(); |
284 testFile.Close(); |
268 |
285 |
269 TRequestStatus clientNotify=KErrNone; |
286 TRequestStatus clientNotify=KErrNone; |
270 TRequestStatus clientDismount=KErrNone; |
287 TRequestStatus clientDismount=KErrNone; |
271 TheFs.NotifyDismount(driveNo, clientNotify); // Register for notification |
288 TheFs.NotifyDismount(driveNo, clientNotify); // Register for dismount notification |
272 test(clientNotify == KRequestPending); |
289 test(clientNotify == KRequestPending); |
273 |
290 |
|
291 // register for disk change notifcation, so we can detect when dismount has actually taken place |
|
292 TRequestStatus diskChangeStatus; |
|
293 TheFs.NotifyChange(ENotifyDisk, diskChangeStatus); |
|
294 test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int()); |
|
295 test(diskChangeStatus == KRequestPending); // no disk change yet |
|
296 |
|
297 |
274 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
298 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
275 test(clientDismount == KRequestPending); |
299 test(clientDismount == KRequestPending); |
276 User::WaitForRequest(clientNotify); |
300 User::WaitForRequest(clientNotify); |
277 test(clientNotify == KErrNone); |
301 test(clientNotify == KErrNone); |
278 |
302 |
279 r=TheFs.AllowDismount(driveNo); // Respond to dismount notification |
303 r=TheFs.AllowDismount(driveNo); // Respond to dismount notification |
280 test(r == KErrNone); |
304 test(r == KErrNone); |
281 test(clientDismount == KRequestPending); // Dismount is deferred |
305 test(clientDismount == KRequestPending); // Dismount is deferred |
|
306 test(diskChangeStatus == KRequestPending); // no disk change yet |
282 |
307 |
283 // |
308 // |
284 // Now unclamp the file, and check that the deferred dismount is performed. |
309 // Now unclamp the file, and check that the deferred dismount is performed. |
285 r=handlePtr->Close(TheFs); |
310 r=handlePtr->Close(TheFs); |
286 test(r==KErrNone); |
311 test(r==KErrNone); |
287 User::WaitForRequest(clientDismount); |
312 User::WaitForRequest(clientDismount); |
288 test(clientDismount == KErrNone); |
313 test(clientDismount == KErrNone); |
289 |
314 |
|
315 // wait for disk change notification following dismount |
|
316 User::WaitForRequest(diskChangeStatus); |
|
317 test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount |
|
318 r = TheFs.Drive(driveInfo, driveNo); |
|
319 test (r==KErrNone); |
|
320 test (driveInfo.iType == EMediaNotPresent); |
|
321 |
|
322 // re-register for disk change notifcation, so we can detect when remount has actually taken place |
|
323 TheFs.NotifyChange(ENotifyDisk, diskChangeStatus); |
|
324 test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int()); |
|
325 test(diskChangeStatus == KRequestPending); // no disk change yet |
|
326 |
290 // Try to write to the opened file: this should return KErrNotReady as there is no drive thread |
327 // Try to write to the opened file: this should return KErrNotReady as there is no drive thread |
291 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
328 if (!writeProtectedMedia) |
292 { |
329 { |
293 r=dirtyFile.Write(_L8("My name isn't really Michael Caine")); |
330 r=dirtyFile.Write(_L8("My name isn't really Michael Caine")); |
294 test(r==KErrNotReady); |
331 test(r==KErrNotReady); |
295 } |
332 } |
296 |
333 |
297 // Re-mount the file system |
334 // Re-mount the file system |
298 if(fsExt0Present) |
335 RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1); |
299 { |
336 |
300 r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); |
337 // wait for disk change notification following remount |
301 test(r==KErrNone); |
338 User::WaitForRequest(diskChangeStatus); |
302 } |
339 test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount |
303 else if(fsExt1Present) // untested ! |
340 r = TheFs.Drive(driveInfo, driveNo); |
304 { |
341 test (r==KErrNone); |
305 r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); |
342 test (driveInfo.iType != EMediaNotPresent); |
306 test(r==KErrNone); |
|
307 } |
|
308 else |
|
309 { |
|
310 r=TheFs.MountFileSystem(fsName,driveNo); |
|
311 test_KErrNone(r); |
|
312 } |
|
313 |
343 |
314 // create some more dirty data to verify that the file server can cope with the drive thread |
344 // create some more dirty data to verify that the file server can cope with the drive thread |
315 // having gone & come back again |
345 // having gone & come back again |
316 if (!(driveInfo.iMediaAtt & KMediaAttWriteProtected)) |
346 if (!writeProtectedMedia) |
317 { |
347 { |
318 r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish.")); |
348 r=dirtyFile.Write(_L8("My name is Michael Phelps and I'm a fish.")); |
319 test(r==KErrDisMounted); |
349 test(r==KErrDisMounted); |
320 |
350 |
321 dirtyFile.Close(); |
351 dirtyFile.Close(); |
322 r = TheFs.Delete(dirtyFileName); |
352 r = TheFs.Delete(dirtyFileName); |
323 test(r == KErrNone); |
353 test(r == KErrNone); |
324 } |
354 } |
325 |
355 |
|
356 //******************************************************************************************************* |
326 // Issue a EFsDismountNotifyClients with no clients but with files clamped |
357 // Issue a EFsDismountNotifyClients with no clients but with files clamped |
327 // & verify that the dismount request completes when clamps are removed |
358 // & verify that the dismount request completes when clamps are removed |
|
359 //******************************************************************************************************* |
|
360 test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with no registered clients & clamped files")); |
|
361 |
328 r=testFile.Open(TheFs,aFileName,EFileRead); |
362 r=testFile.Open(TheFs,aFileName,EFileRead); |
329 test(r==KErrNone); |
363 test(r==KErrNone); |
330 r=handlePtr->Clamp(testFile); |
364 r=handlePtr->Clamp(testFile); |
331 test(r==KErrNone); |
365 test(r==KErrNone); |
332 testFile.Close(); |
366 testFile.Close(); |
367 test(clientDismount == KRequestPending); |
387 test(clientDismount == KRequestPending); |
368 r=handlePtr->Close(TheFs); |
388 r=handlePtr->Close(TheFs); |
369 test(r==KErrNone); |
389 test(r==KErrNone); |
370 User::WaitForRequest(clientDismount); |
390 User::WaitForRequest(clientDismount); |
371 test(clientDismount == KErrNone); |
391 test(clientDismount == KErrNone); |
|
392 |
|
393 |
372 // Re-mount the file system again |
394 // Re-mount the file system again |
373 if(fsExt0Present) |
395 RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1); |
374 { |
396 |
375 r=TheFs.MountFileSystem(fsName,fsExtName_0,driveNo); |
397 |
376 test(r==KErrNone); |
398 const TInt KNumClients = 5; |
377 } |
399 RFs clientFs[KNumClients]; |
378 else if(fsExt1Present) // untested ! |
400 TRequestStatus clientNotifies[KNumClients]; |
379 { |
401 TRequestStatus clientDiskChanges[KNumClients]; |
380 r=TheFs.MountFileSystem(fsName,fsExtName_1,driveNo); |
402 TRequestStatus clientComplete; |
381 test(r==KErrNone); |
403 |
382 } |
404 #define LOG_AND_TEST(a, e) {if (a!=e) {test.Printf(_L("lvalue %d, rvalue%d\n\r"), a,e); test(EFalse);}} |
383 else |
405 |
384 { |
406 //******************************************************************************************************* |
385 r=TheFs.MountFileSystem(fsName,driveNo); |
407 // Test unmounting with multiple registered clients which do not respond & close their sessions |
386 test_KErrNone(r); |
408 //******************************************************************************************************* |
387 } |
409 test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with multiple registered clients which do not respond & close their sessions")); |
388 |
410 |
|
411 TheFs.NotifyChange(ENotifyDisk, diskChangeStatus); |
|
412 test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int()); |
|
413 |
|
414 TInt i; |
|
415 for (i=0; i< KNumClients; i++) |
|
416 { |
|
417 LOG_AND_TEST(KErrNone, clientFs[i].Connect()); |
|
418 clientFs[i].NotifyDismount(driveNo, clientNotifies[i]); |
|
419 test(clientNotifies[i] == KRequestPending); |
|
420 } |
|
421 |
|
422 test.Next(_L("Close all but one client sessions with outstanding notifiers")); |
|
423 for (i=0; i< KNumClients-1; i++) |
|
424 clientFs[i].Close(); |
|
425 |
|
426 // Since all clients have NOT been closed, the next stage should not yet complete |
|
427 test.Next(_L("Notify clients of pending media removal and check status - should not complete")); |
|
428 TheFs.NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); |
|
429 test(clientComplete == KRequestPending); |
|
430 |
|
431 |
|
432 test.Next(_L("Close the remaining sessions with an outstanding notifier")); |
|
433 clientFs[KNumClients-1].Close(); |
|
434 |
|
435 // Check that the dismount completes now that all session have been closed |
|
436 test.Next(_L("Check that the dismount completes")); |
|
437 User::WaitForRequest(clientComplete); |
|
438 test_KErrNone(clientComplete.Int()); |
|
439 |
|
440 // wait for disk change notification following dismount |
|
441 User::WaitForRequest(diskChangeStatus); |
|
442 test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount |
|
443 r = TheFs.Drive(driveInfo, driveNo); |
|
444 test (r==KErrNone); |
|
445 test (driveInfo.iType == EMediaNotPresent); |
|
446 |
|
447 // re-register for disk change notifcation, so we can detect when remount has actually taken place |
|
448 TheFs.NotifyChange(ENotifyDisk, diskChangeStatus); |
|
449 test.Printf(_L("diskChangeStatus %d"), diskChangeStatus.Int()); |
|
450 test(diskChangeStatus == KRequestPending); // no disk change yet |
|
451 |
|
452 |
|
453 // Re-mount the file system again |
|
454 RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1); |
|
455 |
|
456 // wait for disk change notification following remount |
|
457 User::WaitForRequest(diskChangeStatus); |
|
458 test(diskChangeStatus == KErrNone); // should have got a disk change notification after dismount |
|
459 r = TheFs.Drive(driveInfo, driveNo); |
|
460 test (r==KErrNone); |
|
461 test (driveInfo.iType != EMediaNotPresent); |
|
462 |
|
463 |
|
464 |
|
465 //******************************************************************************************************* |
|
466 // Issue a EFsDismountNotifyClients with multiple clients |
|
467 // Verify that the dismount completes if a client re-registers for dismount notifications BEFORE calling AllowDismount |
|
468 //******************************************************************************************************* |
|
469 |
|
470 test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with multiple registered clients & a re-registration")); |
|
471 |
|
472 for(i=0; i< KNumClients; i++) |
|
473 { |
|
474 r=clientFs[i].Connect(); |
|
475 test(r==KErrNone); |
|
476 } |
|
477 // Cancel any deferred dismount in preparation for the next test |
|
478 TheFs.NotifyDismountCancel(); |
|
479 |
|
480 // All clients register for dismount notification |
|
481 for(i=0; i< KNumClients; i++) |
|
482 { |
|
483 clientNotifies[i] = KErrNone; |
|
484 clientFs[i].NotifyDismount(driveNo, clientNotifies[i]); |
|
485 test(clientNotifies[i] == KRequestPending); |
|
486 } |
|
487 |
|
488 // Issue a EFsDismountNotifyClients & wait for clients to respond |
|
489 clientDismount = KErrNone; |
|
490 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
|
491 test(clientDismount == KRequestPending); |
|
492 |
|
493 // Check all clients have received the notification |
|
494 for(i=0; i< KNumClients; i++) |
|
495 { |
|
496 User::WaitForRequest(clientNotifies[i]); |
|
497 test(clientNotifies[i] == KErrNone); |
|
498 } |
|
499 // All clients - except first one - invoke AllowDismount |
|
500 for(i=1; i< KNumClients; i++) |
|
501 { |
|
502 r=clientFs[i].AllowDismount(driveNo); |
|
503 test(r==KErrNone); |
|
504 } |
|
505 |
|
506 |
|
507 // verify dismount has not yet completed |
|
508 test(clientDismount == KRequestPending); |
|
509 |
|
510 |
|
511 // first client re-registers for dismount notifications |
|
512 clientFs[0].NotifyDismount(driveNo, clientNotifies[0]); |
|
513 test(clientNotifies[0] == KRequestPending); |
|
514 |
|
515 // first client allows dismount |
|
516 clientFs[0].AllowDismount(driveNo); |
|
517 test(r==KErrNone); |
|
518 |
|
519 // Wait for dismount |
|
520 User::WaitForRequest(clientDismount); |
|
521 test(clientDismount == KErrNone); |
|
522 |
|
523 |
|
524 // verify the first client's re-issued dismount notification is still pending |
|
525 test(clientNotifies[0] == KRequestPending); |
|
526 |
|
527 |
|
528 // Re-mount the file system again |
|
529 RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1); |
|
530 |
|
531 |
|
532 // Issue a EFsDismountNotifyClients again & check previously re-registered notification completes |
|
533 test(clientNotifies[0] == KRequestPending); |
|
534 clientDismount = KErrNone; |
|
535 TheFs.NotifyDismount(driveNo, clientDismount, EFsDismountNotifyClients); |
|
536 test(clientDismount == KRequestPending); |
|
537 |
|
538 // wait for notification |
|
539 User::WaitForRequest(clientNotifies[0]); |
|
540 |
|
541 // first client allows dismount |
|
542 clientFs[0].AllowDismount(driveNo); |
|
543 test(r==KErrNone); |
|
544 |
|
545 // Wait for dismount |
|
546 User::WaitForRequest(clientDismount); |
|
547 test(clientDismount == KErrNone); |
|
548 |
|
549 |
|
550 |
|
551 // Re-mount the file system again |
|
552 RemountFileSystem(driveNo, fsName, fsExtName_0, fsExtName_1); |
|
553 |
|
554 |
|
555 |
|
556 //******************************************************************************************************* |
|
557 // Issue a EFsDismountNotifyClients again with a multiple clients & then call RFs::NotifyDismountCancel() |
|
558 // Verify that all clients receive a disk change notification |
|
559 //******************************************************************************************************* |
|
560 test.Next(_L("T_Clamp - TestDeferredDismount(), testing unmounting with registered clients, a re-registration & a cancel")); |
|
561 |
|
562 // All clients register for dismount notification & disk change notification |
|
563 for(i=0; i< KNumClients; i++) |
|
564 { |
|
565 clientNotifies[i] = KErrNone; |
|
566 clientFs[i].NotifyDismount(driveNo, clientNotifies[i], EFsDismountRegisterClient); |
|
567 test(clientNotifies[i] == KRequestPending); |
|
568 |
|
569 clientFs[i].NotifyChange(ENotifyDisk, clientDiskChanges[i]); |
|
570 test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int()); |
|
571 test(clientDiskChanges[i] == KRequestPending); |
|
572 } |
|
573 |
|
574 |
|
575 // Issue a EFsDismountNotifyClients |
|
576 TheFs.NotifyDismount(driveNo, clientComplete, EFsDismountNotifyClients); |
|
577 test(clientComplete == KRequestPending); |
|
578 |
|
579 |
|
580 // Check all clients have received the notification |
|
581 for(i=0; i< KNumClients; i++) |
|
582 { |
|
583 User::WaitForRequest(clientNotifies[i]); |
|
584 test(clientNotifies[i] == KErrNone); |
|
585 |
|
586 test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int()); |
|
587 test(clientDiskChanges[i] == KRequestPending); |
|
588 } |
|
589 |
|
590 // verify dismount has not yet completed |
|
591 test(clientComplete == KRequestPending); |
|
592 |
|
593 |
|
594 // first client re-registers for dismount notifications |
|
595 clientFs[0].NotifyDismount(driveNo, clientNotifies[0]); |
|
596 test(clientNotifies[0] == KRequestPending); |
|
597 |
|
598 // first client acknowledges the dismount request |
|
599 r = clientFs[0].AllowDismount(driveNo); |
|
600 test(r == KErrNone); |
|
601 |
|
602 |
|
603 // cancel dismount |
|
604 // TheFs.NotifyDismountCancel(clientComplete); |
|
605 TheFs.NotifyDismountCancel(); |
|
606 test(clientComplete == KErrCancel); |
|
607 User::WaitForRequest(clientComplete); |
|
608 |
|
609 // Check all clients have received a disk change notification - |
|
610 // the file server should send a disk change notification when RFs::NotifyDismountCancel() is called |
|
611 for(i=0; i< KNumClients; i++) |
|
612 { |
|
613 User::WaitForRequest(clientDiskChanges[i]); |
|
614 test.Printf(_L("diskChangeStatus %d"), clientDiskChanges[i].Int()); |
|
615 test(clientDiskChanges[i] == KErrNone); |
|
616 } |
|
617 |
|
618 |
|
619 // cleanup |
|
620 for(i=0; i< KNumClients; i++) |
|
621 { |
|
622 clientFs[i].Close(); |
|
623 test(r==KErrNone); |
|
624 } |
389 } |
625 } |
390 |
626 |
391 |
627 |
392 |
628 |
393 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName) |
629 LOCAL_C void Test3Operations(TDesC& aRoot, TDesC& aFileName) |