summaryrefslogtreecommitdiffstats
path: root/Source/CTest/cmCTestMultiProcessHandler.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2023-08-14 15:17:47 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-08-14 15:18:03 (GMT)
commit0d95b68bd807ccc4eee44619da29974caf3a1a1b (patch)
treeac0fb4f0bb2741544dd6fd87e7442097ef304e89 /Source/CTest/cmCTestMultiProcessHandler.cxx
parent944fda58b2c02ca0ad94095a4b4fee2bd1dadc25 (diff)
parentc8c1dd0d9540acbe6172afe192c149fe04d0625b (diff)
downloadCMake-0d95b68bd807ccc4eee44619da29974caf3a1a1b.zip
CMake-0d95b68bd807ccc4eee44619da29974caf3a1a1b.tar.gz
CMake-0d95b68bd807ccc4eee44619da29974caf3a1a1b.tar.bz2
Merge topic 'ctest-generate-resource-spec-file'
c8c1dd0d95 CTest: Add ability to dynamically generate resource spec file 3f5a5a5856 cmCTestRunTest::StartFailure(): Add total argument Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8699
Diffstat (limited to 'Source/CTest/cmCTestMultiProcessHandler.cxx')
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx100
1 files changed, 91 insertions, 9 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 7d22a87..ca07a08 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -35,6 +35,7 @@
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
+#include "cmJSONState.h"
#include "cmListFileCache.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -75,6 +76,7 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
this->ProcessorsAvailable = cmAffinity::GetProcessorsAvailable();
this->HaveAffinity = this->ProcessorsAvailable.size();
this->HasCycles = false;
+ this->HasInvalidGeneratedResourceSpec = false;
this->SerialTestRunning = false;
}
@@ -95,7 +97,9 @@ void cmCTestMultiProcessHandler::SetTests(TestMap& tests,
if (!this->CTest->GetShowOnly()) {
this->ReadCostData();
this->HasCycles = !this->CheckCycles();
- if (this->HasCycles) {
+ this->HasInvalidGeneratedResourceSpec =
+ !this->CheckGeneratedResourceSpec();
+ if (this->HasCycles || this->HasInvalidGeneratedResourceSpec) {
return;
}
this->CreateTestCostList();
@@ -125,7 +129,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
void cmCTestMultiProcessHandler::RunTests()
{
this->CheckResume();
- if (this->HasCycles) {
+ if (this->HasCycles || this->HasInvalidGeneratedResourceSpec) {
return;
}
#ifdef CMAKE_UV_SIGNAL_HACK
@@ -180,7 +184,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
- if (this->TestHandler->UseResourceSpec) {
+ if (this->UseResourceSpec) {
testRun->SetUseAllocatedResources(true);
testRun->SetAllocatedResources(this->AllocatedResources[test]);
}
@@ -229,15 +233,15 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
e << "\n";
}
- e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
- cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ e << "Resource spec file:\n\n " << this->ResourceSpecFile;
+ cmCTestRunTest::StartFailure(std::move(testRun), this->Total, e.str(),
"Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- cmCTestRunTest::StartFailure(std::move(testRun),
+ cmCTestRunTest::StartFailure(std::move(testRun), this->Total,
"Failed to change working directory to " +
this->Properties[test]->Directory + " : " +
std::strerror(workdir.GetLastResult()),
@@ -253,7 +257,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
bool cmCTestMultiProcessHandler::AllocateResources(int index)
{
- if (!this->TestHandler->UseResourceSpec) {
+ if (!this->UseResourceSpec) {
return true;
}
@@ -322,7 +326,7 @@ bool cmCTestMultiProcessHandler::TryAllocateResources(
void cmCTestMultiProcessHandler::DeallocateResources(int index)
{
- if (!this->TestHandler->UseResourceSpec) {
+ if (!this->UseResourceSpec) {
return;
}
@@ -358,7 +362,7 @@ bool cmCTestMultiProcessHandler::AllResourcesAvailable()
void cmCTestMultiProcessHandler::CheckResourcesAvailable()
{
- if (this->TestHandler->UseResourceSpec) {
+ if (this->UseResourceSpec) {
for (auto test : this->SortedTests) {
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>
allocations;
@@ -1445,3 +1449,81 @@ bool cmCTestMultiProcessHandler::CheckCycles()
this->Quiet);
return true;
}
+
+bool cmCTestMultiProcessHandler::CheckGeneratedResourceSpec()
+{
+ for (auto& test : this->Properties) {
+ if (!test.second->GeneratedResourceSpecFile.empty()) {
+ if (this->ResourceSpecSetupTest) {
+ cmCTestLog(
+ this->CTest, ERROR_MESSAGE,
+ "Only one test may define the GENERATED_RESOURCE_SPEC_FILE property"
+ << std::endl);
+ return false;
+ }
+
+ if (test.second->FixturesSetup.size() != 1) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Test that defines GENERATED_RESOURCE_SPEC_FILE must have "
+ "exactly one FIXTURES_SETUP"
+ << std::endl);
+ return false;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(
+ test.second->GeneratedResourceSpecFile)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "GENERATED_RESOURCE_SPEC_FILE must be an absolute path"
+ << std::endl);
+ return false;
+ }
+
+ this->ResourceSpecSetupTest = test.first;
+ this->ResourceSpecSetupFixture = *test.second->FixturesSetup.begin();
+ }
+ }
+
+ if (!this->ResourceSpecSetupFixture.empty()) {
+ for (auto& test : this->Properties) {
+ if (!test.second->ResourceGroups.empty() &&
+ !test.second->FixturesRequired.count(
+ this->ResourceSpecSetupFixture)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "All tests that have RESOURCE_GROUPS must include the "
+ "resource spec generator fixture in their FIXTURES_REQUIRED"
+ << std::endl);
+ return false;
+ }
+ }
+ }
+
+ if (!this->ResourceSpecFile.empty()) {
+ if (this->ResourceSpecSetupTest) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "GENERATED_RESOURCE_SPEC_FILE test property cannot be used "
+ "in conjunction with ResourceSpecFile option"
+ << std::endl);
+ return false;
+ }
+ std::string error;
+ if (!this->InitResourceAllocator(error)) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, error << std::endl);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool cmCTestMultiProcessHandler::InitResourceAllocator(std::string& error)
+{
+ if (!this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile)) {
+ error = cmStrCat("Could not read/parse resource spec file ",
+ this->ResourceSpecFile, ": ",
+ this->ResourceSpec.parseState.GetErrorMessage());
+ return false;
+ }
+ this->UseResourceSpec = true;
+ this->ResourceAllocator.InitializeFromResourceSpec(this->ResourceSpec);
+ return true;
+}