First public contribution.
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
21 #include "test_thread.h"
27 // Global array of test cases
28 extern RPointerArray<TTestCase> TestArray;
31 extern TBool gVerboseOutput; // Verbose output control
34 const TInt KParameterTextLenMax = 80; // command-line param length
37 This function prints out the PSL test Information
39 void Print(const TDmaV2TestInfo& aInfo);
42 Runs all framework self tests
48 class CSingleTransferTest;
50 class CMultiTransferTest;
54 An interface to a classs that sets up the buffers before a test
56 //TODO both pre and post transfer checks should perhaps derive from an
57 //abstract visitor base
61 virtual ~MPreTransfer()
63 virtual void Setup(const CSingleTransferTest& aTest) const = 0;
64 virtual void Setup(const CIsrRequeTest& aTest) const = 0;
65 virtual void Setup(const CMultiTransferTest& aTest) const = 0;
69 An interface for a check which takes place at the end of a DMA
70 transfer test to verify the transfer was as expected.
72 class MPostTransferCheck
75 virtual ~MPostTransferCheck()
77 virtual TInt Check(const CSingleTransferTest& aTest) const = 0;
78 virtual TInt Check(const CIsrRequeTest& aTest) const = 0;
79 virtual TInt Check(CMultiTransferTest& aTest) const = 0;
82 class TCompare2D : public MPostTransferCheck
88 virtual TInt Check(const CSingleTransferTest& aTest) const;
89 virtual TInt Check(const CIsrRequeTest& aTest) const;
90 virtual TInt Check(CMultiTransferTest& aTest) const;
94 class TAlwaysFail : public MPostTransferCheck
97 virtual TInt Check(const CSingleTransferTest& /*aTest*/) const
99 virtual TInt Check(const CIsrRequeTest&) const
100 {return KErrUnknown;}
101 virtual TInt Check(CMultiTransferTest&) const
102 {return KErrUnknown;}
105 class TAlwaysPass : public MPostTransferCheck
108 virtual TInt Check(const CSingleTransferTest& /*aTest*/) const
110 virtual TInt Check(const CIsrRequeTest&) const
112 virtual TInt Check(CMultiTransferTest&) const
117 Compare that all the various source buffers of a test match
118 its destination buffers
120 class TCompareSrcDst : public MPostTransferCheck
126 virtual TInt Check(const CSingleTransferTest& aTest) const;
127 virtual TInt Check(const CIsrRequeTest& aTest) const;
128 virtual TInt Check(CMultiTransferTest& aTest) const;
131 TInt Check(const TIsrRequeArgsSet& aRequeueArgSet, TUint8* aChunkBase, const TDmaTransferArgs& aTferArgs) const;
132 TInt Check(const TIsrRequeArgs& aRequeueArgs) const;
133 TInt Check(const TDmaTransferArgs& aTransferArgs, TUint8* aChunkBase) const;
137 Base class for all DMA tests
139 class CDmaTest : public CTest
142 CDmaTest(const TDesC& aName, TInt aIterations, const MPreTransfer* aPreTransfer, const MPostTransferCheck* aPostTransfer)
143 : CTest(aName, aIterations), iPreTransfer(aPreTransfer), iPostTransferCheck(aPostTransfer)
146 void OpenDmaSession();
147 void CloseDmaSession();
149 virtual void PrintTestInfo() const;
150 virtual TBool Result() = 0;
152 const RChunk& Chunk() const
156 Tells the test which DMA channel it should run on
158 void SetChannelCookie(TUint32 aCookie)
159 {iChannelCookie = aCookie;}
161 virtual void PreTransferSetup() =0;
162 virtual TInt DoPostTransferCheck() =0;
164 RDmaSession iDmaSession;
168 Identifies the channel to open (as understood by a DMA PSL)
170 TUint iChannelCookie;
171 const MPreTransfer* iPreTransfer;
173 const MPostTransferCheck* iPostTransferCheck; //!< Some check to be run after the transfer
177 Holds return codes for the various functions which must be called
178 to create, fragment, and queue a DMA request
180 struct TRequestResults
184 TInt aCreate = KErrNone,
185 TInt aFragmentCount = 0,
186 TInt aFragmentationResult = KErrNone,
187 TInt aQueueResult = KErrNone
189 :iCreate(aCreate), iFragmentCount(aFragmentCount), iFragmentationResult(aFragmentationResult), iQueueResult(aQueueResult)
193 Constructs with error results
195 TRequestResults(TFalse)
196 :iCreate(KErrUnknown), iFragmentCount(0), iFragmentationResult(KErrUnknown), iQueueResult(KErrUnknown)
199 inline TRequestResults& CreationResult(TInt aErrorCode) {iCreate = aErrorCode; return *this;}
200 inline TRequestResults& FragmentCount(TInt aCount) {iFragmentCount = aCount; return *this;}
201 inline TRequestResults& FragmentationResult(TInt aErrorCode) {iFragmentationResult = aErrorCode; return *this;}
202 inline TRequestResults& QueueResult(TInt aErrorCode) {iQueueResult = aErrorCode; return *this;}
205 TInt iFragmentCount; //!< 0 means any result permitted
206 TInt iFragmentationResult;
211 Holds all the results for a DMA CSingleTransferTest
218 TResultSet(TInt aChannelOpenResult = KErrNone,
219 const TRequestResults aRequestResults = TRequestResults(),
220 TInt aPostTransferCheck = KErrNone,
221 const TCallbackRecord aCallbackRecord = TCallbackRecord(TCallbackRecord::EThread,1)
224 iChannelOpenResult(aChannelOpenResult),
225 iRequestResult(aRequestResults),
226 iPostTransferCheck(aPostTransferCheck),
227 iCallbackRecord(aCallbackRecord)
230 explicit TResultSet(const TCallbackRecord& aRecord)
231 :iChannelOpenResult(KErrNone),
233 iPostTransferCheck(KErrNone),
234 iCallbackRecord(aRecord)
241 :iChannelOpenResult(KErrUnknown),
242 iRequestResult(EFalse),
243 iPostTransferCheck(KErrUnknown),
244 iCallbackRecord(TCallbackRecord::Empty())
248 TBool operator == (const TResultSet& aOther) const;
250 /** Set channel opening result */
251 TResultSet& ChannelOpenResult(TInt aResult) {iChannelOpenResult = aResult; return *this;}
252 TResultSet& PostTransferResult(TInt aResult) {iPostTransferCheck = aResult; return *this;}
253 /** Set request results */
254 TResultSet& RequestResult(const TRequestResults& aResults) {iRequestResult = aResults; return *this;}
255 /** Set Callback record */
256 TResultSet& CallbackRecord(const TCallbackRecord& aCallbackRecord) {iCallbackRecord = aCallbackRecord; return *this;}
258 TInt iChannelOpenResult;
259 TRequestResults iRequestResult;
260 TInt iPostTransferCheck;
261 TCallbackRecord iCallbackRecord;
265 Fills each source buffer with an increasing value and clears each destination
267 class TPreTransferIncrBytes : public MPreTransfer
270 TPreTransferIncrBytes()
273 virtual void Setup(const CSingleTransferTest& aTest) const;
274 virtual void Setup(const CIsrRequeTest& aTest) const;
275 virtual void Setup(const CMultiTransferTest& aTest) const;
277 virtual void Setup(const TAddressParms& aParams) const;
278 TBool CheckBuffers(const CIsrRequeTest& aTest) const;
279 TBool CheckBuffers(const RArray<const TAddressParms> aTransferParams) const;
282 const TPreTransferIncrBytes KPreTransferIncrBytes;
283 const TCompareSrcDst KCompareSrcDst;
284 const TCompare2D KCompare2D;
288 Iterates over the bytes in buffer, in the order
289 the supllied DMA config would access them
295 :iCfg(NULL), iPtr(NULL)
298 TTransferIter(const TDmaTransferConfig& aCfg, TUint8* aChunkBase=NULL)
299 :iElem(0), iFrame(0), iCfg(&aCfg), iChunkBase(aChunkBase), iPtr(Start()), iBytes(0)
309 TBool operator!= (const TTransferIter& aOther)
311 return (iPtr != aOther.iPtr);
314 static void SelfTest();
316 TUint8* Start() const
318 return iChunkBase + iCfg->iAddr;
321 void Invariant() const;
323 TUint iElem; //!< The current element
324 TUint iFrame; //!< The current frame
326 const TDmaTransferConfig* const iCfg;
329 TUint8* iPtr; //<! Pointer to the current byte
331 TInt iBytes; //!< The number of bytes traversed
335 Performs a single DMA transfer using the member TDmaTransferArgs on
336 one channel. At each stage of the transfer results are recorded in a
337 TResultSet struct: at the end these are compared with a set of expected
340 class CSingleTransferTest : public CDmaTest
344 const TDesC& aName, TInt aIterations,
345 const TDmaTransferArgs& aArgs,
346 const TResultSet& aExpected,
347 TUint aMaxFragmentSize = 0,
348 const MPostTransferCheck* aPostTferChk = &KCompareSrcDst,
349 const MPreTransfer* aPreTfer = &KPreTransferIncrBytes
351 : CDmaTest(aName, aIterations, aPreTfer, aPostTferChk),
352 iTransferArgs(aArgs),iExpected(aExpected),iActual(EFalse),
353 iUseNewRequest(ETrue),
354 iUseNewFragment(ETrue),
355 iMaxFragmentSize(aMaxFragmentSize)
359 Perform each stage of trasnfer
361 virtual void RunTest();
362 virtual void PrintTestType() const;
364 virtual CTest* Clone() const {return new CSingleTransferTest(*this);}
367 Compares the actual vs the exepected results and reports
369 @return ETrue for a pass, EFalse for a fail
371 virtual TBool Result();
374 An accessor function for the object's TDmaTransferArgs
376 const TDmaTransferArgs& TransferArgs() const
377 {return iTransferArgs;}
379 // The below methods are setters, which may be chained together
380 // ie. The Named Parameter Idiom
381 // @see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18
382 inline CSingleTransferTest& UseNewRequest(TBool aFlag) {iUseNewRequest=aFlag; return *this;}
383 inline CSingleTransferTest& UseNewFragment(TBool aFlag) {iUseNewFragment=aFlag; return *this;}
384 inline CSingleTransferTest& UseNewDmaApi(TBool aFlag) {UseNewRequest(aFlag); UseNewFragment(aFlag); return *this;}
387 virtual void OpenChannel();
388 virtual void PreTransferSetup();
389 virtual void CreateDmaRequest();
390 virtual void Fragment();
391 virtual void Queue();
392 virtual void PostTransferCheck();
393 virtual TInt DoPostTransferCheck();
394 virtual void FreeRequest();
395 virtual void CloseChannel();
399 A handle to kernel side TDmaChannel object received after a channel is opened.
401 TUint iChannelSessionCookie;
403 A handle to kernel side DDmaRequest object.
405 TUint iRequestSessionCookie;
407 const TDmaTransferArgs& iTransferArgs;
410 Expected transfer results
412 TResultSet iExpected;
415 Filled with actual transfer results
419 TBool iUseNewRequest; //!< If true then CSingleTransferTest will create a DDmaRequest with the v2 ctor
420 TBool iUseNewFragment; //!< If true then CSingleTransferTest will use v2 Fragment API
421 const TUint iMaxFragmentSize;
425 This class will be used for tests which benchmark certain DMA operations
427 class CDmaBenchmark : public CSingleTransferTest
430 CDmaBenchmark(const TDesC& aName, TInt aIterations, const TResultSet& aExpectedResults, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize);
433 virtual TBool Result();
435 static void SelfTest();
439 @return The mean average of the result array
441 TUint64 MeanResult();
443 //TODO must be included within copy ctor or all instances will
444 //share on result set!
445 RArray<TUint64> iResultArray;
450 Fragments requests (only) and records duration
451 TODO make sure we are using old style DDmaRequest
453 class CDmaBmFragmentation : public CDmaBenchmark
456 CDmaBmFragmentation(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize);
457 virtual CTest* Clone() const {return new CDmaBmFragmentation(*this);}
458 virtual TInt DoPostTransferCheck()
459 {TEST_FAULT; return KErrNotSupported;}
461 virtual void RunTest();
462 virtual void PrintTestType() const;
466 static const TResultSet ExpectedResults;
470 Performs a transfer using an old style DDmaRequest and
473 class CDmaBmTransfer : public CDmaBenchmark
476 CDmaBmTransfer(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aTransferArgs, TUint aMaxFragmentSize);
477 virtual CTest* Clone() const {return new CDmaBmTransfer(*this);}
478 virtual TInt DoPostTransferCheck()
479 {TEST_FAULT; return KErrNotSupported;}
481 virtual void RunTest();
482 virtual void PrintTestType() const;
484 inline CDmaBmTransfer& UseNewDmaApi(TBool aFlag) {CSingleTransferTest::UseNewDmaApi(aFlag); return *this;}
485 inline CDmaBmTransfer& ExpectedResults(const TResultSet& aArgs) {iExpected=aArgs; return *this;}
493 Will create and queue multiple requests
495 Unlike CSingleTransferTest the class does not permit the use of TResultSet to
496 define expected results (for neagative testing)
498 class CMultiTransferTest : public CDmaTest
501 CMultiTransferTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs* aTransferArgs, const TResultSet* aResultSets, TInt aCount);
502 CMultiTransferTest(const CMultiTransferTest& aOther);
503 virtual ~CMultiTransferTest();
504 virtual CTest* Clone() const {return new CMultiTransferTest(*this);}
506 virtual TBool Result();
507 virtual void RunTest();
508 virtual void PrintTestType() const;
510 inline CMultiTransferTest& PauseWhileQueuing() {iPauseWhileQueuing = ETrue; return *this;}
511 inline CMultiTransferTest& SetPreTransferTest(const MPreTransfer* aPreTfer) {iPreTransfer = aPreTfer; return *this;}
512 inline CMultiTransferTest& SetPostTransferTest(const MPostTransferCheck* aPostTfer) {iPostTransferCheck = aPostTfer; return *this;}
514 const TDmaTransferArgs& TransferArgs(TInt aIndex) const;
515 inline TInt TransferCount() const {return iTransferArgsCount;}
517 void SetPostTransferResult(TInt aIndex, TInt aErrorCode);
521 void CreateDmaRequests();
523 void QueueRequests();
525 virtual void PreTransferSetup();
526 virtual TInt DoPostTransferCheck();
528 TBool Result(TInt aTransfer);
530 const TDmaTransferArgs* const iTransferArgs; //pointer to an array of transfer args
531 const TInt iTransferArgsCount;
534 TBool iNewDmaApi; //!< If true then CMultiTransferTest will use new style API
537 A handle to kernel side TDmaChannel object received after a channel is opened.
539 TUint iChannelSessionCookie;
540 RArray<TUint> iRequestCookies;
542 const TResultSet* const iExpectedArray; // array will be of length iTransferArgsCount
543 RArray<TResultSet> iActualResults;
546 If set, the test will pause the channel before queuing requests, and
547 resume once they are all queued
549 TBool iPauseWhileQueuing;
553 Used for testing TDmaChannel::IsrRedoRequest
555 Extends CSingle transfer by adding the capability to queue with
556 additonal transfer parameters (TIsrRequeArgs) which are passed
557 to IsrRedoRequest in ISR callback
559 class CIsrRequeTest : public CSingleTransferTest
562 CIsrRequeTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs,
563 TIsrRequeArgs* aRequeueArgs, TInt aCount,
564 const TResultSet& aExpected, const MPreTransfer* aPreTfer,
565 const MPostTransferCheck* aPostTferChk, TUint aMaxFragmentSize=0);
567 virtual void PrintTestType() const;
569 virtual void Queue();
572 Compares the actual vs the exepected results and reports
574 @return ETrue for a pass, EFalse for a fail
576 //virtual TBool Result();
579 virtual CTest* Clone() const {return new CIsrRequeTest(*this);}
581 const TIsrRequeArgsSet& GetRequeueArgs() const
582 {return iRequeArgSet;}
586 virtual TInt DoPostTransferCheck();
587 virtual void PreTransferSetup();
589 TIsrRequeArgsSet iRequeArgSet;
593 A channel record collects DMA channel capabilities and other PSL information
594 before running tests.
608 DMA Channel Capabilities
610 TDmacTestCaps iChannelCaps;
614 A test case collects together a DMA test (CDmaTest), its hardware prerequisites,
615 and other information about how the test should be run.
620 //TODO it might be better to group sets of TDmaCapability
621 //into their own class eg. TDmaCapSet.
622 TTestCase(CDmaTest* aTest,
623 TBool aConcurrent = EFalse,
624 const TDmaCapability = TDmaCapability(),
625 const TDmaCapability = TDmaCapability(),
626 const TDmaCapability = TDmaCapability(),
627 const TDmaCapability = TDmaCapability(),
628 const TDmaCapability = TDmaCapability()
631 static void SelfTest();
634 Compares the requirements held in the class
635 against those described in aChannelCaps and makes a decision
636 as to whether this test case should be run, skipped, or failed.
638 TResult TestCaseValid(const SDmacCaps& aChannelCaps) const;
639 TResult TestCaseValid(const TDmacTestCaps& aChannelCaps) const;
641 enum {KMaxChannelCaps=5};
642 TDmaCapability iChannelCaps[KMaxChannelCaps];
646 TBool iConcurrentTest;
647 TBool iDmaV2Only; //!< If true then this test cannot be run on DMA v1 framework
651 A TestRunner manages the whole testing process.Before running any test cases it will open its own RDmaSession
652 handle, not associated with a DMA channel, so that it can recover the TDmaTestInfo object (as used by the
653 existing DMA framework) which says what channels are available to be tested.It will use TTestThread objects
654 to run tests in new threads.TTestThread contains a number of useful features such as waiting for thread exit
655 and accepting a TFunctor object to be run in a new thread.
664 This function will populate TTestRunner with an array of test cases which
665 would be a collection of DMA test,its hardware prerequisites,and other
666 information about how the test
668 @aTTestCases on return, this contains an the DMA test cases
670 void AddTestCases(RPointerArray<TTestCase>& aTTestCases);
673 This will iterate over all test cases held by the test runner and
674 for each one will judge which DMA channels it can be run on, running
675 the test if possible.
681 This functions retrieves the PSL cookies from all the DMA channels
682 and stores them in a single array. It will use information from
688 This function will generate the DMA channel records.i.e channel cookies,Caps.
690 void GenerateChannelRecord();
693 Holds the PslTestInfo
695 TDmaV2TestInfo iPslTestInfo;
698 A handle to RDmaSession
700 RDmaSession iDmaSession;
703 Array of DMA test cases
705 RPointerArray<TTestCase> iTestCases;
708 Array of DMA channel records,channel capabilities and other PSL information
710 RArray<TChannelRecord> iChannelRecords;
713 Array of DMA channel cookies
715 RArray<TUint> iPslCookies;
719 #endif // #ifndef __T_DMA2_H__