/*
* Copyright (c) 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 module contains implementation of CTestReport
* class member functions.
*
*/
// INCLUDE FILES
#include <e32svr.h>
#include <f32file.h>
#include <hal.h>
#include "TestReport.h"
#include "TestEngineCommon.h"
#include "Logging.h"
// EXTERNAL DATA STRUCTURES
// None
// EXTERNAL FUNCTION PROTOTYPES
// None
// CONSTANTS
// None
// MACROS
const TInt KMaxLenEol = 6;
const TInt KMaxReportData = 256;
typedef TBuf<KMaxReportData> TPrintInfo;
const TInt KSummaryLineEndLen = 12;
_LIT( KSummaryLineEnd, " ");
// XML Tags (alphabetically)
_LIT(KXMLCaseNumberTag, "<CaseNumber>");
_LIT(KXMLCaseNumberTagEnd, "</CaseNumber>");
_LIT(KXMLCaseTitleTag, "<Title>");
_LIT(KXMLCaseTitleTagEnd, "</Title>");
_LIT(KXMLConfigFileTag, "<Config>");
_LIT(KXMLConfigFileTagEnd, "</Config>");
_LIT(KXMLCpuSpeedTag, "<CPUSpeed>");
_LIT(KXMLCpuSpeedTagEnd, "</CPUSpeed>");
_LIT(KXMLCpuTag, "<CPU>");
_LIT(KXMLCpuTagEnd, "</CPU>");
_LIT(KXMLCrashedTag, "<Crashed>");
_LIT(KXMLCrashedTagEnd, "</Crashed>");
_LIT(KXMLDateTag, "<Date>");
_LIT(KXMLDateTagEnd, "</Date>");
_LIT(KXMLDllSummaryTag, "<Dlls>");
_LIT(KXMLDllSummaryTagEnd, "</Dlls>");
_LIT(KXMLDllTag, "<Dll>");
_LIT(KXMLDllTagEnd, "</Dll>");
_LIT(KXMLEndTimeTag, "<EndTime>");
_LIT(KXMLEndTimeTagEnd, "</EndTime>");
_LIT(KXMLEnvironmentInfoTag, "<EnvironmentInfo>");
_LIT(KXMLEnvironmentInfoTagEnd, "</EnvironmentInfo>");
_LIT(KXMLExecutionResultTag, "<ExecutionResultCode>");
_LIT(KXMLExecutionResultTagEnd, "</ExecutionResultCode>");
_LIT(KXMLFailedTag, "<Failed>");
_LIT(KXMLFailedTagEnd, "</Failed>");
_LIT(KXMLFileNameTag, "<FileName>");
_LIT(KXMLFileNameTagEnd, "</FileName>");
_LIT(KXMLHardwareInfoTag, "<HardwareInfo>");
_LIT(KXMLHardwareInfoTagEnd, "</HardwareInfo>");
_LIT(KXMLHwRevisionTag, "<HwRevision>");
_LIT(KXMLHwRevisionTagEnd, "</HwRevision>");
_LIT(KXMLLanguageTag, "<Language>");
_LIT(KXMLLanguageTagEnd, "</Language>");
_LIT(KXMLMachineUidTag, "<MachineUID>");
_LIT(KXMLMachineUidTagEnd, "</MachineUID>");
_LIT(KXMLManufacturerTag, "<Manufacturer>");
_LIT(KXMLManufacturerTagEnd, "</Manufacturer>");
_LIT(KXMLMemoryInfoTag, "<MemoryInfo>");
_LIT(KXMLMemoryInfoTagEnd, "</MemoryInfo>");
_LIT(KXMLModelTag, "<Model>");
_LIT(KXMLModelTagEnd, "</Model>");
_LIT(KXMLModuleNameTag, "<ModuleName>");
_LIT(KXMLModuleNameTagEnd, "</ModuleName>");
_LIT(KXMLModuleSummaryTag, "<Modules>");
_LIT(KXMLModuleSummaryTagEnd, "</Modules>");
_LIT(KXMLModuleTag, "<Module>");
_LIT(KXMLModuleTagEnd, "</Module>");
_LIT(KXMLPassedTag, "<Passed>");
_LIT(KXMLPassedTagEnd, "</Passed>");
_LIT(KXMLRamFreeTag, "<RAMFree>");
_LIT(KXMLRamFreeTagEnd, "</RAMFree>");
_LIT(KXMLRamTag, "<RAM>");
_LIT(KXMLRamTagEnd, "</RAM>");
_LIT(KXMLResultDescrTag, "<ResultDescription>");
_LIT(KXMLResultDescrTagEnd, "</ResultDescription>");
_LIT(KXMLResultTag, "<Result>");
_LIT(KXMLResultTagEnd, "</Result>");
_LIT(KXMLSoftwareInfoTag, "<SoftwareInfo>");
_LIT(KXMLSoftwareInfoTagEnd, "</SoftwareInfo>");
_LIT(KXMLStartTimeTag, "<StartTime>");
_LIT(KXMLStartTimeTagEnd, "</StartTime>");
_LIT(KXMLSwBuildTag, "<SwBuild>");
_LIT(KXMLSwBuildTagEnd, "</SwBuild>");
_LIT(KXMLSwRevisionTag, "<SwRevision>");
_LIT(KXMLSwRevisionTagEnd, "</SwRevision>");
_LIT(KXMLTestCasesSummaryTag, "<TestCasesSummary>");
_LIT(KXMLTestCasesSummaryTagEnd, "</TestCasesSummary>");
_LIT(KXMLTestCasesTag, "<TestCases>");
_LIT(KXMLTestCasesTagEnd, "</TestCases>");
_LIT(KXMLTestCaseTag, "<TestCase>");
_LIT(KXMLTestCaseTagEnd, "</TestCase>");
_LIT(KXMLTestReportTag, "<TestReport>");
_LIT(KXMLTestReportTagEnd, "</TestReport>");
_LIT(KXMLTestResultTag, "<ResultCode>");
_LIT(KXMLTestResultTagEnd, "</ResultCode>");
_LIT(KXMLTimeoutedTag, "<Timeout>");
_LIT(KXMLTimeoutedTagEnd, "</Timeout>");
_LIT(KXMLTimeTag, "<Time>");
_LIT(KXMLTimeTagEnd, "</Time>");
_LIT(KXMLTotalTag, "<Total>");
_LIT(KXMLTotalTagEnd, "</Total>");
_LIT(KXMLVersionTag, "<Version>");
_LIT(KXMLVersionTagEnd, "</Version>");
// LOCAL CONSTANTS AND MACROS
// None
// MODULE DATA STRUCTURES
// None
// LOCAL FUNCTION PROTOTYPES
// None
// FORWARD DECLARATIONS
// None
// ==================== LOCAL FUNCTIONS =======================================
// None
// ================= MEMBER FUNCTIONS =========================================
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: CTestReport
Description: Default constructor
C++ default constructor can NOT contain any code, that
might leave.
Parameters: const TTestReportMode aReportMode: in: Report mode
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport::CTestReport( const TTestReportMode aReportMode ):
iReportMode( aReportMode )
{
iXML = EFalse;
iReportHWInfo = TTestHWInfo();
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: ConstructL
Description: Symbian OS second phase constructor
Symbian OS default constructor can leave.
Parameters: CTestReportSettings& aTestReportSettings: in: Report settings
Return Values: None
Errors/Exceptions: Leaves if memory allocation for iTotalSummary fails
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestReport::ConstructL( TTestReportSettings& aTestReportSettings )
{
// Create summary for all test cases
_LIT( KName, "All test cases" );
iTotalSummary = new ( ELeave ) TTestSummary( KName() );
User::LeaveIfError( iFs.Connect() );
TPtrC path;
path.Set( aTestReportSettings.iPath->Des() );
TPtrC name;
name.Set( aTestReportSettings.iName->Des() );
iFormat = aTestReportSettings.iFormat;
iOutput = aTestReportSettings.iOutput;
iXML = aTestReportSettings.iXML;
// XML format can be used only when report is of txt file type.
if(iFormat != CStifLogger::ETxt && iOutput != CStifLogger::EFile && iXML)
{
RDebug::Print(_L("Stif: XML report is available only when TestReportFormat is TXT and TestReportOutput is FILE"));
iXML = EFalse;
}
if( iOutput == CStifLogger::EFile )
{
iFs.MkDirAll( path );
HBufC* pathAndFileBuf = HBufC::NewLC( path.Length() + name.Length() + 5 );
TPtr pathAndFile(pathAndFileBuf->Des() );
pathAndFile.Append( path );
pathAndFile.Append( name );
if(iXML)
{
pathAndFile.Append( _L(".xml") );
}
else
{
if( ( iFormat == CStifLogger::EHtml ) &&
( iOutput == CStifLogger::EFile ) )
{
pathAndFile.Append( _L(".html") );
}
else
{
pathAndFile.Append( _L(".txt") );
}
}
if( aTestReportSettings.iOverwrite )
{
User::LeaveIfError( iFile.Replace( iFs,
pathAndFile,
EFileWrite | EFileStreamText | EFileShareAny ) );
}
else
{
TBool isOpen( EFalse );
TInt fileOpen = iFs.IsFileOpen( pathAndFile, isOpen );
if( fileOpen == KErrNotFound )
{
User::LeaveIfError(
iFile.Create( iFs,
pathAndFile,
EFileWrite | EFileStreamText | EFileShareAny ) );
}
else if( fileOpen == KErrNone )
{
User::LeaveIfError(
iFile.Open( iFs,
pathAndFile,
EFileWrite | EFileStreamText | EFileShareAny ) );
TInt endPosOfFile = 0;
User::LeaveIfError( iFile.Seek( ESeekEnd, endPosOfFile ) );
}
else
{
User::Leave( fileOpen );
}
}
CleanupStack::PopAndDestroy( pathAndFileBuf );
}
WriteHeaderL();
// Add temporarily closing tags to keep valid xml structure
CloseXMLTagsInUnfinishedFileL();
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: NewL
Description: Two-phased constructor.
Parameters: CTestReportSettings& aTestReportSettings: in: Report settings
const TTestReportMode aReportMode: in: Report mode
Return Values: CTestReport* : pointer to created object
Errors/Exceptions: Leaves if memory allocation for object fails
Leaves if ConstructL leaves
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport* CTestReport::NewL( TTestReportSettings& aTestReportSettings,
const TTestReportMode aReportMode )
{
CTestReport* self = new ( ELeave ) CTestReport( aReportMode );
CleanupStack::PushL( self );
self->ConstructL( aTestReportSettings );
CleanupStack::Pop( self );
return self;
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: ~CTestReport
Description: Destructor
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport::~CTestReport()
{
// Reset and destroy arrays
iTestSummaries.ResetAndDestroy();
delete iTotalSummary;
if( iOutput != CStifLogger::ERDebug )
{
// Delete file
iFile.Close();
iFs.Close();
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: AddTestCaseResultL
Description: Add new test case result.
Parameters: const TTestInfo& aTestInfo: in: TTestInfo: Test info
const TFullTestResult& aTestResult: in: TTestResult: Testresult
const TInt aError: in: Symbian OS error: Additional error code
Return Values: None
Errors/Exceptions: Leave is iReportGenerated is generated
Leave if summary creation fails
Leave if summary adding fails
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestReport::AddTestCaseResultL( const TTestInfo& aTestInfo,
const TFullTestResult& aTestResult,
const TInt aError )
{
// Create summary for this test case
TTestCaseSummary summary;
summary.iTestInfo = aTestInfo;
summary.iFullTestResult = aTestResult;
TBool passed( EFalse );
TBool crashed( EFalse );
TBool timeout( EFalse );
if( ( aError == KErrNone ) &&
( summary.iFullTestResult.iCaseExecutionResultType == TFullTestResult::ECaseExecuted ) &&
( KErrNone == summary.iFullTestResult.iTestResult.iResult ) )
{
passed = ETrue;
}
else if( summary.iFullTestResult.iCaseExecutionResultType == TFullTestResult::ECaseTimeout )
{
timeout = ETrue;
}
else if( ( summary.iFullTestResult.iCaseExecutionResultCode != KErrNone )
|| ( summary.iFullTestResult.iCaseExecutionResultType == TFullTestResult::ECasePanic )
|| ( summary.iFullTestResult.iCaseExecutionResultType == TFullTestResult::ECaseException ) )
{
crashed = ETrue;
}
if ( iReportMode & ETestReportCases )
{
// Print summary to file
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCaseTag);
WriteLineL(_L("%S%S%S"), &KXMLModuleNameTag, &summary.iTestInfo.iModuleName, &KXMLModuleNameTagEnd);
if(summary.iTestInfo.iConfig != KNullDesC)
{
WriteLineL(_L("%S%S%S"), &KXMLConfigFileTag, &summary.iTestInfo.iConfig, &KXMLConfigFileTagEnd);
}
WriteLineL(_L("%S%d%S"), &KXMLCaseNumberTag, summary.iTestInfo.iTestCaseInfo.iCaseNumber, &KXMLCaseNumberTagEnd);
WriteLineL(_L("%S%S%S"), &KXMLCaseTitleTag, &summary.iTestInfo.iTestCaseInfo.iTitle, &KXMLCaseTitleTagEnd);
}
else
{
WriteLineL( _L("[%S][%S][%d] Title:[%S]"),
&summary.iTestInfo.iModuleName,
&summary.iTestInfo.iConfig,
summary.iTestInfo.iTestCaseInfo.iCaseNumber,
&summary.iTestInfo.iTestCaseInfo.iTitle );
}
const TInt KTimeFieldLength = 30;
TBuf<KTimeFieldLength> startTime;
TBuf<KTimeFieldLength> endTime;
_LIT(KDateString4,"%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B");
summary.iFullTestResult.iStartTime.FormatL(
startTime,KDateString4 );
summary.iFullTestResult.iEndTime.FormatL(
endTime,KDateString4 );
// Result description needs max length 0x80(Must be same as
// TResultDes length) + specific characters see below.
TBuf<KMaxReportData> printBuf2;
TInt code = CStifLogger::ENoStyle;
if( ( summary.iFullTestResult.iCaseExecutionResultType
!= TFullTestResult::ECasePanic ) &&
( summary.iFullTestResult.iCaseExecutionResultCode
== KErrNone ) )
{
printBuf2.AppendFormat( _L("\tResult: %d [%S]"),
summary.iFullTestResult.iTestResult.iResult,
&summary.iFullTestResult.iTestResult.iResultDes );
if ( KErrNone ==
summary.iFullTestResult.iTestResult.iResult )
{
printBuf2.AppendFormat( _L(" ==> PASSED"));
}
else
{
code = CStifLogger::ERed;
printBuf2.AppendFormat( _L(" ==> FAILED"));
}
}
else
{
code = CStifLogger::ERed;
printBuf2.AppendFormat( _L("\tCaseExecutionResult: %S with %d"),
&summary.iFullTestResult.iTestResult.iResultDes,
summary.iFullTestResult.iCaseExecutionResultCode );
}
if(iXML)
{
WriteLineL(_L("%S%S%S"), &KXMLStartTimeTag, &startTime, &KXMLStartTimeTagEnd);
WriteLineL(_L("%S%S%S"), &KXMLEndTimeTag, &endTime, &KXMLEndTimeTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLTestResultTag, summary.iFullTestResult.iTestResult.iResult, &KXMLTestResultTagEnd);
WriteLineL(_L("%S%S%S"), &KXMLResultDescrTag, &summary.iFullTestResult.iTestResult.iResultDes, &KXMLResultDescrTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLExecutionResultTag, summary.iFullTestResult.iCaseExecutionResultCode, &KXMLExecutionResultTagEnd);
}
else
{
WriteLineL( _L("\tStartTime: %S, EndTime: %S"),
&startTime,
&endTime );
WriteLineL( printBuf2, code );
WriteDelimiterL( _L( "- " ), 10 );
WriteLineL( _L( "" ) );
}
}
// Add test summary
// Check if the module already exists for this test case
TTestSummary* moduleSummary = NULL;
TInt count = iTestSummaries.Count();
for( TInt i = 0; i < count; i++ )
{
if ( iTestSummaries[i]->iName == aTestInfo.iModuleName )
{
moduleSummary = iTestSummaries[i];
break;
}
}
if( moduleSummary == NULL )
{
// Create new module array
moduleSummary = new ( ELeave ) TTestSummary( aTestInfo.iModuleName );
User::LeaveIfError( iTestSummaries.Append( moduleSummary ) );
}
if( passed )
{
moduleSummary->iPassedCases++;
iTotalSummary->iPassedCases++;
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%SPASSED%S"), &KXMLResultTag, &KXMLResultTagEnd);
}
}
else if( timeout )
{
moduleSummary->iTimeoutCases++;
iTotalSummary->iTimeoutCases++;
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%STIMEOUT%S"), &KXMLResultTag, &KXMLResultTagEnd);
}
}
else if( crashed ||
( aError != KErrNone ) )
{
moduleSummary->iCrashedCases++;
iTotalSummary->iCrashedCases++;
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%SCRASHED%S"), &KXMLResultTag, &KXMLResultTagEnd);
}
}
else
{
moduleSummary->iFailedCases++;
iTotalSummary->iFailedCases++;
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%SFAILED%S"), &KXMLResultTag, &KXMLResultTagEnd);
}
}
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%S"), &KXMLTestCaseTagEnd);
}
// Add temporarily closing tags to keep valid xml structure
CloseXMLTagsInUnfinishedFileL();
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: WriteHeaderL
Description: Write test report header.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CTestReport::WriteHeaderL()
{
if( ( iFormat == CStifLogger::EHtml ) &&
( iOutput == CStifLogger::EFile ) )
{
// Html start tags to whole page and header section
iFile.Write(
_L8( "\n<html>\n<head>\n<title>TestReport</title>\n</head>\n\n\n<body>\n" ) );
}
if(iXML)
{
WriteLineL(_L("<?xml version=\"1.0\" ?>"));
WriteLineL(_L("%S"), &KXMLTestReportTag);
}
else
{
WriteDelimiterL( _L( "***" ), 25 );
}
// Generate date and time
TTime time;
time.HomeTime();
TBuf<30> date;
TBuf<30> clock;
// Date
_LIT( KDate, "%E%D%X%N%Y %1 %2 %3" );
time.FormatL( date, KDate );
// Time
_LIT( KClock,"%-B%:0%J%:1%T%:2%S%:3%+B" );
time.FormatL( clock,KClock );
// Add date and time
if(iXML)
{
WriteLineL(_L("%S%S%S"), &KXMLDateTag, &date, &KXMLDateTagEnd);
WriteLineL(_L("%S%S%S"), &KXMLTimeTag, &clock, &KXMLTimeTagEnd);
}
else
{
WriteLineL( _L( "%S" ), &date );
WriteLineL( _L( "%S" ), &clock );
}
if ( iReportMode & ETestReportSummary )
{
if( iOutput == CStifLogger::EFile )
{
// Get current file position
iSummaryPos = 0;
User::LeaveIfError( iFile.Seek( ESeekCurrent, iSummaryPos ) );
}
// Generate Summary to Report
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTag);
WriteLineL(_L("%S%S%S"), &KXMLPassedTag, &KXMLPassedTagEnd, &KSummaryLineEnd);
WriteLineL(_L("%S%S%S"), &KXMLFailedTag, &KXMLFailedTagEnd, &KSummaryLineEnd);
WriteLineL(_L("%S%S%S"), &KXMLTimeoutedTag, &KXMLTimeoutedTagEnd, &KSummaryLineEnd);
WriteLineL(_L("%S%S%S"), &KXMLCrashedTag, &KXMLCrashedTagEnd, &KSummaryLineEnd);
WriteLineL(_L("%S%S%S"), &KXMLTotalTag, &KXMLTotalTagEnd, &KSummaryLineEnd);
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTagEnd);
}
else
{
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL(_L("SUMMARY:") );
WriteLineL(_L("\tPassed cases: %S"), &KSummaryLineEnd );
WriteLineL(_L("\tFailed cases: %S"), &KSummaryLineEnd );
WriteLineL(_L("\tTimeout cases: %S"), &KSummaryLineEnd );
WriteLineL(_L("\tCrashed cases: %S"), &KSummaryLineEnd );
WriteLineL(_L("\tTotal cases: %S"), &KSummaryLineEnd );
WriteLineL( _L( "" ));
}
}
if ( iReportMode & ETestReportEnvironment )
{
const TInt KMegaByte = 1024*1024;
if(iXML)
{
WriteLineL(_L("%S"), &KXMLEnvironmentInfoTag);
WriteLineL(_L("%S"), &KXMLHardwareInfoTag);
WriteLineL(_L("%S0x%x%S"), &KXMLManufacturerTag, iReportHWInfo.iHwInfo.iManufacturer, &KXMLManufacturerTagEnd);
WriteLineL(_L("%S0x%x%S"), &KXMLMachineUidTag, iReportHWInfo.iHwInfo.iMachineUid, &KXMLMachineUidTagEnd);
WriteLineL(_L("%S0x%x%S"), &KXMLModelTag, iReportHWInfo.iHwInfo.iModel, &KXMLModelTagEnd);
WriteLineL(_L("%S0x%x%S"), &KXMLHwRevisionTag, iReportHWInfo.iHwInfo.iHwRev, &KXMLHwRevisionTagEnd);
WriteLineL(_L("%S0x%x%S"), &KXMLCpuTag, iReportHWInfo.iHwInfo.iCpu, &KXMLCpuTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLCpuSpeedTag, iReportHWInfo.iHwInfo.iCpuSpeed/1000, &KXMLCpuSpeedTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLLanguageTag, iReportHWInfo.iHwInfo.iLanguage, &KXMLLanguageTagEnd);
WriteLineL(_L("%S"), &KXMLHardwareInfoTagEnd);
WriteLineL(_L("%S"), &KXMLSoftwareInfoTag);
WriteLineL(_L("%S0x%x%S"), &KXMLSwRevisionTag, iReportHWInfo.iSwInfo.iSwRev, &KXMLSwRevisionTagEnd);
WriteLineL(_L("%S0x%x%S"), &KXMLSwBuildTag, iReportHWInfo.iSwInfo.iSwBuild, &KXMLSwBuildTagEnd);
WriteLineL(_L("%S"), &KXMLSoftwareInfoTagEnd);
WriteLineL(_L("%S"), &KXMLMemoryInfoTag);
WriteLineL(_L("%S%d%S"), &KXMLRamTag, iReportHWInfo.iMemoryInfo.iRAM/KMegaByte, &KXMLRamTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLRamFreeTag, iReportHWInfo.iMemoryInfo.iRAMFree/KMegaByte, &KXMLRamFreeTagEnd);
WriteLineL(_L("%S"), &KXMLMemoryInfoTagEnd);
WriteLineL(_L("%S"), &KXMLEnvironmentInfoTagEnd);
}
else
{
// HW Info
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL( _L("ENVIRONMENT INFO:") );
WriteLineL( _L("HW Info:") );
WriteLineL(
_L("\tManufacturer: 0x%x, MachineUid: 0x%x, Model: 0x%x "),
iReportHWInfo.iHwInfo.iManufacturer,
iReportHWInfo.iHwInfo.iMachineUid,
iReportHWInfo.iHwInfo.iModel );
WriteLineL(
_L("\tHW Rev: 0x%x, CPU: 0x%x, CPU Speed: %d MHz "),
iReportHWInfo.iHwInfo.iHwRev,
iReportHWInfo.iHwInfo.iCpu,
iReportHWInfo.iHwInfo.iCpuSpeed/1000 );
WriteLineL(_L("\tLanguage: %d "),
iReportHWInfo.iHwInfo.iLanguage );
// SW Info
WriteLineL(_L("SW Info:") );
WriteLineL(_L("\tSW Rev: 0x%x, SW Build: 0x%x"),
iReportHWInfo.iSwInfo.iSwRev,
iReportHWInfo.iSwInfo.iSwBuild );
// Memory Info
WriteLineL(_L("Memory Info:") );
WriteLineL(_L("\tRAM: %d MB, RAM Free: %d MB"),
( iReportHWInfo.iMemoryInfo.iRAM/KMegaByte ),
( iReportHWInfo.iMemoryInfo.iRAMFree/KMegaByte ) );
WriteLineL( _L( "" ) );
}
}
if ( iReportMode & ETestReportCases )
{
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesTag);
}
else
{
// Generate Test Cases to Report
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL( _L("TESTCASE SUMMARY:") );
}
}
if ( iReportMode == ETestReportBlank )
{
if(!iXML)
{
WriteLineL( _L( "") );
WriteLineL( _L( "'Empty' configuration given in initialization file's [Engine_Defaults] section" ) );
WriteLineL( _L( "No test report created" ) );
}
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: WriteTrailerL
Description: Write test report trailer.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CTestReport::WriteTrailerL()
{
if(iXML && (iReportMode & ETestReportCases))
{
WriteLineL(_L("%S"), &KXMLTestCasesTagEnd);
}
if ( iReportMode & ETestReportSummary )
{
if(iXML)
{
WriteLineL(_L("%S"), &KXMLModuleSummaryTag);
}
else
{
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL(_L("TESTMODULE SUMMARIES:") );
}
// Generate module related reports
for ( TInt k = 0; k < iTestSummaries.Count(); k++ )
{
if(iXML)
{
WriteLineL(_L("%S"), &KXMLModuleTag);
WriteLineL(_L("%S%S%S"), &KXMLModuleNameTag, &iTestSummaries[k]->iName, &KXMLModuleNameTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLPassedTag, iTestSummaries[k]->iPassedCases, &KXMLPassedTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLFailedTag, iTestSummaries[k]->iFailedCases, &KXMLFailedTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLTimeoutedTag, iTestSummaries[k]->iTimeoutCases, &KXMLTimeoutedTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLCrashedTag, iTestSummaries[k]->iCrashedCases, &KXMLCrashedTagEnd);
WriteLineL(_L("%S%d%S"), &KXMLTotalTag, iTestSummaries[k]->iPassedCases + iTestSummaries[k]->iFailedCases + iTestSummaries[k]->iTimeoutCases + iTestSummaries[k]->iCrashedCases, &KXMLTotalTagEnd);
WriteLineL(_L("%S"), &KXMLModuleTagEnd);
}
else
{
WriteLineL(_L("Module: [%S]"),
&iTestSummaries[k]->iName );
WriteLineL(_L("\tPassed cases: %d"),
iTestSummaries[k]->iPassedCases );
WriteLineL(_L("\tFailed cases: %d"),
iTestSummaries[k]->iFailedCases );
WriteLineL(_L("\tTimeout cases: %d"),
iTestSummaries[k]->iTimeoutCases );
WriteLineL(_L("\tCrashed cases: %d"),
iTestSummaries[k]->iCrashedCases );
TInt moduleTotal = iTestSummaries[k]->iPassedCases +
iTestSummaries[k]->iFailedCases +
iTestSummaries[k]->iTimeoutCases +
iTestSummaries[k]->iCrashedCases;
WriteLineL(_L("\tTotal cases: %d"), moduleTotal );
WriteLineL( _L( "" ) );
}
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLModuleSummaryTagEnd);
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLDllSummaryTag);
}
else
{
WriteDelimiterL(_L( "-- " ), 25 );
WriteLineL(_L("TEST MODULES VERSIONS:"));
}
// Generate test module versions info
for( TInt i = 0; i < iTestModulesVersionsInfo.Count(); i++ )
{
TTestModuleVersionInfo* versionInfo = (TTestModuleVersionInfo*)iTestModulesVersionsInfo[i];
if(iXML)
{
WriteLineL(_L("%S"), &KXMLDllTag);
WriteLineL(_L("%S%S%S"), &KXMLFileNameTag, &(versionInfo->iTestModuleName), &KXMLFileNameTagEnd);
WriteLineL(_L("%S%d.%d.%d%S"), &KXMLVersionTag, versionInfo->iMajor, versionInfo->iMinor, versionInfo->iBuild, &KXMLVersionTagEnd);
WriteLineL(_L("%S"), &KXMLDllTagEnd);
}
else
{
WriteLineL(_L("%S %d.%d.%d"), &(versionInfo->iTestModuleName), versionInfo->iMajor, versionInfo->iMinor, versionInfo->iBuild);
}
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLDllSummaryTagEnd);
}
}
if(!iXML)
{
WriteLineL( _L( "" ) );
}
if( ( iFormat == CStifLogger::EHtml ) &&
( iOutput == CStifLogger::EFile ) )
{
// Html start tags to whole page and header section
iFile.Write(
_L8( "\n\n\n</html>\n</body>\n\n\n" ) );
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestReportTagEnd);
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: UpdateReportSummaryL
Description: Updates the test report summary.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CTestReport::UpdateReportSummaryL()
{
TInt currentPos = 0;
// Add numeric information to summary
if ( iReportMode & ETestReportSummary )
{
// Go to the summary start position of the file
if( iOutput == CStifLogger::EFile )
{
User::LeaveIfError(iFile.Seek(ESeekCurrent, currentPos));//Get current position
User::LeaveIfError( iFile.Seek( ESeekStart, iSummaryPos ) );
}
TBuf<KSummaryLineEndLen> numStr;
// Generate Summary to Report
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTag);
}
else
{
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL(_L("SUMMARY:") );
}
numStr.Num( iTotalSummary->iPassedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLPassedTag, &numStr, &KXMLPassedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tPassed cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iFailedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLFailedTag, &numStr, &KXMLFailedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tFailed cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iTimeoutCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLTimeoutedTag, &numStr, &KXMLTimeoutedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tTimeout cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iCrashedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLCrashedTag, &numStr, &KXMLCrashedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tCrashed cases: %S"), &numStr );
}
TInt total = iTotalSummary->iPassedCases +
iTotalSummary->iFailedCases +
iTotalSummary->iTimeoutCases +
iTotalSummary->iCrashedCases;
numStr.Num( total );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLTotalTag, &numStr, &KXMLTotalTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tTotal cases: %S"), &numStr );
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTagEnd);
}
if(iOutput == CStifLogger::EFile)
{
User::LeaveIfError(iFile.Seek(ESeekStart, currentPos));
}
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: GenerateReportL
Description: Generate the test report.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestReport::GenerateReportL()
{
WriteTrailerL();
// Add numeric information to summary
if ( iReportMode & ETestReportSummary )
{
// Go to the summary start position of the file
if( iOutput == CStifLogger::EFile )
{
User::LeaveIfError( iFile.Seek( ESeekStart, iSummaryPos ) );
}
TBuf<KSummaryLineEndLen> numStr;
// Generate Summary to Report
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTag);
}
else
{
WriteDelimiterL( _L( "-- " ), 25 );
WriteLineL(_L("SUMMARY:") );
}
numStr.Num( iTotalSummary->iPassedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLPassedTag, &numStr, &KXMLPassedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tPassed cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iFailedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLFailedTag, &numStr, &KXMLFailedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tFailed cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iTimeoutCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLTimeoutedTag, &numStr, &KXMLTimeoutedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tTimeout cases: %S"), &numStr );
}
numStr.Num( iTotalSummary->iCrashedCases );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLCrashedTag, &numStr, &KXMLCrashedTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tCrashed cases: %S"), &numStr );
}
TInt total = iTotalSummary->iPassedCases +
iTotalSummary->iFailedCases +
iTotalSummary->iTimeoutCases +
iTotalSummary->iCrashedCases;
numStr.Num( total );
if(iXML)
{
TPtrC spaces(KSummaryLineEnd().Ptr(), KSummaryLineEnd().Length() - numStr.Length());
WriteLineL(_L("%S%S%S%S"), &KXMLTotalTag, &numStr, &KXMLTotalTagEnd, &spaces);
}
else
{
numStr.Append( KSummaryLineEnd().Ptr(),
KSummaryLineEnd().Length() - numStr.Length() );
WriteLineL(_L("\tTotal cases: %S"), &numStr );
}
if(iXML)
{
WriteLineL(_L("%S"), &KXMLTestCasesSummaryTagEnd);
}
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: WriteLine
Description: Write line to file.
Parameters: TRefByValue<const TDesC> aStr: in: test to print
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CTestReport::WriteLineL( TRefByValue<const TDesC> aStr,... )
{
VA_LIST list;
VA_START( list, aStr );
TPrintInfo line;
// Parse parameters
line.AppendFormatList( aStr, list, NULL );
if( iOutput == CStifLogger::ERDebug )
{
// RDebug output
RDebug::Print( line );
return;
}
HBufC8* buf = HBufC8::NewLC( line.Length() + KMaxLenEol );
TPtr8 ptr( buf->Des() );
ptr.Copy( line );
if( ( iFormat == CStifLogger::EHtml ) &&
( iOutput == CStifLogger::EFile ) )
{
// Html output, add linefeed
ptr.Append( _L8("<BR>\r\n") );
}
else
{
// Default: Text format to file
// Add linefeed
ptr.Append( _L8("\r\n") );
}
// Write to file
iFile.Write( ptr );
CleanupStack::PopAndDestroy( buf );
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: WriteDelimiter
Description: Write delimiter line to file.
Parameters: const TDesC& aDelimiter: in: delimiter mark
TInt aCount: in: number of delimiters written
Return Values: None
Errors/Exceptions: None
Status: Proposal
-------------------------------------------------------------------------------
*/
void CTestReport::WriteDelimiterL( const TDesC& aDelimiter, TInt aCount )
{
if( iOutput == CStifLogger::ERDebug )
{
// RDebug output
// Nothing is printed
return;
}
HBufC8* buf = HBufC8::NewLC( aDelimiter.Length() );
TPtr8 ptr( buf->Des() );
ptr.Copy( aDelimiter );
for( TInt i = 0; i<aCount; i++ )
{
// Write to file
iFile.Write( ptr );
}
CleanupStack::PopAndDestroy( buf );
TBuf8<KMaxLenEol> linefeed;
if( ( iFormat == CStifLogger::EHtml ) &&
( iOutput == CStifLogger::EFile ) )
{
// Html output, add linefeed
linefeed.Append( _L8("<BR>\r\n") );
}
else
{
// Default: Text format to file
// Add linefeed
linefeed.Append( _L8("\r\n") );
}
// Write to file
iFile.Write( linefeed );
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: TTestReportHeader::TTestReportHeader
Description: Constructor of TTestReportHeader
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport::TTestHWInfo::TTestHWInfo()
{
// Initialize, fills a specified block of data with binary zeroes
Mem::FillZ( this, sizeof( CTestReport::TTestHWInfo ) );
// Get HW Info
HAL::Get( HALData::EManufacturer, iHwInfo.iManufacturer );
HAL::Get( HALData::EMachineUid, iHwInfo.iMachineUid );
HAL::Get( HALData::EManufacturerHardwareRev, iHwInfo.iHwRev );
HAL::Get( HALData::EModel, iHwInfo.iModel );
HAL::Get( HALData::ECPU, iHwInfo.iCpu );
HAL::Get( HALData::ECPUSpeed, iHwInfo.iCpuSpeed );
HAL::Get( HALData::ELanguageIndex, iHwInfo.iLanguage );
// Get SW Info
HAL::Get( HALData::EManufacturerSoftwareRev, iSwInfo.iSwRev );
HAL::Get( HALData::EManufacturerSoftwareBuild, iSwInfo.iSwBuild );
// Memory Info
HAL::Get( HALData::EMemoryRAM, iMemoryInfo.iRAM );
HAL::Get( HALData::EMemoryRAMFree, iMemoryInfo.iRAMFree );
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: TTestSummary::TTestSummary
Description: Constructor of TTestSummary.
Parameters: const TName& aName: in: Name of summary
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport::TTestSummary::TTestSummary( const TName& aName ) :
iName( aName ),
iPassedCases( 0 ),
iFailedCases( 0 ),
iCrashedCases( 0 ),
iTimeoutCases( 0 )
{
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: AddTestModuleVersion
Description: Method adds version of a test module to the list of versions
that will be printed when stif is stopped.
Parameters: TTestModuleVersionInfo aVersion : object contains information about version and
name of test module.
Return Values: None
Errors/Exceptions: None
-------------------------------------------------------------------------------
*/
void CTestReport::AddTestModuleVersion(TTestModuleVersionInfo& aVersion)
{
for(TInt i = 0; i < iTestModulesVersionsInfo.Count(); i++)
{
if( aVersion.iTestModuleName == iTestModulesVersionsInfo[i]->iTestModuleName )
{
return;
}
}
TTestModuleVersionInfo* testModuleVersionInfo = new (ELeave) TTestModuleVersionInfo;
testModuleVersionInfo->iMajor = aVersion.iMajor;
testModuleVersionInfo->iMinor = aVersion.iMinor;
testModuleVersionInfo->iBuild = aVersion.iBuild;
testModuleVersionInfo->iTestModuleName = aVersion.iTestModuleName;
TInt res = iTestModulesVersionsInfo.Append(testModuleVersionInfo);
if( res != KErrNone )
{
delete testModuleVersionInfo;
}
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: TTestCaseSummary::TTestCaseSummary
Description: Constructor of TTestCaseSummary.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
CTestReport::TTestCaseSummary::TTestCaseSummary()
{
}
/*
-------------------------------------------------------------------------------
Class: CTestReport
Method: CloseXMLTagsInUnfinishedFileL
Description: Adds needed tags to get valid xml file.
Parameters: None
Return Values: None
Errors/Exceptions: Seek operations may cause leaves
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestReport::CloseXMLTagsInUnfinishedFileL(void)
{
// For xml file keep current position in file.
if(iXML)
{
TInt currentPos = 0;
User::LeaveIfError(iFile.Seek(ESeekCurrent, currentPos));
// Add closing tags to get valid xml file
WriteLineL(_L("%S"), &KXMLTestCasesTagEnd);
WriteLineL(_L("%S"), &KXMLTestReportTagEnd);
// Move back to previous position
User::LeaveIfError(iFile.Seek(ESeekStart, currentPos));
}
}
// ================= OTHER EXPORTED FUNCTIONS =================================
// None
// End of File