k3s/third_party/forked/shell2junit/sh2ju.sh

179 lines
5.6 KiB
Bash
Raw Normal View History

#!/bin/bash
2016-06-22 23:38:31 +00:00
### Copyright 2010 Manuel Carrasco Moñino. (manolo at apache.org)
###
### Licensed under the Apache License, Version 2.0.
### You may obtain a copy of it at
### http://www.apache.org/licenses/LICENSE-2.0
###
### A library for shell scripts which creates reports in jUnit format.
### These reports can be used in Jenkins, or any other CI.
###
### Usage:
### - Include this file in your shell script
### - Use juLog to call your command any time you want to produce a new report
### Usage: juLog <options> command arguments
### options:
### -class="MyClass" : a class name which will be shown in the junit report
### -name="TestName" : the test name which will be shown in the junit report
### -error="RegExp" : a regexp which sets the test as failure when the output matches it
### -ierror="RegExp" : same as -error but case insensitive
### -output="Path" : path to output directory, defaults to "./results"
2016-06-22 23:38:31 +00:00
### - Junit reports are left in the folder 'result' under the directory where the script is executed.
### - Configure Jenkins to parse junit files from the generated folder
###
asserts=00; errors=0; total=0; content=""
date=`which gdate 2>/dev/null || which date`
# default output folder
2016-06-22 23:38:31 +00:00
juDIR=`pwd`/results
# The name of the suite is calculated based in your script name
suite=""
# A wrapper for the eval method witch allows catching seg-faults and use tee
errfile=/tmp/evErr.$$.log
function eVal() {
(eval "$1")
2016-06-22 23:38:31 +00:00
# stdout and stderr may currently be inverted (see below) so echo may write to stderr
echo $? 2>&1 | tr -d "\n" > $errfile
}
# Method to clean old tests
function juLogClean() {
2016-06-22 23:38:31 +00:00
echo "+++ Removing old junit reports from: $juDIR "
2016-06-28 22:02:36 +00:00
rm -f "$juDIR"/junit-*
2016-06-22 23:38:31 +00:00
}
# Execute a command and record its results
function juLog() {
2016-06-22 23:38:31 +00:00
suite="";
errfile=/tmp/evErr.$$.log
date=`which gdate || which date`
asserts=00; errors=0; total=0; content=""
# parse arguments
ya=""; icase=""
while [ -z "$ya" ]; do
case "$1" in
-name=*) name=`echo "$1" | sed -e 's/-name=//'`; shift;;
-class=*) class=`echo "$1" | sed -e 's/-class=//'`; shift;;
-ierror=*) ereg=`echo "$1" | sed -e 's/-ierror=//'`; icase="-i"; shift;;
-error=*) ereg=`echo "$1" | sed -e 's/-error=//'`; shift;;
-output=*) juDIR=`echo "$1" | sed -e 's/-output=//'`; shift;;
2016-06-22 23:38:31 +00:00
*) ya=1;;
esac
done
# create output directory
mkdir -p "$juDIR" || exit
2016-06-22 23:38:31 +00:00
# use first arg as name if it was not given
if [ -z "$name" ]; then
name="$asserts-$1"
shift
fi
if [[ "$class" = "" ]]; then
class="default"
fi
suite=$class
# calculate command to eval
[ -z "$1" ] && return
cmd="$1"; shift
while [ -n "$1" ]
do
cmd="$cmd \"$1\""
shift
done
# eval the command sending output to a file
outf=/var/tmp/ju$$.txt
errf=/var/tmp/ju$$-err.txt
>$outf
echo "" | tee -a $outf
echo "+++ Running case: $class.$name " | tee -a $outf
echo "+++ working dir: "`pwd` | tee -a $outf
echo "+++ command: $cmd" | tee -a $outf
ini=`$date +%s.%N`
# execute the command, temporarily swapping stderr and stdout so they can be tee'd to separate files,
# then swapping them back again so that the streams are written correctly for the invoking process
( (eVal "$cmd" | tee -a $outf) 3>&1 1>&2 2>&3 | tee $errf) 3>&1 1>&2 2>&3
2016-06-22 23:38:31 +00:00
evErr=`cat $errfile`
rm -f $errfile
end=`$date +%s.%N`
echo "+++ exit code: $evErr" | tee -a $outf
# set the appropriate error, based in the exit code and the regex
[ $evErr != 0 ] && err=1 || err=0
out=`cat $outf | sed -e 's/^\([^+]\)/| \1/g'`
if [ $err = 0 -a -n "$ereg" ]; then
H=`echo "$out" | egrep $icase "$ereg"`
[ -n "$H" ] && err=1
fi
[ $err != 0 ] && echo "+++ error: $err" | tee -a $outf
2016-06-22 23:38:31 +00:00
rm -f $outf
errMsg=`cat $errf`
rm -f $errf
# calculate vars
asserts=$(($asserts+1))
errors=$(($errors+$err))
2016-06-22 23:38:31 +00:00
time=`echo "$end - $ini" | bc -l`
total=`echo "$total + $time" | bc -l`
# write the junit xml report
## failure tag
[ $err = 0 ] && failure="" || failure="
<failure type=\"ScriptError\" message=\"Script Error\">
<![CDATA[
$errMsg
]]>
</failure>
2016-06-22 23:38:31 +00:00
"
## testcase tag
content="$content
<testcase assertions=\"1\" name=\"$name\" time=\"$time\" classname=\"$class\">
2016-06-22 23:38:31 +00:00
$failure
<system-err>
<![CDATA[
$errMsg
]]>
</system-err>
</testcase>
"
## testsuite block
2017-06-15 20:38:41 +00:00
if [[ -e "$juDIR/junit_$suite.xml" ]]; then
# file exists. first update the failures count
2017-06-15 20:38:41 +00:00
failCount=`sed -n "s/.*testsuite.*failures=\"\([0-9]*\)\".*/\1/p" "$juDIR/junit_$suite.xml"`
errors=$(($failCount+$errors))
2017-06-15 20:38:41 +00:00
sed -i "0,/failures=\"$failCount\"/ s/failures=\"$failCount\"/failures=\"$errors\"/" "$juDIR/junit_$suite.xml"
sed -i "0,/errors=\"$failCount\"/ s/errors=\"$failCount\"/errors=\"$errors\"/" "$juDIR/junit_$suite.xml"
2016-06-22 23:38:31 +00:00
# file exists. Need to append to it. If we remove the testsuite end tag, we can just add it in after.
2017-06-15 20:38:41 +00:00
sed -i "s^</testsuite>^^g" $juDIR/junit_$suite.xml ## remove testSuite so we can add it later
sed -i "s^</testsuites>^^g" $juDIR/junit_$suite.xml
cat <<EOF >> "$juDIR/junit_$suite.xml"
2016-06-22 23:38:31 +00:00
$content
</testsuite>
2017-06-14 01:35:29 +00:00
</testsuites>
2016-06-22 23:38:31 +00:00
EOF
else
# no file exists. Adding a new file
2017-06-15 20:38:41 +00:00
cat <<EOF > "$juDIR/junit_$suite.xml"
2017-06-14 01:35:29 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite failures="$errors" assertions="$assertions" name="$suite" tests="1" errors="$errors" time="$total">
2016-06-22 23:38:31 +00:00
$content
</testsuite>
2017-06-14 01:35:29 +00:00
</testsuites>
2016-06-22 23:38:31 +00:00
EOF
fi
2017-06-12 21:08:52 +00:00
return $err
}