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