Ver Fonte

Ctest: Support build tree on command line

Fixes: #21268
Asit Dhal há 4 anos atrás
pai
commit
dbcf86d24d

+ 3 - 0
Help/manual/ctest.1.rst

@@ -324,6 +324,9 @@ Options
 ``--build-and-test``
 See `Build and Test Mode`_.
 
+``--test-dir <dir>``
+Specify the directory in which to look for tests.
+
 ``--test-output-size-passed <size>``
  Limit the output for passed tests to ``<size>`` bytes.
 

+ 5 - 0
Help/release/dev/ctest-test-dir.rst

@@ -0,0 +1,5 @@
+ctest-test-dir.rst
+------------------
+
+* :manual:`ctest(1)` gained a ``--test-dir`` option to specify the directory
+  in which to look for tests.

+ 33 - 2
Source/cmCTest.cxx

@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <cctype>
+#include <cerrno>
 #include <chrono>
 #include <cstdio>
 #include <cstdlib>
@@ -179,6 +180,7 @@ struct cmCTest::Private
 
   // information for the --build-and-test options
   std::string BinaryDir;
+  std::string TestDir;
 
   std::string NotesFiles;
 
@@ -2059,6 +2061,13 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
     i++;
     this->SetNotesFiles(args[i]);
     return true;
+  } else if (this->CheckArgument(arg, "--test-dir"_s)) {
+    if (i >= args.size() - 1) {
+      errormsg = "'--test-dir' requires an argument";
+      return false;
+    }
+    i++;
+    this->Impl->TestDir = std::string(args[i]);
   }
 
   cm::string_view noTestsPrefix = "--no-tests=";
@@ -2467,8 +2476,26 @@ int cmCTest::ExecuteTests()
       handler->SetVerbose(this->Impl->Verbose);
       handler->SetSubmitIndex(this->Impl->SubmitIndex);
     }
-    std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-    if (!this->Initialize(cwd.c_str(), nullptr)) {
+
+    const std::string currDir = cmSystemTools::GetCurrentWorkingDirectory();
+    std::string workDir = currDir;
+    if (!this->Impl->TestDir.empty()) {
+      workDir = cmSystemTools::CollapseFullPath(this->Impl->TestDir);
+    }
+
+    if (currDir != workDir) {
+      cmCTestLog(this, OUTPUT,
+                 "Internal ctest changing into directory: " << workDir
+                                                            << std::endl);
+      if (cmSystemTools::ChangeDirectory(workDir) != 0) {
+        auto msg = "Failed to change working directory to \"" + workDir +
+          "\" : " + std::strerror(errno) + "\n";
+        cmCTestLog(this, ERROR_MESSAGE, msg);
+        return 1;
+      }
+    }
+
+    if (!this->Initialize(workDir.c_str(), nullptr)) {
       res = 12;
       cmCTestLog(this, ERROR_MESSAGE,
                  "Problem initializing the dashboard." << std::endl);
@@ -2476,6 +2503,10 @@ int cmCTest::ExecuteTests()
       res = this->ProcessSteps();
     }
     this->Finalize();
+
+    if (currDir != workDir) {
+      cmSystemTools::ChangeDirectory(currDir);
+    }
   }
   if (res != 0) {
     cmCTestLog(this, DEBUG,

+ 1 - 0
Source/ctest.cxx

@@ -111,6 +111,7 @@ static const char* cmDocumentationOptions[][2] = {
   { "--no-subproject-summary",
     "Disable timing summary information for "
     "subprojects." },
+  { "--test-dir <dir>", "Specify the directory in which to look for tests." },
   { "--build-and-test", "Configure, build and run a test." },
   { "--build-target", "Specify a specific target to build." },
   { "--build-nocmake", "Run the build without running cmake first." },

+ 17 - 0
Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake

@@ -380,3 +380,20 @@ run_MemCheckSan(Leak "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode
 run_MemCheckSan(Memory "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
 run_MemCheckSan(Thread "report_bugs=1:history_size=5:exitcode=55")
 run_MemCheckSan(UndefinedBehavior "simulate_sanitizer=1")
+
+run_cmake_command(test-dir-invalid-arg ${CMAKE_CTEST_COMMAND} --test-dir)
+run_cmake_command(test-dir-non-existing-dir ${CMAKE_CTEST_COMMAND} --test-dir non-existing-dir)
+
+function(run_testDir)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/testDir)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/sub")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/sub/CTestTestfile.cmake" "
+  add_test(Test1 \"${CMAKE_COMMAND}\" -E true)
+  add_test(Test2 \"${CMAKE_COMMAND}\" -E true)
+  ")
+  run_cmake_command(testDir ${CMAKE_CTEST_COMMAND} --test-dir "${RunCMake_TEST_BINARY_DIR}/sub")
+endfunction()
+run_testDir()

+ 1 - 0
Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/CTestCommandLine/test-dir-invalid-arg-stderr.txt

@@ -0,0 +1 @@
+CMake Error: '--test-dir' requires an argument

+ 1 - 0
Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stderr.txt

@@ -0,0 +1 @@
+Failed to change working directory to ".*/non-existing-dir" : No such file or directory

+ 1 - 0
Tests/RunCMake/CTestCommandLine/test-dir-non-existing-dir-stdout.txt

@@ -0,0 +1 @@
+Internal ctest changing into directory: .*/non-existing-dir