Skip to content

Commit

Permalink
Merge "feat(tests): Add support for coverage report" into integration
Browse files Browse the repository at this point in the history
  • Loading branch information
soby-mathew authored and TrustedFirmware Code Review committed Dec 14, 2022
2 parents 35f487b + 576071e commit 6ef4ab3
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ set(CMAKE_C_EXTENSIONS TRUE)
if(RMM_STATIC_ANALYSIS_CPPCHECK)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()

#
# Include the platform makefile
#
include("cmake/Platforms.cmake")

#
# Include Coverage report framework
#
include("cmake/CoverageReport.cmake")

#
# Include the Unit Test Framework
#
Expand Down
151 changes: 151 additions & 0 deletions cmake/CoverageReport.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#
# SPDX-License-Identifier: BSD-3-Clause
# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
#

arm_config_option(
NAME RMM_COVERAGE
HELP "Enable coverage tests"
TYPE BOOL
DEFAULT "OFF")

arm_config_option(
NAME RMM_HTML_COV_REPORT
HELP "Enable html coverage report"
TYPE BOOL
DEPENDS RMM_COVERAGE
DEFAULT "ON")

arm_config_option(
NAME COVERAGE_REPORT_NAME
HELP "Canonical name for the coverage report"
TYPE STRING
DEPENDS RMM_COVERAGE
DEFAULT "tf-rmm-coverage"
ADVANCED)

macro(check_and_prepare_c_coverage_flags)
# Store a copy of CMAKE_C_FLAGS
set(CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}")

foreach(flag ${ARGN})
string(REPLACE "-" "_" flag_no_hyphen ${flag})
check_c_compiler_flag("-${flag}" COVERAGE_C_FLAG_${flag_no_hyphen})
if (COVERAGE_C_FLAG_${flag_no_hyphen})
# Some of the coverage flags depend on the previous ones being
# enabled, so add them to the C Flags now for the next check.
string(APPEND CMAKE_C_FLAGS " -${flag}")
string(APPEND COVERAGE_C_FLAGS " -${flag}")
else()
set(COVERAGE_SUPPORTED "FALSE")
endif()
endforeach()

# Restore CMAKE_C_FLAGS
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}")
endmacro(check_and_prepare_c_coverage_flags)

macro(check_and_prepare_cxx_coverage_flags)
# Store a copy of CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}")

foreach(flag ${ARGN})
string(REPLACE "-" "_" flag_no_hyphen ${flag})
check_cxx_compiler_flag("-${flag}" COVERAGE_CXX_FLAG_${flag_no_hyphen})
if (COVERAGE_CXX_FLAG_${flag_no_hyphen})
# Some of the coverage flags depend on the previous ones being
# enabled, so add them to the CXX Flags now for the next check.
string(APPEND CMAKE_CXX_FLAGS " -${flag}")
string(APPEND COVERAGE_CXX_FLAGS " -${flag}")
endif()
endforeach()

# Restore CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}")
endmacro(check_and_prepare_cxx_coverage_flags)

if(RMM_COVERAGE)

find_program(GCOVR_EXECUTABLE "gcovr" DOC "Path to gcovr")

if(${GCOVR_EXECUTABLE} STREQUAL "GCOVR_EXECUTABLE-NOTFOUND")
message (WARNING "gcovr executable not found. Coverage tests disabled")
return()
endif()

include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)

if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
# Using LLVM. Select the coverage flags to test
set(COVERAGE_FLAGS
ftest-coverage
fprofile-instr-generate
fprofile-arcs
fcoverage-mapping)

# Setup the right coverage tool if using llvm
set(GCOVR_EXE_OPTION --gcov-executable "llvm-cov gcov"
CACHE INTERNAL "GCOV_EXECUTABLE")

elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Using GNU. Select the coverage flags to test
set(COVERAGE_FLAGS
-coverage)

# Flags needed to enable coverage testing
string(APPEND CMAKE_EXE_LINKER_FLAGS " -coverage -lgcov ")
else()
message(WARNING "Toolchain ${CMAKE_C_COMPILER_ID} does not support coverage")
return()
endif()

set(COVERAGE_SUPPORTED "TRUE")
check_and_prepare_c_coverage_flags(${COVERAGE_FLAGS})
check_and_prepare_cxx_coverage_flags(${COVERAGE_FLAGS})

# If coverage is not supported by the C compiler, or the C and C++
# compilers do not support the same set of coverage flags (which can
# lead to link problems), abort.
if ((COVERAGE_SUPPORTED STREQUAL "FALSE") OR
(NOT (COVERAGE_C_FLAGS STREQUAL COVERAGE_CXX_FLAGS)))
message (WARNING "Toolchain ${CMAKE_C_COMPILER_ID} does not support coverage")
return()
endif()

# Setup flags for coverage
foreach(language in ITEMS C CXX)
string(APPEND CMAKE_${language}_FLAGS
" ${COVERAGE_${language}_FLAGS} ")
endforeach()

# Directory where to store the results
set(COVERAGE_DIRECTORY
"${CMAKE_BINARY_DIR}/$<CONFIG>/coverage")

set(COVERAGE_OUTPUT "${COVERAGE_DIRECTORY}/${COVERAGE_REPORT_NAME}")

if(RMM_HTML_COV_REPORT)
set(HTML_REPORT --html-details ${COVERAGE_OUTPUT}.html)
endif()

#
# Rules for coverage report generation
#
add_custom_target(run-coverage
COMMAND ${CMAKE_COMMAND} -E make_directory "${COVERAGE_DIRECTORY}"
COMMAND ${GCOVR_EXECUTABLE}
${GCOVR_EXE_OPTION}
--exclude "'((.+)ext(.+))|((.+)CMakeFiles(.+)\..)|((.+)\.cpp)|((.+)test(.+))'"
-r ${CMAKE_SOURCE_DIR}
-x ${COVERAGE_OUTPUT}.xml
${HTML_REPORT}
${CMAKE_BINARY_DIR})
#
# Add dependency on unit test target if being invoked in a
# multi-target build command line.
#
if(RMM_UNITTESTS)
add_dependencies(run-coverage run-unittests)
endif()
endif() # RMM_COVERAGE
19 changes: 15 additions & 4 deletions docs/getting_started/build-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Run checkincludes on entire codebase:
cmake -DRMM_CONFIG=fvp_defcfg -S ${RMM_SOURCE_DIR} -B ${RMM_BUILD_DIR}
cmake --build ${RMM_BUILD_DIR} -- checkincludes-codebase
14. Perform unit tests on development host:
14. Perform unit tests on development host:

Build and run unit tests on host platform. It is recommended to do the Debug
build of RMM.
Expand All @@ -172,6 +172,17 @@ build of RMM.
cmake -DRMM_CONFIG=host_defcfg -DHOST_VARIANT=host_test -DCMAKE_BUILD_TYPE=Debug -S ${RMM_SOURCE_DIR} -B ${RMM_BUILD_DIR}
cmake --build ${RMM_BUILD_DIR} -- run-unittests
Run coverage analysis on unit tests.

.. code-block:: bash
cmake -DRMM_CONFIG=host_defcfg -DHOST_VARIANT=host_test -DRMM_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug -S ${RMM_SOURCE_DIR} -B ${RMM_BUILD_DIR}
cmake --build ${RMM_BUILD_DIR} -- run-coverage
The above commands will automatically generate the HTML coverage report in folder
`build/Debug/coverage` within build directory. The HTML generation can be
disabled by setting `RMM_HTML_COV_REPORT=OFF`.

.. _build_options_table:

###################
Expand Down Expand Up @@ -208,9 +219,9 @@ The |RMM| build system supports the following CMake build options.
MBEDTLS_ECP_MAX_OPS ,248 - ,1000 ,"Number of max operations per ECC signing iteration"
RMM_FPU_USE_AT_REL2 ,ON | OFF ,OFF(fake_host) ON(aarch64),"Enable FPU/SIMD usage in RMM."
RMM_MAX_GRANULES , ,0 ,"Maximum number of memory granules available to the system"
HOST_VARIANT ,host_build | host_test ,host_build , "Variant to build for the host platform. Only available when RMM_PLATFORM=host"


HOST_VARIANT ,host_build | host_test ,host_build ,"Variant to build for the host platform. Only available when RMM_PLATFORM=host"
RMM_COVERAGE ,ON | OFF ,OFF ,"Enable coverage analysis"
RMM_HTML_COV_REPORT ,ON | OFF ,ON ,"Enable HTML output report for coverage analysis"

.. _llvm_build:

Expand Down
25 changes: 25 additions & 0 deletions docs/getting_started/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ The following tools are required to obtain and build |RMM|:
"Git",, "Firmware, Documentation"
"Graphviz dot",">v2.38.0","Documentation"
"docutils",">v2.38.0","Documentation"
"gcovr",">=v4.2","Tools(Coverage analysis)"

.. _getting_started_toolchain:

Expand Down Expand Up @@ -143,6 +144,30 @@ Install them with ``pip3``:
cd <rmm source folder>
pip3 install -r docs/requirements.txt
############################################
Install coverage tools analysis dependencies
############################################

.. note::

This is an optional step only needed if you intend to run coverage
analysis on the source code.

On Ubuntu, ``gcovr`` tool can be installed in two different ways:

Using the pagckage manager:

.. code-block:: bash
sudo apt-get install gcovr
The second (and recommended) way is install it with ``pip3``:

.. code-block:: bash
pip3 install --upgrade pip
pip3 install gcovr
.. _getting_started_get_source:

#########################
Expand Down
1 change: 1 addition & 0 deletions plat/host/host_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library(rmm-plat-host_test)
arm_config_option(
NAME RMM_UNITTESTS
HELP "Enable Unitests for the build"
TYPE BOOL
DEFAULT "ON"
TYPE INTERNAL)

Expand Down

0 comments on commit 6ef4ab3

Please sign in to comment.