From 9f02839448accd749823fb18385da3db1e1fc95a Mon Sep 17 00:00:00 2001 From: Songqian Li Date: Mon, 3 Jun 2024 15:30:45 +0800 Subject: [PATCH] scripts: add code coverage script Fixes: #6507 Signed-off-by: Songqian Li --- scripts/dev_cli.sh | 29 +++++++++++++++++++ scripts/run_coverage.sh | 63 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100755 scripts/run_coverage.sh diff --git a/scripts/dev_cli.sh b/scripts/dev_cli.sh index 2854e0c36..aade4accb 100755 --- a/scripts/dev_cli.sh +++ b/scripts/dev_cli.sh @@ -200,6 +200,7 @@ cmd_help() { echo " --integration-rate-limiter Run the rate-limiter integration tests." echo " --libc Select the C library Cloud Hypervisor will be built against. Default is gnu" echo " --metrics Generate performance metrics" + echo " --coverage Generate code coverage information" echo " --volumes Hash separated volumes to be exported. Example --volumes /mnt:/mnt#/myvol:/myvol" echo " --hypervisor Underlying hypervisor. Options kvm, mshv" echo " --all Run all tests." @@ -332,6 +333,7 @@ cmd_tests() { integration_live_migration=false integration_rate_limiter=false metrics=false + coverage=false libc="gnu" arg_vols="" hypervisor="kvm" @@ -350,6 +352,7 @@ cmd_tests() { "--integration-live-migration") { integration_live_migration=true; } ;; "--integration-rate-limiter") { integration_rate_limiter=true; } ;; "--metrics") { metrics=true; } ;; + "--coverage") { coverage=true; } ;; "--libc") shift [[ "$1" =~ ^(musl|gnu)$ ]] || @@ -417,6 +420,7 @@ cmd_tests() { --env BUILD_TARGET="$target" \ --env RUSTFLAGS="$rustflags" \ --env TARGET_CC="$target_cc" \ + --env LLVM_PROFILE_FILE="$LLVM_PROFILE_FILE" \ "$CTR_IMAGE" \ ./scripts/run_unit_tests.sh "$@" || fix_dir_perms $? || exit $? fi @@ -440,6 +444,7 @@ cmd_tests() { --env RUSTFLAGS="$rustflags" \ --env TARGET_CC="$target_cc" \ --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \ + --env LLVM_PROFILE_FILE="$LLVM_PROFILE_FILE" \ "$CTR_IMAGE" \ dbus-run-session ./scripts/run_integration_tests_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $? fi @@ -532,6 +537,7 @@ cmd_tests() { --env RUSTFLAGS="$rustflags" \ --env TARGET_CC="$target_cc" \ --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \ + --env LLVM_PROFILE_FILE="$LLVM_PROFILE_FILE" \ "$CTR_IMAGE" \ ./scripts/run_integration_tests_live_migration.sh "$@" || fix_dir_perms $? || exit $? fi @@ -583,6 +589,29 @@ cmd_tests() { ./scripts/run_metrics.sh "$@" || fix_dir_perms $? || exit $? fi + if [ "$coverage" = true ]; then + say "Generating code coverage information for $target..." + $DOCKER_RUNTIME run \ + --workdir "$CTR_CLH_ROOT_DIR" \ + --rm \ + --privileged \ + --security-opt seccomp=unconfined \ + --ipc=host \ + --net="$CTR_CLH_NET" \ + --mount type=tmpfs,destination=/tmp \ + --volume /dev:/dev \ + --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \ + ${exported_volumes:+"$exported_volumes"} \ + --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \ + --env USER="root" \ + --env BUILD_TARGET="$target" \ + --env RUSTFLAGS="$rustflags" \ + --env TARGET_CC="$target_cc" \ + --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \ + "$CTR_IMAGE" \ + dbus-run-session ./scripts/run_coverage.sh "$@" || fix_dir_perms $? || exit $? + fi + fix_dir_perms $? } diff --git a/scripts/run_coverage.sh b/scripts/run_coverage.sh new file mode 100755 index 000000000..c3e8eca2e --- /dev/null +++ b/scripts/run_coverage.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -x + +# shellcheck source=/dev/null +source "$HOME"/.cargo/env + +PROJECT_DIR="/cloud-hypervisor" +TARGET_DIR="$PROJECT_DIR/target" + +pushd $PROJECT_DIR || exit + +export BUILD_TARGET=${BUILD_TARGET-$(uname -m)-unknown-linux-gnu} + +# GLIBC > 2.31 +GRCOV_RELEASE_URL="https://github.com/mozilla/grcov/releases/download/v0.8.19/grcov-$BUILD_TARGET.tar.bz2" +wget --quiet "$GRCOV_RELEASE_URL" || exit 1 +tar -xjf "grcov-$BUILD_TARGET.tar.bz2" + +rustup component add llvm-tools-preview + +export_lcov() { + rm "coverage.info" + + ./grcov "$(find . -name 'ch-*.profraw' -print)" -s . \ + --ignore "tests/*" \ + --ignore "test_infra/*" \ + --ignore "performance-metrics/*" \ + --binary-path "$TARGET_DIR/$BUILD_TARGET/release/" \ + --branch --ignore-not-existing -t lcov \ + -o "coverage.info" + + find . -type f -name 'ch-*.profraw' -exec rm {} \; +} + +# Generate HTML report +export_html() { + OUTPUT_DIR="$TARGET_DIR/coverage" + rm -rf $OUTPUT_DIR + ./grcov "$(find . -name 'ch-*.profraw' -print)" -s . \ + --ignore "tests/*" \ + --ignore "test_infra/*" \ + --ignore "performance-metrics/*" \ + --binary-path "$TARGET_DIR/$BUILD_TARGET/release/" \ + --branch --ignore-not-existing -t html \ + -o $OUTPUT_DIR + find . -type f -name 'ch-*.profraw' -exec rm {} \; +} + +# $1 is now a command name. Check if it is a valid command and, if so, +# run it. +# +declare -f "export_$1" >/dev/null +code=$? +[[ $code == 0 ]] || echo "Unknown command: $1. Only support \"lcov\" and \"html\". Change to default command: html" +type=${1-html} + +func=export_$type +shift + +$func "$@" + +popd || exit 1