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