summaryrefslogtreecommitdiff
path: root/Source/CTest
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-08 09:20:10 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-08 09:20:10 +0900
commitf58f7a233a9b66287e1a0fad0d149e3202a098b4 (patch)
treecc0cea82fae3f153df9299b27650e17c58da1125 /Source/CTest
parent46f8b5215bbbfcf4bc0caed1daf52b678fd2b976 (diff)
downloadcmake-f58f7a233a9b66287e1a0fad0d149e3202a098b4.tar.gz
cmake-f58f7a233a9b66287e1a0fad0d149e3202a098b4.tar.bz2
cmake-f58f7a233a9b66287e1a0fad0d149e3202a098b4.zip
Imported Upstream version 3.18.0upstream/3.18.0
Diffstat (limited to 'Source/CTest')
-rw-r--r--Source/CTest/cmCTestBZR.cxx4
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx32
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx24
-rw-r--r--Source/CTest/cmCTestCVS.cxx6
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx2
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx6
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx54
-rw-r--r--Source/CTest/cmCTestCurl.h2
-rw-r--r--Source/CTest/cmCTestGIT.cxx4
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx60
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx78
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h8
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx6
-rw-r--r--Source/CTest/cmCTestRunTest.cxx97
-rw-r--r--Source/CTest/cmCTestRunTest.h15
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx53
-rw-r--r--Source/CTest/cmCTestScriptHandler.h26
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx11
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx29
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx13
-rw-r--r--Source/CTest/cmCTestTestCommand.h1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx196
-rw-r--r--Source/CTest/cmCTestTestHandler.h5
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx3
-rw-r--r--Source/CTest/cmCTestVC.cxx2
-rw-r--r--Source/CTest/cmCTestVC.h2
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx34
-rw-r--r--Source/CTest/cmParseCacheCoverage.h5
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.h2
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx9
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h4
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx10
-rw-r--r--Source/CTest/cmProcess.cxx26
-rw-r--r--Source/CTest/cmProcess.h14
39 files changed, 442 insertions, 411 deletions
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index c87fb83b3..c533cd7f9 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -10,9 +10,9 @@
#include <cmext/algorithm>
-#include "cmsys/RegularExpression.hxx"
+#include <cm3p/expat.h>
-#include "cm_expat.h"
+#include "cmsys/RegularExpression.hxx"
#include "cmCTest.h"
#include "cmCTestVC.h"
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 5e29386c7..db426b2ff 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -379,7 +379,7 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
const std::vector<std::string>& allArgs)
{
// --build-and-test options
- if (currentArg.find("--build-and-test", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-and-test") &&
idx < allArgs.size() - 1) {
if (idx + 2 < allArgs.size()) {
idx++;
@@ -397,25 +397,29 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
return 0;
}
}
- if (currentArg.find("--build-target", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-target") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildTargets.push_back(allArgs[idx]);
}
- if (currentArg.find("--build-nocmake", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) {
this->BuildNoCMake = true;
}
- if (currentArg.find("--build-run-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-run-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildRunDir = allArgs[idx];
}
- if (currentArg.find("--build-two-config", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-two-config")) {
this->BuildTwoConfig = true;
}
- if (currentArg.find("--build-exe-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->ExecutableDirectory = allArgs[idx];
}
- if (currentArg.find("--test-timeout", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-timeout") &&
+ idx < allArgs.size() - 1) {
idx++;
this->Timeout = cmDuration(atof(allArgs[idx].c_str()));
}
@@ -431,31 +435,33 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++;
this->BuildGeneratorToolset = allArgs[idx];
}
- if (currentArg.find("--build-project", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-project") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildProject = allArgs[idx];
}
- if (currentArg.find("--build-makeprogram", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") &&
idx < allArgs.size() - 1) {
idx++;
this->BuildMakeProgram = allArgs[idx];
}
- if (currentArg.find("--build-config-sample", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-config-sample") &&
idx < allArgs.size() - 1) {
idx++;
this->ConfigSample = allArgs[idx];
}
- if (currentArg.find("--build-noclean", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-noclean")) {
this->BuildNoClean = true;
}
- if (currentArg.find("--build-options", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-options")) {
while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" &&
allArgs[idx + 1] != "--test-command") {
++idx;
this->BuildOptions.push_back(allArgs[idx]);
}
}
- if (currentArg.find("--test-command", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-command") &&
+ idx < allArgs.size() - 1) {
++idx;
this->TestCommand = allArgs[idx];
while (idx + 1 < allArgs.size()) {
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index d1b7701ec..44fdc2945 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -5,7 +5,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 03a3fd306..35c2b1118 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -386,24 +386,20 @@ int cmCTestBuildHandler::ProcessHandler()
if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
std::string srcdir =
this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
- for (cc = srcdir.size() - 2; cc > 0; cc--) {
- if (srcdir[cc] == '/') {
- srcdir = srcdir.substr(0, cc + 1);
- break;
- }
+ cc = srcdir.rfind('/', srcdir.size() - 2);
+ if (cc != std::string::npos) {
+ srcdir.resize(cc + 1);
+ this->SimplifySourceDir = std::move(srcdir);
}
- this->SimplifySourceDir = srcdir;
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
std::string bindir =
this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
- for (cc = bindir.size() - 2; cc > 0; cc--) {
- if (bindir[cc] == '/') {
- bindir = bindir.substr(0, cc + 1);
- break;
- }
+ cc = bindir.rfind('/', bindir.size() - 2);
+ if (cc != std::string::npos) {
+ bindir.resize(cc + 1);
+ this->SimplifyBuildDir = std::move(bindir);
}
- this->SimplifyBuildDir = bindir;
}
// Ok, let's do the build
@@ -545,11 +541,11 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
const char* fname = launchDir.GetFile(i);
if (this->IsLaunchedErrorFile(fname) && numErrorsAllowed) {
numErrorsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalErrors;
} else if (this->IsLaunchedWarningFile(fname) && numWarningsAllowed) {
numWarningsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalWarnings;
}
}
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 45ec39066..1209e06d0 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -152,10 +152,12 @@ private:
this->FinishRevision();
}
} else if (this->Section == SectionRevisions) {
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if (!this->Rev.Log.empty()) {
// Continue the existing log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
} else if (this->Rev.Rev.empty() &&
this->RegexRevision.find(this->Line)) {
this->Rev.Rev = this->RegexRevision.match(1);
@@ -166,7 +168,7 @@ private:
} else if (!this->RegexBranches.find(this->Line)) {
// Start the log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
}
}
return this->Section != SectionEnd;
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 385471081..f42c3f18a 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -6,7 +6,7 @@
#include <sstream>
#include <vector>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be395..7432d0850 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,9 @@
#include <set>
-#include "cm_static_string_view.hxx"
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
@@ -22,7 +22,7 @@ void cmCTestCoverageCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
this->LabelsMentioned =
- !this->Labels.empty() || cmContains(keywords, "LABELS");
+ !this->Labels.empty() || cm::contains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 2c8f11937..b839c10ad 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -680,8 +680,9 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile* mf)
//
#ifdef _WIN32
# define fnc(s) cmSystemTools::LowerCase(s)
+# define fnc_prefix(s, t) fnc(s.substr(0, t.size())) == fnc(t)
#else
-# define fnc(s) s
+# define fnc_prefix(s, t) cmHasPrefix(s, t)
#endif
bool IsFileInDir(const std::string& infile, const std::string& indir)
@@ -689,8 +690,8 @@ bool IsFileInDir(const std::string& infile, const std::string& indir)
std::string file = cmSystemTools::CollapseFullPath(infile);
std::string dir = cmSystemTools::CollapseFullPath(indir);
- return file.size() > dir.size() &&
- fnc(file.substr(0, dir.size())) == fnc(dir) && file[dir.size()] == '/';
+ return file.size() > dir.size() && fnc_prefix(file, dir) &&
+ file[dir.size()] == '/';
}
int cmCTestCoverageHandler::HandlePHPCoverage(
@@ -1214,8 +1215,6 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
while (cmSystemTools::GetLineFromStream(ifile, nl)) {
cnt++;
- // TODO: Handle gcov 3.0 non-coverage lines
-
// Skip empty lines
if (nl.empty()) {
continue;
@@ -1226,6 +1225,14 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
continue;
}
+ // Handle gcov 3.0 non-coverage lines
+ // non-coverage lines seem to always start with something not
+ // a space and don't have a ':' in the 9th position
+ // TODO: Verify that this is actually a robust metric
+ if (nl[0] != ' ' && nl[9] != ':') {
+ continue;
+ }
+
// Read the coverage count from the beginning of the gcov output
// line
std::string prefix = nl.substr(0, 12);
@@ -1709,29 +1716,26 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
// Read the coverage count from the beginning of the Trace.py output
// line
- std::string prefix = nl.substr(0, 6);
- if (prefix[5] != ' ' && prefix[5] != ':') {
- // This is a hack. We should really do something more elaborate
- prefix = nl.substr(0, 7);
- if (prefix[6] != ' ' && prefix[6] != ':') {
- prefix = nl.substr(0, 8);
- if (prefix[7] != ' ' && prefix[7] != ':') {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Currently the limit is maximum coverage of 999999"
- << std::endl);
- }
+ std::string::size_type pos;
+ int cov = 0;
+ // This is a hack. We should really do something more elaborate
+ for (pos = 5; pos < 8; pos++) {
+ if (nl[pos] == ' ') {
+ // This line does not have ':' so no coverage here. That said,
+ // Trace.py does not handle not covered lines versus comments etc.
+ // So, this will be set to 0.
+ break;
+ }
+ if (nl[pos] == ':') {
+ cov = atoi(nl.substr(0, pos - 1).c_str());
+ break;
}
}
- int cov = atoi(prefix.c_str());
- if (prefix[prefix.size() - 1] != ':') {
- // This line does not have ':' so no coverage here. That said,
- // Trace.py does not handle not covered lines versus comments etc.
- // So, this will be set to 0.
- cov = 0;
+ if (pos == 8) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Currently the limit is maximum coverage of 999999"
+ << std::endl);
}
- cmCTestOptionalLog(
- this->CTest, DEBUG,
- "Prefix: " << prefix << " cov: " << cov << std::endl, this->Quiet);
// Read the line number starting at the 10th character of the gcov
// output line
long lineIdx = cnt;
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 9c5ba667e..b0d7f0757 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
class cmCTest;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 3f3c1074f..568b0917c 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -6,6 +6,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
+#include <utility>
#include <vector>
#include "cmsys/FStream.hxx"
@@ -193,7 +194,8 @@ bool cmCTestGIT::UpdateByFetchAndReset()
if (line.find("\tnot-for-merge\t") == std::string::npos) {
std::string::size_type pos = line.find('\t');
if (pos != std::string::npos) {
- sha1 = line.substr(0, pos);
+ sha1 = std::move(line);
+ sha1.resize(pos);
}
}
}
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index b1034c9ff..a755632c5 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,7 +7,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 39dec6d87..d0e297452 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index c1ecaf125..85b8ab15f 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -10,11 +10,12 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmSystemTools.h"
@@ -297,9 +298,6 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf)
this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE",
this->CustomTestsIgnore);
- std::string cmake = cmSystemTools::GetCMakeCommand();
- this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(),
- this->Quiet);
}
int cmCTestMemCheckHandler::GetDefectCount()
@@ -490,31 +488,31 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"AddressSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"LeakSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::LEAK_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"ThreadSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"MemorySanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"UndefinedBehaviorSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
@@ -594,11 +592,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
std::string tempDrMemoryDir =
this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
- if (!cmContains(this->MemoryTesterOptions, "-quiet")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-quiet")) {
this->MemoryTesterOptions.emplace_back("-quiet");
}
- if (!cmContains(this->MemoryTesterOptions, "-batch")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-batch")) {
this->MemoryTesterOptions.emplace_back("-batch");
}
@@ -957,35 +955,25 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
"valgrind line " << lines[cc] << std::endl,
this->Quiet);
int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
- if (vgFIM.find(lines[cc])) {
+ auto& line = lines[cc];
+ if (vgFIM.find(line)) {
failure = cmCTestMemCheckHandler::FIM;
- } else if (vgFMM.find(lines[cc])) {
+ } else if (vgFMM.find(line)) {
failure = cmCTestMemCheckHandler::FMM;
- } else if (vgMLK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MLK;
- } else if (vgMLK2.find(lines[cc])) {
+ } else if (vgMLK1.find(line) || vgMLK2.find(line)) {
failure = cmCTestMemCheckHandler::MLK;
- } else if (vgPAR.find(lines[cc])) {
+ } else if (vgPAR.find(line)) {
failure = cmCTestMemCheckHandler::PAR;
- } else if (vgMPK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MPK;
- } else if (vgMPK2.find(lines[cc])) {
+ } else if (vgMPK1.find(line) || vgMPK2.find(line)) {
failure = cmCTestMemCheckHandler::MPK;
- } else if (vgUMC.find(lines[cc])) {
+ } else if (vgUMC.find(line)) {
failure = cmCTestMemCheckHandler::UMC;
- } else if (vgUMR1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR2.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR3.find(lines[cc])) {
+ } else if (vgUMR1.find(line) || vgUMR2.find(line) || vgUMR3.find(line) ||
+ vgUMR4.find(line) || vgUMR5.find(line)) {
failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR4.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR5.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgIPW.find(lines[cc])) {
+ } else if (vgIPW.find(line)) {
failure = cmCTestMemCheckHandler::IPW;
- } else if (vgABR.find(lines[cc])) {
+ } else if (vgABR.find(line)) {
failure = cmCTestMemCheckHandler::ABR;
}
@@ -1049,13 +1037,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckDrMemoryOutput(
ostr << l << std::endl;
if (drMemoryError.find(l)) {
defects++;
- if (unaddressableAccess.find(l)) {
+ if (unaddressableAccess.find(l) || uninitializedRead.find(l)) {
results[cmCTestMemCheckHandler::UMR]++;
- } else if (uninitializedRead.find(l)) {
- results[cmCTestMemCheckHandler::UMR]++;
- } else if (leak.find(l)) {
- results[cmCTestMemCheckHandler::MLK]++;
- } else if (handleLeak.find(l)) {
+ } else if (leak.find(l) || handleLeak.find(l)) {
results[cmCTestMemCheckHandler::MLK]++;
} else if (invalidHeapArgument.find(l)) {
results[cmCTestMemCheckHandler::FMM]++;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 2192843ec..a08cb3480 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -6,30 +6,29 @@
#include <cassert>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
-#include <memory>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <utility>
#include <vector>
+#include <cm/memory>
#include <cmext/algorithm>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+#include <cm3p/uv.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#include "cm_uv.h"
-
#include "cmAffinity.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestBinPacker.h"
#include "cmCTestRunTest.h"
@@ -138,7 +137,7 @@ void cmCTestMultiProcessHandler::RunTests()
uv_run(&this->Loop, UV_RUN_DEFAULT);
uv_loop_close(&this->Loop);
- if (!this->StopTimePassed) {
+ if (!this->StopTimePassed && !this->CheckStopOnFailure()) {
assert(this->Completed == this->Total);
assert(this->Tests.empty());
}
@@ -172,7 +171,8 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
- cmCTestRunTest* testRun = new cmCTestRunTest(*this);
+ auto testRun = cm::make_unique<cmCTestRunTest>(*this);
+
if (this->RepeatMode != cmCTest::Repeat::Never) {
testRun->SetRepeatMode(this->RepeatMode);
testRun->SetNumberOfRuns(this->RepeatCount);
@@ -187,7 +187,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// Find any failed dependencies for this test. We assume the more common
// scenario has no failed tests, so make it the outer loop.
for (std::string const& f : *this->Failed) {
- if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
+ if (cm::contains(this->Properties[test]->RequireSuccessDepends, f)) {
testRun->AddFailedDependency(f);
}
}
@@ -229,28 +229,25 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
e << "\n";
}
e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
- testRun->StartFailure(e.str(), "Insufficient resources");
- this->FinishTestProcess(testRun, false);
+ cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ "Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- testRun->StartFailure("Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
- } else {
- if (testRun->StartTest(this->Completed, this->Total)) {
- // Ownership of 'testRun' has moved to another structure.
- // When the test finishes, FinishTestProcess will be called.
- return true;
- }
+ cmCTestRunTest::StartFailure(std::move(testRun),
+ "Failed to change working directory to " +
+ this->Properties[test]->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
+ return false;
}
- // Pass ownership of 'testRun'.
- this->FinishTestProcess(testRun, false);
- return false;
+ // Ownership of 'testRun' has moved to another structure.
+ // When the test finishes, FinishTestProcess will be called.
+ return cmCTestRunTest::StartTest(std::move(testRun), this->Completed,
+ this->Total);
}
bool cmCTestMultiProcessHandler::AllocateResources(int index)
@@ -370,6 +367,11 @@ void cmCTestMultiProcessHandler::CheckResourcesAvailable()
}
}
+bool cmCTestMultiProcessHandler::CheckStopOnFailure()
+{
+ return this->CTest->GetStopOnFailure();
+}
+
bool cmCTestMultiProcessHandler::CheckStopTimePassed()
{
if (!this->StopTimePassed) {
@@ -447,7 +449,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
{
// Check for locked resources
for (std::string const& i : this->Properties[test]->LockedResources) {
- if (cmContains(this->LockedResources, i)) {
+ if (cm::contains(this->LockedResources, i)) {
return false;
}
}
@@ -486,6 +488,10 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ if (this->CheckStopOnFailure() && !this->Failed->empty()) {
+ return;
+ }
+
size_t numToStart = 0;
if (this->RunningCount < this->ParallelLevel) {
@@ -540,7 +546,8 @@ void cmCTestMultiProcessHandler::StartNextTests()
if (this->SerialTestRunning) {
break;
}
- // We can only start a RUN_SERIAL test if no other tests are also running.
+ // We can only start a RUN_SERIAL test if no other tests are also
+ // running.
if (this->Properties[test]->RunSerial && this->RunningCount > 0) {
continue;
}
@@ -618,8 +625,8 @@ void cmCTestMultiProcessHandler::OnTestLoadRetryCB(uv_timer_t* timer)
self->StartNextTests();
}
-void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
- bool started)
+void cmCTestMultiProcessHandler::FinishTestProcess(
+ std::unique_ptr<cmCTestRunTest> runner, bool started)
{
this->Completed++;
@@ -631,7 +638,8 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->SetStopTimePassed();
}
if (started) {
- if (!this->StopTimePassed && runner->StartAgain(this->Completed)) {
+ if (!this->StopTimePassed &&
+ cmCTestRunTest::StartAgain(std::move(runner), this->Completed)) {
this->Completed--; // remove the completed test because run again
return;
}
@@ -659,7 +667,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
}
properties->Affinity.clear();
- delete runner;
+ runner.reset();
if (started) {
this->StartNextTests();
}
@@ -802,7 +810,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// In parallel test runs add previously failed tests to the front
// of the cost list and queue other tests for further sorting
for (auto const& t : this->Tests) {
- if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
+ if (cm::contains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
// If the test failed last time, it should be run first.
this->SortedTests.push_back(t.first);
alreadySortedTests.insert(t.first);
@@ -841,7 +849,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
TestComparator(this));
for (auto const& j : sortedCopy) {
- if (!cmContains(alreadySortedTests, j)) {
+ if (!cm::contains(alreadySortedTests, j)) {
this->SortedTests.push_back(j);
alreadySortedTests.insert(j);
}
@@ -873,7 +881,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
TestSet alreadySortedTests;
for (int test : presortedList) {
- if (cmContains(alreadySortedTests, test)) {
+ if (cm::contains(alreadySortedTests, test)) {
continue;
}
@@ -881,7 +889,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
- if (!cmContains(alreadySortedTests, testDependency)) {
+ if (!cm::contains(alreadySortedTests, testDependency)) {
alreadySortedTests.insert(testDependency);
this->SortedTests.push_back(testDependency);
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 5b429d4ae..e21b912c7 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,14 +6,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
-#include "cm_uv.h"
-
#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
@@ -124,7 +124,7 @@ protected:
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
- void FinishTestProcess(cmCTestRunTest* runner, bool started);
+ void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
static void OnTestLoadRetryCB(uv_timer_t* timer);
@@ -137,6 +137,8 @@ protected:
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
+ bool CheckStopOnFailure();
+
bool CheckStopTimePassed();
void SetStopTimePassed();
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 8f91efb45..21c97de34 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -7,12 +7,12 @@
#include <utility>
#include <vector>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-
static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 58289ea50..2c8e3855f 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -3,7 +3,7 @@
#include "cmCTestRunTest.h"
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <cstdio>
#include <cstring>
@@ -314,23 +314,27 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
return passed || skipped;
}
-bool cmCTestRunTest::StartAgain(size_t completed)
+bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed)
{
- if (!this->RunAgain) {
+ auto* testRun = runner.get();
+
+ if (!testRun->RunAgain) {
return false;
}
- this->RunAgain = false; // reset
+ testRun->RunAgain = false; // reset
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
// change to tests directory
- cmWorkingDirectory workdir(this->TestProperties->Directory);
+ cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- this->StartFailure("Failed to change working directory to " +
- this->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()),
- "Failed to change working directory");
+ testRun->StartFailure("Failed to change working directory to " +
+ testRun->TestProperties->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
return true;
}
- this->StartTest(completed, this->TotalNumberOfTests);
+ testRun->StartTest(completed, testRun->TotalNumberOfTests);
return true;
}
@@ -387,6 +391,18 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index);
}
+void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+ testRun->StartFailure(output, detail);
+
+ testRun->FinalizeTest(false);
+}
+
void cmCTestRunTest::StartFailure(std::string const& output,
std::string const& detail)
{
@@ -418,7 +434,7 @@ void cmCTestRunTest::StartFailure(std::string const& output,
this->TestResult.Path = this->TestProperties->Directory;
this->TestResult.Output = output;
this->TestResult.FullCommandLine.clear();
- this->TestProcess = cm::make_unique<cmProcess>(*this);
+ this->TestResult.Environment.clear();
}
std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -442,6 +458,21 @@ std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
return outputStream.str();
}
+bool cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+
+ if (!testRun->StartTest(completed, total)) {
+ testRun->FinalizeTest(false);
+ return false;
+ }
+
+ return true;
+}
+
// Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t completed, size_t total)
{
@@ -473,9 +504,9 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->TestProperties->Disabled) {
this->TestResult.CompletionStatus = "Disabled";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestResult.Output = "Disabled";
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
return false;
}
@@ -487,7 +518,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
// its arguments are irrelevant. This matters for the case where a fixture
// dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg = "Failed test dependencies:";
for (std::string const& failedDep : this->FailedDependencies) {
msg += " " + failedDep;
@@ -496,6 +526,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl);
this->TestResult.Output = msg;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Fixture dependency failed";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -504,7 +535,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
msg = "Test not available without configuration. (Missing \"-C "
@@ -517,6 +547,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
this->TestResult.Output = msg;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Missing Configuration";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -526,13 +557,13 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
for (std::string const& file : this->TestProperties->RequiredFiles) {
if (!cmSystemTools::FileExists(file)) {
// Required file was not found
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find required file: " << file
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to find required file: " << file << std::endl);
this->TestResult.Output = "Unable to find required file: " + file;
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Required Files Missing";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -542,13 +573,13 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->ActualCommand.empty()) {
// if the command was not found create a TestResult object
// that has that information
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find executable: " << args[1]
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unable to find executable: " << args[1] << std::endl);
this->TestResult.Output = "Unable to find executable: " + args[1];
this->TestResult.FullCommandLine.clear();
+ this->TestResult.Environment.clear();
this->TestResult.CompletionStatus = "Unable to find executable";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
return false;
@@ -654,7 +685,6 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
std::vector<std::string>* environment,
std::vector<size_t>* affinity)
{
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
this->TestProcess->SetCommand(this->ActualCommand);
@@ -694,25 +724,43 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
cmSystemTools::SaveRestoreEnvironment sre;
#endif
+ std::ostringstream envMeasurement;
if (environment && !environment->empty()) {
cmSystemTools::AppendEnv(*environment);
+ for (auto const& var : *environment) {
+ envMeasurement << var << std::endl;
+ }
}
if (this->UseAllocatedResources) {
- this->SetupResourcesEnvironment();
+ std::vector<std::string> envLog;
+ this->SetupResourcesEnvironment(&envLog);
+ for (auto const& var : envLog) {
+ envMeasurement << var << std::endl;
+ }
} else {
cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT");
+ // Signify that this variable is being actively unset
+ envMeasurement << "#CTEST_RESOURCE_GROUP_COUNT=" << std::endl;
}
+ this->TestResult.Environment = envMeasurement.str();
+ // Remove last newline
+ this->TestResult.Environment.erase(this->TestResult.Environment.length() -
+ 1);
+
return this->TestProcess->StartProcess(this->MultiTestHandler.Loop,
affinity);
}
-void cmCTestRunTest::SetupResourcesEnvironment()
+void cmCTestRunTest::SetupResourcesEnvironment(std::vector<std::string>* log)
{
std::string processCount = "CTEST_RESOURCE_GROUP_COUNT=";
processCount += std::to_string(this->AllocatedResources.size());
cmSystemTools::PutEnv(processCount);
+ if (log) {
+ log->push_back(processCount);
+ }
std::size_t i = 0;
for (auto const& process : this->AllocatedResources) {
@@ -738,8 +786,14 @@ void cmCTestRunTest::SetupResourcesEnvironment()
var += "id:" + it2.Id + ",slots:" + std::to_string(it2.Slots);
}
cmSystemTools::PutEnv(var);
+ if (log) {
+ log->push_back(var);
+ }
}
cmSystemTools::PutEnv(resourceList);
+ if (log) {
+ log->push_back(resourceList);
+ }
++i;
}
}
@@ -821,7 +875,8 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
"Testing " << this->TestProperties->Name << " ... ");
}
-void cmCTestRunTest::FinalizeTest()
+void cmCTestRunTest::FinalizeTest(bool started)
{
- this->MultiTestHandler.FinishTestProcess(this, true);
+ this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(),
+ started);
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 4988839b0..d831247e1 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -65,6 +65,15 @@ public:
// Read and store output. Returns true if it must be called again.
void CheckOutput(std::string const& line);
+ static bool StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total);
+ static bool StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed);
+
+ static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail);
+
// launch the test process, return whether it started correctly
bool StartTest(size_t completed, size_t total);
// capture and report the test results
@@ -74,8 +83,6 @@ public:
void ComputeWeightedCost();
- bool StartAgain(size_t completed);
-
void StartFailure(std::string const& output, std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
@@ -84,7 +91,7 @@ public:
const std::vector<std::string>& GetArguments() { return this->Arguments; }
- void FinalizeTest();
+ void FinalizeTest(bool started = true);
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
@@ -112,7 +119,7 @@ private:
// Run post processing of the process output for MemCheck
void MemCheckPostProcess();
- void SetupResourcesEnvironment();
+ void SetupResourcesEnvironment(std::vector<std::string>* log = nullptr);
// Returns "completed/total Test #Index: "
std::string GetTestPrefix(size_t completed, size_t total) const;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7803e3764..4fa4dc0da 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -6,7 +6,6 @@
#include <cstdlib>
#include <cstring>
#include <map>
-#include <memory>
#include <ratio>
#include <sstream>
#include <utility>
@@ -51,22 +50,7 @@
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
-cmCTestScriptHandler::cmCTestScriptHandler()
-{
- this->Backup = false;
- this->EmptyBinDir = false;
- this->EmptyBinDirOnce = false;
- this->Makefile = nullptr;
- this->ParentMakefile = nullptr;
- this->CMake = nullptr;
- this->GlobalGenerator = nullptr;
-
- this->ScriptStartTime = std::chrono::steady_clock::time_point();
-
- // the *60 is because the settings are in minutes but GetTime is seconds
- this->MinimumInterval = 30 * 60;
- this->ContinuousDuration = -1;
-}
+cmCTestScriptHandler::cmCTestScriptHandler() = default;
void cmCTestScriptHandler::Initialize()
{
@@ -95,22 +79,15 @@ void cmCTestScriptHandler::Initialize()
// what time in seconds did this script start running
this->ScriptStartTime = std::chrono::steady_clock::time_point();
- delete this->Makefile;
- this->Makefile = nullptr;
+ this->Makefile.reset();
this->ParentMakefile = nullptr;
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
+ this->GlobalGenerator.reset();
- delete this->CMake;
+ this->CMake.reset();
}
-cmCTestScriptHandler::~cmCTestScriptHandler()
-{
- delete this->Makefile;
- delete this->GlobalGenerator;
- delete this->CMake;
-}
+cmCTestScriptHandler::~cmCTestScriptHandler() = default;
// just adds an argument to the vector
void cmCTestScriptHandler::AddConfigurationScript(const char* script,
@@ -247,23 +224,20 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
void cmCTestScriptHandler::CreateCMake()
{
// create a cmake instance to read the configuration script
- if (this->CMake) {
- delete this->CMake;
- delete this->GlobalGenerator;
- delete this->Makefile;
- }
- this->CMake = new cmake(cmake::RoleScript, cmState::CTest);
+ this->CMake = cm::make_unique<cmake>(cmake::RoleScript, cmState::CTest);
this->CMake->SetHomeDirectory("");
this->CMake->SetHomeOutputDirectory("");
this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
this->CMake->AddCMakePaths();
- this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
+ this->GlobalGenerator =
+ cm::make_unique<cmGlobalGenerator>(this->CMake.get());
cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
snapshot.GetDirectory().SetCurrentSource(cwd);
snapshot.GetDirectory().SetCurrentBinary(cwd);
- this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+ this->Makefile =
+ cm::make_unique<cmMakefile>(this->GlobalGenerator.get(), snapshot);
if (this->ParentMakefile) {
this->Makefile->SetRecursionDepth(
this->ParentMakefile->GetRecursionDepth());
@@ -310,12 +284,14 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
// if the argument has a , in it then it needs to be broken into the fist
// argument (which is the script) and the second argument which will be
// passed into the scripts as S_ARG
- std::string script = total_script_arg;
+ std::string script;
std::string script_arg;
const std::string::size_type comma_pos = total_script_arg.find(',');
if (comma_pos != std::string::npos) {
script = total_script_arg.substr(0, comma_pos);
script_arg = total_script_arg.substr(comma_pos + 1);
+ } else {
+ script = total_script_arg;
}
// make sure the file exists
if (!cmSystemTools::FileExists(script)) {
@@ -878,7 +854,7 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
const char* sname, bool InProcess,
int* returnValue)
{
- cmCTestScriptHandler* sh = new cmCTestScriptHandler();
+ auto sh = cm::make_unique<cmCTestScriptHandler>();
sh->SetCTestInstance(ctest);
sh->ParentMakefile = mf;
sh->AddConfigurationScript(sname, InProcess);
@@ -886,7 +862,6 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
if (returnValue) {
*returnValue = res;
}
- delete sh;
return true;
}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d0031990b..ebb79055f 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -101,12 +101,14 @@ public:
cmDuration GetRemainingTimeAllowed();
cmCTestScriptHandler();
+ cmCTestScriptHandler(const cmCTestScriptHandler&) = delete;
+ const cmCTestScriptHandler& operator=(const cmCTestScriptHandler&) = delete;
~cmCTestScriptHandler() override;
void Initialize() override;
void CreateCMake();
- cmake* GetCMake() { return this->CMake; }
+ cmake* GetCMake() { return this->CMake.get(); }
void SetRunCurrentScript(bool value);
@@ -143,9 +145,9 @@ private:
bool ShouldRunCurrentScript;
- bool Backup;
- bool EmptyBinDir;
- bool EmptyBinDirOnce;
+ bool Backup = false;
+ bool EmptyBinDir = false;
+ bool EmptyBinDirOnce = false;
std::string SourceDir;
std::string BinaryDir;
@@ -161,16 +163,18 @@ private:
std::string CMOutFile;
std::vector<std::string> ExtraUpdates;
- double MinimumInterval;
- double ContinuousDuration;
+ // the *60 is because the settings are in minutes but GetTime is seconds
+ double MinimumInterval = 30 * 60;
+ double ContinuousDuration = -1;
// what time in seconds did this script start running
- std::chrono::steady_clock::time_point ScriptStartTime;
+ std::chrono::steady_clock::time_point ScriptStartTime =
+ std::chrono::steady_clock::time_point();
- cmMakefile* Makefile;
- cmMakefile* ParentMakefile;
- cmGlobalGenerator* GlobalGenerator;
- cmake* CMake;
+ std::unique_ptr<cmMakefile> Makefile;
+ cmMakefile* ParentMakefile = nullptr;
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
+ std::unique_ptr<cmake> CMake;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index acb75b2ed..279216eeb 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,10 +8,9 @@
#include <cm/memory>
#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
@@ -172,8 +171,10 @@ void cmCTestSubmitCommand::BindArguments()
void cmCTestSubmitCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
- this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
- this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+ this->PartsMentioned =
+ !this->Parts.empty() || cm::contains(keywords, "PARTS");
+ this->FilesMentioned =
+ !this->Files.empty() || cm::contains(keywords, "FILES");
cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 22ab48f57..ea36df54a 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -9,9 +9,9 @@
#include <cmext/algorithm>
-#include "cm_curl.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
+#include <cm3p/curl/curl.h>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
#include "cmAlgorithms.h"
#include "cmCTest.h"
@@ -21,6 +21,7 @@
#include "cmCurl.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -260,11 +261,10 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
if (cm) {
- const char* subproject =
- cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
upload_as += "&subproject=";
- upload_as += ctest_curl.Escape(subproject);
+ upload_as += ctest_curl.Escape(*subproject);
}
}
}
@@ -506,18 +506,19 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
std::string url = this->CTest->GetSubmitURL();
- std::string fields;
- std::string::size_type pos = url.find('?');
- if (pos != std::string::npos) {
- fields = url.substr(pos + 1);
- url = url.substr(0, pos);
- }
if (!cmHasLiteralPrefix(url, "http://") &&
!cmHasLiteralPrefix(url, "https://")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
}
+
+ std::string fields;
+ std::string::size_type pos = url.find('?');
+ if (pos != std::string::npos) {
+ fields = url.substr(pos + 1);
+ url.erase(pos);
+ }
bool internalTest = cmIsOn(this->GetOption("InternalTest"));
// Get RETRY_COUNT and RETRY_DELAY values if they were set.
@@ -555,11 +556,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
// a "&subproject=subprojectname" to the first POST.
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
- const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
// TODO: Encode values for a URL instead of trusting caller.
std::ostringstream str;
if (subproject) {
- str << "subproject=" << curl.Escape(subproject) << "&";
+ str << "subproject=" << curl.Escape(*subproject) << "&";
}
auto timeNow =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 0f9b6958d..c71b409ff 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -6,7 +6,7 @@
#include <cstdlib>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
@@ -34,6 +34,7 @@ void cmCTestTestCommand::BindArguments()
this->Bind("STOP_TIME"_s, this->StopTime);
this->Bind("TEST_LOAD"_s, this->TestLoad);
this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
+ this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -52,6 +53,13 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
}
}
this->CTest->SetTimeOut(timeout);
+
+ const char* resourceSpecFile =
+ this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && resourceSpecFile) {
+ this->ResourceSpecFile = resourceSpecFile;
+ }
+
cmCTestGenericHandler* handler = this->InitializeActualHandler();
if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
handler->SetOption(
@@ -83,6 +91,9 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
handler->SetOption("ExcludeFixtureCleanupRegularExpression",
this->ExcludeFixtureCleanup.c_str());
}
+ if (this->StopOnFailure) {
+ handler->SetOption("StopOnFailure", "ON");
+ }
if (!this->ParallelLevel.empty()) {
handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 2345afbcf..792558679 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -60,6 +60,7 @@ protected:
std::string StopTime;
std::string TestLoad;
std::string ResourceSpecFile;
+ bool StopOnFailure = false;
};
#endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4f324ea6d..d0dbaae81 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -5,7 +5,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -18,6 +18,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include <cmsys/Base64.h>
@@ -26,7 +29,6 @@
#include "cm_utf8.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestResourceGroupsLexerHelper.h"
@@ -406,7 +408,9 @@ int cmCTestTestHandler::ProcessHandler()
// start the real time clock
auto clock_start = std::chrono::steady_clock::now();
- this->ProcessDirectory(passed, failed);
+ if (!this->ProcessDirectory(passed, failed)) {
+ return -1;
+ }
auto clock_finish = std::chrono::steady_clock::now();
@@ -510,6 +514,10 @@ bool cmCTestTestHandler::ProcessOptions()
this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
}
+ if (this->GetOption("StopOnFailure")) {
+ this->CTest->SetStopOnFailure(true);
+ }
+
const char* val;
val = this->GetOption("LabelRegularExpression");
if (val) {
@@ -543,22 +551,11 @@ bool cmCTestTestHandler::ProcessOptions()
if (val) {
this->ExcludeFixtureCleanupRegExp = val;
}
- this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
-
val = this->GetOption("ResourceSpecFile");
if (val) {
- this->UseResourceSpec = true;
this->ResourceSpecFile = val;
- auto result = this->ResourceSpec.ReadFromJSONFile(val);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Could not read/parse resource spec file "
- << val << ": "
- << cmCTestResourceSpec::ResultToString(result)
- << std::endl);
- return false;
- }
}
+ this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
return true;
}
@@ -718,7 +715,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestTestProperties& p = *result.Properties;
for (std::string const& l : p.Labels) {
// only use labels found in labels
- if (cmContains(labels, l)) {
+ if (cm::contains(labels, l)) {
labelTimes[l] +=
result.ExecutionTime.count() * result.Properties->Processors;
++labelCounts[l];
@@ -860,14 +857,15 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion) {
// if it is not in the list and not in the regexp then skip
- if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) &&
+ if ((!this->TestsToRun.empty() &&
+ !cm::contains(this->TestsToRun, cnt)) &&
!tp.IsInBasedOnREOptions) {
continue;
}
} else {
// is this test in the list of tests to run? If not then skip it
if ((!this->TestsToRun.empty() &&
- !cmContains(this->TestsToRun, inREcnt)) ||
+ !cm::contains(this->TestsToRun, inREcnt)) ||
!tp.IsInBasedOnREOptions) {
continue;
}
@@ -896,7 +894,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
+ if (!this->TestsToRun.empty() && !cm::contains(this->TestsToRun, cnt)) {
continue;
}
@@ -1015,7 +1013,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
const std::string& setupTestName = sIt->second->Name;
tests[i].RequireSuccessDepends.insert(setupTestName);
- if (!cmContains(tests[i].Depends, setupTestName)) {
+ if (!cm::contains(tests[i].Depends, setupTestName)) {
tests[i].Depends.push_back(setupTestName);
}
}
@@ -1119,7 +1117,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& reqTestName = tests[index].Name;
- if (!cmContains(p.Depends, reqTestName)) {
+ if (!cm::contains(p.Depends, reqTestName)) {
p.Depends.push_back(reqTestName);
}
}
@@ -1132,7 +1130,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& setupTestName = tests[index].Name;
- if (!cmContains(p.Depends, setupTestName)) {
+ if (!cm::contains(p.Depends, setupTestName)) {
p.Depends.push_back(setupTestName);
}
}
@@ -1259,7 +1257,7 @@ bool cmCTestTestHandler::GetValue(const char* tag, std::string& value,
return ret;
}
-void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
+bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed)
{
this->ComputeTestList();
@@ -1267,7 +1265,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
this->StartTestTime = std::chrono::system_clock::now();
auto elapsed_time_start = std::chrono::steady_clock::now();
- cmCTestMultiProcessHandler* parallel = new cmCTestMultiProcessHandler;
+ auto parallel = cm::make_unique<cmCTestMultiProcessHandler>();
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
@@ -1283,7 +1281,17 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
- if (this->UseResourceSpec) {
+ if (!this->ResourceSpecFile.empty()) {
+ this->UseResourceSpec = true;
+ auto result = this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile);
+ if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not read/parse resource spec file "
+ << this->ResourceSpecFile << ": "
+ << cmCTestResourceSpec::ResultToString(result)
+ << std::endl);
+ return false;
+ }
parallel->InitResourceAllocator(this->ResourceSpec);
}
@@ -1338,12 +1346,13 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->RunTests();
}
- delete parallel;
this->EndTest = this->CTest->CurrentTime();
this->EndTestTime = std::chrono::system_clock::now();
this->ElapsedTestingTime =
std::chrono::steady_clock::now() - elapsed_time_start;
*this->LogFile << "End testing: " << this->CTest->CurrentTime() << std::endl;
+
+ return true;
}
void cmCTestTestHandler::GenerateTestCommand(
@@ -1423,6 +1432,12 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
xml.Attribute("name", "Command Line");
xml.Element("Value", result.FullCommandLine);
xml.EndElement(); // NamedMeasurement
+
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("type", "text/string");
+ xml.Attribute("name", "Environment");
+ xml.Element("Value", result.Environment);
+ xml.EndElement(); // NamedMeasurement
for (auto const& measure : result.Properties->Measurements) {
xml.StartElement("NamedMeasurement");
xml.Attribute("type", "text/string");
@@ -1742,6 +1757,10 @@ void cmCTestTestHandler::GetListOfTests()
if (cmSystemTools::GetErrorOccuredFlag()) {
return;
}
+ const char* specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && specFile) {
+ this->ResourceSpecFile = specFile;
+ }
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Done constructing a list of tests" << std::endl,
this->Quiet);
@@ -1894,7 +1913,8 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
continue;
}
- int val = atoi(line.substr(0, pos).c_str());
+ line.erase(pos);
+ int val = atoi(line.c_str());
this->TestsToRun.push_back(val);
}
ifs.close();
@@ -2016,13 +2036,13 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
| std::ios::binary
#endif
);
- unsigned char* file_buffer = new unsigned char[len + 1];
- ifs.read(reinterpret_cast<char*>(file_buffer), len);
- unsigned char* encoded_buffer = new unsigned char[static_cast<int>(
- static_cast<double>(len) * 1.5 + 5.0)];
+ auto file_buffer = cm::make_unique<unsigned char[]>(len + 1);
+ ifs.read(reinterpret_cast<char*>(file_buffer.get()), len);
+ auto encoded_buffer = cm::make_unique<unsigned char[]>(
+ static_cast<int>(static_cast<double>(len) * 1.5 + 5.0));
- size_t rlen =
- cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+ size_t rlen = cmsysBase64_Encode(file_buffer.get(), len,
+ encoded_buffer.get(), 1);
xml.StartElement("NamedMeasurement");
xml.Attribute(measurementfile.match(1).c_str(),
@@ -2039,8 +2059,6 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
}
xml.Element("Value", ostr.str());
xml.EndElement(); // NamedMeasurement
- delete[] file_buffer;
- delete[] encoded_buffer;
}
} else {
int idx = 4;
@@ -2085,19 +2103,18 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
if (cmSystemTools::FileExists(in)) {
cmsys::ifstream fin(in);
unsigned long filelen = cmSystemTools::FileLength(in);
- char* buff = new char[filelen + 1];
- fin.getline(buff, filelen);
+ auto buff = cm::make_unique<char[]>(filelen + 1);
+ fin.getline(buff.get(), filelen);
buff[fin.gcount()] = 0;
- this->TestsToRunString = buff;
- delete[] buff;
+ this->TestsToRunString = buff.get();
}
}
-bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
{
if (!length || length >= output.size() ||
output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
- return true;
+ return;
}
// Truncate at given length but do not break in the middle of a multi-byte
@@ -2118,7 +2135,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
++current;
}
}
- output = output.substr(0, current - begin);
+ output.erase(current - begin);
// Append truncation message.
std::ostringstream msg;
@@ -2128,7 +2145,6 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
"of "
<< length << " bytes.\n";
output += msg.str();
- return true;
}
bool cmCTestTestHandler::SetTestsProperties(
@@ -2149,16 +2165,16 @@ bool cmCTestTestHandler::SetTestsProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (std::string const& t : tests) {
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
- if (key == "_BACKTRACE_TRIPLES") {
+ if (key == "_BACKTRACE_TRIPLES"_s) {
std::vector<std::string> triples;
// allow empty args in the triples
cmExpandList(val, triples, true);
@@ -2182,91 +2198,70 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Backtrace = rt.Backtrace.Push(fc);
}
}
- }
- if (key == "WILL_FAIL") {
+ } else if (key == "WILL_FAIL"_s) {
rt.WillFail = cmIsOn(val);
- }
- if (key == "DISABLED") {
+ } else if (key == "DISABLED"_s) {
rt.Disabled = cmIsOn(val);
- }
- if (key == "ATTACHED_FILES") {
+ } else if (key == "ATTACHED_FILES"_s) {
cmExpandList(val, rt.AttachedFiles);
- }
- if (key == "ATTACHED_FILES_ON_FAIL") {
+ } else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
cmExpandList(val, rt.AttachOnFail);
- }
- if (key == "RESOURCE_LOCK") {
+ } else if (key == "RESOURCE_LOCK"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.LockedResources.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_SETUP") {
+ } else if (key == "FIXTURES_SETUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesSetup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_CLEANUP") {
+ } else if (key == "FIXTURES_CLEANUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesCleanup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_REQUIRED") {
+ } else if (key == "FIXTURES_REQUIRED"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesRequired.insert(lval.begin(), lval.end());
- }
- if (key == "TIMEOUT") {
+ } else if (key == "TIMEOUT"_s) {
rt.Timeout = cmDuration(atof(val.c_str()));
rt.ExplicitTimeout = true;
- }
- if (key == "COST") {
+ } else if (key == "COST"_s) {
rt.Cost = static_cast<float>(atof(val.c_str()));
- }
- if (key == "REQUIRED_FILES") {
+ } else if (key == "REQUIRED_FILES"_s) {
cmExpandList(val, rt.RequiredFiles);
- }
- if (key == "RUN_SERIAL") {
+ } else if (key == "RUN_SERIAL"_s) {
rt.RunSerial = cmIsOn(val);
- }
- if (key == "FAIL_REGULAR_EXPRESSION") {
+ } else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "SKIP_REGULAR_EXPRESSION") {
+ } else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "PROCESSORS") {
+ } else if (key == "PROCESSORS"_s) {
rt.Processors = atoi(val.c_str());
if (rt.Processors < 1) {
rt.Processors = 1;
}
- }
- if (key == "PROCESSOR_AFFINITY") {
+ } else if (key == "PROCESSOR_AFFINITY"_s) {
rt.WantAffinity = cmIsOn(val);
- }
- if (key == "RESOURCE_GROUPS") {
+ } else if (key == "RESOURCE_GROUPS"_s) {
if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
return false;
}
- }
- if (key == "SKIP_RETURN_CODE") {
+ } else if (key == "SKIP_RETURN_CODE"_s) {
rt.SkipReturnCode = atoi(val.c_str());
if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
rt.SkipReturnCode = -1;
}
- }
- if (key == "DEPENDS") {
+ } else if (key == "DEPENDS"_s) {
cmExpandList(val, rt.Depends);
- }
- if (key == "ENVIRONMENT") {
+ } else if (key == "ENVIRONMENT"_s) {
cmExpandList(val, rt.Environment);
- }
- if (key == "LABELS") {
+ } else if (key == "LABELS"_s) {
std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
@@ -2274,8 +2269,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// remove duplicates
auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
rt.Labels.erase(new_end, rt.Labels.end());
- }
- if (key == "MEASUREMENT") {
+ } else if (key == "MEASUREMENT"_s) {
size_t pos = val.find_first_of('=');
if (pos != std::string::npos) {
std::string mKey = val.substr(0, pos);
@@ -2284,17 +2278,14 @@ bool cmCTestTestHandler::SetTestsProperties(
} else {
rt.Measurements[val] = "1";
}
- }
- if (key == "PASS_REGULAR_EXPRESSION") {
+ } else if (key == "PASS_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "WORKING_DIRECTORY") {
+ } else if (key == "WORKING_DIRECTORY"_s) {
rt.Directory = val;
- }
- if (key == "TIMEOUT_AFTER_MATCH") {
+ } else if (key == "TIMEOUT_AFTER_MATCH"_s) {
std::vector<std::string> propArgs = cmExpandedList(val);
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
@@ -2334,16 +2325,16 @@ bool cmCTestTestHandler::SetDirectoryProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (cmCTestTestProperties& rt : this->TestList) {
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
- if (key == "LABELS") {
+ if (key == "LABELS"_s) {
std::vector<std::string> DirectoryLabels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
@@ -2422,10 +2413,9 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
test.SkipReturnCode = -1;
test.PreviousRuns = 0;
if (this->UseIncludeRegExpFlag &&
- !this->IncludeTestsRegularExpression.find(testname)) {
- test.IsInBasedOnREOptions = false;
- } else if (this->UseExcludeRegExpFlag && !this->UseExcludeRegExpFirst &&
- this->ExcludeTestsRegularExpression.find(testname)) {
+ (!this->IncludeTestsRegularExpression.find(testname) ||
+ (!this->UseExcludeRegExpFirst &&
+ this->ExcludeTestsRegularExpression.find(testname)))) {
test.IsInBasedOnREOptions = false;
}
this->TestList.push_back(test);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index b1c875502..0d88c306f 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -169,6 +169,7 @@ public:
std::string Path;
std::string Reason;
std::string FullCommandLine;
+ std::string Environment;
cmDuration ExecutionTime;
std::int64_t ReturnValue;
int Status;
@@ -235,7 +236,7 @@ protected:
void AttachFiles(cmXMLWriter& xml, cmCTestTestResult& result);
//! Clean test output to specified length
- bool CleanTestOutput(std::string& output, size_t length);
+ void CleanTestOutput(std::string& output, size_t length);
cmDuration ElapsedTestingTime;
@@ -278,7 +279,7 @@ private:
/**
* Run the tests for a directory and any subdirectories
*/
- void ProcessDirectory(std::vector<std::string>& passed,
+ bool ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed);
/**
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index eaef1ca6a..f86ee0d7c 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -6,8 +6,7 @@
#include <sstream>
#include <cm/vector>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6026c69bb..452d7143b 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -38,7 +38,7 @@ void cmCTestVC::SetSourceDirectory(std::string const& dir)
this->SourceDirectory = dir;
}
-bool cmCTestVC::InitialCheckout(const char* command)
+bool cmCTestVC::InitialCheckout(const std::string& command)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT,
" First perform the initial checkout: " << command << "\n");
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 2a4765d28..3037e01c9 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -36,7 +36,7 @@ public:
std::string GetNightlyTime();
/** Prepare the work tree. */
- bool InitialCheckout(const char* command);
+ bool InitialCheckout(const std::string& command);
/** Perform cleanup operations on the work tree. */
void Cleanup();
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index 8c4da7577..84d7de02c 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -4,6 +4,7 @@
#include <cstdlib>
#include <map>
#include <utility>
+#include <vector>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -19,7 +20,7 @@ cmParseCacheCoverage::cmParseCacheCoverage(
{
}
-bool cmParseCacheCoverage::LoadCoverageData(const char* d)
+bool cmParseCacheCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
@@ -69,26 +70,6 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles()
}
}
-bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
- std::string const& line)
-{
- std::string::size_type pos1 = 0;
- std::string::size_type pos2 = line.find(',', 0);
- if (pos2 == std::string::npos) {
- return false;
- }
- std::string arg;
- while (pos2 != std::string::npos) {
- arg = line.substr(pos1, pos2 - pos1);
- args.push_back(arg);
- pos1 = pos2 + 1;
- pos2 = line.find(',', pos1);
- }
- arg = line.substr(pos1);
- args.push_back(arg);
- return true;
-}
-
bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
cmsys::ifstream in(file);
@@ -97,7 +78,6 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
return false;
}
std::string line;
- std::vector<std::string> separateLine;
if (!cmSystemTools::GetLineFromStream(in, line)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Empty file : " << file
@@ -106,8 +86,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
<< line << "]\n");
return false;
}
- separateLine.clear();
- this->SplitString(separateLine, line);
+ std::vector<std::string> separateLine =
+ cmSystemTools::SplitString(line, ',');
if (separateLine.size() != 4 || separateLine[0] != "Routine" ||
separateLine[1] != "Line" || separateLine[2] != "RtnLine" ||
separateLine[3] != "Code") {
@@ -120,10 +100,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
std::string routine;
std::string filepath;
while (cmSystemTools::GetLineFromStream(in, line)) {
- // clear out line argument vector
- separateLine.clear();
// parse the comma separated line
- this->SplitString(separateLine, line);
+ separateLine = cmSystemTools::SplitString(line, ',');
// might have more because code could have a quoted , in it
// but we only care about the first 3 args anyway
if (separateLine.size() < 4) {
@@ -155,7 +133,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
// if we have a routine name, check for end of routine
else {
// Totals in arg 0 marks the end of a routine
- if (separateLine[0].substr(0, 6) == "Totals") {
+ if (cmHasLiteralPrefix(separateLine[0], "Totals")) {
routine.clear(); // at the end of this routine
filepath.clear();
continue; // move to next line
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index e89b9e454..a8200b787 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -6,7 +6,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <vector>
#include "cmParseMumpsCoverage.h"
@@ -26,13 +25,11 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// remove files with no coverage
void RemoveUnCoveredFiles();
// Read a single mcov file
bool ReadCMCovFile(const char* f);
- // split a string based on ,
- bool SplitString(std::vector<std::string>& args, std::string const& line);
};
#endif
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 05da84e2e..711a8564b 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -67,7 +67,7 @@ protected:
// Check if this is an absolute path that falls within our
// source or binary directories.
for (std::string const& filePath : FilePaths) {
- if (filename.find(filePath) == 0) {
+ if (cmHasPrefix(filename, filePath)) {
this->CurFileName = filename;
break;
}
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 1dc5b7038..14417cc30 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -19,7 +19,7 @@ cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
{
}
-bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+bool cmParseGTMCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index fe0ae0bfd..41cc7f575 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -25,7 +25,7 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// Read a single mcov file
bool ReadMCovFile(const char* f);
// find out what line in a mumps file (filepath) the given entry point
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index b16f1014a..dc3064d22 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -39,9 +39,9 @@ bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
std::string type = line.substr(0, pos);
std::string path = line.substr(pos + 1);
if (type == "packages") {
- this->LoadPackages(path.c_str());
+ this->LoadPackages(path);
} else if (type == "coverage_dir") {
- this->LoadCoverageData(path.c_str());
+ this->LoadCoverageData(path);
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Parse Error in Mumps coverage file :\n"
@@ -105,7 +105,7 @@ void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
}
}
-bool cmParseMumpsCoverage::LoadPackages(const char* d)
+bool cmParseMumpsCoverage::LoadPackages(std::string const& d)
{
cmsys::Glob glob;
glob.RecurseOn();
@@ -113,7 +113,8 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
glob.FindFiles(pat);
for (std::string& file : glob.GetFiles()) {
std::string name = cmSystemTools::GetFilenameName(file);
- this->RoutineToDirectory[name.substr(0, name.size() - 2)] = file;
+ name.erase(name.size() - 2);
+ this->RoutineToDirectory[name] = file;
// initialize each file, this is left out until CDash is fixed
// to handle large numbers of files
this->InitializeMumpsFile(file);
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
index 2c544954b..8c0870254 100644
--- a/Source/CTest/cmParseMumpsCoverage.h
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -29,10 +29,10 @@ public:
protected:
// sub classes will use this to
// load all coverage files found in the given directory
- virtual bool LoadCoverageData(const char* d) = 0;
+ virtual bool LoadCoverageData(std::string const& d) = 0;
// search the package directory for mumps files and fill
// in the RoutineToDirectory map
- bool LoadPackages(const char* dir);
+ bool LoadPackages(std::string const& dir);
// initialize the coverage information for a single mumps file
void InitializeMumpsFile(std::string& file);
// Find mumps file for routine
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index a494b92b9..044f518ef 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -3,6 +3,8 @@
#include <cstdlib>
#include <cstring>
+#include <cm/memory>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -142,17 +144,15 @@ bool cmParsePHPCoverage::ReadFileInformation(std::istream& in)
int size = 0;
if (this->ReadInt(in, size)) {
size++; // add one for null termination
- char* s = new char[size + 1];
+ auto s = cm::make_unique<char[]>(size + 1);
// read open quote
if (in.get(c) && c != '"') {
- delete[] s;
return false;
}
// read the string data
- in.read(s, size - 1);
+ in.read(s.get(), size - 1);
s[size - 1] = 0;
- std::string fileName = s;
- delete[] s;
+ std::string fileName = s.get();
// read close quote
if (in.get(c) && c != '"') {
cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 6097aa5bd..a549117ca 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -5,6 +5,7 @@
#include <csignal>
#include <iostream>
#include <string>
+#include <utility>
#include <cmext/algorithm>
@@ -16,14 +17,13 @@
#include "cmGetPipes.h"
#include "cmStringAlgorithms.h"
#if defined(_WIN32)
-# include "cm_kwiml.h"
+# include <cm3p/kwiml/int.h>
#endif
-#include <utility>
#define CM_PROCESS_BUF_SIZE 65536
-cmProcess::cmProcess(cmCTestRunTest& runner)
- : Runner(runner)
+cmProcess::cmProcess(std::unique_ptr<cmCTestRunTest> runner)
+ : Runner(std::move(runner))
, Conv(cmProcessOutput::UTF8, CM_PROCESS_BUF_SIZE)
{
this->Timeout = cmDuration::zero();
@@ -69,7 +69,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
cm::uv_timer_ptr timer;
int status = timer.init(loop, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing timer: " << uv_strerror(status)
<< std::endl);
return false;
@@ -84,7 +84,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
int fds[2] = { -1, -1 };
status = cmGetPipes(fds);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing pipe: " << uv_strerror(status)
<< std::endl);
return false;
@@ -127,7 +127,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error starting read events: " << uv_strerror(status)
<< std::endl);
return false;
@@ -135,7 +135,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
status = this->Process.spawn(loop, options, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Process not started\n " << this->Command << "\n["
<< uv_strerror(status) << "]\n");
return false;
@@ -152,7 +152,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
void cmProcess::StartTimer()
{
- auto properties = this->Runner.GetTestProperties();
+ auto properties = this->Runner->GetTestProperties();
auto msec =
std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
@@ -222,7 +222,7 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
cm::append(this->Output, strdata);
while (this->Output.GetLine(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
line.clear();
}
@@ -236,13 +236,13 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
// The process will provide no more data.
if (nread != UV_EOF) {
auto error = static_cast<int>(nread);
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error reading stream: " << uv_strerror(error) << std::endl);
}
// Look for partial last lines.
if (this->Output.GetLast(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
}
this->ReadHandleClosed = true;
@@ -339,7 +339,7 @@ void cmProcess::Finish()
if (this->TotalTime <= cmDuration::zero()) {
this->TotalTime = cmDuration::zero();
}
- this->Runner.FinalizeTest();
+ this->Runner->FinalizeTest();
}
cmProcess::State cmProcess::GetProcessStatus()
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index ea72a2650..1e6578cf9 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,14 +6,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
#include <stdint.h>
-#include "cm_uv.h"
-
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmUVHandlePtr.h"
@@ -28,7 +29,7 @@ class cmCTestRunTest;
class cmProcess
{
public:
- explicit cmProcess(cmCTestRunTest& runner);
+ explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
~cmProcess();
void SetCommand(std::string const& command);
void SetCommandArguments(std::vector<std::string> const& arg);
@@ -70,6 +71,11 @@ public:
Exception GetExitException();
std::string GetExitExceptionString();
+ std::unique_ptr<cmCTestRunTest> GetRunner()
+ {
+ return std::move(this->Runner);
+ }
+
private:
cmDuration Timeout;
std::chrono::steady_clock::time_point StartTime;
@@ -82,7 +88,7 @@ private:
cm::uv_timer_ptr Timer;
std::vector<char> Buf;
- cmCTestRunTest& Runner;
+ std::unique_ptr<cmCTestRunTest> Runner;
cmProcessOutput Conv;
int Signal = 0;
cmProcess::State ProcessState = cmProcess::State::Starting;