traceservices/tracefw/integ_test/ost/TEF/te_ostv2integsuite_performance/src/te_perfcsvgenerator.cpp
changeset 0 08ec8eefde2f
child 23 26645d81f48d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/traceservices/tracefw/integ_test/ost/TEF/te_ostv2integsuite_performance/src/te_perfcsvgenerator.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,477 @@
+// 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 "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:
+// UTrace Performance Tests CSV output generator.
+//
+
+
+
+/**
+ @file te_perfcsvgenerator.cpp
+ @internalTechnology
+ @prototype
+*/
+
+#include "te_perfcsvgenerator.h"
+#include "te_ostv2integsuite_defs.h"
+#include "te_perfapinames.h"
+
+
+//Punctuation symbols required for generating csv files.
+
+
+CUptCsvGenerator::CUptCsvGenerator()
+	{
+	/*Constructor*/
+	}
+
+CUptCsvGenerator::~CUptCsvGenerator()
+	{
+	/*Destructor*/
+	}
+
+/** This user-side method uses the RFs and RFile Session methods to open a file specified by the user, 
+if the file already exists, it will be appended or overwritten as per the user's specification.
+The file information is stored in the private data member iCSVFile.
+@param aFileName the constant descriptor containing the filepath as specified by the user.
+@param aAppend is the TBool controlling whether files should be appended to or overwritten
+				ETrue=Append, EFalse=Overwrite
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */
+TInt CUptCsvGenerator::Open(const TDesC& aFileName, const TBool& aAppend)
+	{
+
+	iCsvFileSession.Connect();
+	//if the user has set for the file to be overwritten if it already exists
+	//then this part with ensure this is carried out with write permissions
+	if(aAppend==EFalse)
+		{
+		User::LeaveIfError(iCsvFile.Replace(iCsvFileSession, aFileName, EFileWrite));	
+		}
+	//otherwise, the file is opened and appended to if it already exists
+	//and if it doesnt exist, the file is created with write perimission with the user defined filename.
+	else
+		if(iCsvFile.Open(iCsvFileSession, aFileName ,EFileWrite)!=KErrNone)
+			{
+			User::LeaveIfError(iCsvFile.Create(iCsvFileSession, aFileName, EFileWrite));			
+			}
+			
+	//NB!!!! may need to put in check if file is already open if this is going to be run on emulator 
+	//(not that that matters for performance tests). Not an issue on device.
+	return KErrNone;
+
+	}
+
+/** This user-side method uses the RFs and RFile Session methods to close the file specified by the user in the OpenL()
+method above and described by the private data member iCSVFile.
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */
+TInt CUptCsvGenerator::Close()
+	{
+	//close the csv file
+	iCsvFile.Close();
+	iCsvFileSession.Close();	
+	
+	return KErrNone;
+	}
+	
+/** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile and 
+appends a newline character.
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */
+TInt CUptCsvGenerator::WriteNewLine() 
+	{
+	TInt filesize;
+	
+	// find end of this file, and append the newline data field from here.
+	iCsvFile.Size(filesize);
+	iCsvFile.Seek(ESeekStart, filesize);
+	User::LeaveIfError(iCsvFile.Write(KCsvNewLine));
+	
+	return KErrNone;				
+	}
+
+/** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile.
+It then appends performance data metrics by element from the passed array, with each element separated by a comma character.
+@param aPerformanceData is the constant array of performance data stored as TInt32
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */
+void CUptCsvGenerator::WriteL(const RArray<TInt64>& aPerformanceData)
+	{
+	
+	// find end of this file, and append the passed data from here.
+	TInt filesize;
+	iCsvFile.Size(filesize);
+	iCsvFile.Seek(ESeekStart, filesize);
+	
+	RBuf8 buf; 
+	CleanupClosePushL(buf);
+	//create a buf large enough to contain the passed data and comma separators
+	TInt numbytes = 2*aPerformanceData.Count()*sizeof(TInt64);
+	buf.CreateL(numbytes);
+	
+	//for the number of elements in the passed array:- append each element, separated by a comma, to the buffer
+	for(TInt i=0; i!=aPerformanceData.Count(); i++) //could replace aPerformance.Count() with structure paramter Parameter.Count
+		{
+		buf.AppendNum(aPerformanceData[i]);
+		//may reimplement this
+		if(i!=aPerformanceData.Count()) 
+			buf.Append(KCsvComma);  
+
+		}
+	
+	//write the buffer to the given file	
+	User::LeaveIfError(iCsvFile.Write(buf));
+	
+	//close and cleanup the heap objects
+	buf.Close();
+	CleanupStack::PopAndDestroy(&buf);
+
+	}
+
+/** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile.
+It then appends performance data metrics by element from the passed array, with each element separated by a comma character.
+@param aPerformanceData is the constant array of performance data stored as TDesC
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */
+void CUptCsvGenerator::WriteL(const RArray<TPtrC8>& aPerformanceConfig)
+	{
+	// find end of this file, and append the passed data from here.
+	TInt filesize;
+	iCsvFile.Size(filesize);
+	iCsvFile.Seek(ESeekStart, filesize);
+	
+	RBuf8 buf; 
+	CleanupClosePushL(buf);
+	//create a buf large enough to contain the passed data and comma separators
+	TInt numbytes = 5*aPerformanceConfig.Count()*sizeof(TPtrC8);
+	buf.CreateL(numbytes);
+		
+	//for the number of elements in the passed array:- append each element, separated by a comma, to the buffer
+	for(TInt i=0; i!=aPerformanceConfig.Count(); i++) //could replace aPerformance.Count() with structure paramter Parameter.Count
+		{
+		buf.Append(aPerformanceConfig[i]);
+		//may reimplement this
+		if(i!=aPerformanceConfig.Count()) 	
+			buf.Append(KCsvComma);  
+
+		}
+	//write the buffer to the given file	
+	User::LeaveIfError(iCsvFile.Write(buf));
+	
+	
+	//close and cleanup the heap objects
+	buf.Close();
+	CleanupStack::PopAndDestroy(&buf);
+
+	}
+
+
+void CUptCsvGenerator::WriteApiNameL(const TInt aApiEnum)
+	{
+	// find end of this file, and append the passed data from here.
+	TInt filesize;
+	iCsvFile.Size(filesize);
+	iCsvFile.Seek(ESeekStart, filesize);
+		
+	RBuf8 buf; 
+	CleanupClosePushL(buf);
+	//create a buf large enough to contain the passed data and comma separators
+	TInt numbytes = 1024;//2*sizeof(TPtrC8);
+	buf.CreateL(numbytes);
+		
+	//read the APIenum (which is the same as the first element of aPerformanceData)
+	//use this enum value to write the name of the API being tested
+	TApiNames getApiName;
+	buf.Append(getApiName.GetApiIdString(aApiEnum));
+	buf.Append(KCsvComma); 
+	
+	//write the buffer to the given file	
+	User::LeaveIfError(iCsvFile.Write(buf));
+		
+		
+	//close and cleanup the heap objects
+	buf.Close();
+	CleanupStack::PopAndDestroy(&buf);
+		
+	}
+
+/** This user-side method writes the column titles (from the KLit string defined in the relevent test.cpp
+    to the user-specified csv file, according to the parameters for aTestType.
+@param aTestType is the enum identifier for the test in question
+@return KErrNone if command was prepared correctly and a system wide error code otherwise.
+ */	
+TInt CUptCsvGenerator::WriteHeader(const TInt& aTestType)
+	{
+	RBuf8 buf; 
+	CleanupClosePushL(buf);
+	
+	TInt numbytes = 0;
+
+	//test which testtype is to be written and
+	//append the header string to the buffer and write it to the csv file
+	//create general KGeneralHeader? 
+	//first identify which test
+	switch(aTestType)
+	{
+	case 0:
+		//KGeneralHeader=KApiCallHeader;
+		//now create a buf large enough to contain the passed data and comma separators
+		numbytes = sizeof(KApiCallHeader); 
+		buf.CreateL(numbytes);
+	
+		//append the relevant header to the file
+		buf.Append(KApiCallHeader);
+	break;
+	case 1:
+	//now create a buf large enough to contain the passed data and comma separators
+		numbytes = sizeof(KOutputPluginHeader); 
+		buf.CreateL(numbytes);
+
+		//append the relevant header to the file
+		buf.Append(KOutputPluginHeader);
+	break;
+	case 2:
+	//now create a buf large enough to contain the passed data and comma separators
+		numbytes = sizeof(KOutputPluginHeader); 
+		buf.CreateL(numbytes);
+
+		//append the relevant header to the file
+		buf.Append(KOutputPluginHeader);
+	break;
+	//case 3://to be implemented on next iteration
+	//break;
+	//case 4://to be implemented on next iteration
+	//break;
+	default:
+		// NB: change this to an empty string
+		//now create a buf large enough to contain the passed data and comma separators
+		numbytes = sizeof(KApiCallHeader); 
+		buf.CreateL(numbytes);
+
+		//append the relevant header to the file
+		buf.Append(KApiCallHeader);
+	break;
+	
+	}
+	
+	//now create a buf large enough to contain the passed data and comma separators
+	//numbytes = sizeof(KGeneralHeader); 
+	//buf.CreateL(numbytes);
+	
+	//append the relevant header to the file
+	//buf.Append(KGeneralHeader);		
+
+	
+	//append a newline to the buffer in preparation for the data
+	buf.Append(KCsvNewLine);
+	TInt startpos = 0;
+	//go to the start of the file and write the buffer 
+	iCsvFile.Seek(ESeekStart, startpos); //nb: put in check incase this overwrites data when appending to a file??
+	User::LeaveIfError(iCsvFile.Write(buf));
+
+	//close and cleanup the heap objects
+	buf.Close();
+	CleanupStack::PopAndDestroy(&buf);
+	
+	return KErrNone;
+	}
+
+/** This sanity test method is executed at the start of the test run to verify that UPT methods in
+this class are stable before any of the performance tests are carried out
+
+// what tests does it do?
+ 
+@return KErrNone if command was prepared correctly and system wide error code otherwise.
+ */
+TInt CUptCsvGenerator::Test()
+	{
+	//define filepaths for the test csv files according to the test platform.
+#ifdef __WINSCW__
+	_LIT(KTestFileAppend, "c:\\te_CSVoutputfileAppend.csv");
+	_LIT(KTestFileOverwrite, "c:\\te_CSVoutputfileOverwrite.csv");
+#else
+	_LIT(KTestFileAppend, "e:\\te_CSVoutputfileAppend.csv");
+	_LIT(KTestFileOverwrite, "e:\\te_CSVoutputfileOverwrite.csv");
+#endif	
+
+	//initialise some generic data to write to csv
+	RArray<TInt64> atestdata1;
+	RArray<TInt64> atestdata2;
+	CleanupClosePushL(atestdata1); 
+	CleanupClosePushL(atestdata2); 
+		
+	//data of the form:
+	//0	1	2	3	4	5	6	7	8	9
+	TInt data1element=10;
+	for(TInt i=0; i!=data1element;i++)
+		{
+		atestdata1.Append((TInt64) i);
+		}		
+	//data of the form:
+	//0	1000	2000	3000	4000	5000	6000	7000	8000	9000	10000	11000
+	TInt data2element=12;
+	for(TInt i=0; i!=data2element;i++)
+		{
+		atestdata2.Append((TInt64) i*1000);
+		}
+	
+	
+	//now test the CSV Generator functions
+	//test the append data option - outputfile should contain an extra 6 lines of data of the form:
+	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
+	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
+	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
+	TInt appendcount=3;
+	for(TInt i=0; i!=appendcount;i++)
+		{ 
+		Open(KTestFileAppend, ETrue);
+		WriteL(atestdata1);
+		WriteNewLine();
+		WriteL(atestdata2);
+		WriteNewLine();
+		Close();	
+		}
+
+		
+	//test the overwrite data option - outputfile should contain only 2 lines of data of the form:
+	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
+	for(TInt i=0; i!=appendcount;i++)
+		{
+		Open(KTestFileOverwrite, EFalse);
+		WriteL(atestdata1);
+		WriteNewLine();
+		WriteL(atestdata2);
+		WriteNewLine();
+		Close();	
+		}
+
+	// read the files back to check they are valid, as an automated check
+	
+	RFs fsSession;
+	RFile appendfile;
+	RFile overwritefile;
+	TInt filesize;
+	User::LeaveIfError(fsSession.Connect());
+	
+	//sizes in bytes of generated output csv data
+	TInt appendsize=appendcount*(sizeof(atestdata1)+sizeof(atestdata2)+2*sizeof(KCsvNewLine)+(data1element+data2element)*sizeof(KCsvComma));
+	TInt overwritesize=(sizeof(atestdata1)+sizeof(atestdata2)+2*sizeof(KCsvNewLine)+(data1element+data2element)*sizeof(KCsvComma));
+	
+	// fill buffers used for data read from the outputted file
+	RBuf8 readappendfile;
+	readappendfile.CreateL(appendsize);
+	RBuf8 readoverwritefile;
+	readoverwritefile.CreateL(overwritesize);
+	CleanupClosePushL(readappendfile); 
+	CleanupClosePushL(readoverwritefile); 
+
+	// comparison data buffers used to contain the expected data
+	RBuf8 acompareappend;
+	acompareappend.CreateL(appendsize);	
+	RBuf8 acompareoverwrite;
+	acompareoverwrite.CreateL(overwritesize);
+	CleanupClosePushL(acompareappend); 
+	CleanupClosePushL(acompareoverwrite); 
+		
+	//fill comparison array for appended data
+	TInt err=FillReferenceBuffer(acompareappend, appendcount, atestdata1, data1element, atestdata2, data2element);
+
+	//first check the appended file by reading back the last 6 lines in the file and comparing with acompareappend
+	if(err==KErrNone)
+		{
+		if(appendfile.Open(fsSession, KTestFileAppend, EFileRead))
+			{
+			if(appendfile.Size(filesize))	
+				{
+				if(appendfile.Read((filesize-sizeof(acompareappend)),readappendfile))
+					{
+					if(!readappendfile.Compare(acompareappend))
+						err=KErrGeneral;
+					}
+				}
+			}
+		}
+	// close test output csv file
+	appendfile.Close();
+	
+	
+	//given the above has passed,
+	//fill comparison array for overwritten data			
+	if(err==KErrNone)
+		err=FillReferenceBuffer(acompareoverwrite, (TInt) 0, atestdata1, data1element, atestdata2, data2element);
+	
+	//check the overwritten file by reading back the only 2 lines in the file and comparing with acompareoverwrite
+	//Note: as a thorough check- read from a zero offset
+	if(err==KErrNone)
+		{
+		if(overwritefile.Open(fsSession, KTestFileOverwrite, EFileRead))
+			{
+			if(overwritefile.Size(filesize))	
+				{
+				if(overwritefile.Read(0,readoverwritefile))
+					{
+					if(!readoverwritefile.Compare(acompareoverwrite))
+						err=KErrGeneral;
+					}
+				}
+			}
+		}
+	// close test output csv file
+	overwritefile.Close();
+	CleanupStack::PopAndDestroy(&atestdata1); 
+	CleanupStack::PopAndDestroy(&atestdata2); 
+	CleanupStack::PopAndDestroy(&readappendfile); 
+	CleanupStack::PopAndDestroy(&readoverwritefile); 
+	CleanupStack::PopAndDestroy(&acompareappend); 
+	CleanupStack::PopAndDestroy(&acompareoverwrite); 
+	return err;
+	}
+	
+	
+TInt CUptCsvGenerator::FillReferenceBuffer(RBuf8& aBufferName, const TInt& aAppendCount, const RArray<TInt64>& aData1Name, const TInt& aData1Count, const RArray<TInt64>& aData2Name, const TInt& aData2Count)
+	{
+	for(TInt i=0; i!=aAppendCount;i++)
+		{
+		// first line of data
+		for(TInt j=0;j!=aData1Count;j++)
+			{
+			aBufferName.AppendNum(aData1Name[j]);
+			//if(j!=aData1Count-1)
+			if(j!=aData1Count)
+				aBufferName.Append(KCsvComma);
+			}	
+			
+		// newline
+		aBufferName.Append(KCsvNewLine);
+		
+		// second line of data with a potentially different number of elements
+		for(TInt j=0;j!=aData2Count;j++)
+			{
+			aBufferName.AppendNum(aData2Name[j]);
+			//if(j!=aData2Count-1)
+			if(j!=aData2Count)
+				aBufferName.Append(KCsvComma);
+			}	
+		aBufferName.Append(KCsvNewLine);	
+		}
+	return 0;
+	}
+
+// eof
+
+