浏览代码

Added RESOURCE_LOCK test property.

Zach Mullen 15 年之前
父节点
当前提交
767ffba8ff

+ 35 - 1
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;
@@ -112,6 +116,25 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
   cmSystemTools::ChangeDirectory(current_dir.c_str());
 }
 
+//---------------------------------------------------------
+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)
 {
@@ -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;
     }

+ 5 - 1
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

+ 2 - 2
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)

+ 11 - 0
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());

+ 1 - 0
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

+ 6 - 0
Source/cmTest.cxx

@@ -142,6 +142,12 @@ void cmTest::DefineProperties(cmake *cm)
      "Specify a list of text labels associated with a test.",
      "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.",