os/persistentdata/traceservices/commsdebugutility/TE_commsdebugutility/src/teststepcomsdbg.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // This contains CTestCase which is the base class for all the TestCase DLLs
    15 //just to test p4
    16 
    17 // EPOC includes
    18 #include <e32base.h>
    19 #include <commdb.h>
    20 #include <f32file.h>
    21 // Test system includes
    22 #include "teststepcomsdbg.h"
    23 #include <comms-infras/commsdebugutility.h>
    24 #include "TestMessage.h"
    25 
    26 
    27 // constructor
    28 CTestStepFlogger::CTestStepFlogger() 
    29 	{
    30 	}
    31 
    32 // destructor
    33 CTestStepFlogger::~CTestStepFlogger()
    34 	{
    35 	}
    36 
    37 
    38 TVerdict CTestStepFlogger::doTestStepPostambleL()
    39 	{
    40         SetTestStepResult(EPass);	return TestStepResult();
    41 	}
    42 
    43 	
    44 TInt CTestStepFlogger::executeStepL()
    45 	{
    46 		return KErrGeneral;
    47 	}
    48 
    49 TInt CTestStepFlogger::executeStepL( /*aLogger*/ TBool /*aStatus*/)
    50 	{
    51 		return KErrGeneral;
    52 	}
    53 
    54 
    55 TInt CTestStepFlogger::executeStep(CTestStepFlogger& aTestStep)
    56 	{
    57 	TInt r = 0;
    58 	TInt ret= 0;
    59 
    60 	TRAP( r, ret = aTestStep.executeStepL() );
    61 
    62 	if ( r != KErrNone )
    63 		ret = r;
    64 
    65 	return ret;
    66 	}
    67 
    68 TInt CTestStepFlogger::executeStep( TBool bypassChecks )
    69 	{
    70 	TInt ret=0;
    71 	TInt r;
    72 
    73 	// bypassChecks is optional, so many clients don't know to supply it
    74 	if (bypassChecks)
    75 		{
    76 		TRAP( r, ret = executeStepL(bypassChecks) );
    77 		}
    78 	else
    79 		{
    80 		TRAP( r, ret = executeStepL() );
    81 		}
    82 
    83 	if ( r != KErrNone )
    84 		ret = r;
    85 
    86 	return ret;
    87 	}
    88 
    89 TInt CTestStepFlogger::executeStep(CTestStepFlogger& aTestStep, TBool aStatus)
    90 	{
    91 	TInt result=KErrNone;
    92 	TRAPD(err,result=aTestStep.executeStepL(aStatus));
    93 	return (KErrNone!=err)?err:result;
    94 	}
    95 
    96 //
    97 //This heap failure member function is used to ensure correct operation in low-memory
    98 // situations. It requires the flogger server to be started in order to inform the server
    99 // on each loop iteration as to the new memory requirement. Thus, this harness is no
   100 // good for cases where the flogger server must be shut down and restarted or
   101 // when server is not meant to be running before the test case commences.
   102 //
   103 TInt CTestStepFlogger::doTestStepWithHeapFailureL( CTestStepFlogger& aTestStep, TInt lowMemory, TInt highMemory, TInt aReturnValue, TBool bypassChecks)
   104 /**
   105  @param bypassChecks allows a parameter to be passed to the executeStep to let it know that the
   106  case is being used for heap checking. This is needed because most flogger methods do
   107  not return an error code when they fail to write due to no memory. Thus, when running
   108  the heap test the part of the test case which ensures the data was written to disk
   109  may fail to find the data, and thus we need to bypass these checks.
   110  @param aReturnValue - expected return value if everything works
   111  @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
   112  @param highMemory - amount of memory to stop testing at - if we reach this, test has failed.
   113  */
   114 	{
   115 	TInt ret=0;
   116 	TInt loop;
   117 	TPtrC8 ptrSubSystemTmp;
   118 	TPtrC8 ptrComponentTmp;
   119 	ptrSubSystemTmp.Set(_L8("SubSystem"));
   120 	ptrComponentTmp.Set(_L8("Component"));
   121 
   122 	RFileLogger logger;
   123 	User::LeaveIfError(logger.Connect());
   124 	CleanupClosePushL(logger);
   125 	logger.SetLogTags(KStdSubsysTag8, KStdCompTag8);
   126 	// clear the log so that any previous test data is gone and not detected
   127 	logger.ClearLog();
   128 	User::After(KTimeToLog);
   129 
   130 	for (loop = lowMemory; loop < highMemory ; loop++)
   131 		{
   132 		INFO_PRINTF2(_L("%d"),loop);
   133 		logger.__DbgSetHeapFailure(loop);
   134 
   135 		ret = aTestStep.executeStep(bypassChecks);
   136 
   137 		if ( ret == KErrNoMemory)
   138 			{
   139 			//The heap failure has been trapped correctly
   140 			continue;
   141 			}
   142 		else if (( ret == aReturnValue ) && (loop != lowMemory))
   143 			{
   144 			//Test step normal behaviour
   145 			INFO_PRINTF4(_L("%S PASSED heap failure test, loop = %d return code==%d"), 
   146 			&aTestStep.TestStepName(), loop, ret );
   147 			SetTestStepResult(EPass);			break;
   148 			}
   149 		else
   150 			{
   151 			// test step has not returned the exepected error value ( which was either KErrNoMemory or aReturnValue )
   152 			INFO_PRINTF5(_L("%S *FAILED* heap failure test, loop=%d return code:%d expected:%d"), 
   153 				&aTestStep.TestStepName(), loop, ret, aReturnValue );
   154 			SetTestStepResult(EFail);			break;
   155 			}
   156 
   157 		}
   158 	// shutdown flogger server so we can see if any memory leaks - flogger svr will panic if there are
   159 	// This also means the next test does not get any residuals in the log buffers.
   160 	logger.ClearLog();
   161 	logger.__DbgShutDownServer();
   162 	CleanupStack::PopAndDestroy();	//logger
   163 	if (loop == highMemory)
   164 		{
   165 		// often the return code isn't checked, so make sure the test harness sees that it failed.
   166 		SetTestStepResult(EFail);		return KErrGeneral;
   167 		}
   168 	if ( ret != aReturnValue )
   169 		{
   170 		// often the return code isn't checked, so make sure the test harness sees that it failed.
   171 		SetTestStepResult(EFail);		return KErrGeneral;
   172 		}
   173 	return KErrNone;
   174 	}
   175 
   176 
   177 
   178 
   179 
   180 TInt CTestStepFlogger::DoTestConnect(RFileLogger& aLogger)
   181 	{
   182 	TInt ret = KErrNone;
   183 	TPtrC8 ptrSubSystem;
   184 	TPtrC8  ptrComponent;
   185 	ptrSubSystem.Set(_L8("SubSystem"));
   186 	ptrComponent.Set(_L8("Component"));
   187 
   188 	ret = aLogger.Connect();
   189 	if (ret == KErrNone)
   190 		ret = aLogger.SetLogTags(ptrSubSystem, ptrComponent); //SetLogTags() of Flogger called
   191 
   192 	if (ret == KErrNone)
   193 		ret = aLogger.ClearLog(); //clear the contents from the log
   194 	
   195 	return ret;
   196 	}
   197 
   198 
   199 TInt CTestStepFlogger::constructFloggerIniL( const TDesC8& additionalConfig )
   200 /**
   201 Replace the flogger.ini with a new one made up of the contents of ts_flogger.ini and additionalConfig.
   202 @param additionalConfig string with the extra config items to be set in flogger.ini
   203 @return KErrNone if no probs, otherwise an error code.
   204 @note This function deletes then recreates the flogger.ini file, so during the short time between
   205  the delete and the recreate, if flogger server is running, it will report that there were errors in the ini file (because
   206  the ini file is not there).
   207  */
   208 	{
   209 	RFile theFile;
   210 	RFile outFile;
   211 	RFs fileServer; 
   212 	User::LeaveIfError(fileServer.Connect());
   213 	HBufC8 * fileContentsHeap;
   214 	TInt fileSize;
   215 	TInt returnCode;	
   216 
   217 	returnCode = theFile.Open(fileServer,KFloggerTestIniMediaSourceFile,EFileRead);
   218 	
   219 	if (returnCode == KErrNone)
   220 		{
   221 		theFile.Size(fileSize);
   222 		
   223 		// allocate the heap space for the string given size of ts_flogger and
   224 		// the length of the additional items string.
   225 		TInt newFileSize = fileSize + additionalConfig.Length();  //just so we can see this during debugging
   226 
   227 		fileContentsHeap = HBufC8::NewLC(newFileSize);
   228 
   229 		TPtr8 fileContentsAppend(fileContentsHeap->Des());
   230 		
   231 		// read into the buffer the contents of ts_flogger.ini
   232 		User::LeaveIfError(returnCode = theFile.Read(fileContentsAppend));
   233 		
   234 		// append addition items
   235 		fileContentsAppend.Append(additionalConfig);
   236 
   237 		// We must assume the flogger.ini is either there or not there,
   238 		// If the flogger.ini is already there, and the flogger server is already running
   239 		// and watching this file, we cannot do any of the following:
   240 		//* Open and overwrite - if we overwrite a large file with a smaller one, it fails to overwrite the whole file
   241 		//* Delete and create - after the delete but before the create flogger server will attempt to access
   242 		//* use RFile::Replace - between the replace and the write flogger server will attempt access
   243 		
   244 		// so we must create a temporary file and then use the file system to overwrite the
   245 		// current with our temp using "replace" which is an atomic operation as far as flogger server is concerned
   246 
   247 		returnCode = outFile.Create(fileServer,KTempDuringCreationFloggerIniFile,EFileWrite);
   248 		if (returnCode == KErrNone)
   249 			{
   250 			TInt pos = 0;
   251 			outFile.Seek(ESeekStart,pos);
   252 			outFile.Write(fileContentsAppend);
   253 			
   254 			outFile.Close();
   255 			
   256 			fileServer.Replace(KTempDuringCreationFloggerIniFile,KFloggerIniFile);
   257 			}
   258 		CleanupStack::PopAndDestroy(fileContentsHeap);
   259 		theFile.Close();
   260 		}
   261 	
   262 	fileServer.Close();
   263 
   264 	if (returnCode != KErrNone)
   265 		{
   266 		return returnCode;
   267 		}
   268 	else
   269 		{
   270 		return KErrNone;
   271 		}
   272 
   273 	}
   274 	
   275 TInt CTestStepFlogger::replaceFloggerIniL( const TDesC8& newConfig )
   276 /**
   277 Replace the flogger.ini with a new one made up of the contents of newConfig
   278 @param newConfig string with all the config items to be set in flogger.ini
   279 @return KErrNone if no probs, otherwise an error code.
   280  */
   281 	{
   282 	RFile outFile;
   283 	RFs fileServer; 
   284 	User::LeaveIfError(fileServer.Connect());
   285 	HBufC8 * fileContentsHeap;
   286 	TInt returnCode;	
   287 
   288 	// allocate the heap space for the string given size of 
   289 	// the items string.
   290 	TInt newFileSize = newConfig.Length();  //just so we can see this during debugging
   291 
   292 	fileContentsHeap = HBufC8::NewLC(newFileSize);
   293 
   294 	TPtr8 newFileContents(fileContentsHeap->Des());
   295 	
   296 	// add the config items
   297 	newFileContents.Append(newConfig);
   298 
   299 	// We must assume the flogger.ini is either there or not there,
   300 	// If the flogger.ini is already there, and the flogger server is already running
   301 	// and watching this file, we cannot do any of the following:
   302 	//* Open and overwrite - if we overwrite a large file with a smaller one, it fails to overwrite the whole file
   303 	//* Delete and create - after the delete but before the create flogger server will attempt to access
   304 	//* use RFile::Replace - between the replace and the write flogger server will attempt access
   305 	
   306 	// so we must create a temporary file and then use the file system to overwrite the
   307 	// current with our temp using "replace" which is an atomic operation as far as flogger server is concerned
   308 
   309 	returnCode = outFile.Create(fileServer,KTempDuringCreationFloggerIniFile,EFileWrite);
   310 	if (returnCode == KErrNone)
   311 		{
   312 		TInt pos = 0;
   313 		outFile.Seek(ESeekStart,pos);
   314 		outFile.Write(newFileContents);
   315 		
   316 		outFile.Close();
   317 		
   318 		fileServer.Replace(KTempDuringCreationFloggerIniFile,KFloggerIniFile);
   319 		}
   320 	CleanupStack::PopAndDestroy(fileContentsHeap);
   321 	
   322 	fileServer.Close();
   323 
   324 	if (returnCode != KErrNone)
   325 		{
   326 		return returnCode;
   327 		}
   328 	else
   329 		{
   330 		return KErrNone;
   331 		}
   332 
   333 	}
   334 
   335 
   336 /**
   337 * Function  Name		: ForceLogFlush
   338 * Input parameters		: None
   339 * Output parameters		: RFileLogger 
   340 * Description 			: This function writes enough data to flogger to force it to flush its
   341   file buffer. We need to do this for heap tests since the timer is disabled during heap tests. 
   342   Normally, the timer would ensure the buffer is flushed each second. 
   343   We must write enough data to match the KHeapBufSize (50K) constant in flogger.
   344   However, it is usually necessary to wait one second after writing this data to ensure flogger
   345   gets a chance to move the data from its queue to the buffer.
   346   When determining how much to write, we take into account that flogger will have added the
   347   component, subsystem and a few other characters to each line.
   348 
   349 * 						  
   350 */
   351 
   352 
   353 void CTestStepFlogger::ForceLogFlush(RFileLogger& aLogger)
   354 	{
   355 	const TInt KLineLen = KLogBufferSize - KMarginTemplateSize;
   356 	TBuf8<KLineLen> buf;
   357 	buf.SetLength(KLineLen);
   358 	
   359 	for(TUint8 i = 0; i < KLineLen; i++)
   360 		{
   361 		buf[i] = i;
   362 		}
   363 	for(TInt j = 0; j < KHeapBufFillIterations; j++)
   364 		{
   365 		aLogger.Write(buf);
   366 		}
   367 	}