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