diff -r 000000000000 -r a41df078684a kerneltest/e32test/usbho/t_otgdi/src/testengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/usbho/t_otgdi/src/testengine.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,482 @@ +// 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: +// @internalComponent +// +// + +#include +#include +#include // unicode builds +#include +#include +#include +#include // RTest headder +#include +#include +#include "debugmacros.h" +#include "TestEngine.h" +#include "TestCaseController.h" +#include "TestCaseFactory.h" +#include "TestCaseRoot.h" + +// Console application parameter options +_LIT(KArgAllTestCases,"/ALL"); // see default test-list below +_LIT(KArgGoTestCase, "/G:"); +_LIT(KArgAutomatedTest, "/AUTO"); // removes "press any key to continue" prompts +_LIT(KArgVerboseOutput, "/VERBOSE"); // also turns on RDebug logging of all test output (to serial) +_LIT(KArgSetOpenIterations, "/LOOPO:"); // Open/Close test loop count +_LIT(KArgSetOOMIterations, "/LOOPM:"); // OOM test set #allocs +_LIT(KArgSetRoleMaster, "/MASTER"); // this is the default +_LIT(KArgSetRoleSlave, "/SLAVE"); // slave - Runs a dual-role test's Slave steps instead of Master +_LIT(KArgOverrideVidPid, "/PID:"); // vendor, product ID XXXX 4 hex digits /PID:0670 + +_LIT(KidFormatter,"PBASE-USB_OTGDI-%04d"); +_LIT(KidFormatterS,"PBASE-USB_OTGDI-%S"); + +// '/ALL' tests grouping +const TInt KAllDefaultTestIDs[6] = + { + 456, // (a) PBASE-USB_OTG-0456 open/close 'A' + 457, // (a) PBASE-USB_OTG-0457 open/close disconnected + 459, // (m) PBASE-USB_OTG-0459 detect 'A' + 460, // (m) PBASE-USB_OTG-0460 detect 'A' removal + 464, // (m) PBASE-USB_OTG-0464 raise + 465 // (m) PBASE-USB_OTG-0465 lower + }; + + + +// +// CTestEngine implementation +// +CTestEngine* CTestEngine::NewL() + { + CTestEngine* self = new (ELeave) CTestEngine; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CTestEngine::CTestEngine(): + iTestCaseIndex(0), + iHelpRequested(EFalse) + { + + } + + +CTestEngine::~CTestEngine() + { + LOG_FUNC + // Destroy the test case controller + if (iTestCaseController) + { + delete iTestCaseController; + } + // Destroy the test identity array and its contents + iTestCasesIdentities.ResetAndDestroy(); + + } + + +void CTestEngine::ConstructL() + { + LOG_FUNC + TInt menuSelection(0); + + // Display information + test.Title(); + test.Start(_L("Test Engine Initiation v2.00 ")); + test.Printf(_L(">>\n")); + test.Printf(_L(">> T E S T R U N \n")); + test.Printf(_L(">>\n")); + + + // Process the command line parameters for batch/etc + TRAPD(err, ProcessCommandLineL()); + if (err != KErrNone) + { + User::Panic(_L("Test F/W Err"), KErrNoMemory); + } + + if (iHelpRequested) + { + PrintUsage(); + User::Leave(-2); // nothing to do! + } + + // if no command-line, we use a menu UI + if (!iTestCasesIdentities.Count()) + { + RPointerArray testCaseNames; + // no tests added, select ONE to run from the menu + + // list test cases (PRINT MENU) - in numeric order + RTestFactory::ListRegisteredTestCases(testCaseNames); + + iTestCaseIndex = 0; // be sure we go back to beginning of the collection! + iTestCasesIdentities.ResetAndDestroy(); + + test.Printf(_L("Please select 0 to %d\n"), RTestFactory::TestCaseCount()-1); + test.Printf(_L("or 99 to exit\n")); + GetNumericInput(menuSelection); + if ((menuSelection >=0) &&(menuSelection < RTestFactory::TestCaseCount())) + { + // add it to the list,and we can go + TBuf aSelectionID; + HBufC* tc = HBufC::NewLC(KTestCaseIdLength); + + // get name from index + *tc = aSelectionID; + *tc = *testCaseNames[menuSelection]; + + iTestCasesIdentities.Append(tc); + CleanupStack::Pop(tc); + } + testCaseNames.ResetAndDestroy(); + } + + if ((menuSelection < RTestFactory::TestCaseCount()) && (menuSelection>=0)) + { + // Create the test case controller + test.Printf(_L("Creating the test controller\n")); + iTestCaseController = CTestCaseController::NewL(*this, ETrue); + + // Test-engine is non CActive class + } + else + { + // nothing to do, exit. USER aborted + test.Printf(_L("Test run stopped by user, nothing to do.\n")); + User::Leave(-2); + } + } + + +/* Displayed if used supplied no parameters, garbage, or a ? in the parameters + */ +void CTestEngine::PrintUsage() + { + test.Printf(_L("OTGDI Unit Test Suite.\n")); + test.Printf(_L("Usage : t_otgdi.exe [/option] /G:\n")); + test.Printf(_L(" /ALL = add default test subset to List\n")); + test.Printf(_L(" /G: where is the test# to add \n")); + test.Printf(_L(" /AUTO = largely unattended operation\n")); + test.Printf(_L(" /VERBOSE = test debugging info\n")); + test.Printf(_L(" /LOOPO: = Open/close repeat counter\n")); + test.Printf(_L(" /LOOPM: = OOM HEAP_ALLOCS counter\n")); + test.Printf(_L(" /SLAVE = Test-peer server mode\n")); + test.Printf(_L(" /PID: = USB VID/PID in hex eg 2670\n")); + test.Printf(_L("Valid test ID range 0456...0469\n")); + test.Printf(_L("and 0675...0684 .\n")); + test.Printf(_L("\n")); + } + +/** process the command-line, ; arguments appear in any order + IN : User::CommandLine() + OUT : iTestCasesIdentities + iHelpRequested + gSemiAutomated + gVerboseOutput + gOpenIterations + gOOMIterations + gTestRoleMaster + gUSBVidPid +*/ +void CTestEngine::ProcessCommandLineL() + { + // example t_otgdi.exe /ALL /G:0468 /VERBOSE + TInt cmdLineLength(User::CommandLineLength()); + HBufC* cmdLine = HBufC::NewMaxLC(cmdLineLength); + TPtr cmdLinePtr = cmdLine->Des(); + User::CommandLine(cmdLinePtr); + TBool tokenParsed(EFalse); + + TLex args(*cmdLine); + args.SkipSpace(); // args are separated by spaces + + // first arg is the exe name, skip it + TPtrC cmdToken = args.NextToken(); + HBufC* tc = HBufC::NewLC(KParameterTextLenMax); + *tc = cmdToken; + while (tc->Length()) + { + tokenParsed = EFalse; + + // '/?' help wanted flag '?' or /? parameter + TInt pos(0); + if ((0== tc->FindF(_L("?"))) || (0==tc->FindF(_L("/?")))) + { + iHelpRequested = ETrue; + tokenParsed = ETrue; + } + + // '/ALL' parameter + pos = tc->FindF(KArgAllTestCases); + if (pos != KErrNotFound) + { + AddAllDefaultTests(); + tokenParsed = ETrue; + } + + // '/AUTO' + pos = tc->FindF(KArgAutomatedTest); + if (pos != KErrNotFound) + { + // skip some of the press-any key things + test.Printf(_L("Test semi-automated mode.\n")); + gSemiAutomated = ETrue; + tokenParsed = ETrue; + } + + // '/G:TESTNAME' + pos = tc->FindF(KArgGoTestCase); + if (pos != KErrNotFound) + { + HBufC* tcPart = HBufC::NewLC(KTestCaseIdLength); + TPtrC testID = tc->Right(tc->Length() - pos - KArgGoTestCase().Length()); + + LOG_VERBOSE2(_L("Parameter found:'%S'\n"), &testID); + + // Check if it is a test we know of in our suite, users may provide the full + // name "PBASE-USB_OTGDI-0466", or just the last 4 digits "0466", in such cases, fetch the full name + if (!RTestFactory::TestCaseExists(testID)) + { // try use just the test#part + TPtr tcDes = tcPart->Des(); + + // build and add the full name + tcDes.Format(KidFormatterS, &testID); + if (!RTestFactory::TestCaseExists(tcDes)) + { + + test.Printf(_L("Test case does NOT Exist: '%lS'\n"), &testID); + } + else + { // only the number was supplied, copy the full name + testID.Set(tcDes); + } + } + // check that it's valid before adding it to the run-list + if (RTestFactory::TestCaseExists(testID)) + { + HBufC* testIdentity = HBufC::NewLC(KTestCaseIdLength); + *testIdentity = testID; + test.Printf(_L("Test case specified: %lS\n"), testIdentity); + + iTestCasesIdentities.Append(testIdentity); + CleanupStack::Pop(testIdentity); + } + CleanupStack::PopAndDestroy(tcPart); + tokenParsed = ETrue; + } + + // '/VERBOSE' option + pos = tc->FindF(KArgVerboseOutput); + if (pos != KErrNotFound) + { + gVerboseOutput = ETrue; + tokenParsed = ETrue; + + // turn on logging of test Printf() output to serial debug/log at the same time + test.SetLogged(ETrue); + + } + + // '/LOOPO:n' option (Set #times to run open/close tests amongst others) + pos = tc->FindF(KArgSetOpenIterations); + if (pos != KErrNotFound) + { + TPtrC iterationStr = tc->Right(tc->Length() - pos - KArgSetOpenIterations().Length()); + TLex lex(iterationStr); + lex.Val(gOpenIterations); + MINMAX_CLAMPVALUE(gOpenIterations, OPEN_MINREPEATS, OPEN_MAXREPEATS); + tokenParsed = ETrue; + } + + // '/LOOPM:n' option (Set # of allocs to start at for OOM test) + pos = tc->FindF(KArgSetOOMIterations); + if (pos != KErrNotFound) + { + TPtrC iterationStr = tc->Right(tc->Length() - pos - KArgSetOOMIterations().Length()); + TLex lex(iterationStr); + lex.Val(gOOMIterations); + MINMAX_CLAMPVALUE(gOOMIterations, OOM_MINREPEATS, OOM_MAXREPEATS); + tokenParsed = ETrue; + } + + + // '/VID:nnnn' option (Set Symbian or other VID-Pid example /VID:0670) + pos = tc->FindF(KArgOverrideVidPid); + if (pos != KErrNotFound) + { + TPtrC vidpidStr = tc->Right(tc->Length() - pos - KArgOverrideVidPid().Length()); + TUint16 prodID; + TLex lex(vidpidStr); + + if (KErrNone == lex.Val(prodID, EHex)) + { + if (prodID> 0xFFFF) + prodID = 0xFFFF; + tokenParsed = ETrue; + LOG_VERBOSE2(_L(" accept param %04X \n\n"), prodID); + gUSBVidPid = prodID; // replace the vid-pid with the user-supplied one + } + else + { + // print error + test.Printf(_L("Warning: VID+PID '%lS' not parsed .\n"), tc); + } + } + + // '/SLAVE' (peer) + pos = tc->FindF(KArgSetRoleSlave); + if (pos != KErrNotFound) + { + gTestRoleMaster = EFalse; + tokenParsed = ETrue; + } + // '/MASTER' - default role + pos = tc->FindF(KArgSetRoleMaster); // note that master is the default role, so this parameter is optional + if (pos != KErrNotFound) + { + gTestRoleMaster = ETrue; + tokenParsed = ETrue; + } + + if (!tokenParsed) + { + // warn about unparsed parameter + test.Printf(_L("Warning: '%lS'??? not parsed\n"), tc); + iHelpRequested = ETrue; + } + + // next parameter + *tc = args.NextToken(); + } + CleanupStack::PopAndDestroy(tc); + CleanupStack::PopAndDestroy(cmdLine); + } + + +/** Add all default tests to the front of the test-list so we run them all in sequence +*/ +void CTestEngine::AddAllDefaultTests() + { + test.Printf(_L("Adding default set test cases\n")); + // + TInt index(0); + while (index < sizeof(KAllDefaultTestIDs)/sizeof(KAllDefaultTestIDs[0])) + { + // allocate heap string + HBufC* tc(NULL); + TRAPD(err, tc = HBufC::NewL(KTestCaseIdLength)) + if (err != KErrNone) + { + User::Panic(_L("Test F/W Err"), KErrNoMemory); + } + TPtr tcDes = tc->Des(); + + // build and add it + tcDes.Format(KidFormatter, KAllDefaultTestIDs[index]); + iTestCasesIdentities.Append(tc); + index++; + } + } + + +/* Return subsequent test case IDs from the test run-list KerrNotFound = end of list. + */ +TInt CTestEngine::NextTestCaseId(TDes& aTestCaseId) + { + if (iTestCaseIndex < iTestCasesIdentities.Count()) + { + aTestCaseId = *iTestCasesIdentities[iTestCaseIndex++]; + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +///////////////////////////////////////////////////////////////////////////// +// utility functions + + +void CTestEngine::GetNumericInput(TInt &aNumber) + { + TUint value(0); + TUint digits(0); + TKeyCode key = (TKeyCode) 0; + + aNumber = -1; + while ( key != EKeyEnter ) + { + key = test.Getch(); + + if ( ( key >= '0' ) && ( key <= '9' ) ) + { + test.Printf(_L("%c"),key); + + value = ( 10 * value ) + ( key - '0' ); + digits++; + } else + { // very basic keyboard processing, backspace + if (key == EKeyBackspace) + { + value = value/10; + digits--; + test.Printf(_L("\r \r%d"), value); + } + } + } + + if (digits > 0) + { + aNumber = value; + } + test.Printf(_L("\n")); + } + + +/** Print a report at the end of a test run of all PASSED tests, Note: If a + test fails, the framework gets Panic'd */ +void CTestEngine::Report() + { + TBuf aTestCaseId; + test.Printf(_L("============================\n")); + test.Printf(_L("PASSED TESTS:\n")); + // itterate our list of tests to perform + ResetTestCaseIndex(); + while (KErrNone == NextTestCaseId(aTestCaseId)) + { + test.Printf(_L("%S\n"), &aTestCaseId); + } + } + + +void CTestEngine::DoCancel() + { + LOG_FUNC + test.Console()->ReadCancel(); + } + + +TInt CTestEngine::RunError(TInt aError) + { + return aError; + } +