-
Notifications
You must be signed in to change notification settings - Fork 0
/
Test.cmake
165 lines (143 loc) · 6.7 KB
/
Test.cmake
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
#=============================================================================
# mcl - The Missing CMake Library
# Copyright 2013 John Lamp
#
# Distributed under the OSI-approved Modified BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
include(mcl/List)
include(mcl/Option)
include(mcl/ParseArguments)
#! @todo add an option for excluding tests from all
#! @todo add a list for including only certain tags in check
#! @todo add a list for excluding certain tags from check
#! @todo add an option for auto-running tests
mcl_option(MCL_AUTO_RUN_TESTS
"Automatically run tets whenever any of their dependencies have been updated."
ON)
#!
# Enable testing and create the check target. This should be called before
# mcl_add_test() if check functionality is desired.
#
macro(mcl_enable_check)
enable_testing()
# enable_testing() does not work as desired if called from within a
# function. Apparently the scope causes problems which is why this is a
# macro.
_mcl_test_enableCheckWorker()
# To avoid possible scope pollution and work around other problems the
# bulk of the work for mcl_enable_check() is done in this worker
# function.
endmacro()
#!
# mcl_add_test(<name> <command>... [DEPENDS] [<dependencies>...] [NO_AUTO])
#
# Add a test target as add_test() does, if enable_testing() has been called
# first. If mcl_enable_check() has been called then <dependencies> will be
# added as dependencies of the check target. Additionally any element of the
# command can be marked as a target by prepending [TARGET] to it, these will
# also be added as dependencies of the check target. If NO_AUTO is specified
# then the test will not be run automatically even if MCL_AUTO_RUN_TESTS is
# true.
#
# Example:
# mcl_add_test(sample [TARGET]myProg --input [TARGET]generatedFile DEPENDS config)
# - the test command is: myProg --input generatedFile
# - check will depend on: myProg, generatedFile, and config
#
# @todo add tags so that tests can be categorized
#
function(mcl_add_test)
mcl_parse_arguments(mcl_add_test mclat_
"<name> <command>... [DEPENDS] [<dependencies>...] [NO_AUTO]"
ARGN ${ARGN})
mcl_list(PROCESS_TAGS mclat_command mclat_ TARGET)
add_test(${mclat_name} ${mclat_command})
_mcl_test_add_dependencies_to_check(${mclat_TARGET} ${mclat_dependencies})
if (MCL_AUTO_RUN_TESTS AND NOT mclat_NO_AUTO)
get_property(mclScriptsDir GLOBAL PROPERTY mclScriptsDir)
set(testCommand ${CMAKE_COMMAND} -P
${mclScriptsDir}/RunTestWithCTest.cmake ${mclat_name})
set(testComment "Running test ${mclat_name}")
set(targets)
set(generatedFiles)
foreach (dependency ${mclat_TARGET} ${mclat_dependencies})
if (TARGET ${dependency})
list(APPEND targets ${dependency})
else()
list(APPEND generatedFiles ${dependency})
endif()
endforeach()
list(LENGTH targets targetsLength)
list(LENGTH generatedFiles generatedFilesLength)
if (targetsLength EQUAL 0 AND
generatedFilesLength EQUAL 0)
message(AUTHOR_WARNING "Test '${mclat_name}' has no dependencies, "
"auto-running may not work as desired.")
add_custom_target(run_${mclat_name} ALL
${testCommand}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT ${testComment}
VERBATIM)
elseif(targetsLength EQUAL 1 AND
generatedFilesLength EQUAL 0)
add_custom_command(TARGET ${mclat_TARGET} POST_BUILD
COMMAND ${testCommand}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT ${testComment}
VERBATIM)
else()
set(flagFile ${CMAKE_CURRENT_BINARY_DIR}/${mclat_name}.flag)
foreach (target ${targets})
add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E touch ${flagFile}
VERBATIM)
endforeach()
# handle generated files
set(generateCheck)
if (generatedFiles)
set(generateTarget generateFilesFor_${mclat_name})
set(generateCheck checkGeneratedFilesFor_${mclat_name})
add_custom_target(${generateTarget}
DEPENDS ${generatedFiles})
add_custom_target(${generateCheck}
${CMAKE_COMMAND} -P
${mclScriptsDir}/CheckGeneratedFiles.cmake
${mclat_name} ${flagFile} ${generatedFiles}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${generateTarget}
VERBATIM)
endif()
add_custom_target(run_${mclat_name} ALL
${testCommand} ${flagFile}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${targets} ${generateCheck}
COMMENT ${testComment}
VERBATIM)
endif()
endif()
endfunction()
function(_mcl_test_add_dependencies_to_check)
# if mcl_enable_check() hasn't been called we don't want to do anything
endfunction()
function(_mcl_test_enableCheckWorker)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
COMMENT "Running tests...")
# Redefine this function to actually do what it says it will now that we
# have created the check target.
function(_mcl_test_add_dependencies_to_check)
if (NOT "${ARGN}" STREQUAL "")
add_dependencies(check ${ARGN})
endif()
endfunction()
# Note that because of the use of ${ARGN} we could not define this
# function inside the mcl_enable_check() macro as it would replace
# ${ARGN} with nothing, yeilding this function useless.
endfunction()
get_filename_component(mclDir ${CMAKE_CURRENT_LIST_FILE} PATH)
get_filename_component(mclScriptsDir ${mclDir}/scripts ABSOLUTE)
set_property(GLOBAL PROPERTY mclScriptsDir ${mclScriptsDir})