|
1 // Copyright (c) 1997-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_alert.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include <f32file.h> |
|
19 #include <e32test.h> |
|
20 #include <e32math.h> |
|
21 #include <e32svr.h> |
|
22 #include "t_server.h" |
|
23 |
|
24 GLDEF_D RTest test(_L("T_ALERT")); |
|
25 |
|
26 LOCAL_D TInt gFileWrites; |
|
27 LOCAL_D TInt gFileReads; |
|
28 LOCAL_D TInt gFileCreates; |
|
29 LOCAL_D TInt gFileDeletes; |
|
30 LOCAL_D TInt gNotifies; |
|
31 LOCAL_D TInt gNotifyCancels; |
|
32 LOCAL_D TInt gMediaChanges; |
|
33 |
|
34 LOCAL_D const TInt gMaxIteration=100; |
|
35 LOCAL_D const TInt KHeapSize=0x4000; |
|
36 LOCAL_D const TInt gMaxDelay=100; |
|
37 LOCAL_D const TInt gMaxMediaChangeInterval=1000; |
|
38 LOCAL_D const TInt gUpdateInterval=10000; |
|
39 LOCAL_D const TInt gMaxFiles=4; |
|
40 LOCAL_D const TInt gMaxTempSize=1024; |
|
41 LOCAL_D const TFileName gPathThread1=_L("C:\\F32-TST\\TALERT\\"); |
|
42 |
|
43 // Test2 |
|
44 LOCAL_D const TInt gHeartBeatInterval=10000000; |
|
45 LOCAL_D TInt gThreadTick; |
|
46 LOCAL_D TInt gFileCreateFail; |
|
47 |
|
48 #if defined(__WINS__) |
|
49 LOCAL_D const TFileName gPathThread0=_L("X:\\F32-TST\\TALERT\\"); |
|
50 LOCAL_D const TFileName gPathThread2=_L("X:\\F32-TST\\TALERT\\"); |
|
51 #else |
|
52 LOCAL_D TFileName gPathThread0=_L("?:\\F32-TST\\TALERT\\"); |
|
53 LOCAL_D TFileName gPathThread2=_L("?:\\F32-TST\\TALERT\\"); |
|
54 #endif |
|
55 |
|
56 LOCAL_C void WaitForMedia() |
|
57 // |
|
58 // Wait until the media change is serviced |
|
59 // |
|
60 { |
|
61 FOREVER |
|
62 { |
|
63 TInt r=TheFs.MkDir(gPathThread0); |
|
64 if (r==KErrNone || r==KErrAlreadyExists) |
|
65 break; |
|
66 } |
|
67 } |
|
68 |
|
69 LOCAL_C TInt FileAccess(TAny* aPathPtr) |
|
70 // |
|
71 // Do lots of file access - ignore all errors |
|
72 // |
|
73 { |
|
74 |
|
75 TFileName file[gMaxFiles]; |
|
76 TFileName sessionPath=*(TDesC*)aPathPtr; |
|
77 HBufC8* tempPtr=HBufC8::New(gMaxTempSize); |
|
78 HBufC* tempPtrx=HBufC::New(gMaxTempSize); |
|
79 TPtr8 temp(tempPtr->Des()); |
|
80 TPtr tempx(tempPtrx->Des()); |
|
81 |
|
82 RFs fs; |
|
83 fs.Connect(); |
|
84 fs.SetSessionPath(sessionPath); |
|
85 |
|
86 FOREVER |
|
87 { |
|
88 switch(Math::Rand(gSeed)%4) |
|
89 { |
|
90 case 0: |
|
91 { |
|
92 TInt fileNum=Math::Rand(gSeed)%gMaxFiles; |
|
93 if (file[fileNum].Length()==0) |
|
94 break; |
|
95 RFile f; |
|
96 TInt r=f.Open(fs,file[fileNum],EFileRead|EFileWrite); |
|
97 if (r!=KErrNone) |
|
98 break; |
|
99 CreateLongName(tempx,gSeed,Math::Rand(gSeed)%gMaxTempSize); |
|
100 temp.Copy(tempx); |
|
101 r=f.Write(temp); |
|
102 if (r==KErrNone) |
|
103 gFileWrites++; |
|
104 f.Close(); |
|
105 break; |
|
106 } |
|
107 case 1: |
|
108 { |
|
109 TInt fileNum=Math::Rand(gSeed)%gMaxFiles; |
|
110 if (file[fileNum].Length()==0) |
|
111 break; |
|
112 RFile f; |
|
113 TInt r=f.Open(fs,file[fileNum],EFileRead|EFileWrite); |
|
114 if (r!=KErrNone) |
|
115 break; |
|
116 r=f.Read(temp); |
|
117 if (r==KErrNone) |
|
118 gFileReads++; |
|
119 f.Close(); |
|
120 break; |
|
121 } |
|
122 case 2: |
|
123 { |
|
124 TInt fileNum=Math::Rand(gSeed)%gMaxFiles; |
|
125 if (file[fileNum].Length()!=0) |
|
126 break; |
|
127 RFile f; |
|
128 TInt r=f.Temp(fs,sessionPath,file[fileNum],EFileRead|EFileWrite); |
|
129 if (r==KErrNone) |
|
130 gFileCreates++; |
|
131 f.Close(); |
|
132 break; |
|
133 } |
|
134 case 3: |
|
135 { |
|
136 TInt fileNum=Math::Rand(gSeed)%gMaxFiles; |
|
137 if (file[fileNum].Length()==0) |
|
138 break; |
|
139 TInt r=fs.Delete(file[fileNum]); |
|
140 if (r==KErrNone) |
|
141 { |
|
142 file[fileNum].SetLength(0); |
|
143 gFileDeletes++; |
|
144 } |
|
145 break; |
|
146 } |
|
147 default: |
|
148 break; |
|
149 } |
|
150 } |
|
151 |
|
152 //delete tempPtr; |
|
153 //delete tempPtrx; |
|
154 //return(KErrNone); |
|
155 } |
|
156 |
|
157 |
|
158 LOCAL_C void StartThread0() |
|
159 // |
|
160 // Start a thread that reads and writes to D: |
|
161 // |
|
162 { |
|
163 |
|
164 RThread clientThread; |
|
165 TInt r=clientThread.Create(_L("TALERT_Thread0"),FileAccess,0x4000,KHeapSize,KHeapSize,(TAny*)&gPathThread0,EOwnerThread); |
|
166 test(r==KErrNone); |
|
167 clientThread.Resume(); |
|
168 clientThread.Close(); |
|
169 } |
|
170 |
|
171 LOCAL_C void StartThread1() |
|
172 // |
|
173 // Start a thread that reads and writes to C: |
|
174 // |
|
175 { |
|
176 |
|
177 RThread clientThread; |
|
178 TInt r=clientThread.Create(_L("TALERT_Thread1"),FileAccess,0x4000,KHeapSize,KHeapSize,(TAny*)&gPathThread1,EOwnerThread); |
|
179 test(r==KErrNone); |
|
180 clientThread.Resume(); |
|
181 clientThread.Close(); |
|
182 } |
|
183 |
|
184 LOCAL_C void StartThread2() |
|
185 // |
|
186 // Start a thread that reads and writes to D: |
|
187 // |
|
188 { |
|
189 |
|
190 RThread clientThread; |
|
191 TInt r=clientThread.Create(_L("TALERT_Thread2"),FileAccess,0x4000,KHeapSize,KHeapSize,(TAny*)&gPathThread2,EOwnerThread); |
|
192 test(r==KErrNone); |
|
193 clientThread.Resume(); |
|
194 clientThread.Close(); |
|
195 } |
|
196 |
|
197 |
|
198 LOCAL_C TInt NotifyAccess(TAny*) |
|
199 // |
|
200 // Create, wait for and cancel notifiers. |
|
201 // |
|
202 { |
|
203 |
|
204 RFs fs; |
|
205 fs.Connect(); |
|
206 TRequestStatus status; |
|
207 |
|
208 FOREVER |
|
209 { |
|
210 switch(Math::Rand(gSeed)%4) |
|
211 { |
|
212 case 0: |
|
213 gNotifies++; |
|
214 fs.NotifyChange(ENotifyAll,status); |
|
215 User::WaitForRequest(status); |
|
216 break; |
|
217 case 1: |
|
218 gNotifies++; |
|
219 fs.NotifyChange(ENotifyEntry,status); |
|
220 User::WaitForRequest(status); |
|
221 break; |
|
222 case 2: |
|
223 gNotifyCancels++; |
|
224 fs.NotifyChange(ENotifyAll,status); |
|
225 User::After(Math::Rand(gSeed)%gMaxDelay); |
|
226 fs.NotifyChangeCancel(); |
|
227 User::WaitForRequest(status); |
|
228 break; |
|
229 case 3: |
|
230 gNotifyCancels++; |
|
231 fs.NotifyChange(ENotifyEntry,status); |
|
232 User::After(Math::Rand(gSeed)%gMaxDelay); |
|
233 fs.NotifyChangeCancel(); |
|
234 User::WaitForRequest(status); |
|
235 break; |
|
236 } |
|
237 } |
|
238 |
|
239 //return(KErrNone); |
|
240 } |
|
241 |
|
242 LOCAL_C void StartThread3() |
|
243 // |
|
244 // Start a thread that creates and waits/cancel RFs::Notifiers |
|
245 // |
|
246 { |
|
247 |
|
248 RThread clientThread; |
|
249 TInt r=clientThread.Create(_L("TALERT_Thread3"),NotifyAccess,0x4000,KHeapSize,KHeapSize,NULL,EOwnerThread); |
|
250 test(r==KErrNone); |
|
251 clientThread.Resume(); |
|
252 clientThread.Close(); |
|
253 } |
|
254 |
|
255 LOCAL_C TInt MediaChange(TAny*) |
|
256 // |
|
257 // Cause media changes a random intervals |
|
258 // |
|
259 { |
|
260 gMediaChanges=0; |
|
261 FOREVER |
|
262 { |
|
263 TInt interval=Math::Rand(gSeed)%gMaxMediaChangeInterval; |
|
264 User::After(interval); |
|
265 // UserSvr::ForceRemountMedia(ERemovableMedia0); // Generate media change |
|
266 ++gMediaChanges; |
|
267 } |
|
268 |
|
269 //return(KErrNone); |
|
270 } |
|
271 |
|
272 LOCAL_C void StartThread4() |
|
273 // |
|
274 // Start a thread that creates media changes |
|
275 // |
|
276 { |
|
277 |
|
278 RThread clientThread; |
|
279 TInt r=clientThread.Create(_L("TALERT_Thread4"),MediaChange,0x4000,KHeapSize,KHeapSize,NULL,EOwnerThread); |
|
280 test(r==KErrNone); |
|
281 clientThread.SetPriority(EPriorityMore); |
|
282 clientThread.Resume(); |
|
283 clientThread.Close(); |
|
284 } |
|
285 |
|
286 LOCAL_C void StartClock() |
|
287 // |
|
288 // Display ongoing reads/writes. Getch to exit |
|
289 // |
|
290 { |
|
291 |
|
292 test.Console()->ClearScreen(); |
|
293 FOREVER |
|
294 { |
|
295 User::After(gUpdateInterval); |
|
296 test.Console()->SetPos(0,5); |
|
297 test.Printf(_L("File writes = %d \n"),gFileWrites); |
|
298 test.Printf(_L("File reads = %d \n"),gFileReads); |
|
299 test.Printf(_L("File creates = %d \n"),gFileCreates); |
|
300 test.Printf(_L("File deletes = %d \n"),gFileDeletes); |
|
301 test.Printf(_L("File notifies = %d \n"),gNotifies); |
|
302 test.Printf(_L("File notifies cancelled = %d \n"),gNotifyCancels); |
|
303 // test.Printf(_L("Press any key to exit\n")); |
|
304 // TKeyCode keycode=test.Console()->KeyCode(); |
|
305 // if (keycode!=EKeyNull) |
|
306 // break; |
|
307 if (gFileWrites>gMaxIteration) |
|
308 break; |
|
309 } |
|
310 } |
|
311 |
|
312 LOCAL_C void KillThreads() |
|
313 // |
|
314 // Kill all threads |
|
315 // |
|
316 { |
|
317 test.Printf(_L("+Kill threads")); |
|
318 RThread t; |
|
319 |
|
320 TInt r=t.Open(_L("TALERT_Thread0"),EOwnerThread); |
|
321 if(r==KErrNone) |
|
322 { |
|
323 t.Kill(KErrCancel); |
|
324 t.Close(); |
|
325 } |
|
326 else |
|
327 test(r==KErrNotFound); |
|
328 |
|
329 r=t.Open(_L("TALERT_Thread1"),EOwnerThread); |
|
330 if(r==KErrNone) |
|
331 { |
|
332 t.Kill(KErrCancel); |
|
333 t.Close(); |
|
334 } |
|
335 else |
|
336 test(r==KErrNotFound); |
|
337 |
|
338 r=t.Open(_L("TALERT_Thread2"),EOwnerThread); |
|
339 if(r==KErrNone) |
|
340 { |
|
341 t.Kill(KErrCancel); |
|
342 t.Close(); |
|
343 } |
|
344 else |
|
345 test(r==KErrNotFound); |
|
346 |
|
347 r=t.Open(_L("TALERT_Thread3"),EOwnerThread); |
|
348 if(r==KErrNone) |
|
349 { |
|
350 t.Kill(KErrCancel); |
|
351 t.Close(); |
|
352 } |
|
353 else |
|
354 test(r==KErrNotFound); |
|
355 |
|
356 r=t.Open(_L("TALERT_Thread4"),EOwnerThread); |
|
357 if(r==KErrNone) |
|
358 { |
|
359 t.Kill(KErrCancel); |
|
360 t.Close(); |
|
361 } |
|
362 else |
|
363 test(r==KErrNotFound); |
|
364 |
|
365 /* TFindThread threadFinder(_L("TALERT_*")); |
|
366 FOREVER |
|
367 { |
|
368 TFullName threadName; |
|
369 TInt r=threadFinder.Next(threadName); |
|
370 test.Printf(_L("r=%d"),r); |
|
371 if (r==KErrNotFound) |
|
372 break; |
|
373 test(r==KErrNone); |
|
374 test.Printf(_L("Killing Thread %S\n"),&threadName); |
|
375 RThread t; |
|
376 r=t.Open(threadName,EOwnerThread); |
|
377 test(r==KErrNone); |
|
378 t.Kill(KErrCancel); |
|
379 t.Close(); |
|
380 } */ |
|
381 test.Printf(_L("-Kill threads")); |
|
382 } |
|
383 |
|
384 LOCAL_C void Test1() |
|
385 // |
|
386 // Create lots of threads and change notifiers |
|
387 // |
|
388 { |
|
389 test.Next(_L("Create lots of threads and change notifiers")); |
|
390 TInt r=TheFs.MkDirAll(gPathThread1); |
|
391 test(r==KErrNone || r==KErrAlreadyExists); |
|
392 r=TheFs.MkDir(gPathThread2); |
|
393 test(r==KErrNone || r==KErrAlreadyExists); |
|
394 |
|
395 StartThread0(); // Read and write to D: |
|
396 StartThread1(); // Read and write to C: |
|
397 StartThread2(); // Read and write to D: (again) |
|
398 StartThread3(); // Set RFs::Notifiers |
|
399 StartThread4(); // Generate media changes |
|
400 StartClock(); // Time how long test has run |
|
401 KillThreads(); |
|
402 } |
|
403 |
|
404 LOCAL_C TInt ThreadHangTest(TAny*) |
|
405 // |
|
406 // Keep writing to the fileserver and setting gThreadTick |
|
407 // |
|
408 { |
|
409 |
|
410 RFs fs; |
|
411 fs.Connect(); |
|
412 fs.SetSessionPath(gPathThread0); |
|
413 |
|
414 FOREVER |
|
415 { |
|
416 gFileCreateFail++; |
|
417 gThreadTick=ETrue; |
|
418 RFile f; |
|
419 TInt r=f.Replace(fs,_L("TwiddleThumbs"),EFileRead|EFileWrite); |
|
420 if (r!=KErrNone) |
|
421 continue; |
|
422 gFileCreateFail=0; |
|
423 f.Close(); |
|
424 gThreadTick=ETrue; |
|
425 fs.Delete(_L("TwiddleThumbs")); |
|
426 gThreadTick=ETrue; |
|
427 } |
|
428 |
|
429 //return(KErrNone); |
|
430 } |
|
431 |
|
432 LOCAL_C void Test2() |
|
433 // |
|
434 // Create a hung server then kill the thread it wants to write to. |
|
435 // |
|
436 { |
|
437 |
|
438 test.Next(_L("Create a hung server and kill the thread it is writing to")); |
|
439 TInt r=TheFs.MkDir(gPathThread0); |
|
440 test(r==KErrNone || r==KErrAlreadyExists); |
|
441 StartThread4(); // Generate media changes |
|
442 |
|
443 RThread clientThread; |
|
444 r=clientThread.Create(_L("TALERT_ThreadHangTest"),ThreadHangTest,0x4000,KHeapSize,KHeapSize,NULL,EOwnerThread); |
|
445 test(r==KErrNone); |
|
446 TRequestStatus status; |
|
447 clientThread.Logon(status); |
|
448 clientThread.Resume(); |
|
449 gThreadTick=ETrue; |
|
450 test.Next(_L("ThreadHangTest is running")); |
|
451 |
|
452 TInt count=0; |
|
453 FOREVER |
|
454 { |
|
455 test.Printf(_L("Thread tick = %d File create failures = %d \n"),count,gFileCreateFail); |
|
456 test.Printf(_L("Media changes = %d\n"),gMediaChanges); |
|
457 User::After(gHeartBeatInterval); |
|
458 if (gThreadTick==0) |
|
459 break; |
|
460 gThreadTick=0; |
|
461 count++; |
|
462 } |
|
463 |
|
464 test.Next(_L("Thread is hung")); |
|
465 clientThread.Kill(KErrCancel); |
|
466 clientThread.Close(); |
|
467 User::WaitForRequest(status); |
|
468 KillThreads(); |
|
469 User::After(1000000); |
|
470 |
|
471 test.Printf(_L("Press return to the clear notifier, then any key to continue test")); |
|
472 test.Getch(); |
|
473 |
|
474 test.Next(_L("Test fileserver is still alive after thread is killed")); |
|
475 WaitForMedia(); |
|
476 r=TheFs.MkDir(gPathThread0); // Check fileserver ok |
|
477 if(r!=KErrNone && r!=KErrAlreadyExists) |
|
478 test.Printf(_L("r=%d"),r); |
|
479 test(r==KErrNone || r==KErrAlreadyExists); |
|
480 |
|
481 } |
|
482 |
|
483 GLDEF_C void CallTestsL() |
|
484 // |
|
485 // Do tests relative to the session path |
|
486 // |
|
487 { |
|
488 |
|
489 RThread().SetPriority(EPriorityLess); |
|
490 #if defined(__WINS__) |
|
491 if (gSessionPath[0]!='X') |
|
492 return; |
|
493 #else |
|
494 // Test on two drives where possible. This should be C: together with |
|
495 // the drive referenced by the default path. Where the default path is |
|
496 // C:, then only C: is used. The standard way to run the test is to |
|
497 // set the default path to D: |
|
498 |
|
499 gPathThread0[0]=gSessionPath[0]; |
|
500 gPathThread2[0]=gSessionPath[0]; |
|
501 #endif |
|
502 |
|
503 Test2(); |
|
504 Test1(); |
|
505 //This test can leave the drive corrupt so a format is required |
|
506 #if defined(__WINS__) |
|
507 Format(EDriveX); |
|
508 #else |
|
509 Format(EDriveD); |
|
510 #endif |
|
511 //clean up the talert directory after the test completes |
|
512 /* CFileMan* FileMan=NULL; |
|
513 FileMan=CFileMan::NewL(TheFs); |
|
514 TInt r=FileMan->RmDir(_L("\\F32-TST\\TALERT\\")); |
|
515 test.Printf(_L("r=%d"),r); |
|
516 test(r==KErrNone || r==KErrPathNotFound); |
|
517 delete FileMan; |
|
518 */ |
|
519 } |