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