112 } |
113 } |
113 |
114 |
114 void PrintFileCacheConfig(TFileCacheConfig& aFileCacheConfig, TBool aDisplay = ETrue) |
115 void PrintFileCacheConfig(TFileCacheConfig& aFileCacheConfig, TBool aDisplay = ETrue) |
115 { |
116 { |
116 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheConfig, aFileCacheConfig); |
117 TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheConfig, aFileCacheConfig); |
117 test (r == KErrNone); |
118 test_KErrNone(r); |
118 if (!aDisplay) |
119 if (!aDisplay) |
119 return; |
120 return; |
120 |
121 |
121 test.Printf(_L("File cache:\nDrive %c\nFlags %08X\nFileCacheReadAsync %d\nFairSchedulingLen %d\nCacheSize %d\nMaxReadAheadLen %d\nClosedFileKeepAliveTime %d\nDirtyDataFlushTime %d"), |
122 test.Printf(_L("File cache:\nDrive %c\nFlags %08X\nFileCacheReadAsync %d\nFairSchedulingLen %d\nCacheSize %d\nMaxReadAheadLen %d\nClosedFileKeepAliveTime %d\nDirtyDataFlushTime %d"), |
122 aFileCacheConfig.iDrive + 'A', |
123 aFileCacheConfig.iDrive + 'A', |
248 TestBufferFail(aBuffer, pos, aLength); |
249 TestBufferFail(aBuffer, pos, aLength); |
249 } |
250 } |
250 } |
251 } |
251 } |
252 } |
252 |
253 |
|
254 TInt FreeRam() |
|
255 { |
|
256 // wait for any async cleanup in the supervisor to finish first... |
|
257 UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); |
|
258 |
|
259 TMemoryInfoV1Buf meminfo; |
|
260 UserHal::MemoryInfo(meminfo); |
|
261 return meminfo().iFreeRamInBytes; |
|
262 } |
|
263 |
|
264 void LowMemoryTest() |
|
265 { |
|
266 TInt fileSize = 0; |
|
267 |
|
268 const TInt KWriteLen = 128*1024; |
|
269 test.Next(_L("Test appending to a file with low memory")); |
|
270 gBufPtr.SetLength(KBufSize); |
|
271 |
|
272 RFile f; |
|
273 TFileName testFile = _L("TEST.BIN"); |
|
274 |
|
275 TInt r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteBuffered); |
|
276 test_KErrNone(r); |
|
277 |
|
278 TInt pos = 0; |
|
279 |
|
280 TPtrC8 writePtr; |
|
281 writePtr.Set(gBufPtr.MidTPtr(pos, KWriteLen)); |
|
282 |
|
283 r = f.Write(pos, writePtr); |
|
284 test_KErrNone(r); |
|
285 pos+= writePtr.Length(); |
|
286 |
|
287 r = f.Size(fileSize); |
|
288 test_KErrNone(r); |
|
289 test_Equal(fileSize,pos); |
|
290 |
|
291 |
|
292 |
|
293 TUint freeRam = FreeRam(); |
|
294 const TInt KPageSize=4096; |
|
295 freeRam = (freeRam + KPageSize -1) & ~(KPageSize-1); |
|
296 test.Printf(_L("FreeRam = %d"), freeRam); |
|
297 |
|
298 RChunk chunk; |
|
299 TChunkCreateInfo chunkInfo; |
|
300 chunkInfo.SetDisconnected(0, 0, freeRam); |
|
301 chunkInfo.SetPaging(TChunkCreateInfo::EUnpaged); |
|
302 test_KErrNone(chunk.Create(chunkInfo)); |
|
303 |
|
304 test.Printf(_L("Gobbling all of memory...")); |
|
305 |
|
306 TUint commitEnd; |
|
307 for (commitEnd = 0; commitEnd < freeRam; commitEnd += KPageSize) |
|
308 { |
|
309 r = chunk.Commit(commitEnd,KPageSize); |
|
310 if (r != KErrNone) |
|
311 break; |
|
312 |
|
313 } |
|
314 test.Printf(_L("commitEnd %d, r %d"), commitEnd, r); |
|
315 test_Value(r, r == KErrNoMemory || r == KErrNone); |
|
316 |
|
317 test.Printf(_L("FreeRam = %d"), FreeRam()); |
|
318 |
|
319 pos-= KSegmentSize; |
|
320 writePtr.Set(gBufPtr.MidTPtr(pos, KWriteLen)); |
|
321 |
|
322 test.Printf(_L("Writing to file...")); |
|
323 |
|
324 // now we have gobbled all or most of memory, the next write can fail |
|
325 // if it does keep decommitting memory until it succeeds and then test that the file size is correct |
|
326 commitEnd = 0; |
|
327 do { |
|
328 |
|
329 r = f.Write(pos, writePtr); |
|
330 test_Value(r, r == KErrNoMemory || r == KErrNone); |
|
331 if (r == KErrNoMemory) |
|
332 { |
|
333 chunk.Decommit(commitEnd,KPageSize); |
|
334 commitEnd += KPageSize; |
|
335 } |
|
336 } |
|
337 while (r == KErrNoMemory); |
|
338 |
|
339 pos+= writePtr.Length(); |
|
340 |
|
341 test.Printf(_L("Gsetting size of file ...")); |
|
342 r = f.Size(fileSize); |
|
343 test_KErrNone(r); |
|
344 test_Equal(fileSize,pos); |
|
345 |
|
346 test.Printf(_L("Closing file ...")); |
|
347 f.Close(); |
|
348 |
|
349 test.Printf(_L("Closing chunk ...")); |
|
350 chunk.Close(); |
|
351 |
|
352 test.Printf(_L("FreeRam = %d"), FreeRam()); |
|
353 } |
|
354 |
|
355 |
253 |
356 |
254 LOCAL_C void UnitTests() |
357 LOCAL_C void UnitTests() |
255 // |
358 // |
256 // Test read file handling. |
359 // Test read file handling. |
257 // |
360 // |
269 |
372 |
270 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
373 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
271 TBool simulatelockFailureMode; |
374 TBool simulatelockFailureMode; |
272 TFileCacheStats fileCacheStats; |
375 TFileCacheStats fileCacheStats; |
273 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
376 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
274 test (r == KErrNone); |
377 test_KErrNone(r); |
275 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
378 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
276 test(fileCacheStats.iFilesOnClosedQueue == 0); |
379 test(fileCacheStats.iFilesOnClosedQueue == 0); |
277 #endif |
380 #endif |
278 |
381 |
279 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
382 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
280 // turn OFF lock failure mode |
383 // turn OFF lock failure mode |
281 simulatelockFailureMode = EFalse; |
384 simulatelockFailureMode = EFalse; |
282 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
385 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
283 test (r == KErrNone); |
386 test_KErrNone(r); |
284 #endif |
387 #endif |
285 |
388 |
286 TFileName testFile = _L("TEST.BIN"); |
389 TFileName testFile = _L("TEST.BIN"); |
287 |
390 |
288 //********************************** |
391 //********************************** |
297 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
400 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
298 TInt uncachedBytesRead; |
401 TInt uncachedBytesRead; |
299 TInt uncachedPacketsRead; |
402 TInt uncachedPacketsRead; |
300 #endif |
403 #endif |
301 |
404 |
|
405 LowMemoryTest(); |
|
406 |
302 // create an empty file, so that any writes overlapping segemt boundaries |
407 // create an empty file, so that any writes overlapping segemt boundaries |
303 // need a read first |
408 // need a read first |
304 // create a test file using directIO and then re-open it in buffered mode, |
409 // create a test file using directIO and then re-open it in buffered mode, |
305 // so that any writes overlapping segemt boundaries need a read first |
410 // so that any writes overlapping segemt boundaries need a read first |
306 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO); |
411 r = f.Replace(TheFs, testFile, EFileWrite | EFileWriteDirectIO); |
616 r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileWrite); |
724 r = f.Open(TheFs, testFile, EFileRead | EFileReadBuffered | EFileWrite); |
617 test_KErrNone(r); |
725 test_KErrNone(r); |
618 |
726 |
619 TInt size; |
727 TInt size; |
620 r = f.Size(size); |
728 r = f.Size(size); |
621 test (r == KErrNone); |
729 test_KErrNone(r); |
622 test (size = KBufSize); |
730 test (size = KBufSize); |
623 |
731 |
624 readPtr.Set(gBuf->Des()); |
732 readPtr.Set(gBuf->Des()); |
625 |
733 |
626 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
734 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
627 // Allocate full cachelines - so we can enable hole testing |
735 // Allocate full cachelines - so we can enable hole testing |
628 TBool allocateAllSegmentsInCacheLine = ETrue; |
736 TBool allocateAllSegmentsInCacheLine = ETrue; |
629 r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine); |
737 r = controlIo(TheFs, gDrive, KControlIoAllocateMaxSegments, allocateAllSegmentsInCacheLine); |
630 test (r == KErrNone); |
738 test_KErrNone(r); |
631 PrintFileCacheStats(fileCacheStats, EFalse); |
739 PrintFileCacheStats(fileCacheStats, EFalse); |
632 TInt holesDetected = fileCacheStats.iHoleCount; |
740 TInt holesDetected = fileCacheStats.iHoleCount; |
633 TInt lockFailures = fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount; |
741 TInt lockFailures = fileCacheStats.iCommitFailureCount + fileCacheStats.iLockFailureCount; |
634 #endif |
742 #endif |
635 |
743 |
810 f.Close(); |
918 f.Close(); |
811 |
919 |
812 |
920 |
813 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
921 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
814 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
922 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
815 test (r == KErrNone); |
923 test_KErrNone(r); |
816 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
924 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
817 test(fileCacheStats.iFilesOnClosedQueue == 1); |
925 test(fileCacheStats.iFilesOnClosedQueue == 1); |
818 #endif |
926 #endif |
819 // |
927 // |
820 |
928 |
844 TestBuffer(gBufPtr, pos, len); |
952 TestBuffer(gBufPtr, pos, len); |
845 test_KErrNone(r); |
953 test_KErrNone(r); |
846 |
954 |
847 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
955 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
848 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
956 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
849 test (r == KErrNone); |
957 test_KErrNone(r); |
850 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
958 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
851 test(fileCacheStats.iFilesOnClosedQueue == 0); |
959 test(fileCacheStats.iFilesOnClosedQueue == 0); |
852 #endif |
960 #endif |
853 f.Close(); |
961 f.Close(); |
854 |
962 |
855 test.Next(_L("close & verify file is back on close queue")); |
963 test.Next(_L("close & verify file is back on close queue")); |
856 |
964 |
857 |
965 |
858 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
966 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
859 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
967 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
860 test (r == KErrNone); |
968 test_KErrNone(r); |
861 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
969 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
862 test(fileCacheStats.iFilesOnClosedQueue == 1); |
970 test(fileCacheStats.iFilesOnClosedQueue == 1); |
863 #endif |
971 #endif |
864 |
972 |
865 if (testNum == ETestCloseQueueEmptyAfterDelete) |
973 if (testNum == ETestCloseQueueEmptyAfterDelete) |
884 f.Close(); |
992 f.Close(); |
885 } |
993 } |
886 |
994 |
887 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
995 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
888 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
996 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
889 test (r == KErrNone); |
997 test_KErrNone(r); |
890 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
998 test.Printf(_L("Number of files on closed queue=%d\n"),fileCacheStats.iFilesOnClosedQueue); |
891 test(fileCacheStats.iFilesOnClosedQueue == 0); |
999 test(fileCacheStats.iFilesOnClosedQueue == 0); |
892 #endif |
1000 #endif |
893 } |
1001 } |
894 |
1002 |
895 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1003 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
896 // turn lock failure mode back ON (if enabled) |
1004 // turn lock failure mode back ON (if enabled) |
897 simulatelockFailureMode = ETrue; |
1005 simulatelockFailureMode = ETrue; |
898 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
1006 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
899 test (r == KErrNone); |
1007 test_KErrNone(r); |
900 #endif |
1008 #endif |
901 |
1009 |
902 //************************************************************** |
1010 //************************************************************** |
903 // Test opening a file with a silly open mode flags combinations |
1011 // Test opening a file with a silly open mode flags combinations |
904 //************************************************************** |
1012 //************************************************************** |
920 const TInt KWriteLen = KSegmentSize+1; |
1028 const TInt KWriteLen = KSegmentSize+1; |
921 writePtr.Set(gBuf->Des().Ptr(), KWriteLen); |
1029 writePtr.Set(gBuf->Des().Ptr(), KWriteLen); |
922 |
1030 |
923 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1031 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
924 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
1032 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
925 test (r == KErrNone); |
1033 test_KErrNone(r); |
926 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount); |
1034 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount); |
927 TInt writeThroughWithDirtyDataCountOld = fileCacheStats.iWriteThroughWithDirtyDataCount; |
1035 TInt writeThroughWithDirtyDataCountOld = fileCacheStats.iWriteThroughWithDirtyDataCount; |
928 TInt writeThroughWithDirtyDataCountNew = writeThroughWithDirtyDataCountOld; |
1036 TInt writeThroughWithDirtyDataCountNew = writeThroughWithDirtyDataCountOld; |
929 #endif |
1037 #endif |
930 |
1038 |
931 TInt fileSize = 0; |
1039 TInt fileSize = 0; |
932 for (TInt i=0; i<4; i++) |
1040 for (TInt i=0; i<4; i++) |
933 { |
1041 { |
934 fileSize = 0; |
1042 fileSize = 0; |
935 r = f.SetSize(fileSize); |
1043 r = f.SetSize(fileSize); |
936 test (r == KErrNone); |
1044 test_KErrNone(r); |
937 for (pos = 0; pos < KMaxFileSize; ) |
1045 for (pos = 0; pos < KMaxFileSize; ) |
938 { |
1046 { |
939 r = f.Write(pos, writePtr); |
1047 r = f.Write(pos, writePtr); |
940 if (r != KErrNone) |
1048 if (r != KErrNone) |
941 { |
1049 { |
942 test.Printf(_L("Iter #%d, write pos %d size %d, Write() returned %d"), i, pos, fileSize, r); |
1050 test.Printf(_L("Iter #%d, write pos %d size %d, Write() returned %d"), i, pos, fileSize, r); |
943 r = f.Flush(); |
1051 r = f.Flush(); |
944 test.Printf(_L("Flush returned %d"), r); |
1052 test.Printf(_L("Flush returned %d"), r); |
945 test(0); |
1053 test(0); |
946 } |
1054 } |
947 test(r == KErrNone); |
1055 test_KErrNone(r); |
948 pos+= writePtr.Length(); |
1056 pos+= writePtr.Length(); |
949 |
1057 |
950 r = f.Size(fileSize); |
1058 r = f.Size(fileSize); |
951 test (r == KErrNone); |
1059 test_KErrNone(r); |
952 if (fileSize != pos) |
1060 if (fileSize != pos) |
953 { |
1061 { |
954 test.Printf(_L("Iter #%d, write pos %d != size %d"), i, pos, fileSize); |
1062 test.Printf(_L("Iter #%d, write pos %d != size %d"), i, pos, fileSize); |
955 r = f.Flush(); |
1063 r = f.Flush(); |
956 test.Printf(_L("Flush returned %d"), r); |
1064 test.Printf(_L("Flush returned %d"), r); |
958 } |
1066 } |
959 test (fileSize == pos); |
1067 test (fileSize == pos); |
960 |
1068 |
961 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1069 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
962 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
1070 r = controlIo(TheFs, gDrive, KControlIoFileCacheStats, fileCacheStats); |
963 test (r == KErrNone); |
1071 test_KErrNone(r); |
964 writeThroughWithDirtyDataCountNew = fileCacheStats.iWriteThroughWithDirtyDataCount; |
1072 writeThroughWithDirtyDataCountNew = fileCacheStats.iWriteThroughWithDirtyDataCount; |
965 if (writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld) |
1073 if (writeThroughWithDirtyDataCountNew > writeThroughWithDirtyDataCountOld) |
966 { |
1074 { |
967 test.Printf(_L("Iter #%d, write pos %d size %d"), i, pos, fileSize); |
1075 test.Printf(_L("Iter #%d, write pos %d size %d"), i, pos, fileSize); |
968 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount); |
1076 test.Printf(_L("Number of Write-throughs with dirty data=%d\n"),fileCacheStats.iWriteThroughWithDirtyDataCount); |
1633 { |
1741 { |
1634 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1742 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1635 // turn OFF lock failure mode |
1743 // turn OFF lock failure mode |
1636 TBool simulatelockFailureMode = EFalse; |
1744 TBool simulatelockFailureMode = EFalse; |
1637 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
1745 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
1638 test (r == KErrNone); |
1746 test_KErrNone(r); |
1639 #endif |
1747 #endif |
1640 |
1748 |
1641 TestFileRead(EFileReadDirectIO); |
1749 TestFileRead(EFileReadDirectIO); |
1642 if (gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn)) |
1750 if (gDriveCacheFlags & (EFileCacheReadEnabled | EFileCacheReadOn)) |
1643 { |
1751 { |
1653 |
1761 |
1654 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1762 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
1655 // turn lock failure mode back ON (if enabled) |
1763 // turn lock failure mode back ON (if enabled) |
1656 simulatelockFailureMode = ETrue; |
1764 simulatelockFailureMode = ETrue; |
1657 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
1765 r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
1658 test (r == KErrNone); |
1766 test_KErrNone(r); |
1659 #endif |
1767 #endif |
1660 } // if (gRunPerformanceTests) |
1768 } // if (gRunPerformanceTests) |
1661 |
1769 |
1662 TestsEnd(); |
1770 TestsEnd(); |
1663 } |
1771 } |