1# Determine if we should print to the output 2if (CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT) 3 set(THIRD_PARTY_LOGGING 0) 4else() 5 set(THIRD_PARTY_LOGGING 1) 6endif() 7 8# We use the check unit testing framework for our C unit tests 9include(ExternalProject) 10#if(NOT WIN32) 11# # Apply the patch to check to fix CMake building on OS X 12# set(CHECK_PATCH_COMMAND patch 13# ${CIVETWEB_THIRD_PARTY_DIR}/src/check-unit-test-framework/CMakeLists.txt 14# ${CMAKE_SOURCE_DIR}/cmake/check/c82fe8888aacfe784476112edd3878256d2e30bc.patch 15# ) 16#else() 17# set(CHECK_PATCH_COMMAND "") 18#endif() 19ExternalProject_Add(check-unit-test-framework 20 DEPENDS civetweb-c-library 21 22## Use an official, released check version: 23# URL "https://codeload.github.com/libcheck/check/zip/${CIVETWEB_CHECK_VERSION}" 24# DOWNLOAD_NAME "${CIVETWEB_CHECK_VERSION}.zip" 25# URL_MD5 ${CIVETWEB_CHECK_MD5_HASH} 26 27## Use a civetweb specific patched version 28URL "https://github.com/civetweb/check/archive/master.zip" 29DOWNLOAD_NAME "master.zip" 30# <Edit this file to flush AppVeyor build cache and force reloading check> 31 32 PREFIX "${CIVETWEB_THIRD_PARTY_DIR}" 33 BUILD_IN_SOURCE 1 34 PATCH_COMMAND ${CHECK_PATCH_COMMAND} 35 CMAKE_ARGS 36 "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" 37 "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" 38 "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>" 39 LOG_DOWNLOAD ${THIRD_PARTY_LOGGING} 40 LOG_UPDATE ${THIRD_PARTY_LOGGING} 41 LOG_CONFIGURE ${THIRD_PARTY_LOGGING} 42 LOG_BUILD ${THIRD_PARTY_LOGGING} 43 LOG_TEST ${THIRD_PARTY_LOGGING} 44 LOG_INSTALL ${THIRD_PARTY_LOGGING}) 45 46ExternalProject_Get_Property(check-unit-test-framework INSTALL_DIR) 47set(CHECK_INSTALL_DIR ${INSTALL_DIR}) 48unset(INSTALL_DIR) 49link_directories("${CHECK_INSTALL_DIR}/lib") 50include_directories("${CHECK_INSTALL_DIR}/include") 51if ((WIN32 AND MINGW) OR APPLE) 52 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcheck.a") 53 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcompat.a") 54elseif (WIN32) 55 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/check.lib") 56 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/compat.lib") 57else() 58 set(CHECK_LIBRARIES "${CHECK_INSTALL_DIR}/lib/libcheck.a") 59endif() 60find_package(LibM) 61if (LIBM_FOUND) 62 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBM::LIBM") 63endif() 64find_package(LibRt) 65if (LIBRT_FOUND) 66 set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBRT::LIBRT") 67endif() 68 69# Build the C unit tests 70add_library(shared-c-unit-tests STATIC shared.c) 71target_include_directories( 72 shared-c-unit-tests PUBLIC 73 ${PROJECT_SOURCE_DIR}/include) 74 75add_library(public-func-c-unit-tests STATIC public_func.c) 76if (BUILD_SHARED_LIBS) 77 target_compile_definitions(public-func-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS) 78endif() 79target_include_directories( 80 public-func-c-unit-tests PUBLIC 81 ${PROJECT_SOURCE_DIR}/include) 82target_link_libraries(public-func-c-unit-tests civetweb-c-library ${CHECK_LIBRARIES}) 83add_dependencies(public-func-c-unit-tests check-unit-test-framework) 84 85add_library(public-server-c-unit-tests STATIC public_server.c) 86if (BUILD_SHARED_LIBS) 87 target_compile_definitions(public-server-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS) 88endif() 89target_include_directories( 90 public-server-c-unit-tests PUBLIC 91 ${PROJECT_SOURCE_DIR}/include) 92target_link_libraries(public-server-c-unit-tests civetweb-c-library ${CHECK_LIBRARIES}) 93add_dependencies(public-server-c-unit-tests check-unit-test-framework) 94 95add_library(private-c-unit-tests STATIC private.c) 96target_include_directories( 97 private-c-unit-tests PUBLIC 98 ${PROJECT_SOURCE_DIR}/include) 99target_link_libraries(private-c-unit-tests ${CHECK_LIBRARIES}) 100add_dependencies(private-c-unit-tests check-unit-test-framework) 101 102add_library(timer-c-unit-tests STATIC timertest.c) 103target_include_directories( 104 timer-c-unit-tests PUBLIC 105 ${PROJECT_SOURCE_DIR}/include) 106target_link_libraries(timer-c-unit-tests ${CHECK_LIBRARIES}) 107add_dependencies(timer-c-unit-tests check-unit-test-framework) 108 109add_library(exe-c-unit-tests STATIC private_exe.c) 110if (BUILD_SHARED_LIBS) 111 target_compile_definitions(exe-c-unit-tests PRIVATE) 112endif() 113target_include_directories( 114 exe-c-unit-tests PUBLIC 115 ${PROJECT_SOURCE_DIR}/include) 116target_link_libraries(exe-c-unit-tests civetweb-c-library ${CHECK_LIBRARIES}) 117add_dependencies(exe-c-unit-tests check-unit-test-framework) 118 119add_executable(main-c-unit-test main.c) 120target_link_libraries(main-c-unit-test 121 shared-c-unit-tests 122 public-func-c-unit-tests 123 public-server-c-unit-tests 124 private-c-unit-tests 125 timer-c-unit-tests 126 exe-c-unit-tests 127 ${CHECK_LIBRARIES}) 128add_dependencies(main-c-unit-test check-unit-test-framework) 129 130# Add a check command that builds the dependent test program 131add_custom_target(check 132 COMMAND ${CMAKE_CTEST_COMMAND} 133 DEPENDS main-c-unit-test) 134 135# A macro for adding tests 136macro(civetweb_add_test suite test_case) 137 set(test "test-${suite}-${test_case}") 138 string(TOLOWER "${test}" test) 139 string(REGEX REPLACE "[^-A-Za-z0-9]" "-" test "${test}") 140 add_test( 141 NAME ${test} 142 COMMAND main-c-unit-test "--test-dir=${CMAKE_CURRENT_SOURCE_DIR}" "--suite=${suite}" "--test-case=${test_case}") 143 if (WIN32) 144 string(REPLACE ";" "\\;" test_path "$ENV{PATH}") 145 set_tests_properties(${test} PROPERTIES 146 ENVIRONMENT "PATH=${test_path}\\;$<TARGET_FILE_DIR:civetweb-c-library>") 147 endif() 148endmacro(civetweb_add_test) 149 150 151# Tests of private functions 152civetweb_add_test(Private "HTTP Message") 153civetweb_add_test(Private "HTTP Keep Alive") 154civetweb_add_test(Private "URL Parsing 1") 155civetweb_add_test(Private "URL Parsing 2") 156civetweb_add_test(Private "URL Parsing 3") 157civetweb_add_test(Private "Internal Parsing 1") 158civetweb_add_test(Private "Internal Parsing 2") 159civetweb_add_test(Private "Internal Parsing 3") 160civetweb_add_test(Private "Internal Parsing 4") 161civetweb_add_test(Private "Internal Parsing 5") 162civetweb_add_test(Private "Internal Parsing 6") 163civetweb_add_test(Private "Encode Decode") 164civetweb_add_test(Private "Mask Data") 165civetweb_add_test(Private "Date Parsing") 166civetweb_add_test(Private "SHA1") 167civetweb_add_test(Private "Config Options") 168 169# Public API function tests 170civetweb_add_test(PublicFunc "Version") 171civetweb_add_test(PublicFunc "Options") 172civetweb_add_test(PublicFunc "MIME types") 173civetweb_add_test(PublicFunc "strcasecmp") 174civetweb_add_test(PublicFunc "URL encoding decoding") 175civetweb_add_test(PublicFunc "Cookies and variables") 176civetweb_add_test(PublicFunc "MD5") 177civetweb_add_test(PublicFunc "Aux functions") 178 179# Public API server tests 180civetweb_add_test(PublicServer "Check test environment") 181civetweb_add_test(PublicServer "Init library") 182civetweb_add_test(PublicServer "Start threads") 183civetweb_add_test(PublicServer "Minimal HTTP Server") 184civetweb_add_test(PublicServer "Minimal HTTPS Server") 185civetweb_add_test(PublicServer "Minimal HTTP Client") 186civetweb_add_test(PublicServer "Minimal HTTPS Client") 187civetweb_add_test(PublicServer "Start Stop HTTP Server") 188civetweb_add_test(PublicServer "Start Stop HTTP Server IPv6") 189civetweb_add_test(PublicServer "Start Stop HTTPS Server") 190civetweb_add_test(PublicServer "TLS Server Client") 191civetweb_add_test(PublicServer "Server Requests") 192civetweb_add_test(PublicServer "Store Body") 193civetweb_add_test(PublicServer "Handle Form") 194civetweb_add_test(PublicServer "HTTP Authentication") 195civetweb_add_test(PublicServer "HTTP Keep Alive") 196civetweb_add_test(PublicServer "Error handling") 197civetweb_add_test(PublicServer "Error logging") 198civetweb_add_test(PublicServer "Limit speed") 199civetweb_add_test(PublicServer "Large file") 200civetweb_add_test(PublicServer "File in memory") 201 202# Timer tests 203civetweb_add_test(Timer "Timer Single Shot") 204civetweb_add_test(Timer "Timer Periodic") 205civetweb_add_test(Timer "Timer Mixed") 206 207# Tests with main.c 208#civetweb_add_test(EXE "Helper funcs") 209 210 211# Add the coverage command(s) 212if (${CMAKE_BUILD_TYPE} MATCHES "[Cc]overage") 213 find_program(GCOV_EXECUTABLE gcov) 214 find_program(LCOV_EXECUTABLE lcov) 215 find_program(GENHTML_EXECUTABLE genhtml) 216 find_program(CTEST_EXECUTABLE ctest) 217 if (GCOV_EXECUTABLE AND LCOV_EXECUTABLE AND GENHTML_EXECUTABLE AND CTEST_EXECUTABLE AND HAVE_C_FLAG_COVERAGE) 218 add_custom_command( 219 OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html 220 COMMAND ${LCOV_EXECUTABLE} -q -z -d . 221 COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i 222 COMMAND ${CTEST_EXECUTABLE} --force-new-ctest-process 223 COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov 224 COMMAND ${LCOV_EXECUTABLE} -q -a before.lcov -a after.lcov --output-file final.lcov 225 COMMAND ${LCOV_EXECUTABLE} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/unittest/*'" -o final.lcov 226 COMMAND ${GENHTML_EXECUTABLE} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_SOURCE_DIR}" -t benchmark 227 DEPENDS main-c-unit-test 228 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 229 COMMENT "Running LCOV" 230 ) 231 add_custom_target(coverage 232 DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html 233 COMMENT "LCOV report at lcov/index.html" 234 ) 235 message(STATUS "Coverage command added") 236 else() 237 if (HAVE_C_FLAG_COVERAGE) 238 set(C_FLAG_COVERAGE_MESSAGE supported) 239 else() 240 set(C_FLAG_COVERAGE_MESSAGE unavailable) 241 endif() 242 message(WARNING 243 "Coverage command not available:\n" 244 " gcov: ${GCOV_EXECUTABLE}\n" 245 " lcov: ${LCOV_EXECUTABLE}\n" 246 " genhtml: ${GENHTML_EXECUTABLE}\n" 247 " ctest: ${CTEST_EXECUTABLE}\n" 248 " --coverage flag: ${C_FLAG_COVERAGE_MESSAGE}") 249 endif() 250endif() 251