Skip to content

Instantly share code, notes, and snippets.

@andyscott
Created December 10, 2019 05:15
Show Gist options
  • Save andyscott/ac6c9b599104888a133c3b2b9e2c95a1 to your computer and use it in GitHub Desktop.
Save andyscott/ac6c9b599104888a133c3b2b9e2c95a1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
function show_usage {
cat <<'EOF'
Converts Bazel's build event protocol to JUnit XML
usage: bep-json-to-junit-xml <output-dir> [<input-bep-json>]
options:
output-dir : The directory to write junit xmls.
input-bep-json: The input json to read. Defaults to stdin, if not present.
EOF
}
# --- begin bash runfile prelude --
if ! hash runfile; then
if [[ -e "${TEST_SRCDIR:-}" ]]; then
function runfile() {
echo "$TEST_SRCDIR/$1"
}
elif [[ -f "$0.runfiles_manifest" ]]; then
__runfiles_manifest_file="$0.runfiles_manifest"
export __runfiles_manifest_file
function runfile() {
grep -m1 "^$1 " "$__runfiles_manifest_file" | cut -d ' ' -f 2-
}
else
echo "please run this script through bazel"
exit 1
fi
export -f runfile
fi
# --- end bash runfile prelude --
set -eo pipefail
PATH=$(dirname "$(runfile jq/bin/jq)"):$PATH
case $# in
1|2)
output_dir="$1"
input_fd="${2:-/dev/stdin}"
;;
*)
show_usage
exit 1
;;
esac
# jq filter to find failed tests and return
# the label as well as the output log file
test_failures_filter=$(cat <<-'EOF'
( select(.id.testResult != null) |
select(.testResult.status == "FAILED") |
( (.id.testResult.label)
, (.id.testResult.label)
, (.testResult.testActionOutput[] | select(.name == "test.log").uri)
)
) //
( select(.id.actionCompleted != null) |
select(.action.success? != true) |
( (.id.actionCompleted.label)
, (.action.type)
, (.action.stderr.uri)
)
)
EOF
)
# action for each failed tests
# receives the jq outputs as params over stdin
function test_failures_handler {
while read -r label extra log_file;
do
if [[ -z "$label" || -z "$extra" || -z "$log_file" ]]; then
echo "Warning! Handler received" 1>&2
echo "label : $label" 1>&2
echo "log_file: $log_file" 1>&2
break
fi
log_file=${log_file#"file://"}
# shellcheck disable=SC2001
output_file_name="$(echo "${label#"//"}" | sed -e 's/[^[:alnum:]_]/_/g')".xml
make_junit_xml "$label" "$extra" "$log_file" > "$output_dir"/"$output_file_name"
done
}
function make_junit_xml {
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<testsuites>'
printf ' <testsuite name="%s" tests="1" failures="0" errors="1">\n' "$1"
printf ' <testcase name="%s" status="run" duration="1" time="1">\n' "$2"
echo ' <error message="exited with error code 1"></error>'
echo ' </testcase>'
echo ' <system-out><![CDATA['
sed -e 's/]]>/]]]]><![CDATA[>/g' < "${3:-/dev/stdin}"
echo ']]></system-out>'
echo ' </testsuite>'
echo '</testsuites>'
}
jq \
--unbuffered \
--raw-output \
"$test_failures_filter" \
< "$input_fd" \
| xargs -n3 echo \
| test_failures_handler
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment