os/kernelhwsrv/kerneltest/f32test/filesystem/fat/t_fatcache_bm.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32test\server\t_mount.cpp
sl@0
    15
// Testing FAT cache performance
sl@0
    16
//
sl@0
    17
//
sl@0
    18
sl@0
    19
/**
sl@0
    20
 @file
sl@0
    21
*/
sl@0
    22
sl@0
    23
#define __E32TEST_EXTENSION__
sl@0
    24
sl@0
    25
#include <f32file.h>
sl@0
    26
#include <e32test.h>
sl@0
    27
#include <e32math.h>
sl@0
    28
#include <e32property.h>
sl@0
    29
sl@0
    30
#include "t_server.h"
sl@0
    31
//#include "t_std.h"
sl@0
    32
sl@0
    33
#include "fat_utils.h"
sl@0
    34
sl@0
    35
using namespace Fat_Test_Utils;
sl@0
    36
sl@0
    37
#ifdef __VC32__
sl@0
    38
    // Solve compilation problem caused by non-English locale
sl@0
    39
    #pragma setlocale("english")
sl@0
    40
#endif
sl@0
    41
sl@0
    42
RTest test(_L("T_FAT_Cache_BM"));
sl@0
    43
sl@0
    44
//-- note that this test disables all FAT mount enhancements, like asynchronous mounting and using FSInfo sector.
sl@0
    45
sl@0
    46
static void WaitForFatBkGndActivityEnd();
sl@0
    47
sl@0
    48
//-------------------------------------------------------------------
sl@0
    49
//-- debug bit flags that may be set in the property which controls FAT volume mounting
sl@0
    50
sl@0
    51
const TUid KThisTestSID={0x10210EB3}; ///< this EXE SID
sl@0
    52
sl@0
    53
//const TUint32 KMntProp_EnableALL    = 0x00000000; //-- enable all operations
sl@0
    54
const TUint32 KMntProp_DisableALL   = 0xFFFFFFFF; //-- disable all operations
sl@0
    55
sl@0
    56
//const TUint32 KMntProp_Disable_FsInfo       = 0x00000001; //-- mask for disabling/enabling FSInfo information
sl@0
    57
//const TUint32 KMntProp_Disable_FatBkGndScan = 0x00000002; //-- mask for disabling/enabling FAT background scanner
sl@0
    58
sl@0
    59
//-------------------------------------------------------------------
sl@0
    60
sl@0
    61
static TInt     gDriveNum=-1; ///< drive number we are dealing with
sl@0
    62
static TInt64   gRndSeed;
sl@0
    63
static TFatBootSector gBootSector;
sl@0
    64
sl@0
    65
static void DoRemountFS(TInt aDrive);
sl@0
    66
sl@0
    67
//-- Array of integer file tars. Tags are used to identify files (the file name is generated by KFnTemplate template)
sl@0
    68
typedef CArrayFixFlat<TInt> CFileTagsArray;
sl@0
    69
static CFileTagsArray *pFTagArray = NULL;
sl@0
    70
sl@0
    71
sl@0
    72
//-------------------------------------------------------------------
sl@0
    73
const TInt KMaxFiles = 1000; //-- maximal number of files to create
sl@0
    74
sl@0
    75
//-- number of unfragmented files that will be left, other files will be merged to bigger ones.
sl@0
    76
const TInt KUnfragmentedFilesLeave = KMaxFiles/10;
sl@0
    77
sl@0
    78
_LIT(KDirName, "\\DIR1\\");  //-- directory name we a working with (FAT12/16 won't allow KMaxFiles in the root dir.)
sl@0
    79
_LIT(KFirstFileName, "\\First_file_1.nul"); //-- the name of the first file on the volume
sl@0
    80
sl@0
    81
//-------------------------------------------------------------------
sl@0
    82
sl@0
    83
/**
sl@0
    84
    Make a file name by its numeric tag
sl@0
    85
    @param aDes here will be a file name
sl@0
    86
    @param aFileNameTag numeric tag for the file name generation
sl@0
    87
sl@0
    88
*/
sl@0
    89
void MakeFileName(TDes& aDes, TInt aFileNameTag)
sl@0
    90
{
sl@0
    91
    _LIT(KFnTemplate, "F%d.NUL");//-- file name template, use 8.3 names here in order not to stress dir. cache much.
sl@0
    92
    aDes.Copy(KDirName);
sl@0
    93
    aDes.AppendFormat(KFnTemplate, aFileNameTag);
sl@0
    94
}
sl@0
    95
sl@0
    96
//-------------------------------------------------------------------
sl@0
    97
/**
sl@0
    98
    format the volume and read the boot sector
sl@0
    99
*/
sl@0
   100
static void FormatVolume(TBool aQuickFormat)
sl@0
   101
{
sl@0
   102
    (void)aQuickFormat;
sl@0
   103
sl@0
   104
    #ifndef  __EPOC32__
sl@0
   105
    test.Printf(_L("This is emulator configuration!!!!\n"));
sl@0
   106
sl@0
   107
    //-- FAT32 SPC:1; for the FAT32 testing on the emulator
sl@0
   108
    //TFatFormatParam fp;
sl@0
   109
    //fp.iFatType = EFat32;
sl@0
   110
    //fp.iSecPerCluster = 1;
sl@0
   111
    //FormatFatDrive(TheFs, CurrentDrive(), ETrue, &fp); //-- always quick; doesn't matter for the emulator
sl@0
   112
sl@0
   113
    aQuickFormat = ETrue;
sl@0
   114
    #endif
sl@0
   115
sl@0
   116
sl@0
   117
    FormatFatDrive(TheFs, CurrentDrive(), aQuickFormat);
sl@0
   118
sl@0
   119
sl@0
   120
    TInt nRes = ReadBootSector(TheFs, gDriveNum, 0x00, gBootSector);
sl@0
   121
    test_KErrNone(nRes);
sl@0
   122
}
sl@0
   123
sl@0
   124
sl@0
   125
//-------------------------------------------------------------------
sl@0
   126
sl@0
   127
/**
sl@0
   128
    Helper method. Does one iteration of merging test files into one fragmented one.
sl@0
   129
    See DoMergeFiles()
sl@0
   130
sl@0
   131
    @param  aFTagArray  reference to the file tags array
sl@0
   132
    @param  aBigFileNo  a sequential number of the result file to be merged from random number of smaller ones (names are taken from the tag array)
sl@0
   133
    @param  aTimeTaken_us  on return will contain time taken to this operation, in microseconds
sl@0
   134
sl@0
   135
    @return number of files merged into one.
sl@0
   136
*/
sl@0
   137
TInt DoMergeTestFiles(CFileTagsArray& aFTagArray, TInt aBigFileNo, TInt64&  aTimeTaken_us)
sl@0
   138
{
sl@0
   139
sl@0
   140
    aTimeTaken_us = 0;
sl@0
   141
    TTime   timeStart;
sl@0
   142
    TTime   timeEnd;
sl@0
   143
sl@0
   144
sl@0
   145
    //-- merged files' names start with this number
sl@0
   146
    const TInt KMergedFileFnThreshold = 20000;
sl@0
   147
sl@0
   148
    const TInt KMaxMergedFiles = 20;
sl@0
   149
    const TInt nFilesToMerge = Max((Math::Rand(gRndSeed) % KMaxMergedFiles), 2); //-- how many files to merge into one
sl@0
   150
sl@0
   151
    test(aFTagArray.Count() > KMaxMergedFiles);
sl@0
   152
sl@0
   153
    TInt selectedFTags[KMaxMergedFiles]; //-- here we will store file tags to be merged to one large fragmented file
sl@0
   154
    TInt i;
sl@0
   155
    TInt nRes;
sl@0
   156
sl@0
   157
    i=0;
sl@0
   158
    do
sl@0
   159
    {
sl@0
   160
        //-- randomly select a file tag from the global array
sl@0
   161
        const TInt index = (TUint)Math::Rand(gRndSeed) % aFTagArray.Count();
sl@0
   162
        const TInt fnTag = aFTagArray[index];
sl@0
   163
sl@0
   164
        if(fnTag < 0 || //-- no such file, already deleted
sl@0
   165
           fnTag >= KMergedFileFnThreshold) //-- this is a big, already merged file
sl@0
   166
           continue;
sl@0
   167
sl@0
   168
sl@0
   169
        selectedFTags[i] = fnTag;
sl@0
   170
        aFTagArray.Delete(index);
sl@0
   171
sl@0
   172
        ++i;
sl@0
   173
    }while(i<nFilesToMerge);
sl@0
   174
sl@0
   175
    //-- here we have file tags in selectedFNumbers array. delete these files and create one big file
sl@0
   176
    //-- with the equal size. This file will be perfectly fragmented.
sl@0
   177
    //-- search for FAT entries had priority to the right, so delete files in reverse order.
sl@0
   178
sl@0
   179
    TUint32 newFileSize = 0;
sl@0
   180
    TBuf<128> buf;
sl@0
   181
    RFile file;
sl@0
   182
sl@0
   183
    timeStart.UniversalTime(); //-- take start time
sl@0
   184
sl@0
   185
    for(i=0; i<nFilesToMerge; ++i)
sl@0
   186
    {
sl@0
   187
        MakeFileName(buf, selectedFTags[nFilesToMerge-1-i]);
sl@0
   188
sl@0
   189
        nRes=file.Open(TheFs, buf, EFileRead);
sl@0
   190
        test_KErrNone(nRes);
sl@0
   191
sl@0
   192
        TInt nSize;
sl@0
   193
        nRes = file.Size(nSize);
sl@0
   194
        test_KErrNone(nRes);
sl@0
   195
        file.Close();
sl@0
   196
sl@0
   197
        newFileSize+=(TUint32)nSize; //-- this will be the size of the new file
sl@0
   198
sl@0
   199
        //-- delete small file
sl@0
   200
        nRes = TheFs.Delete(buf);
sl@0
   201
        test_KErrNone(nRes);
sl@0
   202
sl@0
   203
    }
sl@0
   204
sl@0
   205
    //-- create a large file taking the place of few smaller. It will be framented.
sl@0
   206
    const TInt bigFileTag = aBigFileNo+KMergedFileFnThreshold;
sl@0
   207
sl@0
   208
    MakeFileName(buf, bigFileTag);
sl@0
   209
    nRes = CreateEmptyFile(TheFs, buf, newFileSize);
sl@0
   210
    test_KErrNone(nRes);
sl@0
   211
sl@0
   212
    timeEnd.UniversalTime(); //-- take end time
sl@0
   213
    aTimeTaken_us = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   214
sl@0
   215
    //-- put new big file name tag to the global array in order not to forget it for later use.
sl@0
   216
    aFTagArray.AppendL(bigFileTag);
sl@0
   217
sl@0
   218
    return nFilesToMerge;
sl@0
   219
}
sl@0
   220
sl@0
   221
//----------------------------------------------------------------------------------------------
sl@0
   222
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0689
sl@0
   223
//! @SYMTestType        PT
sl@0
   224
//! @SYMPREQ            PREQ1721
sl@0
   225
//! @SYMTestCaseDesc    randomly deletes small files and creates larger. Measures time taken by this FAT fragmentation
sl@0
   226
//!
sl@0
   227
//! @SYMTestActions
sl@0
   228
//!                     0   delete a random number of small files
sl@0
   229
//!                     1   create a random number of larger files, measure time taken
sl@0
   230
//!
sl@0
   231
//! @SYMTestExpectedResults successful files deletion/creation
sl@0
   232
//! @SYMTestPriority        High
sl@0
   233
//! @SYMTestStatus          Implemented
sl@0
   234
//----------------------------------------------------------------------------------------------
sl@0
   235
sl@0
   236
/**
sl@0
   237
    precondition: We have a lot of (KMaxFiles) files of the same size on the volume. They occupy almost all FAT.
sl@0
   238
    This method randomly selects several files on the volume, deletes them and creates a bigger file that occupies space from the
sl@0
   239
    deleted files. So that we got a fragmented big file. Repeat this until we have KUnfragmentedFilesLeave initial files left on the
sl@0
   240
    volume.
sl@0
   241
*/
sl@0
   242
void DoMergeFiles(CFileTagsArray& aFTagArray)
sl@0
   243
{
sl@0
   244
    test.Next(_L("Merging small files to larger creating FAT fragmentation...\n"));
sl@0
   245
sl@0
   246
    TInt64  usTotalTime=0;
sl@0
   247
    TInt64  usCurrTime;
sl@0
   248
sl@0
   249
    TInt nUnfragmentedLeft = aFTagArray.Count();
sl@0
   250
    for(TInt i=0; nUnfragmentedLeft > KUnfragmentedFilesLeave; ++i)
sl@0
   251
    {
sl@0
   252
        nUnfragmentedLeft -= DoMergeTestFiles(aFTagArray, i, usCurrTime);
sl@0
   253
        usTotalTime += usCurrTime;
sl@0
   254
    }
sl@0
   255
sl@0
   256
    test.Printf(_L("#--> Merging files :%d ms\n"), (TUint32)usTotalTime/K1mSec);
sl@0
   257
}
sl@0
   258
sl@0
   259
//-------------------------------------------------------------------
sl@0
   260
/**
sl@0
   261
    Randomly shuffles entries in file name tags array.
sl@0
   262
*/
sl@0
   263
void ShuffleArray(CFileTagsArray& aFTagArray)
sl@0
   264
{
sl@0
   265
    const TInt KSwapIterations = 500;
sl@0
   266
    const TInt arrSize = aFTagArray.Count();
sl@0
   267
sl@0
   268
sl@0
   269
    for(TInt i = 0; i<KSwapIterations; ++i)
sl@0
   270
    {//-- randomly swap 2 elements in the array
sl@0
   271
        const TInt idx1 = (TUint)Math::Rand(gRndSeed) % arrSize;
sl@0
   272
        const TInt idx2 = (TUint)Math::Rand(gRndSeed) % arrSize;
sl@0
   273
sl@0
   274
        TInt tmp = aFTagArray[idx1];
sl@0
   275
        aFTagArray[idx1] = aFTagArray[idx2];;
sl@0
   276
        aFTagArray[idx2] = tmp;
sl@0
   277
    }
sl@0
   278
sl@0
   279
}
sl@0
   280
sl@0
   281
//----------------------------------------------------------------------------------------------
sl@0
   282
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0690
sl@0
   283
//! @SYMTestType        PT
sl@0
   284
//! @SYMPREQ            PREQ1721
sl@0
   285
//! @SYMTestCaseDesc    Measure open and seek time for all files that have tags in aFTagArray.
sl@0
   286
//!
sl@0
   287
//! @SYMTestActions
sl@0
   288
//!                     0   remount FS
sl@0
   289
//!                     1   open all files, that have tags in aFTagArray, measure time taken
sl@0
   290
//!                     2   seek to the each file end, measure time taken
sl@0
   291
//!
sl@0
   292
//! @SYMTestExpectedResults successful files open/seek
sl@0
   293
//! @SYMTestPriority        High
sl@0
   294
//! @SYMTestStatus          Implemented
sl@0
   295
//----------------------------------------------------------------------------------------------
sl@0
   296
void MeasureSeekTime(CFileTagsArray& aFTagArray)
sl@0
   297
{
sl@0
   298
    test.Next(_L("Measuring seek time...\n"));
sl@0
   299
sl@0
   300
    TInt nRes;
sl@0
   301
    RFile file;
sl@0
   302
    TBuf<128> buf;
sl@0
   303
sl@0
   304
    TTime   timeStart;
sl@0
   305
    TTime   timeEnd;
sl@0
   306
    TInt64  usTotalTimeSeek=0;
sl@0
   307
    TInt64  usTotalTimeOpen=0;
sl@0
   308
sl@0
   309
    const TInt KNumRepetitions = 10;
sl@0
   310
sl@0
   311
    for(TInt repCnt=0; repCnt<KNumRepetitions; ++repCnt)
sl@0
   312
    {
sl@0
   313
        //-- remount file system, reset caches
sl@0
   314
        DoRemountFS(gDriveNum);
sl@0
   315
sl@0
   316
        for(TInt i = 0; i<aFTagArray.Count(); ++i)
sl@0
   317
        {
sl@0
   318
            MakeFileName(buf, aFTagArray[i]);
sl@0
   319
sl@0
   320
            //-- 1. open the file
sl@0
   321
            timeStart.UniversalTime(); //-- take start time
sl@0
   322
sl@0
   323
                nRes = file.Open(TheFs, buf, EFileRead);
sl@0
   324
sl@0
   325
            timeEnd.UniversalTime(); //-- take end time
sl@0
   326
            usTotalTimeOpen += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   327
sl@0
   328
            test_KErrNone(nRes);
sl@0
   329
sl@0
   330
sl@0
   331
            //-- 2. goto the end of the file. This operation shall traverse whole file's cluster chain in FAT
sl@0
   332
            timeStart.UniversalTime(); //-- take start time
sl@0
   333
sl@0
   334
                TInt seekPos = 0;
sl@0
   335
                nRes = file.Seek(ESeekEnd, seekPos);
sl@0
   336
sl@0
   337
            timeEnd.UniversalTime(); //-- take end time
sl@0
   338
            usTotalTimeSeek += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   339
sl@0
   340
            test_KErrNone(nRes);
sl@0
   341
            file.Close();
sl@0
   342
        }
sl@0
   343
    }
sl@0
   344
sl@0
   345
    test.Printf(_L("#--> Total open time for %d files is %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTimeOpen/(K1mSec*KNumRepetitions));
sl@0
   346
    test.Printf(_L("#--> Total seek time for %d files is %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTimeSeek/(K1mSec*KNumRepetitions));
sl@0
   347
}
sl@0
   348
sl@0
   349
sl@0
   350
//----------------------------------------------------------------------------------------------
sl@0
   351
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0692
sl@0
   352
//! @SYMTestType        PT
sl@0
   353
//! @SYMPREQ            PREQ1721
sl@0
   354
//! @SYMTestCaseDesc    Detetes all files that have name tags in name tags array and measures time taken.
sl@0
   355
//!
sl@0
   356
//! @SYMTestActions
sl@0
   357
//!                     0   remount the FS
sl@0
   358
//!                     1   delete files and measure time taken.
sl@0
   359
//!
sl@0
   360
//! @SYMTestExpectedResults successful creating files
sl@0
   361
//! @SYMTestPriority        High
sl@0
   362
//! @SYMTestStatus          Implemented
sl@0
   363
//----------------------------------------------------------------------------------------------
sl@0
   364
void DeleteAllFiles(CFileTagsArray& aFTagArray)
sl@0
   365
{
sl@0
   366
    TInt nRes;
sl@0
   367
    TBuf<128> buf;
sl@0
   368
sl@0
   369
    TTime   timeStart;
sl@0
   370
    TTime   timeEnd;
sl@0
   371
    TInt64  usTotalTime=0;
sl@0
   372
sl@0
   373
    test.Next(_L("Deleting all files...\n"));
sl@0
   374
sl@0
   375
    //-- remount file system, reset caches
sl@0
   376
    DoRemountFS(gDriveNum);
sl@0
   377
sl@0
   378
    for(TInt i = 0; i<aFTagArray.Count(); ++i)
sl@0
   379
    {
sl@0
   380
        MakeFileName(buf, aFTagArray[i]);
sl@0
   381
sl@0
   382
        timeStart.UniversalTime(); //-- take start time
sl@0
   383
sl@0
   384
        nRes = TheFs.Delete(buf);
sl@0
   385
sl@0
   386
        timeEnd.UniversalTime(); //-- take end time
sl@0
   387
        usTotalTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   388
sl@0
   389
        test_KErrNone(nRes);
sl@0
   390
    }
sl@0
   391
sl@0
   392
    test.Printf(_L("#--> Deleted %d files in %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTime/K1mSec);
sl@0
   393
}
sl@0
   394
sl@0
   395
//----------------------------------------------------------------------------------------------
sl@0
   396
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0687
sl@0
   397
//! @SYMTestType        PT
sl@0
   398
//! @SYMPREQ            PREQ1721
sl@0
   399
//! @SYMTestCaseDesc    Create KMaxFiles files to fill in space in FAT table and measure time taken.
sl@0
   400
//!
sl@0
   401
//! @SYMTestActions
sl@0
   402
//!                     0   Create KMaxFiles files and measure time taken.
sl@0
   403
//!
sl@0
   404
//! @SYMTestExpectedResults successful creating files
sl@0
   405
//! @SYMTestPriority        High
sl@0
   406
//! @SYMTestStatus          Implemented
sl@0
   407
//----------------------------------------------------------------------------------------------
sl@0
   408
/**
sl@0
   409
    Create KMaxFiles files to fill in space in FAT table and measure time taken.
sl@0
   410
    @return EFalse if it is impossible to create test files
sl@0
   411
*/
sl@0
   412
TBool DoCreateFiles(CFileTagsArray& aFTagArray)
sl@0
   413
{
sl@0
   414
    TInt nRes;
sl@0
   415
    TBuf<128> buf;
sl@0
   416
sl@0
   417
    TTime   timeStart;
sl@0
   418
    TTime   timeEnd;
sl@0
   419
    TInt64  usTotalTime=0;
sl@0
   420
sl@0
   421
    test.Next(_L("Creating many files\n"));
sl@0
   422
    test.Printf(_L("Number of files:%d\n"), KMaxFiles);
sl@0
   423
sl@0
   424
    aFTagArray.Reset();
sl@0
   425
sl@0
   426
    TVolumeInfo volInfo;
sl@0
   427
    nRes = TheFs.Volume(volInfo, gDriveNum);
sl@0
   428
    test_KErrNone(nRes);
sl@0
   429
sl@0
   430
sl@0
   431
    test(gBootSector.IsValid());
sl@0
   432
sl@0
   433
    const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
sl@0
   434
    const TUint32 maxClusters = (TUint32)(volInfo.iFree / clustSz);
sl@0
   435
sl@0
   436
    if(KMaxFiles > 0.8 * maxClusters)
sl@0
   437
    {
sl@0
   438
        test.Printf(_L("Can't create %d files; skipping the test!\n"), KMaxFiles);
sl@0
   439
        return EFalse;
sl@0
   440
    }
sl@0
   441
sl@0
   442
    //-- adjust file size for very small volumes
sl@0
   443
    TUint32 fillFileSz = (maxClusters/KMaxFiles)*clustSz;
sl@0
   444
    if(fillFileSz*KMaxFiles >= 0.8*volInfo.iFree) //-- take into account the size of the directory with 1000 files.
sl@0
   445
    {
sl@0
   446
        if(fillFileSz <= clustSz)
sl@0
   447
        {
sl@0
   448
            test.Printf(_L("Can't create %d files; skipping the test!\n"), KMaxFiles);
sl@0
   449
            return EFalse;
sl@0
   450
        }
sl@0
   451
sl@0
   452
        fillFileSz -= clustSz;
sl@0
   453
    }
sl@0
   454
sl@0
   455
    //-- create the first file on the volume. It will be deleted then in order to create 1 free FAT entry
sl@0
   456
    //-- in the very beginnng of the FAT. So, the size of this file shan't be more that 1 sector/cluster.
sl@0
   457
    nRes = CreateEmptyFile(TheFs, KFirstFileName, 100);
sl@0
   458
    test_KErrNone(nRes);
sl@0
   459
sl@0
   460
sl@0
   461
    //-- to avoid affected timings in UREL mode.
sl@0
   462
    WaitForFatBkGndActivityEnd();
sl@0
   463
sl@0
   464
    //-- disable FAT test utils print out, it affects measured time when we create empty files
sl@0
   465
    EnablePrintOutput(EFalse);
sl@0
   466
sl@0
   467
    //-- create KMaxFiles files on the volume
sl@0
   468
    for(TInt i=0; i<KMaxFiles; ++i)
sl@0
   469
    {
sl@0
   470
        //-- create empty file
sl@0
   471
        MakeFileName(buf, i);
sl@0
   472
sl@0
   473
        timeStart.UniversalTime(); //-- take start time
sl@0
   474
sl@0
   475
        nRes = CreateEmptyFile(TheFs, buf, fillFileSz);
sl@0
   476
sl@0
   477
        timeEnd.UniversalTime(); //-- take end time
sl@0
   478
        usTotalTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   479
sl@0
   480
        test_KErrNone(nRes);
sl@0
   481
        //-- put its id number to the array.
sl@0
   482
        aFTagArray.AppendL(i);
sl@0
   483
sl@0
   484
        if((i % 100) == 0)
sl@0
   485
            test.Printf(_L("*"));
sl@0
   486
sl@0
   487
    }
sl@0
   488
sl@0
   489
    EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
sl@0
   490
sl@0
   491
    test.Printf(_L("\n#--> Created %d files in %d ms\n"), KMaxFiles, (TUint32)usTotalTime/K1mSec);
sl@0
   492
sl@0
   493
    return ETrue;
sl@0
   494
}
sl@0
   495
sl@0
   496
//----------------------------------------------------------------------------------------------
sl@0
   497
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0691
sl@0
   498
//! @SYMTestType        PT
sl@0
   499
//! @SYMPREQ            PREQ1721
sl@0
   500
//! @SYMTestCaseDesc    Check that all FAT copies are the same.
sl@0
   501
//!
sl@0
   502
//! @SYMTestActions
sl@0
   503
//!                     0   read all available FAT copies and compare them
sl@0
   504
//!
sl@0
   505
//! @SYMTestExpectedResults all FAT copies on the vollume must be the same.
sl@0
   506
//! @SYMTestPriority        High
sl@0
   507
//! @SYMTestStatus          Implemented
sl@0
   508
//----------------------------------------------------------------------------------------------
sl@0
   509
void CheckFatCopies()
sl@0
   510
{
sl@0
   511
    test.Next(_L("Comparing FATs...\n"));
sl@0
   512
sl@0
   513
    TFatBootSector bootSec;
sl@0
   514
sl@0
   515
    TInt nRes = ReadBootSector(TheFs, gDriveNum, 0x00, bootSec);
sl@0
   516
    test_KErrNone(nRes);
sl@0
   517
sl@0
   518
    const TInt numFATs = bootSec.NumberOfFats();
sl@0
   519
    if(numFATs < 2)
sl@0
   520
    {//-- only one FAT, nothing to compare with.
sl@0
   521
        test.Printf(_L("The volume has only 1 FAT. Nothing to do.\n"));
sl@0
   522
        return;
sl@0
   523
    }
sl@0
   524
sl@0
   525
    const TUint32 bytesPerSec = bootSec.BytesPerSector();
sl@0
   526
    const TUint32 posFat1Start =  bootSec.FirstFatSector() * bytesPerSec;
sl@0
   527
    const TUint32 fatSize = bootSec.TotalFatSectors() * bytesPerSec;
sl@0
   528
sl@0
   529
    RBuf8 fatBuf1;
sl@0
   530
    RBuf8 fatBuf2;
sl@0
   531
sl@0
   532
    nRes = fatBuf1.CreateMax(bytesPerSec);
sl@0
   533
    test_KErrNone(nRes);
sl@0
   534
sl@0
   535
    nRes = fatBuf2.CreateMax(bytesPerSec);
sl@0
   536
    test_KErrNone(nRes);
sl@0
   537
sl@0
   538
    //-- read FAT sector by sector comparing all copies
sl@0
   539
    TUint32 currPos = posFat1Start;
sl@0
   540
    for(TUint cntSectors=0; cntSectors<bootSec.TotalFatSectors(); ++cntSectors)
sl@0
   541
    {
sl@0
   542
        //-- read a sector of FAT#0
sl@0
   543
        nRes = MediaRawRead(TheFs, gDriveNum, currPos, bytesPerSec, fatBuf1);
sl@0
   544
        test_KErrNone(nRes);
sl@0
   545
sl@0
   546
        //-- read the same sector from other copies of FAT and compare with FAT#0
sl@0
   547
        for(TInt currFat=1; currFat<numFATs; ++currFat)
sl@0
   548
        {
sl@0
   549
            nRes = MediaRawRead(TheFs, gDriveNum, (currFat*fatSize + currPos), bytesPerSec, fatBuf2);
sl@0
   550
            test_KErrNone(nRes);
sl@0
   551
sl@0
   552
            //-- compare the buffer to FAT#0
sl@0
   553
            if(fatBuf1.CompareF(fatBuf2) !=0)
sl@0
   554
            {//-- current FAT is different from FAT0
sl@0
   555
             test.Printf(_L("FAT#%d differs from FAT#0! FAT sector:%d, media Sector:%d\n"), currFat, cntSectors, cntSectors+bootSec.FirstFatSector());
sl@0
   556
             test(0);
sl@0
   557
            }
sl@0
   558
sl@0
   559
        }
sl@0
   560
sl@0
   561
sl@0
   562
        currPos+=bytesPerSec;
sl@0
   563
    }
sl@0
   564
sl@0
   565
sl@0
   566
    fatBuf1.Close();
sl@0
   567
    fatBuf2.Close();
sl@0
   568
sl@0
   569
}
sl@0
   570
sl@0
   571
//----------------------------------------------------------------------------------------------
sl@0
   572
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0688
sl@0
   573
//! @SYMTestType        PT
sl@0
   574
//! @SYMPREQ            PREQ1721
sl@0
   575
//! @SYMTestCaseDesc    Create the file whose FAT entries will go to the end of the FAT table and measure the time taken.
sl@0
   576
//!
sl@0
   577
//! @SYMTestActions
sl@0
   578
//!                     0   delete a file in the very beginning of the FAT
sl@0
   579
//!                     1   remount file system
sl@0
   580
//!                     2   create a larger file finishing at the end of FAT, measure time taken
sl@0
   581
//!
sl@0
   582
//! @SYMTestExpectedResults successful files creation
sl@0
   583
//! @SYMTestPriority        High
sl@0
   584
//! @SYMTestStatus          Implemented
sl@0
   585
//----------------------------------------------------------------------------------------------
sl@0
   586
sl@0
   587
/**
sl@0
   588
    Create the file whose FAT entries will go to the end of the FAT table and measure the time taken.
sl@0
   589
    preconditions:
sl@0
   590
    1. The FAT table must be almost full already. This is done previously in DoCreateFiles().
sl@0
   591
    2. There shall be a small file in the very beginning of the FAT which this test deletes and remounts the FS.
sl@0
   592
       this will cause "the last known free cluster"  in the FAT to be set to the beginning of the FAT.
sl@0
   593
sl@0
   594
    Then when we create a larger file, whole occupied FAT region will be scanned for the free cluster.
sl@0
   595
*/
sl@0
   596
void CreateLastFile()
sl@0
   597
{
sl@0
   598
    test.Next(_L("Create a file in the end of FAT\n"));
sl@0
   599
sl@0
   600
    TTime   timeStart;
sl@0
   601
    TTime   timeEnd;
sl@0
   602
    TInt64  usTotalTime=0;
sl@0
   603
sl@0
   604
    TInt nRes;
sl@0
   605
sl@0
   606
sl@0
   607
    //-- 1. delete the first file on the volume (see KFirstFileName & DoCreateFiles()
sl@0
   608
    //-- it will create free FAT entry in the very beginning.
sl@0
   609
    nRes = TheFs.Delete(KFirstFileName);
sl@0
   610
    test_KErrNone(nRes);
sl@0
   611
sl@0
   612
sl@0
   613
    //-- 2. remount file system, reset caches etc. The first known free cluster will be number 2 or 3, because of the point 1.
sl@0
   614
    //-- the rest of the FAT is filled, because we've created plenty of files in the DoCreateFiles()
sl@0
   615
    DoRemountFS(gDriveNum);
sl@0
   616
sl@0
   617
    //-- 3. create a file that will occupy more that 2 clusters; the 1st cluster of it will be in the very beginning of the FAT,
sl@0
   618
    //-- and the rest will be in the very end of the FAT. Measure the time taken to walk all FAT when searching free entry.
sl@0
   619
    _LIT(KLastFn, "\\last-last.file");
sl@0
   620
sl@0
   621
    test(gBootSector.IsValid());
sl@0
   622
sl@0
   623
    const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
sl@0
   624
sl@0
   625
sl@0
   626
    //-- disable FAT test utils print out, it affects measured time
sl@0
   627
    EnablePrintOutput(EFalse);
sl@0
   628
sl@0
   629
    timeStart.UniversalTime(); //-- take start time
sl@0
   630
sl@0
   631
    //-- create an empty file, it is supposed to be placed in the very end of FAT (FAT table is almost full because of the
sl@0
   632
    //-- previous test)
sl@0
   633
    nRes = CreateEmptyFile(TheFs, KLastFn, 7*clustSz);
sl@0
   634
sl@0
   635
    timeEnd.UniversalTime(); //-- take end time
sl@0
   636
    usTotalTime = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   637
sl@0
   638
    test_KErrNone(nRes);
sl@0
   639
sl@0
   640
    test.Printf(_L("#--> file at the end of FAT created in %d ms\n"), (TUint32)usTotalTime/K1mSec);
sl@0
   641
sl@0
   642
    //-- delete the file
sl@0
   643
    nRes = TheFs.Delete(KLastFn);
sl@0
   644
    test_KErrNone(nRes);
sl@0
   645
sl@0
   646
    EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
sl@0
   647
}
sl@0
   648
sl@0
   649
//-------------------------------------------------------------------
sl@0
   650
/**
sl@0
   651
    Create 100 directories in the root and measure time
sl@0
   652
*/
sl@0
   653
void DoCreateDirsInRoot()
sl@0
   654
{
sl@0
   655
    test.Next(_L("Measure time to create many directories in the Root.\n"));
sl@0
   656
sl@0
   657
    if(!Is_Fat32(TheFs, gDriveNum))
sl@0
   658
    {
sl@0
   659
        test.Printf(_L("This test requires FAT32, skipping\n"));
sl@0
   660
        return;
sl@0
   661
    }
sl@0
   662
sl@0
   663
    TTime   timeStart;
sl@0
   664
    TTime   timeEnd;
sl@0
   665
    TInt64  usTotalTime=0;
sl@0
   666
    TFileName dirName;
sl@0
   667
sl@0
   668
    //-- remount file system, reset caches etc. The first known free cluster will be number 2 or 3
sl@0
   669
    DoRemountFS(gDriveNum);
sl@0
   670
sl@0
   671
    //-- disable FAT test utils print out, it affects measured time
sl@0
   672
    EnablePrintOutput(EFalse);
sl@0
   673
sl@0
   674
    timeStart.UniversalTime(); //-- take start time
sl@0
   675
sl@0
   676
    //-- create some subdirectories in the root dir and measure time
sl@0
   677
    const TInt KMaxDirs = 100;
sl@0
   678
    for(TInt i=0; i<KMaxDirs; ++i)
sl@0
   679
    {
sl@0
   680
        dirName.Format(_L("\\directory%04d\\"), i);
sl@0
   681
        TInt nRes = TheFs.MkDir(dirName);
sl@0
   682
        test_KErrNone(nRes);
sl@0
   683
    }
sl@0
   684
sl@0
   685
    timeEnd.UniversalTime(); //-- take end time
sl@0
   686
    usTotalTime = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   687
sl@0
   688
    test.Printf(_L("#--> %d Dirs. created in %d ms\n"), KMaxDirs, (TUint32)usTotalTime/K1mSec);
sl@0
   689
sl@0
   690
    EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
sl@0
   691
}
sl@0
   692
sl@0
   693
//----------------------------------------------------------------------------------------------
sl@0
   694
//! @SYMTestCaseID      PBASE-T_FATCACHE_BM-0693
sl@0
   695
//! @SYMTestType        PT
sl@0
   696
//! @SYMPREQ            PREQ1721
sl@0
   697
//! @SYMTestCaseDesc    Create a large file (2G max) and measure the time. Then delete this file and measure time taken
sl@0
   698
//!
sl@0
   699
//! @SYMTestActions
sl@0
   700
//!                     0   quick format the volume
sl@0
   701
//!                     1   create emply file that takes either 80% of the volume of 2G max, masure time taken
sl@0
   702
//!                     2   remount FS
sl@0
   703
//!                     3   delete this file and measure time taken
sl@0
   704
//!
sl@0
   705
//! @SYMTestExpectedResults successful files creation/deletion
sl@0
   706
//! @SYMTestPriority        High
sl@0
   707
//! @SYMTestStatus          Implemented
sl@0
   708
//----------------------------------------------------------------------------------------------
sl@0
   709
static void CreateLargeFile()
sl@0
   710
{
sl@0
   711
    test.Next(_L("Create a large file and measure time\n"));
sl@0
   712
sl@0
   713
    FormatVolume(ETrue); //-- quick format the volume.
sl@0
   714
sl@0
   715
    _LIT(KBigFileName, "\\BigFile.big");
sl@0
   716
sl@0
   717
    test(gBootSector.IsValid());
sl@0
   718
sl@0
   719
    //-- calculate the size of the file, it shall be max 2G or take almost all volume
sl@0
   720
    TVolumeInfo volInfo;
sl@0
   721
    TInt nRes;
sl@0
   722
sl@0
   723
    nRes = TheFs.Volume(volInfo, gDriveNum);
sl@0
   724
    test_KErrNone(nRes);
sl@0
   725
sl@0
   726
    const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
sl@0
   727
    const TUint32 maxClusters = (TUint32)(volInfo.iFree / clustSz);
sl@0
   728
sl@0
   729
    const TUint32 clustersPer1G = K1GigaByte / clustSz;
sl@0
   730
    const TUint32 clustersPer2G = 2*clustersPer1G;
sl@0
   731
sl@0
   732
    TUint32 fileClusters=0;
sl@0
   733
    if(maxClusters*0.8 < clustersPer2G)
sl@0
   734
        fileClusters = (TUint32)(maxClusters*0.8);
sl@0
   735
    else
sl@0
   736
        fileClusters = (TUint32)(clustersPer2G*0.8);
sl@0
   737
sl@0
   738
    const TUint32 fileSize = fileClusters*clustSz;
sl@0
   739
sl@0
   740
    //-- create empty file and measure time
sl@0
   741
    TTime   timeStart;
sl@0
   742
    TTime   timeEnd;
sl@0
   743
    TInt64  usTimeCreate=0;
sl@0
   744
    TInt64  usTimeDelete=0;
sl@0
   745
sl@0
   746
    timeStart.UniversalTime(); //-- take start time
sl@0
   747
    nRes = CreateEmptyFile(TheFs, KBigFileName, fileSize);
sl@0
   748
    timeEnd.UniversalTime(); //-- take end time
sl@0
   749
    test_KErrNone(nRes);
sl@0
   750
sl@0
   751
    usTimeCreate = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   752
sl@0
   753
    //-- remount file system, reset caches etc.
sl@0
   754
    DoRemountFS(gDriveNum);
sl@0
   755
sl@0
   756
    //-- delete the file
sl@0
   757
    timeStart.UniversalTime(); //-- take start time
sl@0
   758
    nRes = TheFs.Delete(KBigFileName);
sl@0
   759
    timeEnd.UniversalTime(); //-- take end time
sl@0
   760
sl@0
   761
    test_KErrNone(nRes);
sl@0
   762
    usTimeDelete = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
sl@0
   763
sl@0
   764
    test.Printf(_L("#--> Big file sz:%u created:%d ms, deleted:%d ms\n"), fileSize, (TUint32)(usTimeCreate/K1mSec) , (TUint32)(usTimeDelete/K1mSec));
sl@0
   765
sl@0
   766
}
sl@0
   767
sl@0
   768
sl@0
   769
//-------------------------------------------------------------------
sl@0
   770
/**
sl@0
   771
    Start tests.
sl@0
   772
*/
sl@0
   773
void RunTest()
sl@0
   774
{
sl@0
   775
    test.Printf(_L("Prepare the volume for BM testing...\n"));
sl@0
   776
sl@0
   777
    test(pFTagArray != NULL);
sl@0
   778
    CFileTagsArray &fTagArray = *pFTagArray;
sl@0
   779
    fTagArray.Reset();
sl@0
   780
sl@0
   781
    //-- full format the drive
sl@0
   782
    FormatVolume(EFalse);
sl@0
   783
sl@0
   784
    test.Printf(_L("\n#--> t_fatcache_bm\n"));
sl@0
   785
sl@0
   786
    //-- create test directory.
sl@0
   787
    MakeDir(KDirName);
sl@0
   788
sl@0
   789
    //-- 1. create KMaxFiles files to fill in space in FAT table.
sl@0
   790
    if(!DoCreateFiles(fTagArray))
sl@0
   791
        return; //-- test is inconsistent
sl@0
   792
sl@0
   793
sl@0
   794
    //-- 1.1 create a file in the very end of the full volume (FAT table is almost full). Measure time taken
sl@0
   795
    CreateLastFile();
sl@0
   796
sl@0
   797
    //-- 1.2 create multiple directories in the root and measure time
sl@0
   798
//    DoCreateDirsInRoot();
sl@0
   799
sl@0
   800
    //-- 2. randomly merge some small files to bigger ones that will be fragmented
sl@0
   801
    DoMergeFiles(fTagArray);
sl@0
   802
sl@0
   803
    //-- 3. randomly shuffle file tags in the array
sl@0
   804
    ShuffleArray(fTagArray);
sl@0
   805
sl@0
   806
    //-- 4. measure file open and seek time
sl@0
   807
    MeasureSeekTime(fTagArray);
sl@0
   808
sl@0
   809
    //-- 4.5 Check that all copies of FAT are the same.
sl@0
   810
    CheckFatCopies();
sl@0
   811
sl@0
   812
    //-- 5. delete all files and print out time taken
sl@0
   813
    DeleteAllFiles(fTagArray);
sl@0
   814
sl@0
   815
    //-- 6. Create a large file (2G max) and measure the time
sl@0
   816
    //!!!!
sl@0
   817
    CreateLargeFile();
sl@0
   818
sl@0
   819
}
sl@0
   820
sl@0
   821
sl@0
   822
sl@0
   823
//-------------------------------------------------------------------
sl@0
   824
static void WaitForFatBkGndActivityEnd()
sl@0
   825
{
sl@0
   826
    //-- if we work in release mode, we need to use a hardcore solution to wait until possible FAT background activity finishes
sl@0
   827
    //-- because transient FAT threads can affect timings (e.g. creating a file may need waiting to FAT background thread to
sl@0
   828
    //-- parse some portion of FAT) etc.
sl@0
   829
    //-- for debug mode background FAT activity is disabled in InitGlobals() and timings are not precise anyway
sl@0
   830
    //-- for release mode we just need to wait some time
sl@0
   831
    #ifndef _DEBUG
sl@0
   832
    const TInt KWaitTimeSec = 10;
sl@0
   833
    test.Printf(_L("waiting %d sec...\n"), KWaitTimeSec);
sl@0
   834
    User::After(KWaitTimeSec*K1Sec);
sl@0
   835
    #endif
sl@0
   836
sl@0
   837
}
sl@0
   838
sl@0
   839
sl@0
   840
sl@0
   841
//-------------------------------------------------------------------
sl@0
   842
sl@0
   843
/**
sl@0
   844
    Dismounts and mounts the FS on a drive aDrive
sl@0
   845
    This will cause resetting "last known free cluster number" value in the FAT table implementation in FSY.
sl@0
   846
    (Mounting enhancements are disabled.) Empty the caches etc.
sl@0
   847
*/
sl@0
   848
static void DoRemountFS(TInt aDrive)
sl@0
   849
{
sl@0
   850
    TInt nRes = RemountFS(TheFs, aDrive);
sl@0
   851
    test_KErrNone(nRes);
sl@0
   852
sl@0
   853
    //-- get volume info, this is a trick that can help avoiding asynchronous FAT mount in UREL mode
sl@0
   854
    //TVolumeInfo v;
sl@0
   855
    //nRes = TheFs.Volume(v);
sl@0
   856
sl@0
   857
    //-- to avoid affected timings in UREL mode.
sl@0
   858
    WaitForFatBkGndActivityEnd();
sl@0
   859
}
sl@0
   860
sl@0
   861
sl@0
   862
//-------------------------------------------------------------------
sl@0
   863
sl@0
   864
/** initialise test global objects */
sl@0
   865
static void InitGlobals()
sl@0
   866
{
sl@0
   867
    //-- initialise random generator
sl@0
   868
    gRndSeed = 0x67fc1a9;
sl@0
   869
sl@0
   870
    //-- construct file numbers array
sl@0
   871
    pFTagArray = new CFileTagsArray(KMaxFiles);
sl@0
   872
    test(pFTagArray != NULL);
sl@0
   873
    pFTagArray->SetReserveL(KMaxFiles);
sl@0
   874
sl@0
   875
    //-- define a propery which will control mount process in the fsy.
sl@0
   876
    //-- The property key is a drive number being tested
sl@0
   877
    _LIT_SECURITY_POLICY_PASS(KTestPropPolicy);
sl@0
   878
    TInt nRes = RProperty::Define(KThisTestSID, gDriveNum, RProperty::EInt, KTestPropPolicy, KTestPropPolicy);
sl@0
   879
    test(nRes == KErrNone || nRes == KErrAlreadyExists);
sl@0
   880
sl@0
   881
    //-- disable all volume mount enhancements, like asynch mount and FSInfo.
sl@0
   882
    //-- this works only in debug mode.
sl@0
   883
    nRes = RProperty::Set(KThisTestSID, gDriveNum, (TInt)KMntProp_DisableALL);
sl@0
   884
    test_KErrNone(nRes);
sl@0
   885
sl@0
   886
}
sl@0
   887
sl@0
   888
/** destroy test global objects */
sl@0
   889
static void DestroyGlobals()
sl@0
   890
{
sl@0
   891
    delete pFTagArray;
sl@0
   892
sl@0
   893
    //-- delete test property
sl@0
   894
    RProperty::Delete(KThisTestSID, gDriveNum);
sl@0
   895
sl@0
   896
}
sl@0
   897
sl@0
   898
sl@0
   899
//-------------------------------------------------------------------
sl@0
   900
void CallTestsL()
sl@0
   901
    {
sl@0
   902
sl@0
   903
    //-- set up console output
sl@0
   904
    Fat_Test_Utils::SetConsole(test.Console());
sl@0
   905
sl@0
   906
    TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum);
sl@0
   907
    test(nRes==KErrNone);
sl@0
   908
sl@0
   909
    //-- check if this is FAT
sl@0
   910
    if(!Is_Fat(TheFs, gDriveNum))
sl@0
   911
    {
sl@0
   912
        test.Printf(_L("Skipping. This test requires FAT drive.\n"));
sl@0
   913
        return;
sl@0
   914
    }
sl@0
   915
sl@0
   916
    //-- check this is not the internal ram drive
sl@0
   917
    TVolumeInfo v;
sl@0
   918
    nRes = TheFs.Volume(v);
sl@0
   919
    test(nRes==KErrNone);
sl@0
   920
    if(v.iDrive.iMediaAtt & KMediaAttVariableSize)
sl@0
   921
        {
sl@0
   922
        test.Printf(_L("Skipping. Internal ram drive not tested.\n"));
sl@0
   923
        return;
sl@0
   924
        }
sl@0
   925
sl@0
   926
sl@0
   927
    //-------------------------------------
sl@0
   928
    PrintDrvInfo(TheFs, gDriveNum);
sl@0
   929
sl@0
   930
    InitGlobals();
sl@0
   931
sl@0
   932
    RunTest();
sl@0
   933
sl@0
   934
    //-------------------------------------
sl@0
   935
    DestroyGlobals();
sl@0
   936
sl@0
   937
    }
sl@0
   938
sl@0
   939
sl@0
   940
sl@0
   941
sl@0
   942
sl@0
   943
sl@0
   944
sl@0
   945
sl@0
   946
sl@0
   947
sl@0
   948
sl@0
   949
sl@0
   950
sl@0
   951
sl@0
   952
sl@0
   953
sl@0
   954