First public contribution.
1 // Copyright (c) 2000-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.
17 #include <e32std_private.h>
21 #include "user_config.h"
23 RTest test( _L("TF_READ") );
26 const TInt KTestUserDataSize = 1024;
27 const TInt KBufferGuardSize = 16384;
29 const TInt KMaxWriteLength = 512;
31 const TInt64 KSampleDataRandomSeed = MAKE_TINT64(0x3e000111,0xAFCBDF0F);
32 const TInt64 KRandomTestSeed = MAKE_TINT64(0x90009901,0xABEF1011);
37 EPanicGetDesInitialOverflow,
41 LOCAL_D void Panic( TPanicNo aPanic )
43 _LIT( KPanicCat, "TF_READ" );
44 User::Panic( KPanicCat, aPanic );
48 class CCheckedBuffer : public CBase
51 CCheckedBuffer( TInt auserDataSize, TInt aGuardSize );
55 void InitialiseGuard();
56 TBool CheckGuard( TInt aUserDataLength ) const;
57 TBool CheckGuardAtStartOfUserData( TInt aGuardLength ) const;
58 void GetDes( TPtrC8& aDes ) const;
59 void GetDes( TPtr8& aDes, TInt aInitialLength, TInt aMaxLength ) const;
66 TPtr8 iUserData; // pointer to user data area
67 const TInt iUserDataSize;
68 const TInt iGuardSize;
74 CCheckedBuffer::CCheckedBuffer( TInt aUserDataSize, TInt aGuardSize )
75 : iUserData(0,0), iUserDataSize( aUserDataSize ), iGuardSize( aGuardSize )
79 CCheckedBuffer::~CCheckedBuffer()
84 void CCheckedBuffer::CreateL()
86 TInt totalCellSizeRequired = iUserDataSize + (2 * iGuardSize);
88 iAllocCell = (TUint8*)User::AllocL( totalCellSizeRequired );
90 test.Printf( _L("Allocated heap cell for checked buffer\n") );
92 iUserData.Set( iAllocCell + iGuardSize, iUserDataSize, iUserDataSize );
95 void CCheckedBuffer::GetDes( TPtrC8& aDes ) const
97 // Create descriptor to the whole user data area in aDes
100 aDes.Set( iAllocCell + iGuardSize, iUserDataSize );
103 void CCheckedBuffer::GetDes( TPtr8& aDes, TInt aInitialLength, TInt aMaxLength ) const
105 // Create modifiable descriptor to the user data area in aDes,
106 // with a maximum length aMaxLength, and initial length aInitialLength
109 __ASSERT_ALWAYS( aMaxLength <= iUserDataSize, Panic(EPanicGetDesOverflow) );
110 __ASSERT_ALWAYS( aInitialLength <= iUserDataSize, Panic(EPanicGetDesInitialOverflow) );
111 aDes.Set( iAllocCell + iGuardSize, aInitialLength, aMaxLength );
115 void CCheckedBuffer::InitialiseGuard()
117 // Create the guard regions
120 TInt totalCellSize = User::AllocLen( iAllocCell );
121 Mem::Fill( iAllocCell, totalCellSize, 0x5A );
124 TBool CCheckedBuffer::CheckGuard( TInt aUserDataLength ) const
126 // Checks that the guard value is still present before the user data
127 // area, and after aUserDataLength bytes of user data
130 const TUint8* p = iAllocCell;
131 const TUint8* pUserDataStart = iUserData.Ptr();
133 for( ; p < pUserDataStart; p++ )
141 p = pUserDataStart + aUserDataLength;
142 const TUint8* pEnd = iAllocCell + User::AllocLen( iAllocCell );
144 for( ; p < pEnd; p++ )
156 TBool CCheckedBuffer::CheckGuardAtStartOfUserData( TInt aGuardLength ) const
158 // Checks that the first aGuardLength bytes of the user data area
159 // contain the guard value
162 const TUint8* p = iUserData.Ptr();
163 const TUint8* pEnd = p + aGuardLength;
165 for( ; p < pEnd; p++ )
178 class CReadTest : public CBase
188 static TInt DummyThread( TAny* aParam );
190 void CreateSampleData();
191 static TBool CheckZero( const TPtrC8& aDes );
192 void CreateTestData( TInt aBlockNumber, TBool aEndOfBlock );
193 TBool CompareAgainstFlash( TInt aFlashOffset, const TPtrC8& aDes, TInt aDescOffset );
195 void TestSimpleReads();
196 void TestSimpleThreadReads();
197 void TestUnalignedReads();
198 void TestUnalignedThreadReads();
199 void TestOffsetBufferThreadReads();
200 void TestOffsetBufferUnalignedThreadReads();
201 void TestReadsFromAllBlocks();
202 void TestSimpleScatterReads1();
203 void TestSimpleScatterReads2();
204 void TestScatterGather();
205 void TestReadAcrossBlock();
207 void PerformCheckedRead( TInt aReadPos, TInt aReadLen );
208 void PerformCheckedThreadRead( TInt aReadPos, TInt aReadLen, TInt aDescOffset );
215 TBusLocalDrive iDrive;
217 TBuf8<512> iReadBuffer;
219 TRandomGenerator iRandom;
221 TBuf8<KTestUserDataSize> iSampleData;
223 CCheckedBuffer* iBuffer;
225 RThread iDummyThread;
228 CReadTest::~CReadTest()
238 void CReadTest::CreateL()
241 // Load the device drivers
245 #ifndef SKIP_PDD_LOAD
246 test.Printf( _L("Loading %S\n"), &KLfsDriverName );
247 r = User::LoadPhysicalDevice( KLfsDriverName );
248 test( KErrNone == r || KErrAlreadyExists == r );
253 test( KErrNone == fs.Connect() );
254 #if 0 // XXX - API violation on EKA2
255 test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
258 fs.FileSystemName( name, KLffsLogicalDriveNumber );
259 if( name.Length() > 0 )
261 test.Printf( _L("Unmounting drive") );
262 test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
263 User::After( 2000000 );
264 test.Printf( _L("Drive unmounted") );
271 // Open a TBusLogicalDevice to it
273 test.Printf( _L("Opening media channel\n") );
274 TBool changedFlag = EFalse;
275 r = iDrive.Connect( KDriveNumber, changedFlag );
276 User::LeaveIfError( r );
277 iDriveOpened = ETrue;
280 // Get size of Flash drive
282 TLocalDriveCapsV2Buf info;
284 iFlashSize = I64LOW(info().iSize);
285 iBlockSize = info().iEraseBlockSize;
286 iBlockCount = iFlashSize / iBlockSize;
288 test.Printf( _L("Flash size is 0x%x bytes\n"), iFlashSize );
291 // Create a dummy thread that we can use to force
292 // other-thread write operations
295 test( KErrNone == iDummyThread.Create( _L("DUMMY"), DummyThread, 256, KMinHeapSize, KMinHeapSize, NULL ) );
298 test( KErrNone == iDummyThread.Create( _L("DUMMY"), DummyThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL ) );
300 // test.Printf( _L("== do it"));
301 // TInt pas = iDummyThread.Create( _L("DUMMY"), DummyThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL );
302 // test.Printf( _L("CREATE = %d"), pas);
303 // test (pas == KErrNone);
306 iDummyThread.Resume();
310 // Create a checked buffer
312 iBuffer = new(ELeave) CCheckedBuffer( KTestUserDataSize, KBufferGuardSize );
316 // Seed the pseudo-random number generator
318 iRandom.SetSeed( KSampleDataRandomSeed );
320 test.Printf( _L("CreateL complete\n") );
325 TInt CReadTest::DummyThread( TAny* /* aParam */ )
327 // Thread does nothing at all
331 test.Printf( _L("== do it"));
335 User::WaitForAnyRequest(); // just block
340 void CReadTest::TestSimpleReads()
342 // Makes reads of 1 byte to 512 bytes into the start of the
343 // checked buffer and tests that only the expected bytes have changed
344 // This uses the simple read function from TBusLocalDrive, and
345 // reads from an aligned Flash address
348 test.Next( _L("Testing simple reads\n") );
351 // Descriptor to user data area, passed to media driver
355 for( TInt readLen = 1; readLen <= 512; readLen++ )
357 test.Printf( _L("Reading %d bytes\n"), readLen );
360 // Prepare the guard data
362 iBuffer->InitialiseGuard();
365 // Set up the descriptor, length=0, maxlen=readLen
367 iBuffer->GetDes( des, 0, readLen );
370 // Now read some data into it
372 test( KErrNone == iDrive.Read( 0, readLen, des ) );
377 test( des.Length() == readLen );
381 iBuffer->GetDes( newDes );
383 test( newDes.Ptr() == des.Ptr() );
385 test( iBuffer->CheckGuard( readLen ) );
387 test( CompareAgainstFlash( 0, des, 0 ) );
392 void CReadTest::TestSimpleThreadReads()
394 // Makes reads of 1 byte to 512 bytes into the start of the
395 // checked buffer and tests that only the expected bytes have changed
396 // This uses the more complex read function from TBusLocalDrive, and
397 // reads from an aligned Flash address
400 test.Next( _L("Testing simple reads using other-thread read function\n") );
403 // Descriptor to user data area, passed to media driver
407 for( TInt readLen = 1; readLen <= 512; readLen++ )
409 test.Printf( _L("Reading %d bytes\n"), readLen );
412 // Prepare the guard data
414 iBuffer->InitialiseGuard();
415 test.Printf( _L("AA\n"));
418 // Set up the descriptor, length=0, maxlen=readLen
420 iBuffer->GetDes( des, 0, readLen );
421 test.Printf( _L("BB\n"));
424 // Now read some data into it
426 test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, 0 ) );
427 test.Printf( _L("CC\n"));
429 test( KErrNone == iDrive.Read( 0, readLen, &des, iDummyThread.Handle(), 0 ) );
432 test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, 0 ) );
438 test.Printf( _L("DD\n"));
439 test.Printf( _L("DD\n"));
440 test.Printf( _L("DD\n"));
441 test.Printf( _L("DD\n"));
442 test( des.Length() == readLen );
445 test.Printf( _L("EE\n"));
446 iBuffer->GetDes( newDes );
447 test.Printf( _L("FF\n"));
448 test( newDes.Ptr() == des.Ptr() );
450 test( iBuffer->CheckGuard( readLen ) );
452 test.Printf( _L("GG\n"));
453 test( CompareAgainstFlash( 0, des, 0 ) );
454 test.Printf( _L("HH\n"));
460 void CReadTest::TestUnalignedReads()
462 // Makes reads of 1 byte to 512 bytes into the start of the
463 // checked buffer and tests that only the expected bytes have changed
464 // This uses the simple read function from TBusLocalDrive.
465 // The data is read from an unaligned address (0ffset 1, 2, 3)
468 test.Next( _L("Testing unaligned reads\n") );
471 // Descriptor to user data area, passed to media driver
475 for( TInt readLen = 1; readLen <= 512; readLen++ )
478 // Set up the descriptor, length=0, maxlen=readLen
480 iBuffer->GetDes( des, 0, readLen );
483 // Repeat for each offset
485 for( TInt offs = 1; offs < 4; offs++ )
487 test.Printf( _L("Reading %d unaligned bytes from offset %d\n"), readLen, offs );
489 iBuffer->InitialiseGuard();
490 test( KErrNone == iDrive.Read( offs, readLen, des ) );
492 test( des.Length() == readLen );
495 iBuffer->GetDes( newDes );
496 test( newDes.Ptr() == des.Ptr() );
498 test( iBuffer->CheckGuard( readLen ) );
500 test( CompareAgainstFlash( offs, des, 0 ) );
507 void CReadTest::TestUnalignedThreadReads()
509 // Makes reads of 1 byte to 512 bytes into the start of the
510 // checked buffer and tests that only the expected bytes have changed
511 // This uses the thread read function from TBusLocalDrive.
512 // The data is read from an unaligned address (0ffset 1, 2, 3)
515 test.Next( _L("Testing unaligned other-thread reads\n") );
518 // Descriptor to user data area, passed to media driver
522 for( TInt readLen = 1; readLen <= 512; readLen++ )
525 // Set up the descriptor, length=0, maxlen=readLen
527 iBuffer->GetDes( des, 0, readLen );
530 // Repeat for each offset
532 for( TInt offs = 1; offs < 4; offs++ )
534 test.Printf( _L("Reading %d unaligned bytes from offset %d\n"), readLen, offs );
536 iBuffer->InitialiseGuard();
538 test( KErrNone == iDrive.Read( offs, readLen, &des, iDummyThread.Handle(), 0 ) );
540 test( KErrNone == iDrive.Read( offs, readLen, &des, KLocalMessageHandle, 0 ) );
543 test( des.Length() == readLen );
546 iBuffer->GetDes( newDes );
547 test( newDes.Ptr() == des.Ptr() );
549 test( iBuffer->CheckGuard( readLen ) );
551 test( CompareAgainstFlash( offs, des, 0 ) );
558 void CReadTest::TestOffsetBufferThreadReads()
560 // Makes reads of 1 byte to 512 bytes to an offset position in the
561 // checked buffer and tests that only the expected bytes have changed
562 // This uses the more complex read function from TBusLocalDrive, and
563 // reads from an aligned Flash address
566 test.Next( _L("Testing other-thread reads into offset position in descriptor\n") );
569 // Descriptor to user data area, passed to media driver
573 for( TInt readLen = 1; readLen <= 512; readLen++ )
575 test.Printf( _L("Reading %d bytes\n"), readLen );
579 // Repeat test for offsets 0..64 in buffer
581 for( TInt destOffset = 1; destOffset < 64; destOffset++ )
583 // test.Printf( _L("... dest offset = %d"), destOffset );
586 // Prepare the guard data
588 iBuffer->InitialiseGuard();
591 // Set up the descriptor, length=0, maxlen=readLen+destOffset
593 iBuffer->GetDes( des, 0, readLen + destOffset );
596 test( KErrNone == iDrive.Read( 0, readLen, &des, iDummyThread.Handle(), destOffset ) );
598 test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, destOffset ) );
604 test( des.Length() == readLen + destOffset );
607 iBuffer->GetDes( newDes );
608 test( newDes.Ptr() == des.Ptr() );
611 // end of written data is at readLen + destOffset
613 test( iBuffer->CheckGuard( readLen+destOffset ) );
615 // check the section between that start of the user data and
616 // the offset position still contains guard data
618 test( iBuffer->CheckGuardAtStartOfUserData( destOffset ) );
620 test( CompareAgainstFlash( 0, des, destOffset ) );
627 void CReadTest::TestOffsetBufferUnalignedThreadReads()
629 // Makes reads of 1 byte to 512 bytes to an offset position in the
630 // checked buffer and tests that only the expected bytes have changed
631 // This uses the more complex read function from TBusLocalDrive, and
632 // reads from an aligned Flash address
635 test.Next( _L("Testing other-thread unaligned reads into offset position in descriptor\n") );
638 // Descriptor to user data area, passed to media driver
642 for( TInt readLen = 1; readLen <= 500; readLen++ )
644 test.Printf( _L("Reading %d bytes\n"), readLen );
648 // Repeat test for offsets 0..64 in buffer
650 for( TInt destOffset = 1; destOffset < 64; destOffset++ )
652 // test.Printf( _L("... dest offset = %d"), destOffset );
655 // repeat for each source offset
657 for( TInt offs = 1; offs < 4; offs++ )
660 // Prepare the guard data
662 iBuffer->InitialiseGuard();
665 // Set up the descriptor, length=0, maxlen=readLen+destOffset
667 iBuffer->GetDes( des, 0, readLen + destOffset );
670 test( KErrNone == iDrive.Read( offs, readLen, &des, iDummyThread.Handle(), destOffset ) );
672 test( KErrNone == iDrive.Read( offs, readLen, &des, KLocalMessageHandle, destOffset ) );
679 test( des.Length() == readLen + destOffset );
682 iBuffer->GetDes( newDes );
683 test( newDes.Ptr() == des.Ptr() );
686 // end of written data is at readLen + destOffset
688 test( iBuffer->CheckGuard( readLen+destOffset ) );
690 // check the section between that start of the user data and
691 // the offset position still contains guard data
693 test( iBuffer->CheckGuardAtStartOfUserData( destOffset ) );
695 test( CompareAgainstFlash( offs, des, destOffset ) );
702 void CReadTest::PerformCheckedRead( TInt aReadPos, TInt aReadLen )
705 iBuffer->InitialiseGuard();
706 iBuffer->GetDes( des, 0, aReadLen );
708 test.Printf( _L("Reading %d byte(s) from offset 0x%x\n"), aReadLen, aReadPos );
709 test( KErrNone == iDrive.Read( aReadPos, aReadLen, des ) );
710 test( des.Length() == aReadLen );
711 test( iBuffer->CheckGuard( aReadLen ) );
712 test( CompareAgainstFlash( aReadPos, des, 0 ) );
715 void CReadTest::PerformCheckedThreadRead( TInt aReadPos, TInt aReadLen, TInt aDescOffset )
718 iBuffer->InitialiseGuard();
719 iBuffer->GetDes( des, 0, aReadLen + aDescOffset );
721 test.Printf( _L("Reading %d byte(s) from offset 0x%x to thread descriptor offset %d\n"), aReadLen, aReadPos, aDescOffset );
723 test( KErrNone == iDrive.Read( aReadPos, aReadLen, &des, iDummyThread.Handle(), aDescOffset ) );
725 test( KErrNone == iDrive.Read( aReadPos, aReadLen, &des, KLocalMessageHandle, aDescOffset ) );
728 // test.Printf( _L("Check descriptor length") );
729 test( des.Length() == aReadLen + aDescOffset );
730 // test.Printf( _L("Check guard") );
731 test( iBuffer->CheckGuard( aReadLen + aDescOffset ) );
732 // test.Printf( _L("Check guard at start of descriptor") );
733 test( iBuffer->CheckGuardAtStartOfUserData( aDescOffset ) );
734 test( CompareAgainstFlash( aReadPos, des, aDescOffset ) );
738 void CReadTest::TestReadsFromAllBlocks()
740 // Does some spot-test reads from all blocks to make sure
741 // that reading across the whole Flash works
744 test.Next( _L("Testing reads from all blocks\n") );
746 for( TInt block = 0; block < iBlockCount; block++ )
748 test.Printf( _L("Reading from block %d"), block );
749 TInt readBase = (block * iBlockSize);
751 PerformCheckedRead( readBase, 1 );
752 PerformCheckedRead( readBase, 24 );
753 PerformCheckedRead( readBase, 99 );
754 PerformCheckedRead( readBase, 511 );
755 PerformCheckedRead( readBase+1, 1 );
756 PerformCheckedRead( readBase+1, 24 );
757 PerformCheckedRead( readBase+1, 99 );
758 PerformCheckedRead( readBase+1, 511 );
759 PerformCheckedRead( readBase+3, 1 );
760 PerformCheckedRead( readBase+3, 24 );
761 PerformCheckedRead( readBase+3, 99 );
762 PerformCheckedRead( readBase+3, 511 );
764 PerformCheckedThreadRead( readBase, 1, 0 );
765 PerformCheckedThreadRead( readBase, 24, 0 );
766 PerformCheckedThreadRead( readBase, 99, 2 );
767 PerformCheckedThreadRead( readBase, 511, 0 );
768 PerformCheckedThreadRead( readBase+1, 1, 11 );
769 PerformCheckedThreadRead( readBase+1, 24, 4 );
770 PerformCheckedThreadRead( readBase+1, 99, 24 );
771 PerformCheckedThreadRead( readBase+1, 511, 0 );
772 PerformCheckedThreadRead( readBase+3, 1, 32 );
773 PerformCheckedThreadRead( readBase+3, 24, 333 );
774 PerformCheckedThreadRead( readBase+3, 99, 0 );
775 PerformCheckedThreadRead( readBase+3, 511, 1 );
779 void CReadTest::TestSimpleScatterReads1()
781 // Does some simple reads of varying length from the
782 // blocks in pseudo-random order.
785 test.Next( _L("Testing simple scatter reads\n") );
787 TRandomGenerator random;
788 random.SetSeed( KRandomTestSeed );
790 for( TInt readLen = 1; readLen <= 512; readLen++ )
792 TInt block = random.Next() % iBlockCount;
793 test.Printf( _L("Reading block %d"), block );
794 TInt readBase = (block * iBlockSize);
795 PerformCheckedRead( readBase, readLen );
799 void CReadTest::TestSimpleScatterReads2()
801 // Does some simple reads of varying length from the
802 // blocks in pseudo-random order.
804 // This is similar to TestSimpleScatterReads1 except that
805 // as the length reduces the read position is moved along
806 // and the test uses the thread-read variant
809 test.Next( _L("Testing simple scatter reads\n") );
811 TRandomGenerator random;
812 random.SetSeed( KRandomTestSeed );
814 for( TInt readLen = 1; readLen <= 512; readLen++ )
816 TInt block = random.Next() % iBlockCount;
817 test.Printf( _L("Reading block %d"), block );
818 TInt readBase = (block * iBlockSize) + (512 - readLen);
819 PerformCheckedRead( readBase, readLen );
823 void CReadTest::TestScatterGather()
825 // This reads bytes from all over the Flash and concatenates
826 // them into a single descriptor. This isn't representative of
827 // anything a real filesystem would do (at present!) but
828 // is an interesting test of the media driver
831 test.Next( _L("Testing scatter-gather reads\n") );
833 TRandomGenerator random;
834 random.SetSeed( KRandomTestSeed );
836 const TInt KMaxReads = 500;
843 SReadInfo* readInfoArray = new SReadInfo[KMaxReads];
844 test( NULL != readInfoArray );
847 iBuffer->InitialiseGuard();
848 iBuffer->GetDes( des, 0, KTestUserDataSize );
852 for( readCount = 0; readCount < KMaxReads; readCount++ )
855 // Create random read position and length
857 TInt block = random.Next() % iBlockCount;
858 TInt blockOffset = random.Next() % 1000;
859 if( blockOffset > 500 )
861 blockOffset = iBlockSize - 1 - blockOffset;
863 TInt readOffset = (block * iBlockSize) + blockOffset;
864 TInt readLength = (random.Next() % 8) + 1;
866 if( des.Length() + readLength > des.MaxLength() )
872 // Save the position & length
874 readInfoArray[readCount].iOffset = readOffset;
875 readInfoArray[readCount].iLength = readLength;
880 _LIT( KScatterReadMsg, "Reading Flash @%x %d bytes to desc offset %d" );
881 test.Printf( KScatterReadMsg, readOffset, readLength, descOffset );
883 test( KErrNone == iDrive.Read( readOffset, readLength, &des, iDummyThread.Handle(), descOffset ) );
885 test( KErrNone == iDrive.Read( readOffset, readLength, &des, KLocalMessageHandle, descOffset ) );
887 test( des.Length() == descOffset + readLength );
889 descOffset += readLength;
893 // Now check all the data against the Flash contents
896 for( TInt i = 0; i < readCount; i++ )
898 TInt readOffset = readInfoArray[i].iOffset ;
899 TInt readLength = readInfoArray[i].iLength;
901 TPtrC8 ptr( des.Ptr() + descOffset, readLength );
902 test( CompareAgainstFlash( readOffset, ptr, 0 ) );
903 descOffset += readLength;
906 delete[] readInfoArray;
912 void CReadTest::TestReadAcrossBlock()
914 // Test reads that cross a block boundary
917 test.Next( _L("Testing reads across block boundary\n") );
919 for( TInt block = 1; block < iBlockCount - 1; block++ )
921 for( TInt readLen = 2; readLen <= 1024; readLen++ )
923 TInt blockBase = (block * iBlockSize);
924 TInt readOffs = blockBase + (iBlockSize - (readLen/2));
925 PerformCheckedRead( readOffs, readLen );
932 void CReadTest::CreateSampleData()
934 // Fills iSampleData with pseudo-random test data
937 TUint32* p = (TUint32*)iSampleData.Ptr();
938 for( TInt j = 0; j < KTestUserDataSize/4; j++ )
940 *p++ = iRandom.Next();
943 iSampleData.SetLength( KTestUserDataSize );
947 TBool CReadTest::CheckZero( const TPtrC8& aDes )
949 // Checks that all bytes in aDes are zero
952 for( TInt i = aDes.Length(); i > 0; )
965 void CReadTest::CreateTestData( TInt aBlockNumber, TBool aEndOfBlock )
967 // Writes some test data to the Flash. If aEndOfBlock is EFalse the
968 // data is created at the start of the block. If it is ETrue then
969 // the data is created right at the end of the block
973 test.Printf( _L("Writing test data to Flash block %d\n"), aBlockNumber );
976 // Generate some test data
980 test.Printf( _L("Erasing block") );
981 TInt writeBaseOffset = (aBlockNumber * iBlockSize);
982 test( KErrNone == iDrive.Format( writeBaseOffset, iBlockSize ) );
985 TInt writeCount = iSampleData.Length() / KMaxWriteLength;
989 writeBaseOffset += iBlockSize - iSampleData.Length();
992 TInt writeOffset = writeBaseOffset;
994 const TUint8* src = iSampleData.Ptr();
996 test.Printf( _L("Writing data") );
997 for( ; (writeCount > 0) && (KErrNone == r); writeCount-- )
999 TPtrC8 buf( src, KMaxWriteLength );
1000 test( KErrNone == iDrive.Write( writeOffset, buf ) );
1001 writeOffset += KMaxWriteLength;
1002 src += KMaxWriteLength;
1004 test( r == KErrNone );
1007 // check that the data was written ok
1009 test.Printf( _L("Verifying data") );
1010 test( CompareAgainstFlash( writeBaseOffset, iSampleData, 0 ) );
1012 test.Printf( _L("... test data written\n") );
1015 TBool CReadTest::CompareAgainstFlash( TInt aFlashOffset, const TPtrC8& aDes, TInt aDescOffset )
1017 // Checks that the data in aDes matches that in the Flash at position
1019 // The test starts at offset aDescOffset in aSampleData. The data length
1020 // tested is aDes->Length() - aDescOffset
1023 TInt dataLength = aDes.Length() - aDescOffset;
1024 const TUint8* srcPtr = aDes.Ptr() + aDescOffset;
1026 TUint offset = aFlashOffset;
1028 TBool failed = EFalse;
1029 const TInt readBufLen = iReadBuffer.MaxLength();
1031 while( (dataLength > 0) && !failed )
1033 TInt len = Min( dataLength, readBufLen );
1034 TInt r = iDrive.Read( offset, len, iReadBuffer );
1037 test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset );
1038 test( KErrNone == r );
1040 test( iReadBuffer.Length() == len );
1042 if( 0 != Mem::Compare( srcPtr, len, iReadBuffer.Ptr(), len ) )
1044 test.Printf( _L("... FAIL: mismatch around offset 0x%x\n"), offset );
1057 void CReadTest::DoTest()
1059 // Main test dispatcher
1063 // Create some test data at start of block 0
1065 CreateTestData( 0, EFalse );
1068 // Now do the simple tests, all reads will return zeros
1073 TestSimpleThreadReads();
1074 TestUnalignedReads();
1075 TestUnalignedThreadReads();
1076 TestOffsetBufferThreadReads();
1077 TestOffsetBufferUnalignedThreadReads();
1080 // Create some more data at start of all other blocks
1082 test.Next( _L("Creating more test data in other blocks") );
1083 for( TInt i = 1; i < iBlockCount; i++ )
1085 CreateTestData( i, EFalse );
1089 // Make sure we can read valid data out of the other blocks
1091 TestReadsFromAllBlocks();
1094 // Now do some scatter-read tests
1096 TestSimpleScatterReads1();
1097 TestSimpleScatterReads2();
1100 // Create some more testdata at end of all blocks
1102 test.Next( _L("Creating test data at end of blocks") );
1103 for( TInt i = 0; i < iBlockCount; i++ )
1105 CreateTestData( i, ETrue );
1109 // Do a full scatter-gather test
1111 TestScatterGather();
1113 TestReadAcrossBlock();
1123 test.Start(_L("Testing media read operations"));
1126 TRAPD( ret, reader.CreateL() );
1127 test( KErrNone == ret );