Skip to content
This repository was archived by the owner on Dec 6, 2024. It is now read-only.

Commit be83985

Browse files
authored
Refactor cmake project tests to remove unecessary boilerplate (#216)
* Refactor cmake project tests This commit adds a "test_" prefix to each cmake project test. Additionally, it factors out the boilerplate required to setup each test into a few cmake macros which can be used in a more declarative manner.
1 parent 0e3e304 commit be83985

File tree

19 files changed

+123
-142
lines changed

19 files changed

+123
-142
lines changed
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
add_subdirectory(add_subdirectory)
2-
add_subdirectory(find_package)
3-
add_subdirectory(find_package_compatible_version)
4-
add_subdirectory(find_package_incompatible_version)
1+
include(DeclareProjectTest.cmake)
2+
add_subdirectory(test_add_subdirectory)
3+
add_subdirectory(test_find_package)
4+
add_subdirectory(test_find_package_compatible_version)
5+
add_subdirectory(test_find_package_incompatible_version)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# This file defines macros which can be used to setup
2+
# new cmake project tests without introducing excessive boilerplate.
3+
4+
# declare_add_subdirectory_test(<name of test>):
5+
# Use when the test depends on ldserverapi via add_subdirectory.
6+
7+
# declare_find_package_test(<test name>):
8+
# Use when the test depends on ldserverapi via find_package.
9+
10+
# add_build_step(<test name>):
11+
# By default, the declare_* macros result in a test where "cmake -DSOMEVARIABLE=WHATEVER .."
12+
# (the cmake configure step) is invoked. This may be sufficient for a particular test,
13+
# for example testing that the configure step fails.
14+
# If the test should also invoke "cmake --build .", use this macro.
15+
16+
# require_configure_failure(<test name>):
17+
# Asserts that the cmake configure step should fail. For example, this would
18+
# happen if a required version of a dependency couldn't be satisfied with find_package.
19+
20+
# require_build_failure(<test name>):
21+
# Asserts that the cmake build step should fail.
22+
23+
macro(declare_add_subdirectory_test name)
24+
set(test_prefix ${name})
25+
26+
add_test(
27+
NAME ${test_prefix}_configure
28+
COMMAND
29+
${CMAKE_COMMAND}
30+
# Since project/CMakeLists.txt is going to call add_subdirectory(), it needs to know where
31+
# the SDK's project is (which is actually a couple directories above this particular file; not normally the case.)
32+
# The variable name is arbitrary.
33+
-DLDSERVERAPI_SOURCE_DIR=${PROJECT_SOURCE_DIR}
34+
# Do not setup all of the SDK's testing machinery, which would normally happen when calling add_subdirectory.
35+
-DBUILD_TESTING=OFF
36+
# Forward variables from the SDK project to the test project, if set.
37+
$<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}>
38+
$<$<BOOL:${CURL_LIBRARY}>:-DCURL_LIBRARY=${CURL_LIBRARY}>
39+
$<$<BOOL:${CURL_INCLUDE_DIR}>:-DCURL_INCLUDE_DIR=${CURL_INCLUDE_DIR}>
40+
$<$<BOOL:${PCRE_LIBRARY}>:-DPCRE_LIBRARY=${PCRE_LIBRARY}>
41+
$<$<BOOL:${PCRE_INCLUDE_DIR}>:-DPCRE_INCLUDE_DIR=${PCRE_INCLUDE_DIR}>
42+
${CMAKE_CURRENT_SOURCE_DIR}/project
43+
)
44+
45+
set_tests_properties(${test_prefix}_configure
46+
PROPERTIES
47+
FIXTURES_SETUP ${test_prefix}
48+
# Forward along the CC and CXX environment variables, because clang11 CI build uses them.
49+
ENVIRONMENT "CC=${CMAKE_C_COMPILER};CXX=${CMAKE_CXX_COMPILER}"
50+
)
51+
endmacro()
52+
53+
macro(require_configure_failure name)
54+
set_tests_properties(${name}_configure PROPERTIES WILL_FAIL TRUE)
55+
endmacro()
56+
57+
macro(require_build_failure name)
58+
set_tests_properties(${name}_build PROPERTIES WILL_FAIL TRUE)
59+
endmacro()
60+
61+
macro(add_build_step name)
62+
# Setup a 'test' to perform the cmake build step.
63+
add_test(
64+
NAME ${name}_build
65+
COMMAND ${CMAKE_COMMAND} --build .
66+
)
67+
68+
set_tests_properties(${name}_build
69+
PROPERTIES
70+
FIXTURES_REQUIRED ${name}
71+
)
72+
endmacro()
73+
74+
macro(declare_find_package_test name)
75+
# This test assumes that the SDK has been installed at CMAKE_INSTALL_PREFIX.
76+
set(test_prefix ${name})
77+
78+
add_test(
79+
NAME ${test_prefix}_configure
80+
COMMAND
81+
${CMAKE_COMMAND}
82+
# Since project/CMakeLists.txt uses find_package(), it needs to know where to find
83+
# ldserverapiConfig.cmake. That can be found where the SDK is installed, which is CMAKE_INSTALL_PREFIX.
84+
-DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}
85+
# Forward variables from the SDK project to the test project, if set.
86+
$<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}>
87+
$<$<BOOL:${CURL_LIBRARY}>:-DCURL_LIBRARY=${CURL_LIBRARY}>
88+
$<$<BOOL:${CURL_INCLUDE_DIR}>:-DCURL_INCLUDE_DIR=${CURL_INCLUDE_DIR}>
89+
$<$<BOOL:${PCRE_LIBRARY}>:-DPCRE_LIBRARY=${PCRE_LIBRARY}>
90+
$<$<BOOL:${PCRE_INCLUDE_DIR}>:-DPCRE_INCLUDE_DIR=${PCRE_INCLUDE_DIR}>
91+
${CMAKE_CURRENT_SOURCE_DIR}/project
92+
)
93+
94+
set_tests_properties(${test_prefix}_configure
95+
PROPERTIES
96+
FIXTURES_SETUP ${test_prefix}
97+
# Forward along the CC and CXX environment variables, because clang11 CI build uses them.
98+
ENVIRONMENT "CC=${CMAKE_C_COMPILER};CXX=${CMAKE_CXX_COMPILER}"
99+
)
100+
endmacro()

tests/cmake_projects/README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,19 @@ This could obscure linker errors if the release artifacts are generated incorrec
2828
## CMake test setup
2929

3030
The toplevel `CMakeLists.txt` in each subdirectory is responsible for setting up
31-
the actual CTest tests that configure and build the projects.
31+
the actual CTest tests that configure and build the projects.
3232

33-
This is generally done in two phases:
33+
Note, the logic described below is encapsulated in two macros defined in `DeclareProjectTest.cmake`, so that
34+
that new tests don't need to copy boilerplate.
35+
36+
Test creation is generally done in two phases:
3437
1) Make a test that configures the project (simulating `cmake .. [options]`)
3538
2) Make a test that builds the project (simulating `cmake --build .`)
3639

3740
The tests are ordered via `set_tests_properties` to ensure the configure test
3841
runs before the build test, as would be expected.
3942

40-
The toplevel `CMakeLists.txt` harbors additional complexity because these tests are executed
43+
The test creation logic harbors additional complexity because these tests are executed
4144
in CI on multiple types of executors (Windows/Mac/Linux) in various configurations.
4245

4346
In particular, some environment variables must be forwarded to each test project CMake configuration.
@@ -52,7 +55,7 @@ Additionally, certain variables must be forwarded to each test project CMake con
5255
| `PCRE_LIBRARY`/`PCRE_INCLUDE_DIR` | Windows build uses PCRE downloaded at runtime, not system PCRE. |
5356
| `CMAKE_GENERATOR_PLATFORM` | Windows build explicitly specifies x64 build, whereas the default project build would be x86. Linker errors would ensue. |
5457

55-
Each toplevel `CMakeLists.txt` uses a series of CMake generator expressions (`$<...>`) to forward the variables
58+
The creation logic uses a series of CMake generator expressions (`$<...>`) to forward the variables
5659
in the table above from the main SDK project (which `add_subdirectory`'d each test) to the test projects.
5760

5861
Simply specifying the variables directly using `-DVARIABLE=${VARIABLE}` as is normally done on the command line

tests/cmake_projects/add_subdirectory/CMakeLists.txt

Lines changed: 0 additions & 38 deletions
This file was deleted.

tests/cmake_projects/find_package/CMakeLists.txt

Lines changed: 0 additions & 34 deletions
This file was deleted.

tests/cmake_projects/find_package_compatible_version/CMakeLists.txt

Lines changed: 0 additions & 35 deletions
This file was deleted.

tests/cmake_projects/find_package_incompatible_version/CMakeLists.txt

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare_add_subdirectory_test(test_add_subdirectory)
2+
add_build_step(test_add_subdirectory)

0 commit comments

Comments
 (0)