Update contrib.
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 "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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
18 @internalComponent - Internal Symbian test code */
23 #include <e32msgqueue.h>
24 #include <ecom/ecom.h>
25 #include <test/testexecuteserverbase.h>
27 #include "localtestbase.h"
28 #include "egltest_commscommon.h"
29 #include "egltest_endpoint_util.h"
32 _LIT(KEglEndpointTestServerName,"eglendpointtestserver");
35 CLocalTestStepBase::CLocalTestStepBase(enum TTestUid aUid) :
41 void CLocalTestStepBase::DoPreambleL()
43 //null implmentation for base class
46 void CLocalTestStepBase::DoPostambleL()
48 //null implmentation for base class
51 //function used for creating the queues.
52 TVerdict CLocalTestStepBase::doTestStepPreambleL()
55 User::LeaveIfError(iResultOutQueue.OpenGlobal(KResultQueueName));
56 User::LeaveIfError(iParamsInQueue.OpenGlobal(KParamsQueueName));
57 SetTestStepResult(EPass);
58 iHasCurrentTestIds = EFalse;
59 iResultLog = CTestIdResultLogger::NewL(Logger());
64 TVerdict CLocalTestStepBase::doTestStepPostambleL()
66 //Log the result of the current tests.
67 if(iHasCurrentTestIds)
69 iResultLog->LogResult(iTestIdVerdict);
75 iResultOutQueue.Close();
76 iParamsInQueue.Close();
80 CLocalTestStepBase::~CLocalTestStepBase()
82 //closing an already closed handle is harmless
83 iResultOutQueue.Close();
84 iParamsInQueue.Close();
87 TVerdict CLocalTestStepBase::StartRemoteTestStep(const TRemoteTestParams& aMessageIn)
89 //Starting the remote test step is implemented as a special case
90 //of running a test case, with TestCase = KStartTestStepCaseNumber.
91 iIsInTestStep = ETrue;
92 TVerdict retVal = RunRemoteTestCase(KStartTestStepCaseNumber, aMessageIn);
95 iIsInTestStep = EFalse;
100 TVerdict CLocalTestStepBase::EndRemoteTestStep(const TRemoteTestParams& aMessageIn)
102 //Ending the remote test step is implemented as a special case
103 //of running a test case, with TestCase = KEndTestStepCaseNumber.
104 TVerdict retVal = RunRemoteTestCase(KEndTestStepCaseNumber, aMessageIn);
105 iIsInTestStep = EFalse;
109 TVerdict CLocalTestStepBase::RunRemoteTestCase(TInt aTestCase, const TRemoteTestParams& aMessageIn)
111 //Don't attempt to run any test cases if we are not in a test step.
114 SetTestStepResult(EFail);
115 return TestStepResult();
119 TRemoteTestParamsPacket message(iTestId, aTestCase, aMessageIn);
120 iParamsInQueue.SendBlocking(message);
122 TRemoteTestResult result;
125 //relying on TEF timeout if there are problems such as the render stage not loaded.
126 iResultOutQueue.ReceiveBlocking(result);
128 //if uid and test case doesn't match something has gone badly wrong
129 if (result.iUid != iTestId || result.iTestCase != aTestCase)
131 //test is out of Sync
132 User::Panic(_L("Test out of sync with render stage"), KErrGeneral);
135 //log the message if there is one
136 if (!result.iFinished)
138 //Convert the filename to a C string. The remote test env guarantees
139 //that there is a free space at the end of the descriptor to add NULL.
140 const TText8* file = result.iFile.PtrZ();
142 //Convert the message to unicode and log the message.
143 TBuf<KRSLogMessageLength> message;
144 message.Copy(result.iMessage);
145 Logger().LogExtra(file, result.iLine, result.iSeverity, _L("%S"), &message);
147 }while (!result.iFinished);
149 //Translate the RemoteTestStep verdict to a TVerdict.
150 TVerdict retVal = EPass;
151 switch (result.iVerdict)
161 case ERtvInconclusive:
162 retVal = EInconclusive;
170 //The remote test paniced, so we panic too.
171 //This means the output log relects what actually happened.
172 User::Panic(_L("Remote Test Step Paniced!"), KErrGeneral);
176 //The remote test timedout, so we sleep so that tef times us out too.
177 //This means the output log relects what actually happened.
178 User::After(KMaxTInt);
181 case ERtvUnknownTestUid:
186 User::Panic(_L("Invalid verdict returned from the remote test step!"), KErrGeneral);
192 SetTestStepResult(retVal);
199 void CLocalTestStepBase::RegisterTestIdsL(const TDesC& aTestString)
201 iResultLog->RegisterTestIdsL(aTestString);
205 void CLocalTestStepBase::SetCurrentTestIds(const TDesC& aTestString)
207 if(iHasCurrentTestIds)
209 iResultLog->LogResult(iTestIdVerdict);
212 iResultLog->SetCurrentTestIds(aTestString);
213 iHasCurrentTestIds = ETrue;
214 iTestIdVerdict = EPass;
218 void CLocalTestStepBase::SetTestStepResult(TVerdict aVerdict)
220 iTestIdVerdict = aVerdict;
221 CTestStep::SetTestStepResult(aVerdict);
225 //Used by the result logger to delimit the csv test id strings.
226 class TCommaDelimiter
229 mutable TPtrC iRemaining;
232 TCommaDelimiter(const TDesC& aString)
234 //Set our remaining string to the whole string, or NULL if empty.
235 if(aString.Length() == 0)
237 iRemaining.Set(NULL, 0);
241 iRemaining.Set(aString);
246 TInt GetNext(TPtrC& aSegment) const
248 //Trim off any leading commas.
249 while(iRemaining.Length() >= 2 && iRemaining[0] == ',')
251 iRemaining.Set(&iRemaining[1], iRemaining.Length() - 1);
254 //If remaining string is empty or has one remaining comma, return.
255 if(iRemaining.Length() == 0 || iRemaining[0] == ',')
257 iRemaining.Set(NULL, 0);
261 //Find the first comma.
262 TInt pos = iRemaining.Locate(',');
264 //If comma not found, return all remaining string.
265 if(pos == KErrNotFound)
267 aSegment.Set(iRemaining);
268 iRemaining.Set(NULL, 0);
272 //Comma found. There must be non-comma chars between 0
273 //and pos since we trimmed leading commas previously.
274 aSegment.Set(&iRemaining[0], pos);
275 iRemaining.Set(&iRemaining[pos], iRemaining.Length() - pos);
280 TInt GetNextTrimmed(TPtrC& aSegment) const
282 //Keep calling GetNext() until we get a segment that has
283 //chars other than spaces or there are no more segments.
287 TInt err = GetNext(segment);
295 for(front = 0; front < segment.Length() && segment[front] == ' '; front++) {}
296 for(back = segment.Length() - 1; back >= 0 && segment[back] == ' '; back--) {}
298 TInt length = (back + 1) - front;
299 if(length > 0 && segment[front] != ' ' && segment[back] != ' ')
301 aSegment.Set(&segment[front], length);
309 CTestIdResultLogger* CTestIdResultLogger::NewL(CTestExecuteLogger& aLogger)
311 CTestIdResultLogger* self = new (ELeave) CTestIdResultLogger(aLogger);
312 CleanupStack::PushL(self);
314 CleanupStack::Pop(self);
319 CTestIdResultLogger::CTestIdResultLogger(CTestExecuteLogger& aLogger) :
320 iOriginalThread(RThread().Id()),
326 void CTestIdResultLogger::ConstructL()
328 //Create panic monitor thread. Note that we share the heap with this
329 //thread so that the arrays remain in scope if this thread panics.
330 //Note also no need for explicit locking of arrays since the panic
331 //monitor will only access them if a panic occurs here.
332 static const TInt KStackSize = 0x2000; // 8KB
333 TUint32 random = Math::Random();
335 _LIT(KThreadNameFormat, "%S-%u");
336 _LIT(KEnvName, "EpTestIdLogger");
337 threadName.Format(KThreadNameFormat, &KEnvName, random);
338 User::LeaveIfError(iPanicMonitor.Create(threadName, PanicMonitorMain, KStackSize, &User::Heap(), this, EOwnerThread));
340 //Rendezvous with panic thread.
341 TRequestStatus rendStat;
342 iPanicMonitor.Rendezvous(rendStat);
343 iPanicMonitor.Resume();
344 User::WaitForRequest(rendStat);
348 CTestIdResultLogger::~CTestIdResultLogger()
350 TRequestStatus logonStat;
351 iPanicMonitor.Logon(logonStat);
352 iPanicMonitor.RequestComplete(iCloseMonitor, KErrNone);
353 User::WaitForRequest(logonStat);
354 iPanicMonitor.Close();
355 iRegisteredTestIds.Close();
356 iCurrentTestIds.Close();
360 void CTestIdResultLogger::RegisterTestIdsL(const TDesC& aTestString)
363 TCommaDelimiter delimit(aTestString);
365 //Get every test id from the string and add it to the registered test ids array.
367 while(delimit.GetNextTrimmed(testIdPtr) == KErrNone)
369 TTestId testId(testIdPtr);
370 iRegisteredTestIds.AppendL(testId);
373 //Reserve enough space in the current test ids array so that SCurrentTestIds() can not fail.
374 iCurrentTestIds.ReserveL(iRegisteredTestIds.Count());
378 void CTestIdResultLogger::SetCurrentTestIds(const TDesC& aTestString)
380 ASSERT(iCurrentTestIds.Count() == 0);
383 TCommaDelimiter delimit(aTestString);
385 //Get every test id from the string and add it to the registered test ids array.
387 while(delimit.GetNextTrimmed(testIdPtr) == KErrNone)
389 TTestId testId(testIdPtr);
391 //This cannot fail under legitimate circumstances, since enough
392 //space is reserved in this array when registering TestIds.
393 TInt err = iCurrentTestIds.Append(testId);
394 ASSERT(err == KErrNone);
397 //Make sure these tests were registered and remove from the registered array.
398 for(TInt i=0; i < iCurrentTestIds.Count(); i++)
400 TInt idx = iRegisteredTestIds.Find(iCurrentTestIds[i]);
401 ASSERT(idx != KErrNotFound);
402 iRegisteredTestIds.Remove(idx);
407 void CTestIdResultLogger::LogResult(TVerdict aVerdict)
409 const TInt KMaxVerdictLength = 20;
410 TBuf<KMaxVerdictLength> verdict;
413 case EPass: verdict.Append(_L("PASS")); break;
414 case EFail: verdict.Append(_L("FAIL")); break;
415 case EInconclusive: verdict.Append(_L("INCONCLUSIVE")); break;
416 case ETestSuiteError: verdict.Append(_L("TEST SUTE ERROR")); break;
417 case EAbort: verdict.Append(_L("ABORT")); break;
418 case EIgnore: verdict.Append(_L("IGNORE")); break;
421 while(iCurrentTestIds.Count())
423 LogResult(iLogger, iCurrentTestIds[0], verdict);
424 iCurrentTestIds.Remove(0);
429 void CTestIdResultLogger::LogResult(CTestExecuteLogger& aLogger, const TTestId& aTestId, const TDesC& aVerdict)
431 aLogger.LogExtra(((TText8*)"EGL ENDPOINT TEST RESULT >>>"), 0, ESevrInfo, _L("GRAPHICS-EGL-%S: %S"), &aTestId, &aVerdict);
435 TInt CTestIdResultLogger::PanicMonitorMain(TAny* aSelf)
437 CTestIdResultLogger* self = static_cast<CTestIdResultLogger*>(aSelf);
439 //Create cleanup stack.
440 CTrapCleanup* cleanup = CTrapCleanup::New();
443 //Create active scheduler.
444 CActiveScheduler* scheduler = new CActiveScheduler();
446 CActiveScheduler::Install(scheduler);
448 TRAPD(err, self->PanicMonitorMainL());
449 __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
457 void CTestIdResultLogger::PanicMonitorMainL()
460 CTestExecuteLogger logger;
461 TEndpointUtil::SetLoggerForProcessWrapperL(logger);
463 //Tell parent how to close us.
464 TRequestStatus closeStatus = KRequestPending;
465 iCloseMonitor = &closeStatus;
467 //Open parent thread and logon.
469 User::LeaveIfError(origThread.Open(iOriginalThread, EOwnerThread));
470 TRequestStatus origStatus;
471 origThread.Logon(origStatus);
473 //Rendevous with our parent then wait for thread to exit or close command.
474 RThread().Rendezvous(KErrNone);
475 User::WaitForRequest(closeStatus, origStatus);
477 if (closeStatus != KRequestPending)
479 //Parent is shutting us down. Just cancel our outstanding request and exit.
480 origThread.LogonCancel(origStatus);
481 User::WaitForRequest(origStatus);
483 else if (origStatus != KRequestPending)
485 //We can only get here if parent panicked.
486 //Log that all current tests were panicked and all registered tests were not run.
487 _LIT(KPanicked, "PANIC");
488 _LIT(KNotRun, "NOT RUN DUE TO PREVIOUS PANIC");
489 while(iCurrentTestIds.Count())
491 LogResult(logger, iCurrentTestIds[0], KPanicked);
492 iCurrentTestIds.Remove(0);
494 while(iRegisteredTestIds.Count())
496 LogResult(logger, iRegisteredTestIds[0], KNotRun);
497 iRegisteredTestIds.Remove(0);
505 CEglEndpointTestServer* CEglEndpointTestServer::NewL()
507 CEglEndpointTestServer* server = new(ELeave) CEglEndpointTestServer();
508 CleanupStack::PushL(server);
509 // CServer base class call
510 TParsePtrC serverName(RProcess().FileName());
511 server->StartL(serverName.Name());
512 CleanupStack::Pop(server);
518 CActiveScheduler* sched=NULL;
519 sched=new(ELeave) CActiveScheduler;
520 CActiveScheduler::Install(sched);
522 CEglEndpointTestServer* server = NULL;
523 // Create the CTestServer derived server
524 TRAPD(err, server = CEglEndpointTestServer::NewL());
527 // Sync with the client and enter the active scheduler
528 RProcess::Rendezvous(KErrNone);
536 @return Standard Epoc error code on process exit
537 Process entry point. Called by client using RProcess API
542 CTrapCleanup* cleanup = CTrapCleanup::New();
551 RDebug::Print(_L("CEglEndpointTestServer::MainL - Error: %d"), err);
552 User::Panic(KEglEndpointTestServerName, err);
556 REComSession::FinalClose();