2017-08-26 02:19:58 +08:00
|
|
|
option(JSON_Sanitizer "Build test suite with Clang sanitizer" OFF)
|
|
|
|
option(JSON_Valgrind "Execute test suite with Valgrind" OFF)
|
2017-08-26 03:29:27 +08:00
|
|
|
option(JSON_NoExceptions "Build test suite without exceptions" OFF)
|
2017-10-05 04:18:21 +08:00
|
|
|
option(JSON_Coverage "Build test suite with coverage information" OFF)
|
2017-08-26 02:12:21 +08:00
|
|
|
|
|
|
|
if(JSON_Sanitizer)
|
2017-08-26 02:19:58 +08:00
|
|
|
message(STATUS "Building test suite with Clang sanitizer")
|
2017-08-26 02:12:21 +08:00
|
|
|
if(NOT MSVC)
|
.travis/cmake: Rework clang sanitizer invocation
- Switch to clang-7
- Adapt PATH so that llvm-symbolizer can be found for useful stacktraces
- Adapt compile flags
"-O0" ensures much faster compile times
"-fno-sanitize-recover=all
-fsanitize-recover=unsigned-integer-overflow" this fails the build on
all issues except unsigned integer overflows. Not failing in this case
is required in combination with the sanitizer suppression file as only
recoverable errors can be suppressed.
The UBSAN suppression file ignores errors from stl_bvector.h (which
holds std::vector<bool>).
Clang reports that error as
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20 in
Start 34: test-deserialization_all
28/88 Test #71: test-testsuites_default .............***Failed 0.32 sec
/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
#0 0x628f72 in std::_Bit_iterator_base::_M_bump_down() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20
#1 0x628d16 in std::_Bit_iterator::operator--() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:251:7
#2 0x634aac in std::vector<bool, std::allocator<bool> >::pop_back() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:1010:7
#3 0x61eff0 in bool nlohmann::detail::parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::sax_parse_internal<nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > >(nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >*) /home/firma/devel/json/include/nlohmann/detail/input/parser.hpp:439:28
#4 0x604864 in nlohmann::detail::parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::parse(bool, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer>&) /home/firma/devel/json/include/nlohmann/detail/input/parser.hpp:116:13
#5 0x5f8079 in nlohmann::operator>>(std::istream&, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer>&) /home/firma/devel/json/include/nlohmann/json.hpp:6356:42
#6 0x5e1d92 in _DOCTEST_ANON_FUNC_21() /home/firma/devel/json/test/src/unit-testsuites.cpp:343:9
#7 0x7207fe in doctest::Context::run() /home/firma/devel/json/test/thirdparty/doctest/doctest.h:5938:21
#8 0x72681a in main /home/firma/devel/json/test/thirdparty/doctest/doctest.h:6016:71
#9 0x7f75d22362e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
#10 0x4c28b9 in _start (/home/firma/devel/json/build/test/test-testsuites+0x4c28b9)
The pop_back() in parser.hpp
assert(not states.empty());
-> states.pop_back();
triggers the UBSAN report. But the assertion above ensure that we only
call pop_back() on an non-empty vector, therefore this is a STL library
bug and thus must be ignored for us.
2019-08-27 20:22:19 +08:00
|
|
|
set(CMAKE_CXX_FLAGS "-g -O0 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow")
|
2017-08-26 02:12:21 +08:00
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
|
|
|
|
if(JSON_Valgrind)
|
|
|
|
find_program(CMAKE_MEMORYCHECK_COMMAND valgrind)
|
2017-08-26 02:19:58 +08:00
|
|
|
message(STATUS "Executing test suite with Valgrind (${CMAKE_MEMORYCHECK_COMMAND})")
|
2018-03-29 23:19:21 +08:00
|
|
|
set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1 --leak-check=full")
|
2017-08-26 02:12:21 +08:00
|
|
|
separate_arguments(memcheck_command)
|
|
|
|
endif()
|
|
|
|
|
2017-08-26 03:29:27 +08:00
|
|
|
if(JSON_NoExceptions)
|
|
|
|
message(STATUS "Building test suite without exceptions")
|
|
|
|
if(NOT MSVC)
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSON_NOEXCEPTION")
|
|
|
|
endif()
|
2019-01-14 00:41:21 +08:00
|
|
|
set(DOCTEST_TEST_FILTER --no-throw)
|
2017-08-26 03:29:27 +08:00
|
|
|
endif()
|
|
|
|
|
2017-10-05 04:18:21 +08:00
|
|
|
if(JSON_Coverage)
|
|
|
|
message(STATUS "Building test suite with coverage information")
|
2019-04-06 15:02:17 +08:00
|
|
|
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|
|
|
message(FATAL_ERROR "JSON_Coverage requires GCC.")
|
|
|
|
endif()
|
2017-10-05 04:18:21 +08:00
|
|
|
|
|
|
|
# enable profiling
|
|
|
|
set(CMAKE_CXX_FLAGS "--coverage -g -O0 -fprofile-arcs -ftest-coverage")
|
|
|
|
|
|
|
|
# from https://github.com/RWTH-HPC/CMake-codecov/blob/master/cmake/FindGcov.cmake
|
2019-04-04 15:50:27 +08:00
|
|
|
get_filename_component(COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
|
|
|
|
string(REGEX MATCH "^[0-9]+" GCC_VERSION "${CMAKE_CXX_COMPILER_VERSION}")
|
|
|
|
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov HINTS ${COMPILER_PATH})
|
2017-10-05 04:18:21 +08:00
|
|
|
|
2018-02-10 04:30:15 +08:00
|
|
|
# collect all source files from the chosen include dir
|
|
|
|
file(GLOB_RECURSE SOURCE_FILES ${NLOHMANN_JSON_INCLUDE_BUILD_DIR}*.hpp)
|
|
|
|
|
2017-10-05 04:18:21 +08:00
|
|
|
# add target to collect coverage information and generate HTML file
|
2017-10-06 01:08:15 +08:00
|
|
|
# (filter script from https://stackoverflow.com/a/43726240/266378)
|
2017-10-05 04:18:21 +08:00
|
|
|
add_custom_target(lcov_html
|
2019-04-03 23:28:47 +08:00
|
|
|
COMMAND lcov --directory . --capture --output-file json.info --rc lcov_branch_coverage=1
|
2019-04-06 15:02:17 +08:00
|
|
|
COMMAND lcov -e json.info ${SOURCE_FILES} --output-file json.info.filtered --gcov-tool ${GCOV_BIN} --rc lcov_branch_coverage=1
|
2017-10-06 01:08:15 +08:00
|
|
|
COMMAND ${CMAKE_SOURCE_DIR}/test/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept
|
2019-03-30 16:12:32 +08:00
|
|
|
COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept
|
|
|
|
COMMENT "Generating HTML report test/html/index.html"
|
|
|
|
)
|
|
|
|
|
2019-04-06 15:02:17 +08:00
|
|
|
add_custom_target(fastcov_html
|
2019-04-06 06:24:19 +08:00
|
|
|
COMMAND ${CMAKE_SOURCE_DIR}/test/thirdparty/fastcov/fastcov.py --branch-coverage --lcov -o json.info --gcov ${GCOV_BIN} --compiler-directory ${CMAKE_BINARY_DIR} --source-files ${SOURCE_FILES}
|
2019-04-06 15:02:17 +08:00
|
|
|
COMMAND ${CMAKE_SOURCE_DIR}/test/thirdparty/imapdl/filterbr.py json.info > json.info.noexcept
|
|
|
|
COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.noexcept
|
2017-10-05 04:18:21 +08:00
|
|
|
COMMENT "Generating HTML report test/html/index.html"
|
|
|
|
)
|
|
|
|
endif()
|
|
|
|
|
2017-08-26 00:06:22 +08:00
|
|
|
#############################################################################
|
2019-01-14 00:41:21 +08:00
|
|
|
# doctest library with the main function to speed up build
|
2017-08-26 00:06:22 +08:00
|
|
|
#############################################################################
|
|
|
|
|
2019-01-14 00:41:21 +08:00
|
|
|
add_library(doctest_main OBJECT
|
2017-02-12 19:46:54 +08:00
|
|
|
"src/unit.cpp"
|
|
|
|
)
|
2019-01-14 00:41:21 +08:00
|
|
|
set_target_properties(doctest_main PROPERTIES
|
2017-08-26 00:06:22 +08:00
|
|
|
COMPILE_DEFINITIONS "$<$<CXX_COMPILER_ID:MSVC>:_SCL_SECURE_NO_WARNINGS>"
|
|
|
|
COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>"
|
2017-02-12 19:46:54 +08:00
|
|
|
)
|
2019-08-27 20:22:01 +08:00
|
|
|
if (${CMAKE_VERSION} VERSION_LESS "3.8.0")
|
2019-03-26 04:04:37 +08:00
|
|
|
target_compile_features(doctest_main PUBLIC cxx_range_for)
|
2019-01-16 21:21:49 +08:00
|
|
|
else()
|
2019-03-26 04:04:37 +08:00
|
|
|
target_compile_features(doctest_main PUBLIC cxx_std_11)
|
2019-01-16 21:21:49 +08:00
|
|
|
endif()
|
2019-01-14 00:41:21 +08:00
|
|
|
target_include_directories(doctest_main PRIVATE "thirdparty/doctest")
|
2017-02-12 19:46:54 +08:00
|
|
|
|
2017-10-16 16:02:48 +08:00
|
|
|
# https://stackoverflow.com/questions/2368811/how-to-set-warning-level-in-cmake
|
|
|
|
if(MSVC)
|
|
|
|
# Force to always compile with W4
|
|
|
|
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
|
|
|
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
|
|
else()
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
|
|
|
endif()
|
|
|
|
|
2017-10-18 13:53:35 +08:00
|
|
|
# Disable warning C4389: '==': signed/unsigned mismatch
|
|
|
|
# Disable warning C4309: 'static_cast': truncation of constant value
|
|
|
|
# Disable warning C4566: character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252)
|
|
|
|
# Disable warning C4996: 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer>::operator <<': was declared deprecated
|
2017-10-17 14:23:55 +08:00
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4389 /wd4309 /wd4566 /wd4996")
|
2019-08-27 20:22:01 +08:00
|
|
|
|
2018-06-29 12:04:41 +08:00
|
|
|
# https://github.com/nlohmann/json/issues/1114
|
|
|
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
|
2017-10-16 16:02:48 +08:00
|
|
|
endif()
|
|
|
|
|
2017-08-26 00:06:22 +08:00
|
|
|
#############################################################################
|
|
|
|
# one executable for each unit test file
|
|
|
|
#############################################################################
|
2016-05-11 08:25:54 +08:00
|
|
|
|
2019-10-08 03:13:09 +08:00
|
|
|
set(files
|
|
|
|
src/unit-algorithms.cpp
|
|
|
|
src/unit-allocator.cpp
|
|
|
|
src/unit-alt-string.cpp
|
|
|
|
src/unit-bson.cpp
|
|
|
|
src/unit-capacity.cpp
|
|
|
|
src/unit-cbor.cpp
|
|
|
|
src/unit-class_const_iterator.cpp
|
|
|
|
src/unit-class_iterator.cpp
|
|
|
|
src/unit-class_lexer.cpp
|
|
|
|
src/unit-class_parser.cpp
|
|
|
|
src/unit-comparison.cpp
|
|
|
|
src/unit-concepts.cpp
|
|
|
|
src/unit-constructor1.cpp
|
|
|
|
src/unit-constructor2.cpp
|
|
|
|
src/unit-convenience.cpp
|
|
|
|
src/unit-conversions.cpp
|
|
|
|
src/unit-deserialization.cpp
|
|
|
|
src/unit-element_access1.cpp
|
|
|
|
src/unit-element_access2.cpp
|
|
|
|
src/unit-inspection.cpp
|
|
|
|
src/unit-items.cpp
|
|
|
|
src/unit-iterators1.cpp
|
|
|
|
src/unit-iterators2.cpp
|
|
|
|
src/unit-json_patch.cpp
|
|
|
|
src/unit-json_pointer.cpp
|
2019-11-10 02:12:39 +08:00
|
|
|
src/unit-large_json.cpp
|
2019-10-08 03:13:09 +08:00
|
|
|
src/unit-merge_patch.cpp
|
|
|
|
src/unit-meta.cpp
|
|
|
|
src/unit-modifiers.cpp
|
|
|
|
src/unit-msgpack.cpp
|
|
|
|
src/unit-noexcept.cpp
|
|
|
|
src/unit-pointer_access.cpp
|
|
|
|
src/unit-readme.cpp
|
|
|
|
src/unit-reference_access.cpp
|
|
|
|
src/unit-regression.cpp
|
|
|
|
src/unit-serialization.cpp
|
|
|
|
src/unit-testsuites.cpp
|
|
|
|
src/unit-to_chars.cpp
|
|
|
|
src/unit-ubjson.cpp
|
|
|
|
src/unit-udt.cpp
|
|
|
|
src/unit-unicode.cpp
|
|
|
|
src/unit-wstring.cpp)
|
|
|
|
|
2017-08-26 00:06:22 +08:00
|
|
|
foreach(file ${files})
|
|
|
|
get_filename_component(file_basename ${file} NAME_WE)
|
|
|
|
string(REGEX REPLACE "unit-([^$]+)" "test-\\1" testcase ${file_basename})
|
2016-05-11 08:25:54 +08:00
|
|
|
|
2019-01-14 00:41:21 +08:00
|
|
|
add_executable(${testcase} $<TARGET_OBJECTS:doctest_main> ${file})
|
2018-10-01 22:34:23 +08:00
|
|
|
target_compile_definitions(${testcase} PRIVATE
|
2019-01-16 04:58:12 +08:00
|
|
|
DOCTEST_CONFIG_SUPER_FAST_ASSERTS
|
2018-10-01 22:34:23 +08:00
|
|
|
)
|
|
|
|
target_compile_options(${testcase} PRIVATE
|
|
|
|
$<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
|
|
|
|
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
|
|
|
|
$<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
|
|
|
|
)
|
|
|
|
target_include_directories(${testcase} PRIVATE
|
2019-01-14 00:41:21 +08:00
|
|
|
thirdparty/doctest
|
2018-10-01 22:34:23 +08:00
|
|
|
thirdparty/fifo_map
|
2017-02-12 19:46:54 +08:00
|
|
|
)
|
2017-11-26 17:29:51 +08:00
|
|
|
target_link_libraries(${testcase} ${NLOHMANN_JSON_TARGET_NAME})
|
2017-08-26 00:06:22 +08:00
|
|
|
|
|
|
|
add_test(NAME "${testcase}_default"
|
2019-01-14 00:41:21 +08:00
|
|
|
COMMAND ${testcase} ${DOCTEST_TEST_FILTER}
|
2017-08-26 00:06:22 +08:00
|
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
2017-02-12 19:46:54 +08:00
|
|
|
)
|
2017-08-26 00:06:22 +08:00
|
|
|
set_tests_properties("${testcase}_default" PROPERTIES LABELS "default")
|
2017-02-12 19:46:54 +08:00
|
|
|
|
2017-08-26 00:06:22 +08:00
|
|
|
add_test(NAME "${testcase}_all"
|
2019-01-14 00:41:21 +08:00
|
|
|
COMMAND ${testcase} ${DOCTEST_TEST_FILTER} --no-skip
|
2017-08-26 00:06:22 +08:00
|
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
|
|
)
|
|
|
|
set_tests_properties("${testcase}_all" PROPERTIES LABELS "all")
|
2017-08-26 02:12:21 +08:00
|
|
|
|
|
|
|
if(JSON_Valgrind)
|
|
|
|
add_test(NAME "${testcase}_valgrind"
|
2019-01-14 00:41:21 +08:00
|
|
|
COMMAND ${memcheck_command} ${CMAKE_CURRENT_BINARY_DIR}/${testcase} ${DOCTEST_TEST_FILTER}
|
2017-08-26 02:12:21 +08:00
|
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
|
|
)
|
|
|
|
set_tests_properties("${testcase}_valgrind" PROPERTIES LABELS "valgrind")
|
|
|
|
endif()
|
2017-08-26 00:06:22 +08:00
|
|
|
endforeach()
|
2018-09-26 22:46:34 +08:00
|
|
|
|
|
|
|
#############################################################################
|
|
|
|
# Test the generated build configs
|
|
|
|
#############################################################################
|
|
|
|
add_subdirectory(cmake_import)
|
|
|
|
add_subdirectory(cmake_import_minver)
|
|
|
|
add_subdirectory(cmake_add_subdirectory)
|