diff -r 000000000000 -r bde4ae8d615e os/security/cryptomgmtlibs/securitytestfw/test/testhandler2/t_testrunner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/cryptomgmtlibs/securitytestfw/test/testhandler2/t_testrunner.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,336 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 "t_testrunner.h" +#include "t_testaction.h" +#include "t_output.h" + +// CTestRunner ///////////////////////////////////////////////////////////////// + +EXPORT_C CTestRunner::CTestRunner(Output& aOut) : + CActive(EPriorityNormal), + iOut(aOut) + { + CActiveScheduler::Add(this); + } + +EXPORT_C CTestRunner::~CTestRunner() + { + Cancel(); + } + +EXPORT_C TInt CTestRunner::PerformPrerequisiteL(CTestAction* aAction) + { + TInt err = KErrNone; + while (!aAction->Finished() && aAction->iActionState == CTestAction::EPrerequisite) + { + err = RunAsyncMethodL(&CTestAction::PerformPrerequisite, aAction, err); + } + return err; + } + +EXPORT_C TInt CTestRunner::PerformActionL(CTestAction* aAction) + { + TInt err = KErrNone; + while (!aAction->Finished() && aAction->iActionState == CTestAction::EAction) + { + err = RunAsyncMethodL(&CTestAction::PerformAction, aAction, err); + } + return err; + } + +EXPORT_C TInt CTestRunner::PerformPostrequisiteL(CTestAction* aAction, TInt aInitialStatus) + { + TInt err = aInitialStatus; + while (!aAction->Finished() && aAction->iActionState == CTestAction::EPostrequisite) + { + err = RunAsyncMethodL(&CTestAction::PerformPostrequisite, aAction, err); + } + return err; + } + +TInt CTestRunner::RunAsyncMethodL(TTestMethod aMethod, CTestAction* aAction, TInt aInitialStatus) + { + iStatus = aInitialStatus; + TRAPD(err, (aAction->*aMethod)(iStatus)); + if (err != KErrNone) + { + iStatus = err; + if (err != KErrNoMemory) + { + aAction->iActionState = CTestAction::EPostrequisite; + } + } + else + { + SetActive(); + RunSchedulerL(); + } + + return iStatus.Int(); + } + +void CTestRunner::RunSchedulerL() + { + iSchedulerRunning = ETrue; + CActiveScheduler::Start(); + } + +TBool CTestRunner::StepScheduler() + { + User::WaitForAnyRequest(); + TInt err; + if (!CActiveScheduler::Current()->RunIfReady(err, EPriorityNull)) + { + User::Invariant(); + } + return !IsActive(); + } + +EXPORT_C void CTestRunner::RunL() + { + if (iSchedulerRunning) + { + iSchedulerRunning = EFalse; + CActiveScheduler::Stop(); + } + } + +EXPORT_C TInt CTestRunner::RunError(TInt /*aError*/) + { + return KErrGeneral; // RunL() can never leave + } + +EXPORT_C void CTestRunner::DoCancel() + { + } + +// COOMTestRunnerBase //////////////////////////////////////////////////////////////////// + +/// Max OOM fail count, to prevent runaway tests +const TInt KOOMFailLimit = 10000; + +EXPORT_C COOMTestRunnerBase::COOMTestRunnerBase(Output& aOut) : + CTestRunner(aOut) + { + } + +EXPORT_C COOMTestRunnerBase::~COOMTestRunnerBase() + { + } + +EXPORT_C TInt COOMTestRunnerBase::PerformActionL(CTestAction* aAction) + { + iOut.writeString(_L("Running OOM test...")); + iOut.writeNewLine(); + iOut.writeString(_L("Fail point: Heap used: Action state: Status:")); + iOut.writeNewLine(); + + StartOOMTestL(); + + TInt allocStart = AllocCount(); + + TInt failCount; + TInt err = KErrNone; + for (failCount = 1 ; failCount < KOOMFailLimit ; ++failCount) + { + IncHeapFailPoint(); + + err = KErrNone; + TInt actionState = 0; + while (!aAction->Finished() && aAction->iActionState == CTestAction::EAction && err != KErrNoMemory) + { + ++actionState; + err = RunAsyncMethodL(&CTestAction::PerformAction, aAction, err); + } + + TInt allocEnd = AllocCount(); + ResetHeapFail(); + + TBuf<128> buffer; + buffer.Format(_L(" %8d %8d %8d %8d"), failCount, allocEnd - allocStart, actionState, err); + iOut.writeString(buffer); + iOut.writeNewLine(); + + if (err != KErrNoMemory || aAction->Finished() || aAction->iActionState != CTestAction::EAction) + { + // Test finished + break; + } + + aAction->AfterOOMFailure(); + aAction->Reset(); + aAction->ResetState(); + } + + EndOOMTestL(); + + if (failCount == KOOMFailLimit) + { + // Runaway OOM test + iOut.writeString(_L("OOM test failed to terminate")); + iOut.writeNewLine(); + return KErrGeneral; + } + + return err; + } + +// COOMTestRunner //////////////////////////////////////////////////////////////////////// + +COOMTestRunner::COOMTestRunner(Output& aOut) : + COOMTestRunnerBase(aOut) + { + } + +COOMTestRunner::~COOMTestRunner() + { + } + +void COOMTestRunner::StartOOMTestL() + { + iFailPoint = 0; + } + +void COOMTestRunner::IncHeapFailPoint() + { + ++iFailPoint; + __UHEAP_SETFAIL(RHeap::EDeterministic, iFailPoint); + } + +void COOMTestRunner::ResetHeapFail() + { + __UHEAP_RESET; + } + +TInt COOMTestRunner::AllocCount() + { + return User::CountAllocCells(); + } + +void COOMTestRunner::EndOOMTestL() + { + } + +// CCancelTestRunner ///////////////////////////////////////////////////////////////////// + +/// Max cancel step, to prevent runaway tests +const TInt KCancelStepLimit = 200; + +CCancelTestRunner::CCancelTestRunner(Output& aOut) : + CTestRunner(aOut) + { + } + +CCancelTestRunner::~CCancelTestRunner() + { + } + +/** + * Run the async PerformAction method for a specified number of steps and then + * cancel it. This does the equivalent of RunAsyncMethod, but calling + * PerformAction and cancelling it. + */ +TInt CCancelTestRunner::RunAndCancelPeformActionMethod(CTestAction* aAction, TInt aInitialStatus, + TInt aCancelStep, TInt& aStep) + { + iStatus = aInitialStatus; + TRAPD(err, aAction->PerformAction(iStatus)); + if (err != KErrNone) + { + return err; + } + + SetActive(); + + // This is our equivalent of an active scheduler loop + while (IsActive()) + { + StepScheduler(); + + // Check if we can cancel this step + if (iStatus.Int() == KRequestPending) + { + ++aStep; + // Check if this is the step we want to cancel + if (aStep == aCancelStep) + { + // Cancel request + aAction->PerformCancel(); + + // Check request completed immediately + if (iStatus.Int() == KRequestPending) + { + iOut.writeString(_L("Cancelled request not completed immediately!")); + iOut.writeNewLine(); + iAbort = ETrue; + } + } + } + } + + return iAbort ? KErrGeneral : iStatus.Int(); + } + +/** + * Run the test action for a specified number of steps and then cancel it. + */ +TInt CCancelTestRunner::RunAndCancelTestAction(CTestAction* aAction, TInt aCancelStep) + { + TInt err = KErrNone; + TInt step = 0; + TInt actionState = 0; + while (!iAbort && !aAction->Finished() && aAction->iActionState == CTestAction::EAction && err != KErrCancel) + { + ++actionState; + err = RunAndCancelPeformActionMethod(aAction, err, aCancelStep, step); + } + + TBuf<128> buffer; + buffer.Format(_L(" %8d %8d %8d %8d"), aCancelStep, step, actionState, err); + iOut.writeString(buffer); + iOut.writeNewLine(); + + return err; + } + +TInt CCancelTestRunner::PerformActionL(CTestAction* aAction) + { + iOut.writeString(_L("Running cancellation test...")); + iOut.writeNewLine(); + iOut.writeString(_L("Fail step: Total steps: Action state: Status:")); + iOut.writeNewLine(); + + iAbort = EFalse; + for (TInt step = 1 ; step <= KCancelStepLimit ; ++step) + { + TInt err = RunAndCancelTestAction(aAction, step); + + if (iAbort || aAction->Finished() || aAction->iActionState != CTestAction::EAction) + { + return err; + } + + aAction->Reset(); + } + + // Runaway cancel test + iOut.writeString(_L("Cancel test failed to terminate")); + iOut.writeNewLine(); + return KErrGeneral; + }