|
1 // Copyright (c) 2006-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 // Test the ability of the debug system to handle events from several debug targets |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32base.h> |
|
19 #include <e32property.h> |
|
20 |
|
21 #include <hal.h> |
|
22 #include <e32test.h> |
|
23 |
|
24 #include "t_multi_target.h" |
|
25 #include "t_target_launcher.h" |
|
26 #include "t_rmdebug_app.h" |
|
27 |
|
28 #ifdef KERNEL_OOM_TESTING |
|
29 #ifdef USER_OOM_TESTING |
|
30 #error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING" |
|
31 #endif |
|
32 #endif |
|
33 |
|
34 |
|
35 using namespace Debug; |
|
36 |
|
37 const TVersion securityServerVersion(0,1,1); |
|
38 |
|
39 const TVersion testVersion(2,1,0); |
|
40 |
|
41 #ifdef NO_DEBUGTOKEN |
|
42 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET")); |
|
43 #endif |
|
44 |
|
45 #ifdef SOMECAPS_DEBUGTOKEN |
|
46 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM")); |
|
47 #endif |
|
48 |
|
49 #ifdef FEWCAPS_DEBUGTOKEN |
|
50 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM2")); |
|
51 #endif |
|
52 |
|
53 |
|
54 |
|
55 CMultiTargetAgent* CMultiTargetAgent::NewL() |
|
56 // |
|
57 // CMultiTargetAgent::NewL |
|
58 // |
|
59 { |
|
60 CMultiTargetAgent* self = new(ELeave) CMultiTargetAgent(); |
|
61 |
|
62 self->ConstructL(); |
|
63 |
|
64 return self; |
|
65 } |
|
66 |
|
67 |
|
68 CMultiTargetAgent::~CMultiTargetAgent() |
|
69 // |
|
70 // CMultiTargetAgent destructor |
|
71 // |
|
72 { |
|
73 RDebug::Printf("~CMultiTargetAgent\n"); |
|
74 iServSession.Close(); |
|
75 } |
|
76 |
|
77 |
|
78 CMultiTargetAgent::CMultiTargetAgent() : |
|
79 iEventPtr( (TUint8*)&iEventInfo, sizeof(TEventInfo) ) |
|
80 { |
|
81 } |
|
82 |
|
83 |
|
84 void CMultiTargetAgent::ConstructL() |
|
85 // |
|
86 // CMultiTargetAgent::ConstructL |
|
87 // |
|
88 { |
|
89 } |
|
90 |
|
91 /** |
|
92 * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second. |
|
93 * |
|
94 * @return Number of nanokernel ticks. 0 if unsuccesful. |
|
95 */ |
|
96 TInt CMultiTargetAgent::HelpTicksPerSecond(void) |
|
97 { |
|
98 TInt nanokernel_tick_period; |
|
99 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period); |
|
100 |
|
101 ASSERT(nanokernel_tick_period != 0); |
|
102 |
|
103 static const TInt KOneMillion = 1000000; |
|
104 |
|
105 return KOneMillion/nanokernel_tick_period; |
|
106 } |
|
107 |
|
108 void CMultiTargetAgent::ClientAppL() |
|
109 // |
|
110 // Performs each test in turn |
|
111 // |
|
112 { |
|
113 test.Start(_L("ClientAppL")); |
|
114 TInt err = iServSession.Connect(securityServerVersion); |
|
115 if (err != KErrNone) |
|
116 { |
|
117 User::Panic(_L("Can't open server session"), err); |
|
118 } |
|
119 SetupDebugServerL(); |
|
120 LaunchTargetsInOrderL(); |
|
121 RDebug::Printf( "returning from CMultiTargetAgent::ClientAppL" ); |
|
122 test.End(); |
|
123 } |
|
124 |
|
125 /** |
|
126 Launch a process |
|
127 |
|
128 @param aProcess The RProcess object to use to create the process |
|
129 @param aExeName File name of the executable to create the process from |
|
130 @param aCommandLine The command line to pass to the new process |
|
131 @return KErrNone on success, or one of the other system wide error codes |
|
132 */ |
|
133 TInt CMultiTargetAgent::LaunchProcess(RProcess& aProcess, TDesC & aExeName, TDesC & aCommandLine ) |
|
134 { |
|
135 TInt err = aProcess.Create( aExeName, aCommandLine ); |
|
136 if(err != KErrNone) |
|
137 { |
|
138 RDebug::Printf( "aProcess.Create ret %d", err); |
|
139 return err; |
|
140 } |
|
141 |
|
142 TRequestStatus status = KRequestPending; |
|
143 aProcess.Rendezvous(status); |
|
144 if(KRequestPending != status.Int()) |
|
145 { |
|
146 // startup failed so kill the process |
|
147 aProcess.Kill(KErrNone); |
|
148 return status.Int(); |
|
149 } |
|
150 else |
|
151 { |
|
152 // start up succeeded so resume the process |
|
153 aProcess.Resume(); |
|
154 // Give the process a chance to run |
|
155 User::After( 500000 ); |
|
156 return KErrNone; |
|
157 } |
|
158 } |
|
159 |
|
160 void CMultiTargetAgent::SetupDebugServerL() |
|
161 { |
|
162 RDebug::Printf( "CMultiTargetAgent::SetupDebugServerL" ); |
|
163 test.Next(_L("SetupDebugServerL\n")); |
|
164 iTargets.ReserveL( KNumApps ); |
|
165 |
|
166 RBuf targetName; |
|
167 CleanupClosePushL( targetName ); |
|
168 |
|
169 for( TInt numApps = 0; numApps < KNumApps; numApps++ ) |
|
170 { |
|
171 iTargets.AppendL( targetName ); |
|
172 RDebug::Printf( "Attach to DSS for app %d ", numApps ); |
|
173 |
|
174 iTargets[numApps].CreateL( KTargetExe().Length() + 2 ); |
|
175 iTargets[numApps].Format( KTargetExe(), numApps+1 ); |
|
176 |
|
177 TInt ret = iServSession.AttachExecutable( iTargets[numApps], EFalse ); |
|
178 test( ret == KErrNone ); |
|
179 |
|
180 RDebug::Printf( ">SetEventAction app %d, EEventsStartThread EActionSuspend", numApps ); |
|
181 ret = iServSession.SetEventAction( iTargets[numApps], EEventsStartThread, EActionSuspend ); |
|
182 test( ret == KErrNone ); |
|
183 |
|
184 RDebug::Printf( ">SetEventAction app %d, EEventsAddProcess EActionContinue", numApps ); |
|
185 ret = iServSession.SetEventAction( iTargets[numApps], EEventsAddProcess, EActionContinue ); |
|
186 test( ret == KErrNone ); |
|
187 |
|
188 RDebug::Printf( ">SetEventAction app %d, EEventsRemoveProcess EActionContinue", numApps ); |
|
189 ret = iServSession.SetEventAction( iTargets[numApps], EEventsRemoveProcess, EActionContinue ); |
|
190 test( ret == KErrNone ); |
|
191 } |
|
192 |
|
193 CleanupStack::PopAndDestroy( &targetName ); // targetName |
|
194 |
|
195 } |
|
196 |
|
197 |
|
198 |
|
199 TInt CMultiTargetAgent::LaunchTargetsInOrderL() |
|
200 { |
|
201 RDebug::Printf( "CMultiTargetAgent::LaunchTargetsInOrderL" ); |
|
202 |
|
203 RBuf launcher; |
|
204 CleanupClosePushL( launcher ); |
|
205 launcher.CreateL( KLauncherExe() ); |
|
206 |
|
207 RBuf launcherOptions; |
|
208 CleanupClosePushL( launcherOptions ); |
|
209 launcherOptions.CreateL( KTargetOptions().Length() + 2 ); |
|
210 launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit ); |
|
211 |
|
212 RDebug::Printf( ">LaunchProcess()" ); |
|
213 RProcess launcherProc; |
|
214 CleanupClosePushL( launcherProc ); |
|
215 |
|
216 TInt ret = LaunchProcess( launcherProc, launcher, launcherOptions ); |
|
217 RDebug::Printf( "<LaunchProcess() ret %d", ret ); |
|
218 |
|
219 CleanupStack::PopAndDestroy( &launcherProc ); // launcherProc |
|
220 CleanupStack::PopAndDestroy( &launcherOptions ); // launcherOptions |
|
221 CleanupStack::PopAndDestroy( &launcher ); //launcher |
|
222 |
|
223 test( ret == KErrNone ); |
|
224 |
|
225 RSemaphore launchSemaphore; |
|
226 CleanupClosePushL( launchSemaphore ); |
|
227 |
|
228 TFindSemaphore launchSemFinder( KLaunchSemaphoreNameSearchString ); |
|
229 TFullName semaphoreResult; |
|
230 ret = launchSemFinder.Next(semaphoreResult); |
|
231 RDebug::Printf( "> Find Launch Semaphote.Next ret=%d, %lS", ret, &semaphoreResult ); |
|
232 test( ret == KErrNone ); |
|
233 |
|
234 ret = launchSemaphore.OpenGlobal( semaphoreResult ); |
|
235 RDebug::Printf( "> OpenGlobal semaphore ret=%d", ret ); |
|
236 test( ret == KErrNone ); |
|
237 |
|
238 TBool thisLaunchCompleted; |
|
239 |
|
240 test.Next(_L("LaunchTargetsInOrderL\n")); |
|
241 for( TInt numLaunches = KNumLaunches; numLaunches > 0; numLaunches-- ) |
|
242 { |
|
243 for( TInt numApps = KNumApps; numApps > 0; numApps-- ) |
|
244 { |
|
245 thisLaunchCompleted = EFalse; |
|
246 // This will trigger the launcher app to launch the next target |
|
247 RDebug::Printf( " >Semaphore.Signal app=%d, launch=%d", numApps, numLaunches); |
|
248 launchSemaphore.Signal(); |
|
249 |
|
250 RBuf8 tgt8Name; |
|
251 CleanupClosePushL( tgt8Name ); |
|
252 |
|
253 RBuf tgtCollapseName; |
|
254 CleanupClosePushL( tgtCollapseName ); |
|
255 |
|
256 tgtCollapseName.CreateL( iTargets[numApps-1] ); |
|
257 tgt8Name.CreateL( tgtCollapseName.Collapse() ); |
|
258 |
|
259 |
|
260 while( ! thisLaunchCompleted ) |
|
261 { |
|
262 RDebug::Printf( ">GetEvent app %d for %S", numApps, &tgt8Name ); |
|
263 iServSession.GetEvent( iTargets[numApps-1], iStatus, iEventPtr ); |
|
264 |
|
265 // Wait for the target to get started. |
|
266 RDebug::Printf( " >Wait for event from target app=%d, launch=%d\n", numApps, numLaunches); |
|
267 User::WaitForRequest( iStatus ); |
|
268 RDebug::Printf( " <Wait for request returned with status %d", iStatus.Int() ); |
|
269 test( iStatus==KErrNone ); |
|
270 |
|
271 RDebug::Printf( " > Got iEventType =%d, app=%d", iEventInfo.iEventType, numApps ); |
|
272 switch( iEventInfo.iEventType ) |
|
273 { |
|
274 case EEventsAddProcess: |
|
275 { |
|
276 RDebug::Printf( "Got EEventsAddProcess" ); |
|
277 TPtrC8 exeNamePtr8( iEventInfo.iAddProcessInfo.iFileName, iEventInfo.iAddProcessInfo.iFileNameLength ); |
|
278 |
|
279 RBuf8 exeName8; |
|
280 CleanupClosePushL( exeName8 ); |
|
281 exeName8.CreateL( exeNamePtr8 ); |
|
282 RDebug::Printf( " from event: exeName8=%S", &exeName8 ); |
|
283 CleanupStack::PopAndDestroy( &exeName8 ); |
|
284 |
|
285 RBuf8 compareName8; |
|
286 CleanupClosePushL( compareName8 ); |
|
287 compareName8.CreateL( KTargetExeName().Length() + 10 ); |
|
288 compareName8.Format( KTargetExeName(), numApps ); |
|
289 RDebug::Printf( " comparing to: compareName8=%S", &compareName8 ); |
|
290 |
|
291 test( compareName8.CompareC( exeNamePtr8 ) == 0 ); |
|
292 CleanupStack::PopAndDestroy( &compareName8 ); |
|
293 |
|
294 RDebug::Printf( "Testing if event process id is valid" ); |
|
295 test( iEventInfo.iProcessIdValid ); |
|
296 RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) ); |
|
297 |
|
298 RProcess targetProc; |
|
299 ret = targetProc.Open( TProcessId( iEventInfo.iProcessId ) ); |
|
300 RDebug::Printf( "RProcess open ret=%d",ret ); |
|
301 targetProc.Close(); |
|
302 test( ret == KErrNone ); |
|
303 |
|
304 break; |
|
305 }//EEventsAddProcess |
|
306 |
|
307 case EEventsStartThread: |
|
308 { |
|
309 RDebug::Printf( "Got EEventsStartThread" ); |
|
310 |
|
311 TPtrC8 exeNamePtr8( iEventInfo.iStartThreadInfo.iFileName, iEventInfo.iStartThreadInfo.iFileNameLength ); |
|
312 RBuf8 exe8Name; |
|
313 CleanupClosePushL( exe8Name ); |
|
314 exe8Name.CreateL( exeNamePtr8 ); |
|
315 RDebug::Printf( " from event: exeName8=%S", &exe8Name ); |
|
316 CleanupStack::PopAndDestroy( &exe8Name ); |
|
317 |
|
318 test( tgt8Name.CompareC( exeNamePtr8 ) == 0 ); |
|
319 |
|
320 RDebug::Printf( "Testing if event process id is valid" ); |
|
321 test( iEventInfo.iProcessIdValid ); |
|
322 RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) ); |
|
323 |
|
324 RDebug::Printf( "Testing if event thread id is valid" ); |
|
325 test( iEventInfo.iThreadIdValid ); |
|
326 RDebug::Printf( "Got iEventInfo.iThreadId=%d", I64LOW( iEventInfo.iThreadId ) ); |
|
327 |
|
328 RThread targetThread; |
|
329 CleanupClosePushL( targetThread ); |
|
330 |
|
331 ret = targetThread.Open( TThreadId( iEventInfo.iThreadId ) ); |
|
332 RDebug::Printf( "RThread open ret=%d", ret ); |
|
333 test( ret == KErrNone ); |
|
334 |
|
335 test( iEventInfo.iThreadId == targetThread.Id() ); |
|
336 |
|
337 RDebug::Printf( "Resuming thread for app=%d, id=%d", numApps, I64LOW( targetThread.Id() )); |
|
338 ret = iServSession.ResumeThread( iEventInfo.iThreadId ); |
|
339 CleanupStack::PopAndDestroy( &targetThread ); |
|
340 |
|
341 test( ret == KErrNone ); |
|
342 |
|
343 ret = iServSession.ResumeThread( iEventInfo.iThreadId ); |
|
344 break; |
|
345 }//case EEventsStartThread |
|
346 |
|
347 case ( EEventsRemoveProcess ): |
|
348 { |
|
349 RDebug::Printf( "*** Got EEventsRemoveProcess. app%d has exited. Moving on to next app", numApps ); |
|
350 thisLaunchCompleted = ETrue; |
|
351 break; |
|
352 } |
|
353 |
|
354 default : |
|
355 RDebug::Printf( "Got unknown event" ); |
|
356 test( EFalse ); |
|
357 break; |
|
358 } |
|
359 }//while |
|
360 |
|
361 CleanupStack::PopAndDestroy( &tgtCollapseName ); // tgtCollapseName |
|
362 CleanupStack::PopAndDestroy( &tgt8Name ); // tgt8Name |
|
363 } |
|
364 } |
|
365 |
|
366 launchSemaphore.Signal(); |
|
367 |
|
368 CleanupStack::PopAndDestroy( &launchSemaphore ); // launchSemaphore |
|
369 |
|
370 for( TInt i = iTargets.Count()-1; i>=0; i-- ) |
|
371 { |
|
372 RDebug::Printf( "Closing target %d", i ); |
|
373 iTargets[ i ].Close(); |
|
374 } |
|
375 |
|
376 iTargets.Close(); |
|
377 |
|
378 return KErrNone; |
|
379 } |
|
380 |
|
381 |
|
382 GLDEF_C TInt E32Main() |
|
383 { |
|
384 TInt ret = KErrNone; |
|
385 |
|
386 |
|
387 CTrapCleanup* trap = CTrapCleanup::New(); |
|
388 if (!trap) |
|
389 return KErrNoMemory; |
|
390 test.Title(); |
|
391 |
|
392 CMultiTargetAgent *runModeAgent = CMultiTargetAgent::NewL(); |
|
393 if (runModeAgent != NULL) |
|
394 { |
|
395 __UHEAP_MARK; |
|
396 TRAP(ret,runModeAgent->ClientAppL()); |
|
397 __UHEAP_MARKEND; |
|
398 |
|
399 RDebug::Printf( "ClientAppL returned %d", ret ); |
|
400 delete runModeAgent; |
|
401 } |
|
402 |
|
403 delete trap; |
|
404 return ret; |
|
405 } |