serialserver/c32serialserver/Test/CapTestFramework/CSuite.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // @file
       
    15 // for (WINS && !EKA2) versions will be xxxServer.Dll and require a thread to be started
       
    16 // in the process of the client. The client initialises the server by calling the
       
    17 // one and only ordinal.
       
    18 // 
       
    19 //
       
    20 
       
    21 // EPOC includes
       
    22 #include <e32base.h>
       
    23 #include <e32cmn.h> 
       
    24 #include <c32root.h>
       
    25 #include <e32property.h>
       
    26 
       
    27 #if (!defined TS_PARAM_SVR_SUITENAME_SERVER_H_)
       
    28 	#include "CSuite.h"
       
    29 #endif
       
    30 
       
    31 
       
    32 //ADD TEST STEP HEADERS HERE
       
    33 PARAM_FOREACH_MESS_BEGIN
       
    34 #include "PARAM_MESS_NAME_CStep.h"
       
    35 PARAM_FOREACH_MESS_END
       
    36 
       
    37 // __EDIT_ME__ - Substitute the name of your test server 
       
    38 _LIT(KServerName,"Cap_PARAM_SVR_SUITENAME_sc");
       
    39 // __EDIT_ME__ - Use your own server class name
       
    40 
       
    41 CTestPARAM_SVR_SUITENAMEServer* CTestPARAM_SVR_SUITENAMEServer::NewL()
       
    42 /**
       
    43  * @return - Instance of the test server
       
    44  * Same code for Secure and non-secure variants
       
    45  * Called inside the MainL() function to create and start the
       
    46  * CTestServer derived server.
       
    47  */
       
    48 	{
       
    49 // __EDIT_ME__ - Use your own server class name
       
    50 	CTestPARAM_SVR_SUITENAMEServer * server = new (ELeave) CTestPARAM_SVR_SUITENAMEServer();
       
    51 	CleanupStack::PushL(server);
       
    52 	// CServer base class call
       
    53 	server->StartL(KServerName);
       
    54 	CleanupStack::Pop(server);
       
    55 	return server;
       
    56 	}
       
    57 
       
    58 CTestStep* CTestPARAM_SVR_SUITENAMEServer::CreateTestStep(const TDesC& aStepName)
       
    59 /**
       
    60  * @return - A CTestStep derived instance
       
    61  * Secure and non-secure variants
       
    62  * Implementation of CTestServer pure virtual
       
    63  */
       
    64 	{
       
    65 	 CTestStep* testStep = NULL;
       
    66 	// add test steps
       
    67 PARAM_FOREACH_MESS_BEGIN
       
    68 		if (aStepName == _L("CPARAM_MESS_NAMEStep"))
       
    69 			{
       
    70 			testStep =  new CPARAM_MESS_NAMEStep  ;
       
    71 			return testStep;
       
    72 			 }
       
    73 			 
       
    74 PARAM_FOREACH_MESS_END
       
    75 		return testStep;
       
    76 	 }
       
    77 
       
    78 	
       
    79 
       
    80 // Secure variants much simpler
       
    81 // Just an E32Main and a MainL()
       
    82 LOCAL_C void MainL()
       
    83 /**
       
    84  * Secure variant
       
    85  * Much simpler, uses the new Rendezvous() call to sync with the client
       
    86  */
       
    87 	{
       
    88 	CActiveScheduler* sched=NULL;
       
    89 	sched=new(ELeave) CActiveScheduler;
       
    90 	CActiveScheduler::Install(sched);
       
    91 // __EDIT_ME__ - Use your own server class name
       
    92 	CTestPARAM_SVR_SUITENAMEServer* server = NULL;
       
    93 	// Create the CTestServer derived server
       
    94 	TRAPD(err,server = CTestPARAM_SVR_SUITENAMEServer::NewL());
       
    95 	if(!err)
       
    96 		{
       
    97 		// Sync with the client and enter the active scheduler
       
    98 		RProcess::Rendezvous(KErrNone);
       
    99 		sched->Start();
       
   100 		}
       
   101 	delete server;
       
   102 	delete sched;
       
   103 	}
       
   104 
       
   105 
       
   106 GLDEF_C TInt E32Main()
       
   107 /**
       
   108  * @return - Standard Epoc error code on process exit
       
   109  * Secure variant only
       
   110  * Process entry point. Called by client using RProcess API
       
   111  */
       
   112 	{
       
   113 	__UHEAP_MARK;
       
   114 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   115 	if(cleanup == NULL)
       
   116 		{
       
   117 		return KErrNoMemory;
       
   118 		}
       
   119 	TRAPD(err,MainL());
       
   120 	delete cleanup;
       
   121 	__UHEAP_MARKEND;
       
   122 	return KErrNone;
       
   123     }
       
   124 
       
   125 
       
   126 TVerdict CCapabilityTestStep::doTestStepPreambleL( void )
       
   127 	{
       
   128 	//If Preamble is not required just pass a success value
       
   129 	TVerdict testResult = CTestStep::doTestStepPreambleL();
       
   130 	
       
   131 	INFO_PRINTF1(_L("test step preamble."));
       
   132 	//Do nothing
       
   133 	INFO_PRINTF1(_L("end preamble."));
       
   134 		
       
   135 	return TestStepResult();
       
   136 	
       
   137 	}
       
   138 TVerdict CCapabilityTestStep::doTestStepPostambleL( void )
       
   139 	{
       
   140 	//If Postamble is not required just pass a success value
       
   141 	TVerdict testResult = CTestStep::doTestStepPostambleL();
       
   142 
       
   143 	return TestStepResult();
       
   144 	
       
   145 	}
       
   146 
       
   147 
       
   148 // Moved from CStep.cpp
       
   149 
       
   150 enum TVerdict CCapabilityTestStep::doTestStepL()
       
   151 	{
       
   152 	//DEF! INFO_PRINTF2(_L("%S - Starting ..."), &iTestStepName);
       
   153 
       
   154 	//The MainThread()creates a separate thread that executes SendReceive
       
   155 	TVerdict vResult = MainThread();
       
   156 	
       
   157 	SetTestStepResult(vResult);
       
   158 	return TestStepResult();
       
   159 	}
       
   160 
       
   161 /*
       
   162 ThreadStartFn:
       
   163 Called by:	The Child thread
       
   164 Function:	Calls the Exec_SendReceive
       
   165 */
       
   166 static TInt ThreadStartFn( TAny * ptr )
       
   167 	{
       
   168 	return(((CCapabilityTestStep *)ptr)->Exec_SendReceive());
       
   169 	}
       
   170 
       
   171 /*
       
   172 TVerdict GetVerdict(TInt aAPIretValue)
       
   173 
       
   174 Called by: "MainThread" for returning verdict
       
   175 
       
   176 Parameters(TInt aRetValue) :	0 if API call gets thru without any rejection
       
   177 								1 if API call is rejected for capability error	
       
   178 */
       
   179 enum TVerdict CCapabilityTestStep::GetVerdict(TInt aAPIretValue)
       
   180 	{
       
   181 	TVerdict vVerdict[] = {EPass, EFail};
       
   182 
       
   183 	//please leave the following if/else block as the information printed by INFO_PRINTF1 is used bu CapTestSumm
       
   184 	if(iExpect_Rejection)//[Inverse Test] EPass for 1 while EFail for 0
       
   185 		{
       
   186 		INFO_PRINTF1(_L("Test Expected to Fail due to lack of capabilities"));
       
   187 		return vVerdict[(aAPIretValue)?0:1];
       
   188 		
       
   189 		}
       
   190 	else //[Direct Test] EPass for 0 while EFail for 1
       
   191 		{
       
   192 		INFO_PRINTF1(_L("Test Expected to Pass with correct capabilities"));
       
   193 		return vVerdict[(aAPIretValue)?1:0];
       
   194 		}
       
   195 	}
       
   196 
       
   197 
       
   198 /*
       
   199 TVerdict MainThread()
       
   200 
       
   201 Called by: "doTestStepL"
       
   202 
       
   203 Purpose:	Creates the child thread(which calls the respective function with regard
       
   204 			to the server and also implements the Message Call). Then this fn.waits for the
       
   205 			completion of the childthread( doesnt matter how the thread did die!)
       
   206 
       
   207 Return Value(Verdict of the TestStep):
       
   208 
       
   209 			A.Reporting PASS/FAIL
       
   210 				Direct Test:
       
   211 						When a message call gets thru. Please note that in such cases
       
   212 						actually the implementation of the message has started. As we
       
   213 						are passing "0" Parameters, server may panic, though our botheration
       
   214 						stops once the call gets thru.
       
   215 						NOTE:	The style is the same when CONNECTION capabilities
       
   216 								are tested, the only diff is you dont have to expect a 
       
   217 								panic from server
       
   218 				Inverse Test:
       
   219 						The call should be either failed or panicked with
       
   220 						"KErrPermissionDenied" flag. 
       
   221 
       
   222 				General Case:
       
   223 						If a thread creation failed or if the server couldnt be connected
       
   224 						apart from the above two cases, then a FAIL is reported
       
   225 			
       
   226 			B.Reporting INCONCLUSIVE
       
   227 						Any panic say from unexpected source (eg:KERN-EXEC) will be
       
   228 						reported INCONCLUSIVE														
       
   229 */
       
   230 TVerdict CCapabilityTestStep::MainThread()
       
   231 	{
       
   232 
       
   233 	TBuf<100>	tExitCategory;
       
   234 	TInt		tExitReason = 0;		
       
   235 	TBuf<100>	TestStyle;
       
   236 
       
   237 	iExpect_Rejection?TestStyle = _L("Inverse"):TestStyle = _L("Direct");
       
   238 	TCapabilitySet theCaps =  TSecurityInfo(RProcess()).iCaps ;
       
   239 	const TInt KMaxTestThreadHeapSize = 0x10000;
       
   240 
       
   241 	//Initialize return values
       
   242 	iResult_SR = iResult_Server = KErrNone;	
       
   243 		
       
   244 
       
   245 	// Create a child thread, with a new heap
       
   246 	TInt nRes_Thread =	tChildThread.Create(
       
   247 						ChildThread_SR,
       
   248 						ThreadStartFn,
       
   249 						KDefaultStackSize,
       
   250 						KMinHeapSize,
       
   251 						KMaxTestThreadHeapSize,
       
   252 						this,			
       
   253 						EOwnerProcess);
       
   254 
       
   255 
       
   256 	if(nRes_Thread == KErrNone)//Thread Created
       
   257 		{
       
   258 
       
   259 		//Let me know when the thread is dead
       
   260 		TRequestStatus ThreadStatus;
       
   261 		tChildThread.Logon(ThreadStatus);
       
   262 		tChildThread.Resume(); 
       
   263 		//Is the thread dead?
       
   264 		User::WaitForRequest( ThreadStatus );
       
   265 		
       
   266 		//yes, he is dead. RIP!  Now the Killer's profile
       
   267 		tExitCategory	=	tChildThread.ExitCategory();
       
   268 		tExitReason		=	tChildThread.ExitReason();
       
   269 		
       
   270 	
       
   271 		//Somebody Please say what are we testing!!		
       
   272 		if(iSessionCreated && (SR_MESSAGE_ID >=0))//Flag set by Child thread when connected to Server
       
   273 		{
       
   274 			//DEF INFO_PRINTF5(_L("Connected to Server(%S) for %S Test [MessageID: %d,Req.Cap: 0x%x,Present.Cap: 0x%x]"),&SR_ServerName,&TestStyle,SR_MESSAGE_ID,iStepCap,TSecurityInfo(RProcess()));			
       
   275 		}
       
   276 		else if(SR_MESSAGE_ID < 0)
       
   277 		{
       
   278 			//DEF INFO_PRINTF5(_L("Testing Connection capabilities[%S Test] for Server(%S)  [Req.Cap: 0x%x,Present.Cap: 0x%x]"),&TestStyle,
       
   279 			//&SR_ServerName,TSecurityInfo(RProcess()));			
       
   280 		}
       
   281 		else if(!iSessionCreated)// NO Connection
       
   282 			{
       
   283 			INFO_PRINTF4(_L("Couldnt connect to the Server(%S) ErrorCode - ServerRet: %d C32ret: %d"),&SR_ServerName,iResult_Server,iResult_C32);
       
   284 			//INFO_PRINTF3(_L("Child Thread: ExitCategory : %S ExitReason : %d"),&tExitCategory,tExitReason);
       
   285   			return EFail;
       
   286  			}
       
   287 
       
   288 
       
   289 
       
   290 		switch(tChildThread.ExitType())
       
   291 			{			
       
   292 			case EExitPanic:
       
   293 				//1.A Panic from the connected Server 
       
   294 				//2.A CServer Panic normally for capability rejection
       
   295 				//3.A kernel Panic (consider yourself doomed!)
       
   296 				if((tExitReason == KErrPermissionDenied) //||
       
   297 					//DEF ? 	it's old version (tExitReason == CServer::EClientDoesntHaveRequiredCaps))//Rejected for Insufficient Cap.
       
   298 					// is it correct ?
       
   299 					//NMc: Commented out this check as it conflicts with CommServer panic code EBadCommHandle which has the same value (3).
       
   300 					/*(tExitReason == CServer2::EClientDoesntHaveRequiredCaps)*/)//Rejected for Insufficient Cap.
       
   301 					{
       
   302 					INFO_PRINTF2(_L("Rejected for insufficient capabilities [Return Value : %d] "),tExitReason);
       
   303 					return(GetVerdict(API_RetValue_PermissionDenied));
       
   304 					}
       
   305 				else if(tExitCategory == iServer_Panic) //Panic from Server
       
   306 					{
       
   307 					INFO_PRINTF2(_L("Server(%S) Panic to child thread"),&tExitCategory);	
       
   308 					INFO_PRINTF3(_L("Child Thread: ExitCategory : %S ExitReason : %d"),&tExitCategory,tExitReason);			
       
   309 					return(GetVerdict(API_RetValue_ServerPanic));
       
   310 					}
       
   311 				else//A kernel Panic possibly
       
   312 					{
       
   313 					INFO_PRINTF3(_L("Child Thread: Panic from unexpected source (ExitCategory: %S ExitReason : %d)!"),&tExitCategory,tExitReason);
       
   314 					return EInconclusive;
       
   315 					}
       
   316 
       
   317 					break;
       
   318 			case EExitKill:
       
   319 				if(iResult_SR != KErrPermissionDenied)
       
   320 					{
       
   321 					INFO_PRINTF2(_L("A Successfull call (Return Value : %d)"),((SR_MESSAGE_ID >=0)?iResult_SR:iResult_Server));
       
   322 					return(GetVerdict(API_RetValue_NoCapError));
       
   323 					}
       
   324 				else 
       
   325 					{
       
   326 					INFO_PRINTF2(_L("Rejected for insufficient capabilities [Return Value : %d] "),((SR_MESSAGE_ID >=0)?iResult_SR:iResult_Server));
       
   327 					return(GetVerdict(API_RetValue_PermissionDenied));			
       
   328 					}
       
   329 
       
   330 					break;
       
   331 			default:					
       
   332 					break;
       
   333 			}
       
   334 		}			
       
   335 	else //Our thread couldnt start	:o(
       
   336 		{
       
   337 		INFO_PRINTF2(_L("ERROR: Failed to create Child thread,  ErrorCode:(%d)"),nRes_Thread);
       
   338 		return EFail;
       
   339 		}
       
   340 
       
   341 	return EInconclusive;
       
   342 	}
       
   343 
       
   344 
       
   345 TInt CCapabilityTestStep::StartServer()
       
   346 	{
       
   347 #define C32_SERVER_START_SEQUENCE 5
       
   348 
       
   349 	TInt ret = StartC32();
       
   350 	if (ret==KErrNone || ret==KErrAlreadyExists)
       
   351 		{
       
   352 		RProperty property;
       
   353 		ret=property.Attach(KUidSystemCategory, KUidC32StartPropertyKey.iUid);
       
   354 		if(ret!=KErrNone)
       
   355 			return ret;
       
   356 		// C32 Server is loaded at sequence C32_SERVER_START_SEQUENCE, loop until it has finished.
       
   357 		TInt propertyValue=0;
       
   358 		ret = property.Get(propertyValue);
       
   359 		if(ret!=KErrNone)
       
   360 			return ret;
       
   361 
       
   362 		TRequestStatus status;
       
   363 		while(propertyValue<C32_SERVER_START_SEQUENCE)
       
   364 			{
       
   365 			property.Subscribe(status);
       
   366 			User::WaitForRequest(status);
       
   367 			property.Get(propertyValue);
       
   368 			}
       
   369 		property.Close();
       
   370 			
       
   371 		return KErrNone;
       
   372 		}
       
   373 User::After(2000000);
       
   374     return ret;
       
   375 	}
       
   376 
       
   377  
       
   378 TInt CCapabilityTestStep::TestDebugHeap(TInt aDbgIPCNo)
       
   379  	{
       
   380  	TInt fnToTest(-1);
       
   381 	if(SR_MESSAGE_ID == ECommDbgMarkHeap)
       
   382 		fnToTest=0;
       
   383 	else if (SR_MESSAGE_ID == ECommDbgCheckHeap)
       
   384 		fnToTest=2;
       
   385 	else if(SR_MESSAGE_ID == ECommDbgMarkEnd)
       
   386 		fnToTest=1;
       
   387 	else if(SR_MESSAGE_ID == ECommDbgFailNext)
       
   388 		fnToTest=3;
       
   389 	else
       
   390 		User::Panic(_L("CCapabilityTestStep::TestDebugHeap incorrect debug IPC"),aDbgIPCNo);
       
   391 
       
   392 	const TInt C32CapTestDbgResetFailNext(-1);
       
   393 	TInt dbgIPCNo[] =  	{
       
   394 							ECommDbgMarkHeap, ECommDbgMarkEnd, ECommDbgCheckHeap, ECommDbgFailNext, C32CapTestDbgResetFailNext,
       
   395 						};
       
   396 
       
   397  	TInt dbgTestSequence[5][6]	=	{	{MarkHeapStart	,2,0,1,-1,-1},
       
   398  										{MarkHeapEnd	,2,0,1,-1,-1},
       
   399  										{CheckHeap		,3,0,2, 1,-1},
       
   400  										{FailNext		,4,0,3, 4, 1},
       
   401  										{ResetFailNext	,4,0,3, 4, 1} // actually, there is no C32 IPC for this one - call FailNext(-1) instead
       
   402  									};
       
   403  	TInt count = dbgTestSequence[fnToTest][1];
       
   404  	TInt iResult_SR [6] ={0};
       
   405  	TInt testedFn = 0;
       
   406  	TInt currentIPC(-1);
       
   407 
       
   408     TInt i = 1;
       
   409  	while(count--  )
       
   410  		{
       
   411  		testedFn =  dbgTestSequence[fnToTest][(++i)];
       
   412  		currentIPC=  dbgIPCNo[testedFn];
       
   413  		TIpcArgs args(0,0,0,0);
       
   414 		if(dbgIPCNo[testedFn]==ECommDbgFailNext )
       
   415 				args.Set(0,4);
       
   416 		else if(dbgIPCNo[testedFn]==C32CapTestDbgResetFailNext ) // do ResetFailnext
       
   417 			 {
       
   418 			 	currentIPC=ECommDbgFailNext;
       
   419 				args.Set(0,-1);
       
   420 			 }
       
   421 
       
   422 		iResult_SR[testedFn ]= SendReceive(currentIPC,args);
       
   423 
       
   424  		if( ((testedFn !=fnToTest)?iResult_SR[testedFn]:KErrNone) == KErrPermissionDenied)
       
   425 
       
   426 			User::Panic(_L("Failed at Initialization"),iResult_SR[testedFn]);
       
   427 
       
   428 		}
       
   429 
       
   430 	return iResult_SR[fnToTest];
       
   431 	}
       
   432 	
       
   433 TInt CCapabilityTestStep::TestDeferCaps(TInt aDeferIPCNo)
       
   434 	{
       
   435 	TInt result=0;
       
   436 	
       
   437 	TFileName csymodule;
       
   438 	TFileName csyport;
       
   439 	TInt port=0;
       
   440 
       
   441 		switch(aDeferIPCNo)
       
   442 			{
       
   443 		case KCommOpenWithEcuart2:
       
   444 			port++;
       
   445 		case KCommOpenWithEcuart1:
       
   446 			port++;
       
   447 		case KCommOpenWithEcuart0:			
       
   448 			SR_MESSAGE_ID = ECommOpen;
       
   449 			csymodule = _L("Ecuart");
       
   450 			csyport.Format(_L("COMM::%d"), port);
       
   451 			break;
       
   452 		case KCommOpenWithDummy2:
       
   453 			port++;
       
   454 		case KCommOpenWithDummy1:
       
   455 			port++;
       
   456 		case KCommOpenWithDummy0:
       
   457 		default:
       
   458 			SR_MESSAGE_ID = ECommOpen;
       
   459 			csymodule = _L("Dummy");
       
   460 			csyport.Format(_L("%S::%d"), &csymodule, port);
       
   461 			break;		
       
   462 		}
       
   463 	
       
   464 	const TDesC& module = csymodule;	
       
   465 	const TDesC& name = csyport; 
       
   466 
       
   467 	//Step 1: Load the CSY								
       
   468 	result = SendReceive(ECommLoadCommModule, TIpcArgs(&module));
       
   469 					
       
   470 	//Step 2: Open the Port, (creating a subsession!!)			
       
   471 	return SendReceive(SR_MESSAGE_ID, TIpcArgs(&name,0,0,0));
       
   472 	}
       
   473  
       
   474