From a8e65d908ea49c51c4e95565dfe11711d2a484df Mon Sep 17 00:00:00 2001 From: Chung Min Kim Date: Mon, 30 Jul 2018 09:35:55 -0700 Subject: [PATCH] Fixing up `make html` target Add types of files that genhtml (the program that generates html files from .gcno/.gcda files, included in lcov) should ignore, such as .yy and .ll files. --- testing/coverage/Makefile | 5 +-- testing/coverage/README | 11 ++---- testing/coverage/code_coverage.sh | 12 ++++-- testing/coverage/lcov_html.sh | 61 +++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 15 deletions(-) create mode 100755 testing/coverage/lcov_html.sh diff --git a/testing/coverage/Makefile b/testing/coverage/Makefile index 1aa8036bbf..7f458a4f9c 100644 --- a/testing/coverage/Makefile +++ b/testing/coverage/Makefile @@ -9,7 +9,4 @@ distclean: cleanup @find ../../ -name "*.gcno" -exec rm {} \; html: - @(cd ../../; if which lcov; then\ - lcov --capture --directory . --output-file coverage.info \ - && genhtml coverage.info && rm coverage.info; \ - fi) + @./lcov_html.sh $(COVERAGE_HTML_DIR) diff --git a/testing/coverage/README b/testing/coverage/README index 0c19e14d51..2cda389452 100644 --- a/testing/coverage/README +++ b/testing/coverage/README @@ -2,12 +2,7 @@ On a Bro build configured with --enable-coverage, this script produces a code co This depends on gcov, which should come with your gcc. If gcov is not installed, the script will abort with an error message. -TODO: Use `make html` as make target in this directory to output the html files that gcov can create (must have lcov on system). +After `make all` in the upper directory, use `make html` as make target in this directory to output the html files that lcov can create. By default, the html files will be contained in a directory named "coverage-html" in the base directory. To set a custom name, use `make html COVERAGE_HTML_DIR=custom-dir-name`. -The goal of code-coverage.sh script is to automate code coverage testing. See the following steps for the code structure: - 1. Run test suite - 2. Check for .gcda files existing. - 3a. Run gcov (-p to preserve path) - 3b. Prune .gcov files for objects outside of the Bro tree - 4a. Analyze .gcov files generated and create summary file - 4b. Send .gcov files to appropriate path +The script code_coverage.sh is triggered by `make coverage` (included in `make` in /testing), and its goal is to automate code coverage testing. +The script lcov_html.sh is triggered by `make html`, and its goal is to create html files from the aforementioned coverage data. diff --git a/testing/coverage/code_coverage.sh b/testing/coverage/code_coverage.sh index ec583b1e5e..758b2fa915 100755 --- a/testing/coverage/code_coverage.sh +++ b/testing/coverage/code_coverage.sh @@ -17,13 +17,12 @@ # 4b. Send .gcov files to appropriate path # CURR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Location of script -BASE="$(readlink -f "${CURR}/../../")" +BASE="$( cd "$CURR" && cd ../../ && pwd )" TMP="${CURR}/tmp.$$" mkdir -p $TMP # DEFINE CLEANUP PROCESS function finish { - find "$BASE" -name "*.gcda" -exec rm {} \; > /dev/null 2>&1 rm -rf $TMP } trap finish EXIT @@ -98,13 +97,20 @@ echo "ok" # 3a. Run gcov (-p to preserve path) and move into tmp directory # ... if system does not have gcov installed, exit with message. echo -n "Creating coverage files... " -if which gcov; then +if which gcov > /dev/null 2>&1; then ( cd "$TMP" && find "$BASE" -name "*.o" -exec gcov -p {} > /dev/null 2>&1 \; ) NUM_GCOVS=$(find "$TMP" -name *.gcov | wc -l) if [ $NUM_GCOVS -eq 0 ]; then echo "no gcov files produced, aborting" exit 1 fi + + # Account for '^' that occurs in macOS due to LLVM + # This character seems to be equivalent to ".." (up 1 dir) + for file in $(ls $TMP/*.gcov | grep '\^'); do + mv $file "$(sed 's/#[^#]*#\^//g' <<< "$file")" + done + echo "ok, $NUM_GCOVS coverage files" else echo "gcov is not installed on system, aborting" diff --git a/testing/coverage/lcov_html.sh b/testing/coverage/lcov_html.sh new file mode 100755 index 0000000000..d1af203437 --- /dev/null +++ b/testing/coverage/lcov_html.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# +# On a Bro build configured with --enable-coverage, this script +# produces a code coverage report in HTML format after Bro has been invoked. The +# intended application of this script is after the btest testsuite has run. + +# This depends on lcov to run. + +function die { + echo "$@" + exit 1 +} +function finish { + rm -rf "$TMP" +} +function verify-run { + if bash -c "$1" > /dev/null 2>&1; then + echo ${2:-"ok"} + else + die ${3:-"error, abort"} + fi +} +trap finish EXIT + +COVERAGE_FILE="./$TMP/coverage.info" +COVERAGE_HTML_DIR="${1:-"coverage-html"}" +REMOVE_TARGETS="*.yy *.ll *.y *.l" + +# 1. Move to base dir, create tmp dir +cd ../../; +TMP=".tmp.$$" +mkdir "$TMP" + +# 2. Check for .gcno and .gcda file presence +echo -n "Checking for coverage files... " +for pat in gcda gcno; do + if [ -z "$(find "$BASE" -name "*.$pat" 2>/dev/null)" ]; then + echo "no .$pat files, nothing to do" + exit 0 + fi +done +echo "ok" + +# 3. If lcov does not exist, abort process. +echo -n "Checking for lcov... " +verify-run "which lcov" \ + "lcov installed on system, continue" \ + "lcov not installed, abort" + +# 4. Create a "tracefile" through lcov, which is necessary to create html files later on. +echo -n "Creating tracefile for html generation... " +verify-run "lcov --no-external --capture --directory . --output-file $COVERAGE_FILE" + +for TARGET in $REMOVE_TARGETS; do + echo -n "Getting rid of $TARGET files from tracefile... " + verify-run "lcov --remove $COVERAGE_FILE $TARGET --output-file $COVERAGE_FILE" +done + +# 5. Create HTML files. +echo -n "Creating HTML files... " +verify-run "genhtml -q -o $COVERAGE_HTML_DIR $COVERAGE_FILE"