1set(libs
2    ${mbedtls_target}
3)
4
5# Set the project root directory if it's not already defined, as may happen if
6# the tests folder is included directly by a parent project, without including
7# the top level CMakeLists.txt.
8if(NOT DEFINED MBEDTLS_DIR)
9    set(MBEDTLS_DIR ${CMAKE_SOURCE_DIR})
10endif()
11
12if(NOT MBEDTLS_PYTHON_EXECUTABLE)
13    message(FATAL_ERROR "Cannot build test suites without Python 3")
14endif()
15
16# generated .data files will go there
17file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/suites)
18
19# Get base names for generated files (starting at "suites/")
20execute_process(
21    COMMAND
22        ${MBEDTLS_PYTHON_EXECUTABLE}
23        ${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_psa_tests.py
24        --list-for-cmake
25        --directory suites
26    WORKING_DIRECTORY
27        ${CMAKE_CURRENT_SOURCE_DIR}/..
28    OUTPUT_VARIABLE
29        base_generated_data_files)
30
31# Derive generated file paths in the build directory
32set(generated_data_files "")
33foreach(file ${base_generated_data_files})
34    list(APPEND generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/${file})
35endforeach()
36
37if(GEN_FILES)
38    add_custom_command(
39        OUTPUT
40            ${generated_data_files}
41        WORKING_DIRECTORY
42            ${CMAKE_CURRENT_SOURCE_DIR}/..
43        COMMAND
44            ${MBEDTLS_PYTHON_EXECUTABLE}
45            ${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_psa_tests.py
46            --directory ${CMAKE_CURRENT_BINARY_DIR}/suites
47        DEPENDS
48            ${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_psa_tests.py
49            ${CMAKE_CURRENT_SOURCE_DIR}/../include/psa/crypto_config.h
50            ${CMAKE_CURRENT_SOURCE_DIR}/../include/psa/crypto_values.h
51            ${CMAKE_CURRENT_SOURCE_DIR}/../include/psa/crypto_extra.h
52    )
53else()
54    foreach(file ${base_generated_data_files})
55        link_to_source(${file})
56    endforeach()
57endif()
58
59# Test suites caught by SKIP_TEST_SUITES are built but not executed.
60# "foo" as a skip pattern skips "test_suite_foo" and "test_suite_foo.bar"
61# but not "test_suite_foobar".
62string(REGEX REPLACE "[ ,;]" "|" SKIP_TEST_SUITES_REGEX "${SKIP_TEST_SUITES}")
63string(REPLACE "." "\\." SKIP_TEST_SUITES_REGEX "${SKIP_TEST_SUITES_REGEX}")
64set(SKIP_TEST_SUITES_REGEX "^(${SKIP_TEST_SUITES_REGEX})(\$|\\.)")
65
66function(add_test_suite suite_name)
67    if(ARGV1)
68        set(data_name ${ARGV1})
69    else()
70        set(data_name ${suite_name})
71    endif()
72
73    # Get the test names of the tests with generated .data files
74    # from the generated_data_files list in parent scope.
75    set(generated_data_names "")
76    foreach(generated_data_file ${generated_data_files})
77        # Get the plain filename
78        get_filename_component(generated_data_name ${generated_data_file} NAME)
79        # Remove the ".data" extension
80        get_name_without_last_ext(generated_data_name ${generated_data_name})
81        # Remove leading "test_suite_"
82        string(SUBSTRING ${generated_data_name} 11 -1 generated_data_name)
83        list(APPEND generated_data_names ${generated_data_name})
84    endforeach()
85
86    if(";${generated_data_names};" MATCHES ";${data_name};")
87        set(data_file
88            ${CMAKE_CURRENT_BINARY_DIR}/suites/test_suite_${data_name}.data)
89    else()
90        set(data_file
91            ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${data_name}.data)
92    endif()
93
94    add_custom_command(
95        OUTPUT
96            # The output filename of generate_test_code.py is derived from the -d
97            # input argument.
98            test_suite_${data_name}.c
99        COMMAND
100            ${MBEDTLS_PYTHON_EXECUTABLE}
101            ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py
102            -f ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function
103            -d ${data_file}
104            -t ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function
105            -p ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function
106            -s ${CMAKE_CURRENT_SOURCE_DIR}/suites
107            --helpers-file ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function
108            -o .
109        DEPENDS
110            ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_test_code.py
111            ${CMAKE_CURRENT_SOURCE_DIR}/suites/test_suite_${suite_name}.function
112            ${data_file}
113            ${CMAKE_CURRENT_SOURCE_DIR}/suites/main_test.function
114            ${CMAKE_CURRENT_SOURCE_DIR}/suites/host_test.function
115            ${CMAKE_CURRENT_SOURCE_DIR}/suites/helpers.function
116            ${mbedtls_target}
117        BYPRODUCTS
118            test_suite_${data_name}.datax
119    )
120
121    add_executable(test_suite_${data_name} test_suite_${data_name}.c $<TARGET_OBJECTS:mbedtls_test>)
122    target_link_libraries(test_suite_${data_name} ${libs})
123    # Include test-specific header files from ./include and private header
124    # files (used by some invasive tests) from ../library. Public header
125    # files are automatically included because the library targets declare
126    # them as PUBLIC.
127    target_include_directories(test_suite_${data_name}
128        PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
129        PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../library)
130
131    if(${data_name} MATCHES ${SKIP_TEST_SUITES_REGEX})
132        message(STATUS "The test suite ${data_name} will not be executed.")
133    else()
134        add_test(${data_name}-suite test_suite_${data_name} --verbose)
135    endif()
136endfunction(add_test_suite)
137
138# Enable definition of various functions used throughout the testsuite
139# (gethostname, strdup, fileno...) even when compiling with -std=c99. Harmless
140# on non-POSIX platforms.
141add_definitions("-D_POSIX_C_SOURCE=200809L")
142
143if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
144    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
145endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
146
147if(CMAKE_COMPILER_IS_CLANG)
148    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code")
149endif(CMAKE_COMPILER_IS_CLANG)
150
151if(MSVC)
152    # If a warning level has been defined, suppress all warnings for test code
153    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W0")
154    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX-")
155endif(MSVC)
156
157add_test_suite(aes aes.cbc)
158add_test_suite(aes aes.cfb)
159add_test_suite(aes aes.ecb)
160add_test_suite(aes aes.ofb)
161add_test_suite(aes aes.rest)
162add_test_suite(aes aes.xts)
163add_test_suite(aria)
164add_test_suite(asn1parse)
165add_test_suite(asn1write)
166add_test_suite(base64)
167add_test_suite(camellia)
168add_test_suite(ccm)
169add_test_suite(chacha20)
170add_test_suite(chachapoly)
171add_test_suite(cipher cipher.aes)
172add_test_suite(cipher cipher.camellia)
173add_test_suite(cipher cipher.ccm)
174add_test_suite(cipher cipher.chacha20)
175add_test_suite(cipher cipher.chachapoly)
176add_test_suite(cipher cipher.des)
177add_test_suite(cipher cipher.gcm)
178add_test_suite(cipher cipher.misc)
179add_test_suite(cipher cipher.nist_kw)
180add_test_suite(cipher cipher.null)
181add_test_suite(cipher cipher.padding)
182add_test_suite(cmac)
183add_test_suite(ctr_drbg)
184add_test_suite(debug)
185add_test_suite(des)
186add_test_suite(dhm)
187add_test_suite(ecdh)
188add_test_suite(ecdsa)
189add_test_suite(ecjpake)
190add_test_suite(ecp)
191add_test_suite(entropy)
192add_test_suite(error)
193add_test_suite(gcm gcm.aes128_de)
194add_test_suite(gcm gcm.aes128_en)
195add_test_suite(gcm gcm.aes192_de)
196add_test_suite(gcm gcm.aes192_en)
197add_test_suite(gcm gcm.aes256_de)
198add_test_suite(gcm gcm.aes256_en)
199add_test_suite(gcm gcm.camellia)
200add_test_suite(gcm gcm.misc)
201add_test_suite(hkdf)
202add_test_suite(hmac_drbg hmac_drbg.misc)
203add_test_suite(hmac_drbg hmac_drbg.no_reseed)
204add_test_suite(hmac_drbg hmac_drbg.nopr)
205add_test_suite(hmac_drbg hmac_drbg.pr)
206add_test_suite(md)
207add_test_suite(mdx)
208add_test_suite(memory_buffer_alloc)
209add_test_suite(mpi)
210add_test_suite(mps)
211add_test_suite(net)
212add_test_suite(nist_kw)
213add_test_suite(oid)
214add_test_suite(pem)
215add_test_suite(pk)
216add_test_suite(pkcs1_v15)
217add_test_suite(pkcs1_v21)
218add_test_suite(pkcs5)
219add_test_suite(pkparse)
220add_test_suite(pkwrite)
221add_test_suite(poly1305)
222add_test_suite(psa_crypto)
223add_test_suite(psa_crypto_attributes)
224add_test_suite(psa_crypto_entropy)
225add_test_suite(psa_crypto_hash)
226add_test_suite(psa_crypto_init)
227add_test_suite(psa_crypto_metadata)
228add_test_suite(psa_crypto_not_supported psa_crypto_not_supported.generated)
229add_test_suite(psa_crypto_not_supported psa_crypto_not_supported.misc)
230add_test_suite(psa_crypto_persistent_key)
231add_test_suite(psa_crypto_se_driver_hal)
232add_test_suite(psa_crypto_se_driver_hal_mocks)
233add_test_suite(psa_crypto_slot_management)
234add_test_suite(psa_crypto_storage_format psa_crypto_storage_format.misc)
235add_test_suite(psa_crypto_storage_format psa_crypto_storage_format.current)
236add_test_suite(psa_crypto_storage_format psa_crypto_storage_format.v0)
237add_test_suite(psa_its)
238add_test_suite(random)
239add_test_suite(rsa)
240add_test_suite(shax)
241add_test_suite(ssl)
242add_test_suite(timing)
243add_test_suite(version)
244add_test_suite(x509parse)
245add_test_suite(x509write)
246
247# Make scripts and data files needed for testing available in an
248# out-of-source build.
249if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
250    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/seedfile")
251        link_to_source(seedfile)
252    endif()
253    link_to_source(compat.sh)
254    link_to_source(context-info.sh)
255    link_to_source(data_files)
256    link_to_source(scripts)
257    link_to_source(ssl-opt.sh)
258endif()
259