瀏覽代碼

ENH: Test CTest update logic with VCS tools

This creates new tests "CTest.UpdateSVN" and "CTest.UpdateCVS".  They
test that the Update.xml produced by CTest for a version-controlled
project contains entries for files added, changed, and removed.
Brad King 17 年之前
父節點
當前提交
3584a4eceb
共有 4 個文件被更改,包括 440 次插入0 次删除
  1. 51 0
      Tests/CMakeLists.txt
  2. 114 0
      Tests/CTestUpdateCVS.cmake.in
  3. 159 0
      Tests/CTestUpdateCommon.cmake
  4. 116 0
      Tests/CTestUpdateSVN.cmake.in

+ 51 - 0
Tests/CMakeLists.txt

@@ -820,6 +820,57 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
     LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
   ENDIF(APPLE AND CTEST_TEST_CPACK)
 
+  SET(CTEST_TEST_UPDATE 1)
+  IF(CTEST_TEST_UPDATE)
+    # Test CTest Update with Subversion
+    FIND_PACKAGE(Subversion QUIET)
+    IF(Subversion_FOUND)
+      GET_FILENAME_COMPONENT(_Subversion_BIN_DIR
+        ${Subversion_SVN_EXECUTABLE} PATH)
+      FIND_PROGRAM(Subversion_SVNADMIN_EXECUTABLE svnadmin
+        HINTS ${_Subversion_BIN_DIR}
+        )
+      MARK_AS_ADVANCED(Subversion_SVNADMIN_EXECUTABLE)
+      IF(NOT Subversion_SVNADMIN_EXECUTABLE)
+        SET(Subversion_FOUND FALSE)
+      ENDIF(NOT Subversion_SVNADMIN_EXECUTABLE)
+    ENDIF(Subversion_FOUND)
+    IF(Subversion_FOUND)
+      SET(CTestUpdateSVN_DIR "CTest UpdateSVN")
+      CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateSVN.cmake.in"
+        "${CMake_BINARY_DIR}/Tests/CTestUpdateSVN.cmake" @ONLY)
+      ADD_TEST(CTest.UpdateSVN ${CMAKE_CMAKE_COMMAND}
+        -P "${CMake_BINARY_DIR}/Tests/CTestUpdateSVN.cmake"
+        )
+      LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateSVN_DIR}")
+    ENDIF(Subversion_FOUND)
+
+    # Test CTest Update with CVS
+    IF(UNIX)
+      # The test is expected to work by default on UNIX-like systems.
+      SET(CTEST_TEST_UPDATE_CVS 1)
+    ELSE(UNIX)
+      # Special CVS configuration is needed for test to pass on Windows.
+      OPTION(CTEST_TEST_UPDATE_CVS
+        "Enable CTest.UpdateCVS test.  Requires extra CVS setup on windows."
+        OFF)
+      MARK_AS_ADVANCED(CTEST_TEST_UPDATE_CVS)
+    ENDIF(UNIX)
+    IF(CTEST_TEST_UPDATE_CVS)
+      FIND_PACKAGE(CVS QUIET)
+    ENDIF(CTEST_TEST_UPDATE_CVS)
+    IF(CTEST_TEST_UPDATE_CVS AND CVS_FOUND)
+      SET(CTestUpdateCVS_DIR "CTest UpdateCVS")
+      CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateCVS.cmake.in"
+        "${CMake_BINARY_DIR}/Tests/CTestUpdateCVS.cmake" @ONLY)
+      ADD_TEST(CTest.UpdateCVS ${CMAKE_CMAKE_COMMAND}
+        -P "${CMake_BINARY_DIR}/Tests/CTestUpdateCVS.cmake"
+        )
+      LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateCVS_DIR}")
+    ENDIF(CTEST_TEST_UPDATE_CVS AND CVS_FOUND)
+
+  ENDIF(CTEST_TEST_UPDATE)
+
   IF (CTEST_TEST_CTEST AND CMAKE_RUN_LONG_TESTS)
     CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestTest/test.cmake.in"
       "${CMake_BINARY_DIR}/Tests/CTestTest/test.cmake" @ONLY ESCAPE_QUOTES)

+ 114 - 0
Tests/CTestUpdateCVS.cmake.in

@@ -0,0 +1,114 @@
+# This script drives creation of a CVS repository and checks
+# that CTest can update from it.
+
+#-----------------------------------------------------------------------------
+# Test in a directory next to this script.
+get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(TOP "${TOP}/@CTestUpdateCVS_DIR@")
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report CVS tools in use.
+message("Using CVS tools:")
+set(CVS "@CVS_EXECUTABLE@")
+message(" cvs = ${CVS}")
+
+set(REPO ${TOP}/repo)
+set(CVSCMD ${CVS} -d${REPO})
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo)
+run_child(
+  COMMAND ${CVSCMD} init
+  )
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(
+  WORKING_DIRECTORY ${TOP}/import
+  COMMAND ${CVSCMD} import -m "Initial content" Project vendor-tag release-tag
+  )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+  WORKING_DIRECTORY ${TOP}
+  COMMAND ${CVSCMD} co -d user-source Project
+  )
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${CVSCMD} tag Revision1
+  )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed)
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${CVSCMD} add ${files_added}
+  )
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${CVSCMD} rm ${files_removed}
+  )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${CVSCMD} commit -m "Changed content"
+  )
+
+#-----------------------------------------------------------------------------
+# Go back to before the changes so we can test updating.
+message("Backing up to revision 1...")
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${CVSCMD} up -rRevision1
+  )
+
+#-----------------------------------------------------------------------------
+# Test updating the user work directory with the command-line interface.
+message("Running CTest Dashboard Command Line...")
+
+# Create the user build tree.
+create_build_tree(user-source user-binary)
+file(APPEND ${TOP}/user-binary/CTestConfiguration.ini
+  "# CVS command configuration
+CVSCommand: ${CVS}
+CVSUpdateOptions: -dAP
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dashboard.cmake
+  "# CVS command configuration
+set(CTEST_CVS_COMMAND \"${CVS}\")
+set(CTEST_CVS_UPDATE_OPTIONS -dAP)
+set(CTEST_CHECKOUT_COMMAND
+  \"\\\"\${CTEST_CVS_COMMAND}\\\" -d \\\"${REPO}\\\" co -rRevision1 -d dash-source Project\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dashboard.cmake)

+ 159 - 0
Tests/CTestUpdateCommon.cmake

@@ -0,0 +1,159 @@
+#-----------------------------------------------------------------------------
+# 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.  Output is\n  ${OUTPUT}\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
+  file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES
+    REGEX "FullName"
+    LIMIT_INPUT 4096
+    )
+
+  # Verify that expected entries exist
+  set(MISSING)
+  foreach(f ${ARGN})
+    if(NOT "${UPDATE_XML_ENTRIES}" MATCHES "<FullName>${f}</FullName>")
+      list(APPEND MISSING ${f})
+    endif()
+  endforeach(f)
+
+  # Report the result
+  if(MISSING)
+    # List the missing entries
+    set(MSG "Update.xml is missing an entry for:\n")
+    foreach(f ${MISSING})
+      set(MSG "${MSG}  ${f}\n")
+    endforeach(f)
+
+    # 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}")
+  else(MISSING)
+    # Success
+    message(" no entries missing from Update.xml")
+  endif(MISSING)
+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)
+  file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n")
+  file(WRITE ${TOP}/${dir}/zot.txt "zot\n")
+  file(REMOVE ${TOP}/${dir}/bar.txt)
+  set(${added_var} zot.txt PARENT_SCOPE)
+  set(${removed_var} bar.txt PARENT_SCOPE)
+endfunction(update_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.
+  check_updates(${bin_dir} foo.txt bar.txt zot.txt)
+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.
+  check_updates(dash-binary foo.txt bar.txt zot.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)

+ 116 - 0
Tests/CTestUpdateSVN.cmake.in

@@ -0,0 +1,116 @@
+# This script drives creation of a Subversion repository and checks
+# that CTest can update from it.
+
+#-----------------------------------------------------------------------------
+# Test in a directory next to this script.
+get_filename_component(TOP "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(TOP "${TOP}/@CTestUpdateSVN_DIR@")
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report subversion tools in use.
+message("Using subversion tools:")
+set(SVN "@Subversion_SVN_EXECUTABLE@")
+set(SVNADMIN "@Subversion_SVNADMIN_EXECUTABLE@")
+message(" svn      = ${SVN}")
+message(" svnadmin = ${SVNADMIN}")
+
+# Isolate svn test operations from the user configuration.
+file(MAKE_DIRECTORY ${TOP}/config)
+set(SVNCMD ${SVN} --config-dir ${TOP}/config)
+set(SVNUSER --username testauthor --non-interactive)
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo)
+run_child(
+  COMMAND ${SVNADMIN} create --config-dir ${TOP}/config ${TOP}/repo
+  )
+set(REPO file:///${TOP}/repo/trunk)
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(
+  WORKING_DIRECTORY ${TOP}/import
+  COMMAND ${SVNCMD} import ${SVNUSER} -m "Initial content" . "${REPO}"
+  )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+  WORKING_DIRECTORY ${TOP}
+  COMMAND ${SVNCMD} co ${SVNUSER} ${REPO} user-source
+  )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed)
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${SVNCMD} add ${files_added}
+  )
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${SVNCMD} rm ${files_removed}
+  )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${SVNCMD} commit -m "Changed content"
+  )
+
+#-----------------------------------------------------------------------------
+# Go back to before the changes so we can test updating.
+message("Backing up to revision 1...")
+run_child(
+  WORKING_DIRECTORY ${TOP}/user-source
+  COMMAND ${SVNCMD} up -r1
+  )
+
+#-----------------------------------------------------------------------------
+# Test updating the user work directory with the command-line interface.
+message("Running CTest Dashboard Command Line...")
+
+# Create the user build tree.
+create_build_tree(user-source user-binary)
+file(APPEND ${TOP}/user-binary/CTestConfiguration.ini
+  "# SVN command configuration
+SVNCommand: ${SVN}
+SVNUpdateOptions: --config-dir \"${TOP}/config\"
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dashboard.cmake
+  "# Subversion command configuration
+set(CTEST_SVN_COMMAND \"${SVN}\")
+set(CTEST_SVN_UPDATE_OPTIONS
+  \"--config-dir \\\"\${CTEST_DASHBOARD_ROOT}/config\\\"\")
+set(CTEST_CHECKOUT_COMMAND
+  \"\\\"\${CTEST_SVN_COMMAND}\\\" co -r1 \\\"${REPO}\\\" dash-source\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dashboard.cmake)