--- /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<TAny*>(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<HBufC*>(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("<Error %d> 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("<Error %d><Test Policy> RunError",aError);
+ return KErrNone;
+ }
+
+ }