landmarks/locationlandmarks/tsrc/LandmarkTestModule/src/FT_CPosTp58.cpp
author hgs
Fri, 09 Jul 2010 20:18:03 +0530
changeset 35 1a92308afc46
parent 33 834e27cad510
permissions -rw-r--r--
201027

/*
* Copyright (c) 2005 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: 
*   ?description_line
*
*/


//  INCLUDES
#include "FT_CPosTp58.h"
#include <EPos_CPosLandmarkDatabase.h>
#include <EPos_CPosLandmarkParser.h>

// CONSTANTS
#ifdef __WINS__
_LIT(KXMLFile, "z:\\system\\test\\testdata\\Tp49ImportInput.xml"); // re-use
#else
_LIT(KXMLFile, "c:\\system\\test\\testdata\\Tp49ImportInput.xml"); // re-use
#endif
_LIT(KTp58Panic, "Timeout Panic");
const TInt KTp58PanicNumber = 58;

// ================= LOCAL FUNCTIONS =======================

// ---------------------------------------------------------
// LOCAL_C ImportThreadFunction
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C TInt ImportThreadFunction(TAny* aData)
    {
    CTrapCleanup* cleanup = CTrapCleanup::New(); 

    CActiveScheduler* actSch = new (ELeave) CActiveScheduler;
    CActiveScheduler::Install(actSch);

    TRAPD(err, CPosTp58::RunImportTestL(aData));
       
    delete actSch;
    delete cleanup;
    return err;
    }

// ---------------------------------------------------------
// LOCAL_C KillerThreadFunction
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
LOCAL_C TInt KillerThreadFunction(TAny* aData)
    {
    CTrapCleanup* cleanup = CTrapCleanup::New(); 

    CActiveScheduler* actSch = new (ELeave) CActiveScheduler;
    CActiveScheduler::Install(actSch);

    TRAPD(err, CPosTp58::RunThreadKillerL(reinterpret_cast <RThread*> (aData)));
       
    delete actSch;
    delete cleanup;
    return err;
    }

// ================= MEMBER FUNCTIONS =======================

// ---------------------------------------------------------
// CPosTp58::GetName
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::GetName(TDes& aName) const
    {
    _LIT(KTestName, "TP58 - Import landmarks using User::WaitForRequest()");
    aName = KTestName;
    }

// ---------------------------------------------------------
// CPosTp58::InitTestL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::InitTestL()
    {
    MakeSurePanicDebugFileExistsL();
    }

// ---------------------------------------------------------
// CPosTp58::CloseTest
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::CloseTest()
    {
    }

// ---------------------------------------------------------
// CPosTp58::StartL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::StartL()
    {
// Test Import all landmarks
    iLog->Put(_L("Importing all landmarks"));
    iTestCase = ETestImportAllLandmarks;
    iExpectedErrorCode = KErrGeneral;
    ResumeThreadsAndVerifyExitL();

// Test Import subset of landmarks
    iLog->Put(_L("Importing subset of all landmarks"));
    iTestCase = ETestImportSubsetOfLandmarks;
    iExpectedErrorCode = KErrGeneral;
    ResumeThreadsAndVerifyExitL();
    }

// ---------------------------------------------------------
// CPosTp58::InitDbLC
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
CPosLandmarkDatabase* CPosTp58::InitDbLC()
    {
    RemoveDefaultDbL();
    CPosLandmarkDatabase* database = CPosLandmarkDatabase::OpenL();
    CleanupStack::PushL(database);
    
    if (database->IsInitializingNeeded())
        {
        ExecuteAndDeleteLD(database->InitializeL());
        }

    return database;
    }

// ---------------------------------------------------------
// CPosTp58::RunImportTestL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::RunImportTestL(TAny* aData)
    {
    CPosTp58* tp58 = reinterpret_cast <CPosTp58*> (aData);

    switch (tp58->iTestCase)
        {
        case ETestImportAllLandmarks:
            tp58->ImportLandmarksL(NULL);
            break;
        case ETestImportSubsetOfLandmarks:
            {
            RArray<TUint> subset;
            CleanupClosePushL(subset);    
            subset.Append(5);
            subset.Append(1);
            subset.Append(9);
            subset.Append(3);

            tp58->ImportLandmarksL(&subset);

            CleanupStack::PopAndDestroy(&subset);
            }
            break;
        };
    }

// ---------------------------------------------------------
// CPosTp58::RunThreadKillerL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::RunThreadKillerL(RThread* aThread)
    {
    TTimeIntervalMicroSeconds32 oneMinute = 60 * 1000000;

    // Enter a infinite loop. This reason to this is that I want to be sure 
    // that it is killed by the TP58-thread.
    TBool forever = ETrue;
    while (forever)
        {
        User::After(oneMinute);

        // Panic importThread if it is still alive
        if (aThread->ExitType() == EExitPending)
            {
            TRequestStatus status;
            aThread->Logon(status);
            aThread->Panic(KTp58Panic, KTp58PanicNumber);
            User::WaitForRequest(status);
            }
        }
    }

// ---------------------------------------------------------
// CPosTp58::ImportLandmarksL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::ImportLandmarksL(const RArray<TUint>* aLandmarkSubSet)
    {
    CPosLandmarkDatabase* db = InitDbLC();

    // Recreate parser
    CPosLandmarkParser* landmarkParser = CPosLandmarkParser::NewL(KMimeType);
    CleanupStack::PushL(landmarkParser);
    landmarkParser->SetInputFileL(KXMLFile);

    CPosLmOperation* operation = NULL;
    if (aLandmarkSubSet)
        {
        // Import only a subset of the landmarks in parser
        operation = db->ImportLandmarksL(
            *landmarkParser, 
            *aLandmarkSubSet,  
            CPosLandmarkDatabase::EDefaultOptions);
        }
    else
        {
        operation = db->ImportLandmarksL(
            *landmarkParser, 
            CPosLandmarkDatabase::EDefaultOptions);
        }
    TRequestStatus status(KPosLmOperationNotComplete);
    TReal32 progress(0);
    operation->NextStep(status, progress);

    // Wait for NextStep to complete - should hang
    User::WaitForRequest(status);

    // Cancel the import operation
    delete operation;

    CleanupStack::PopAndDestroy(2, db);
    }

// ---------------------------------------------------------
// CPosTp58::ResumeThreadsAndVerifyExitL
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CPosTp58::ResumeThreadsAndVerifyExitL()
    {
    iLog->Put(_L("ResumeThreadAndVerifyExitL"));
    _LIT(KCreateThreadErr, "Creating thread failed with %d");

	TBuf<100> threadName;
    // Create import thread
    RThread importThread;
    CleanupClosePushL(importThread);
    _LIT(KImportThreadName, "TP58 - Import thread, part %d");
    threadName.Format(KImportThreadName, iTestCase);
    iLog->Put(_L("Creating Import thread"));
    //TInt err = importThread.Create(KImportThreadName, ImportThreadFunction, 
    TInt err = importThread.Create(threadName, ImportThreadFunction, 
        KDefaultStackSize, KMinHeapSize, KMaxHeapSize, this);

    AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);

    // Create killer thread
    RThread killerThread;
    CleanupClosePushL(killerThread);
    _LIT(KKillerThreadName, "TP58 - Killer thread, part %d");
    threadName.Format(KKillerThreadName, iTestCase);
    iLog->Put(_L("Creating Killer thread"));
    err = killerThread.Create(threadName, KillerThreadFunction, 
        KDefaultStackSize, KMinHeapSize, KMaxHeapSize, &importThread);
    AssertTrueSecL(err == KErrNone, KCreateThreadErr, err);

    // Start threads and wait until either of them exits.
    TRequestStatus importThreadStatus, killerThreadStatus;
    importThread.Logon(importThreadStatus);
    importThread.Resume();
    killerThread.Logon(killerThreadStatus);
    killerThread.Resume();
    User::WaitForRequest(importThreadStatus, killerThreadStatus);

    // Kill the thread that might still be alive
    TExitType importThreadExitType = importThread.ExitType();
    TExitCategoryName importThreadExitCategory = importThread.ExitCategory();
    TInt importThreadExitReason = importThread.ExitReason();
    if (importThreadExitType == EExitPending)
        {
        importThread.Kill(KErrCancel);
        User::WaitForRequest(importThreadStatus);
        }
    TExitType killerThreadExitType = killerThread.ExitType();
    TExitCategoryName killerThreadExitCategory = killerThread.ExitCategory();
    TInt killerThreadExitReason = killerThread.ExitReason();
    if (killerThreadExitType == EExitPending)
        {
        killerThread.Kill(KErrCancel);
        User::WaitForRequest(killerThreadStatus);
        }
    
    // Log threads' exit results
    TBuf<100> buf;
    buf.Format(
        _L("ImportThread ended with exit type: %d, exit reason: %d, exit category: %S"), 
        importThreadExitType, importThreadExitReason, &importThreadExitCategory);
    iLog->Put(buf);
    buf.Format(
        _L("KillerThread ended with exit type: %d, exit reason: %d, exit category: %S"), 
        killerThreadExitType, killerThreadExitReason, &killerThreadExitCategory);
    iLog->Put(buf);

    // Verify thread exit results
    TBool error = VerifyThreadExitResults(killerThreadExitType, importThreadExitType, 
        importThreadExitCategory, importThreadExitReason);
    if (error)
        {
        User::Leave(KErrGeneral);
        }

    CleanupStack::PopAndDestroy(2, &importThread);
    }

// ---------------------------------------------------------
// CPosTp58::VerifyThreadExitResults
//
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CPosTp58::VerifyThreadExitResults(
    TExitType aKillerThreadExitType,
    TExitType aImportThreadExitType,
    const TExitCategoryName& aImportThreadExitCategory,
    TInt aImportThreadExitReason)
    {
    TBool error = EFalse;

    if (aImportThreadExitType != EExitPanic)
        {
        _LIT(KExitTypeErr, "Import thread was not panicked as expected.");
        iLog->PutError(KExitTypeErr);
        error = ETrue;
        }
    if (aImportThreadExitCategory != KTp58Panic)
        {
        _LIT(KPanicErr, "Import thread had unexpected panic category");
        iLog->PutError(KPanicErr);
        error = ETrue;
        }
    if (aImportThreadExitReason != KTp58PanicNumber)
        {
        _LIT(KPanicCodeErr, "Import thread had unexpected panic number");
        iLog->PutError(KPanicCodeErr);
        error = ETrue;
        }
    if (aKillerThreadExitType != EExitPending)
        {
        _LIT(KExitTypeErr, "Killer thread was not alive as expected.");
        iLog->PutError(KExitTypeErr);
        error = ETrue;
        }

    return error;
    }

//  End of File