summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx36
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h6
-rw-r--r--Source/CTest/cmCTestRunTest.cxx4
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx11
-rw-r--r--Source/CTest/cmCTestTestHandler.h1
-rw-r--r--Source/cmTest.cxx6
6 files changed, 60 insertions, 4 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 9d76dd4..84df303 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -95,12 +95,16 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(this->Properties[test]->Directory.c_str());
+ // Lock the resources we'll be using
+ this->LockResources(test);
+
if(testRun->StartTest(this->Total))
{
this->RunningTests.insert(testRun);
}
else
{
+ this->UnlockResources(test);
this->Completed++;
this->TestFinishMap[test] = true;
this->TestRunningMap[test] = false;
@@ -113,6 +117,25 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
}
//---------------------------------------------------------
+void cmCTestMultiProcessHandler::LockResources(int index)
+{
+ this->LockedResources.insert(
+ this->Properties[index]->LockedResources.begin(),
+ this->Properties[index]->LockedResources.end());
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::UnlockResources(int index)
+{
+ for(std::set<std::string>::iterator i =
+ this->Properties[index]->LockedResources.begin();
+ i != this->Properties[index]->LockedResources.end(); ++i)
+ {
+ this->LockedResources.erase(*i);
+ }
+}
+
+//---------------------------------------------------------
void cmCTestMultiProcessHandler::EraseTest(int test)
{
this->Tests.erase(test);
@@ -146,6 +169,17 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
//---------------------------------------------------------
bool cmCTestMultiProcessHandler::StartTest(int test)
{
+ //Check for locked resources
+ for(std::set<std::string>::iterator i =
+ this->Properties[test]->LockedResources.begin();
+ i != this->Properties[test]->LockedResources.end(); ++i)
+ {
+ if(this->LockedResources.find(*i) != this->LockedResources.end())
+ {
+ return false;
+ }
+ }
+
// copy the depend tests locally because when
// a test is finished it will be removed from the depend list
// and we don't want to be iterating a list while removing from it
@@ -274,7 +308,7 @@ bool cmCTestMultiProcessHandler::CheckOutput()
this->TestRunningMap[test] = false;
this->RunningTests.erase(p);
this->WriteCheckpoint(test);
-
+ this->UnlockResources(test);
this->RunningCount -= GetProcessorsUsed(test);
delete p;
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index ebec6c7..d4f6c71 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -55,7 +55,7 @@ public:
cmCTestTestHandler * GetTestHandler()
{ return this->TestHandler; }
-protected:
+protected:
// Start the next test or tests as many as are allowed by
// ParallelLevel
void StartNextTests();
@@ -83,6 +83,9 @@ protected:
bool CheckCycles();
int FindMaxIndex();
inline size_t GetProcessorsUsed(int index);
+
+ void LockResources(int index);
+ void UnlockResources(int index);
// map from test number to set of depend tests
TestMap Tests;
TestCostMap TestCosts;
@@ -99,6 +102,7 @@ protected:
std::vector<cmStdString>* Passed;
std::vector<cmStdString>* Failed;
std::vector<std::string> LastTestsFailed;
+ std::set<std::string> LockedResources;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
std::set<cmCTestRunTest*> RunningTests; // current running tests
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index fa9794a..659cb73 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -448,7 +448,7 @@ bool cmCTestRunTest::StartTest(size_t total)
//----------------------------------------------------------------------
void cmCTestRunTest::ComputeArguments()
{
- std::vector<std::string>::const_iterator j =
+ std::vector<std::string>::const_iterator j =
this->TestProperties->Args.begin();
++j; // skip test name
@@ -463,7 +463,7 @@ void cmCTestRunTest::ComputeArguments()
}
else
{
- this->ActualCommand =
+ this->ActualCommand =
this->TestHandler->FindTheExecutable(
this->TestProperties->Args[1].c_str());
++j; //skip the executable (it will be actualCommand)
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index e36074f..b9cee6c 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -2099,6 +2099,17 @@ bool cmCTestTestHandler::SetTestsProperties(
rtit->AttachOnFail.push_back(*f);
}
}
+ if ( key == "RESOURCE_LOCK" )
+ {
+ std::vector<std::string> lval;
+ cmSystemTools::ExpandListArgument(val.c_str(), lval);
+
+ for(std::vector<std::string>::iterator f = lval.begin();
+ f != lval.end(); ++f)
+ {
+ rtit->LockedResources.insert(*f);
+ }
+ }
if ( key == "TIMEOUT" )
{
rtit->Timeout = atof(val.c_str());
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 05bdf86..7049564 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -104,6 +104,7 @@ public:
int Processors;
std::vector<std::string> Environment;
std::vector<std::string> Labels;
+ std::set<std::string> LockedResources;
};
struct cmCTestTestResult
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index b52bc19..4e9b973 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -143,6 +143,12 @@ void cmTest::DefineProperties(cmake *cm)
"The list is reported in dashboard submissions.");
cm->DefineProperty
+ ("RESOURCE_LOCK", cmProperty::TEST,
+ "Specify a list of resources that are locked by this test.",
+ "If multiple tests specify the same resource lock, they are guaranteed "
+ "not to run concurrently.");
+
+ cm->DefineProperty
("MEASUREMENT", cmProperty::TEST,
"Specify a CDASH measurement and value to be reported for a test.",
"If set to a name then that name will be reported to CDASH as a "