diff -r 000000000000 -r a41df078684a kerneltest/e32test/usbho/t_usbdi/src/TestPolicy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/usbho/t_usbdi/src/TestPolicy.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,347 @@ +// Copyright (c) 2007-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: +// @file testpolicy.cpp +// @internalComponent +// +// + +#include "TestPolicy.h" +#include "TestCaseFactory.h" +#include "BaseTestCase.h" +#include "TestCaseFactory.h" +#include "testdebug.h" + +namespace NUnitTesting_USBDI + { + +CBasicTestPolicy* CBasicTestPolicy::NewL() + { + CBasicTestPolicy* self = new (ELeave) CBasicTestPolicy; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CBasicTestPolicy::CBasicTestPolicy() +: CActive(EPriorityStandard) + { + CActiveScheduler::Add(this); + } + + +CBasicTestPolicy::~CBasicTestPolicy() + { + LOG_FUNC + + Cancel(); + } + + +void CBasicTestPolicy::ConstructL() + { + } + + +void CBasicTestPolicy::RunTestCaseL(const TDesC& aTestCaseId,TRequestStatus& aNotifierStatus) + { + LOG_FUNC + + iNotifierStatus = &aNotifierStatus; + + // Create the specified test case + + iTestCase = RTestFactory::CreateTestCaseL(aTestCaseId,EFalse); + iTestCase->SetTestPolicy(this); + iTestCase->PerformTestL(); + + // Set the request of the notifier to pending + + *iNotifierStatus = iStatus = KRequestPending; + SetActive(); + } + + +void CBasicTestPolicy::DoCancel() + { + LOG_FUNC + + // Cancel running the test cases + + iTestCase->Cancel(); + + // Notify the test case controller that test case execution was cancelled + + User::RequestComplete(iNotifierStatus,KErrCancel); + } + + +void CBasicTestPolicy::SignalTestComplete(TInt aCompletionCode) + { + LOG_FUNC + + // Complete the test policy request with the test case completion code + // (Basically self completion) + + TRequestStatus* s = &iStatus; + User::RequestComplete(s,aCompletionCode); + } + + +void CBasicTestPolicy::RunL() + { + LOG_FUNC + + // Complete the request of the notifier with the test case + // completion code + + User::RequestComplete(iNotifierStatus,iStatus.Int()); + + // Destroy the test case + + delete iTestCase; + } + + +TInt CBasicTestPolicy::RunError(TInt aError) + { + LOG_FUNC + + aError = KErrNone; + return aError; + } + +CThreadTestPolicy* CThreadTestPolicy::NewL() + { + CThreadTestPolicy* self = new (ELeave) CThreadTestPolicy; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CThreadTestPolicy::CThreadTestPolicy() + { + } + + +CThreadTestPolicy::~CThreadTestPolicy() + { + iTestThread.Close(); + if(iTestCaseId) + { + delete iTestCaseId; + iTestCaseId = NULL; + } + } + +void CThreadTestPolicy::ConstructL() + { + } + +void CThreadTestPolicy::RunTestCaseL(const TDesC& aTestCaseId,TRequestStatus& aNotifierStatus) + { + LOG_FUNC + + iNotifierStatus = &aNotifierStatus; + RDebug::Printf("Creating thread for test case '%S'",&aTestCaseId); + + if(iTestCaseId) + { + delete iTestCaseId; + iTestCaseId = NULL; + } + iTestCaseId = HBufC::NewL(aTestCaseId.Length()); + *iTestCaseId = aTestCaseId; + + // Create the thread to run the test case in + TInt err(iTestThread.Create(aTestCaseId,CThreadTestPolicy::ThreadFunction, + KDefaultStackSize,NULL,reinterpret_cast(iTestCaseId))); + + if(err != KErrNone) + { + RDebug::Printf("Test thread creation unsuccessful: %d",err); + User::Leave(err); + } + + RDebug::Printf("Test thread '%S' created",&aTestCaseId); + // Start the test case in the thread + iTestThread.Logon(iStatus); + SetActive(); + iTestThread.Resume(); + *iNotifierStatus = KRequestPending; + } + + +void CThreadTestPolicy::SignalTestComplete(TInt aCompletionCode) + { + LOG_FUNC + + if(aCompletionCode == KErrNone) + { + RDebug::Printf("CActiveScheduler::Stop CThreadTestPolicy::SignalTestComplete"); + CActiveScheduler::Stop(); + } + else + { + RDebug::Printf("Killing thread with: %d",aCompletionCode); + iTestThread.Kill(aCompletionCode); + } + } + +void CThreadTestPolicy::DoCancel() + { + LOG_FUNC + + iTestCase->Cancel(); + LOG_POINT(1) + TInt err(iTestThread.LogonCancel(iStatus)); + if(err != KErrNone) + { + RDebug::Printf("Unable to cancel thread logon: %d",err); + } + LOG_POINT(2) + TRequestStatus cancelStatus; + iTestThread.Logon(cancelStatus); + LOG_POINT(3) + iTestThread.Kill(KErrCancel); + LOG_POINT(4) + User::RequestComplete(iNotifierStatus,cancelStatus.Int()); + } + +TInt CThreadTestPolicy::ThreadFunction(TAny* aThreadParameter) + { + LOG_CFUNC + + TInt err(KErrNone); + TInt leaveCode(KErrNone); + + HBufC* testCaseId = reinterpret_cast(aThreadParameter); + + // Create the cleanup stack for this thread + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(cleanup == NULL) + { + return KErrNoMemory; + } + + TRAP(leaveCode,err = CThreadTestPolicy::DoTestL(*testCaseId)); + if(leaveCode != KErrNone) + { + RDebug::Printf(" Thread '%S' DoTest",leaveCode,&testCaseId); + err = leaveCode; + } + + delete cleanup; + return err; + } + + +TInt CThreadTestPolicy::DoTestL(const TDesC& aTestCaseId) + { + LOG_CFUNC + TInt err(KErrNone); + + // Create a new active scheduler for this thread + CActiveScheduler* sched = new (ELeave) CActiveScheduler; + CleanupStack::PushL(sched); + CActiveScheduler::Install(sched); + + CBaseTestCase* testCase = RTestFactory::CreateTestCaseL(aTestCaseId,ETrue); + CleanupStack::PushL(testCase); + + // Do the test + testCase->PerformTestL(); + + if(!testCase->IsHostOnly()) + { + // Loop for active objects + RDebug::Printf("CActiveScheduler::Start in CThreadTestPolicy::DoTestL"); + CActiveScheduler::Start(); + } + // Get the test case execution result + err = testCase->TestResult(); + + // Destroy test case + CleanupStack::PopAndDestroy(testCase); + + // Destroy the active scheduler + CleanupStack::PopAndDestroy(sched); + + return err; + } + +void CThreadTestPolicy::RunL() + { + LOG_FUNC + TInt completionCode(iStatus.Int()); + + TExitType exitType(iTestThread.ExitType()); + TExitCategoryName exitName(iTestThread.ExitCategory()); + TInt exitReason(iTestThread.ExitReason()); + RDebug::Printf("Test thread '%S' completed with completion code %d",&iTestThread.Name(),completionCode); + + switch(exitType) + { + // The test thread has panicked + // This will occur if test API panics or RTest expression is false (i.e. test case fails) + case EExitPanic: + { + RDebug::Printf("Test thread '%S' has panicked with category '%S' reason %d", + &iTestThread.Name(),&exitName,exitReason); + // May require to stop and start host/client USB depending on what panic category it is + // can no longer trust RUsbHubDriver/RDevUsbcClient to be in good state + completionCode = KErrAbort; + } + break; + + // The thread has been terminated + case EExitTerminate: + { + RDebug::Printf("Test thread '%S' terminated with category %s reason %d", + &iTestThread.Name(),&exitName,exitReason); + } + break; + + // The thread has been killed + // This will occur when the test thread executes normally or is cancelled + case EExitKill: + { + RDebug::Printf("Test thread '%S' has been killed with reason %d",&iTestThread.Name(),exitReason); + } + break; + + // These cases should not occur at this stage + case EExitPending: //follow through + default: + gtest(EFalse); // Panic main thread + break; + } + + // Close the just executed test thread + iTestThread.Close(); + + // Complete the notifier's request status + User::RequestComplete(iNotifierStatus,completionCode); + } + +TInt CThreadTestPolicy::RunError(TInt aError) + { + RDebug::Printf(" RunError",aError); + return KErrNone; + } + + }