Skip to content

Commit 47b0361

Browse files
committed
[#491] Add test coverage reports into the runtime documentation
1 parent d953148 commit 47b0361

File tree

8 files changed

+157
-33
lines changed

8 files changed

+157
-33
lines changed

cmake/coverage_utils.cmake

+19-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function(create_coverage_target)
2727
set(cov_tgt_name "coverage")
2828
endif ()
2929

30-
set(cov_binary_dir "${PROJECT_BINARY_DIR}/${cov_tgt_name}")
30+
set(cov_html_dir "${PROJECT_BINARY_DIR}/zserio_doc/${cov_tgt_name}")
3131

3232
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
3333
set(cov_fail)
@@ -40,25 +40,33 @@ function(create_coverage_target)
4040
list(APPEND cov_exclude "--exclude=${cov_EXCLUDE_SOURCES}")
4141
endif ()
4242

43+
set(cov_html_gcc_dir "${cov_html_dir}/gcc")
4344
add_custom_target(
4445
${cov_tgt_name}
45-
COMMAND ${CMAKE_COMMAND} -E make_directory ${cov_binary_dir}
46+
COMMAND ${CMAKE_COMMAND} -E make_directory ${cov_html_gcc_dir}
4647
COMMAND ${GCOVR_BIN}
4748
-s
48-
--html --html-details -o "${cov_tgt_name}/index.html"
4949
-r ${PROJECT_SOURCE_DIR}
5050
--object-directory=${PROJECT_BINARY_DIR}
51-
${cov_fail}
5251
${cov_exclude}
52+
COMMAND ${GCOVR_BIN}
53+
-s
54+
--html --html-details -o "${cov_html_gcc_dir}/index.html"
55+
-r ${PROJECT_SOURCE_DIR}
56+
--object-directory=${PROJECT_BINARY_DIR}
57+
${cov_fail}
58+
${cov_exclude} > ${cov_html_gcc_dir}/coverage_report.txt
5359
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
5460
VERBATIM
55-
COMMENT "Generating html code coverage report in ${cov_binary_dir}/index.html")
61+
COMMENT "Generating html code coverage report in ${cov_html_gcc_dir}/index.html")
5662
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
57-
set(cov_test_exectable "${ZserioCppRuntimeTest_BINARY_DIR}/ZserioCppRuntimeTest")
5863
set(cov_exclude)
5964
if (cov_EXCLUDE_SOURCES)
6065
list(APPEND cov_exclude "--ignore-filename-regex=${cov_EXCLUDE_SOURCES}")
6166
endif ()
67+
set(cov_test_exectable "${ZserioCppRuntimeTest_BINARY_DIR}/ZserioCppRuntimeTest")
68+
set(cov_binary_dir "${PROJECT_BINARY_DIR}/${cov_tgt_name}")
69+
set(cov_html_clang_dir "${cov_html_dir}/clang")
6270
add_custom_target(
6371
${cov_tgt_name}
6472
COMMAND ${CMAKE_COMMAND} -E make_directory ${cov_binary_dir}
@@ -67,19 +75,22 @@ function(create_coverage_target)
6775
COMMAND ${LLVM_PROFDATA_BIN} merge --sparse default.profraw -o ${cov_binary_dir}/runtime.profdata
6876
COMMAND ${LLVM_COV_BIN} show ${cov_test_exectable}
6977
-instr-profile=${cov_binary_dir}/runtime.profdata
70-
--format=html --show-instantiations=false -output-dir=${cov_binary_dir}
78+
-format=html -show-instantiations=false -show-branches=count -output-dir=${cov_html_clang_dir}
7179
${cov_exclude}
7280
COMMAND ${LLVM_COV_BIN} report ${cov_test_exectable}
7381
-instr-profile=${cov_binary_dir}/runtime.profdata
7482
${cov_exclude}
83+
COMMAND bash -c "${LLVM_COV_BIN} report ${cov_test_exectable} \
84+
-instr-profile=${cov_binary_dir}/runtime.profdata ${cov_exclude} \
85+
> ${cov_html_clang_dir}/coverage_report.txt"
7586
COMMAND bash -c "(( \
7687
`${LLVM_COV_BIN} report ${cov_test_exectable} \
7788
-instr-profile=${cov_binary_dir}/runtime.profdata ${cov_exclude} | grep TOTAL | \
7889
tr -s ' ' | cut -d' ' -f 10 | cut -d. -f 1` >= ${cov_INCOMPLETE_COVERAGE_FAIL} \
7990
))"
8091
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
8192
VERBATIM
82-
COMMENT "Generating html code coverage report in ${cov_binary_dir}/index.html")
93+
COMMENT "Generating html code coverage report in ${cov_html_clang_dir}/index.html")
8394
else ()
8495
message(FATAL_ERROR "Coverage reports are not supported for target compiler ${CMAKE_CXX_COMPILER_ID}!")
8596
endif ()

compiler/extensions/cpp/runtime/src/zserio/MainPage.dox

+6
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,10 @@
77
*
88
* - Serialization (`SerializeUtil.h` module)
99
* - Debug string output (`DebugStringUtil.h` module)
10+
*
11+
* Test coverage report of this library is available for <a href="coverage/gcc/index.html">gcc</a> and for
12+
* <a href="coverage/clang/index.html">clang</a>. Please note that <a href="coverage/gcc/index.html">gcc</a>
13+
* coverage report has many uncovered branches because of
14+
* <a href="https://gcovr.com/en/stable/faq.html#why-does-c-code-have-so-many-uncovered-branches">
15+
* different measurement approach</a>.
1016
*/

compiler/extensions/java/runtime/build.xml

+12-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ spotbugs.home_dir - Location of the spotbugs tool. If not set, spo
5454
value="${zserio_java_runtime.test.build_dir}/coverage"/>
5555
<property name="zserio_java_runtime.test.coverage_file"
5656
value="${zserio_java_runtime.test.coverage_dir}/jacoco_coverage.bin"/>
57+
<property name="zserio_java_runtime.test.coverage_html_dir"
58+
value="${zserio_java_runtime.javadocs_dir}/coverage"/>
5759

5860
<property name="zserio_java_runtime.jar_dir" value="${zserio_java_runtime.build_dir}/jar"/>
5961
<property name="zserio_java_runtime.jar_file" value="${zserio_java_runtime.jar_dir}/zserio_runtime.jar"/>
@@ -310,14 +312,23 @@ spotbugs.home_dir - Location of the spotbugs tool. If not set, spo
310312
</sourcefiles>
311313
</structure>
312314

313-
<html destdir="${zserio_java_runtime.test.coverage_dir}"/>
315+
<html destdir="${zserio_java_runtime.test.coverage_html_dir}"/>
316+
<xml destfile="${zserio_java_runtime.test.coverage_html_dir}/jacoco_report.xml"/>
314317

315318
<check>
316319
<rule element="BUNDLE">
317320
<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="92%"/>
318321
</rule>
319322
</check>
320323
</jacoco:report>
324+
325+
<jar destfile="${zserio_java_runtime.javadocs_jar_file}" update="true">
326+
<fileset dir="${zserio_java_runtime.javadocs_dir}">
327+
<include name="**"/>
328+
</fileset>
329+
</jar>
330+
<copy file="${zserio_java_runtime.javadocs_jar_file}" todir="${zserio_java_runtime.install_dir}"
331+
overwrite="true"/>
321332
</target>
322333

323334
<target name="test" depends="test.run">

compiler/extensions/java/runtime/src/zserio/runtime/overview.html

+2
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@
1111
<li>Debug string output (<code><a class="el" href="zserio/runtime/DebugStringUtil.html">zserio.runtime.DebugStringUtil.java</a></code> module)</li>
1212
</ul>
1313

14+
<p><a href="coverage/index.html">Test coverage report</a> of this library is available as well.
15+
1416
</body>
1517
</html>

compiler/extensions/python/runtime/src/zserio/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
99
- Serialization (:obj:`zserio.serialization` module)
1010
- Debug string output (:obj:`zserio.debugstring` module)
11+
12+
`Test coverage report <coverage/index.html>`_ of this library is available as well.
1113
"""
1214

1315
from zserio.bitbuffer import BitBuffer

scripts/build.sh

+22-16
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ test_python_runtime()
3838
ZSERIO_CPP_DIR=$(ls -d1 "${BUILD_DIR}/zserio_cpp/lib"*)
3939
if [ $? -ne 0 ] ; then
4040
stderr_echo "Failed to locate C++ runtime binding to Python!"
41+
popd > /dev/null
4142
return 1
4243
fi
4344

@@ -57,6 +58,13 @@ test_python_runtime()
5758
echo
5859

5960
python -m coverage combine --keep coverage_cpp.data coverage_python.data
61+
python -m coverage xml -o "coverage/coverage_report.xml" --omit="*test_object*"
62+
local COVERAGE_RESULT=$?
63+
if [ ${COVERAGE_RESULT} -ne 0 ] ; then
64+
stderr_echo "Running python coverage report failed with return code ${COVERAGE_RESULT}!"
65+
popd > /dev/null
66+
return 1
67+
fi
6068
python -m coverage html --directory="coverage" --fail-under=100 \
6169
--omit="*test_object*" --title="Zserio Python Runtime Library"
6270
local COVERAGE_RESULT=$?
@@ -120,8 +128,12 @@ install_python_runtime()
120128
local PYTHON_RUNTIME_DOC_BUILD_DIR="${PYTHON_RUNTIME_BUILD_DIR}/doc"
121129
local ZSERIO_LOGO="${ZSERIO_PROJECT_ROOT}/doc/Zserio.png"
122130

123-
# build doc
124-
echo "Building documentation for Zserio Python runtime library."
131+
echo "Purging python distr dir ${PYTHON_RUNTIME_DISTR_DIR}."
132+
rm -rf "${PYTHON_RUNTIME_DISTR_DIR}/"
133+
mkdir -p "${PYTHON_RUNTIME_DISTR_DIR}"
134+
135+
# install doc together with test coverage report
136+
echo "Installing documentation for Zserio Python runtime library."
125137
echo
126138
rm -rf "${PYTHON_RUNTIME_DOC_BUILD_DIR}/"
127139
mkdir -p "${PYTHON_RUNTIME_DOC_BUILD_DIR}"
@@ -137,22 +149,24 @@ install_python_runtime()
137149
sphinx-apidoc --module-first --force --separate -o . "${PYTHON_RUNTIME_SOURCES}/zserio/"
138150
rm modules.rst
139151
PYTHONPATH="${PYTHON_RUNTIME_SOURCES}" \
140-
sphinx-build -Wa -b html -d . -Dhtml_logo="${ZSERIO_LOGO}" . zserio_doc
152+
sphinx-build -Wa -b html -d . -Dhtml_logo="${ZSERIO_LOGO}" . "${PYTHON_RUNTIME_DISTR_DIR}/zserio_doc"
141153
if [ $? -ne 0 ] ; then
142154
popd > /dev/null
143155
return 1
144156
fi
145-
146157
popd > /dev/null
147158

159+
cp -r "${PYTHON_RUNTIME_BUILD_DIR}/coverage" "${PYTHON_RUNTIME_DISTR_DIR}/zserio_doc/coverage"
160+
if [ $? -ne 0 ] ; then
161+
stderr_echo "Failed to install documentation!"
162+
return 1
163+
fi
164+
rm -f "${PYTHON_RUNTIME_DISTR_DIR}/zserio_doc/coverage/.gitignore"
165+
148166
echo
149167
echo "Installing Zserio Python runtime library."
150168
echo
151169

152-
echo "Purging python distr dir: ${PYTHON_RUNTIME_DISTR_DIR}"
153-
rm -rf "${PYTHON_RUNTIME_DISTR_DIR}/"
154-
mkdir -p "${PYTHON_RUNTIME_DISTR_DIR}"
155-
156170
# install sources
157171
pushd "${PYTHON_RUNTIME_SOURCES}" > /dev/null
158172

@@ -168,14 +182,6 @@ install_python_runtime()
168182

169183
popd > /dev/null
170184

171-
# install doc
172-
echo "Installing API documentation"
173-
cp -r "${PYTHON_RUNTIME_DOC_BUILD_DIR}/zserio_doc" "${PYTHON_RUNTIME_DISTR_DIR}/"
174-
if [ $? -ne 0 ] ; then
175-
stderr_echo "Failed to install documentation!"
176-
return 1
177-
fi
178-
179185
return 0
180186
}
181187

scripts/common_tools.sh

+17-2
Original file line numberDiff line numberDiff line change
@@ -724,13 +724,17 @@ compile_cpp_for_target()
724724
mkdir -p "${BUILD_DIR}"
725725
pushd "${BUILD_DIR}" > /dev/null
726726

727-
local CMAKE_BUILD_TARGET=${MAKE_TARGET}
727+
if [[ ${MAKE_TARGET} == "install" ]] ; then
728+
local CMAKE_BUILD_TARGET="all"
729+
else
730+
local CMAKE_BUILD_TARGET="${MAKE_TARGET}"
731+
fi
728732

729733
# resolve CMake generator
730734
if [[ ${TARGET} == *"-msvc" ]] ; then
731735
local CMAKE_BUILD_CONFIG="--config ${BUILD_TYPE}"
732736
CTEST_ARGS+=("-C ${BUILD_TYPE}")
733-
if [[ ${MAKE_TARGET} == "all" ]] ; then
737+
if [[ ${CMAKE_BUILD_TARGET} == "all" ]] ; then
734738
CMAKE_BUILD_TARGET="ALL_BUILD" # all target doesn't exist in MSVC solution
735739
fi
736740
local CMAKE_GENERATOR="${MSVC_CMAKE_GENERATOR}";
@@ -782,6 +786,17 @@ compile_cpp_for_target()
782786
fi
783787
fi
784788

789+
# install it running cmake
790+
if [[ ${MAKE_TARGET} == "install" ]] ; then
791+
"${CMAKE}" --build . --target install ${CMAKE_BUILD_CONFIG} -- ${CMAKE_BUILD_OPTIONS}
792+
local CMAKE_RESULT=$?
793+
if [ ${CMAKE_RESULT} -ne 0 ] ; then
794+
stderr_echo "Running CMake failed with return code ${CMAKE_RESULT}!"
795+
popd > /dev/null
796+
return 1
797+
fi
798+
fi
799+
785800
popd > /dev/null
786801

787802
return 0

scripts/release.sh

+77-6
Original file line numberDiff line numberDiff line change
@@ -554,14 +554,13 @@ update_web_pages()
554554
fi
555555
echo "Done"
556556

557+
echo -ne "Creating Zserio runtime library GitHub badges..."
558+
create_github_badge_jsons "${ZSERIO_PROJECT_ROOT}" "${ZSERIO_VERSION}"
559+
echo "Done"
560+
557561
# This is necessary because Jekyll ignores Python runtime doc directories that start with underscores.
558562
echo -ne "Creating Jekyll configuration file..."
559-
echo "theme: jekyll-theme-slate" > "${ZSERIO_PROJECT_ROOT}"/_config.yml
560-
echo "exclude: 3rdparty" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
561-
echo "include:" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
562-
echo " - _images" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
563-
echo " - _modules" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
564-
echo " - _static" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
563+
create_jekyll_config_file "${ZSERIO_PROJECT_ROOT}"
565564
echo "Done"
566565

567566
echo
@@ -590,6 +589,78 @@ update_web_pages()
590589
return 0
591590
}
592591

592+
# Create JSON configuration files for all GitHub badges
593+
create_github_badge_jsons()
594+
{
595+
exit_if_argc_ne $# 2
596+
local ZSERIO_PROJECT_ROOT="$1"; shift
597+
local ZSERIO_VERSION="$1"; shift
598+
599+
local CLANG_COVERAGE_DIR="${ZSERIO_PROJECT_ROOT}"/doc/runtime/cpp/coverage/clang
600+
local CLANG_LINES_COVERAGE=`cat "${CLANG_COVERAGE_DIR}"/coverage_report.txt | grep TOTAL | \
601+
tr -s ' ' | cut -d' ' -f 10`
602+
create_github_badge_json "${CLANG_COVERAGE_DIR}"/coverage_github_badge.json \
603+
"C++ clang runtime ${ZSERIO_VERSION} coverage" "${CLANG_LINES_COVERAGE}"
604+
605+
local GCC_COVERAGE_DIR="${ZSERIO_PROJECT_ROOT}"/doc/runtime/cpp/coverage/gcc
606+
local GCC_LINES_COVERAGE=`cat "${GCC_COVERAGE_DIR}"/coverage_report.txt | grep lines: | \
607+
tr -s ' ' | cut -d' ' -f 2`
608+
create_github_badge_json "${GCC_COVERAGE_DIR}"/coverage_github_badge.json \
609+
"C++ gcc runtime ${ZSERIO_VERSION} coverage" "${GCC_LINES_COVERAGE}"
610+
611+
local JAVA_COVERAGE_DIR="${ZSERIO_PROJECT_ROOT}"/doc/runtime/java/coverage
612+
local JAVA_COVERAGE_REPORT=`cat "${JAVA_COVERAGE_DIR}"/jacoco_report.xml`
613+
local JAVA_LINES_MISSED=`echo ${JAVA_COVERAGE_REPORT##*INSTRUCTION} | cut -d'"' -f3`
614+
local JAVA_LINES_COVERED=`echo ${JAVA_COVERAGE_REPORT##*INSTRUCTION} | cut -d'"' -f5`
615+
local JAVA_LINES_VALID=$((${JAVA_LINES_COVERED} - ${JAVA_LINES_MISSED}))
616+
local JAVA_LINES_COVERAGE=$((10000 * ${JAVA_LINES_VALID} / ${JAVA_LINES_COVERED}))
617+
create_github_badge_json "${JAVA_COVERAGE_DIR}"/coverage_github_badge.json \
618+
"Java runtime ${ZSERIO_VERSION} coverage" \
619+
"${JAVA_LINES_COVERAGE:0:-2}.${JAVA_LINES_COVERAGE: -2}%"
620+
621+
local PYTHON_COVERAGE_DIR="${ZSERIO_PROJECT_ROOT}"/doc/runtime/python/coverage
622+
local PYTHON_LINES_VALID=`cat "${PYTHON_COVERAGE_DIR}"/coverage_report.xml | grep lines-covered | \
623+
cut -d' ' -f 4 | cut -d= -f2 | tr -d \"`
624+
local PYTHON_LINES_COVERED=`cat "${PYTHON_COVERAGE_DIR}"/coverage_report.xml | grep lines-covered | \
625+
cut -d' ' -f 5 | cut -d= -f2 | tr -d \"`
626+
local PYTHON_LINES_COVERAGE=$((10000 * ${PYTHON_LINES_VALID} / ${PYTHON_LINES_COVERED}))
627+
create_github_badge_json "${PYTHON_COVERAGE_DIR}"/coverage_github_badge.json \
628+
"Python runtime ${ZSERIO_VERSION} coverage" \
629+
"${PYTHON_LINES_COVERAGE:0:-2}.${PYTHON_LINES_COVERAGE: -2}%"
630+
}
631+
632+
# Create JSON configuration file for GitHub badge
633+
create_github_badge_json()
634+
{
635+
exit_if_argc_ne $# 3
636+
local BADGE_JSON_FILE="$1"; shift
637+
local BADGE_LABEL="$1"; shift
638+
local BADGE_MESSAGE="$1"; shift
639+
640+
cat > "${BADGE_JSON_FILE}" << EOF
641+
{
642+
"schemaVersion": 1,
643+
"label": "${BADGE_LABEL}",
644+
"message": "${BADGE_MESSAGE}",
645+
"color": "green"
646+
}
647+
EOF
648+
}
649+
650+
# Create Jekyll configuration file
651+
create_jekyll_config_file()
652+
{
653+
exit_if_argc_ne $# 1
654+
local ZSERIO_PROJECT_ROOT="$1"; shift
655+
656+
echo "theme: jekyll-theme-slate" > "${ZSERIO_PROJECT_ROOT}"/_config.yml
657+
echo "exclude: 3rdparty" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
658+
echo "include:" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
659+
echo " - _images" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
660+
echo " - _modules" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
661+
echo " - _static" >> "${ZSERIO_PROJECT_ROOT}"/_config.yml
662+
}
663+
593664
# Print help message.
594665
print_help()
595666
{

0 commit comments

Comments
 (0)