Skip to content

Commit 864faaf

Browse files
tawdry-audreybaldwinmatt
authored andcommitted
fuzz test coverage reporting
1 parent f8de4e3 commit 864faaf

37 files changed

+255
-33
lines changed

.travis.yml

-5
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ jobs:
1313
dist: bionic
1414
env: S2N_LIBCRYPTO=openssl-1.1.1 BUILD_S2N=true TESTS=integration GCC_VERSION=6 S2N_COVERAGE=true CODECOV_IO_UPLOAD=true
1515

16-
- os: linux
17-
# coverage + fuzz flags don't work simultaneously on bionic
18-
dist: trusty
19-
env: S2N_LIBCRYPTO=openssl-1.1.1 LATEST_CLANG=true TESTS=fuzz FUZZ_TIMEOUT_SEC=90 S2N_COVERAGE=true CODECOV_IO_UPLOAD=true
20-
2116
# Normal Build Targets
2217
- os: linux
2318
dist: bionic

.travis/s2n_after_travis_build.sh

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,9 @@ set -ex
1717

1818
# Upload Code Coverage Information to CodeCov.io
1919
if [[ -n "$CODECOV_IO_UPLOAD" ]]; then
20-
bash <(curl -s https://codecov.io/bash) -F ${TESTS};
21-
fi
20+
if [[ -n "$FUZZ_COVERAGE" ]]; then
21+
bash <(curl -s https://codecov.io/bash) -f coverage/fuzz/codecov.txt
22+
else
23+
bash <(curl -s https://codecov.io/bash) -F ${TESTS};
24+
fi
25+
fi

codebuild/bin/install_clang.sh

+10-1
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,21 @@ git clone https://chromium.googlesource.com/chromium/src/tools/clang
4646
echo "Updating Clang..."
4747
python3 "$CLANG_DOWNLOAD_DIR"/clang/scripts/update.py
4848

49-
# "third_party" directory is created above $CLANG_DOWNLOAD_DIR after running
49+
# "third_party" directory is created above $CLANG_DOWNLOAD_DIR after running
5050
# update, move it into $CLANG_DOWNLOAD_DIR once update is complete.
5151
mv ../third_party "$CLANG_DOWNLOAD_DIR"
5252

5353
echo "Installed Clang Version: "
5454
"$CLANG_DOWNLOAD_DIR"/third_party/llvm-build/Release+Asserts/bin/clang --version
5555

56+
# Install matching LLVM if FUZZ_COVERAGE is enabled
57+
if [[ -v FUZZ_COVERAGE ]]; then
58+
LLVM_INSTALL_DIR="$CLANG_INSTALL_DIR"/../llvm
59+
mkdir -p "$LLVM_INSTALL_DIR"
60+
python3 "$CLANG_DOWNLOAD_DIR"/clang/scripts/update.py --package="coverage_tools" --output-dir="$LLVM_INSTALL_DIR"
61+
ln -s $LLVM_INSTALL_DIR/bin/llvm-cov /usr/bin/llvm-cov
62+
ln -s $LLVM_INSTALL_DIR/bin/llvm-profdata /usr/bin/llvm-profdata
63+
fi
64+
5665
mkdir -p "$CLANG_INSTALL_DIR" && cp -rf "$CLANG_DOWNLOAD_DIR"/third_party/llvm-build/Release+Asserts/* "$CLANG_INSTALL_DIR"
5766

codebuild/bin/s2n_after_codebuild.sh

+6-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,10 @@ set -ex
1717

1818
# Upload Code Coverage Information to CodeCov.io
1919
if [[ -n "$CODECOV_IO_UPLOAD" ]]; then
20-
bash <(curl -s https://codecov.io/bash) -F ${TESTS};
20+
if [[ -n "$FUZZ_COVERAGE" ]]; then
21+
bash <(curl -s https://codecov.io/bash) -f coverage/fuzz/codecov.txt
22+
else
23+
bash <(curl -s https://codecov.io/bash) -F ${TESTS};
24+
fi
2125
fi
26+

codebuild/bin/s2n_codebuild.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,6 @@ if [[ "$TESTS" == "ALL" || "$TESTS" == "sawBIKE_r1" ]]; then make -C tests/saw b
8787

8888
# Generate *.gcov files that can be picked up by the CodeCov.io Bash helper script. Don't run lcov or genhtml
8989
# since those will delete .gcov files as they're processed.
90-
if [[ -n "$CODECOV_IO_UPLOAD" ]]; then
90+
if [[ -n "$CODECOV_IO_UPLOAD" && -z "$FUZZ_COVERAGE" ]]; then
9191
make run-gcov;
9292
fi

codebuild/bin/s2n_setup_env.sh

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ export FUZZ_TIMEOUT_SEC
7272
export OS_NAME
7373
export S2N_CORKED_IO
7474

75+
# S2N_COVERAGE should not be used with fuzz tests, use FUZZ_COVERAGE instead
76+
if [[ -v S2N_COVERAGE && "$TESTS" == "fuzz" ]]; then
77+
unset S2N_COVERAGE
78+
export FUZZ_COVERAGE=true
79+
fi
7580

7681
# Select the libcrypto to build s2n against. If this is unset, default to the latest stable version(Openssl 1.1.1)
7782
if [[ -z $S2N_LIBCRYPTO ]]; then export LIBCRYPTO_ROOT=$OPENSSL_1_1_1_INSTALL_DIR ; fi

codebuild/codebuild.config

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ source_version:
2323
# Fuzzers
2424
[CodeBuild:s2nfuzzerOpenSSL111Coverage]
2525
snippet: UbuntuBoilerplate2XL
26-
env: S2N_LIBCRYPTO=openssl-1.1.1 LATEST_CLANG=true TESTS=fuzz FUZZ_TIMEOUT_SEC=120 S2N_COVERAGE=true
26+
env: S2N_LIBCRYPTO=openssl-1.1.1 LATEST_CLANG=true TESTS=fuzz FUZZ_TIMEOUT_SEC=120 FUZZ_COVERAGE=true CODECOV_IO_UPLOAD=true
2727

2828
[CodeBuild:s2nfuzzerOpenSSL102FIPS]
2929
snippet: UbuntuBoilerplate2XL

codebuild/spec/buildspec_ubuntu.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ phases:
3232
if expr "${GCC_VERSION}" : "6" >/dev/null; then
3333
apt-get install -y --no-install-recommends g++ g++-6 gcc gcc-6;
3434
fi
35-
- apt-get install -y --no-install-recommends indent kwstyle lcov libssl-dev clang-3.9 llvm-3.9 m4 make net-tools nettle-bin nettle-dev pkg-config psmisc python3-pip shellcheck sudo tcpdump unzip valgrind zlib1g-dev zlibc
35+
36+
# Don't install old clang and llvm if LATEST_CLANG is enabled, handle it in install_clang.sh instead
37+
- |
38+
if expr "${LATEST_CLANG}" != "true" >/dev/null; then
39+
apt-get install -y --no-install-recommends clang-3.9 llvm-3.9;
40+
fi
41+
- apt-get install -y --no-install-recommends indent kwstyle lcov libssl-dev m4 make net-tools nettle-bin nettle-dev pkg-config psmisc python3-pip shellcheck sudo tcpdump unzip valgrind zlib1g-dev zlibc
3642
pre_build:
3743
commands:
3844
- codebuild/bin/install_default_dependencies.sh

coverage/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ include ../s2n.mk
1818
.PHONY : clean
1919
clean: decruft
2020
rm -rf ./html/*
21-
21+
rm -rf ./fuzz/*

lib/Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ all: libs2n.a libs2n.so libs2n.dylib
2020

2121
include ../s2n.mk
2222

23+
ifdef FUZZ_COVERAGE
24+
FUZZCOV_FLAGS = -fprofile-instr-generate -fcoverage-mapping
25+
endif
26+
2327
libs2n.a: ${OBJS}
2428
$(AR) cru libs2n.a ${OBJS}
2529
$(RANLIB) libs2n.a
2630

2731
libs2n.so: ${OBJS}
28-
${CC} -shared -o libs2n.so ${OBJS} ${LIBS} -L${LIBCRYPTO_ROOT}/lib ${CRYPTO_LIBS}
32+
${CC} ${FUZZCOV_FLAGS} -shared -o libs2n.so ${OBJS} ${LIBS} -L${LIBCRYPTO_ROOT}/lib ${CRYPTO_LIBS}
2933

3034
libs2n.dylib: ${OBJS}
3135
test ! -f /usr/lib/libSystem.dylib || libtool -dynamic ${LIBS} -L${LIBCRYPTO_ROOT}/lib ${CRYPTO_LIBS} -o libs2n.dylib ${OBJS}

s2n.mk

+11-4
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,17 @@ DEFAULT_CFLAGS = -pedantic -Wall -Werror -Wimplicit -Wunused -Wcomment -Wchar-su
4444
COVERAGE_CFLAGS = -fprofile-arcs -ftest-coverage
4545
COVERAGE_LDFLAGS = --coverage
4646

47-
ifdef S2N_COVERAGE
48-
DEFAULT_CFLAGS += ${COVERAGE_CFLAGS}
49-
LIBS += ${COVERAGE_LDFLAGS}
47+
FUZZ_CFLAGS = -fsanitize-coverage=trace-pc-guard -fsanitize=address,undefined,leak
48+
49+
# Define FUZZ_COVERAGE - to be used for generating coverage reports on fuzz tests
50+
# !!! NOT COMPATIBLE WITH S2N_COVERAGE !!!
51+
ifdef FUZZ_COVERAGE
52+
FUZZ_CFLAGS += -fprofile-instr-generate -fcoverage-mapping
53+
else
54+
ifdef S2N_COVERAGE
55+
DEFAULT_CFLAGS += ${COVERAGE_CFLAGS}
56+
LIBS += ${COVERAGE_LDFLAGS}
57+
endif
5058
endif
5159

5260
# Add a flag to disable stack protector for alternative libcs without
@@ -88,7 +96,6 @@ ifdef S2N_DEBUG
8896
CFLAGS += ${DEBUG_CFLAGS}
8997
endif
9098

91-
FUZZ_CFLAGS = -fsanitize-coverage=trace-pc-guard -fsanitize=address,undefined,leak
9299
LLVM_GCOV_MARKER_FILE=${COVERAGE_DIR}/use-llvm-gcov.tmp
93100

94101
ifeq ($(S2N_UNSAFE_FUZZING_MODE),1)

tests/fuzz/Makefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@ ifndef FUZZ_TESTS
3030
export FUZZ_TESTS=${TESTS}
3131
endif
3232

33-
3433
.PHONY : all
3534
all : run_tests
3635

3736
include ../../s2n.mk
3837

39-
CRUFT += $(wildcard *_test) $(wildcard fuzz-*.log) $(wildcard *_test_output.txt) $(wildcard *_test_results.txt) $(wildcard LD_PRELOAD/*.so)
38+
CRUFT += $(wildcard *_test) $(wildcard fuzz-*.log) $(wildcard *_test_output.txt) $(wildcard *_test_results.txt) $(wildcard LD_PRELOAD/*.so) $(wildcard *.prof*)
4039
LIBS += -lm -ltests2n
4140

4241
CFLAGS += -Wno-unreachable-code -O0 -I$(LIBCRYPTO_ROOT)/include/ -I../
@@ -59,7 +58,9 @@ run_tests:: $(TESTS) ld-preload
5958
./runFuzzTest.sh $${test_name} ${FUZZ_TIMEOUT_SEC} || fail_count=`expr $$fail_count + 1`; done; \
6059
exit $${fail_count}; \
6160
)
61+
@./calcTotalCov.sh
6262

6363
.PHONY : clean
6464
clean: decruft
6565
${MAKE} -C LD_PRELOAD decruft
66+
rm -rf profiles

tests/fuzz/Readme.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Fuzz Tests
2-
Every test in this directory will be run as a Fuzz test for several minutes during builds. To run all fuzz tests simply run `make fuzz` from the top `s2n` directory to compile s2n with the proper flags and run the fuzz tests.
2+
By default, every test in this directory will be run as a fuzz test for several minutes each during builds. To run all fuzz tests simply run `make fuzz` from the top `s2n` directory to compile s2n with the proper flags and run the fuzz tests. To run a specific subset of fuzz tests, simply set the FUZZ_TESTS variable as follows:
3+
4+
> FUZZ_TESTS="test1 test2 test3"
35
46
#### Each Fuzz Test should conform to the following rules:
57
1. End in either `*_test.c` or `*_negative_test.c`.
@@ -10,6 +12,17 @@ Every test in this directory will be run as a Fuzz test for several minutes duri
1012
4. Have a function `int LLVMFuzzerInitialize(const uint8_t *buf, size_t len)` that will perform any initialization that will be run only once at startup.
1113
5. Have a function `int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)` that will pass `buf` to one of s2n's API's
1214

15+
## Fuzz Test Coverage
16+
To generate coverage reports for fuzz tests, simply set the FUZZ_COVERAGE environment variable to any non-null value and run `make fuzz`. This will report the target function coverage and overall S2N coverage when running the tests. In order to define target functions for a fuzz test, simply add the following line to your fuzz test below the copyright notice:
17+
18+
> /* Target Functions: function1 function2 function3 */
19+
20+
As the tests run, more detailed coverage reports are placed in the following directory:
21+
22+
> s2n/coverage/fuzz
23+
24+
Each test outputs an HTML file which displays line by line coverage statistics and a .txt report which gives per-function coverage statistics in human-readable ASCII. After all fuzz tests have ran, a matching pair of coverage reports is generated for the total coverage of S2N by the entire set of tests performed.
25+
1326
## Fuzz Test Directory Structure
1427
For a test with name `$TEST_NAME`, its files should be laid out with the following structure:
1528

tests/fuzz/calcTotalCov.sh

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://aws.amazon.com/apache2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
#
15+
16+
set -e
17+
18+
usage() {
19+
echo "Usage: calcTotalCov.sh"
20+
exit 1
21+
}
22+
23+
if [ "$#" -ne "0" ]; then
24+
usage
25+
fi
26+
27+
if [[ ! -v S2N_ROOT ]]; then
28+
S2N_ROOT=../..
29+
fi
30+
31+
FUZZCOV_SOURCES="${S2N_ROOT}/api ${S2N_ROOT}/bin ${S2N_ROOT}/crypto ${S2N_ROOT}/error ${S2N_ROOT}/pq-crypto ${S2N_ROOT}/stuffer ${S2N_ROOT}/tls ${S2N_ROOT}/utils"
32+
33+
34+
# Outputs fuzz coverage results if the FUZZ_COVERAGE environment variable is set
35+
# Total coverage is overlayed on source code in s2n_cov.html and coverage statistics are available in s2n_cov.txt
36+
# If using LLVM version 9 or greater, coverage is output in LCOV format instead of HTML
37+
# All files are stored in the s2n coverage directory
38+
if [[ -v FUZZ_COVERAGE ]]; then
39+
40+
printf "Calculating total s2n coverage... "
41+
42+
# The llvm-profdata merge command warns that the profraws were created from different binaries (which is true) but
43+
# works fine for what we care about (the s2n library). Therefore, for user clarity all output is suppressed.
44+
llvm-profdata merge -sparse ./profiles/*/*.profdata -o ./profiles/s2n_cov.profdata > /dev/null 2>&1
45+
llvm-cov report -instr-profile=./profiles/s2n_cov.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} > ${COVERAGE_DIR}/fuzz/s2n_cov.txt
46+
47+
# Use LCOV format instead of HTML if the LLVM version we're using supports it
48+
if [[ $(grep -Eo "[0-9]*" <<< `llvm-cov --version` | head -1) > 8 ]]; then
49+
llvm-cov export -instr-profile=./profiles/s2n_cov.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} -format=lcov > ${COVERAGE_DIR}/fuzz/s2n_cov.info
50+
genhtml -q -o ${COVERAGE_DIR}/html/overall_fuzz_coverage ${COVERAGE_DIR}/fuzz/s2n_cov.info
51+
else
52+
llvm-cov show -instr-profile=./profiles/s2n_cov.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} -use-color -format=html > ${COVERAGE_DIR}/fuzz/s2n_cov.html
53+
fi
54+
# Generate coverage report compatible with codecov.io
55+
llvm-cov show -instr-profile=./profiles/s2n_cov.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} > ${COVERAGE_DIR}/fuzz/codecov.txt
56+
57+
S2N_COV=`grep -Eo '[0-9]*\.[0-9]*\%' ${COVERAGE_DIR}/fuzz/s2n_cov.txt | tail -1`
58+
printf "total s2n coverage from fuzz tests: %s\n" $S2N_COV
59+
fi

tests/fuzz/runFuzzTest.sh

+60-7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ LIBFUZZER_ARGS+="-timeout=5 -max_len=4096 -print_final_stats=1 -jobs=${NUM_CPU_T
4545
TEST_SPECIFIC_OVERRIDES="${PWD}/LD_PRELOAD/${TEST_NAME}_overrides.so"
4646
GLOBAL_OVERRIDES="${PWD}/LD_PRELOAD/global_overrides.so"
4747

48+
FUZZCOV_SOURCES="${S2N_ROOT}/api ${S2N_ROOT}/bin ${S2N_ROOT}/crypto ${S2N_ROOT}/error ${S2N_ROOT}/pq-crypto ${S2N_ROOT}/stuffer ${S2N_ROOT}/tls ${S2N_ROOT}/utils"
49+
4850
if [ -e $TEST_SPECIFIC_OVERRIDES ];
4951
then
5052
export LD_PRELOAD="$TEST_SPECIFIC_OVERRIDES $GLOBAL_OVERRIDES"
@@ -68,18 +70,69 @@ ACTUAL_TEST_FAILURE=0
6870
TEMP_CORPUS_DIR="$(mktemp -d)"
6971
cp -r ./corpus/${TEST_NAME}/. "${TEMP_CORPUS_DIR}"
7072

71-
7273
printf "Running %-s %-40s for %5d sec with %2d threads... " "${FIPS_TEST_MSG}" ${TEST_NAME} ${FUZZ_TIMEOUT_SEC} ${NUM_CPU_THREADS}
73-
./${TEST_NAME} ${LIBFUZZER_ARGS} ${TEMP_CORPUS_DIR} > ${TEST_NAME}_output.txt 2>&1 || ACTUAL_TEST_FAILURE=1
74+
75+
# Setup and clean profile structure if FUZZ_COVERAGE is enabled, otherwise run as normal
76+
if [[ -v FUZZ_COVERAGE ]]; then
77+
mkdir -p "./profiles/${TEST_NAME}"
78+
rm -f ./profiles/${TEST_NAME}/*.profraw
79+
LLVM_PROFILE_FILE="./profiles/${TEST_NAME}/${TEST_NAME}.%p.profraw" ./${TEST_NAME} ${LIBFUZZER_ARGS} ${TEMP_CORPUS_DIR} > ${TEST_NAME}_output.txt 2>&1 || ACTUAL_TEST_FAILURE=1
80+
else
81+
./${TEST_NAME} ${LIBFUZZER_ARGS} ${TEMP_CORPUS_DIR} > ${TEST_NAME}_output.txt 2>&1 || ACTUAL_TEST_FAILURE=1
82+
fi
83+
7484

7585
TEST_COUNT=`grep -o "stat::number_of_executed_units: [0-9]*" ${TEST_NAME}_output.txt | awk '{test_count += $2} END {print test_count}'`
7686
TESTS_PER_SEC=`echo $(($TEST_COUNT / $FUZZ_TIMEOUT_SEC))`
7787
FEATURE_COVERAGE=`grep -o "ft: [0-9]*" ${TEST_NAME}_output.txt | awk '{print $2}' | sort | tail -1`
88+
TARGET_FUNCS=''
89+
declare -i TARGET_TOTAL=0
90+
declare -i TARGET_COV=0
91+
92+
# Outputs fuzz coverage results if the FUZZ_COVERAGE environment variable is set
93+
# Coverage is overlayed on source code in ${TEST_NAME}_cov.html, and coverage statistics are available in ${TEST_NAME}_cov.txt
94+
# If using LLVM version 9 or greater, coverage is output in LCOV format instead of HTML
95+
# All files are stored in the s2n coverage directory
96+
if [[ -v FUZZ_COVERAGE ]]; then
97+
mkdir -p ${COVERAGE_DIR}/fuzz
98+
llvm-profdata merge -sparse ./profiles/${TEST_NAME}/*.profraw -o ./profiles/${TEST_NAME}/${TEST_NAME}.profdata
99+
llvm-cov report -instr-profile=./profiles/${TEST_NAME}/${TEST_NAME}.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} -show-functions > ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.txt
100+
101+
# Use LCOV format instead of HTML if the LLVM version we're using supports it
102+
if [[ $(grep -Eo "[0-9]*" <<< `llvm-cov --version` | head -1) > 8 ]]; then
103+
llvm-cov export -instr-profile=./profiles/${TEST_NAME}/${TEST_NAME}.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} -format=lcov > ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.info
104+
genhtml -q -o ${COVERAGE_DIR}/html/${TEST_NAME} ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.info
105+
else
106+
llvm-cov show -instr-profile=./profiles/${TEST_NAME}/${TEST_NAME}.profdata ${S2N_ROOT}/lib/libs2n.so ${FUZZCOV_SOURCES} -use-color -format=html > ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.html
107+
fi
108+
109+
# Extract target functions from test source
110+
TARGET_FUNCS=`grep -Pzo "(?<=/\* Target Functions: )[\w\s]*" ${TEST_NAME}.c | tr -d "\0"`
111+
112+
# Find line coverage statistics for target functions
113+
if [[ ! -z TARGET_FUNCS ]];
114+
then
115+
for TARGET in ${TARGET_FUNCS}
116+
do
117+
TARGET_TOTAL+=`sed -n "s/^.*${TARGET} .*% *\([0-9]*\) .*$/\1/p" ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.txt`
118+
TARGET_COV+=`sed -n "s/^.*${TARGET} .*% *[0-9]* *\([0-9]*\) .*$/\1/p" ${COVERAGE_DIR}/fuzz/${TEST_NAME}_cov.txt`
119+
done
120+
fi
121+
fi
78122
79123
if [ $ACTUAL_TEST_FAILURE == $EXPECTED_TEST_FAILURE ];
80124
then
81-
printf "\033[32;1mPASSED\033[0m %8d tests, %6d test/sec, %5d features covered" $TEST_COUNT $TESTS_PER_SEC $FEATURE_COVERAGE
82-
125+
printf "\033[32;1mPASSED\033[0m %8d tests, %6d test/sec" $TEST_COUNT $TESTS_PER_SEC
126+
127+
# Output target function coverage percentage if target functions are defined and fuzzing coverage is enabled
128+
# Otherwise, print number of features covered
129+
if [[ -v FUZZ_COVERAGE && ! -z TARGET_FUNCS && $EXPECTED_TEST_FAILURE != 1 && $TARGET_TOTAL != 0 ]];
130+
then
131+
printf ", %6.2f%% target coverage" "$(( 10000 * ($TARGET_TOTAL - $TARGET_COV) / $TARGET_TOTAL ))e-2"
132+
else
133+
printf ", %5d features covered" $FEATURE_COVERAGE
134+
fi
135+
83136
if [ $EXPECTED_TEST_FAILURE == 1 ];
84137
then
85138
# Clean up LibFuzzer corpus files if the test is negative.
@@ -89,11 +142,11 @@ then
89142
# TEMP_CORPUS_DIR may contain many new inputs that only covers a small set of new branches.
90143
# Instead of copying all new inputs to the corpus directory, only copy back minimum number of new inputs that reach new branches.
91144
./${TEST_NAME} -merge=1 "./corpus/${TEST_NAME}" "${TEMP_CORPUS_DIR}" > ${TEST_NAME}_results.txt 2>&1
92-
145+
93146
# Print number of new files and branches found in new Inputs (if any)
94147
RESULTS=`grep -Eo "[0-9]+ new files .*$" ${TEST_NAME}_results.txt | tail -1`
95148
printf ", ${RESULTS}\n"
96-
149+
97150
if [ "$TESTS_PER_SEC" -lt $MIN_TEST_PER_SEC ]; then
98151
printf "\033[33;1mWARNING!\033[0m ${TEST_NAME} is only ${TESTS_PER_SEC} tests/sec, which is below ${MIN_TEST_PER_SEC}/sec! Fuzz tests are more effective at higher rates.\n\n"
99152
fi
@@ -103,7 +156,7 @@ then
103156
exit -1;
104157
fi
105158
fi
106-
159+
107160
else
108161
cat ${TEST_NAME}_output.txt
109162
printf "\033[31;1mFAILED\033[0m %10d tests, %6d features covered\n" $TEST_COUNT $FEATURE_COVERAGE

tests/fuzz/s2n_bike_r1_fuzz_test.c

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16+
/* Target Functions: s2n_kem_decapsulate BIKE_L1_R1_crypto_kem_dec */
17+
1618
#include "tests/s2n_test.h"
1719
#include "tests/testlib/s2n_nist_kats.h"
1820
#include "tests/testlib/s2n_testlib.h"

0 commit comments

Comments
 (0)