First public contribution.
1 // Copyright (c) 1998-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_dspace.cpp
24 /* This tests disk space notification. Using RFs::NotifyDiskSpace a client can request
25 to be notified if the free disk space crosses a specified threshold. This test requires
26 a card to be present in d: */
28 GLDEF_D RTest test(_L("T_DSPACE"));
30 const TInt KMaxBufSize=512;
41 const TInt KHeapSize=0x2000;
42 const TInt KStackSize=0x4000;
46 TBool LffsDrive = EFalse;
48 TBuf8<KMaxBufSize> TheBuffer;
51 TBuf<4> RemovableDriveBuf=_L("?:\\");
53 _LIT(KTestFile1, "\\F32-TST\\testfile1");
54 _LIT(KTestFile2, "\\F32-TST\\testFile2");
55 _LIT(KTestDir1, "\\F32-TST\\testDir1\\");
56 _LIT(KTestDir2, "\\F32-TST\\testDir2\\");
57 _LIT(KFileFiller, "\\F32-TST\\fileFiller");
59 // functions that may cause change in free disk space
60 // not all of them of tested since some require knowledge of file system
61 // to ensure change in free disk space
71 ETaskFileReplace, // test
73 ETaskFileWrite, // test
76 ETaskFileSetSize, // test
80 ETaskFileCreateLffs,// test
85 LOCAL_C TBool IsWinsCDrive(TInt aDrive)
91 if(aDrive==KDefaultDrive)
92 return(gSessionPath[0]==(TText)'C');
94 return(aDrive==EDriveC);
100 LOCAL_C TInt64 FreeDiskSpace(TInt aDrive)
106 TInt r=TheFs.Volume(v,aDrive);
111 LOCAL_C TInt64 DiskSize(TInt aDrive)
117 TInt r=TheFs.Volume(v,aDrive);
122 // MinimumFileSize() -
123 // Deduces the minimum space occupied by a file by creating a file of one byte
124 // in length. This should equal the cluster size on FAT volumes.
126 LOCAL_C TInt MinimumFileSize(TInt aDrive)
128 TInt r = TheFs.Delete(KTestFile1);
129 test(r==KErrNone || r==KErrNotFound);
131 TInt64 freeSpace = FreeDiskSpace(aDrive);
136 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
139 r = file.Write(TheBuffer,1);
142 TInt64 newSpace = FreeDiskSpace(aDrive);
144 r = TheFs.Delete(KTestFile1);
148 TInt64 minFileSize = freeSpace - newSpace;
149 test (minFileSize >= 0);
150 minFileSize = Max(minFileSize, 512);
151 test (minFileSize < KMaxTInt);
153 TInt minFileSizeLow = I64LOW(minFileSize);
155 RDebug::Print(_L("minFileSize %u"), minFileSizeLow);
157 #if defined(__WINS__)
158 KFileSize1 = minFileSizeLow << 2; // 512 * 2^2 = 512 * 4 = 2048;
159 KFileSize2 = minFileSizeLow << 3; // 512 * 2^3 = 512 * 8 = 4096;
160 KFileSize3 = minFileSizeLow << 4; // 512 * 2^4 = 512 * 16 = 8192;
162 KFileSize1 = minFileSizeLow; // 512;
163 KFileSize2 = minFileSizeLow << 1; // 512 * 2^1 = 512 * 2 = 1024;
164 KFileSize3 = minFileSizeLow << 3; // 512 * 2^3 = 512 * 8 = 4096;
168 return (TInt) minFileSizeLow;
171 LOCAL_C void Initialise()
173 // do any initialisation before starting tests
176 if(TheBuffer.Length()!=KMaxBufSize)
178 TheBuffer.SetLength(KMaxBufSize);
179 Mem::Fill((void*)TheBuffer.Ptr(),KMaxBufSize,0xab);
181 #if defined(__WINS__)
182 RemovableDrive=EDriveX;
185 if(KErrNone == TheFs.DriveList(drvList))
188 //should be successful, otherwise it means a system w/o any drive!!!
189 for(i=0;i<KMaxDrives;i++)
191 TDriveInfo driveInfo;
193 && (KErrNone == TheFs.Drive(driveInfo, i))
194 && (driveInfo.iType == EMediaHardDisk))
197 test.Printf(_L("RemovableDrive = %d\n"),RemovableDrive);
203 test.Printf(_L("No Removable media found! Testing discontinued.\n"));
204 User::Exit(KErrNone);
209 test.Printf(_L("No Drive found! Testing discontinued.\n"));
210 User::Exit(KErrNone);
214 test.Printf(_L("inside init++++++++++++++++++++++++++>\n\n\n"));
215 test.Printf(_L("RemovableDrive = %d\n"),RemovableDrive);
216 // initialise removable drive descriptor
218 TInt r=RFs::DriveToChar(RemovableDrive,c);
220 RemovableDriveBuf[0]=(TText)c;
224 // and create the default directory
225 TFileName d=gSessionPath;
226 d[0]=RemovableDriveBuf[0];
230 // better format the default drive as long as not WINS c drive
232 r= RFs::CharToDrive(gSessionPath[0],drive);
234 #if defined(__WINS__)
239 // test not run on c: drive but does use it
242 TheDiskSize=DiskSize(KDefaultDrive);
243 // and set the default directory
244 r=TheFs.MkDirAll(gSessionPath);
245 test(r==KErrNone || r==KErrAlreadyExists);
247 r=TheFs.Delete(KFileFiller);
248 test(r==KErrNone || r==KErrNotFound);
249 r=TheFs.Delete(KTestFile1);
250 test(r==KErrNone || r==KErrNotFound);
251 r=TheFs.Delete(KTestFile2);
252 test(r==KErrNone || r==KErrNotFound);
253 r=TheFs.RmDir(KTestDir1);
254 test(r==KErrNone || r==KErrNotFound);
255 r=TheFs.RmDir(KTestDir2);
256 test(r==KErrNone || r==KErrNotFound);
258 gMinFileSize = MinimumFileSize(drive);
261 LOCAL_C TInt64 FillDisk(RFile& aFile,TInt64 aNewSpace,TInt aDrive)
263 // fill a file until free disk space equals aFreeSpace
266 TInt64 space=FreeDiskSpace(aDrive);
267 test(space>aNewSpace);
268 while(space>aNewSpace)
270 TInt s=Min(KMaxBufSize, I64INT(space-aNewSpace));
271 TInt r=aFile.Write(TheBuffer,s);
279 // LFFS is less predictable than a normal drive because of the logging
280 // and metadata arrangement
282 test( (KErrNone==r) || (KErrDiskFull==r) );
283 if( KErrDiskFull == r )
285 // shrink the file back down again to give the requested free space
287 r=aFile.Size( fileSize );
288 test( KErrNone == r );
289 test( TInt64(fileSize) > aNewSpace );
290 fileSize -= I64LOW(aNewSpace);
291 r=aFile.SetSize( fileSize );
292 test( KErrNone == r );
294 space=FreeDiskSpace(aDrive);
295 while( space < aNewSpace )
297 fileSize -= I64LOW(aNewSpace - space);
298 test( fileSize > 0 );
299 r=aFile.SetSize( fileSize );
300 test( KErrNone == r );
301 space=FreeDiskSpace(aDrive);
307 space=FreeDiskSpace(aDrive);
312 LOCAL_C void WriteToFile(RFile& aFile,TInt aSize)
319 TInt s=Min(KMaxBufSize,aSize);
320 TInt r=aFile.Write(TheBuffer,s);
323 // Flush if write caching enabled to ensure we get disk space notifications
324 if ((gDriveCacheFlags & EFileCacheWriteOn) && (r == KErrNone))
333 // we can't accurately predict the amount of data we can actually get
334 // on an LFFS drive, so it's posible we could exceed the available
335 // space even though we are writing less that the reported free space
336 test( (KErrNone==r) || (KErrDiskFull==r) );
337 if( KErrDiskFull == r )
346 LOCAL_C void CleanupForThread(TInt aTask)
355 r=TheFs.RmDir(KTestDir1);
358 case ETaskRmDir: break;
359 case ETaskDelete: break;
361 r=TheFs.Delete(KTestFile2);
364 case ETaskFileReplace:
365 r=TheFs.Delete(KTestFile1);
369 case ETaskFileWrite4KB:
370 case ETaskFileWrite64KB:
371 case ETaskFileSetSize:
372 case ETaskFileCreateLffs:
375 r=TheFs.Delete(KTestFile1);
378 test.Printf(_L("r=%d"),r);
387 LOCAL_C void InitialiseForThread(TInt aTask)
396 case ETaskMkDir: break;
398 r=TheFs.MkDir(KTestDir1);
402 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
406 r=file.SetSize(KFileSize1);
411 // LFFS supports sparse files, so we have to write real data
412 // into the file to ensure that it uses up disk space
413 WriteToFile( file, KFileSize1 );
418 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
422 r=file.SetSize(KFileSize1);
427 WriteToFile( file, KFileSize2 );
430 r=file2.Create(TheFs,KTestFile2,EFileShareAny|EFileWrite);
434 r=file2.SetSize(KFileSize3);
439 WriteToFile( file2, gMinFileSize << 4); // 512 * 16 = 8K
443 case ETaskFileReplace:
444 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
448 r=file.SetSize(KFileSize3*2);
452 WriteToFile( file, KFileSize3 );
458 case ETaskFileWrite4KB:
459 case ETaskFileWrite64KB:
460 case ETaskFileSetSize:
461 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
466 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
470 r=file.SetSize(KFileSize1);
475 WriteToFile( file, KFileSize1 );
480 r=file.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
484 case ETaskFileCreateLffs:
485 r = TheFs.Delete(KTestFile1);
492 LOCAL_C TInt ThreadFunction(TAny* aThreadTask)
497 RTest test(_L("T_DSPACE_ThreadFunction"));
501 r=fs.SetSessionPath(gSessionPath);
503 TThreadTask task=*(TThreadTask*)&aThreadTask;
508 r=fs.MkDir(KTestDir1);
512 r=fs.RmDir(KTestDir1);
516 r=fs.Delete(KTestFile1);
520 r=fs.Replace(KTestFile1,KTestFile2);
523 case ETaskFileReplace:
524 r=file.Replace(fs,KTestFile1,EFileShareAny|EFileWrite);
529 r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
531 #if defined(__WINS__)
532 WriteToFile( file, gMinFileSize << 4); // 512 * 16 = 8K
534 WriteToFile( file, gMinFileSize << 1); // 512 * 2 = 1K
538 case ETaskFileWrite4KB:
539 r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
541 WriteToFile(file,gMinFileSize << 3); // 512 * 2^3 = 512 * 8 = 4K
544 case ETaskFileWrite64KB:
545 r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
547 WriteToFile(file,gMinFileSize<<7); // 512 * 2^7 = 512 * 128 = 64K
550 case ETaskFileSetSize:
551 r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
553 r=file.SetSize(KFileSize3);
556 case ETaskFileCreateLffs:
557 r=file.Create(fs,KTestFile1,EFileShareAny|EFileWrite);
563 r=file.Open(fs,KTestFile1,EFileShareAny|EFileWrite);
567 r=file.SetModified(time);
575 r=fs.Entry(KTestFile1,e);
589 void TestCancellation()
591 // test error disk space notification requests can be cancelled
594 test.Next(_L("test disk space cancellation"));
595 const TInt ThresholdSize=500;
596 // test a cancellation
597 // Up the priority of this thread so that we can cancel the request before the drive thread
598 // runs, to test whether cancelling still works.
599 RThread().SetPriority(EPriorityRealTime);
600 TRequestStatus stat1;
601 TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat1);
602 test(stat1==KRequestPending);
603 TheFs.NotifyDiskSpaceCancel(stat1);
604 test(stat1==KErrCancel);
605 RThread().SetPriority(EPriorityNormal);
606 // test no affect if already cancelled
608 TheFs.NotifyDiskSpaceCancel(stat1);
609 test(stat1==KErrNone);
610 // set up two requests, cancel 1
611 TRequestStatus stat2;
612 TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat1);
613 TheFs.NotifyDiskSpace(ThresholdSize,KDefaultDrive,stat2);
614 test(stat1==KRequestPending && stat2==KRequestPending);
615 TheFs.NotifyDiskSpaceCancel(stat2);
616 test(stat1==KRequestPending && stat2==KErrCancel);
617 TheFs.NotifyDiskSpaceCancel(stat1);
618 test(stat1==KErrCancel);
622 // now repeat with c: and removable drive
623 TheFs.NotifyDiskSpace(ThresholdSize,EDriveC,stat1);
624 TheFs.NotifyDiskSpace(ThresholdSize,RemovableDrive,stat2);
625 test(stat1==KRequestPending && stat2==KRequestPending);
626 TheFs.NotifyDiskSpaceCancel(stat1);
627 test(stat2==KRequestPending && stat1==KErrCancel);
628 TheFs.NotifyDiskSpaceCancel(stat2);
629 test(stat2==KErrCancel);
633 void TestErrorConditions()
635 // test disk space notification requests return correct error value
638 test.Next(_L("test error conditions"));
639 // attempt to set up disk space notification with a threshold of zero
640 TRequestStatus status;
641 TheFs.NotifyDiskSpace(0,KDefaultDrive,status);
642 test(status==KErrArgument);
643 // test on an empty drive
644 TheFs.NotifyDiskSpace(100,EDriveO,status);
645 test(status==KErrNotReady);
646 // test on a drive out of rance
647 TheFs.NotifyDiskSpace(100,27,status);
648 test(status==KErrBadName);
649 // new setup with threshold of one
650 TheFs.NotifyDiskSpace(1,KDefaultDrive,status);
651 test(status==KRequestPending);
652 TheFs.NotifyDiskSpaceCancel(status);
653 test(status==KErrCancel);
654 // and with a threshold > disk size
655 TheFs.NotifyDiskSpace(TheDiskSize+10,KDefaultDrive,status);
656 test(status==KErrArgument);
657 // now with a size of max size -1
658 TheFs.NotifyDiskSpace(TheDiskSize-1,KDefaultDrive,status);
659 test(status==KRequestPending);
660 TheFs.NotifyDiskSpaceCancel(status);
661 test(status==KErrCancel);
662 // set up mutiple requests and cancel one
663 TRequestStatus status2,status3;
664 TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status);
665 TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status2);
666 TheFs.NotifyDiskSpace(TheDiskSize-10,KDefaultDrive,status3);
667 test(status==KRequestPending&&status2==KRequestPending&&status3==KRequestPending);
668 TheFs.NotifyDiskSpaceCancel(status3);
669 test(status==KRequestPending&&status2==KRequestPending&&status3==KErrCancel);
670 // cancel the remaining ones
671 TheFs.NotifyDiskSpaceCancel();
672 test(status==KErrCancel&&status2==KErrCancel&&status3==KErrCancel);
675 TInt GenerateMediaChange()
679 //Find the local drive number corresponding to removabledrive
680 TMediaSerialNumber serialNum;
681 TInt r = TheFs.GetMediaSerialNumber(serialNum, RemovableDrive);
685 TInt len = serialNum.Length();
686 test.Printf(_L("Serial number (len %d) :"), len);
688 TInt localDriveNum = -1;
689 for (TInt n=0; n<KMaxLocalDrives; n++)
691 r = d.Connect(n, flag);
694 test.Printf(_L("drive %d: TBusLocalDrive::Connect() failed %d\n"), n, r);
698 TLocalDriveCapsV5Buf capsBuf;
699 TLocalDriveCapsV5& caps = capsBuf();
703 test.Printf(_L("drive %d: TBusLocalDrive::Caps() failed %d\n"), n, r);
708 TPtrC8 localSerialNum(caps.iSerialNum, caps.iSerialNumLength);
709 if (serialNum.Compare(localSerialNum) == 0)
718 r =d.Connect(localDriveNum,flag);
721 d.ForceMediaChange();
726 void TestDiskNotify()
728 // test functions that can result in disk change notification
729 // format,scandrive, media change
732 // make default directory
733 _LIT(defaultDir,"C:\\F32-TST\\");
734 TInt r=TheFs.MkDirAll(defaultDir);
735 test(r==KErrNone||r==KErrAlreadyExists);
736 // create the filler file
738 TFileName fileName=_L("C:");
739 fileName+=KFileFiller;
740 r=file.Create(TheFs,fileName,EFileShareAny|EFileWrite);
742 TInt64 free=FreeDiskSpace(EDriveC);
744 FillDisk(file,free-16384,EDriveC);
746 // test formatting notifies clients on only specific drive
747 test.Next(_L("test formatting"));
748 TRequestStatus stat1, stat2;
749 TInt64 freeC=FreeDiskSpace(EDriveC);
750 TInt64 freeD=FreeDiskSpace(RemovableDrive);
751 TheFs.NotifyDiskSpace(freeC+1024,EDriveC,stat1);
752 TheFs.NotifyDiskSpace(freeD-1024,RemovableDrive,stat2);
753 test(stat1==KRequestPending && stat2==KRequestPending);
756 r=f.Open(TheFs,RemovableDriveBuf,EQuickFormat,count);
764 User::After(1000000);
765 User::WaitForRequest(stat2);
766 test(stat1==KRequestPending && stat2==KErrNone);
767 TheFs.NotifyDiskSpaceCancel(stat1);
768 test(stat1==KErrCancel);
770 // and create the test directory for the removable drive
771 TFileName fName=_L("");
772 fName+=RemovableDriveBuf;
773 fName+=_L("F32-TST\\");
774 r=TheFs.MkDirAll(fName);
777 // test that a media change notifies clients on all drives
778 test.Next(_L("media change"));
779 freeC=FreeDiskSpace(EDriveC);
780 freeD=FreeDiskSpace(RemovableDrive);
781 test.Printf(_L("free space on drive %d = 0x%x\n"),EDriveC,freeC);
782 test.Printf(_L("free space on drive %d = 0x%x\n"),RemovableDrive,freeD);
783 TheFs.NotifyDiskSpace(freeC+1024,EDriveC,stat1);
784 TheFs.NotifyDiskSpace(freeD-1024,RemovableDrive,stat2);
785 test(stat1==KRequestPending && stat2==KRequestPending);
786 // UserSvr::ForceRemountMedia(ERemovableMedia0);
787 r = GenerateMediaChange();
790 User::After(1000000);
791 User::WaitForRequest(stat2);
792 test(stat1==KRequestPending && stat2==KErrNone);
793 TheFs.NotifyDiskSpaceCancel(stat1);
794 test(stat1==KErrCancel);
798 test.Printf(_L("media change not supported, skipping this step\n"));
799 TheFs.NotifyDiskSpaceCancel(stat1);
800 test(stat1 == KErrCancel);
801 TheFs.NotifyDiskSpaceCancel(stat2);
802 test(stat2 == KErrCancel);
805 // test that scandrive notifies clients on only specific drives
806 test.Next(_L("scandrive"));
807 // first test that scandrive does not find any problems on the removable media
808 r=TheFs.ScanDrive(RemovableDriveBuf);
810 // now set up disk space notification
811 freeC=FreeDiskSpace(EDriveC);
812 freeD=FreeDiskSpace(RemovableDrive);
813 test.Printf(_L("free space on drive %d = 0x%x\n"),EDriveC,freeC);
814 test.Printf(_L("free space on drive %d = 0x%x\n"),RemovableDrive,freeD);
815 TheFs.NotifyDiskSpace(freeC+8192,EDriveC,stat1);
816 TheFs.NotifyDiskSpace(freeD-8192,RemovableDrive,stat2);
817 test(stat1==KRequestPending && stat2==KRequestPending);
818 r=TheFs.ScanDrive(RemovableDriveBuf);
820 User::After(1000000);
821 User::WaitForRequest(stat2);
822 test(stat1==KRequestPending && stat2==KErrNone);
823 TheFs.NotifyDiskSpaceCancel(stat1);
824 test(stat1==KErrCancel);
827 r=TheFs.Delete(fileName);
829 if(gSessionPath[0]!=(TText)'C')
831 r=TheFs.RmDir(defaultDir);
832 test(r==KErrNone||r==KErrInUse);
839 // test some of the functions that may result in a change in free disk space
840 // not testing all functions that may result in free disk space change since
841 // change is dependent on the file system
844 test.Next(_L("test disk space functions"));
845 // create the filler file
847 TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
849 TInt64 newSpace = FreeDiskSpace(KDefaultDrive)-8192;
850 FillDisk(file,newSpace,KDefaultDrive);
853 test.Next(_L("check RFile:Write"));
854 TThreadTask task=ETaskFileWrite;
855 InitialiseForThread(task);
856 TInt64 free=FreeDiskSpace(KDefaultDrive);
857 TRequestStatus stat1;
858 TInt64 threshold=free-200;
859 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
860 test(stat1==KRequestPending);
862 r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
865 User::WaitForRequest(stat1);
866 test(stat1==KErrNone);
867 free=FreeDiskSpace(KDefaultDrive);
868 test(free<threshold);
869 TRequestStatus deathStat;
870 thread.Logon( deathStat );
871 User::WaitForRequest( deathStat );
873 CleanupForThread(task);
875 // check file set size
876 // setting file size on LFFS only uses a small amount of disk space for metadata
877 // so we skip this test for an LFFS drive
880 test.Next(_L("check RFile:SetSize"));
881 task=ETaskFileSetSize;
882 InitialiseForThread(task);
883 free=FreeDiskSpace(KDefaultDrive);
885 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
886 test(stat1==KRequestPending);
887 r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
889 TRequestStatus deathStat;
890 thread.Logon( deathStat );
892 User::WaitForRequest(stat1);
893 test(stat1==KErrNone);
894 free=FreeDiskSpace(KDefaultDrive);
895 test(free<threshold);
896 User::WaitForRequest( deathStat );
898 CleanupForThread(task);
901 // check disk space notification does not occur when threshold not crossed
903 test.Next(_L("check RFile:SetSize with wrong threshold"));
905 User::After(1000000); //put in due to thread latency
907 task=ETaskFileSetSize;
908 InitialiseForThread(task);
909 free=FreeDiskSpace(KDefaultDrive);
911 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
912 test(stat1==KRequestPending);
913 r=thread.Create(_L("thread3"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
915 thread.Logon( deathStat );
918 User::After(1000000);
920 test(stat1==KRequestPending);
921 newFree=FreeDiskSpace(KDefaultDrive);
923 test.Printf(_L("threshold = %d and %d"),threshold.High(), threshold.Low());
924 test.Printf(_L("free = %d and %d"),free.High(), free.Low());
925 test.Printf(_L("newFree = %d and %d"),newFree.High(), newFree.Low());
928 test(free<threshold && newFree<free);
930 test(free<threshold); //changing file size on lffs does not do anything
932 User::WaitForRequest( deathStat );
934 CleanupForThread(task);
935 TheFs.NotifyDiskSpaceCancel(stat1);
936 test(stat1==KErrCancel);
938 // check for file delete
939 test.Next(_L("check RFs::Delete"));
941 InitialiseForThread(task);
942 free=FreeDiskSpace(KDefaultDrive);
944 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
945 test(stat1==KRequestPending);
946 r=thread.Create(_L("thread4"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
948 thread.Logon( deathStat );
950 User::WaitForRequest(stat1);
951 test(stat1==KErrNone);
952 free=FreeDiskSpace(KDefaultDrive);
953 test(free>threshold);
954 User::WaitForRequest( deathStat );
956 CleanupForThread(task);
958 // check for replace with threshold too high
959 test.Next(_L("check RFs::Replace with threshold too high"));
963 test.Printf( _L("Skipped.... test isn't consistent on LFFS drive\n") );
968 InitialiseForThread(task);
969 free=FreeDiskSpace(KDefaultDrive);
970 #if defined(__WINS__)
971 threshold=free + gMinFileSize * 16 + 2048; // 512 * 16 + 2K = 10K
974 threshold=free + (gMinFileSize << 4) + 2048; // 512 * 16 + 2K = 10K
976 threshold=free + gMinFileSize * 9 + 392; // 512 * 9 + 392 = 5000;
979 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
980 test(stat1==KRequestPending);
982 r=thread.Create(_L("thread5"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
984 thread.Logon( deathStat );
987 User::After(1000000);
988 test(stat1==KRequestPending);
989 newFree=FreeDiskSpace(KDefaultDrive);
990 test(newFree<threshold && free<newFree);
991 TheFs.NotifyDiskSpaceCancel();
992 test(stat1==KErrCancel);
993 User::WaitForRequest( deathStat );
995 CleanupForThread(task);
999 test.Next(_L("check RFs:Replace"));
1001 InitialiseForThread(task);
1002 free=FreeDiskSpace(KDefaultDrive);
1004 TheFs.NotifyDiskSpace(threshold,KDefaultDrive,stat1);
1005 test(stat1==KRequestPending);
1006 r=thread.Create(_L("thread6"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1008 thread.Logon( deathStat );
1010 User::WaitForRequest(stat1);
1011 //User::After(1000000);
1012 test(stat1==KErrNone);
1013 User::WaitForRequest( deathStat );
1014 test(deathStat==KErrNone);
1016 CleanupForThread(task);
1017 free=FreeDiskSpace(KDefaultDrive);
1018 test(free>threshold);
1021 // check that CSessionFS::iTheDrive is set in subsession calls
1022 test.Next(_L("Check iTheDrive and subsessions"));
1025 test.Printf( _L("Skipped.... test not done on LFFS drive\n") );
1030 #if defined(__WINS__)
1031 _LIT(someFile,"X:\\abcdef");
1033 TBuf<10> someFile=_L("?:\\abcdef");
1035 TInt r=RFs::DriveToChar(RemovableDrive,c);
1037 someFile[0]=(TText)c;
1039 _LIT(someDir,"C:\\1234\\");
1041 r=f2.Create(TheFs,someFile,EFileShareAny|EFileWrite);
1043 r=TheFs.MkDir(someDir);
1045 TRequestStatus stat2;
1046 TInt64 freeC=FreeDiskSpace(EDriveC);
1047 TInt64 freeD=FreeDiskSpace(RemovableDrive);
1048 TheFs.NotifyDiskSpace(freeC-4097,EDriveC,stat1);
1049 TheFs.NotifyDiskSpace(freeD-4097,RemovableDrive,stat2);
1050 test(stat1==KRequestPending && stat2==KRequestPending);
1051 // before fix this would result in iTheDrive not being updated in next subsession call
1052 // therefore this could would not result in a disk space notification
1055 User::After(1000000);
1056 User::WaitForRequest(stat2);
1058 if (stat2!=KErrNone)
1059 test.Printf(_L("stat2=%d\n"),stat2.Int());
1060 test(stat2==KErrNone);
1061 if (stat1!=KRequestPending)
1062 test.Printf(_L("stat1=%d\n"),stat1.Int());
1063 test(stat1==KRequestPending);
1066 TheFs.NotifyDiskSpaceCancel();
1067 test(stat1==KErrCancel);
1068 r=TheFs.Delete(someFile);
1070 r=TheFs.RmDir(someDir);
1075 r=TheFs.Delete(KFileFiller);
1081 void TestLffsFunctions()
1083 // LFFS-specific tests for some functions which may cause a disk
1088 test.Next(_L("test LFFS disk space functions"));
1089 // create the filler file
1091 TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
1093 TInt64 newSpace = FreeDiskSpace(KDefaultDrive)-8192;
1094 FillDisk(file,newSpace,KDefaultDrive);
1097 // check file create
1098 // Creating a file will always allocate space for the inode
1099 test.Next(_L("check RFile:Create"));
1100 TThreadTask task=ETaskFileCreateLffs;
1101 InitialiseForThread(task);
1102 TInt64 free=FreeDiskSpace(KDefaultDrive);
1103 TInt64 threshold1=free-64;
1104 TInt64 threshold2=free-KFileSize3;
1105 TRequestStatus stat1, stat2;
1106 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1107 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1108 test(stat1==KRequestPending && stat2==KRequestPending);
1110 r=thread.Create(_L("thread7"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1112 TRequestStatus deathStat;
1113 thread.Logon( deathStat );
1115 User::WaitForRequest(stat1);
1116 test(stat1==KErrNone);
1117 free=FreeDiskSpace(KDefaultDrive);
1118 test(free<threshold1);
1119 test(stat2==KRequestPending);
1120 test(free>threshold2);
1121 TheFs.NotifyDiskSpaceCancel(stat2);
1122 User::WaitForRequest(stat2);
1123 test(stat2==KErrCancel);
1124 User::WaitForRequest( deathStat );
1126 CleanupForThread(task);
1129 TRequestStatus stat3;
1131 // don't test for wins urel since cant use RFs::ControlIo
1133 // check background thread notification
1134 test.Next(_L("check Background thread notification"));
1135 task=ETaskSpin; // create thread to block background thread
1136 InitialiseForThread(task);
1137 free=FreeDiskSpace(KDefaultDrive);
1138 threshold1=free-64; // this should occur when we create test file
1139 threshold2=free+9750; // some impossible value
1140 threshold3=free+10000; // some other impossible value that will never happen
1141 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1142 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1143 TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1144 test(stat1==KRequestPending && stat2==KRequestPending && stat3==KRequestPending);
1145 r=thread.Create(_L("thread8"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1147 thread.Logon( deathStat );
1148 thread.SetPriority( EPriorityLess );
1149 thread.Resume(); // start spinning, blocks background thread
1150 // request background thread to notify a daft value
1151 TPckgBuf<TInt64> cBuf;
1152 cBuf() = threshold2;
1153 // Hard code the value of ECioBackgroundNotifyDiskSize.
1154 // Although the value is enumerated in f32\slffs\lffs_controlio.h this header file is being
1155 // removed from the release codeline but retained in the base team development codeline.
1156 #define ECioBackgroundNotifyDiskSize 10016
1157 r = TheFs.ControlIo(GetDriveLFFS(), ECioBackgroundNotifyDiskSize, cBuf);
1158 test( KErrNone==r );
1159 // create a file to force some roll-forward
1160 r=file2.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
1162 User::WaitForRequest(stat1);
1163 test(stat1==KErrNone);
1164 test(stat2==KRequestPending);
1165 test(stat3==KRequestPending);
1166 // kill the spinner thread to allow the background thread to execute
1167 thread.Kill(KErrNone);
1168 User::WaitForRequest( deathStat );
1170 // wait for the notifier
1171 User::WaitForRequest(stat2);
1172 test( stat2==KErrNone );
1173 test( stat3==KRequestPending);
1174 TheFs.NotifyDiskSpaceCancel(stat3);
1175 User::WaitForRequest(stat3);
1176 test(stat3==KErrCancel);
1177 CleanupForThread(task);
1179 TheFs.Delete( KTestFile1 );
1182 // check background thread notification again, this time we won't request
1183 // a special value - check that it notifies normally
1184 test.Next(_L("check Background thread notification again"));
1185 task=ETaskSpin; // create thread to block background thread
1186 InitialiseForThread(task);
1187 free=FreeDiskSpace(KDefaultDrive);
1188 threshold1=free-64; // this should occur when we create test file
1189 threshold2=free+9750; // some impossible value
1190 threshold3=free+10000; // some other impossible value that will never happen
1191 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1192 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1193 TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1194 test(stat1==KRequestPending && stat2==KRequestPending && stat3==KRequestPending);
1195 r=thread.Create(_L("thread9"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1197 thread.Logon( deathStat );
1198 thread.SetPriority( EPriorityLess );
1199 thread.Resume(); // start spinning, blocks background thread
1200 // create a file to force some roll-forward
1201 r=file2.Create(TheFs,KTestFile1,EFileShareAny|EFileWrite);
1203 User::WaitForRequest(stat1);
1204 test(stat1==KErrNone);
1205 test(stat2==KRequestPending);
1206 test(stat3==KRequestPending);
1207 // kill the spinner thread to allow the background thread to execute
1208 thread.Kill(KErrNone);
1209 User::WaitForRequest( deathStat );
1211 // wait for the notifier
1212 test( stat2==KRequestPending );
1213 test( stat3==KRequestPending);
1214 TheFs.NotifyDiskSpaceCancel(stat2);
1215 User::WaitForRequest(stat2);
1216 test(stat2==KErrCancel);
1217 TheFs.NotifyDiskSpaceCancel(stat3);
1218 User::WaitForRequest(stat3);
1219 test(stat3==KErrCancel);
1220 CleanupForThread(task);
1222 TheFs.Delete( KTestFile1 );
1226 r=TheFs.Delete(KFileFiller);
1233 // test muliple requests and multiple sessions
1236 // create the filler file
1238 TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
1240 TInt64 free=FreeDiskSpace(KDefaultDrive);
1241 TInt64 freeSpaceLeft = gMinFileSize << 4; // 512 * 2^4 = 512 * 16 = 8K
1242 FillDisk(file,free-freeSpaceLeft,KDefaultDrive);
1247 test.Printf(_L("filler file size=0x%x\n"),size);
1249 // test multiple requests
1250 test.Next(_L("test multiple requests"));
1251 TThreadTask task = ETaskFileWrite4KB;
1252 InitialiseForThread(task);
1253 free=FreeDiskSpace(KDefaultDrive);
1254 TInt64 threshold1=free-gMinFileSize; // 512;
1255 TInt64 threshold2=free - (gMinFileSize << 2); // 512 * 4 = 2048;
1256 #if defined(__WINS__)
1257 TInt64 threshold3=free-70000; //NTFS over-allocates then reduces when file closed
1259 TInt64 threshold3=free - (gMinFileSize << 5); // 512 * 2^5 = 512 * 32 = 16K
1261 TRequestStatus stat1,stat2,stat3;
1262 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1263 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1264 TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1265 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1267 r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1269 TRequestStatus deathStat;
1270 thread.Logon( deathStat );
1272 User::After(1000000);
1273 User::WaitForRequest(stat1);
1274 User::WaitForRequest(stat2);
1275 test(stat1==KErrNone && stat2==KErrNone);
1276 test(stat3==KRequestPending);
1277 free=FreeDiskSpace(KDefaultDrive);
1278 test(free<threshold1 && free<threshold2 && free>threshold3);
1279 TheFs.NotifyDiskSpaceCancel(stat3);
1280 test(stat3==KErrCancel);
1281 User::WaitForRequest( deathStat );
1283 CleanupForThread(task);
1285 // test multiple requests again
1286 test.Next(_L("test multiple requests again"));
1289 // SetSize doesn't use disk space on LFFS
1290 test.Printf( _L("test skipped on LFFS drive\n") );
1294 task=ETaskFileSetSize;
1295 InitialiseForThread(task); // this also does initialisation for task2
1296 free=FreeDiskSpace(KDefaultDrive);
1297 threshold1 = free + (gMinFileSize << 1); // 512 * 2 = 1024
1298 threshold2 = free + (gMinFileSize * 12); // 512 * 12 = 6144
1299 threshold3 = free - (gMinFileSize << 1); // 512 * 2 = 1024;
1300 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1301 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1302 TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1303 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1304 r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1306 thread.Logon( deathStat );
1309 User::WaitForRequest(stat3);
1310 test(stat3==KErrNone && stat1==KRequestPending && stat2==KRequestPending);
1311 free=FreeDiskSpace(KDefaultDrive);
1312 test(free<threshold1);
1313 User::WaitForRequest( deathStat );
1315 CleanupForThread(task);
1316 if(!IsWinsCDrive(KDefaultDrive))
1318 free=FreeDiskSpace(KDefaultDrive);
1319 test(stat1==KRequestPending && stat2==KRequestPending);
1320 file.SetSize(size - (gMinFileSize << 2)); // 512 * 4 = 2048
1321 free=FreeDiskSpace(KDefaultDrive);
1322 User::After(1000000);
1323 User::WaitForRequest(stat1);
1324 //User::WaitForRequest(stat2);
1325 test(stat1==KErrNone && stat2==KRequestPending);
1326 free=FreeDiskSpace(KDefaultDrive);
1327 test(free>threshold1 && free<threshold2);
1328 TheFs.NotifyDiskSpaceCancel();
1329 test(stat2==KErrCancel);
1333 TheFs.NotifyDiskSpaceCancel();
1334 test(stat1==KErrCancel&&stat2==KErrCancel&&stat3==KErrNone);
1338 // test multiple sessions all notified on disk space change
1339 test.Next(_L("test multiple sessions on same drive"));
1345 r=ses2.SetSessionPath(gSessionPath);
1347 r=ses3.SetSessionPath(gSessionPath);
1349 task=ETaskFileReplace;
1350 InitialiseForThread(task);
1351 free=FreeDiskSpace(KDefaultDrive);
1352 test.Printf(_L("free space on default drive = 0x%x\n"),free);
1353 threshold1=free+gMinFileSize; // 512
1354 threshold2=free+(gMinFileSize << 1); // 1024;
1355 threshold3=free+(gMinFileSize << 2); // 2048;
1356 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1357 ses2.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1358 ses3.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1359 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1360 r=thread.Create(_L("thread3"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1362 thread.Logon( deathStat );
1364 User::After(1000000);
1365 User::WaitForRequest(stat1);
1366 User::WaitForRequest(stat2);
1367 User::WaitForRequest(stat3);
1368 test(stat1==KErrNone && stat2==KErrNone && stat3==KErrNone);
1369 free=FreeDiskSpace(KDefaultDrive);
1370 test(free>threshold1 && free>threshold2 && free>threshold3);
1371 User::WaitForRequest( deathStat );
1373 CleanupForThread(task);
1375 // test NotifyDiskSpaceCancel()
1376 test.Next(_L("test RFs:NotifyDiskSpaceCancel"));
1377 free=FreeDiskSpace(KDefaultDrive);
1378 TheFs.NotifyDiskSpace(free-100,KDefaultDrive,stat1);
1379 ses2.NotifyDiskSpace(free-100,KDefaultDrive,stat2);
1380 ses3.NotifyDiskSpace(free-100,KDefaultDrive,stat3);
1381 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1382 TheFs.NotifyDiskSpaceCancel();
1383 test(stat1==KErrCancel&&stat2==KRequestPending&&stat3==KRequestPending);
1384 ses2.NotifyDiskSpaceCancel(stat2);
1385 test(stat2==KErrCancel&&stat3==KRequestPending);
1386 ses3.NotifyDiskSpaceCancel();
1387 test(stat3==KErrCancel);
1392 r=RFs::CharToDrive(gSessionPath[0],sessionDrive);
1394 if(sessionDrive!=RemovableDrive)
1396 // first create a file on the removable drive
1398 TFileName file2name=RemovableDriveBuf;
1399 file2name+=_L("F32-TST\\testfile1");
1400 TheFs.Delete(file2name);
1401 r=file2.Create(TheFs,file2name,EFileShareAny|EFileWrite);
1403 r=file2.SetSize(KFileSize3);
1405 // test multiple sessions not notified on disk space change on wrong drive
1406 test.Next(_L("test multiple sessions on different drives"));
1407 task=ETaskFileReplace;
1408 InitialiseForThread(task);
1409 TInt64 freeDef=FreeDiskSpace(KDefaultDrive);
1410 TInt64 freeRem=FreeDiskSpace(RemovableDrive);
1411 threshold1=freeDef + (gMinFileSize << 1); // 1024;
1412 threshold2=freeRem + (gMinFileSize << 1); // 1024;
1413 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1414 ses2.NotifyDiskSpace(threshold2,RemovableDrive,stat2);
1415 test(stat1==KRequestPending&&stat2==KRequestPending);
1416 r=thread.Create(_L("thread4"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1418 thread.Logon( deathStat );
1420 User::After(1000000);
1421 User::WaitForRequest(stat1);
1422 test(stat1==KErrNone && stat2==KRequestPending);
1423 free=FreeDiskSpace(KDefaultDrive);
1424 test(free>threshold1);
1425 User::WaitForRequest( deathStat );
1427 CleanupForThread(task);
1428 TheFs.NotifyDiskSpaceCancel(stat2);
1429 test(stat2==KRequestPending);
1430 ses2.NotifyDiskSpaceCancel(stat2);
1431 test(stat2==KErrCancel);
1433 r=TheFs.Delete(file2name);
1443 r=TheFs.Delete(KFileFiller);
1449 void TestLffsMultiple()
1451 // test muliple requests and multiple sessions speicifcally for LFFS drive
1454 // create the filler file
1456 TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
1458 TInt64 free=FreeDiskSpace(KDefaultDrive);
1459 FillDisk(file,free-8192,KDefaultDrive);
1463 test.Printf(_L("filler file size=0x%x\n"),size);
1466 // test multiple requests again
1467 test.Next(_L("test multiple requests on LFFS") );
1469 TThreadTask task=ETaskFileCreateLffs;
1470 InitialiseForThread(task); // this also does initialisation for task2
1471 free=FreeDiskSpace(KDefaultDrive);
1472 TInt64 threshold1=free+8192;
1473 TInt64 threshold2=free+700; //increased threshold as LFFS, unpredicatably, can release drive space
1474 TInt64 threshold3=free-64;
1475 TRequestStatus stat1, stat2, stat3;
1476 //test.Printf(_L("set up notifiers"));
1477 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1478 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1479 TheFs.NotifyDiskSpace(threshold3,KDefaultDrive,stat3);
1480 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1482 r=thread.Create(_L("thread10"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1484 TRequestStatus deathStat;
1485 thread.Logon( deathStat );
1486 // test.Printf(_L("Resuming other thread"));
1489 User::WaitForRequest(stat3);
1490 test(stat3==KErrNone && stat1==KRequestPending && stat2==KRequestPending);
1491 free=FreeDiskSpace(KDefaultDrive);
1492 test(free<threshold1);
1493 User::WaitForRequest( deathStat );
1495 CleanupForThread(task);
1496 free=FreeDiskSpace(KDefaultDrive);
1497 // test.Printf(_L("free =%d and %d"),free.Low(), free.High());
1498 // test.Printf(_L("stat1=%d, stat2=%d"),stat1,stat2);
1499 test(stat1==KRequestPending && stat2==KRequestPending);
1501 User::After(1000000);
1502 User::WaitForRequest(stat2);
1503 test(stat1==KRequestPending && stat2==KErrNone);
1504 free=FreeDiskSpace(KDefaultDrive);
1505 test(free<threshold1 && free>threshold2);
1506 TheFs.NotifyDiskSpaceCancel();
1507 User::WaitForRequest( stat1 );
1508 test(stat1==KErrCancel);
1513 r=RFs::CharToDrive(gSessionPath[0],sessionDrive);
1515 if(sessionDrive!=EDriveC)
1517 // test multiple sessions not notified on disk space change on wrong drive
1518 test.Next(_L("test multiple sessions on different drives"));
1525 r=ses2.SetSessionPath(gSessionPath);
1527 r=ses3.SetSessionPath(gSessionPath);
1530 // first create a file on the C:\ drive
1532 TFileName file2name=_L("C:\\");
1533 file2name+=_L("F32-TST\\");
1534 r=TheFs.MkDir(file2name);
1535 test( KErrNone==r || KErrAlreadyExists==r );
1536 file2name+=_L("testfile1");
1537 TheFs.Delete(file2name);
1538 r=file2.Create(TheFs,file2name,EFileShareAny|EFileWrite);
1540 WriteToFile( file2, KFileSize3 );
1542 task=ETaskFileReplace;
1543 InitialiseForThread(task);
1544 TInt64 freeLffs=FreeDiskSpace(KDefaultDrive);
1545 TInt64 freeD=FreeDiskSpace(EDriveC);
1546 threshold1=freeLffs+1024;
1547 threshold2=freeD+1024;
1548 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1549 ses2.NotifyDiskSpace(threshold2,EDriveC,stat2);
1550 test(stat1==KRequestPending&&stat2==KRequestPending);
1551 r=thread.Create(_L("thread11"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1553 thread.Logon( deathStat );
1555 User::After(1000000);
1556 User::WaitForRequest(stat1);
1557 test(stat1==KErrNone && stat2==KRequestPending);
1558 free=FreeDiskSpace(KDefaultDrive);
1559 test(free>threshold1);
1560 User::WaitForRequest( deathStat );
1562 CleanupForThread(task);
1563 TheFs.NotifyDiskSpaceCancel(stat2);
1564 test(stat2==KRequestPending);
1565 ses2.NotifyDiskSpaceCancel(stat2);
1566 User::WaitForRequest( stat2 );
1567 test(stat2==KErrCancel);
1569 r=TheFs.Delete(file2name);
1578 r=TheFs.Delete(KFileFiller);
1584 void TestChangeNotification()
1586 // test that disk space notification works with (extended) change notification
1589 // create a filler file
1591 TInt r=file.Create(TheFs,KFileFiller,EFileShareAny|EFileWrite|EFileWriteDirectIO);
1593 TInt64 free=FreeDiskSpace(KDefaultDrive);
1594 // use 8KB in filler file
1595 FillDisk(file,free-8192,KDefaultDrive);
1597 // test change notification when no disk space change
1598 test.Next(_L("test change notification"));
1599 TThreadTask task = ETaskNoChange1;
1600 InitialiseForThread(task);
1601 free=FreeDiskSpace(KDefaultDrive);
1602 TInt64 threshold1=free+gMinFileSize;
1603 TInt64 threshold2=free-gMinFileSize;
1604 TRequestStatus stat1,stat2,stat3;
1605 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1); //more free space becoming available
1606 TheFs.NotifyDiskSpace(threshold2,KDefaultDrive,stat2);
1607 TheFs.NotifyChange(ENotifyAll,stat3);
1608 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1610 r=thread.Create(_L("thread1"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1612 TRequestStatus deathStat;
1613 thread.Logon( deathStat );
1615 User::After(1000000);
1616 User::WaitForRequest(stat3);
1618 test(stat1==KRequestPending && stat2==KRequestPending && stat3==KErrNone);
1620 test(stat2==KRequestPending && stat3==KErrNone); //As below
1622 TheFs.NotifyDiskSpaceCancel();
1624 test(stat1==KErrCancel && stat2==KErrCancel);
1626 test(stat2==KErrCancel); //is invalid for LFFS as can free up space un expectedly
1628 User::WaitForRequest( deathStat );
1630 CleanupForThread(task);
1632 // Have three different sessions
1633 // do an operation that will cause the change notification
1634 // and disk change notification to be signalled
1635 test.Next(_L(" test change notification and disk space notification"));
1636 RFs session2,session3;
1637 r=session2.Connect();
1639 r=session3.Connect();
1641 r=session2.SetSessionPath(gSessionPath);
1643 r=session3.SetSessionPath(gSessionPath);
1645 task=ETaskFileWrite;
1646 InitialiseForThread(task);
1647 free=FreeDiskSpace(KDefaultDrive);
1648 threshold1=free-400;
1649 TheFs.NotifyDiskSpace(threshold1,KDefaultDrive,stat1);
1650 session2.NotifyChange(ENotifyAll,stat2);
1651 session3.NotifyChange(ENotifyAll,stat3,KTestFile1);
1652 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1653 r=thread.Create(_L("thread2"),ThreadFunction,KStackSize,KHeapSize,KHeapSize,(TAny*)task);
1655 thread.Logon( deathStat );
1657 User::After(1000000);
1658 User::WaitForRequest(stat1);
1659 User::WaitForRequest(stat2);
1660 User::WaitForRequest(stat3);
1661 test(stat1==KErrNone && stat2==KErrNone && stat3==KErrNone);
1662 free=FreeDiskSpace(KDefaultDrive);
1663 test(free<threshold1);
1664 User::WaitForRequest( deathStat );
1666 CleanupForThread(task);
1668 // check cancellation of change notification and disk space notification
1670 test.Next(_L("test cancellation of notifications"));
1671 TheFs.NotifyDiskSpace(FreeDiskSpace(KDefaultDrive)-512,KDefaultDrive,stat1);
1672 TheFs.NotifyChange(ENotifyAll,stat2);
1673 TheFs.NotifyChange(ENotifyAll,stat3,KTestFile1);
1674 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1675 TheFs.NotifyChangeCancel();
1676 test(stat1==KRequestPending&&stat2==KErrCancel&&stat3==KErrCancel);
1677 TheFs.NotifyDiskSpaceCancel();
1678 test(stat1==KErrCancel);
1679 // request change notification again
1680 TheFs.NotifyDiskSpace(FreeDiskSpace(KDefaultDrive)-512,KDefaultDrive,stat1);
1681 TheFs.NotifyChange(ENotifyAll,stat2);
1682 TheFs.NotifyChange(ENotifyAll,stat3,KTestFile1);
1683 test(stat1==KRequestPending&&stat2==KRequestPending&&stat3==KRequestPending);
1684 TheFs.NotifyDiskSpaceCancel();
1685 test(stat1==KErrCancel&&stat2==KRequestPending&&stat3==KRequestPending);
1686 TheFs.NotifyChangeCancel();
1687 test(stat1==KErrCancel&&stat2==KErrCancel&&stat3==KErrCancel);
1694 r=TheFs.Delete(KFileFiller);
1699 GLDEF_C void CallTestsL()
1709 r = TheFs.CharToDrive( gSessionPath[0], driveNumber );
1710 test( KErrNone == r );
1713 // at present internal ram drive not tested - the test should allow for fact
1714 // that memory allocation will affect the free disk space on the internal ram drive
1716 // pc file system c drive is also not tested - the test should allow for the fact
1717 // that other windows processes may affect the free disk space
1719 if(gSessionPath[0]==(TText)'C')
1721 // check if gSessionPath drive is RAM drive
1722 TDriveInfo driveInfo;
1723 test(KErrNone == TheFs.CharToDrive(gSessionPath[0], driveNumber));
1724 test(KErrNone == TheFs.Drive(driveInfo, driveNumber));
1725 if(driveInfo.iType == EMediaRam)
1729 test.Printf( _L("C:\\ is not tested, test will exit") );
1731 test.Printf( _L("%c:\\ is not tested (is RAM drive), test will exit"), gSessionPath[0]);
1735 //Test uses C drive as secondary drive so test can't be tested on that drive
1736 r = TheFs.CharToDrive(gSessionPath[0], driveNumber);
1737 test(r == KErrNone);
1738 if(driveNumber == EDriveC)
1740 test.Printf(_L("Test uses C drive as secondary drive so test can't be test on C drive, test will exit"));
1745 TestErrorConditions();
1754 TestChangeNotification();
1759 TestLffsFunctions();