Created
August 31, 2015 16:25
-
-
Save jclarkin/f4ce895a3b7ac4caf476 to your computer and use it in GitHub Desktop.
Perl Script to Generate the Test History based on a collection of JUnit XML file inputs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/perl | |
# | |
# Build Historical Pass/Fail results on all unit tests | |
# | |
# Configurables | |
my $iType = "Geronimo"; # WLS or JBoss or Geronimo | |
my $iDirInput; | |
my $iDirOutput; | |
my $iMax = 100.00; | |
my $iMin = 0.00; | |
my $iRunType; # stats or tests | |
# Input/Output variables | |
my $iOutput; | |
################### BODY ################# | |
## Loads all Runtime Parameters passed into the Script | |
&loadCommands(); | |
my $iFileName = &getFileName($iType); | |
if($iRunType =~ /stats/) { | |
print "Generating Statistics...\n"; | |
my %lStats = | |
%{&generateStatistics( $iDirInput, $iFileName )}; | |
&printStatistics(\%lStats, "$iDirOutput/$iOutput" ); | |
die "Complete!\n"; | |
} | |
elsif($iRunType =~ /tests/) { | |
print "Generating Test Case Results...\n"; | |
# die "Complete!\n" | |
} else { | |
die "Invalid Run Type\n"; | |
} | |
# Get a list of all folders to traverse | |
my @folders = @{&getFolders($iDirInput)}; | |
my %iResults; | |
my %iBuilds; | |
# Open the statistic file for each subfolder and analyze | |
foreach $folder (sort @folders) { | |
next if (-l "$iDirInput/$folder"); # skip non-directories | |
next if (-f "$iDirInput/$folder"); # skip non-directories | |
next if ($folder =~ m/ignore/); # skip selected directories | |
print "Folder: $folder\n"; | |
my $lFile = "$iDirInput/$folder/$iFileName"; | |
if( !open(STATS, $lFile) ) { | |
print "Err: Unable to open $lFile\n"; | |
next; | |
} | |
my @lines = <STATS>; | |
close(STATS); | |
# File Details | |
my $lBuild = ""; | |
my $lDate = ""; | |
my $lineNo = 0; | |
my $line = @lines[$lineNo++]; | |
## While line is not </properties> Look for Build Info | |
while($line !~ m/<\/properties>/) { | |
if($line =~ m/property name=\"build\.timestamp\"/) { | |
# Get the TimeStamp | |
$line =~ m/value=\"([^\ ]+)/; | |
$lDate = $1; | |
} elsif($line =~ m/property name=\"build\.label\"/) { | |
# Get the Build Name | |
$line =~ m/value=\"([^\"]+)\"/; | |
$lBuild = $1; | |
} | |
# Increment the Line count | |
$line = @lines[$lineNo++]; | |
} | |
# Determine the Build no | |
$folder =~ m/-(\d+)/; | |
my $lBuildNo = sprintf("%03d", $1); | |
# Store the build names | |
$iBuilds{$lBuildNo} = $lBuild; | |
## For all the remaining lines | |
my $maxLines = @lines; | |
for(;$lineNo < $maxLines;) { | |
my $testName; | |
my $testState = '?'; | |
## If line has <testcase | |
if($line =~ m/<testcase/) { | |
## Get the Test Case Name | |
$testName = &getTestClassName($line); | |
## If the line ends in '/>', mark as Pass | |
if($line =~ m/\"\/>/) { | |
$testState=''; | |
} elsif($line =~ m/\">/){ | |
## If there is a body to this tag, then there are errors | |
while($line !~ m/<\/testcase>/) { | |
## If see '<error' flag as an error | |
if($line =~ m/<error/) { | |
$testState='Err'; | |
} | |
## If see '<failure' flag as a failure | |
elsif($line =~ m/<failure/) { | |
$testState='Fail'; | |
} | |
$line = @lines[$lineNo++]; | |
} | |
if($testState eq '?') {print "$testState Could Not Find for $lBuildNo: $testName\n";} | |
} else { | |
print "Could Not Find for $lBuildNo: $testName\n"; | |
} | |
## Store that result (if not blank) | |
if($testState ne '') { | |
$iResults{$testName}{$lBuild} = $testState; | |
} | |
} | |
# Increment the line count | |
$line = @lines[$lineNo++]; | |
} | |
} | |
### Generate the Statistics | |
&printHistory(\%iResults, \%iBuilds, "$iDirOutput/$iOutput" ); | |
print "Complete!\n"; | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
################################################################################ | |
sub loadCommands { | |
my $lVarSize = @ARGV; | |
my $lErrorMessage = | |
"Missing Runtime Commands: \n". | |
" -r Type of run: tests or stats \n". | |
" -t Which server to run against: JBoss or WLS \n". | |
" -i Input folder. E.g. C:/0706 \n". | |
" -o Output folder. E.g. C:/0706/out \n". | |
" -f Output filename \n". | |
" \n"; | |
if($lVarSize < 1 or $lVarSize%2 > 0) { | |
die $lErrorMessage; | |
} | |
for (my $lIndex = 0; $lIndex < $lVarSize; $lIndex++) { | |
my $lCommand = @ARGV[$lIndex++]; | |
my $lText = @ARGV[$lIndex]; | |
if($lCommand eq "-t") { | |
$iType = $lText; print "For ".$lText."\n"; | |
} | |
elsif($lCommand eq "-r") { | |
$iRunType = $lText; print "Run ".$lText."\n"; | |
} | |
elsif($lCommand eq "-i") { | |
$iDirInput = $lText; print "Input: '".$lText."'\n"; | |
} | |
elsif($lCommand eq "-o") { | |
$iDirOutput = $lText; print "Output: '".$lText."'\n"; | |
} | |
elsif($lCommand eq "-f") { | |
$iOutput = $lText; print "Filename: '".$lText."'\n"; | |
} | |
elsif($lCommand eq "-x") { | |
$iMax = $lText; print "Max Range: '".$lText."'\n"; | |
} | |
elsif($lCommand eq "-n") { | |
$iMin = $lText; print "Min Range: '".$lText."'\n"; | |
} | |
} | |
#Validate the input | |
if(not defined $iType){ | |
die $lErrorMessage; | |
} | |
if(not defined $iRunType){ | |
die $lErrorMessage; | |
} | |
if(not defined $iDirInput){ | |
die $lErrorMessage; | |
} | |
if(not defined $iDirOutput){ | |
die $lErrorMessage; | |
} | |
if(not defined $iOutput){ | |
die $lErrorMessage; | |
} | |
print "\n"; | |
} | |
sub getTestClassName { | |
my $aLine = @_[0]; | |
my $lTestClass; | |
my $lTestName; | |
## Get the Name and Class | |
$aLine =~ m/ name=\"([^\"]+)\"/; | |
$lTestName = $1; | |
$aLine =~ m/classname=\"([^\"]+)\"/; | |
$lTestClass = $1; | |
# Parse out any WIP naming | |
if($lTestName =~ m/^(.*)_WIP_/) { | |
$lTestName = $1; | |
} | |
return "$lTestClass,$lTestName"; | |
} | |
sub getFileName { | |
my $aType = @_[0]; | |
if($aType eq "JBoss") { | |
return "results.jboss.xml"; | |
} elsif($aType eq "WLS") { | |
return "results.weblogic.xml"; | |
} elsif($aType eq "Geronimo") { | |
return "results.geronimo.xml"; | |
} | |
return ""; | |
} | |
sub getFolders { | |
my $aDir = @_[0]; | |
my @lFolders; | |
# Open the directory and get a list of all the subfolders | |
opendir(DIR,"$iDirInput") or die " unable to open the main directory"; | |
@lFolders = grep (!/^\.\.?/, readdir(DIR)); | |
closedir(DIR); | |
return \@lFolders; | |
} | |
################################################################################ | |
# | |
# Obtains and Prints out the Statistics for the builds | |
# | |
# @param aDirInput The directory where all the Build Results folders are located | |
# @param aFileName The input file to be read from each directory | |
# | |
################################################################################ | |
sub generateStatistics { | |
# IO Variables | |
my $aDirInput = @_[0]; | |
my $aFileName = @_[1]; | |
my %lStats; | |
# Open the directory and get a list of all the subfolders | |
my @folders = @{&getFolders($aDirInput)}; | |
# Open the statistic file for each subfolder and analyze | |
foreach $folder (sort @folders) { | |
next if (-l "$aDirInput/$folder"); # skip non-directories | |
next if (-f "$aDirInput/$folder"); # skip non-directories | |
next if ($folder =~ m/ignore/); # skip selected directories | |
print "Folder: $folder\n"; | |
my $lFile = "$aDirInput/$folder/$aFileName"; | |
my @lResults = @{&getStatistics($lFile)}; | |
# Determine the Build no | |
$folder =~ m/-(\d+)/; | |
my $lBuildNo = sprintf("%03d", $1); | |
# Store the results, if any were found | |
if(@lResults > 0) { | |
$lStats{$lBuildNo} = \@lResults; | |
} else { | |
print "No stats found for $folder.\n"; | |
} | |
} | |
# Print the Statistics | |
return \%lStats; | |
} | |
################################################################################ | |
# | |
# Prints out the History of Pass / Fail / Error Unit Test Cases | |
# | |
# @param aResults The Hashmap of all the test results | |
# @param aBuilds The Hashmap of all the Build names | |
# @param aOutput The full directory and filename to which the results will be saved | |
# | |
################################################################################ | |
sub printHistory { | |
my %aResults = %{@_[0]}; | |
my %aBuilds = %{@_[1]}; | |
my $aOutput = @_[2]; | |
my $lOutputLine; | |
# Open/Create the File to publish the results | |
open(OUT,">$aOutput") or die "Unable to create '$aOutput'\n"; | |
# Setup the initial line: Reverse order of all build names | |
$lOutputLine = "Package,Name"; | |
foreach $lBuildId (reverse sort keys %aBuilds){ | |
$lBuildName = $aBuilds{$lBuildId}; | |
$lOutputLine = "$lOutputLine,$lBuildName"; | |
} | |
print OUT "$lOutputLine\n"; | |
# Print out the individual test results: reverse order of builds | |
foreach my $lTestname (sort keys %aResults) { | |
$lOutputLine = $lTestname; | |
foreach $lBuildId (reverse sort keys %aBuilds){ | |
my $lBuildName = $aBuilds{$lBuildId}; | |
my $lTestResult = $aResults{$lTestname}{$lBuildName}; | |
$lOutputLine = "$lOutputLine,$lTestResult"; | |
} | |
print OUT "$lOutputLine\n"; | |
} | |
# Close the output file | |
close(OUT); | |
return; | |
} | |
################################################################################ | |
# | |
# Prints out the Success Rate of the Unit Tests | |
# | |
# @param aBuilds The Hashmap of all the Builds: name, date, tests, failures, errors, % | |
# @param aOutput The full directory and filename to which the results will be saved | |
# | |
################################################################################ | |
sub printStatistics { | |
my %aBuilds = %{@_[0]}; | |
my $aOutput = @_[1]; | |
my $lOutputLine; | |
# Open/Create the File to publish the results | |
open(OUT,">$aOutput") or die "Unable to create '$aOutput'\n"; | |
# Setup the initial line in the Stats file | |
$lOutputLine = "|| *Date* || *Build* || *Total Tests* || *Total Failures* || *Total Errors* || *Success Rate* || *Notes* ||"; | |
print OUT "$lOutputLine\n"; | |
# Print out the individual test results | |
foreach $lBuildId (sort keys %aBuilds){ | |
@lBuildDetails = @{$aBuilds{$lBuildId}}; | |
my $lName = @lBuildDetails[0]; | |
my $lDate = @lBuildDetails[1]; | |
my $lTests = @lBuildDetails[2]; | |
my $lFailures = @lBuildDetails[3]; | |
my $lErrors = @lBuildDetails[4]; | |
my $lPercent = @lBuildDetails[5]; | |
$lOutputLine = "| $lDate | $lName | $lTests | $lFailures | $lErrors | $lPercent | |"; | |
print OUT "$lOutputLine\n"; | |
} | |
# Close the output file | |
close(OUT); | |
return; | |
} | |
################################################################################ | |
# | |
# Determines the Success Rate of the Unit Tests for a specific Build | |
# | |
# @param aInput The full directory and filename to the file under analysis | |
# | |
# @return lResults An array of the build details: name, date, tests, failures, errors, % | |
# | |
################################################################################ | |
sub getStatistics { | |
my $aInput = @_[0]; | |
my @lResults; | |
# Read in the Build Results File | |
if( !open(STATS, $aInput) ) { | |
return @lResults; | |
} | |
my @lLines = <STATS>; | |
close(STATS); | |
# Test Statistics | |
my $lName = ""; | |
my $lDate = ""; | |
my $lTotalTests = 0; | |
my $lTotalErrors = 0; | |
my $lTotalFailures = 0; | |
my $lPercentage = 0; | |
foreach $lLine (@lLines) { | |
# Three valid cases: timestamp, build name, results | |
if($lLine =~ m/property name=\"build\.timestamp\"/) { | |
# Get the TimeStamp | |
$lLine =~ m/value=\"([^\ ]+)/; | |
$lDate = $1; | |
} elsif($lLine =~ m/property name=\"build\.label\"/) { | |
# Get the Build Name | |
$lLine =~ m/value=\"([^\"]+)\"/; | |
$lName = $1; | |
} elsif ($lLine =~ m/<testsuite/) { | |
# Get the Statistics | |
if($lLine =~ m/tests=\"(\d+)\"/) { | |
$lTotalTests += $1; | |
} | |
if($lLine =~ m/failures=\"(\d+)\"/) { | |
$lTotalFailures += $1; | |
} | |
if($lLine =~ m/errors=\"(\d+)\"/) { | |
$lTotalErrors += $1; | |
} | |
} | |
} | |
# Calculate Success Rate % | |
if($lTotalTests > 0) { | |
my $lTotalBad = ($lTotalErrors+$lTotalFailures); | |
$lPercentage = ($lTotalTests - $lTotalBad) * 100 / $lTotalTests; | |
} | |
$lPercentage = sprintf("%.2f", $lPercentage); | |
if($lDate == "") {print "ERR: $lFile\n";} | |
# Store the results: name, date, tests, failures, errors, % | |
@lResults = ($lName, $lDate, $lTotalTests, $lTotalFailures, $lTotalErrors, $lPercentage); | |
return \@lResults; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment