mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-02 20:29:49 -05:00
cmCTestRunTest: Consolidate test timeout selection logic
Test timeout selection was previously spread out over several locations. Consolidate it in a single place to make it easier to follow.
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
#include <cm/optional>
|
||||||
#include <cmext/algorithm>
|
#include <cmext/algorithm>
|
||||||
|
|
||||||
#include <cm3p/json/value.h>
|
#include <cm3p/json/value.h>
|
||||||
@@ -1095,9 +1096,9 @@ static Json::Value DumpCTestProperties(
|
|||||||
properties.append(
|
properties.append(
|
||||||
DumpCTestProperty("SKIP_RETURN_CODE", testProperties.SkipReturnCode));
|
DumpCTestProperty("SKIP_RETURN_CODE", testProperties.SkipReturnCode));
|
||||||
}
|
}
|
||||||
if (testProperties.ExplicitTimeout) {
|
if (testProperties.Timeout) {
|
||||||
properties.append(
|
properties.append(
|
||||||
DumpCTestProperty("TIMEOUT", testProperties.Timeout.count()));
|
DumpCTestProperty("TIMEOUT", testProperties.Timeout->count()));
|
||||||
}
|
}
|
||||||
if (!testProperties.TimeoutRegularExpressions.empty()) {
|
if (!testProperties.TimeoutRegularExpressions.empty()) {
|
||||||
properties.append(DumpCTestProperty(
|
properties.append(DumpCTestProperty(
|
||||||
|
|||||||
@@ -14,12 +14,14 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
#include "cmsys/RegularExpression.hxx"
|
#include "cmsys/RegularExpression.hxx"
|
||||||
|
|
||||||
#include "cmCTest.h"
|
#include "cmCTest.h"
|
||||||
#include "cmCTestMemCheckHandler.h"
|
#include "cmCTestMemCheckHandler.h"
|
||||||
#include "cmCTestMultiProcessHandler.h"
|
#include "cmCTestMultiProcessHandler.h"
|
||||||
|
#include "cmDuration.h"
|
||||||
#include "cmProcess.h"
|
#include "cmProcess.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
@@ -618,25 +620,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
|
|||||||
}
|
}
|
||||||
this->StartTime = this->CTest->CurrentTime();
|
this->StartTime = this->CTest->CurrentTime();
|
||||||
|
|
||||||
auto timeout = this->TestProperties->Timeout;
|
return this->ForkProcess();
|
||||||
|
|
||||||
this->TimeoutIsForStopTime = false;
|
|
||||||
std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime();
|
|
||||||
if (stop_time != std::chrono::system_clock::time_point()) {
|
|
||||||
std::chrono::duration<double> stop_timeout =
|
|
||||||
(stop_time - std::chrono::system_clock::now()) % std::chrono::hours(24);
|
|
||||||
|
|
||||||
if (stop_timeout <= std::chrono::duration<double>::zero()) {
|
|
||||||
stop_timeout = std::chrono::duration<double>::zero();
|
|
||||||
}
|
|
||||||
if (timeout == std::chrono::duration<double>::zero() ||
|
|
||||||
stop_timeout < timeout) {
|
|
||||||
this->TimeoutIsForStopTime = true;
|
|
||||||
timeout = stop_timeout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->ForkProcess(timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmCTestRunTest::ComputeArguments()
|
void cmCTestRunTest::ComputeArguments()
|
||||||
@@ -734,46 +718,79 @@ void cmCTestRunTest::ParseOutputForMeasurements()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut)
|
bool cmCTestRunTest::ForkProcess()
|
||||||
{
|
{
|
||||||
this->TestProcess->SetId(this->Index);
|
this->TestProcess->SetId(this->Index);
|
||||||
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
|
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
|
||||||
this->TestProcess->SetCommand(this->ActualCommand);
|
this->TestProcess->SetCommand(this->ActualCommand);
|
||||||
this->TestProcess->SetCommandArguments(this->Arguments);
|
this->TestProcess->SetCommandArguments(this->Arguments);
|
||||||
|
|
||||||
// determine how much time we have
|
cm::optional<cmDuration> timeout;
|
||||||
cmDuration timeout = this->CTest->GetRemainingTimeAllowed();
|
|
||||||
if (timeout != cmCTest::MaxDuration()) {
|
// Check TIMEOUT test property.
|
||||||
timeout -= std::chrono::minutes(2);
|
if (this->TestProperties->Timeout &&
|
||||||
|
*this->TestProperties->Timeout >= cmDuration::zero()) {
|
||||||
|
timeout = this->TestProperties->Timeout;
|
||||||
}
|
}
|
||||||
if (this->CTest->GetTimeOut() > cmDuration::zero() &&
|
|
||||||
this->CTest->GetTimeOut() < timeout) {
|
|
||||||
timeout = this->CTest->GetTimeOut();
|
|
||||||
}
|
|
||||||
if (testTimeOut > cmDuration::zero() &&
|
|
||||||
testTimeOut < this->CTest->GetRemainingTimeAllowed()) {
|
|
||||||
timeout = testTimeOut;
|
|
||||||
}
|
|
||||||
// always have at least 1 second if we got to here
|
|
||||||
if (timeout <= cmDuration::zero()) {
|
|
||||||
timeout = std::chrono::seconds(1);
|
|
||||||
}
|
|
||||||
// handle timeout explicitly set to 0
|
|
||||||
if (testTimeOut == cmDuration::zero() &&
|
|
||||||
this->TestProperties->ExplicitTimeout) {
|
|
||||||
timeout = cmDuration::zero();
|
|
||||||
}
|
|
||||||
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
||||||
this->Index << ": "
|
|
||||||
<< "Test timeout computed to be: "
|
|
||||||
<< cmDurationTo<unsigned int>(timeout)
|
|
||||||
<< "\n",
|
|
||||||
this->TestHandler->GetQuiet());
|
|
||||||
|
|
||||||
// An explicit TIMEOUT=0 test property means "no timeout".
|
// An explicit TIMEOUT=0 test property means "no timeout".
|
||||||
if (timeout != cmDuration::zero() ||
|
if (timeout && *timeout == std::chrono::duration<double>::zero()) {
|
||||||
!this->TestProperties->ExplicitTimeout) {
|
timeout = cm::nullopt;
|
||||||
this->TestProcess->SetTimeout(timeout);
|
} else {
|
||||||
|
// Check --timeout.
|
||||||
|
if (!timeout && this->CTest->GetGlobalTimeout() > cmDuration::zero()) {
|
||||||
|
timeout = this->CTest->GetGlobalTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check CTEST_TEST_TIMEOUT.
|
||||||
|
cmDuration ctestTestTimeout = this->CTest->GetTimeOut();
|
||||||
|
if (ctestTestTimeout > cmDuration::zero() &&
|
||||||
|
(!timeout || ctestTestTimeout < *timeout)) {
|
||||||
|
timeout = ctestTestTimeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check CTEST_TIME_LIMIT.
|
||||||
|
cmDuration timeRemaining = this->CTest->GetRemainingTimeAllowed();
|
||||||
|
if (timeRemaining != cmCTest::MaxDuration()) {
|
||||||
|
// This two minute buffer is historical.
|
||||||
|
timeRemaining -= std::chrono::minutes(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check --stop-time.
|
||||||
|
std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime();
|
||||||
|
if (stop_time != std::chrono::system_clock::time_point()) {
|
||||||
|
cmDuration timeUntilStop =
|
||||||
|
(stop_time - std::chrono::system_clock::now()) % std::chrono::hours(24);
|
||||||
|
if (timeUntilStop < timeRemaining) {
|
||||||
|
timeRemaining = timeUntilStop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce remaining time even over explicit TIMEOUT=0.
|
||||||
|
if (timeRemaining <= cmDuration::zero()) {
|
||||||
|
timeRemaining = cmDuration::zero();
|
||||||
|
}
|
||||||
|
if (!timeout || timeRemaining < *timeout) {
|
||||||
|
this->TimeoutIsForStopTime = true;
|
||||||
|
timeout = timeRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout) {
|
||||||
|
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||||
|
this->Index << ": "
|
||||||
|
<< "Test timeout computed to be: "
|
||||||
|
<< cmDurationTo<unsigned int>(*timeout)
|
||||||
|
<< "\n",
|
||||||
|
this->TestHandler->GetQuiet());
|
||||||
|
|
||||||
|
this->TestProcess->SetTimeout(*timeout);
|
||||||
|
} else {
|
||||||
|
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||||
|
this->Index
|
||||||
|
<< ": "
|
||||||
|
<< "Test timeout suppressed by TIMEOUT property.\n",
|
||||||
|
this->TestHandler->GetQuiet());
|
||||||
}
|
}
|
||||||
|
|
||||||
cmSystemTools::SaveRestoreEnvironment sre;
|
cmSystemTools::SaveRestoreEnvironment sre;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "cmCTest.h"
|
#include "cmCTest.h"
|
||||||
#include "cmCTestMultiProcessHandler.h"
|
#include "cmCTestMultiProcessHandler.h"
|
||||||
#include "cmCTestTestHandler.h"
|
#include "cmCTestTestHandler.h"
|
||||||
#include "cmDuration.h"
|
|
||||||
#include "cmProcess.h"
|
#include "cmProcess.h"
|
||||||
|
|
||||||
/** \class cmRunTest
|
/** \class cmRunTest
|
||||||
@@ -110,7 +109,7 @@ private:
|
|||||||
bool NeedsToRepeat();
|
bool NeedsToRepeat();
|
||||||
void ParseOutputForMeasurements();
|
void ParseOutputForMeasurements();
|
||||||
void ExeNotFound(std::string exe);
|
void ExeNotFound(std::string exe);
|
||||||
bool ForkProcess(cmDuration testTimeOut);
|
bool ForkProcess();
|
||||||
void WriteLogOutputTop(size_t completed, size_t total);
|
void WriteLogOutputTop(size_t completed, size_t total);
|
||||||
// Run post processing of the process output for MemCheck
|
// Run post processing of the process output for MemCheck
|
||||||
void MemCheckPostProcess();
|
void MemCheckPostProcess();
|
||||||
|
|||||||
@@ -1379,11 +1379,6 @@ bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
|
|||||||
p.Cost = static_cast<float>(rand());
|
p.Cost = static_cast<float>(rand());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.Timeout == cmDuration::zero() && !p.ExplicitTimeout &&
|
|
||||||
this->CTest->GetGlobalTimeout() != cmDuration::zero()) {
|
|
||||||
p.Timeout = this->CTest->GetGlobalTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p.Depends.empty()) {
|
if (!p.Depends.empty()) {
|
||||||
for (std::string const& i : p.Depends) {
|
for (std::string const& i : p.Depends) {
|
||||||
for (cmCTestTestProperties const& it2 : this->TestList) {
|
for (cmCTestTestProperties const& it2 : this->TestList) {
|
||||||
@@ -2252,7 +2247,6 @@ bool cmCTestTestHandler::SetTestsProperties(
|
|||||||
rt.FixturesRequired.insert(lval.begin(), lval.end());
|
rt.FixturesRequired.insert(lval.begin(), lval.end());
|
||||||
} else if (key == "TIMEOUT"_s) {
|
} else if (key == "TIMEOUT"_s) {
|
||||||
rt.Timeout = cmDuration(atof(val.c_str()));
|
rt.Timeout = cmDuration(atof(val.c_str()));
|
||||||
rt.ExplicitTimeout = true;
|
|
||||||
} else if (key == "COST"_s) {
|
} else if (key == "COST"_s) {
|
||||||
rt.Cost = static_cast<float>(atof(val.c_str()));
|
rt.Cost = static_cast<float>(atof(val.c_str()));
|
||||||
} else if (key == "REQUIRED_FILES"_s) {
|
} else if (key == "REQUIRED_FILES"_s) {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
#include "cmsys/RegularExpression.hxx"
|
#include "cmsys/RegularExpression.hxx"
|
||||||
|
|
||||||
#include "cmCTest.h"
|
#include "cmCTest.h"
|
||||||
@@ -145,8 +147,7 @@ public:
|
|||||||
float Cost = 0;
|
float Cost = 0;
|
||||||
int PreviousRuns = 0;
|
int PreviousRuns = 0;
|
||||||
bool RunSerial = false;
|
bool RunSerial = false;
|
||||||
cmDuration Timeout = cmDuration::zero();
|
cm::optional<cmDuration> Timeout;
|
||||||
bool ExplicitTimeout = false;
|
|
||||||
cmDuration AlternateTimeout;
|
cmDuration AlternateTimeout;
|
||||||
int Index = 0;
|
int Index = 0;
|
||||||
// Requested number of process slots
|
// Requested number of process slots
|
||||||
|
|||||||
Reference in New Issue
Block a user