ExternalProjectUpdateTest.cmake 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. # Set the ExternalProject GIT_TAG to desired_tag, and make sure the
  2. # resulting checked out version is resulting_sha and rebuild.
  3. # This check's the correct behavior of the ExternalProject UPDATE_COMMAND.
  4. # Also verify that a fetch only occurs when fetch_expected_tsX is 1.
  5. macro(check_a_tag
  6. desired_tag
  7. resulting_sha
  8. fetch_expected_ts1 # TutorialStep1-GIT
  9. fetch_expected_ts2 # TutorialStep2-GIT
  10. update_strategy
  11. )
  12. message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag}" )
  13. # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git
  14. # fetch'.
  15. set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/.git/FETCH_HEAD )
  16. file( REMOVE ${FETCH_HEAD_file} )
  17. # Give ourselves a marker in the output. It is difficult to tell where we
  18. # are up to without this
  19. message(STATUS "===> check_a_tag: "
  20. "${desired_tag} ${resulting_sha} "
  21. "${fetch_expected_ts1} ${fetch_expected_ts2} "
  22. "${update_strategy}"
  23. )
  24. # Configure
  25. execute_process(COMMAND ${CMAKE_COMMAND}
  26. -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}"
  27. -A "${CMAKE_GENERATOR_PLATFORM}"
  28. -DTEST_GIT_TAG:STRING=${desired_tag}
  29. -DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY:STRING=${update_strategy}
  30. ${ExternalProjectUpdate_SOURCE_DIR}
  31. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
  32. RESULT_VARIABLE error_code
  33. )
  34. if(error_code)
  35. message(FATAL_ERROR "Could not configure the project.")
  36. endif()
  37. # Build
  38. execute_process(COMMAND ${CMAKE_COMMAND}
  39. --build ${ExternalProjectUpdate_BINARY_DIR}
  40. RESULT_VARIABLE error_code
  41. )
  42. if(error_code)
  43. message(FATAL_ERROR "Could not build the project.")
  44. endif()
  45. # Check the resulting SHA
  46. execute_process(COMMAND ${GIT_EXECUTABLE}
  47. rev-list --max-count=1 HEAD
  48. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
  49. RESULT_VARIABLE error_code
  50. OUTPUT_VARIABLE tag_sha
  51. OUTPUT_STRIP_TRAILING_WHITESPACE
  52. )
  53. if(error_code)
  54. message(FATAL_ERROR "Could not check the sha.")
  55. endif()
  56. if(NOT (${tag_sha} STREQUAL ${resulting_sha}))
  57. message(FATAL_ERROR "UPDATE_COMMAND produced
  58. ${tag_sha}
  59. when
  60. ${resulting_sha}
  61. was expected."
  62. )
  63. endif()
  64. if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected_ts1})
  65. message( FATAL_ERROR "Fetch did NOT occur when it was expected.")
  66. endif()
  67. if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected_ts1})
  68. message( FATAL_ERROR "Fetch DID occur when it was not expected.")
  69. endif()
  70. message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag} (disconnected)" )
  71. # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git
  72. # fetch'.
  73. set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT/.git/FETCH_HEAD )
  74. file( REMOVE ${FETCH_HEAD_file} )
  75. # Check initial SHA
  76. execute_process(COMMAND ${GIT_EXECUTABLE}
  77. rev-list --max-count=1 HEAD
  78. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
  79. RESULT_VARIABLE error_code
  80. OUTPUT_VARIABLE initial_sha
  81. OUTPUT_STRIP_TRAILING_WHITESPACE
  82. )
  83. # Configure
  84. execute_process(COMMAND ${CMAKE_COMMAND}
  85. -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}"
  86. -A "${CMAKE_GENERATOR_PLATFORM}"
  87. -DTEST_GIT_TAG:STRING=${desired_tag}
  88. ${ExternalProjectUpdate_SOURCE_DIR}
  89. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
  90. RESULT_VARIABLE error_code
  91. )
  92. if(error_code)
  93. message(FATAL_ERROR "Could not configure the project.")
  94. endif()
  95. # Build
  96. execute_process(COMMAND ${CMAKE_COMMAND}
  97. --build ${ExternalProjectUpdate_BINARY_DIR}
  98. RESULT_VARIABLE error_code
  99. )
  100. if(error_code)
  101. message(FATAL_ERROR "Could not build the project.")
  102. endif()
  103. if( EXISTS ${FETCH_HEAD_file} )
  104. message( FATAL_ERROR "Fetch occurred when it was not expected.")
  105. endif()
  106. # Check the resulting SHA
  107. execute_process(COMMAND ${GIT_EXECUTABLE}
  108. rev-list --max-count=1 HEAD
  109. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
  110. RESULT_VARIABLE error_code
  111. OUTPUT_VARIABLE tag_sha
  112. OUTPUT_STRIP_TRAILING_WHITESPACE
  113. )
  114. if(error_code)
  115. message(FATAL_ERROR "Could not check the sha.")
  116. endif()
  117. if(NOT (${tag_sha} STREQUAL ${initial_sha}))
  118. message(FATAL_ERROR "Update occurred when it was not expected.")
  119. endif()
  120. # Update
  121. execute_process(COMMAND ${CMAKE_COMMAND}
  122. --build ${ExternalProjectUpdate_BINARY_DIR}
  123. --target TutorialStep2-GIT-update
  124. RESULT_VARIABLE error_code
  125. )
  126. if(error_code)
  127. message(FATAL_ERROR "Could not build the project.")
  128. endif()
  129. # Check the resulting SHA
  130. execute_process(COMMAND ${GIT_EXECUTABLE}
  131. rev-list --max-count=1 HEAD
  132. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT
  133. RESULT_VARIABLE error_code
  134. OUTPUT_VARIABLE tag_sha
  135. OUTPUT_STRIP_TRAILING_WHITESPACE
  136. )
  137. if(error_code)
  138. message(FATAL_ERROR "Could not check the sha.")
  139. endif()
  140. if(NOT (${tag_sha} STREQUAL ${resulting_sha}))
  141. message(FATAL_ERROR "UPDATE_COMMAND produced
  142. ${tag_sha}
  143. when
  144. ${resulting_sha}
  145. was expected."
  146. )
  147. endif()
  148. if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected_ts2})
  149. message( FATAL_ERROR "Fetch did NOT occur when it was expected.")
  150. endif()
  151. if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected_ts2})
  152. message( FATAL_ERROR "Fetch DID occur when it was not expected.")
  153. endif()
  154. endmacro()
  155. find_package(Git)
  156. set(do_git_tests 0)
  157. if(GIT_EXECUTABLE)
  158. set(do_git_tests 1)
  159. message(STATUS "Git_VERSION='${Git_VERSION}'")
  160. if(Git_VERSION VERSION_LESS 1.6.5)
  161. message(STATUS "No ExternalProject git tests with git client less than version 1.6.5")
  162. set(do_git_tests 0)
  163. endif()
  164. endif()
  165. # When re-running tests locally, this ensures we always start afresh
  166. file(REMOVE_RECURSE ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals)
  167. if(do_git_tests)
  168. check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
  169. check_a_tag(tag1 4209914b424925d6f1b558d79454d60967d4b0f3 1 0 REBASE)
  170. # With the Git UPDATE_COMMAND performance patch, this will not require a
  171. # 'git fetch'
  172. check_a_tag(tag1 4209914b424925d6f1b558d79454d60967d4b0f3 0 0 REBASE)
  173. check_a_tag(tag2 ae72641040f1c9512f152d08afb6909f0498f958 1 0 REBASE)
  174. check_a_tag(4209914b42 4209914b424925d6f1b558d79454d60967d4b0f3 0 0 REBASE)
  175. check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
  176. # This is a remote symbolic ref, so it will always trigger a 'git fetch'
  177. check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
  178. foreach(strategy IN ITEMS CHECKOUT REBASE_CHECKOUT)
  179. # Move local master back, then apply a change that will cause a conflict
  180. # during rebase
  181. execute_process(COMMAND ${GIT_EXECUTABLE} checkout master
  182. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
  183. RESULT_VARIABLE error_code
  184. )
  185. if(error_code)
  186. message(FATAL_ERROR "Could not reset local master back to tag1.")
  187. endif()
  188. execute_process(COMMAND ${GIT_EXECUTABLE} reset --hard tag1
  189. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
  190. RESULT_VARIABLE error_code
  191. )
  192. if(error_code)
  193. message(FATAL_ERROR "Could not reset local master back to tag1.")
  194. endif()
  195. set(cmlFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/CMakeLists.txt)
  196. file(READ ${cmlFile} contents)
  197. string(REPLACE "find TutorialConfig.h" "find TutorialConfig.h (conflict here)"
  198. conflictingContent "${contents}"
  199. )
  200. file(WRITE ${cmlFile} "${conflictingContent}")
  201. execute_process(COMMAND ${GIT_EXECUTABLE} commit -a -m "This should cause a conflict"
  202. WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
  203. RESULT_VARIABLE error_code
  204. )
  205. if(error_code)
  206. message(FATAL_ERROR "Could not commit conflicting change.")
  207. endif()
  208. # This should discard our commit but leave behind an annotated tag
  209. check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 ${strategy})
  210. endforeach()
  211. # This file matches a .gitignore rule that the last commit defines. We can't
  212. # directly check that updates don't stash ignored contents because the stash
  213. # and pop are both done within the update step. We don't have an opportunity
  214. # to check things in between, but we can at least check that the update step
  215. # doesn't choke on it.
  216. set(ignoredFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/ignored_item)
  217. file(TOUCH ${ignoredFile})
  218. check_a_tag(origin/master b5f0fc2d442b72dd29e655c329af0062e1f8d129 1 1 REBASE)
  219. if(NOT EXISTS ${ignoredFile})
  220. message(FATAL_ERROR "Ignored file is missing")
  221. endif()
  222. endif()