Skip to content

Commit 5eda9cb

Browse files
authored
build FEATURE enable code coverage (#273)
1 parent aa08322 commit 5eda9cb

3 files changed

Lines changed: 94 additions & 3 deletions

File tree

CMakeLists.txt

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,35 @@ else()
124124
option(ENABLE_BUILD_TESTS "Build tests" OFF)
125125
option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
126126
endif()
127+
option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
128+
129+
if(ENABLE_COVERAGE)
130+
find_program(PATH_GCOV NAMES gcov)
131+
if(NOT PATH_GCOV)
132+
message(WARNING "'gcov' executable not found! Disabling building code coverage report.")
133+
set(ENABLE_COVERAGE OFF)
134+
endif()
135+
136+
find_program(PATH_LCOV NAMES lcov)
137+
if(NOT PATH_LCOV)
138+
message(WARNING "'lcov' executable not found! Disabling building code coverage report.")
139+
set(ENABLE_COVERAGE OFF)
140+
endif()
141+
142+
find_program(PATH_GENHTML NAMES genhtml)
143+
if(NOT PATH_GENHTML)
144+
message(WARNING "'genhtml' executable not found! Disabling building code coverage report.")
145+
set(ENABLE_COVERAGE OFF)
146+
endif()
147+
148+
if(NOT CMAKE_COMPILER_IS_GNUCC)
149+
message(WARNING "Compiler is not gcc! Coverage may break the tests!")
150+
endif()
151+
152+
if(ENABLE_COVERAGE)
153+
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
154+
endif()
155+
endif()
127156

128157
# dependencies - pthread
129158
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
@@ -141,7 +170,7 @@ if(ENABLE_TLS OR ENABLE_DNSSEC OR ENABLE_SSH)
141170
find_package(OpenSSL REQUIRED)
142171
if(ENABLE_TLS)
143172
message(STATUS "OPENSSL found, required for TLS")
144-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNC_ENABLED_TLS")
173+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_COVERAGE} -DNC_ENABLED_TLS")
145174
endif()
146175

147176
target_link_libraries(netconf2 ${OPENSSL_LIBRARIES})
@@ -158,7 +187,7 @@ if(ENABLE_SSH)
158187
target_link_libraries(netconf2 ${LIBSSH_LIBRARIES})
159188
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBSSH_LIBRARIES})
160189
include_directories(${LIBSSH_INCLUDE_DIRS})
161-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNC_ENABLED_SSH")
190+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_COVERAGE} -DNC_ENABLED_SSH")
162191

163192
# crypt
164193
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX")
@@ -173,7 +202,7 @@ endif()
173202
# dependencies - libval
174203
if(ENABLE_DNSSEC)
175204
find_package(LibVAL REQUIRED)
176-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_DNSSEC")
205+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_COVERAGE} -DENABLE_DNSSEC")
177206
target_link_libraries(netconf2 ${LIBVAL_LIBRARIES})
178207
include_directories(${LIBVAL_INCLUDE_DIRS})
179208
endif()

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,23 @@ too small.
272272
$ cmake -D MAX_PSPOLL_THREAD_COUNT:String="6" ..
273273
```
274274

275+
### Code Coverage
276+
277+
To generate statistical information about code coverage by tests, set
278+
`ENABLE_COVERAGE` option to `ON`:
279+
```
280+
$ cmake -D ENABLE_COVERAGE="ON" ..
281+
```
282+
and then the make's `coverage` target should be available to generate statistics:
283+
```
284+
$ make coverage
285+
```
286+
287+
Note that `gcc` compiler is required for this option and additional tools are required:
288+
* gcov
289+
* lcov
290+
* genhtml
291+
275292
### CMake Notes
276293

277294
Note that, with CMake, if you want to change the compiler or its options after

tests/CMakeLists.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,50 @@ if(ENABLE_VALGRIND_TESTS)
7070
endif()
7171
endif()
7272

73+
if(ENABLE_COVERAGE)
74+
# Destination
75+
set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/tests/code_coverage/")
76+
set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/tests/coverage_raw.info")
77+
set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/tests/coverage_clean.info")
78+
79+
# Add coverage target
80+
add_custom_target(coverage
81+
COMMENT "Generating code coverage..."
82+
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
83+
# Cleanup code counters
84+
COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
85+
86+
# Run tests
87+
COMMAND "${CMAKE_CTEST_COMMAND}" --quiet
88+
89+
# Capture the counters
90+
COMMAND "${PATH_LCOV}"
91+
--directory .
92+
--rc lcov_branch_coverage=1
93+
--rc 'lcov_excl_line=assert'
94+
--capture --quiet
95+
--output-file "${COVERAGE_FILE_RAW}"
96+
# Remove coverage of tests, system headers, etc.
97+
COMMAND "${PATH_LCOV}"
98+
--remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
99+
--rc lcov_branch_coverage=1
100+
--quiet --output-file "${COVERAGE_FILE_CLEAN}"
101+
# Generate HTML report
102+
COMMAND "${PATH_GENHTML}"
103+
--branch-coverage --function-coverage --quiet --title "libnetconf2"
104+
--legend --show-details --output-directory "${COVERAGE_DIR}"
105+
"${COVERAGE_FILE_CLEAN}"
106+
# Delete the counters
107+
COMMAND "${CMAKE_COMMAND}" -E remove
108+
${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
109+
)
110+
111+
add_custom_command(TARGET coverage POST_BUILD
112+
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
113+
COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
114+
COMMAND ;
115+
)
116+
endif()
117+
73118
include_directories(${CMAKE_SOURCE_DIR}/src ${PROJECT_BINARY_DIR})
74119
configure_file("${PROJECT_SOURCE_DIR}/tests/config.h.in" "${PROJECT_BINARY_DIR}/tests/config.h" ESCAPE_QUOTES @ONLY)

0 commit comments

Comments
 (0)