78a5727d49
Previously these tests just checked for matching file names in the Update.xml files. Now we check the update types (Updated, Modified, or Conflicting) and reject unexpected extra entries.
229 lines
7.6 KiB
CMake
229 lines
7.6 KiB
CMake
#-----------------------------------------------------------------------------
|
|
# 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}")
|
|
|
|
# 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 4096
|
|
)
|
|
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_MAYBE})
|
|
set(MISSING "${ARGN}")
|
|
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 4096
|
|
)
|
|
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 4096)
|
|
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 name custom_text)
|
|
# Write the dashboard script.
|
|
file(WRITE ${TOP}/dashboard.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}/dash-binary)
|
|
${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.
|
|
set(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}
|
|
Modified{CTestConfig.cmake}
|
|
)
|
|
endfunction(run_dashboard_command_line)
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Function to run the dashboard through a script
|
|
function(run_dashboard_script name)
|
|
run_child(
|
|
WORKING_DIRECTORY ${TOP}
|
|
COMMAND ${CMAKE_CTEST_COMMAND} -S ${name} -V
|
|
)
|
|
|
|
# Verify the updates reported by CTest.
|
|
set(UPDATE_MAYBE Updated{subdir})
|
|
check_updates(dash-binary
|
|
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)
|