|
1 // Copyright (c) 2007-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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // f32test\server\t_wcache.cpp |
|
15 // This file contains a test for the Write Caching functionality of the File Server |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file |
|
21 @internalTechnology |
|
22 */ |
|
23 |
|
24 #define __E32TEST_EXTENSION__ |
|
25 #include <f32file.h> |
|
26 #include <e32test.h> |
|
27 #include <e32svr.h> |
|
28 #include <f32dbg.h> |
|
29 #include "t_server.h" |
|
30 #include <e32twin.h> |
|
31 |
|
32 const TInt KTotalCacheSize = 32 * 1024 * 1024; |
|
33 const TInt KDefaultCacheSize = (128 + 12) * 1024; // This size is the default configuration size |
|
34 const TInt KFilesNeededToFillCache = (KTotalCacheSize / KDefaultCacheSize) + 2; |
|
35 const TInt KMinSize = 254; // Boundary minim limit |
|
36 const TInt KMaxSize = 257; // Boundary max limit |
|
37 |
|
38 |
|
39 |
|
40 //---------------------------------------------------------------------------------------------- |
|
41 //! @SYMTestCaseID PBASE-T_WCACHE-0271 |
|
42 //! @SYMTestType CIT |
|
43 //! @SYMPREQ PREQ914 |
|
44 //! @SYMTestCaseDesc This test case is exercising the Write Caching functionality added to |
|
45 //! the File Server. There are negative and positive tests. |
|
46 //! @SYMTestActions 0 setup the environment to execute the tests |
|
47 //! 1 TestBoundaries writes/reads around the write cache boundaries to |
|
48 //! the behaviour of the cache in some common cases. |
|
49 //! 2 TestNegative ensures the integrity of data in the cache gets |
|
50 //! preserved under error conditions |
|
51 //! 3 TestIntegrity is trying to make sure integrity of the data is preserved |
|
52 //! 4 TestFillCache fills the cache and then executes TestBoundaries. |
|
53 //! 5 TestFillCacheNegative fills the cache with uncommitted data |
|
54 //! |
|
55 //! @SYMTestExpectedResults finishes if the read cache behaves as expected, panics otherwise |
|
56 //! @SYMTestPriority High |
|
57 //! @SYMTestStatus Implemented |
|
58 //---------------------------------------------------------------------------------------------- |
|
59 |
|
60 |
|
61 //////////////////////////////////////////////////////////// |
|
62 // Template functions encapsulating ControlIo magic |
|
63 // |
|
64 template <class C> |
|
65 TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c) |
|
66 { |
|
67 TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C)); |
|
68 |
|
69 TInt r = fs.ControlIo(drv, fkn, ptrC); |
|
70 |
|
71 return r; |
|
72 } |
|
73 |
|
74 RTest test(_L("T_WCACHE")); |
|
75 |
|
76 RFs gTheFs; |
|
77 TInt gDrive; |
|
78 TFileName gSessionPath; |
|
79 TChar gDriveToTest; |
|
80 TThreadId gMainThreadId; |
|
81 TInt gManual = 0; |
|
82 |
|
83 HBufC8* gBuf = NULL; |
|
84 TPtr8 gBufReadPtr(NULL, 0); |
|
85 HBufC8* gBufSec = NULL; |
|
86 TPtr8 gBufWritePtr(NULL, 0); |
|
87 |
|
88 const TInt KOneK = 1024; |
|
89 const TInt KOneMeg = KOneK * 1024; |
|
90 const TInt KBlockSize = KOneK; |
|
91 const TInt KWaitRequestsTableSize = 256; |
|
92 const TInt KMs = 1000; |
|
93 |
|
94 TInt gSecondFileSize = 0; |
|
95 TInt gFirstFileSize = 0; |
|
96 |
|
97 TInt64 gMediaSize = 0; |
|
98 |
|
99 TTimeIntervalMicroSeconds gTimeTakenBigFile(0); |
|
100 TBuf16<25> gFirstFile; |
|
101 TBuf16<25> gSecondFile; |
|
102 TBuf16<25> gCurrentFile; |
|
103 |
|
104 TInt gNextFile = 0; |
|
105 TTime gTime1; |
|
106 TTime gTime2; |
|
107 |
|
108 |
|
109 // Concurrent Threads |
|
110 RThread gThread1; |
|
111 RSemaphore gClient; |
|
112 const TInt KHeapSize = 0x4000; |
|
113 const TInt KMaxHeapSize = 0x100000; |
|
114 |
|
115 |
|
116 /** Formats the drive |
|
117 |
|
118 @param aDrive Drive to be formatted |
|
119 @param aFormatMode Mode for the format operation |
|
120 */ |
|
121 void Formatting(TInt aDrive, TUint aFormatMode ) |
|
122 { |
|
123 |
|
124 test.Next(_L("Format")); |
|
125 TBuf<4> driveBuf = _L("?:\\"); |
|
126 driveBuf[0]=(TText)(aDrive+'A'); |
|
127 RFormat format; |
|
128 TInt count; |
|
129 TInt r = format.Open(gTheFs,driveBuf,aFormatMode,count); |
|
130 test_KErrNone(r); |
|
131 while(count) |
|
132 { |
|
133 TInt r = format.Next(count); |
|
134 test_KErrNone(r); |
|
135 } |
|
136 format.Close(); |
|
137 |
|
138 } |
|
139 |
|
140 /** Verifies the content of a buffer |
|
141 This function returns KErrNone when all the letters are consecutive in the aBuffer, KErrCorrupt otherwise |
|
142 |
|
143 @param aBuffer Buffer to be verified |
|
144 |
|
145 @return KErrNone if all the letters are the same, KErrCorrupt otherwise |
|
146 */ |
|
147 TInt VerifyBuffer(TDes8& aBuffer) |
|
148 { |
|
149 TChar c = aBuffer[0]; |
|
150 |
|
151 for(TInt i = 1; i < aBuffer.Length(); i++) |
|
152 { |
|
153 if(i%32 != 0) |
|
154 { |
|
155 if(c != (TChar)(aBuffer[i] - 1)) |
|
156 return KErrCorrupt; |
|
157 } |
|
158 else |
|
159 { |
|
160 if(aBuffer[i] != aBuffer[0]) |
|
161 return KErrCorrupt; |
|
162 } |
|
163 c = aBuffer[i]; |
|
164 } |
|
165 |
|
166 return KErrNone; |
|
167 } |
|
168 |
|
169 /** Fills a buffer with character aC, aC+1, aC+2, ..., aC+0x20, aC, etc |
|
170 |
|
171 @param aBuffer Buffer to be filled, output |
|
172 @param aLength Length to be filled |
|
173 @param aC Character to be used to fill the buffer |
|
174 */ |
|
175 void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC) |
|
176 { |
|
177 test (aBuffer.MaxLength() >= aLength); |
|
178 for(TInt i = 0; i < aLength; i++) |
|
179 { |
|
180 aBuffer.Append((i%32) + aC); |
|
181 } |
|
182 } |
|
183 |
|
184 /** Returns true if fat filesystem present on aDrive |
|
185 |
|
186 @param aFsSession Session on the File Server |
|
187 @param aDrive Drive to be looked at |
|
188 |
|
189 @return ETrue if FAT, EFalse otherwise |
|
190 */ |
|
191 TBool IsFSFAT(RFs &aFsSession,TInt aDrive) |
|
192 { |
|
193 TFileName f; |
|
194 TInt r = aFsSession.FileSystemName(f,aDrive); |
|
195 |
|
196 if (r != KErrNone) |
|
197 { |
|
198 test.Printf(_L("Unable to get file system name\n")); |
|
199 return EFalse; |
|
200 } |
|
201 |
|
202 return (f.CompareF(_L("Fat")) == 0); |
|
203 } |
|
204 |
|
205 /** Generates a file name of the form FFFFF*<aPos>.TXT (aLong.3) |
|
206 |
|
207 @param aBuffer The filename will be returned here |
|
208 @param aLong Defines the longitude of the file name |
|
209 @param aPos Defines the number that will be attached to the filename |
|
210 */ |
|
211 void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos) |
|
212 { |
|
213 TInt padding; |
|
214 TInt i = 0; |
|
215 TBuf16<10> tempbuf; |
|
216 |
|
217 _LIT(KNumber,"%d"); |
|
218 tempbuf.Format(KNumber,aPos); |
|
219 padding = aLong-tempbuf.Size()/2; |
|
220 aBuffer = _L(""); |
|
221 while(i < padding) |
|
222 { |
|
223 aBuffer.Append('F'); |
|
224 i++; |
|
225 } |
|
226 aBuffer.Append(tempbuf); |
|
227 |
|
228 _LIT(KExtension1, ".TXT"); |
|
229 aBuffer.Append(KExtension1); |
|
230 } |
|
231 |
|
232 /** Delete content of directory |
|
233 |
|
234 @param aDir Target directory |
|
235 |
|
236 @return Error returned if any, otherwise KErrNone |
|
237 */ |
|
238 TInt DeleteAllL(TDes16& aDir) |
|
239 { |
|
240 TBuf16<100> dir; |
|
241 CFileMan* fMan = CFileMan::NewL(gTheFs); |
|
242 TInt r=0; |
|
243 |
|
244 dir = aDir; |
|
245 dir.Append(_L("F*.*")); |
|
246 r = fMan->Delete(dir); |
|
247 |
|
248 delete fMan; |
|
249 return r; |
|
250 } |
|
251 |
|
252 /** Waits for all the TRequestStatus in status[] to complete |
|
253 |
|
254 @param status Array of TRequestStatus |
|
255 @param aSize Length to be filled |
|
256 */ |
|
257 void WaitForAll(TRequestStatus* status, TInt aSize) |
|
258 { |
|
259 TInt i = 0; |
|
260 |
|
261 RTest test(_L("T_WCACHE")); |
|
262 |
|
263 while(i < aSize) |
|
264 { |
|
265 User::WaitForRequest(status[i]); |
|
266 if (status[i] != KErrNone) |
|
267 { |
|
268 test.Printf(_L("status[%d] == %d\n"), i, status[i].Int()); |
|
269 test(EFalse); |
|
270 } |
|
271 i++; |
|
272 } |
|
273 |
|
274 test.Close(); |
|
275 } |
|
276 |
|
277 /** Reads the parameters from the comand line |
|
278 and updates the appropriate variables |
|
279 */ |
|
280 void parseCommandLine() |
|
281 { |
|
282 TBuf<0x100> cmd; |
|
283 User::CommandLine(cmd); |
|
284 TLex lex(cmd); |
|
285 TPtrC token = lex.NextToken(); |
|
286 TInt r=0; |
|
287 |
|
288 if(token.Length() != 0) |
|
289 { |
|
290 gDriveToTest = token[0]; |
|
291 gDriveToTest.UpperCase(); |
|
292 } |
|
293 else |
|
294 { |
|
295 gDriveToTest = 'C'; |
|
296 } |
|
297 |
|
298 r = gTheFs.CharToDrive(gDriveToTest,gDrive); |
|
299 test_KErrNone(r); |
|
300 |
|
301 if(!lex.Eos()) |
|
302 { |
|
303 token.Set(lex.NextToken()); |
|
304 if(token.Length() != 0) |
|
305 { |
|
306 TChar c = token[0]; |
|
307 c.UpperCase(); |
|
308 |
|
309 gManual = (c == 'M'); |
|
310 } |
|
311 } |
|
312 |
|
313 gSessionPath = _L("?:\\F32-TST\\"); |
|
314 gSessionPath[0] = (TUint16) gDriveToTest; |
|
315 test.Printf(_L("\nCLP=%C\n"),(TInt)gDriveToTest); |
|
316 } |
|
317 |
|
318 |
|
319 |
|
320 /** Writes a file synchronously in blocks of aBlockSize size |
|
321 |
|
322 @param aFs RFs object |
|
323 @param aFile File |
|
324 @param aFileName File name |
|
325 @param aSize Size of the file in bytes |
|
326 @param aBlockSize Size of the blocks to be used in bytes |
|
327 @param aBuf Buffer to be used to write |
|
328 @param aMode Mode in which the file is meant to be opened |
|
329 |
|
330 @return Returns KErrNone if everything ok, otherwise it panics |
|
331 */ |
|
332 TInt WriteFile(RFs& aFs, RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TDes8& aBuf, TInt aMode) |
|
333 { |
|
334 RTest test(_L("T_WCACHE")); |
|
335 |
|
336 TInt r = 0; |
|
337 |
|
338 test(aBlockSize > 0); |
|
339 |
|
340 |
|
341 r = aFile.Replace(aFs,aFileName,aMode); |
|
342 test_KErrNone(r); |
|
343 |
|
344 TInt j = 0; |
|
345 while(j < aSize) |
|
346 { |
|
347 r = aFile.Write(aBuf, aBlockSize); |
|
348 test_KErrNone(r); |
|
349 j += aBlockSize; |
|
350 } |
|
351 |
|
352 test.Close(); |
|
353 return KErrNone; |
|
354 } |
|
355 |
|
356 /** Write a file that fits in the cache, and dies without proper cleaning |
|
357 |
|
358 */ |
|
359 LOCAL_C TInt WriteFileT(TAny* ) |
|
360 { |
|
361 RTest test(_L("T_WCACHE")); |
|
362 RFs fs; |
|
363 RFile file; |
|
364 TInt r = fs.Connect(); |
|
365 test_KErrNone(r); |
|
366 |
|
367 r = fs.SetSessionPath(gSessionPath); |
|
368 test_KErrNone(r); |
|
369 |
|
370 r = WriteFile(fs, file, gFirstFile, KMinSize * KOneK, KBlockSize, gBufWritePtr, EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
371 test_KErrNone(r); |
|
372 |
|
373 gClient.Signal(); |
|
374 |
|
375 |
|
376 FOREVER |
|
377 { |
|
378 // waiting for the kill |
|
379 } |
|
380 } |
|
381 |
|
382 /** Read File in blocks of size aBlockSize |
|
383 |
|
384 @param aFs RFs object |
|
385 @param aFile File |
|
386 @param aFileName File name |
|
387 @param aSize Expected file size |
|
388 @param aBlockSize Size of the blocks to be used in bytes |
|
389 @param aMode Mode in which the file is meant to be opened |
|
390 |
|
391 @return Returns KErrNone if everything ok, otherwise it panics |
|
392 */ |
|
393 TInt ReadFile(RFs& aFs, RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) |
|
394 { |
|
395 RTest test(_L("T_WCACHE")); |
|
396 |
|
397 TInt r = 0, size = 0; |
|
398 |
|
399 test(aBlockSize>0); // Block size must be greater than 0 |
|
400 |
|
401 r = aFile.Open(aFs,aFileName,aMode); |
|
402 test_KErrNone(r); |
|
403 |
|
404 // Make sure the size of the file is the right one at this stage |
|
405 r = aFile.Size(size); |
|
406 test.Printf(_L("size of the file: %d \n"), size/KOneK); |
|
407 test(size == aSize); |
|
408 |
|
409 TInt j = 0; |
|
410 while(j < size) |
|
411 { |
|
412 r = aFile.Read(gBufReadPtr, aBlockSize); |
|
413 test_KErrNone(r); |
|
414 j += aBlockSize; |
|
415 } |
|
416 |
|
417 test.Close(); |
|
418 return KErrNone; |
|
419 } |
|
420 |
|
421 /** Write a file asynchronously in blocks of aBlockSize size |
|
422 |
|
423 @param aFs RFs object |
|
424 @param aFileWrite RFile object, needs to exist beyond the scope of this function |
|
425 @param aFile File name |
|
426 @param aSize Size of the file in bytes |
|
427 @param aMode Specifies the mode in which the file should be openned |
|
428 @param aStatus TRequestStatus array for all the requests |
|
429 */ |
|
430 void WriteFileAsync(RFs& aFs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aMode, TRequestStatus aStatus[]) |
|
431 { |
|
432 RTest test(_L("T_WCACHE")); |
|
433 |
|
434 TInt r = 0; |
|
435 |
|
436 r = aFileWrite.Replace(aFs,aFile,aMode); |
|
437 test_KErrNone(r); |
|
438 |
|
439 TInt j = 0, i = 0; |
|
440 while(j < aSize) |
|
441 { |
|
442 aFileWrite.Write(gBufWritePtr, KBlockSize, aStatus[i]); |
|
443 r = aStatus[i].Int(); |
|
444 if (r != KErrNone && r != KRequestPending) |
|
445 { |
|
446 test.Printf(_L("Write %d returned %d\n"), i, r); |
|
447 test(0); |
|
448 } |
|
449 i++; |
|
450 |
|
451 j += KBlockSize; |
|
452 } |
|
453 test.Close(); |
|
454 } |
|
455 |
|
456 /** Read a file asynchronously in blocks of aBlockSize size |
|
457 |
|
458 @param aFs RFs object |
|
459 @param aFileRead RFile object, needs to exist beyond the scope of this function |
|
460 @param aFile File name |
|
461 @param aFileSize Size of the file in bytes |
|
462 @param aBlockSize Size of the blocks to be used in bytes |
|
463 @param aStatus TRequestStatus array for all the requests |
|
464 @param aMode Specifies the mode in which the file should be openned |
|
465 |
|
466 @return KErrNone |
|
467 */ |
|
468 TInt ReadFileAsync(RFs& aFs,RFile& aFileRead, TDes16& aFile, TInt aFileSize, TInt aBlockSize,TRequestStatus aStatus[], TInt aMode) |
|
469 { |
|
470 RTest test(_L("T_WCACHE")); |
|
471 |
|
472 TInt r = 0; |
|
473 TInt size = 0; |
|
474 |
|
475 test(aBlockSize > 0); |
|
476 |
|
477 |
|
478 r = aFileRead.Open(aFs,aFile, aMode); |
|
479 test_KErrNone(r); |
|
480 |
|
481 r = aFileRead.Size(size); |
|
482 test_KErrNone(r); |
|
483 |
|
484 test.Printf(_L("size of the file %d\n"), size/KOneK); |
|
485 test(size == aFileSize); |
|
486 |
|
487 TInt j = 0, i = 0; |
|
488 while(j < size) |
|
489 { |
|
490 aFileRead.Read(gBufReadPtr, aBlockSize, aStatus[i]); |
|
491 r = aStatus[i].Int(); |
|
492 if (r != KErrNone && r != KRequestPending) |
|
493 { |
|
494 test.Printf(_L("Read %d returned %d\n"), i, r); |
|
495 test(0); |
|
496 } |
|
497 i++; |
|
498 |
|
499 j += aBlockSize; |
|
500 } |
|
501 |
|
502 test.Close(); |
|
503 return KErrNone; |
|
504 } |
|
505 |
|
506 /** Measure the time taken for this file to be written synchronously |
|
507 |
|
508 @param aFile File object |
|
509 @param aFileName File Name |
|
510 @param aSize Size in kilobytes |
|
511 @param aBlockSize Size of the block |
|
512 @param aMode Mode in which the file is going to be opened |
|
513 |
|
514 @return time taken to perform the operation in uS |
|
515 */ |
|
516 TInt WriteTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) |
|
517 { |
|
518 RTest test(_L("T_WCACHE")); |
|
519 |
|
520 TTime startTime; |
|
521 TTime endTime; |
|
522 TInt r = 0; |
|
523 |
|
524 startTime.HomeTime(); |
|
525 |
|
526 r = WriteFile(gTheFs,aFile, aFileName , aSize * KOneK, aBlockSize, gBufWritePtr, aMode); |
|
527 test_KErrNone(r); |
|
528 |
|
529 endTime.HomeTime(); |
|
530 |
|
531 gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); |
|
532 |
|
533 test.Close(); |
|
534 return I64LOW(gTimeTakenBigFile.Int64()); |
|
535 } |
|
536 |
|
537 /** Measure the time taken for this file to be read synchronously |
|
538 |
|
539 @param aFile File object |
|
540 @param aFileName File Name |
|
541 @param aSize Size in kilobytes |
|
542 @param aBlockSize Size of the block |
|
543 @param aMode Mode in which the file is going to be opened |
|
544 |
|
545 @return time taken to perform the operation in uS |
|
546 |
|
547 */ |
|
548 TInt ReadTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) |
|
549 { |
|
550 TTime startTime; |
|
551 TTime endTime; |
|
552 |
|
553 startTime.HomeTime(); |
|
554 ReadFile(gTheFs,aFile, aFileName, aSize * KOneK, aBlockSize, aMode); |
|
555 endTime.HomeTime(); |
|
556 |
|
557 gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); |
|
558 |
|
559 return I64LOW(gTimeTakenBigFile.Int64()) ; |
|
560 } |
|
561 |
|
562 /** Read asynchronously the test file from the disc |
|
563 |
|
564 @param aFile File object |
|
565 @param aFileName File Name |
|
566 @param aSize Size in kilobytes |
|
567 @param aBlockSize Size of the block |
|
568 @param aMode Mode in which the file is going to be opened |
|
569 |
|
570 @return time taken to perform the operation in uS |
|
571 */ |
|
572 TInt ReadAsyncTestFile(RFile& file, TDes16& aFile, TInt aSize, TInt aBlockSize, TInt aMode) |
|
573 { |
|
574 TTime startTime; |
|
575 TTime endTime; |
|
576 TRequestStatus status[KWaitRequestsTableSize]; |
|
577 |
|
578 startTime.HomeTime(); |
|
579 |
|
580 ReadFileAsync(gTheFs, file, aFile, aSize * KOneK, aBlockSize, status, aMode); |
|
581 WaitForAll(status, (aSize * KOneK)/KBlockSize); |
|
582 |
|
583 endTime.HomeTime(); |
|
584 |
|
585 gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); |
|
586 |
|
587 return I64LOW(gTimeTakenBigFile.Int64()); |
|
588 } |
|
589 |
|
590 /** Read asynchronously the test file from the disc |
|
591 |
|
592 @param aFile File object |
|
593 @param aFileName File Name |
|
594 @param aSize Size in kilobytes |
|
595 @param aMode Mode in which the file is going to be opened |
|
596 |
|
597 @return time taken to perform the operation in uS |
|
598 */ |
|
599 TInt WriteAsyncTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aMode) |
|
600 { |
|
601 TTime startTime; |
|
602 TTime endTime; |
|
603 TRequestStatus status[KWaitRequestsTableSize]; |
|
604 |
|
605 startTime.HomeTime(); |
|
606 |
|
607 WriteFileAsync(gTheFs, aFile, aFileName, aSize * KOneK, aMode, status ); |
|
608 WaitForAll(status, (aSize * KOneK)/KBlockSize); |
|
609 |
|
610 endTime.HomeTime(); |
|
611 |
|
612 gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); |
|
613 |
|
614 return I64LOW(gTimeTakenBigFile.Int64()); |
|
615 } |
|
616 |
|
617 /** Test Boundaries |
|
618 |
|
619 This function is testing the behaviour on the boundaries of the write cache size |
|
620 */ |
|
621 void TestBoundaries() |
|
622 { |
|
623 TInt r = 0; |
|
624 TInt time = 0; |
|
625 TInt rtime = 0; |
|
626 TInt tcreate = 0; |
|
627 RFile fileWriter; |
|
628 RFile fileWriter2; |
|
629 RFile fileReader; |
|
630 |
|
631 test.Start(_L("Test Boundaries")); |
|
632 |
|
633 // Test boundaries from 254K to 256K, synchronous operations |
|
634 TInt i = KMinSize; |
|
635 |
|
636 |
|
637 test.Printf(_L("\n\n\n")); |
|
638 |
|
639 while(i < KMaxSize) |
|
640 { |
|
641 test.Printf(_L("\nSync: Write from 1 K to %d K \n"), i); |
|
642 |
|
643 tcreate = WriteTestFile(fileWriter, gSecondFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteDirectIO); |
|
644 test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs); |
|
645 fileWriter.Close(); |
|
646 |
|
647 time = WriteTestFile(fileWriter2, gFirstFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
648 test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs); |
|
649 |
|
650 rtime = ReadTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); |
|
651 test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs); |
|
652 |
|
653 |
|
654 fileReader.Close(); |
|
655 fileWriter2.Close(); |
|
656 |
|
657 #if !defined(__WINS__) |
|
658 test((tcreate > time) || (tcreate > rtime)); |
|
659 #endif |
|
660 |
|
661 r = gTheFs.Delete(gFirstFile); |
|
662 test_KErrNone(r); |
|
663 r = gTheFs.Delete(gSecondFile); |
|
664 test_KErrNone(r); |
|
665 |
|
666 i++; |
|
667 } |
|
668 |
|
669 test.Printf(_L("\n\n\n")); |
|
670 |
|
671 // Test boundaries from 254K to 256K, asynchronous operations |
|
672 i = KMinSize; |
|
673 |
|
674 while(i < KMaxSize) |
|
675 { |
|
676 test.Printf(_L("\nAsync: Write from 1 K to %d K \n"), i); |
|
677 |
|
678 tcreate = WriteAsyncTestFile(fileWriter, gSecondFile, i, EFileShareAny|EFileWrite|EFileWriteDirectIO); |
|
679 test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs); |
|
680 fileWriter.Close(); |
|
681 |
|
682 time = WriteAsyncTestFile(fileWriter2, gFirstFile, i,EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
683 test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs); |
|
684 |
|
685 |
|
686 rtime = ReadAsyncTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); |
|
687 test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs); |
|
688 |
|
689 fileReader.Close(); |
|
690 fileWriter2.Close(); |
|
691 |
|
692 #if !defined(__WINS__) |
|
693 test((tcreate > time) || (tcreate > rtime)); |
|
694 #endif |
|
695 |
|
696 r = gTheFs.Delete(gFirstFile); |
|
697 test_KErrNone(r); |
|
698 r = gTheFs.Delete(gSecondFile); |
|
699 test_KErrNone(r); |
|
700 |
|
701 i++; |
|
702 } |
|
703 |
|
704 test.End(); |
|
705 } |
|
706 |
|
707 /** Test negative cases |
|
708 |
|
709 */ |
|
710 void TestNegative() |
|
711 { |
|
712 TInt r = 0; |
|
713 RFile file; |
|
714 TInt size =0; |
|
715 |
|
716 TBuf<20> buf = _L("Write File"); |
|
717 |
|
718 |
|
719 test.Start(_L("Test Negative")); |
|
720 |
|
721 test.Next(_L("Kill a simple operation")); |
|
722 |
|
723 r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); |
|
724 test_KErrNone(r); |
|
725 |
|
726 gThread1.Resume(); |
|
727 gClient.Wait(); |
|
728 |
|
729 gThread1.Kill(KErrGeneral); |
|
730 |
|
731 r = file.Open(gTheFs,gFirstFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff); |
|
732 test_KErrNone(r); |
|
733 |
|
734 r = file.Size(size); |
|
735 test_KErrNone(r); |
|
736 |
|
737 test.Printf(_L("The size of the file is %d KB\n\n"), size/KOneK); |
|
738 test(size == (KMinSize * KOneK)); |
|
739 |
|
740 file.Close(); |
|
741 |
|
742 test.End(); |
|
743 } |
|
744 |
|
745 |
|
746 /** Read the file verifying content |
|
747 |
|
748 @param aFile file name to verify |
|
749 |
|
750 @return returns the time that took to do the verification in mS, fails if the file is not corrupted/modified |
|
751 */ |
|
752 TInt ReadTestFileVerif(TDes16& aFile) |
|
753 { |
|
754 TTime startTime; |
|
755 TTime endTime; |
|
756 TInt r = 0; |
|
757 TInt size = 0; |
|
758 RFile fileRead; |
|
759 TInt corrupt = 0; |
|
760 TBool isFat=IsFSFAT(gTheFs,gDrive); |
|
761 |
|
762 startTime.HomeTime(); |
|
763 |
|
764 r = fileRead.Open(gTheFs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff); |
|
765 test_KErrNone(r); |
|
766 |
|
767 r = fileRead.Size(size); |
|
768 test_KErrNone(r); |
|
769 |
|
770 TInt j = 0; |
|
771 |
|
772 while(j < size) |
|
773 { |
|
774 r = fileRead.Read(gBufReadPtr, KBlockSize); |
|
775 if(isFat) |
|
776 { |
|
777 test_KErrNone(r); |
|
778 } |
|
779 else |
|
780 { |
|
781 if(r == KErrCorrupt) |
|
782 corrupt++; |
|
783 } |
|
784 |
|
785 j += KBlockSize; |
|
786 r = VerifyBuffer(gBufReadPtr); |
|
787 if(r == KErrCorrupt) |
|
788 corrupt++; |
|
789 } |
|
790 |
|
791 fileRead.Close(); |
|
792 |
|
793 test(corrupt>0); // Ensure the cache returns the changed content |
|
794 |
|
795 endTime.HomeTime(); |
|
796 |
|
797 gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); |
|
798 |
|
799 return I64LOW(gTimeTakenBigFile.Int64()) / KMs; |
|
800 } |
|
801 |
|
802 /** Modifies the second file |
|
803 |
|
804 */ |
|
805 LOCAL_C TInt CorruptSecondFile() |
|
806 { |
|
807 TInt r = 0; |
|
808 RFile fileWrite; |
|
809 HBufC8* dummy = NULL; |
|
810 TPtr8 dummyPtr(NULL, 0); |
|
811 |
|
812 TRAPD(res,dummy = HBufC8::NewL(4)); |
|
813 test(res == KErrNone && dummy != NULL); |
|
814 |
|
815 dummyPtr.Set(dummy->Des()); |
|
816 FillBuffer(dummyPtr, 4, '1'); |
|
817 |
|
818 r = fileWrite.Open(gTheFs,gSecondFile,EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
819 if(r != KErrNone) |
|
820 return r; |
|
821 TInt pos = 30; |
|
822 r = fileWrite.Seek(ESeekStart,pos); |
|
823 test_KErrNone(r); |
|
824 |
|
825 r = fileWrite.Write(dummyPtr); |
|
826 if(r != KErrNone) |
|
827 return r; |
|
828 |
|
829 fileWrite.Close(); |
|
830 |
|
831 delete dummy; |
|
832 |
|
833 return KErrNone; |
|
834 } |
|
835 |
|
836 |
|
837 /** Integrity testing |
|
838 |
|
839 */ |
|
840 LOCAL_C void TestIntegrity() |
|
841 { |
|
842 TInt r = 0; |
|
843 TInt time; |
|
844 TInt tcreate = 0; |
|
845 RFile file; |
|
846 |
|
847 // Modify file in some position |
|
848 test.Printf(_L("Overwrite partially a file\n")); |
|
849 |
|
850 test.Printf(_L("\nSync: Write from 1 K to %d K \n"), 255); |
|
851 |
|
852 tcreate = WriteTestFile(file, gSecondFile, 255, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
853 test.Printf(_L("Time to write %d K with caching: %d mS\n"), 255, tcreate/KMs); |
|
854 file.Close(); |
|
855 |
|
856 test.Printf(_L("Mess the content that is still in the cache\n")); |
|
857 CorruptSecondFile(); |
|
858 |
|
859 time = ReadTestFileVerif(gSecondFile); |
|
860 test.Printf(_L("Time taken to verify: %d\n"),time); |
|
861 |
|
862 test.Printf(_L("Integrity verified\n")); |
|
863 |
|
864 r = DeleteAllL(gSessionPath); |
|
865 test_KErrNone(r); |
|
866 } |
|
867 |
|
868 /** Creates the files to fill the cache with dirty data |
|
869 |
|
870 @return KErrNone |
|
871 */ |
|
872 TInt CreateFilesThread(TAny *) |
|
873 { |
|
874 TInt i = 0; |
|
875 TInt r = 0; |
|
876 TBuf16<50> directory; |
|
877 |
|
878 TBuf16<50> path; |
|
879 TBuf16<50> buffer(50); |
|
880 RFile file[KFilesNeededToFillCache]; |
|
881 |
|
882 RTest test(_L("T_WCACHE2")); |
|
883 RFs fs; |
|
884 |
|
885 fs.Connect(); |
|
886 |
|
887 directory = gSessionPath; |
|
888 |
|
889 test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), KFilesNeededToFillCache, KDefaultCacheSize); |
|
890 |
|
891 // create a big buffer to speed things up |
|
892 HBufC8* bigBuf = NULL; |
|
893 TInt KBigBifferSize = 32 * KOneK; |
|
894 |
|
895 TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize)); |
|
896 test(res == KErrNone && bigBuf != NULL); |
|
897 |
|
898 TPtr8 bigBufWritePtr(NULL, 0); |
|
899 bigBufWritePtr.Set(bigBuf->Des()); |
|
900 FillBuffer(bigBufWritePtr, KBigBifferSize, 'A'); |
|
901 |
|
902 i = 0; |
|
903 while(i < KFilesNeededToFillCache) |
|
904 { |
|
905 if (i % 10 == 0) |
|
906 test.Printf(_L("Creating file %d of %d...\r"), i, KFilesNeededToFillCache); |
|
907 FileNameGen(buffer, 8, i+3) ; |
|
908 path = directory; |
|
909 path.Append(buffer); |
|
910 |
|
911 r = file[i].Create(fs,path,EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
912 if(r == KErrAlreadyExists) |
|
913 r = file[i].Open(fs,path,EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
914 test_KErrNone(r); |
|
915 TInt j = 0; |
|
916 |
|
917 while(j < KDefaultCacheSize) |
|
918 { |
|
919 bigBufWritePtr.SetLength(Min(KBigBifferSize, KDefaultCacheSize - j)); |
|
920 |
|
921 r = file[i].Write(bigBufWritePtr); |
|
922 test_KErrNone(r); |
|
923 j += bigBufWritePtr.Length(); |
|
924 } |
|
925 |
|
926 // Not closing the files is done on purpose, as part of the test |
|
927 |
|
928 i++; |
|
929 } |
|
930 test.Printf(_L("\nFiles created\n")); |
|
931 delete bigBuf; |
|
932 |
|
933 gClient.Signal(); |
|
934 |
|
935 return KErrNone; |
|
936 } |
|
937 |
|
938 |
|
939 /** Creates the files to fill the read cache |
|
940 |
|
941 @param aFiles Number of files needed to fill the cache |
|
942 @param aFileSize The file size |
|
943 */ |
|
944 void CreateFiles(TInt aFiles, TInt aFileSize) |
|
945 { |
|
946 TInt i = 0; |
|
947 TInt r = 0; |
|
948 RFile file; |
|
949 TBuf16<50> directory; |
|
950 |
|
951 TBuf16<50> path; |
|
952 TBuf16<50> buffer(50); |
|
953 |
|
954 directory = gSessionPath; |
|
955 |
|
956 test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), aFiles, aFileSize); |
|
957 |
|
958 // create a big buffer to speed things up |
|
959 HBufC8* bigBuf = NULL; |
|
960 const TInt KBigBifferSize = 32 * 1024; |
|
961 TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize)); |
|
962 test(res == KErrNone && bigBuf != NULL); |
|
963 |
|
964 TPtr8 bigBufWritePtr(NULL, 0); |
|
965 bigBufWritePtr.Set(bigBuf->Des()); |
|
966 FillBuffer(bigBufWritePtr, KBigBifferSize, 'A'); |
|
967 |
|
968 i = 0; |
|
969 while(i < aFiles) |
|
970 { |
|
971 if (i % 10 == 0) |
|
972 test.Printf(_L("Creating file %d of %d...\r"), i, aFiles); |
|
973 FileNameGen(buffer, 8, i+3) ; |
|
974 path = directory; |
|
975 path.Append(buffer); |
|
976 |
|
977 // delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue) |
|
978 r = gTheFs.Delete(path); |
|
979 test_Value(r, r == KErrNone || r == KErrNotFound); |
|
980 |
|
981 r = file.Create(gTheFs,path,EFileShareAny|EFileWrite|EFileWriteDirectIO); |
|
982 if(r == KErrAlreadyExists) |
|
983 r = file.Open(gTheFs,path,EFileShareAny|EFileWrite|EFileWriteDirectIO); |
|
984 test_KErrNone(r); |
|
985 TInt j = 0; |
|
986 while(j < aFileSize) |
|
987 { |
|
988 bigBufWritePtr.SetLength(Min(KBigBifferSize, aFileSize - j)); |
|
989 r = file.Write(bigBufWritePtr); |
|
990 test_KErrNone(r); |
|
991 j += bigBufWritePtr.Length(); |
|
992 } |
|
993 |
|
994 file.Close(); |
|
995 i++; |
|
996 } |
|
997 test.Printf(_L("\nFiles created\n")); |
|
998 delete bigBuf; |
|
999 } |
|
1000 |
|
1001 /** Fills the read cache |
|
1002 |
|
1003 @param aFile Array of files needed to fill the cache |
|
1004 @param aFiles Number of files needed to fill the cache |
|
1005 @param aFileSize The file size |
|
1006 */ |
|
1007 void FillCache(RFile aFile[KFilesNeededToFillCache], TInt aFiles, TInt aFileSize) |
|
1008 { |
|
1009 TInt i = 0; |
|
1010 TInt r = 0; |
|
1011 TBuf16<50> directory; |
|
1012 |
|
1013 TBuf16<50> path; |
|
1014 TBuf16<50> buffer(50); |
|
1015 HBufC8* buf = NULL; |
|
1016 TPtr8 bufPtr(NULL, 0); |
|
1017 |
|
1018 TRAPD(res,buf = HBufC8::NewL(2)); |
|
1019 test(res == KErrNone && buf != NULL); |
|
1020 bufPtr.Set(buf->Des()); |
|
1021 |
|
1022 directory = gSessionPath; |
|
1023 |
|
1024 i = 0; |
|
1025 while(i < aFiles) |
|
1026 { |
|
1027 FileNameGen(buffer, 8, i+3) ; |
|
1028 path = directory; |
|
1029 path.Append(buffer); |
|
1030 r = aFile[i].Open(gTheFs,path,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff); |
|
1031 test_KErrNone(r); |
|
1032 |
|
1033 TInt j = 0; |
|
1034 while(j < aFileSize) |
|
1035 { |
|
1036 r = aFile[i].Read(j,bufPtr); |
|
1037 test_KErrNone(r); |
|
1038 j += 4*KOneK; |
|
1039 } |
|
1040 |
|
1041 i++; |
|
1042 } |
|
1043 |
|
1044 delete buf; |
|
1045 test.Printf(_L("Cache filled\n")); |
|
1046 } |
|
1047 |
|
1048 /** Fills the default cache |
|
1049 |
|
1050 */ |
|
1051 void TestFillCache() |
|
1052 { |
|
1053 TInt nFiles = KFilesNeededToFillCache; |
|
1054 TInt fSize = KDefaultCacheSize; |
|
1055 RFile file[KFilesNeededToFillCache]; |
|
1056 TInt r = 0; |
|
1057 |
|
1058 if(gMediaSize> ((fSize * nFiles)+gSecondFileSize+gFirstFileSize)) |
|
1059 { |
|
1060 test.Start(_L("Creating files for filling the cache\n")); |
|
1061 CreateFiles(nFiles,fSize); |
|
1062 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1063 // get number of items on Page Cache |
|
1064 TFileCacheStats startPageCacheStats; |
|
1065 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1066 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1067 test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount); |
|
1068 test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount); |
|
1069 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1070 #endif |
|
1071 FillCache(file,nFiles,fSize); |
|
1072 |
|
1073 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1074 // get number of items on Page Cache |
|
1075 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1076 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1077 test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount); |
|
1078 test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount); |
|
1079 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1080 #endif |
|
1081 |
|
1082 TestBoundaries(); |
|
1083 |
|
1084 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1085 // get number of items on Page Cache |
|
1086 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1087 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1088 test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount); |
|
1089 test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount); |
|
1090 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1091 #endif |
|
1092 |
|
1093 TInt i = 0; |
|
1094 while( i < KFilesNeededToFillCache ) |
|
1095 { |
|
1096 file[i++].Close(); |
|
1097 } |
|
1098 |
|
1099 r = DeleteAllL(gSessionPath); |
|
1100 test_KErrNone(r); |
|
1101 |
|
1102 test.End(); |
|
1103 } |
|
1104 else |
|
1105 test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n")); |
|
1106 } |
|
1107 |
|
1108 /** Fills the cache and generate error situations |
|
1109 |
|
1110 */ |
|
1111 void TestFillCacheNegative() |
|
1112 { |
|
1113 TInt nFiles = KFilesNeededToFillCache; |
|
1114 TInt r = 0; |
|
1115 |
|
1116 if(gMediaSize> ((KDefaultCacheSize * nFiles)+gSecondFileSize+gFirstFileSize)) |
|
1117 { |
|
1118 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1119 // get number of items on Page Cache |
|
1120 TFileCacheStats startPageCacheStats; |
|
1121 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1122 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1123 test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount); |
|
1124 test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount); |
|
1125 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1126 #endif |
|
1127 test.Start(_L("Creating files for filling the cache, with uncommitted data\n")); |
|
1128 |
|
1129 TBuf<20> buf = _L("FillCache"); |
|
1130 |
|
1131 r = gThread1.Create(buf,CreateFilesThread,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL); |
|
1132 test_KErrNone(r); |
|
1133 |
|
1134 gThread1.Resume(); |
|
1135 gClient.Wait(); |
|
1136 |
|
1137 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1138 // get number of items on Page Cache |
|
1139 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1140 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1141 test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount); |
|
1142 test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount); |
|
1143 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1144 #endif |
|
1145 |
|
1146 TestBoundaries(); |
|
1147 |
|
1148 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1149 // get number of items on Page Cache |
|
1150 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1151 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1152 test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount); |
|
1153 test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount); |
|
1154 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1155 |
|
1156 User::After(180000); |
|
1157 |
|
1158 r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats); |
|
1159 test_Value(r, r == KErrNone || r == KErrNotSupported); |
|
1160 test.Printf(_L("Number of page cache lines on free list after the boundary testing=%d\n"),startPageCacheStats.iFreeCount); |
|
1161 test.Printf(_L("Number of page cache lines on used list after the boundary testing=%d\n"),startPageCacheStats.iUsedCount); |
|
1162 test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue); |
|
1163 |
|
1164 #endif |
|
1165 test.End(); |
|
1166 |
|
1167 r = DeleteAllL(gSessionPath); |
|
1168 test_KErrNone(r); |
|
1169 |
|
1170 } |
|
1171 else |
|
1172 test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n")); |
|
1173 } |
|
1174 |
|
1175 |
|
1176 /** Manual test for card removal |
|
1177 |
|
1178 */ |
|
1179 void TestRemoval() |
|
1180 { |
|
1181 TInt time = 0, rtime = 0; |
|
1182 RFile file1, file2; |
|
1183 |
|
1184 |
|
1185 TInt r = gClient.CreateLocal(0); |
|
1186 test_KErrNone(r); |
|
1187 |
|
1188 r = gTheFs.SetSessionPath(gSessionPath); |
|
1189 test_KErrNone(r); |
|
1190 |
|
1191 r = gTheFs.MkDirAll(gSessionPath); |
|
1192 test_Value(r, r == KErrNone || r == KErrAlreadyExists); |
|
1193 |
|
1194 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1195 test.Printf(_L("Disabling Lock Fail simulation ...\n")); |
|
1196 // turn OFF lock failure mode |
|
1197 TBool simulatelockFailureMode = EFalse; |
|
1198 r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
|
1199 test_KErrNone(r); |
|
1200 #endif |
|
1201 |
|
1202 TBuf16<45> dir; |
|
1203 |
|
1204 // FileNames/File generation |
|
1205 test.Start(_L("Preparing the environmnet\n")); |
|
1206 FileNameGen(gFirstFile, 8, gNextFile++); |
|
1207 FileNameGen(gSecondFile, 8, gNextFile++); |
|
1208 dir = gSessionPath; |
|
1209 dir.Append(gFirstFile); |
|
1210 gFirstFile = dir; |
|
1211 dir = gSessionPath; |
|
1212 dir.Append(gSecondFile); |
|
1213 gSecondFile = dir; |
|
1214 |
|
1215 |
|
1216 TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1)); |
|
1217 test(res == KErrNone && gBuf != NULL); |
|
1218 |
|
1219 gBufWritePtr.Set(gBuf->Des()); |
|
1220 FillBuffer(gBufWritePtr, KBlockSize, 'A'); |
|
1221 |
|
1222 TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1)); |
|
1223 test(res2 == KErrNone && gBufSec != NULL); |
|
1224 gBufReadPtr.Set(gBufSec->Des()); |
|
1225 |
|
1226 |
|
1227 test.Printf(_L("\nSync: Write from 1 K to 254 K \n")); |
|
1228 |
|
1229 time = WriteTestFile(file1, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
1230 test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize, time/KMs); |
|
1231 test.Printf(_L("Remove MMC card,! and then press a key\n")); |
|
1232 test.Getch(); |
|
1233 |
|
1234 test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n")); |
|
1235 test.Getch(); |
|
1236 |
|
1237 rtime = ReadTestFile(file2, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); |
|
1238 test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize, rtime/KMs); |
|
1239 |
|
1240 test.Printf(_L("Remove MMC card! and then press a key\n")); |
|
1241 test.Getch(); |
|
1242 |
|
1243 test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n")); |
|
1244 test.Getch(); |
|
1245 |
|
1246 |
|
1247 test.Printf(_L("\nSync: Write from 1 K to 255 K \n")); |
|
1248 |
|
1249 time = WriteTestFile(file1, gFirstFile, KMinSize + 1 , KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); |
|
1250 test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize + 1, time/KMs); |
|
1251 test.Printf(_L("Remove MMC card and delete the file //F32-TST//FFFFFFF0.TXT and then press a key\n")); |
|
1252 test.Getch(); |
|
1253 |
|
1254 test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n")); |
|
1255 test.Getch(); |
|
1256 |
|
1257 rtime = ReadTestFile(file2, gFirstFile, KMinSize + 1, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); |
|
1258 test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize + 1, rtime/KMs); |
|
1259 |
|
1260 test.Printf(_L("Remove MMC card! and then press a key\n")); |
|
1261 test.Getch(); |
|
1262 |
|
1263 test.Printf(_L("Wait 3 seconds and insert MMC card! and then press a key\n")); |
|
1264 test.Getch(); |
|
1265 |
|
1266 |
|
1267 file1.Close(); |
|
1268 file2.Close(); |
|
1269 delete gBuf; |
|
1270 delete gBufSec; |
|
1271 } |
|
1272 |
|
1273 |
|
1274 /** Main tests function |
|
1275 */ |
|
1276 void CallTestsL() |
|
1277 { |
|
1278 |
|
1279 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1280 test.Printf(_L("Disabling Lock Fail simulation ...\n")); |
|
1281 // turn OFF lock failure mode |
|
1282 TBool simulatelockFailureMode = EFalse; |
|
1283 TInt r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
|
1284 test_KErrNone(r); |
|
1285 #endif |
|
1286 |
|
1287 TBuf16<45> dir; |
|
1288 |
|
1289 // FileNames/File generation |
|
1290 test.Start(_L("Preparing the environmnet\n")); |
|
1291 FileNameGen(gFirstFile, 8, gNextFile++); |
|
1292 FileNameGen(gSecondFile, 8, gNextFile++); |
|
1293 dir = gSessionPath; |
|
1294 dir.Append(gFirstFile); |
|
1295 gFirstFile = dir; |
|
1296 dir = gSessionPath; |
|
1297 dir.Append(gSecondFile); |
|
1298 gSecondFile = dir; |
|
1299 |
|
1300 |
|
1301 TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1)); |
|
1302 test(res == KErrNone && gBuf != NULL); |
|
1303 |
|
1304 gBufWritePtr.Set(gBuf->Des()); |
|
1305 FillBuffer(gBufWritePtr, KBlockSize, 'A'); |
|
1306 |
|
1307 TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1)); |
|
1308 test(res2 == KErrNone && gBufSec != NULL); |
|
1309 gBufReadPtr.Set(gBufSec->Des()); |
|
1310 |
|
1311 test.Next(_L("Boundary test")); |
|
1312 TestBoundaries(); |
|
1313 |
|
1314 test.Next(_L("Negative test\n")); |
|
1315 TestNegative(); |
|
1316 |
|
1317 test.Next(_L("Integrity test\n")); |
|
1318 TestIntegrity(); |
|
1319 |
|
1320 |
|
1321 test.Next(_L("Fill the cache, boundary testing\n")); |
|
1322 TestFillCache(); |
|
1323 |
|
1324 test.Next(_L("Fill the cache negative, boundary testing\n")); |
|
1325 TestFillCacheNegative(); |
|
1326 |
|
1327 test.End(); |
|
1328 delete gBuf; |
|
1329 delete gBufSec; |
|
1330 |
|
1331 #if defined(_DEBUG) || defined(_DEBUG_RELEASE) |
|
1332 // turn lock failure mode back ON (if enabled) |
|
1333 simulatelockFailureMode = ETrue; |
|
1334 r = controlIo(gTheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode); |
|
1335 test_KErrNone(r); |
|
1336 #endif |
|
1337 |
|
1338 } |
|
1339 |
|
1340 /** Initialises semaphores and call the tests |
|
1341 */ |
|
1342 void DoTests() |
|
1343 { |
|
1344 TInt r = 0; |
|
1345 |
|
1346 r = gClient.CreateLocal(0); |
|
1347 test_KErrNone(r); |
|
1348 |
|
1349 r = gTheFs.SetSessionPath(gSessionPath); |
|
1350 test_KErrNone(r); |
|
1351 |
|
1352 r = gTheFs.MkDirAll(gSessionPath); |
|
1353 test_Value(r, r == KErrNone || r == KErrAlreadyExists); |
|
1354 gTheFs.ResourceCountMarkStart(); |
|
1355 |
|
1356 TRAP(r,CallTestsL()); |
|
1357 |
|
1358 test_KErrNone(r); |
|
1359 gTheFs.ResourceCountMarkEnd(); |
|
1360 } |
|
1361 |
|
1362 /** Determines the space that can be used for the files |
|
1363 |
|
1364 */ |
|
1365 TBool CheckForDiskSize() |
|
1366 { |
|
1367 TVolumeInfo volInfo; |
|
1368 TInt r = gTheFs.Volume(volInfo, gDrive); |
|
1369 test_KErrNone(r); |
|
1370 gMediaSize = volInfo.iSize; |
|
1371 |
|
1372 test.Printf(_L("\nMedia size: %d MB\n"), gMediaSize/KOneMeg ); |
|
1373 |
|
1374 return ETrue; |
|
1375 } |
|
1376 |
|
1377 /** Main function |
|
1378 |
|
1379 @return KErrNone if everything was ok, panics otherwise |
|
1380 */ |
|
1381 TInt E32Main() |
|
1382 { |
|
1383 RThread t; |
|
1384 gMainThreadId = t.Id(); |
|
1385 |
|
1386 CTrapCleanup* cleanup; |
|
1387 cleanup = CTrapCleanup::New(); |
|
1388 |
|
1389 __UHEAP_MARK; |
|
1390 test.Start(_L("Starting tests... T_WCACHE")); |
|
1391 parseCommandLine(); |
|
1392 |
|
1393 TInt r = gTheFs.Connect(); |
|
1394 test_KErrNone(r); |
|
1395 |
|
1396 TDriveInfo info; |
|
1397 TVolumeInfo volInfo; |
|
1398 r = gTheFs.Drive(info,gDrive); |
|
1399 test_KErrNone(r); |
|
1400 |
|
1401 if(info.iMediaAtt&KMediaAttVariableSize) |
|
1402 { |
|
1403 test.Printf(_L("Tests skipped in RAM drive\n")); |
|
1404 goto out; |
|
1405 } |
|
1406 |
|
1407 r = gTheFs.Volume(volInfo, gDrive); |
|
1408 if (r == KErrNotReady) |
|
1409 { |
|
1410 if (info.iType == EMediaNotPresent) |
|
1411 test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest); |
|
1412 else |
|
1413 test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType); |
|
1414 } |
|
1415 else if (r == KErrCorrupt) |
|
1416 { |
|
1417 test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest); |
|
1418 } |
|
1419 test_KErrNone(r); |
|
1420 |
|
1421 if(!(volInfo.iFileCacheFlags & (EFileCacheReadEnabled | EFileCacheReadAheadEnabled))) |
|
1422 { |
|
1423 test.Printf(_L("Skipping tests, Read caching not enabled in this drive\n")); |
|
1424 goto out; |
|
1425 } |
|
1426 |
|
1427 if (((volInfo.iDrive.iMediaAtt & KMediaAttFormattable))) |
|
1428 Formatting(gDrive,ESpecialFormat); |
|
1429 |
|
1430 if(!CheckForDiskSize()) |
|
1431 { |
|
1432 test.Printf(_L("Skipping tests due to lack of space to perform them in this drive\n")); |
|
1433 } |
|
1434 else if(!gManual) |
|
1435 { |
|
1436 DoTests(); |
|
1437 } |
|
1438 else |
|
1439 { |
|
1440 TestRemoval(); |
|
1441 } |
|
1442 |
|
1443 out: |
|
1444 test.End(); |
|
1445 |
|
1446 gTheFs.Close(); |
|
1447 test.Close(); |
|
1448 |
|
1449 __UHEAP_MARKEND; |
|
1450 delete cleanup; |
|
1451 return(KErrNone); |
|
1452 } |
|
1453 |