diff -r 000000000000 -r 60b4b6493d7b tsrc/testing/tools/testdoc.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tsrc/testing/tools/testdoc.pl Thu Nov 04 11:16:56 2010 +0200 @@ -0,0 +1,5437 @@ +# +# Copyright (c) 2006 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: +# + +#----------------------------------------------- +# Sequence +#----------------------------------------------- +# Reads parameters -> [if !ok params] ShowHelp +# ReadConfigFiles +# -> ParseCfg +# -> ReadCase +# +# for all testreports: +# ReadTestRunInfoFromStifReport +# GetReportLogFileNames +# ParseResultsAndLogs +# +# ParseResultsAndLogs +# WriteCaseLog +# LogLineTimeMatchesForCase +# FormatLogLine +# UpdateCase +# CheckCaseEntriesInLog +# +# OLD: +# -> ParseReportFile +# -> ReadReportLogs +# -> WriteCaseLog +# -> LogLineTimeMatchesForCase +# -> FormatLogLine +# -> CheckCaseEntriesInLog +# +# ReportNotDocumentedCases +# SortCases +# CalculateStats +# WriteOfficeXml -> XmlReadyText +# exit() + +#----------------------------------------------- +# Other functions: +#----------------------------------------------- +# RemoveWhiteSpaces +# SpecialChars +# ReplaceChar +# GetCaseField +# GetCase (id or name) +# GetCaseDesc (id or name) +# PrintCases +# JustFormatLogFile + +# +# +# +# STIF CFG: +#************************************************************************************ +#[IptvETDescription] +# Testname: +# +# Purpose: +# +# Means: +# +# Required environment settings: +# +# Verification: +# +# Note: +# +# Related requirements: .. +# +#[EndIptvETDescription] +#------------------------------------------------------------------------------------ +#[Test] +# do stuff here +#[Endtest] + +#------------------------------------------------------------------------------------ +# Includes +#------------------------------------------------------------------------------------ +#use strict; +use warnings; +use Cwd; # for cwd +use FindBin; # for FindBin:Bin +use File::Path; # for mkpath +use File::Copy; +use Date::Calc; + +#------------------------------------------------------------------------------------ +# Globals +#------------------------------------------------------------------------------------ + +my $lastCaseLogLine = 0; + +my $ALT_RESULTCOUNT = 10; # maximum number of runs in alternative report + +my @cases; #references to case arrays +my @gCfgFiles; # list of cfg files. +my @caseDescs; # case description and the case itself in text +my @notDocumentedCases; #array to hold information about the cases without documentation + +$regexpCaseName = '[\x3C\x3E\(\)\[\]\w.,\/:_\-&\' ]+'; + +my $caseDefaultStatus = "NOT RUN"; + +# +# Case field numerations +# + +my $CASE_NAME = 0; +my $CASE_ID = 1; +my $CASE_RUN_TIMES = 2; +my $CASE_CRASHED = 3; +my $CASE_FAILED = 4; +my $CASE_PASSED = 5; +my $CASE_STATUS = 6; +my $CASE_PURPOSE = 7; +my $CASE_MEANS = 8; +my $CASE_REQUIRED_SETTINGS = 9; +my $CASE_RELATED_REQUIREMENTS = 10; +my $CASE_VERIFICATION = 11; +my $CASE_NOTE = 12; +my $CASE_REASON = 13; # where crashed or what returned the error code +my $CASE_RESULT = 14; # error code +my $CASE_LOG_FILE = 15; # test case specific log file. +my $CASE_LOG_FILE_SCRIPTER = 16; # test case specific log from STIF testscripter logs. +my $CASE_CHECK_RESULT_LOG_FILE = 17; # set if the case is in the log files, if next line is found: >>>Case start: ETxxxxx CaseName + # or STIF own trace: Starting testcase [ET1000 Add multiple Iaps] (usually from fasttrace or emulator log) +my $CASE_CFG_FILE = 18; +my $CASE_RUN_TIME_SECONDS = 19; # how many seconds it took to run the case +my $CASE_REPORTLINE1 = 20; +my $CASE_REPORTLINE2 = 21; +my $CASE_REPORTLINE3 = 22; +my $CASE_ENTRY_LOG_START = 23; + +my $TDTOOLRESULTFILE = ".\\text_file.txt"; +my $XML_OUTPUT_FILE = ".\\test_cases.xml"; +my $XML_BRIEF_OUTPUT_FILE = ".\\test_cases_brief.xml"; +my $NOT_DOCUMENTED_CASES_FILE = ".\\test_cases_notdocumented.txt"; + +my @globalTempFiles; + +# +# Tags inside the xml, will be replaced by case data when writing the xml file +# + +my $CaseCountMul8 = "CASE_COUNT_MUL8"; + +my $STYLE_ID_STATUS_TAG = "STYLE_ID_STATUS"; # must be in the xml data + +my $STYLE_ID_STATUS_FAILED = "s36"; +my $STYLE_ID_STATUS_PASSED = "s37"; +my $STYLE_ID_STATUS_CRASHED = "s38"; +my $STYLE_ID_STATUS_UNKNOWN = "s401"; +my $STYLE_ID_STATUS_NA = "s39"; + +my $STYLE_ID_STATUS_FAILED_CENTERED = "s36centered"; +my $STYLE_ID_STATUS_PASSED_CENTERED = "s37centered"; +my $STYLE_ID_STATUS_CRASHED_CENTERED = "s38centered"; +my $STYLE_ID_STATUS_UNKNOWN_CENTERED = "s401centered"; +my $STYLE_ID_STATUS_NA_CENTERED = "s39centered"; + +# these must be in the xml data to get the results inserted into xml +my $xmlDataCaseName = "XML_DATA_CASE_NAME"; +my $xmlDataCaseRunTimes = "XML_DATA_CASE_RUN_TIMES"; +my $xmlDataCaseFailed = "XML_DATA_CASE_FAILED"; +my $xmlDataCaseCrashed = "XML_DATA_CASE_CRASHED"; +my $xmlDataCasePassed = "XML_DATA_CASE_PASSED"; +my $xmlDataCaseStatus = "XML_DATA_CASE_STATUS"; +my $xmlDataCasePurpose = "XML_DATA_CASE_PURPOSE"; +my $xmlDataCaseMeans = "XML_DATA_CASE_MEANS"; +my $xmlDataCaseRequiredSettings = "XML_DATA_CASE_REQUIRED_SETTINGS"; +my $xmlDataCaseRelatedRequirements = "XML_DATA_CASE_RELATED_REQUIREMENTS"; +my $xmlDataCaseVerification = "XML_DATA_CASE_VERIFICATION"; +my $xmlDataCaseNote = "XML_DATA_CASE_NOTE"; +my $xmlDataCaseReason = "XML_DATA_CASE_REASON"; +my $xmlDataCaseResult = "XML_DATA_CASE_RESULT"; +my $xmlDataCaseLink1 = "XML_DATA_CASE_LINK1"; +my $xmlDataCaseLink2 = "XML_DATA_CASE_LINK2"; + +my $xmlDataSummaryCaseCount = "XML_DATA_SUMMARY_TOTAL_CASES"; +my $xmlDataSummaryPassed = "XML_DATA_SUMMARY_PASSED"; +my $xmlDataSummaryFailed = "XML_DATA_SUMMARY_FAILED"; +my $xmlDataSummaryCrashed = "XML_DATA_SUMMARY_CRASHED"; +my $xmlDataSummaryTimeout = "XML_DATA_SUMMARY_TIMEOUT"; +my $xmlDataSummaryPassRateTotal = "XML_DATA_SUMMARY_PASS_RATE_TOTAL"; +my $xmlDataSummaryPassRateRun = "XML_DATA_SUMMARY_PASS_RATE_RUN"; +my $xmlDataSummaryRunRate = "XML_DATA_SUMMARY_RUN_RATE"; + +my $xmlDataAltDateX = "XML_DATA_ALTDATE"; + +my $xmlDataAltResultX = "XML_DATA_ALTRESULT"; + +my $xmlDataCfgFile = "XML_DATA_CFG_FILE"; + +# +# Statistics +# + +my $summaryCaseCount = 0; +my $summaryPassedCases = 0; +my $summaryFailedCases = 0; +my $summaryCrashedCases = 0; +my $summaryTimeoutCases = 0; +my $summaryPassRateTotal = 0; +my $summaryPassRateRun = 0; +my $summaryRunRate = 0; + +# +# Xml data +# + +my $xmlHeader; +my $xmlHeaderTableColumns; +my $xmlHeaderTableColumnsBrief; +my $xmlFooter; +my $xmlDataEmptyRow; +my $xmlSummaryData; +my $xmlData; +my $xmlDataCaseStatusDisabled; +my $xmlData2; +my $xmlDataBriefHeader; +my $xmlDataBrief; +my $xmlCfgFileBrief; +my $xmlHeaderTableColumnsAlt; +my $xmlCfgFileAltHeader; +my $xmlCfgFileAltData; + +InitXmlData(); + +#------------------------------------------------------------------------------------ +# GLOBAL CODE +#------------------------------------------------------------------------------------ + +my $argcount = scalar(@ARGV); + +my $optionSortCases = 0; +my $optionShowMessages = 0; +my $optionHtml = 0; +my $optionLogAllCases = 1; +my $optionNoLogs = 0; +my $optionNoSecurityTests = 0; +my $optionNoLiveTvTests = 0; +my $optionCaseIncludedInLog = 0; +my $optionGoodIsBetter = 1; +my $optionPrintCfgSummaries = 0; +my $optionCaseRunTimes = 0; +my $optionFinalDoc = 1; +my $optionFixFilename = ""; +my $optionDebug = 0; +my $optionCaseList = ""; +my $optionAltResults = 0; +my $optionLogFileName = "fusion"; + +while(scalar(@ARGV) >= 1) +{ + my $argument = shift(@ARGV); + + if($argument eq "-h") + { + ShowHelp(); + } + + elsif($argument eq "-e") + { + $optionShowMessages = 1; + } + + elsif($argument eq "-s") + { + $optionSortCases = 1; + } + + elsif($argument eq "-html") + { + $optionHtml = 1; + } + + elsif($argument eq "-logall") + { + $optionLogAllCases = 1; + } + + elsif($argument eq "-nologs") + { + $optionNoLogs = 1; + } + + elsif($argument eq "-nosecuritytests") + { + $optionNoSecurityTests = 1; + } + + elsif($argument eq "-nolivetvtests") + { + $optionNoLiveTvTests = 1; + } + + elsif($argument eq "-i") + { + $optionCaseIncludedInLog = 1; + } + + elsif($argument eq "-file") + { + $file = shift(@ARGV); + + JustFormatLogFile($file); + exit; + } + elsif($argument eq "-runtimes") + { + $optionCaseRunTimes = 1; + } + + elsif($argument eq "-xxx") + { + $optionCaseIncludedInLog = 1; + $optionNoLiveTvTests = 1; + $optionNoSecurityTests = 1; + $optionHtml = 1; + } + elsif($argument eq "-good") + { + $optionGoodIsBetter = 1; + } + elsif($argument eq "-cfgsum") + { + $optionPrintCfgSummaries = 1; + } + elsif($argument eq "-finalize") + { + $optionFinalDoc = 1; + } + elsif($argument eq "-fix") { + $optionFixFilename = shift(@ARGV); + FixExcelLogPaths(); + exit(); + } + elsif($argument eq "-debug") { + $optionShowMessages = 1; + $optionDebug = 1; + } + elsif($argument eq "-caselist") { + $optionCaseList = shift(@ARGV); + } + elsif($argument eq "-alt") { + $optionAltResults = 1; + } + elsif( $argument eq "-logfile") { + $optionLogFileName = shift(@ARGV); + } + else + { + ShowHelp(); + } +} + +UnzipAndCopyFiles(); + +my $totalExecutionTime = 0; + +my $caseLogOutDir = "testcase_logs\\testcase_logs\\"; + +my @caseList; + +if($optionCaseList ne "") +{ + ReadCaseList(\@caseList, $optionCaseList); +} + +# Find cfg files. +FindCfgFiles( ".", \@gCfgFiles ); + +# None found from current dir, see one dir lower. +FindCfgFiles( "..", \@gCfgFiles ) if( scalar( @gCfgFiles ) < 1 ); + +# Parse results +if($optionPrintCfgSummaries) +{ + PrintCfgSummaries(); +} +elsif( !$optionAltResults ) +{ + my $res = ReadTestReports(); + + if( $res == 0 ) + { + foreach my $file ( @globalTempFiles ) + { + unlink $file if( -e $file ); + } + print("No reports to read.\n"); + exit; + } + + #ReportNotDocumentedCases($NOT_DOCUMENTED_CASES_FILE); + + if($optionSortCases) + { + @cases = sort SortCases @cases; + } + + CalculateStats(); + + #WriteOfficeXml($XML_OUTPUT_FILE, 0); + WriteOfficeXml($XML_BRIEF_OUTPUT_FILE, 1); +} +else +{ + my @runs; + ReadTestReportsAlt(\@runs); + + WriteOfficeXmlAlt($XML_BRIEF_OUTPUT_FILE, \@runs); +} + +#print("Total run time: " . $totalExecutionTime . "\n") if( $optionCaseRunTimes ); + +foreach my $file ( @globalTempFiles ) +{ + unlink $file if( defined( $file ) && -e $file ); +} + +exit(); + +#------------------------------------------------------------------------------------ +# UnzipAndCopyFiles +#------------------------------------------------------------------------------------ +sub UnzipAndCopyFiles +{ + my @files; + system("rmdir ziptemp /s /q>NUL") if( -e "ziptemp" ); + + # Unzip zips in current directory and one level of subdirectories. -> ATS results. + GetAllFiles( ".", \@files, 1 ); + + foreach my $file ( @files ) + { + if( $file =~ m/\.zip/i ) + { + my $fileName = GetPathFileName( $file ); + + mkdir ("ziptemp"); + my $cmd = "unzip -o \"$file\" -d ziptemp\\$fileName >NUL"; + print("Unzipping $file\n") if( $optionShowMessages ); + system( $cmd ); + } + } + + undef( @files ); + GetAllFiles( ".", \@files, -1 ); + + # Copy files to current dir. + + my $currDir = cwd; + + foreach my $file ( @files ) + { + next if( -d $file ); + + $file =~ s/\//\\/g; + + # Do nothing for files which are in current dir. + my $srcDir = GetPathDir( $file ); + my $currpath = cwd; + $currpath =~ s/\//\\/g; + next if( $srcDir eq $currpath ); + + my $filename = GetPathFileName( $file ); + + # LOOP all testreport*.txt testscripter*.txt + # if file is testreport.txt + # lastFolder = last folder from the path + # LOOP all fusion*.txt + # LOOP remove tailing text from lastFolder starting from last index of '.' until it matches with folder of fusion*.txt + # pair fusion*.txt with testreport + + + if( ( $filename =~ m/testreport/i || $filename =~ m/testscripter/i ) && $filename =~ m/\.txt/i ) + #if( ( $filename =~ m/$optionLogFileName/i || $filename =~ m/testreport/i || $filename =~ m/testscripter/i ) && $filename =~ m/\.txt/i ) + { + my $dst = ""; + + if( $filename =~ m/testreport/i ) + { + # Pair testreports and logs. + CopyTestReportWithLog( $file, \@files ); + } + else + { + print("Copying file $file\n") if( $optionDebug ); + # For other files we just need unique filename and copy them. + $dst = $filename; + + if( -e $filename ) + { + # Separate file's name and extension. + my $name = ""; + my $ext = ""; + my $pos = index($filename, "."); + if( $pos != -1) + { + $ext = substr( $filename, $pos ); + $name = substr( $filename, 0, $pos ); + + my $count = 0; + while( 1 ) + { + $dst = "$name" . "_" . $count . $ext; + last if( ! -e "$dst" ); + $count++; + if( $count > 1000 ) + { + $dst = ""; + last; + } + } + } + } + push @globalTempFiles, $dst; + + print("Dest: $dst\n") if( $optionDebug ); + + copy( $file, $dst ) or die "Could not copy '$file' to '$dst'\n"; + } + } + } + + system("rmdir ziptemp /s /q>NUL") if( -e "ziptemp" ); +} + +sub CopyTestReportWithLog +{ + my ( $reportFileName, $refFiles ) = @_; + + print("\nTrying to pair: $reportFileName\n") if( $optionDebug ); + + my $reportPath = GetPathDir( $reportFileName ); + + my $logFileName = ""; + +#\ResultAndLogFiles_vod\22507.23325.1.4.25129-lab.net\TestReport.txt +#\ResultAndLogFiles_vod\22507.23325.1.4.25130-lab.net\Fusion.txt +# ^^^^^^^^^^^^^^^ matching part + # Find log file with about same path with the report. + while( 1 ) + { + # Check the log files. + foreach $file ( @$refFiles ) + { + $file =~ s/\//\\/g; + my $filename = GetPathFileName( $file ); + + if( $filename =~ m/$optionLogFileName/i ) + { + if( index( $file, $reportPath ) == 0 ) + { + $logFileName = $file; + + print("PAIRED: \n") if( $optionDebug ); + print("reportPath: $reportPath\n") if( $optionDebug ); + print("report: $reportFileName\n") if( $optionDebug ); + print("log : $logFileName\n") if( $optionDebug ); + + print("Report log pair: $logFileName\n") if( $optionShowMessages && !$optionDebug ); + last; + } + } + } + + last if( $logFileName ne "" ); + + # Remove all from last dot in the path. + my $pos = rindex( $reportPath, "." ); + last if( $pos == -1 ); + $reportPath = substr( $reportPath, 0, $pos ); + + # The first 4 numbers might be same with multiple reports and logs. Ignore file if match is not found before. + last if( rindex( $reportPath, "\\" ) == -1 ); + my $dotstr = substr( $reportPath, rindex( $reportPath, "\\" )+1 ); + last if( ! ( $dotstr =~ m/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ ) ); + print( "DOT: $dotstr\n" ) if( $optionDebug ); + } + + if( $logFileName eq "" ) + { + print("Could not find log file for: $reportFileName\n") if( $optionShowMessages ); + } + + my $dstReportFileName = ""; + my $dstReportLogName = ""; + + # Find first available name for the report in current directory. + my $fileNum = 0; + + my $filename = GetPathFileName( $reportFileName ); + + # Separate file's name and extension. + my $name = ""; + my $ext = ""; + + my $pos = index($filename, "."); + return if( $pos == -1); + + $ext = substr( $filename, $pos ); + $name = substr( $filename, 0, $pos ); + + # Find free filename. + while( 1 ) + { + $dstReportFileName = "$name" . "_" . $fileNum . $ext; + last if( ! -e "$dstReportFileName" ); + $fileNum++; + if( $fileNum > 1000 ) + { + die("Too many files to copy."); + } + } + + if( $logFileName ne "" ) + { + # Get new name for the log with same numbering. + + $filename = GetPathFileName( $logFileName ); + + $pos = index($filename, "."); + return if( $pos == -1); + + $ext = substr( $filename, $pos ); + $name = substr( $filename, 0, $pos ); + + $dstLogFileName = "$name" . "_" . $fileNum . $ext; + die("Log filename already exists.") if( -e "$dstLogFileName" ); # Shouldn't happen. + } + + # Copy the files. + + push @globalTempFiles, $dstReportFileName; + push @globalTempFiles, $dstLogFileName; + + print("Copying $reportFileName\n") if( $optionShowMessages ); + print("Dest: $dstReportFileName\n") if( $optionShowMessages ); + + copy( $reportFileName, $dstReportFileName ) or die "Could not copy '$reportFileName' to '$dstReportFileName'\n"; + + if( $logFileName ne "" ) + { + print("Copying $logFileName\n") if( $optionShowMessages ); + print("Dest: $dstLogFileName\n") if( $optionShowMessages ); + copy( $logFileName, $dstLogFileName ) or die "Could not copy '$logFileName' to '$dstLogFileName'\n"; + } +} + +#------------------------------------------------------------------------------------ +# ReadCaseList +# +#------------------------------------------------------------------------------------ +sub ReadCaseList +{ + my ($refList, $filename) = @_; + + if( open(FILE_HANDLE, ".\\" . $filename) ) + { + my @lines = ; + close(FILE_HANDLE); + foreach $line (@lines) + { + my $caseId; + + if($line =~ m/^case /i) + { + if($line =~ m/^case ET([0-9]+) /i) + { + $caseId = "ET" . $1; + } + else + { + $caseId = substr($line, 4); + } + RemoveWhiteSpaces(\$caseId); + push @$refList, $caseId; + } + } + } +} + +#------------------------------------------------------------------------------------ +# IsCaseInCaseList +# +#------------------------------------------------------------------------------------ +sub IsCaseInCaseList +{ + my ($caseNameOrId) = @_; + + return 1 if(scalar(@caseList) <= 0); + + my $caseIdFromName = GetCaseIdFromName($caseNameOrId); + + foreach $caseId (@caseList) + { + if($caseId eq $caseNameOrId) + { + return 1; + } + } + + foreach $caseId (@caseList) + { + if($caseId eq $caseIdFromName) + { + return 1; + } + } + + return 0; +} + +#------------------------------------------------------------------------------------ +# FixExcelLogPaths +# +# Changes the paths on lines: +# +# To: +# +# +# Because the absolute path does not work in Excel. +# +#------------------------------------------------------------------------------------ +sub FixExcelLogPaths +{ + if( open(FILE_HANDLE, ".\\" . $optionFixFilename) ) + { + my @lines = ; + close(FILE_HANDLE); + + if(!open(FILE_HANDLE, ">" . $optionFixFilename) ) + { + die("Could not write to file $file\n"); + } + + foreach my $line(@lines) + { + my $pos = index($line, "\\testcase_logs\\testcase_logs\\"); + if($pos != -1) + { + my $start = rindex($line, "\"", $pos); + my $remstr = substr($line, $start+1, $pos-$start + length("\\testcase_logs") ); + + $line = substr( $line, 0, index($line, $remstr) ) . + substr( $line, index($line, $remstr) + length($remstr) ); + + } + + print FILE_HANDLE ($line); + + } + close(FILE_HANDLE); + + print("Fixed paths in $optionFixFilename\n"); + } + else + { + die("Coult not open file $optionFixFilename\n"); + } +} + +#------------------------------------------------------------------------------------ +# CalculateStats +#------------------------------------------------------------------------------------ +sub CalculateStats +{ + $summaryCaseCount = scalar( @cases ); + $summaryPassedCases = 0; + $summaryFailedCases = 0; + $summaryCrashedCases = 0; + $summaryTimeoutCases = 0; + $summaryPassRateTotal = 0; + $summaryPassRateRun = 0; + $summaryRunRate = 0; + + foreach $case(@cases) + { + if(defined(@{$case}[$CASE_STATUS])) + { + my $status = @{$case}[$CASE_STATUS]; + + $summaryPassedCases++ if($status eq "PASSED"); + $summaryFailedCases++ if($status eq "FAILED"); + $summaryCrashedCases++ if($status eq "CRASHED"); + } + } + + my $runCases = $summaryPassedCases + $summaryFailedCases + $summaryCrashedCases; + + $summaryPassRateTotal = $summaryPassedCases / $summaryCaseCount * 100; + $summaryPassRateRun = $summaryPassedCases / $runCases * 100; + $summaryRunRate = $runCases / $summaryCaseCount * 100; +} + +#------------------------------------------------------------------------------------ +# SortCases +#------------------------------------------------------------------------------------ +sub SortCases() +{ + $aprio = 0; + $bprio = 0; + + #print @{$a}[$CASE_STATUS] . " - " . $a . " vs " . $b . " - " . @{$b}[$CASE_STATUS] . "\n"; + + if(@{$a}[$CASE_STATUS] eq "CRASHED") { $aprio = 5; } + elsif(@{$a}[$CASE_STATUS] eq "FAILED") { $aprio = 4; } + elsif(@{$a}[$CASE_STATUS] eq "PASSED") { $aprio = 3; } + + if(@{$b}[$CASE_STATUS] eq "CRASHED") { $bprio = 5; } + elsif(@{$b}[$CASE_STATUS] eq "FAILED") { $bprio = 4; } + elsif(@{$b}[$CASE_STATUS] eq "PASSED") { $bprio = 3; } + + if($aprio == $bprio) + { + return lc(@{$a}[$CASE_NAME]) cmp lc(@{$b}[$CASE_NAME]); + } + + return $bprio cmp $aprio; +} + + +#------------------------------------------------------------------------------------ +# ShowHelp +#------------------------------------------------------------------------------------ +sub ShowHelp { + +print <: Only formats defined log file into html +-runtimes: Result of the case will contain the case execution time in seconds. +-good: If case has passed once it will be marked as passed no matter how many + times it has failed. +-cfgsum: Prints summary info for cfgs: how many cases and how long the cfg did + take to execute. +-finalize +-fix if you save the file in Excel the log paths will come absolute and don't + work if moved to another directory. use this fix it. +-caselist : Only reports the cases in caselist.txt, see genrerun.pl for + file format. +-logfile : Sets filter for log filenames. Default is fusion. +-slogs: Reads STIF testscripter logs instead of custom logs. +These files will be generated: + test_cases.xml + test_cases_brief.xml + test_cases_notdocumented.txt + +Case specific log files are generated in testcase_logs directory and result +file has links to them. + +USAGE_EOF + + exit(); + +}; + +#------------------------------------------------------------------------------------ +# ReadReportLogs +# +# Parameters: +# $fileName +# $refLogLines +# +# Reads log file of specific TestReport. +# +# The function has two different behaviours: +# +# Filenames for test report and log must match. For example +# if test report file is TestReport_XXX.txt then fusion_XXX.txt is read if found. +# +# If fileName is * then *fusion*.txt files will be read one by one and processed by function CheckCaseEntriesInLog() +#------------------------------------------------------------------------------------ +sub ReadReportLogs +{ + my ($fileName, $refLogLines) = @_; + + return if($optionNoLogs || $optionPrintCfgSummaries); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + #default mask for logs + my $filemask = "^$optionLogFileName\.TXT"; + + #create file mask for logs if testreport.txt is in format: testreport_*.txt + if(index($fileName, "_") != -1) + { + my $spos = index($fileName, "_"); + my $epos = rindex($fileName, "."); + + $filemask = substr($fileName, $spos, $epos - $spos); + #print("filemask: $filemask\n"); + + #$filemask = "$optionLogFileName" . $filemask . "[a-z\-0-9_]*\.txt"; # this finds $optionLogFileName_xxx*.txt + $filemask = "$optionLogFileName" . $filemask . "\.txt"; # this finds only $optionLogFileName_xxx.txt + #print("filemask: $filemask\n"); + #die(); + } + + my $processLogsHere = 0; + + if($fileName eq "*") + { + $processLogsHere = 1; + $filemask = $optionLogFileName . "[a-z\-0-9_]*\.txt" + } + + my $i; + + #read the files into refLogLines array + foreach $file(@filelist) + { + #if($file =~ m/^$optionLogFileName[a-z0-9_]+\.TXT$/i or $file =~ m/^$optionLogFileName\.TXT$/i ) + if($file =~ m/$filemask/i ) + { + print("Reading log file: " . $file . "."); + + if( open(FILE_HANDLE, ".\\" . $file) ) + { + my @tempArray = ; + close(FILE_HANDLE); + + FormatFasttraceTraces(\@tempArray); + + if($processLogsHere) + { + FindAndMarkCaseEntriesInLog(\@tempArray, \@cases); + + CheckCaseEntriesInLog(\@tempArray); + } + else + { + while(scalar(@tempArray) > 0) + { + push @$refLogLines, (shift(@tempArray)); + } + } + } + } + } + + FindAndMarkCaseEntriesInLog($refLogLines, \@cases); +} + +#------------------------------------------------------------------------------------ +# GetReportLogFileNames +# +# Parameters: +# $fileName +# $refLogFiles +# +# Gets log filenames for specific testreport. +# +# The function has two different behaviours: +# +# Filenames for test report and log must match. For example +# if test report file is TestReport_XXX.txt then $optionLogFileName_XXX.txt is read if found. +# +# If fileName is * then *$optionLogFileName*.txt files will be read one by one and processed by function CheckCaseEntriesInLog() +#------------------------------------------------------------------------------------ +sub GetReportLogFileNames +{ + my ($fileName, $refLogFiles) = @_; + + return if($optionNoLogs || $optionPrintCfgSummaries); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + #default mask for logs + my $filemask = "^$optionLogFileName\.TXT"; + + #create file mask for logs if testreport.txt is in format: testreport_*.txt + if(index($fileName, "_") != -1) + { + my $spos = index($fileName, "_"); + my $epos = rindex($fileName, "."); + + $filemask = substr($fileName, $spos, $epos - $spos); + $filemask = "$optionLogFileName" . $filemask . "\.txt"; # this finds only $optionLogFileName_xxx.txt + } + + if($fileName eq "*") + { + $filemask = $optionLogFileName . "[a-z0-9_]*\.txt" + } + + foreach $file(@filelist) + { + if($file =~ m/$filemask/i ) + { + push @$refLogFiles, $file; + } + } +} + +#------------------------------------------------------------------------------------ +# FindAndMarkCaseEntriesInLog +# +# Parameters: +# $refLogLines +# +# Searches for case entries in the log and if found then marks the case in @cases array +#------------------------------------------------------------------------------------ +sub FindAndMarkCaseEntriesInLog +{ + my ($refLogLines, $refCases) = @_; + + my $line; + + print(" - Searching case start entries from log\n") if($optionShowMessages); + + my $startLineIndex = 0; + + # scan the log thru and mark if there's log start entries + for( my $i = 0; $i < scalar(@$refLogLines); $i++ ) + { + my $line = @$refLogLines[$i]; + + my $caseStartInLog = 0; + + my $caseId = ""; + + if($line =~ m/>>> Case start:/i) + { + $startLineIndex = $i; + $caseStartInLog = 1; + $caseId = substr($line, index($line, ">>> Case start:") + length(">>> Case start:")); + print("Found case start: $caseId\n") if($optionShowMessages); + } + + if($caseStartInLog) + { + RemoveWhiteSpaces(\$caseId); + + my $refCase = GetCase($caseId, $refCases); + + if(defined($refCase)) + { + @$refCase[$CASE_CHECK_RESULT_LOG_FILE] = 1; + @$refCase[$CASE_ENTRY_LOG_START] = $startLineIndex; + } + else + { + print("Case start in log found: $caseId\n") if($optionShowMessages); + print("ERROR! The start in log found but case is not found from report or cfg.\n"); + } + } + } +} + +#------------------------------------------------------------------------------------ +# FormatFasttraceTraces +# +# Parameters: +# $refLogArray +#------------------------------------------------------------------------------------ +sub FormatFasttraceTraces +{ + my ($refLogArray) = @_; + + my $ftDebug = 0; + + # strip fasttrace logging text from the start of lines + #[13:58:17.234] sti: MCU_ASCII_PRINTF; channel:0xE0; msg:$optionLogFileName.TXT 09/10/2006¿1:57:08¿C$optionLogFileName::CheckIsPluginRunning + + my $stripFasttrace = 0; + # find first occurance of Musti message, remove anything before that + my $i; + + for($i= 0; $i<100; $i++) + { + if(defined(@$refLogArray[$i])) + { + if(@$refLogArray[$i] =~ m/MCU_ASCII_PRINTF/i) + { + $stripFasttrace = 1; + last; + } + } + } + + print("fasttrace: end $i, strip: $stripFasttrace\n") if($ftDebug); + + #remove the fasttrace specific lines + print("fasttrace: lines before: " . scalar(@$refLogArray) . "\n") if($ftDebug); + + splice(@$refLogArray, 0, $i) if($stripFasttrace); + + return if(!$stripFasttrace); + + print("fasttrace: lines " . scalar(@$refLogArray) . "\n") if($ftDebug); + + #remove the fasttrace line startings and change format of STIF messages + + for($i = 0; $i >>> Case start: " format, otherwise it will be not be recognized later + if(@$refLogArray[$i] =~ m/Starting testcase \[([[a-z0-9_]+) ($regexpCaseName)\]/i) + { + print("debug: " . @$refLogArray[$i] . "\n"); + @$refLogArray[$i] = substr(@$refLogArray[$i], 0, index(@$refLogArray[$i], "Starting testcase")); + + my $timeStr = FasttraceLogFindIptvTraceTime($refLogArray, $i); + + @$refLogArray[$i] .= "$optionLogFileName.TXT $timeStr\t>>> Case start: $1" . "\r\n"; + + print("fasttrace: '" . @$refLogArray[$i] . "'\n") if($ftDebug); + + #@$refLogArray[$i] = "[14:38:37.953] sti: MCU_ASCII_PRINTF; channel:0xE0; msg:$optionLogFileName.TXT 18/10/2006\t2:37:34\t>>> Case start: $1"; + } + + if(@$refLogArray[$i] =~ m/channel\:[0-9a-z]+; msg:$optionLogFileName.TXT [0-9]+\/[0-9]+\/[0-9]+/i) + { + @$refLogArray[$i] = substr(@$refLogArray[$i], index(@$refLogArray[$i], "msg:$optionLogFileName.TXT") + length("msg:$optionLogFileName.TXT") + 1); + + #replace fasttrace tab chars + @$refLogArray[$i] =~ s/¿/\t/g; + #print(@$refLogArray[$i]); + + } + else + { + # if there's no match then this is not a trace for $optionLogFileName + splice(@$refLogArray, $i, 1); + $i--; + } + } +} + + +#------------------------------------------------------------------------------------ +# FastTraceLogFindIptvTraceTime +# +# Parameters: +# $refLines: reference to array of the log line +# $startLine: line where to start looking for +# +# Finds next time stamp of Iptvengine from Fasttrace log +#------------------------------------------------------------------------------------ +sub FasttraceLogFindIptvTraceTime +{ + my ($refLines, $startLine) = @_; + + #find next trace of iptvengine and get the time and date + my $timeStr = ""; + for(my $e = $startLine+1; $e < scalar(@$refLines); $e++) + { + if(@$refLines[$e] =~m/msg:$optionLogFileName.TXT/) + { + my $line = @$refLines[$e]; + #remove the fasttrace trace from line start, we don't want it's time + $line = substr($line, index($line, "msg:$optionLogFileName.TXT")); + + if($line =~ m/([0-9]+\/[0-9]+\/[0-9]+)/i) + { + $timeStr .= $1 . "\t"; + } + + if($line =~ m/([0-9]+:[0-9]+:[0-9]+)/i) + { + $timeStr .= $1; + } + last if($timeStr ne ""); + } + } + + return $timeStr; +} + +#------------------------------------------------------------------------------------ +# ReportNotDocumentedCases +# +# Parameters: +# $file +# +# Writes the @notDocumentedCases array into a file +#------------------------------------------------------------------------------------ +sub ReportNotDocumentedCases +{ + my ($file) = @_; + + if(scalar(@notDocumentedCases) > 0) + { + if(!open(FILE_HANDLE, ">" . $file) ) + { + print("ERROR! Could not open file '" . $file . "'\n"); + } else { + print FILE_HANDLE ( @notDocumentedCases ); + close(FILE_HANDLE); + print("Report " . $NOT_DOCUMENTED_CASES_FILE . " written.\n"); + } + } else + { + print("All cases are documented."); + } +} + +#------------------------------------------------------------------------------------ +# ReadTestReports +# +# Reads TestReportXX.txt files from the current directory and updates the cases with the results. +# Reads also logs for the report and creates case specific logs. +#------------------------------------------------------------------------------------ +sub ReadTestReports +{ + # Read filelist of current directory + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + my $readSomething = 0; + + my @testScripterLogLines; + ReadTestScripterLogs( \@testScripterLogLines ); + + # Read reports and logs in the current directory + foreach $file(@filelist) + { + next if( -d $file or $file eq "." or $file eq ".."); + + # Read results STIF testreport + if($file =~ m/^TestReport[a-z\-0-9_]+\.txt$/i or $file =~ m/^TestReport\.txt$/i ) + { + if($optionShowMessages) { print("***************************\n"); }; + print("Report file: " . $file . "\n"); + + my @logFiles; + my @caseResults; + + ReadTestRunInfoFromStifReport( $file, \@caseResults, \@logFiles ); + ParseResultsAndLogs( \@caseResults, \@logFiles, \@testScripterLogLines ); + + undef(@logFiles); + undef(@caseResults); + + $readSomething++; + } + } + + return if($optionPrintCfgSummaries); + + # No testreports found. Read all logs and parse them. + if($readSomething == 0) + { + print("\nNo test reports found in the current directory. Trying to read all the logs.\n"); + + my @logFileLines; + + ReadReportLogs("*", \@logFileLines); + + if( scalar( @logFileLines ) > 0 ) + { + $readSomething = 1; + } + + undef(@logFileLines); + } + + return $readSomething; +} + +#------------------------------------------------------------------------------------ +# ReadTestReportsAlt +# +# Every test report is one run and those should have as much same cases as possible. +#------------------------------------------------------------------------------------ +sub ReadTestReportsAlt +{ + my ($refRuns) = @_; + + # Read filelist of current directory + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + my @runs; + + # Read reports and logs in the current directory + foreach $file(@filelist) + { + if($file eq "." or $file eq "..") {next}; + + # Read results STIF testreport + if($file =~ m/^TestReport[a-z0-9_]+\.txt$/i or $file =~ m/^TestReport\.txt$/i ) + { + if($optionShowMessages) { print("***************************\n"); }; + print("Report file: " . $file . "\n"); + + # Store report filename, run date and then cases into array + + # Read date from report + if( !open(FILE_HANDLE, $file) ) { + print("ERROR! Could not open file '" . $file . "'\n"); + return; + } + my @array = ; + close(FILE_HANDLE); + + #Monday 25th August 2008 + my @pieces = split(' ', $array[1]); + + $pieces[1] =~ s/st//; + $pieces[1] =~ s/nd//; + $pieces[1] =~ s/rd//; + $pieces[1] =~ s/th//; + + undef(@array); + + my @runInfo; + $runInfo[0] = $file; + $runInfo[1] = substr( $pieces[0], 0, 3 ) . " " . $pieces[1] . " " . substr( $pieces[2], 0, 3 ); + + my @runResults; + my @logFiles; + ReadTestRunInfoFromStifReport($file, \@runResults, \@logFiles ); + $runInfo[2] = \@runResults; + + push @$refRuns, \@runInfo; + } + } +} + +#------------------------------------------------------------------------------------ +# ReadTestScripterLogs +#------------------------------------------------------------------------------------ +sub ReadTestScripterLogs +{ + my ( $refLogLines ) = @_; + + return if($optionNoLogs || $optionPrintCfgSummaries); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + foreach $file(@filelist) + { + if($file =~ m/^testscripter[a-z0-9_]+.txt/i ) + { + print("Reading scripter log: $file\n") if( $optionDebug ); + if( open(FILE_HANDLE, $file) ) + { + my @tempArray = ; + close(FILE_HANDLE); + + while(scalar(@tempArray) > 0) + { + push @$refLogLines, ( shift( @tempArray ) ); + } + undef(@tempArray); + } + else + { + print("ERROR: Could not open the log file: $file!\n"); + } + } + else + { + print("Not a scripter log: $file\n") if( $optionDebug ); + } + } +} + + +#------------------------------------------------------------------------------------ +# ReadTestReportDates +# +# Reads the date from each testreport in current directory +#------------------------------------------------------------------------------------ +sub ReadTestReportDates +{ + my ($refDates) = @_; + + # Read filelist of current directory + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + my @runs; + + # Read reports and logs in the current directory + foreach $file(@filelist) + { + if($file eq "." or $file eq "..") {next}; + + # Read results STIF testreport + if($file =~ m/^TestReport[a-z0-9_]+\.txt$/i or $file =~ m/^TestReport\.txt$/i ) + { + my @fileDate; + $fileDate[0] = $file; + + if( !open(FILE_HANDLE, $file) ) { + print("ERROR! Could not open file '" . $file . "'\n"); + return; + } + my @array = ; + close(FILE_HANDLE); + + #Monday 25th August 2008 + my @pieces = split(' ', $array[1]); + + $pieces[1] =~ s/st//; + $pieces[1] =~ s/nd//; + $pieces[1] =~ s/rd//; + $pieces[1] =~ s/th//; + + $fileDate[1] = substr( $pieces[0], 0, 3 ) . " " . $pieces[1] . " " . substr( $pieces[2], 0, 3 ); + + undef(@array); + + push @$refDates, \@fileDate; + } + } +} + +#------------------------------------------------------------------------------------ +# ParseTimeFromLine +# +#------------------------------------------------------------------------------------ +sub ParseTimeFromLine +{ + my ($line) = @_; + + my $timestr = ""; + + if($line =~ m/([0-9]+)(:[0-9]+:[0-9]+\,[0-9]*)/i || $line =~ m/([0-9]+)(:[0-9]+:[0-9]+\.[0-9]*)/i) + { + $timestr = "" . $1 . $2; + if($1 > 12) + { + $timestr = "" . ($1-12) . $2; + } + } + + return $timestr; +} + +#------------------------------------------------------------------------------------ +# ReadTestRunInfoFromStifReport +# +# Parameters: +# $file, the testreport +# $refCaseResults, results for all cases of the testreport +# $refLogFiles, filenames for the log files of the testreport +#------------------------------------------------------------------------------------ +sub ReadTestRunInfoFromStifReport +{ + my ($file, $refCaseResults, $refLogFiles) = @_; + + if( !open(FILE_HANDLE, $file) ) { + print("ERROR! Could not open file '" . $file . "'\n"); + return; + } + my @array = ; + close(FILE_HANDLE); + + # Get log files for the report + GetReportLogFileNames($file, $refLogFiles); + + my $index = 0; + my $line = ""; + + for(my $i = 0; $i < scalar(@array); $i++) + { + $line = $array[$i]; + RemoveWhiteSpaces(\$line); + +#[testscripter_iptvservicetest][C:\TestFramework\IptvServiceTest.cfg][10] Title:[ET9009 Set id] +#[testscripter][c:\testframework\iptvvoddlapitest2.cfg][2] Title:[ET12100 Purchase] +# StartTime: 8:54:23.5565 PM, EndTime: 8:54:24.3471 PM +# Result: 0 [] ==> PASSED +# Info: xxx + + # found a start of a result + #[1] Title:[ET1000 Add multiple Iaps] + my $cfgFile = ""; + + if($line =~ m/([a-z_0-9.]+)\]\[[0-9]+\][ ]+Title:\[/i) + { + $cfgFile = $1; + if($optionShowMessages) { print(" - Cfg: $cfgFile\n"); }; + + for( my $e = 0; $e < scalar( @gCfgFiles ); $e++ ) + { + if( $gCfgFiles[$e] =~ m/$cfgFile/i ) + { + my $caseCount = ParseCfg( $gCfgFiles[$e] ); + $gCfgFiles[$e] = ""; # We don't want to read it again. + } + } + } + + if($line =~ m/\[[0-9]+\][ ]+Title:\[($regexpCaseName)\]$/i) + { + if($optionShowMessages) { print(" - Case: " . $1 . "\n"); }; + + #get the case name + my $caseName = $1; + my $caseId = GetCaseIdFromName($caseName); + my $caseRunTime = CountCaseRunTime($array[$i+1]); + + # Save case report lines for later use + my $caseLine1 = $array[$i]; + my $caseLine2 = $array[$i+1]; + my $caseLine3 = $array[$i+2]; + + # Read the case result + + # StartTime: 3:54:10.1670 PM, EndTime: 3:54:23.8226 PM + $line = $array[$i+2]; + RemoveWhiteSpaces(\$line); + + my $info = ""; + my $result = "N/A"; + my $status = "$caseDefaultStatus"; + my $reason = ""; + + # Result: 0 [] ==> PASSED / something + if($line =~ m/^Result:[ ]([-]*[0-9]+)[ ]\[[\w]*\][ ]==>[ ]([\w ]+)$/i) + { + $result = $1; + $status = $2; + } + # Result: -2 [CTestRunner::RunError [CTestRunner::ExecuteCommandL returned error]] ==> FAILED + # Result: -2 [CTestRunner::ExecuteCommandL returned error] ==> FAILED + elsif($line =~ m/^Result:[ ]([-]*[0-9]+)[ ]\[([\w: ]+)\][ ]==>[ ]([\w]+)$/i or + $line =~ m/^Result:[ ]([-]*[0-9]+)[ ]\[[\w: ]+\[([\w: ]+)\]\][ ]==>[ ]([\w]+)$/i ) + { + $result = $1; + $status = $3; + $reason = $2; + } + + #CaseExecutionResult: Test case execution fails with -15 + elsif($line =~ m/^CaseExecutionResult:[ ]Test case execution fails with ([-]*[0-9]+)$/i) + { + $result = $1; + $status = "FAILED"; + $reason = "Test case execution failed."; + } + + # CaseExecutionResult: Leave during case: with -4 + elsif($line =~ m/^CaseExecutionResult:[ ]Leave during case: with ([-]*[0-9]+)$/i) + { + $result = $1; + $status = "FAILED"; + $reason = "Leave during case"; + } + #CaseExecutionResult: Crash reason:Error in test ca with 69 + #CaseExecutionResult: Crash reason:IptvEngineServer with 13 + elsif($line =~ m/^CaseExecutionResult:[ ]Crash reason:([\w_ \-]+)[ ]with[ ]([-]*[0-9]+)$/i) + { + $result = $2; + $status = "CRASHED"; + $reason = $1; + } + + # Result: -2 [Crash reason:KERN-EXEC] ==> FAILED + elsif($line =~ m/^Result:[ ]([-]*[0-9]+)[ ]\[Crash reason:([\w\-:\. ]+)\] ==> ([\w]+)/i) + { + $result = $1; + $status = "CRASHED"; + $reason = $2; + } + + # CaseExecutionResult: TestModule loading fails, cannot connect to the TestModule with -2 + elsif($line =~ m/^CaseExecutionResult: TestModule loading fails, cannot connect to the TestModule with ([-]*[0-9]+)/i) + { + $result = $1; + $status = "FAILED"; + $reason = "Test module loading failed."; + } + else + { + print("Error while parsing case result line: " . $line . "\n"); + } + + $line = $array[$i+3]; + RemoveWhiteSpaces(\$line); + + # Info: xxx + if($line =~ m/^Info:/i) + { + $info = substr($line, 5) . " / "; + RemoveWhiteSpaces(\$info); + $info .= " "; + } + + my @caseResult; + + $caseResult[$CASE_CFG_FILE] = $cfgFile; + $caseResult[$CASE_NAME] = $caseName; + $caseResult[$CASE_ID] = $caseId; + $caseResult[$CASE_RUN_TIME_SECONDS] = $caseRunTime; + $caseResult[$CASE_NOTE] = $info; + $caseResult[$CASE_RESULT] = $result; + $caseResult[$CASE_STATUS] = $status; + $caseResult[$CASE_REASON] = $reason; + $caseResult[$CASE_REPORTLINE1] = $caseLine1; + $caseResult[$CASE_REPORTLINE2] = $caseLine2; + $caseResult[$CASE_REPORTLINE3] = $caseLine3; + + push @$refCaseResults, \@caseResult; + } + } +} + +#------------------------------------------------------------------------------------ +# ParseResultsAndLogs +# +# Parameters: +# $refCaseResults +# $refLogFiles +# $refTestScripterLogLines +#------------------------------------------------------------------------------------ +sub ParseResultsAndLogs +{ + my ($refCaseResults, $refLogFiles, $refTestScripterLogLines) = @_; + + my @logLines; + + # Read log files + foreach $file (@$refLogFiles) + { + $file =~ s/\//\\/g; + + print("Reading log file: " . $file . " .. "); + + if( open(FILE_HANDLE, $file) ) + { + my @tempArray = ; + close(FILE_HANDLE); + + FormatFasttraceTraces(\@tempArray); + print " .. "; + + while(scalar(@tempArray) > 0) + { + push @logLines, (shift(@tempArray)); + } + print " done.\n"; + + undef(@tempArray); + } + else + { + print("ERROR: Could not open the log file: $file!\n"); + } + } + + FindAndMarkCaseEntriesInLog( \@logLines, $refCaseResults ); + + my @caseSpecificLogs; + + foreach $refCaseResult (@$refCaseResults) + { + my $cfgFile = @$refCaseResult[$CASE_CFG_FILE]; + my $caseName = @$refCaseResult[$CASE_NAME]; + my $caseId = @$refCaseResult[$CASE_ID]; + my $caseRunTime = @$refCaseResult[$CASE_RUN_TIME_SECONDS]; + my $info = @$refCaseResult[$CASE_NOTE]; + my $result = @$refCaseResult[$CASE_RESULT]; + my $status = @$refCaseResult[$CASE_STATUS]; + my $reason = @$refCaseResult[$CASE_REASON]; + my $reportLine1 = @$refCaseResult[$CASE_REPORTLINE1]; + my $reportLine2 = @$refCaseResult[$CASE_REPORTLINE2]; + my $reportLine3 = @$refCaseResult[$CASE_REPORTLINE3]; + + if($optionShowMessages) { print(" - Case: " . $caseName . "\n"); }; + + # Create case specific log into the log directory + my $caseLogFile = GetCaseField($caseId, $CASE_LOG_FILE); + my $caseScripterLogFile = GetCaseField($caseId, $CASE_LOG_FILE_SCRIPTER); + my $refCaseDesc = GetCaseDesc($caseId); + + $caseLogFile = GetFileNameForCaseLog( $reportLine1, $reportLine2, $reportLine3 ); + $caseScripterLogFile = GetFileNameForCaseLog( $reportLine1, $reportLine2, $reportLine3, "_scripter" ); + + if( -e $caseLogFile ) + { + unlink ( $caseLogFile ); + } + + if( -e $caseScripterLogFile ) + { + unlink ( $caseScripterLogFile ); + } + + my @logInfo; + $logInfo[0] = $caseLogFile; + if( defined( @$refCaseResult[$CASE_CHECK_RESULT_LOG_FILE] ) ) + { + # Case start entry trace was found from log. + $logInfo[1] = @$refCaseResult[$CASE_ENTRY_LOG_START]; + } + else + { + $logInfo[1] = -1; + } + $logInfo[2] = $reportLine1; + $logInfo[3] = $reportLine2; + $logInfo[4] = $reportLine3; + $logInfo[5] = $refCaseDesc; + $logInfo[6] = $caseScripterLogFile; + push @caseSpecificLogs, \@logInfo; + + # Update case + my $refCase = GetCase($caseId, \@cases); + if(!defined($refCase)) + { + $refCase = GetCaseByNameOnly($caseName); + } + + if(defined($refCase)) + { + UpdateCase($refCase, $caseLogFile, $caseScripterLogFile, $result, $status, $info, $reason, $caseRunTime); + } + else + { + # Case doesn't exist yet, add it. + my @case; + $case[$CASE_NAME] = $caseName; + $case[$CASE_ID] = $caseId; + $case[$CASE_RUN_TIMES] = 0; + $case[$CASE_CRASHED] = 0; + $case[$CASE_FAILED] = 0; + $case[$CASE_PASSED] = 0; + $case[$CASE_STATUS] = "$caseDefaultStatus"; + $case[$CASE_PURPOSE] = "N/A"; + $case[$CASE_MEANS] = "N/A"; + $case[$CASE_REQUIRED_SETTINGS] = "N/A"; + $case[$CASE_RELATED_REQUIREMENTS] = "N/A"; + $case[$CASE_VERIFICATION] = "N/A"; + $case[$CASE_NOTE] = "N/A"; + $case[$CASE_REASON] = ""; + $case[$CASE_RESULT] = ""; + $case[$CASE_LOG_FILE] = ""; + $case[$CASE_LOG_FILE_SCRIPTER] = ""; + $case[$CASE_CHECK_RESULT_LOG_FILE] = 0; + $case[$CASE_CFG_FILE] = $cfgFile; + $case[$CASE_RUN_TIME_SECONDS] = 0; + + $refCase = GetCaseByNameOnly($caseName); + + UpdateCase(\@case, $caseLogFile, $caseScripterLogFile, $result, $status, $info, $reason, $caseRunTime); + + # Insert case after other cases from same CFG, if any. + + my $indexToInsert = -1; + + for( my $i = 0; $i < scalar(@cases); $i++ ) + { + my $case = $cases[$i]; + + if( defined(@$case[$CASE_CFG_FILE]) ) + { + if( @$case[$CASE_CFG_FILE] eq $cfgFile ) + { + $indexToInsert = $i; + } + } + } + + if( $indexToInsert == -1 ) + { + push @cases, [ @case ]; + } + else + { + splice @cases, $indexToInsert+1, 0, [ @case ]; + } + } + } + + my $caseCount = scalar( @$refCaseResults ); + + my @testScripterLogCaseLocations; + PrepareTestScripterLogs( $refTestScripterLogLines, \@testScripterLogCaseLocations ); + WriteCaseSpecificScripterLogs( \@caseSpecificLogs, $refTestScripterLogLines, \@testScripterLogCaseLocations ); + WriteCaseSpecificLogs( \@caseSpecificLogs, $caseCount, \@logLines ); + + if($caseCount >= 10 && $optionShowMessages == 0) + { + print("\n"); #line break for the progress bar + } + elsif($optionShowMessages == 0) + { + print("##########\n"); # fake it + } + + undef(@logLines); +} + +#------------------------------------------------------------------------------------ +# WriteCaseSpecificLogs +# +# Parameters: +# $refCaseSpecificLogs +# $caseCount +# $refLogLines +#------------------------------------------------------------------------------------ +sub WriteCaseSpecificLogs +{ + my ($refCaseSpecificLogs, $caseCount, $refLogLines ) = @_; + + my $caseLogProgress = 0; + + foreach my $refLogInfo ( @$refCaseSpecificLogs ) + { + #@logInfo[1] = @$refCaseResult[$CASE_ENTRY_LOG_START]; + + my $caseLogFile = @$refLogInfo[0]; + my $reportLine1 = @$refLogInfo[2]; + my $reportLine2 = @$refLogInfo[3]; + my $reportLine3 = @$refLogInfo[4]; + my $refCaseDesc = @$refLogInfo[5]; + + my $logWritten = 0; + if( @$refLogInfo[1] != -1 ) + { + # Case start entry trace found from log files. + $logWritten = WriteCaseLogFromEntry($caseLogFile, $refLogLines, @$refLogInfo[1], $reportLine1, $reportLine2, $reportLine3); + } + + if( !$logWritten ) + { + # Use case start and end times to write case specific log. + WriteCaseLog($caseLogFile, $refLogLines, $refCaseDesc, $reportLine1, $reportLine2, $reportLine3); + } + + # Show simple progress bar + if($caseCount >= 10 && $optionShowMessages == 0) + { + $caseLogProgress++; + if($caseLogProgress > $caseCount/10) + { + $caseLogProgress = 0; + print("#"); + } + } + } + + if($caseCount >= 10 && $optionShowMessages == 0) + { + print("\n"); #line break for the progress bar + } + elsif($optionShowMessages == 0) + { + print("##########\n"); # fake it + } +} + +#------------------------------------------------------------------------------------ +# PrepareTestScripterLogs +# +# Parameters: +# $refTestScripterLogLines +# $refTestScripterLogCaseLocations +#------------------------------------------------------------------------------------ +sub PrepareTestScripterLogs +{ + my ($refTestScripterLogLines, $refTestScripterLogCaseLocations ) = @_; + + for( my $i = 0; $i < scalar(@$refTestScripterLogLines); $i++ ) + { + my $line = @$refTestScripterLogLines[$i]; + + if( $line =~ m/RunTest:/ ) + { + push @$refTestScripterLogCaseLocations, ( $i ); + } + } +} + +#------------------------------------------------------------------------------------ +# WriteCaseSpecificScripterLogs +# +# Parameters: +# $refLogFiles +# $refCaseResults +# $refTestScripterLogCaseLocations +#------------------------------------------------------------------------------------ +sub WriteCaseSpecificScripterLogs +{ + my ($refCaseSpecificLogs, $refScripterLogLines, $refTestScripterLogCaseLocations ) = @_; + + foreach my $refLogInfo ( @$refCaseSpecificLogs ) + { + my $caseLogFile = @$refLogInfo[6]; + my $reportLine1 = @$refLogInfo[2]; + my $reportLine2 = @$refLogInfo[3]; + my $reportLine3 = @$refLogInfo[4]; + my $refCaseDesc = @$refLogInfo[5]; + + WriteCaseLogFromTestScripterLogs( $caseLogFile, $refScripterLogLines, $refTestScripterLogCaseLocations, $refCaseDesc, $reportLine1, $reportLine2, $reportLine3); + } +} + +#------------------------------------------------------------------------------------ +# WriteCaseLogFromTestScripterLogs +# +#------------------------------------------------------------------------------------ +sub WriteCaseLogFromTestScripterLogs +{ + my ( $caseLogFile, $refLogLines, $refTestScripterLogCaseLocations, $refCaseDesc, $line1, $line2, $line3 ) = @_; + + print("### WriteCaseLogFromTestScripterLogs") if( $optionDebug ); + + # Don't generate log files if we only print summary + if($optionPrintCfgSummaries) + { + return; + } + + RemoveWhiteSpaces(\$line1); + RemoveWhiteSpaces(\$line2); + RemoveWhiteSpaces(\$line3); + + my $lineBreak = "\n"; + $lineBreak = "
\n" if($optionHtml); + + my $caseName = ""; + + if($line1 =~ m/\[[0-9]+\][ ]+Title:\[([a-z0-9]+$regexpCaseName)\]$/i) + { + #"' ultraedit + $caseName = $1; + print(" Writing scripter log for: $caseName.\n") if($optionShowMessages); + } + else + { + return; + } + + # Write header for case + + my @writeArray; + + # split the first line + push @writeArray, ( "
" ) if($optionHtml); + push @writeArray, ( substr($line1, 0, index($line1, "Title:")) . $lineBreak ); + push @writeArray, ( substr($line1, index($line1, "Title:")) . $lineBreak ); + my $title = substr($line1, index($line1, "Title:")); + + #($line1 . "\n"); + push @writeArray, ($line2 . $lineBreak); + push @writeArray, ($line3 . $lineBreak); + push @writeArray, ("\n"); + push @writeArray, ( "
" ) if($optionHtml); + + # Include the script for the case in the file? + + if($optionCaseIncludedInLog) + { + foreach $linexxx (@{$refCaseDesc}) + { + push @writeArray, ("$linexxx"); + push @writeArray, ($lineBreak) if($optionHtml); + } + push @writeArray, ( "
" ) if($optionHtml); + push @writeArray, ("\n"); + } + + # Create log directory + + if ( !(-e "testcase_logs") ) + { + mkdir("testcase_logs"); + } + + if ( !(-e "$caseLogOutDir") ) + { + mkdir($caseLogOutDir, 0755); + } + + # Find start and end lines for the case. + my $startLine = -1; + my $endLine = -1; + + my $caseNameRegexp = $caseName; + $caseNameRegexp =~s/\)/\\\)/; + $caseNameRegexp =~s/\(/\\\(/; + + # Try to find case start from cached locations. + foreach my $lineNum ( @$refTestScripterLogCaseLocations ) + { + if( @$refLogLines[$lineNum] =~ m/RunTest: $caseNameRegexp/ ) + { + print(" - found cached start: $lineNum") if( $optionDebug ); + $startLine = $lineNum; + last; + } + } + + for( my $i = $startLine; $i < scalar(@$refLogLines); $i++ ) + { + $i++ if( $i < 0 ); + + my $line = @$refLogLines[$i]; + + next if( !defined $line ); + + # Case start was not found from cached locations, find it as we go thru the lines. + if( $startLine == -1 ) + { + if( $line =~ m/RunTest: $caseNameRegexp/ ) + { + print(" - found start: $line") if( $optionDebug ); + $startLine = $i; + } + } + else + { + if( $line =~ m/\*\*\*Testcase [a-z]+\*\*\*/i ) + { + print(" - found end: $line") if( $optionDebug ); + $endLine = $i + 1; + last; + } + } + } + + if( $startLine == -1 || $endLine == -1 ) + { + return; + } + + # Write the log file + + my $fileMode = ">>"; + + print(" - Case log file: " . $caseLogFile ."\n") if($optionShowMessages); + + if( open(FILE_HANDLE, $fileMode . $caseLogFile) ) + { + if($optionHtml) + { + print FILE_HANDLE ( + "\n" . + "\n" . + "$title\n" . + "\n" . + "\n" . + "\n" + ); + } + + foreach $line(@writeArray) + { + print FILE_HANDLE ($line); + } + + for( my $i = $startLine; $i < $endLine; $i++ ) + { + my $line = @$refLogLines[$i]; + FormatLogLine(\$line) if($optionHtml); + + print FILE_HANDLE ($line); + } + + if($optionHtml) + { + print FILE_HANDLE ( + "\n" . + "" + ); + } + + print FILE_HANDLE ( $lineBreak ); + print FILE_HANDLE ( $lineBreak ); + + close FILE_HANDLE; + + } else + { + print("ERROR: Could not write to file: " . $caseLogFile . "\n"); + } +} + +#------------------------------------------------------------------------------------ +# CheckCaseEntriesInLog +# +# Parameters: +# $refLogLines: reference to array of log lines +# +# Finds if there's log entries for cases that are not reported in the testreport files +# and create case specific logs for them +#------------------------------------------------------------------------------------ +sub CheckCaseEntriesInLog +{ + my ($refLogLines) = @_; + + foreach $case(@cases) + { + if(@{$case}[$CASE_CHECK_RESULT_LOG_FILE] == 1) + { + @{$case}[$CASE_CHECK_RESULT_LOG_FILE] = 0; + +#create the next lines for WriteCaseLog function + +#line1: [testscripter_iptvservicemanagementapitestasync][c:\TestFramework\IptvServiceManagementApiTestAsync.cfg][2] Title:[ET08203 Add valid hardcoded service_0 ASYNC] +#line2: StartTime: 3:06:14.2212 PM, EndTime: 3:06:18.1037 PM +#line3: Result: 0 [] ==> PASSED + + #starttime = case startline + #endttime = next case starttline | lastline + + my $line1 = "[unknown.cfg][0] Title:[" . @{$case}[$CASE_NAME] . "]"; + my $line2 = ""; + my $line3 = "Result: 0 [] ==> UNKNOWN"; + + my $startTime = ""; + my $endTime = ""; + my $status = "UNKNOWN"; + my $caseLogFile = ""; + my $result = "0"; + my $info = ""; + my $reason = ""; + + my $caseId = ""; + foreach $line(@$refLogLines) + { + # take the times from lines where is case start text + + if($startTime eq "" && $line =~ m/>>> Case start:/i) + { + $caseId = substr($line, index($line, ">>> Case start:") + length(">>> Case start:")); + + RemoveWhiteSpaces(\$caseId); + + # set start time if case matches + #02/08/2006 12:15:42 >>> Case start: ET00000 caseId + if($caseId eq @{$case}[$CASE_ID]) + { + #print("*** Reading case name\n\n"); + if($line =~ m/([0-9]+):([0-9]+):([0-9]+)/) + { + #print("CASESTART: $line\n"); + $startTime = "$1:$2:$3.0000"; + #print("*** READ TIME $startTime\n\n"); + next; # skip the rest of loop otherwise endtime will be same + } + } + } + + # find endtime for case if starttime is set + if($startTime ne "") + { + #[14:38:40.641] sti: MCU_ASCII_PRINTF; channel:0xE0; msg:TestCase [ET1024 Sort IapList when it has no IAPs] finished with verdict[0] + + #die("$line") if($line =~m/$caseId/i); + #die("line: $line\n") if($line =~ m/finished with verdict/); + + if($line =~ m/$caseId/i and $line =~ m/finished with verdict\[([-]*[0-9]+)\]/) + { + + $result = $1; + + if($1 eq "0") + { + $status = "PASSED"; + $line3 = "Result: $1 [] ==> PASSED"; + } + else + { + $status = "FAILED"; + $line3 = "Result: $1 [] ==> FAILED"; + } + } + + #if line has time then grab it + if($line =~ m/([0-9]+):([0-9]+):([0-9]+)/) + { + $endTime = "$1:$2:$3.9999"; + # stop searching when next case is starting + if( ($line =~ m/>>> Case start:/i || $line =~ m/>>> Case end./i) and !($line =~ m/$caseId/) ) + { + #print("CASEEND: $line\n"); + last; + } + } + } + + } + + $line2 = "StartTime: $startTime PM, EndTime: $endTime PM"; + + #print("l1: $line1\nl2: $line2\nl3: $line3\n\n"); + + my $refCaseDesc = GetCaseDesc($caseId); + + $caseLogFile = GetFileNameForCaseLog( $line1, $line2, $line3 ); + + WriteCaseLog($caseLogFile, $refLogLines, $refCaseDesc, $line1, $line2, $line3); + + my $refCase = GetCase($caseId, \@cases); + + UpdateCase($refCase, $caseLogFile, "", $result, $status, $info, $reason, 0); + } + } +} + +sub UpdateCase +{ + my ($refCase, $caseLogFile, $caseScripterLogFile, $result, $status, $info, $reason, $caseRunTimeSeconds) = @_; + + if($optionShowMessages) { print(" - Case update: $result, $status, $reason, $caseRunTimeSeconds\n\n"); }; + + die("Result not defined. Cannot update.\n") if(!defined($result) ); + die("Status not defined. Cannot update.\n") if(!defined($status) ); + die("Info not defined. Cannot update.\n") if( !defined($info) ); + die("Reason not defined. Cannot update.\n") if( !defined($reason) ); + + $caseRunTimeSeconds = 0 if($caseRunTimeSeconds < 0); + + # we have actual result, no need for this anymore + @$refCase[$CASE_CHECK_RESULT_LOG_FILE] = 0; + + if(!$optionFinalDoc) + { + @$refCase[$CASE_RUN_TIMES]++; + + @$refCase[$CASE_RUN_TIME_SECONDS] = $caseRunTimeSeconds; + + if($status eq "CRASHED") { + @$refCase[$CASE_CRASHED]++; + } + elsif($status eq "FAILED") { + @$refCase[$CASE_FAILED]++; + } + elsif($status eq "PASSED") { + @$refCase[$CASE_PASSED]++; + } + } + else + { + if($status eq "PASSED") { + @$refCase[$CASE_PASSED] = 1; + @$refCase[$CASE_CRASHED] = 0; + @$refCase[$CASE_FAILED] = 0; + } + elsif($status eq "CRASHED" && @$refCase[$CASE_STATUS] ne "PASSED") { + @$refCase[$CASE_PASSED] = 0; + @$refCase[$CASE_CRASHED] = 1; + @$refCase[$CASE_FAILED] = 0; + } + elsif($status eq "FAILED" && @$refCase[$CASE_STATUS] ne "PASSED" && @$refCase[$CASE_STATUS] ne "CRASHED") { + @$refCase[$CASE_PASSED] = 0; + @$refCase[$CASE_CRASHED] = 0; + @$refCase[$CASE_FAILED] = 1; + } + } + + my $updateCase = 0; + + if(!$optionGoodIsBetter and !$optionFinalDoc) + { + # Only update case status if it's more fatal than the current, CRASHED > FAILED > UNKNOWN > PASSED + if($status ne "$caseDefaultStatus") + { + if (@$refCase[$CASE_STATUS] eq "$caseDefaultStatus") { + $updateCase = 1; + } + elsif (@$refCase[$CASE_STATUS] eq "CRASHED" ) { + + } + elsif (@$refCase[$CASE_STATUS] eq "FAILED") { + $updateCase = 1 if($status eq "CRASHED"); + } + elsif(@$refCase[$CASE_STATUS] eq "PASSED") { + $updateCase = 1; + } + } + } + else + { + # Only update case status if it's less fatal than the current, PASSED > FAILED > CRASHED > UNKNOWN + if($status ne "$caseDefaultStatus") + { + if (@$refCase[$CASE_STATUS] eq "$caseDefaultStatus") { + $updateCase = 1; + } + elsif(@$refCase[$CASE_STATUS] eq "UNKNOWN") { + $updateCase = 1; + } + elsif($status eq "PASSED") + { + $updateCase = 1; + } + elsif (@$refCase[$CASE_STATUS] eq "CRASHED" ) { + $updateCase = 1 if($status eq "FAILED"); + } + elsif (@$refCase[$CASE_STATUS] eq "FAILED") { + + } + } + } + + if($updateCase) + { + @$refCase[$CASE_REASON] = $info . $reason; + @$refCase[$CASE_RESULT] = $result; + @$refCase[$CASE_STATUS] = $status; + @$refCase[$CASE_LOG_FILE] = $caseLogFile; + @$refCase[$CASE_LOG_FILE_SCRIPTER] = $caseScripterLogFile; + } + else + { + # -1112 overrides other error codes because the case succeeded but verifying has failed. + if(@$refCase[$CASE_RESULT] ne "-1112" and $result eq "-1112") + { + @$refCase[$CASE_RESULT] = $result; + } + } + #print "case: " . @{$case}[$CASE_NAME] . "\n" . "run: " . @{$case}[$CASE_RUN_TIMES] . ", crash: " . @{$case}[$CASE_CRASHED] . ", fail " . @{$case}[$CASE_FAILED] . ", passed: " . @{$case}[$CASE_PASSED] . "\n"; +} + +sub CountCaseRunTime +{ + my ($line) = @_; + my $found = 0; + RemoveWhiteSpaces(\$line); + #StartTime: 16:12:10,2440, EndTime: 16:12:34,3880 + #StartTime: 12:02:49.9302 pm, EndTime: 12:03:04.5781 pm + if($line =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*$/i) + { + $found = 1; + } + elsif($line =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*$/i) + { + $found = 1; + } + + my $caseRunTime = 0; + + if($found) + { + my $startSeconds = ($1 * 60 * 60) + $2 * 60 + $3; + my $endSeconds = ($4 * 60 * 60) + $5 * 60 + $6; + + $caseRunTime = $endSeconds - $startSeconds; + } + $caseRunTime = 0 if($caseRunTime < 0); + + $totalExecutionTime += $caseRunTime; + return $caseRunTime; +} + +sub GetFileNameForCaseLog +{ + my ($line1, $line2, $line3, $extra) = @_; + + RemoveWhiteSpaces(\$line1); + RemoveWhiteSpaces(\$line2); + RemoveWhiteSpaces(\$line3); + + my $caseId = ""; + + if($line1 =~ m/\[[0-9]+\][ ]+Title:\[([a-z0-9]+)$regexpCaseName\]$/i) + { + #"' ultraedit + $caseId = $1; + } + + my $caseTimeStr = ""; + + #StartTime: 16:12:10,2440, EndTime: 16:12:34,3880 + if($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*$/i) + { + $found = 1; + } + elsif($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*$/i) + { + $found = 1; + } + + if( $found ) + { + $caseTimeStr = $1 . $2 . $3 . $4 . $5 . $6; + } + + my $fileext = ".txt"; + $fileext = ".html" if($optionHtml); + + my $caseLogFile; + + if( !defined( $extra ) ) + { + $caseLogFile = $caseLogOutDir . $caseId . "_" . $caseTimeStr . $fileext; + } + else + { + $caseLogFile = $caseLogOutDir . $caseId . "_" . $caseTimeStr . $extra . $fileext; + } + + print(" - Case log file: " . $caseLogFile ."\n") if($optionShowMessages); + return $caseLogFile; +} + +#------------------------------------------------------------------------------------ +# WriteCaseLog +# +# Parameters: +# $caseLogFile: filename to write +# $refLogLines: input where log lines are stored +# $caseDesc: optional text description of case which will be written into the log file +# $line1: [testscripter_iptvservicemanagementapitestasync][c:\TestFramework\IptvServiceManagementApiTestAsync.cfg][2] Title:[ET08203 Add valid hardcoded service_0 ASYNC] +# $line2: StartTime: 3:06:14.2212 PM, EndTime: 3:06:18.1037 PM +# $line3: Result: 0 [] ==> PASSED +# +# Writes case specific log file into testcase_logs/testcase_logs directory. Reads the lines from @caseLogLines array +#------------------------------------------------------------------------------------ +sub WriteCaseLog +{ +#[testscripter_iptvservicemanagementapitestasync][c:\TestFramework\IptvServiceManagementApiTestAsync.cfg][2] Title:[ET08203 Add valid hardcoded service_0 ASYNC] +# StartTime: 3:06:14.2212 PM, EndTime: 3:06:18.1037 PM +# StartTime: 12:34:41.5407, EndTime: 12:34:41.9687 +# Result: 0 [] ==> PASSED + + my ($caseLogFile, $refLogLines, $refCaseDesc, $line1, $line2, $line3) = @_; + + # Don't generate log files if we only print summary + if($optionPrintCfgSummaries) + { + return; + } + + #print("1: $line1"); print("2: $line2"); print("3: $line3"); + + RemoveWhiteSpaces(\$line1); + RemoveWhiteSpaces(\$line2); + RemoveWhiteSpaces(\$line3); + + my $lineBreak = "\n"; + $lineBreak = "
\n" if($optionHtml); + + my $caseId = ""; + + if($line1 =~ m/\[[0-9]+\][ ]+Title:\[([a-z0-9]+)$regexpCaseName\]$/i) + { + #"' ultraedit + $caseId = $1; + print("Writing log for: $caseId.\n") if($optionShowMessages); + } + + # Write header for case + + my @writeArray; + + # split the first line + push @writeArray, ( "
" ) if($optionHtml); + push @writeArray, ( substr($line1, 0, index($line1, "Title:")) . $lineBreak ); + push @writeArray, ( substr($line1, index($line1, "Title:")) . $lineBreak ); + my $title = substr($line1, index($line1, "Title:")); + + #($line1 . "\n"); + push @writeArray, ($line2 . $lineBreak); + push @writeArray, ($line3 . $lineBreak); + push @writeArray, ("\n"); + push @writeArray, ( "
" ) if($optionHtml); + + # Include the script for the case in the file? + + if($optionCaseIncludedInLog) + { + foreach $linexxx (@{$refCaseDesc}) + { + push @writeArray, ("$linexxx"); + push @writeArray, ($lineBreak) if($optionHtml); + } + push @writeArray, ( "
" ) if($optionHtml); + push @writeArray, ("\n"); + } + + my $passed = 0; + $passed = 1 if($line3 =~ m/==> PASSED/); + + # Get the log for the case + + my $startLine = 0; + my $endLine = 0; + + my $logLineCount = scalar(@$refLogLines); + + if($logLineCount > 0 && ($optionLogAllCases || !$passed) ) + { + if($lastCaseLogLine >= $logLineCount) + { + $lastCaseLogLine = 0; + } + + # Get the start and end time for the case + + my $found = 0; + #StartTime: 16:12:10,2440, EndTime: 16:12:34,3880 + if($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*$/i) + { + $found = 1; + } + elsif($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*$/i) + { + $found = 1; + } + else + { + print(" *ERROR* Could not parse case run time for case $caseId. Can not write case log note. Returning.\n"); + return; + } + + my $startSeconds = 0; + my $endSeconds = 0; + + if($found) + { + $startSeconds = ($1 * 60 * 60) + $2 * 60 + $3; + $endSeconds = ($4 * 60 * 60) + $5 * 60 + $6; + + my $caseRunTime = $endSeconds - $startSeconds; + + if($caseRunTime < 0) + { + # It's possible to code solution but it'd slow down the script. + print(" *ERROR* Case $caseId has probably passed midnight/midday. Giving up writing case specific log.\n"); + return; + } + + #print " - start:" . $1 . ":" . $2 . ":" . $3 . " = " . $startSeconds . "\n"; + #print " - end: " . $4 . ":" . $5 . ":" . $6 . " = " . $endSeconds . "\n"; + } + + # Find indexes for start and end lines + + $startLine = -1; + # If the line at $lastCaseLogLine matches then find backwards the first matching line, + # otherwise some lines might be missed from the log note. + if(LogLineTimeMatchesForCase(\@$refLogLines[$lastCaseLogLine], $startSeconds, $startSeconds)) + { + #print("find back\n"); + for(my $i=$lastCaseLogLine; $i > 0; $i--) + { + if(!LogLineTimeMatchesForCase(\@$refLogLines[$i], $startSeconds, $startSeconds)) + { + $startLine = $i+1; + last; + } + } + } + # Otherwise try to find match forward. + else + { + $startLine = FindLogLineMatch($refLogLines, $startSeconds, $endSeconds, $lastCaseLogLine, 1); + } + # If that doesn't succeed then lets go at start of the log. SLOW for huge logs. + if($startLine == -1) + { + $startLine = FindLogLineMatch($refLogLines, $startSeconds, $endSeconds, 0, 1); + $lastCaseLogLine = 0; + } + if($startLine == -1) + { + print(" *ERROR* startLine not found!\n"); + return; + } + + print(" - StartLine: $startLine\n") if($optionShowMessages); + + # Find forward the last line which does not match. + $endLine = FindLogLineMatch($refLogLines, $startSeconds, $endSeconds, $startLine+1, 0); + + if($endLine == -1 || $endLine < $startLine) + { + print(" - End line not found, trying alternative method.\n") if($optionShowMessages); + # Find first not matching line forward from the case start. + $endLine = FindLogLineMatch($refLogLines, $startSeconds, $endSeconds, scalar(@$refLogLines)-1, 0); + if( $endLine == -1 || $endLine < $startLine ) + { + # Just take the rest of the log + $endLine = scalar(@$refLogLines)-1; + } + } + + print(" - EndLine: $endLine\n") if($optionShowMessages); + + $lastCaseLogLine = $endLine-1; + } + + # Create log directory + + if ( !(-e "testcase_logs") ) + { + mkdir("testcase_logs"); + } + + if ( !(-e "$caseLogOutDir") ) + { + mkdir($caseLogOutDir, 0755); + } + + # Write the log file + + my $fileMode = ">>"; + + print(" - Case log file: " . $caseLogFile ."\n") if($optionShowMessages); + + if( open(FILE_HANDLE, $fileMode . $caseLogFile) ) + { + if($optionHtml) + { + print FILE_HANDLE ( + "\n" . + "\n" . + "$title\n" . + "\n" . + "\n" . + "\n" + ); + } + + foreach $line(@writeArray) + { + print FILE_HANDLE ($line); + } + + for(my $i=$startLine;$i<$endLine;$i++) + { + my $line = @$refLogLines[$i]; + FormatLogLine(\$line) if($optionHtml); + + print FILE_HANDLE ($line); + } + + if($optionHtml) + { + print FILE_HANDLE ( + "\n" . + "" + ); + } + + print FILE_HANDLE ( $lineBreak ); + print FILE_HANDLE ( $lineBreak ); + + close FILE_HANDLE; + + } else + { + print("ERROR: Could not write to file: " . $caseLogFile . "\n"); + } +} + +# There's case start entry in the log, write case log from there onwards. +sub WriteCaseLogFromEntry +{ + my ($caseLogFile, $refLogLines, $caseEntryLogStartLine, $line1, $line2, $line3) = @_; + + # Don't generate log files if we only print summary + if($optionPrintCfgSummaries) + { + return 0; + } + + RemoveWhiteSpaces(\$line1); + RemoveWhiteSpaces(\$line2); + RemoveWhiteSpaces(\$line3); + + my $lineBreak = "\n"; + $lineBreak = "
\n" if($optionHtml); + + my $caseId = ""; + + if($line1 =~ m/\[[0-9]+\][ ]+Title:\[([a-z0-9]+)$regexpCaseName\]$/i) + { + #"' ultraedit + $caseId = $1; + } + + # Write header for case + + my @writeArray; + + # split the first line + push @writeArray, ( "
" ) if($optionHtml); + push @writeArray, ( substr($line1, 0, index($line1, "Title:")) . $lineBreak ); + push @writeArray, ( substr($line1, index($line1, "Title:")) . $lineBreak ); + my $title = substr($line1, index($line1, "Title:")); + + #($line1 . "\n"); + push @writeArray, ($line2 . $lineBreak); + push @writeArray, ($line3 . $lineBreak); + push @writeArray, ("\n"); + push @writeArray, ( "
" ) if($optionHtml); + + my $passed = 0; + $passed = 1 if($line3 =~ m/==> PASSED/); + + # Get the log for the case + + my $logLineCount = scalar(@$refLogLines); + + if($logLineCount > 0 && ($optionLogAllCases || !$passed) ) + { + # Get the start and end time for the case + + my $found = 0; + #StartTime: 16:12:10,2440, EndTime: 16:12:34,3880 + if($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\,[0-9]*$/i) + { + $found = 1; + } + elsif($line2 =~ m/^StartTime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*, Endtime: ([0-9]+):([0-9]+):([0-9]+)\.[0-9]*[ A-Z]*$/i) + { + $found = 1; + } + else + { + print(" *ERROR* Could not parse case run time for case $caseId. Can not write case log note. Returning.\n"); + return 0; + } + + my $startSeconds = 0; + my $endSeconds = 0; + + if($found) + { + $startSeconds = ($1 * 60 * 60) + $2 * 60 + $3; + $endSeconds = ($4 * 60 * 60) + $5 * 60 + $6; + + my $caseRunTime = $endSeconds - $startSeconds; + + if($caseRunTime < 0) + { + # It's possible to code solution but it'd slow down the script. + #print(" *ERROR* Case has probably passed midnight/midday. Giving up writing case specific log.\n"); + #return; + } + } + } + + # Create log directory + + if ( !(-e "testcase_logs") ) + { + mkdir("testcase_logs"); + } + + if ( !(-e "$caseLogOutDir") ) + { + mkdir($caseLogOutDir, 0755); + } + + # Write the log file + + my $fileMode = ">>"; + + print(" - Case log file: " . $caseLogFile ."\n") if($optionShowMessages); + + my $caseEntryLogEndLine = -1; + for(my $i=$caseEntryLogStartLine; $i\n" . + "\n" . + "$title\n" . + "\n" . + "\n" . + "\n" + ); + } + + for( my $i = $caseEntryLogStartLine; $i < $caseEntryLogEndLine; $i++ ) + { + my $line = @$refLogLines[$i]; + FormatLogLine(\$line) if($optionHtml); + print FILE_HANDLE ($line); + } + + if($optionHtml) + { + print FILE_HANDLE ( + "\n" . + "" + ); + } + print FILE_HANDLE ( $lineBreak ); + print FILE_HANDLE ( $lineBreak ); + + close FILE_HANDLE; + + } else + { + print("ERROR: Could not write to file: " . $caseLogFile . "\n"); + return 0; + } + + return 1; +} + +#------------------------------------------------------------------------------------ +# FindLogLineMatchRecurse +# +# Parameters: +# $startsSeconds the min time the log line will match +# $endSeconds the max time the log line will match +# $refStartLine index of line to start searching +# $refLogLines reference to array of the log +# $boolOp 1 = first line with match is returned, 0 = first line with no match is returned +# $inc increment in the search loop +# $recurse can the function call itself, if yes this will be passed to the new call too +# $maxLine the last line to search +# +#------------------------------------------------------------------------------------ +sub FindLogLineMatchRecurse +{ + my ($startSeconds, $endSeconds, $refStartLine, $refLogLines, $boolOp, $inc, $recurse, $maxLine) = @_; + + print("IN FindLogLineMatchRecurse\n") if($optionDebug); + my $spacer = ""; + for(my $i = 0;$i<$recurse; $i++) + { + $spacer .= "-"; + } + + $maxLine = scalar(@$refLogLines) if(!defined($maxLine) or $maxLine > scalar(@$refLogLines)); + print("s: $startSeconds, e: $endSeconds, sl: $$refStartLine, b: $boolOp, i: $inc, r: $recurse, ml: $maxLine\n") if($optionDebug); + print("$spacer ENTER: range: $$refStartLine - $maxLine, $inc\n") if($optionDebug); + print("$spacer rec: $recurse\n") if($optionDebug); + print("$spacer prev: $$refStartLine\n") if($optionDebug); + print("$spacer inc: $inc\n") if($optionDebug); + + # First try to find the start line without recursion. + for(my $i = $$refStartLine; $i < $maxLine; $i += $inc) + { + if(LogLineTimeMatchesForCase(\@$refLogLines[$i], $startSeconds, $endSeconds) == $boolOp) + { + # We have exact match. + if($inc == 1) + { + $$refStartLine = $i; + } + # Not exatch match. Return start of previous block. + elsif($i >= $$refStartLine + $inc) + { + $$refStartLine = $i - $inc; + } + + print("MATCH LINE: $i: " . @$refLogLines[$i] . "\n") if($optionDebug); + print("return line: " . $$refStartLine . "\n") if($optionDebug); + print("EXIT FindLogLineMatchRecurse. return 1\n") if($optionDebug); + return 1; + } + } + + if($recurse && $inc > 500) + { + # Split the current search block to smaller blocks and do search to them + for(my $i = $$refStartLine; $i < $maxLine; $i += $inc) + { + print("$spacer $i\n") if($inc != 1 && $optionDebug); + print("...RECURSING!\n") if($optionDebug); + + # Start search from the start of current block. + my $prevPos = $i; + + # New last line to search + my $end = $i + $inc; + $end = scalar(@$refLogLines)-1 if($end > scalar(@$refLogLines)-1); + + # New increment, twice smaller than now + my $newInc = int($inc / 2 + 0.5); + $newInc = 200 if($newInc < 200); + + if(FindLogLineMatchRecurse($startSeconds, $endSeconds, \$prevPos, $refLogLines, $boolOp, $newInc, $recurse-1, $end) == 1) + { + $$refStartLine = $prevPos; + print("EXIT FindLogLineMatchRecurse. return 1\n") if($optionDebug); + return 1; + } + } + } + + print("EXIT FindLogLineMatchRecurse. return 0\n") if($optionDebug); + return 0; +} + +#------------------------------------------------------------------------------------ +# FindLogLineMatch +# +# Searches for log line with time between the startSeconds and endSeconds. +# +# Parameters: +# $refLogLines reference to array of the log +# $startsSeconds the min time the log line will match +# $endSeconds the max time the log line will match +# $startLine index of line to start searching +# $boolOp 1 = first line with match is returned, 0 = first line with no match is returned +#------------------------------------------------------------------------------------ +sub FindLogLineMatch +{ + my ($refLogLines, $startSeconds, $endSeconds, $startLine, $boolOp) = @_; + print("IN FindLogLineMatch\n") if($optionDebug); + my $prevPos = $startLine; + + #print("\n\nSTART: $startLine, boolop: $boolOp \n"); + + my $match = 0; + $match = FindLogLineMatchRecurse($startSeconds, $endSeconds, \$prevPos, $refLogLines, $boolOp, 6000, 5); + $prevPos = 0 if(!$match); + # Refine the search to be exact line + $match = FindLogLineMatchRecurse($startSeconds, $endSeconds, \$prevPos, $refLogLines, $boolOp, 1, 0); + + print("EXIT FindLogLineMatch\n") if($optionDebug); + # Not found. + return -1 if(!$match); + + return $prevPos; +} + +#------------------------------------------------------------------------------------ +# JustFormatLogFile +# +# Parameters: +# $fileName +#------------------------------------------------------------------------------------ +sub JustFormatLogFile +{ + my ($fileName) = @_; + + if( !open(FILE_HANDLE, $fileName) ) + { + die("ERROR! Could not open file '" . $fileName . "'\n"); + } + my @array = ; + close(FILE_HANDLE); + + $fileName = substr($fileName, 0, index($fileName, ".txt")) . ".html"; + + if( open(FILE_HANDLE, ">" . $fileName) ) + { + + print FILE_HANDLE ( + "\n" . + "\n" . + "$fileName\n" . + "\n" . + "\n" . + "\n" + ); + + + my $i; + for($i = 0;$i\n" . + "" + ); + + close FILE_HANDLE; + } else + { + print("ERROR: Could not write to file: " . $fileName . "\n"); + } + +} + +#------------------------------------------------------------------------------------ +# LogLineTimeMatchesForCase +# +# Parameters: +# $refLine +# $startSeconds +# $endSeconds +#------------------------------------------------------------------------------------ +sub LogLineTimeMatchesForCase +{ + my ($refLine, $startSeconds, $endSeconds) = @_; + + return 0 if(!defined($$refLine)); + + $$refLine =~ s/\t/ /; #remove tabs + + #print($$refLine . "\n"); + #print(" - $startSeconds, $endSeconds\n"); + + if(${$refLine} =~ m/[0-9\/]+ ([0-9]+):([0-9]+):([0-9]+)/i) + { +# print("YES " . $1 . "\n"); + + my $currSeconds = $1 * 60 * 60 + $2 * 60 + $3; + #print(" - curr: $currSeconds\n"); + + #print("curr: $currSeconds, start: $startSeconds, end: $endSeconds\n"); + + if($currSeconds >= $startSeconds and $currSeconds <= $endSeconds) + { + #print("MATCH curr: " . $1 . ":" . $2 . ":" . $3 . " = " . $currSeconds . "\n"); + return 1; + } + } + #print("NO MATCH\n"); + return 0; +} + +#------------------------------------------------------------------------------------ +# FormatLogLine +# Parameters: +# $line +#------------------------------------------------------------------------------------ +sub FormatLogLine +{ + my ($line) = @_; + +#Color + +# sisään +#27/06/2006 9:37:52 >>>* royalblue #2B60DE +# pois +#27/06/2006 9:37:52 <<<* lightblue #0000FF +#27/06/2006 9:23:57 * exit +# destructor +#27/06/2006 9:23:58 ~* #FF0000 +#27/06/2006 9:23:58 >>>~* + +#27/06/2006 9:37:52 CIptv*Test * GREY #808080 +#27/06/2006 9:37:52 *error/fail RED #FF0000 +#27/06/2006 9:23:41 CreateServerProcess() GREEN #00FF00 + +#!! TTestObject::~TTestObject #800080 + +my $color = "#000000"; + + +if(${$line} =~ m/([0-9\/]+ [0-9]+:[0-9]+:[0-9]+)/i) +{ + $date = $1; + ${$line} = substr(${$line}, length($date)); + + $color = "#808080" if(${$line} =~ m/CIptvTest[a-z0-9]+Test/i); + + $color = "#2B60DE" if(${$line} =~ m/^[\t ]*>>>/i); + $color = "#2B60DE" if(${$line} =~ m/\(\)$/i); + $color = "#2B60DE" if(${$line} =~ m/enter$/i); + + $color = "#0000FF" if(${$line} =~ m/^[\t ]*<<<*/i); + $color = "#0000FF" if(${$line} =~ m/ exit$/i); + + $color = "#800080" if(${$line} =~ m/^[\t ]*~/i); + $color = "#800080" if(${$line} =~ m/^[\t ]*>>>~/i); + $color = "#800080" if(${$line} =~ m/::~/i); + + $color = "#FF0000" if(${$line} =~ m/error|fail/i); + + $color = "#00AA00" if(${$line} =~ m/passed/i); + $color = "#FF0000" if(${$line} =~ m/\*\*\*Testcase[a-z ]+\*\*\*/i); + $color = "#00AA00" if(${$line} =~ m/\*\*\*Testcase PASSED+\*\*\*/i); + $color = "#0000FF" if(${$line} =~ m/Executing line/i); + + my $formatStart = "", $formatEnd = ""; + + if(${$line} =~ m/Client created semaphore, init/i) { $formatStart = ""; $formatEnd = ""; } + if(${$line} =~ m/CIptvEngineServer:: ->Starting server shutdown/i) { $formatStart = ""; $formatEnd = ""; } + + SpecialChars($line); + + $date = "" . $date . ""; + ${$line} = $date . "$formatStart" . ${$line} . "$formatEnd
"; +} + + +#$line = " . $line + +#$color = "#2B60DE" if($line =~ m/([0-9\/]+ [0-9]+:[0-9]+:[0-9]+) >>>/i) + + +} + +sub PrintCfgSummaries +{ + my $caseCfgFileName = ""; + my %cfgCaseCount; + my %cfgCaseTotalTime; + + foreach $case(@cases) + { + $caseCfgFileName = @{$case}[$CASE_CFG_FILE]; + + if(!defined($cfgCaseCount{$caseCfgFileName})) + { + $cfgCaseCount{$caseCfgFileName} = 0; + $cfgCaseTotalTime{$caseCfgFileName} = 0; + } + + if(defined(@{$case}[$CASE_RUN_TIME_SECONDS])) + { + $cfgCaseTotalTime{$caseCfgFileName} += @{$case}[$CASE_RUN_TIME_SECONDS]; + } + + + $cfgCaseCount{$caseCfgFileName}++ if(@{$case}[$CASE_STATUS] ne "$caseDefaultStatus") ; + } + + my $totalTime = 0; + printf("\n%-50s %10s %10s\n", "CFG", "Case count", "Case run time"); + foreach $caseCfgFileName (sort keys(%cfgCaseCount)) + { + if($cfgCaseCount{$caseCfgFileName} > 0) + { + my $mins = ($cfgCaseTotalTime{$caseCfgFileName}/60); + $totalTime += $mins; + printf("%-50s %10d %10.1f\n", $caseCfgFileName, $cfgCaseCount{$caseCfgFileName}, $mins); + } + } + printf("Total time: %.2f hours\n\n", $totalTime/60 ); + + print("No cases run for:\n"); + foreach $caseCfgFileName (sort keys(%cfgCaseCount)) + { + if($cfgCaseCount{$caseCfgFileName} == 0) + { + print("$caseCfgFileName\n"); + } + } +} + +#------------------------------------------------------------------------------------ +# WriteOfficeXml +# +# Parameters: +# $outputFile +# $briefSummary +# +# Writes the cases into a word formatted xml file. +#------------------------------------------------------------------------------------ +sub WriteOfficeXml +{ + my ($outputFile, $briefSummary) = @_; + + if( !open(FILE_HANDLE, ">" . $outputFile) ) + { + print("ERROR! Could not open file '" . $outputFile . "'\n"); + return; + } + + my $writeData = $xmlHeader; + my $replacement; + + if($briefSummary == 0) { + $writeData .= $xmlHeaderTableColumns; + } + else { + $writeData .= $xmlHeaderTableColumnsBrief; + } + + $excelRowCount = scalar(@cases) * 9 + 100; + $writeData =~ s/$CaseCountMul8/$excelRowCount/; + + print FILE_HANDLE ( $writeData ); + + if($briefSummary) { + $writeData = $xmlSummaryData; + + $writeData =~ s/$xmlDataSummaryCaseCount/$summaryCaseCount/; + $writeData =~ s/$xmlDataSummaryPassed/$summaryPassedCases/; + $writeData =~ s/$xmlDataSummaryFailed/$summaryFailedCases/; + $writeData =~ s/$xmlDataSummaryCrashed/$summaryCrashedCases/; + $writeData =~ s/$xmlDataSummaryTimeout/$summaryTimeoutCases/; + $writeData =~ s/$xmlDataSummaryRunRate/$summaryRunRate/; + $writeData =~ s/$xmlDataSummaryPassRateTotal/$summaryPassRateTotal/; + $writeData =~ s/$xmlDataSummaryPassRateRun/$summaryPassRateRun/; + + print FILE_HANDLE ( $writeData ); + } + + my $caseCfgFileName = ""; + + my %cfgCaseCount; + + # Sort the cases by the config files, cfg's which have no run cases come last + + if(!$optionSortCases) + { + #print("HASH CREATE\n"); + #create hash of cfg case counts + foreach $case(@cases) + { + $caseCfgFileName = @{$case}[$CASE_CFG_FILE]; + + if(!defined($cfgCaseCount{$caseCfgFileName})) + { + $cfgCaseCount{$caseCfgFileName} = 0; + } + + $cfgCaseCount{$caseCfgFileName}++ if(@{$case}[$CASE_STATUS] ne "$caseDefaultStatus") ; + } + + #print("THRU CASES\n"); + + foreach $caseCfgFileName (keys(%cfgCaseCount)) + { + # if cfg has zero cases run then it's cases are put back of the array + if($cfgCaseCount{$caseCfgFileName} == 0) + { + #print("ZERO CASES RUN: $caseCfgFileName\n"); + my @moveCases; + + my $i; + for($i=0; $i< scalar(@cases); $i++) + { + if($cases[$i][$CASE_CFG_FILE] eq $caseCfgFileName) + { + push @moveCases, splice(@cases, $i, 1); + $i--; + } + } + + push @cases, @moveCases; + } + } + } + + # Write the xml file + + $caseCfgFileName = ""; + + foreach $case(@cases) + { + if($optionShowMessages || $optionDebug) + { + print(" - Case Xml : " . @{$case}[$CASE_NAME] . ", status: " . @{$case}[$CASE_STATUS] . "\n") if( $optionDebug || @{$case}[$CASE_STATUS] ne "Not planned" ); + } + + if($briefSummary == 0) + { + $writeData = $xmlData; + $writeData .= $xmlData2; + $writeData .= $xmlDataEmptyRow; + } + else + { + $writeData = ""; + + # Write cfg file to the brief xml if it has changed for the case + if($optionSortCases == 0 && $caseCfgFileName ne @{$case}[$CASE_CFG_FILE]) + { + $caseCfgFileName = @{$case}[$CASE_CFG_FILE]; + + $writeData .= $xmlDataEmptyRow; + $writeData .= $xmlCfgFileBrief; + $writeData .= $xmlDataBriefHeader; + + $replacement = @{$case}[$CASE_CFG_FILE]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCfgFile/$replacement/; + } + + # Write log file links to xml. + + my $caseHasLog = ( defined(@{$case}[$CASE_LOG_FILE]) and @{$case}[$CASE_LOG_FILE] ne "" ); + my $caseHasScripterLog = ( defined(@{$case}[$CASE_LOG_FILE_SCRIPTER]) and @{$case}[$CASE_LOG_FILE_SCRIPTER] ne "" ); + my $caseLogLink1 = ""; + my $caseLogLink2 = ""; + + if( $caseHasLog && $caseHasScripterLog ) + { + print(" - Case has both log files\n") if ($optionDebug ); + $writeData .= $xmlDataBrief2Links; + $caseLogLink1 = @{$case}[$CASE_LOG_FILE]; + $caseLogLink2 = @{$case}[$CASE_LOG_FILE_SCRIPTER]; + } + elsif( $caseHasLog ) + { + print(" - Case has log file\n") if ($optionDebug ); + $writeData .= $xmlDataBrief1Link; + $caseLogLink1 = @{$case}[$CASE_LOG_FILE]; + } + elsif( $caseHasScripterLog ) + { + print(" - Case has scripter log file\n") if ($optionDebug ); + $writeData .= $xmlDataBrief1Link; + $caseLogLink1 = @{$case}[$CASE_LOG_FILE_SCRIPTER]; + } + else + { + print(" - Case has no log files\n") if ($optionDebug ); + $writeData .= $xmlDataBriefNoLinks; + } + + if( $caseLogLink1 ne "" ) + { + print(" - Log file 1: $caseLogLink1\n") if ($optionDebug ); + $replacement = $caseLogLink1; + XmlReadyText(\$replacement); + + #print("wordxml log file 1: $replacement\n"; + + #print("repl: " . $replacement . "\n"); + $replacement = substr($replacement, index($replacement, "\\") + 1); + #$replacement = ".\\testcase_logs\\..\\" . $replacement; + #print("repl: " . $replacement . "\n"); + + $writeData =~ s/$xmlDataCaseLink1/$replacement/; + } + + if( $caseLogLink2 ne "" ) + { + print(" - Log file 2: $caseLogLink2\n") if ($optionDebug ); + $replacement = $caseLogLink2; + XmlReadyText(\$replacement); + + #print("wordxml log file 2: $replacement\n"; + + #print("repl: " . $replacement . "\n"); + $replacement = substr($replacement, index($replacement, "\\") + 1); + #$replacement = ".\\testcase_logs\\..\\" . $replacement; + #print("repl: " . $replacement . "\n"); + + $writeData =~ s/$xmlDataCaseLink2/$replacement/; + } + + # Write case fail reason to xml. + + $replacement = @{$case}[$CASE_REASON]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseReason/$replacement/; + + # Write case run time or result to xml. + + if(!$optionCaseRunTimes) + { + $replacement = @{$case}[$CASE_RESULT]; + } + else + { + $replacement = @{$case}[$CASE_RUN_TIME_SECONDS]; + } + + # Write result to xml. + + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseResult/$replacement/; + } + + #$writeData = $xmlData; + #if($option_brief_summary == 0) { $writeData .= $xmlData2; } + #$writeData .= $xmlDataEmptyRow; + + $replacement = @{$case}[$CASE_NAME]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseName/$replacement/; + + $replacement = @{$case}[$CASE_RUN_TIMES]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseRunTimes/$replacement/; + + $replacement = @{$case}[$CASE_FAILED]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseFailed/$replacement/; + + $replacement = @{$case}[$CASE_CRASHED]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseCrashed/$replacement/; + + $replacement = @{$case}[$CASE_PASSED]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCasePassed/$replacement/; + + $replacement = @{$case}[$CASE_STATUS]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseStatus/$replacement/; + + $replacement = @{$case}[$CASE_PURPOSE]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCasePurpose/$replacement/; + + $replacement = @{$case}[$CASE_MEANS]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseMeans/$replacement/; + + $replacement = @{$case}[$CASE_REQUIRED_SETTINGS]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseRequiredSettings/$replacement/; + + $replacement = @{$case}[$CASE_RELATED_REQUIREMENTS]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseRelatedRequirements/$replacement/; + + $replacement = @{$case}[$CASE_VERIFICATION]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseVerification/$replacement/; + + $replacement = @{$case}[$CASE_NOTE]; + XmlReadyText(\$replacement); + $writeData =~ s/$xmlDataCaseNote/$replacement/; + + if(@{$case}[$CASE_STATUS] eq "UNKNOWN") { + $replacement = $STYLE_ID_STATUS_UNKNOWN; + } + elsif(@{$case}[$CASE_STATUS] eq "CRASHED") { + $replacement = $STYLE_ID_STATUS_CRASHED; + } + elsif(@{$case}[$CASE_STATUS] eq "FAILED") { + $replacement = $STYLE_ID_STATUS_FAILED; + } + elsif(@{$case}[$CASE_STATUS] eq "PASSED") { + $replacement = $STYLE_ID_STATUS_PASSED; + } + else { + $replacement = $STYLE_ID_STATUS_NA; + } + + $writeData =~ s/$STYLE_ID_STATUS_TAG/$replacement/; + + print FILE_HANDLE ( $writeData ); + } + + print FILE_HANDLE ( $xmlFooter ); + + close(FILE_HANDLE); + + print("Report " . $outputFile . " written.\n"); +} + +#------------------------------------------------------------------------------------ +# WriteOfficeXmlAlt +# +# Parameters: +# $outputFile +# +# Writes the cases into a word formatted xml file. +#------------------------------------------------------------------------------------ +sub WriteOfficeXmlAlt +{ + my ($outputFile, $refRuns) = @_; + + CalculateStats(); + + if( !open(FILE_HANDLE, ">" . $outputFile) ) + { + print("ERROR! Could not open file '" . $outputFile . "'\n"); + return; + } + + my $writeData = $xmlHeader; + my $replacement; + + $writeData .= $xmlHeaderTableColumnsAlt; + + my $xRefRunInfo = @$refRuns[0]; + my $xRefCases = @$xRefRunInfo[2]; + my $caseCount = scalar( @$xRefCases ) + 1000; + + $excelRowCount = $caseCount * 9 + 100; + $writeData =~ s/$CaseCountMul8/$excelRowCount/; + + print FILE_HANDLE ( $writeData ); + + my $caseCfgFileName = ""; + + my %cfgCaseCount; + + # Sort the cases by the config files, cfg's which have no run cases come last + + if(!$optionSortCases) + { + #print("HASH CREATE\n"); + #create hash of cfg case counts + foreach $case(@cases) + { + $caseCfgFileName = @{$case}[$CASE_CFG_FILE]; + + if(!defined($cfgCaseCount{$caseCfgFileName})) + { + $cfgCaseCount{$caseCfgFileName} = 0; + } + + $cfgCaseCount{$caseCfgFileName}++ if(@{$case}[$CASE_STATUS] ne "$caseDefaultStatus") ; + } + + #print("THRU CASES\n"); + + foreach $caseCfgFileName (keys(%cfgCaseCount)) + { + # if cfg has zero cases run then it's cases are put back of the array + if($cfgCaseCount{$caseCfgFileName} == 0) + { + #print("ZERO CASES RUN: $caseCfgFileName\n"); + my @moveCases; + + my $i; + for($i=0; $i< scalar(@cases); $i++) + { + if($cases[$i][$CASE_CFG_FILE] eq $caseCfgFileName) + { + push @moveCases, splice(@cases, $i, 1); + $i--; + } + } + + push @cases, @moveCases; + } + } + } + + my @sortedRuns; + + #Monday 25th August 2008 + while( 1 ) + { + my $maxTotal = 0; + my $refWinner; + for( my $i=0; $i" . $outputFile) ) + { + print("ERROR! Could not open file '" . $outputFile . "'\n"); + return; + } + + my $writeData; + my $replacement; + + my %cfgCaseCount; + + # sort the cases by the config files, cfg's which have no run cases come last + if(!$optionSortCases) + { + foreach $case(@cases) + { + $caseCfgFileName = @{$case}[$CASE_CFG_FILE]; + + if(!defined($cfgCaseCount{$caseCfgFileName})) + { + $cfgCaseCount{$caseCfgFileName} = 0; + } + + $cfgCaseCount{$caseCfgFileName}++ if(@{$case}[$CASE_STATUS] ne "$caseDefaultStatus") ; + } + + #print("THRU CASES\n"); + + foreach $caseCfgFileName (keys(%cfgCaseCount)) + { + # if cfg has zero cases run then it's cases are put back of the array + if($cfgCaseCount{$caseCfgFileName} == 0) + { + #print("ZERO CASES RUN: $caseCfgFileName\n"); + my @moveCases; + + my $i; + for($i=0; $i< scalar(@cases); $i++) + { + if($cases[$i][$CASE_CFG_FILE] eq $caseCfgFileName) + { + push @moveCases, splice(@cases, $i, 1); + $i--; + } + } + + push @cases, @moveCases; + } + } + } + +#test_set_name_here +#[1]APES PTSW_WBA_TS -1.1. - Server Version - (01) - COMM_SERVER_VERSION_GET_REQ +#Passed&Actual result: Info: 0 + + print FILE_HANDLE ( "IPTV_Engine test set\n" ); + + foreach $case(@cases) + { + $writeData = "[1]"; + + my $caseName = @{$case}[$CASE_NAME]; + $writeData .= $caseName; + + $writeData .= "\n"; + + my $result; + + if(@{$case}[$CASE_STATUS] eq "UNKNOWN") { + $result = "N/A"; + } + elsif(@{$case}[$CASE_STATUS] eq "CRASHED") { + $result = "Failed"; + } + elsif(@{$case}[$CASE_STATUS] eq "FAILED") { + $result = "Failed"; + } + elsif(@{$case}[$CASE_STATUS] eq "PASSED") { + $result = "Passed"; + } + else { + $result = "No Run"; + } + + $writeData .= $result; + + + + my $comments = "&Info"; + + #$comments = "CFG file: @{$case}[$CASE_CFG_FILE]; + + #$comments .= "Actual result = " . @{$case}[$CASE_RESULT] . ", Info = " . @{$case}[$CASE_REASON]; + + $writeData .= $comments; + + $writeData .= "\n"; + + # Replace bad characters for QC + $writeData =~ s/\\/-/g; + $writeData =~ s/\//-/g; + $writeData =~ s/:/-/g; + $writeData =~ s/\"/-/g; + $writeData =~ s/\?/-/g; + $writeData =~ s/\'/-/g; + $writeData =~ s/\|/-/g; + $writeData =~ s/\*/-/g; + $writeData =~ s/\%/-/g; + $writeData =~ s/ä/a/g; + $writeData =~ s/ö/o/g; + $writeData =~ s/\å/a/g; + $writeData =~ s//)/g; + + if($result eq "Passed" or $result eq "Failed") + { + print FILE_HANDLE ( $writeData ); + } + } + + close(FILE_HANDLE); + + print("Report " . $outputFile . " written.\n"); +} + + +#------------------------------------------------------------------------------------ +# FindCfgFiles +# Parameters: +# $godir, $refFiles +# +# Finds cfg files from the the specified directory and it's sub directories. +#------------------------------------------------------------------------------------ +sub FindCfgFiles +{ + my ($godir, $refFiles) = @_; + + my $startDir = cwd; + + chdir($godir) or die("Could not change dir to $godir"); + + opendir(DIR, "."); + my @files = sort(readdir(DIR)); + closedir(DIR); + + foreach $file(@files) + { + if($file eq "." or $file eq "..") {next}; + + if (-d $file) + { + FindCfgFiles( $file, $refFiles ); + } else { + if($file =~ m/\.cfg$/i) + { + next if($file =~ m/livetv/i and $optionNoLiveTvTests); + + next if( + ($file =~ m/IptvSecurityServicesTest/i or + $file =~ m/IptvRssSecurityTest/i or + $file =~ m/IptvLiveTvSep/i or + $file =~ m/IptvRssDownloadSecurityTest/i) + + and $optionNoSecurityTests + ); + + next if($file =~ m/example.cfg/i); + + push @$refFiles, ( cwd . "/" . $file ); + } + } + } + + chdir("$startDir") or die("Could not change dir to $startDir"); +} + +#------------------------------------------------------------------------------------ +# ParseCfg +# Parameters: +# $file +#------------------------------------------------------------------------------------ +sub ParseCfg +{ + my ($file) = @_; + + my $fileCaseCount = 0; + + if( !open(FILE_HANDLE, $file) ) + { + print("ERROR! Could not open file '" . $file . "'\n"); + return 0; + } + my @array = ; + close(FILE_HANDLE); + + my $lineCount = scalar(@array); + my $i; + my $cfgFileWritten = 0; + my $caseDocumentationStart = -1; + my $line; + + my @caseDesc; # lines for case desc and case itself + + for($i=0; $i<$lineCount; $i++ ) { + $line = $array[$i]; + + RemoveWhiteSpaces(\$line); + + #print(" $line\n"); + + if($line =~ m/^\#\[IptvETDescription\]/) + { + $caseDocumentationStart = $i; + } + + if($line =~ m/\[Test\]/) + { + if($caseDocumentationStart >= 0) + { + ReadCaseAndDescText(\@array, \@caseDesc, $caseDocumentationStart-1) + } + else + { + ReadCaseAndDescText(\@array, \@caseDesc, $i); + } + + #print("readcase desc: " . scalar(@caseDesc) . "\n"); + } + else + { + #print("NOT READ readcase desc: " . scalar(@caseDesc) . "\n"); + } + + #test case starts here + if($line =~ m/^title /) + { + #print("COUNT: " . scalar(@caseDesc) . "\n\n"); + + if($caseDocumentationStart >= 0) + { + #print(">>> Case start: " . $line . "\n"); + #$i += + ReadCase(\@array, $caseDocumentationStart, $file); + $caseDocumentationStart = -1; + } + + my $caseName = substr($line, length("title ")); + my $caseId = GetCaseIdFromName($caseName); + + RemoveWhiteSpaces(\$caseName); + #SpecialChars(\$caseName); + + my $documentationExists = GetCase($caseId, \@cases); + + $caseDesc[0] = $caseName; + push @caseDescs, [ @caseDesc ]; + @caseDesc = (); #new case starts + + # create empty array for case + if(!$documentationExists) + { + if($cfgFileWritten == 0) + { + $cfgFileWritten = 1; + push @notDocumentedCases, ("\n\n" . $file . +"\n************************************************************************************************\n" + ); + + } + push @notDocumentedCases, ($caseName . "\n"); + + #create dummy case + my @case; + $case[$CASE_NAME] = $caseName; + + $case[$CASE_ID] = $caseId; + + $case[$CASE_RUN_TIMES] = 0; + $case[$CASE_CRASHED] = 0; + $case[$CASE_FAILED] = 0; + $case[$CASE_PASSED] = 0; + $case[$CASE_STATUS] = "$caseDefaultStatus"; + $case[$CASE_PURPOSE] = "N/A"; + $case[$CASE_MEANS] = "N/A"; + $case[$CASE_REQUIRED_SETTINGS] = "N/A"; + $case[$CASE_RELATED_REQUIREMENTS] = "N/A"; + $case[$CASE_VERIFICATION] = "N/A"; + $case[$CASE_NOTE] = "N/A"; + $case[$CASE_REASON] = ""; + $case[$CASE_RESULT] = ""; + $case[$CASE_LOG_FILE] = ""; + $case[$CASE_LOG_FILE_SCRIPTER] = ""; + $case[$CASE_CHECK_RESULT_LOG_FILE] = 0; + $case[$CASE_CFG_FILE] = lc( GetPathFileName($file) ); + $case[$CASE_RUN_TIME_SECONDS] = 0; + + if( IsCaseInCaseList( $case[$CASE_ID] ) ) + { + push @cases, [ @case ]; + } + } + + $fileCaseCount++; + if($optionShowMessages) { print(" - Case: " . $caseName . "\n"); }; + } + } + + return $fileCaseCount; +} + + +#------------------------------------------------------------------------------------ +# ReadCaseAndDescText +# +# Parameters: +# $lines +# $caseInfo +# $startIndex +#------------------------------------------------------------------------------------ +sub ReadCaseAndDescText +{ + my ($lines, $caseInfo, $startIndex) = @_; + my $lineCount = @{$lines}; + + my $readLines = 0; + my $i = 0; + + @{$caseInfo}[0] = "N/A"; + + for($i=$startIndex; $i<$lineCount; $i++) + { + my $line = @{$lines}[$i]; + + @{$caseInfo}[ scalar(@{$caseInfo}) ] = $line; + + #print($line . "\n"); + + if($line =~ m/\[Endtest\]/i) + { +# push @cases, [ @case ]; + + #foreach $xxx (@{$caseInfo}) { print("XXX: " . $xxx . ""); } + + return $readLines; + } + + $readLines++; + } + + return $readLines; +} + +#------------------------------------------------------------------------------------ +# ReadCase +# +# Parameters: +# $lines +# $startIndex +# $file +#------------------------------------------------------------------------------------ +sub ReadCase +{ + my ($lines, $startIndex, $file) = @_; + my $lineCount = @{$lines}; + + my $readLines = 0; + my $i = 0; + + my $caseName = ""; + my $casePurpose = ""; + my $caseMeans = ""; + my $caseRequiredSettings = ""; + my $caseRelatedRequirements = ""; + my $caseVerification = ""; + my $caseNote = ""; + + #this is where text is appended if it's on a line which has no description tag + # -> multiline descriptions can be specified + my $refAppend = 0; + + for($i=$startIndex; $i<$lineCount; $i++) + { + my $line = @{$lines}[$i]; + + #print($line . "\n"); + + RemoveWhiteSpaces(\$line); + #$line =~ s/\s+$//; #whitespaces in the end + #$line =~ s/^\s+//; #whitespaces at the start + + if($line =~ m/^\#\[EndIptvETDescription\]/) + { + #print(" ***** End case\n"); + + my @case; + + $case[$CASE_NAME] = $caseName; + $case[$CASE_ID] = GetCaseIdFromName($caseName); + + $case[$CASE_RUN_TIMES] = 0; + $case[$CASE_CRASHED] = 0; + $case[$CASE_FAILED] = 0; + $case[$CASE_PASSED] = 0; + $case[$CASE_STATUS] = "$caseDefaultStatus"; + $case[$CASE_PURPOSE] = $casePurpose; + $case[$CASE_MEANS] = $caseMeans; + $case[$CASE_REQUIRED_SETTINGS] = $caseRequiredSettings; + $case[$CASE_RELATED_REQUIREMENTS] = $caseRelatedRequirements; + $case[$CASE_VERIFICATION] = $caseVerification; + $case[$CASE_NOTE] = $caseNote; + $case[$CASE_REASON] = ""; + $case[$CASE_RESULT] = ""; + $case[$CASE_LOG_FILE] = ""; + $case[$CASE_LOG_FILE_SCRIPTER] = ""; + $case[$CASE_CHECK_RESULT_LOG_FILE] = 0; + $case[$CASE_CFG_FILE] = $file; + $case[$CASE_RUN_TIME_SECONDS] = 0; + + if( IsCaseInCaseList( $case[$CASE_ID] ) ) + { + push @cases, [ @case ]; + } + + return $readLines; + } + + elsif($line =~ m/^\# Testname:/) + { + $caseName = substr($line, length("# Testname:")); + RemoveWhiteSpaces(\$caseName); + #SpecialChars(\$caseName); + $refAppend = \$caseName; + } + + elsif($line =~ m/^\# Purpose:/) + { + $casePurpose = substr($line, length("# Purpose:")); + RemoveWhiteSpaces(\$casePurpose); + #SpecialChars(\$casePurpose); + $refAppend = \$casePurpose; + } + + elsif($line =~ m/^\# Means:/) + { + $caseMeans = substr($line, length("# Means:")); + RemoveWhiteSpaces(\$caseMeans); + #SpecialChars(\$caseMeans); + $refAppend = \$caseMeans; + } + + elsif($line =~ m/^\# Required environment settings:/) + { + $caseRequiredSettings = substr($line, length("# Required environment settings:")); + RemoveWhiteSpaces(\$caseRequiredSettings); + #SpecialChars(\$caseRequiredSettings); + $refAppend = \$caseRequiredSettings; + } + + elsif($line =~ m/^\# Related requirements:/) + { + $caseRelatedRequirements = substr($line, length("# Related requirements:")); + RemoveWhiteSpaces(\$caseRelatedRequirements); + $refAppend = \$caseRelatedRequirements; + } + + elsif($line =~ m/^\# Verification:/) + { + $caseVerification = substr($line, length("# Verification:")); + RemoveWhiteSpaces(\$caseVerification); + $refAppend = \$caseVerification; + } + + elsif($line =~ m/^\# Note:/) + { + $caseNote = substr($line, length("# Note:")); + RemoveWhiteSpaces(\$caseNote); + $refAppend = \$caseNote; + } + + elsif($line =~ m/^\#/) + { + my $text = substr($line, length("#")); + RemoveWhiteSpaces(\$text); + #print(" ***** JOTTAI MUuTA: " . $text. "\n"); + ${$refAppend} .= " " . $text; + + RemoveWhiteSpaces($refAppend); + + } + + $readLines++; + } + + return $readLines; +} + +#------------------------------------------------------------------------------------ +# GetCaseIdFromName +# +# Parameters: +# $caseName +#------------------------------------------------------------------------------------ +sub GetCaseIdFromName +{ + my ($caseName) = @_; + + return "NOID" if(!defined($caseName) || $caseName eq ""); + + RemoveWhiteSpaces(\$caseName); + #SpecialChars(\$caseName); + + if($caseName =~ m/(ET[0-9]+)[ ]+/) + { + return $1; + } + + return $caseName; +} + +#------------------------------------------------------------------------------------ +# GetCaseField +# +# Parameters: +# $caseName +# $caseField +#------------------------------------------------------------------------------------ +sub GetCaseField +{ + my ($caseNameOrId, $caseField) = @_; + + my $ret = ""; + + foreach my $case(@cases) + { + if(@{$case}[$CASE_NAME] eq $caseNameOrId or @{$case}[$CASE_ID] eq $caseNameOrId) + { + if( defined(@{$case}[$caseField]) ) + { + $ret = @{$case}[$caseField]; + } + } + } + + return $ret; +} + +#------------------------------------------------------------------------------------ +# GetCaseByNameOnly +# +# Parameters: +# $caseName +# +# Removes the case IDs from case names and tries to find case from @cases array +#------------------------------------------------------------------------------------ +sub GetCaseByNameOnly +{ + my ($caseName) = @_; + + my $startPos = index($caseName, " "); + $caseName = substr($caseName, $startPos) if($startPos != -1); + + RemoveWhiteSpaces(\$caseName); + + for(my $i = 0; $i/$txtgt/g; + + ${$text} =~ s/Ä/Ä/g; + ${$text} =~ s/ä/ä/g; + ${$text} =~ s/Ö/Ö/g; + ${$text} =~ s/ö/ö/g; + + #ä ä + +# Ö Ö + +# ö ö + +} + +#------------------------------------------------------------------------------------ +# SpecialChars +# +# Parameters: +# $text +#------------------------------------------------------------------------------------ +sub SpecialChars +{ + my ($text) = @_; + + + ReplaceChar($text, "etmerkki#39;", "'" ); + ReplaceChar($text, "etmerkkiamp;", "&" ); + ReplaceChar($text, "etmerkkiacute;", "´" ); + + ReplaceChar($text, "etmerkkilsquo;", "‘" ); + ReplaceChar($text, "etmerkkirsquo;", "’" ); + ReplaceChar($text, "etmerkkisbquo;", "‚" ); + ReplaceChar($text, "etmerkkildquo;", "“" ); + ReplaceChar($text, "etmerkkirdquo;", "”" ); + ReplaceChar($text, "etmerkkibdquo;", "„" ); + ReplaceChar($text, "etmerkki#34;", "\"" ); + + ReplaceChar($text, "etmerkki#40;", "(" ); + ReplaceChar($text, "etmerkki#41;", ")" ); + + ReplaceChar($text, "etmerkkifrasl;", "/" ); + ReplaceChar($text, "etmerkkilt;", "<" ); + ReplaceChar($text, "etmerkkigt;", ">" ); + ReplaceChar($text, "etmerkki#166;" , "¦" ); + + ReplaceChar($text, "etmerkkipara;", "¶" ); + ReplaceChar($text, "etmerkkimiddot;", "·" ); + ReplaceChar($text, "etmerkkifrac14;", "¼" ); + ReplaceChar($text, "etmerkkifrac12;", "½" ); + ReplaceChar($text, "etmerkkifrac34;" , "¾" ); + + + ${$text} =~ s/etmerkki/&/g; + + # print("TEXT: " . ${$text} . "\n"); +} + +#------------------------------------------------------------------------------------ +# ReplaceChar +# +# Parameters: +# $text +# $replacement +# $char +#------------------------------------------------------------------------------------ +sub ReplaceChar +{ + my ($text, $replacement, $char) = @_; + +# print("txt: " . ${$text} . "char: " . $char . ", repl: " . $replacement . "\n"); + + while(index(${$text}, $char) != -1) + { + my $pos = index(${$text}, $char); + if($pos < 0) { $pos = 0 }; + + $str1 = substr(${$text}, 0, $pos); + $str2 = substr(${$text}, $pos+1); + +# print "STR: '" . $str1 . "' - '" . $str2 . "'\n"; + +# print "XXX: " . $str1 . $replacement . $str2 . "\n"; + + ${$text} = $str1 . $replacement . $str2;; + } +} + +#------------------------------------------------------------------------------------ +# PrintCases +#------------------------------------------------------------------------------------ +sub PrintCases +{ + + my ($fileName) = @_; + + my @buff; + + push @buff, ("Name, Status, LogFile\n"); + + my $i; + + push @buff, ("----------------------------------------\nCASES\n--------------------------------------\n"); + foreach $case(@cases) + { + + # my $case = $cases[$i]; + if(0 or @{$case}[$CASE_STATUS] ne "$caseDefaultStatus") + { + + push @buff, (@{$case}[$CASE_NAME] . " "); + #@{$case}[$CASE_RUN_TIMES] + #@{$case}[$CASE_CRASHED] + #@{$case}[$CASE_FAILED] + #@{$case}[$CASE_PASSED] + push @buff, (@{$case}[$CASE_STATUS] . " "); + #@{$case}[$CASE_PURPOSE] + #@{$case}[$CASE_MEANS] + #@{$case}[$CASE_REQUIRED_SETTINGS] + #@{$case}[$CASE_RELATED_REQUIREMENTS] + #@{$case}[$CASE_VERIFICATION] + #@{$case}[$CASE_NOTE] + #@{$case}[$CASE_REASON] + #@{$case}[$CASE_RESULT] + push @buff, ("file: " . @{$case}[$CASE_LOG_FILE] . " "); + + push @buff, ("check log: " . @{$case}[$CASE_CHECK_RESULT_LOG_FILE] . " "); + + push @buff, ("\n"); + + } + } + + open(XXX, ">" . $fileName); + print XXX ( @buff ); + close(XXX); + +} + +#------------------------------------------------------------------------------------ +# FindFiles +# Parameters: +# $goDir, where to start finding +# $fileSearch, filename search +# $searchType, 0 = fullname search, 1 = filetype search +# $refIncfiles, reference to array which will hold found files +#------------------------------------------------------------------------------------ +sub FindFiles +{ + my ($godir, $fileSearch, $searchType, $refIncfiles) = @_; + + my $startDir = cwd; + + chdir($godir) or die("Could not change dir to $godir"); + + #print("Now in: " . cwd . "\n"); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + foreach my $file(@filelist) + { + if($file eq "." or $file eq "..") {next}; + + if (-d $file) + { + FindFiles( $file, $fileSearch, $searchType, $refIncfiles); + } else + { + if( ($file =~ m/$fileSearch/i and $searchType == 0 ) or ($file =~ m/$fileSearch$/i and $searchType == 1 ) ) + { + $file = cwd . "/" . $file; + push @$refIncfiles, $file; + #print("$file\n"); + } + } + } + + chdir ($startDir) or die("Could not change dir to $startDir"); +} + + +#------------------------------------------------------------------------------------ +# GetAllFiles +# Parameters: +# $goDir, where to start finding +# $refIncfiles, reference to array which will hold found files +# $subDirLevel, how deep in the directories we go to search files. < 0 is no limit. +#------------------------------------------------------------------------------------ +sub GetAllFiles +{ + my ($godir, $refIncfiles, $subDirLevel) = @_; + + my $startDir = cwd; + + chdir($godir) or die("Could not change dir to $godir"); + + #print("Now in: " . cwd . "\n"); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + foreach my $file(@filelist) + { + if($file eq "." or $file eq "..") {next}; + + if (! (-d $file) ) + { + my $path = $startDir . "/" . $file; + push @$refIncfiles, $path; + } elsif( $subDirLevel > 0 || $subDirLevel < 0 ) + { + my $backupDir = cwd; + chdir( $file ) or die("Could not change dir to $file"); + GetAllFiles( $godir, $refIncfiles, $subDirLevel-1 ); + chdir( $backupDir ) or die("Could not change dir to $backupDir"); + } + } + + chdir ($startDir) or die("Could not change dir to $startDir"); +} + +#------------------------------------------------------------------------------------ +# FindDirs +# Parameters: +# $goDir, where to start finding +# $fileSearch, filename search +# $refIncfiles, reference to array which will hold found files +#------------------------------------------------------------------------------------ +sub FindDirs +{ + my ($godir, $fileSearch, $refIncfiles) = @_; + + my $startDir = cwd; + + chdir($godir) or die("Could not change dir to $godir"); + + #print("Now in: " . cwd . "\n"); + + opendir(DIR, "."); + my @filelist = sort(readdir(DIR)); + closedir(DIR); + + foreach my $file(@filelist) + { + if($file eq "." or $file eq "..") {next}; + + if (-d $file) + { + if( $file =~ m/$fileSearch/i ) + { + push @$refIncfiles, (cwd . "/" . $file); + } + FindDirs( $file, $fileSearch, $refIncfiles ); + } + } + + chdir ($startDir) or die("Could not change dir to $startDir"); +} + +#------------------------------------------------------------------------------------ +# GetPathFileName +# +# Parameters: +# $str +#------------------------------------------------------------------------------------ +sub GetPathFileName +{ + my ($str) = @_; + + my $startPos = rindex($str, "\\"); + if($startPos == -1) + { + $startPos = rindex($str, "/"); + return $str if($startPos == -1); + } + + my $filename = substr($str, $startPos+1); + + return $filename; +} + +#------------------------------------------------------------------------------------ +# GetPathDir +# +# Parameters: +# $str +#------------------------------------------------------------------------------------ +sub GetPathDir +{ + my ($str) = @_; + + my $startPos = rindex($str, "\\"); + if($startPos == -1) + { + $startPos = rindex($str, "/"); + return $str if($startPos == -1); + } + + my $filename = substr($str, 0, $startPos); + + return $filename; +} + +sub InitXmlData +{ + +$xmlHeader = +"" . +"" . +"" . +" " . +" Senbom Petri" . +" Senbom Petri" . +" 2006-06-09T11:08:05Z" . +" Nokia Oyj" . +" 11.6568" . +" " . +" " . +" 12210" . +" 18780" . +" 360" . +" 255" . +" False" . +" False" . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . + +#failed + +" " . + +#passed style + +" " . + +#crashed style + +" " . + +# UNKNOWN style + +" " . + + +#NA style +" " . + + +#failed centered + +" " . + +#passed style centered + +" " . + +#crashed style centered + +" " . + +# UNKNOWN style centered + +" " . + + +#NA style centered +" " . + +#summary style +" " . + +#summary real number style +" " . + +#summary header +" " . + +#brief header +" " . + +" " . + +#link +" " . + +" " . + +" " . +" "; + +$xmlHeaderTableColumns = +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" \n\n"; + +$xmlHeaderTableColumnsBrief = +"
" . +" " . +" " . +" " . +" " . +" " . +" " . +" " . #status +" " . +" " . +" " . # info +" " . # link1 +" " . # link2 +" " . +" " . +" \n\n"; + +$xmlHeaderTableColumnsAlt = +"
" . +" " . +" " . +" " . +" " . +" "; + +$xmlFooter = + +"
" . +" " . + +#splitted panes +#" " . +#" 3060" . +#" 11" . +#" 2" . +#" " . +#" " . +#" 3" . +#" " . +#" " . +#" 2" . +#" R12C1:R12C8" . +#" " . +#" " . + +#not splitted +" " . +" " . +" " . +" 3" . +" 7" . +" 2" . +" " . +" " . + +" False" . +" False" . +" " . +"
" . +" " . +" " . +" False" . +" False" . +" " . +" " . +" " . +" " . +" False" . +" False" . +" " . +" " . +"
\n\n"; + +$xmlDataEmptyRow = +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +" \n\n"; + +$xmlSummaryData = + +$xmlDataEmptyRow . + +" " . +" " . "INSERT TEST SOFTWARE HERE" . +" \n\n" . + +" " . +" " . "INSERT TEST DEVICE HERE" . +" \n\n" . + +$xmlDataEmptyRow . + +" \n" . +" Test Execution Metrics" . +" \n" . +" \n" . +" \n" . +" Total cases:" . +" $xmlDataSummaryCaseCount" . +" \n" . +" \n" . +" \n" . +" Passed:" . +" $xmlDataSummaryPassed" . +" \n" . +" \n" . +" \n" . +" Failed:" . +" $xmlDataSummaryFailed" . +" \n" . +" \n" . +" \n" . +" Crashed:" . +" $xmlDataSummaryCrashed" . +" \n" . +" \n" . +" \n" . +" Timeout:" . +" $xmlDataSummaryTimeout" . +" \n" . +" \n" . +" \n" . +" Pass rate % (total cases):" . +" $xmlDataSummaryPassRateTotal" . +" \n" . +" \n" . +" \n" . +" Pass rate % (run cases):" . +" $xmlDataSummaryPassRateRun" . +" \n" . +" \n" . +" \n" . +" Run rate %:" . +" $xmlDataSummaryRunRate" . +" \n" . +" \n" . + $xmlDataEmptyRow; + +$xmlData = +" " . +" Name:" . +" XML_DATA_CASE_NAME" . +" " . +" "; + +# not included in the case documentation report +$xmlDataCaseStatusDisabled = +" " . +" Run times:" . +" XML_DATA_CASE_RUN_TIMES" . +# +" Crashed" . +" XML_DATA_CASE_CRASHED" . + +" Failed" . +" XML_DATA_CASE_FAILED" . +" Passed" . +" XML_DATA_CASE_PASSED" . +" Status" . +#orig status style id s28 +" XML_DATA_CASE_STATUS" . +" " . +" " . +" " . +" " . +" " . +" " . +" " . +#" " . +#" " . +" " . +" \n\n"; +$xmlDataCaseStatusDisabled .= ""; + +$xmlData2 = +" " . +" Purpose:" . +" XML_DATA_CASE_PURPOSE" . +" " . +" " . +" " . +" Means:" . +" XML_DATA_CASE_MEANS" . +" " . +" " . +" " . +" Required environment settings:" . +" XML_DATA_CASE_REQUIRED_SETTINGS" . +" " . +" " . +" " . +" Related requirements:" . +" XML_DATA_CASE_RELATED_REQUIREMENTS" . +" " . +" " . + +" " . +" Verification:" . +" XML_DATA_CASE_VERIFICATION" . +" " . +" " . +" " . +" Note:" . +" XML_DATA_CASE_NOTE" . +" " . +" \n\n"; + + +$xmlDataBriefHeader = +" " . +" Name" . +" Status" . +" Passes" . +" Fails" . +" Crashes" . +" Result" . +" Info" . +" " . +" \n\n"; + +$xmlDataBriefNoLinks = +" \n" . +" XML_DATA_CASE_NAME\n" . +" XML_DATA_CASE_STATUS\n" . +" XML_DATA_CASE_PASSED\n" . +" XML_DATA_CASE_FAILED\n" . +" XML_DATA_CASE_CRASHED\n" . +" XML_DATA_CASE_RESULT\n" . +" XML_DATA_CASE_REASON\n" . +" \n" . +" \n\n"; + +$xmlDataBrief1Link = +" \n" . +" XML_DATA_CASE_NAME\n" . +" XML_DATA_CASE_STATUS\n" . +" XML_DATA_CASE_PASSED\n" . +" XML_DATA_CASE_FAILED\n" . +" XML_DATA_CASE_CRASHED\n" . +" XML_DATA_CASE_RESULT\n" . +" XML_DATA_CASE_REASON\n" . +" Link\n" . +" \n" . +" \n\n"; + +$xmlDataBrief2Links = +" \n" . +" XML_DATA_CASE_NAME\n" . +" XML_DATA_CASE_STATUS\n" . +" XML_DATA_CASE_PASSED\n" . +" XML_DATA_CASE_FAILED\n" . +" XML_DATA_CASE_CRASHED\n" . +" XML_DATA_CASE_RESULT\n" . +" XML_DATA_CASE_REASON\n" . +" Link\n" . +" Link\n" . +" \n" . +" \n\n"; + +$xmlCfgFileBrief = +" " . +" XML_DATA_CFG_FILE" . +" " . +" \n\n"; + + +$xmlCfgFileAltHeader = +" " . +" Name" . +" XML_DATA_ALTDATE1" . +" XML_DATA_ALTDATE2" . +" XML_DATA_ALTDATE3" . +" XML_DATA_ALTDATE4" . +" XML_DATA_ALTDATE5" . +" XML_DATA_ALTDATE6" . +" XML_DATA_ALTDATE7" . +" XML_DATA_ALTDATE8" . +" XML_DATA_ALTDATE9" . +" XML_DATA_ALTDATE10" . +" " . +" \n\n"; + + +$xmlCfgFileAltData = +" " . +" XML_DATA_CASE_NAME\n" . +" XML_DATA_ALTRESULT1" . +" XML_DATA_ALTRESULT2" . +" XML_DATA_ALTRESULT3" . +" XML_DATA_ALTRESULT4" . +" XML_DATA_ALTRESULT5" . +" XML_DATA_ALTRESULT6" . +" XML_DATA_ALTRESULT7" . +" XML_DATA_ALTRESULT8" . +" XML_DATA_ALTRESULT9" . +" XML_DATA_ALTRESULT10" . +" " . +" \n\n"; + +} # sub InitXml +