diff --git a/.github/workflows/lcov.yml b/.github/workflows/lcov.yml new file mode 100644 index 00000000..1d77d69c --- /dev/null +++ b/.github/workflows/lcov.yml @@ -0,0 +1,47 @@ +name: Coverage + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + coverage: + name: Test Coverage + runs-on: ubuntu-latest + container: + image: vsaglib/vsag:ubuntu + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.10' + - name: Install + run: | + python -m pip install --upgrade pip + pip install lcov_cobertura + apt install -y curl jq + - name: Load Cache + uses: actions/cache@v4.1.2 + with: + path: ./build/ + key: build-${{ hashFiles('./CMakeLists.txt') }}-${{ hashFiles('./.circleci/fresh_ci_cache.commit') }} + - name: Compile + run: make cov + - name: Run Test + run: | + ./build/mockimpl/tests_mockimpl -d yes ${UT_FILTER} --allow-running-no-tests ${UT_SHARD} + - name: Collect Coverage Info + run: bash scripts/collect_cpp_coverage.sh + - name: Generate XML + run: lcov_cobertura coverage.info --output coverage.xml + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + fail_ci_if_error: true + files: coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + diff --git a/Makefile b/Makefile index 9ea75cff..bbe25915 100644 --- a/Makefile +++ b/Makefile @@ -88,8 +88,8 @@ test_cov: cov ## Build and run unit tests with code coverage enabled. ./build/tests/unittests -d yes ${UT_FILTER} --allow-running-no-tests ${UT_SHARD} ./build/tests/functests -d yes ${UT_FILTER} --allow-running-no-tests ${UT_SHARD} ./build/mockimpl/tests_mockimpl -d yes ${UT_FILTER} --allow-running-no-tests ${UT_SHARD} - bash scripts/aci/collect_cpp_coverage.sh - genhtml --output-directory testresult/coverage/html testresult/coverage/coverage.info --ignore-errors inconsistent,inconsistent + bash scripts/collect_cpp_coverage.sh + genhtml --output-directory coverage/coverage/html coverage/coverage.info --ignore-errors inconsistent,inconsistent .PHONY: clean clean: ## Clear build/ directory. diff --git a/scripts/check_cov.sh b/scripts/check_cov.sh new file mode 100644 index 00000000..2888fcc4 --- /dev/null +++ b/scripts/check_cov.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +line_coverage=`lcov --summary coverage/coverage.info | grep "lines......" | awk '/lines/ { print $2 }' | cut -d '%' -f 1` +line_coverage=$(printf "%.0f" $line_coverage) +if [ "$line_coverage" -gt 84 ]; then + echo "line coverage is ${line_coverage}, more than 84" + exit 0; +else + echo "line coverage is ${line_coverage}, less than 84" + exit 1; +fi diff --git a/scripts/collect_cpp_coverage.sh b/scripts/collect_cpp_coverage.sh new file mode 100644 index 00000000..c788a3bf --- /dev/null +++ b/scripts/collect_cpp_coverage.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e +set -x + +SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT_DIR="${SCRIPTS_DIR}/../" + +COVERAGE_DIR="${ROOT_DIR}/coverage" +if [ -d "${COVERAGE_DIR}" ]; then + rm -rf "${COVERAGE_DIR:?}"/* +else + mkdir -p "${COVERAGE_DIR}" +fi + +lcov --gcov-tool ${SCRIPTS_DIR}/gcov_for_clang.sh \ + --rc branch_coverage=1 \ + --rc geninfo_unexecuted_blocks=1 \ + --include "*/vsag/include/*" \ + --include "*/vsag/src/*" \ + --exclude "*/vsag/include/vsag/expected.hpp*" \ + --exclude "*_test.cpp" \ + --capture \ + --directory . \ + --output-file "${COVERAGE_DIR}/coverage_ut.info" + +pushd "${COVERAGE_DIR}" +coverages=$(ls coverage_*.info) +if [ ! "$coverages" ];then + echo "no coverage file" + exit 0 +fi +lcov_command="lcov" +for coverage in $coverages; do + echo "$coverage" + lcov_command="$lcov_command -a $coverage" +done +$lcov_command -o coverage.info \ + --rc branch_coverage=1 \ + --ignore-errors inconsistent,inconsistent \ + --ignore-errors corrupt,corrupt +popd diff --git a/scripts/gcov_for_clang.sh b/scripts/gcov_for_clang.sh new file mode 100755 index 00000000..ec6863ca --- /dev/null +++ b/scripts/gcov_for_clang.sh @@ -0,0 +1,3 @@ +#!/bin/bash +exec gcov "$@" +