diff options
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.cxx | 36 | ||||
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.h | 6 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 4 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.cxx | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.h | 1 | ||||
-rw-r--r-- | Source/cmTest.cxx | 6 |
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 " |