build REFACTOR separate code coverage into a module
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 024f6b5..1c2d0ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,7 @@
include(ABICheck)
include(SourceFormat)
include(GenDoc)
+include(GenCoverage)
# set default build type if not specified by user
if(NOT CMAKE_BUILD_TYPE)
@@ -215,43 +216,30 @@
set(PLUGINS_DIR_EXTENSIONS "${PLUGINS_DIR}/extensions" CACHE STRING "Directory with libyang user extensions plugins")
set(PLUGINS_DIR_TYPES "${PLUGINS_DIR}/types" CACHE STRING "Directory with libyang user types plugins")
-if(ENABLE_COVERAGE)
- if(NOT ENABLE_BUILD_TESTS)
- message(WARNING "you cannot generage coverage when tests are disabled. Enable test by additing parameter -DENABLE_BUILD_TESTS=ON or run cmake in some debug mode")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- find_program(PATH_GCOV NAMES gcov)
- if(NOT PATH_GCOV)
- message(WARNING "'gcov' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- find_program(PATH_LCOV NAMES lcov)
- if(NOT PATH_LCOV)
- message(WARNING "'lcov' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- find_program(PATH_GENHTML NAMES genhtml)
- if(NOT PATH_GENHTML)
- message(WARNING "'genhtml' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- if(NOT CMAKE_COMPILER_IS_GNUCC)
- message(WARNING "Compiler is not gcc! Coverage may break the tests!")
- endif()
-
- if(ENABLE_COVERAGE)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
- endif()
-endif()
-
# by default build shared library
# static build requires static libpcre2 library
option(ENABLE_STATIC "Build static (.a) library" OFF)
+#
+# checks
+#
+if(ENABLE_BUILD_TESTS)
+ find_package(CMocka 1.0.0)
+ if(NOT CMOCKA_FOUND)
+ message(STATUS "Disabling tests because of missing CMocka")
+ set(ENABLE_BUILD_TESTS OFF)
+ endif()
+endif(ENABLE_BUILD_TESTS)
+
+if(ENABLE_COVERAGE)
+ gen_coverage_enable(${ENABLE_BUILD_TESTS})
+endif()
+
+if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
+ # enable before adding tests to let them detect that format checking is available - one of the tests is format checking
+ source_format_enable()
+endif()
+
# generate files
configure_file(${PROJECT_SOURCE_DIR}/src/config.h.in ${PROJECT_BINARY_DIR}/src/config.h @ONLY)
configure_file(${PROJECT_SOURCE_DIR}/src/version.h.in ${PROJECT_BINARY_DIR}/src/version.h @ONLY)
@@ -325,8 +313,8 @@
# check that pkg-config includes the used path
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable pc_path pkg-config RESULT_VARIABLE RETURN OUTPUT_VARIABLE PC_PATH ERROR_QUIET)
if(RETURN EQUAL 0)
- string(STRIP "${PC_PATH}" PC_PATH)
- set(PC_PATH "${PC_PATH}:$ENV{PKG_CONFIG_PATH}")
+ string(STRIP "${PC_PATH}" PC_PATH)
+ set(PC_PATH "${PC_PATH}:$ENV{PKG_CONFIG_PATH}")
string(REGEX MATCH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig" SUBSTR "${PC_PATH}")
string(LENGTH "${SUBSTR}" SUBSTR_LEN)
if(SUBSTR_LEN EQUAL 0)
@@ -335,28 +323,14 @@
endif()
endif()
-if(ENABLE_BUILD_TESTS)
- find_package(CMocka 1.0.0)
-endif(ENABLE_BUILD_TESTS)
-
-if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
- # enable before adding tests to let them detect that format checking is available - one of the tests is format checking
- source_format_enable()
-endif()
-
# tests
if(ENABLE_VALGRIND_TESTS)
set(ENABLE_BUILD_TESTS ON)
endif()
if(ENABLE_BUILD_TESTS)
- if(CMOCKA_FOUND)
- enable_testing()
- add_subdirectory(tests)
- else()
- message(STATUS "Disabling tests because of missing CMocka")
- set(ENABLE_BUILD_TESTS OFF)
- endif()
+ enable_testing()
+ add_subdirectory(tests)
endif()
if(ENABLE_FUZZ_TARGETS)
@@ -369,6 +343,9 @@
endif()
endif()
+# create coverage target for generating coverage reports
+gen_coverage("utest_.*" "utest_.*_valgrind")
+
# tools - yanglint, yangre
add_subdirectory(tools)
diff --git a/CMakeModules/GenCoverage.cmake b/CMakeModules/GenCoverage.cmake
new file mode 100644
index 0000000..43a576b
--- /dev/null
+++ b/CMakeModules/GenCoverage.cmake
@@ -0,0 +1,104 @@
+# generate test code coverage report
+
+# check that coverage tools are available - always use before GEN_COVERAGE
+macro(GEN_COVERAGE_ENABLE ENABLE_TESTS)
+ # make into normal variable
+ set(TESTS_ENABLED ${ENABLE_TESTS})
+
+ set(GEN_COVERAGE_ENABLED ON)
+ if(NOT TESTS_ENABLED)
+ message(WARNING "You cannot generate coverage when tests are disabled. Enable test by additing parameter -DENABLE_BUILD_TESTS=ON or run cmake with Debug build target.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GCOV NAMES gcov)
+ if(NOT PATH_GCOV)
+ message(WARNING "gcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_LCOV NAMES lcov)
+ if(NOT PATH_LCOV)
+ message(WARNING "lcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GENHTML NAMES genhtml)
+ if(NOT PATH_GENHTML)
+ message(WARNING "genhtml executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ if(NOT CMAKE_COMPILER_IS_GNUCC)
+ message(WARNING "Compiler is not gcc! Coverage may break the tests!")
+ endif()
+
+ # add specific required compile flags
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
+ endif()
+endmacro()
+
+# tests are always expected to be in ${CMAKE_SOURCE_DIR}/tests
+function(GEN_COVERAGE MATCH_TEST_REGEX EXCLUDE_TEST_REGEX)
+ if(NOT GEN_COVERAGE_ENABLED)
+ return()
+ endif()
+
+ # destination
+ set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/code_coverage/")
+ set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/coverage_raw.info")
+ set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/coverage_clean.info")
+
+ # test match/exclude
+ if(MATCH_TEST_REGEX)
+ set(MATCH_TEST_ARGS -R \"${MATCH_TEST_REGEX}\")
+ endif()
+ if(EXCLUDE_TEST_REGEX)
+ set(EXCLUDE_TEST_ARGS -E \"${EXCLUDE_TEST_REGEX}\")
+ endif()
+
+ # coverage target
+ add_custom_target(coverage
+ COMMENT "Generating code coverage..."
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ # Cleanup code counters
+ COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
+
+ # Run tests
+ COMMAND "${CMAKE_CTEST_COMMAND}" --quiet ${MATCH_TEST_ARGS} ${EXCLUDE_TEST_ARGS}
+
+ # Capture the counters
+ COMMAND "${PATH_LCOV}"
+ --directory .
+ --rc lcov_branch_coverage=1
+ --rc 'lcov_excl_line=assert'
+ --capture --quiet
+ --output-file "${COVERAGE_FILE_RAW}"
+ # Remove coverage of tests, system headers, etc.
+ COMMAND "${PATH_LCOV}"
+ --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
+ --rc lcov_branch_coverage=1
+ --quiet --output-file "${COVERAGE_FILE_CLEAN}"
+ # Generate HTML report
+ COMMAND "${PATH_GENHTML}"
+ --branch-coverage --function-coverage --quiet --title "${PROJECT_NAME}"
+ --legend --show-details --output-directory "${COVERAGE_DIR}"
+ "${COVERAGE_FILE_CLEAN}"
+ # Delete the counters
+ COMMAND "${CMAKE_COMMAND}" -E remove
+ ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
+ )
+
+ add_custom_command(TARGET coverage POST_BUILD
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
+ COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
+ COMMAND ;
+ )
+endfunction()
diff --git a/README.md b/README.md
index db544d5..4b9c924 100644
--- a/README.md
+++ b/README.md
@@ -209,9 +209,11 @@
### Code Coverage
-Based on the tests run, it is possible to generate code coverage report via the
-make's `coverage` target:
+Based on the tests run, it is possible to generate code coverage report. But
+it must be enabled and these commands are needed to generate the report:
```
+$ cmake -DENABLE_COVERAGE=ON ..
+$ make
$ make coverage
```
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6c58cc9..7516a90 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -43,51 +43,6 @@
endif(ENABLE_VALGRIND_TESTS)
endfunction(ly_add_utest)
-if(ENABLE_COVERAGE)
- # Destination
- set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/tests/code_coverage/")
- set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/tests/coverage_raw.info")
- set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/tests/coverage_clean.info")
-
- # Add coverage target
- add_custom_target(coverage
- COMMENT "Generating code coverage..."
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
- # Cleanup code counters
- COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
-
- # Run tests
- COMMAND "${CMAKE_CTEST_COMMAND}" --quiet
-
- # Capture the counters
- COMMAND "${PATH_LCOV}"
- --directory .
- --rc lcov_branch_coverage=1
- --rc 'lcov_excl_line=assert'
- --capture --quiet
- --output-file "${COVERAGE_FILE_RAW}"
- # Remove coverage of tests, system headers, etc.
- COMMAND "${PATH_LCOV}"
- --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
- --rc lcov_branch_coverage=1
- --quiet --output-file "${COVERAGE_FILE_CLEAN}"
- # Generate HTML report
- COMMAND "${PATH_GENHTML}"
- --branch-coverage --function-coverage --quiet --title "libyang"
- --legend --show-details --output-directory "${COVERAGE_DIR}"
- "${COVERAGE_FILE_CLEAN}"
- # Delete the counters
- COMMAND "${CMAKE_COMMAND}" -E remove
- ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
- )
-
- add_custom_command(TARGET coverage POST_BUILD
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
- COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
- COMMAND ;
- )
-endif()
-
add_subdirectory(style)
add_subdirectory(plugins)
add_subdirectory(utests)