diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..e70db8fc --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,54 @@ +name: coverage + +on: push + +jobs: + + codecov: + timeout-minutes: 30 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: install depends + run: | + sudo apt-get update + sudo apt-get install g++-multilib lcov + - name: Cache boost + id: cache-boost + uses: actions/cache@v1 + with: + path: usr + key: ${{ runner.os }}-boost-20200107 + - name: Build boost + if: steps.cache-boost.outputs.cache-hit != 'true' + run: ./.github/depends/boost.sh -b both -t gcc + - name: Compile tests + run: | + # install gtest + BASE=`pwd` + wget https://github.com/google/googletest/archive/release-1.7.0.zip -O googletest-release-1.7.0.zip + unzip -q googletest-release-1.7.0.zip + cd googletest-release-1.7.0 + g++ -m64 src/gtest-all.cc -I. -Iinclude -c -fPIC + g++ -m64 src/gtest_main.cc -I. -Iinclude -c -fPIC + ar -rv libgtest.a gtest-all.o + ar -rv libgtest_main.a gtest_main.o + mkdir -p ${BASE}/usr/include + cp -r include/gtest ${BASE}/usr/include + mkdir -p ${BASE}/usr/lib + mv *.a ${BASE}/usr/lib + cd .. + + mkdir build && cd build + CMAKE_LIBRARY_PATH="${BASE}/build" GTEST_ROOT="${BASE}/usr" CMAKE_PREFIX_PATH="${BASE}/usr/gcc/lib64/cmake" cmake -DMSGPACK_CXX17=ON -DMSGPACK_32BIT=OFF -DMSGPACK_BOOST=ON -DBUILD_SHARED_LIBS=ON -DMSGPACK_CHAR_SIGN=signed -DMSGPACK_USE_X3_PARSE=ON -DMSGPACK_ENABLE_CXX=ON -DMSGPACK_BUILD_EXAMPLES=ON -DMSGPACK_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DMSGPACK_GEN_COVERAGE=ON .. + make -j4 + make test + - name: Upload coverage to Codecov + working-directory: build + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + run: | + wget https://codecov.io/bash -O codecov + chmod +x codecov + ./codecov -t $CODECOV_TOKEN -B $GITHUB_REF -s . diff --git a/CMakeLists.txt b/CMakeLists.txt index d66a5112..d4c1b4d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ STRING (REGEX MATCH "#define MSGPACK_VERSION_REVISION *([0-9a-zA-Z_]*)" NULL_OUT SET (VERSION_REVISION ${CMAKE_MATCH_1}) SET (VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}) +LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/") SET (prefix ${CMAKE_INSTALL_PREFIX}) SET (exec_prefix "\${prefix}") SET (libdir "\${exec_prefix}/lib") @@ -152,6 +153,7 @@ FIND_PACKAGE (ZLIB) FIND_PACKAGE (Threads) IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND AND NOT "${MSGPACK_FUZZ_REGRESSION}" STREQUAL "ON") OPTION (MSGPACK_BUILD_TESTS "Build msgpack tests." ON) + OPTION (MSGPACK_GEN_COVERAGE "Enable running gcov to get a test coverage report." OFF) ENDIF () IF (DEFINED BUILD_SHARED_LIBS) @@ -277,6 +279,21 @@ IF ("${MSGPACK_FUZZ_REGRESSION}" STREQUAL "ON" AND "${CMAKE_CXX_COMPILER_ID}" ST SET (MSGPACK_BUILD_EXAMPLES OFF) ENDIF () +IF (MSGPACK_GEN_COVERAGE) + IF (NOT MSGPACK_BUILD_TESTS) + MESSAGE(FATAL_ERROR "Coverage requires -DMSGPACK_BUILD_TESTS=ON") + ENDIF () + STRING(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_CMAKE_BUILD_TYPE) + IF (NOT "${UPPER_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG") + MESSAGE(FATAL_ERROR "Coverage requires -DCMAKE_BUILD_TYPE=Debug") + ENDIF () + + INCLUDE(CodeCoverage) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_FLAGS}") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS}") + + SETUP_TARGET_FOR_COVERAGE(coverage make coverage test) +ENDIF () IF (MSGPACK_BUILD_TESTS) ENABLE_TESTING () diff --git a/README.md b/README.md index 1a1ed2cf..7fb6c33d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ =================== Version 3.2.1 [![Build Status](https://travis-ci.org/msgpack/msgpack-c.svg?branch=master)](https://travis-ci.org/msgpack/msgpack-c) [![Build status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/master) +[![codecov](https://codecov.io/gh/msgpack/msgpack-c/branch/master/graph/badge.svg)](https://codecov.io/gh/msgpack/msgpack-c) It's like JSON but smaller and faster. diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake new file mode 100644 index 00000000..dcc7577a --- /dev/null +++ b/cmake/CodeCoverage.cmake @@ -0,0 +1,55 @@ +# Check prereqs +FIND_PROGRAM(GCOV_PATH gcov) +FIND_PROGRAM(LCOV_PATH lcov) +FIND_PROGRAM(GENHTML_PATH genhtml) + +IF(NOT GCOV_PATH) + MESSAGE(FATAL_ERROR "gcov not found! Aborting...") +ENDIF() + +IF(NOT CMAKE_COMPILER_IS_GNUCC) + # Clang version 3.0.0 and greater now supports gcov as well. + MESSAGE(STATUS "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.") + IF(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") + MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") + ENDIF() +ENDIF() + +SET(COVERAGE_FLAGS "-g -O0 --coverage") + +FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname) + + IF(NOT LCOV_PATH) + MESSAGE(FATAL_ERROR "lcov not found! Aborting...") + ENDIF() + + IF(NOT GENHTML_PATH) + MESSAGE(FATAL_ERROR "genhtml not found! Aborting...") + ENDIF() + + # Setup target + ADD_CUSTOM_TARGET(${_targetname} + + # Cleanup lcov + ${LCOV_PATH} --directory . --zerocounters + + # Run tests + COMMAND ${_testrunner} ${ARGV3} + + # Capturing lcov counters and generating report + COMMAND ${LCOV_PATH} --directory . --capture --output-file ${_outputname}.info --base-directory ${CMAKE_SOURCE_DIR} --no-external --quiet + COMMAND ${LCOV_PATH} --remove ${_outputname}.info '*/test/*' '*/fuzz/*' --output-file ${_outputname}.info.cleaned --quiet + COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info.cleaned --prefix ${CMAKE_SOURCE_DIR} + # COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned + + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." + ) + + # Show info where to find the report + ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD + COMMAND ; + COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report." + ) + +ENDFUNCTION()