--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cbsref/csyrefplugins/csy27010/test/unit_test_base/unitTestBase.cpp Tue Aug 31 16:23:08 2010 +0300
@@ -0,0 +1,1266 @@
+//
+// * Copyright 2004 Neusoft America Inc.
+// * All rights reserved.
+// * This component and the accompanying materials are made available
+// * under the terms of the Eclipse Public License v1.0
+// * which accompanies this distribution, and is available
+// * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// *
+// * Contributors:
+// * Keith Collins (Neusoft America Inc.) original software development and additional code and modifications.
+// * Thomas Gahagen (Neusoft America Inc.) additional code and modifications.
+// * Zhen Yuan (Neusoft America Inc.) additional code and modifications.
+// *
+// * Description: This file contains the implementation for the base class from
+// * which all unit test classes are derived.
+//
+
+// UnitTestBase.cpp
+
+/** @file UnitTestBase.cpp
+ *
+ */
+
+#include "unitTestBase.h"
+
+// This indicates that the CSY is loaded by the TSY
+#define LOADED_BY_TSY 1
+
+//
+// CUnitTestBase
+//
+
+// These methods can be overwritten
+
+TBool CUnitTestBase::HasTestRangesDefined()
+ {
+ return EFalse;
+ }
+
+
+void CUnitTestBase::ConstructL()
+/**
+ *
+ *
+ */
+ {
+ //LOGTEXT(">>ConstructL");
+
+ User::LeaveIfError(iFs.Connect());
+ User::LeaveIfError(iFs.SetSessionPath(KTestSessionPath));
+
+ TInt err=iLogFile.Open(iFs,iLogFileName, EFileWrite);
+
+ if (err==KErrNotFound) // file does not exist - create it
+ {
+ err = iLogFile.Create(iFs, iLogFileName, EFileWrite);
+ }
+ // In simultaneous tests, someone else may have created it between our
+ // calls to Open and Create, so no 'else' here.
+ if ( err == KErrInUse || err == KErrAlreadyExists )
+ {
+ //LOGTEXT("Distinct logging required");
+
+ // Same filename already open by someone else. In order to run more
+ // than one test in, say, BasicCall at once AND have logging that
+ // works, create distinct log files when required.
+ TInt n = 0;
+ while ( err == KErrInUse || err == KErrAlreadyExists )
+ {
+ TName newLogFileName(iLogFileName);
+ n++;
+ newLogFileName.AppendFormat(_L("%d"),n);
+ err = iLogFile.Open(iFs, newLogFileName, EFileWrite);
+ if (! err)
+ {
+ TInt pos = 0;
+ iLogFile.Seek(ESeekEnd, pos);
+ }
+ if ( err == KErrNotFound )
+ {
+ err = iLogFile.Create(iFs, newLogFileName, EFileWrite);
+ break;
+ }
+ }
+ }
+
+ if (err)
+ {
+ iTest.Printf(_L("Couldn't open log file (%d). Does the %S path exist?\n"), err, &KTestSessionPath);
+ User::After(4000000);
+ User::Leave(err);
+ }
+ TInt pos = 0;
+ iLogFile.Seek(ESeekEnd, pos);
+
+ err = iLogFile.Write(_L8("#------------------------Test Run Start-------------------------\r\n"));
+ iLogFile.Flush();
+
+ }
+
+CUnitTestBase::CUnitTestBase(const TDesC& aUnitTestName,
+ const TDesC& aLogFileName,
+ const TDesC& aTestSpecName,
+ const TDesC& aTestScriptName)
+/**
+ *
+ *
+ */
+ :iTest(aUnitTestName),
+ iUnitTestName(aUnitTestName),
+ iLogFileName(aLogFileName),
+ iTestScriptName(aTestScriptName),
+ iTestSpecName(aTestSpecName)
+ {
+#ifndef __WINS__
+ iTest.SetLogged(EFalse);
+#endif // __WINS__
+ }
+
+CUnitTestBase::~CUnitTestBase()
+/**
+ *
+ *
+ */
+ {
+ iFailedTests.Close();
+
+ if (iLogFile.SubSessionHandle())
+ {
+ iLogFile.Write(_L8("#------------------------Test Run End-------------------------\r\n"));
+ iLogFile.Flush();
+ }
+ iLogFile.Close();
+ iFs.Close();
+ iTest.Close();
+ }
+
+void CUnitTestBase::ResizeConsoleL(const TDesC& aName, TInt aXOrg, TInt aYOrg, TInt aXSize, TInt aYSize)
+ {
+#if defined (__WINS__)
+ CConsoleBase* cons = iTest.Console();
+ CConsoleBase* newCon = NULL;
+
+ TRAPD(err,newCon = Console::NewL(aName,TSize(aXSize,aYSize)));
+ if (!err)
+ {
+ (void)aXOrg; (void)aYOrg; //unable to use these without a dirty hack!
+ delete cons;
+ iTest.SetConsole(newCon);
+ }
+#else //__WINS__
+ (void)aName; (void)aXOrg; (void)aYOrg; (void)aXSize; (void)aYSize;
+#endif //__WINS__
+ }
+
+TBool CUnitTestBase::DoSingleTestL(TInt aMethodNum, TInt aTestNum, TTestMode aTestMode)
+ {
+ //LOGTEXT3(">>DoSingleTestL [aMethodNum=%d, aTestNum=%d]",aMethodNum,aTestNum);
+
+ TInt numMethods;
+ TInt numTests;
+ TInt errorCode;
+ TInt leaveCode;
+
+ // Check if the specified test is in a valid range - if we can
+ if (HasTestRangesDefined())
+ {
+ RunTestsL(EFalse, EBatch, numMethods, leaveCode, 0, 0);
+
+ // Check that the method number is correct
+ if (aMethodNum == 0 || aMethodNum > numMethods)
+ {
+ iTest.Printf(_L("Bad method number: %d - Needs to be in range 1 to %d\n"),
+ aMethodNum, numMethods);
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ //LOGTEXT("<<DoSingleTestL bad method number");
+ return ETrue;
+ }
+
+
+ TInt testRange = 0;
+ if (aTestNum > 100) testRange = 100;
+
+ // Get the number of tests for this method and test if aTestNum is in range
+ RunTestsL(EFalse, EBatch, numTests, leaveCode, aMethodNum, testRange);
+ numTests += testRange;
+
+ if (aTestNum <= testRange || aTestNum > numTests)
+ {
+ iTest.Printf(_L("Bad test number (%d) for method %d - Needs to be in range %d to %d\n"),
+ aTestNum, aMethodNum, testRange+1, numTests);
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ //LOGTEXT("<<DoSingleTestL bad test number");
+ return ETrue;
+ }
+ }
+
+ errorCode = KErrNone;
+ leaveCode = KErrNone;
+
+ RunTestsL(EFalse, aTestMode, errorCode, leaveCode, aMethodNum,aTestNum);
+
+ LogTestResult(errorCode, leaveCode, EFalse, aMethodNum, aTestNum, aTestMode);
+
+ //LOGTEXT("<<DoSingleTestL ETrue");
+ return ETrue;
+ }
+
+TBool CUnitTestBase::DoAutoMethodTestsL(TInt aMethodNum)
+ {
+ //LOGTEXT2(">>DoAutoMethodTestsL [aMethodNum=%d]",aMethodNum);
+
+ TInt numMethods;
+ TInt numTests;
+ TInt errorCode;
+ TInt leaveCode;
+
+ if (! HasTestRangesDefined())
+ {
+ iTest.Printf(_L("Cannot auto run tests as test ranges not implemented\n"));
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+
+ // Check that the method number is correct
+ RunTestsL(EFalse, EBatch, numMethods, leaveCode, 0, 0);
+
+ if (aMethodNum == 0 || aMethodNum > numMethods)
+ {
+ iTest.Printf(_L("Bad method number: %d - Needs to be in range 1 to %d\n"),
+ aMethodNum, numMethods);
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+
+
+ // Get the number of automated tests for this method
+ RunTestsL(EFalse, EBatch, numTests, leaveCode, aMethodNum, 0);
+
+ for (TInt testIndex = 1; testIndex <= numTests; testIndex++)
+ {
+ errorCode = KErrNone;
+ leaveCode = KErrNone;
+
+ RunTestsL(EFalse, EBatch, errorCode, leaveCode, aMethodNum, testIndex);
+ LogTestResult(errorCode, leaveCode, EFalse, aMethodNum, testIndex, EBatch);
+
+ if (errorCode || leaveCode)
+ {
+ TTestFailure theFailedTest(aMethodNum, testIndex);
+ (void) iFailedTests.Append(theFailedTest);
+ }
+ }
+
+ //LOGTEXT("<<DoAutoMethodTestsL");
+ return ETrue;
+ }
+
+TBool CUnitTestBase::DoTestsInSpecifiedRangeL(TInt aStartMethodNum,
+ TInt aStartTestNum,
+ TInt aEndMethodNum,
+ TInt aEndTestNum)
+ {
+ //LOGTEXT3(">>DoTestsInSpecifiedRangeL [aStartMethodNum=%d, aEndMethodNum=%d]",
+ // aStartMethodNum,aEndMethodNum);
+
+ TInt numMethods;
+ TInt numTests;
+ TInt errorCode;
+ TInt leaveCode;
+
+ if (! HasTestRangesDefined())
+ {
+ iTest.Printf(_L("Cannot auto run tests as test ranges not implemented\n"));
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+
+ // Check that the method number is correct
+ RunTestsL(EFalse, EBatch, numMethods, leaveCode, 0, 0);
+
+ if (aStartMethodNum == 0 || aStartMethodNum > numMethods)
+ {
+ iTest.Printf(_L("Bad method number: %d - Needs to be in range 1 to %d\n"),
+ aStartMethodNum, numMethods);
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+ if (aEndMethodNum == 0 || aEndMethodNum > numMethods)
+ {
+ iTest.Printf(_L("Bad method number: %d - Needs to be in range 1 to %d\n"),
+ aEndMethodNum, numMethods);
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+ if (aEndMethodNum == -1)
+ aEndMethodNum = numMethods;
+
+ for (TInt methodIndex = aStartMethodNum; methodIndex <= aEndMethodNum; methodIndex++)
+ {
+ TInt testIndex;
+
+ if ((methodIndex < aEndMethodNum) || (aEndTestNum == -1))
+ {
+ // Get the number of automated tests for the current method
+ RunTestsL(EFalse, EBatch, numTests, leaveCode, methodIndex, 0);
+ }
+ else
+ {
+ // Finish on a specified test.
+ numTests = aEndTestNum;
+ }
+
+ if (methodIndex == aStartMethodNum)
+ testIndex = aStartTestNum;
+ else
+ testIndex = 1;
+
+ iTest.Printf(_L("Running tests %d to %d in method %d\n"),
+ testIndex, numTests, methodIndex);
+ for (; testIndex <= numTests; testIndex++)
+ {
+ errorCode = KErrNone;
+ leaveCode = KErrNone;
+
+ RunTestsL(EFalse, EBatch, errorCode, leaveCode, methodIndex, testIndex);
+
+ LogTestResult(errorCode, leaveCode, EFalse, methodIndex, testIndex, EBatch);
+ }
+ }
+
+ //LOGTEXT("<<DoTestsInSpecifiedRangeL");
+ return ETrue;
+ }
+
+TBool CUnitTestBase::DoAutoMethodsL()
+ {
+ //LOGTEXT(">>DoAutoMethodsL");
+
+ TInt numMethods;
+ TInt leaveCode;
+
+ if (! HasTestRangesDefined())
+ {
+ iTest.Printf(_L("Cannot auto run tests as test ranges not implemented\n"));
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+
+ // Get the number of automated tests for this method
+ RunTestsL(EFalse, EBatch, numMethods, leaveCode, 0, 0);
+
+ iFailedTests.Reset();
+ for (TInt methodIndex = 1; methodIndex <= numMethods; methodIndex++)
+ {
+ DoAutoMethodTestsL(methodIndex);
+ }
+
+ TInt failedCount = iFailedTests.Count();
+ if ( iRepeatFailedTests
+ && failedCount > 0)
+ {
+ iTest.Printf(_L("%d tests failed. Will retry them now.\n"), failedCount);
+ iLogFile.Write(_L8("#--- Retrying the tests that failed ---\r\n"));
+ for (TInt i = 0; i < failedCount; i++)
+ {
+ TTestFailure theFailedTest = iFailedTests[i];
+ DoSingleTestL(theFailedTest.iMethodNum, theFailedTest.iTestIndex, EBatch);
+ }
+ }
+ iFailedTests.Reset();
+
+ //LOGTEXT("<<DoAutoMethodsL");
+ return ETrue;
+ }
+
+TBool CUnitTestBase::DoTestsL()
+/**
+ * This function selects a unit test, runs it and then logs the result
+ *
+ * @return return a TBool
+ * @retval ETrue if another test to run in interactive mode
+ * @retval EFalse if the test is in batch mode or there is not another
+ * test to run in interactive mode
+ */
+ {
+ TInt methodNum;
+ TInt testNum;
+ TInt endMethodNum;
+ TInt endTestNum;
+ TTestMode testMode = EBatch;
+ TBool exitTests;
+
+ TBool numOK = SelectTestL(methodNum, testNum,
+ endMethodNum, endTestNum, testMode, exitTests);
+
+ if (! numOK)
+ {
+ iTest.Printf(_L("Bad number entered\n"));
+ iTest.Printf(_L("Press a key when ready\n"));
+ iTest.Console()->Getch();
+ return ETrue;
+ }
+
+ if (exitTests)
+ {
+ return EFalse;
+ }
+
+ // Is this a manual test?
+ if ((testNum != -1) && ((endTestNum == -1) || (testMode == EInteractive)))
+ {
+ iTest.Printf(_L("Running single test %d-%d\n"), methodNum, testNum);
+ DoSingleTestL(methodNum, testNum, testMode);
+ return ETrue;
+ }
+
+ // Do we want to auto run all the tests for a specified method
+ if ((methodNum != -1) && (testNum == -1))
+ {
+ iTest.Printf(_L("Running all tests in method %d\n"), methodNum);
+ DoAutoMethodTestsL(methodNum);
+ return ETrue;
+ }
+
+ // Do we want to run tests from one index to another?
+ if (methodNum != -1)
+ {
+ iTest.Printf(_L("Running tests %d-%d to %d-%d\n"), methodNum, testNum, endMethodNum, endTestNum);
+ DoTestsInSpecifiedRangeL(methodNum, testNum, endMethodNum, endTestNum);
+ return ETrue;
+ }
+
+ // methodNum == -1 && testNum == -1 =>
+ // We want to all the tests for every method automatically
+ iTest.Printf(_L("Running all tests\n"));
+ return DoAutoMethodsL();
+ }
+
+TInt CUnitTestBase::PostTestDelayTime()
+/**
+ * This virtual function can be overridden by derived tests to
+ * configure the length of delay between running tests in
+ * automated mode. This used to be hard coded to KTsyTestCompleteTime,
+ * which was 3 seconds.
+ *
+ * With 100 tests, that adds up to 5 minutes of wasted time per run!
+ */
+ {
+ return KTsyTestCompleteTime;
+ }
+
+void CUnitTestBase::ActionNoMatch(TBool aEndInd,TTestMode aTestMode,
+ TInt aApiNumber,TInt aTestNumber)
+/**
+ * This function provides the default action for the case
+ * when the test identified by the API and test number is
+ * not implemented. It is to be called within RunTestsL()
+ * in the default case of its switch statement
+ */
+ {
+ if(!aEndInd)
+ {
+ iTest.Printf(_L("** Not implemented CSY%S-%d-%d yet **\n"),
+ &iUnitTestName,aApiNumber,aTestNumber);
+ if(aTestMode==EInteractive)
+ {
+ iTest.Printf(_L("press any key to continue\n"));
+ iTest.Console()->Getch();
+ }
+ }
+ }
+
+TInt CUnitTestBase::CompareTestResult
+(TInt aExpectedResult,TRequestStatus aStatus)
+/**
+ * This function compare the test result with the expected one
+ *
+ * @param aStatus stores the result of a client API request
+ *
+ */
+ {
+ TInt ret=KErrNone;
+ if (aStatus.Int() != aExpectedResult)
+ {
+ if(aStatus==KErrNone)
+ ret=__LINE__;
+ else
+ ret=aStatus.Int();
+ }
+ return ret;
+ }
+
+void CUnitTestBase::LogTestResult(TInt aErrCode, TInt aLeaveCode,
+ TBool aEndInd,TInt aApiNumber,
+ TInt aTestNumber,TTestMode aTestMode)
+/**
+ * This function logs the test result
+ */
+ {
+ TInt err=KErrNone;
+ if ((aErrCode)||(aLeaveCode))
+ {
+ if (aLeaveCode)
+ {
+ iTest.Printf(_L("Test failed with a LEAVE: CSY%S-%d-%d\n"),
+ &iUnitTestName,aApiNumber,aTestNumber);
+ err=aLeaveCode;
+ }
+ else
+ {
+ iTest.Printf(_L("FAILURE: CSY%S-%d-%d failed with %d\n"),
+ &iUnitTestName,aApiNumber,aTestNumber,aErrCode);
+ err=aErrCode;
+ }
+
+ //Print out test results in Symbian's requested format
+ TUint count=iFunIndices.Count();
+ for(TUint i = 0; i < count; i++)
+ WriteLog(EFalse,iFunIndices[i],aApiNumber,aTestNumber,err);
+ iFunIndices.Reset();
+
+ if (aTestMode==EInteractive)
+ {
+ iTest.Printf(_L("press any key to continue\n"));
+ iTest.Console()->Getch();
+ }
+ }
+ else
+ {
+ //these code will not be run if a user type E or e
+ //to end running the tests in interactive mode
+ if (!aEndInd)
+ {
+ iTest.Printf(_L("CSY%S-%d-%d finished successfully\n"),
+ &iUnitTestName,aApiNumber,aTestNumber);
+
+#ifndef LOG_FAILED_TESTS_ONLY
+ //Print out test results in Symbian's requested format
+ TUint count=iFunIndices.Count();
+ for(TUint i = 0; i < count; i++)
+ WriteLog(ETrue,iFunIndices[i],aApiNumber,aTestNumber,err);
+ iFunIndices.Reset();
+#endif
+ iTest.Printf(_L("Waiting briefly for system to close\n"));
+
+ // give some time for test to complete
+// User::After(this->PostTestDelayTime());
+ }
+ }
+ }
+
+
+TBool CUnitTestBase::UserSelectionL(TChar aMainNumber,
+ TInt aNumMethods,
+ TBool aRangeSpecified,
+ TInt& aApiNum, TInt& aTestNum,
+ TTestMode& aTestMode)
+ {
+ TInt leaveCode = 0;
+ aApiNum = UserChoice(aMainNumber);
+
+ if (aApiNum == -1) return EFalse;
+
+ if (aNumMethods != -1 && (aApiNum < 1 || aApiNum > aNumMethods))
+ {
+ aApiNum = -1;
+ aTestNum = -1;
+ return EFalse;
+ }
+
+ PrintTestDetails(aApiNum);
+
+ TInt numAutoTests = -1;
+ TInt numManualTests = -1;
+
+ if (! HasTestRangesDefined())
+ iTest.Printf(_L("Test number:"));
+ else
+ {
+ RunTestsL(EFalse, EBatch, numAutoTests, leaveCode, aApiNum, 0);
+ RunTestsL(EFalse, EBatch, numManualTests, leaveCode, aApiNum, 100);
+
+ iTest.Printf(_L("There are %d auto and %d manual tests\n"),
+ numAutoTests, numManualTests);
+ if (aRangeSpecified)
+ iTest.Printf(_L("Range test number:"));
+ else
+ iTest.Printf(_L("Test number or 'A' for all tests:"));
+ }
+
+ TChar numberKey = iTest.Console()->Getch();
+ iTest.Printf(_L("\n"));
+
+ if ((!aRangeSpecified) && HasTestRangesDefined() && ((numberKey == 'A')||(numberKey == 'a')))
+ {
+ aTestMode = EBatch;
+ aTestNum = -1;
+ return ETrue;
+ }
+
+ aTestNum = UserChoice(numberKey);
+
+ if (aTestNum == -1) return EFalse;
+
+ TBool ret = EFalse;
+
+ if (! HasTestRangesDefined())
+ ret = ETrue;
+
+ if (aTestNum > 0 && aTestNum <= numAutoTests)
+ ret = ETrue;
+
+ if (aTestNum > 100 && aTestNum <= (100+numManualTests))
+ ret = ETrue;
+
+ return ret;
+ }
+
+TBool CUnitTestBase::SelectTestL(TInt& aApiNum, TInt& aTestNum,
+ TInt& aEndApiNum, TInt& aEndTestNum,
+ TTestMode& aTestMode, TBool& aExit)
+/**
+ * This function selects a unit test which is identified by its API &
+ * test numbers to be run either in batch or interactive mode
+ *
+ * @return return a TBool to indicate whether or not to end the test in
+ * interactive mode
+ */
+ {
+ aTestMode = EBatch;
+ aExit = EFalse;
+
+ iTest.Console()->ClearScreen();
+
+ if (CommandLineL(aApiNum, aTestNum, aEndApiNum, aEndTestNum))
+ {
+ aTestMode = EBatch;
+ iExitAfterTestsComplete = ETrue;
+
+ // we have got the numbers from the command line
+ iTest.Printf(_L("Running %S automated API tests\n"),&iUnitTestName);
+
+ // give tester time to get up and running
+ User::After(KTsyTesterSetupTime);
+ return ETrue;
+ }
+
+ // need to get numbers from the user
+ iTest.Printf(_L("Running %S API Tests - interactively\n"), &iUnitTestName);
+
+ aTestMode = EInteractive;
+
+ // helper to aid user - which identifier relates to which number
+ PrintTestSpecIdentifiers();
+
+ TInt numMethods = -1;
+ TInt leaveCode = 0;
+ TBool rangeSpecified = EFalse;
+
+ // Get the numbers
+ if (! HasTestRangesDefined())
+ iTest.Printf(_L("\nNumber or 'S' for specific test or 'E' to end:"));
+ else
+ {
+ RunTestsL(EFalse, EBatch, numMethods, leaveCode, 0, 0);
+ iTest.Printf(_L("\nNumber or 'S' for specific test, 'R' for range, 'A' for all or 'E' to end:"), numMethods);
+ }
+
+ TChar numberKey = iTest.Console()->Getch();
+ iTest.Printf(_L("\n"));
+
+ if (!numberKey.IsDigit())
+ {
+ switch (numberKey)
+ {
+ case 'E':
+ case 'e':
+ aExit = ETrue;
+ return ETrue;
+ case 'A':
+ case 'a':
+ {
+ if (HasTestRangesDefined())
+ {
+ aTestMode = EBatch;
+ aApiNum = -1;
+ aTestNum = -1;
+ return ETrue;
+ }
+ }
+ return EFalse;
+ case 'R':
+ case 'r':
+ {
+ if (HasTestRangesDefined())
+ {
+ aTestMode = EBatch;
+ iTest.Printf(_L("Enter Start Method of range (1 -> %d):"), numMethods);
+ numberKey = iTest.Console()->Getch();
+ rangeSpecified = ETrue;
+ }
+ else
+ return EFalse;
+ }
+ break;
+ case 'S':
+ case 's':
+ {
+ iTest.Printf(_L("Method to test (1 -> %d):"), numMethods);
+ numberKey = iTest.Console()->Getch();
+ }
+ break;
+ default:
+ iTest.Printf(_L("Incorrect value\n"));
+ return EFalse;
+ }
+ }
+
+ // User to select test case or start of range
+ TBool ret = UserSelectionL(numberKey, numMethods, rangeSpecified,
+ aApiNum, aTestNum, aTestMode);
+
+ if (ret && rangeSpecified)
+ {
+ PrintTestSpecIdentifiers();
+
+ iTest.Printf(_L("Enter end method of range (1 -> %d) or 'L' last"), numMethods);
+ numberKey = iTest.Console()->Getch();
+ iTest.Printf(_L("\n"));
+
+ if ((numberKey == 'L')||(numberKey == 'l'))
+ {
+ aTestMode = EBatch;
+ aEndApiNum = -1;
+ aEndTestNum = -1;
+ return ETrue;
+ }
+
+ // User to select end of range
+ ret = UserSelectionL(numberKey, numMethods, ETrue,
+ aEndApiNum, aEndTestNum, aTestMode);
+ }
+
+ return ret;
+ }
+
+TInt CUnitTestBase::UserChoice(TChar aNumberKey)
+/**
+ * This function gets the number equivalent to the user's keyboard input
+ * and will return once the enter key is pressed
+ *
+ * @param aNumberKey is a key pressed by the user
+ * @return return the number equivalent to the user's keyboard input
+ */
+ {
+ TInt choice=0;
+ TInt mult=1;
+
+ while ( STATIC_CAST(TInt,aNumberKey) != EKeyEnter )
+ {
+ // If the user pressed Backspace, delete the previous number.
+ if (aNumberKey == 0x8)
+ {
+ if (choice > 0)
+ {
+ iTest.Printf(_L("%c %c"), aNumberKey, aNumberKey);
+ choice /= 10;
+ if (choice == 0)
+ mult = 1;
+ }
+ }
+
+ if (!aNumberKey.IsDigit())
+ {
+ aNumberKey = iTest.Console()->Getch();
+ continue;
+ }
+
+ TInt val = aNumberKey.GetNumericValue();
+ iTest.Printf(_L("%d"),val) ;
+ choice = (choice * mult) + val;
+ if(mult==1)
+ mult *= 10;
+ aNumberKey = iTest.Console()->Getch() ;
+ }
+
+ iTest.Printf(_L("\n")) ;
+ return choice;
+ }
+
+TBool CUnitTestBase::CommandLineL(TInt& aApiNum, TInt& aTestNum,
+ TInt& aEndApiNum, TInt& aEndTestNum)
+/**
+ * This function takes inputs from command lines in the batch file run_me.bat
+ */
+ {
+ aApiNum = 0;
+ aTestNum = 0;
+
+ TInt commandLineLength;
+#ifndef BUILD_FOR_JETSTREAM
+ commandLineLength = User::CommandLineLength();
+#else
+ RProcess eteltest;
+ commandLineLength = eteltest.CommandLineLength();
+#endif // BUILD_FOR_JETSTREAM
+
+ if (commandLineLength > 0)
+ {
+ HBufC* argv = HBufC::NewLC(commandLineLength);
+ TPtr cmd(argv->Des());
+
+#ifndef BUILD_FOR_JETSTREAM
+ User::CommandLine(cmd);
+#else
+ eteltest.CommandLine(cmd);
+#endif // BUILD_FOR_JETSTREAM
+
+ TLex argParser(*argv);
+
+ TInt argc = 0;
+ while (argParser.NextToken().Length()) argc++;
+ if ((argc < 2) || (argc > 4))
+ {
+ iTest.Console()->Printf(_L("Usage: <app> <api num> <test num> [<end api> <end test>]\n"));
+ return EFalse;
+ }
+
+ argParser.UnGetToMark(); //Returns to the beginning of argv.
+ argParser.SkipSpace();
+
+ argParser.Val(aApiNum);
+ argParser.SkipSpace();
+ argParser.Val(aTestNum);
+
+ if (argc == 4)
+ {
+ argParser.SkipSpace();
+ argParser.Val(aEndApiNum);
+ argParser.SkipSpace();
+ argParser.Val(aEndTestNum);
+ }
+ else
+ {
+ aEndApiNum = aApiNum;
+ aEndTestNum = aTestNum;
+ }
+
+ delete argv;
+ CleanupStack::Pop();//argv
+
+ // we did find some command line params
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+TInt CUnitTestBase::WriteLog(TBool aIsPassed,TUint aFunIndex,TUint aApiNum,
+ TUint aTstNum, TInt aErrorCode)
+/**
+ * This function write test result to log in the folowing formats:
+ * AUTO;<DATE>;<TIME>;UTS;<TS-Identifier>;<Functionality-Index>;
+ * PASSED;<Test-Script>;<Method-In-Test-Script>;
+ * or
+ * AUTO;<DATE>;<TIME>;UTS;<TS-Identifier>;<Functionality-Index>;
+ * FAILED;<Test-Script>;<Method-In-Test-Script>;<ErrorCode>
+ */
+ {
+ //Get date & time
+ TTime time;
+ TDateTime dateTime;
+ time.HomeTime();
+ dateTime=time.DateTime();
+ TUint year = dateTime.Year();
+ TUint day = dateTime.Day() + 1;//Day() & Month() starts from 0
+ TUint month = dateTime.Month() + 1;
+ TUint hour = dateTime.Hour();
+ TUint minute = dateTime.Minute();
+ TUint second = dateTime.Second();
+
+ //Prepared the PASSED/FAILED field
+ TBuf8<KBufSize10> passedOrFailed;
+ if(aIsPassed)
+ passedOrFailed.Copy(KPassed);
+ else
+ passedOrFailed.Copy(KFailed);
+
+ TBuf8<KMaxName> testResult;
+
+ testResult.Copy(KAutoTestMarker);//AUTO;
+
+ //<DATE>;<TIME>;
+ TBuf8<KBufSize25> dateTimeField;
+ FormDateTimeBit(dateTimeField,day,ETrue,ETrue);
+ FormDateTimeBit(dateTimeField,month,ETrue,ETrue);
+ FormDateTimeBit(dateTimeField,year,ETrue,EFalse);
+ FormDateTimeBit(dateTimeField,hour,EFalse,ETrue);
+ FormDateTimeBit(dateTimeField,minute,EFalse,ETrue);
+ FormDateTimeBit(dateTimeField,second,EFalse,EFalse);
+ testResult.Append(dateTimeField);
+
+ testResult.Append(iTestSpecName);//UTS;
+
+ //<TS-Identifier>;
+ testResult.Append(iTsIdentifier);
+ testResult.Append(KSemiColon);
+
+ //<Functionality-Index>;
+ TBuf8<KBufSize25> buf;
+ buf.Num(aFunIndex);
+ buf.Append(KSemiColon);
+ testResult.Append(buf);
+
+ //PASSED/FAILED;
+ testResult.Append(passedOrFailed);
+
+ //<Test-Script>;
+ testResult.Append(iTestScriptName);
+
+ //<Method-In-Test-Script>
+ TBuf8<KBufSize100> bufMethodWithId;
+ bufMethodWithId.Copy(iMethodName);
+ bufMethodWithId.Append(KHyphen);
+ buf.Num(aApiNum);
+ buf.Append(KHyphen);
+ bufMethodWithId.Append(buf);
+ buf.Num(aTstNum);
+ buf.Append(KSemiColon);
+ bufMethodWithId.Append(buf);
+ testResult.Append(bufMethodWithId);
+
+ if(!aIsPassed)
+ {
+ buf.Num(aErrorCode);
+ testResult.Append(buf);
+ }
+ testResult.Append(KNewLine);
+
+ TInt err = iLogFile.Write(testResult);
+ iLogFile.Flush();
+
+ return err;
+ }
+
+void CUnitTestBase::FormDateTimeBit(TDes8& aDateTimeField,TUint aDateTimeBit,
+ TBool aIsDateSepa,TBool aAddSepa)
+/**
+ * Append a date/time bit(month & hour etc.) and separator or delimiter
+ * into the dateTimeField descriptor
+ */
+ {
+ TBuf8<KBufSize1> separator;//- or :
+ TBuf8<KBufSize4> buf;//year takes 4 digits, the rest takes two digits
+ if(aIsDateSepa)
+ separator.Copy(KHyphen);
+ else
+ separator.Copy(KColon);
+ if(aDateTimeBit < KZeroPadValue)
+ aDateTimeField.Append(KZeroPadding);
+ buf.Num(aDateTimeBit);
+ aDateTimeField.Append(buf);
+ if(aAddSepa)
+ aDateTimeField.Append(separator);
+ else
+ aDateTimeField.Append(KSemiColon);
+ }
+
+
+TInt CUnitTestBase::LoadComms()
+/**
+ *
+ */
+ {
+ // connect to C32
+ TInt ret = iCommServer.Connect();
+ if (ret)
+ {
+ return ret;
+ }
+ return ret;
+ }
+
+TInt CUnitTestBase::UnloadComms()
+/**
+ *
+ */
+ {
+ iCommServer.Close();
+
+ return (KErrNone);
+ }
+
+void CUnitTestBase::ReadStr(TDes& aDes)
+ {
+ TChar inputKey;
+ TInt count = 0;
+ const TInt KMaxLength = aDes.MaxLength();
+
+ aDes.Zero();
+ for (;;)
+ {
+ inputKey = (TInt) iTest.Getch();
+
+ if ((TInt)inputKey == EKeyEnter)
+ {
+ iTest.Printf(_L("\n"));
+ break;
+ }
+
+ if (inputKey == EKeyBackspace)
+ {
+ if (count > 0)
+ {
+ iTest.Printf(_L("%c"), inputKey);
+ aDes.Delete(--count,1);
+ }
+ }
+ else if (inputKey.IsPrint() && count < KMaxLength)
+ {
+ iTest.Printf(_L("%c"), inputKey);
+ aDes.Append(inputKey);
+ count++;
+ }
+ }
+ }
+
+void CUnitTestBase::GetCompilationDate(TInt& aDay, TInt& aMonth, TInt& /*aYear*/)
+ {
+ // The __DATE__ string is guaranteed to be of the form "Mmm dd yyyy"
+ // eg. Sep 9 2002
+
+ const TUint8* KMonthNames[] = {
+ _S8("Jan"), _S8("Feb"), _S8("Mar"), _S8("Apr"), _S8("May"), _S8("Jun"),
+ _S8("Jul"), _S8("Aug"), _S8("Sep"), _S8("Oct"), _S8("Nov"), _S8("Dec") };
+ const TUint8 KDateString[] = __DATE__;
+ const TPtrC8 KMonth(KDateString, 3);
+ const TPtrC8 KDay(KDateString + 4, 2);
+ const TPtrC8 KYear(KDateString + 7, 4);
+
+ TLex8 lex(KDay);
+ lex.SkipSpaceAndMark();
+ //kmif (lex.Val(aDay)) PANIC(10000);
+ aDay--; // get a zero based day for compatibility with TDateTime
+ lex.Assign(KYear);
+ //kmif (lex.Val(aYear)) PANIC(10000);
+
+ aMonth = KErrNotFound;
+ for (TInt i = 0; i < 12; i++)
+ {
+ TPtrC8 month(KMonthNames[i], 3);
+ if (month == KMonth) aMonth = i;
+ }
+
+ //kmif (aMonth < 0) PANIC(10000);
+ //kmif (aMonth > 11) PANIC(10000);
+ }
+
+void CUnitTestBase::EnsureTargetDeviceClockIsSet()
+ {
+ TTime now;
+ now.HomeTime();
+ TDateTime date = now.DateTime();
+
+ TInt month, dayInMonth, year;
+ GetCompilationDate(dayInMonth, month, year);
+
+ //LOGTEXT4("day %d month %d year %d", dayInMonth, month, year);
+
+ // If boards current date is later than our compilation year, just return
+ if ( date.Year() >= year
+ && date.Month() >= month
+ && date.Day() >= dayInMonth)
+ {
+ return;
+ }
+
+ const TInt KCompiledYear = year;
+ for (;;)
+ {
+ iTest.Printf(_L("Enter date as DD MM YYYY (year is optional, defaults to %d) "), year);
+
+ TBuf<12> input;
+ TBuf8<12> input8;
+ ReadStr(input);
+ input.TrimAll();
+ input8.Copy(input);
+
+ TLex8 lex(input8);
+
+ lex.Val(dayInMonth);
+ lex.SkipSpaceAndMark();
+ lex.Val(month);
+ lex.SkipSpaceAndMark();
+ lex.Val(year); // if no year entered, this just returns error - year is unchanged
+
+ TInt err;
+ err = date.SetYear(year);
+ if (!err) err = date.SetMonth(static_cast<TMonth>(month-1));
+ if (!err) err = date.SetDay(dayInMonth-1);
+ if (!err && year < KCompiledYear) err = KErrNotReady;
+
+ if (err == KErrNone)
+ {
+ break; // loop termination condition
+ }
+ else
+ {
+ iTest.Printf(_L("Does not appear to be a correctly formatted date, try again.\n"));
+ month = 0;
+ dayInMonth = 0;
+ year = KCompiledYear;
+ }
+ }
+
+ // Refresh the other time values
+ now.HomeTime();
+ date = now.DateTime();
+ // Now restore the user-entered values
+ date.SetYear(year);
+ date.SetMonth(static_cast<TMonth>(month-1));
+ date.SetDay(dayInMonth-1);
+ User::SetHomeTime(date);
+ }
+
+void CUnitTestBase::RunUnitTestsL()
+/**
+ * This function is called within CreateTestL(), which is a
+ * static member function of CUnitTestBase derived classes, to run
+ * the unit tests for the appropriate module
+ */
+ {
+ // load the CSY
+ iTest(LoadComms() == KErrNone);
+
+#ifdef __EPOC32__
+// EnsureTargetDeviceClockIsSet();
+#endif
+
+ // do test sequence
+ TBool noEnd = ETrue;
+ while(noEnd)
+ {
+ noEnd = DoTestsL();
+ if (iExitAfterTestsComplete)
+ noEnd = EFalse;
+ }
+
+ // unload the CSY
+ iTest(UnloadComms() == KErrNone);
+ }
+
+TInt CUnitTestBase::SetUpTest()
+/**
+ * This function is called within CreateTestL(), which is a
+ * static member function of CUnitTestBase derived classes,
+ * to load drivers & start C32
+ *
+ * If you want to give an 'opening page' of instructions for your unit test,
+ * override this and do so. Remember to base call! See DataUnitTest for an
+ * example.
+ *
+ * @return return an error code if set up fails
+ */
+ {
+ iTest.Title();
+
+ iTest.Start(_L("Loading Serial drivers\n"));
+
+ TInt r;
+
+#if defined (__WINS__)
+ r = User::LoadPhysicalDevice(PDD_NAME);
+ r = User::LoadLogicalDevice(LDD_NAME);
+
+//taproot: tushar commented for OMAP
+//#else // __GCC32__
+// r = User::LoadPhysicalDevice(PDD_SIR_NAME);
+// r = User::LoadPhysicalDevice(PDD_UART_NAME);
+// r = User::LoadLogicalDevice(LDD_NAME);
+#endif
+
+ r = StartC32();
+ if ((r != KErrNone) && (r != KErrAlreadyExists))
+ iTest.Printf(_L("Failed to start C32 %d\n"), r);
+
+ return KErrNone;
+ }
+
+void CUnitTestBase::PrintTestSpecIdentifiers()
+ {
+ // This version prints no helpful info on the screen. Overload this in
+ // your own test class to put out test identifier and number of API test
+ }
+
+void CUnitTestBase::PrintTestDetails(TInt /*aTstSpecNumber*/)
+ {
+ // This version prints no helpful info on the screen. Overload this in
+ // your own test class to put out test details for the test spec idenifier
+ // selected
+ }
+
+void CUnitTestBase::SetFunIndex2(TUint aFunIndex1,TUint aFunIndex2)
+ {
+ iFunIndices.Insert(aFunIndex1,0);
+ iFunIndices.Insert(aFunIndex2,1);
+ }
+
+void CUnitTestBase::SetFunIndex3(TUint aFunIndex1,TUint aFunIndex2,
+ TUint aFunIndex3)
+ {
+ iFunIndices.Insert(aFunIndex1,0);
+ iFunIndices.Insert(aFunIndex2,1);
+ iFunIndices.Insert(aFunIndex3,2);
+ }
+
+void CUnitTestBase::SetFunIndex4(TUint aFunIndex1,TUint aFunIndex2,
+ TUint aFunIndex3,TUint aFunIndex4)
+ {
+ iFunIndices.Insert(aFunIndex1,0);
+ iFunIndices.Insert(aFunIndex2,1);
+ iFunIndices.Insert(aFunIndex3,2);
+ iFunIndices.Insert(aFunIndex4,3);
+ }
+
+TInt CUnitTestBase::GetRequestOrTimeOut(TRequestStatus& aRequestStatus,
+ TTimeIntervalMicroSeconds32 aTimeOut)
+/**
+ * Acts exactly like User::WaitForRequest, except aTimeOut is a timeout period
+ * to give up waiting after.
+ * If the request times out, returns KErrTimedOut, otherwise returns KErrNone
+ * and aRequestStatus is completed as usual.
+ */
+ {
+ //LOGTEXT(">>GetRequestOrTimeOut");
+
+ RTimer timer;
+ TRequestStatus timerRequest;
+ timer.CreateLocal();
+ timer.After(timerRequest, aTimeOut);
+
+ // Wait for the requestto complete or until we time out
+ User::WaitForRequest(timerRequest, aRequestStatus);
+
+ // If timer is no longer pending => we have timed out
+ if (timerRequest != KRequestPending)
+ {
+ //LOGTEXT("<<GetRequestOrTimeOut **** Timed out ****");
+ return KErrTimedOut;
+ }
+
+ timer.Cancel();
+
+ User::WaitForRequest(timerRequest);
+
+ //LOGTEXT2("<<GetRequestOrTimeOut [aRequestStatus=%d]",aRequestStatus);
+ return KErrNone;
+ }