|
1 // Copyright (c) 2002-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 // |
|
15 |
|
16 //! @file f32test\concur\t_csfsoak.cpp |
|
17 |
|
18 #include <f32file.h> |
|
19 #include <e32test.h> |
|
20 #include <e32math.h> |
|
21 #include <f32dbg.h> |
|
22 |
|
23 #include "t_server.h" |
|
24 #include "t_chlffs.h" |
|
25 #include "t_tdebug.h" |
|
26 #include "t_cfssoak.h" |
|
27 |
|
28 GLDEF_D RTest test(_L("T_CFSSOAK")); |
|
29 GLDEF_D RFs TheFs; |
|
30 |
|
31 GLREF_D TPtrC gArgV[]; |
|
32 GLREF_D TInt gArgC; |
|
33 |
|
34 LOCAL_D TFullName gFsName; |
|
35 LOCAL_D TFullName gFsName1; |
|
36 LOCAL_D TFullName gFsName2; |
|
37 LOCAL_D TFullName gOldFsName; |
|
38 LOCAL_D TFullName gNewFsName; |
|
39 LOCAL_D TBool gNoMedia = ETrue; |
|
40 |
|
41 _LIT(KFsFile, "CFAFSDLY"); |
|
42 _LIT(KFsName, "DelayFS"); |
|
43 |
|
44 LOCAL_D const TInt32 KSecond = 1000000; |
|
45 |
|
46 LOCAL_D TChar gRemFsChr = 0; |
|
47 LOCAL_D TInt gRemFsDrv = 0; |
|
48 |
|
49 LOCAL_D TChar gDrvChFill = 0; |
|
50 |
|
51 LOCAL_D TInt gNumRead = 0; |
|
52 LOCAL_D TInt gNumFill = 0; |
|
53 LOCAL_D TInt gNumRem = 0; |
|
54 |
|
55 GLDEF_D TExtension gPrimaryExtensions[KMaxDrives]; |
|
56 |
|
57 inline void TraceError(const char* aFile, TInt aLine, const TDesC& aStr, TInt aRsp) |
|
58 // |
|
59 // 'Helper' routine to output the file and line of an error as well as a string |
|
60 // and a response value. |
|
61 // |
|
62 { |
|
63 TBuf<256> fbuf; |
|
64 TPtrC8 fptr((const TUint8*)aFile); |
|
65 fbuf.Copy(fptr); |
|
66 RDebug::Print(_L("%S:%d %S: r = %d"), &fbuf, aLine, &aStr, aRsp); |
|
67 } |
|
68 |
|
69 #define TESTSTR(r,s,cond) if (!(cond)) { TraceError(__FILE__, __LINE__, (s), (r)); test(0); } |
|
70 #define TESTLIT(r,s,cond) { _LIT(KStr,s); TESTSTR(r,KStr,cond); } |
|
71 #define TESTRES(r,cond) TESTLIT(r,"ERROR",cond) |
|
72 |
|
73 LOCAL_C TChar MountTestFileSystem(TInt aDrive) |
|
74 /// |
|
75 /// Mount a new CTestFileSystem on the drive under test. |
|
76 /// @param aDrive Drive number (EDriveC etc.) to be used. |
|
77 /// |
|
78 { |
|
79 TInt r; |
|
80 // Check attributes |
|
81 TBuf<64> b; |
|
82 TChar c; |
|
83 r=TheFs.DriveToChar(aDrive,c); |
|
84 TESTLIT(r, "TheFs.DriveToChar", r==KErrNone); |
|
85 |
|
86 b.Format(_L("Mount test file system on %c:"),(TUint)c); |
|
87 test.Next(b); |
|
88 |
|
89 r=TheFs.AddFileSystem(KFsFile); |
|
90 TESTLIT(r, "TheFs.AddFileSystem", r==KErrNone || r==KErrAlreadyExists); |
|
91 |
|
92 r=TheFs.FileSystemName(gOldFsName,aDrive); |
|
93 TESTLIT(r, "TheFs.FileSystemName", r==KErrNone || r==KErrNotFound); |
|
94 |
|
95 TDriveInfo drv; |
|
96 r = TheFs.Drive(drv, gRemFsDrv); |
|
97 TESTLIT(r, "Drive()", r == KErrNone); |
|
98 |
|
99 gNoMedia = (drv.iType == EMediaUnknown || drv.iType == EMediaNotPresent); |
|
100 |
|
101 if (gOldFsName.Length() > 0) |
|
102 { |
|
103 r = TheFs.ExtensionName(gPrimaryExtensions[aDrive].iName, aDrive, 0); |
|
104 if (r == KErrNone) |
|
105 gPrimaryExtensions[aDrive].iExists = ETrue; |
|
106 |
|
107 TTest::Printf(_L("Dismount %C: %S"), (TUint)c, &gOldFsName); |
|
108 r=TheFs.DismountFileSystem(gOldFsName,aDrive); |
|
109 TESTLIT(r, "DismountFileSystem", r==KErrNone); |
|
110 } |
|
111 |
|
112 if (gPrimaryExtensions[aDrive].iExists == EFalse) |
|
113 r=TheFs.MountFileSystem(KFsName,aDrive); |
|
114 else |
|
115 r=TheFs.MountFileSystem(KFsName,gPrimaryExtensions[aDrive].iName,aDrive); |
|
116 |
|
117 TESTLIT(r, "TheFs.MountFileSystem", r==KErrNone); |
|
118 |
|
119 r=TheFs.FileSystemName(gNewFsName,aDrive); |
|
120 TESTLIT(r, "TheFs.FileSystemName", r==KErrNone); |
|
121 |
|
122 r = gNewFsName.CompareF(KFsName); |
|
123 TESTLIT(r, "gNewFsName.Compare", r==0); |
|
124 |
|
125 return c; |
|
126 } |
|
127 |
|
128 LOCAL_C void UnmountFileSystem(TInt aDrive) |
|
129 /// |
|
130 /// Dismount the filesystem and remount the original one. |
|
131 /// @param aDrive Drive number (EDriveC etc.) to be unmounted. |
|
132 /// |
|
133 { |
|
134 TChar c; |
|
135 TInt r=TheFs.DriveToChar(aDrive,c); |
|
136 TESTLIT(r, "TheFs.DriveToChar", r==KErrNone); |
|
137 |
|
138 r=TheFs.DismountFileSystem(gNewFsName,aDrive); |
|
139 TESTLIT(r, "TheFs.DismountFileSystem", r==KErrNone); |
|
140 |
|
141 if (gNoMedia) |
|
142 { |
|
143 TTest::Printf(_L("No media on %C: so don't remount it"), (TUint)c); |
|
144 } |
|
145 else if (gOldFsName.Length() > 0) |
|
146 { |
|
147 TTest::Printf(_L("Mount %C: %S"), (TUint)c, &gOldFsName); |
|
148 if (gPrimaryExtensions[aDrive].iExists == EFalse) |
|
149 r=TheFs.MountFileSystem(gOldFsName,aDrive); |
|
150 else |
|
151 r=TheFs.MountFileSystem(gOldFsName,gPrimaryExtensions[aDrive].iName,aDrive); |
|
152 TESTLIT(r, "MountFileSystem", r==KErrNone); |
|
153 } |
|
154 } |
|
155 |
|
156 LOCAL_C TInt testReadOnly(TAny* /*aData*/) |
|
157 /// |
|
158 /// Task to test read-only operations. |
|
159 /// |
|
160 { |
|
161 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
162 TSoakReadOnly rdonly; |
|
163 TInt64 seed = 178543; |
|
164 TInt r = KErrNone; |
|
165 rdonly.ExcludeDrive(gRemFsDrv); |
|
166 while (r == KErrNone) |
|
167 { |
|
168 r = rdonly.ScanDrives(ETrue, Math::Rand(seed) % 90 + 10); |
|
169 TTest::PrintLock(); |
|
170 TTest::Printf(); |
|
171 TTest::Printf(_L("Read-only test results:\n")); |
|
172 TSoakStats::Print(); |
|
173 rdonly.iDrives.Print(_L("Drives:")); |
|
174 rdonly.iDirs.Print(_L("Dirs:")); |
|
175 rdonly.iFiles.Print(_L("Files:")); |
|
176 rdonly.iReads.Print(_L("Reads:")); |
|
177 TTest::Printf(); |
|
178 TTest::PrintUnlock(); |
|
179 gNumRead++; |
|
180 } |
|
181 delete cleanup; |
|
182 TTest::Fail(HERE, r, _L("ScanDrives error")); |
|
183 return r; |
|
184 } |
|
185 |
|
186 LOCAL_C TInt testFillEmpty(TAny* /*aData*/) |
|
187 /// |
|
188 /// Task to repeatedly fill and clean a drive. |
|
189 /// |
|
190 { |
|
191 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
192 TVolumeInfo info; |
|
193 TFullName gFsName; |
|
194 TChar drvch = 0; |
|
195 TInt drive = 0; |
|
196 TInt64 free = 0; |
|
197 RFs fs; |
|
198 TInt r = fs.Connect(); |
|
199 if (r != KErrNone) |
|
200 TTest::Fail(HERE, r, _L("can't connect to fileserver\n")); |
|
201 if (gDrvChFill) |
|
202 { |
|
203 // User specified the drive, so use that explicitly |
|
204 drvch = gDrvChFill; |
|
205 } |
|
206 else |
|
207 { |
|
208 // User didn't specify the drive, so scan through them looking for |
|
209 // likely candidates. Don't use ROM or RAM drives, or LFFS ones, or |
|
210 // our own 'slow' file system. Out of what's left, look for the one |
|
211 // with the least (but non-zero) free space. |
|
212 for (drive = EDriveA; drive <= EDriveZ; drive++) |
|
213 { |
|
214 if (drive != gRemFsDrv) |
|
215 { |
|
216 TDriveInfo d; |
|
217 TInt r; |
|
218 r = fs.Drive(d, drive); |
|
219 if (r == KErrNone && d.iDriveAtt != 0 && |
|
220 !(d.iDriveAtt & KDriveAttRom) && |
|
221 d.iMediaAtt != EMediaRam && |
|
222 !IsFileSystemLFFS(fs, drive)) |
|
223 { |
|
224 r = fs.Volume(info, drive); |
|
225 if (r == KErrNone) |
|
226 { |
|
227 if (free <= 0 || info.iFree < free) |
|
228 { |
|
229 r = fs.DriveToChar(drive, drvch); |
|
230 if (r != KErrNone) |
|
231 TTest::Fail(HERE, r, _L("DriveToChar(%d)"), drive); |
|
232 free = info.iFree; |
|
233 } |
|
234 } |
|
235 else |
|
236 { |
|
237 // not interested in drives which produce errors, they |
|
238 // probably don't really exist. |
|
239 } |
|
240 } |
|
241 else |
|
242 { |
|
243 // Drive doesn't exist, is a ROM drive or an LFFS drive, don't |
|
244 // use it. |
|
245 } |
|
246 } |
|
247 } |
|
248 } |
|
249 |
|
250 // If no drive found, can't do fill test so fail. |
|
251 if (drvch == 0) |
|
252 { |
|
253 TTest::Fail(HERE, _L("No drive found for fill test!")); |
|
254 } |
|
255 |
|
256 r = fs.CharToDrive(drvch, drive); |
|
257 if (r != KErrNone) |
|
258 TTest::Fail(HERE, r, _L("CharToDrive(%C:)\n"), (TUint)drvch); |
|
259 r = fs.FileSystemName(gFsName, drive); |
|
260 if (r != KErrNone) |
|
261 TTest::Fail(HERE, r, _L("FileSystemName(%C:)\n"), (TUint)drvch); |
|
262 |
|
263 r = fs.Volume(info, drive); |
|
264 if (r != KErrNone) |
|
265 TTest::Fail(HERE, r, _L("Volume(%C:)\n"), (TUint)drvch); |
|
266 |
|
267 fs.Close(); |
|
268 |
|
269 TTest::Printf(_L("Using %C: (%S) with %d KB free for fill/clean cycle test\n"), |
|
270 (TUint)drvch, &gFsName, I64LOW(info.iFree / 1024)); |
|
271 |
|
272 TSoakFill fill; |
|
273 r = fill.SetDrive(drvch); |
|
274 if (r != KErrNone) |
|
275 TTest::Fail(HERE, r, _L("Unable to setup drive %C"), (TUint)drvch); |
|
276 |
|
277 r = fill.CleanDrive(); |
|
278 if (r != KErrNone && r != KErrNotFound && r != KErrPathNotFound) |
|
279 TTest::Fail(HERE, r, _L("Error cleaning drive %C"), (TUint)drvch); |
|
280 |
|
281 // Loop to do the actual test |
|
282 while (r == KErrNone) |
|
283 { |
|
284 r = fill.FillDrive(); |
|
285 if (r != KErrNone && r != KErrDiskFull) |
|
286 TTest::Fail(HERE, r, _L("Error filling drive %C"), (TUint)drvch); |
|
287 |
|
288 TTest::PrintLock(); |
|
289 TTest::Printf(_L("%C: filled\n"), (TUint)drvch); |
|
290 TTest::PrintUnlock(); |
|
291 |
|
292 r = fill.CleanDrive(); |
|
293 if (r == KErrPathNotFound) |
|
294 r = KErrNone; |
|
295 if (r != KErrNone) |
|
296 TTest::Fail(HERE, r, _L("cleaning drive %C"), (TUint)drvch); |
|
297 |
|
298 TTest::PrintLock(); |
|
299 TTest::Printf(_L("%C: cleaned\n"), (TUint)drvch); |
|
300 TTest::PrintUnlock(); |
|
301 |
|
302 gNumFill++; |
|
303 } |
|
304 delete cleanup; |
|
305 TTest::Fail(HERE, r, _L("Fill/clean error")); |
|
306 return r; |
|
307 } |
|
308 |
|
309 LOCAL_C TInt testRemote(TAny* /*aData*/) |
|
310 /// |
|
311 /// Task to exercise the remote (special) filesystem. |
|
312 /// |
|
313 { |
|
314 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
315 TSoakRemote rem(gRemFsChr); |
|
316 TInt r = KErrNone; |
|
317 for (TBool sync = EFalse; r == KErrNone; sync = !sync) |
|
318 { |
|
319 for (TInt i = 0; i < 1; i++) |
|
320 { |
|
321 rem.Remount(sync); |
|
322 r = rem.TestSession(); |
|
323 if (r != KErrNone) |
|
324 TTest::Fail(HERE, r, _L("TestSession failed")); |
|
325 r = rem.TestSubSession(); |
|
326 if (r != KErrNone) |
|
327 TTest::Fail(HERE, r, _L("TestSubSession failed")); |
|
328 r = rem.TestMount(); |
|
329 if (r != KErrNone) |
|
330 TTest::Fail(HERE, r, _L("Mount/dismount failed")); |
|
331 User::After(100*1000000); |
|
332 gNumRem++; |
|
333 } |
|
334 } |
|
335 delete cleanup; |
|
336 TTest::Fail(HERE, r, _L("Test (remote) filesystem error")); |
|
337 return r; |
|
338 } |
|
339 |
|
340 GLDEF_C void CallTestsL() |
|
341 /// |
|
342 /// Do all tests. |
|
343 /// |
|
344 { |
|
345 // first thing, initialise local test class to make sure it gets done. |
|
346 TInt r = TTest::Init(); |
|
347 test(r == KErrNone); |
|
348 |
|
349 const TInt KMaxArgs = 4; |
|
350 TPtrC argv[KMaxArgs]; |
|
351 TInt argc = TTest::ParseCommandArguments(argv, KMaxArgs); |
|
352 |
|
353 gRemFsChr = 'M'; // probably a 'safe' drive |
|
354 gDrvChFill = 0; |
|
355 |
|
356 if (argc > 1) |
|
357 gRemFsChr = User::UpperCase(argv[1][0]); |
|
358 if (argc > 2) |
|
359 gDrvChFill = User::UpperCase(argv[2][0]); |
|
360 |
|
361 r = TheFs.CharToDrive(gRemFsChr, gRemFsDrv); |
|
362 |
|
363 if (r != KErrNone || gRemFsDrv == EDriveZ) |
|
364 { |
|
365 test.Printf(_L("Test cannnot run on drive %C:\n"), (TUint)gRemFsChr); |
|
366 return; |
|
367 } |
|
368 |
|
369 // If we can do it, check whether the drives are LFFS and are OK |
|
370 // !!! Disable platform security tests until we get the new APIs |
|
371 /* if (User::Capability() & KCapabilityRoot) |
|
372 { |
|
373 if (gDrvChFill != 0 && gDrvChFill != gRemFsChr) |
|
374 CheckMountLFFS(TheFs, gDrvChFill); |
|
375 } |
|
376 */ |
|
377 MountTestFileSystem(gRemFsDrv); |
|
378 |
|
379 r = TTest::Create(0, testReadOnly, _L("T_ReadOnly")); |
|
380 test(r == KErrNone); |
|
381 |
|
382 r = TTest::Create(1, testFillEmpty, _L("T_FillEmpty")); |
|
383 test(r == KErrNone); |
|
384 |
|
385 r = TTest::Create(2, testRemote, _L("T_Remote")); |
|
386 test(r == KErrNone); |
|
387 |
|
388 TRequestStatus kStat; |
|
389 test.Console()->Read(kStat); |
|
390 TInt displaycount = 0; |
|
391 while ((r = TTest::Run(ETrue, 1*KSecond)) == KErrNone) // run until any thread exits |
|
392 { |
|
393 if (++displaycount >= 60 || kStat == KErrNone) |
|
394 { |
|
395 test.Printf(_L("Fill %-6d Rem %-6d Read %d\n"), gNumFill, gNumRem, gNumRead); |
|
396 displaycount = 0; |
|
397 } |
|
398 if (kStat == KErrNone) |
|
399 { |
|
400 test.Printf(_L("Aborted by user!\n")); |
|
401 break; |
|
402 } |
|
403 } |
|
404 test(r == KErrNone); |
|
405 |
|
406 // Kill all outstanding threads. |
|
407 TTest::KillAll(KErrAbort); |
|
408 |
|
409 UnmountFileSystem(gRemFsDrv); |
|
410 } |
|
411 |
|
412 GLDEF_C TInt E32Main() |
|
413 // |
|
414 // Main entry point |
|
415 // |
|
416 { |
|
417 for (TInt i = 0; i < KMaxDrives; i++) |
|
418 { |
|
419 gPrimaryExtensions[i].iExists = EFalse; |
|
420 } |
|
421 |
|
422 TInt r; |
|
423 CTrapCleanup* cleanup; |
|
424 cleanup=CTrapCleanup::New(); |
|
425 __UHEAP_MARK; |
|
426 |
|
427 test.Title(); |
|
428 test.Start(_L("Starting tests...")); |
|
429 |
|
430 r=TheFs.Connect(); |
|
431 test(r==KErrNone); |
|
432 |
|
433 // TheFs.SetAllocFailure(gAllocFailOn); |
|
434 TTime timerC; |
|
435 timerC.HomeTime(); |
|
436 |
|
437 // Do the test |
|
438 TRAP(r,CallTestsL()); |
|
439 |
|
440 // reset the debug register |
|
441 TheFs.SetDebugRegister(0); |
|
442 |
|
443 TTime endTimeC; |
|
444 endTimeC.HomeTime(); |
|
445 TTimeIntervalSeconds timeTakenC; |
|
446 r=endTimeC.SecondsFrom(timerC,timeTakenC); |
|
447 test(r==KErrNone); |
|
448 test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int()); |
|
449 // TheFs.SetAllocFailure(gAllocFailOff); |
|
450 TheFs.Close(); |
|
451 test.End(); |
|
452 test.Close(); |
|
453 __UHEAP_MARKEND; |
|
454 delete cleanup; |
|
455 return(KErrNone); |
|
456 } |