1 #-----------------------------------------------------------------------------
2 # Function to run a child process and report output only on error.
4 execute_process(${ARGN}
8 OUTPUT_STRIP_TRAILING_WHITESPACE
9 ERROR_STRIP_TRAILING_WHITESPACE
12 string(REPLACE "\n" "\n " OUTPUT "${OUTPUT}")
13 message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n"
14 "Command = [${ARGN}]\n")
17 # Pass output back up to the parent scope for possible further inspection.
18 set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
21 #-----------------------------------------------------------------------------
22 # Function to find the Update.xml file and check for expected entries.
23 function(check_updates build)
24 # Find the Update.xml file for the given build tree
25 set(PATTERN ${TOP}/${build}/Testing/*/Update.xml)
26 file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
27 string(REGEX REPLACE "//Update.xml$" "/Update.xml"
28 UPDATE_XML_FILE "${UPDATE_XML_FILE}"
30 if(NOT UPDATE_XML_FILE)
31 message(FATAL_ERROR "Cannot find Update.xml with pattern\n ${PATTERN}")
33 message(" found ${UPDATE_XML_FILE}")
35 set(max_update_xml_size 16384)
37 # Read entries from the Update.xml file
38 set(types "Updated|Modified|Conflicting")
39 file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES
40 REGEX "<(${types}|FullName)>"
41 LIMIT_INPUT ${max_update_xml_size}
45 "[ \t]*<(${types})>[ \t]*;[ \t]*<FullName>([^<]*)</FullName>"
46 "\\1{\\2}" UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
48 # If specified, remove the given prefix from the files in Update.xml.
49 # Some VCS systems, like Perforce, return absolute locations
50 if(DEFINED REPOSITORY_FILE_PREFIX)
52 "${REPOSITORY_FILE_PREFIX}" ""
53 UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
56 # Compare expected and actual entries
57 set(EXTRA "${UPDATE_XML_ENTRIES}")
58 list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_EXTRA} ${UPDATE_MAYBE})
59 set(MISSING "${ARGN}" ${UPDATE_EXTRA})
60 if(NOT "" STREQUAL "${UPDATE_XML_ENTRIES}")
61 list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
64 if(NOT UPDATE_NOT_GLOBAL)
65 set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS})
66 string(REPLACE ";" "|" rev_regex "${rev_elements}")
67 set(rev_regex "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$")
68 file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
70 LIMIT_INPUT ${max_update_xml_size}
72 foreach(r IN LISTS UPDATE_XML_REVISIONS)
73 string(REGEX REPLACE "${rev_regex}" "\\1" element "${r}")
74 set(element_${element} 1)
76 foreach(element IN LISTS rev_elements)
77 if(NOT element_${element})
78 list(APPEND MISSING "global <${element}> element")
86 # List the missing entries
87 string(APPEND MSG "Update.xml is missing expected entries:\n")
88 foreach(f IN LISTS MISSING)
89 string(APPEND MSG " ${f}\n")
93 message(" no entries missing from Update.xml")
98 # List the extra entries
99 string(APPEND MSG "Update.xml has extra unexpected entries:\n")
100 foreach(f IN LISTS EXTRA)
101 string(APPEND MSG " ${f}\n")
105 message(" no extra entries in Update.xml")
109 # Provide the log file
110 file(GLOB UPDATE_LOG_FILE
111 ${TOP}/${build}/Testing/Temporary/LastUpdate*.log)
113 file(READ ${UPDATE_LOG_FILE} UPDATE_LOG LIMIT ${max_update_xml_size})
114 string(REPLACE "\n" "\n " UPDATE_LOG "${UPDATE_LOG}")
115 string(APPEND MSG "Update log:\n ${UPDATE_LOG}")
117 string(APPEND MSG "No update log found!")
120 # Display the error message
121 message(FATAL_ERROR "${MSG}")
125 #-----------------------------------------------------------------------------
126 # Function to create initial content.
127 function(create_content dir)
128 file(MAKE_DIRECTORY ${TOP}/${dir})
130 # An example CTest project configuration file.
131 file(WRITE ${TOP}/${dir}/CTestConfig.cmake
132 "# CTest Configuration File
133 set(CTEST_NIGHTLY_START_TIME \"21:00:00 EDT\")
137 file(WRITE ${TOP}/${dir}/foo.txt "foo\n")
138 file(WRITE ${TOP}/${dir}/bar.txt "bar\n")
141 #-----------------------------------------------------------------------------
142 # Function to update content.
143 function(update_content dir added_var removed_var dirs_var)
144 file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n")
145 file(WRITE ${TOP}/${dir}/zot.txt "zot\n")
146 file(REMOVE ${TOP}/${dir}/bar.txt)
147 file(MAKE_DIRECTORY ${TOP}/${dir}/subdir)
148 file(WRITE ${TOP}/${dir}/subdir/foo.txt "foo\n")
149 file(WRITE ${TOP}/${dir}/subdir/bar.txt "bar\n")
150 set(${dirs_var} subdir PARENT_SCOPE)
151 set(${added_var} zot.txt subdir/foo.txt subdir/bar.txt PARENT_SCOPE)
152 set(${removed_var} bar.txt PARENT_SCOPE)
155 #-----------------------------------------------------------------------------
156 # Function to change existing files
157 function(change_content dir)
158 file(APPEND ${TOP}/${dir}/foo.txt "foo line 3\n")
159 file(APPEND ${TOP}/${dir}/subdir/foo.txt "foo line 2\n")
162 #-----------------------------------------------------------------------------
163 # Function to create local modifications before update
164 function(modify_content dir)
165 file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n")
168 #-----------------------------------------------------------------------------
169 # Function to write CTestConfiguration.ini content.
170 function(create_build_tree src_dir bin_dir)
171 file(MAKE_DIRECTORY ${TOP}/${bin_dir})
172 file(WRITE ${TOP}/${bin_dir}/CTestConfiguration.ini
173 "# CTest Configuration File
174 SourceDirectory: ${TOP}/${src_dir}
175 BuildDirectory: ${TOP}/${bin_dir}
181 #-----------------------------------------------------------------------------
182 # Function to write the dashboard test script.
183 function(create_dashboard_script bin_dir custom_text)
184 if (NOT ctest_update_check)
185 set(ctest_update_check [[
187 message(FATAL_ERROR "ctest_update failed with ${ret}")
192 # Write the dashboard script.
193 file(WRITE ${TOP}/${bin_dir}.cmake
194 "# CTest Dashboard Script
195 set(CTEST_DASHBOARD_ROOT \"${TOP}\")
196 set(CTEST_SITE test.site)
197 set(CTEST_BUILD_NAME dash-test)
198 set(CTEST_SOURCE_DIRECTORY \${CTEST_DASHBOARD_ROOT}/dash-source)
199 set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/${bin_dir})
201 # Start a dashboard and run the update step
202 ctest_start(Experimental)
203 ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY} RETURN_VALUE ret ${ctest_update_args})
204 ${ctest_update_check}")
207 #-----------------------------------------------------------------------------
208 # Function to run the dashboard through the command line
209 function(run_dashboard_command_line bin_dir)
211 WORKING_DIRECTORY ${TOP}/${bin_dir}
212 COMMAND ${CMAKE_CTEST_COMMAND} -M Experimental -T Start -T Update
215 # Verify the updates reported by CTest.
216 list(APPEND UPDATE_MAYBE Updated{subdir})
217 set(_modified Modified{CTestConfig.cmake})
218 if(UPDATE_NO_MODIFIED)
221 check_updates(${bin_dir}
225 Updated{subdir/foo.txt}
226 Updated{subdir/bar.txt}
231 #-----------------------------------------------------------------------------
232 # Function to find the Update.xml file and make sure
233 # it only has the Revision in it and no updates
234 function(check_no_update bin_dir)
235 set(PATTERN ${TOP}/${bin_dir}/Testing/*/Update.xml)
236 file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
237 string(REGEX REPLACE "//Update.xml$" "/Update.xml"
238 UPDATE_XML_FILE "${UPDATE_XML_FILE}")
239 message(" found ${UPDATE_XML_FILE}")
240 set(rev_regex "Revision|PriorRevision")
241 file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
242 REGEX "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$"
244 set(found_revisons FALSE)
245 foreach(r IN LISTS UPDATE_XML_REVISIONS)
246 if("${r}" MATCHES "PriorRevision")
247 message(FATAL_ERROR "Found PriorRevision in no update test")
249 if("${r}" MATCHES "<Revision>")
250 set(found_revisons TRUE)
254 message(" found <Revision> in no update test")
256 message(FATAL_ERROR " missing <Revision> in no update test")
260 #-----------------------------------------------------------------------------
261 # Function to find the Update.xml file and make sure
262 # it only has the UpdateReturnStatus failure message and no updates.
263 function(check_fail_update bin_dir)
264 set(PATTERN ${TOP}/${bin_dir}/Testing/*/Update.xml)
265 file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
266 string(REGEX REPLACE "//Update.xml$" "/Update.xml"
267 UPDATE_XML_FILE "${UPDATE_XML_FILE}")
268 message(" found ${UPDATE_XML_FILE}")
269 file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_STATUS
270 REGEX "^\t<UpdateReturnStatus>[^<\n]+"
272 if(UPDATE_XML_STATUS MATCHES "Update command failed")
273 message(" correctly found 'Update command failed'")
275 message(FATAL_ERROR " missing 'Update command failed'")
279 #-----------------------------------------------------------------------------
280 # Function to run the dashboard through a script
281 function(run_dashboard_script bin_dir)
283 WORKING_DIRECTORY ${TOP}
284 COMMAND ${CMAKE_CTEST_COMMAND} -S ${bin_dir}.cmake -V
287 # Verify the updates reported by CTest.
288 list(APPEND UPDATE_MAYBE Updated{subdir} Updated{CTestConfig.cmake})
290 check_no_update(${bin_dir})
292 check_fail_update(${bin_dir})
294 check_updates(${bin_dir}
298 Updated{subdir/foo.txt}
299 Updated{subdir/bar.txt}
303 # Pass console output up to the parent, in case they'd like to inspect it.
304 set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
307 #-----------------------------------------------------------------------------
308 # Function to initialize the testing directory.
309 function(init_testing)
310 file(REMOVE_RECURSE ${TOP})
311 file(MAKE_DIRECTORY ${TOP})