diff -r 000000000000 -r 08ec8eefde2f traceservices/commsdebugutility/TE_commsdebugutility/src/teststepcomsdbg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/traceservices/commsdebugutility/TE_commsdebugutility/src/teststepcomsdbg.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,367 @@ +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// This contains CTestCase which is the base class for all the TestCase DLLs +//just to test p4 + +// EPOC includes +#include +#include +#include +// Test system includes +#include "teststepcomsdbg.h" +#include +#include "TestMessage.h" + + +// constructor +CTestStepFlogger::CTestStepFlogger() + { + } + +// destructor +CTestStepFlogger::~CTestStepFlogger() + { + } + + +TVerdict CTestStepFlogger::doTestStepPostambleL() + { + SetTestStepResult(EPass); return TestStepResult(); + } + + +TInt CTestStepFlogger::executeStepL() + { + return KErrGeneral; + } + +TInt CTestStepFlogger::executeStepL( /*aLogger*/ TBool /*aStatus*/) + { + return KErrGeneral; + } + + +TInt CTestStepFlogger::executeStep(CTestStepFlogger& aTestStep) + { + TInt r = 0; + TInt ret= 0; + + TRAP( r, ret = aTestStep.executeStepL() ); + + if ( r != KErrNone ) + ret = r; + + return ret; + } + +TInt CTestStepFlogger::executeStep( TBool bypassChecks ) + { + TInt ret=0; + TInt r; + + // bypassChecks is optional, so many clients don't know to supply it + if (bypassChecks) + { + TRAP( r, ret = executeStepL(bypassChecks) ); + } + else + { + TRAP( r, ret = executeStepL() ); + } + + if ( r != KErrNone ) + ret = r; + + return ret; + } + +TInt CTestStepFlogger::executeStep(CTestStepFlogger& aTestStep, TBool aStatus) + { + TInt result=KErrNone; + TRAPD(err,result=aTestStep.executeStepL(aStatus)); + return (KErrNone!=err)?err:result; + } + +// +//This heap failure member function is used to ensure correct operation in low-memory +// situations. It requires the flogger server to be started in order to inform the server +// on each loop iteration as to the new memory requirement. Thus, this harness is no +// good for cases where the flogger server must be shut down and restarted or +// when server is not meant to be running before the test case commences. +// +TInt CTestStepFlogger::doTestStepWithHeapFailureL( CTestStepFlogger& aTestStep, TInt lowMemory, TInt highMemory, TInt aReturnValue, TBool bypassChecks) +/** + @param bypassChecks allows a parameter to be passed to the executeStep to let it know that the + case is being used for heap checking. This is needed because most flogger methods do + not return an error code when they fail to write due to no memory. Thus, when running + the heap test the part of the test case which ensures the data was written to disk + may fail to find the data, and thus we need to bypass these checks. + @param aReturnValue - expected return value if everything works + @param lowMemory - amount of memory to start testing at - must be at least 10 lower than highMemory and test must fail due to low memory at this level + @param highMemory - amount of memory to stop testing at - if we reach this, test has failed. + */ + { + TInt ret=0; + TInt loop; + TPtrC8 ptrSubSystemTmp; + TPtrC8 ptrComponentTmp; + ptrSubSystemTmp.Set(_L8("SubSystem")); + ptrComponentTmp.Set(_L8("Component")); + + RFileLogger logger; + User::LeaveIfError(logger.Connect()); + CleanupClosePushL(logger); + logger.SetLogTags(KStdSubsysTag8, KStdCompTag8); + // clear the log so that any previous test data is gone and not detected + logger.ClearLog(); + User::After(KTimeToLog); + + for (loop = lowMemory; loop < highMemory ; loop++) + { + INFO_PRINTF2(_L("%d"),loop); + logger.__DbgSetHeapFailure(loop); + + ret = aTestStep.executeStep(bypassChecks); + + if ( ret == KErrNoMemory) + { + //The heap failure has been trapped correctly + continue; + } + else if (( ret == aReturnValue ) && (loop != lowMemory)) + { + //Test step normal behaviour + INFO_PRINTF4(_L("%S PASSED heap failure test, loop = %d return code==%d"), + &aTestStep.TestStepName(), loop, ret ); + SetTestStepResult(EPass); break; + } + else + { + // test step has not returned the exepected error value ( which was either KErrNoMemory or aReturnValue ) + INFO_PRINTF5(_L("%S *FAILED* heap failure test, loop=%d return code:%d expected:%d"), + &aTestStep.TestStepName(), loop, ret, aReturnValue ); + SetTestStepResult(EFail); break; + } + + } + // shutdown flogger server so we can see if any memory leaks - flogger svr will panic if there are + // This also means the next test does not get any residuals in the log buffers. + logger.ClearLog(); + logger.__DbgShutDownServer(); + CleanupStack::PopAndDestroy(); //logger + if (loop == highMemory) + { + // often the return code isn't checked, so make sure the test harness sees that it failed. + SetTestStepResult(EFail); return KErrGeneral; + } + if ( ret != aReturnValue ) + { + // often the return code isn't checked, so make sure the test harness sees that it failed. + SetTestStepResult(EFail); return KErrGeneral; + } + return KErrNone; + } + + + + + +TInt CTestStepFlogger::DoTestConnect(RFileLogger& aLogger) + { + TInt ret = KErrNone; + TPtrC8 ptrSubSystem; + TPtrC8 ptrComponent; + ptrSubSystem.Set(_L8("SubSystem")); + ptrComponent.Set(_L8("Component")); + + ret = aLogger.Connect(); + if (ret == KErrNone) + ret = aLogger.SetLogTags(ptrSubSystem, ptrComponent); //SetLogTags() of Flogger called + + if (ret == KErrNone) + ret = aLogger.ClearLog(); //clear the contents from the log + + return ret; + } + + +TInt CTestStepFlogger::constructFloggerIniL( const TDesC8& additionalConfig ) +/** +Replace the flogger.ini with a new one made up of the contents of ts_flogger.ini and additionalConfig. +@param additionalConfig string with the extra config items to be set in flogger.ini +@return KErrNone if no probs, otherwise an error code. +@note This function deletes then recreates the flogger.ini file, so during the short time between + the delete and the recreate, if flogger server is running, it will report that there were errors in the ini file (because + the ini file is not there). + */ + { + RFile theFile; + RFile outFile; + RFs fileServer; + User::LeaveIfError(fileServer.Connect()); + HBufC8 * fileContentsHeap; + TInt fileSize; + TInt returnCode; + + returnCode = theFile.Open(fileServer,KFloggerTestIniMediaSourceFile,EFileRead); + + if (returnCode == KErrNone) + { + theFile.Size(fileSize); + + // allocate the heap space for the string given size of ts_flogger and + // the length of the additional items string. + TInt newFileSize = fileSize + additionalConfig.Length(); //just so we can see this during debugging + + fileContentsHeap = HBufC8::NewLC(newFileSize); + + TPtr8 fileContentsAppend(fileContentsHeap->Des()); + + // read into the buffer the contents of ts_flogger.ini + User::LeaveIfError(returnCode = theFile.Read(fileContentsAppend)); + + // append addition items + fileContentsAppend.Append(additionalConfig); + + // We must assume the flogger.ini is either there or not there, + // If the flogger.ini is already there, and the flogger server is already running + // and watching this file, we cannot do any of the following: + //* Open and overwrite - if we overwrite a large file with a smaller one, it fails to overwrite the whole file + //* Delete and create - after the delete but before the create flogger server will attempt to access + //* use RFile::Replace - between the replace and the write flogger server will attempt access + + // so we must create a temporary file and then use the file system to overwrite the + // current with our temp using "replace" which is an atomic operation as far as flogger server is concerned + + returnCode = outFile.Create(fileServer,KTempDuringCreationFloggerIniFile,EFileWrite); + if (returnCode == KErrNone) + { + TInt pos = 0; + outFile.Seek(ESeekStart,pos); + outFile.Write(fileContentsAppend); + + outFile.Close(); + + fileServer.Replace(KTempDuringCreationFloggerIniFile,KFloggerIniFile); + } + CleanupStack::PopAndDestroy(fileContentsHeap); + theFile.Close(); + } + + fileServer.Close(); + + if (returnCode != KErrNone) + { + return returnCode; + } + else + { + return KErrNone; + } + + } + +TInt CTestStepFlogger::replaceFloggerIniL( const TDesC8& newConfig ) +/** +Replace the flogger.ini with a new one made up of the contents of newConfig +@param newConfig string with all the config items to be set in flogger.ini +@return KErrNone if no probs, otherwise an error code. + */ + { + RFile outFile; + RFs fileServer; + User::LeaveIfError(fileServer.Connect()); + HBufC8 * fileContentsHeap; + TInt returnCode; + + // allocate the heap space for the string given size of + // the items string. + TInt newFileSize = newConfig.Length(); //just so we can see this during debugging + + fileContentsHeap = HBufC8::NewLC(newFileSize); + + TPtr8 newFileContents(fileContentsHeap->Des()); + + // add the config items + newFileContents.Append(newConfig); + + // We must assume the flogger.ini is either there or not there, + // If the flogger.ini is already there, and the flogger server is already running + // and watching this file, we cannot do any of the following: + //* Open and overwrite - if we overwrite a large file with a smaller one, it fails to overwrite the whole file + //* Delete and create - after the delete but before the create flogger server will attempt to access + //* use RFile::Replace - between the replace and the write flogger server will attempt access + + // so we must create a temporary file and then use the file system to overwrite the + // current with our temp using "replace" which is an atomic operation as far as flogger server is concerned + + returnCode = outFile.Create(fileServer,KTempDuringCreationFloggerIniFile,EFileWrite); + if (returnCode == KErrNone) + { + TInt pos = 0; + outFile.Seek(ESeekStart,pos); + outFile.Write(newFileContents); + + outFile.Close(); + + fileServer.Replace(KTempDuringCreationFloggerIniFile,KFloggerIniFile); + } + CleanupStack::PopAndDestroy(fileContentsHeap); + + fileServer.Close(); + + if (returnCode != KErrNone) + { + return returnCode; + } + else + { + return KErrNone; + } + + } + + +/** +* Function Name : ForceLogFlush +* Input parameters : None +* Output parameters : RFileLogger +* Description : This function writes enough data to flogger to force it to flush its + file buffer. We need to do this for heap tests since the timer is disabled during heap tests. + Normally, the timer would ensure the buffer is flushed each second. + We must write enough data to match the KHeapBufSize (50K) constant in flogger. + However, it is usually necessary to wait one second after writing this data to ensure flogger + gets a chance to move the data from its queue to the buffer. + When determining how much to write, we take into account that flogger will have added the + component, subsystem and a few other characters to each line. + +* +*/ + + +void CTestStepFlogger::ForceLogFlush(RFileLogger& aLogger) + { + const TInt KLineLen = KLogBufferSize - KMarginTemplateSize; + TBuf8 buf; + buf.SetLength(KLineLen); + + for(TUint8 i = 0; i < KLineLen; i++) + { + buf[i] = i; + } + for(TInt j = 0; j < KHeapBufFillIterations; j++) + { + aLogger.Write(buf); + } + }