1#!/bin/sh
2
3help () {
4    cat <<EOF
5Usage: $0 [-r]
6Collect coverage statistics of library code into an HTML report.
7
8General instructions:
91. Build the library with CFLAGS="--coverage -O0 -g3" and link the test
10   programs with LDFLAGS="--coverage".
11   This can be an out-of-tree build.
12   For example (in-tree):
13        make CFLAGS="--coverage -O0 -g3" LDFLAGS="--coverage"
14   Or (out-of-tree):
15        mkdir build-coverage && cd build-coverage &&
16        cmake -D CMAKE_BUILD_TYPE=Coverage .. && make
172. Run whatever tests you want.
183. Run this script from the parent of the directory containing the library
19   object files and coverage statistics files.
204. Browse the coverage report in Coverage/index.html.
215. After rework, run "$0 -r", then re-test and run "$0" to get a fresh report.
22
23Options
24  -r    Reset traces. Run this before re-testing to get fresh measurements.
25EOF
26}
27
28# Copyright The Mbed TLS Contributors
29# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
30
31set -eu
32
33# Repository detection
34in_mbedtls_build_dir () {
35    test -d library
36}
37
38# Collect stats and build a HTML report.
39lcov_library_report () {
40    rm -rf Coverage
41    mkdir Coverage Coverage/tmp
42    # Pass absolute paths as lcov output files. This works around a bug
43    # whereby lcov tries to create the output file in the root directory
44    # if it has emitted a warning. A fix was released in lcov 1.13 in 2016.
45    # Ubuntu 16.04 is affected, 18.04 and above are not.
46    # https://github.com/linux-test-project/lcov/commit/632c25a0d1f5e4d2f4fd5b28ce7c8b86d388c91f
47    COVTMP=$PWD/Coverage/tmp
48    lcov --capture --initial --directory $library_dir -o "$COVTMP/files.info"
49    lcov --rc lcov_branch_coverage=1 --capture --directory $library_dir -o "$COVTMP/tests.info"
50    lcov --rc lcov_branch_coverage=1 --add-tracefile "$COVTMP/files.info" --add-tracefile "$COVTMP/tests.info" -o "$COVTMP/all.info"
51    lcov --rc lcov_branch_coverage=1 --remove "$COVTMP/all.info" -o "$COVTMP/final.info" '*.h'
52    gendesc tests/Descriptions.txt -o "$COVTMP/descriptions"
53    genhtml --title "$title" --description-file "$COVTMP/descriptions" --keep-descriptions --legend --branch-coverage -o Coverage "$COVTMP/final.info"
54    rm -f "$COVTMP/"*.info "$COVTMP/descriptions"
55    echo "Coverage report in: Coverage/index.html"
56}
57
58# Reset the traces to 0.
59lcov_reset_traces () {
60    # Location with plain make
61    rm -f $library_dir/*.gcda
62    # Location with CMake
63    rm -f $library_dir/CMakeFiles/*.dir/*.gcda
64}
65
66if [ $# -gt 0 ] && [ "$1" = "--help" ]; then
67    help
68    exit
69fi
70
71if in_mbedtls_build_dir; then
72    library_dir='library'
73    title='Mbed TLS'
74else
75    library_dir='core'
76    title='TF-PSA-Crypto'
77fi
78
79main=lcov_library_report
80while getopts r OPTLET; do
81    case $OPTLET in
82        r) main=lcov_reset_traces;;
83        *) help 2>&1; exit 120;;
84    esac
85done
86shift $((OPTIND - 1))
87
88"$main" "$@"
89