summaryrefslogtreecommitdiffstats
path: root/src/civetweb/test/CMakeLists.txt
blob: e6a360c306b622de82f41da01825a3c4808b5f96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# Determine if we should print to the output
if (CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT)
  set(THIRD_PARTY_LOGGING 0)
else()
  set(THIRD_PARTY_LOGGING 1)
endif()

# We use the check unit testing framework for our C unit tests
include(ExternalProject)
#if(NOT WIN32)
#  # Apply the patch to check to fix CMake building on OS X
#  set(CHECK_PATCH_COMMAND patch
#     ${CIVETWEB_THIRD_PARTY_DIR}/src/check-unit-test-framework/CMakeLists.txt
#     ${CMAKE_SOURCE_DIR}/cmake/check/c82fe8888aacfe784476112edd3878256d2e30bc.patch
#   )
#else()
#  set(CHECK_PATCH_COMMAND "")
#endif()
ExternalProject_Add(check-unit-test-framework
  DEPENDS c-library

## Use an official, released check version:
#  URL "https://codeload.github.com/libcheck/check/zip/${CIVETWEB_CHECK_VERSION}"
#  DOWNLOAD_NAME "${CIVETWEB_CHECK_VERSION}.zip"
#  URL_MD5 ${CIVETWEB_CHECK_MD5_HASH}

## Use a civetweb specific patched version
URL "https://github.com/civetweb/check/archive/master.zip"
DOWNLOAD_NAME "master.zip"
# <Edit this file to flush AppVeyor build cache and force reloading check>

  PREFIX "${CIVETWEB_THIRD_PARTY_DIR}"
  BUILD_IN_SOURCE 1
  PATCH_COMMAND ${CHECK_PATCH_COMMAND}
  CMAKE_ARGS
    "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
    "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
    "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
  LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
  LOG_UPDATE ${THIRD_PARTY_LOGGING}
  LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
  LOG_BUILD ${THIRD_PARTY_LOGGING}
  LOG_TEST ${THIRD_PARTY_LOGGING}
  LOG_INSTALL ${THIRD_PARTY_LOGGING})

ExternalProject_Get_Property(check-unit-test-framework INSTALL_DIR)
set(CHECK_INSTALL_DIR ${INSTALL_DIR})
unset(INSTALL_DIR)
link_directories("${CHECK_INSTALL_DIR}/lib")
include_directories("${CHECK_INSTALL_DIR}/include")
if ((WIN32 AND MINGW) OR APPLE)
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcheck.a")
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcompat.a")
elseif (WIN32)
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/check.lib")
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/compat.lib")
else()
  set(CHECK_LIBRARIES "${CHECK_INSTALL_DIR}/lib/libcheck.a")
endif()
find_package(LibM)
if (LIBM_FOUND)
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBM::LIBM")
endif()
find_package(LibRt)
if (LIBRT_FOUND)
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBRT::LIBRT")
endif()
find_package(LibSubunit)
if (LIBSUBUNIT_FOUND)
  set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBSUBUNIT::LIBSUBUNIT")
endif()

# Build the C unit tests
add_library(shared-c-unit-tests STATIC shared.c)
target_include_directories(
  shared-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)

add_library(public-func-c-unit-tests STATIC public_func.c)
if (BUILD_SHARED_LIBS)
  target_compile_definitions(public-func-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS)
endif()
target_include_directories(
  public-func-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(public-func-c-unit-tests c-library ${CHECK_LIBRARIES})
add_dependencies(public-func-c-unit-tests check-unit-test-framework)

add_library(public-server-c-unit-tests STATIC public_server.c)
if (BUILD_SHARED_LIBS)
  target_compile_definitions(public-server-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS)
endif()
target_include_directories(
  public-server-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(public-server-c-unit-tests c-library ${CHECK_LIBRARIES})
add_dependencies(public-server-c-unit-tests check-unit-test-framework)

add_library(private-c-unit-tests STATIC private.c)
target_include_directories(
  private-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(private-c-unit-tests ${CHECK_LIBRARIES})
add_dependencies(private-c-unit-tests check-unit-test-framework)

add_library(timer-c-unit-tests STATIC timertest.c)
target_include_directories(
  timer-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(timer-c-unit-tests ${CHECK_LIBRARIES})
add_dependencies(timer-c-unit-tests check-unit-test-framework)

add_library(exe-c-unit-tests STATIC private_exe.c)
if (BUILD_SHARED_LIBS)
  target_compile_definitions(exe-c-unit-tests PRIVATE)
endif()
target_include_directories(
  exe-c-unit-tests PUBLIC
  ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(exe-c-unit-tests c-library ${CHECK_LIBRARIES})
add_dependencies(exe-c-unit-tests check-unit-test-framework)

add_executable(main-c-unit-test main.c)
target_link_libraries(main-c-unit-test
  shared-c-unit-tests
  public-func-c-unit-tests
  public-server-c-unit-tests
  private-c-unit-tests
  timer-c-unit-tests
  exe-c-unit-tests
  ${CHECK_LIBRARIES})
add_dependencies(main-c-unit-test check-unit-test-framework)

# Add a check command that builds the dependent test program
add_custom_target(check
  COMMAND ${CMAKE_CTEST_COMMAND}
  DEPENDS main-c-unit-test)

# A macro for adding tests
macro(civetweb_add_test suite test_case)
  set(test "test-${suite}-${test_case}")
  string(TOLOWER "${test}" test)
  string(REGEX REPLACE "[^-A-Za-z0-9]" "-" test "${test}")
  add_test(
    NAME ${test}
    COMMAND main-c-unit-test "--test-dir=${CMAKE_CURRENT_SOURCE_DIR}" "--suite=${suite}" "--test-case=${test_case}")
  if (WIN32)
    string(REPLACE ";" "\\;" test_path "$ENV{PATH}")
    set_tests_properties(${test} PROPERTIES
      ENVIRONMENT "PATH=${test_path}\\;$<TARGET_FILE_DIR:c-library>")
  endif()
endmacro(civetweb_add_test)


# Tests of private functions
civetweb_add_test(Private "HTTP Message")
civetweb_add_test(Private "HTTP Keep Alive")
civetweb_add_test(Private "URL Parsing 1")
civetweb_add_test(Private "URL Parsing 2")
civetweb_add_test(Private "URL Parsing 3")
civetweb_add_test(Private "Internal Parsing 1")
civetweb_add_test(Private "Internal Parsing 2")
civetweb_add_test(Private "Internal Parsing 3")
civetweb_add_test(Private "Internal Parsing 4")
civetweb_add_test(Private "Internal Parsing 5")
civetweb_add_test(Private "Internal Parsing 6")
civetweb_add_test(Private "Encode Decode")
civetweb_add_test(Private "Mask Data")
civetweb_add_test(Private "Date Parsing")
civetweb_add_test(Private "SHA1")

# Public API function tests
civetweb_add_test(PublicFunc "Version")
civetweb_add_test(PublicFunc "Options")
civetweb_add_test(PublicFunc "MIME types")
civetweb_add_test(PublicFunc "strcasecmp")
civetweb_add_test(PublicFunc "URL encoding decoding")
civetweb_add_test(PublicFunc "Cookies and variables")
civetweb_add_test(PublicFunc "MD5")
civetweb_add_test(PublicFunc "Aux functions")

# Public API server tests
civetweb_add_test(PublicServer "Check test environment")
civetweb_add_test(PublicServer "Init library")
civetweb_add_test(PublicServer "Start threads")
civetweb_add_test(PublicServer "Minimal Server")
civetweb_add_test(PublicServer "Minimal Client")
civetweb_add_test(PublicServer "Start Stop HTTP Server")
civetweb_add_test(PublicServer "Start Stop HTTP Server IPv6")
civetweb_add_test(PublicServer "Start Stop HTTPS Server")
civetweb_add_test(PublicServer "TLS Server Client")
civetweb_add_test(PublicServer "Server Requests")
civetweb_add_test(PublicServer "Store Body")
civetweb_add_test(PublicServer "Handle Form")
civetweb_add_test(PublicServer "HTTP Authentication")
civetweb_add_test(PublicServer "HTTP Keep Alive")
civetweb_add_test(PublicServer "Error handling")
civetweb_add_test(PublicServer "Limit speed")
civetweb_add_test(PublicServer "Large file")
civetweb_add_test(PublicServer "File in memory")

# Timer tests
civetweb_add_test(Timer "Timer Single Shot")
civetweb_add_test(Timer "Timer Periodic")
civetweb_add_test(Timer "Timer Mixed")

# Tests with main.c
#civetweb_add_test(EXE "Helper funcs")


# Add the coverage command(s)
if (${CMAKE_BUILD_TYPE} MATCHES "[Cc]overage")
  find_program(GCOV_EXECUTABLE gcov)
  find_program(LCOV_EXECUTABLE lcov)
  find_program(GENHTML_EXECUTABLE genhtml)
  find_program(CTEST_EXECUTABLE ctest)
  if (GCOV_EXECUTABLE AND LCOV_EXECUTABLE AND GENHTML_EXECUTABLE AND CTEST_EXECUTABLE AND HAVE_C_FLAG_COVERAGE)
    add_custom_command(
      OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html
      COMMAND ${LCOV_EXECUTABLE} -q -z -d .
      COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i
      COMMAND ${CTEST_EXECUTABLE} --force-new-ctest-process
      COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov
      COMMAND ${LCOV_EXECUTABLE} -q -a before.lcov -a after.lcov --output-file final.lcov
      COMMAND ${LCOV_EXECUTABLE} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov
      COMMAND ${GENHTML_EXECUTABLE} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_SOURCE_DIR}" -t benchmark
      DEPENDS main-c-unit-test
      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
      COMMENT "Running LCOV"
    )
    add_custom_target(coverage
      DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html
      COMMENT "LCOV report at lcov/index.html"
    )
    message(STATUS "Coverage command added")
  else()
    if (HAVE_C_FLAG_COVERAGE)
      set(C_FLAG_COVERAGE_MESSAGE supported)
    else()
      set(C_FLAG_COVERAGE_MESSAGE unavailable)
    endif()
    message(WARNING
      "Coverage command not available:\n"
      "  gcov: ${GCOV_EXECUTABLE}\n"
      "  lcov: ${LCOV_EXECUTABLE}\n"
      "  genhtml: ${GENHTML_EXECUTABLE}\n"
      "  ctest: ${CTEST_EXECUTABLE}\n"
      "  --coverage flag: ${C_FLAG_COVERAGE_MESSAGE}")
  endif()
endif()