debugsrv/runmodedebug/tsrc/rm_debug/multi_agent_tests/t_multi_agent_launcher.cpp
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
// Helper app to launch debug targets
hgs
parents:
diff changeset
    15
//
hgs
parents:
diff changeset
    16
//
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include "t_multi_agent_launcher.h"
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
#include "t_debug_logging.h"
hgs
parents:
diff changeset
    21
hgs
parents:
diff changeset
    22
/**
hgs
parents:
diff changeset
    23
 * Launch a process
hgs
parents:
diff changeset
    24
 * @param aProcess the RProcess object used for creating the process
hgs
parents:
diff changeset
    25
 * @param aExeName the name of the executable to run 
hgs
parents:
diff changeset
    26
 * @param aCommandLine command line parameters to pass when creating the process 
hgs
parents:
diff changeset
    27
 * @return KErrNone on success, or one of the other system wide error codes
hgs
parents:
diff changeset
    28
 */
hgs
parents:
diff changeset
    29
TInt LaunchProcess(RProcess& aProcess, TDesC& aExeName, TDesC& aCommandLine )    
hgs
parents:
diff changeset
    30
	{
hgs
parents:
diff changeset
    31
	LOG_MSG("ENTER: t_multi_agent_launcher: launchProcess"); 
hgs
parents:
diff changeset
    32
hgs
parents:
diff changeset
    33
	LOG_MSG2("aExeName %S ", &TPtr8((TUint8*)aExeName.Ptr(), 2*aExeName.Length(), 2*aExeName.Length()));
hgs
parents:
diff changeset
    34
	LOG_MSG2("aCommandLine %S", &TPtr8((TUint8*)aCommandLine.Ptr(), 2*aCommandLine.Length(), 2*aCommandLine.Length()));
hgs
parents:
diff changeset
    35
hgs
parents:
diff changeset
    36
	TInt err = aProcess.Create( aExeName, aCommandLine );
hgs
parents:
diff changeset
    37
	LOG_MSG2("t_multi_agent_launcher launchProcess, aProcess.Create err = %d", err); 
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
	// check that there was no error raised
hgs
parents:
diff changeset
    40
	if(err != KErrNone)
hgs
parents:
diff changeset
    41
		{
hgs
parents:
diff changeset
    42
		return err;
hgs
parents:
diff changeset
    43
		}
hgs
parents:
diff changeset
    44
hgs
parents:
diff changeset
    45
	// rendezvous with process
hgs
parents:
diff changeset
    46
	TRequestStatus status = KRequestPending;
hgs
parents:
diff changeset
    47
	aProcess.Rendezvous(status);
hgs
parents:
diff changeset
    48
hgs
parents:
diff changeset
    49
	if(KRequestPending != status.Int())
hgs
parents:
diff changeset
    50
		{
hgs
parents:
diff changeset
    51
		// startup failed so kill the process
hgs
parents:
diff changeset
    52
		LOG_MSG2("t_multi_agent_launcher: launchProcess: RProcess Rendezvous() failed with %d. Killing process", status.Int());
hgs
parents:
diff changeset
    53
		aProcess.Kill(KErrNone);
hgs
parents:
diff changeset
    54
		return status.Int();
hgs
parents:
diff changeset
    55
		}
hgs
parents:
diff changeset
    56
	else
hgs
parents:
diff changeset
    57
		{
hgs
parents:
diff changeset
    58
		aProcess.Resume();
hgs
parents:
diff changeset
    59
		User::WaitForRequest(status);
hgs
parents:
diff changeset
    60
hgs
parents:
diff changeset
    61
		LOG_MSG2("t_multi_agent_launcher: launchProcess: RProcess Resume() Rendezvous successful %d: ", status.Int());
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
		if(KErrNone != status.Int())
hgs
parents:
diff changeset
    64
			{
hgs
parents:
diff changeset
    65
			LOG_MSG2("t_multi_agent_launcher: RProcess Resume() failed with %d. Killing process", status.Int());
hgs
parents:
diff changeset
    66
			aProcess.Kill(KErrNone);
hgs
parents:
diff changeset
    67
			}
hgs
parents:
diff changeset
    68
hgs
parents:
diff changeset
    69
		LOG_MSG("EXIT: t_multi_agent_launcher launchProcess");
hgs
parents:
diff changeset
    70
		return status.Int();
hgs
parents:
diff changeset
    71
		}
hgs
parents:
diff changeset
    72
	}
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
/**
hgs
parents:
diff changeset
    75
 * Read command line parameters and control the launching of the agents. 
hgs
parents:
diff changeset
    76
 */
hgs
parents:
diff changeset
    77
void MainL()
hgs
parents:
diff changeset
    78
	{	
hgs
parents:
diff changeset
    79
	LOG_MSG( "ENTER: t_multi_agent_launcher MainL()");
hgs
parents:
diff changeset
    80
hgs
parents:
diff changeset
    81
	TInt ret = KErrNone;
hgs
parents:
diff changeset
    82
	TInt numAgents = KNumAgents;
hgs
parents:
diff changeset
    83
	TInt numTargets = KNumTargets;
hgs
parents:
diff changeset
    84
	TInt numTestRuns = KNumTestRuns;
hgs
parents:
diff changeset
    85
hgs
parents:
diff changeset
    86
	TInt argc = User::CommandLineLength();
hgs
parents:
diff changeset
    87
	HBufC* commandLine = NULL;
hgs
parents:
diff changeset
    88
	LOG_MSG2("t_multi_agent_launcher: MainL(): argc=%d", argc);
hgs
parents:
diff changeset
    89
    
hgs
parents:
diff changeset
    90
	if(argc)
hgs
parents:
diff changeset
    91
		{
hgs
parents:
diff changeset
    92
		commandLine = HBufC::NewLC(argc);
hgs
parents:
diff changeset
    93
		TPtr commandLineBuffer = commandLine->Des();
hgs
parents:
diff changeset
    94
		User::CommandLine(commandLineBuffer);
hgs
parents:
diff changeset
    95
hgs
parents:
diff changeset
    96
		RBuf printCommandLine;
hgs
parents:
diff changeset
    97
		CleanupClosePushL( printCommandLine );
hgs
parents:
diff changeset
    98
		printCommandLine.CreateL( commandLine->Des().Length() );
hgs
parents:
diff changeset
    99
		printCommandLine.Copy( commandLine->Des() );
hgs
parents:
diff changeset
   100
		printCommandLine.Collapse();
hgs
parents:
diff changeset
   101
		LOG_MSG2("t_multi_agent_launcher: command line = %S", &printCommandLine);
hgs
parents:
diff changeset
   102
		CleanupStack::PopAndDestroy( &printCommandLine );
hgs
parents:
diff changeset
   103
 
hgs
parents:
diff changeset
   104
		// create a lexer and read through the command line
hgs
parents:
diff changeset
   105
		TLex lex(*commandLine);
hgs
parents:
diff changeset
   106
		while (!lex.Eos())
hgs
parents:
diff changeset
   107
			{
hgs
parents:
diff changeset
   108
			// only look for options with first character '-'
hgs
parents:
diff changeset
   109
			if (lex.Get() == '-')
hgs
parents:
diff changeset
   110
				{
hgs
parents:
diff changeset
   111
					TChar arg = lex.Get();
hgs
parents:
diff changeset
   112
					switch ( arg )
hgs
parents:
diff changeset
   113
						{
hgs
parents:
diff changeset
   114
						case 'n':
hgs
parents:
diff changeset
   115
							lex.Val( numAgents );
hgs
parents:
diff changeset
   116
							LOG_MSG2("t_multi_agent_launcher: parsed numAgents as %d", numAgents);
hgs
parents:
diff changeset
   117
							break;
hgs
parents:
diff changeset
   118
						case 'm':
hgs
parents:
diff changeset
   119
							lex.Val( numTargets );
hgs
parents:
diff changeset
   120
							LOG_MSG2("t_multi_agent_launcher: parsed numTargets as %d", numTargets);                        
hgs
parents:
diff changeset
   121
							break;  
hgs
parents:
diff changeset
   122
						case 't':
hgs
parents:
diff changeset
   123
							lex.Val( numTestRuns );
hgs
parents:
diff changeset
   124
							LOG_MSG2("t_multi_agent_launcher: parsed numTestRuns as %d", numTestRuns);                        
hgs
parents:
diff changeset
   125
							break;                    
hgs
parents:
diff changeset
   126
						default:
hgs
parents:
diff changeset
   127
							LOG_MSG("t_multi_agent_launcher: unknown argument ignoring it");
hgs
parents:
diff changeset
   128
							break;                 
hgs
parents:
diff changeset
   129
						}
hgs
parents:
diff changeset
   130
				}
hgs
parents:
diff changeset
   131
			}
hgs
parents:
diff changeset
   132
		}
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
	// Note: below is a workaround to overcome an issue with RTest server crashing 
hgs
parents:
diff changeset
   135
	// when writing to the windows console from different agents (on different CPUs 
hgs
parents:
diff changeset
   136
	// at the same time). To overcome this we get signaled by the agents when they have 
hgs
parents:
diff changeset
   137
	// completed their tests so that we can do a RTest complete
hgs
parents:
diff changeset
   138
	RSemaphore launchSemaphore;
hgs
parents:
diff changeset
   139
	CleanupClosePushL(launchSemaphore);
hgs
parents:
diff changeset
   140
	ret = launchSemaphore.CreateGlobal(KLaunchSemaphoreName, 0);
hgs
parents:
diff changeset
   141
	LOG_MSG2( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
hgs
parents:
diff changeset
   142
	User::LeaveIfError( ret );
hgs
parents:
diff changeset
   143
hgs
parents:
diff changeset
   144
	ret = launchSemaphore.OpenGlobal(KLaunchSemaphoreName);
hgs
parents:
diff changeset
   145
	LOG_MSG2( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
hgs
parents:
diff changeset
   146
	User::LeaveIfError( ret );
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
	//Now launch the requested number of apps for the requested number of test runs
hgs
parents:
diff changeset
   149
	for( TInt j = 0; j < numTestRuns; j++ )
hgs
parents:
diff changeset
   150
		{ 
hgs
parents:
diff changeset
   151
			for( TInt i = 0; i < numAgents; i++ )  
hgs
parents:
diff changeset
   152
				{
hgs
parents:
diff changeset
   153
					RBuf targetName;
hgs
parents:
diff changeset
   154
					targetName.CleanupClosePushL();
hgs
parents:
diff changeset
   155
					targetName.CreateL(KAgentExe());
hgs
parents:
diff changeset
   156
hgs
parents:
diff changeset
   157
					RProcess aProc;
hgs
parents:
diff changeset
   158
					CleanupClosePushL(aProc); 
hgs
parents:
diff changeset
   159
					RBuf launcherOptions;
hgs
parents:
diff changeset
   160
					CleanupClosePushL(launcherOptions);
hgs
parents:
diff changeset
   161
				    const TInt additionalWords = 2;	
hgs
parents:
diff changeset
   162
					launcherOptions.CreateL( KAgentOptions().Length() + additionalWords );
hgs
parents:
diff changeset
   163
		
hgs
parents:
diff changeset
   164
					// Apply offset: launcherOptions.Format( .., .., i * numTargets, ..)
hgs
parents:
diff changeset
   165
					// workaround to ensure we have the same binary for multiple agents. 
hgs
parents:
diff changeset
   166
					// e.g. So if offset = 0, agent attaches to app1, app2, app3, app4, app5
hgs
parents:
diff changeset
   167
					// if offset = 5, agent attached to app6, app7, app8, app9, app10 etc.
hgs
parents:
diff changeset
   168
					// Note: apps need to be in rom otherwise the agent will fail on an assert 
hgs
parents:
diff changeset
   169
					// (with KErrNotFound)
hgs
parents:
diff changeset
   170
					launcherOptions.Format( KAgentOptions(), (TUint)numTargets, i * numTargets, 0);
hgs
parents:
diff changeset
   171
			
hgs
parents:
diff changeset
   172
					ret = LaunchProcess( aProc, targetName, launcherOptions );	
hgs
parents:
diff changeset
   173
					CleanupStack::PopAndDestroy(3,&targetName);
hgs
parents:
diff changeset
   174
					User::LeaveIfError(ret);
hgs
parents:
diff changeset
   175
				}
hgs
parents:
diff changeset
   176
		}
hgs
parents:
diff changeset
   177
hgs
parents:
diff changeset
   178
	// Wait for all agents to do their testing before checking the semaphore
hgs
parents:
diff changeset
   179
	User::After(12000000);
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
	LOG_MSG( ">Target Launcher:  Semaphore wait");
hgs
parents:
diff changeset
   182
hgs
parents:
diff changeset
   183
	for (TInt i = 0; i < numAgents; i ++)
hgs
parents:
diff changeset
   184
		{
hgs
parents:
diff changeset
   185
		//We need this delay just in case an agent crashes and never signals the sem
hgs
parents:
diff changeset
   186
		ret = launchSemaphore.Wait(100000);
hgs
parents:
diff changeset
   187
		if( ret != KErrNone )
hgs
parents:
diff changeset
   188
			{
hgs
parents:
diff changeset
   189
			LOG_MSG3("launchSemaphore.Wait ret %d for agent %d", ret, i);
hgs
parents:
diff changeset
   190
			break;
hgs
parents:
diff changeset
   191
			}
hgs
parents:
diff changeset
   192
		}
hgs
parents:
diff changeset
   193
hgs
parents:
diff changeset
   194
	LOG_MSG2( "testing for Semaphore ret %d", ret);
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
	// We only want to have one RTest instance at any one time since otherwise RTest can panic
hgs
parents:
diff changeset
   197
	RTest test(_L("T_MULTI_AGENT_LAUNCHER"));
hgs
parents:
diff changeset
   198
	test.Start(_L("t_multi_agent_launcher Check for agents finishing correctly"));
hgs
parents:
diff changeset
   199
	test(ret == KErrNone);
hgs
parents:
diff changeset
   200
	test.End();
hgs
parents:
diff changeset
   201
	test.Close();
hgs
parents:
diff changeset
   202
hgs
parents:
diff changeset
   203
	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore
hgs
parents:
diff changeset
   204
hgs
parents:
diff changeset
   205
	if( commandLine )
hgs
parents:
diff changeset
   206
	CleanupStack::PopAndDestroy(commandLine);
hgs
parents:
diff changeset
   207
	
hgs
parents:
diff changeset
   208
	LOG_MSG("EXIT: t_multi_agent_launcher MainL()");
hgs
parents:
diff changeset
   209
	}
hgs
parents:
diff changeset
   210
 
hgs
parents:
diff changeset
   211
GLDEF_C TInt E32Main()
hgs
parents:
diff changeset
   212
	{
hgs
parents:
diff changeset
   213
	LOG_MSG("ENTER: Multi_agent_launcher E32Main()");
hgs
parents:
diff changeset
   214
	__UHEAP_MARK;
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
	CTrapCleanup* trap = CTrapCleanup::New();
hgs
parents:
diff changeset
   217
	if (!trap)
hgs
parents:
diff changeset
   218
		return KErrNoMemory;
hgs
parents:
diff changeset
   219
hgs
parents:
diff changeset
   220
	TRAPD(err, MainL());
hgs
parents:
diff changeset
   221
	LOG_MSG2("Multi_agent_launcher: returning from MainL(), err = %d", err);
hgs
parents:
diff changeset
   222
	
hgs
parents:
diff changeset
   223
	delete trap;
hgs
parents:
diff changeset
   224
	LOG_MSG("EXIT: Multi_agent_launcher E32Main()");
hgs
parents:
diff changeset
   225
	__UHEAP_MARKEND;
hgs
parents:
diff changeset
   226
hgs
parents:
diff changeset
   227
	return err;
hgs
parents:
diff changeset
   228
	}
hgs
parents:
diff changeset
   229