traceservices/commsdebugutility/TE_commsdebugutility/src/teststepcomsdbg.cpp
changeset 0 08ec8eefde2f
--- /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 <e32base.h>
+#include <commdb.h>
+#include <f32file.h>
+// Test system includes
+#include "teststepcomsdbg.h"
+#include <comms-infras/commsdebugutility.h>
+#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<KLineLen> buf;
+	buf.SetLength(KLineLen);
+	
+	for(TUint8 i = 0; i < KLineLen; i++)
+		{
+		buf[i] = i;
+		}
+	for(TInt j = 0; j < KHeapBufFillIterations; j++)
+		{
+		aLogger.Write(buf);
+		}
+	}