[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