|
3 | 3 | # allowing CTest to control the execution, parallelization, and collection of |
4 | 4 | # test results. |
5 | 5 |
|
6 | | -if (NOT EXISTS "${TEST_LIBMONGOC_EXE}") |
| 6 | +if(NOT EXISTS "${TEST_LIBMONGOC_EXE}") |
7 | 7 | # This will fail if 'test-libmongoc' is not compiled yet. |
8 | | - message (WARNING "The test executable ${TEST_LIBMONGOC_EXE} is not present. " |
9 | | - "Its tests will not be registered") |
10 | | - add_test (mongoc/not-found NOT_FOUND) |
11 | | - return () |
12 | | -endif () |
13 | | - |
14 | | -# Get the list of tests |
15 | | -execute_process ( |
16 | | - COMMAND "${TEST_LIBMONGOC_EXE}" --list-tests --no-fork |
17 | | - OUTPUT_VARIABLE tests_out |
| 8 | + message(WARNING "The test executable ${TEST_LIBMONGOC_EXE} is not present. " |
| 9 | + "Its tests will not be registered") |
| 10 | + add_test(mongoc/not-found NOT_FOUND) |
| 11 | + return() |
| 12 | +endif() |
| 13 | + |
| 14 | +# Get the list of tests. This command emits CMake code that defines variables for |
| 15 | +# all test cases defined in the suite |
| 16 | +execute_process( |
| 17 | + COMMAND "${TEST_LIBMONGOC_EXE}" --tests-cmake --no-fork |
| 18 | + OUTPUT_VARIABLE tests_cmake |
18 | 19 | WORKING_DIRECTORY "${SRC_ROOT}" |
19 | 20 | RESULT_VARIABLE retc |
20 | 21 | ) |
21 | | -if (retc) |
| 22 | +if(retc) |
22 | 23 | # Failed to list the tests. That's bad. |
23 | | - message (FATAL_ERROR "Failed to run test-libmongoc to discover tests [${retc}]:\n${tests_out}") |
24 | | -endif () |
| 24 | + message(FATAL_ERROR "Failed to run test-libmongoc to discover tests [${retc}]:\n${tests_out}") |
| 25 | +endif() |
25 | 26 |
|
26 | | -# Split lines on newlines |
27 | | -string (REPLACE "\n" ";" lines "${tests_out}") |
| 27 | +# Execute the code that defines the test case information |
| 28 | +cmake_language(EVAL CODE "${tests_cmake}") |
28 | 29 |
|
29 | | -# TODO: Allow individual test cases to specify the fixtures they want. |
30 | | -set (all_fixtures "mongoc/fixtures/fake_kms_provider_server") |
31 | | -set (all_env |
| 30 | +# Define environment variables that are common to all test cases |
| 31 | +set(all_env |
32 | 32 | TEST_KMS_PROVIDER_HOST=localhost:14987 # Refer: Fixtures.cmake |
33 | 33 | ) |
34 | 34 |
|
35 | | -# Generate the test definitions |
36 | | -foreach (line IN LISTS lines) |
37 | | - if (NOT line MATCHES "^/") |
38 | | - # Only generate if the line begins with `/`, which all tests should. |
39 | | - continue () |
40 | | - endif () |
41 | | - # The new test name is prefixed with 'mongoc' |
42 | | - set (test "mongoc${line}") |
43 | | - # Define the test. Use `--ctest-run` to tell it that CTest is in control. |
44 | | - add_test ("${test}" "${TEST_LIBMONGOC_EXE}" --ctest-run "${line}") |
45 | | - set_tests_properties ("${test}" PROPERTIES |
| 35 | +function(list_select list_var) |
| 36 | + cmake_parse_arguments(PARSE_ARGV 1 arg "" "SELECT;REPLACE;OUT" "") |
| 37 | + set(seq "${${list_var}}") |
| 38 | + list(FILTER seq INCLUDE REGEX "${arg_SELECT}") |
| 39 | + list(TRANSFORM seq REPLACE "${arg_SELECT}" "${arg_REPLACE}") |
| 40 | + set("${arg_OUT}" "${seq}" PARENT_SCOPE) |
| 41 | +endfunction() |
| 42 | + |
| 43 | +# The emitted code defines a list MONGOC_TESTS with the name of every test case |
| 44 | +# in the suite. |
| 45 | +foreach(casename IN LISTS MONGOC_TESTS) |
| 46 | + set(name "mongoc${casename}") |
| 47 | + # Run the program with --ctest-run to select only this one test case |
| 48 | + add_test("${name}" "${TEST_LIBMONGOC_EXE}" --ctest-run "${casename}") |
| 49 | + # The emitted code defines a TAGS list for every test case that it emits. We use |
| 50 | + # these as the LABELS for the test case |
| 51 | + unset(labels) |
| 52 | + set(labels "${MONGOC_TEST_${casename}_TAGS}") |
| 53 | + |
| 54 | + # Find what test fixtures the test wants by inspecting labels. Each "uses:" |
| 55 | + # label defines the names of the test fixtures that a particular case requires |
| 56 | + list_select(labels SELECT "^uses:(.*)$" REPLACE "mongoc/fixtures/\\1" OUT fixtures) |
| 57 | + |
| 58 | + # For any "lock:..." labels, add a resource lock with the corresponding name |
| 59 | + list_select(labels SELECT "^lock:(.*)$" REPLACE "\\1" OUT locks) |
| 60 | + |
| 61 | + # Tests can set a timeout with a tag: |
| 62 | + list_select(labels SELECT "^timeout:(.*)$" REPLACE "\\1" OUT timeout) |
| 63 | + if(NOT timeout) |
| 64 | + # Default timeout of 10 seconds. If a test takes longer than this, it either |
| 65 | + # has a bug or it needs to declare a longer timeout. |
| 66 | + set(timeout 10) |
| 67 | + endif() |
| 68 | + |
| 69 | + # Add a label for all test cases generated via this script so that they |
| 70 | + # can be (de)selected separately: |
| 71 | + list(APPEND labels test-libmongoc-generated) |
| 72 | + # Set up the test: |
| 73 | + set_tests_properties("${name}" PROPERTIES |
46 | 74 | # test-libmongoc expects to execute in the root of the source directory |
47 | 75 | WORKING_DIRECTORY "${SRC_ROOT}" |
48 | 76 | # If a test emits '@@ctest-skipped@@', this tells us that the test is |
49 | 77 | # skipped. |
50 | 78 | SKIP_REGULAR_EXPRESSION "@@ctest-skipped@@" |
51 | | - # 45 seconds of timeout on each test. |
52 | | - TIMEOUT 45 |
53 | | - FIXTURES_REQUIRED "${all_fixtures}" |
| 79 | + # Apply a timeout to each test, either the default or one from test tags |
| 80 | + TIMEOUT "${timeout}" |
| 81 | + # Common environment variables: |
54 | 82 | ENVIRONMENT "${all_env}" |
55 | | - # Mark all tests generated from the executable, so they can be (de)selected |
56 | | - # for execution separately. |
57 | | - LABELS "test-libmongoc-generated" |
58 | | - ) |
59 | | -endforeach () |
| 83 | + # Apply the labels |
| 84 | + LABELS "${labels}" |
| 85 | + # Fixture requirements: |
| 86 | + FIXTURES_REQUIRED "${fixtures}" |
| 87 | + # Test may lock resources: |
| 88 | + RESOURCE_LOCK "${locks}" |
| 89 | + ) |
| 90 | +endforeach() |
0 commit comments