diff --git a/.gitignore b/.gitignore index 62dca37b89..a7b0513023 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ tmp/ *.zip *.tar.gz models +genhtml diff --git a/Makefile b/Makefile index 601105274a..f5dc0dd4fa 100644 --- a/Makefile +++ b/Makefile @@ -477,7 +477,7 @@ get_coverage: fi check_coverage: @echo "Checking if coverage is above threshold..." - @docker run $(OVMS_CPP_DOCKER_IMAGE)-build:$(OVMS_CPP_IMAGE_TAG) ./check_coverage.bat | grep success + @bash ci/check_coverage.bat test_checksec: venv @echo "Running checksec on libovms_shared library..." diff --git a/ci/check_coverage.bat b/ci/check_coverage.bat index e962c255ed..6883c33131 100755 --- a/ci/check_coverage.bat +++ b/ci/check_coverage.bat @@ -1,23 +1,31 @@ #!/bin/bash #Ubuntu -MIN_LINES_COV=76.8 -MIN_FUNCTION_COV=87.6 +MIN_LINES_COV=76.0 +MIN_FUNCTION_COV=83.0 #Rhel -MIN_LINES_COV=75.6 -MIN_FUNCTION_COV=73.0 +MIN_LINES_COV=76.0 +MIN_FUNCTION_COV=83.0 -LINES_COV=`cat genhtml/index.html | grep "headerCovTableEntry.*%" | grep -oP ">\K(\d*.\d*) " | head -n 1` -FUNC_COV=`cat genhtml/index.html | grep "headerCovTableEntry.*%" | grep -oP ">\K(\d*.\d*) " | tail -n 1` +LINES_COV=$(grep "headerCovTableEntry.*%" genhtml/index.html | grep -oP '\d+\.\d+(?=\s*%| %)' | head -n 1) +FUNC_COV=$(grep "headerCovTableEntry.*%" genhtml/index.html | grep -oP '\d+\.\d+(?=\s*%| %)' | tail -n 1) + +echo "Lines coverage: ${LINES_COV}% (minimum: ${MIN_LINES_COV}%)" +echo "Functions coverage: ${FUNC_COV}% (minimum: ${MIN_FUNCTION_COV}%)" + +if [ -z "$LINES_COV" ] || [ -z "$FUNC_COV" ]; then + echo "Error: Could not parse coverage values from genhtml/index.html" + exit 1 +fi if (( $(echo "$MIN_LINES_COV > $LINES_COV" | bc -l) )); then - echo "Error: $LINES_COV % Lines coverage is lower than minimal $MIN_LINES_COV %" + echo "Error: ${LINES_COV}% Lines coverage is lower than minimal ${MIN_LINES_COV}%" exit 1 fi if (( $(echo "$MIN_FUNCTION_COV > $FUNC_COV" | bc -l) )); then - echo "Error: $FUNCTION_COV % Functions coverage is lower than minimal $MIN_FUNCTION_COV %" + echo "Error: ${FUNC_COV}% Functions coverage is lower than minimal ${MIN_FUNCTION_COV}%" exit 1 fi diff --git a/run_unit_tests.sh b/run_unit_tests.sh index e05b0c73b5..c3a1842b9c 100755 --- a/run_unit_tests.sh +++ b/run_unit_tests.sh @@ -56,8 +56,32 @@ compress_logs() { } generate_coverage_report() { - test_success_procedure - genhtml --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat" + local coverage_dat="$(bazel info output_path)/_coverage/_coverage_report.dat" + + # lcov 2.x supports --ignore-errors negative,unused; lcov 1.x does not + local lcov_ver + lcov_ver=$(lcov --version | grep -oP '\d+' | head -1) + local lcov_ignore="" + local genhtml_ignore="" + if [ "$lcov_ver" -ge 2 ] 2>/dev/null; then + lcov_ignore="--ignore-errors negative,unused" + genhtml_ignore="--ignore-errors negative" + fi + + if ! lcov --extract "$coverage_dat" 'src/*' --output-file filtered_coverage.dat $lcov_ignore; then + echo "Error: lcov extraction failed" >&2 + return 1 + fi + + if ! lcov --remove filtered_coverage.dat 'src/test/*' 'external/*' --output-file filtered_coverage.dat $lcov_ignore; then + echo "Error: lcov filtering failed" >&2 + return 1 + fi + + if ! genhtml $genhtml_ignore --output genhtml filtered_coverage.dat; then + echo "Error: genhtml report generation failed" >&2 + return 1 + fi } echo "Run test: ${RUN_TESTS}" @@ -65,11 +89,17 @@ echo "Run GPU test: ${RUN_GPU_TESTS}" echo "Run coverage: ${CHECK_COVERAGE}" if [ "$RUN_TESTS" == "1" ] ; then if [ "$CHECK_COVERAGE" == "1" ] ; then - { bazel coverage --instrumentation_filter="-src/test" --combined_report=lcov \ + if bazel coverage --instrumentation_filter="-src/test" --combined_report=lcov \ ${SHARED_OPTIONS} ${TEST_FILTER} \ - //src:ovms_test ${SHARED_OPTIONS} > ${TEST_LOG} 2>&1 || \ - compress_logs && exit 1; } && \ - generate_coverage_report; + //src:ovms_test ${SHARED_OPTIONS} > ${TEST_LOG} 2>&1 ; then + if ! generate_coverage_report ; then + compress_logs + exit 1 + fi + else + compress_logs + exit 1 + fi fi bazel test ${SHARED_OPTIONS} "${TEST_FILTER}" //src/python/binding:test_python_binding || exit 1 bazel build ${SHARED_OPTIONS} //src:ovms_test || exit 1