CTestUpdateCommon.cmake 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #-----------------------------------------------------------------------------
  2. # Function to run a child process and report output only on error.
  3. function(run_child)
  4. execute_process(${ARGN}
  5. RESULT_VARIABLE FAILED
  6. OUTPUT_VARIABLE OUTPUT
  7. ERROR_VARIABLE OUTPUT
  8. OUTPUT_STRIP_TRAILING_WHITESPACE
  9. ERROR_STRIP_TRAILING_WHITESPACE
  10. )
  11. if(FAILED)
  12. string(REGEX REPLACE "\n" "\n " OUTPUT "${OUTPUT}")
  13. message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n"
  14. "Command = [${ARGN}]\n")
  15. endif(FAILED)
  16. endfunction(run_child)
  17. #-----------------------------------------------------------------------------
  18. # Function to find the Update.xml file and check for expected entries.
  19. function(check_updates build)
  20. # Find the Update.xml file for the given build tree
  21. set(PATTERN ${TOP}/${build}/Testing/*/Update.xml)
  22. file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
  23. string(REGEX REPLACE "//Update.xml$" "/Update.xml"
  24. UPDATE_XML_FILE "${UPDATE_XML_FILE}"
  25. )
  26. if(NOT UPDATE_XML_FILE)
  27. message(FATAL_ERROR "Cannot find Update.xml with pattern\n ${PATTERN}")
  28. endif(NOT UPDATE_XML_FILE)
  29. message(" found ${UPDATE_XML_FILE}")
  30. # Read entries from the Update.xml file
  31. set(types "Updated|Modified|Conflicting")
  32. file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES
  33. REGEX "<(${types}|FullName)>"
  34. LIMIT_INPUT 4096
  35. )
  36. string(REGEX REPLACE
  37. "[ \t]*<(${types})>[ \t]*;[ \t]*<FullName>([^<]*)</FullName>"
  38. "\\1{\\2}" UPDATE_XML_ENTRIES "${UPDATE_XML_ENTRIES}")
  39. # Compare expected and actual entries
  40. set(EXTRA "${UPDATE_XML_ENTRIES}")
  41. list(REMOVE_ITEM EXTRA ${ARGN} ${UPDATE_MAYBE})
  42. set(MISSING "${ARGN}")
  43. list(REMOVE_ITEM MISSING ${UPDATE_XML_ENTRIES})
  44. if(NOT UPDATE_NOT_GLOBAL)
  45. set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS})
  46. string(REPLACE ";" "|" rev_regex "${rev_elements}")
  47. set(rev_regex "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$")
  48. file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
  49. REGEX "${rev_regex}"
  50. LIMIT_INPUT 4096
  51. )
  52. foreach(r IN LISTS UPDATE_XML_REVISIONS)
  53. string(REGEX REPLACE "${rev_regex}" "\\1" element "${r}")
  54. set(element_${element} 1)
  55. endforeach()
  56. foreach(element ${rev_elements})
  57. if(NOT element_${element})
  58. list(APPEND MISSING "global <${element}> element")
  59. endif()
  60. endforeach()
  61. endif()
  62. # Report the result
  63. set(MSG "")
  64. if(MISSING)
  65. # List the missing entries
  66. set(MSG "${MSG}Update.xml is missing expected entries:\n")
  67. foreach(f ${MISSING})
  68. set(MSG "${MSG} ${f}\n")
  69. endforeach(f)
  70. else(MISSING)
  71. # Success
  72. message(" no entries missing from Update.xml")
  73. endif(MISSING)
  74. # Report the result
  75. if(EXTRA)
  76. # List the extra entries
  77. set(MSG "${MSG}Update.xml has extra unexpected entries:\n")
  78. foreach(f ${EXTRA})
  79. set(MSG "${MSG} ${f}\n")
  80. endforeach(f)
  81. else(EXTRA)
  82. # Success
  83. message(" no extra entries in Update.xml")
  84. endif(EXTRA)
  85. if(MSG)
  86. # Provide the log file
  87. file(GLOB UPDATE_LOG_FILE
  88. ${TOP}/${build}/Testing/Temporary/LastUpdate*.log)
  89. if(UPDATE_LOG_FILE)
  90. file(READ ${UPDATE_LOG_FILE} UPDATE_LOG LIMIT 4096)
  91. string(REGEX REPLACE "\n" "\n " UPDATE_LOG "${UPDATE_LOG}")
  92. set(MSG "${MSG}Update log:\n ${UPDATE_LOG}")
  93. else(UPDATE_LOG_FILE)
  94. set(MSG "${MSG}No update log found!")
  95. endif(UPDATE_LOG_FILE)
  96. # Display the error message
  97. message(FATAL_ERROR "${MSG}")
  98. endif(MSG)
  99. endfunction(check_updates)
  100. #-----------------------------------------------------------------------------
  101. # Function to create initial content.
  102. function(create_content dir)
  103. file(MAKE_DIRECTORY ${TOP}/${dir})
  104. # An example CTest project configuration file.
  105. file(WRITE ${TOP}/${dir}/CTestConfig.cmake
  106. "# CTest Configuration File
  107. set(CTEST_PROJECT_NAME TestProject)
  108. set(CTEST_NIGHTLY_START_TIME \"21:00:00 EDT\")
  109. ")
  110. # Some other files.
  111. file(WRITE ${TOP}/${dir}/foo.txt "foo\n")
  112. file(WRITE ${TOP}/${dir}/bar.txt "bar\n")
  113. endfunction(create_content)
  114. #-----------------------------------------------------------------------------
  115. # Function to update content.
  116. function(update_content dir added_var removed_var dirs_var)
  117. file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n")
  118. file(WRITE ${TOP}/${dir}/zot.txt "zot\n")
  119. file(REMOVE ${TOP}/${dir}/bar.txt)
  120. file(MAKE_DIRECTORY ${TOP}/${dir}/subdir)
  121. file(WRITE ${TOP}/${dir}/subdir/foo.txt "foo\n")
  122. file(WRITE ${TOP}/${dir}/subdir/bar.txt "bar\n")
  123. set(${dirs_var} subdir PARENT_SCOPE)
  124. set(${added_var} zot.txt subdir/foo.txt subdir/bar.txt PARENT_SCOPE)
  125. set(${removed_var} bar.txt PARENT_SCOPE)
  126. endfunction(update_content)
  127. #-----------------------------------------------------------------------------
  128. # Function to change existing files
  129. function(change_content dir)
  130. file(APPEND ${TOP}/${dir}/foo.txt "foo line 3\n")
  131. file(APPEND ${TOP}/${dir}/subdir/foo.txt "foo line 2\n")
  132. endfunction(change_content)
  133. #-----------------------------------------------------------------------------
  134. # Function to create local modifications before update
  135. function(modify_content dir)
  136. file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n")
  137. endfunction(modify_content)
  138. #-----------------------------------------------------------------------------
  139. # Function to write CTestConfiguration.ini content.
  140. function(create_build_tree src_dir bin_dir)
  141. file(MAKE_DIRECTORY ${TOP}/${bin_dir})
  142. file(WRITE ${TOP}/${bin_dir}/CTestConfiguration.ini
  143. "# CTest Configuration File
  144. SourceDirectory: ${TOP}/${src_dir}
  145. BuildDirectory: ${TOP}/${bin_dir}
  146. Site: test.site
  147. BuildName: user-test
  148. ")
  149. endfunction(create_build_tree)
  150. #-----------------------------------------------------------------------------
  151. # Function to write the dashboard test script.
  152. function(create_dashboard_script name custom_text)
  153. # Write the dashboard script.
  154. file(WRITE ${TOP}/dashboard.cmake
  155. "# CTest Dashboard Script
  156. set(CTEST_DASHBOARD_ROOT \"${TOP}\")
  157. set(CTEST_SITE test.site)
  158. set(CTEST_BUILD_NAME dash-test)
  159. set(CTEST_SOURCE_DIRECTORY \${CTEST_DASHBOARD_ROOT}/dash-source)
  160. set(CTEST_BINARY_DIRECTORY \${CTEST_DASHBOARD_ROOT}/dash-binary)
  161. ${custom_text}
  162. # Start a dashboard and run the update step
  163. ctest_start(Experimental)
  164. ctest_update(SOURCE \${CTEST_SOURCE_DIRECTORY})
  165. ")
  166. endfunction(create_dashboard_script)
  167. #-----------------------------------------------------------------------------
  168. # Function to run the dashboard through the command line
  169. function(run_dashboard_command_line bin_dir)
  170. run_child(
  171. WORKING_DIRECTORY ${TOP}/${bin_dir}
  172. COMMAND ${CMAKE_CTEST_COMMAND} -M Experimental -T Start -T Update
  173. )
  174. # Verify the updates reported by CTest.
  175. list(APPEND UPDATE_MAYBE Updated{subdir})
  176. check_updates(${bin_dir}
  177. Updated{foo.txt}
  178. Updated{bar.txt}
  179. Updated{zot.txt}
  180. Updated{subdir/foo.txt}
  181. Updated{subdir/bar.txt}
  182. Modified{CTestConfig.cmake}
  183. )
  184. endfunction(run_dashboard_command_line)
  185. #-----------------------------------------------------------------------------
  186. # Function to run the dashboard through a script
  187. function(run_dashboard_script name)
  188. run_child(
  189. WORKING_DIRECTORY ${TOP}
  190. COMMAND ${CMAKE_CTEST_COMMAND} -S ${name} -V
  191. )
  192. # Verify the updates reported by CTest.
  193. list(APPEND UPDATE_MAYBE Updated{subdir})
  194. check_updates(dash-binary
  195. Updated{foo.txt}
  196. Updated{bar.txt}
  197. Updated{zot.txt}
  198. Updated{subdir/foo.txt}
  199. Updated{subdir/bar.txt}
  200. )
  201. endfunction(run_dashboard_script)
  202. #-----------------------------------------------------------------------------
  203. # Function to initialize the testing directory.
  204. function(init_testing)
  205. file(REMOVE_RECURSE ${TOP})
  206. file(MAKE_DIRECTORY ${TOP})
  207. endfunction(init_testing)