kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent.cpp
changeset 259 57b9594f5772
parent 247 d8d70de2bd36
child 260 a1a318fd91af
child 266 0008ccd16016
equal deleted inserted replaced
247:d8d70de2bd36 259:57b9594f5772
     1 // Copyright (c) 2007-2010 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 the License "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 // Tests the run mode debug device component by launching multiple targets 
       
    15 // on different CPUs. On a single core the targets run on the same CPU.  
       
    16 //
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <e32property.h>
       
    20 #include <hal.h>
       
    21 #include <e32test.h>
       
    22 #include <e32def.h>
       
    23 #include <e32svr.h>
       
    24 
       
    25 #include "t_rmdebug_app.h"
       
    26 #include "t_multi_agent.h"
       
    27 #include "t_agent_eventhandler.h"
       
    28 #include "t_debug_logging.h"
       
    29 
       
    30 const TVersion securityServerVersion(0,1,1);
       
    31 
       
    32 /**
       
    33  * First phase constructor
       
    34  */
       
    35 CMultiAgent* CMultiAgent::NewL()
       
    36 	{
       
    37 	CMultiAgent* self = new(ELeave) CMultiAgent();
       
    38 	self->ConstructL();
       
    39 	return self;
       
    40 	}
       
    41 
       
    42 /**
       
    43   * Destructor
       
    44   */
       
    45 CMultiAgent::~CMultiAgent()
       
    46 	{
       
    47 	LOG_MSG("~CMultiTargetAgent\n");
       
    48 	iServSession.Close();
       
    49 	}
       
    50 
       
    51 /**
       
    52  * Constructor
       
    53  */
       
    54 CMultiAgent::CMultiAgent() 
       
    55 	{
       
    56 	}
       
    57 
       
    58 /**
       
    59  * Second phase constructor
       
    60  */
       
    61 void CMultiAgent::ConstructL()
       
    62 	{
       
    63 	}
       
    64 
       
    65 /**
       
    66   Parse the command line, set agent cpu affinity and call main test function
       
    67   */
       
    68 void CMultiAgent::ClientAppL()
       
    69 	{
       
    70 	LOG_MSG("ENTER: CMultiTargetAgent::ClientAppL"); 
       
    71 
       
    72 	iNumApps = KNumApps;
       
    73 	iAgentCpuNo = KAgentCpu;
       
    74 	iTargetNameOffset = KTargetOffset;
       
    75 
       
    76 	TInt argc = User::CommandLineLength();
       
    77 	HBufC* commandLine = NULL;
       
    78 	LOG_MSG2(">Launcher Process() argc=%d", argc);
       
    79 	
       
    80 	if(argc)
       
    81 		{
       
    82 		commandLine = HBufC::NewLC(argc);
       
    83 		TPtr commandLineBuffer = commandLine->Des();
       
    84 		User::CommandLine(commandLineBuffer);
       
    85 
       
    86 		RBuf printCommandLine;
       
    87 		CleanupClosePushL(printCommandLine);
       
    88 		printCommandLine.CreateL(commandLine->Des().Length());
       
    89 		printCommandLine.Copy(commandLine->Des());
       
    90 		printCommandLine.Collapse();
       
    91 		LOG_MSG2(">command line = %S", &printCommandLine );
       
    92 		CleanupStack::PopAndDestroy( &printCommandLine );
       
    93 
       
    94 		// create a lexer and read through the command line
       
    95 		TLex lex(*commandLine);
       
    96 	
       
    97 		while (!lex.Eos())
       
    98 		{
       
    99 			// only look for options with first character '-'
       
   100 			if (lex.Get() == '-')
       
   101 			{
       
   102 			TChar arg = lex.Get();
       
   103 			
       
   104 				switch ( arg )
       
   105 				{
       
   106 				case 'n':
       
   107 					lex.Val( iNumApps );
       
   108 					LOG_MSG2("parsed numApps as %d", iNumApps); 
       
   109 					break;
       
   110 		
       
   111 				case 'a':
       
   112 					lex.Val( iAgentCpuNo );
       
   113 					LOG_MSG2("parsed agentCpuNo as %d", iAgentCpuNo);                        
       
   114 					break;
       
   115 
       
   116 				case 'o':
       
   117 					lex.Val( iTargetNameOffset );
       
   118 					LOG_MSG2("parsed iTargetNameOffset as %d", iTargetNameOffset);        
       
   119 					break;
       
   120 
       
   121 				default:
       
   122 					LOG_MSG("Bad argument from user"); 
       
   123 					break;                 
       
   124 				}
       
   125 			}
       
   126 		}
       
   127 	}
       
   128 	// Create active scheduler (to run active objects)
       
   129 	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
   130 	CleanupStack::PushL(scheduler);
       
   131 	CActiveScheduler::Install(scheduler);
       
   132 	
       
   133 	if (iAgentCpuNo)
       
   134 		{
       
   135 		LOG_MSG2("CMultiAgent::ClientAppL() - setting agent to cpu %d", iAgentCpuNo);
       
   136 		UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)iAgentCpuNo, 0);
       
   137 		}
       
   138 
       
   139 	TInt err = iServSession.Connect(securityServerVersion);
       
   140 	
       
   141 	if (err != KErrNone)
       
   142 		{
       
   143 		User::Panic(_L("Can't open server session"), err);
       
   144 		}
       
   145 
       
   146 	StartTest();
       
   147 
       
   148 	// Note: below is a workaround to overcome an issue with RTest server crashing 
       
   149 	// when writing to the windows console from different agents (on different CPUs 
       
   150 	// at the same time). To overcome this we signal the launcher using a global 
       
   151 	// semaphore to indicate a RTest complete instead
       
   152 	RSemaphore launchSemaphore;
       
   153 	CleanupClosePushL(launchSemaphore);
       
   154             
       
   155 	TFindSemaphore launchSemFinder(KLaunchSemaphoreSearchString);
       
   156 	TFullName semaphoreResult;
       
   157 	TInt ret = launchSemFinder.Next(semaphoreResult);
       
   158 	LOG_MSG3( "> Find Launch Semaphote.Next ret=%d, %lS", ret, &semaphoreResult);
       
   159          
       
   160 	ret = launchSemaphore.OpenGlobal(semaphoreResult);
       
   161 	LOG_MSG2( ">OpenGlobal semaphore ret=%d", ret );         
       
   162     
       
   163 	LOG_MSG( ">Signalling semaphore" );
       
   164 	launchSemaphore.Signal();
       
   165 	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore
       
   166 
       
   167 	// Delete active scheduler
       
   168 	CleanupStack::PopAndDestroy(scheduler);
       
   169 
       
   170 	if (commandLine)
       
   171 	CleanupStack::PopAndDestroy(commandLine);
       
   172 	
       
   173 	LOG_MSG( "EXIT: CMultiTargetAgent::ClientAppL"); 
       
   174 	}
       
   175 
       
   176 /**
       
   177   Launch a process
       
   178   @param aProcess the RProcess object used to create the process
       
   179   @param aFileName file name of the executable used to create the process
       
   180   @return KErrNone on success, or one of the other system wide error codes
       
   181   */
       
   182 TInt CMultiAgent::LaunchProcess(RProcess& aProcess, const TDesC& aExeName, const TDesC& aCommandLine)    
       
   183 	{
       
   184 	LOG_MSG( "ENTER: CMultiAgent::LaunchProcess");
       
   185     LOG_MSG2("%S", &TPtr8((TUint8*)aExeName.Ptr(), 2*aExeName.Length(), 2*aExeName.Length()));	
       
   186 	
       
   187 	// wait for 0.5 seconds due to issue with creating several processes in smp quickly
       
   188 	User::After(500000);
       
   189 	
       
   190 	TInt err = aProcess.Create( aExeName, aCommandLine );
       
   191 	LOG_MSG2( "CMultiAgent::LaunchProcess, aProcess.Create err = %d", err); 
       
   192 
       
   193 	// check that there was no error raised
       
   194 	if (err != KErrNone)
       
   195 		return err;
       
   196 	
       
   197 	// rendezvous with process
       
   198 	TRequestStatus status = KRequestPending;
       
   199 	aProcess.Rendezvous(status);
       
   200 
       
   201 	if (KRequestPending != status.Int())
       
   202 		{
       
   203 		// startup failed so kill the process
       
   204 		LOG_MSG2( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() );
       
   205 		aProcess.Kill(KErrNone);
       
   206 		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
       
   207 		return status.Int();
       
   208 		}
       
   209 	else
       
   210 		{
       
   211 		// start the test target
       
   212 		aProcess.Resume();
       
   213 		User::WaitForRequest(status);
       
   214 	
       
   215 		LOG_MSG2( "> CMultiAgent::LaunchProcess: RProcess Resume() Rendezvous successful %d: ", status.Int() );
       
   216 
       
   217 		if(KErrNone != status.Int())
       
   218 			{
       
   219 			LOG_MSG2( "> RProcess Resume() failed with %d. Killing process", status.Int() );
       
   220 			aProcess.Kill(KErrNone);
       
   221 			}
       
   222 
       
   223 		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
       
   224 		return status.Int();
       
   225 		}
       
   226 	}
       
   227 
       
   228 /**
       
   229   Handle Event
       
   230   @param aEventInfo object containing event information from the DSS 
       
   231   */
       
   232 void CMultiAgent::HandleEvent(TEventInfo& aEventInfo)
       
   233 	{
       
   234 	LOG_MSG( "ENTER: CMultiAgent::HandleEvent" ); 
       
   235 	TInt ret = KErrNone;
       
   236 	const TInt idValid = 1;
       
   237 	
       
   238 	switch ( aEventInfo.iEventType )
       
   239 		{
       
   240 		case EEventsAddProcess:
       
   241 			{
       
   242 			LOG_MSG(">> EEventsAddProcess");                        
       
   243 			TPtrC8 exeNamePtr8(aEventInfo.iAddProcessInfo.iFileName, aEventInfo.iAddProcessInfo.iFileNameLength);
       
   244 	
       
   245 			RBuf8 exeName8;
       
   246 			CleanupClosePushL(exeName8);
       
   247 			exeName8.CreateL(exeNamePtr8);
       
   248 			LOG_MSG2("From event: exeName8=%S", &exeName8);
       
   249 			CleanupStack::PopAndDestroy(&exeName8);
       
   250 			LOG_MSG("Testing if event process id is valid");
       
   251 
       
   252 			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW( aEventInfo.iProcessId));
       
   253 			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   254 	
       
   255 			RProcess targetProc;
       
   256 			ret = targetProc.Open(TProcessId(aEventInfo.iProcessId));
       
   257 			LOG_MSG2("RProcess open ret=%d", ret);
       
   258 			targetProc.Close();
       
   259 
       
   260 			__ASSERT_ALWAYS((ret == KErrNone), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   261 			break;
       
   262 			}
       
   263 	
       
   264 		case EEventsStartThread:
       
   265 			{
       
   266 			LOG_MSG(">> EEventsStartThread");                
       
   267 			TPtrC8 exeNamePtr8(aEventInfo.iStartThreadInfo.iFileName, aEventInfo.iStartThreadInfo.iFileNameLength);
       
   268 			RBuf8 exe8Name;
       
   269 			CleanupClosePushL(exe8Name);
       
   270 			exe8Name.CreateL(exeNamePtr8);
       
   271 			LOG_MSG2("From event: exeName8=%S", &exe8Name);
       
   272 			CleanupStack::PopAndDestroy(&exe8Name);
       
   273 	
       
   274 			LOG_MSG("Testing if event process id is valid" );
       
   275 
       
   276 			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   277 
       
   278 			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW(aEventInfo.iProcessId));
       
   279 
       
   280 			LOG_MSG("Testing if event thread id is valid");
       
   281 
       
   282 			__ASSERT_ALWAYS((aEventInfo.iThreadIdValid==idValid), User::Panic(_L("ThreadId Invalid"), aEventInfo.iThreadIdValid));
       
   283 
       
   284 			LOG_MSG2("Got aEventInfo.iThreadId=%d", I64LOW(aEventInfo.iThreadId));
       
   285 			break;                    
       
   286 			}                       
       
   287 
       
   288 		case EEventsUserTrace:
       
   289 			{
       
   290 			LOG_MSG(">> EEventsUserTrace");  
       
   291 			break;
       
   292 			}
       
   293 
       
   294 		case EEventsRemoveProcess:
       
   295 			{
       
   296 			LOG_MSG( ">> EEventsRemoveProcess");                        
       
   297 			iLaunchCompleted++; 
       
   298 			break;
       
   299 			}
       
   300 	
       
   301 		default:   
       
   302 			{
       
   303 			LOG_MSG( ">> Unknown event - probably due to DSS busy?");
       
   304 			break;
       
   305 			}	
       
   306 		}
       
   307  	 
       
   308 	LOG_MSG("EXIT: CMultiAgent::HandleEvent"); 
       
   309 	}
       
   310 
       
   311 /**
       
   312  * Main test function which launches several targets and stresses the DSS 
       
   313  */
       
   314 TInt CMultiAgent::StartTest()
       
   315 	{
       
   316 	LOG_MSG("ENTER: CMultiTargetAgent::StartTest");
       
   317 
       
   318 	for( TInt i = 0; i < iNumApps; i++ )
       
   319 		{
       
   320 		RBuf targetName;
       
   321 		RBuf launcherOptions;
       
   322 
       
   323 		CleanupClosePushL(targetName); 
       
   324 		CleanupClosePushL(launcherOptions); 
       
   325 
       
   326 		targetName.CreateL( KTargetExe().Length() + 2 );
       
   327 		targetName.Format( KTargetExe(), i + iTargetNameOffset + 1 );
       
   328 
       
   329 		LOG_MSG2("App %d: ", i+1);
       
   330 		LOG_MSG2("%S", &TPtr8((TUint8*)targetName.Ptr(), 2*targetName.Length(), 2*targetName.Length()));	
       
   331 
       
   332 		launcherOptions.CreateL( KTargetOptions().Length() + 2 );
       
   333 		launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit, (i+1) );
       
   334 
       
   335 		LOG_MSG( "AppOptions : ");
       
   336 		LOG_MSG2("%S", &TPtr8((TUint8*)launcherOptions.Ptr(), 2*launcherOptions.Length(), 2*launcherOptions.Length()));	
       
   337 		
       
   338 		// Add each test target to array
       
   339 		iTargetList.AppendL(CAgentAsyncEvent::NewL(*this, targetName, launcherOptions));
       
   340 		CleanupStack::PopAndDestroy(2, &targetName );
       
   341 		}
       
   342 	
       
   343 	iLaunchCompleted = 0;
       
   344 	TInt err = KErrNone;
       
   345 		
       
   346 	for (TInt i = 0; i < iNumApps; i++)
       
   347 		{
       
   348 		// Attach to process non-passively
       
   349 		LOG_MSG2( ">AttachExecutable app %d ", i + iTargetNameOffset + 1 );
       
   350 		LOG_MSG2("%S", &TPtr8((TUint8*)iTargetList[i]->GetExecutable().Ptr(), 2*iTargetList[i]->GetExecutable().Length(), 
       
   351 					2*iTargetList[i]->GetExecutable().Length()));
       
   352 
       
   353 		err = iServSession.AttachExecutable( iTargetList[i]->GetExecutable(), EFalse);
       
   354 		__ASSERT_ALWAYS((err == KErrNone), User::Panic(_L("DSS Attach failed"), err));
       
   355 
       
   356 		// Continue on interested event actions
       
   357 		LOG_MSG2( ">SetEventAction app %d,  EEventsStartThread EAcionContinue", i + iTargetNameOffset + 1);
       
   358 
       
   359 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsStartThread, EActionContinue);
       
   360 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   361 	
       
   362 		LOG_MSG2(">SetEventAction app %d,  EEventsAddProcess EActionContinue", i + iTargetNameOffset + 1);
       
   363 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsAddProcess, EActionContinue);
       
   364 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   365 
       
   366 		LOG_MSG2(">SetEventAction app %d,  EEventsUserTrace EActionContinue", i + iTargetNameOffset + 1);
       
   367 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsUserTrace, EActionContinue);
       
   368 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   369 	
       
   370 		LOG_MSG2(">SetEventAction app %d,  EEventsRemoveProcess EActionContinue", i + iTargetNameOffset + 1);
       
   371 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsRemoveProcess, EActionContinue);
       
   372 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   373 
       
   374 		// Add target object to active schedular
       
   375 		iTargetList[i]->Watch();
       
   376 		}
       
   377 
       
   378 	for (TInt i= 0; i< iNumApps; i++)
       
   379 		{
       
   380 		LOG_MSG( ">Calling LaunchProcess function");
       
   381 		err = LaunchProcess(iTargetList[i]->GetProcHandle(), iTargetList[i]->GetExecutable(), iTargetList[i]->GetExeConfig());
       
   382 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("LaunchProcess failed"), err));
       
   383 		}
       
   384 
       
   385 	LOG_MSG( ">CActiveScheduler::Start()");
       
   386 	CActiveScheduler::Start();
       
   387 
       
   388 	for (TInt i= 0; i < iNumApps; i++)
       
   389 		{
       
   390 		// Now detach again
       
   391 		LOG_MSG( "Before iServSession.DetachExecutable" );
       
   392 		err = iServSession.DetachExecutable(iTargetList[i]->GetExecutable());
       
   393 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("DetachExecutable failed"), err));
       
   394 		}
       
   395 	
       
   396 	// Free all the memory
       
   397 	iTargetList.ResetAndDestroy();
       
   398 	LOG_MSG( "EXIT: CMultiTargetAgent::StartTest" );
       
   399 
       
   400 	return KErrNone;
       
   401 	}
       
   402 
       
   403 /**
       
   404   * Entry point for run mode debug driver test
       
   405   */
       
   406 GLDEF_C TInt E32Main()
       
   407 	{
       
   408 	LOG_MSG( "ENTER: Multi_agent E32Main ");
       
   409 	__UHEAP_MARK;
       
   410 
       
   411 	TInt ret = KErrNone;
       
   412 	RProcess::Rendezvous(KErrNone);
       
   413 	
       
   414 	CTrapCleanup* trap = CTrapCleanup::New();
       
   415 		
       
   416 	if (!trap)
       
   417 		return KErrNoMemory;
       
   418 	
       
   419 	CMultiAgent *runModeAgent = CMultiAgent::NewL();
       
   420 
       
   421 	if (runModeAgent != NULL)
       
   422 		{
       
   423 		TRAP(ret,runModeAgent->ClientAppL());
       
   424 		LOG_MSG2( "ClientAppL returned %d", ret );
       
   425 		delete runModeAgent;
       
   426 		}
       
   427 
       
   428 	delete trap;
       
   429 	__UHEAP_MARKEND;
       
   430 	LOG_MSG( "EXIT: Multi_agent E32Main ");
       
   431 	return ret;
       
   432 	}
       
   433