traceservices/tracefw/integ_test/ost/TEF/te_ostv2integsuite_performance/src/te_perfcsvgenerator.cpp
changeset 0 08ec8eefde2f
child 23 26645d81f48d
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2007-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 // UTrace Performance Tests CSV output generator.
       
    15 //
       
    16 
       
    17 
       
    18 
       
    19 /**
       
    20  @file te_perfcsvgenerator.cpp
       
    21  @internalTechnology
       
    22  @prototype
       
    23 */
       
    24 
       
    25 #include "te_perfcsvgenerator.h"
       
    26 #include "te_ostv2integsuite_defs.h"
       
    27 #include "te_perfapinames.h"
       
    28 
       
    29 
       
    30 //Punctuation symbols required for generating csv files.
       
    31 
       
    32 
       
    33 CUptCsvGenerator::CUptCsvGenerator()
       
    34 	{
       
    35 	/*Constructor*/
       
    36 	}
       
    37 
       
    38 CUptCsvGenerator::~CUptCsvGenerator()
       
    39 	{
       
    40 	/*Destructor*/
       
    41 	}
       
    42 
       
    43 /** This user-side method uses the RFs and RFile Session methods to open a file specified by the user, 
       
    44 if the file already exists, it will be appended or overwritten as per the user's specification.
       
    45 The file information is stored in the private data member iCSVFile.
       
    46 @param aFileName the constant descriptor containing the filepath as specified by the user.
       
    47 @param aAppend is the TBool controlling whether files should be appended to or overwritten
       
    48 				ETrue=Append, EFalse=Overwrite
       
    49 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
    50  */
       
    51 TInt CUptCsvGenerator::Open(const TDesC& aFileName, const TBool& aAppend)
       
    52 	{
       
    53 
       
    54 	iCsvFileSession.Connect();
       
    55 	//if the user has set for the file to be overwritten if it already exists
       
    56 	//then this part with ensure this is carried out with write permissions
       
    57 	if(aAppend==EFalse)
       
    58 		{
       
    59 		User::LeaveIfError(iCsvFile.Replace(iCsvFileSession, aFileName, EFileWrite));	
       
    60 		}
       
    61 	//otherwise, the file is opened and appended to if it already exists
       
    62 	//and if it doesnt exist, the file is created with write perimission with the user defined filename.
       
    63 	else
       
    64 		if(iCsvFile.Open(iCsvFileSession, aFileName ,EFileWrite)!=KErrNone)
       
    65 			{
       
    66 			User::LeaveIfError(iCsvFile.Create(iCsvFileSession, aFileName, EFileWrite));			
       
    67 			}
       
    68 			
       
    69 	//NB!!!! may need to put in check if file is already open if this is going to be run on emulator 
       
    70 	//(not that that matters for performance tests). Not an issue on device.
       
    71 	return KErrNone;
       
    72 
       
    73 	}
       
    74 
       
    75 /** This user-side method uses the RFs and RFile Session methods to close the file specified by the user in the OpenL()
       
    76 method above and described by the private data member iCSVFile.
       
    77 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
    78  */
       
    79 TInt CUptCsvGenerator::Close()
       
    80 	{
       
    81 	//close the csv file
       
    82 	iCsvFile.Close();
       
    83 	iCsvFileSession.Close();	
       
    84 	
       
    85 	return KErrNone;
       
    86 	}
       
    87 	
       
    88 /** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile and 
       
    89 appends a newline character.
       
    90 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
    91  */
       
    92 TInt CUptCsvGenerator::WriteNewLine() 
       
    93 	{
       
    94 	TInt filesize;
       
    95 	
       
    96 	// find end of this file, and append the newline data field from here.
       
    97 	iCsvFile.Size(filesize);
       
    98 	iCsvFile.Seek(ESeekStart, filesize);
       
    99 	User::LeaveIfError(iCsvFile.Write(KCsvNewLine));
       
   100 	
       
   101 	return KErrNone;				
       
   102 	}
       
   103 
       
   104 /** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile.
       
   105 It then appends performance data metrics by element from the passed array, with each element separated by a comma character.
       
   106 @param aPerformanceData is the constant array of performance data stored as TInt32
       
   107 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
   108  */
       
   109 void CUptCsvGenerator::WriteL(const RArray<TInt64>& aPerformanceData)
       
   110 	{
       
   111 	
       
   112 	// find end of this file, and append the passed data from here.
       
   113 	TInt filesize;
       
   114 	iCsvFile.Size(filesize);
       
   115 	iCsvFile.Seek(ESeekStart, filesize);
       
   116 	
       
   117 	RBuf8 buf; 
       
   118 	CleanupClosePushL(buf);
       
   119 	//create a buf large enough to contain the passed data and comma separators
       
   120 	TInt numbytes = 2*aPerformanceData.Count()*sizeof(TInt64);
       
   121 	buf.CreateL(numbytes);
       
   122 	
       
   123 	//for the number of elements in the passed array:- append each element, separated by a comma, to the buffer
       
   124 	for(TInt i=0; i!=aPerformanceData.Count(); i++) //could replace aPerformance.Count() with structure paramter Parameter.Count
       
   125 		{
       
   126 		buf.AppendNum(aPerformanceData[i]);
       
   127 		//may reimplement this
       
   128 		if(i!=aPerformanceData.Count()) 
       
   129 			buf.Append(KCsvComma);  
       
   130 
       
   131 		}
       
   132 	
       
   133 	//write the buffer to the given file	
       
   134 	User::LeaveIfError(iCsvFile.Write(buf));
       
   135 	
       
   136 	//close and cleanup the heap objects
       
   137 	buf.Close();
       
   138 	CleanupStack::PopAndDestroy(&buf);
       
   139 
       
   140 	}
       
   141 
       
   142 /** This user-side method uses the RFile Session methods to find the end of the file described by iCSVFile.
       
   143 It then appends performance data metrics by element from the passed array, with each element separated by a comma character.
       
   144 @param aPerformanceData is the constant array of performance data stored as TDesC
       
   145 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
   146  */
       
   147 void CUptCsvGenerator::WriteL(const RArray<TPtrC8>& aPerformanceConfig)
       
   148 	{
       
   149 	// find end of this file, and append the passed data from here.
       
   150 	TInt filesize;
       
   151 	iCsvFile.Size(filesize);
       
   152 	iCsvFile.Seek(ESeekStart, filesize);
       
   153 	
       
   154 	RBuf8 buf; 
       
   155 	CleanupClosePushL(buf);
       
   156 	//create a buf large enough to contain the passed data and comma separators
       
   157 	TInt numbytes = 5*aPerformanceConfig.Count()*sizeof(TPtrC8);
       
   158 	buf.CreateL(numbytes);
       
   159 		
       
   160 	//for the number of elements in the passed array:- append each element, separated by a comma, to the buffer
       
   161 	for(TInt i=0; i!=aPerformanceConfig.Count(); i++) //could replace aPerformance.Count() with structure paramter Parameter.Count
       
   162 		{
       
   163 		buf.Append(aPerformanceConfig[i]);
       
   164 		//may reimplement this
       
   165 		if(i!=aPerformanceConfig.Count()) 	
       
   166 			buf.Append(KCsvComma);  
       
   167 
       
   168 		}
       
   169 	//write the buffer to the given file	
       
   170 	User::LeaveIfError(iCsvFile.Write(buf));
       
   171 	
       
   172 	
       
   173 	//close and cleanup the heap objects
       
   174 	buf.Close();
       
   175 	CleanupStack::PopAndDestroy(&buf);
       
   176 
       
   177 	}
       
   178 
       
   179 
       
   180 void CUptCsvGenerator::WriteApiNameL(const TInt aApiEnum)
       
   181 	{
       
   182 	// find end of this file, and append the passed data from here.
       
   183 	TInt filesize;
       
   184 	iCsvFile.Size(filesize);
       
   185 	iCsvFile.Seek(ESeekStart, filesize);
       
   186 		
       
   187 	RBuf8 buf; 
       
   188 	CleanupClosePushL(buf);
       
   189 	//create a buf large enough to contain the passed data and comma separators
       
   190 	TInt numbytes = 1024;//2*sizeof(TPtrC8);
       
   191 	buf.CreateL(numbytes);
       
   192 		
       
   193 	//read the APIenum (which is the same as the first element of aPerformanceData)
       
   194 	//use this enum value to write the name of the API being tested
       
   195 	TApiNames getApiName;
       
   196 	buf.Append(getApiName.GetApiIdString(aApiEnum));
       
   197 	buf.Append(KCsvComma); 
       
   198 	
       
   199 	//write the buffer to the given file	
       
   200 	User::LeaveIfError(iCsvFile.Write(buf));
       
   201 		
       
   202 		
       
   203 	//close and cleanup the heap objects
       
   204 	buf.Close();
       
   205 	CleanupStack::PopAndDestroy(&buf);
       
   206 		
       
   207 	}
       
   208 
       
   209 /** This user-side method writes the column titles (from the KLit string defined in the relevent test.cpp
       
   210     to the user-specified csv file, according to the parameters for aTestType.
       
   211 @param aTestType is the enum identifier for the test in question
       
   212 @return KErrNone if command was prepared correctly and a system wide error code otherwise.
       
   213  */	
       
   214 TInt CUptCsvGenerator::WriteHeader(const TInt& aTestType)
       
   215 	{
       
   216 	RBuf8 buf; 
       
   217 	CleanupClosePushL(buf);
       
   218 	
       
   219 	TInt numbytes = 0;
       
   220 
       
   221 	//test which testtype is to be written and
       
   222 	//append the header string to the buffer and write it to the csv file
       
   223 	//create general KGeneralHeader? 
       
   224 	//first identify which test
       
   225 	switch(aTestType)
       
   226 	{
       
   227 	case 0:
       
   228 		//KGeneralHeader=KApiCallHeader;
       
   229 		//now create a buf large enough to contain the passed data and comma separators
       
   230 		numbytes = sizeof(KApiCallHeader); 
       
   231 		buf.CreateL(numbytes);
       
   232 	
       
   233 		//append the relevant header to the file
       
   234 		buf.Append(KApiCallHeader);
       
   235 	break;
       
   236 	case 1:
       
   237 	//now create a buf large enough to contain the passed data and comma separators
       
   238 		numbytes = sizeof(KOutputPluginHeader); 
       
   239 		buf.CreateL(numbytes);
       
   240 
       
   241 		//append the relevant header to the file
       
   242 		buf.Append(KOutputPluginHeader);
       
   243 	break;
       
   244 	case 2:
       
   245 	//now create a buf large enough to contain the passed data and comma separators
       
   246 		numbytes = sizeof(KOutputPluginHeader); 
       
   247 		buf.CreateL(numbytes);
       
   248 
       
   249 		//append the relevant header to the file
       
   250 		buf.Append(KOutputPluginHeader);
       
   251 	break;
       
   252 	//case 3://to be implemented on next iteration
       
   253 	//break;
       
   254 	//case 4://to be implemented on next iteration
       
   255 	//break;
       
   256 	default:
       
   257 		// NB: change this to an empty string
       
   258 		//now create a buf large enough to contain the passed data and comma separators
       
   259 		numbytes = sizeof(KApiCallHeader); 
       
   260 		buf.CreateL(numbytes);
       
   261 
       
   262 		//append the relevant header to the file
       
   263 		buf.Append(KApiCallHeader);
       
   264 	break;
       
   265 	
       
   266 	}
       
   267 	
       
   268 	//now create a buf large enough to contain the passed data and comma separators
       
   269 	//numbytes = sizeof(KGeneralHeader); 
       
   270 	//buf.CreateL(numbytes);
       
   271 	
       
   272 	//append the relevant header to the file
       
   273 	//buf.Append(KGeneralHeader);		
       
   274 
       
   275 	
       
   276 	//append a newline to the buffer in preparation for the data
       
   277 	buf.Append(KCsvNewLine);
       
   278 	TInt startpos = 0;
       
   279 	//go to the start of the file and write the buffer 
       
   280 	iCsvFile.Seek(ESeekStart, startpos); //nb: put in check incase this overwrites data when appending to a file??
       
   281 	User::LeaveIfError(iCsvFile.Write(buf));
       
   282 
       
   283 	//close and cleanup the heap objects
       
   284 	buf.Close();
       
   285 	CleanupStack::PopAndDestroy(&buf);
       
   286 	
       
   287 	return KErrNone;
       
   288 	}
       
   289 
       
   290 /** This sanity test method is executed at the start of the test run to verify that UPT methods in
       
   291 this class are stable before any of the performance tests are carried out
       
   292 
       
   293 // what tests does it do?
       
   294  
       
   295 @return KErrNone if command was prepared correctly and system wide error code otherwise.
       
   296  */
       
   297 TInt CUptCsvGenerator::Test()
       
   298 	{
       
   299 	//define filepaths for the test csv files according to the test platform.
       
   300 #ifdef __WINSCW__
       
   301 	_LIT(KTestFileAppend, "c:\\te_CSVoutputfileAppend.csv");
       
   302 	_LIT(KTestFileOverwrite, "c:\\te_CSVoutputfileOverwrite.csv");
       
   303 #else
       
   304 	_LIT(KTestFileAppend, "e:\\te_CSVoutputfileAppend.csv");
       
   305 	_LIT(KTestFileOverwrite, "e:\\te_CSVoutputfileOverwrite.csv");
       
   306 #endif	
       
   307 
       
   308 	//initialise some generic data to write to csv
       
   309 	RArray<TInt64> atestdata1;
       
   310 	RArray<TInt64> atestdata2;
       
   311 	CleanupClosePushL(atestdata1); 
       
   312 	CleanupClosePushL(atestdata2); 
       
   313 		
       
   314 	//data of the form:
       
   315 	//0	1	2	3	4	5	6	7	8	9
       
   316 	TInt data1element=10;
       
   317 	for(TInt i=0; i!=data1element;i++)
       
   318 		{
       
   319 		atestdata1.Append((TInt64) i);
       
   320 		}		
       
   321 	//data of the form:
       
   322 	//0	1000	2000	3000	4000	5000	6000	7000	8000	9000	10000	11000
       
   323 	TInt data2element=12;
       
   324 	for(TInt i=0; i!=data2element;i++)
       
   325 		{
       
   326 		atestdata2.Append((TInt64) i*1000);
       
   327 		}
       
   328 	
       
   329 	
       
   330 	//now test the CSV Generator functions
       
   331 	//test the append data option - outputfile should contain an extra 6 lines of data of the form:
       
   332 	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
       
   333 	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
       
   334 	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
       
   335 	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
       
   336 	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
       
   337 	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
       
   338 	TInt appendcount=3;
       
   339 	for(TInt i=0; i!=appendcount;i++)
       
   340 		{ 
       
   341 		Open(KTestFileAppend, ETrue);
       
   342 		WriteL(atestdata1);
       
   343 		WriteNewLine();
       
   344 		WriteL(atestdata2);
       
   345 		WriteNewLine();
       
   346 		Close();	
       
   347 		}
       
   348 
       
   349 		
       
   350 	//test the overwrite data option - outputfile should contain only 2 lines of data of the form:
       
   351 	// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
       
   352 	// 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000
       
   353 	for(TInt i=0; i!=appendcount;i++)
       
   354 		{
       
   355 		Open(KTestFileOverwrite, EFalse);
       
   356 		WriteL(atestdata1);
       
   357 		WriteNewLine();
       
   358 		WriteL(atestdata2);
       
   359 		WriteNewLine();
       
   360 		Close();	
       
   361 		}
       
   362 
       
   363 	// read the files back to check they are valid, as an automated check
       
   364 	
       
   365 	RFs fsSession;
       
   366 	RFile appendfile;
       
   367 	RFile overwritefile;
       
   368 	TInt filesize;
       
   369 	User::LeaveIfError(fsSession.Connect());
       
   370 	
       
   371 	//sizes in bytes of generated output csv data
       
   372 	TInt appendsize=appendcount*(sizeof(atestdata1)+sizeof(atestdata2)+2*sizeof(KCsvNewLine)+(data1element+data2element)*sizeof(KCsvComma));
       
   373 	TInt overwritesize=(sizeof(atestdata1)+sizeof(atestdata2)+2*sizeof(KCsvNewLine)+(data1element+data2element)*sizeof(KCsvComma));
       
   374 	
       
   375 	// fill buffers used for data read from the outputted file
       
   376 	RBuf8 readappendfile;
       
   377 	readappendfile.CreateL(appendsize);
       
   378 	RBuf8 readoverwritefile;
       
   379 	readoverwritefile.CreateL(overwritesize);
       
   380 	CleanupClosePushL(readappendfile); 
       
   381 	CleanupClosePushL(readoverwritefile); 
       
   382 
       
   383 	// comparison data buffers used to contain the expected data
       
   384 	RBuf8 acompareappend;
       
   385 	acompareappend.CreateL(appendsize);	
       
   386 	RBuf8 acompareoverwrite;
       
   387 	acompareoverwrite.CreateL(overwritesize);
       
   388 	CleanupClosePushL(acompareappend); 
       
   389 	CleanupClosePushL(acompareoverwrite); 
       
   390 		
       
   391 	//fill comparison array for appended data
       
   392 	TInt err=FillReferenceBuffer(acompareappend, appendcount, atestdata1, data1element, atestdata2, data2element);
       
   393 
       
   394 	//first check the appended file by reading back the last 6 lines in the file and comparing with acompareappend
       
   395 	if(err==KErrNone)
       
   396 		{
       
   397 		if(appendfile.Open(fsSession, KTestFileAppend, EFileRead))
       
   398 			{
       
   399 			if(appendfile.Size(filesize))	
       
   400 				{
       
   401 				if(appendfile.Read((filesize-sizeof(acompareappend)),readappendfile))
       
   402 					{
       
   403 					if(!readappendfile.Compare(acompareappend))
       
   404 						err=KErrGeneral;
       
   405 					}
       
   406 				}
       
   407 			}
       
   408 		}
       
   409 	// close test output csv file
       
   410 	appendfile.Close();
       
   411 	
       
   412 	
       
   413 	//given the above has passed,
       
   414 	//fill comparison array for overwritten data			
       
   415 	if(err==KErrNone)
       
   416 		err=FillReferenceBuffer(acompareoverwrite, (TInt) 0, atestdata1, data1element, atestdata2, data2element);
       
   417 	
       
   418 	//check the overwritten file by reading back the only 2 lines in the file and comparing with acompareoverwrite
       
   419 	//Note: as a thorough check- read from a zero offset
       
   420 	if(err==KErrNone)
       
   421 		{
       
   422 		if(overwritefile.Open(fsSession, KTestFileOverwrite, EFileRead))
       
   423 			{
       
   424 			if(overwritefile.Size(filesize))	
       
   425 				{
       
   426 				if(overwritefile.Read(0,readoverwritefile))
       
   427 					{
       
   428 					if(!readoverwritefile.Compare(acompareoverwrite))
       
   429 						err=KErrGeneral;
       
   430 					}
       
   431 				}
       
   432 			}
       
   433 		}
       
   434 	// close test output csv file
       
   435 	overwritefile.Close();
       
   436 	CleanupStack::PopAndDestroy(&atestdata1); 
       
   437 	CleanupStack::PopAndDestroy(&atestdata2); 
       
   438 	CleanupStack::PopAndDestroy(&readappendfile); 
       
   439 	CleanupStack::PopAndDestroy(&readoverwritefile); 
       
   440 	CleanupStack::PopAndDestroy(&acompareappend); 
       
   441 	CleanupStack::PopAndDestroy(&acompareoverwrite); 
       
   442 	return err;
       
   443 	}
       
   444 	
       
   445 	
       
   446 TInt CUptCsvGenerator::FillReferenceBuffer(RBuf8& aBufferName, const TInt& aAppendCount, const RArray<TInt64>& aData1Name, const TInt& aData1Count, const RArray<TInt64>& aData2Name, const TInt& aData2Count)
       
   447 	{
       
   448 	for(TInt i=0; i!=aAppendCount;i++)
       
   449 		{
       
   450 		// first line of data
       
   451 		for(TInt j=0;j!=aData1Count;j++)
       
   452 			{
       
   453 			aBufferName.AppendNum(aData1Name[j]);
       
   454 			//if(j!=aData1Count-1)
       
   455 			if(j!=aData1Count)
       
   456 				aBufferName.Append(KCsvComma);
       
   457 			}	
       
   458 			
       
   459 		// newline
       
   460 		aBufferName.Append(KCsvNewLine);
       
   461 		
       
   462 		// second line of data with a potentially different number of elements
       
   463 		for(TInt j=0;j!=aData2Count;j++)
       
   464 			{
       
   465 			aBufferName.AppendNum(aData2Name[j]);
       
   466 			//if(j!=aData2Count-1)
       
   467 			if(j!=aData2Count)
       
   468 				aBufferName.Append(KCsvComma);
       
   469 			}	
       
   470 		aBufferName.Append(KCsvNewLine);	
       
   471 		}
       
   472 	return 0;
       
   473 	}
       
   474 
       
   475 // eof
       
   476 
       
   477