Update contrib.
1 // Copyright (c) 1997-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.
21 #include "fat_utils.h"
25 using namespace Fat_Test_Utils;
27 RTest test(_L("t_falsespace"));
29 const TInt KNumberThreads=2;
30 const TInt KHeapSize=0x2000;
32 static TInt RsrvSpaceThread(TAny* aArg);
33 static TInt SessCloseThread(TAny* aArg);
34 static void GetFreeDiskSpace(TInt64 &aFree);
37 TInt gCount; //count of files used to fill up the disk
38 TInt gTestDrive; //drive number of the drive currently being tested
42 _LIT(KBasePath,"\\F32-TST\\FILLDIR\\");
43 _LIT(KBaseName,"\\F32-TST\\FILLDIR\\FILE");
45 _LIT(KTestFile,"?:\\test.txt");
46 _LIT8(KTestData, "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678");
47 _LIT(KDir, "?:\\adodgydir\\");
49 _LIT(KNewName,"?:\\newname.txt");
58 //-- FAT32 SPC:1; for the FAT32 testing on the emulator
61 fp.iSecPerCluster = 1;
63 nRes = FormatFatDrive(TheFs, gTestDrive, ETrue, &fp);
66 nRes = FormatFatDrive(TheFs, gTestDrive, ETrue);
70 test(nRes == KErrNone);
73 void SynchronousClose(RFs &aSession)
76 aSession.NotifyDestruction(s);
77 test(s.Int()==KRequestPending);
79 User::WaitForRequest(s);
83 static TInt CreateFileX(const TDesC& aBaseName,TInt aX, TInt aFileSize)
85 // Create a large file. Return KErrEof or KErrNone
89 TBuf<128> fileName=aBaseName;
90 fileName.AppendNum(aX);
93 TInt r=file.Replace(TheFs,fileName,EFileWrite);
98 test.Printf(_L("ERROR:: Replace returned %d\n"),r);
100 return(KErrDiskFull);
103 if (!IsTestingLFFS())
104 r=file.SetSize(aFileSize);
107 TBuf8<1024> testdata(1024);
108 TInt count=(aFileSize/testdata.Length());
110 while (count-- && r==KErrNone)
111 r=file.Write(testdata);
120 test.Printf(_L("ERROR:: SetSize/Write returned %d\n"),r);
124 return(KErrDiskFull);
129 test.Printf(_L("Created file %d size %d\n"),aX,aFileSize);
133 LOCAL_C TInt DeleteFileX(const TDesC& aBaseName,TInt aX)
135 // Delete a large file
138 TBuf<128> fileName=aBaseName;
139 fileName.AppendNum(aX);
140 return TheFs.Delete(fileName);
144 static void FillUpDisk()
146 // Test that a full disk is ok
150 test.Start(_L("Fill disk to capacity"));
151 TInt r=TheFs.MkDirAll(KBasePath);
152 test(r==KErrNone || r==KErrAlreadyExists);
154 TFileName sessionPath;
155 r=TheFs.SessionPath(sessionPath);
157 TBuf<128> fileName=KBaseName();
160 TInt64 freespaceBeforeScanDrive = 0;
161 TInt64 freespaceAfterScanDrive = 0;
165 GetFreeDiskSpace(freespace);
167 if (I64HIGH(freespace))
168 fillfilesize=KMaxTInt;
170 fillfilesize=I64LOW(freespace)* 7/8;
174 TInt r=CreateFileX(fileName,gCount,fillfilesize);
177 if(fillfilesize <= 2)
180 fillfilesize=fillfilesize/2;
182 test(r==KErrNone || r==KErrDiskFull);
187 r=TheFs.CheckDisk(fileName);
188 if (r!=KErrNone && r!=KErrNotSupported)
190 test.Printf(_L("ERROR:: CheckDisk returned %d\n"),r);
195 // Test that scan drive passes on a full disk
196 // DEF071696 - KErrCorrupt on Scan Drive
197 GetFreeDiskSpace(freespaceBeforeScanDrive);
198 test.Printf(_L("Before ScanDrive freeSpace = %08X:%08X\n"),
199 I64HIGH(freespaceBeforeScanDrive), I64LOW(freespaceBeforeScanDrive));
200 r = TheFs.ScanDrive(fileName);
201 if (r!=KErrNone && r!=KErrNotSupported)
203 test.Printf(_L("ScanDrive returned %d\n"), r);
206 GetFreeDiskSpace(freespaceAfterScanDrive);
207 test.Printf(_L("After ScanDrive freeSpace = %08X:%08X\n"),
208 I64HIGH(freespaceAfterScanDrive), I64LOW(freespaceAfterScanDrive));
210 while (freespaceBeforeScanDrive != freespaceAfterScanDrive );
217 static void GetFreeDiskSpace(TInt64 &aFree)
219 // Get free disk space
224 TInt r=TheFs.Volume(v,gTestDrive);
232 // Test the API fundamentaly works for one session
235 test.Next(_L("Test Disk Space reserve APIs"));
244 r=TheFs.GetReserveAccess(gTestDrive);
245 test(r==KErrPermissionDenied);
247 //make sure nothing odd happens if we didnt already have access
248 r=TheFs.ReleaseReserveAccess(gTestDrive);
252 GetFreeDiskSpace(free2);
254 r=TheFs.ReserveDriveSpace(gTestDrive,0x1000);
257 GetFreeDiskSpace(free1);
258 diff = free2 - free1;
259 test(I64INT(diff) > 0xfe0 && I64INT(diff) < 0x1100);
261 r=TheFs.GetReserveAccess(gTestDrive);
264 GetFreeDiskSpace(free1);
265 TInt64 temp = free2-free1;
266 test(I64INT(temp)>(-0x90) && I64INT(temp)<0x90);
268 r=TheFs.ReleaseReserveAccess(gTestDrive);
270 GetFreeDiskSpace(free1);
272 diff = free2 - free1;
273 test(I64INT(diff) > 0xfe0 && I64INT(diff) < 0x1100);
276 //test reallocation of reserved space is possible
277 r=TheFs.ReserveDriveSpace(gTestDrive,0x2000);
280 //test upper limit of reserved space
281 r=TheFs.ReserveDriveSpace(gTestDrive,0x2000000);
282 test(r==KErrArgument);
284 r=TheFs.ReserveDriveSpace(gTestDrive,0);
287 r=TheFs.GetReserveAccess(gTestDrive);
288 test(r==KErrPermissionDenied);
290 //make sure nothing odd happens if we didnt already have access
291 r=TheFs.ReleaseReserveAccess(gTestDrive);
294 r=TheFs.ReserveDriveSpace(gTestDrive,-45);
295 test(r==KErrArgument);
301 // Test multiple sessions, ensure the drive limit is not exceeded
305 test.Next(_L("Test Session and total reserve limits"));
317 r = sessions[i].Connect();
321 test.Next(_L("Test breaching sesson reserve limit"));
322 r=sessions[0].ReserveDriveSpace(gTestDrive,0x10001);
323 test(r==KErrArgument);
325 //Get Volume Free Space
326 r = sessions[0].Volume(v, gTestDrive);
328 if(v.iFree > 0x100000)
330 test.Next(_L("Test breaching drive reserve limit"));
334 r=sessions[i].ReserveDriveSpace(gTestDrive,0x10000);
339 r=sessions[16].ReserveDriveSpace(gTestDrive,0x10);
344 test.Printf(_L("Drive too small: breaching drive reserve limit test skipped\n"));
345 test.Next(_L("Testing exhausting available drive free space instead"));
347 for(i=0; (v.iFree -= 0x10000) >= 0; i++)
349 r=sessions[i].ReserveDriveSpace(gTestDrive,0x10000);
354 r=sessions[i].ReserveDriveSpace(gTestDrive,0x10000);
355 test(r==KErrDiskFull);
361 SynchronousClose(sessions[i]);
367 // Test session cleanup
370 test.Next(_L("Test session close and clean up of resrved space"));
386 GetFreeDiskSpace(free1);
388 r=fs1.ReserveDriveSpace(gTestDrive,0x10000);
390 r=fs2.ReserveDriveSpace(gTestDrive,0x10000);
393 GetFreeDiskSpace(free2);
394 diff = free1 - free2;
395 test(I64INT(diff)>0x1FBD0 && I64INT(diff)<0x21000);
397 SynchronousClose(fs1);
399 GetFreeDiskSpace(free2);
401 test(I64INT(diff)>0xFA00 && I64INT(diff)<0x103C4);
406 GetFreeDiskSpace(free1);
408 test(I64INT(diff)== 0 || I64INT(diff)<0xFA0 );
410 r=fs1.ReserveDriveSpace(gTestDrive,0x10000);
413 GetFreeDiskSpace(free2);
414 diff = free1 - free2;
415 test(I64INT(diff)>0xFA00 && I64INT(diff)<0x103C4);
417 // Make sure no reserve space is allocated
418 r=fs1.ReserveDriveSpace(gTestDrive,0);
420 r=fs2.ReserveDriveSpace(gTestDrive,0);
423 // Now fill up the disk
426 // Should fail as there is no space
427 r=fs1.ReserveDriveSpace(gTestDrive,0x10000);
428 test(r==KErrDiskFull);
430 SynchronousClose(fs1);
431 SynchronousClose(fs2);
437 // Test real out of disk space conditions i.e. properly run out of disk space and try to
438 // reserve an area etc
441 test.Next(_L("Test Filling disk and using APIs"));
445 //-- This test is not valid for LFFS, because free space on this FS can change itself because of some
446 //-- internal FS activities
447 test.Printf(_L("This test is inconsistent on LFFS\n"));
460 //start with known amount of space
462 //create a single file to use for futher tests
467 r=file.Replace(fs, buf, EFileWrite);
470 r=file.Write(KTestData());
475 r=fs.ReserveDriveSpace(gTestDrive,0x10000); //reserve some disk space
478 FillUpDisk(); //fill up the disk
480 TVolumeInfo v; //get disk space
481 r=fs.Volume(v,gTestDrive);
485 r=fs.GetReserveAccess(gTestDrive); //get access to reserve space
488 r=fs.Volume(v,gTestDrive); //get disk space
492 r=fs.ReleaseReserveAccess(gTestDrive); //release reserve space
495 test(freeA == (freeB - 0x10000)); //test difference in space is equal to the amount reserved
497 r=fs.Volume(v,gTestDrive); //get disk space
500 test(freeA == freeB); //check reading is still correct
502 TBuf <20> dir = KDir();
505 test(r==KErrDiskFull);
508 test(r==KErrDiskFull);
511 TBuf<5> drv = KDrv();
513 r=file.Temp(fs, drv, temp, EFileWrite);
514 test(r==KErrDiskFull);
516 r=file.Replace(fs, buf, EFileWrite);
517 test(r==KErrDiskFull);
519 r=file.Create(fs, buf, EFileWrite);
520 test(r==KErrDiskFull);
522 r=file.Open(fs, buf, EFileWrite);
525 r=file.Write(128, KTestData());
527 if ((gDriveCacheFlags & EFileCacheWriteOn) && (r == KErrNone))
530 test(r==KErrDiskFull);
532 r=file.SetSize(0x1000);
533 test(r==KErrDiskFull);
535 r=file.SetAtt(KEntryAttHidden,0);
536 test(r==KErrDiskFull);
539 r=file.SetModified(dtime);
540 test(r==KErrDiskFull);
542 r=file.Set(dtime,KEntryAttHidden,0);
543 test(r==KErrDiskFull);
546 test(r==KErrDiskFull);
551 // Test that we can create a temporary file & write to it after acquiring reserved access,
552 r=fs.GetReserveAccess(gTestDrive); //get access to reserve space
555 r=fs.Volume(v,gTestDrive); //get disk space
559 r=file.Temp(fs, drv, temp, EFileWrite);
562 r = file.Write(KTestData());
563 test (r == KErrNone);
565 // If write caching is enabled, call RFs::Entry() to flush the file "anonymously"
566 if ((gDriveCacheFlags & EFileCacheWriteOn) && (r == KErrNone))
569 test (r == KErrNone);
572 r=fs.Volume(v,gTestDrive); //get disk space
575 test (freeB < freeA);
579 r=fs.ReleaseReserveAccess(gTestDrive); //release reserve space
583 TBuf<20> newname =KNewName();
584 newname[0]=(TUint16)gCh;
585 r=fs.Rename(buf, newname);
586 test(r==KErrDiskFull);
588 r=fs.Replace(buf, newname);
589 test(r==KErrDiskFull);
591 r=fs.SetEntry(buf, dtime, KEntryAttHidden, 0);
592 test(r==KErrDiskFull);
594 r=fs.CreatePrivatePath(gTestDrive);
595 test(r==KErrDiskFull);
597 r=fs.SetVolumeLabel(_L("Moooo"), gTestDrive);
598 test(r==KErrDiskFull);
600 r=fs.SetModified(buf, dtime);
601 test(r==KErrDiskFull);
603 SynchronousClose(fs);
613 test.Next(_L("Test Session limits"));
617 //-- This test is not valid for LFFS, because free space on this FS can change itself because of some
618 //-- internal FS activities
619 test.Printf(_L("This test is inconsistent on LFFS\n"));
635 r=fs1.ReserveDriveSpace(gTestDrive,0x10000);
638 r=fs2.ReserveDriveSpace(gTestDrive,0x10000);
643 r=fs1.GetReserveAccess(gTestDrive);
646 TBuf<20> dir = KDir();
651 test(r==KErrDiskFull);
653 r=fs1.ReserveDriveSpace(gTestDrive,0); //can not release reserve space while you have reserve access
656 r=fs1.ReleaseReserveAccess(gTestDrive);
659 r=fs1.ReserveDriveSpace(gTestDrive,0);
665 SynchronousClose(fs1);
666 SynchronousClose(fs2);
669 static TInt RsrvSpaceThread(TAny* aArg)
677 r=((RFs*)aArg)->Volume(v,gTestDrive);
683 r=((RFs*)aArg)->ReserveDriveSpace(gTestDrive,0x10000);
687 r=((RFs*)aArg)->Volume(v,gTestDrive);
693 if(!(I64INT(diff)> 0xef38 && I64INT(diff)<0xf100))
698 static TInt SessCloseThread(TAny* aArg)
706 r=((RFs*)aArg)->Volume(v,gTestDrive);
711 ((RFs*)aArg)->ReserveDriveSpace(gTestDrive,0x1000);
713 r=((RFs*)aArg)->Volume(v,gTestDrive);
719 if(!(I64INT(diff)> 0xef38 && I64INT(diff)<0xf100))
722 SynchronousClose(*((RFs*)aArg));
729 // Test sharabale session
733 test.Next(_L("Test sharable session"));
740 RThread t[KNumberThreads];
741 TRequestStatus tStat[KNumberThreads];
748 r= fsess.ShareAuto();
751 GetFreeDiskSpace(free1);
753 fsess.ReserveDriveSpace(gTestDrive,0x1000);
755 r = t[0].Create(_L("Sub_Thread1"),RsrvSpaceThread,KDefaultStackSize,KHeapSize,KHeapSize,&fsess);
758 t[0].Rendezvous(tStat[0]);
761 User::WaitForRequest(tStat[0]);
764 test(tStat[0]==KErrNone);
766 r = t[1].Create(_L("Sub_Thread2"),SessCloseThread,KDefaultStackSize,KHeapSize,KHeapSize,&fsess);
769 t[1].Rendezvous(tStat[1]);
772 User::WaitForRequest(tStat[1]);
775 test(tStat[1]==KErrNone);
777 GetFreeDiskSpace(free2);
780 test(I64INT(diff)== 0 || I64INT(diff)<0xFA0 );
786 // Tests notifier events for sessions with and without reserved access
791 // This test is not valid for LFFS...
792 test.Printf(_L("Test reserved access notification not run for LFFS\n"));
797 test.Next(_L("Test reserved access notification"));
804 TInt err = theNrm.Connect();
805 test(KErrNone == err);
807 err = theRes.Connect();
808 test(KErrNone == err);
812 GetFreeDiskSpace(freeSpace);
815 theTestSession.Connect();
817 _LIT(KFileFiller, "?:\\t_falseSpaceFiller");
819 fileName = KFileFiller;
820 fileName[0] = (TUint16)gCh;
822 err = theTestSession.Connect();
823 test(err == KErrNone);
825 // determine the cluster size
827 err=theFile.Replace(theTestSession, fileName, EFileShareAny | EFileWrite);
830 // Neither notifier should be triggered here
831 err = theFile.SetSize(1);
832 test(KErrNone == err);
836 GetFreeDiskSpace(newFreeSpace);
837 TInt clusterSize = TInt(freeSpace - newFreeSpace);
838 theTestSession.Delete(fileName);
839 GetFreeDiskSpace(newFreeSpace);
840 test (newFreeSpace == freeSpace);
842 TInt resSpace = Max(0x1000, clusterSize);
845 theNrm.Volume(volInfo, gTestDrive);
846 test(volInfo.iFree == freeSpace);
848 err = theRes.ReserveDriveSpace(gTestDrive, resSpace);
849 test(KErrNone == err);
850 err = theRes.GetReserveAccess(gTestDrive);
851 test(KErrNone == err);
853 theRes.Volume(volInfo, gTestDrive);
854 test(volInfo.iFree == freeSpace);
856 theNrm.Volume(volInfo, gTestDrive);
857 test(volInfo.iFree == freeSpace - resSpace);
861 // Register the notifiers and verify that the only the "Normal"
862 // and not the "Reserved" session is triggered.
864 TRequestStatus statNrm;
865 TRequestStatus statRes;
867 TInt64 threshold(freeSpace - resSpace*2);
868 theNrm.NotifyDiskSpace(threshold, gTestDrive, statNrm);
869 theRes.NotifyDiskSpace(threshold, gTestDrive, statRes);
870 test((statNrm == KRequestPending) && (statRes == KRequestPending));
874 // Main part of the test starts here.
875 // First we create a new file, then we increase its size to cause the
876 // "Normal" notifier to trigger but not the "Reserved" notifier
878 err=theFile.Replace(theTestSession, fileName, EFileShareAny | EFileWrite);
880 test((statNrm == KRequestPending) && (statRes == KRequestPending));
882 // Neither notifier should be triggered here
883 err = theFile.SetSize(resSpace);
884 test(KErrNone == err);
885 test((statNrm == KRequestPending) && (statRes == KRequestPending));
887 // This should trigger the "Normal" notifier, but not the "Reserved" one
888 err = theFile.SetSize(2*resSpace);
889 test(KErrNone == err);
890 test((statNrm == KErrNone) && (statRes == KRequestPending));
894 // Reset the "Normal" notifier then increase the amount of reserved space
895 // on the drive. This should re-trigger the "Normal" notifier but leave
896 // the "Reserved" notifier untouched.
898 theNrm.NotifyDiskSpace(threshold - resSpace, gTestDrive, statNrm);
899 test((statNrm == KRequestPending) && (statRes == KRequestPending));
901 err = theTestSession.ReserveDriveSpace(gTestDrive, resSpace * 3);
902 if (err != KErrArgument) // will have exceeded limit if resSpace = 32K
904 test(err == KErrNone);
905 test((statNrm == KErrNone) && (statRes == KRequestPending));
909 // All done - tidy up.
912 theTestSession.Delete(fileName);
913 theTestSession.Close();
918 LOCAL_C void TestForDEF142554()
920 test.Next(_L("Test for DEF142554: test RFile::Modified and RFile::Att when disk full"));
928 TInt err = fs.Connect();
929 test(err == KErrNone);
933 fileName = KTestFile;
934 fileName[0] = (TUint16)gCh;
936 err = fs.ReserveDriveSpace(gTestDrive,0x10000);
937 test(err == KErrNone);
939 err = file.Replace(fs, fileName, EFileWrite);
940 test(err == KErrNone);
942 err = file.Write(KTestData);
943 test(err == KErrNone);
946 test(err == KErrNone);
950 err = file.Open(fs, fileName, EFileRead);
951 test(err == KErrNone);
954 test(err == KErrNone);
956 err = file.Modified(time);
957 test(err == KErrNone);
963 err = file.Open(fs, fileName, EFileRead);
964 test(err == KErrNone);
967 err = file.Att(att1);
968 test(err == KErrNone);
972 err = file.Modified(time1);
973 test(err == KErrNone);
982 //-----------------------------------------------------------------------------
985 test creation of the the file that crosses 4G boundary on the FAT media
988 static void TestFAT4G_Boundary()
990 const TInt64 K4Gig = 4*(TInt64)K1GigaByte;
992 test.Next(_L("Test files crossing 4G boundary on FAT"));
994 if(!Is_Fat32(TheFs, gTestDrive))
996 test.Printf(_L("This test requires FAT32. Skipping.\n"));
1000 TVolumeInfo volInfo;
1002 TInt nRes = TheFs.Volume(volInfo,gTestDrive);
1003 test(nRes == KErrNone);
1005 if(volInfo.iSize < K4Gig+K1MegaByte)
1007 test.Printf(_L("This test requires volume > 4G. Skipping.\n"));
1011 //-- 1. format the volume
1014 //-- find out media position of the data region start
1015 TFatBootSector bootSector;
1016 nRes = ReadBootSector(TheFs, gTestDrive, 0, bootSector);
1017 test(nRes == KErrNone);
1018 test(bootSector.IsValid());
1020 const TInt64 dataStartPos = bootSector.FirstDataSector() << KDefaultSectorLog2;
1021 const TInt64 lowRegion = K4Gig - dataStartPos - K1MegaByte;
1024 //-- 2. create several empty files that take a bit less that 4gig
1025 //-- the drive is freshly formatted and the files will expand linearry
1026 _LIT(KBaseFN, "\\LargeFile");
1028 const TInt MaxDummyFiles = 5;
1029 const TUint32 DummyFileLen = (TUint32)(lowRegion / MaxDummyFiles);
1031 for(i=0; i<MaxDummyFiles; ++i)
1033 nRes = CreateFileX(KBaseFN, i, DummyFileLen);
1034 test(nRes == KErrNone);
1037 //-- 3. create a real file that crosses 4G boundary
1038 nRes = CreateCheckableStuffedFile(TheFs, KBaseFN, 5*K1MegaByte);
1039 test(nRes == KErrNone);
1041 test.Printf(_L("Verifying the file that crosses 4G boundary.\n"));
1043 nRes = VerifyCheckableFile(TheFs, KBaseFN);
1044 test(nRes == KErrNone);
1047 nRes = TheFs.Delete(KBaseFN);
1048 test(nRes == KErrNone);
1049 for(i=0; i<MaxDummyFiles; ++i)
1051 nRes = DeleteFileX(KBaseFN, i);
1052 test(nRes == KErrNone);
1056 //-----------------------------------------------------------------------------
1058 GLDEF_C void CallTestsL()
1060 // Do tests relative to session path
1063 //-- set up console output
1064 Fat_Test_Utils::SetConsole(test.Console());
1067 if (gSessionPath[0]=='C') //only test on non C drives
1069 test.Printf(_L("TEST NOT RUN FOR THIS DRIVE"));
1073 if (UserSvr::DebugMask(2)&0x00000002) // TESTFAST mode set? (for automated test builds)
1076 // Don't run on LFFS (to increase speed of automated testing)
1077 test.Printf(_L("TEST NOT RUN FOR THIS DRIVE"));
1081 //get the number of the drive we are currently testing
1083 r=RFs::CharToDrive(gSessionPath[0],gTestDrive);
1086 r=RFs::DriveToChar(gTestDrive,gCh);
1089 //-- print drive information
1090 PrintDrvInfo(TheFs, gTestDrive);
1092 Test1(); //General test for new APIs
1093 Test2(); //Test to ensure drive and session reserve limits are not exceeded
1095 Test4(); //test filling the drive and that each checked API fails
1100 Test2(); //run this test to check reserves are being cleared correctly
1102 TestFAT4G_Boundary();
1104 TurnAllocFailureOff();