|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This module contains implementation of CTestServer |
|
15 * class member functions. |
|
16 * |
|
17 */ |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <e32std.h> |
|
21 #include <e32svr.h> |
|
22 #include "TestEngineClient.h" |
|
23 #include <StifTestModule.h> |
|
24 #include <stifinternal/TestServerClient.h> |
|
25 #include "TestServer.h" |
|
26 #include "TestServerCommon.h" |
|
27 #include "TestServerModuleIf.h" |
|
28 |
|
29 // EXTERNAL DATA STRUCTURES |
|
30 |
|
31 // EXTERNAL FUNCTION PROTOTYPES |
|
32 |
|
33 // CONSTANTS |
|
34 |
|
35 // MACROS |
|
36 |
|
37 // LOCAL CONSTANTS AND MACROS |
|
38 |
|
39 // MODULE DATA STRUCTURES |
|
40 // Struct to pass parameters to server thread |
|
41 struct TThreadStartTestServerSession |
|
42 { |
|
43 RThread iServerThread; // The server thread |
|
44 RSemaphore iStarted; // Startup syncronisation semaphore |
|
45 TInt iStartupResult;// Start-up result |
|
46 }; |
|
47 |
|
48 // LOCAL FUNCTION PROTOTYPES |
|
49 |
|
50 // FORWARD DECLARATIONS |
|
51 |
|
52 // ==================== LOCAL FUNCTIONS ======================================= |
|
53 |
|
54 // None |
|
55 |
|
56 // ================= MEMBER FUNCTIONS ========================================= |
|
57 |
|
58 |
|
59 /* |
|
60 ------------------------------------------------------------------------------- |
|
61 |
|
62 Class: CTestModule |
|
63 |
|
64 Method: NewL |
|
65 |
|
66 Description: Create new Test Module |
|
67 |
|
68 Parameters: RThread& aClient :in: Handle to client |
|
69 CTestServer* aServer :in: Pointer to server |
|
70 |
|
71 Return Values: CTestModule* Pointer to new test module |
|
72 |
|
73 Errors/Exceptions: Leaves if memory allocation fails or ConstructL leaves. |
|
74 |
|
75 Status: Approved |
|
76 |
|
77 ------------------------------------------------------------------------------- |
|
78 */ |
|
79 CTestModule* CTestModule::NewL( CTestServer* aServer ) |
|
80 { |
|
81 |
|
82 CTestModule* self=new( ELeave ) CTestModule(); |
|
83 CleanupStack::PushL( self ); |
|
84 self->ConstructL( aServer ); |
|
85 CleanupStack::Pop(); |
|
86 return self; |
|
87 } |
|
88 |
|
89 /* |
|
90 ------------------------------------------------------------------------------- |
|
91 |
|
92 Class: CTestModule |
|
93 |
|
94 Method: CTestModule |
|
95 |
|
96 Description: Constructor. |
|
97 Initialise base class. |
|
98 |
|
99 Parameters: RThread& aClient :in: Handle to client |
|
100 |
|
101 Return Values: None |
|
102 |
|
103 Errors/Exceptions: None |
|
104 |
|
105 Status: Approved |
|
106 |
|
107 ------------------------------------------------------------------------------- |
|
108 */ |
|
109 CTestModule::CTestModule() : |
|
110 CSession2(), |
|
111 iIni(0, 0) |
|
112 { |
|
113 } |
|
114 |
|
115 /* |
|
116 ------------------------------------------------------------------------------- |
|
117 |
|
118 Class: CTestModule |
|
119 |
|
120 Method: ~CTestModule |
|
121 |
|
122 Description: Destructor. |
|
123 Deallocate memory and close handles. |
|
124 |
|
125 Parameters: None |
|
126 |
|
127 Return Values: None |
|
128 |
|
129 Errors/Exceptions: None. |
|
130 |
|
131 Status: Proposal |
|
132 |
|
133 ------------------------------------------------------------------------------- |
|
134 */ |
|
135 CTestModule::~CTestModule() |
|
136 { |
|
137 |
|
138 __TRACE( KVerbose, ( _L( "Closing test module" ) ) ); |
|
139 |
|
140 // Free test case related data. No error checking here, because if freeing |
|
141 // fails, then nothing can be done in destructor. |
|
142 FreeCaseData(); |
|
143 |
|
144 // Delete all test module instances. |
|
145 // Cleanup all RTestExecution has been opened by client but not properly |
|
146 // closed for example if timeout occurs and client died. This almost do |
|
147 // same than CloseSession() in "if( iTestExecutionHandle )" branch. |
|
148 if( iTestExecutionHandle ) |
|
149 { |
|
150 TInt handle = 0; |
|
151 CObject* theObj = NULL; |
|
152 TInt count = iTestExecutionHandle->Count(); |
|
153 |
|
154 for( TInt i = 0 ; i < count; i++ ) |
|
155 { |
|
156 // Get pointer to CTestExecution |
|
157 theObj=iTestExecutionHandle->operator[]( i ); |
|
158 if( theObj ) |
|
159 { |
|
160 handle=iTestExecutionHandle->At( theObj ); |
|
161 |
|
162 CTestExecution* testcase = (CTestExecution*) theObj; |
|
163 // Cancels test(s) execution(timeout, exit, etc) |
|
164 // For example TestCombiner is timeouted => TestCombiner's |
|
165 // TestServer+TestModule(s) should cancel also. |
|
166 testcase->CancelTestExecution(); |
|
167 // CTestExecution will panic if test case is ongoing!!! This |
|
168 // should be stopped, client should handless this. |
|
169 iTestExecutionHandle->Remove( handle ); |
|
170 } |
|
171 } |
|
172 |
|
173 delete iTestExecutionHandle; |
|
174 iTestExecutionHandle = NULL; |
|
175 |
|
176 } |
|
177 |
|
178 // Delete all FREE Test Module instances. |
|
179 if( iTestModuleInstances ) |
|
180 { |
|
181 iTestModuleInstances->ResetAndDestroy(); |
|
182 delete iTestModuleInstances; |
|
183 iTestModuleInstances = NULL; |
|
184 } |
|
185 |
|
186 // Delete ini file heap buffer |
|
187 delete iIniBuffer; |
|
188 iIniBuffer = NULL; |
|
189 |
|
190 // Delete array of test case titles |
|
191 iTestCaseTitles.ResetAndDestroy(); |
|
192 iTestCaseTitles.Close(); |
|
193 } |
|
194 |
|
195 /* |
|
196 ------------------------------------------------------------------------------- |
|
197 |
|
198 Class: CTestModule |
|
199 |
|
200 Method: ConstructL |
|
201 |
|
202 Description: Second level constructor. |
|
203 |
|
204 Parameters: CTestServer* aServer :in: Server |
|
205 |
|
206 Return Values: None |
|
207 |
|
208 Errors/Exceptions: Leaves if: |
|
209 base class CreateL leaves |
|
210 Object index creation fails |
|
211 Object container creation fails |
|
212 Pointer array construction fails |
|
213 |
|
214 Status: Approved |
|
215 |
|
216 ------------------------------------------------------------------------------- |
|
217 */ |
|
218 void CTestModule::ConstructL( CTestServer* aServer ) |
|
219 { |
|
220 |
|
221 __TRACE( KVerbose, ( _L( "CTestModule::ConstructL - constructing server session" ) ) ); |
|
222 |
|
223 // second-phase construct base class |
|
224 //CSession2::CreateL( /* *aServer */ ); |
|
225 iTestServer = aServer; |
|
226 |
|
227 // create new object index |
|
228 iTestExecutionHandle = CObjectIx::NewL(); |
|
229 |
|
230 // Initialize the object container using the object |
|
231 // container index in the server. |
|
232 iContainer = iTestServer->NewContainerL(); |
|
233 |
|
234 iTestModuleInstances = new( ELeave ) RPointerArray<CTestModuleContainer>; |
|
235 |
|
236 __TRACE( KError, ( _L( "CTestModule::ConstructL - constructing server session done" ) ) ); |
|
237 |
|
238 } |
|
239 |
|
240 |
|
241 /* |
|
242 ------------------------------------------------------------------------------- |
|
243 |
|
244 Class: CTestModule |
|
245 |
|
246 Method: CountResources |
|
247 |
|
248 Description: Resource counting |
|
249 |
|
250 Parameters: None |
|
251 |
|
252 Return Values: TInt Resource count |
|
253 |
|
254 Errors/Exceptions: None |
|
255 |
|
256 Status: Approved |
|
257 |
|
258 ------------------------------------------------------------------------------- |
|
259 */ |
|
260 TInt CTestModule::CountResources() |
|
261 { |
|
262 |
|
263 return iResourceCount; |
|
264 |
|
265 } |
|
266 |
|
267 |
|
268 /* |
|
269 ------------------------------------------------------------------------------- |
|
270 |
|
271 Class: CTestModule |
|
272 |
|
273 Method: NumResources |
|
274 |
|
275 Description: Get resources, writes to Message() |
|
276 |
|
277 Parameters: None |
|
278 |
|
279 Return Values: None |
|
280 |
|
281 Errors/Exceptions: Panic client if result can't be written to descriptor. |
|
282 |
|
283 Status: Approved |
|
284 |
|
285 ------------------------------------------------------------------------------- |
|
286 */ |
|
287 void CTestModule::NumResources( const RMessage2& aMessage ) |
|
288 { |
|
289 |
|
290 TPckgBuf<TInt> countPckg( iResourceCount ); |
|
291 |
|
292 TRAPD( r, aMessage.WriteL( 0, countPckg ) ); |
|
293 if( r !=KErrNone ) |
|
294 { |
|
295 PanicClient( EBadDescriptor, aMessage ); |
|
296 } |
|
297 |
|
298 } |
|
299 |
|
300 /* |
|
301 ------------------------------------------------------------------------------- |
|
302 |
|
303 Class: CTestModule |
|
304 |
|
305 Method: PanicClient |
|
306 |
|
307 Description: Panic clients. |
|
308 |
|
309 Parameters: TInt aPanic :in: Panic code |
|
310 |
|
311 Return Values: None |
|
312 |
|
313 Errors/Exceptions: None |
|
314 |
|
315 Status: Approved |
|
316 |
|
317 ------------------------------------------------------------------------------- |
|
318 */ |
|
319 void CTestModule::PanicClient( const TInt aPanic, const RMessage2& aMessage ) const |
|
320 { |
|
321 |
|
322 __TRACE( KError,( _L( "CTestModule::PanicClient code = %d" ), aPanic ) ); |
|
323 |
|
324 _LIT( KTxtTestModule,"CTestModule" ); |
|
325 |
|
326 aMessage.Panic( KTxtTestModule, aPanic ); |
|
327 } |
|
328 |
|
329 |
|
330 /* |
|
331 ------------------------------------------------------------------------------- |
|
332 |
|
333 Class: CTestModule |
|
334 |
|
335 Method: CloseSession |
|
336 |
|
337 Description: Close session |
|
338 |
|
339 Parameters: None |
|
340 |
|
341 Return Values: TInt: Symbian error code. |
|
342 |
|
343 Errors/Exceptions: None |
|
344 |
|
345 Status: Approved |
|
346 |
|
347 ------------------------------------------------------------------------------- |
|
348 */ |
|
349 TInt CTestModule::CloseSession( const RMessage2& aMessage ) |
|
350 { |
|
351 |
|
352 __TRACE( KMessage,( _L( "CTestModule::CloseSession in" ) ) ); |
|
353 |
|
354 // Delete all unclosed subsession handle before closing session. |
|
355 // Remove iTestExecutionHandle contents. iTestExecutionHandle countains |
|
356 // CTestExecution that handles test case have been created. |
|
357 if( iTestExecutionHandle ) |
|
358 { |
|
359 TInt handle = 0; |
|
360 CObject* theObj = NULL; |
|
361 TInt count = iTestExecutionHandle->Count(); |
|
362 |
|
363 for( TInt i = 0 ; i < count; i++ ) |
|
364 { |
|
365 theObj=iTestExecutionHandle->operator[]( i ); |
|
366 if( theObj ) |
|
367 { |
|
368 handle=iTestExecutionHandle->At( theObj ); |
|
369 // CTestExecution will panic if test case is ongoing!!! This |
|
370 // should be stopped, client should handle this. |
|
371 iTestExecutionHandle->Remove( handle ); |
|
372 } |
|
373 } |
|
374 |
|
375 delete iTestExecutionHandle; |
|
376 iTestExecutionHandle = NULL; |
|
377 |
|
378 } |
|
379 |
|
380 // Deletion must be done here, because the "CloseSession" message is |
|
381 // completed before execution continues from CActiveScheduler::Start |
|
382 // location, and the main thread can continue execution |
|
383 // and therefore shutdown itself and all threads in that process. |
|
384 |
|
385 // Delete the object container |
|
386 iTestServer->DeleteContainer( iContainer ); |
|
387 |
|
388 // Free test case related data |
|
389 TInt r = FreeCaseData(); |
|
390 |
|
391 // Delete all FREE Test Module instances |
|
392 iTestModuleInstances->ResetAndDestroy(); |
|
393 delete iTestModuleInstances; |
|
394 iTestModuleInstances = NULL; |
|
395 |
|
396 // Inform server that session is closed |
|
397 iTestServer->SessionClosed(); |
|
398 |
|
399 // Check for avoiding multiple complete, see CTestModule::ServiceL() |
|
400 if( r != KErrNone ) |
|
401 { |
|
402 // In error cases do not complete, just return |
|
403 __TRACE( KMessage,( _L( "CTestModule::CloseSession out (1)" ) ) ); |
|
404 return r; |
|
405 } |
|
406 |
|
407 aMessage.Complete( KErrNone ); |
|
408 |
|
409 // After active scheduler shutdown is done, execution continues from |
|
410 // CTestServer::ThreadFunction() |
|
411 |
|
412 __TRACE( KMessage,( _L( "CTestModule::CloseSession out (2)" ) ) ); |
|
413 return r; |
|
414 } |
|
415 |
|
416 |
|
417 /* |
|
418 ------------------------------------------------------------------------------- |
|
419 |
|
420 Class: CTestModule |
|
421 |
|
422 Method: ServiceL |
|
423 |
|
424 Description: Trap harness for dispatcher |
|
425 |
|
426 Parameters: const RMessage& aMessage :inout: Message |
|
427 |
|
428 Return Values: None |
|
429 |
|
430 Errors/Exceptions: None |
|
431 |
|
432 Status: Proposal |
|
433 |
|
434 ------------------------------------------------------------------------------- |
|
435 */ |
|
436 void CTestModule::ServiceL( const RMessage2& aMessage ) |
|
437 { |
|
438 |
|
439 // NOTE! HW testing slows down dramatically if adds commants here |
|
440 |
|
441 //__TRACE( KMessage,( _L( "CTestModule::ServiceL in" ) ) ); |
|
442 |
|
443 TInt r = KErrNone; |
|
444 TRAPD( ret, r = DispatchMessageL( aMessage ) ); |
|
445 |
|
446 if ( ret != KErrNone ) |
|
447 { |
|
448 // Complete message on leaving cases with leave code. |
|
449 __TRACE( KError, ( CStifLogger::ERed, _L( "CTestModule::DispatchMessageL leaved" ) ) ); |
|
450 aMessage.Complete( ret ); |
|
451 } |
|
452 |
|
453 // Complete message with error code originating from message handling |
|
454 // function. |
|
455 if ( r != KErrNone ) |
|
456 { |
|
457 __TRACE( KError, ( CStifLogger::ERed, _L( "CTestModule::DispatchMessageL returned error" ) ) ); |
|
458 aMessage.Complete( r ); |
|
459 } |
|
460 |
|
461 // __TRACE( KMessage,( _L( "CTestModule::ServiceL out" ) ) ); |
|
462 |
|
463 } |
|
464 |
|
465 |
|
466 /* |
|
467 ------------------------------------------------------------------------------- |
|
468 |
|
469 Class: CTestModule |
|
470 |
|
471 Method: DispatchMessageL |
|
472 |
|
473 Description: Dispatch message, calls corresponding function to do it. |
|
474 |
|
475 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
476 |
|
477 Return Values: TInt Error code |
|
478 |
|
479 Errors/Exceptions: Leaves if operation handling function leaves |
|
480 |
|
481 Status: Proposal |
|
482 |
|
483 ------------------------------------------------------------------------------- |
|
484 */ |
|
485 TInt CTestModule::DispatchMessageL( const RMessage2& aMessage ) |
|
486 { |
|
487 |
|
488 __TRACE( KMessage,( _L( "CTestModule::DispatchMessageL %d" ), |
|
489 aMessage.Function() ) ); |
|
490 switch( aMessage.Function() ) |
|
491 { |
|
492 // Session specific |
|
493 case ETestServerCloseSession: // Close whole session |
|
494 { |
|
495 __TRACE( KError ,( _L( "Closing test module session" ) ) ); |
|
496 return CloseSession( aMessage ); |
|
497 } |
|
498 case ETestServerGetServerThreadId: // Get Server ThreadId |
|
499 { |
|
500 __TRACE( KError ,( _L( "Return server thread id" ) ) ); |
|
501 return GetServerThreadIdL( aMessage ); |
|
502 } |
|
503 |
|
504 case ETestModuleCreateSubSession : // Create new test module subsession |
|
505 { |
|
506 __TRACE( KError,( _L( "Creating test module session" ) ) ); |
|
507 return CreateModuleSessionL( aMessage ); |
|
508 } |
|
509 |
|
510 case ETestModuleCloseSubSession: // Close module subsession |
|
511 { |
|
512 // Nothing to do. |
|
513 aMessage.Complete( KErrNone ); |
|
514 return KErrNone; |
|
515 } |
|
516 |
|
517 case ETestExecutionCreateSubSession: // Create new test execution subsession |
|
518 { |
|
519 return NewTestExecutionL( aMessage ); |
|
520 } |
|
521 |
|
522 case ETestModuleEnumerateTestCases: // Enumerate test cases |
|
523 { |
|
524 __TRACE( KError,( _L( "Enumerating test cases" ) ) ); |
|
525 return EnumerateTestCasesL( aMessage ); |
|
526 } |
|
527 |
|
528 case ETestModuleGetTestCases: // Get test cases |
|
529 { |
|
530 return GetTestCasesL( aMessage ); |
|
531 } |
|
532 |
|
533 case ETestModuleErrorNotification: // Request error notification |
|
534 { |
|
535 return HandleErrorNotificationL( aMessage ); |
|
536 } |
|
537 |
|
538 case ETestModuleCancelAsyncRequest: |
|
539 { |
|
540 return CancelAsyncRequestL( aMessage ); |
|
541 } |
|
542 |
|
543 // Subsession specific |
|
544 case ETestExecutionRunTestCase: // Run test case |
|
545 { |
|
546 __TRACE( KInit,( _L( "Running test case" ) ) ); |
|
547 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
548 return testCase->RunTestCase( aMessage ); |
|
549 } |
|
550 |
|
551 case ETestExecutionNotifyProgress: // Test case prints |
|
552 { |
|
553 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
554 return testCase->NotifyPrint( aMessage ); |
|
555 } |
|
556 |
|
557 case ETestExecutionNotifyEvent: // Event notifications |
|
558 { |
|
559 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
560 return testCase->NotifyEvent( aMessage ); |
|
561 } |
|
562 |
|
563 case ETestExecutionNotifyRemoteCmd: // RemoteCmd notifications |
|
564 { |
|
565 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
566 return testCase->NotifyRemoteCmd( aMessage ); |
|
567 } |
|
568 case ETestExecutionReadRemoteCmdInfo: // RemoteCmd reading |
|
569 { |
|
570 //CTestExecution* testCase=CaseFromHandle( aMessage.Int3() ); |
|
571 //return testCase->NotifyRemoteCmd( aMessage ); |
|
572 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
573 return testCase->ReadRemoteCmdInfo( aMessage ); |
|
574 } |
|
575 |
|
576 |
|
577 case ETestExecutionResume: // Resume case execution |
|
578 { |
|
579 __TRACE( KVerbose,( _L( "Resuming test execution" ) ) ); |
|
580 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
581 return testCase->Resume( aMessage ); |
|
582 } |
|
583 |
|
584 case ETestExecutionPause: // Pause case execution |
|
585 { |
|
586 __TRACE( KVerbose,( _L( "Pausing test execution" ) ) ); |
|
587 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
588 return testCase->Pause( aMessage ); |
|
589 } |
|
590 |
|
591 case ETestExecutionCloseSubSession: // Close execution subsession |
|
592 { |
|
593 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
594 return testCase->CloseTestExecution( aMessage ); |
|
595 } |
|
596 |
|
597 case ETestExecutionCancelAsyncRequest: // Cancel async request |
|
598 { |
|
599 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
600 return testCase->CancelRequestL( aMessage ); |
|
601 } |
|
602 case ETestExecutionNotifyCommand: // Command notifications |
|
603 { |
|
604 CTestExecution* testCase=CaseFromHandle( aMessage.Int3(), aMessage ); |
|
605 return testCase->NotifyCommand( aMessage ); |
|
606 } |
|
607 |
|
608 default: // Invalid request |
|
609 { |
|
610 PanicClient( EBadRequest, aMessage ); |
|
611 return KErrNotSupported; |
|
612 } |
|
613 } |
|
614 |
|
615 } |
|
616 |
|
617 |
|
618 /* |
|
619 ------------------------------------------------------------------------------- |
|
620 |
|
621 Class: CTestModule |
|
622 |
|
623 Method: EnumerateTestCases |
|
624 |
|
625 Description: Enumerates test cases and returns test case count by writing |
|
626 result to client side package. |
|
627 |
|
628 Function obtains a TestModule and calls EnumerateTestCases from it. |
|
629 Test module will be released when calling GetTestCases function. |
|
630 |
|
631 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
632 |
|
633 Return Values: TInt Operation result |
|
634 |
|
635 Errors/Exceptions: None |
|
636 |
|
637 Status: Proposal |
|
638 |
|
639 ------------------------------------------------------------------------------- |
|
640 */ |
|
641 TInt CTestModule::EnumerateTestCasesL( const RMessage2& aMessage ) |
|
642 { |
|
643 |
|
644 __TRACE( KMessage,( _L( "CTestModule::EnumerateTestCasesL in" ) ) ); |
|
645 |
|
646 // Get data from message |
|
647 TFileName config; |
|
648 TRAPD( res, aMessage.ReadL( 0, config ) ); |
|
649 if( res != KErrNone ) |
|
650 { |
|
651 PanicClient( EBadDescriptor, aMessage ); |
|
652 return res; |
|
653 } |
|
654 |
|
655 // Free old case data |
|
656 User::LeaveIfError( FreeCaseData() ); |
|
657 |
|
658 // Get test cases from the test module |
|
659 User::LeaveIfError( GetTestModule( iEnumerateModule, config ) ); |
|
660 |
|
661 // Enumerate test cases |
|
662 iEnumerateModule->EnumerateTestCases( config ); |
|
663 |
|
664 // Something fatal? |
|
665 TInt r = iEnumerateModule->OperationErrorResult(); |
|
666 if( r != KErrNone ) |
|
667 { |
|
668 // Enumeration module have crashed. |
|
669 delete iEnumerateModule; |
|
670 iEnumerateModule = NULL; |
|
671 |
|
672 return r; |
|
673 } |
|
674 |
|
675 // Error from module? |
|
676 if( iEnumerateModule->ModuleResult() != KErrNone ) |
|
677 { |
|
678 return iEnumerateModule->ModuleResult(); |
|
679 } |
|
680 |
|
681 // Write count to Ptr1() |
|
682 const RPointerArray<TTestCaseInfo>* testCases = iEnumerateModule->TestCases(); |
|
683 |
|
684 if( testCases == NULL ) |
|
685 { |
|
686 User::Leave( KErrGeneral ); |
|
687 } |
|
688 |
|
689 // Store titles (for further use, i.e. when asked for title from the interface via CTestModuleIf->CTestThreadContainer->CTestModuleContainer) |
|
690 iTestCaseTitles.ResetAndDestroy(); |
|
691 TInt i; |
|
692 for(i = 0; i < testCases->Count(); i++) |
|
693 { |
|
694 //Handle situation when test cases are enumerated not as 0-based (testscripter, ...) |
|
695 if(i == 0 && (*testCases)[i]->iCaseNumber > 0) |
|
696 { |
|
697 iTestCaseTitles.Append(NULL); |
|
698 } |
|
699 HBufC* title = (*testCases)[i]->iTitle.AllocL(); |
|
700 iTestCaseTitles.Append(title); |
|
701 } |
|
702 |
|
703 TPckgBuf<TInt> countPckg( testCases->Count() ); |
|
704 TRAP( res, aMessage.WriteL( 1, countPckg ) ); |
|
705 if( res != KErrNone ) |
|
706 { |
|
707 PanicClient( EBadDescriptor, aMessage ); |
|
708 return res; |
|
709 } |
|
710 |
|
711 // All ok, complete message |
|
712 aMessage.Complete( KErrNone ); |
|
713 |
|
714 __TRACE( KMessage,( _L( "CTestModule::EnumerateTestCasesL out" ) ) ); |
|
715 |
|
716 return KErrNone; |
|
717 |
|
718 } |
|
719 |
|
720 |
|
721 /* |
|
722 ------------------------------------------------------------------------------- |
|
723 |
|
724 Class: CTestModule |
|
725 |
|
726 Method: GetTestCasesL |
|
727 |
|
728 Description: Get test cases. Enumerate test cases must be called before |
|
729 calling this function. |
|
730 |
|
731 Function releases the test module reserved by EnumerateTestCase(). |
|
732 |
|
733 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
734 |
|
735 Return Values: TInt Operation result |
|
736 |
|
737 Errors/Exceptions: Leaves if cases have not been enumerated. |
|
738 |
|
739 Status: Proposal |
|
740 |
|
741 ------------------------------------------------------------------------------- |
|
742 */ |
|
743 TInt CTestModule::GetTestCasesL( const RMessage2& aMessage ) |
|
744 { |
|
745 |
|
746 __TRACE( KMessage,( _L( "CTestModule::GetTestCasesL in" ) ) ); |
|
747 |
|
748 // Leave if cases have not been enumerated. |
|
749 //User::LeaveIfNull(( TAny* ) iEnumerateModule->TestCases() ); |
|
750 if( ( TAny* ) iEnumerateModule->TestCases() == NULL ) |
|
751 { |
|
752 User::Leave( KErrGeneral ); |
|
753 } |
|
754 |
|
755 const TInt len = sizeof( TTestCaseInfo ); |
|
756 |
|
757 // Get cases |
|
758 const RPointerArray<TTestCaseInfo>& cases = *iEnumerateModule->TestCases(); |
|
759 |
|
760 // Get number of cases |
|
761 const TInt Kcount = cases.Count(); |
|
762 |
|
763 // Loop through case and copy then to client's descriptor. |
|
764 for( TInt i = 0; i < Kcount; i++ ) |
|
765 { |
|
766 |
|
767 // Construct package for source data |
|
768 TTestCaseInfoPckg tmpPackage( *cases[i] ); |
|
769 |
|
770 // Write to correct location |
|
771 aMessage.WriteL( 0, tmpPackage, i *len ); |
|
772 |
|
773 } |
|
774 |
|
775 // Free case data and the test module |
|
776 User::LeaveIfError( FreeCaseData() ); |
|
777 |
|
778 // Finished |
|
779 aMessage.Complete( KErrNone ); |
|
780 |
|
781 __TRACE( KMessage,( _L( "CTestModule::GetTestCasesL out" ) ) ); |
|
782 |
|
783 return KErrNone; |
|
784 |
|
785 } |
|
786 |
|
787 |
|
788 /* |
|
789 ------------------------------------------------------------------------------- |
|
790 |
|
791 Class: CTestModule |
|
792 |
|
793 Method: HandleErrorNotification |
|
794 |
|
795 Description: Request error notification. |
|
796 |
|
797 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
798 |
|
799 Return Values: TInt Operation result |
|
800 |
|
801 Errors/Exceptions: None |
|
802 |
|
803 Status: Proposal |
|
804 |
|
805 ------------------------------------------------------------------------------- |
|
806 */ |
|
807 TInt CTestModule::HandleErrorNotificationL( const RMessage2& aMessage ) |
|
808 { |
|
809 |
|
810 iErrorMessage = aMessage; |
|
811 iErrorMessageAvailable = ETrue; |
|
812 |
|
813 return KErrNone; |
|
814 |
|
815 } |
|
816 |
|
817 /* |
|
818 ------------------------------------------------------------------------------- |
|
819 |
|
820 Class: CTestModule |
|
821 |
|
822 Method: GetServerThreadId |
|
823 |
|
824 Description: Request server state notification. |
|
825 |
|
826 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
827 |
|
828 Return Values: TInt Operation result |
|
829 |
|
830 Errors/Exceptions: None |
|
831 |
|
832 Status: Proposal |
|
833 |
|
834 ------------------------------------------------------------------------------- |
|
835 */ |
|
836 TInt CTestModule::GetServerThreadIdL( const RMessage2& aMessage ) |
|
837 { |
|
838 |
|
839 TInt id( iTestServer->GetServerThreadId() ); |
|
840 |
|
841 TPckg<TThreadId> threadIdPckg( id ); |
|
842 |
|
843 TRAPD( res, aMessage.WriteL( 0, threadIdPckg ) ); |
|
844 |
|
845 // Finished |
|
846 aMessage.Complete( res ); |
|
847 |
|
848 return KErrNone; |
|
849 |
|
850 } |
|
851 |
|
852 /* |
|
853 ------------------------------------------------------------------------------- |
|
854 |
|
855 Class: CTestModule |
|
856 |
|
857 Method: CancelAsyncRequest |
|
858 |
|
859 Description: Cancels asynchronous request |
|
860 |
|
861 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
862 |
|
863 Return Values: TInt Operation result |
|
864 |
|
865 Errors/Exceptions: None |
|
866 |
|
867 Status: Proposal |
|
868 |
|
869 ------------------------------------------------------------------------------- |
|
870 */ |
|
871 TInt CTestModule::CancelAsyncRequestL( const RMessage2& aMessage ) |
|
872 { |
|
873 |
|
874 switch ( aMessage.Int0() ) |
|
875 { |
|
876 case ETestModuleErrorNotification: |
|
877 { |
|
878 if ( iErrorMessageAvailable ) |
|
879 { |
|
880 iErrorMessage.Complete ( KErrCancel ); |
|
881 iErrorMessageAvailable = EFalse; |
|
882 } |
|
883 aMessage.Complete ( KErrNone ); |
|
884 break; |
|
885 } |
|
886 |
|
887 default: |
|
888 { |
|
889 PanicClient( EInvalidRequestCancel, aMessage ); |
|
890 break; |
|
891 } |
|
892 } |
|
893 |
|
894 return KErrNone; |
|
895 |
|
896 } |
|
897 |
|
898 /* |
|
899 ------------------------------------------------------------------------------- |
|
900 |
|
901 Class: CTestModule |
|
902 |
|
903 Method: ErrorPrint |
|
904 |
|
905 Description: Prints error |
|
906 |
|
907 Parameters: const TInt aPriority :in: Priority |
|
908 TPtrC aError: in: Error |
|
909 |
|
910 Return Values: None |
|
911 |
|
912 Errors/Exceptions: None |
|
913 |
|
914 Status: Proposal |
|
915 |
|
916 ------------------------------------------------------------------------------- |
|
917 */ |
|
918 void CTestModule::ErrorPrint( const TInt aPriority, |
|
919 TPtrC aError ) |
|
920 { |
|
921 |
|
922 if ( iErrorMessageAvailable ) |
|
923 { |
|
924 TErrorNotification error; |
|
925 TErrorNotificationPckg errorPckg ( error ); |
|
926 |
|
927 error.iModule = _L("TestServer"); |
|
928 error.iPriority = aPriority; |
|
929 error.iText = aError; |
|
930 |
|
931 TRAPD( r, iErrorMessage.WriteL( 0, errorPckg ) ); |
|
932 |
|
933 // Do not handle errors |
|
934 iErrorMessageAvailable = EFalse; |
|
935 iErrorMessage.Complete( r ); |
|
936 |
|
937 } |
|
938 else |
|
939 { |
|
940 RDebug::Print (_L("Error message lost %d [%S]"), aPriority, &aError ); |
|
941 } |
|
942 |
|
943 } |
|
944 |
|
945 /* |
|
946 ------------------------------------------------------------------------------- |
|
947 |
|
948 Class: CTestModule |
|
949 |
|
950 Method: FreeCaseData |
|
951 |
|
952 Description: Frees the test case data and test module that is used in |
|
953 enumeration. |
|
954 |
|
955 Parameters: None |
|
956 |
|
957 Return Values: TInt Error code |
|
958 |
|
959 Errors/Exceptions: None |
|
960 |
|
961 Status: Proposal |
|
962 |
|
963 ------------------------------------------------------------------------------- |
|
964 */ |
|
965 TInt CTestModule::FreeCaseData() |
|
966 { |
|
967 |
|
968 __TRACE( KMessage,( _L( "CTestModule::FreeCaseData in" ) ) ); |
|
969 |
|
970 TInt r = KErrNone; |
|
971 |
|
972 if( iEnumerateModule ) |
|
973 { |
|
974 |
|
975 // Deallocate testcase memory |
|
976 iEnumerateModule->FreeEnumerationData(); |
|
977 |
|
978 // Free the module |
|
979 r = FreeTestModule( iEnumerateModule ); |
|
980 |
|
981 iEnumerateModule = NULL; |
|
982 |
|
983 } |
|
984 |
|
985 __TRACE( KMessage,( _L( "CTestModule::FreeCaseData out" ) ) ); |
|
986 |
|
987 return r; |
|
988 |
|
989 } |
|
990 |
|
991 |
|
992 /* |
|
993 ------------------------------------------------------------------------------- |
|
994 |
|
995 Class: CTestModule |
|
996 |
|
997 Method: CreateModuleSessionL |
|
998 |
|
999 Description: Creates a new module session. |
|
1000 Just take the initialisation file name from message. |
|
1001 |
|
1002 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
1003 |
|
1004 Return Values: TInt Operation result |
|
1005 |
|
1006 Errors/Exceptions: Leaves if memory allocation fails |
|
1007 |
|
1008 Status: Proposal |
|
1009 |
|
1010 ------------------------------------------------------------------------------- |
|
1011 */ |
|
1012 TInt CTestModule::CreateModuleSessionL( const RMessage2& aMessage ) |
|
1013 { |
|
1014 |
|
1015 __TRACE( KMessage,( _L( "CTestModule::CreateModuleSession in" ) ) ); |
|
1016 |
|
1017 // Take parameters |
|
1018 TFileName ini; |
|
1019 TRAPD( res, aMessage.ReadL( 0, ini ) ); |
|
1020 if( res != KErrNone ) |
|
1021 { |
|
1022 PanicClient( EBadDescriptor, aMessage ); |
|
1023 return res; |
|
1024 } |
|
1025 |
|
1026 // Construct heap buffer for initialization file name |
|
1027 iIniBuffer = HBufC::NewL( ini.Length() ); |
|
1028 iIni.Set ( iIniBuffer->Des() ); |
|
1029 iIni.Copy ( ini ); |
|
1030 |
|
1031 aMessage.Complete( KErrNone ); |
|
1032 |
|
1033 __TRACE( KMessage,( _L( "CTestModule::CreateModuleSession out" ) ) ); |
|
1034 |
|
1035 return KErrNone; |
|
1036 |
|
1037 } |
|
1038 |
|
1039 /* |
|
1040 ------------------------------------------------------------------------------- |
|
1041 |
|
1042 Class: CTestModule |
|
1043 |
|
1044 Method: NewTestExecutionL |
|
1045 |
|
1046 Description: Create new test execution subsession |
|
1047 |
|
1048 Parameters: const RMessage& aMessage :inout: Message to be handled |
|
1049 |
|
1050 Return Values: TInt Operation result |
|
1051 |
|
1052 Errors/Exceptions: Function leaves if object can't be created or |
|
1053 it can't be added to container. |
|
1054 Function panics client if message contains invalid |
|
1055 descriptor. |
|
1056 |
|
1057 Status: Proposal |
|
1058 |
|
1059 ------------------------------------------------------------------------------- |
|
1060 */ |
|
1061 TInt CTestModule::NewTestExecutionL( const RMessage2& aMessage ) |
|
1062 { |
|
1063 |
|
1064 __TRACE( KMessage,( _L( "CTestModule::NewTestExecutionL in" ) ) ); |
|
1065 |
|
1066 // Get data from message |
|
1067 TInt caseNumber = aMessage.Int0(); |
|
1068 TFileName config; |
|
1069 |
|
1070 TRAPD( res, aMessage.ReadL( 1, config ) ); |
|
1071 if( res != KErrNone ) |
|
1072 { |
|
1073 PanicClient( EBadDescriptor, aMessage ); |
|
1074 return res; |
|
1075 } |
|
1076 |
|
1077 // Make new object |
|
1078 CTestExecution* execution=CTestExecution::NewL( this, caseNumber, config ); |
|
1079 |
|
1080 // add object to object container to generate unique id |
|
1081 iContainer->AddL( execution ); |
|
1082 |
|
1083 // add object to object index; this returns a unique handle so we can get it again |
|
1084 TInt handle=iTestExecutionHandle->AddL( execution ); |
|
1085 |
|
1086 // write the handle to client |
|
1087 TPckg<TInt> handlePckg( handle ); |
|
1088 TRAP( res, aMessage.WriteL( 3, handlePckg ) ); |
|
1089 if( res != KErrNone ) |
|
1090 { |
|
1091 iTestExecutionHandle->Remove( handle ); |
|
1092 PanicClient( EBadDescriptor, aMessage ); |
|
1093 return res; |
|
1094 } |
|
1095 |
|
1096 // notch up another resource |
|
1097 iResourceCount++; |
|
1098 |
|
1099 // Complete message |
|
1100 aMessage.Complete( KErrNone ); |
|
1101 |
|
1102 __TRACE( KMessage,( _L( "CTestModule::NewTestExecutionL out" ) ) ); |
|
1103 |
|
1104 return KErrNone; |
|
1105 } |
|
1106 |
|
1107 /* |
|
1108 ------------------------------------------------------------------------------- |
|
1109 |
|
1110 Class: CTestModule |
|
1111 |
|
1112 Method: DeleteTestExecution |
|
1113 |
|
1114 Description: Deletes Test Execution by handle |
|
1115 |
|
1116 Parameters: const TUint aHandle :in: Handle |
|
1117 |
|
1118 Return Values: None |
|
1119 |
|
1120 Errors/Exceptions: Panics client if invalid handle |
|
1121 |
|
1122 Status: Proposal |
|
1123 |
|
1124 ------------------------------------------------------------------------------- |
|
1125 */ |
|
1126 void CTestModule::DeleteTestExecution( const TUint aHandle, const RMessage2& aMessage ) |
|
1127 { |
|
1128 |
|
1129 // Verify that handle is valid |
|
1130 CaseFromHandle( aHandle, aMessage ); |
|
1131 |
|
1132 // Remove object |
|
1133 iTestExecutionHandle->Remove( aHandle ); |
|
1134 |
|
1135 // Decrement resource count. |
|
1136 iResourceCount--; |
|
1137 |
|
1138 } |
|
1139 |
|
1140 |
|
1141 /* |
|
1142 ------------------------------------------------------------------------------- |
|
1143 |
|
1144 Class: CTestModule |
|
1145 |
|
1146 Method: CaseFromHandle |
|
1147 |
|
1148 Description: Return subsession from handle |
|
1149 |
|
1150 Parameters: const TUint aHandle :in: Handle |
|
1151 |
|
1152 Return Values: CTestExecution* Test Execution object |
|
1153 |
|
1154 Errors/Exceptions: Function panics client if invalid handle. |
|
1155 |
|
1156 Status: Approved |
|
1157 |
|
1158 ------------------------------------------------------------------------------- |
|
1159 */ |
|
1160 CTestExecution* CTestModule::CaseFromHandle( const TUint aHandle, const RMessage2& aMessage ) const |
|
1161 { |
|
1162 |
|
1163 CTestExecution* testcase =( CTestExecution* ) iTestExecutionHandle->At( aHandle ); |
|
1164 |
|
1165 if( testcase == NULL ) |
|
1166 { |
|
1167 PanicClient( EBadSubsessionHandle, aMessage ); |
|
1168 } |
|
1169 |
|
1170 return testcase; |
|
1171 |
|
1172 } |
|
1173 |
|
1174 |
|
1175 /* |
|
1176 ------------------------------------------------------------------------------- |
|
1177 |
|
1178 Class: CTestModule |
|
1179 |
|
1180 Method: GetTestModule |
|
1181 |
|
1182 Description: Gets a CTestModuleBase*. If there is a free entry |
|
1183 in the free list, then it is returned. Otherwise a new one is created. |
|
1184 |
|
1185 Parameters: CTestModuleContainer*& aContainer: out: container pointer. |
|
1186 const TDesC& aConfig: in: Test case (config) file name. |
|
1187 |
|
1188 Return Values: Symbian OS error code |
|
1189 |
|
1190 Errors/Exceptions: None |
|
1191 |
|
1192 Status: Proposal |
|
1193 |
|
1194 ------------------------------------------------------------------------------- |
|
1195 */ |
|
1196 TInt CTestModule::GetTestModule( CTestModuleContainer*& aContainer, |
|
1197 const TDesC& aConfig ) |
|
1198 { |
|
1199 TInt ret = KErrNone; |
|
1200 |
|
1201 if( iTestModuleInstances->Count() ) |
|
1202 { |
|
1203 // Return an existing one |
|
1204 aContainer =( *iTestModuleInstances )[0]; |
|
1205 iTestModuleInstances->Remove( 0 ); |
|
1206 __TRACE( KInit,( _L( "Reusing old test module container instance at 0x%x" ), (TUint32) aContainer ) ); |
|
1207 } |
|
1208 else |
|
1209 { |
|
1210 // Create a new one |
|
1211 __TRACE( KInit,( _L( "Creating new test module instance" ) ) ); |
|
1212 TRAPD( err, aContainer = CTestModuleContainer::NewL( |
|
1213 iTestServer->ModuleName(), |
|
1214 this, |
|
1215 aConfig ) ); |
|
1216 |
|
1217 // If module can't be created, then return NULL. |
|
1218 if( err ) |
|
1219 { |
|
1220 __TRACE( KError,( _L( "Can't create new test module container instance" ) ) ); |
|
1221 aContainer = NULL; |
|
1222 ret = err; |
|
1223 } |
|
1224 else |
|
1225 { |
|
1226 __TRACE( KInit,( _L( "Test module instance container created" ) ) ); |
|
1227 } |
|
1228 |
|
1229 if( aContainer ) |
|
1230 { |
|
1231 |
|
1232 // Initialise module |
|
1233 aContainer->Initialize( iTestServer->ModuleName(), iTestServer->FirstTime() ); |
|
1234 |
|
1235 if( aContainer->OperationErrorResult() != KErrNone ) |
|
1236 { |
|
1237 // Can't initialise module, delete it |
|
1238 __TRACE( KError,( CStifLogger::ERed, _L( "Operation error, can't initialize test module container instance" ) ) ); |
|
1239 ret = aContainer->OperationErrorResult(); |
|
1240 delete aContainer; |
|
1241 aContainer = NULL; |
|
1242 } |
|
1243 else if( aContainer->ModuleResult() != KErrNone ) |
|
1244 { |
|
1245 // Can't initialise module, delete it |
|
1246 __TRACE( KError,( CStifLogger::ERed, _L( "Module error, can't initialize test module container instance" ) ) ); |
|
1247 ret = aContainer->ModuleResult(); |
|
1248 delete aContainer; |
|
1249 aContainer = NULL; |
|
1250 } |
|
1251 else |
|
1252 { |
|
1253 // Module initialised properly, clear the first time flag. |
|
1254 iTestServer->ClearFirstTime(); |
|
1255 __TRACE( KInit,( _L( "Test module container initialized at 0x%x" ), (TUint32) aContainer ) ); |
|
1256 } |
|
1257 } |
|
1258 } |
|
1259 |
|
1260 return ret; |
|
1261 |
|
1262 } |
|
1263 |
|
1264 |
|
1265 /* |
|
1266 ------------------------------------------------------------------------------- |
|
1267 |
|
1268 Class: CTestModule |
|
1269 |
|
1270 Method: FreeTestModule |
|
1271 |
|
1272 Description:Frees a CTestModuleContainer. This function can be called |
|
1273 from the context of the test execution thread. |
|
1274 |
|
1275 Parameters: CTestModuleContainer* aModule :in: Module to be freed |
|
1276 |
|
1277 Return Values: TInt Error code |
|
1278 |
|
1279 Errors/Exceptions: None |
|
1280 |
|
1281 Status: Proposal |
|
1282 |
|
1283 ------------------------------------------------------------------------------- |
|
1284 */ |
|
1285 TInt CTestModule::FreeTestModule( CTestModuleContainer* aModule ) |
|
1286 { |
|
1287 |
|
1288 // Free the module |
|
1289 TInt r = iTestModuleInstances->Append( aModule ); |
|
1290 if( r != KErrNone ) |
|
1291 { |
|
1292 delete aModule; |
|
1293 aModule = NULL; |
|
1294 } |
|
1295 |
|
1296 return r; |
|
1297 |
|
1298 } |
|
1299 |
|
1300 /* |
|
1301 ------------------------------------------------------------------------------- |
|
1302 |
|
1303 Class: CTestModule |
|
1304 |
|
1305 Method: IniName |
|
1306 |
|
1307 Returns the initialisation file name |
|
1308 |
|
1309 Parameters: None |
|
1310 |
|
1311 Return Values: const TDesC& Initialisation file name |
|
1312 |
|
1313 Errors/Exceptions: None |
|
1314 |
|
1315 Status: Proposal |
|
1316 |
|
1317 ------------------------------------------------------------------------------- |
|
1318 */ |
|
1319 |
|
1320 const TDesC& CTestModule::IniName() const |
|
1321 { |
|
1322 |
|
1323 return iIni; |
|
1324 |
|
1325 } |
|
1326 |
|
1327 /* |
|
1328 ------------------------------------------------------------------------------- |
|
1329 |
|
1330 Class: CTestModule |
|
1331 |
|
1332 Method: Name |
|
1333 |
|
1334 Returns the module name |
|
1335 |
|
1336 Parameters: None |
|
1337 |
|
1338 Return Values: const TDesC& Initialisation file name |
|
1339 |
|
1340 Errors/Exceptions: None |
|
1341 |
|
1342 Status: Proposal |
|
1343 |
|
1344 ------------------------------------------------------------------------------- |
|
1345 */ |
|
1346 const TDesC& CTestModule::Name() const |
|
1347 { |
|
1348 |
|
1349 return iTestServer->ModuleName(); |
|
1350 |
|
1351 } |
|
1352 |
|
1353 /* |
|
1354 ------------------------------------------------------------------------------- |
|
1355 |
|
1356 Class: CTestModule |
|
1357 |
|
1358 Method: GetTestCaseTitleL |
|
1359 |
|
1360 Gets title of currently running test case |
|
1361 |
|
1362 Parameters: None |
|
1363 |
|
1364 Return Values: TInt aTestCaseNumber: in: index of currently running test case |
|
1365 TDes& aTestCaseTitle: out: test case title |
|
1366 |
|
1367 Errors/Exceptions: None |
|
1368 |
|
1369 Status: Proposal |
|
1370 |
|
1371 ------------------------------------------------------------------------------- |
|
1372 */ |
|
1373 void CTestModule::GetTestCaseTitleL(TInt aTestCaseNumber, TDes& aTestCaseTitle) |
|
1374 { |
|
1375 RDebug::Print(_L("Trying to get test case title from module. Index=%d, count=%d"), aTestCaseNumber, iTestCaseTitles.Count()); |
|
1376 aTestCaseTitle.Copy(*(iTestCaseTitles[aTestCaseNumber])); |
|
1377 } |
|
1378 |
|
1379 |
|
1380 /* |
|
1381 ------------------------------------------------------------------------------- |
|
1382 |
|
1383 Class: CTestModule |
|
1384 |
|
1385 Method: GetTestServer |
|
1386 |
|
1387 Gets pointer to TestServer |
|
1388 |
|
1389 Parameters: None |
|
1390 |
|
1391 Return Values: CTestServer : pointer to TestServer |
|
1392 |
|
1393 Errors/Exceptions: None |
|
1394 |
|
1395 Status: Proposal |
|
1396 |
|
1397 ------------------------------------------------------------------------------- |
|
1398 */ |
|
1399 CTestServer* CTestModule::GetTestServer() |
|
1400 { |
|
1401 return iTestServer; |
|
1402 } |
|
1403 |
|
1404 |
|
1405 |
|
1406 // End of File |