|
1 // Copyright (c) 2001-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 // e32test\secure\t_sthread.cpp |
|
15 // Overview: |
|
16 // Test the platform security aspects of the RThread class |
|
17 // API Information: |
|
18 // RThread |
|
19 // Details: |
|
20 // - Test renaming the current thread and renaming a thread from |
|
21 // another thread. Verify results are as expected. |
|
22 // - Test resuming a thread from a different process and from the |
|
23 // process that created the thread. Verify results are as expected. |
|
24 // - Verify that other processes can not suspend a thread and that the |
|
25 // creating process can. |
|
26 // - Perform a variety of tests on killing, terminating and panicking |
|
27 // a thread. Verify results are as expected. |
|
28 // - Test setting thread priority in a variety of ways, verify results |
|
29 // are as expected. Includes ensuring real-time priorities are |
|
30 // unavailable to processes without capability ProtServ. |
|
31 // - Test RequestComplete and RequestSignal on a thread in a variety |
|
32 // of ways, verify results are as expected. |
|
33 // - Test SetProcessPriority on a thread in a variety of ways, verify |
|
34 // results are as expected. |
|
35 // - Test the Heap, ExceptionHandler, SetExceptionHandler, |
|
36 // ModifyExceptionMask, RaiseException, IsExceptionHandled, |
|
37 // SetProtected and SetSystem methods. Verify results as expected. |
|
38 // Platforms/Drives/Compatibility: |
|
39 // All. |
|
40 // Assumptions/Requirement/Pre-requisites: |
|
41 // Failures and causes: |
|
42 // Base Port information: |
|
43 // |
|
44 // |
|
45 |
|
46 #include <e32test.h> |
|
47 |
|
48 LOCAL_D RTest test(_L("T_STHREAD")); |
|
49 |
|
50 _LIT(KSyncMutex,"T_STHREAD-sync-mutex"); |
|
51 RMutex SyncMutex; |
|
52 |
|
53 void Wait() |
|
54 { |
|
55 RMutex syncMutex; |
|
56 if(syncMutex.OpenGlobal(KSyncMutex)!=KErrNone) |
|
57 User::Invariant(); |
|
58 syncMutex.Wait(); |
|
59 syncMutex.Signal(); |
|
60 syncMutex.Close(); |
|
61 } |
|
62 |
|
63 enum TTestProcessFunctions |
|
64 { |
|
65 ETestProcessResume, |
|
66 ETestProcessSuspend, |
|
67 ETestProcessKill, |
|
68 ETestProcessTerminate, |
|
69 ETestProcessPanic, |
|
70 ETestProcessRequestComplete, |
|
71 ETestProcessRequestSignal, |
|
72 ETestProcessPriorityControlOff, |
|
73 ETestProcessPriorityControlOn, |
|
74 ETestProcessSetPriority, |
|
75 ETestProcessSetPrioritiesWithoutProtServ, |
|
76 ETestProcessSetPrioritiesWithProtServ |
|
77 }; |
|
78 |
|
79 #include "testprocess.h" |
|
80 |
|
81 _LIT(KTestPanicCategory,"TEST PANIC"); |
|
82 _LIT(KTestThreadName,"TestName"); |
|
83 |
|
84 |
|
85 class RTestThread : public RThread |
|
86 { |
|
87 public: |
|
88 void Create(TThreadFunction aFunction,TAny* aArg=0); |
|
89 }; |
|
90 |
|
91 volatile TInt TestThreadCount = 0; |
|
92 |
|
93 TInt TestThreadNull(TAny*) |
|
94 { |
|
95 ++TestThreadCount; |
|
96 Wait(); |
|
97 return KErrNone; |
|
98 } |
|
99 |
|
100 void RTestThread::Create(TThreadFunction aFunction,TAny* aArg) |
|
101 { |
|
102 TInt r=RThread::Create(_L("TestThread"),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,aArg); |
|
103 test(r==KErrNone); |
|
104 } |
|
105 |
|
106 |
|
107 // these priorities are available to any process |
|
108 void TestSetNormalApplicationPriorities(RThread& aThread) |
|
109 { |
|
110 TThreadPriority priority = aThread.Priority(); // save priority to restore before return |
|
111 aThread.SetPriority(EPriorityAbsoluteVeryLow); |
|
112 test(aThread.Priority()==EPriorityAbsoluteVeryLow); |
|
113 aThread.SetPriority(EPriorityAbsoluteLowNormal); |
|
114 test(aThread.Priority()==EPriorityAbsoluteLowNormal); |
|
115 aThread.SetPriority(EPriorityAbsoluteLow); |
|
116 test(aThread.Priority()==EPriorityAbsoluteLow); |
|
117 aThread.SetPriority(EPriorityAbsoluteBackgroundNormal); |
|
118 test(aThread.Priority()==EPriorityAbsoluteBackgroundNormal); |
|
119 aThread.SetPriority(EPriorityAbsoluteBackground); |
|
120 test(aThread.Priority()==EPriorityAbsoluteBackground); |
|
121 aThread.SetPriority(EPriorityAbsoluteForegroundNormal); |
|
122 test(aThread.Priority()==EPriorityAbsoluteForegroundNormal); |
|
123 aThread.SetPriority(EPriorityAbsoluteForeground); |
|
124 test(aThread.Priority()==EPriorityAbsoluteForeground); |
|
125 aThread.SetPriority(EPriorityAbsoluteHighNormal); |
|
126 test(aThread.Priority()==EPriorityAbsoluteHighNormal); |
|
127 aThread.SetPriority(EPriorityAbsoluteHigh); |
|
128 test(aThread.Priority()==EPriorityAbsoluteHigh); |
|
129 aThread.SetPriority(priority); |
|
130 } |
|
131 |
|
132 TInt TestThreadSetPriority(TAny* aArg) |
|
133 { |
|
134 RThread thisThread; |
|
135 thisThread.SetPriority((TThreadPriority)(reinterpret_cast<TInt>(aArg))); |
|
136 return KErrNone; |
|
137 } |
|
138 |
|
139 void TestSetPriorityPanic(TThreadPriority aPriority) |
|
140 { |
|
141 RTestThread thread; |
|
142 TRequestStatus status; |
|
143 thread.Create(TestThreadSetPriority, reinterpret_cast<TAny*>(aPriority)); |
|
144 thread.Logon(status); |
|
145 thread.Resume(); |
|
146 User::WaitForRequest(status); |
|
147 test(thread.ExitType()==EExitPanic); |
|
148 test(thread.ExitCategory()==_L("KERN-EXEC")); |
|
149 test(thread.ExitReason()==46); |
|
150 CLOSE_AND_WAIT(thread); |
|
151 } |
|
152 |
|
153 void TestSetPrioritySuccess(TThreadPriority aPriority) |
|
154 { |
|
155 RTestThread thread; |
|
156 TRequestStatus status; |
|
157 thread.Create(TestThreadSetPriority, reinterpret_cast<TAny*>(aPriority)); |
|
158 thread.Logon(status); |
|
159 thread.Resume(); |
|
160 User::WaitForRequest(status); |
|
161 test(thread.Priority()==aPriority); |
|
162 test(thread.ExitCategory()==_L("Kill")); |
|
163 test(thread.ExitReason()==0); |
|
164 CLOSE_AND_WAIT(thread); |
|
165 } |
|
166 |
|
167 TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2) |
|
168 { |
|
169 RThread thread; |
|
170 TInt r; |
|
171 |
|
172 switch(aTestNum) |
|
173 { |
|
174 |
|
175 case ETestProcessResume: |
|
176 { |
|
177 r = thread.Open(aArg1); |
|
178 if(r==KErrNone) |
|
179 thread.Resume(); // Should panic us |
|
180 return r; |
|
181 } |
|
182 |
|
183 case ETestProcessSuspend: |
|
184 { |
|
185 r = thread.Open(aArg1); |
|
186 if(r==KErrNone) |
|
187 thread.Suspend(); // Should panic us |
|
188 return r; |
|
189 } |
|
190 |
|
191 case ETestProcessKill: |
|
192 { |
|
193 r = thread.Open(aArg1); |
|
194 if(r==KErrNone) |
|
195 thread.Kill(999); // Should panic us |
|
196 return r; |
|
197 } |
|
198 |
|
199 case ETestProcessTerminate: |
|
200 { |
|
201 r = thread.Open(aArg1); |
|
202 if(r==KErrNone) |
|
203 thread.Terminate(999); // Should panic us |
|
204 return r; |
|
205 } |
|
206 |
|
207 case ETestProcessPanic: |
|
208 { |
|
209 r = thread.Open(aArg1); |
|
210 if(r==KErrNone) |
|
211 thread.Panic(KTestPanicCategory,999); // Should panic us |
|
212 return r; |
|
213 } |
|
214 |
|
215 case ETestProcessSetPriority: |
|
216 { |
|
217 r = thread.Open(aArg1); |
|
218 if(r==KErrNone) |
|
219 thread.SetPriority((TThreadPriority)aArg2); |
|
220 return r; |
|
221 } |
|
222 |
|
223 case ETestProcessRequestComplete: |
|
224 { |
|
225 r = thread.Open(aArg1); |
|
226 if(r==KErrNone) |
|
227 { |
|
228 // use a local request status because Thread::RequestComplete is |
|
229 // implemented to write to it in our context |
|
230 TRequestStatus myStatus; |
|
231 TRequestStatus* status = &myStatus; |
|
232 thread.RequestComplete(status,KErrNone); |
|
233 } |
|
234 return r; |
|
235 } |
|
236 |
|
237 case ETestProcessRequestSignal: |
|
238 { |
|
239 r = thread.Open(aArg1); |
|
240 if(r==KErrNone) |
|
241 thread.RequestSignal(); |
|
242 return r; |
|
243 } |
|
244 |
|
245 case ETestProcessPriorityControlOn: |
|
246 User::SetPriorityControl(ETrue); |
|
247 // fall through... |
|
248 case ETestProcessPriorityControlOff: |
|
249 RProcess::Rendezvous(RThread().Id()); |
|
250 Wait(); |
|
251 return KErrNone; |
|
252 |
|
253 case ETestProcessSetPrioritiesWithoutProtServ: |
|
254 { |
|
255 RThread thread; |
|
256 TestSetNormalApplicationPriorities(thread); |
|
257 TestSetPriorityPanic(EPriorityAbsoluteRealTime1); |
|
258 TestSetPriorityPanic(EPriorityAbsoluteRealTime2); |
|
259 TestSetPriorityPanic(EPriorityAbsoluteRealTime3); |
|
260 TestSetPriorityPanic(EPriorityAbsoluteRealTime4); |
|
261 TestSetPriorityPanic(EPriorityAbsoluteRealTime5); |
|
262 TestSetPriorityPanic(EPriorityAbsoluteRealTime6); |
|
263 TestSetPriorityPanic(EPriorityAbsoluteRealTime7); |
|
264 TestSetPriorityPanic(EPriorityAbsoluteRealTime8); |
|
265 return KErrNone; |
|
266 } |
|
267 |
|
268 case ETestProcessSetPrioritiesWithProtServ: |
|
269 { |
|
270 RThread thread; |
|
271 TestSetNormalApplicationPriorities(thread); |
|
272 TestSetPrioritySuccess(EPriorityAbsoluteRealTime1); |
|
273 TestSetPrioritySuccess(EPriorityAbsoluteRealTime2); |
|
274 TestSetPrioritySuccess(EPriorityAbsoluteRealTime3); |
|
275 TestSetPrioritySuccess(EPriorityAbsoluteRealTime4); |
|
276 TestSetPrioritySuccess(EPriorityAbsoluteRealTime5); |
|
277 TestSetPrioritySuccess(EPriorityAbsoluteRealTime6); |
|
278 TestSetPrioritySuccess(EPriorityAbsoluteRealTime7); |
|
279 TestSetPrioritySuccess(EPriorityAbsoluteRealTime8); |
|
280 return KErrNone; |
|
281 } |
|
282 |
|
283 default: |
|
284 User::Panic(_L("T_STHREAD"),1); |
|
285 } |
|
286 |
|
287 return KErrNone; |
|
288 } |
|
289 |
|
290 |
|
291 |
|
292 void TestThreadForPlatformSecurityTrap(TThreadFunction aFunction) |
|
293 { |
|
294 TBool jit = User::JustInTime(); |
|
295 TRequestStatus logonStatus; |
|
296 RTestThread thread; |
|
297 thread.Create(aFunction,(TAny*)(TUint)RThread().Id()); |
|
298 thread.Logon(logonStatus); |
|
299 User::SetJustInTime(EFalse); |
|
300 thread.Resume(); |
|
301 User::WaitForRequest(logonStatus); |
|
302 User::SetJustInTime(jit); |
|
303 test(thread.ExitType()==EExitPanic); |
|
304 test(logonStatus==EPlatformSecurityTrap); |
|
305 CLOSE_AND_WAIT(thread); |
|
306 } |
|
307 |
|
308 |
|
309 void TestProcessForPlatformSecurityTrap(TTestProcessFunctions aFunction) |
|
310 { |
|
311 TRequestStatus logonStatus2; |
|
312 RTestProcess process; |
|
313 process.Create(~0u,aFunction,RThread().Id(),EPriorityAbsoluteLow); |
|
314 process.Logon(logonStatus2); |
|
315 process.Resume(); |
|
316 User::WaitForRequest(logonStatus2); |
|
317 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
318 test(logonStatus2==EPlatformSecurityTrap); |
|
319 CLOSE_AND_WAIT(process); |
|
320 } |
|
321 |
|
322 |
|
323 void TestRename() |
|
324 { |
|
325 TName name; |
|
326 |
|
327 test.Start(_L("Renaming the current thread")); |
|
328 name = RThread().Name(); |
|
329 name.SetLength(KTestThreadName().Length()); |
|
330 test(name.CompareF(KTestThreadName)!=0); |
|
331 User::RenameThread(KTestThreadName); |
|
332 name = RThread().Name(); |
|
333 name.SetLength(KTestThreadName().Length()); |
|
334 test(name.CompareF(KTestThreadName)==0); |
|
335 |
|
336 |
|
337 test.End(); |
|
338 } |
|
339 |
|
340 |
|
341 |
|
342 void TestResume() |
|
343 { |
|
344 RTestProcess process; |
|
345 RTestThread thread; |
|
346 TRequestStatus logonStatus; |
|
347 TInt testCount = TestThreadCount; |
|
348 |
|
349 test.Start(_L("Try to get another process to resume one we've created")); |
|
350 thread.Create(TestThreadNull); |
|
351 process.Create(~0u,ETestProcessResume,thread.Id()); |
|
352 process.Logon(logonStatus); |
|
353 process.Resume(); |
|
354 User::WaitForRequest(logonStatus); |
|
355 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
356 test(logonStatus==EPlatformSecurityTrap); |
|
357 User::After(1000000); // Give time for thread to run (if it had been resumed)... |
|
358 test(TestThreadCount==testCount); // it shouldn't have, so count will be unchanged. |
|
359 |
|
360 test.Next(_L("Test resuming a thread we've created")); |
|
361 thread.Logon(logonStatus); |
|
362 test(logonStatus==KRequestPending); |
|
363 thread.Resume(); |
|
364 User::WaitForRequest(logonStatus); |
|
365 test(logonStatus==KErrNone); |
|
366 test(TestThreadCount==testCount+1); // Thread should have run and incremented the count |
|
367 CLOSE_AND_WAIT(thread); |
|
368 CLOSE_AND_WAIT(process); |
|
369 |
|
370 test.End(); |
|
371 } |
|
372 |
|
373 |
|
374 |
|
375 TInt TestThreadCounting(TAny*) |
|
376 { |
|
377 RThread().SetPriority(EPriorityAbsoluteVeryLow); |
|
378 for(;;) |
|
379 ++TestThreadCount; |
|
380 } |
|
381 |
|
382 TBool IsTestThreadRunning() |
|
383 { |
|
384 // Thread should have been busy incrementing the count if it is running |
|
385 TInt testCount = TestThreadCount; |
|
386 User::After(100000); |
|
387 if(testCount!=TestThreadCount) |
|
388 return ETrue; |
|
389 User::After(1000000); |
|
390 return testCount!=TestThreadCount; |
|
391 } |
|
392 |
|
393 void TestSuspend() |
|
394 { |
|
395 RTestProcess process; |
|
396 RTestThread thread; |
|
397 TRequestStatus logonStatus; |
|
398 |
|
399 test.Start(_L("Creating a never ending thread...")); |
|
400 thread.Create(TestThreadCounting); |
|
401 thread.Resume(); |
|
402 test(IsTestThreadRunning()); // Thread should still be running |
|
403 |
|
404 test.Next(_L("Checking other process can't supspend it")); |
|
405 process.Create(~0u,ETestProcessSuspend,thread.Id()); |
|
406 process.Logon(logonStatus); |
|
407 process.Resume(); |
|
408 User::WaitForRequest(logonStatus); |
|
409 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
410 test(logonStatus==EPlatformSecurityTrap); |
|
411 test(IsTestThreadRunning()); // Thread should still be running |
|
412 |
|
413 test.Next(_L("Test suspending a thread in same process")); |
|
414 thread.Logon(logonStatus); |
|
415 thread.Suspend(); |
|
416 test(!IsTestThreadRunning()); // Thread should have stopped... |
|
417 test(logonStatus==KRequestPending); // but not have died |
|
418 thread.LogonCancel(logonStatus); |
|
419 User::WaitForRequest(logonStatus); |
|
420 |
|
421 test.Next(_L("Kill thread")); |
|
422 thread.Kill(0); |
|
423 CLOSE_AND_WAIT(thread); |
|
424 CLOSE_AND_WAIT(process); |
|
425 |
|
426 test.End(); |
|
427 } |
|
428 |
|
429 |
|
430 |
|
431 TInt TestThreadKillSelf(TAny* ) |
|
432 { |
|
433 RThread().Kill(999); |
|
434 return KErrGeneral; |
|
435 } |
|
436 |
|
437 TInt TestThreadTerminateSelf(TAny*) |
|
438 { |
|
439 RThread().Terminate(999); |
|
440 return KErrGeneral; |
|
441 } |
|
442 |
|
443 TInt TestThreadPanicSelf(TAny*) |
|
444 { |
|
445 RThread().Panic(KTestPanicCategory,999); |
|
446 return KErrGeneral; |
|
447 } |
|
448 |
|
449 void TestKill() |
|
450 { |
|
451 RTestProcess process; |
|
452 RTestThread thread; |
|
453 TRequestStatus logonStatus; |
|
454 TRequestStatus logonStatus2; |
|
455 TBool jit = User::JustInTime(); |
|
456 |
|
457 // Test RProcess::Kill() |
|
458 |
|
459 test.Start(_L("Test killing an un-resumed thread created by us")); |
|
460 thread.Create(TestThreadNull); |
|
461 thread.Logon(logonStatus); |
|
462 thread.Kill(999); |
|
463 User::WaitForRequest(logonStatus); |
|
464 test(thread.ExitType()==EExitKill); |
|
465 test(logonStatus==999); |
|
466 CLOSE_AND_WAIT(thread); |
|
467 |
|
468 test.Next(_L("Test killing a resumed thread created by us")); |
|
469 thread.Create(TestThreadNull); |
|
470 thread.Logon(logonStatus); |
|
471 SyncMutex.Wait(); |
|
472 thread.Resume(); |
|
473 thread.Kill(999); |
|
474 SyncMutex.Signal(); |
|
475 User::WaitForRequest(logonStatus); |
|
476 test(thread.ExitType()==EExitKill); |
|
477 test(logonStatus==999); |
|
478 CLOSE_AND_WAIT(thread); |
|
479 |
|
480 test.Next(_L("Try killing un-resumed thread not created by self")); |
|
481 thread.Create(TestThreadNull); |
|
482 process.Create(~0u,ETestProcessKill,thread.Id()); |
|
483 thread.Logon(logonStatus2); |
|
484 process.Logon(logonStatus); |
|
485 process.Resume(); |
|
486 User::WaitForRequest(logonStatus); |
|
487 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
488 test(logonStatus==EPlatformSecurityTrap); |
|
489 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
490 thread.Resume(); |
|
491 User::WaitForRequest(logonStatus2); |
|
492 test(logonStatus2==KErrNone); |
|
493 CLOSE_AND_WAIT(thread); |
|
494 CLOSE_AND_WAIT(process); |
|
495 |
|
496 test.Next(_L("Try killing resumed thread not created by self")); |
|
497 thread.Create(TestThreadNull); |
|
498 process.Create(~0u,ETestProcessKill,thread.Id()); |
|
499 thread.Logon(logonStatus2); |
|
500 process.Logon(logonStatus); |
|
501 SyncMutex.Wait(); |
|
502 thread.Resume(); |
|
503 process.Resume(); |
|
504 User::WaitForRequest(logonStatus); |
|
505 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
506 test(logonStatus==EPlatformSecurityTrap); |
|
507 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
508 SyncMutex.Signal(); |
|
509 User::WaitForRequest(logonStatus2); |
|
510 test(logonStatus2==KErrNone); |
|
511 CLOSE_AND_WAIT(thread); |
|
512 CLOSE_AND_WAIT(process); |
|
513 |
|
514 test.Next(_L("Test a thread killing itself")); |
|
515 thread.Create(TestThreadKillSelf); |
|
516 thread.Logon(logonStatus); |
|
517 thread.Resume(); |
|
518 User::WaitForRequest(logonStatus); |
|
519 test(thread.ExitType()==EExitKill); |
|
520 test(logonStatus==999); |
|
521 CLOSE_AND_WAIT(thread); |
|
522 |
|
523 // Test RProcess::Teminate() |
|
524 |
|
525 test.Next(_L("Test terminating an un-resumed thread created by us")); |
|
526 thread.Create(TestThreadNull); |
|
527 thread.Logon(logonStatus); |
|
528 thread.Terminate(999); |
|
529 User::WaitForRequest(logonStatus); |
|
530 test(thread.ExitType()==EExitTerminate); |
|
531 test(logonStatus==999); |
|
532 CLOSE_AND_WAIT(thread); |
|
533 |
|
534 test.Next(_L("Test terminating a resumed thread created by us")); |
|
535 thread.Create(TestThreadNull); |
|
536 thread.Logon(logonStatus); |
|
537 SyncMutex.Wait(); |
|
538 thread.Resume(); |
|
539 thread.Terminate(999); |
|
540 SyncMutex.Signal(); |
|
541 User::WaitForRequest(logonStatus); |
|
542 test(thread.ExitType()==EExitTerminate); |
|
543 test(logonStatus==999); |
|
544 CLOSE_AND_WAIT(thread); |
|
545 |
|
546 test.Next(_L("Try terminating un-resumed thread not created by self")); |
|
547 thread.Create(TestThreadNull); |
|
548 process.Create(~0u,ETestProcessTerminate,thread.Id()); |
|
549 thread.Logon(logonStatus2); |
|
550 process.Logon(logonStatus); |
|
551 process.Resume(); |
|
552 User::WaitForRequest(logonStatus); |
|
553 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
554 test(logonStatus==EPlatformSecurityTrap); |
|
555 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
556 thread.Resume(); |
|
557 User::WaitForRequest(logonStatus2); |
|
558 test(logonStatus2==KErrNone); |
|
559 CLOSE_AND_WAIT(thread); |
|
560 CLOSE_AND_WAIT(process); |
|
561 |
|
562 test.Next(_L("Try terminating resumed thread not created by self")); |
|
563 thread.Create(TestThreadNull); |
|
564 process.Create(~0u,ETestProcessTerminate,thread.Id()); |
|
565 thread.Logon(logonStatus2); |
|
566 process.Logon(logonStatus); |
|
567 SyncMutex.Wait(); |
|
568 thread.Resume(); |
|
569 process.Resume(); |
|
570 User::WaitForRequest(logonStatus); |
|
571 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
572 test(logonStatus==EPlatformSecurityTrap); |
|
573 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
574 SyncMutex.Signal(); |
|
575 User::WaitForRequest(logonStatus2); |
|
576 test(logonStatus2==KErrNone); |
|
577 CLOSE_AND_WAIT(thread); |
|
578 CLOSE_AND_WAIT(process); |
|
579 |
|
580 test.Next(_L("Test a thread terminating itself")); |
|
581 thread.Create(TestThreadTerminateSelf); |
|
582 thread.Logon(logonStatus); |
|
583 thread.Resume(); |
|
584 User::WaitForRequest(logonStatus); |
|
585 test(thread.ExitType()==EExitTerminate); |
|
586 test(logonStatus==999); |
|
587 CLOSE_AND_WAIT(thread); |
|
588 |
|
589 // Test RProcess::Panic() |
|
590 |
|
591 test.Next(_L("Test panicking an un-resumed thread created by us")); |
|
592 thread.Create(TestThreadNull); |
|
593 thread.Logon(logonStatus); |
|
594 User::SetJustInTime(EFalse); |
|
595 thread.Panic(KTestPanicCategory,999); |
|
596 User::WaitForRequest(logonStatus); |
|
597 User::SetJustInTime(jit); |
|
598 test(thread.ExitType()==EExitPanic); |
|
599 test(logonStatus==999); |
|
600 CLOSE_AND_WAIT(thread); |
|
601 |
|
602 test.Next(_L("Test panicking a resumed thread created by us")); |
|
603 thread.Create(TestThreadNull); |
|
604 thread.Logon(logonStatus); |
|
605 SyncMutex.Wait(); |
|
606 thread.Resume(); |
|
607 User::SetJustInTime(EFalse); |
|
608 thread.Panic(KTestPanicCategory,999); |
|
609 SyncMutex.Signal(); |
|
610 User::WaitForRequest(logonStatus); |
|
611 User::SetJustInTime(jit); |
|
612 test(thread.ExitType()==EExitPanic); |
|
613 test(logonStatus==999); |
|
614 CLOSE_AND_WAIT(thread); |
|
615 |
|
616 test.Next(_L("Try panicking un-resumed thread not created by self")); |
|
617 thread.Create(TestThreadNull); |
|
618 process.Create(~0u,ETestProcessPanic,thread.Id()); |
|
619 thread.Logon(logonStatus2); |
|
620 process.Logon(logonStatus); |
|
621 process.Resume(); |
|
622 User::WaitForRequest(logonStatus); |
|
623 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
624 test(logonStatus==EPlatformSecurityTrap); |
|
625 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
626 thread.Resume(); |
|
627 User::WaitForRequest(logonStatus2); |
|
628 test(logonStatus2==KErrNone); |
|
629 CLOSE_AND_WAIT(thread); |
|
630 CLOSE_AND_WAIT(process); |
|
631 |
|
632 test.Next(_L("Try panicking resumed thread not created by self")); |
|
633 thread.Create(TestThreadNull); |
|
634 process.Create(~0u,ETestProcessPanic,thread.Id()); |
|
635 thread.Logon(logonStatus2); |
|
636 process.Logon(logonStatus); |
|
637 SyncMutex.Wait(); |
|
638 thread.Resume(); |
|
639 process.Resume(); |
|
640 User::WaitForRequest(logonStatus); |
|
641 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
642 test(logonStatus==EPlatformSecurityTrap); |
|
643 test(logonStatus2==KRequestPending); // the thread should still be alive |
|
644 SyncMutex.Signal(); |
|
645 User::WaitForRequest(logonStatus2); |
|
646 test(logonStatus2==KErrNone); |
|
647 CLOSE_AND_WAIT(thread); |
|
648 CLOSE_AND_WAIT(process); |
|
649 |
|
650 test.Next(_L("Test a thread panicking itself")); |
|
651 thread.Create(TestThreadPanicSelf); |
|
652 thread.Logon(logonStatus); |
|
653 User::SetJustInTime(EFalse); |
|
654 thread.Resume(); |
|
655 User::WaitForRequest(logonStatus); |
|
656 User::SetJustInTime(jit); |
|
657 test(thread.ExitType()==EExitPanic); |
|
658 test(logonStatus==999); |
|
659 CLOSE_AND_WAIT(thread); |
|
660 |
|
661 // |
|
662 |
|
663 test.End(); |
|
664 } |
|
665 |
|
666 |
|
667 //--------------------------------------------- |
|
668 //! @SYMTestCaseID KBASE-T_STHREAD-0120 |
|
669 //! @SYMTestCaseDesc Set thread priority |
|
670 //! @SYMTestType UT |
|
671 //! @SYMREQ historical, enhanced under PREQ955 |
|
672 //! @SYMTestActions Test setting all thread priority values to threads in this process, |
|
673 //! and in another process, resumed and not. |
|
674 //! @SYMTestExpectedResults Confirm can set and get "normal application" thread priorities |
|
675 //! for threads in this process, whether resumed or not. Confirm thread is panicked |
|
676 //! if attempts to set priority of thread in another process. Confirm can set and get |
|
677 //! "real-time" thread priorities if this process has ProtServ capability, and that |
|
678 //! calling thread is panicked if not. |
|
679 //! @SYMTestPriority Critical |
|
680 //! @SYMTestStatus Implemented |
|
681 //--------------------------------------------- |
|
682 void TestSetPriority() |
|
683 { |
|
684 RTestThread thread; |
|
685 RTestProcess process; |
|
686 TRequestStatus logonStatus; |
|
687 TRequestStatus logonStatus2; |
|
688 |
|
689 test.Start(_L("Test changing our own threads priority")); |
|
690 TestSetNormalApplicationPriorities(thread); |
|
691 |
|
692 test.Next(_L("Test changing priority of un-resumed thread in our process")); |
|
693 thread.Create(TestThreadNull); |
|
694 thread.Logon(logonStatus); |
|
695 TestSetNormalApplicationPriorities(thread); |
|
696 |
|
697 test.Next(_L("Test changing priority of resumed thread in our process")); |
|
698 SyncMutex.Wait(); |
|
699 thread.Resume(); |
|
700 TestSetNormalApplicationPriorities(thread); |
|
701 SyncMutex.Signal(); |
|
702 User::WaitForRequest(logonStatus); |
|
703 test(logonStatus==KErrNone); |
|
704 CLOSE_AND_WAIT(thread); |
|
705 |
|
706 test.Next(_L("Try changing priority of an un-resumed thread in other process")); |
|
707 thread.Create(TestThreadNull); |
|
708 thread.Logon(logonStatus); |
|
709 thread.SetPriority(EPriorityAbsoluteHigh); |
|
710 process.Create(~0u,ETestProcessSetPriority,thread.Id(),EPriorityAbsoluteLow); |
|
711 process.Logon(logonStatus2); |
|
712 process.Resume(); |
|
713 User::WaitForRequest(logonStatus2); |
|
714 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
715 test(logonStatus2==EPlatformSecurityTrap); |
|
716 test(thread.Priority()==EPriorityAbsoluteHigh); // Priority should be unaltered |
|
717 |
|
718 test.Next(_L("Try changing priority of a resumed thread in other process")); |
|
719 process.Create(~0u,ETestProcessSetPriority,thread.Id(),EPriorityAbsoluteLow); |
|
720 process.Logon(logonStatus2); |
|
721 SyncMutex.Wait(); |
|
722 thread.Resume(); |
|
723 process.Resume(); |
|
724 User::WaitForRequest(logonStatus2); |
|
725 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
726 test(logonStatus2==EPlatformSecurityTrap); |
|
727 test(thread.Priority()==EPriorityAbsoluteHigh); // Priority should be unaltered |
|
728 SyncMutex.Signal(); |
|
729 User::WaitForRequest(logonStatus); |
|
730 test(logonStatus==KErrNone); |
|
731 CLOSE_AND_WAIT(thread); |
|
732 |
|
733 test.Next(_L("Test setting thread priorities without ECapabilityProtServ")); |
|
734 process.Create(~(1u<<ECapabilityProtServ), ETestProcessSetPrioritiesWithoutProtServ); |
|
735 process.Run(); |
|
736 |
|
737 test.Next(_L("Test setting thread priorities with ECapabilityProtServ")); |
|
738 process.Create(1<<ECapabilityProtServ, ETestProcessSetPrioritiesWithProtServ); |
|
739 process.Run(); |
|
740 |
|
741 test.End(); |
|
742 } |
|
743 |
|
744 |
|
745 TRequestStatus TestRequest; |
|
746 |
|
747 TInt TestThreadRequestComplete(TAny* aArg) |
|
748 { |
|
749 RThread thread; |
|
750 TInt r = thread.Open((TInt)aArg); |
|
751 if(r==KErrNone) |
|
752 { |
|
753 TRequestStatus* status = &TestRequest; |
|
754 thread.RequestComplete(status,KErrNone); |
|
755 } |
|
756 return r; |
|
757 } |
|
758 |
|
759 void TestRequestComplete() |
|
760 { |
|
761 RTestThread thread; |
|
762 RTestProcess process; |
|
763 TRequestStatus logonStatus; |
|
764 |
|
765 test.Start(_L("Test RequestComplete on thread in current process")); |
|
766 TestRequest = KRequestPending; |
|
767 thread.Create(TestThreadRequestComplete,(TAny*)(TUint)RThread().Id()); |
|
768 thread.Logon(logonStatus); |
|
769 thread.Resume(); |
|
770 User::WaitForRequest(TestRequest); |
|
771 test(TestRequest==KErrNone); |
|
772 User::WaitForRequest(logonStatus); |
|
773 test(logonStatus==KErrNone); |
|
774 CLOSE_AND_WAIT(thread); |
|
775 |
|
776 test.Next(_L("Test RequestComplete on with NULL request pointer")); |
|
777 test(RThread().RequestCount()==0); // No signals |
|
778 TRequestStatus* nullReq = 0; |
|
779 RThread().RequestComplete(nullReq,0); |
|
780 test(RThread().RequestCount()==0); // No signals |
|
781 |
|
782 test.Next(_L("Test RequestComplete on thread in different process")); |
|
783 TestRequest = KRequestPending; |
|
784 process.Create(~0u,ETestProcessRequestComplete,RThread().Id(),(TInt)&TestRequest); |
|
785 process.Logon(logonStatus); |
|
786 process.Resume(); |
|
787 User::WaitForRequest(logonStatus); |
|
788 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
789 test(logonStatus==EPlatformSecurityTrap); |
|
790 test(TestRequest==KRequestPending); |
|
791 CLOSE_AND_WAIT(process); |
|
792 |
|
793 test.End(); |
|
794 } |
|
795 |
|
796 |
|
797 |
|
798 TInt TestThreadRequestSignal(TAny* aArg) |
|
799 { |
|
800 RThread thread; |
|
801 TInt r = thread.Open((TInt)aArg); |
|
802 if(r==KErrNone) |
|
803 thread.RequestSignal(); |
|
804 return r; |
|
805 } |
|
806 |
|
807 void TestRequestSignal() |
|
808 { |
|
809 RTestThread thread; |
|
810 RTestProcess process; |
|
811 TRequestStatus logonStatus; |
|
812 TInt count; |
|
813 |
|
814 test.Start(_L("Test RequestSignal on thread in current process")); |
|
815 thread.Create(TestThreadRequestSignal,(TAny*)(TUint)RThread().Id()); |
|
816 thread.Logon(logonStatus); |
|
817 count = RThread().RequestCount(); |
|
818 test(count==0); // No signals yet |
|
819 thread.Resume(); |
|
820 User::WaitForRequest(logonStatus); |
|
821 test(logonStatus==KErrNone); |
|
822 count = RThread().RequestCount(); |
|
823 test(count==1); // We should have been signalled |
|
824 User::WaitForAnyRequest(); // eat signal |
|
825 CLOSE_AND_WAIT(thread); |
|
826 |
|
827 test.Next(_L("Test RequestSignal on thread in different process")); |
|
828 process.Create(~0u,ETestProcessRequestSignal,RThread().Id(),0); |
|
829 process.Logon(logonStatus); |
|
830 process.Resume(); |
|
831 User::WaitForRequest(logonStatus); |
|
832 test(process.ExitType()==EExitPanic); // Process should have got a Platform Security panic |
|
833 test(logonStatus==EPlatformSecurityTrap); |
|
834 count = RThread().RequestCount(); |
|
835 test(count==0); // We shouldn't have been signalled |
|
836 CLOSE_AND_WAIT(process); |
|
837 |
|
838 test.End(); |
|
839 } |
|
840 |
|
841 |
|
842 |
|
843 void TestSetProcessPriority() |
|
844 { |
|
845 RTestThread thread; |
|
846 RTestProcess process; |
|
847 TProcessPriority priority; |
|
848 TRequestStatus rendezvousStatus; |
|
849 TRequestStatus logonStatus; |
|
850 TInt r; |
|
851 |
|
852 test.Start(_L("Test changing our own process priority")); |
|
853 priority = process.Priority(); |
|
854 thread.SetProcessPriority(EPriorityLow); |
|
855 test(process.Priority()==EPriorityLow); |
|
856 thread.SetProcessPriority(EPriorityBackground); |
|
857 test(process.Priority()==EPriorityBackground); |
|
858 thread.SetProcessPriority(EPriorityForeground); |
|
859 test(process.Priority()==EPriorityForeground); |
|
860 thread.SetProcessPriority(priority); |
|
861 |
|
862 test.Next(_L("Try changing other process's priority (no priority-control enabled)")); |
|
863 process.Create(~0u,ETestProcessPriorityControlOff); |
|
864 process.Rendezvous(rendezvousStatus); |
|
865 process.Logon(logonStatus); |
|
866 SyncMutex.Wait(); |
|
867 process.Resume(); |
|
868 User::WaitForRequest(rendezvousStatus); // Process has started |
|
869 r = thread.Open(rendezvousStatus.Int()); // Process returned Id of main thread as status value |
|
870 test(r==KErrNone); |
|
871 priority = process.Priority(); |
|
872 thread.SetProcessPriority(EPriorityLow); |
|
873 test(process.Priority()==priority); // priority shouldn't have changed |
|
874 thread.SetProcessPriority(EPriorityBackground); |
|
875 test(process.Priority()==priority); // priority shouldn't have changed |
|
876 thread.SetProcessPriority(EPriorityForeground); |
|
877 test(process.Priority()==priority); // priority shouldn't have changed |
|
878 test(logonStatus==KRequestPending); // wait for process to end |
|
879 SyncMutex.Signal(); |
|
880 User::WaitForRequest(logonStatus); |
|
881 CLOSE_AND_WAIT(thread); |
|
882 CLOSE_AND_WAIT(process); |
|
883 |
|
884 test.Next(_L("Try changing other process's priority (priority-control enabled)")); |
|
885 process.Create(~0u,ETestProcessPriorityControlOn); |
|
886 process.Rendezvous(rendezvousStatus); |
|
887 process.Logon(logonStatus); |
|
888 SyncMutex.Wait(); |
|
889 process.Resume(); |
|
890 User::WaitForRequest(rendezvousStatus); // Process has started |
|
891 r = thread.Open(rendezvousStatus.Int()); // Process returned Id of main thread as status value |
|
892 test(r==KErrNone); |
|
893 priority = process.Priority(); |
|
894 thread.SetProcessPriority(EPriorityForeground); |
|
895 test(process.Priority()==EPriorityForeground); |
|
896 thread.SetProcessPriority(EPriorityBackground); |
|
897 test(process.Priority()==EPriorityBackground); |
|
898 thread.SetProcessPriority(EPriorityForeground); |
|
899 test(process.Priority()==EPriorityForeground); |
|
900 thread.SetProcessPriority(EPriorityLow); |
|
901 test(process.Priority()==EPriorityForeground); // should still be foreground priority |
|
902 thread.SetProcessPriority(priority); |
|
903 test(logonStatus==KRequestPending); // wait for process to end |
|
904 SyncMutex.Signal(); |
|
905 User::WaitForRequest(logonStatus); |
|
906 CLOSE_AND_WAIT(thread); |
|
907 CLOSE_AND_WAIT(process); |
|
908 |
|
909 test.End(); |
|
910 } |
|
911 |
|
912 |
|
913 |
|
914 GLDEF_C TInt E32Main() |
|
915 { |
|
916 TBuf16<512> cmd; |
|
917 User::CommandLine(cmd); |
|
918 if(cmd.Length() && TChar(cmd[0]).IsDigit()) |
|
919 { |
|
920 TInt function = -1; |
|
921 TInt arg1 = -1; |
|
922 TInt arg2 = -1; |
|
923 TLex lex(cmd); |
|
924 |
|
925 lex.Val(function); |
|
926 lex.SkipSpace(); |
|
927 lex.Val(arg1); |
|
928 lex.SkipSpace(); |
|
929 lex.Val(arg2); |
|
930 return DoTestProcess(function,arg1,arg2); |
|
931 } |
|
932 |
|
933 test.Title(); |
|
934 |
|
935 if((!PlatSec::ConfigSetting(PlatSec::EPlatSecProcessIsolation))||(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement))) |
|
936 { |
|
937 test.Start(_L("TESTS NOT RUN - PlatSecProcessIsolation is not enforced")); |
|
938 test.End(); |
|
939 return 0; |
|
940 } |
|
941 |
|
942 test(SyncMutex.CreateGlobal(KSyncMutex)==KErrNone); |
|
943 |
|
944 test.Start(_L("Test Rename")); |
|
945 TestRename(); |
|
946 |
|
947 test.Next(_L("Test Resume")); |
|
948 TestResume(); |
|
949 |
|
950 test.Next(_L("Test Suspend")); |
|
951 TestSuspend(); |
|
952 |
|
953 test.Next(_L("Test Kill, Panic and Teminate")); |
|
954 TestKill(); |
|
955 |
|
956 test.Next(_L("Test SetPriority")); |
|
957 TestSetPriority(); |
|
958 |
|
959 test.Next(_L("Test RequestComplete")); |
|
960 TestRequestComplete(); |
|
961 |
|
962 test.Next(_L("Test RequestSignal")); |
|
963 TestRequestSignal(); |
|
964 |
|
965 test.Next(_L("Test SetProcessPriority")); |
|
966 TestSetProcessPriority(); |
|
967 |
|
968 |
|
969 SyncMutex.Close(); |
|
970 test.End(); |
|
971 |
|
972 return(0); |
|
973 } |
|
974 |