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# Get a shell 69./scripts/dev_cli.sh shell 70 71# Install llvm-tools-preview for llvm-profdata 72rustup component add llvm-tools-preview 73# Merge data files by using the following command 74find . -name '*.profraw' -exec `rustc --print sysroot`/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse {} -o coverage.profdata \; 75 76# As of writing, the container has Rust 1.67.1. It is too old for grcov. 77rustup install stable 78cargo +stable install grcov 79# Run grcov as usual 80grcov . --binary-path ./target/x86_64-unknown-linux-gnu/release -s . -t html --branch --ignore-not-existing -o coverage-html-output/ 81``` 82