summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-09-12 14:49:08 (GMT)
committerBrad King <brad.king@kitware.com>2018-09-12 14:59:55 (GMT)
commited71ec757995e78de31a083a6c8b1092b13dbc08 (patch)
tree3eb1a18db69b44f4dfaf46bc6baf89d74552d1c8
parent344eb9c8dc3b16a524729cb66ad25fc1c127a02c (diff)
downloadCMake-ed71ec757995e78de31a083a6c8b1092b13dbc08.zip
CMake-ed71ec757995e78de31a083a6c8b1092b13dbc08.tar.gz
CMake-ed71ec757995e78de31a083a6c8b1092b13dbc08.tar.bz2
CTest: Improve stop-time implementation
The CTestTestStopTime test has been failing sporadically because the stop time causes the first internal test to have a timeout short enough that we might hit it and start the second test just before the stop time is reached. Instead we should track when a timeout is shortened in order to stay within the stop time. If a test times out for this reason then we should consider the stop time reached and not start any more tests.
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx49
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx5
-rw-r--r--Source/CTest/cmCTestRunTest.h3
4 files changed, 44 insertions, 18 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 54b4be2..3e0c1ac 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -56,7 +56,6 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
this->RunningCount = 0;
this->ProcessorsAvailable = cmAffinity::GetProcessorsAvailable();
this->HaveAffinity = this->ProcessorsAvailable.size();
- this->StopTimePassed = false;
this->HasCycles = false;
this->SerialTestRunning = false;
}
@@ -130,17 +129,6 @@ void cmCTestMultiProcessHandler::RunTests()
bool cmCTestMultiProcessHandler::StartTestProcess(int test)
{
- std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime();
- if (stop_time != std::chrono::system_clock::time_point() &&
- stop_time <= std::chrono::system_clock::now()) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "The stop time has been passed. "
- "Stopping all tests."
- << std::endl);
- this->StopTimePassed = true;
- return false;
- }
-
if (this->HaveAffinity && this->Properties[test]->WantAffinity) {
size_t needProcessors = this->GetProcessorsUsed(test);
if (needProcessors > this->ProcessorsAvailable.size()) {
@@ -199,6 +187,30 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
return false;
}
+bool cmCTestMultiProcessHandler::CheckStopTimePassed()
+{
+ if (!this->StopTimePassed) {
+ std::chrono::system_clock::time_point stop_time =
+ this->CTest->GetStopTime();
+ if (stop_time != std::chrono::system_clock::time_point() &&
+ stop_time <= std::chrono::system_clock::now()) {
+ this->SetStopTimePassed();
+ }
+ }
+ return this->StopTimePassed;
+}
+
+void cmCTestMultiProcessHandler::SetStopTimePassed()
+{
+ if (!this->StopTimePassed) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "The stop time has been passed. "
+ "Stopping all tests."
+ << std::endl);
+ this->StopTimePassed = true;
+ }
+}
+
void cmCTestMultiProcessHandler::LockResources(int index)
{
this->LockedResources.insert(
@@ -279,6 +291,10 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ if (this->CheckStopTimePassed()) {
+ return;
+ }
+
size_t numToStart = 0;
if (this->RunningCount < this->ParallelLevel) {
@@ -358,10 +374,6 @@ void cmCTestMultiProcessHandler::StartNextTests()
}
if (testLoadOk && processors <= numToStart && this->StartTest(test)) {
- if (this->StopTimePassed) {
- return;
- }
-
numToStart -= processors;
} else if (numToStart == 0) {
break;
@@ -424,8 +436,11 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
auto properties = runner->GetTestProperties();
bool testResult = runner->EndTest(this->Completed, this->Total, started);
+ if (runner->TimedOutForStopTime()) {
+ this->SetStopTimePassed();
+ }
if (started) {
- if (runner->StartAgain()) {
+ if (!this->StopTimePassed && runner->StartAgain()) {
this->Completed--; // remove the completed test because run again
return;
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 07a5fe7..3927a8a 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -113,6 +113,9 @@ protected:
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
+ bool CheckStopTimePassed();
+ void SetStopTimePassed();
+
void LockResources(int index);
void UnlockResources(int index);
// map from test number to set of depend tests
@@ -125,7 +128,7 @@ protected:
size_t RunningCount;
std::set<size_t> ProcessorsAvailable;
size_t HaveAffinity;
- bool StopTimePassed;
+ bool StopTimePassed = false;
// list of test properties (indices concurrent to the test map)
PropertiesMap Properties;
std::map<int, bool> TestRunningMap;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index ef0a49d..23d4616 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -140,6 +140,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
bool passed = true;
cmProcess::State res =
started ? this->TestProcess->GetProcessStatus() : cmProcess::State::Error;
+ if (res != cmProcess::State::Expired) {
+ this->TimeoutIsForStopTime = false;
+ }
int retVal = this->TestProcess->GetExitValue();
bool forceFail = false;
bool skipped = false;
@@ -537,6 +540,7 @@ bool cmCTestRunTest::StartTest(size_t total)
auto timeout = this->TestProperties->Timeout;
+ 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 =
@@ -547,6 +551,7 @@ bool cmCTestRunTest::StartTest(size_t total)
}
if (timeout == std::chrono::duration<double>::zero() ||
stop_timeout < timeout) {
+ this->TimeoutIsForStopTime = true;
timeout = stop_timeout;
}
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 3b1d674..7e80157 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -80,6 +80,8 @@ public:
void FinalizeTest();
+ bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
+
private:
bool NeedsToRerun();
void DartProcessing();
@@ -92,6 +94,7 @@ private:
void MemCheckPostProcess();
cmCTestTestHandler::cmCTestTestProperties* TestProperties;
+ bool TimeoutIsForStopTime = false;
// Pointer back to the "parent"; the handler that invoked this test run
cmCTestTestHandler* TestHandler;
cmCTest* CTest;