CTestUpdateCommon.cmake 7.59 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#-----------------------------------------------------------------------------
# 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}")
13 14
    message(FATAL_ERROR "Child failed (${FAILED}), output is\n  ${OUTPUT}\n"
      "Command = [${ARGN}]\n")
15 16
  endif()
endfunction()
17 18 19 20 21 22 23 24 25 26 27 28

#-----------------------------------------------------------------------------
# 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}")
29
  endif()
30 31
  message(" found ${UPDATE_XML_FILE}")

32 33
  set(max_update_xml_size 16384)

34
  # Read entries from the Update.xml file
35
  set(types "Updated|Modified|Conflicting")
36
  file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES
37
    REGEX "<(${types}|FullName)>"
38
    LIMIT_INPUT ${max_update_xml_size}
39
    )
40 41 42
  string(REGEX REPLACE
    "[ \t]*<(${types})>[ \t]*;[ \t]*<FullName>([^<]*)</FullName>"
    "\\1{\\2}" UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
43

44 45
  # Compare expected and actual entries
  set(EXTRA "${UPDATE_XML_ENTRIES}")
46 47
  list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_EXTRA} ${UPDATE_MAYBE})
  set(MISSING "${ARGN}" ${UPDATE_EXTRA})
48
  list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
49

50
  if(NOT UPDATE_NOT_GLOBAL)
51 52 53
    set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS})
    string(REPLACE ";" "|" rev_regex "${rev_elements}")
    set(rev_regex "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$")
54 55
    file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
      REGEX "${rev_regex}"
56
      LIMIT_INPUT ${max_update_xml_size}
57 58 59 60 61 62 63 64 65 66 67 68
      )
    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()

69
  # Report the result
70
  set(MSG "")
71 72
  if(MISSING)
    # List the missing entries
73
    set(MSG "${MSG}Update.xml is missing expected entries:\n")
74 75
    foreach(f ${MISSING})
      set(MSG "${MSG}  ${f}\n")
76 77
    endforeach()
  else()
78 79
    # Success
    message(" no entries missing from Update.xml")
80
  endif()
81

82 83 84 85 86 87
  # 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")
88 89
    endforeach()
  else()
90 91
    # Success
    message(" no extra entries in Update.xml")
92
  endif()
93 94

  if(MSG)
95 96 97 98
    # Provide the log file
    file(GLOB UPDATE_LOG_FILE
      ${TOP}/${build}/Testing/Temporary/LastUpdate*.log)
    if(UPDATE_LOG_FILE)
99
      file(READ ${UPDATE_LOG_FILE} UPDATE_LOG LIMIT ${max_update_xml_size})
100 101
      string(REGEX REPLACE "\n" "\n  " UPDATE_LOG "${UPDATE_LOG}")
      set(MSG "${MSG}Update log:\n  ${UPDATE_LOG}")
102
    else()
103
      set(MSG "${MSG}No update log found!")
104
    endif()
105 106 107

    # Display the error message
    message(FATAL_ERROR "${MSG}")
108 109
  endif()
endfunction()
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

#-----------------------------------------------------------------------------
# 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")
126
endfunction()
127 128 129

#-----------------------------------------------------------------------------
# Function to update content.
130
function(update_content dir added_var removed_var dirs_var)
131 132 133
  file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n")
  file(WRITE ${TOP}/${dir}/zot.txt "zot\n")
  file(REMOVE ${TOP}/${dir}/bar.txt)
134 135 136 137 138
  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)
139
  set(${removed_var} bar.txt PARENT_SCOPE)
140
endfunction()
141

142 143 144 145 146
#-----------------------------------------------------------------------------
# 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")
147
endfunction()
148

149 150 151 152
#-----------------------------------------------------------------------------
# Function to create local modifications before update
function(modify_content dir)
  file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n")
153
endfunction()
154

155 156 157 158 159 160 161 162 163 164 165
#-----------------------------------------------------------------------------
# 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
")
166
endfunction()
167 168 169

#-----------------------------------------------------------------------------
# Function to write the dashboard test script.
170
function(create_dashboard_script bin_dir custom_text)
171
  # Write the dashboard script.
172
  file(WRITE ${TOP}/${bin_dir}.cmake
173 174 175 176 177
    "# 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)
178
set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/${bin_dir})
179 180 181 182 183
${custom_text}
# Start a dashboard and run the update step
ctest_start(Experimental)
ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY})
")
184
endfunction()
185 186 187 188 189 190 191 192 193 194

#-----------------------------------------------------------------------------
# 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.
195
  list(APPEND UPDATE_MAYBE Updated{subdir})
196 197 198 199
  set(_modified Modified{CTestConfig.cmake})
  if(UPDATE_NO_MODIFIED)
    set(_modified "")
  endif()
200 201 202 203 204 205
  check_updates(${bin_dir}
    Updated{foo.txt}
    Updated{bar.txt}
    Updated{zot.txt}
    Updated{subdir/foo.txt}
    Updated{subdir/bar.txt}
206
    ${_modified}
207
    )
208
endfunction()
209 210 211

#-----------------------------------------------------------------------------
# Function to run the dashboard through a script
212
function(run_dashboard_script bin_dir)
213 214
  run_child(
    WORKING_DIRECTORY ${TOP}
215
    COMMAND ${CMAKE_CTEST_COMMAND} -S ${bin_dir}.cmake -V
216 217 218
    )

  # Verify the updates reported by CTest.
219
  list(APPEND UPDATE_MAYBE Updated{subdir} Updated{CTestConfig.cmake})
220
  check_updates(${bin_dir}
221 222 223 224 225 226
    Updated{foo.txt}
    Updated{bar.txt}
    Updated{zot.txt}
    Updated{subdir/foo.txt}
    Updated{subdir/bar.txt}
    )
227
endfunction()
228 229 230 231 232 233

#-----------------------------------------------------------------------------
# Function to initialize the testing directory.
function(init_testing)
  file(REMOVE_RECURSE ${TOP})
  file(MAKE_DIRECTORY ${TOP})
234
endfunction()