[mlpack-git] master: Added test coverage framework (ff02cb5)
gitdub at mlpack.org
gitdub at mlpack.org
Mon Jul 11 16:38:40 EDT 2016
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/57a24a9d9fbdb4687ea0e0fef85bc2a133420dcc...82cf86500e8ad98b32db9fd9cceca4a844f4bb19
>---------------------------------------------------------------
commit ff02cb500867c83c848d69c3f85c5004b1d9fb4a
Author: sumedhghaisas <sumedhghaisas at gmail.com>
Date: Mon Jul 11 13:34:42 2016 -0700
Added test coverage framework
* Added mlpack_coverage script to generate report by running tests
* mlpack_coverage script can upload the results to coveralls
>---------------------------------------------------------------
ff02cb500867c83c848d69c3f85c5004b1d9fb4a
CMake/mlpack_coverage.in | 125 +++++++++++++++++++++++++++++++++++++++++++++++
CMakeLists.txt | 32 +++++++++++-
2 files changed, 155 insertions(+), 2 deletions(-)
diff --git a/CMake/mlpack_coverage.in b/CMake/mlpack_coverage.in
new file mode 100755
index 0000000..36c1eaf
--- /dev/null
+++ b/CMake/mlpack_coverage.in
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+test_case="ALL"
+gcov_loc=""
+token=""
+clean=true
+current_log_file=`date +'%Y.%h.%d:%H:%M:%S-coverage.log'`
+current_coverage_file=`date +'%Y.%h.%d:%H:%M:%S-coverage.info'`
+max_cov_count=50000
+
+# Extract arguments
+for i in "$@"
+do
+case $i in
+ -h|--help)
+ echo "Usage: mlpack_coverage --help|-h"
+ echo " mlpack_coverage [-r=test_suite] [-g=gcov_tool_location]"
+ echo " [--token=coveralls_token]"
+ echo "Optional parameters:"
+ echo " -n|--no_test Do not run test before coverage computation"
+ echo " -r|--run_test Run tests with specific test suite"
+ echo " --no_clean Do not remove existing gcda file"
+ echo " -g|--gcov_tool_location Gcov location if not default"
+ echo " -t|--token Upload to coveralls with given token"
+ echo " --max_cov_count Max line coverage count (default 50000)"
+ exit 0
+ shift
+ ;;
+ -n|--no_test)
+ test_case=""
+ shift
+ ;;
+ -r=*|--run_test=*)
+ test_case="${i#*=}"
+ shift # past argument=value
+ ;;
+ --no_clean)
+ clean=false
+ shift
+ ;;
+ -g=*|--gcov_tool_location=*)
+ gcov_loc="${i#*=}"
+ shift # past argument=value
+ ;;
+ -t=*|--token=*)
+ token="${i#*=}"
+ shift # past argument=value
+ ;;
+ --max_cov_count)
+ max_cov_count="${i#*=}"
+ shift
+ ;;
+ *)
+ # unknown option
+ ;;
+esac
+done
+
+if [ "$clean" = true ]; then
+ echo "Deleting existing coverage data..."
+ find ./ -name "*.gcda" -type f -delete
+fi
+
+# initial pass
+echo "Generating primary coverage report"
+lcov -b . -c -i -d ./ -o .coverage.wtest.base >> ./coveragehistory/$current_log_file
+
+# Run the tests
+if [ "$test_case" = "ALL" ]; then
+ echo "Running all the tests..."
+ @CMAKE_BINARY_DIR@/bin/mlpack_test
+elif ! [ "$test_case" = "" ]; then
+ echo "Running test suite: $test_case"
+ @CMAKE_BINARY_DIR@/bin/mlpack_test --run_test=$test_case
+fi
+
+# Generate coverage based on executed tests
+echo "Computing coverage..."
+if [ "$gcov_loc" = "" ];
+then lcov -b . -c -d ./ -o .coverage.wtest.run >> ./coveragehistory/$current_log_file
+else
+ lcov -b . -c -d ./ -o .coverage.wtest.run --gcov-tool=$gcov_loc >> ./coveragehistory/$current_log_file
+fi
+
+echo "Filtering coverage files..."
+# Merge coverage tracefiles
+lcov -a .coverage.wtest.base -a .coverage.wtest.run -o .coverage.total >> ./coveragehistory/$current_log_file
+
+# Filtering, extracting project files
+lcov -e .coverage.total "@CMAKE_CURRENT_SOURCE_DIR@/src/mlpack/*" -o .coverage.total.filtered >> ./coveragehistory/$current_log_file
+
+# Filtering, removing test-files and main.cpp
+lcov -r .coverage.total.filtered "@CMAKE_CURRENT_SOURCE_DIR@/src/mlpack/*/*_main.cpp" -o .coverage.total.filtered >> ./coveragehistory/$current_log_file
+lcov -r .coverage.total.filtered "@CMAKE_CURRENT_SOURCE_DIR@/src/mlpack/tests/*" -o .coverage.total.filtered >> ./coveragehistory/$current_log_file
+
+# Remove untestable files
+lcov -r .coverage.total.filtered "@CMAKE_CURRENT_SOURCE_DIR@/src/mlpack/core/util/gitversion.hpp" -o .coverage.total.filtered >> ./coveragehistory/$current_log_file
+lcov -r .coverage.total.filtered "@CMAKE_CURRENT_SOURCE_DIR@/src/mlpack/core/util/arma_config.hpp" -o .coverage.total.filtered >> ./coveragehistory/$current_log_file
+
+# Extra: Replace /build/ with /src/ to unify directories
+cat .coverage.total.filtered > .coverage.total
+
+# Extra: Clear up previous data, create html folder
+if [[ -d ./coverage/ ]] ; then
+ rm -rf ./coverage/*
+else
+ mkdir coverage
+fi
+
+# Step 9: Generate webpage
+genhtml -o ./coverage/ .coverage.total
+
+# Extra: Preserve coverage file in coveragehistory folder
+coverage_file=$current_coverage_file
+[[ -d ./coveragehistory/ ]] || mkdir coveragehistory
+cp .coverage.total ./coveragehistory/$current_coverage_file
+
+# clean temp coverage files
+#rm .coverage.*
+
+# Upload the result to coveralls if token is provided
+if ! [ "$token" = "" ]; then
+ cpp-coveralls -n -r ../ -b ../ -l ./coveragehistory/$current_coverage_file -t "$token" --max-cov-count $max_cov_count
+fi
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 80a92a8..cc2189c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,8 +26,8 @@ option(TEST_VERBOSE "Run test cases with verbose output." OFF)
option(BUILD_TESTS "Build tests." ON)
option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
option(BUILD_SHARED_LIBS
- "Compile shared libraries (if OFF, static libraries are compiled)." ON)
-
+ "Compile shared libraries (if OFF, static libraries are compiled)" ON)
+option(BUILD_WITH_COVERAGE "Build with COVTOOL" OFF)
enable_testing()
# Include modules in the CMake directory.
@@ -74,6 +74,34 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -lm")
endif()
+# Setup build for test coverage
+if(BUILD_WITH_COVERAGE)
+ # Currently coverage only works with GNU g++
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ # Find gcov and lcov
+ find_program(GCOV gcov)
+ find_program(LCOV lcov)
+
+ if(NOT GCOV)
+ message(FATAL_ERROR "gcov not found! Aborting...")
+ endif()
+
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fno-inline -fno-inline-small-functions -fno-default-inline -fprofile-arcs -fkeep-inline-functions")
+ message(WARNING "Adding debug options for coverage")
+ # Remove optimizations for better line coverage
+ set(DEBUG ON)
+
+ if(LCOV)
+ configure_file(CMake/mlpack_coverage.in mlpack_coverage @ONLY)
+ add_custom_target(mlpack_coverage DEPENDS mlpack_test COMMAND ${PROJECT_BINARY_DIR}/mlpack_coverage)
+ else()
+ message(WARNING "'lcov' not found, local coverage report is disabled. Install 'lcov' and rerun cmake to generate local coverage report.")
+ endif()
+ else()
+ message(FATAL_ERROR "Coverage will only work with GNU environment.")
+ endif()
+endif()
+
# Debugging CFLAGS. Turn optimizations off; turn debugging symbols on.
if(DEBUG)
add_definitions(-DDEBUG)
More information about the mlpack-git
mailing list