--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lowlevellibsandfws/pluginfw/Test_Bed/test_bed/UnitTest.cpp Tue Feb 02 02:01:42 2010 +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 <ecom/test_bed/unittest.h>
+#include <ecom/test_bed/transition.h>
+#include <ecom/test_bed/datalogger.h>
+#include <ecom/test_bed/testbeddefinitions.h>
+
+
+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<CTransition>;
+ iOutstandingTransitions = new(ELeave) RPointerArray<CTransition>;
+ _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);
+ }
+