diff options
Diffstat (limited to 'Source/CTest/cmCTestMultiProcessHandler.cxx')
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.cxx | 80 |
1 files changed, 63 insertions, 17 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 37679b9..2192843 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -196,8 +196,40 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) // working directory because FinishTestProcess() will try to unlock them this->LockResources(test); - if (!this->TestsHaveSufficientResources[test]) { - testRun->StartFailure("Insufficient resources"); + if (!this->ResourceAllocationErrors[test].empty()) { + std::ostringstream e; + e << "Insufficient resources for test " << this->Properties[test]->Name + << ":\n\n"; + for (auto const& it : this->ResourceAllocationErrors[test]) { + switch (it.second) { + case ResourceAllocationError::NoResourceType: + e << " Test requested resources of type '" << it.first + << "' which does not exist\n"; + break; + + case ResourceAllocationError::InsufficientResources: + e << " Test requested resources of type '" << it.first + << "' in the following amounts:\n"; + for (auto const& group : this->Properties[test]->ResourceGroups) { + for (auto const& requirement : group) { + if (requirement.ResourceType == it.first) { + e << " " << requirement.SlotsNeeded + << (requirement.SlotsNeeded == 1 ? " slot\n" : " slots\n"); + } + } + } + e << " but only the following units were available:\n"; + for (auto const& res : + this->ResourceAllocator.GetResources().at(it.first)) { + e << " '" << res.first << "': " << res.second.Total + << (res.second.Total == 1 ? " slot\n" : " slots\n"); + } + break; + } + e << "\n"; + } + e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile; + testRun->StartFailure(e.str(), "Insufficient resources"); this->FinishTestProcess(testRun, false); return false; } @@ -205,8 +237,9 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) 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())); + 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. @@ -249,7 +282,8 @@ bool cmCTestMultiProcessHandler::AllocateResources(int index) bool cmCTestMultiProcessHandler::TryAllocateResources( int index, - std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations) + std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations, + std::map<std::string, ResourceAllocationError>* errors) { allocations.clear(); @@ -264,18 +298,28 @@ bool cmCTestMultiProcessHandler::TryAllocateResources( ++processIndex; } + bool result = true; auto const& availableResources = this->ResourceAllocator.GetResources(); for (auto& it : allocations) { if (!availableResources.count(it.first)) { - return false; - } - if (!cmAllocateCTestResourcesRoundRobin(availableResources.at(it.first), - it.second)) { - return false; + if (errors) { + (*errors)[it.first] = ResourceAllocationError::NoResourceType; + result = false; + } else { + return false; + } + } else if (!cmAllocateCTestResourcesRoundRobin( + availableResources.at(it.first), it.second)) { + if (errors) { + (*errors)[it.first] = ResourceAllocationError::InsufficientResources; + result = false; + } else { + return false; + } } } - return true; + return result; } void cmCTestMultiProcessHandler::DeallocateResources(int index) @@ -316,11 +360,13 @@ bool cmCTestMultiProcessHandler::AllResourcesAvailable() void cmCTestMultiProcessHandler::CheckResourcesAvailable() { - for (auto test : this->SortedTests) { - std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations; - this->TestsHaveSufficientResources[test] = - !this->TestHandler->UseResourceSpec || - this->TryAllocateResources(test, allocations); + if (this->TestHandler->UseResourceSpec) { + for (auto test : this->SortedTests) { + std::map<std::string, std::vector<cmCTestBinPackerAllocation>> + allocations; + this->TryAllocateResources(test, allocations, + &this->ResourceAllocationErrors[test]); + } } } @@ -407,7 +453,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test) } // Allocate resources - if (this->TestsHaveSufficientResources[test] && + if (this->ResourceAllocationErrors[test].empty() && !this->AllocateResources(test)) { this->DeallocateResources(test); return false; |