1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/egl/egltest/endpointtestsuite/automated/src/localtestbase.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,559 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +
1.20 +/** @file
1.21 + @internalComponent - Internal Symbian test code */
1.22 +
1.23 +
1.24 +#include <e32base.h>
1.25 +#include <e32debug.h>
1.26 +#include <e32msgqueue.h>
1.27 +#include <ecom/ecom.h>
1.28 +#include <test/testexecuteserverbase.h>
1.29 +#include <e32math.h>
1.30 +#include "localtestbase.h"
1.31 +#include "egltest_commscommon.h"
1.32 +#include "egltest_endpoint_util.h"
1.33 +
1.34 +
1.35 +_LIT(KEglEndpointTestServerName,"eglendpointtestserver");
1.36 +
1.37 +
1.38 +CLocalTestStepBase::CLocalTestStepBase(enum TTestUid aUid) :
1.39 + iTestId(aUid),
1.40 + iIsInTestStep(EFalse)
1.41 + {
1.42 + }
1.43 +
1.44 +void CLocalTestStepBase::DoPreambleL()
1.45 + {
1.46 + //null implmentation for base class
1.47 + }
1.48 +
1.49 +void CLocalTestStepBase::DoPostambleL()
1.50 + {
1.51 + //null implmentation for base class
1.52 + }
1.53 +
1.54 +//function used for creating the queues.
1.55 +TVerdict CLocalTestStepBase::doTestStepPreambleL()
1.56 + {
1.57 + //Open the queues.
1.58 + User::LeaveIfError(iResultOutQueue.OpenGlobal(KResultQueueName));
1.59 + User::LeaveIfError(iParamsInQueue.OpenGlobal(KParamsQueueName));
1.60 + SetTestStepResult(EPass);
1.61 + iHasCurrentTestIds = EFalse;
1.62 + iResultLog = CTestIdResultLogger::NewL(Logger());
1.63 + DoPreambleL();
1.64 + return EPass;
1.65 + }
1.66 +
1.67 +TVerdict CLocalTestStepBase::doTestStepPostambleL()
1.68 + {
1.69 + //Log the result of the current tests.
1.70 + if(iHasCurrentTestIds)
1.71 + {
1.72 + iResultLog->LogResult(iTestIdVerdict);
1.73 + }
1.74 +
1.75 + DoPostambleL();
1.76 + delete iResultLog;
1.77 + iResultLog = NULL;
1.78 + iResultOutQueue.Close();
1.79 + iParamsInQueue.Close();
1.80 + return EPass;
1.81 + }
1.82 +
1.83 +CLocalTestStepBase::~CLocalTestStepBase()
1.84 + {
1.85 + //closing an already closed handle is harmless
1.86 + iResultOutQueue.Close();
1.87 + iParamsInQueue.Close();
1.88 + }
1.89 +
1.90 +TVerdict CLocalTestStepBase::StartRemoteTestStep(const TRemoteTestParams& aMessageIn)
1.91 + {
1.92 + //Starting the remote test step is implemented as a special case
1.93 + //of running a test case, with TestCase = KStartTestStepCaseNumber.
1.94 + iIsInTestStep = ETrue;
1.95 + TVerdict retVal = RunRemoteTestCase(KStartTestStepCaseNumber, aMessageIn);
1.96 + if(retVal != EPass)
1.97 + {
1.98 + iIsInTestStep = EFalse;
1.99 + }
1.100 + return retVal;
1.101 + }
1.102 +
1.103 +TVerdict CLocalTestStepBase::EndRemoteTestStep(const TRemoteTestParams& aMessageIn)
1.104 + {
1.105 + //Ending the remote test step is implemented as a special case
1.106 + //of running a test case, with TestCase = KEndTestStepCaseNumber.
1.107 + TVerdict retVal = RunRemoteTestCase(KEndTestStepCaseNumber, aMessageIn);
1.108 + iIsInTestStep = EFalse;
1.109 + return retVal;
1.110 + }
1.111 +
1.112 +TVerdict CLocalTestStepBase::RunRemoteTestCase(TInt aTestCase, const TRemoteTestParams& aMessageIn)
1.113 + {
1.114 + //Don't attempt to run any test cases if we are not in a test step.
1.115 + if(!iIsInTestStep)
1.116 + {
1.117 + SetTestStepResult(EFail);
1.118 + return TestStepResult();
1.119 + }
1.120 +
1.121 + //send the message
1.122 + TRemoteTestParamsPacket message(iTestId, aTestCase, aMessageIn);
1.123 + iParamsInQueue.SendBlocking(message);
1.124 +
1.125 + TRemoteTestResult result;
1.126 + do
1.127 + {
1.128 + //relying on TEF timeout if there are problems such as the render stage not loaded.
1.129 + iResultOutQueue.ReceiveBlocking(result);
1.130 +
1.131 + //if uid and test case doesn't match something has gone badly wrong
1.132 + if (result.iUid != iTestId || result.iTestCase != aTestCase)
1.133 + {
1.134 + //test is out of Sync
1.135 + User::Panic(_L("Test out of sync with render stage"), KErrGeneral);
1.136 + }
1.137 +
1.138 + //log the message if there is one
1.139 + if (!result.iFinished)
1.140 + {
1.141 + //Convert the filename to a C string. The remote test env guarantees
1.142 + //that there is a free space at the end of the descriptor to add NULL.
1.143 + const TText8* file = result.iFile.PtrZ();
1.144 +
1.145 + //Convert the message to unicode and log the message.
1.146 + TBuf<KRSLogMessageLength> message;
1.147 + message.Copy(result.iMessage);
1.148 + Logger().LogExtra(file, result.iLine, result.iSeverity, _L("%S"), &message);
1.149 + }
1.150 + }while (!result.iFinished);
1.151 +
1.152 + //Translate the RemoteTestStep verdict to a TVerdict.
1.153 + TVerdict retVal = EPass;
1.154 + switch (result.iVerdict)
1.155 + {
1.156 + case ERtvPass:
1.157 + retVal = EPass;
1.158 + break;
1.159 +
1.160 + case ERtvFail:
1.161 + retVal = EFail;
1.162 + break;
1.163 +
1.164 + case ERtvInconclusive:
1.165 + retVal = EInconclusive;
1.166 + break;
1.167 +
1.168 + case ERtvAbort:
1.169 + retVal = EAbort;
1.170 + break;
1.171 +
1.172 + case ERtvPanic:
1.173 + //The remote test paniced, so we panic too.
1.174 + //This means the output log relects what actually happened.
1.175 + User::Panic(_L("Remote Test Step Paniced!"), KErrGeneral);
1.176 + break;
1.177 +
1.178 + case ERtvTimeout:
1.179 + //The remote test timedout, so we sleep so that tef times us out too.
1.180 + //This means the output log relects what actually happened.
1.181 + User::After(KMaxTInt);
1.182 + break;
1.183 +
1.184 + case ERtvUnknownTestUid:
1.185 + retVal = EIgnore;
1.186 + break;
1.187 +
1.188 + default:
1.189 + User::Panic(_L("Invalid verdict returned from the remote test step!"), KErrGeneral);
1.190 + break;
1.191 + }
1.192 +
1.193 + if(retVal != EPass)
1.194 + {
1.195 + SetTestStepResult(retVal);
1.196 + }
1.197 +
1.198 + return retVal;
1.199 + }
1.200 +
1.201 +
1.202 +void CLocalTestStepBase::RegisterTestIdsL(const TDesC& aTestString)
1.203 + {
1.204 + iResultLog->RegisterTestIdsL(aTestString);
1.205 + }
1.206 +
1.207 +
1.208 +void CLocalTestStepBase::SetCurrentTestIds(const TDesC& aTestString)
1.209 + {
1.210 + if(iHasCurrentTestIds)
1.211 + {
1.212 + iResultLog->LogResult(iTestIdVerdict);
1.213 + }
1.214 +
1.215 + iResultLog->SetCurrentTestIds(aTestString);
1.216 + iHasCurrentTestIds = ETrue;
1.217 + iTestIdVerdict = EPass;
1.218 + }
1.219 +
1.220 +
1.221 +void CLocalTestStepBase::SetTestStepResult(TVerdict aVerdict)
1.222 + {
1.223 + iTestIdVerdict = aVerdict;
1.224 + CTestStep::SetTestStepResult(aVerdict);
1.225 + }
1.226 +
1.227 +
1.228 +//Used by the result logger to delimit the csv test id strings.
1.229 +class TCommaDelimiter
1.230 + {
1.231 +private:
1.232 + mutable TPtrC iRemaining;
1.233 +
1.234 +public:
1.235 + TCommaDelimiter(const TDesC& aString)
1.236 + {
1.237 + //Set our remaining string to the whole string, or NULL if empty.
1.238 + if(aString.Length() == 0)
1.239 + {
1.240 + iRemaining.Set(NULL, 0);
1.241 + }
1.242 + else
1.243 + {
1.244 + iRemaining.Set(aString);
1.245 + }
1.246 + }
1.247 +
1.248 +
1.249 + TInt GetNext(TPtrC& aSegment) const
1.250 + {
1.251 + //Trim off any leading commas.
1.252 + while(iRemaining.Length() >= 2 && iRemaining[0] == ',')
1.253 + {
1.254 + iRemaining.Set(&iRemaining[1], iRemaining.Length() - 1);
1.255 + }
1.256 +
1.257 + //If remaining string is empty or has one remaining comma, return.
1.258 + if(iRemaining.Length() == 0 || iRemaining[0] == ',')
1.259 + {
1.260 + iRemaining.Set(NULL, 0);
1.261 + return KErrNotFound;
1.262 + }
1.263 +
1.264 + //Find the first comma.
1.265 + TInt pos = iRemaining.Locate(',');
1.266 +
1.267 + //If comma not found, return all remaining string.
1.268 + if(pos == KErrNotFound)
1.269 + {
1.270 + aSegment.Set(iRemaining);
1.271 + iRemaining.Set(NULL, 0);
1.272 + return KErrNone;
1.273 + }
1.274 +
1.275 + //Comma found. There must be non-comma chars between 0
1.276 + //and pos since we trimmed leading commas previously.
1.277 + aSegment.Set(&iRemaining[0], pos);
1.278 + iRemaining.Set(&iRemaining[pos], iRemaining.Length() - pos);
1.279 + return KErrNone;
1.280 + }
1.281 +
1.282 +
1.283 + TInt GetNextTrimmed(TPtrC& aSegment) const
1.284 + {
1.285 + //Keep calling GetNext() until we get a segment that has
1.286 + //chars other than spaces or there are no more segments.
1.287 + while(1)
1.288 + {
1.289 + TPtrC segment;
1.290 + TInt err = GetNext(segment);
1.291 + if(err != KErrNone)
1.292 + {
1.293 + return err;
1.294 + }
1.295 +
1.296 + TInt front;
1.297 + TInt back;
1.298 + for(front = 0; front < segment.Length() && segment[front] == ' '; front++) {}
1.299 + for(back = segment.Length() - 1; back >= 0 && segment[back] == ' '; back--) {}
1.300 +
1.301 + TInt length = (back + 1) - front;
1.302 + if(length > 0 && segment[front] != ' ' && segment[back] != ' ')
1.303 + {
1.304 + aSegment.Set(&segment[front], length);
1.305 + return KErrNone;
1.306 + }
1.307 + }
1.308 + }
1.309 + };
1.310 +
1.311 +
1.312 +CTestIdResultLogger* CTestIdResultLogger::NewL(CTestExecuteLogger& aLogger)
1.313 + {
1.314 + CTestIdResultLogger* self = new (ELeave) CTestIdResultLogger(aLogger);
1.315 + CleanupStack::PushL(self);
1.316 + self->ConstructL();
1.317 + CleanupStack::Pop(self);
1.318 + return self;
1.319 + }
1.320 +
1.321 +
1.322 +CTestIdResultLogger::CTestIdResultLogger(CTestExecuteLogger& aLogger) :
1.323 + iOriginalThread(RThread().Id()),
1.324 + iLogger(aLogger)
1.325 + {
1.326 + }
1.327 +
1.328 +
1.329 +void CTestIdResultLogger::ConstructL()
1.330 + {
1.331 + //Create panic monitor thread. Note that we share the heap with this
1.332 + //thread so that the arrays remain in scope if this thread panics.
1.333 + //Note also no need for explicit locking of arrays since the panic
1.334 + //monitor will only access them if a panic occurs here.
1.335 + static const TInt KStackSize = 0x2000; // 8KB
1.336 + TUint32 random = Math::Random();
1.337 + TName threadName;
1.338 + _LIT(KThreadNameFormat, "%S-%u");
1.339 + _LIT(KEnvName, "EpTestIdLogger");
1.340 + threadName.Format(KThreadNameFormat, &KEnvName, random);
1.341 + User::LeaveIfError(iPanicMonitor.Create(threadName, PanicMonitorMain, KStackSize, &User::Heap(), this, EOwnerThread));
1.342 +
1.343 + //Rendezvous with panic thread.
1.344 + TRequestStatus rendStat;
1.345 + iPanicMonitor.Rendezvous(rendStat);
1.346 + iPanicMonitor.Resume();
1.347 + User::WaitForRequest(rendStat);
1.348 + }
1.349 +
1.350 +
1.351 +CTestIdResultLogger::~CTestIdResultLogger()
1.352 + {
1.353 + TRequestStatus logonStat;
1.354 + iPanicMonitor.Logon(logonStat);
1.355 + iPanicMonitor.RequestComplete(iCloseMonitor, KErrNone);
1.356 + User::WaitForRequest(logonStat);
1.357 + iPanicMonitor.Close();
1.358 + iRegisteredTestIds.Close();
1.359 + iCurrentTestIds.Close();
1.360 + }
1.361 +
1.362 +
1.363 +void CTestIdResultLogger::RegisterTestIdsL(const TDesC& aTestString)
1.364 + {
1.365 + //Set up delimitter.
1.366 + TCommaDelimiter delimit(aTestString);
1.367 +
1.368 + //Get every test id from the string and add it to the registered test ids array.
1.369 + TPtrC testIdPtr;
1.370 + while(delimit.GetNextTrimmed(testIdPtr) == KErrNone)
1.371 + {
1.372 + TTestId testId(testIdPtr);
1.373 + iRegisteredTestIds.AppendL(testId);
1.374 + }
1.375 +
1.376 + //Reserve enough space in the current test ids array so that SCurrentTestIds() can not fail.
1.377 + iCurrentTestIds.ReserveL(iRegisteredTestIds.Count());
1.378 + }
1.379 +
1.380 +
1.381 +void CTestIdResultLogger::SetCurrentTestIds(const TDesC& aTestString)
1.382 + {
1.383 + ASSERT(iCurrentTestIds.Count() == 0);
1.384 +
1.385 + //Set up delimitter.
1.386 + TCommaDelimiter delimit(aTestString);
1.387 +
1.388 + //Get every test id from the string and add it to the registered test ids array.
1.389 + TPtrC testIdPtr;
1.390 + while(delimit.GetNextTrimmed(testIdPtr) == KErrNone)
1.391 + {
1.392 + TTestId testId(testIdPtr);
1.393 +
1.394 + //This cannot fail under legitimate circumstances, since enough
1.395 + //space is reserved in this array when registering TestIds.
1.396 + TInt err = iCurrentTestIds.Append(testId);
1.397 + ASSERT(err == KErrNone);
1.398 + }
1.399 +
1.400 + //Make sure these tests were registered and remove from the registered array.
1.401 + for(TInt i=0; i < iCurrentTestIds.Count(); i++)
1.402 + {
1.403 + TInt idx = iRegisteredTestIds.Find(iCurrentTestIds[i]);
1.404 + ASSERT(idx != KErrNotFound);
1.405 + iRegisteredTestIds.Remove(idx);
1.406 + }
1.407 + }
1.408 +
1.409 +
1.410 +void CTestIdResultLogger::LogResult(TVerdict aVerdict)
1.411 + {
1.412 + const TInt KMaxVerdictLength = 20;
1.413 + TBuf<KMaxVerdictLength> verdict;
1.414 + switch(aVerdict)
1.415 + {
1.416 + case EPass: verdict.Append(_L("PASS")); break;
1.417 + case EFail: verdict.Append(_L("FAIL")); break;
1.418 + case EInconclusive: verdict.Append(_L("INCONCLUSIVE")); break;
1.419 + case ETestSuiteError: verdict.Append(_L("TEST SUTE ERROR")); break;
1.420 + case EAbort: verdict.Append(_L("ABORT")); break;
1.421 + case EIgnore: verdict.Append(_L("IGNORE")); break;
1.422 + }
1.423 +
1.424 + while(iCurrentTestIds.Count())
1.425 + {
1.426 + LogResult(iLogger, iCurrentTestIds[0], verdict);
1.427 + iCurrentTestIds.Remove(0);
1.428 + }
1.429 + }
1.430 +
1.431 +
1.432 +void CTestIdResultLogger::LogResult(CTestExecuteLogger& aLogger, const TTestId& aTestId, const TDesC& aVerdict)
1.433 + {
1.434 + aLogger.LogExtra(((TText8*)"EGL ENDPOINT TEST RESULT >>>"), 0, ESevrInfo, _L("GRAPHICS-EGL-%S: %S"), &aTestId, &aVerdict);
1.435 + }
1.436 +
1.437 +
1.438 +TInt CTestIdResultLogger::PanicMonitorMain(TAny* aSelf)
1.439 + {
1.440 + CTestIdResultLogger* self = static_cast<CTestIdResultLogger*>(aSelf);
1.441 +
1.442 + //Create cleanup stack.
1.443 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.444 + ASSERT(cleanup);
1.445 +
1.446 + //Create active scheduler.
1.447 + CActiveScheduler* scheduler = new CActiveScheduler();
1.448 + ASSERT(scheduler);
1.449 + CActiveScheduler::Install(scheduler);
1.450 +
1.451 + TRAPD(err, self->PanicMonitorMainL());
1.452 + __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
1.453 +
1.454 + delete scheduler;
1.455 + delete cleanup;
1.456 + return KErrNone;
1.457 + }
1.458 +
1.459 +
1.460 +void CTestIdResultLogger::PanicMonitorMainL()
1.461 + {
1.462 + //Setup logging.
1.463 + CTestExecuteLogger logger;
1.464 + TEndpointUtil::SetLoggerForProcessWrapperL(logger);
1.465 +
1.466 + //Tell parent how to close us.
1.467 + TRequestStatus closeStatus = KRequestPending;
1.468 + iCloseMonitor = &closeStatus;
1.469 +
1.470 + //Open parent thread and logon.
1.471 + RThread origThread;
1.472 + User::LeaveIfError(origThread.Open(iOriginalThread, EOwnerThread));
1.473 + TRequestStatus origStatus;
1.474 + origThread.Logon(origStatus);
1.475 +
1.476 + //Rendevous with our parent then wait for thread to exit or close command.
1.477 + RThread().Rendezvous(KErrNone);
1.478 + User::WaitForRequest(closeStatus, origStatus);
1.479 +
1.480 + if (closeStatus != KRequestPending)
1.481 + {
1.482 + //Parent is shutting us down. Just cancel our outstanding request and exit.
1.483 + origThread.LogonCancel(origStatus);
1.484 + User::WaitForRequest(origStatus);
1.485 + }
1.486 + else if (origStatus != KRequestPending)
1.487 + {
1.488 + //We can only get here if parent panicked.
1.489 + //Log that all current tests were panicked and all registered tests were not run.
1.490 + _LIT(KPanicked, "PANIC");
1.491 + _LIT(KNotRun, "NOT RUN DUE TO PREVIOUS PANIC");
1.492 + while(iCurrentTestIds.Count())
1.493 + {
1.494 + LogResult(logger, iCurrentTestIds[0], KPanicked);
1.495 + iCurrentTestIds.Remove(0);
1.496 + }
1.497 + while(iRegisteredTestIds.Count())
1.498 + {
1.499 + LogResult(logger, iRegisteredTestIds[0], KNotRun);
1.500 + iRegisteredTestIds.Remove(0);
1.501 + }
1.502 + }
1.503 +
1.504 + origThread.Close();
1.505 + }
1.506 +
1.507 +
1.508 +CEglEndpointTestServer* CEglEndpointTestServer::NewL()
1.509 + {
1.510 + CEglEndpointTestServer* server = new(ELeave) CEglEndpointTestServer();
1.511 + CleanupStack::PushL(server);
1.512 + // CServer base class call
1.513 + TParsePtrC serverName(RProcess().FileName());
1.514 + server->StartL(serverName.Name());
1.515 + CleanupStack::Pop(server);
1.516 + return server;
1.517 + }
1.518 +
1.519 +static void MainL()
1.520 + {
1.521 + CActiveScheduler* sched=NULL;
1.522 + sched=new(ELeave) CActiveScheduler;
1.523 + CActiveScheduler::Install(sched);
1.524 +
1.525 + CEglEndpointTestServer* server = NULL;
1.526 + // Create the CTestServer derived server
1.527 + TRAPD(err, server = CEglEndpointTestServer::NewL());
1.528 + if(!err)
1.529 + {
1.530 + // Sync with the client and enter the active scheduler
1.531 + RProcess::Rendezvous(KErrNone);
1.532 + sched->Start();
1.533 + }
1.534 + delete server;
1.535 + delete sched;
1.536 + }
1.537 +
1.538 +/**
1.539 + @return Standard Epoc error code on process exit
1.540 + Process entry point. Called by client using RProcess API
1.541 + */
1.542 +TInt E32Main()
1.543 + {
1.544 + __UHEAP_MARK;
1.545 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.546 + if(!cleanup)
1.547 + {
1.548 + return KErrNoMemory;
1.549 + }
1.550 + TRAPD(err,MainL());
1.551 +
1.552 + if (err)
1.553 + {
1.554 + RDebug::Print(_L("CEglEndpointTestServer::MainL - Error: %d"), err);
1.555 + User::Panic(KEglEndpointTestServerName, err);
1.556 + }
1.557 +
1.558 + delete cleanup;
1.559 + REComSession::FinalClose();
1.560 + __UHEAP_MARKEND;
1.561 + return KErrNone;
1.562 + }