sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "ComponentTester.h" sl@0: #include sl@0: #include sl@0: sl@0: EXPORT_C CComponentTester::CComponentTester(CDataLogger& aDataLogger, sl@0: MComponentTestObserver& aObserver) sl@0: : CActive(CActive::EPriorityStandard), sl@0: iDataLogger(aDataLogger), sl@0: iObserver(aObserver) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: sl@0: EXPORT_C CComponentTester::~CComponentTester() sl@0: { sl@0: Cancel(); sl@0: sl@0: // This should only be true during if TransitionSetsL() left and we are being sl@0: // destroyed as part of cleanup sl@0: if(iTransitionSets) sl@0: { sl@0: iTransitionSets->ResetAndDestroy(); sl@0: delete iTransitionSets; sl@0: } sl@0: iParameterizedTests.Reset(); sl@0: if(iUnitTests) sl@0: { sl@0: iUnitTests->ResetAndDestroy(); sl@0: delete iUnitTests; sl@0: } sl@0: if(iUnitTestsToRun) sl@0: { sl@0: // We own the list but not the things on it. So reset the list and delete it sl@0: iUnitTestsToRun->Reset(); sl@0: delete iUnitTestsToRun; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::ComponentTesterConstructL() sl@0: { sl@0: iUnitTests = new(ELeave) RPointerArray; sl@0: } sl@0: sl@0: sl@0: EXPORT_C RPointerArray* CComponentTester::TransitionSetsL() const sl@0: { sl@0: // Create the array in a member variable to ensure correct cleanup but we do not sl@0: // own this object. Ownership is passed at the return sl@0: iTransitionSets = new(ELeave) RPointerArray; sl@0: sl@0: if(iUnitTests) sl@0: { sl@0: TInt numTests = iUnitTests->Count(); sl@0: for(TInt index = 0; index < numTests; index++) sl@0: { sl@0: CUnitTestInfo* newSet = (*iUnitTests)[index]->TransitionSetL(); sl@0: CleanupStack::PushL(newSet); sl@0: User::LeaveIfError(iTransitionSets->Append(newSet)); sl@0: CleanupStack::Pop(newSet); // now owned by iTransitionSets sl@0: } sl@0: } sl@0: sl@0: // Return the pointer and null our member variable because we don't own it sl@0: RPointerArray* transitionSets = iTransitionSets; sl@0: iTransitionSets = 0; sl@0: return transitionSets; sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::Complete(CUnitTest* aUnitTest) sl@0: { sl@0: if(iUnitTestsToRun != 0) sl@0: { sl@0: if(iCurrentUnitTest == iUnitTestsToRun->Count()) sl@0: { sl@0: iObserver.Complete(this, iUnitTests->Find(aUnitTest)); sl@0: } sl@0: else sl@0: { sl@0: TRequestStatus* status = &iStatus; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if(iCurrentUnitTest == iUnitTests->Count()) sl@0: { sl@0: iObserver.Complete(this, iUnitTests->Find(aUnitTest)); sl@0: } sl@0: else sl@0: { sl@0: TRequestStatus* status = &iStatus; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::AddUnitTestL(const CUnitTest* aUnitTest) sl@0: { sl@0: CUnitTest* thisTest = CONST_CAST(CUnitTest*, aUnitTest); sl@0: CleanupStack::PushL(thisTest); sl@0: User::LeaveIfError(iUnitTests->Append(thisTest)); sl@0: CleanupStack::Pop(thisTest); sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::AddParamUnitTestL(const CUnitTest* aUnitTest) sl@0: { sl@0: CUnitTest* thisTest = CONST_CAST(CUnitTest*, aUnitTest); sl@0: CleanupStack::PushL(thisTest); sl@0: User::LeaveIfError(iUnitTests->Append(thisTest)); sl@0: CleanupStack::Pop(thisTest); sl@0: TInt testId = iUnitTests->Find(thisTest); sl@0: User::LeaveIfError(iParameterizedTests.Append(testId)); sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::TestComponent(RPointerArray* aTests) sl@0: { sl@0: _LIT(KStartingTestMessage, "Starting CComponentTester::TestComponent()..."); sl@0: iDataLogger.LogInformation(KStartingTestMessage); sl@0: sl@0: iUnitTestsToRun = aTests; sl@0: sl@0: SetActive(); sl@0: TRequestStatus* status = &iStatus; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::RunL() sl@0: { sl@0: TBool lastTestRun = EFalse; sl@0: if(iUnitTestsToRun == 0) sl@0: { sl@0: TBool startFromFirst = iCurrentUnitTest == 0; sl@0: TBool haveRunTest = EFalse; sl@0: while((iCurrentUnitTest < iUnitTests->Count()) && !haveRunTest) sl@0: { sl@0: if(iParameterizedTests.Find(iCurrentUnitTest) == -1) sl@0: { sl@0: (*iUnitTests)[iCurrentUnitTest]->PrepareUnitTestL(); sl@0: (*iUnitTests)[iCurrentUnitTest]->RunTest(0); sl@0: haveRunTest = ETrue; sl@0: } sl@0: ++iCurrentUnitTest; sl@0: lastTestRun = iCurrentUnitTest == iUnitTests->Count(); sl@0: } sl@0: if(startFromFirst && !haveRunTest) sl@0: iObserver.Complete(this, KErrNotFound); sl@0: } sl@0: else sl@0: { sl@0: if(iCurrentUnitTest < iUnitTestsToRun->Count()) sl@0: { sl@0: TInt testToRun = (*iUnitTestsToRun)[iCurrentUnitTest]->iUnitTestId; sl@0: TTimeIntervalMicroSeconds32 time = (*iUnitTestsToRun)[iCurrentUnitTest]->iRunTime; sl@0: (*iUnitTests)[testToRun]->SetParametersL((*iUnitTestsToRun)[iCurrentUnitTest]->iParameters); sl@0: (*iUnitTests)[testToRun]->PrepareUnitTestL(); sl@0: (*iUnitTests)[testToRun]->RunTest(time); sl@0: ++iCurrentUnitTest; sl@0: lastTestRun = iCurrentUnitTest == iUnitTestsToRun->Count(); sl@0: } sl@0: } sl@0: sl@0: // We don't need to be active for the last test because we don't RunL again sl@0: if(!lastTestRun) sl@0: { sl@0: iStatus = KRequestPending; sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::DoCancel() sl@0: { sl@0: // If we have started a test then we have already advanced iCurrentUnitTest so cancel sl@0: // the previous test sl@0: if(iCurrentUnitTest > 0) sl@0: (*iUnitTests)[iCurrentUnitTest - 1]->Cancel(); sl@0: sl@0: iObserver.Complete(this, KTestBedTestCancel); sl@0: } sl@0: sl@0: EXPORT_C void CComponentTester::SetRTest(RTest* aRTest) sl@0: { sl@0: // Record a handle on the RTest object to use in component testing. sl@0: iRTest = aRTest; sl@0: sl@0: // We have a new RTest, best tell the unit tests we know about sl@0: for (int ut=0; ut < iUnitTests->Count(); ut++) sl@0: (*iUnitTests)[ut]->SetRTest(aRTest); sl@0: } sl@0: