|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Exercises the test implementation of the session count server, |
|
16 * to test the base SCS functionality. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 /** |
|
22 @file |
|
23 */ |
|
24 |
|
25 #include <e32ldr.h> |
|
26 #include <f32file.h> |
|
27 #include <scs/rtestwrapper.h> |
|
28 |
|
29 #include <scs/scscommon.h> |
|
30 #include "scstestcommon.h" |
|
31 #include "scstestclient.h" |
|
32 |
|
33 const TInt KOneSecondUs = 1000 * 1000; ///< One second in microseconds. |
|
34 |
|
35 /** Top-level test object renders stages and confirms conditions. */ |
|
36 static RTestWrapper test(_L("SCSTEST")); |
|
37 |
|
38 /** |
|
39 This session handle is defined at the file level so each individual test |
|
40 does not have to connect to the server. |
|
41 */ |
|
42 static RScsTestSession sTestSession; |
|
43 /** |
|
44 This subsession handle is defined at the file level so each individual test |
|
45 does not have to connect to the server and create a subssesion. |
|
46 */ |
|
47 static RScsTestSubsession sTestSubsession; |
|
48 |
|
49 /** Arbitrary integer value used to construct subsession. */ |
|
50 static const TInt KSubsessValue = 10; |
|
51 |
|
52 static void LetServerRun() |
|
53 /** |
|
54 Sleep for 100ms so the server thread can run to clean up, |
|
55 terminate, or just process the last request which it was sent. |
|
56 */ |
|
57 { |
|
58 User::After(100 * 1000); |
|
59 } |
|
60 |
|
61 // -------- OOM testing -------- |
|
62 |
|
63 static void RunOomTest(TInt (*aAllocFunc)(), void (*aFreeFunc)()) |
|
64 /** |
|
65 Run the supplied allocator function while forcing OOM on the server side. |
|
66 On failure, this functions tests that the server heap is balanced. On |
|
67 success, it runs the free function and also tests that the server heap is |
|
68 balanced. |
|
69 |
|
70 @param aAllocFunc Function which allocates resources on the server heap. |
|
71 @param aFreeFunc Frees the resources allocated with aAllocFunc. It should |
|
72 only be necessary to call this function if aAllocFunc |
|
73 succeeds. This argument can be NULL if there is no |
|
74 corresponding free function. |
|
75 */ |
|
76 { |
|
77 TInt r = KErrNoMemory; |
|
78 |
|
79 for (TInt i = 1; r == KErrNoMemory; ++i) |
|
80 { |
|
81 sTestSession.SetServerHeapFail(i); |
|
82 |
|
83 r = aAllocFunc(); |
|
84 |
|
85 test(r == KErrNone || r == KErrNoMemory); |
|
86 if (r == KErrNone && aFreeFunc != NULL) |
|
87 aFreeFunc(); |
|
88 |
|
89 sTestSession.ResetServerHeapFail(); |
|
90 } |
|
91 } |
|
92 |
|
93 // -------- panic testing -------- |
|
94 |
|
95 /** |
|
96 To test that a client is panicked, pass a function with this |
|
97 signature to TestPanic. It will be called from a new thread. |
|
98 |
|
99 @see TestPanic |
|
100 */ |
|
101 typedef void (*TPanicFunc)(RScsTestSession&); |
|
102 |
|
103 static void ConfirmPanicReason(RThread aThread, TInt aExpectedReason) |
|
104 /** |
|
105 Test the supplied thread was panicked with category |
|
106 ScsImpl::KScsClientPanicCat and the supplied reason. |
|
107 |
|
108 @param aThread Panicked thread. |
|
109 @param aExpectedReason The thread should have been panicked with |
|
110 this reason. |
|
111 @see ScsImpl::KScsClientPanicCat |
|
112 */ |
|
113 { |
|
114 TExitType exitType = aThread.ExitType(); |
|
115 TExitCategoryName exitCat = aThread.ExitCategory(); |
|
116 TInt exitReason = aThread.ExitReason(); |
|
117 |
|
118 test(exitType == EExitPanic); |
|
119 test(exitCat == ScsImpl::KScsClientPanicCat); |
|
120 test(exitReason == aExpectedReason); |
|
121 } |
|
122 |
|
123 static TInt TestPanicEntrypoint(TAny* aPtr) |
|
124 /** |
|
125 This entrypoint is called by the panic thread. The |
|
126 function connects to the SCS test server and passes |
|
127 the handle to the function that should be panicked. |
|
128 |
|
129 @param aPtr Standard entrypoint argument. This is actually |
|
130 a pointer to the function to call with the connected |
|
131 session. |
|
132 @return KErrNone. Required to satisfy entrypoint signature. |
|
133 */ |
|
134 { |
|
135 RScsTestSession s; |
|
136 TInt r = s.Connect(); |
|
137 test(r == KErrNone); |
|
138 |
|
139 TPanicFunc f = TAnyPtrToFuncPtr<TPanicFunc>(aPtr); |
|
140 f(s); |
|
141 |
|
142 test(EFalse); // should not reach here |
|
143 return KErrNone; |
|
144 } |
|
145 |
|
146 static void TestPanic(TPanicFunc aFunc, TInt aExpectedReason) |
|
147 /** |
|
148 Create a thread which should be panicked because it will |
|
149 pass invalid data to the SCS test server. Test the thread |
|
150 is panicked with the expected category and reason. |
|
151 |
|
152 @param aFunc Function to call from panic thread. |
|
153 @param aExpectedReason Reason with which the thread should |
|
154 be panicked. |
|
155 */ |
|
156 { |
|
157 RThread thd; |
|
158 TInt r = thd.Create( |
|
159 _L("ScsTestPanic"), TestPanicEntrypoint, |
|
160 KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*) aFunc); |
|
161 test(r == KErrNone); |
|
162 |
|
163 TRequestStatus rs; |
|
164 thd.Rendezvous(rs); |
|
165 test(rs == KRequestPending); |
|
166 TBool jit = User::JustInTime(); |
|
167 User::SetJustInTime(EFalse); |
|
168 thd.Resume(); |
|
169 |
|
170 User::WaitForRequest(rs); |
|
171 User::SetJustInTime(jit); |
|
172 ConfirmPanicReason(thd, aExpectedReason); |
|
173 thd.Close(); |
|
174 } |
|
175 |
|
176 // -------- open / close -------- |
|
177 |
|
178 /** Handle to a session which the test code attempts to open in server-side OOM. */ |
|
179 RScsTestSession sOomTestSession; |
|
180 |
|
181 static TInt OpenOomSession() |
|
182 /** |
|
183 This function is invoked by RunOomTest. It just |
|
184 attempts to connect to the SCS test server. |
|
185 |
|
186 @return Return code from RScsTestSession::Connect. |
|
187 @see CloseOomSession |
|
188 */ |
|
189 { |
|
190 return sOomTestSession.Connect(); |
|
191 } |
|
192 |
|
193 static void CloseOomSession() |
|
194 /** |
|
195 Closes the session which was opened by OpenOomSession. |
|
196 |
|
197 @see OpenOomSession |
|
198 @pre OpenOomSession was successfully opened by OpenOomSession. |
|
199 */ |
|
200 { |
|
201 sOomTestSession.Close(); |
|
202 } |
|
203 |
|
204 static void TestServerDeath() |
|
205 { |
|
206 test.Start(_L("TestServerDeath")); |
|
207 |
|
208 test.Next(_L("Starting server without shutdown timer")); |
|
209 // Create marker file to get server to run without a activity timeout |
|
210 RFs fs; |
|
211 TInt r = fs.Connect(); |
|
212 test(r == KErrNone); |
|
213 (void) fs.Delete(KDisableScsTestServerTimeout()); |
|
214 |
|
215 RFile file; |
|
216 r = file.Create(fs, KDisableScsTestServerTimeout(), EFileShareAny|EFileWrite); |
|
217 test(r == KErrNone); |
|
218 file.Close(); |
|
219 |
|
220 // Start server |
|
221 RScsTestSession scsts; |
|
222 r = scsts.Connect(); |
|
223 test(r == KErrNone); |
|
224 |
|
225 test.Next(_L("Checking ShutdownServer is not allowed")); |
|
226 r = scsts.ShutdownServer(); |
|
227 test(r == KErrNotSupported); |
|
228 |
|
229 |
|
230 test.Next(_L("Doing an async call to check server does not attempt to restart the timer and crash")); |
|
231 TPckgBuf<TInt> x1 = 1; |
|
232 TRequestStatus rs1; |
|
233 scsts.Treble(x1, rs1); |
|
234 User::WaitForRequest(rs1); |
|
235 |
|
236 test.Printf(_L("NukeServer - scstestserver.exe SHOULD panic\n")); |
|
237 r = scsts.NukeServer(); |
|
238 test(r == KErrServerTerminated); |
|
239 |
|
240 |
|
241 (void) fs.Delete(KDisableScsTestServerTimeout()); |
|
242 fs.Close(); |
|
243 scsts.Close(); |
|
244 test.End(); |
|
245 } |
|
246 |
|
247 static void TestOpenClose() |
|
248 /** |
|
249 Attempt to connect to the server when supplying default, |
|
250 lower, and higher version numbers. Attempt to open a session |
|
251 in server-side OOM. |
|
252 */ |
|
253 { |
|
254 test.Start(_L("TestOpenClose")); |
|
255 |
|
256 TInt r; |
|
257 RScsTestSession scsts; |
|
258 |
|
259 // default version |
|
260 r = scsts.Connect(); |
|
261 test(r == KErrNone); |
|
262 scsts.Close(); |
|
263 |
|
264 // lower-than-supported version |
|
265 TVersion v = ScsTestImpl::Version(); |
|
266 --v.iMajor; |
|
267 r = scsts.Connect(v); |
|
268 test(r == KErrNone); |
|
269 scsts.Close(); |
|
270 |
|
271 // supported version (should be same as default) |
|
272 ++v.iMajor; |
|
273 r = scsts.Connect(v); |
|
274 test(r == KErrNone); |
|
275 scsts.Close(); |
|
276 |
|
277 // greater-than-supported version |
|
278 ++v.iMajor; |
|
279 r = scsts.Connect(v); |
|
280 test(r == KErrNotSupported); |
|
281 |
|
282 // test opening session when server running out of memory |
|
283 r = sTestSession.Connect(); // required to send OOM commands |
|
284 test(r == KErrNone); |
|
285 |
|
286 RunOomTest(OpenOomSession, CloseOomSession); |
|
287 |
|
288 sTestSession.Close(); |
|
289 |
|
290 #if 0 |
|
291 // Test closing server with an out standing request |
|
292 r = scsts.Connect(); |
|
293 test(r == KErrNone); |
|
294 test(r == KErrNone); |
|
295 TPckgBuf<TInt> x1 = 1; |
|
296 TRequestStatus rs1; |
|
297 scsts.Treble(x1, rs1); |
|
298 // Bypass the presession close |
|
299 RSessionBase *session = &scsts; |
|
300 session->Close(); |
|
301 User::WaitForRequest(rs1); |
|
302 test(rs1 == KErrCancel); |
|
303 #endif |
|
304 |
|
305 test.End(); |
|
306 } |
|
307 |
|
308 // -------- invalid session function -------- |
|
309 |
|
310 static void TestInvalidSessionFunction() |
|
311 /** |
|
312 Send an unrecognized SCS code and confirm that it is |
|
313 rejected with KErrNotSupported. This tests the SCS |
|
314 implementation. |
|
315 |
|
316 Send an unrecognized function identifier to the session |
|
317 and confirm that it is also rejected with KErrNotSupported. |
|
318 This tests the test server session implementation. |
|
319 */ |
|
320 { |
|
321 test.Start(_L("TestInvalidSessionFunction")); |
|
322 |
|
323 TInt r; |
|
324 |
|
325 r = sTestSession.SendCustomFunction(ScsImpl::EScsUnused); |
|
326 test(r == KErrNotSupported); |
|
327 |
|
328 r = sTestSession.SendCustomFunction(ScsImpl::ECallSessionFunc | ScsTestImpl::ESessUnused); |
|
329 test(r == KErrNotSupported); |
|
330 |
|
331 test.End(); |
|
332 } |
|
333 |
|
334 // -------- synchronous session function -------- |
|
335 |
|
336 static void TestSyncSessionFunction() |
|
337 /** |
|
338 Send a recognized function to the SCS test session, |
|
339 and confirm that it is executed correctly. |
|
340 */ |
|
341 { |
|
342 test.Start(_L("TestSyncSessionFunction")); |
|
343 |
|
344 TInt x = 3; |
|
345 TInt r = sTestSession.Double(x); |
|
346 test(r == KErrNone); |
|
347 test(x == 6); |
|
348 |
|
349 test.End(); |
|
350 } |
|
351 |
|
352 // -------- asynchronous session function -------- |
|
353 |
|
354 static TInt LaunchSessionTrebleOom() |
|
355 /** |
|
356 Attempt to launch an asynchronous command on a session |
|
357 under OOM conditions. |
|
358 */ |
|
359 { |
|
360 TPckgBuf<TInt> x = 3; |
|
361 TRequestStatus rs; |
|
362 sTestSession.Treble(x, rs); |
|
363 User::WaitForRequest(rs); |
|
364 |
|
365 if (rs == KErrNone) |
|
366 { |
|
367 test(x() == 9); |
|
368 } |
|
369 |
|
370 return rs.Int(); |
|
371 } |
|
372 |
|
373 static void TestAsyncInvalidDescPanic(RScsTestSession& aSession) |
|
374 /** |
|
375 Pass an invalid descriptor to the SCS test server. |
|
376 The current thread should be panicked. |
|
377 |
|
378 @param aSession Open session to SCS test server, |
|
379 supplied by TestPanic. |
|
380 @see TestPanic |
|
381 */ |
|
382 { |
|
383 TDes8* nullDes8 = 0; |
|
384 TRequestStatus rs; |
|
385 aSession.Treble(*nullDes8, rs); |
|
386 User::WaitForRequest(rs); |
|
387 } |
|
388 |
|
389 static void TestRequeueOutstandingPanic(RScsTestSession& aSession) |
|
390 /** |
|
391 Attempt to requeue an asynchronous request which is still |
|
392 outstanding. The current thread should be panicked. |
|
393 |
|
394 @param aSession Connected session to SCS test server. |
|
395 @see TestPanic |
|
396 */ |
|
397 { |
|
398 TPckgBuf<TInt> x1 = 1; |
|
399 TRequestStatus rs1; |
|
400 aSession.Treble(x1, rs1); |
|
401 |
|
402 TPckgBuf<TInt> x2 = 2; |
|
403 TRequestStatus rs2; |
|
404 aSession.Treble(x2, rs2); |
|
405 |
|
406 User::WaitForRequest(rs1, rs2); |
|
407 User::WaitForRequest(rs1, rs2); |
|
408 } |
|
409 |
|
410 static void TestAsyncSessionFunction() |
|
411 /** |
|
412 Test asynchronous session-relative functions. |
|
413 |
|
414 Launch a request and wait for it to complete. |
|
415 |
|
416 Launch a request and cancel it. |
|
417 |
|
418 Launch a request with an invalid descriptor. |
|
419 |
|
420 Cancel a request which is not outstanding. |
|
421 |
|
422 Launch a request in OOM. |
|
423 |
|
424 Launch an asynchronous request on a session and wait |
|
425 for it to complete. |
|
426 */ |
|
427 { |
|
428 test.Start(_L("TestAsyncSessionFunction")); |
|
429 |
|
430 TInt r; |
|
431 |
|
432 LaunchSessionTrebleOom(); |
|
433 |
|
434 // test launching async request in OOM |
|
435 RunOomTest(LaunchSessionTrebleOom, NULL); |
|
436 |
|
437 // cancel async request |
|
438 TPckgBuf<TInt> x = 3; |
|
439 TRequestStatus rs; |
|
440 sTestSession.Treble(x, rs); |
|
441 sTestSession.CancelTreble(); |
|
442 User::WaitForRequest(rs); |
|
443 test(rs == KErrCancel); |
|
444 |
|
445 // bad descriptor panic |
|
446 TestPanic(TestAsyncInvalidDescPanic, ScsImpl::EScsClBadDesc); |
|
447 |
|
448 // safely cancel async request which is not queued |
|
449 sTestSession.CancelTreble(); |
|
450 |
|
451 // panic if requeue outstanding request |
|
452 TestPanic(TestRequeueOutstandingPanic, ScsImpl::EScsClAsyncAlreadyQueued); |
|
453 |
|
454 // test outstanding request cancelled when session closed with RScsSessionBase::Close |
|
455 RScsTestSession asyncSession; |
|
456 r = asyncSession.Connect(); |
|
457 test(r == KErrNone); |
|
458 x() = 4; |
|
459 asyncSession.Treble(x, rs); |
|
460 asyncSession.Close(); |
|
461 User::After(ScsTestImpl::KTrebleTimerDelayUs + KOneSecondUs); |
|
462 test(rs == KErrCancel); |
|
463 User::WaitForRequest(rs); |
|
464 |
|
465 // test outstanding request not cancelled when session closed with RSessionBase::Close |
|
466 r = asyncSession.Connect(); |
|
467 test(r == KErrNone); |
|
468 x() = 4; |
|
469 asyncSession.Treble(x, rs); |
|
470 asyncSession.RSessionBase::Close(); |
|
471 User::After(ScsTestImpl::KTrebleTimerDelayUs + KOneSecondUs); |
|
472 test(rs == KRequestPending); // client request not cancelled or completed |
|
473 |
|
474 test.End(); |
|
475 } |
|
476 |
|
477 // -------- open / close subsession -------- |
|
478 |
|
479 /** |
|
480 This subsession handle is opened in OOM testing. |
|
481 |
|
482 @see OpenOomSubsession |
|
483 @see CloseOomSubsession |
|
484 */ |
|
485 RScsTestSubsession sOomSubsession; |
|
486 |
|
487 static TInt OpenOomSubsession() |
|
488 /** |
|
489 Attempt to open a subsession in OOM. |
|
490 |
|
491 @see CloseOomSubsession |
|
492 @see RunOomTest |
|
493 */ |
|
494 { |
|
495 return sOomSubsession.Create(sTestSession, 10); |
|
496 } |
|
497 |
|
498 static void CloseOomSubsession() |
|
499 /** |
|
500 Free the subsession which was opened in OOM. |
|
501 |
|
502 @see OpenOomSubsession |
|
503 @see RunOomTest |
|
504 */ |
|
505 { |
|
506 sOomSubsession.Close(); |
|
507 } |
|
508 |
|
509 static void TestOpenCloseSubsession() |
|
510 /** |
|
511 Test opening and closing a subsession, including |
|
512 opening in OOM. |
|
513 */ |
|
514 { |
|
515 test.Start(_L("TestOpenCloseSubsession")); |
|
516 |
|
517 TInt r; |
|
518 |
|
519 RScsTestSubsession ss; |
|
520 r = ss.Create(sTestSession, 10); |
|
521 test(r == KErrNone); |
|
522 ss.Close(); |
|
523 |
|
524 // test creating in OOM |
|
525 RunOomTest(OpenOomSubsession, CloseOomSubsession); |
|
526 |
|
527 test.End(); |
|
528 } |
|
529 |
|
530 // -------- invalid subsession function -------- |
|
531 |
|
532 static void TestInvalidSubsessionFunction() |
|
533 /** |
|
534 Pass an unrecognized function to a subession and test |
|
535 the subsession handles it properly. This tests the SCS |
|
536 test implementation, rather than the SCS itself. |
|
537 */ |
|
538 { |
|
539 test.Start(_L("TestInvalidSubsessionFunction")); |
|
540 |
|
541 TInt r = sTestSubsession.SendFunction(ScsTestImpl::ESubsessUnused); |
|
542 test(r == KErrNotSupported); |
|
543 |
|
544 test.End(); |
|
545 } |
|
546 |
|
547 // -------- synchronous subsession function -------- |
|
548 |
|
549 static void TestBadHandlePanic(RScsTestSession& aSession) |
|
550 /** |
|
551 Call a subsession function passing in an invalid handle. |
|
552 The current thread should be panicked. |
|
553 |
|
554 @param aSession Open session to SCS test server, |
|
555 supplied by TestPanic. |
|
556 @see TestPanic |
|
557 */ |
|
558 { |
|
559 RScsTestSubsession ss; |
|
560 TInt r = ss.Create(aSession, 10); |
|
561 test(r == KErrNone); |
|
562 |
|
563 // modify the subsession handle |
|
564 TUint8* addrOfHandle; |
|
565 addrOfHandle = (TUint8*)&ss; |
|
566 addrOfHandle += sizeof(RSessionBase); |
|
567 *((TInt*)addrOfHandle) ^= ~0; |
|
568 |
|
569 TInt x = 3; |
|
570 r = ss.Quadruple(x); // should be panicked with EScsClBadHandle |
|
571 } |
|
572 |
|
573 static void TestSyncSubsessionFunction() |
|
574 /** |
|
575 Call a synchronous function on a subsession. This ensures |
|
576 the request is routed to the subsession by the SCS. Also test |
|
577 the SCS correctly handles an invalid subsession handle. |
|
578 */ |
|
579 { |
|
580 test.Start(_L("TestSyncSubsessionFunction")); |
|
581 |
|
582 TInt x = -1; |
|
583 TInt r = sTestSubsession.Quadruple(x); |
|
584 test(r == KErrNone); |
|
585 test(x == 4 * KSubsessValue); |
|
586 |
|
587 TestPanic(TestBadHandlePanic, ScsImpl::EScsClBadHandle); |
|
588 |
|
589 test.End(); |
|
590 } |
|
591 |
|
592 // -------- asynchronous subsession function -------- |
|
593 |
|
594 static TInt LaunchSsTrebleOom() |
|
595 /** |
|
596 Launch an asynchronous request on a subsession in OOM. |
|
597 |
|
598 @see RunOomTest |
|
599 */ |
|
600 { |
|
601 TPckgBuf<TInt> x = 3; |
|
602 TRequestStatus rs; |
|
603 sTestSubsession.Treble(x, rs); |
|
604 User::WaitForRequest(rs); |
|
605 |
|
606 if (rs == KErrNone) |
|
607 { |
|
608 test(x() == 9); |
|
609 } |
|
610 |
|
611 return rs.Int(); |
|
612 } |
|
613 |
|
614 static void TestAsyncSubsessionFunction() |
|
615 /** |
|
616 Test queueing and cancelling asynchronous requests on a subsession. |
|
617 */ |
|
618 { |
|
619 test.Start(_L("TestAsyncSubsessionFunction")); |
|
620 |
|
621 TPckgBuf<TInt> x = 7; |
|
622 TRequestStatus rs; |
|
623 sTestSubsession.Treble(x, rs); |
|
624 User::WaitForRequest(rs); |
|
625 test(rs == KErrNone); |
|
626 test(x() == 21); |
|
627 |
|
628 // test launching async request in OOM |
|
629 RunOomTest(LaunchSsTrebleOom, NULL); |
|
630 |
|
631 // cancel async request |
|
632 sTestSubsession.Treble(x, rs); |
|
633 sTestSubsession.CancelTreble(); |
|
634 User::WaitForRequest(rs); |
|
635 test(rs == KErrCancel); |
|
636 |
|
637 // cancel when no outstanding request |
|
638 sTestSubsession.CancelTreble(); |
|
639 |
|
640 test.End(); |
|
641 } |
|
642 |
|
643 // -------- leak subsession -------- |
|
644 |
|
645 static void TestLeakSubsession() |
|
646 /** |
|
647 Test closing a session with a remaining subsession; |
|
648 ensure server does not leak memory. |
|
649 */ |
|
650 { |
|
651 test.Start(_L("TestLeakSubsession")); |
|
652 |
|
653 TInt r; |
|
654 |
|
655 sTestSession.SetServerHeapFail(KMaxTInt); |
|
656 |
|
657 RScsTestSession s; |
|
658 r = s.Connect(); |
|
659 test(r == KErrNone); |
|
660 |
|
661 RScsTestSubsession ss; |
|
662 r = ss.Create(s, KSubsessValue); |
|
663 test(r == KErrNone); |
|
664 |
|
665 s.Close(); |
|
666 LetServerRun(); // 100ms, let server clean up |
|
667 sTestSession.ResetServerHeapFail(); |
|
668 |
|
669 test.End(); |
|
670 } |
|
671 |
|
672 // -------- correct async requests cancelled -------- |
|
673 |
|
674 static void TestCorrectAsyncCancelled() |
|
675 /** |
|
676 Test the correct requests are cancelled. |
|
677 */ |
|
678 { |
|
679 test.Start(_L("TestCorrectAsyncCancelled")); |
|
680 |
|
681 TInt r; |
|
682 |
|
683 RScsTestSession s1; |
|
684 r = s1.Connect(); |
|
685 test(r == KErrNone); |
|
686 |
|
687 RScsTestSubsession ss1a; |
|
688 r = ss1a.Create(s1, KSubsessValue); |
|
689 test(r == KErrNone); |
|
690 |
|
691 RScsTestSubsession ss1b; |
|
692 r = ss1b.Create(s1, KSubsessValue); |
|
693 test(r == KErrNone); |
|
694 |
|
695 RScsTestSession s2; |
|
696 r = s2.Connect(); |
|
697 test(r == KErrNone); |
|
698 |
|
699 RScsTestSubsession ss2a; |
|
700 r = ss2a.Create(s2, KSubsessValue); |
|
701 test(r == KErrNone); |
|
702 |
|
703 TRequestStatus r1, r1a, r1b, r2, r2a; |
|
704 TPckgBuf<TInt> i1(10), i1a(20), i1b(30), i2(40), i2a(50); |
|
705 |
|
706 s1.Treble(i1, r1); |
|
707 ss1a.Treble(i1a, r1a); |
|
708 ss1b.Treble(i1b, r1b); |
|
709 s2.Treble(i2, r2); |
|
710 ss2a.Treble(i2a, r2a); |
|
711 |
|
712 test(r1 == KRequestPending); |
|
713 test(r1a == KRequestPending); |
|
714 test(r1b == KRequestPending); |
|
715 test(r2 == KRequestPending); |
|
716 test(r2a == KRequestPending); |
|
717 |
|
718 ss1a.CancelTreble(); // subsession doesn't affect parent or siblings |
|
719 LetServerRun(); |
|
720 test(r1 == KRequestPending); |
|
721 test(r1a == KErrCancel); |
|
722 test(r1b == KRequestPending); |
|
723 test(r2 == KRequestPending); |
|
724 test(r2a == KRequestPending); |
|
725 |
|
726 s2.CancelTreble(); // session doesn't affect child |
|
727 LetServerRun(); |
|
728 test(r1 == KRequestPending); |
|
729 test(r1a == KErrCancel); |
|
730 test(r1b == KRequestPending); |
|
731 test(r2 == KErrCancel); |
|
732 test(r2a == KRequestPending); |
|
733 |
|
734 ss2a.Close(); // close subsession cancels outstanding request |
|
735 LetServerRun(); |
|
736 test(r1 == KRequestPending); |
|
737 test(r1a == KErrCancel); |
|
738 test(r1b == KRequestPending); |
|
739 test(r2 == KErrCancel); |
|
740 test(r2a == KErrCancel); |
|
741 |
|
742 // consume pending signals |
|
743 User::WaitForRequest(r1); |
|
744 User::WaitForRequest(r1a); |
|
745 User::WaitForRequest(r1b); |
|
746 User::WaitForRequest(r2); |
|
747 User::WaitForRequest(r2a); |
|
748 |
|
749 test(r1 == KErrNone); |
|
750 test(r1a == KErrCancel); |
|
751 test(r1b == KErrNone); |
|
752 test(r2 == KErrCancel); |
|
753 test(r2a == KErrCancel); |
|
754 |
|
755 s1.Close(); |
|
756 s2.Close(); |
|
757 |
|
758 test.End(); |
|
759 } |
|
760 |
|
761 // -------- entrypoint -------- |
|
762 |
|
763 |
|
764 void MainL() |
|
765 { |
|
766 test.Title(_L("c:\\scstest.log")); |
|
767 test.Start(_L(" @SYMTestCaseID:SEC-SCSTEST-0001 scstest ")); |
|
768 |
|
769 TestServerDeath(); |
|
770 |
|
771 TestOpenClose(); |
|
772 |
|
773 TInt r = sTestSession.Connect(); |
|
774 test(r == KErrNone); |
|
775 |
|
776 TestInvalidSessionFunction(); |
|
777 TestSyncSessionFunction(); |
|
778 TestAsyncSessionFunction(); |
|
779 |
|
780 TestOpenCloseSubsession(); |
|
781 |
|
782 r = sTestSubsession.Create(sTestSession, KSubsessValue); |
|
783 test(r == KErrNone); |
|
784 |
|
785 TestInvalidSubsessionFunction(); |
|
786 TestSyncSubsessionFunction(); |
|
787 TestAsyncSubsessionFunction(); |
|
788 TestLeakSubsession(); |
|
789 TestCorrectAsyncCancelled(); |
|
790 |
|
791 sTestSubsession.Close(); |
|
792 sTestSession.ShutdownServer(); // Synchronous shutdown of server |
|
793 |
|
794 test.End(); |
|
795 test.Close(); |
|
796 } |
|
797 |
|
798 void PanicIfError(TInt r) |
|
799 { |
|
800 if(r != KErrNone) |
|
801 { |
|
802 User::Panic(_L("upstest failed: "), r); |
|
803 } |
|
804 } |
|
805 |
|
806 |
|
807 TInt E32Main() |
|
808 /** |
|
809 Executable entrypoint establishes connection with SCS test server |
|
810 and then invokes tests for each functional area. |
|
811 */ |
|
812 { |
|
813 // disable lazy DLL unloading so kernel heap balances at end |
|
814 RLoader l; |
|
815 PanicIfError(l.Connect()); |
|
816 PanicIfError(l.CancelLazyDllUnload()); |
|
817 l.Close(); |
|
818 |
|
819 (void)test.Console(); |
|
820 |
|
821 __UHEAP_MARK; |
|
822 __KHEAP_MARK; |
|
823 |
|
824 // allocating a cleanup stack also installs it |
|
825 CTrapCleanup* tc = CTrapCleanup::New(); |
|
826 if (tc == 0) |
|
827 return KErrNoMemory; |
|
828 |
|
829 TRAPD(err, MainL()); |
|
830 PanicIfError(err); |
|
831 |
|
832 |
|
833 delete tc; |
|
834 |
|
835 // The kernel appears to leave some memory allocated related to |
|
836 // econs.dll (maybe some sort of internal cache), which is |
|
837 // indirectly used by the test code, so we need to ignore this |
|
838 // allocation to allow our test to pass... |
|
839 User::__DbgMarkEnd(TRUE,1); |
|
840 __UHEAP_MARKEND; |
|
841 |
|
842 |
|
843 return KErrNone; |
|
844 } |
|
845 |
|
846 |
|
847 // End of file |