sl@0
|
1 |
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
#include <e32std.h>
|
sl@0
|
17 |
#include <e32std_private.h>
|
sl@0
|
18 |
#include <e32svr.h>
|
sl@0
|
19 |
#include <e32test.h>
|
sl@0
|
20 |
#include "randgen.h"
|
sl@0
|
21 |
#include "user_config.h"
|
sl@0
|
22 |
|
sl@0
|
23 |
RTest test( _L("TF_READ") );
|
sl@0
|
24 |
|
sl@0
|
25 |
|
sl@0
|
26 |
const TInt KTestUserDataSize = 1024;
|
sl@0
|
27 |
const TInt KBufferGuardSize = 16384;
|
sl@0
|
28 |
|
sl@0
|
29 |
const TInt KMaxWriteLength = 512;
|
sl@0
|
30 |
|
sl@0
|
31 |
const TInt64 KSampleDataRandomSeed = MAKE_TINT64(0x3e000111,0xAFCBDF0F);
|
sl@0
|
32 |
const TInt64 KRandomTestSeed = MAKE_TINT64(0x90009901,0xABEF1011);
|
sl@0
|
33 |
|
sl@0
|
34 |
enum TPanicNo
|
sl@0
|
35 |
{
|
sl@0
|
36 |
EPanicGetDesOverflow,
|
sl@0
|
37 |
EPanicGetDesInitialOverflow,
|
sl@0
|
38 |
EPanicCheckOverflow
|
sl@0
|
39 |
};
|
sl@0
|
40 |
|
sl@0
|
41 |
LOCAL_D void Panic( TPanicNo aPanic )
|
sl@0
|
42 |
{
|
sl@0
|
43 |
_LIT( KPanicCat, "TF_READ" );
|
sl@0
|
44 |
User::Panic( KPanicCat, aPanic );
|
sl@0
|
45 |
}
|
sl@0
|
46 |
|
sl@0
|
47 |
|
sl@0
|
48 |
class CCheckedBuffer : public CBase
|
sl@0
|
49 |
{
|
sl@0
|
50 |
public:
|
sl@0
|
51 |
CCheckedBuffer( TInt auserDataSize, TInt aGuardSize );
|
sl@0
|
52 |
~CCheckedBuffer();
|
sl@0
|
53 |
|
sl@0
|
54 |
void CreateL();
|
sl@0
|
55 |
void InitialiseGuard();
|
sl@0
|
56 |
TBool CheckGuard( TInt aUserDataLength ) const;
|
sl@0
|
57 |
TBool CheckGuardAtStartOfUserData( TInt aGuardLength ) const;
|
sl@0
|
58 |
void GetDes( TPtrC8& aDes ) const;
|
sl@0
|
59 |
void GetDes( TPtr8& aDes, TInt aInitialLength, TInt aMaxLength ) const;
|
sl@0
|
60 |
|
sl@0
|
61 |
|
sl@0
|
62 |
private:
|
sl@0
|
63 |
CCheckedBuffer();
|
sl@0
|
64 |
|
sl@0
|
65 |
private:
|
sl@0
|
66 |
TPtr8 iUserData; // pointer to user data area
|
sl@0
|
67 |
const TInt iUserDataSize;
|
sl@0
|
68 |
const TInt iGuardSize;
|
sl@0
|
69 |
TUint8* iAllocCell;
|
sl@0
|
70 |
};
|
sl@0
|
71 |
|
sl@0
|
72 |
|
sl@0
|
73 |
|
sl@0
|
74 |
CCheckedBuffer::CCheckedBuffer( TInt aUserDataSize, TInt aGuardSize )
|
sl@0
|
75 |
: iUserData(0,0), iUserDataSize( aUserDataSize ), iGuardSize( aGuardSize )
|
sl@0
|
76 |
{
|
sl@0
|
77 |
}
|
sl@0
|
78 |
|
sl@0
|
79 |
CCheckedBuffer::~CCheckedBuffer()
|
sl@0
|
80 |
{
|
sl@0
|
81 |
delete iAllocCell;
|
sl@0
|
82 |
}
|
sl@0
|
83 |
|
sl@0
|
84 |
void CCheckedBuffer::CreateL()
|
sl@0
|
85 |
{
|
sl@0
|
86 |
TInt totalCellSizeRequired = iUserDataSize + (2 * iGuardSize);
|
sl@0
|
87 |
|
sl@0
|
88 |
iAllocCell = (TUint8*)User::AllocL( totalCellSizeRequired );
|
sl@0
|
89 |
|
sl@0
|
90 |
test.Printf( _L("Allocated heap cell for checked buffer\n") );
|
sl@0
|
91 |
|
sl@0
|
92 |
iUserData.Set( iAllocCell + iGuardSize, iUserDataSize, iUserDataSize );
|
sl@0
|
93 |
}
|
sl@0
|
94 |
|
sl@0
|
95 |
void CCheckedBuffer::GetDes( TPtrC8& aDes ) const
|
sl@0
|
96 |
//
|
sl@0
|
97 |
// Create descriptor to the whole user data area in aDes
|
sl@0
|
98 |
//
|
sl@0
|
99 |
{
|
sl@0
|
100 |
aDes.Set( iAllocCell + iGuardSize, iUserDataSize );
|
sl@0
|
101 |
}
|
sl@0
|
102 |
|
sl@0
|
103 |
void CCheckedBuffer::GetDes( TPtr8& aDes, TInt aInitialLength, TInt aMaxLength ) const
|
sl@0
|
104 |
//
|
sl@0
|
105 |
// Create modifiable descriptor to the user data area in aDes,
|
sl@0
|
106 |
// with a maximum length aMaxLength, and initial length aInitialLength
|
sl@0
|
107 |
//
|
sl@0
|
108 |
{
|
sl@0
|
109 |
__ASSERT_ALWAYS( aMaxLength <= iUserDataSize, Panic(EPanicGetDesOverflow) );
|
sl@0
|
110 |
__ASSERT_ALWAYS( aInitialLength <= iUserDataSize, Panic(EPanicGetDesInitialOverflow) );
|
sl@0
|
111 |
aDes.Set( iAllocCell + iGuardSize, aInitialLength, aMaxLength );
|
sl@0
|
112 |
}
|
sl@0
|
113 |
|
sl@0
|
114 |
|
sl@0
|
115 |
void CCheckedBuffer::InitialiseGuard()
|
sl@0
|
116 |
//
|
sl@0
|
117 |
// Create the guard regions
|
sl@0
|
118 |
//
|
sl@0
|
119 |
{
|
sl@0
|
120 |
TInt totalCellSize = User::AllocLen( iAllocCell );
|
sl@0
|
121 |
Mem::Fill( iAllocCell, totalCellSize, 0x5A );
|
sl@0
|
122 |
}
|
sl@0
|
123 |
|
sl@0
|
124 |
TBool CCheckedBuffer::CheckGuard( TInt aUserDataLength ) const
|
sl@0
|
125 |
//
|
sl@0
|
126 |
// Checks that the guard value is still present before the user data
|
sl@0
|
127 |
// area, and after aUserDataLength bytes of user data
|
sl@0
|
128 |
//
|
sl@0
|
129 |
{
|
sl@0
|
130 |
const TUint8* p = iAllocCell;
|
sl@0
|
131 |
const TUint8* pUserDataStart = iUserData.Ptr();
|
sl@0
|
132 |
|
sl@0
|
133 |
for( ; p < pUserDataStart; p++ )
|
sl@0
|
134 |
{
|
sl@0
|
135 |
if( 0x5a != *p )
|
sl@0
|
136 |
{
|
sl@0
|
137 |
return EFalse;
|
sl@0
|
138 |
}
|
sl@0
|
139 |
}
|
sl@0
|
140 |
|
sl@0
|
141 |
p = pUserDataStart + aUserDataLength;
|
sl@0
|
142 |
const TUint8* pEnd = iAllocCell + User::AllocLen( iAllocCell );
|
sl@0
|
143 |
|
sl@0
|
144 |
for( ; p < pEnd; p++ )
|
sl@0
|
145 |
{
|
sl@0
|
146 |
if( 0x5a != *p )
|
sl@0
|
147 |
{
|
sl@0
|
148 |
return EFalse;
|
sl@0
|
149 |
}
|
sl@0
|
150 |
}
|
sl@0
|
151 |
|
sl@0
|
152 |
return ETrue;
|
sl@0
|
153 |
}
|
sl@0
|
154 |
|
sl@0
|
155 |
|
sl@0
|
156 |
TBool CCheckedBuffer::CheckGuardAtStartOfUserData( TInt aGuardLength ) const
|
sl@0
|
157 |
//
|
sl@0
|
158 |
// Checks that the first aGuardLength bytes of the user data area
|
sl@0
|
159 |
// contain the guard value
|
sl@0
|
160 |
//
|
sl@0
|
161 |
{
|
sl@0
|
162 |
const TUint8* p = iUserData.Ptr();
|
sl@0
|
163 |
const TUint8* pEnd = p + aGuardLength;
|
sl@0
|
164 |
|
sl@0
|
165 |
for( ; p < pEnd; p++ )
|
sl@0
|
166 |
{
|
sl@0
|
167 |
if( 0x5a != *p )
|
sl@0
|
168 |
{
|
sl@0
|
169 |
return EFalse;
|
sl@0
|
170 |
}
|
sl@0
|
171 |
}
|
sl@0
|
172 |
|
sl@0
|
173 |
return ETrue;
|
sl@0
|
174 |
}
|
sl@0
|
175 |
|
sl@0
|
176 |
|
sl@0
|
177 |
|
sl@0
|
178 |
class CReadTest : public CBase
|
sl@0
|
179 |
{
|
sl@0
|
180 |
public:
|
sl@0
|
181 |
~CReadTest();
|
sl@0
|
182 |
|
sl@0
|
183 |
void CreateL();
|
sl@0
|
184 |
|
sl@0
|
185 |
void DoTest();
|
sl@0
|
186 |
|
sl@0
|
187 |
private:
|
sl@0
|
188 |
static TInt DummyThread( TAny* aParam );
|
sl@0
|
189 |
|
sl@0
|
190 |
void CreateSampleData();
|
sl@0
|
191 |
static TBool CheckZero( const TPtrC8& aDes );
|
sl@0
|
192 |
void CreateTestData( TInt aBlockNumber, TBool aEndOfBlock );
|
sl@0
|
193 |
TBool CompareAgainstFlash( TInt aFlashOffset, const TPtrC8& aDes, TInt aDescOffset );
|
sl@0
|
194 |
|
sl@0
|
195 |
void TestSimpleReads();
|
sl@0
|
196 |
void TestSimpleThreadReads();
|
sl@0
|
197 |
void TestUnalignedReads();
|
sl@0
|
198 |
void TestUnalignedThreadReads();
|
sl@0
|
199 |
void TestOffsetBufferThreadReads();
|
sl@0
|
200 |
void TestOffsetBufferUnalignedThreadReads();
|
sl@0
|
201 |
void TestReadsFromAllBlocks();
|
sl@0
|
202 |
void TestSimpleScatterReads1();
|
sl@0
|
203 |
void TestSimpleScatterReads2();
|
sl@0
|
204 |
void TestScatterGather();
|
sl@0
|
205 |
void TestReadAcrossBlock();
|
sl@0
|
206 |
|
sl@0
|
207 |
void PerformCheckedRead( TInt aReadPos, TInt aReadLen );
|
sl@0
|
208 |
void PerformCheckedThreadRead( TInt aReadPos, TInt aReadLen, TInt aDescOffset );
|
sl@0
|
209 |
|
sl@0
|
210 |
private:
|
sl@0
|
211 |
TInt iFlashSize;
|
sl@0
|
212 |
TInt iBlockSize;
|
sl@0
|
213 |
TInt iBlockCount;
|
sl@0
|
214 |
|
sl@0
|
215 |
TBusLocalDrive iDrive;
|
sl@0
|
216 |
TBool iDriveOpened;
|
sl@0
|
217 |
TBuf8<512> iReadBuffer;
|
sl@0
|
218 |
|
sl@0
|
219 |
TRandomGenerator iRandom;
|
sl@0
|
220 |
|
sl@0
|
221 |
TBuf8<KTestUserDataSize> iSampleData;
|
sl@0
|
222 |
|
sl@0
|
223 |
CCheckedBuffer* iBuffer;
|
sl@0
|
224 |
|
sl@0
|
225 |
RThread iDummyThread;
|
sl@0
|
226 |
};
|
sl@0
|
227 |
|
sl@0
|
228 |
CReadTest::~CReadTest()
|
sl@0
|
229 |
{
|
sl@0
|
230 |
if( iDriveOpened )
|
sl@0
|
231 |
{
|
sl@0
|
232 |
iDrive.Disconnect();
|
sl@0
|
233 |
}
|
sl@0
|
234 |
}
|
sl@0
|
235 |
|
sl@0
|
236 |
|
sl@0
|
237 |
|
sl@0
|
238 |
void CReadTest::CreateL()
|
sl@0
|
239 |
{
|
sl@0
|
240 |
//
|
sl@0
|
241 |
// Load the device drivers
|
sl@0
|
242 |
//
|
sl@0
|
243 |
TInt r;
|
sl@0
|
244 |
|
sl@0
|
245 |
#ifndef SKIP_PDD_LOAD
|
sl@0
|
246 |
test.Printf( _L("Loading %S\n"), &KLfsDriverName );
|
sl@0
|
247 |
r = User::LoadPhysicalDevice( KLfsDriverName );
|
sl@0
|
248 |
test( KErrNone == r || KErrAlreadyExists == r );
|
sl@0
|
249 |
#endif
|
sl@0
|
250 |
|
sl@0
|
251 |
#ifdef UNMOUNT_DRIVE
|
sl@0
|
252 |
RFs fs;
|
sl@0
|
253 |
test( KErrNone == fs.Connect() );
|
sl@0
|
254 |
#if 0 // XXX - API violation on EKA2
|
sl@0
|
255 |
test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
|
sl@0
|
256 |
#endif
|
sl@0
|
257 |
TFullName name;
|
sl@0
|
258 |
fs.FileSystemName( name, KLffsLogicalDriveNumber );
|
sl@0
|
259 |
if( name.Length() > 0 )
|
sl@0
|
260 |
{
|
sl@0
|
261 |
test.Printf( _L("Unmounting drive") );
|
sl@0
|
262 |
test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
|
sl@0
|
263 |
User::After( 2000000 );
|
sl@0
|
264 |
test.Printf( _L("Drive unmounted") );
|
sl@0
|
265 |
}
|
sl@0
|
266 |
|
sl@0
|
267 |
fs.Close();
|
sl@0
|
268 |
#endif
|
sl@0
|
269 |
|
sl@0
|
270 |
//
|
sl@0
|
271 |
// Open a TBusLogicalDevice to it
|
sl@0
|
272 |
//
|
sl@0
|
273 |
test.Printf( _L("Opening media channel\n") );
|
sl@0
|
274 |
TBool changedFlag = EFalse;
|
sl@0
|
275 |
r = iDrive.Connect( KDriveNumber, changedFlag );
|
sl@0
|
276 |
User::LeaveIfError( r );
|
sl@0
|
277 |
iDriveOpened = ETrue;
|
sl@0
|
278 |
|
sl@0
|
279 |
//
|
sl@0
|
280 |
// Get size of Flash drive
|
sl@0
|
281 |
//
|
sl@0
|
282 |
TLocalDriveCapsV2Buf info;
|
sl@0
|
283 |
iDrive.Caps(info);
|
sl@0
|
284 |
iFlashSize = I64LOW(info().iSize);
|
sl@0
|
285 |
iBlockSize = info().iEraseBlockSize;
|
sl@0
|
286 |
iBlockCount = iFlashSize / iBlockSize;
|
sl@0
|
287 |
|
sl@0
|
288 |
test.Printf( _L("Flash size is 0x%x bytes\n"), iFlashSize );
|
sl@0
|
289 |
|
sl@0
|
290 |
//
|
sl@0
|
291 |
// Create a dummy thread that we can use to force
|
sl@0
|
292 |
// other-thread write operations
|
sl@0
|
293 |
//
|
sl@0
|
294 |
#if 0
|
sl@0
|
295 |
test( KErrNone == iDummyThread.Create( _L("DUMMY"), DummyThread, 256, KMinHeapSize, KMinHeapSize, NULL ) );
|
sl@0
|
296 |
#else
|
sl@0
|
297 |
// XXX TONYL
|
sl@0
|
298 |
test( KErrNone == iDummyThread.Create( _L("DUMMY"), DummyThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL ) );
|
sl@0
|
299 |
|
sl@0
|
300 |
// test.Printf( _L("== do it"));
|
sl@0
|
301 |
// TInt pas = iDummyThread.Create( _L("DUMMY"), DummyThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL );
|
sl@0
|
302 |
// test.Printf( _L("CREATE = %d"), pas);
|
sl@0
|
303 |
// test (pas == KErrNone);
|
sl@0
|
304 |
#endif
|
sl@0
|
305 |
#if 1
|
sl@0
|
306 |
iDummyThread.Resume();
|
sl@0
|
307 |
#endif
|
sl@0
|
308 |
|
sl@0
|
309 |
//
|
sl@0
|
310 |
// Create a checked buffer
|
sl@0
|
311 |
//
|
sl@0
|
312 |
iBuffer = new(ELeave) CCheckedBuffer( KTestUserDataSize, KBufferGuardSize );
|
sl@0
|
313 |
iBuffer->CreateL();
|
sl@0
|
314 |
|
sl@0
|
315 |
//
|
sl@0
|
316 |
// Seed the pseudo-random number generator
|
sl@0
|
317 |
//
|
sl@0
|
318 |
iRandom.SetSeed( KSampleDataRandomSeed );
|
sl@0
|
319 |
|
sl@0
|
320 |
test.Printf( _L("CreateL complete\n") );
|
sl@0
|
321 |
}
|
sl@0
|
322 |
|
sl@0
|
323 |
|
sl@0
|
324 |
|
sl@0
|
325 |
TInt CReadTest::DummyThread( TAny* /* aParam */ )
|
sl@0
|
326 |
//
|
sl@0
|
327 |
// Thread does nothing at all
|
sl@0
|
328 |
//
|
sl@0
|
329 |
{
|
sl@0
|
330 |
#if 1
|
sl@0
|
331 |
test.Printf( _L("== do it"));
|
sl@0
|
332 |
#endif
|
sl@0
|
333 |
for(;;)
|
sl@0
|
334 |
{
|
sl@0
|
335 |
User::WaitForAnyRequest(); // just block
|
sl@0
|
336 |
}
|
sl@0
|
337 |
}
|
sl@0
|
338 |
|
sl@0
|
339 |
|
sl@0
|
340 |
void CReadTest::TestSimpleReads()
|
sl@0
|
341 |
//
|
sl@0
|
342 |
// Makes reads of 1 byte to 512 bytes into the start of the
|
sl@0
|
343 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
344 |
// This uses the simple read function from TBusLocalDrive, and
|
sl@0
|
345 |
// reads from an aligned Flash address
|
sl@0
|
346 |
//
|
sl@0
|
347 |
{
|
sl@0
|
348 |
test.Next( _L("Testing simple reads\n") );
|
sl@0
|
349 |
|
sl@0
|
350 |
//
|
sl@0
|
351 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
352 |
//
|
sl@0
|
353 |
TPtr8 des(0,0);
|
sl@0
|
354 |
|
sl@0
|
355 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
356 |
{
|
sl@0
|
357 |
test.Printf( _L("Reading %d bytes\n"), readLen );
|
sl@0
|
358 |
|
sl@0
|
359 |
//
|
sl@0
|
360 |
// Prepare the guard data
|
sl@0
|
361 |
//
|
sl@0
|
362 |
iBuffer->InitialiseGuard();
|
sl@0
|
363 |
|
sl@0
|
364 |
//
|
sl@0
|
365 |
// Set up the descriptor, length=0, maxlen=readLen
|
sl@0
|
366 |
//
|
sl@0
|
367 |
iBuffer->GetDes( des, 0, readLen );
|
sl@0
|
368 |
|
sl@0
|
369 |
//
|
sl@0
|
370 |
// Now read some data into it
|
sl@0
|
371 |
//
|
sl@0
|
372 |
test( KErrNone == iDrive.Read( 0, readLen, des ) );
|
sl@0
|
373 |
|
sl@0
|
374 |
//
|
sl@0
|
375 |
// Check what we got
|
sl@0
|
376 |
//
|
sl@0
|
377 |
test( des.Length() == readLen );
|
sl@0
|
378 |
|
sl@0
|
379 |
TPtrC8 newDes;
|
sl@0
|
380 |
|
sl@0
|
381 |
iBuffer->GetDes( newDes );
|
sl@0
|
382 |
|
sl@0
|
383 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
384 |
|
sl@0
|
385 |
test( iBuffer->CheckGuard( readLen ) );
|
sl@0
|
386 |
|
sl@0
|
387 |
test( CompareAgainstFlash( 0, des, 0 ) );
|
sl@0
|
388 |
|
sl@0
|
389 |
}
|
sl@0
|
390 |
}
|
sl@0
|
391 |
|
sl@0
|
392 |
void CReadTest::TestSimpleThreadReads()
|
sl@0
|
393 |
//
|
sl@0
|
394 |
// Makes reads of 1 byte to 512 bytes into the start of the
|
sl@0
|
395 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
396 |
// This uses the more complex read function from TBusLocalDrive, and
|
sl@0
|
397 |
// reads from an aligned Flash address
|
sl@0
|
398 |
//
|
sl@0
|
399 |
{
|
sl@0
|
400 |
test.Next( _L("Testing simple reads using other-thread read function\n") );
|
sl@0
|
401 |
|
sl@0
|
402 |
//
|
sl@0
|
403 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
404 |
//
|
sl@0
|
405 |
TPtr8 des(0,0);
|
sl@0
|
406 |
|
sl@0
|
407 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
408 |
{
|
sl@0
|
409 |
test.Printf( _L("Reading %d bytes\n"), readLen );
|
sl@0
|
410 |
|
sl@0
|
411 |
//
|
sl@0
|
412 |
// Prepare the guard data
|
sl@0
|
413 |
//
|
sl@0
|
414 |
iBuffer->InitialiseGuard();
|
sl@0
|
415 |
test.Printf( _L("AA\n"));
|
sl@0
|
416 |
|
sl@0
|
417 |
//
|
sl@0
|
418 |
// Set up the descriptor, length=0, maxlen=readLen
|
sl@0
|
419 |
//
|
sl@0
|
420 |
iBuffer->GetDes( des, 0, readLen );
|
sl@0
|
421 |
test.Printf( _L("BB\n"));
|
sl@0
|
422 |
|
sl@0
|
423 |
//
|
sl@0
|
424 |
// Now read some data into it
|
sl@0
|
425 |
//
|
sl@0
|
426 |
test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, 0 ) );
|
sl@0
|
427 |
test.Printf( _L("CC\n"));
|
sl@0
|
428 |
#if 0
|
sl@0
|
429 |
test( KErrNone == iDrive.Read( 0, readLen, &des, iDummyThread.Handle(), 0 ) );
|
sl@0
|
430 |
#else
|
sl@0
|
431 |
// XXX - this works
|
sl@0
|
432 |
test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, 0 ) );
|
sl@0
|
433 |
#endif
|
sl@0
|
434 |
|
sl@0
|
435 |
//
|
sl@0
|
436 |
// Check what we got
|
sl@0
|
437 |
//
|
sl@0
|
438 |
test.Printf( _L("DD\n"));
|
sl@0
|
439 |
test.Printf( _L("DD\n"));
|
sl@0
|
440 |
test.Printf( _L("DD\n"));
|
sl@0
|
441 |
test.Printf( _L("DD\n"));
|
sl@0
|
442 |
test( des.Length() == readLen );
|
sl@0
|
443 |
|
sl@0
|
444 |
TPtrC8 newDes;
|
sl@0
|
445 |
test.Printf( _L("EE\n"));
|
sl@0
|
446 |
iBuffer->GetDes( newDes );
|
sl@0
|
447 |
test.Printf( _L("FF\n"));
|
sl@0
|
448 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
449 |
|
sl@0
|
450 |
test( iBuffer->CheckGuard( readLen ) );
|
sl@0
|
451 |
|
sl@0
|
452 |
test.Printf( _L("GG\n"));
|
sl@0
|
453 |
test( CompareAgainstFlash( 0, des, 0 ) );
|
sl@0
|
454 |
test.Printf( _L("HH\n"));
|
sl@0
|
455 |
|
sl@0
|
456 |
}
|
sl@0
|
457 |
}
|
sl@0
|
458 |
|
sl@0
|
459 |
|
sl@0
|
460 |
void CReadTest::TestUnalignedReads()
|
sl@0
|
461 |
//
|
sl@0
|
462 |
// Makes reads of 1 byte to 512 bytes into the start of the
|
sl@0
|
463 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
464 |
// This uses the simple read function from TBusLocalDrive.
|
sl@0
|
465 |
// The data is read from an unaligned address (0ffset 1, 2, 3)
|
sl@0
|
466 |
//
|
sl@0
|
467 |
{
|
sl@0
|
468 |
test.Next( _L("Testing unaligned reads\n") );
|
sl@0
|
469 |
|
sl@0
|
470 |
//
|
sl@0
|
471 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
472 |
//
|
sl@0
|
473 |
TPtr8 des(0,0);
|
sl@0
|
474 |
|
sl@0
|
475 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
476 |
{
|
sl@0
|
477 |
//
|
sl@0
|
478 |
// Set up the descriptor, length=0, maxlen=readLen
|
sl@0
|
479 |
//
|
sl@0
|
480 |
iBuffer->GetDes( des, 0, readLen );
|
sl@0
|
481 |
|
sl@0
|
482 |
//
|
sl@0
|
483 |
// Repeat for each offset
|
sl@0
|
484 |
//
|
sl@0
|
485 |
for( TInt offs = 1; offs < 4; offs++ )
|
sl@0
|
486 |
{
|
sl@0
|
487 |
test.Printf( _L("Reading %d unaligned bytes from offset %d\n"), readLen, offs );
|
sl@0
|
488 |
|
sl@0
|
489 |
iBuffer->InitialiseGuard();
|
sl@0
|
490 |
test( KErrNone == iDrive.Read( offs, readLen, des ) );
|
sl@0
|
491 |
|
sl@0
|
492 |
test( des.Length() == readLen );
|
sl@0
|
493 |
|
sl@0
|
494 |
TPtrC8 newDes;
|
sl@0
|
495 |
iBuffer->GetDes( newDes );
|
sl@0
|
496 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
497 |
|
sl@0
|
498 |
test( iBuffer->CheckGuard( readLen ) );
|
sl@0
|
499 |
|
sl@0
|
500 |
test( CompareAgainstFlash( offs, des, 0 ) );
|
sl@0
|
501 |
}
|
sl@0
|
502 |
|
sl@0
|
503 |
}
|
sl@0
|
504 |
}
|
sl@0
|
505 |
|
sl@0
|
506 |
|
sl@0
|
507 |
void CReadTest::TestUnalignedThreadReads()
|
sl@0
|
508 |
//
|
sl@0
|
509 |
// Makes reads of 1 byte to 512 bytes into the start of the
|
sl@0
|
510 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
511 |
// This uses the thread read function from TBusLocalDrive.
|
sl@0
|
512 |
// The data is read from an unaligned address (0ffset 1, 2, 3)
|
sl@0
|
513 |
//
|
sl@0
|
514 |
{
|
sl@0
|
515 |
test.Next( _L("Testing unaligned other-thread reads\n") );
|
sl@0
|
516 |
|
sl@0
|
517 |
//
|
sl@0
|
518 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
519 |
//
|
sl@0
|
520 |
TPtr8 des(0,0);
|
sl@0
|
521 |
|
sl@0
|
522 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
523 |
{
|
sl@0
|
524 |
//
|
sl@0
|
525 |
// Set up the descriptor, length=0, maxlen=readLen
|
sl@0
|
526 |
//
|
sl@0
|
527 |
iBuffer->GetDes( des, 0, readLen );
|
sl@0
|
528 |
|
sl@0
|
529 |
//
|
sl@0
|
530 |
// Repeat for each offset
|
sl@0
|
531 |
//
|
sl@0
|
532 |
for( TInt offs = 1; offs < 4; offs++ )
|
sl@0
|
533 |
{
|
sl@0
|
534 |
test.Printf( _L("Reading %d unaligned bytes from offset %d\n"), readLen, offs );
|
sl@0
|
535 |
|
sl@0
|
536 |
iBuffer->InitialiseGuard();
|
sl@0
|
537 |
#if 0
|
sl@0
|
538 |
test( KErrNone == iDrive.Read( offs, readLen, &des, iDummyThread.Handle(), 0 ) );
|
sl@0
|
539 |
#else
|
sl@0
|
540 |
test( KErrNone == iDrive.Read( offs, readLen, &des, KLocalMessageHandle, 0 ) );
|
sl@0
|
541 |
#endif
|
sl@0
|
542 |
|
sl@0
|
543 |
test( des.Length() == readLen );
|
sl@0
|
544 |
|
sl@0
|
545 |
TPtrC8 newDes;
|
sl@0
|
546 |
iBuffer->GetDes( newDes );
|
sl@0
|
547 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
548 |
|
sl@0
|
549 |
test( iBuffer->CheckGuard( readLen ) );
|
sl@0
|
550 |
|
sl@0
|
551 |
test( CompareAgainstFlash( offs, des, 0 ) );
|
sl@0
|
552 |
}
|
sl@0
|
553 |
|
sl@0
|
554 |
}
|
sl@0
|
555 |
}
|
sl@0
|
556 |
|
sl@0
|
557 |
|
sl@0
|
558 |
void CReadTest::TestOffsetBufferThreadReads()
|
sl@0
|
559 |
//
|
sl@0
|
560 |
// Makes reads of 1 byte to 512 bytes to an offset position in the
|
sl@0
|
561 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
562 |
// This uses the more complex read function from TBusLocalDrive, and
|
sl@0
|
563 |
// reads from an aligned Flash address
|
sl@0
|
564 |
//
|
sl@0
|
565 |
{
|
sl@0
|
566 |
test.Next( _L("Testing other-thread reads into offset position in descriptor\n") );
|
sl@0
|
567 |
|
sl@0
|
568 |
//
|
sl@0
|
569 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
570 |
//
|
sl@0
|
571 |
TPtr8 des(0,0);
|
sl@0
|
572 |
|
sl@0
|
573 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
574 |
{
|
sl@0
|
575 |
test.Printf( _L("Reading %d bytes\n"), readLen );
|
sl@0
|
576 |
|
sl@0
|
577 |
|
sl@0
|
578 |
//
|
sl@0
|
579 |
// Repeat test for offsets 0..64 in buffer
|
sl@0
|
580 |
//
|
sl@0
|
581 |
for( TInt destOffset = 1; destOffset < 64; destOffset++ )
|
sl@0
|
582 |
{
|
sl@0
|
583 |
// test.Printf( _L("... dest offset = %d"), destOffset );
|
sl@0
|
584 |
|
sl@0
|
585 |
//
|
sl@0
|
586 |
// Prepare the guard data
|
sl@0
|
587 |
//
|
sl@0
|
588 |
iBuffer->InitialiseGuard();
|
sl@0
|
589 |
|
sl@0
|
590 |
//
|
sl@0
|
591 |
// Set up the descriptor, length=0, maxlen=readLen+destOffset
|
sl@0
|
592 |
//
|
sl@0
|
593 |
iBuffer->GetDes( des, 0, readLen + destOffset );
|
sl@0
|
594 |
|
sl@0
|
595 |
#if 0
|
sl@0
|
596 |
test( KErrNone == iDrive.Read( 0, readLen, &des, iDummyThread.Handle(), destOffset ) );
|
sl@0
|
597 |
#else
|
sl@0
|
598 |
test( KErrNone == iDrive.Read( 0, readLen, &des, KLocalMessageHandle, destOffset ) );
|
sl@0
|
599 |
#endif
|
sl@0
|
600 |
|
sl@0
|
601 |
//
|
sl@0
|
602 |
// Check what we got
|
sl@0
|
603 |
//
|
sl@0
|
604 |
test( des.Length() == readLen + destOffset );
|
sl@0
|
605 |
|
sl@0
|
606 |
TPtrC8 newDes;
|
sl@0
|
607 |
iBuffer->GetDes( newDes );
|
sl@0
|
608 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
609 |
|
sl@0
|
610 |
//
|
sl@0
|
611 |
// end of written data is at readLen + destOffset
|
sl@0
|
612 |
//
|
sl@0
|
613 |
test( iBuffer->CheckGuard( readLen+destOffset ) );
|
sl@0
|
614 |
//
|
sl@0
|
615 |
// check the section between that start of the user data and
|
sl@0
|
616 |
// the offset position still contains guard data
|
sl@0
|
617 |
//
|
sl@0
|
618 |
test( iBuffer->CheckGuardAtStartOfUserData( destOffset ) );
|
sl@0
|
619 |
|
sl@0
|
620 |
test( CompareAgainstFlash( 0, des, destOffset ) );
|
sl@0
|
621 |
}
|
sl@0
|
622 |
|
sl@0
|
623 |
}
|
sl@0
|
624 |
}
|
sl@0
|
625 |
|
sl@0
|
626 |
|
sl@0
|
627 |
void CReadTest::TestOffsetBufferUnalignedThreadReads()
|
sl@0
|
628 |
//
|
sl@0
|
629 |
// Makes reads of 1 byte to 512 bytes to an offset position in the
|
sl@0
|
630 |
// checked buffer and tests that only the expected bytes have changed
|
sl@0
|
631 |
// This uses the more complex read function from TBusLocalDrive, and
|
sl@0
|
632 |
// reads from an aligned Flash address
|
sl@0
|
633 |
//
|
sl@0
|
634 |
{
|
sl@0
|
635 |
test.Next( _L("Testing other-thread unaligned reads into offset position in descriptor\n") );
|
sl@0
|
636 |
|
sl@0
|
637 |
//
|
sl@0
|
638 |
// Descriptor to user data area, passed to media driver
|
sl@0
|
639 |
//
|
sl@0
|
640 |
TPtr8 des(0,0);
|
sl@0
|
641 |
|
sl@0
|
642 |
for( TInt readLen = 1; readLen <= 500; readLen++ )
|
sl@0
|
643 |
{
|
sl@0
|
644 |
test.Printf( _L("Reading %d bytes\n"), readLen );
|
sl@0
|
645 |
|
sl@0
|
646 |
|
sl@0
|
647 |
//
|
sl@0
|
648 |
// Repeat test for offsets 0..64 in buffer
|
sl@0
|
649 |
//
|
sl@0
|
650 |
for( TInt destOffset = 1; destOffset < 64; destOffset++ )
|
sl@0
|
651 |
{
|
sl@0
|
652 |
// test.Printf( _L("... dest offset = %d"), destOffset );
|
sl@0
|
653 |
|
sl@0
|
654 |
//
|
sl@0
|
655 |
// repeat for each source offset
|
sl@0
|
656 |
//
|
sl@0
|
657 |
for( TInt offs = 1; offs < 4; offs++ )
|
sl@0
|
658 |
{
|
sl@0
|
659 |
//
|
sl@0
|
660 |
// Prepare the guard data
|
sl@0
|
661 |
//
|
sl@0
|
662 |
iBuffer->InitialiseGuard();
|
sl@0
|
663 |
|
sl@0
|
664 |
//
|
sl@0
|
665 |
// Set up the descriptor, length=0, maxlen=readLen+destOffset
|
sl@0
|
666 |
//
|
sl@0
|
667 |
iBuffer->GetDes( des, 0, readLen + destOffset );
|
sl@0
|
668 |
|
sl@0
|
669 |
#if 0
|
sl@0
|
670 |
test( KErrNone == iDrive.Read( offs, readLen, &des, iDummyThread.Handle(), destOffset ) );
|
sl@0
|
671 |
#else
|
sl@0
|
672 |
test( KErrNone == iDrive.Read( offs, readLen, &des, KLocalMessageHandle, destOffset ) );
|
sl@0
|
673 |
#endif
|
sl@0
|
674 |
|
sl@0
|
675 |
|
sl@0
|
676 |
//
|
sl@0
|
677 |
// Check what we got
|
sl@0
|
678 |
//
|
sl@0
|
679 |
test( des.Length() == readLen + destOffset );
|
sl@0
|
680 |
|
sl@0
|
681 |
TPtrC8 newDes;
|
sl@0
|
682 |
iBuffer->GetDes( newDes );
|
sl@0
|
683 |
test( newDes.Ptr() == des.Ptr() );
|
sl@0
|
684 |
|
sl@0
|
685 |
//
|
sl@0
|
686 |
// end of written data is at readLen + destOffset
|
sl@0
|
687 |
//
|
sl@0
|
688 |
test( iBuffer->CheckGuard( readLen+destOffset ) );
|
sl@0
|
689 |
//
|
sl@0
|
690 |
// check the section between that start of the user data and
|
sl@0
|
691 |
// the offset position still contains guard data
|
sl@0
|
692 |
//
|
sl@0
|
693 |
test( iBuffer->CheckGuardAtStartOfUserData( destOffset ) );
|
sl@0
|
694 |
|
sl@0
|
695 |
test( CompareAgainstFlash( offs, des, destOffset ) );
|
sl@0
|
696 |
} // end for
|
sl@0
|
697 |
}
|
sl@0
|
698 |
}
|
sl@0
|
699 |
}
|
sl@0
|
700 |
|
sl@0
|
701 |
|
sl@0
|
702 |
void CReadTest::PerformCheckedRead( TInt aReadPos, TInt aReadLen )
|
sl@0
|
703 |
{
|
sl@0
|
704 |
TPtr8 des(0,0);
|
sl@0
|
705 |
iBuffer->InitialiseGuard();
|
sl@0
|
706 |
iBuffer->GetDes( des, 0, aReadLen );
|
sl@0
|
707 |
|
sl@0
|
708 |
test.Printf( _L("Reading %d byte(s) from offset 0x%x\n"), aReadLen, aReadPos );
|
sl@0
|
709 |
test( KErrNone == iDrive.Read( aReadPos, aReadLen, des ) );
|
sl@0
|
710 |
test( des.Length() == aReadLen );
|
sl@0
|
711 |
test( iBuffer->CheckGuard( aReadLen ) );
|
sl@0
|
712 |
test( CompareAgainstFlash( aReadPos, des, 0 ) );
|
sl@0
|
713 |
}
|
sl@0
|
714 |
|
sl@0
|
715 |
void CReadTest::PerformCheckedThreadRead( TInt aReadPos, TInt aReadLen, TInt aDescOffset )
|
sl@0
|
716 |
{
|
sl@0
|
717 |
TPtr8 des(0,0);
|
sl@0
|
718 |
iBuffer->InitialiseGuard();
|
sl@0
|
719 |
iBuffer->GetDes( des, 0, aReadLen + aDescOffset );
|
sl@0
|
720 |
|
sl@0
|
721 |
test.Printf( _L("Reading %d byte(s) from offset 0x%x to thread descriptor offset %d\n"), aReadLen, aReadPos, aDescOffset );
|
sl@0
|
722 |
#if 0
|
sl@0
|
723 |
test( KErrNone == iDrive.Read( aReadPos, aReadLen, &des, iDummyThread.Handle(), aDescOffset ) );
|
sl@0
|
724 |
#else
|
sl@0
|
725 |
test( KErrNone == iDrive.Read( aReadPos, aReadLen, &des, KLocalMessageHandle, aDescOffset ) );
|
sl@0
|
726 |
#endif
|
sl@0
|
727 |
|
sl@0
|
728 |
// test.Printf( _L("Check descriptor length") );
|
sl@0
|
729 |
test( des.Length() == aReadLen + aDescOffset );
|
sl@0
|
730 |
// test.Printf( _L("Check guard") );
|
sl@0
|
731 |
test( iBuffer->CheckGuard( aReadLen + aDescOffset ) );
|
sl@0
|
732 |
// test.Printf( _L("Check guard at start of descriptor") );
|
sl@0
|
733 |
test( iBuffer->CheckGuardAtStartOfUserData( aDescOffset ) );
|
sl@0
|
734 |
test( CompareAgainstFlash( aReadPos, des, aDescOffset ) );
|
sl@0
|
735 |
}
|
sl@0
|
736 |
|
sl@0
|
737 |
|
sl@0
|
738 |
void CReadTest::TestReadsFromAllBlocks()
|
sl@0
|
739 |
//
|
sl@0
|
740 |
// Does some spot-test reads from all blocks to make sure
|
sl@0
|
741 |
// that reading across the whole Flash works
|
sl@0
|
742 |
//
|
sl@0
|
743 |
{
|
sl@0
|
744 |
test.Next( _L("Testing reads from all blocks\n") );
|
sl@0
|
745 |
|
sl@0
|
746 |
for( TInt block = 0; block < iBlockCount; block++ )
|
sl@0
|
747 |
{
|
sl@0
|
748 |
test.Printf( _L("Reading from block %d"), block );
|
sl@0
|
749 |
TInt readBase = (block * iBlockSize);
|
sl@0
|
750 |
|
sl@0
|
751 |
PerformCheckedRead( readBase, 1 );
|
sl@0
|
752 |
PerformCheckedRead( readBase, 24 );
|
sl@0
|
753 |
PerformCheckedRead( readBase, 99 );
|
sl@0
|
754 |
PerformCheckedRead( readBase, 511 );
|
sl@0
|
755 |
PerformCheckedRead( readBase+1, 1 );
|
sl@0
|
756 |
PerformCheckedRead( readBase+1, 24 );
|
sl@0
|
757 |
PerformCheckedRead( readBase+1, 99 );
|
sl@0
|
758 |
PerformCheckedRead( readBase+1, 511 );
|
sl@0
|
759 |
PerformCheckedRead( readBase+3, 1 );
|
sl@0
|
760 |
PerformCheckedRead( readBase+3, 24 );
|
sl@0
|
761 |
PerformCheckedRead( readBase+3, 99 );
|
sl@0
|
762 |
PerformCheckedRead( readBase+3, 511 );
|
sl@0
|
763 |
|
sl@0
|
764 |
PerformCheckedThreadRead( readBase, 1, 0 );
|
sl@0
|
765 |
PerformCheckedThreadRead( readBase, 24, 0 );
|
sl@0
|
766 |
PerformCheckedThreadRead( readBase, 99, 2 );
|
sl@0
|
767 |
PerformCheckedThreadRead( readBase, 511, 0 );
|
sl@0
|
768 |
PerformCheckedThreadRead( readBase+1, 1, 11 );
|
sl@0
|
769 |
PerformCheckedThreadRead( readBase+1, 24, 4 );
|
sl@0
|
770 |
PerformCheckedThreadRead( readBase+1, 99, 24 );
|
sl@0
|
771 |
PerformCheckedThreadRead( readBase+1, 511, 0 );
|
sl@0
|
772 |
PerformCheckedThreadRead( readBase+3, 1, 32 );
|
sl@0
|
773 |
PerformCheckedThreadRead( readBase+3, 24, 333 );
|
sl@0
|
774 |
PerformCheckedThreadRead( readBase+3, 99, 0 );
|
sl@0
|
775 |
PerformCheckedThreadRead( readBase+3, 511, 1 );
|
sl@0
|
776 |
}
|
sl@0
|
777 |
}
|
sl@0
|
778 |
|
sl@0
|
779 |
void CReadTest::TestSimpleScatterReads1()
|
sl@0
|
780 |
//
|
sl@0
|
781 |
// Does some simple reads of varying length from the
|
sl@0
|
782 |
// blocks in pseudo-random order.
|
sl@0
|
783 |
//
|
sl@0
|
784 |
{
|
sl@0
|
785 |
test.Next( _L("Testing simple scatter reads\n") );
|
sl@0
|
786 |
|
sl@0
|
787 |
TRandomGenerator random;
|
sl@0
|
788 |
random.SetSeed( KRandomTestSeed );
|
sl@0
|
789 |
|
sl@0
|
790 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
791 |
{
|
sl@0
|
792 |
TInt block = random.Next() % iBlockCount;
|
sl@0
|
793 |
test.Printf( _L("Reading block %d"), block );
|
sl@0
|
794 |
TInt readBase = (block * iBlockSize);
|
sl@0
|
795 |
PerformCheckedRead( readBase, readLen );
|
sl@0
|
796 |
}
|
sl@0
|
797 |
}
|
sl@0
|
798 |
|
sl@0
|
799 |
void CReadTest::TestSimpleScatterReads2()
|
sl@0
|
800 |
//
|
sl@0
|
801 |
// Does some simple reads of varying length from the
|
sl@0
|
802 |
// blocks in pseudo-random order.
|
sl@0
|
803 |
//
|
sl@0
|
804 |
// This is similar to TestSimpleScatterReads1 except that
|
sl@0
|
805 |
// as the length reduces the read position is moved along
|
sl@0
|
806 |
// and the test uses the thread-read variant
|
sl@0
|
807 |
//
|
sl@0
|
808 |
{
|
sl@0
|
809 |
test.Next( _L("Testing simple scatter reads\n") );
|
sl@0
|
810 |
|
sl@0
|
811 |
TRandomGenerator random;
|
sl@0
|
812 |
random.SetSeed( KRandomTestSeed );
|
sl@0
|
813 |
|
sl@0
|
814 |
for( TInt readLen = 1; readLen <= 512; readLen++ )
|
sl@0
|
815 |
{
|
sl@0
|
816 |
TInt block = random.Next() % iBlockCount;
|
sl@0
|
817 |
test.Printf( _L("Reading block %d"), block );
|
sl@0
|
818 |
TInt readBase = (block * iBlockSize) + (512 - readLen);
|
sl@0
|
819 |
PerformCheckedRead( readBase, readLen );
|
sl@0
|
820 |
}
|
sl@0
|
821 |
}
|
sl@0
|
822 |
|
sl@0
|
823 |
void CReadTest::TestScatterGather()
|
sl@0
|
824 |
//
|
sl@0
|
825 |
// This reads bytes from all over the Flash and concatenates
|
sl@0
|
826 |
// them into a single descriptor. This isn't representative of
|
sl@0
|
827 |
// anything a real filesystem would do (at present!) but
|
sl@0
|
828 |
// is an interesting test of the media driver
|
sl@0
|
829 |
//
|
sl@0
|
830 |
{
|
sl@0
|
831 |
test.Next( _L("Testing scatter-gather reads\n") );
|
sl@0
|
832 |
|
sl@0
|
833 |
TRandomGenerator random;
|
sl@0
|
834 |
random.SetSeed( KRandomTestSeed );
|
sl@0
|
835 |
|
sl@0
|
836 |
const TInt KMaxReads = 500;
|
sl@0
|
837 |
struct SReadInfo
|
sl@0
|
838 |
{
|
sl@0
|
839 |
TInt iOffset;
|
sl@0
|
840 |
TInt iLength;
|
sl@0
|
841 |
};
|
sl@0
|
842 |
|
sl@0
|
843 |
SReadInfo* readInfoArray = new SReadInfo[KMaxReads];
|
sl@0
|
844 |
test( NULL != readInfoArray );
|
sl@0
|
845 |
|
sl@0
|
846 |
TPtr8 des(0,0);
|
sl@0
|
847 |
iBuffer->InitialiseGuard();
|
sl@0
|
848 |
iBuffer->GetDes( des, 0, KTestUserDataSize );
|
sl@0
|
849 |
TInt descOffset = 0;
|
sl@0
|
850 |
|
sl@0
|
851 |
TInt readCount;
|
sl@0
|
852 |
for( readCount = 0; readCount < KMaxReads; readCount++ )
|
sl@0
|
853 |
{
|
sl@0
|
854 |
//
|
sl@0
|
855 |
// Create random read position and length
|
sl@0
|
856 |
//
|
sl@0
|
857 |
TInt block = random.Next() % iBlockCount;
|
sl@0
|
858 |
TInt blockOffset = random.Next() % 1000;
|
sl@0
|
859 |
if( blockOffset > 500 )
|
sl@0
|
860 |
{
|
sl@0
|
861 |
blockOffset = iBlockSize - 1 - blockOffset;
|
sl@0
|
862 |
}
|
sl@0
|
863 |
TInt readOffset = (block * iBlockSize) + blockOffset;
|
sl@0
|
864 |
TInt readLength = (random.Next() % 8) + 1;
|
sl@0
|
865 |
|
sl@0
|
866 |
if( des.Length() + readLength > des.MaxLength() )
|
sl@0
|
867 |
{
|
sl@0
|
868 |
break; // finished
|
sl@0
|
869 |
}
|
sl@0
|
870 |
|
sl@0
|
871 |
//
|
sl@0
|
872 |
// Save the position & length
|
sl@0
|
873 |
//
|
sl@0
|
874 |
readInfoArray[readCount].iOffset = readOffset;
|
sl@0
|
875 |
readInfoArray[readCount].iLength = readLength;
|
sl@0
|
876 |
|
sl@0
|
877 |
//
|
sl@0
|
878 |
// do the read
|
sl@0
|
879 |
//
|
sl@0
|
880 |
_LIT( KScatterReadMsg, "Reading Flash @%x %d bytes to desc offset %d" );
|
sl@0
|
881 |
test.Printf( KScatterReadMsg, readOffset, readLength, descOffset );
|
sl@0
|
882 |
#if 0
|
sl@0
|
883 |
test( KErrNone == iDrive.Read( readOffset, readLength, &des, iDummyThread.Handle(), descOffset ) );
|
sl@0
|
884 |
#else
|
sl@0
|
885 |
test( KErrNone == iDrive.Read( readOffset, readLength, &des, KLocalMessageHandle, descOffset ) );
|
sl@0
|
886 |
#endif
|
sl@0
|
887 |
test( des.Length() == descOffset + readLength );
|
sl@0
|
888 |
|
sl@0
|
889 |
descOffset += readLength;
|
sl@0
|
890 |
}
|
sl@0
|
891 |
|
sl@0
|
892 |
//
|
sl@0
|
893 |
// Now check all the data against the Flash contents
|
sl@0
|
894 |
//
|
sl@0
|
895 |
descOffset = 0;
|
sl@0
|
896 |
for( TInt i = 0; i < readCount; i++ )
|
sl@0
|
897 |
{
|
sl@0
|
898 |
TInt readOffset = readInfoArray[i].iOffset ;
|
sl@0
|
899 |
TInt readLength = readInfoArray[i].iLength;
|
sl@0
|
900 |
|
sl@0
|
901 |
TPtrC8 ptr( des.Ptr() + descOffset, readLength );
|
sl@0
|
902 |
test( CompareAgainstFlash( readOffset, ptr, 0 ) );
|
sl@0
|
903 |
descOffset += readLength;
|
sl@0
|
904 |
}
|
sl@0
|
905 |
|
sl@0
|
906 |
delete[] readInfoArray;
|
sl@0
|
907 |
|
sl@0
|
908 |
}
|
sl@0
|
909 |
|
sl@0
|
910 |
|
sl@0
|
911 |
|
sl@0
|
912 |
void CReadTest::TestReadAcrossBlock()
|
sl@0
|
913 |
//
|
sl@0
|
914 |
// Test reads that cross a block boundary
|
sl@0
|
915 |
//
|
sl@0
|
916 |
{
|
sl@0
|
917 |
test.Next( _L("Testing reads across block boundary\n") );
|
sl@0
|
918 |
|
sl@0
|
919 |
for( TInt block = 1; block < iBlockCount - 1; block++ )
|
sl@0
|
920 |
{
|
sl@0
|
921 |
for( TInt readLen = 2; readLen <= 1024; readLen++ )
|
sl@0
|
922 |
{
|
sl@0
|
923 |
TInt blockBase = (block * iBlockSize);
|
sl@0
|
924 |
TInt readOffs = blockBase + (iBlockSize - (readLen/2));
|
sl@0
|
925 |
PerformCheckedRead( readOffs, readLen );
|
sl@0
|
926 |
}
|
sl@0
|
927 |
}
|
sl@0
|
928 |
}
|
sl@0
|
929 |
|
sl@0
|
930 |
|
sl@0
|
931 |
|
sl@0
|
932 |
void CReadTest::CreateSampleData()
|
sl@0
|
933 |
//
|
sl@0
|
934 |
// Fills iSampleData with pseudo-random test data
|
sl@0
|
935 |
//
|
sl@0
|
936 |
{
|
sl@0
|
937 |
TUint32* p = (TUint32*)iSampleData.Ptr();
|
sl@0
|
938 |
for( TInt j = 0; j < KTestUserDataSize/4; j++ )
|
sl@0
|
939 |
{
|
sl@0
|
940 |
*p++ = iRandom.Next();
|
sl@0
|
941 |
}
|
sl@0
|
942 |
|
sl@0
|
943 |
iSampleData.SetLength( KTestUserDataSize );
|
sl@0
|
944 |
}
|
sl@0
|
945 |
|
sl@0
|
946 |
|
sl@0
|
947 |
TBool CReadTest::CheckZero( const TPtrC8& aDes )
|
sl@0
|
948 |
//
|
sl@0
|
949 |
// Checks that all bytes in aDes are zero
|
sl@0
|
950 |
//
|
sl@0
|
951 |
{
|
sl@0
|
952 |
for( TInt i = aDes.Length(); i > 0; )
|
sl@0
|
953 |
{
|
sl@0
|
954 |
--i;
|
sl@0
|
955 |
if( 0 != aDes[i] )
|
sl@0
|
956 |
{
|
sl@0
|
957 |
return EFalse;
|
sl@0
|
958 |
}
|
sl@0
|
959 |
}
|
sl@0
|
960 |
return ETrue;
|
sl@0
|
961 |
}
|
sl@0
|
962 |
|
sl@0
|
963 |
|
sl@0
|
964 |
|
sl@0
|
965 |
void CReadTest::CreateTestData( TInt aBlockNumber, TBool aEndOfBlock )
|
sl@0
|
966 |
//
|
sl@0
|
967 |
// Writes some test data to the Flash. If aEndOfBlock is EFalse the
|
sl@0
|
968 |
// data is created at the start of the block. If it is ETrue then
|
sl@0
|
969 |
// the data is created right at the end of the block
|
sl@0
|
970 |
//
|
sl@0
|
971 |
{
|
sl@0
|
972 |
|
sl@0
|
973 |
test.Printf( _L("Writing test data to Flash block %d\n"), aBlockNumber );
|
sl@0
|
974 |
|
sl@0
|
975 |
//
|
sl@0
|
976 |
// Generate some test data
|
sl@0
|
977 |
//
|
sl@0
|
978 |
CreateSampleData();
|
sl@0
|
979 |
|
sl@0
|
980 |
test.Printf( _L("Erasing block") );
|
sl@0
|
981 |
TInt writeBaseOffset = (aBlockNumber * iBlockSize);
|
sl@0
|
982 |
test( KErrNone == iDrive.Format( writeBaseOffset, iBlockSize ) );
|
sl@0
|
983 |
|
sl@0
|
984 |
|
sl@0
|
985 |
TInt writeCount = iSampleData.Length() / KMaxWriteLength;
|
sl@0
|
986 |
TInt r = KErrNone;
|
sl@0
|
987 |
if( aEndOfBlock )
|
sl@0
|
988 |
{
|
sl@0
|
989 |
writeBaseOffset += iBlockSize - iSampleData.Length();
|
sl@0
|
990 |
}
|
sl@0
|
991 |
|
sl@0
|
992 |
TInt writeOffset = writeBaseOffset;
|
sl@0
|
993 |
|
sl@0
|
994 |
const TUint8* src = iSampleData.Ptr();
|
sl@0
|
995 |
|
sl@0
|
996 |
test.Printf( _L("Writing data") );
|
sl@0
|
997 |
for( ; (writeCount > 0) && (KErrNone == r); writeCount-- )
|
sl@0
|
998 |
{
|
sl@0
|
999 |
TPtrC8 buf( src, KMaxWriteLength );
|
sl@0
|
1000 |
test( KErrNone == iDrive.Write( writeOffset, buf ) );
|
sl@0
|
1001 |
writeOffset += KMaxWriteLength;
|
sl@0
|
1002 |
src += KMaxWriteLength;
|
sl@0
|
1003 |
}
|
sl@0
|
1004 |
test( r == KErrNone );
|
sl@0
|
1005 |
|
sl@0
|
1006 |
//
|
sl@0
|
1007 |
// check that the data was written ok
|
sl@0
|
1008 |
//
|
sl@0
|
1009 |
test.Printf( _L("Verifying data") );
|
sl@0
|
1010 |
test( CompareAgainstFlash( writeBaseOffset, iSampleData, 0 ) );
|
sl@0
|
1011 |
|
sl@0
|
1012 |
test.Printf( _L("... test data written\n") );
|
sl@0
|
1013 |
}
|
sl@0
|
1014 |
|
sl@0
|
1015 |
TBool CReadTest::CompareAgainstFlash( TInt aFlashOffset, const TPtrC8& aDes, TInt aDescOffset )
|
sl@0
|
1016 |
//
|
sl@0
|
1017 |
// Checks that the data in aDes matches that in the Flash at position
|
sl@0
|
1018 |
// aFlashOffset.
|
sl@0
|
1019 |
// The test starts at offset aDescOffset in aSampleData. The data length
|
sl@0
|
1020 |
// tested is aDes->Length() - aDescOffset
|
sl@0
|
1021 |
//
|
sl@0
|
1022 |
{
|
sl@0
|
1023 |
TInt dataLength = aDes.Length() - aDescOffset;
|
sl@0
|
1024 |
const TUint8* srcPtr = aDes.Ptr() + aDescOffset;
|
sl@0
|
1025 |
|
sl@0
|
1026 |
TUint offset = aFlashOffset;
|
sl@0
|
1027 |
|
sl@0
|
1028 |
TBool failed = EFalse;
|
sl@0
|
1029 |
const TInt readBufLen = iReadBuffer.MaxLength();
|
sl@0
|
1030 |
|
sl@0
|
1031 |
while( (dataLength > 0) && !failed )
|
sl@0
|
1032 |
{
|
sl@0
|
1033 |
TInt len = Min( dataLength, readBufLen );
|
sl@0
|
1034 |
TInt r = iDrive.Read( offset, len, iReadBuffer );
|
sl@0
|
1035 |
if( r != KErrNone )
|
sl@0
|
1036 |
{
|
sl@0
|
1037 |
test.Printf( _L("... FAIL: read failed (%d) at offset 0x%x\n"), r, offset );
|
sl@0
|
1038 |
test( KErrNone == r );
|
sl@0
|
1039 |
}
|
sl@0
|
1040 |
test( iReadBuffer.Length() == len );
|
sl@0
|
1041 |
|
sl@0
|
1042 |
if( 0 != Mem::Compare( srcPtr, len, iReadBuffer.Ptr(), len ) )
|
sl@0
|
1043 |
{
|
sl@0
|
1044 |
test.Printf( _L("... FAIL: mismatch around offset 0x%x\n"), offset );
|
sl@0
|
1045 |
failed = ETrue;
|
sl@0
|
1046 |
}
|
sl@0
|
1047 |
offset += len;
|
sl@0
|
1048 |
dataLength -= len;
|
sl@0
|
1049 |
srcPtr += len;
|
sl@0
|
1050 |
}
|
sl@0
|
1051 |
|
sl@0
|
1052 |
return !failed;
|
sl@0
|
1053 |
}
|
sl@0
|
1054 |
|
sl@0
|
1055 |
|
sl@0
|
1056 |
|
sl@0
|
1057 |
void CReadTest::DoTest()
|
sl@0
|
1058 |
//
|
sl@0
|
1059 |
// Main test dispatcher
|
sl@0
|
1060 |
//
|
sl@0
|
1061 |
{
|
sl@0
|
1062 |
//
|
sl@0
|
1063 |
// Create some test data at start of block 0
|
sl@0
|
1064 |
//
|
sl@0
|
1065 |
CreateTestData( 0, EFalse );
|
sl@0
|
1066 |
|
sl@0
|
1067 |
//
|
sl@0
|
1068 |
// Now do the simple tests, all reads will return zeros
|
sl@0
|
1069 |
//
|
sl@0
|
1070 |
#if 0
|
sl@0
|
1071 |
TestSimpleReads();
|
sl@0
|
1072 |
#endif
|
sl@0
|
1073 |
TestSimpleThreadReads();
|
sl@0
|
1074 |
TestUnalignedReads();
|
sl@0
|
1075 |
TestUnalignedThreadReads();
|
sl@0
|
1076 |
TestOffsetBufferThreadReads();
|
sl@0
|
1077 |
TestOffsetBufferUnalignedThreadReads();
|
sl@0
|
1078 |
|
sl@0
|
1079 |
//
|
sl@0
|
1080 |
// Create some more data at start of all other blocks
|
sl@0
|
1081 |
//
|
sl@0
|
1082 |
test.Next( _L("Creating more test data in other blocks") );
|
sl@0
|
1083 |
for( TInt i = 1; i < iBlockCount; i++ )
|
sl@0
|
1084 |
{
|
sl@0
|
1085 |
CreateTestData( i, EFalse );
|
sl@0
|
1086 |
}
|
sl@0
|
1087 |
|
sl@0
|
1088 |
//
|
sl@0
|
1089 |
// Make sure we can read valid data out of the other blocks
|
sl@0
|
1090 |
//
|
sl@0
|
1091 |
TestReadsFromAllBlocks();
|
sl@0
|
1092 |
|
sl@0
|
1093 |
//
|
sl@0
|
1094 |
// Now do some scatter-read tests
|
sl@0
|
1095 |
//
|
sl@0
|
1096 |
TestSimpleScatterReads1();
|
sl@0
|
1097 |
TestSimpleScatterReads2();
|
sl@0
|
1098 |
|
sl@0
|
1099 |
//
|
sl@0
|
1100 |
// Create some more testdata at end of all blocks
|
sl@0
|
1101 |
//
|
sl@0
|
1102 |
test.Next( _L("Creating test data at end of blocks") );
|
sl@0
|
1103 |
for( TInt i = 0; i < iBlockCount; i++ )
|
sl@0
|
1104 |
{
|
sl@0
|
1105 |
CreateTestData( i, ETrue );
|
sl@0
|
1106 |
}
|
sl@0
|
1107 |
|
sl@0
|
1108 |
//
|
sl@0
|
1109 |
// Do a full scatter-gather test
|
sl@0
|
1110 |
//
|
sl@0
|
1111 |
TestScatterGather();
|
sl@0
|
1112 |
|
sl@0
|
1113 |
TestReadAcrossBlock();
|
sl@0
|
1114 |
}
|
sl@0
|
1115 |
|
sl@0
|
1116 |
|
sl@0
|
1117 |
|
sl@0
|
1118 |
|
sl@0
|
1119 |
|
sl@0
|
1120 |
TInt E32Main()
|
sl@0
|
1121 |
{
|
sl@0
|
1122 |
test.Title();
|
sl@0
|
1123 |
test.Start(_L("Testing media read operations"));
|
sl@0
|
1124 |
|
sl@0
|
1125 |
CReadTest reader;
|
sl@0
|
1126 |
TRAPD( ret, reader.CreateL() );
|
sl@0
|
1127 |
test( KErrNone == ret );
|
sl@0
|
1128 |
reader.DoTest();
|
sl@0
|
1129 |
test.End();
|
sl@0
|
1130 |
|
sl@0
|
1131 |
return 0;
|
sl@0
|
1132 |
}
|