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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\server\t_mount.cpp
15 // Testing FAT cache performance
23 #define __E32TEST_EXTENSION__
28 #include <e32property.h>
33 #include "fat_utils.h"
35 using namespace Fat_Test_Utils;
38 // Solve compilation problem caused by non-English locale
39 #pragma setlocale("english")
42 RTest test(_L("T_FAT_Cache_BM"));
44 //-- note that this test disables all FAT mount enhancements, like asynchronous mounting and using FSInfo sector.
46 static void WaitForFatBkGndActivityEnd();
48 //-------------------------------------------------------------------
49 //-- debug bit flags that may be set in the property which controls FAT volume mounting
51 const TUid KThisTestSID={0x10210EB3}; ///< this EXE SID
53 //const TUint32 KMntProp_EnableALL = 0x00000000; //-- enable all operations
54 const TUint32 KMntProp_DisableALL = 0xFFFFFFFF; //-- disable all operations
56 //const TUint32 KMntProp_Disable_FsInfo = 0x00000001; //-- mask for disabling/enabling FSInfo information
57 //const TUint32 KMntProp_Disable_FatBkGndScan = 0x00000002; //-- mask for disabling/enabling FAT background scanner
59 //-------------------------------------------------------------------
61 static TInt gDriveNum=-1; ///< drive number we are dealing with
62 static TInt64 gRndSeed;
63 static TFatBootSector gBootSector;
65 static void DoRemountFS(TInt aDrive);
67 //-- Array of integer file tars. Tags are used to identify files (the file name is generated by KFnTemplate template)
68 typedef CArrayFixFlat<TInt> CFileTagsArray;
69 static CFileTagsArray *pFTagArray = NULL;
72 //-------------------------------------------------------------------
73 const TInt KMaxFiles = 1000; //-- maximal number of files to create
75 //-- number of unfragmented files that will be left, other files will be merged to bigger ones.
76 const TInt KUnfragmentedFilesLeave = KMaxFiles/10;
78 _LIT(KDirName, "\\DIR1\\"); //-- directory name we a working with (FAT12/16 won't allow KMaxFiles in the root dir.)
79 _LIT(KFirstFileName, "\\First_file_1.nul"); //-- the name of the first file on the volume
81 //-------------------------------------------------------------------
84 Make a file name by its numeric tag
85 @param aDes here will be a file name
86 @param aFileNameTag numeric tag for the file name generation
89 void MakeFileName(TDes& aDes, TInt aFileNameTag)
91 _LIT(KFnTemplate, "F%d.NUL");//-- file name template, use 8.3 names here in order not to stress dir. cache much.
93 aDes.AppendFormat(KFnTemplate, aFileNameTag);
96 //-------------------------------------------------------------------
98 format the volume and read the boot sector
100 static void FormatVolume(TBool aQuickFormat)
105 test.Printf(_L("This is emulator configuration!!!!\n"));
107 //-- FAT32 SPC:1; for the FAT32 testing on the emulator
108 //TFatFormatParam fp;
109 //fp.iFatType = EFat32;
110 //fp.iSecPerCluster = 1;
111 //FormatFatDrive(TheFs, CurrentDrive(), ETrue, &fp); //-- always quick; doesn't matter for the emulator
113 aQuickFormat = ETrue;
117 FormatFatDrive(TheFs, CurrentDrive(), aQuickFormat);
120 TInt nRes = ReadBootSector(TheFs, gDriveNum, 0x00, gBootSector);
125 //-------------------------------------------------------------------
128 Helper method. Does one iteration of merging test files into one fragmented one.
131 @param aFTagArray reference to the file tags array
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)
133 @param aTimeTaken_us on return will contain time taken to this operation, in microseconds
135 @return number of files merged into one.
137 TInt DoMergeTestFiles(CFileTagsArray& aFTagArray, TInt aBigFileNo, TInt64& aTimeTaken_us)
145 //-- merged files' names start with this number
146 const TInt KMergedFileFnThreshold = 20000;
148 const TInt KMaxMergedFiles = 20;
149 const TInt nFilesToMerge = Max((Math::Rand(gRndSeed) % KMaxMergedFiles), 2); //-- how many files to merge into one
151 test(aFTagArray.Count() > KMaxMergedFiles);
153 TInt selectedFTags[KMaxMergedFiles]; //-- here we will store file tags to be merged to one large fragmented file
160 //-- randomly select a file tag from the global array
161 const TInt index = (TUint)Math::Rand(gRndSeed) % aFTagArray.Count();
162 const TInt fnTag = aFTagArray[index];
164 if(fnTag < 0 || //-- no such file, already deleted
165 fnTag >= KMergedFileFnThreshold) //-- this is a big, already merged file
169 selectedFTags[i] = fnTag;
170 aFTagArray.Delete(index);
173 }while(i<nFilesToMerge);
175 //-- here we have file tags in selectedFNumbers array. delete these files and create one big file
176 //-- with the equal size. This file will be perfectly fragmented.
177 //-- search for FAT entries had priority to the right, so delete files in reverse order.
179 TUint32 newFileSize = 0;
183 timeStart.UniversalTime(); //-- take start time
185 for(i=0; i<nFilesToMerge; ++i)
187 MakeFileName(buf, selectedFTags[nFilesToMerge-1-i]);
189 nRes=file.Open(TheFs, buf, EFileRead);
193 nRes = file.Size(nSize);
197 newFileSize+=(TUint32)nSize; //-- this will be the size of the new file
199 //-- delete small file
200 nRes = TheFs.Delete(buf);
205 //-- create a large file taking the place of few smaller. It will be framented.
206 const TInt bigFileTag = aBigFileNo+KMergedFileFnThreshold;
208 MakeFileName(buf, bigFileTag);
209 nRes = CreateEmptyFile(TheFs, buf, newFileSize);
212 timeEnd.UniversalTime(); //-- take end time
213 aTimeTaken_us = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
215 //-- put new big file name tag to the global array in order not to forget it for later use.
216 aFTagArray.AppendL(bigFileTag);
218 return nFilesToMerge;
221 //----------------------------------------------------------------------------------------------
222 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0689
224 //! @SYMPREQ PREQ1721
225 //! @SYMTestCaseDesc randomly deletes small files and creates larger. Measures time taken by this FAT fragmentation
228 //! 0 delete a random number of small files
229 //! 1 create a random number of larger files, measure time taken
231 //! @SYMTestExpectedResults successful files deletion/creation
232 //! @SYMTestPriority High
233 //! @SYMTestStatus Implemented
234 //----------------------------------------------------------------------------------------------
237 precondition: We have a lot of (KMaxFiles) files of the same size on the volume. They occupy almost all FAT.
238 This method randomly selects several files on the volume, deletes them and creates a bigger file that occupies space from the
239 deleted files. So that we got a fragmented big file. Repeat this until we have KUnfragmentedFilesLeave initial files left on the
242 void DoMergeFiles(CFileTagsArray& aFTagArray)
244 test.Next(_L("Merging small files to larger creating FAT fragmentation...\n"));
246 TInt64 usTotalTime=0;
249 TInt nUnfragmentedLeft = aFTagArray.Count();
250 for(TInt i=0; nUnfragmentedLeft > KUnfragmentedFilesLeave; ++i)
252 nUnfragmentedLeft -= DoMergeTestFiles(aFTagArray, i, usCurrTime);
253 usTotalTime += usCurrTime;
256 test.Printf(_L("#--> Merging files :%d ms\n"), (TUint32)usTotalTime/K1mSec);
259 //-------------------------------------------------------------------
261 Randomly shuffles entries in file name tags array.
263 void ShuffleArray(CFileTagsArray& aFTagArray)
265 const TInt KSwapIterations = 500;
266 const TInt arrSize = aFTagArray.Count();
269 for(TInt i = 0; i<KSwapIterations; ++i)
270 {//-- randomly swap 2 elements in the array
271 const TInt idx1 = (TUint)Math::Rand(gRndSeed) % arrSize;
272 const TInt idx2 = (TUint)Math::Rand(gRndSeed) % arrSize;
274 TInt tmp = aFTagArray[idx1];
275 aFTagArray[idx1] = aFTagArray[idx2];;
276 aFTagArray[idx2] = tmp;
281 //----------------------------------------------------------------------------------------------
282 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0690
284 //! @SYMPREQ PREQ1721
285 //! @SYMTestCaseDesc Measure open and seek time for all files that have tags in aFTagArray.
289 //! 1 open all files, that have tags in aFTagArray, measure time taken
290 //! 2 seek to the each file end, measure time taken
292 //! @SYMTestExpectedResults successful files open/seek
293 //! @SYMTestPriority High
294 //! @SYMTestStatus Implemented
295 //----------------------------------------------------------------------------------------------
296 void MeasureSeekTime(CFileTagsArray& aFTagArray)
298 test.Next(_L("Measuring seek time...\n"));
306 TInt64 usTotalTimeSeek=0;
307 TInt64 usTotalTimeOpen=0;
309 const TInt KNumRepetitions = 10;
311 for(TInt repCnt=0; repCnt<KNumRepetitions; ++repCnt)
313 //-- remount file system, reset caches
314 DoRemountFS(gDriveNum);
316 for(TInt i = 0; i<aFTagArray.Count(); ++i)
318 MakeFileName(buf, aFTagArray[i]);
320 //-- 1. open the file
321 timeStart.UniversalTime(); //-- take start time
323 nRes = file.Open(TheFs, buf, EFileRead);
325 timeEnd.UniversalTime(); //-- take end time
326 usTotalTimeOpen += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
331 //-- 2. goto the end of the file. This operation shall traverse whole file's cluster chain in FAT
332 timeStart.UniversalTime(); //-- take start time
335 nRes = file.Seek(ESeekEnd, seekPos);
337 timeEnd.UniversalTime(); //-- take end time
338 usTotalTimeSeek += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
345 test.Printf(_L("#--> Total open time for %d files is %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTimeOpen/(K1mSec*KNumRepetitions));
346 test.Printf(_L("#--> Total seek time for %d files is %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTimeSeek/(K1mSec*KNumRepetitions));
350 //----------------------------------------------------------------------------------------------
351 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0692
353 //! @SYMPREQ PREQ1721
354 //! @SYMTestCaseDesc Detetes all files that have name tags in name tags array and measures time taken.
358 //! 1 delete files and measure time taken.
360 //! @SYMTestExpectedResults successful creating files
361 //! @SYMTestPriority High
362 //! @SYMTestStatus Implemented
363 //----------------------------------------------------------------------------------------------
364 void DeleteAllFiles(CFileTagsArray& aFTagArray)
371 TInt64 usTotalTime=0;
373 test.Next(_L("Deleting all files...\n"));
375 //-- remount file system, reset caches
376 DoRemountFS(gDriveNum);
378 for(TInt i = 0; i<aFTagArray.Count(); ++i)
380 MakeFileName(buf, aFTagArray[i]);
382 timeStart.UniversalTime(); //-- take start time
384 nRes = TheFs.Delete(buf);
386 timeEnd.UniversalTime(); //-- take end time
387 usTotalTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
392 test.Printf(_L("#--> Deleted %d files in %d ms\n"), aFTagArray.Count(), (TUint32)usTotalTime/K1mSec);
395 //----------------------------------------------------------------------------------------------
396 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0687
398 //! @SYMPREQ PREQ1721
399 //! @SYMTestCaseDesc Create KMaxFiles files to fill in space in FAT table and measure time taken.
402 //! 0 Create KMaxFiles files and measure time taken.
404 //! @SYMTestExpectedResults successful creating files
405 //! @SYMTestPriority High
406 //! @SYMTestStatus Implemented
407 //----------------------------------------------------------------------------------------------
409 Create KMaxFiles files to fill in space in FAT table and measure time taken.
410 @return EFalse if it is impossible to create test files
412 TBool DoCreateFiles(CFileTagsArray& aFTagArray)
419 TInt64 usTotalTime=0;
421 test.Next(_L("Creating many files\n"));
422 test.Printf(_L("Number of files:%d\n"), KMaxFiles);
427 nRes = TheFs.Volume(volInfo, gDriveNum);
431 test(gBootSector.IsValid());
433 const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
434 const TUint32 maxClusters = (TUint32)(volInfo.iFree / clustSz);
436 if(KMaxFiles > 0.8 * maxClusters)
438 test.Printf(_L("Can't create %d files; skipping the test!\n"), KMaxFiles);
442 //-- adjust file size for very small volumes
443 TUint32 fillFileSz = (maxClusters/KMaxFiles)*clustSz;
444 if(fillFileSz*KMaxFiles >= 0.8*volInfo.iFree) //-- take into account the size of the directory with 1000 files.
446 if(fillFileSz <= clustSz)
448 test.Printf(_L("Can't create %d files; skipping the test!\n"), KMaxFiles);
452 fillFileSz -= clustSz;
455 //-- create the first file on the volume. It will be deleted then in order to create 1 free FAT entry
456 //-- in the very beginnng of the FAT. So, the size of this file shan't be more that 1 sector/cluster.
457 nRes = CreateEmptyFile(TheFs, KFirstFileName, 100);
461 //-- to avoid affected timings in UREL mode.
462 WaitForFatBkGndActivityEnd();
464 //-- disable FAT test utils print out, it affects measured time when we create empty files
465 EnablePrintOutput(EFalse);
467 //-- create KMaxFiles files on the volume
468 for(TInt i=0; i<KMaxFiles; ++i)
470 //-- create empty file
471 MakeFileName(buf, i);
473 timeStart.UniversalTime(); //-- take start time
475 nRes = CreateEmptyFile(TheFs, buf, fillFileSz);
477 timeEnd.UniversalTime(); //-- take end time
478 usTotalTime += (timeEnd.MicroSecondsFrom(timeStart)).Int64();
481 //-- put its id number to the array.
482 aFTagArray.AppendL(i);
485 test.Printf(_L("*"));
489 EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
491 test.Printf(_L("\n#--> Created %d files in %d ms\n"), KMaxFiles, (TUint32)usTotalTime/K1mSec);
496 //----------------------------------------------------------------------------------------------
497 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0691
499 //! @SYMPREQ PREQ1721
500 //! @SYMTestCaseDesc Check that all FAT copies are the same.
503 //! 0 read all available FAT copies and compare them
505 //! @SYMTestExpectedResults all FAT copies on the vollume must be the same.
506 //! @SYMTestPriority High
507 //! @SYMTestStatus Implemented
508 //----------------------------------------------------------------------------------------------
509 void CheckFatCopies()
511 test.Next(_L("Comparing FATs...\n"));
513 TFatBootSector bootSec;
515 TInt nRes = ReadBootSector(TheFs, gDriveNum, 0x00, bootSec);
518 const TInt numFATs = bootSec.NumberOfFats();
520 {//-- only one FAT, nothing to compare with.
521 test.Printf(_L("The volume has only 1 FAT. Nothing to do.\n"));
525 const TUint32 bytesPerSec = bootSec.BytesPerSector();
526 const TUint32 posFat1Start = bootSec.FirstFatSector() * bytesPerSec;
527 const TUint32 fatSize = bootSec.TotalFatSectors() * bytesPerSec;
532 nRes = fatBuf1.CreateMax(bytesPerSec);
535 nRes = fatBuf2.CreateMax(bytesPerSec);
538 //-- read FAT sector by sector comparing all copies
539 TUint32 currPos = posFat1Start;
540 for(TUint cntSectors=0; cntSectors<bootSec.TotalFatSectors(); ++cntSectors)
542 //-- read a sector of FAT#0
543 nRes = MediaRawRead(TheFs, gDriveNum, currPos, bytesPerSec, fatBuf1);
546 //-- read the same sector from other copies of FAT and compare with FAT#0
547 for(TInt currFat=1; currFat<numFATs; ++currFat)
549 nRes = MediaRawRead(TheFs, gDriveNum, (currFat*fatSize + currPos), bytesPerSec, fatBuf2);
552 //-- compare the buffer to FAT#0
553 if(fatBuf1.CompareF(fatBuf2) !=0)
554 {//-- current FAT is different from FAT0
555 test.Printf(_L("FAT#%d differs from FAT#0! FAT sector:%d, media Sector:%d\n"), currFat, cntSectors, cntSectors+bootSec.FirstFatSector());
562 currPos+=bytesPerSec;
571 //----------------------------------------------------------------------------------------------
572 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0688
574 //! @SYMPREQ PREQ1721
575 //! @SYMTestCaseDesc Create the file whose FAT entries will go to the end of the FAT table and measure the time taken.
578 //! 0 delete a file in the very beginning of the FAT
579 //! 1 remount file system
580 //! 2 create a larger file finishing at the end of FAT, measure time taken
582 //! @SYMTestExpectedResults successful files creation
583 //! @SYMTestPriority High
584 //! @SYMTestStatus Implemented
585 //----------------------------------------------------------------------------------------------
588 Create the file whose FAT entries will go to the end of the FAT table and measure the time taken.
590 1. The FAT table must be almost full already. This is done previously in DoCreateFiles().
591 2. There shall be a small file in the very beginning of the FAT which this test deletes and remounts the FS.
592 this will cause "the last known free cluster" in the FAT to be set to the beginning of the FAT.
594 Then when we create a larger file, whole occupied FAT region will be scanned for the free cluster.
596 void CreateLastFile()
598 test.Next(_L("Create a file in the end of FAT\n"));
602 TInt64 usTotalTime=0;
607 //-- 1. delete the first file on the volume (see KFirstFileName & DoCreateFiles()
608 //-- it will create free FAT entry in the very beginning.
609 nRes = TheFs.Delete(KFirstFileName);
613 //-- 2. remount file system, reset caches etc. The first known free cluster will be number 2 or 3, because of the point 1.
614 //-- the rest of the FAT is filled, because we've created plenty of files in the DoCreateFiles()
615 DoRemountFS(gDriveNum);
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,
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.
619 _LIT(KLastFn, "\\last-last.file");
621 test(gBootSector.IsValid());
623 const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
626 //-- disable FAT test utils print out, it affects measured time
627 EnablePrintOutput(EFalse);
629 timeStart.UniversalTime(); //-- take start time
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
633 nRes = CreateEmptyFile(TheFs, KLastFn, 7*clustSz);
635 timeEnd.UniversalTime(); //-- take end time
636 usTotalTime = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
640 test.Printf(_L("#--> file at the end of FAT created in %d ms\n"), (TUint32)usTotalTime/K1mSec);
643 nRes = TheFs.Delete(KLastFn);
646 EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
649 //-------------------------------------------------------------------
651 Create 100 directories in the root and measure time
653 void DoCreateDirsInRoot()
655 test.Next(_L("Measure time to create many directories in the Root.\n"));
657 if(!Is_Fat32(TheFs, gDriveNum))
659 test.Printf(_L("This test requires FAT32, skipping\n"));
665 TInt64 usTotalTime=0;
668 //-- remount file system, reset caches etc. The first known free cluster will be number 2 or 3
669 DoRemountFS(gDriveNum);
671 //-- disable FAT test utils print out, it affects measured time
672 EnablePrintOutput(EFalse);
674 timeStart.UniversalTime(); //-- take start time
676 //-- create some subdirectories in the root dir and measure time
677 const TInt KMaxDirs = 100;
678 for(TInt i=0; i<KMaxDirs; ++i)
680 dirName.Format(_L("\\directory%04d\\"), i);
681 TInt nRes = TheFs.MkDir(dirName);
685 timeEnd.UniversalTime(); //-- take end time
686 usTotalTime = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
688 test.Printf(_L("#--> %d Dirs. created in %d ms\n"), KMaxDirs, (TUint32)usTotalTime/K1mSec);
690 EnablePrintOutput(ETrue); //-- Enable FAT test utils print out
693 //----------------------------------------------------------------------------------------------
694 //! @SYMTestCaseID PBASE-T_FATCACHE_BM-0693
696 //! @SYMPREQ PREQ1721
697 //! @SYMTestCaseDesc Create a large file (2G max) and measure the time. Then delete this file and measure time taken
700 //! 0 quick format the volume
701 //! 1 create emply file that takes either 80% of the volume of 2G max, masure time taken
703 //! 3 delete this file and measure time taken
705 //! @SYMTestExpectedResults successful files creation/deletion
706 //! @SYMTestPriority High
707 //! @SYMTestStatus Implemented
708 //----------------------------------------------------------------------------------------------
709 static void CreateLargeFile()
711 test.Next(_L("Create a large file and measure time\n"));
713 FormatVolume(ETrue); //-- quick format the volume.
715 _LIT(KBigFileName, "\\BigFile.big");
717 test(gBootSector.IsValid());
719 //-- calculate the size of the file, it shall be max 2G or take almost all volume
723 nRes = TheFs.Volume(volInfo, gDriveNum);
726 const TUint32 clustSz = gBootSector.SectorsPerCluster() * gBootSector.BytesPerSector();
727 const TUint32 maxClusters = (TUint32)(volInfo.iFree / clustSz);
729 const TUint32 clustersPer1G = K1GigaByte / clustSz;
730 const TUint32 clustersPer2G = 2*clustersPer1G;
732 TUint32 fileClusters=0;
733 if(maxClusters*0.8 < clustersPer2G)
734 fileClusters = (TUint32)(maxClusters*0.8);
736 fileClusters = (TUint32)(clustersPer2G*0.8);
738 const TUint32 fileSize = fileClusters*clustSz;
740 //-- create empty file and measure time
743 TInt64 usTimeCreate=0;
744 TInt64 usTimeDelete=0;
746 timeStart.UniversalTime(); //-- take start time
747 nRes = CreateEmptyFile(TheFs, KBigFileName, fileSize);
748 timeEnd.UniversalTime(); //-- take end time
751 usTimeCreate = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
753 //-- remount file system, reset caches etc.
754 DoRemountFS(gDriveNum);
757 timeStart.UniversalTime(); //-- take start time
758 nRes = TheFs.Delete(KBigFileName);
759 timeEnd.UniversalTime(); //-- take end time
762 usTimeDelete = (timeEnd.MicroSecondsFrom(timeStart)).Int64();
764 test.Printf(_L("#--> Big file sz:%u created:%d ms, deleted:%d ms\n"), fileSize, (TUint32)(usTimeCreate/K1mSec) , (TUint32)(usTimeDelete/K1mSec));
769 //-------------------------------------------------------------------
775 test.Printf(_L("Prepare the volume for BM testing...\n"));
777 test(pFTagArray != NULL);
778 CFileTagsArray &fTagArray = *pFTagArray;
781 //-- full format the drive
782 FormatVolume(EFalse);
784 test.Printf(_L("\n#--> t_fatcache_bm\n"));
786 //-- create test directory.
789 //-- 1. create KMaxFiles files to fill in space in FAT table.
790 if(!DoCreateFiles(fTagArray))
791 return; //-- test is inconsistent
794 //-- 1.1 create a file in the very end of the full volume (FAT table is almost full). Measure time taken
797 //-- 1.2 create multiple directories in the root and measure time
798 // DoCreateDirsInRoot();
800 //-- 2. randomly merge some small files to bigger ones that will be fragmented
801 DoMergeFiles(fTagArray);
803 //-- 3. randomly shuffle file tags in the array
804 ShuffleArray(fTagArray);
806 //-- 4. measure file open and seek time
807 MeasureSeekTime(fTagArray);
809 //-- 4.5 Check that all copies of FAT are the same.
812 //-- 5. delete all files and print out time taken
813 DeleteAllFiles(fTagArray);
815 //-- 6. Create a large file (2G max) and measure the time
823 //-------------------------------------------------------------------
824 static void WaitForFatBkGndActivityEnd()
826 //-- if we work in release mode, we need to use a hardcore solution to wait until possible FAT background activity finishes
827 //-- because transient FAT threads can affect timings (e.g. creating a file may need waiting to FAT background thread to
828 //-- parse some portion of FAT) etc.
829 //-- for debug mode background FAT activity is disabled in InitGlobals() and timings are not precise anyway
830 //-- for release mode we just need to wait some time
832 const TInt KWaitTimeSec = 10;
833 test.Printf(_L("waiting %d sec...\n"), KWaitTimeSec);
834 User::After(KWaitTimeSec*K1Sec);
841 //-------------------------------------------------------------------
844 Dismounts and mounts the FS on a drive aDrive
845 This will cause resetting "last known free cluster number" value in the FAT table implementation in FSY.
846 (Mounting enhancements are disabled.) Empty the caches etc.
848 static void DoRemountFS(TInt aDrive)
850 TInt nRes = RemountFS(TheFs, aDrive);
853 //-- get volume info, this is a trick that can help avoiding asynchronous FAT mount in UREL mode
855 //nRes = TheFs.Volume(v);
857 //-- to avoid affected timings in UREL mode.
858 WaitForFatBkGndActivityEnd();
862 //-------------------------------------------------------------------
864 /** initialise test global objects */
865 static void InitGlobals()
867 //-- initialise random generator
868 gRndSeed = 0x67fc1a9;
870 //-- construct file numbers array
871 pFTagArray = new CFileTagsArray(KMaxFiles);
872 test(pFTagArray != NULL);
873 pFTagArray->SetReserveL(KMaxFiles);
875 //-- define a propery which will control mount process in the fsy.
876 //-- The property key is a drive number being tested
877 _LIT_SECURITY_POLICY_PASS(KTestPropPolicy);
878 TInt nRes = RProperty::Define(KThisTestSID, gDriveNum, RProperty::EInt, KTestPropPolicy, KTestPropPolicy);
879 test(nRes == KErrNone || nRes == KErrAlreadyExists);
881 //-- disable all volume mount enhancements, like asynch mount and FSInfo.
882 //-- this works only in debug mode.
883 nRes = RProperty::Set(KThisTestSID, gDriveNum, (TInt)KMntProp_DisableALL);
888 /** destroy test global objects */
889 static void DestroyGlobals()
893 //-- delete test property
894 RProperty::Delete(KThisTestSID, gDriveNum);
899 //-------------------------------------------------------------------
903 //-- set up console output
904 Fat_Test_Utils::SetConsole(test.Console());
906 TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum);
907 test(nRes==KErrNone);
909 //-- check if this is FAT
910 if(!Is_Fat(TheFs, gDriveNum))
912 test.Printf(_L("Skipping. This test requires FAT drive.\n"));
916 //-- check this is not the internal ram drive
918 nRes = TheFs.Volume(v);
919 test(nRes==KErrNone);
920 if(v.iDrive.iMediaAtt & KMediaAttVariableSize)
922 test.Printf(_L("Skipping. Internal ram drive not tested.\n"));
927 //-------------------------------------
928 PrintDrvInfo(TheFs, gDriveNum);
934 //-------------------------------------