symbianunittestfw/sutfw/sutfwcore/sutfwtestrunner/src/symbianunittestrunner.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 25 Aug 2010 15:52:14 +0300
changeset 0 20abbd395761
permissions -rw-r--r--
Revision: 201033

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  
*
*/

#include "symbianunittestrunner.h"
#include "symbianunittestuicallback.h"
#include "symbianunittestoutputformatter.h"
#include "symbianunittestoutputfactory.h"
#include "symbianunittestresult.h"
#include "symbianunittestversion.h"
#include "sutlogger.h"
#include "symbianunittestlddctl.h"
#include <symbianunittestinterface.h>
#include <e32uid.h>


// Failures while loading dll:
_LIT( KFailedToFindDll, "Failed to find DLL:\n\"%S\"\n" );
_LIT( KFailedToLoadLDD, "Failed to load LDD:\n\"%S\"\n" );
_LIT( KFailedToRunLDD, "Failed to run LDD tests:\n\"%S\"\n" );
_LIT( KNonCompatibleUIDs, "Cannot use DLL with non-compatible UIDs!\n" );
_LIT( KExportFuncNotFound, "Cannot find EXPORT function from test DLL!\n" );
_LIT( KLogVersion, "SymbianUnitTest v%d.%d.%d" );
_LIT( KLogFinish, "SymbianUnitTest finished" );

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C CSymbianUnitTestRunner* CSymbianUnitTestRunner::NewLC( 
    MSymbianUnitTestUiCallBack& aUiCallBack )
    {
    CSymbianUnitTestRunner* self = 
        new( ELeave )CSymbianUnitTestRunner( aUiCallBack );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C CSymbianUnitTestRunner* CSymbianUnitTestRunner::NewL( 
    MSymbianUnitTestUiCallBack& aUiCallBack )
    {
    CSymbianUnitTestRunner* self = CSymbianUnitTestRunner::NewLC( aUiCallBack );
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
CSymbianUnitTestRunner::CSymbianUnitTestRunner( 
    MSymbianUnitTestUiCallBack& aUiCallBack )
    : iUiCallBack( aUiCallBack )
    {
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::ConstructL()
    {
    iResult = CSymbianUnitTestResult::NewL();
    //init logger
    TBuf<50> version;
    version.Format(KLogVersion, SUT_MAJOR_VERSION, SUT_MINOR_VERSION, SUT_BUILD_VERSION);
    SUT_LOG_START(version);
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C CSymbianUnitTestRunner::~CSymbianUnitTestRunner()
    {
    delete iResult;
    }

// -----------------------------------------------------------------------------
// From MSymbianUnitTestObserver
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::TestPass(const TDesC& aTestCaseName)
    {
    iUiCallBack.TestPass(aTestCaseName);
    }

// -----------------------------------------------------------------------------
// From MSymbianUnitTestObserver
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::TestFailed(const TDesC& aTestCaseName, const TDesC8& aErrMsg)
    {
    iUiCallBack.TestFailed(aTestCaseName, aErrMsg);
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CSymbianUnitTestRunner::TestCount()
    {
    return iTestCount;
    }

EXPORT_C TInt CSymbianUnitTestRunner::TestCountL(const MDesCArray& aTestDllNames, const MDesCArray& aTestCaseNames)
    {
    TInt dllCnt = aTestDllNames.MdcaCount(); 
    if (dllCnt == 0)
        {
        return 0;
        }
    TInt caseCnt = aTestCaseNames.MdcaCount();
    if (caseCnt != 0)
        {
        return caseCnt;
        }
    else
        {
        for ( TInt i = 0; i < dllCnt; i++)
            {
            CDesCArray* testCaseNames = new (ELeave) CDesCArrayFlat(1);
            CleanupStack::PushL(testCaseNames);
            this->TestCaseNamesL(aTestDllNames.MdcaPoint(i), *testCaseNames);
            caseCnt += testCaseNames->Count();
            CleanupStack::PopAndDestroy(testCaseNames);
            }
        return caseCnt;
        }
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C void CSymbianUnitTestRunner::ExecuteTestsL(
    const MDesCArray& aTestDllNames,
    TBool aMemoryAllocationFailureSimulation,
    const TDesC& aOutputFileName,
    const TDesC& aOutputFormat,
    const CDesCArray& aTestCaseNames,
    TInt  aTimeout )
    {
    iTestCount = 0;
    
    MSymbianUnitTestInterface::TFailureSimulation failureSimulation = 
        MSymbianUnitTestInterface::ENoFailureSimulation;
    if ( aMemoryAllocationFailureSimulation )
        {
        failureSimulation = 
            MSymbianUnitTestInterface::EMemAllocFailureSimulation;
        }
    
    for ( TInt i = 0; i < aTestDllNames.MdcaCount(); i++ )
        {
        TPtrC16 testDllName( aTestDllNames.MdcaPoint( i ) );
        if (testDllName.Find(_L(".ldd"))>0)
            {
            ExecuteLddTestsL(testDllName, aTestCaseNames, aTimeout);
            }
        else
            {
            //it is dll test
            ExecuteDllTestsL(testDllName, failureSimulation, aTestCaseNames, aTimeout);
            }
        }
    
    CSymbianUnitTestOutputFormatter* outputFormatter = 
        SymbianUnitTestOutputFactory::CreateOutputLC( 
            aOutputFileName, aOutputFormat );
    outputFormatter->PrintL( *iResult );
    CleanupStack::PopAndDestroy( outputFormatter );    
    SUT_LOG_INFO(KLogFinish);
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CSymbianUnitTestRunner::FailedTestCount()
    {
    return iResult->Failures().Count();
    }


// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
EXPORT_C void CSymbianUnitTestRunner::TestCaseNamesL(
    const TDesC& aTestDllName, CDesCArray& aTestCaseNames)
    {
    
    if (aTestDllName.Find(_L(".ldd"))>0)
        {
        //it is kernel ldd test
        return GetLddTestCaseNamesL(aTestDllName, aTestCaseNames);
        }
    else
        {
        //it is dll test
        return GetDllTestCaseNamesL(aTestDllName, aTestCaseNames);
        }
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::GetDllTestCaseNamesL(
        const TDesC& aTestDllName, CDesCArray& aTestCaseNames)
    {
    RLibrary library;
    TInt ret;
    ret = library.Load(aTestDllName);
    if (ret != KErrNone)
        {
        iUiCallBack.InfoMsg(KFailedToFindDll, aTestDllName);
        SUT_LOG_FORMAT(KFailedToFindDll, &aTestDllName);
        User::Leave(ret);
        }
    CleanupClosePushL(library);
    // The second UID of the dll to be used must be compatible
    if (library.Type()[1] != KSymbianUnitTestDllUid)
        {
        iUiCallBack.InfoMsg(KNonCompatibleUIDs);
        User::Leave(KErrNotFound);
        }
    TLibraryFunction entryFunction = library.Lookup(1);
    if (!entryFunction)
        {
        iUiCallBack.InfoMsg(KExportFuncNotFound);
        User::Leave(KErrNotFound);
        }

    MSymbianUnitTestInterface* test =
            reinterpret_cast<MSymbianUnitTestInterface*> (entryFunction());
    
    TCleanupItem cleanupItem(DeleteTest, test);
    CleanupStack::PushL(cleanupItem);
    
    test->TestCaseNamesL(aTestCaseNames);
    CleanupStack::Pop(); // cleanupItem
    CleanupStack::PopAndDestroy(&library);
  
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::GetLddTestCaseNamesL(
        const TDesC& aTestLddName, CDesCArray& aTestCaseNames)
    {
    CSymbianUnitTestLddCtl* lddCtl = CSymbianUnitTestLddCtl::NewLC(
            aTestLddName);
    TInt ret = lddCtl->LoadDriver();
    if (ret != KErrNone)
        {
        iUiCallBack.InfoMsg(KFailedToLoadLDD, aTestLddName);
        SUT_LOG_FORMAT(KFailedToLoadLDD, &aTestLddName);
        User::Leave(ret);
        }

    ret = lddCtl->GetTestCaseNames(aTestCaseNames); 
    if (ret != KErrNone)
        {
        iUiCallBack.InfoMsg(KFailedToRunLDD, aTestLddName);
        SUT_LOG_FORMAT(KFailedToRunLDD, &aTestLddName);
        User::Leave(ret);
        }
    lddCtl->FreeDriver();
    CleanupStack::PopAndDestroy(lddCtl);
    SUT_LOG_FORMAT(_L(" case name count:%d\n"), aTestCaseNames.Length());
    for (TInt i = 0; i < aTestCaseNames.Length(); i++)
        {
            SUT_LOG_FORMAT(_L(" case:%S\n"), &aTestCaseNames[i]);
        }
    }

// -----------------------------------------------------------------------------
// 
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::DeleteTest( TAny* aTest )
    {
    MSymbianUnitTestInterface* test = 
        reinterpret_cast< MSymbianUnitTestInterface* >( aTest );
    delete test;
    }

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::ExecuteDllTestsL(const TDesC& aTestDllName, MSymbianUnitTestInterface::TFailureSimulation aFailureSimulation,
        const CDesCArray& aTestCaseNames, TInt  aTimeout)
    {
    RLibrary library;
    TInt ret;
    ret = library.Load(aTestDllName);
    if (ret != KErrNone)
        {
        iUiCallBack.InfoMsg(KFailedToFindDll, aTestDllName);
        SUT_LOG_FORMAT(KFailedToFindDll, &aTestDllName);
        User::Leave(ret);
        }
    CleanupClosePushL(library);
    // The second UID of the dll to be used must be compatible
    if (library.Type()[1] != KSymbianUnitTestDllUid)
        {
        iUiCallBack.InfoMsg(KNonCompatibleUIDs);
        User::Leave(KErrNotFound);
        }
    TLibraryFunction entryFunction = library.Lookup(1);
    if (!entryFunction)
        {
        iUiCallBack.InfoMsg(KExportFuncNotFound);
        User::Leave(KErrNotFound);
        }

    MSymbianUnitTestInterface* test =
            reinterpret_cast<MSymbianUnitTestInterface*> (entryFunction());
    TCleanupItem cleanupItem(DeleteTest, test);
    CleanupStack::PushL(cleanupItem);
    iTestCount += test->TestCaseCount();
    test->ExecuteL(*this, *iResult, aFailureSimulation, aTestCaseNames,
            aTimeout);
    CleanupStack::Pop(); // cleanupItem
    CleanupStack::PopAndDestroy(&library);
    }


// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
void CSymbianUnitTestRunner::ExecuteLddTestsL(const TDesC& aTestLddName, const CDesCArray& /*aTestCaseNames*/,
        TInt  /*aTimeout*/)
    {
    CSymbianUnitTestLddCtl* lddCtl = CSymbianUnitTestLddCtl::NewLC( aTestLddName );
    TInt ret = lddCtl->LoadDriver();
    if (ret != KErrNone)
        {
        iUiCallBack.InfoMsg(KFailedToLoadLDD, aTestLddName);
        SUT_LOG_FORMAT(KFailedToLoadLDD, &aTestLddName);
        User::Leave(ret);
        }
    
    ret = lddCtl->ExecuteLddTests(*this, *iResult);
    if (ret != KErrNone)
            {
            iUiCallBack.InfoMsg(KFailedToRunLDD, aTestLddName);
            SUT_LOG_FORMAT(KFailedToRunLDD, &aTestLddName);
            User::Leave(ret);
            }
    lddCtl->FreeDriver();
    CleanupStack::PopAndDestroy( lddCtl );
    }