diff options
Diffstat (limited to 'Tests/CTestUpdateCommon.cmake')
-rw-r--r-- | Tests/CTestUpdateCommon.cmake | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake new file mode 100644 index 000000000..335d09e7e --- /dev/null +++ b/Tests/CTestUpdateCommon.cmake @@ -0,0 +1,234 @@ +#----------------------------------------------------------------------------- +# Function to run a child process and report output only on error. +function(run_child) + execute_process(${ARGN} + RESULT_VARIABLE FAILED + OUTPUT_VARIABLE OUTPUT + ERROR_VARIABLE OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + if(FAILED) + string(REGEX REPLACE "\n" "\n " OUTPUT "${OUTPUT}") + message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n" + "Command = [${ARGN}]\n") + endif(FAILED) +endfunction(run_child) + +#----------------------------------------------------------------------------- +# Function to find the Update.xml file and check for expected entries. +function(check_updates build) + # Find the Update.xml file for the given build tree + set(PATTERN ${TOP}/${build}/Testing/*/Update.xml) + file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN}) + string(REGEX REPLACE "//Update.xml$" "/Update.xml" + UPDATE_XML_FILE "${UPDATE_XML_FILE}" + ) + if(NOT UPDATE_XML_FILE) + message(FATAL_ERROR "Cannot find Update.xml with pattern\n ${PATTERN}") + endif(NOT UPDATE_XML_FILE) + message(" found ${UPDATE_XML_FILE}") + + set(max_update_xml_size 16384) + + # Read entries from the Update.xml file + set(types "Updated|Modified|Conflicting") + file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES + REGEX "<(${types}|FullName)>" + LIMIT_INPUT ${max_update_xml_size} + ) + string(REGEX REPLACE + "[ \t]*<(${types})>[ \t]*;[ \t]*<FullName>([^<]*)</FullName>" + "\\1{\\2}" UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}") + + # Compare expected and actual entries + set(EXTRA "${UPDATE_XML_ENTRIES}") + list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_EXTRA} ${UPDATE_MAYBE}) + set(MISSING "${ARGN}" ${UPDATE_EXTRA}) + list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES}) + + if(NOT UPDATE_NOT_GLOBAL) + set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS}) + string(REPLACE ";" "|" rev_regex "${rev_elements}") + set(rev_regex "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$") + file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS + REGEX "${rev_regex}" + LIMIT_INPUT ${max_update_xml_size} + ) + foreach(r IN LISTS UPDATE_XML_REVISIONS) + string(REGEX REPLACE "${rev_regex}" "\\1" element "${r}") + set(element_${element} 1) + endforeach() + foreach(element ${rev_elements}) + if(NOT element_${element}) + list(APPEND MISSING "global <${element}> element") + endif() + endforeach() + endif() + + # Report the result + set(MSG "") + if(MISSING) + # List the missing entries + set(MSG "${MSG}Update.xml is missing expected entries:\n") + foreach(f ${MISSING}) + set(MSG "${MSG} ${f}\n") + endforeach(f) + else(MISSING) + # Success + message(" no entries missing from Update.xml") + endif(MISSING) + + # Report the result + if(EXTRA) + # List the extra entries + set(MSG "${MSG}Update.xml has extra unexpected entries:\n") + foreach(f ${EXTRA}) + set(MSG "${MSG} ${f}\n") + endforeach(f) + else(EXTRA) + # Success + message(" no extra entries in Update.xml") + endif(EXTRA) + + if(MSG) + # Provide the log file + file(GLOB UPDATE_LOG_FILE + ${TOP}/${build}/Testing/Temporary/LastUpdate*.log) + if(UPDATE_LOG_FILE) + file(READ ${UPDATE_LOG_FILE} UPDATE_LOG LIMIT ${max_update_xml_size}) + string(REGEX REPLACE "\n" "\n " UPDATE_LOG "${UPDATE_LOG}") + set(MSG "${MSG}Update log:\n ${UPDATE_LOG}") + else(UPDATE_LOG_FILE) + set(MSG "${MSG}No update log found!") + endif(UPDATE_LOG_FILE) + + # Display the error message + message(FATAL_ERROR "${MSG}") + endif(MSG) +endfunction(check_updates) + +#----------------------------------------------------------------------------- +# Function to create initial content. +function(create_content dir) + file(MAKE_DIRECTORY ${TOP}/${dir}) + + # An example CTest project configuration file. + file(WRITE ${TOP}/${dir}/CTestConfig.cmake + "# CTest Configuration File +set(CTEST_PROJECT_NAME TestProject) +set(CTEST_NIGHTLY_START_TIME \"21:00:00 EDT\") +") + + # Some other files. + file(WRITE ${TOP}/${dir}/foo.txt "foo\n") + file(WRITE ${TOP}/${dir}/bar.txt "bar\n") +endfunction(create_content) + +#----------------------------------------------------------------------------- +# Function to update content. +function(update_content dir added_var removed_var dirs_var) + file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n") + file(WRITE ${TOP}/${dir}/zot.txt "zot\n") + file(REMOVE ${TOP}/${dir}/bar.txt) + file(MAKE_DIRECTORY ${TOP}/${dir}/subdir) + file(WRITE ${TOP}/${dir}/subdir/foo.txt "foo\n") + file(WRITE ${TOP}/${dir}/subdir/bar.txt "bar\n") + set(${dirs_var} subdir PARENT_SCOPE) + set(${added_var} zot.txt subdir/foo.txt subdir/bar.txt PARENT_SCOPE) + set(${removed_var} bar.txt PARENT_SCOPE) +endfunction(update_content) + +#----------------------------------------------------------------------------- +# Function to change existing files +function(change_content dir) + file(APPEND ${TOP}/${dir}/foo.txt "foo line 3\n") + file(APPEND ${TOP}/${dir}/subdir/foo.txt "foo line 2\n") +endfunction(change_content) + +#----------------------------------------------------------------------------- +# Function to create local modifications before update +function(modify_content dir) + file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n") +endfunction(modify_content) + +#----------------------------------------------------------------------------- +# Function to write CTestConfiguration.ini content. +function(create_build_tree src_dir bin_dir) + file(MAKE_DIRECTORY ${TOP}/${bin_dir}) + file(WRITE ${TOP}/${bin_dir}/CTestConfiguration.ini + "# CTest Configuration File +SourceDirectory: ${TOP}/${src_dir} +BuildDirectory: ${TOP}/${bin_dir} +Site: test.site +BuildName: user-test +") +endfunction(create_build_tree) + +#----------------------------------------------------------------------------- +# Function to write the dashboard test script. +function(create_dashboard_script bin_dir custom_text) + # Write the dashboard script. + file(WRITE ${TOP}/${bin_dir}.cmake + "# CTest Dashboard Script +set(CTEST_DASHBOARD_ROOT \"${TOP}\") +set(CTEST_SITE test.site) +set(CTEST_BUILD_NAME dash-test) +set(CTEST_SOURCE_DIRECTORY \${CTEST_DASHBOARD_ROOT}/dash-source) +set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/${bin_dir}) +${custom_text} +# Start a dashboard and run the update step +ctest_start(Experimental) +ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY}) +") +endfunction(create_dashboard_script) + +#----------------------------------------------------------------------------- +# Function to run the dashboard through the command line +function(run_dashboard_command_line bin_dir) + run_child( + WORKING_DIRECTORY ${TOP}/${bin_dir} + COMMAND ${CMAKE_CTEST_COMMAND} -M Experimental -T Start -T Update + ) + + # Verify the updates reported by CTest. + list(APPEND UPDATE_MAYBE Updated{subdir}) + set(_modified Modified{CTestConfig.cmake}) + if(UPDATE_NO_MODIFIED) + set(_modified "") + endif() + check_updates(${bin_dir} + Updated{foo.txt} + Updated{bar.txt} + Updated{zot.txt} + Updated{subdir/foo.txt} + Updated{subdir/bar.txt} + ${_modified} + ) +endfunction(run_dashboard_command_line) + +#----------------------------------------------------------------------------- +# Function to run the dashboard through a script +function(run_dashboard_script bin_dir) + run_child( + WORKING_DIRECTORY ${TOP} + COMMAND ${CMAKE_CTEST_COMMAND} -S ${bin_dir}.cmake -V + ) + + # Verify the updates reported by CTest. + list(APPEND UPDATE_MAYBE Updated{subdir}) + check_updates(${bin_dir} + Updated{foo.txt} + Updated{bar.txt} + Updated{zot.txt} + Updated{subdir/foo.txt} + Updated{subdir/bar.txt} + ) +endfunction(run_dashboard_script) + +#----------------------------------------------------------------------------- +# Function to initialize the testing directory. +function(init_testing) + file(REMOVE_RECURSE ${TOP}) + file(MAKE_DIRECTORY ${TOP}) +endfunction(init_testing) |