egl/egltest/endpointtestsuite/automated/src/remotetestbase.cpp
changeset 98 bf7481649c98
child 136 62bb7c97884c
equal deleted inserted replaced
85:cdf2f6e5c390 98:bf7481649c98
       
     1 // Copyright (c) 2009-2010 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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 
       
    13 
       
    14 /**
       
    15  @file
       
    16  @test
       
    17  @internalComponent - Internal Symbian test code
       
    18 */
       
    19 
       
    20 
       
    21 /*
       
    22  * This file contains the parts of CRemoteTestEnv and CRemoteTestStepBase
       
    23  * that do not need editting when adding new tests.
       
    24  *
       
    25  * CRemoteTestEnv acts as the controller. It provides the means of communicating
       
    26  * with the local side and it instantiates remote test steps and executes them in
       
    27  * their own thread. It monitors this thread for panic / timeout. If this
       
    28  * happens, it informs the local side.
       
    29  */
       
    30 
       
    31 
       
    32 #include "remotetestbase.h"
       
    33 #include <e32debug.h>
       
    34 #include <e32math.h>
       
    35 
       
    36 
       
    37 // Timout for remote test steps. This MUST be smaller
       
    38 // than any timeout passed to TEF for the local test step
       
    39 // in the script file.
       
    40 const TInt KRemoteTestStepTimeout = 10 * 1000000;
       
    41 
       
    42 
       
    43 //Active object used to generate a timeout if worker thread takes too long. ------
       
    44 
       
    45 CTimeoutTimer* CTimeoutTimer::NewL(CRemoteTestEnv& aEnv, TInt aPriority)
       
    46     {
       
    47     CTimeoutTimer* obj = new (ELeave) CTimeoutTimer(aEnv, aPriority);
       
    48     CleanupStack::PushL(obj);
       
    49     obj->ConstructL();
       
    50     CleanupStack::Pop(obj);
       
    51     return obj;
       
    52     }
       
    53 
       
    54 
       
    55 CTimeoutTimer::CTimeoutTimer(CRemoteTestEnv& aEnv, TInt aPriority) :
       
    56     CTimer(aPriority),
       
    57     iEnv(aEnv)
       
    58     {
       
    59     }
       
    60 
       
    61 
       
    62 void CTimeoutTimer::ConstructL()
       
    63     {
       
    64     CTimer::ConstructL();
       
    65     CActiveScheduler::Add(this);
       
    66     }
       
    67 
       
    68 
       
    69 CTimeoutTimer::~CTimeoutTimer()
       
    70     {
       
    71     }
       
    72 
       
    73 
       
    74 void CTimeoutTimer::RunL()
       
    75     {
       
    76     ENDPOINT_ASSERT_DEBUG(iStatus.Int() == KErrNone, User::Invariant());
       
    77     iEnv.TestCaseTimedOut();
       
    78     }
       
    79 
       
    80 //--------------------------------------------------------------------------------
       
    81 
       
    82 
       
    83 //Active object used to listen to the worker thread to see if it panics. ---------
       
    84 
       
    85 CWorkerListener* CWorkerListener::NewL(CRemoteTestEnv& aEnv, TInt aPriority)
       
    86     {
       
    87     CWorkerListener* obj = new (ELeave) CWorkerListener(aEnv, aPriority);
       
    88     CleanupStack::PushL(obj);
       
    89     obj->ConstructL();
       
    90     CleanupStack::Pop(obj);
       
    91     return obj;
       
    92     }
       
    93 
       
    94 
       
    95 CWorkerListener::CWorkerListener(CRemoteTestEnv& aEnv, TInt aPriority) :
       
    96     CActive(aPriority),
       
    97     iEnv(aEnv)
       
    98     {
       
    99     }
       
   100 
       
   101 
       
   102 CWorkerListener::~CWorkerListener()
       
   103     {
       
   104     Cancel();
       
   105     }
       
   106 
       
   107 
       
   108 void CWorkerListener::ConstructL()
       
   109     {
       
   110     CActiveScheduler::Add(this);
       
   111     }
       
   112 
       
   113 
       
   114 void CWorkerListener::Listen(RThread& aThread)
       
   115     {
       
   116     ENDPOINT_ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   117     iThread = &aThread;
       
   118     iThread->Logon(iStatus);
       
   119     SetActive();
       
   120     }
       
   121 
       
   122 
       
   123 void CWorkerListener::RunL()
       
   124     {
       
   125     iEnv.WorkerExitted();
       
   126     }
       
   127 
       
   128 
       
   129 void CWorkerListener::DoCancel()
       
   130     {
       
   131     iThread->LogonCancel(iStatus);
       
   132     }
       
   133 
       
   134 //--------------------------------------------------------------------------------
       
   135 
       
   136 
       
   137 //Active object used to listen for test case completion from the worker thread. --
       
   138 
       
   139 CTestCaseListener* CTestCaseListener::NewL(CRemoteTestEnv& aEnv, TInt aPriority)
       
   140     {
       
   141     CTestCaseListener* obj = new (ELeave) CTestCaseListener(aEnv, aPriority);
       
   142     CleanupStack::PushL(obj);
       
   143     obj->ConstructL();
       
   144     CleanupStack::Pop(obj);
       
   145     return obj;
       
   146     }
       
   147 
       
   148 
       
   149 CTestCaseListener::CTestCaseListener(CRemoteTestEnv& aEnv, TInt aPriority) :
       
   150     CActive(aPriority),
       
   151     iEnv(aEnv)
       
   152     {
       
   153     }
       
   154 
       
   155 
       
   156 CTestCaseListener::~CTestCaseListener()
       
   157     {
       
   158     Cancel();
       
   159     }
       
   160 
       
   161 
       
   162 void CTestCaseListener::ConstructL()
       
   163     {
       
   164     CActiveScheduler::Add(this);
       
   165     }
       
   166 
       
   167 
       
   168 void CTestCaseListener::Listen()
       
   169     {
       
   170     ENDPOINT_ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   171     iStatus = KRequestPending;
       
   172     SetActive();
       
   173     }
       
   174 
       
   175 
       
   176 void CTestCaseListener::RunL()
       
   177     {
       
   178     ENDPOINT_ASSERT_DEBUG(iStatus.Int() == KErrNone, User::Invariant());
       
   179     iEnv.TestCaseCompleted();
       
   180     }
       
   181 
       
   182 
       
   183 void CTestCaseListener::DoCancel()
       
   184     {
       
   185     //There is no way to actually cancel a test case,
       
   186     //But this AO will only be cancelled when the thread
       
   187     //has panicked or timed out - which is as good as a
       
   188     //cancel. We still need to call canel on the AO though
       
   189     //to set it as inactive.
       
   190 
       
   191     //Also need to do a request complete if the worker has not already
       
   192     //done it. There is no danger of the worker completing between our
       
   193     //check (the if) and actually completing because the worker is dead.
       
   194     if(iStatus.Int() == KRequestPending)
       
   195         {
       
   196         TRequestStatus* myStatus = &iStatus;
       
   197         User::RequestComplete(myStatus, KErrCancel);
       
   198         }
       
   199     }
       
   200 
       
   201 //--------------------------------------------------------------------------------
       
   202 
       
   203 
       
   204 //CRemoteTestEnv -----------------------------------------------------------------
       
   205 
       
   206 CRemoteTestEnv* CRemoteTestEnv::NewL()
       
   207     {
       
   208     CRemoteTestEnv* obj = new (ELeave) CRemoteTestEnv();
       
   209     CleanupStack::PushL(obj);
       
   210     obj->ConstructL();
       
   211     CleanupStack::Pop(obj);
       
   212     return obj;
       
   213     }
       
   214 
       
   215 
       
   216 CRemoteTestEnv::CRemoteTestEnv() :
       
   217     CActive(CActive::EPriorityStandard)
       
   218     {
       
   219     }
       
   220 
       
   221 
       
   222 void CRemoteTestEnv::ConstructL()
       
   223     {
       
   224     //Create the message queues.
       
   225     User::LeaveIfError(iResultOutQueue.CreateGlobal(KResultQueueName, 5));
       
   226     User::LeaveIfError(iParamsInQueue.CreateGlobal(KParamsQueueName, 1));
       
   227 
       
   228     iSupervisorId = RThread().Id();
       
   229 
       
   230     //Create AOs that monitor for events.
       
   231     //These priorities are important, since if, for example, the worker
       
   232     //thread exits by returning from the thread entrypoint after
       
   233     //successfully completing the EndTestStep() case, but before the
       
   234     //supervisor runs, the supervisor's AS will find that both iWorkerListener
       
   235     //and iTestCaseListener have completed. We use the priorities to determine
       
   236     //which signal to run first. (The one we run will cancel the others).
       
   237     iTimeoutTimer = CTimeoutTimer::NewL(*this, CActive::EPriorityLow);
       
   238     iWorkerListener = CWorkerListener::NewL(*this, CActive::EPriorityStandard);
       
   239     iTestCaseListener = CTestCaseListener::NewL(*this, CActive::EPriorityHigh);
       
   240 
       
   241     //Add self to active scheduler.
       
   242     CActiveScheduler::Add(this);
       
   243     }
       
   244 
       
   245 
       
   246 CRemoteTestEnv::~CRemoteTestEnv()
       
   247     {
       
   248     Cancel();
       
   249     delete iTimeoutTimer;
       
   250     delete iWorkerListener;
       
   251     delete iTestCaseListener;
       
   252     iParamsInQueue.Close();
       
   253     iResultOutQueue.Close();
       
   254     }
       
   255 
       
   256 
       
   257 void CRemoteTestEnv::StartReceivingCmds()
       
   258     {
       
   259     ReceiveCmd();
       
   260     CActiveScheduler::Start();
       
   261     }
       
   262 
       
   263 
       
   264 void CRemoteTestEnv::ReceiveCmd()
       
   265     {
       
   266     ENDPOINT_ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   267     iParamsInQueue.NotifyDataAvailable(iStatus);
       
   268     SetActive();
       
   269     }
       
   270 
       
   271 
       
   272 //This is run when an packet arrives in the queue from the local side.
       
   273 //It is not rearmed until the test step has run to completion.
       
   274 void CRemoteTestEnv::RunL()
       
   275     {
       
   276     //Retrieve the packet from the queue.
       
   277     TInt err = iParamsInQueue.Receive(iCurTestCaseParamsPacket);
       
   278     ENDPOINT_ASSERT_DEBUG(err == KErrNone, User::Invariant());
       
   279     
       
   280     //Create the appropriate TestStep and launch thread if this is a "StartTestStep".
       
   281     if(iCurTestCaseParamsPacket.iTestCase == KStartTestStepCaseNumber)
       
   282         {
       
   283         //At this point in a well behaved system, iCurTestStep must be NULL.
       
   284         //If it is not, comms has gone wrong (most likely the local side has 
       
   285         //panicked midway through the test step). If iCurTestStep is not NULL
       
   286         //we can also guarantee that the thread is still running. Recover 
       
   287         //from this by getting the thread to do some special teardown, 
       
   288         //followed by tidying up in this thread.
       
   289         if(iCurTestStep)
       
   290             {
       
   291             //Logon to worker then signal to abort the test case
       
   292             //and wait for completion.
       
   293             TRequestStatus threadStat;
       
   294             iCurWorker.Logon(threadStat);
       
   295             TRequestStatus* notifyRunTestCase = &iNotifyRunTestCase;
       
   296             iCurWorker.RequestComplete(notifyRunTestCase, KErrAbort);
       
   297             User::WaitForRequest(threadStat);
       
   298             
       
   299             //Tidy up.
       
   300             iCurWorker.Close();
       
   301             delete iCurTestStep;
       
   302             iCurTestStep = NULL;
       
   303             }
       
   304         
       
   305         TBool result = SetupTestStep();
       
   306 
       
   307         //If we failed to setup the test step (invalid uid),
       
   308         //just register for another command and return.
       
   309         if(!result)
       
   310             {
       
   311             //Register to receive another packet from the message queue.
       
   312             ReceiveCmd();
       
   313             return;
       
   314             }
       
   315         }
       
   316 
       
   317     //Activate the TimoutTimer, TestCaseListener and WorkerListener.
       
   318     iTimeoutTimer->After(KRemoteTestStepTimeout);
       
   319     iTestCaseListener->Listen();
       
   320     iWorkerListener->Listen(iCurWorker);
       
   321 
       
   322     //Signal the worker thread to start a test case.
       
   323     TRequestStatus* notifyRunTestCase = &iNotifyRunTestCase;
       
   324     iCurWorker.RequestComplete(notifyRunTestCase, KErrNone);
       
   325     }
       
   326 
       
   327 
       
   328 void CRemoteTestEnv::DoCancel()
       
   329     {
       
   330     iParamsInQueue.CancelDataAvailable();
       
   331     }
       
   332 
       
   333 
       
   334 //The test case can end in three ways:
       
   335 //    1. Test Case compeletes normally (this includes failing).
       
   336 //    2. The Test Case times out (in which case the thread is panicked).
       
   337 //    3. The Test Case panics the worker thread.
       
   338 //Three AOs listen for each of these possibilities and one of the functions below.
       
   339 
       
   340 
       
   341 //This is called for case 1.
       
   342 void CRemoteTestEnv::TestCaseCompleted()
       
   343     {
       
   344     //Cancel the TimeoutTimer and WorkerListener.
       
   345     iTimeoutTimer->Cancel();
       
   346     iWorkerListener->Cancel();
       
   347 
       
   348     //Test case completed correctly, so send test result.
       
   349     SendResult(iCurTestCaseVerdict);
       
   350 
       
   351     //Tidy up if this is the end of the test step.
       
   352     if(iCurTestCaseParamsPacket.iTestCase == KEndTestStepCaseNumber)
       
   353         {
       
   354         iCurWorker.Close();
       
   355         delete iCurTestStep;
       
   356         iCurTestStep = NULL;
       
   357         }
       
   358 
       
   359     //Register to receive another packet from the message queue.
       
   360     ReceiveCmd();
       
   361     }
       
   362 
       
   363 
       
   364 //This is called for case 2.
       
   365 void CRemoteTestEnv::TestCaseTimedOut()
       
   366     {
       
   367     //Cancel the TestCaseListener and WorkerListener.
       
   368     iTestCaseListener->Cancel();
       
   369     iWorkerListener->Cancel();
       
   370 
       
   371     //Thread timed out so log that it timed out and send the ERtvTimeout result.
       
   372     iCurTestStep->REMOTE_ERR_PRINTF1(_L("Remote test step timed out."));
       
   373     SendResult(ERtvTimeout);
       
   374 
       
   375     //Tidy up. Because we timed out, we abandon the test step, so
       
   376     //kill the thread and release even if this was not an EndTestStep
       
   377     iCurWorker.Kill(KErrTimedOut);
       
   378     iCurWorker.Close();
       
   379     delete iCurTestStep;
       
   380     iCurTestStep = NULL;
       
   381 
       
   382     //Register to receive another packet from the message queue.
       
   383     ReceiveCmd();
       
   384     }
       
   385 
       
   386 
       
   387 //This is called for case 3.
       
   388 void CRemoteTestEnv::WorkerExitted()
       
   389     {
       
   390     //Cancel the TimeoutTimer and TestCaseListener.
       
   391     iTimeoutTimer->Cancel();
       
   392     iTestCaseListener->Cancel();
       
   393 
       
   394     //Even if we were running a EndTestStep (ie the thread will exit normally), TestCaseListener should still
       
   395     //fire first, and it will cancel the WorkerListener - so we know that if we get here, it is because the
       
   396     //thread exitted abnormally.
       
   397 
       
   398     //Thread was panicked, so log the panic category before sending the ERtvPanic result.
       
   399     TExitCategoryName exitCategory = iCurWorker.ExitCategory();
       
   400     iCurTestStep->REMOTE_ERR_PRINTF3(_L("Remote test step panicked with: %S, code = %d."), &exitCategory, iCurWorker.ExitReason());
       
   401     SendResult(ERtvPanic);
       
   402 
       
   403     //Tidy up. Because we panicked, we abandon the test step, so
       
   404     //release resources even if this was not an EndTestStep
       
   405     iCurWorker.Close();
       
   406     delete iCurTestStep;
       
   407     iCurTestStep = NULL;
       
   408 
       
   409     //Register to receive another packet from the message queue.
       
   410     ReceiveCmd();
       
   411     }
       
   412 
       
   413 
       
   414 TBool CRemoteTestEnv::SetupTestStep()
       
   415     {
       
   416     //Set the TRequestStatus that the worker thread triggers off for the first time.
       
   417     //After this, the worker thread will set it back to KRequestPending itself.
       
   418     iNotifyRunTestCase = KRequestPending;
       
   419 
       
   420     //Create TestStep
       
   421     TRAPD(err, iCurTestStep = CreateRemoteTestStepL(iCurTestCaseParamsPacket.iUid));
       
   422     if(err == KErrUnknown)
       
   423         {
       
   424         //Unknown test step. Tell the driver app.
       
   425         SendResult(ERtvUnknownTestUid);
       
   426         return EFalse;
       
   427         }
       
   428     else if(err != KErrNone || !iCurTestStep)
       
   429         {
       
   430         User::Invariant();
       
   431         }
       
   432 
       
   433     //Construct the test step base class.
       
   434     TRAP(err, iCurTestStep->ConstructL(*this));
       
   435     __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
       
   436 
       
   437     //Create Test Thread.
       
   438     static const TInt KStackSize =   0x2000;      //  8KB
       
   439     static const TInt KHeapMinSize = 0x1000;      //  4KB
       
   440     static const TInt KHeapMaxSize = 0x1000000;   // 16MB
       
   441     TUint32 random = Math::Random();
       
   442     TName threadName;
       
   443     _LIT(KThreadNameFormat, "%S-%u");
       
   444     _LIT(KExecName, "EpTestRemoteExec");
       
   445     threadName.Format(KThreadNameFormat, &KExecName, random);
       
   446     err = iCurWorker.Create(threadName, TestThreadEntryPoint, KStackSize, KHeapMinSize, KHeapMaxSize, this);
       
   447     __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
       
   448 
       
   449     //Start the test thread.
       
   450     iCurWorker.Resume();
       
   451 
       
   452     return ETrue;
       
   453     }
       
   454 
       
   455 
       
   456 // The DoEglHeapMark and DoEglHeapCheck are intended to make sure memory
       
   457 // allocations are freed when the testing is complete. The current
       
   458 // implementation only supports the Symbian/Nokia reference implementation.
       
   459 // An implementor of another EGL implementation is free to add their own
       
   460 // variant of heapchecking here, with suitable #if around it.
       
   461 // The function in egl should call __DbgMarkStart() and __DbgMarkEnd()
       
   462 // on the heap for the egl implementation - or the equivalent if the
       
   463 // heap is not a typical Symbian heap.
       
   464 void CRemoteTestEnv::DoEglHeapMark()
       
   465     {
       
   466 #if USE_EGLHEAP_CHECKING
       
   467     typedef void (*TEglDebugHeapMarkStartPtr)(void);
       
   468 
       
   469     TEglDebugHeapMarkStartPtr  heapMarkStart = reinterpret_cast<TEglDebugHeapMarkStartPtr>(eglGetProcAddress("egliDebugHeapMarkStart"));
       
   470     if (heapMarkStart)
       
   471         {
       
   472         heapMarkStart();
       
   473         }
       
   474 #endif
       
   475     }
       
   476 
       
   477 void CRemoteTestEnv::DoEglHeapCheck()
       
   478     {
       
   479 #if USE_EGLHEAP_CHECKING
       
   480     typedef EGLint (*TEglDebugHeapMarkEndPtr)(EGLint count);
       
   481 
       
   482     TEglDebugHeapMarkEndPtr heapMarkEnd = reinterpret_cast<TEglDebugHeapMarkEndPtr>(eglGetProcAddress("egliDebugHeapMarkEnd"));
       
   483     if (heapMarkEnd)
       
   484         {
       
   485         (void)heapMarkEnd(0);
       
   486         }
       
   487 #endif
       
   488     }
       
   489 
       
   490 #define __EGLHEAP_MARK   DoEglHeapMark()
       
   491 #define __EGLHEAP_MARKEND  DoEglHeapCheck()
       
   492 
       
   493 
       
   494 void CRemoteTestEnv::RunCurrentTestStepL()
       
   495     {
       
   496     TInt processHandleMarkDummy;
       
   497     TInt threadHandleMarkStart;
       
   498     TInt threadHandleMarkEnd;
       
   499     TBool finished = EFalse;
       
   500 
       
   501     while(!finished)
       
   502         {
       
   503         //Wait to be signalled to run a test case.
       
   504         User::WaitForRequest(iNotifyRunTestCase);
       
   505         
       
   506         //We are aborting the test step. Tidy up EGL and exit.
       
   507         if(iNotifyRunTestCase.Int() == KErrAbort)
       
   508             {
       
   509             iCurTestStep->EglEndL();
       
   510             iNotifyRunTestCase = KRequestPending;
       
   511             return;
       
   512             }
       
   513         
       
   514         //Rearm the TRequestStatus (The first arming is done in the supervisor thread).
       
   515         iNotifyRunTestCase = KRequestPending;
       
   516 
       
   517         //Run the test case and panic if it leaves. Start/End are just special test cases.
       
   518         if(iCurTestCaseParamsPacket.iTestCase == KStartTestStepCaseNumber)
       
   519             {
       
   520             //Mark the user heap & thread handle count (we don't care about the process handle count).
       
   521             RThread().HandleCount(processHandleMarkDummy, threadHandleMarkStart);
       
   522             __UHEAP_MARK;
       
   523             __EGLHEAP_MARK;
       
   524 
       
   525             //StartRemoteTest.
       
   526             TRAPD(err, iCurTestCaseVerdict = iCurTestStep->DoStartRemoteTestStepL(iCurTestCaseParamsPacket.iParams));
       
   527             __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("tried to leave."), __LINE__));
       
   528             }
       
   529         else if(iCurTestCaseParamsPacket.iTestCase == KEndTestStepCaseNumber)
       
   530             {
       
   531             //EndRemoteTest.
       
   532             TRAPD(err, iCurTestCaseVerdict = iCurTestStep->DoEndRemoteTestStepL(iCurTestCaseParamsPacket.iParams));
       
   533             __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("tried to leave."), __LINE__));
       
   534 
       
   535             //This will cause a panic if the test step leaked memory or thread handles.
       
   536             __UHEAP_MARKEND;
       
   537             __EGLHEAP_MARKEND;
       
   538             RThread().HandleCount(processHandleMarkDummy, threadHandleMarkEnd);
       
   539             __ASSERT_ALWAYS(threadHandleMarkStart == threadHandleMarkEnd, User::Panic(_L("leaked handles."), KErrBadHandle));
       
   540 
       
   541             //Exit the loop (and eventually the thread).
       
   542             finished = ETrue;
       
   543             }
       
   544         else
       
   545             {
       
   546             //Run a regular Test Case.
       
   547             TRAPD(err, iCurTestCaseVerdict = iCurTestStep->DoRunRemoteTestCaseL(iCurTestCaseParamsPacket.iTestCase, iCurTestCaseParamsPacket.iParams));
       
   548             __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("tried to leave."), __LINE__));
       
   549             }
       
   550 
       
   551         //Notify the supervisor that we have completed the test case.
       
   552         RThread supervisor;
       
   553         TInt err = supervisor.Open(iSupervisorId);
       
   554         __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("framework error."), __LINE__));
       
   555         TRequestStatus* notifyFinishTestCase = &iTestCaseListener->iStatus;
       
   556         supervisor.RequestComplete(notifyFinishTestCase, KErrNone);
       
   557         supervisor.Close();
       
   558         }
       
   559     }
       
   560 
       
   561 
       
   562 TInt CRemoteTestEnv::TestThreadEntryPoint(TAny* aSelf)
       
   563     {
       
   564     CRemoteTestEnv* self = static_cast<CRemoteTestEnv*>(aSelf);
       
   565     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   566 
       
   567     TRAPD(err,
       
   568         //Create active scheduler.
       
   569         CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
   570         CleanupStack::PushL(scheduler);
       
   571         CActiveScheduler::Install(scheduler);
       
   572 
       
   573         //Run the current test step.
       
   574         self->RunCurrentTestStepL();
       
   575 
       
   576         //Clean up.
       
   577         CleanupStack::PopAndDestroy(scheduler);
       
   578         );
       
   579 
       
   580     __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
       
   581 
       
   582     delete cleanup;
       
   583     return KErrNone;
       
   584     }
       
   585 
       
   586 
       
   587 void CRemoteTestEnv::SendResult(TRemoteTestVerdict aVerdict)
       
   588     {
       
   589     iResultOutQueue.SendBlocking(TRemoteTestResult(iCurTestCaseParamsPacket.iUid, iCurTestCaseParamsPacket.iTestCase, aVerdict));
       
   590     }
       
   591 
       
   592 
       
   593 void CRemoteTestEnv::SendLog(const TDesC8& aFile, TInt aLine, TInt aSeverity, const TDesC& aMessage)
       
   594     {
       
   595     iResultOutQueue.SendBlocking(TRemoteTestResult(iCurTestCaseParamsPacket.iUid, iCurTestCaseParamsPacket.iTestCase, aFile, aLine, aSeverity, aMessage));
       
   596     }
       
   597 
       
   598 //--------------------------------------------------------------------------------
       
   599 
       
   600 
       
   601 //CRemoteTestStepBase ------------------------------------------------------------
       
   602 
       
   603 CRemoteTestStepBase::CRemoteTestStepBase(TTestUid aUid) :
       
   604     iUid(aUid)
       
   605     {
       
   606     }
       
   607 
       
   608 
       
   609 void CRemoteTestStepBase::ConstructL(CRemoteTestEnv& aTestEnv)
       
   610     {
       
   611     iTestEnv = &aTestEnv;
       
   612     if (iEndpoint.Error() != KErrNone)
       
   613         {
       
   614         RDebug::Printf("Could not construct CRemoteTestStepBase"
       
   615                 " - is EglEndpointNOK enabled?? -- Error: %d", iEndpoint.Error());
       
   616         User::Leave(iEndpoint.Error());
       
   617         }
       
   618     }
       
   619 
       
   620 
       
   621 CRemoteTestStepBase::~CRemoteTestStepBase()
       
   622     {
       
   623     }
       
   624 
       
   625 
       
   626 TRemoteTestVerdict CRemoteTestStepBase::DoStartRemoteTestStepL(const TRemoteTestParams& /*aMessageIn*/)
       
   627     {
       
   628     //Default implementation does nothing.
       
   629     return ERtvPass;
       
   630     }
       
   631 
       
   632 
       
   633 TRemoteTestVerdict CRemoteTestStepBase::DoEndRemoteTestStepL(const TRemoteTestParams& /*aMessageIn*/)
       
   634     {
       
   635     //Default implementation does nothing.
       
   636     return ERtvPass;
       
   637     }
       
   638 
       
   639 
       
   640 class TOverflowTruncate : public TDesOverflow
       
   641     {
       
   642 public:
       
   643     virtual void Overflow(TDes& /*aDes*/)
       
   644         {
       
   645         //Do nothing - just let it truncate.
       
   646         }
       
   647     };
       
   648 
       
   649 
       
   650 void CRemoteTestStepBase::Log(const TText8* aFile, TInt aLine, TInt aSeverity, TRefByValue<const TDesC> aFmt, ...)
       
   651     {
       
   652     if(iTestEnv)
       
   653         {
       
   654         TOverflowTruncate overflow;
       
   655         VA_LIST list;
       
   656         VA_START(list, aFmt);
       
   657         TBuf<0x100> buf;
       
   658         buf.AppendFormatList(aFmt, list, &overflow);
       
   659         TPtrC8 file(aFile);
       
   660         iTestEnv->SendLog(file, aLine, aSeverity, buf);
       
   661         }
       
   662     }
       
   663 
       
   664 
       
   665 void CRemoteTestStepBase::EglStartL()
       
   666     {
       
   667     eglInitialize(eglGetDisplay(EGL_DEFAULT_DISPLAY), NULL, NULL);
       
   668     if (eglGetError()!=EGL_SUCCESS)
       
   669         {
       
   670         REMOTE_INFO_PRINTF1(_L("could not initialise egl"));
       
   671         User::Leave(KErrGeneral);
       
   672         }
       
   673     }
       
   674 
       
   675 
       
   676 void CRemoteTestStepBase::EglEndL()
       
   677     {
       
   678     eglTerminate(eglGetDisplay(EGL_DEFAULT_DISPLAY));
       
   679     if (eglGetError()!=EGL_SUCCESS)
       
   680         {
       
   681         REMOTE_INFO_PRINTF1(_L("could not terminate egl"));
       
   682         User::Leave(KErrGeneral);
       
   683         }
       
   684     eglReleaseThread();
       
   685     }
       
   686 
       
   687 
       
   688 const TEglEndpointWrap& CRemoteTestStepBase::EglEndpoint() const
       
   689     {
       
   690     return iEndpoint;
       
   691     }
       
   692 
       
   693 //--------------------------------------------------------------------------------