cryptomgmtlibs/securitycommonutils/test/source/scstest/scstest.cpp
changeset 8 35751d3474b7
child 15 da2ae96f639b
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     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