sl@0: /* sl@0: * Copyright (c) 2008-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: Some helper classes to assist with writing multi-threaded tests sl@0: * sl@0: */ sl@0: sl@0: sl@0: #ifndef __TEST_THREAD_H__ sl@0: #define __TEST_THREAD_H__ sl@0: sl@0: #include sl@0: #include sl@0: #define __E32TEST_EXTENSION__ sl@0: #include sl@0: #include sl@0: sl@0: _LIT(KPanicCat, "test_thread.h"); sl@0: sl@0: sl@0: static const TInt KHeapSize=0x2000; sl@0: sl@0: enum TPanicCode sl@0: { sl@0: EThreadCreateFailed sl@0: }; sl@0: sl@0: /** sl@0: A utility class for running functions in other threads/processes sl@0: */ sl@0: class TTestRemote sl@0: { sl@0: public: sl@0: virtual TInt WaitForExitL() = 0; sl@0: virtual ~TTestRemote() sl@0: {} sl@0: sl@0: virtual void Rendezvous(TRequestStatus& aStatus) = 0; sl@0: sl@0: protected: sl@0: TTestRemote() sl@0: {} sl@0: sl@0: static TInt RunFunctor(TAny* aFunctor); sl@0: sl@0: TRequestStatus iLogonStatus; sl@0: static TInt iCount; sl@0: }; sl@0: sl@0: class TTestThread : public TTestRemote sl@0: { sl@0: public: sl@0: TTestThread(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume=ETrue); sl@0: sl@0: /** sl@0: Run aFunctor in another thread sl@0: */ sl@0: TTestThread(const TDesC& aName, TFunctor& aFunctor, TBool aAutoResume=ETrue); sl@0: sl@0: ~TTestThread(); sl@0: sl@0: void Resume(); sl@0: sl@0: /** sl@0: If thread exited normally, return its return code sl@0: Otherwise, leave with exit reason sl@0: */ sl@0: virtual TInt WaitForExitL(); sl@0: sl@0: virtual void Rendezvous(TRequestStatus& aStatus); sl@0: sl@0: private: sl@0: void Init(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume); sl@0: sl@0: RThread iThread; sl@0: }; sl@0: sl@0: class CTest : public CBase, public TFunctor sl@0: { sl@0: public: sl@0: ~CTest(); sl@0: sl@0: virtual void operator()(); sl@0: virtual void RunTest() = 0; sl@0: virtual CTest* Clone() const = 0; sl@0: sl@0: /** sl@0: Prints a formatted description of the test sl@0: */ sl@0: void Announce() const; sl@0: sl@0: const TDesC& Name() const; sl@0: sl@0: /** sl@0: Should print the type of test, with no newlines. sl@0: eg. "Transfer", "Fragmentation" sl@0: TODO drop the function, just add a test type member sl@0: */ sl@0: virtual void PrintTestType() const = 0; sl@0: sl@0: /** sl@0: Display any information about test environment, with no newlines sl@0: eg. "DMA channel 16" sl@0: The base class version prints nothing. sl@0: */ sl@0: virtual void PrintTestInfo() const; sl@0: sl@0: protected: sl@0: CTest(const TDesC& aName, TInt aIterations); sl@0: CTest(const CTest& aOther); sl@0: sl@0: //It would be useful to have an RTest member, but this can't be sl@0: //initialised untill the new thread is running as it will refer to sl@0: //the creating thread sl@0: RBuf iName; sl@0: const TInt iIterations; sl@0: }; sl@0: sl@0: /** sl@0: Make aNumberOfThreads copies of aTest and run sl@0: each in its own thread sl@0: sl@0: @param test Reference to test object sl@0: @param aTest Referance sl@0: */ sl@0: void MultipleTestRun(RTest& test, const CTest& aTest, TInt aNumberOfThreads); sl@0: sl@0: void MultipleTestRun(const RPointerArray& aTests); sl@0: #endif // #ifndef __TEST_THREAD_H__ sl@0: