diff -r 000000000000 -r bde4ae8d615e os/ossrv/lowlevellibsandfws/pluginfw/Test_Bed/test_bed/UnitTest.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/lowlevellibsandfws/pluginfw/Test_Bed/test_bed/UnitTest.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,336 @@ +// Copyright (c) 1997-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: +// Implementation of the CUnitTest base class. +// +// + +#include +#include +#include +#include + + +EXPORT_C CUnitTest::~CUnitTest() + { + Cancel(); + + // Delete any outstanding asynchronous transitions + if(iOutstandingTransitions) + { + iOutstandingTransitions->Reset(); + delete iOutstandingTransitions; + } + + if(iTransitions) + { + iTransitions->ResetAndDestroy(); + delete iTransitions; + } + + iLeaveErrorArray.Reset(); + + delete iFileMan; + iFs.Close(); + } + +EXPORT_C void CUnitTest::UnitTestConstructL() + { + User::LeaveIfError(iFs.Connect()); + iFileMan = CFileMan::NewL(iFs); + CTimer::ConstructL(); + iTransitions = new(ELeave) RPointerArray; + iOutstandingTransitions = new(ELeave) RPointerArray; + _LIT(KConstructingUnitTestMsg, "Constructed Unit Test named %S"); + iDataLogger.LogInformationWithParameters(KConstructingUnitTestMsg, &iUnitTestName); + } + + +CUnitTestInfo* CUnitTest::TransitionSetL() const + { + CUnitTestInfo* transitionSet = CUnitTestInfo::NewL(iUnitTestName); + return transitionSet; + } + + +EXPORT_C void CUnitTest::RunTest(TTimeIntervalMicroSeconds32 aTimeAfter /*= 0*/) + { + After(aTimeAfter); + _LIT(KTxtSeparator, "-----------------------------------------------------------------------------------"); + _LIT(KStartingUnitTest, "Beginning Unit Test named %S"); + iDataLogger.LogInformation(KTxtSeparator); + iDataLogger.LogInformationWithParameters(KStartingUnitTest, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KStartingUnitTest, &iUnitTestName); + } + +EXPORT_C void CUnitTest::RunL() + { + _LIT(KUnitTestRunLPanic, "CUnitTest::RunL"); + + TInt status = iStatus.Int(); + switch(status) + { + case (KTestBedRepeatTest): /* A stub has requested repeat of the last test */ + // Go back one so that we repeat the last test + --iNextTransitionIndex; + break; + + case (KTestBedTestLeft): /* The last transition's RunL left */ + case (KTestBedTestCancel): /* The last transition was cancelled */ + case (KTestBedLeakTestLoopDetected): /* A leak test detected an infinite loop */ + case (KTestBedFailedPreConditions): /* The last transition failed it's pre conditions */ + case (KTestBedFailedPostConditions): /* The last transition failed it's post conditions */ + // Go to the end of the test so that it finishes + iNextTransitionIndex = iTransitions->Count(); + break; + + case (KTestBedAsynchronousTransition): /* The last transition started an async request */ + // Remember that we have an outstanding request and then carry on + iOutstandingTransitions->Append((*iTransitions)[iNextTransitionIndex - 1]); + break; + + case (KErrNone): + break; + + default: + User::Panic(KUnitTestRunLPanic, KTestBedInvalidStatus); + } + + // If we still have more transitions to run + if(iNextTransitionIndex < iTransitions->Count()) + { + iStatus = KRequestPending; + SetActive(); + + // If the next transition is a blocking one then wait for all outstanding async + // requests to complete. Otherwise just run the next transition + if(((*iTransitions)[iNextTransitionIndex]->IsBlockingTransition()) && + (iOutstandingTransitions->Count() > 0)) + { + iWaitingForCompletion = ETrue; + } + else + { + (*iTransitions)[iNextTransitionIndex]->RunTransition(&iStatus); + ++iNextTransitionIndex; + } + } + else + { + // If we still have outstanding async requests then wait for these to complete + // otherwise we have finished this test + if(iOutstandingTransitions->Count() > 0) + { + iWaitingForCompletion = ETrue; + iStatus = KRequestPending; + SetActive(); + } + else + { + iUnitTestObserver.Complete(this); + + _LIT(KInfoPrintFailed, "Failed: Unit Test"); + _LIT(KTestLeft, "Failed: Unit Test %S left"); + _LIT(KTestLeftWithUnexpectedError, "Failed: Test %S left with unexpected error"); + _LIT(KTestFailed, "Failed: Unit Test %S failed a pre/post condition validation check"); + _LIT(KTestLeftWithExpectedError, "Test %S left with an anticipated error"); + _LIT(KTestCancelled, "Cancelled: Unit Test Transition %S was cancelled"); + _LIT(KTestEnteredInfiniteLoop, "Unit Test Transition %S aborted (infinitely looping)"); + _LIT(KEndingUnitTest, "Successfully completed Unit Test %S"); + // We use RTest if it is present in the framework to validate + // status codes for errors. Note: not all non KErrNone code mean + // there was an error and so we need to selective over which + // cases below we use RTest(). + switch(status) + { + case (KTestBedTestLeft): + { + TInt leaveCode = iCurrentlyExecutingTransition->GetErrorCode(); + //Check to see if the leave code is NOT on the list of known leaving codes + if(iLeaveErrorArray.Find(leaveCode) == KErrNotFound) + { + iDataLogger.LogInformationWithParameters(KTestLeft, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KTestLeft, &iUnitTestName); + if(iRTest) + { + (*iRTest)(status==KErrNone); + } + } + else //Leave code is on the list + { + TInt count = iTransitions->Count(); + //Check transition number and if it is the last transition then this is an expected error + CTransition* lastTransition = (*iTransitions)[count-1]; + if(iCurrentlyExecutingTransition == lastTransition) + { + iDataLogger.LogInformationWithParameters(KTestLeftWithExpectedError, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KEndingUnitTest, &iUnitTestName); + } + else //Otherwise, if not the last transition, the test failed with an unexpected error + { + User::InfoPrint(KInfoPrintFailed); + User::InfoPrint(iUnitTestName); + iDataLogger.LogInformationWithParameters(KTestLeftWithUnexpectedError, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KTestLeftWithUnexpectedError, &iUnitTestName); + if(iRTest) + { + (*iRTest)(status==KErrNone); + } + } + } + } + break; + + case (KTestBedFailedPreConditions): + case (KTestBedFailedPostConditions): + { + User::InfoPrint(KInfoPrintFailed); + User::InfoPrint(iUnitTestName); + iDataLogger.LogInformationWithParameters(KTestFailed, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KTestFailed, &iUnitTestName); + if(iRTest) + { + (*iRTest)(status==KErrNone); + } + } + break; + + case (KTestBedTestCancel): + iDataLogger.LogInformationWithParameters(KTestCancelled, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KTestCancelled, &iUnitTestName); + if(iRTest) + { + (*iRTest)(status==KErrNone); + } + break; + + case (KTestBedLeakTestLoopDetected): + iDataLogger.LogInformationWithParameters(KTestEnteredInfiniteLoop, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KTestEnteredInfiniteLoop, &iUnitTestName); + if(iRTest) + { + (*iRTest)(status==KErrNone); + } + break; + + case (KErrNone): + iDataLogger.LogInformationWithParameters(KEndingUnitTest, &iUnitTestName); + iDataLogger.ReportInformationWithParameters(KEndingUnitTest, &iUnitTestName); + break; + + default: + User::Panic(KUnitTestRunLPanic, KTestBedInvalidStatus); + } + } + } + } + +EXPORT_C void CUnitTest::AddTransitionL(CTransition* aTransition) + { + __ASSERT_DEBUG(aTransition, User::Panic(_L("CUnitTest"), KErrTestBedInvalidTransition)); + CleanupStack::PushL(aTransition); + User::LeaveIfError(iTransitions->Append(aTransition)); + CleanupStack::Pop(aTransition); + } + +EXPORT_C void CUnitTest::AddBlockingTransitionL(CTransition* aTransition) + { + __ASSERT_DEBUG(aTransition, User::Panic(_L("CUnitTest"), KErrTestBedInvalidTransition)); + aTransition->SetBlockingTransition(ETrue); + CleanupStack::PushL(aTransition); + User::LeaveIfError(iTransitions->Append(aTransition)); + CleanupStack::Pop(aTransition); + } + +EXPORT_C void CUnitTest::AddLeaveErrorCodeL(TInt aLeaveErrorCode) + { + User::LeaveIfError(iLeaveErrorArray.Append(aLeaveErrorCode)); + } + +EXPORT_C CTransition& CUnitTest::GetCurrentTransition() const + { + // Check fror a stray stub call + // We will always have a valid pointer here IF called + // from a stub in response to that transition's call + // on the stub's methods. + __ASSERT_DEBUG(iCurrentlyExecutingTransition, User::Invariant()); + return *iCurrentlyExecutingTransition; + } + +EXPORT_C void CUnitTest::SetCurrentTransition(CTransition& aTransition) + { + iCurrentlyExecutingTransition = &aTransition; + } + +EXPORT_C void CUnitTest::Complete(CTransition& aTransition, TInt aAsyncPostCheckError) + { + // Should never be NULL at this point + __ASSERT_DEBUG(iCurrentlyExecutingTransition, User::Invariant()); + if(iCurrentlyExecutingTransition == &aTransition) + iCurrentlyExecutingTransition = NULL; // Clear the current transition + + // Oops the code will crash if this is ever false + __ASSERT_DEBUG(iOutstandingTransitions, User::Invariant()); + + // Look-up the transition passed in... + TInt index = iOutstandingTransitions->Find(&aTransition); + if(index != KErrNotFound) + { + // ... and remove from the set of outstanding ones. + iOutstandingTransitions->Remove(index); + + // Did we fail a second-phase post-condition validation on an asynchronous transition? + // Or was it a normal transition completion? Regardless, we go for another iteration + // of the AO, passing through the error code. + TBool completeIt = (aAsyncPostCheckError != KErrNone); + if(iWaitingForCompletion && (iOutstandingTransitions->Count() == 0)) + completeIt = ETrue; + + if (completeIt) + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, aAsyncPostCheckError); + } + } + else + { + __ASSERT_DEBUG(ETrue, + User::Panic(_L("CUnitTest"), KErrTestBedInvalidTransition)); + } + } + +EXPORT_C void CUnitTest::SetParametersL(TAny* /*aParams*/) + { + // Do nothing + } + +EXPORT_C void CUnitTest::DoCancel() + { + CTimer::DoCancel(); + + if(iCurrentlyExecutingTransition) + iCurrentlyExecutingTransition->Cancel(); + + // Cancel any outstanding asynchronous transitions + if(iOutstandingTransitions) + { + TInt count = iOutstandingTransitions->Count(); + for(TInt index = 0; index < count; ++index) + { + (*iOutstandingTransitions)[index]->Cancel(); + } + } + + iUnitTestObserver.Complete(this); + } +