os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_mount.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1996-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\server\t_mount.cpp
    15 // Testing some issues connected with mounting/dismounting file fystems, drives finalisation etc.
    16 //
    17 //
    18 
    19 /**
    20  @file
    21 */
    22 
    23 #define __E32TEST_EXTENSION__
    24 
    25 #include <f32file.h>
    26 #include <e32test.h>
    27 #include <e32math.h>
    28 #include <e32property.h>
    29 #include <f32dbg.h>
    30 
    31 #include "t_server.h"
    32 #include "fat_utils.h"
    33 
    34 using namespace Fat_Test_Utils;
    35 
    36 #ifdef __VC32__
    37     // Solve compilation problem caused by non-English locale
    38     #pragma setlocale("english")
    39 #endif
    40 
    41 RTest test(_L("T_Mount"));
    42 
    43 static TInt     gDriveNum=-1; ///< drive number we are dealing with
    44 static TInt64   gRndSeed;
    45 
    46 
    47 const TInt KBM_Repetitions = 5;     ///< number of repetitions for BM testing
    48 const TUint32 KCheckFileSize = 533; ///< size of the small file to be deleted
    49 
    50 _LIT(KFileNameFirst,  "\\FIRST%d.DAT");
    51 _LIT(KFileNameMiddle, "\\MID%d.DAT");
    52 _LIT(KFileNameLast,   "\\LAST%d.DAT");
    53 _LIT(KFileNameFiller, "\\FILL%d.DAT");
    54 
    55 typedef void (*TStressFN)(TInt);    //-- pointer to the FAT mount stress function
    56 
    57 
    58 //-------------------------------------------------------------------
    59 //-- debug bit flags that may be set in the property which controls FAT volume mounting
    60 
    61 const TUid KThisTestSID={0x10210EB3}; ///< this EXE SID
    62 
    63 const TUint32 KMntProp_EnableALL    = 0x00000000; //-- enable all operations
    64 
    65 #ifdef _DEBUG
    66 
    67 const TUint32 KMntProp_DisableALL   = 0xFFFFFFFF; //-- disable all operations
    68 const TUint32 KMntProp_Disable_FsInfo       = 0x00000001; //-- mask for disabling/enabling FSInfo information
    69 const TUint32 KMntProp_Disable_FatBkGndScan = 0x00000002; //-- mask for disabling/enabling FAT background scanner
    70 
    71 #endif
    72 
    73 //-------------------------------------------------------------------
    74 
    75 /** set a debug property value, which then wiil be read by FAT fsy */
    76 void SetFsyDebugFlag(TInt aDriveNo, TUint32 aFlags)
    77 {
    78     TInt nRes;
    79 
    80     nRes = RProperty::Set(KThisTestSID, aDriveNo, aFlags);
    81     test_KErrNone(nRes);
    82 }
    83 
    84 //-------------------------------------------------------------------
    85 /**
    86     format the volume and read the boot sector
    87 */
    88 static void FormatVolume(TBool aQuickFormat)
    89 {
    90     TInt nRes;
    91 
    92     #if 0
    93     //-- FAT32 SPC:1; for the FAT32 testing on the emulator
    94     (void)aQuickFormat;
    95 
    96     #ifdef  __EPOC32__
    97     test.Printf(_L("This is emulator configuration!!!!\n"));
    98     test(0);
    99     #endif
   100 
   101     TFatFormatParam fp;
   102     fp.iFatType = EFat32;
   103     fp.iSecPerCluster = 1;
   104     nRes = FormatFatDrive(TheFs, CurrentDrive(), ETrue, &fp); //-- always quick; doesn't matter for the emulator
   105     #else
   106     nRes = FormatFatDrive(TheFs, CurrentDrive(), aQuickFormat);
   107     #endif
   108 
   109     test_KErrNone(nRes);
   110 
   111 }
   112 
   113 //-------------------------------------------------------------------
   114 
   115 /**
   116     Prepare FAT volume for mounting performance testing
   117 
   118     1. quick format the drive
   119     2. create KBM_Repetitions files in the beginning (first files)
   120     3. create KMaxFillFiles/2 large files (they take about 40% of the volume);
   121     4. create KBM_Repetitions files (middle files)
   122     5. create KMaxFillFiles/2 large files (they take other 40% of the volume);
   123     6. create KBM_Repetitions files (last files)
   124 
   125     @return ETrue if everythis is OK
   126 */
   127 TBool PrepareVolumeForBM()
   128 {
   129     test.Printf(_L("Prepare the volume for BM testing...\n"));
   130 
   131     TInt nRes;
   132     TInt i;
   133 
   134     //-- 1. quick format the drive
   135     FormatVolume(ETrue);
   136 
   137 
   138     if(!Is_Fat32(TheFs, gDriveNum))
   139     {
   140         test.Printf(_L("This test requires FAT32 ! Skipping.\n"));
   141         return EFalse;
   142     }
   143 
   144     TVolumeInfo volInfo;
   145     nRes = TheFs.Volume(volInfo, gDriveNum);
   146     test_KErrNone(nRes);
   147 
   148     //-- the files will take 80% of the drive space
   149     const TInt    KMaxFillFiles = 100;
   150     const TUint32 KFillFileSz = (TUint32)((volInfo.iFree*8) / (10*KMaxFillFiles));
   151 
   152     //-- 2. create KBM_Repetitions files in the very begining (occupies first FAT entries)
   153     TBuf<64> buf;
   154 
   155     for(i=0; i<KBM_Repetitions; ++i)
   156     {
   157         buf.Format(KFileNameFirst, i);
   158         nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
   159         test_KErrNone(nRes);
   160     }
   161 
   162     //-- 3. Fill the FAT with entries and cteate a file in the middle
   163     const TInt nHalf1 = KMaxFillFiles / 2;
   164 
   165     for(i=0; i<nHalf1; ++i)
   166     {
   167         buf.Format(KFileNameFiller, i);
   168         nRes = CreateEmptyFile(TheFs, buf, KFillFileSz);
   169         test_KErrNone(nRes);
   170     }
   171 
   172     //-- 4. create a files in the middle
   173     for(i=0; i<KBM_Repetitions; ++i)
   174     {
   175         buf.Format(KFileNameMiddle, i);
   176         nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
   177         test_KErrNone(nRes);
   178     }
   179 
   180     //-- 5. fill second half FAT
   181     for(i=nHalf1; i<KMaxFillFiles; ++i)
   182     {
   183         buf.Format(KFileNameFiller, i);
   184         nRes = CreateEmptyFile(TheFs, buf, KFillFileSz);
   185         test_KErrNone(nRes);
   186     }
   187 
   188 
   189     //-- 6. create files in the very end (occupiy last FAT entries)
   190     for(i=0; i<KBM_Repetitions; ++i)
   191     {
   192         buf.Format(KFileNameLast, i);
   193         nRes = CreateCheckableStuffedFile(TheFs, buf, KCheckFileSize);
   194         test_KErrNone(nRes);
   195     }
   196 
   197     return ETrue;
   198 }
   199 
   200 /**
   201     Mounts and dismounts FAT volume several times calculating average time taken to mount.
   202     Also can stress FS by calling stress function that can do some work on the volume.
   203 
   204     @param  apStressFN pointer to the stressing function which can be called just after mounting. Can be NULL.
   205     @return time in milliseconds taken to mout the volume
   206 */
   207 static TUint32 DoMeasureMountTime(TStressFN apStressFN)
   208 {
   209 
   210     TInt nRes;
   211 
   212     TTime   timeStart;
   213     TTime   timeEnd;
   214 
   215     TInt64   usMountTime=0;      //-- total time taken by "Mount"
   216 
   217     //-- disable FAT test utils print out, it can affects measured time
   218     EnablePrintOutput(EFalse);
   219 
   220     for(TInt i=0; i<KBM_Repetitions; ++i)
   221     {
   222 
   223         //-- A. remount FS taking the time when mounting starts
   224         nRes = RemountFS(TheFs, gDriveNum, &timeStart);
   225         test_KErrNone(nRes);
   226 
   227         //-- B. call a given stress function
   228         if(apStressFN)
   229             apStressFN(i);
   230 
   231         //-- C. take end time
   232         timeEnd.UniversalTime();
   233         test_KErrNone(nRes);
   234 
   235         usMountTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
   236      }
   237 
   238     const TUint32 msMountTime = (TUint32)usMountTime / (K1mSec*KBM_Repetitions);
   239 
   240     EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
   241 
   242     return msMountTime;
   243 }
   244 
   245 //-------------------------------------------------------------------
   246 
   247 /**
   248     Stress function.
   249     Use case: read access to the first file on the volume in root dir.
   250 */
   251 static void FirstReadAccess_FirstFile_Stress(TInt aRepNo)
   252 {
   253     TBuf<64> buf;
   254     buf.Format(KFileNameFirst, aRepNo);
   255 
   256     TInt nRes = VerifyCheckableFile(TheFs, buf);
   257     test_KErrNone(nRes);
   258 }
   259 
   260 
   261 /**
   262     Stress function.
   263     Use case: read access to the middle file on the volume in root dir.
   264 */
   265 static void FirstReadAccess_MiddleFile_Stress(TInt aRepNo)
   266 {
   267     TBuf<64> buf;
   268     buf.Format(KFileNameMiddle, aRepNo);
   269 
   270     TInt nRes = VerifyCheckableFile(TheFs, buf);
   271     test_KErrNone(nRes);
   272 }
   273 
   274 /**
   275     Stress function.
   276     Use case: read access to the last file on the volume in root dir.
   277 */
   278 static void FirstReadAccess_LastFile_Stress(TInt aRepNo)
   279 {
   280     TBuf<64> buf;
   281     buf.Format(KFileNameLast, aRepNo);
   282 
   283     TInt nRes = VerifyCheckableFile(TheFs, buf);
   284     test_KErrNone(nRes);
   285 }
   286 
   287 /**
   288     Stress function.
   289     Use case: Getting volume information SYNCHRONOUSLY.
   290 */
   291 static void GetVolInfo_Synch_Stress(TInt)
   292 {
   293     TVolumeInfo volInfo;
   294     TInt nRes = TheFs.Volume(volInfo, gDriveNum);
   295     test_KErrNone(nRes);
   296 }
   297 
   298 /**
   299     Stress function.
   300     Use case: Getting volume information _ASYNCHRONOUSLY_, i.e. do not wait until
   301     FAT32 free space scan thread finishes
   302 */
   303 static void GetVolInfo_Asynch_Stress(TInt)
   304 {
   305     TVolumeInfo volInfo;
   306 
   307     //-- let's use special version of the RFS API
   308     TRequestStatus rqStat;
   309     TheFs.Volume(volInfo, gDriveNum, rqStat);
   310 
   311     User::WaitForRequest(rqStat);
   312     test(rqStat.Int()==KErrNone);
   313 
   314 }
   315 
   316 //-------------------------------------------------------------------
   317 
   318 /**
   319     Stress function.
   320     Use case: deletes files in the beginning of the volume (or FAT table)
   321 */
   322 static void DeleteFirstFile_Stress(TInt aRepNo)
   323 {
   324     TBuf<64> buf;
   325     buf.Format(KFileNameFirst, aRepNo);
   326 
   327     TInt nRes = TheFs.Delete(buf);
   328     test_KErrNone(nRes);
   329 }
   330 
   331 
   332 /**
   333     Stress function.
   334     Use case: deletes files in the middle of the volume (or FAT table)
   335 */
   336 static void DeleteMiddleFile_Stress(TInt aRepNo)
   337 {
   338     TBuf<64> buf;
   339     buf.Format(KFileNameMiddle, aRepNo);
   340 
   341     TInt nRes = TheFs.Delete(buf);
   342     test_KErrNone(nRes);
   343 }
   344 
   345 /**
   346     Stress function.
   347     Use case: deletes files in the end of the volume (or FAT table)
   348 */
   349 static void DeleteLastFile_Stress(TInt aRepNo)
   350 {
   351     TBuf<64> buf;
   352     buf.Format(KFileNameLast, aRepNo);
   353 
   354     TInt nRes = TheFs.Delete(buf);
   355     test_KErrNone(nRes);
   356 }
   357 
   358 
   359 //-------------------------------------------------------------------
   360 
   361 /**
   362     perform series of tests that measure and print out FAT volume mount time for different secenarios
   363 */
   364 void MeasureMountTime()
   365 {
   366     TUint32 msTime;
   367 
   368     if(!PrepareVolumeForBM()) //-- prepare the volume for BM tests: format it, create file structure etc.
   369         return;
   370 
   371     //-- 1. no stress function, measure just pure mount time
   372     msTime = DoMeasureMountTime(NULL);
   373     test.Printf(_L("#--> Pure mount:%d ms\n"), msTime);
   374 
   375     //-- 2.1 measure mount time with a read-acess to the first file on the volume
   376     msTime = DoMeasureMountTime(FirstReadAccess_FirstFile_Stress);
   377     test.Printf(_L("#--> mount and read access to 1st file:%d ms\n"), msTime);
   378 
   379     //-- 2.2 measure mount time with a read-acess to the middle file on the volume
   380     msTime = DoMeasureMountTime(FirstReadAccess_MiddleFile_Stress);
   381     test.Printf(_L("#--> mount and read access to middle file:%d ms\n"), msTime);
   382 
   383     //-- 2.3 measure mount time with a read-acess to the last file on the volume
   384     msTime = DoMeasureMountTime(FirstReadAccess_LastFile_Stress);
   385     test.Printf(_L("#--> mount and read access to last file:%d ms\n"), msTime);
   386 
   387     //-- 2.4 measure mount time with getting a volume information
   388     msTime = DoMeasureMountTime(GetVolInfo_Synch_Stress);
   389     test.Printf(_L("#--> mount and getting volInfo (synch):%d ms\n"), msTime);
   390 
   391     msTime = DoMeasureMountTime(GetVolInfo_Asynch_Stress);
   392     test.Printf(_L("#--> mount and getting volInfo (Asynch):%d ms\n"), msTime);
   393 
   394 
   395     //-- 2.4 measure mount time with deleting file in the beginning (write access to the first entries of the FAT32)
   396     msTime = DoMeasureMountTime(DeleteFirstFile_Stress);
   397     test.Printf(_L("#--> mount and delete first file:%d ms\n"), msTime);
   398 
   399     //-- 2.5 measure mount time with deleting file in the middle (write access to the middle entries of the FAT32)
   400     msTime = DoMeasureMountTime(DeleteMiddleFile_Stress);
   401     test.Printf(_L("#--> mount and delete middle file:%d ms\n"), msTime);
   402 
   403     //-- 2.6 measure mount time with deleting file in the end (write access to the last entries of the FAT32)
   404     msTime = DoMeasureMountTime(DeleteLastFile_Stress);
   405     test.Printf(_L("#--> mount and delete last file:%d ms\n"), msTime);
   406 
   407     test.Printf(_L("---\n"), msTime);
   408 }
   409 
   410 //----------------------------------------------------------------------------------------------
   411 //! @SYMTestCaseID      PBASE-T_MOUNT-0521
   412 //! @SYMTestType        PT
   413 //! @SYMPREQ            PREQ1721
   414 //! @SYMTestCaseDesc    Testing FAT volume mount performance for various scenarios
   415 //!
   416 //! @SYMTestActions
   417 //!             0   Prepare the volume by formatting it and creating 100 files to occupy the space.
   418 //!             1   Turn OFF all mount enhancements
   419 //!             2   Measure and print out volume mount time for the next scenarios:
   420 //!                   a.  simple mount
   421 //!                   b.  mount and read access to the media (reading the last file in the root dir.)
   422 //!                   c.  mount and write access to the media (writing data into the last file in the root dir)
   423 //!                   d.  mount getting volume information
   424 //!
   425 //!
   426 //!             3     Turn ON using FSInfo.
   427 //!             4     Repeat step 2 for this case.
   428 //! @SYMTestExpectedResults Finishes ok.
   429 //! @SYMTestPriority        High
   430 //! @SYMTestStatus          Implemented
   431 //----------------------------------------------------------------------------------------------
   432 void TestFAT_Mounting_Performance()
   433 {
   434     test.Next(_L("\n#--> Measuring FAT volumes mount performance.\n"));
   435 #ifndef _DEBUG
   436     test.Printf(_L("Skipping the test in the Release build! \n"));
   437     return;
   438 #else
   439 
   440    //-- 1. turn OFF all mount enhancements like using FSInfo, backround FAT scan etc.
   441    test.Printf(_L("#--> ==== All mount enhancements are disabled ====\n"));
   442    SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL);
   443    MeasureMountTime();
   444 
   445    //-- 2. Turn ON using FSInfo
   446    test.Printf(_L("#--> ==== Enabled Using FSInfo ====\n"));
   447    SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FsInfo);
   448    MeasureMountTime();
   449 
   450    //-- 2. Turn OFF using FSInfo and ON FAT32 bacground scanning
   451    test.Printf(_L("#--> ==== Enabled FAT32 BkGnd scan, FSInfo disabled ====\n"));
   452    SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FatBkGndScan);
   453    MeasureMountTime();
   454 
   455    //-- restore mounting mechanism
   456    SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
   457 
   458 #endif //_DEBUG
   459 }
   460 
   461 
   462 
   463 //-------------------------------------------------------------------
   464 
   465 /**
   466     Check if the drive aDriveNo is finalised or not.
   467     The "CleanShutDown" is obtained by QueryVolumeInfoExt API and by reading 2 FATs directly with checking their consistence.
   468 
   469     @param  aDriveNo drive number to query.
   470     @return ETrue if the drive if finalised
   471 */
   472 static TBool DoCheckVolumeFinalised(TInt aDriveNo)
   473 {
   474     TInt nRes;
   475     TPckgBuf<TBool> boolPckg;
   476 
   477     //-- 1. get "Finalised" state by using the API
   478     nRes = TheFs.QueryVolumeInfoExt(aDriveNo, EIsDriveFinalised, boolPckg);
   479     test_KErrNone(nRes);
   480 
   481     //-- N.B. for FAT12 the result can be either OK or "NotSupported"
   482     //-- If FAT12 is in explicit "finalised" state, the result will be OK
   483     //-- if not, we can't query the volume state, because FAT12 doesn't support flags in FAT[1]
   484 
   485     const TBool bFinalised_From_API = boolPckg() >0;
   486           TBool bFinalised_From_FAT1 = bFinalised_From_API;
   487 
   488     TBuf8<32> fatBuf(32);
   489     TFatBootSector  bootSec;
   490     const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
   491 
   492     nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, bootSec);
   493     test_KErrNone(nRes);
   494 
   495     test(bootSec.IsValid());
   496 
   497     const TUint32 Fat1StartPos = bootSec.FirstFatSector() * bootSec.BytesPerSector();
   498 
   499     if(bootSec.FatType() == EFat16)
   500     {//-- FAT16
   501         TUint16 fatEntry;
   502         const TUint16 KClnShtdnMask = 0x8000; //-- "ClnShutBitMask", see FAT specs
   503 
   504         //-- read "CleanShutDown" flag directly from the 1st FAT
   505         nRes = MediaRawRead(TheFs, gDriveNum, Fat1StartPos, fatBuf.Size(), fatBuf);
   506         test_KErrNone(nRes);
   507 
   508         Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
   509         bFinalised_From_FAT1 = (fatEntry & KClnShtdnMask) >0;
   510 
   511 
   512         for(TInt i=1; i<bootSec.NumberOfFats(); ++i)
   513         {
   514             //-- read a flag from the next FAT
   515             const TUint32 currFatStartPos = (bootSec.FirstFatSector() + i*bootSec.TotalFatSectors())*bootSec.BytesPerSector();
   516 
   517             nRes = MediaRawRead(TheFs, gDriveNum, currFatStartPos, fatBuf.Size(), fatBuf);
   518             test_KErrNone(nRes);
   519 
   520             Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
   521             const TBool bFinalised_From_currFAT = (fatEntry & KClnShtdnMask)>0;
   522 
   523             test(bFinalised_From_currFAT == bFinalised_From_FAT1);
   524         }
   525 
   526     }
   527     else if(bootSec.FatType() == EFat32)
   528     {//-- FAT32
   529         TUint32 fatEntry;
   530         const TUint32 KClnShtdnMask = 0x08000000; //-- "ClnShutBitMask", see FAT specs
   531 
   532         //-- read "CleanShutDown" flag directly from the 1st FAT
   533         nRes = MediaRawRead(TheFs, gDriveNum, Fat1StartPos, fatBuf.Size(), fatBuf);
   534         test_KErrNone(nRes);
   535 
   536         Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
   537         bFinalised_From_FAT1 = (fatEntry & KClnShtdnMask) >0;
   538 
   539         for(TInt i=1; i<bootSec.NumberOfFats(); ++i)
   540         {
   541             //-- read a flag from the next FAT
   542             const TUint32 currFatStartPos = (bootSec.FirstFatSector() + i*bootSec.TotalFatSectors())*bootSec.BytesPerSector();
   543 
   544             nRes = MediaRawRead(TheFs, gDriveNum, currFatStartPos, fatBuf.Size(), fatBuf);
   545             test_KErrNone(nRes);
   546 
   547             Mem::Copy(&fatEntry, (fatBuf.Ptr()+sizeof(fatEntry)), sizeof(fatEntry));
   548             const TBool bFinalised_From_currFAT = (fatEntry & KClnShtdnMask) >0;
   549 
   550             test(bFinalised_From_currFAT == bFinalised_From_FAT1);
   551         }
   552 
   553     }
   554     else  //-- FAT12
   555     {//-- FAT12 doesn't have flags in FAT[1]
   556      bFinalised_From_FAT1 = bFinalised_From_API;
   557     }
   558 
   559     test(bFinalised_From_FAT1 == bFinalised_From_API);
   560 
   561     return bFinalised_From_API;
   562 }
   563 
   564 
   565 
   566 //----------------------------------------------------------------------------------------------
   567 //! @SYMTestCaseID      PBASE-T_MOUNT-0522
   568 //! @SYMTestType        UT
   569 //! @SYMPREQ            PREQ1721
   570 //! @SYMTestCaseDesc    RFs::FinaliseDrive() and RFs::FinaliseDrives() API
   571 //!
   572 //! @SYMTestActions
   573 //!             0   Finalise the drive in RW mode and check the result.
   574 //!             1   Finalise the drive in RW mode once again and check the result.
   575 //!             2   Create a file and check that the volume has become unfinalised.
   576 //!             3   Open a file, try to finalise the volume; it shall fail with KErrInUse
   577 //!             4   close the file, finalise, check that the result is OK.
   578 //!             5   "Unfinalise" the volume; check that the volume is not finalised any longer.
   579 //!             6   Finalise the drive in RO mode and check the result.
   580 //!             7   Try to create a file, shall fail with KErrAccessDenied
   581 //!             8   Try to finalise into RW mode, shall fail with KErrAccessDenied
   582 //!             9   Try to unfinalise volume, it shall remain RO
   583 //!             10  Remount the drive, it shall become RW and finalised
   584 //!             11  Test transition "Not finalised" -> EFinal_RW (expected: KErrNone)
   585 //!             12  Test transition EFinal_RW -> EFinal_RO  (expected: KErrNone)
   586 //!             13  Test transition EFinal_RO -> EFinal_RW  (expected: KErrAccessDenied)
   587 //!             14  Remount the volume to reset RO flag
   588 //!             15  test old RFs::FinaliseDrives() API by finalising all drives in the system
   589 //!
   590 //! @SYMTestExpectedResults finishes if the volume finalisation works correctly. panics otherwise
   591 //! @SYMTestPriority        High
   592 //! @SYMTestStatus          Implemented
   593 //----------------------------------------------------------------------------------------------
   594 static void TestFinaliseFS()
   595 {
   596     test.Next(_L("Testing RFs::FinaliseDrives() API\n"));
   597 
   598     if(!Is_Fat16(TheFs, gDriveNum) && !Is_Fat32(TheFs, gDriveNum))
   599     {
   600         test.Printf(_L("This step requires FAT16 or FAT32 ! Skipping.\n"));
   601         return;
   602     }
   603 
   604     TInt  nRes;
   605     TBool bDriveFinalised;
   606 
   607     //============= 1. finalise the drive (RW mode) and check the result
   608     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   609     test_KErrNone(nRes);
   610 
   611     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   612     test(bDriveFinalised);
   613 
   614     //-- 1.1 finalise the drive second time EFinal_RW -> EFinal_RW shall work
   615     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   616     test_KErrNone(nRes);
   617 
   618     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   619     test(bDriveFinalised);
   620 
   621     //============= 2. create a file. Shall succeed (EFinal_RW), the volume shall become unfinalised
   622 
   623     RFile file;
   624     _LIT(KFileName, "\\my_file1.dat");
   625 
   626     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   627     test_KErrNone(nRes);
   628 
   629     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   630     test(!bDriveFinalised); //-- the volume has become "unfinalised"
   631 
   632     //-- 2.1 open a file, try to finalise; Shall dail with KErrInUse
   633     nRes = file.Replace(TheFs, KFileName, EFileWrite | EFileRead);
   634     test_KErrNone(nRes);
   635 
   636     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   637     test(nRes==KErrInUse); //-- can't finalise drives with opened objects
   638 
   639     file.Close();
   640 
   641     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   642     test_KErrNone(nRes);
   643 
   644     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   645     test(bDriveFinalised);
   646 
   647     //============= 3. test "unfinalise API"
   648     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise);
   649     test_KErrNone(nRes);
   650 
   651     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   652     test(!bDriveFinalised); //-- the volume has become "unfinalised"
   653 
   654     //============= 4. test finalisation into RO mode
   655     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO); //-- the volume becomes RO
   656     test_KErrNone(nRes);
   657 
   658     //-- try to write a file on RO volume; it shall fail with KErrAccessDenied
   659     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   660     test(nRes == KErrAccessDenied);
   661     file.Close();
   662 
   663     //-- 4.1 try to finalise into EFinal_RW mode, shall fail with KErrAccessDenied
   664     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   665     test(nRes == KErrAccessDenied);
   666 
   667     //-- 4.2 "unfinalise" the volume, it still shall remain RO
   668     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EForceUnfinalise);
   669     test_KErrNone(nRes);
   670 
   671     //-- try to write a file on RO volume; it shall fail with KErrAccessDenied
   672     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   673     test(nRes == KErrAccessDenied);
   674     file.Close();
   675 
   676     //-- remount FS, the drive shall become RW
   677     nRes = RemountFS(TheFs, gDriveNum);
   678     test_KErrNone(nRes);
   679 
   680     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   681     test(bDriveFinalised);
   682 
   683     //-- try to write a file on RW volume, shall be OK
   684     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   685     test(nRes == KErrNone);
   686     file.Close();
   687 
   688     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   689     test(!bDriveFinalised);
   690 
   691     //============= 5. test various finalisation modes
   692 
   693     //-- 5.1  Not finalised -> EFinal_RW (KErrNone)
   694     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   695     test(nRes == KErrNone);
   696     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   697     test(bDriveFinalised);
   698 
   699     //-- 5.2  EFinal_RW -> EFinal_RO (KErrNone)
   700     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RO);
   701     test(nRes == KErrNone);
   702     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   703     test(bDriveFinalised);
   704 
   705     //-- 5.2  EFinal_RO -> EFinal_RW  (KErrAccessDenied)
   706     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   707     test(nRes == KErrAccessDenied);
   708     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   709     test(bDriveFinalised);
   710 
   711     //-- 5.3 restore
   712     nRes = RemountFS(TheFs, gDriveNum);
   713     test_KErrNone(nRes);
   714 
   715 
   716     //============= 6. test old RFs::FinaliseDrives API
   717 
   718     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   719     test(nRes == KErrNone);
   720 
   721     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   722     test(!bDriveFinalised);
   723 
   724     TheFs.FinaliseDrives(); //-- shall work as TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW) but for ALL drives
   725 
   726     bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   727     test(bDriveFinalised);
   728 
   729     nRes = CreateEmptyFile(TheFs, KFileName, 128000);
   730     test(nRes == KErrNone);
   731 
   732 }
   733 
   734 //----------------------------------------------------------------------------------------------
   735 //! @SYMTestCaseID      PBASE-T_MOUNT-0523
   736 //! @SYMTestType        UT
   737 //! @SYMPREQ            PREQ1721
   738 //! @SYMTestCaseDesc    testing boot and backup boot sectors on FAT32 volume
   739 //!
   740 //! @SYMTestActions
   741 //!             0   Quick format the drive
   742 //!             1   read main and backup boot & fsinfo sectors and check their validity
   743 //!             2   corrupt main boot sector and check that the drive can be mounted (backup boot sector is used)
   744 //!             3   corrupt backup boot sector and check that the drive can not be mounted.
   745 //!             4   Quick format the drive to restore test environment
   746 //!
   747 //! @SYMTestExpectedResults finishes if the boot sector and backup boot sector functionality compliant with the FAT specs. panics otherwise
   748 //! @SYMTestPriority        High
   749 //! @SYMTestStatus          Implemented
   750 //----------------------------------------------------------------------------------------------
   751 static void TestBackupBootSector()
   752 {
   753     test.Next(_L("Testing Backup Boot Sector.\n"));
   754 
   755     TInt nRes;
   756 
   757     //-- quick format the drive
   758     FormatVolume(ETrue);
   759 
   760     if(!Is_Fat32(TheFs, gDriveNum))
   761     {
   762         test.Printf(_L("This step requires FAT32 ! Skipping.\n"));
   763         return;
   764     }
   765 
   766     TFatBootSector  mainBootSec, backupBootSec;
   767     TFSInfo         mainFSInfo, backupFSInfo;
   768 
   769     const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
   770     const TUint32 posBkBootSec   = KBkBootSectorNum << KDefaultSectorLog2;
   771 
   772     //-- read main and backup boot & fsinfo sectors and check their validity
   773     nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, mainBootSec);
   774     test_KErrNone(nRes);
   775 
   776     //-- backup boot sector # must be 6
   777     nRes = ReadBootSector(TheFs, gDriveNum, posBkBootSec, backupBootSec);
   778     test_KErrNone(nRes);
   779 
   780     test(mainBootSec.IsValid());
   781     test(backupBootSec.IsValid());
   782     test(mainBootSec == backupBootSec);
   783 
   784     //-- read fsinfo sectors
   785     const TUint32 posMainFSInfo = mainBootSec.FSInfoSectorNum() << KDefaultSectorLog2;
   786     const TUint32 posBkFSInfo   = (KBkBootSectorNum + mainBootSec.FSInfoSectorNum()) << KDefaultSectorLog2;
   787 
   788     test(posMainFSInfo != 0);
   789     test(posBkFSInfo != 0);
   790 
   791     nRes = ReadFSInfoSector(TheFs, gDriveNum, posMainFSInfo, mainFSInfo);
   792     test_KErrNone(nRes);
   793 
   794     nRes = ReadFSInfoSector(TheFs, gDriveNum, posBkFSInfo, backupFSInfo);
   795     test_KErrNone(nRes);
   796 
   797     test(mainFSInfo.IsValid());
   798     test(backupFSInfo.IsValid());
   799     test(mainFSInfo == backupFSInfo);
   800 
   801     //-- corrupt main boot sector and check that the drive can be mounted
   802     test.Printf(_L("Corrupting main boot sector...\n"));
   803 
   804 
   805     //-- A1. corrupt main boot sector starting from the pos:0
   806     nRes = FillMedia(TheFs, gDriveNum, posMainBootSec, posMainBootSec+KDefaultSectorSize, 0xaa);
   807 
   808     //-- A2. remount FS, it shall be OK because of the using backup boot sector
   809     nRes = RemountFS(TheFs, gDriveNum);
   810     test_KErrNone(nRes);
   811 
   812 
   813     //-- B1. corrupt BACKUP boot sector starting from the sec:6
   814     nRes = FillMedia(TheFs, gDriveNum, posBkBootSec, posBkBootSec+KDefaultSectorSize, 0xbb);
   815 
   816     //-- B2. remount FS, unable to mount.
   817     nRes = RemountFS(TheFs, gDriveNum);
   818     test(nRes == KErrCorrupt);
   819 
   820 
   821     //-- quick format the drive
   822     FormatVolume(ETrue);
   823 
   824 }
   825 
   826 //----------------------------------------------------------------------------------------------
   827 //! @SYMTestCaseID      PBASE-T_MOUNT-0524
   828 //! @SYMTestType        UT
   829 //! @SYMPREQ            PREQ1721
   830 //! @SYMTestCaseDesc    testing FSInfo sector functionality.
   831 //!
   832 //! @SYMTestActions
   833 //!             0   Quick format the drive
   834 //!             1   finalise the drive to write correct data to the FSInfo & its backup copy.
   835 //!             2   read FSInfo sector, its backup copy and check that they are both valid, identical and contain correct data
   836 //!             3   check that after the formatting FS info values are the same as real, obtained from the FAT scanning.
   837 //!             4   create a random - sized file, check that after finalisation the number of free clusters is identical to the FSinfo
   838 //!             5   Quick format the drive to restore test environment
   839 //!
   840 //! @SYMTestExpectedResults finishes if the FSInfo sectors functionality compliant with the FAT specs. panics otherwise
   841 //! @SYMTestPriority        High
   842 //! @SYMTestStatus          Implemented
   843 //----------------------------------------------------------------------------------------------
   844 static void TestFSInfoSector()
   845 {
   846     test.Next(_L("Testing FSInfo Sector.\n"));
   847 
   848 #ifndef _DEBUG
   849     test.Printf(_L("Skipping the test in the Release build! \n"));
   850     return;
   851 #else
   852 
   853     TInt nRes;
   854 
   855     //-- quick format the drive
   856     FormatVolume(ETrue);
   857 
   858     if(!Is_Fat32(TheFs, gDriveNum))
   859     {
   860         test.Printf(_L("This step requires FAT32 ! Skipping.\n"));
   861         return;
   862     }
   863 
   864     TFatBootSector  bootSec;
   865     const TUint32 posMainBootSec = KBootSectorNum << KDefaultSectorLog2;
   866     nRes = ReadBootSector(TheFs, gDriveNum, posMainBootSec, bootSec);
   867     test_KErrNone(nRes);
   868 
   869     const TUint32 bytesPerSector = bootSec.BytesPerSector();
   870     const TUint32 secPerClust = bootSec.SectorsPerCluster();
   871 
   872     //-- finalise the drive, just in case
   873     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   874     test_KErrNone(nRes);
   875 
   876     //============= 1. read FSInfo sector and its backup copy and compare them
   877     TFSInfo fsInfoSec;
   878 
   879     //-- main FSInfo
   880     nRes = ReadFSInfoSector(TheFs, gDriveNum, KFSInfoSectorNum*bytesPerSector, fsInfoSec);
   881     test_KErrNone(nRes);
   882     test(fsInfoSec.IsValid());
   883 
   884     TUint32 freeClusters_FSInfo = fsInfoSec.FreeClusterCount();
   885     TUint32 nextFree_FSInfo = fsInfoSec.NextFreeCluster();
   886 
   887     //-- backup FSInfo
   888     nRes = ReadFSInfoSector(TheFs, gDriveNum, KBkFSInfoSectorNum*bytesPerSector, fsInfoSec);
   889     test_KErrNone(nRes);
   890     test(fsInfoSec.IsValid());
   891 
   892     //-- both copies must be identical
   893     test(freeClusters_FSInfo == fsInfoSec.FreeClusterCount());
   894     test(nextFree_FSInfo == fsInfoSec.NextFreeCluster());
   895 
   896     //-- FAT[0] and FAT[1] are not used; FAT[2] is taken by the 1st cluster of the FAT32 Root directory.
   897     test(nextFree_FSInfo == (2+1));
   898 
   899     //============= 2. check that after the formatting FS info values are the same as real.
   900 
   901     //-- 2.1 disable using FSInfo and other stuff
   902     SetFsyDebugFlag(gDriveNum, KMntProp_Disable_FsInfo);
   903 
   904     //-- remount FAT; using FSInfo is disabled. FAT will be explicitly scanned.
   905     nRes = RemountFS(TheFs, gDriveNum);
   906     test_KErrNone(nRes);
   907 
   908     //-- restore mounting mechanism
   909     SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
   910 
   911     //-- get free clusters number from the FSY, which in turn had counted them explicitly
   912     TVolumeInfo volInfo;
   913     nRes = TheFs.Volume(volInfo, gDriveNum);
   914     test_KErrNone(nRes);
   915 
   916     TUint32 freeClusters = (TUint32)(volInfo.iFree / (bytesPerSector * secPerClust));
   917     test(freeClusters == freeClusters_FSInfo);
   918 
   919     //============= 3. create a random - sized file, check that after finalisation the number of free clusters is identical to the FSinfo
   920     _LIT(KFileName, "\\FILE1.DAT");
   921     const TUint32 rndClusters = 7+((TUint32)Math::Rand(gRndSeed)) % 5000;
   922     const TUint32 fileSz = rndClusters * bytesPerSector * secPerClust;
   923     nRes = CreateEmptyFile(TheFs, KFileName, fileSz);
   924     test_KErrNone(nRes);
   925 
   926     //-- 3.1 get data from FS
   927     nRes = TheFs.Volume(volInfo, gDriveNum);
   928     test_KErrNone(nRes);
   929     freeClusters = (TUint32)(volInfo.iFree / (bytesPerSector * secPerClust));
   930 
   931     //-- 3.2 finalise the volume and get data from FSInfo
   932     nRes =TheFs.FinaliseDrive(gDriveNum, RFs::EFinal_RW);
   933     test_KErrNone(nRes);
   934 
   935     //-- main FSInfo
   936     nRes = ReadFSInfoSector(TheFs, gDriveNum, KFSInfoSectorNum*bytesPerSector, fsInfoSec);
   937     test_KErrNone(nRes);
   938     test(fsInfoSec.IsValid());
   939 
   940     freeClusters_FSInfo = fsInfoSec.FreeClusterCount();
   941     nextFree_FSInfo = fsInfoSec.NextFreeCluster();
   942 
   943     //-- backup FSInfo
   944     nRes = ReadFSInfoSector(TheFs, gDriveNum, KBkFSInfoSectorNum*bytesPerSector, fsInfoSec);
   945     test_KErrNone(nRes);
   946     test(fsInfoSec.IsValid());
   947 
   948     //-- both copies must be identical
   949     test(freeClusters_FSInfo == fsInfoSec.FreeClusterCount());
   950     test(nextFree_FSInfo == fsInfoSec.NextFreeCluster());
   951 
   952     //-- the information in FSInfo must be the same as in FAT
   953     test(freeClusters == freeClusters_FSInfo);
   954 
   955     TBool bDriveFinalised = DoCheckVolumeFinalised(gDriveNum);
   956     test(bDriveFinalised);
   957 
   958     TheFs.Delete(KFileName);
   959 
   960     //-- restore mounting mechanism
   961     SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
   962 
   963 #endif //_DEBUG
   964 }
   965 
   966 //-------------------------------------------------------------------
   967 
   968 /** initialise test global objects */
   969 static void InitGlobals()
   970 {
   971     TInt nRes;
   972 
   973     //-- define a propery which will control mount process in the fsy.
   974     //-- The property key is a drive number being tested
   975 
   976     _LIT_SECURITY_POLICY_PASS(KTestPropPolicy);
   977     nRes = RProperty::Define(KThisTestSID, gDriveNum, RProperty::EInt, KTestPropPolicy, KTestPropPolicy);
   978     test(nRes == KErrNone || nRes == KErrAlreadyExists);
   979 
   980     nRes = RProperty::Set(KThisTestSID, gDriveNum, KMntProp_EnableALL);
   981     test_KErrNone(nRes);
   982 
   983     gRndSeed = Math::Random();
   984     (void)&gRndSeed; //-- get rid of warning
   985 }
   986 
   987 /** destroy test global objects */
   988 static void DestroyGlobals()
   989 {
   990     //-- delete test property
   991     RProperty::Delete(KThisTestSID, gDriveNum);
   992 
   993     TVolumeInfo v;
   994     TheFs.Volume(v);
   995 }
   996 
   997 //-------------------------------------------------------------------
   998 /**
   999     Manual test. Requires manual removing and putting back the media.
  1000     On the emulator one can use pressing (and holding) F5 key to simulate media removal.
  1001 */
  1002 void Manual_TestRemount_On_MediaRemoval()
  1003 {
  1004     TInt nRes;
  1005 
  1006     _LIT(KFileName, "\\my_file1.dat");
  1007     const TUint32 KFileSz = K1MegaByte;
  1008 
  1009     //-- 1. create a file
  1010     nRes = CreateEmptyFile(TheFs, KFileName, KFileSz);
  1011     test_KErrNone(nRes);
  1012 
  1013     RFile file;
  1014 
  1015     nRes = file.Open(TheFs, KFileName, EFileRead | EFileWrite);
  1016     test_KErrNone(nRes);
  1017 
  1018     TBuf8<512> buf(512);
  1019     TVolumeInfo vi;
  1020     buf.FillZ();
  1021 
  1022     TKeyCode key;
  1023 
  1024     for(;;)
  1025     {
  1026         TheFs.SetDebugRegister(0x00);
  1027 
  1028         nRes = file.Read(0, buf);
  1029 
  1030         test.Printf(_L("Remove the media and press a key.\n"));
  1031         key = test.Getch();
  1032         if(key == EKeyEscape)
  1033                 break;
  1034 
  1035         TheFs.SetDebugRegister(KFSYS | KFSERV);
  1036         nRes = file.Read(0, buf);
  1037 
  1038         if(nRes != KErrNone)
  1039         {
  1040 
  1041             test.Printf(_L("ReadFile: %d!\n"), nRes);
  1042 
  1043             key = test.Getch();
  1044             if(key == EKeyEscape)
  1045                 break;
  1046 
  1047             nRes = TheFs.Volume(vi,gDriveNum);
  1048             test.Printf(_L("Volume: %d!\n"), nRes);
  1049 
  1050             key = test.Getch();
  1051             if(key == EKeyEscape)
  1052                 break;
  1053 
  1054             nRes = file.Write(0, buf);
  1055             test.Printf(_L("WriteFile: %d!\n"), nRes);
  1056 
  1057             key = test.Getch();
  1058             if(key == EKeyEscape)
  1059                 break;
  1060 
  1061         }
  1062 
  1063     }
  1064 
  1065 
  1066     file.Close();
  1067 }
  1068 
  1069 
  1070 //-------------------------------------------------------------------
  1071 /**
  1072     Wait for the request aRqStat to be completed with timeout.
  1073 
  1074     @param  aRqStat         request status object we need to wait to complete
  1075     @param  aTimeout_uS     timeout in microseconds
  1076 
  1077     @return ETrue   if the aRqStat is completed before time is out
  1078             EFalse  if aTimeout_uS has passed. And the state of the aRqStat not changed.
  1079 */
  1080 TBool WaitForRequestWithTimeout(TRequestStatus& aRqStat, TUint32 aTimeout_uS)
  1081 {
  1082     TRequestStatus  rqStatTimeout(KRequestPending);
  1083     RTimer          tmrTimeOut;
  1084     TInt            nRes;
  1085     TBool           bReqCompleted;
  1086 
  1087     if(aRqStat.Int() != KRequestPending)
  1088         return ETrue; //-- nothing to wait for.
  1089 
  1090     //-- set up a timeout timer
  1091     nRes = tmrTimeOut.CreateLocal();
  1092     test(nRes == KErrNone);
  1093 
  1094     tmrTimeOut.After(rqStatTimeout, aTimeout_uS);
  1095 
  1096     User::WaitForRequest(aRqStat, rqStatTimeout);
  1097 
  1098     if(aRqStat == KRequestPending)
  1099         {//-- timeout.
  1100         bReqCompleted = EFalse;
  1101         }
  1102         else
  1103         {//-- the main request has been completed, cancel timer
  1104             bReqCompleted = ETrue;
  1105             if(rqStatTimeout.Int() == KRequestPending)
  1106                 {
  1107                 tmrTimeOut.Cancel();
  1108                 User::WaitForRequest(rqStatTimeout);
  1109                 }
  1110         }
  1111 
  1112     tmrTimeOut.Close();
  1113 
  1114     return bReqCompleted;
  1115 }
  1116 
  1117 //-------------------------------------------------------------------
  1118 
  1119 void TestNotifyDiskSpace()
  1120 {
  1121     test.Next(_L("Testing NotifyDiskSpace() on asynchronous mounting\n"));
  1122 
  1123 #ifndef _DEBUG
  1124     test.Printf(_L("Skipping the test in the Release build! \n"));
  1125     return;
  1126 #else
  1127 
  1128     TInt nRes;
  1129     TRequestStatus rqStat;
  1130     TVolumeInfo volInfo;
  1131 
  1132     //-- quick format the drive
  1133     FormatVolume(ETrue);
  1134 
  1135     if(!Is_Fat32(TheFs, gDriveNum))
  1136     {//-- only FAT32 supports asynch mounting;
  1137         test.Printf(_L("This test step requires FAT32!\n"));
  1138         return;
  1139     }
  1140 
  1141     //-- FAT32 free space threshold that is supposed to be triggered by notifiers
  1142     const TInt64 KFreeSpaceThreshold = 300*K1MegaByte;
  1143 
  1144     //-- Turn OFF using FSInfo and ON FAT32 background scanning; it will cause compulsory FAT32 background free clusters scan.
  1145     //-- if FAT32 background free clusters scan is disabled in config, this test can hang on waiting for free space notifications.
  1146     test.Printf(_L("==== Enabled FAT32 BkGnd scan, FSInfo disabled ====\n"));
  1147     SetFsyDebugFlag(gDriveNum, KMntProp_DisableALL & ~KMntProp_Disable_FatBkGndScan);
  1148 
  1149 
  1150     //===== create a big file in the beginning in order to avoid freeSpaceThreshold being reached too fast
  1151     nRes = CreateEmptyFile(TheFs, _L("\\big_empty_file.bin"), 10*K1MegaByte);
  1152     test_KErrNone(nRes);
  1153 
  1154 //TheFs.SetDebugRegister(0x03);
  1155 
  1156     //===== Test that FAT32 free space scanning thread updates File Server free space notifiers
  1157     test.Printf(_L("Testing FAT32 free space scanning thread triggers notifiers..."));
  1158 
  1159     nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it must cause FAT32 free space scan in background
  1160     test_KErrNone(nRes);
  1161 
  1162     test.Printf(_L("Waiting for %LU bytes available on the volume...\n"), KFreeSpaceThreshold);
  1163 
  1164     //-- check if we can use the notifiers at all... If free space is >= KFreeSpaceThreshold, the notifier won't be triggered
  1165     //-- get _current_ amount of free space asynchronously
  1166     TheFs.Volume(volInfo, gDriveNum, rqStat);
  1167     User::WaitForRequest(rqStat);
  1168     test(rqStat.Int()==KErrNone);
  1169 
  1170     if(volInfo.iSize <= KFreeSpaceThreshold)
  1171     {
  1172     test.Printf(_L("The volume is too small for %LU bytes notify ...\n"), KFreeSpaceThreshold);
  1173     test.Printf(_L("The test is inconclusive ...\n"));
  1174     return;
  1175     }
  1176 
  1177     if(volInfo.iFree >= KFreeSpaceThreshold)
  1178     {
  1179     test.Printf(_L("The volume already has %LU free bytes...\n"), volInfo.iFree);
  1180     test.Printf(_L("The test is inconclusive ...\n"));
  1181     return;
  1182     }
  1183 
  1184 
  1185     TheFs.NotifyDiskSpace(KFreeSpaceThreshold, gDriveNum, rqStat);
  1186     test(rqStat.Int()==KRequestPending);
  1187 
  1188     //-- wait for notification for 30 seconds; If for some reason FAT32 background scanning for free clusters doesn't
  1189     //-- work (e.g. configued out in FAT), this test is inconclusive.
  1190     TBool bCompleted = WaitForRequestWithTimeout(rqStat, 30*K1Sec);
  1191 
  1192     if(!bCompleted)
  1193     {
  1194         test.Printf(_L("Wait timeout! something is wrong...\n"));
  1195         test(0);
  1196     }
  1197 
  1198     test_KErrNone(rqStat.Int());
  1199 
  1200     //-- get _current_ amount of free space asynchronously
  1201     TheFs.Volume(volInfo, gDriveNum, rqStat);
  1202     User::WaitForRequest(rqStat);
  1203     test(rqStat.Int()==KErrNone);
  1204     test.Printf(_L("Current amount of free space on the volume: %LU \n"), volInfo.iFree);
  1205 
  1206 
  1207     //===== Test that aborting FAT32 free space scanning thread will trigger notifiers
  1208     test.Printf(_L("Testing aborting FAT32 free space scanning thread..."));
  1209 
  1210     nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it must cause FAT32 free space scan in background
  1211     test_KErrNone(nRes);
  1212 
  1213     TheFs.NotifyDiskSpace(KFreeSpaceThreshold, gDriveNum, rqStat);
  1214     test(rqStat.Int()==KRequestPending);
  1215 
  1216     nRes = RemountFS(TheFs, gDriveNum); //-- remount FS; it will abort the scanning thread
  1217     test_KErrNone(nRes);
  1218 
  1219     test(rqStat.Int() != KRequestPending);
  1220 
  1221     //-- get _current_ amount of free space asynchronously
  1222     TheFs.Volume(volInfo, gDriveNum, rqStat);
  1223     User::WaitForRequest(rqStat);
  1224     test(rqStat.Int()==KErrNone);
  1225     test.Printf(_L("Current amount of free space on the volume: %LU \n"), volInfo.iFree);
  1226 
  1227 
  1228     //-- find out free space on the volume; it will also blocks until FAT32 free space scanning finishes.
  1229     nRes = TheFs.Volume(volInfo);
  1230     test(nRes==KErrNone);
  1231     test.Printf(_L("free space on the volume: %LU \n"), volInfo.iFree);
  1232 
  1233 
  1234 //TheFs.SetDebugRegister(0x00);
  1235 
  1236     //-- restore mounting mechanism
  1237     SetFsyDebugFlag(gDriveNum, KMntProp_EnableALL);
  1238 
  1239 #endif  //_DEBUG
  1240 }
  1241 
  1242 //-------------------------------------------------------------------
  1243 
  1244 void CallTestsL()
  1245     {
  1246     //-- set up console output
  1247     Fat_Test_Utils::SetConsole(test.Console());
  1248 
  1249     TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum);
  1250     test(nRes==KErrNone);
  1251 
  1252     //-- check if this is FAT
  1253     if(!Is_Fat(TheFs, gDriveNum) || Is_Automounter(TheFs, gDriveNum))
  1254     {//-- it doesn't make much sense to run this test under automounter+FAT. The automounter can't easily handle formatting corrupted media
  1255      //-- and the mounting permaormance measurements don't make much sense in this case as well.
  1256 
  1257         test.Printf(_L("Skipping. This test requires explicitly mounted FAT file system.\n"));
  1258         return;
  1259     }
  1260 
  1261     //-- check this is not the internal ram drive
  1262     TVolumeInfo v;
  1263 
  1264     nRes = TheFs.Volume(v);
  1265     test(nRes==KErrNone);
  1266     if(v.iDrive.iMediaAtt & KMediaAttVariableSize)
  1267         {
  1268         test.Printf(_L("Skipping. Internal ram drive not tested.\n"));
  1269         return;
  1270         }
  1271 
  1272     //-------------------------------------
  1273 
  1274     PrintDrvInfo(TheFs, gDriveNum);
  1275     InitGlobals();
  1276 
  1277 
  1278     TestNotifyDiskSpace();
  1279 
  1280     //-------------------------------------
  1281     TestBackupBootSector();
  1282     TestFSInfoSector();
  1283     TestFinaliseFS();
  1284 
  1285     //-------------------------------------
  1286     TestFAT_Mounting_Performance();
  1287     //-------------------------------------
  1288     //-- manual test
  1289     //Manual_TestRemount_On_MediaRemoval();
  1290 
  1291     //-------------------------------------
  1292     DestroyGlobals();
  1293 
  1294     }
  1295 
  1296 
  1297 
  1298 
  1299 
  1300 
  1301 
  1302 
  1303 
  1304 
  1305 
  1306 
  1307 
  1308 
  1309 
  1310 
  1311 
  1312