Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI/CD: Gather code test coverage. #1124

Merged
merged 3 commits into from
Nov 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,65 @@ jobs:

- run: |
${{ matrix.webdriver }} mk/cargo.sh test -vv --target=${{ matrix.target }} ${{ matrix.features }} ${{ matrix.mode }}

coverage:
# Don't run duplicate `push` jobs for the repo owner's PRs.
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository

runs-on: ${{ matrix.host_os }}

strategy:
matrix:
features:
- # Default

# TODO: targets
target:
- aarch64-unknown-linux-gnu
- i686-unknown-linux-gnu
- x86_64-unknown-linux-musl

mode:
- # debug

# Coverage collection is Nightly-only
rust_channel:
- nightly

# TODO: targets
include:
- target: aarch64-unknown-linux-gnu
host_os: ubuntu-18.04

- target: i686-unknown-linux-gnu
host_os: ubuntu-18.04

- target: x86_64-unknown-linux-musl
host_os: ubuntu-18.04

steps:
- uses: actions/checkout@v2

- if: ${{ !contains(matrix.host_os, 'windows') }}
run: mk/install-build-tools.sh --target=${{ matrix.target }} ${{ matrix.features }}

- uses: actions-rs/toolchain@v1
with:
override: true
target: ${{ matrix.target }}
toolchain: ${{ matrix.rust_channel }}

- if: ${{ matrix.target == 'aarch64-apple-darwin' }}
run: echo "DEVELOPER_DIR=/Applications/Xcode_12.2.app/Contents/Developer" >> $GITHUB_ENV

- if: ${{ !contains(matrix.host_os, 'windows') }}
env:
RING_COVERAGE: 1
run: |
mk/cargo.sh +${{ matrix.rust_channel }} test -vv --target=${{ matrix.target }} ${{ matrix.cargo_options }} ${{ matrix.features }} ${{ matrix.mode }}

- uses: codecov/codecov-action@v1
with:
directory: ./target/${{ matrix.target }}/debug/coverage/reports
fail_ci_if_error: true
verbose: true
157 changes: 103 additions & 54 deletions mk/cargo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,64 +30,113 @@ fi

for arg in $*; do
case $arg in
--target=aarch64-linux-android)
export CC_aarch64_linux_android=$android_tools/aarch64-linux-android21-clang
export AR_aarch64_linux_android=$android_tools/aarch64-linux-android-ar
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$android_tools/aarch64-linux-android21-clang
;;
--target=aarch64-unknown-linux-gnu)
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc-ar
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="$qemu_aarch64"
;;
--target=aarch64-unknown-linux-musl)
export CC_aarch64_unknown_linux_musl=clang-10
export AR_aarch64_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER="$qemu_aarch64"
;;
--target=arm-unknown-linux-gnueabihf)
export CC_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc
export AR_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc-ar
export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER="$qemu_arm"
;;
--target=armv7-linux-androideabi)
export CC_armv7_linux_androideabi=$android_tools/armv7a-linux-androideabi18-clang
export AR_armv7_linux_androideabi=$android_tools/arm-linux-androideabi-ar
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$android_tools/armv7a-linux-androideabi18-clang
;;
--target=armv7-unknown-linux-musleabihf)
export CC_armv7_unknown_linux_musleabihf=clang-10
export AR_armv7_unknown_linux_musleabihf=llvm-ar-10
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUSTFLAGS="$rustflags_self_contained"
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="$qemu_arm"
;;
--target=i686-unknown-linux-gnu)
export CC_i686_unknown_linux_gnu=clang-10
export AR_i686_unknown_linux_gnu=llvm-ar-10
export CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang-10
;;
--target=i686-unknown-linux-musl)
export CC_i686_unknown_linux_musl=clang-10
export AR_i686_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_I686_UNKNOWN_LINUX_MUSL_LINKER=clang-10
;;
--target=x86_64-unknown-linux-musl)
export CC_x86_64_unknown_linux_musl=clang-10
export AR_x86_64_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=clang-10
;;
--target=wasm32-unknown-unknown)
# The first two are only needed for when the "wasm_c" feature is enabled.
export CC_wasm32_unknown_unknown=clang-10
export AR_wasm32_unknown_unknown=llvm-ar-10
export CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner
--target=*)
target=${arg#*=}
;;
*)
;;
esac
done

case $target in
aarch64-linux-android)
export CC_aarch64_linux_android=$android_tools/aarch64-linux-android21-clang
export AR_aarch64_linux_android=$android_tools/aarch64-linux-android-ar
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$android_tools/aarch64-linux-android21-clang
;;
aarch64-unknown-linux-gnu)
export CC_aarch64_unknown_linux_gnu=clang-10
export AR_aarch64_unknown_linux_gnu=llvm-ar-10
export CFLAGS_aarch64_unknown_linux_gnu="--sysroot=/usr/aarch64-linux-gnu"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="$qemu_aarch64"
;;
aarch64-unknown-linux-musl)
export CC_aarch64_unknown_linux_musl=clang-10
export AR_aarch64_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="$rustflags_self_contained"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUNNER="$qemu_aarch64"
;;
arm-unknown-linux-gnueabihf)
export CC_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc
export AR_arm_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc-ar
export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
export CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER="$qemu_arm"
;;
armv7-linux-androideabi)
export CC_armv7_linux_androideabi=$android_tools/armv7a-linux-androideabi18-clang
export AR_armv7_linux_androideabi=$android_tools/arm-linux-androideabi-ar
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=$android_tools/armv7a-linux-androideabi18-clang
;;
armv7-unknown-linux-musleabihf)
export CC_armv7_unknown_linux_musleabihf=clang-10
export AR_armv7_unknown_linux_musleabihf=llvm-ar-10
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUSTFLAGS="$rustflags_self_contained"
export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_RUNNER="$qemu_arm"
;;
i686-unknown-linux-gnu)
export CC_i686_unknown_linux_gnu=clang-10
export AR_i686_unknown_linux_gnu=llvm-ar-10
export CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang-10
;;
i686-unknown-linux-musl)
export CC_i686_unknown_linux_musl=clang-10
export AR_i686_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_I686_UNKNOWN_LINUX_MUSL_LINKER=clang-10
;;
x86_64-unknown-linux-musl)
export CC_x86_64_unknown_linux_musl=clang-10
export AR_x86_64_unknown_linux_musl=llvm-ar-10
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=clang-10
;;
wasm32-unknown-unknown)
# The first two are only needed for when the "wasm_c" feature is enabled.
export CC_wasm32_unknown_unknown=clang-10
export AR_wasm32_unknown_unknown=llvm-ar-10
export CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner
;;
*)
;;
esac

if [ -n "${RING_COVERAGE-}" ]; then
# XXX: Collides between release and debug.
coverage_dir=$PWD/target/$target/debug/coverage
mkdir -p "$coverage_dir"
rm -f "$coverage_dir/*.profraw"

export RING_BUILD_EXECUTABLE_LIST="$coverage_dir/executables"
truncate --size=0 "$RING_BUILD_EXECUTABLE_LIST"

# This doesn't work when profiling under QEMU. Instead mk/runner does
# something similar but different.
# export LLVM_PROFILE_FILE="$coverage_dir/%m.profraw"

# ${target} with hyphens replaced by underscores, lowercase and uppercase.
target_lower=${target//-/_}
target_upper=${target_lower^^}

cflags_var=CFLAGS_${target_lower}
declare -x "${cflags_var}=-fprofile-instr-generate -fcoverage-mapping ${!cflags_var-}"

runner_var=CARGO_TARGET_${target_upper}_RUNNER
declare -x "${runner_var}=mk/runner ${!runner_var-}"

rustflags_var=CARGO_TARGET_${target_upper}_RUSTFLAGS
declare -x "${rustflags_var}=-Zinstrument-coverage ${!rustflags_var-}"
fi

cargo "$@"

if [ -n "${RING_COVERAGE-}" ]; then
while read executable; do
basename=$(basename "$executable")
llvm-profdata-10 merge -sparse ""$coverage_dir"/$basename.profraw" -o "$coverage_dir"/$basename.profdata
mkdir -p "$coverage_dir"/reports
llvm-cov-10 export \
--instr-profile "$coverage_dir"/$basename.profdata \
--format lcov \
"$executable" \
> "$coverage_dir"/reports/coverage-$basename.txt
done < "$RING_BUILD_EXECUTABLE_LIST"
fi
2 changes: 2 additions & 0 deletions mk/install-build-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ esac

case $target in
--target=aarch64-unknown-linux-gnu)
# Clang is needed for code coverage.
use_clang=1
install_packages \
qemu-user \
gcc-aarch64-linux-gnu \
Expand Down
21 changes: 21 additions & 0 deletions mk/runner
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
set -eux -o pipefail
IFS=$'\n\t'

for arg in $*; do
# There can be some arguments prefixed in front of the executable, e.g.
# when qemu-user is used. There can be arguments after the executable,
# e.g. `cargo test` arguments like `TESTNAME`.
if [[ $arg = */deps/* ]]; then
executable=$arg
break
fi
done

export LLVM_PROFILE_FILE=$(dirname "$RING_BUILD_EXECUTABLE_LIST")/$(basename "$executable").profraw

if [ -n "$RING_BUILD_EXECUTABLE_LIST" ]; then
echo "$executable" >> "$RING_BUILD_EXECUTABLE_LIST"
fi

$*