diff --git a/README.md b/README.md index 458fee2e..6d4c2c9f 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ env: - TEST=clang-format # check code formatting for compliance to .clang-format rules - TEST=clang-tidy-fix # perform static code analysis and compliance check against .clang-tidy rules - TEST=catkin_lint # perform catkin_lint checks + - TEST=code-coverage # perform code coverage report # pull in packages from a local .rosinstall file - UPSTREAM_WORKSPACE=moveit.rosinstall # pull in packages from a remote .rosinstall file and run for a non-default ROS_DISTRO @@ -143,3 +144,23 @@ It's also possible to run the script without using docker. To this end, issue th export ROS_WS=/tmp/ros_ws # define a new ROS workspace location mkdir $ROS_WS # and create it .moveit_ci/travis.sh + +## Enabling codecov.io reporting + +For codecov to work you need to build and link your C++ code with specific parameters. To enable this we use the ROS package [code_coverage](https://github.com/mikeferguson/code_coverage). Using the `code-coverage` test in your repo requires the following two changes: + +1. Add `code_coverage` to your package.xml +2. Add this to your `CMakeLists.txt`: + +```cmake +# to run: catkin_make -DENABLE_COVERAGE_TESTING=ON package_name_coverage +if(CATKIN_ENABLE_TESTING AND ENABLE_COVERAGE_TESTING) + find_package(code_coverage REQUIRED) # catkin package ros-*-code-coverage + include(CodeCoverage) + APPEND_COVERAGE_COMPILER_FLAGS() +endif() +``` + +Then you can use the `code-coverage` test and it will run the script provided by [codecov.io](codecov.io) which runs `gcov` to generate the reports and then compiles them into a report and uploads them to their servers. + +If you are using this on a private github repo you will need to set the `CODECOV_TOKEN` enviroment variable in the `global` section of your `.travis.yml` file to the value you can find on the settings page of your project on codecov.io. diff --git a/test_pkgs/valid/CMakeLists.txt b/test_pkgs/valid/CMakeLists.txt index b8a8cc10..3ee6a1bc 100644 --- a/test_pkgs/valid/CMakeLists.txt +++ b/test_pkgs/valid/CMakeLists.txt @@ -13,3 +13,9 @@ include_directories( if(CATKIN_ENABLE_TESTING) catkin_add_gtest(${PROJECT_NAME} test.cpp) endif() + +if(CATKIN_ENABLE_TESTING AND ENABLE_COVERAGE_TESTING) + find_package(code_coverage REQUIRED) # catkin package ros-*-code-coverage + include(CodeCoverage) + APPEND_COVERAGE_COMPILER_FLAGS() +endif() diff --git a/test_pkgs/valid/package.xml b/test_pkgs/valid/package.xml index a401ade1..6e5a2ed1 100644 --- a/test_pkgs/valid/package.xml +++ b/test_pkgs/valid/package.xml @@ -11,6 +11,7 @@ catkin rosunit + code_coverage diff --git a/travis.sh b/travis.sh index dbb517b6..92123960 100755 --- a/travis.sh +++ b/travis.sh @@ -48,6 +48,13 @@ function docker_cp { function run_docker() { run_script BEFORE_DOCKER_SCRIPT + # get ci enviroment parameters to pass into docker for codecov + # this is a list of docker parameters to include enviroment variables + CI_ENV_PARAMS=`bash <(curl -s https://codecov.io/env)` + # The following two varaibles are needed for codecov to work locally + export ${VCS_BRANCH_NAME:=$(git rev-parse --abbrev-ref HEAD)} + export ${VCS_COMMIT_ID:=$(git rev-parse HEAD)} + # Choose the docker container to use if [ -n "${ROS_REPO:=}" ] && [ -n "${DOCKER_IMAGE:=}" ]; then echo -e $(colorize YELLOW "DOCKER_IMAGE=$DOCKER_IMAGE overrides ROS_REPO=$ROS_REPO setting") @@ -79,12 +86,16 @@ function run_docker() { -e TEST_PKG \ -e TEST \ -e TEST_BLACKLIST \ + -e TEST_WHITELIST \ -e WARNINGS_OK \ -e ABI_BASE_URL \ -e CC=${CC_FOR_BUILD:-${CC:-cc}} \ -e CXX=${CXX_FOR_BUILD:-${CXX:-c++}} \ -e CFLAGS \ -e CXXFLAGS \ + -e CCACHE_SLOPPINESS \ + -e CCACHE_MAXSIZE \ + $CI_ENV_PARAMS \ -v $(pwd):/root/$REPOSITORY_NAME \ -v ${CCACHE_DIR:-$HOME/.ccache}:/root/.ccache \ -t \ @@ -167,6 +178,9 @@ function run_early_tests() { abi) # abi-checker requires debug symbols CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS_DEBUG=\"-g -Og\"" ;; + code-coverage) # code coverage test requres specific compiler and linker arguments + CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE_TESTING=ON" + ;; *) echo -e $(colorize RED "Unknown TEST: $t") EARLY_RESULT=$(( ${EARLY_RESULT:-0} + 1 )) @@ -270,8 +284,13 @@ function build_workspace() { # Console output fix for: "WARNING: Could not encode unicode characters" export PYTHONIOENCODING=UTF-8 + # Set compile flag to improve ccache hit rate + export CXXFLAGS="${CXXFLAGS:-} -fdebug-prefix-map=$(pwd)=." + export CCACHE_BASEDIR=$(pwd) + + # If test whitelist is set, explicitly build that project # For a command that doesn’t produce output for more than 10 minutes, prefix it with travis_run_wait - travis_run_wait 60 --title "catkin build" catkin build --no-status --summarize + travis_run_wait 60 --title "catkin build ${TEST_WHITELIST:-}" catkin build ${TEST_WHITELIST:-} --no-status --summarize # Allow to verify ccache usage travis_run --title "ccache statistics" ccache -s @@ -290,6 +309,12 @@ function test_workspace() { echo -e $(colorize YELLOW Test blacklist: $(colorize THIN $TEST_BLACKLIST)) test -n "$TEST_BLACKLIST" && catkin config --blacklist $TEST_BLACKLIST &> /dev/null + # Consider TEST_WHITELIST + TEST_WHITELIST=$(unify_list " ,;" ${TEST_WHITELIST:-}) + echo -e $(colorize YELLOW Test whitelist: $(colorize THIN $TEST_WHITELIST)) + test -n "$TEST_WHITELIST" && catkin config --whitelist $TEST_WHITELIST &> /dev/null + + # Also blacklist external packages local all_pkgs source_pkgs blacklist_pkgs all_pkgs=$(catkin_topological_order $ROS_WS/src --only-names) @@ -371,6 +396,12 @@ for t in $(unify_list " ,;" "$TEST") ; do (source ${MOVEIT_CI_DIR}/check_abi.sh) test $? -eq 0 || result=$(( ${result:-0} + 1 )) ;; + code-coverage) + # redirect output to avoid failures due to filling up logs + travis_run --title "codeco1v.io report upload" \ + bash <(curl -s https://codecov.io/bash) -s $ROS_WS \ + -R $ROS_WS/src/$REPOSITORY_NAME -g '*/test/*' > /dev/null + ;; esac done # Run warnings check diff --git a/unit_tests.sh b/unit_tests.sh index 7610ad2c..88ecaf6a 100755 --- a/unit_tests.sh +++ b/unit_tests.sh @@ -60,7 +60,7 @@ rosdep() { echo "Dummy rosdep $*" } -all_groups="sanity warnings catkin_lint clang-format clang-tidy-fix clang-tidy-check" +all_groups="sanity warnings catkin_lint clang-format clang-tidy-fix clang-tidy-check code-coverage" skip_groups="${SKIP:-}" # process options while true ; do @@ -120,6 +120,10 @@ for group in $test_groups ; do run_test 0 $0:$LINENO "clang-tidy-check on 'valid' package, warnings forbidden" TEST_PKG=valid TEST=clang-tidy-check WARNINGS_OK=false run_test 1 $0:$LINENO "clang-tidy-check on 'clang_tidy' package, warnings forbidden" TEST_PKG=clang_tidy TEST=clang-tidy-check WARNINGS_OK=false ;; + code-coverage) + run_test 0 $0:$LINENO "code-coverage on 'valid' package, warnings forbidden" TEST_PKG=valid TEST=code-coverage WARNINGS_OK=false + run_test 1 $0:$LINENO "code-coverage on 'warnings' package, warnings forbidden" TEST_PKG=warnings TEST=code-coverage WARNINGS_OK=false + ;; *) echo -e $(colorize YELLOW "Unknown test group '$group'.") echo "Known groups are: $all_groups" ;; esac