1# Code coverage 2 3LLVM provides a set of tools to collect code coverage data and present the data 4in human-consumable forms. 5 6## Building a suitable binary 7 8The compiler flag to generate code coverage data has been stabilized since Rust 91.60. 10 11An instrumented binary can be built with the following command: 12 13```shell 14cargo clean && RUSTFLAGS='-C instrument-coverage' cargo build 15``` 16 17Using either `debug` or `release` profile is fine. You will need to adjust 18the path for some commands. 19 20## Running the binary 21 22Run the binary as you normally would. When the process exits, you will see 23files with the prefix `profraw`. 24 25Multiple runs of the same binary will produce multiple `profraw` files. 26 27The more diverse the runs are, the better. Try to exercise different features 28as much as possible. 29 30## Combining raw data 31 32Raw data files can be combined with `llvm-profdata`. 33 34```shell 35rustup component add llvm-tools-preview 36# Assuming profraw files reside in the current directory and its children directories 37find . -name '*.profraw' -exec llvm-profdata merge -sparse {} -o coverage.profdata \; 38``` 39 40A file named `coverage.profdata` will be generated. 41 42## Generating HTML files for human consumption 43 44This can be done either with LLVM or `grcov`. 45 46Here is an example using grcov. 47 48```shell 49cargo install grcov 50# Assuming the profdata file is in the top level directory of the Cloud Hypervisor repository 51grcov . --binary-path ./target/x86_64-unknown-linux-gnu/release -s . -t html --branch --ignore-not-existing -o coverage-html-output/ 52``` 53 54You can then open the `index.html` file under coverage-html-output to see the 55results. 56 57## Notes on running the in-tree integration tests and unit tests 58 59Please set RUSTFLAGS the same way while invoking `dev_cli.sh`. The script will 60pass RUSTFLAGS to the container. 61 62Since the `profraw` files are generated from within the container, the file 63paths embedded in the data files are going to be different. It is easier to do 64the data processing from within the container if you don't want to fight the 65tool chain. 66 67```shell 68# Set env to enable code coverage 69export RUSTFLAGS="-Cinstrument-coverage" 70export LLVM_PROFILE_FILE="ch-%p-%m.profraw" 71 72# Run unit tests 73scripts/dev_cli.sh tests --unit --libc gnu 74 75# Run integration tests 76scripts/dev_cli.sh tests --integration --libc gnu 77scripts/dev_cli.sh tests --integration-live-migration --libc gnu 78 79# Export code coverage report 80scripts/dev_cli.sh tests --coverage -- -- html 81``` 82