#----------------------------------------------------------------------------- # 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() endfunction() #----------------------------------------------------------------------------- # 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() 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]*([^<]*)" "\\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]+$") 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() else() # Success message(" no entries missing from Update.xml") endif() # 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() else() # Success message(" no extra entries in Update.xml") endif() 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() set(MSG "${MSG}No update log found!") endif() # Display the error message message(FATAL_ERROR "${MSG}") endif() endfunction() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # Function to create local modifications before update function(modify_content dir) file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n") endfunction() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # Function to initialize the testing directory. function(init_testing) file(REMOVE_RECURSE ${TOP}) file(MAKE_DIRECTORY ${TOP}) endfunction()