symbianunittestfw/sutfw/sutfwcore/sutfwkernel/src/symbianunittestldd.cpp
branchRCL_3
changeset 3 9397a16b6eb8
parent 1 6edeef394eb7
equal deleted inserted replaced
1:6edeef394eb7 3:9397a16b6eb8
     1 // Copyright (c) 2008-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 the License "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 // Description:
       
    14 //
       
    15 
       
    16 #include <kernel/kern_priv.h>
       
    17 #include "symbianunittestldd.h"
       
    18 #include "symbianunittestlddif.h"
       
    19 
       
    20 
       
    21 const char* KIntsNotEqualFormat = "Asserted: expected=%d, actual=%d";
       
    22 const char* KDesCsNotEqualFormat = "Asserted: expected='%S', actual='%S'";
       
    23 const TInt KMaxSizeOfTwoIntsAsText = 80;
       
    24 const TInt KTestCaseNameLength = 256;
       
    25 
       
    26 /*
       
    27 class DCrashHandler : public DKernelEventHandler
       
    28     {
       
    29 public:
       
    30     // construction & destruction
       
    31     inline DCrashHandler();
       
    32     TInt Create(DLogicalDevice* aDevice);
       
    33     ~DCrashHandler();
       
    34 
       
    35 private:
       
    36     static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
       
    37     void HandleCrash(TAny* aContext);
       
    38     
       
    39 private:    
       
    40     DLogicalDevice* iDevice;    // open reference to LDD for avoiding lifetime issues    
       
    41     
       
    42     };
       
    43 
       
    44 inline DCrashHandler::DCrashHandler()
       
    45     : DKernelEventHandler(EventHandler, this)
       
    46     {
       
    47     }
       
    48 
       
    49 //
       
    50 // second-phase c'tor.  Called in thread critical section.
       
    51 //
       
    52 
       
    53 TInt DCrashHandler::Create(DLogicalDevice* aDevice)
       
    54     {
       
    55 //    TInt r;
       
    56 //    r = aDevice->Open();
       
    57 //    if (r != KErrNone)
       
    58 //        return r;
       
    59     iDevice = aDevice;
       
    60     return Add();
       
    61     }
       
    62 
       
    63 //
       
    64 // Called when reference count reaches zero.  At that point no threads
       
    65 // are in the handler anymore and the handler has been removed from
       
    66 // the queue.
       
    67 //
       
    68 
       
    69 DCrashHandler::~DCrashHandler()
       
    70     {
       
    71 //    if (iDevice)
       
    72 //        iDevice->Close(NULL);
       
    73     }
       
    74 
       
    75 TUint DCrashHandler::EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis)
       
    76     {
       
    77     DThread* pC = &Kern::CurrentThread();
       
    78     switch (aEvent)
       
    79         {
       
    80     case EEventHwExc:
       
    81         ((DCrashHandler*)aThis)->HandleCrash(a1);
       
    82         return EExcHandled;
       
    83     case EEventKillThread:
       
    84         if (pC->iExitType == EExitPanic)
       
    85             ((DCrashHandler*)aThis)->HandleCrash(NULL);
       
    86         return EExcHandled;
       
    87     default:
       
    88         // ignore other events
       
    89         break;
       
    90         }
       
    91     return ERunNext;
       
    92     }
       
    93 
       
    94 void DCrashHandler::HandleCrash(TAny* aContext)
       
    95     {
       
    96     Kern::Printf("CrashHandler handle crash enter");
       
    97     Kern::Printf("CrashHandler handle crash exit");
       
    98     }
       
    99 
       
   100 */
       
   101 
       
   102 EXPORT_C DSymbianUnitTestFactory::DSymbianUnitTestFactory(const TDesC& aName)
       
   103     {
       
   104     iDriverName.Copy(aName);
       
   105     }
       
   106 
       
   107 EXPORT_C TInt DSymbianUnitTestFactory::Install()
       
   108     {
       
   109     iVersion = TVersion(0,0,1);
       
   110     return SetName(&iDriverName);
       
   111     }
       
   112 
       
   113 EXPORT_C void DSymbianUnitTestFactory::GetCaps(TDes8& /*aDes*/) const
       
   114     {
       
   115     //not supported
       
   116     }
       
   117 
       
   118 EXPORT_C DSymbianUnitTestFactory::~DSymbianUnitTestFactory()
       
   119     {
       
   120     }
       
   121 
       
   122 EXPORT_C DSymbianUnitTest::DSymbianUnitTest()
       
   123     {
       
   124     //get the handler for client thread
       
   125     iClient = &Kern::CurrentThread();
       
   126     ((DObject*)iClient)->Open();
       
   127 
       
   128 //    iCrashHandler = new DCrashHandler();
       
   129 //    iCrashHandler->Create(iDevice);
       
   130     }
       
   131 
       
   132 EXPORT_C TInt DSymbianUnitTest::Setup()
       
   133     {
       
   134     //do nothing by default
       
   135     return KErrNone;
       
   136     }
       
   137 
       
   138 EXPORT_C TInt DSymbianUnitTest::Teardown()
       
   139     {
       
   140     //do nothing by default
       
   141     return KErrNone;
       
   142     }
       
   143 EXPORT_C DSymbianUnitTest::~DSymbianUnitTest()
       
   144     {
       
   145     //delete iName;
       
   146     iTestCases.ResetAndDestroy();
       
   147     
       
   148     //close the client thread handler
       
   149     Kern::SafeClose((DObject*&)iClient,NULL);
       
   150     
       
   151 //    if (iCrashHandler)
       
   152 //        {
       
   153 //        iCrashHandler->Close();
       
   154 //        delete iCrashHandler;
       
   155 //        }
       
   156     }
       
   157 
       
   158 /*
       
   159 EXPORT_C void DSymbianUnitTest::Construct()
       
   160     {
       
   161     //do nothing by default
       
   162     }
       
   163 */
       
   164 
       
   165 EXPORT_C void DSymbianUnitTest::AddTestCase( 
       
   166     const TDesC& aName,
       
   167     FunctionPtr aSetupFunction,
       
   168     FunctionPtr aTestFunction,
       
   169     FunctionPtr aTeardownFunction )
       
   170     {
       
   171     DSymbianUnitTestCase* testCase = new DSymbianUnitTestCase( 
       
   172             aName, aSetupFunction, aTestFunction, aTeardownFunction );
       
   173     iTestCases.Append( testCase );
       
   174     }
       
   175 
       
   176 
       
   177 EXPORT_C  TInt DSymbianUnitTest::Request(TInt aReqNo, TAny* a1, TAny* a2)
       
   178 	{
       
   179 	switch(aReqNo)
       
   180 		{
       
   181 		//new
       
   182 		case RSymbianUnitTest::EEXECUTETESTCASE:
       
   183 			{
       
   184 			return ExecuteTestCase(a1, (TDes8*)a2);
       
   185 			}
       
   186 		case RSymbianUnitTest::ETESTCOUNT:
       
   187 		    return TestCount((TInt*) a1);
       
   188 		case RSymbianUnitTest::ETESTCASENAME:
       
   189 		    return GetTestCaseName(a1, (TDes*)a2);
       
   190 		default:
       
   191 			break;
       
   192 		}
       
   193 	return KErrGeneral;
       
   194 	}
       
   195 
       
   196 
       
   197 TInt DSymbianUnitTest::TestCount(TInt* aDest)
       
   198     {
       
   199     __KTRACE_OPT(KHARDWARE,
       
   200         Kern::Printf("DSymbianUnitTest::TestCount() enter"));
       
   201     TInt count = iTestCases.Count();
       
   202     __KTRACE_OPT(KHARDWARE, 
       
   203         Kern::Printf("  kernel space, test case count [%d]", count));
       
   204     TInt ret = Kern::ThreadRawWrite(iClient, aDest, &count, sizeof(TInt), NULL);
       
   205     __KTRACE_OPT(KHARDWARE, 
       
   206         Kern::Printf("DSymbianUnitTest::TestCount() exit"));
       
   207     return ret;
       
   208     }
       
   209 
       
   210 TInt DSymbianUnitTest::GetTestCaseName(TAny* aIndex, TDes* aCaseName)
       
   211     {
       
   212     __KTRACE_OPT(KHARDWARE,
       
   213             Kern::Printf("DSymbianUnitTest::GetTestCaseName() enter"));
       
   214         TInt index;
       
   215         Kern::ThreadRawRead(iClient, aIndex, &index, sizeof(TInt));
       
   216         DSymbianUnitTestCase* testCase = iTestCases[index];
       
   217         TBuf8<KTestCaseNameLength> buf8;
       
   218         buf8.Copy(testCase->Name());
       
   219         TInt ret = Kern::ThreadDesWrite(iClient, aCaseName, buf8, 0, &Kern::CurrentThread());
       
   220         return ret;
       
   221     }
       
   222 
       
   223 
       
   224 TInt DSymbianUnitTest::ExecuteTestCase(TAny* aIndex, TDes8* aResult)
       
   225     {
       
   226     __KTRACE_OPT(KHARDWARE,
       
   227         Kern::Printf("DSymbianUnitTest::ExecuteTestCase() enter"));
       
   228     TInt index;
       
   229     Kern::ThreadRawRead(iClient, aIndex, &index, sizeof(TInt));
       
   230     DSymbianUnitTestCase* testCase = iTestCases[index];
       
   231     
       
   232     TSUTTestCaseResult result;
       
   233     TPckg<TSUTTestCaseResult> resultPckg(result);
       
   234     iCurrentTestCase = testCase;
       
   235     iCurrentResult = &result;
       
   236     
       
   237     result.iTestName.Copy(iCurrentTestCase->Name());
       
   238     __KTRACE_OPT(KHARDWARE,
       
   239         Kern::Printf("DSymbianUnitTest::Run test case: %S",
       
   240                 &iCurrentTestCase->Name()));
       
   241     
       
   242     //set the owning thread for sem
       
   243     iExecSem.iOwningThread = &Kern::CurrentThread().iNThread;
       
   244     
       
   245     __KTRACE_OPT(KHARDWARE,
       
   246         Kern::Printf("create exec thread"));
       
   247     SThreadCreateInfo info;
       
   248     info.iType=EThreadSupervisor;
       
   249     info.iFunction=(TThreadFunction)DSymbianUnitTest::TestThreadEntryFunction;
       
   250     info.iPtr=this;
       
   251     info.iSupervisorStack=NULL;
       
   252     info.iSupervisorStackSize=0;    // zero means use default value
       
   253     info.iInitialThreadPriority=NKern::CurrentThread()->iPriority;
       
   254     
       
   255     info.iName.Set(iCurrentTestCase->Name());
       
   256     info.iTotalSize = sizeof(info);
       
   257     
       
   258     
       
   259     NKern::ThreadEnterCS();
       
   260     TInt ret = Kern::ThreadCreate(info);
       
   261     NKern::ThreadLeaveCS();
       
   262     
       
   263     if (ret == KErrNone)
       
   264         {
       
   265     
       
   266         DThread* pT=(DThread*)info.iHandle;
       
   267         __KTRACE_OPT(KHARDWARE, 
       
   268             Kern::Printf("start exec thread %0 at %08x", pT, pT));
       
   269         Kern::ThreadResume(*pT);
       
   270         __KTRACE_OPT(KHARDWARE,
       
   271             Kern::Printf("main thread starts to wait on NFastSemaphore"));
       
   272         NKern::FSWait(&(iExecSem));
       
   273         }
       
   274     else
       
   275         {
       
   276         __KTRACE_OPT(KHARDWARE,
       
   277             Kern::Printf("error from TheadCreate: %d", ret));
       
   278         //ret the result
       
   279         result.iRetCode = ret;
       
   280         result.iFailureMessage.Copy(_L("error to create kernel thread to execute test case"));
       
   281         }
       
   282     
       
   283     __KTRACE_OPT(KHARDWARE,
       
   284         Kern::Printf("DSymbianUnitTest::Run test case [%S] return: %d",
       
   285             &result.iTestName , result.iRetCode));
       
   286     __KTRACE_OPT(KHARDWARE,
       
   287         Kern::Printf("kernel msg:%S line:%d file:%S",
       
   288                         &result.iFailureMessage,
       
   289                         result.iLineNumber,
       
   290                         &result.iFileName));
       
   291     return  Kern::ThreadDesWrite(iClient, aResult, resultPckg, 0, 0, &Kern::CurrentThread());
       
   292     }
       
   293 
       
   294 TInt DSymbianUnitTest::ExecuteTestCaseInThread()
       
   295     {
       
   296     TInt ret;
       
   297     ret = (this->*iCurrentTestCase->iSetupFunction)();
       
   298     if (ret != KErrNone)
       
   299         {
       
   300         return ret;
       
   301         }
       
   302     ret = (this->*iCurrentTestCase->iTestFunction)();
       
   303     if (ret != KErrNone)
       
   304         {
       
   305         return ret;
       
   306         }
       
   307     ret = (this->*iCurrentTestCase->iTeardownFunction)();
       
   308     if (ret != KErrNone)
       
   309         {
       
   310         return ret;
       
   311         }
       
   312     return KErrNone;
       
   313     }
       
   314 
       
   315 TInt DSymbianUnitTest::TestThreadEntryFunction( TAny* aPtr )
       
   316     {
       
   317     __KTRACE_OPT(KHARDWARE,
       
   318         Kern::Printf("enter TestThreadEntryFunction enter"));
       
   319     DSymbianUnitTest* self = reinterpret_cast< DSymbianUnitTest* >( aPtr );
       
   320     TInt ret = self->ExecuteTestCaseInThread();
       
   321     __KTRACE_OPT(KHARDWARE,
       
   322         Kern::Printf("exec thread FSSignal on Semaphore"));
       
   323     NKern::FSSignal(&(self->iExecSem));
       
   324     return KErrNone;
       
   325     }
       
   326 
       
   327 
       
   328 EXPORT_C TInt DSymbianUnitTest::AssertEquals(
       
   329     TInt aExpectedValue, 
       
   330     TInt aActualValue, 
       
   331     TInt aLineNumber,
       
   332     const TDesC8& aFileName )
       
   333     {
       
   334     if ( aExpectedValue != aActualValue )
       
   335         {
       
   336         TBuf8<sizeof(KIntsNotEqualFormat) + KMaxSizeOfTwoIntsAsText> msg;
       
   337         Printf(msg, KIntsNotEqualFormat, aExpectedValue, aActualValue);
       
   338         return AssertionFailed( msg, aLineNumber, aFileName );
       
   339         }
       
   340     return KErrNone;
       
   341     }
       
   342 
       
   343 
       
   344 EXPORT_C TInt DSymbianUnitTest::AssertEquals(
       
   345         const TDesC8& aExpectedValue,
       
   346         const TDesC8& aActualValue, 
       
   347         TInt aLineNumber, 
       
   348         const TDesC8& aFileName )
       
   349     {
       
   350     if ( aExpectedValue.Compare( aActualValue ) != 0 )
       
   351             {
       
   352             TBuf8<sizeof(KDesCsNotEqualFormat) + KMaxSizeOfTwoIntsAsText> msg;
       
   353             Printf(msg, KDesCsNotEqualFormat, &aExpectedValue, &aActualValue);
       
   354             return AssertionFailed( msg, aLineNumber, aFileName );
       
   355             }
       
   356         return KErrNone;
       
   357     }
       
   358 
       
   359 
       
   360 EXPORT_C TInt DSymbianUnitTest::AssertionFailed(
       
   361     const TDesC8& aFailureMessage,
       
   362     TInt aLineNumber,
       
   363     const TDesC8& aFileName )
       
   364     {
       
   365     
       
   366     __KTRACE_OPT(KHARDWARE,
       
   367         Kern::Printf("Assertion failed [%S] at file:%S , line number:%d", 
       
   368         &aFailureMessage, &aFileName, aLineNumber));
       
   369     iCurrentResult->iLineNumber = aLineNumber;
       
   370     iCurrentResult->iFailureMessage.Copy(aFailureMessage);
       
   371     iCurrentResult->iFileName.Copy(aFileName);
       
   372     
       
   373     __KTRACE_OPT(KHARDWARE,
       
   374         Kern::Printf("kernel msg:%S line:%d file:%S", 
       
   375             &iCurrentResult->iFailureMessage,
       
   376             iCurrentResult->iLineNumber,
       
   377             &iCurrentResult->iFileName));
       
   378     iCurrentResult->iRetCode = KErrGeneral; 
       
   379     return KErrGeneral;
       
   380     }
       
   381 
       
   382 void DSymbianUnitTest::Printf(TDes8 & aDes, const char* aFmt, ...)
       
   383     {
       
   384     VA_LIST list;
       
   385     VA_START(list, aFmt);
       
   386     Kern::AppendFormat(aDes, aFmt, list);
       
   387     }
       
   388 
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 // -----------------------------------------------------------------------------
       
   392 //
       
   393 DSymbianUnitTest::DSymbianUnitTestCase::DSymbianUnitTestCase(
       
   394     const TDesC& aName,
       
   395     FunctionPtr aSetupFunction,
       
   396     FunctionPtr aTestFunction,
       
   397     FunctionPtr aTeardownFunction ) :
       
   398     iSetupFunction( aSetupFunction ),
       
   399     iTestFunction( aTestFunction ),
       
   400     iTeardownFunction( aTeardownFunction )
       
   401     {
       
   402     iName = HBuf8::New(aName);
       
   403     }
       
   404 
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 //
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 DSymbianUnitTest::DSymbianUnitTestCase::~DSymbianUnitTestCase()
       
   411     {
       
   412     delete iName;
       
   413     }
       
   414 
       
   415 // -----------------------------------------------------------------------------
       
   416 //
       
   417 // -----------------------------------------------------------------------------
       
   418 //
       
   419 const TDesC& DSymbianUnitTest::DSymbianUnitTestCase::Name() const
       
   420     {
       
   421     return *iName;
       
   422     }
       
   423