Browse Source

ENH: Added ctest test options PROCESSORS and RUN_SERIAL. These allow specification of resource allocation for given tests running with the ctest -j N option. RUN_SERIAL ensures that a given test does not run in parallel with any other test. Also forced appending of "..." to the longest test name in ctest.

Zach Mullen 16 years ago
parent
commit
5fb958fde9

+ 27 - 6
Source/CTest/cmCTestMultiProcessHandler.cxx

@@ -25,6 +25,7 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
 {
   this->ParallelLevel = 1;
   this->Completed = 0;
+  this->RunningCount = 0;
 }
   // Set the tests
 void 
@@ -112,10 +113,27 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
   else
     {
     this->Completed++;
+    this->RunningCount -= GetProcessorsUsed(test);
     testRun->EndTest(this->Completed, this->Total, false);
     }
 }
 
+inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
+{
+  size_t processors = 
+    static_cast<int>(this->Properties[test]->Processors);
+  //If this is set to run serially, it must run alone.
+  //Also, if processors setting is set higher than the -j
+  //setting, we default to using all of the process slots.
+  if(this->Properties[test]->RunSerial
+     || processors > this->ParallelLevel)
+    {
+    processors = this->ParallelLevel;
+    }
+
+  return processors;
+}
+
 bool cmCTestMultiProcessHandler::StartTest(int test)
 {
   // copy the depend tests locally because when 
@@ -160,7 +178,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
 
 void cmCTestMultiProcessHandler::StartNextTests()
 {
-  size_t numToStart = this->ParallelLevel - this->RunningTests.size();
+  size_t numToStart = this->ParallelLevel - this->RunningCount;
   if(numToStart == 0)
     {
     return;
@@ -171,13 +189,16 @@ void cmCTestMultiProcessHandler::StartNextTests()
   for(TestMap::iterator i = tests.begin();
       i !=  tests.end(); ++i)
     {
-    //int processors = this->Properties[i->first]->Processors;
-    
-//    if(processors > )
+    size_t processors = GetProcessorsUsed(i->first);
+    if(processors > numToStart)
+      {
+      return;
+      }
     // start test should start only one test
     if(this->StartTest(i->first))
       {
-      numToStart--;
+      numToStart -= processors;
+      this->RunningCount += processors;
       }
     else
       {
@@ -241,7 +262,7 @@ bool cmCTestMultiProcessHandler::CheckOutput()
     this->TestRunningMap[test] = false;
     this->RunningTests.erase(p);
     this->WriteCheckpoint(test);
-
+    this->RunningCount -= GetProcessorsUsed(test);
     delete p;
     }
   return true;

+ 2 - 0
Source/CTest/cmCTestMultiProcessHandler.h

@@ -80,6 +80,7 @@ protected:
   //Check if we need to resume an interrupted test set
   void CheckResume();
   int FindMaxIndex();
+  inline size_t GetProcessorsUsed(int index);
   // map from test number to set of depend tests
   TestMap Tests;
   TestMap ExpensiveTests;
@@ -87,6 +88,7 @@ protected:
   size_t Total;
   //Number of tests that are complete
   size_t Completed;
+  size_t RunningCount;
   //list of test properties (indices concurrent to the test map)
   PropertiesMap Properties;
   std::map<int, bool> TestRunningMap;

+ 1 - 1
Source/CTest/cmCTestRunTest.cxx

@@ -476,7 +476,7 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
   cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
   const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
   std::string outname = this->TestProperties->Name + " ";
-  outname.resize(maxTestNameWidth, '.');
+  outname.resize(maxTestNameWidth + 4, '.');
 
   *this->TestHandler->LogFile << this->TestProperties->Index << "/"
     << this->TestHandler->TotalNumberOfTests << " Testing: " 

+ 5 - 0
Source/CTest/cmCTestTestHandler.cxx

@@ -1979,6 +1979,10 @@ bool cmCTestTestHandler::SetTestsProperties(
             {
             rtit->Expensive = cmSystemTools::IsOn(val.c_str());
             }
+          if ( key == "RUN_SERIAL" )
+            {
+            rtit->RunSerial = cmSystemTools::IsOn(val.c_str());
+            }
           if ( key == "FAIL_REGULAR_EXPRESSION" )
             {
             std::vector<std::string> lval;
@@ -2127,6 +2131,7 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
   test.IsInBasedOnREOptions = true;
   test.WillFail = false;
   test.Expensive = false;
+  test.RunSerial = false;
   test.Timeout = 0;
   test.Processors = 1;
   if (this->UseIncludeRegExpFlag &&

+ 1 - 0
Source/CTest/cmCTestTestHandler.h

@@ -97,6 +97,7 @@ public:
     bool IsInBasedOnREOptions;
     bool WillFail;
     bool Expensive;
+    bool RunSerial;
     double Timeout;
     int Index;
     //Requested number of process slots

+ 4 - 1
Source/cmSetTestsPropertiesCommand.h

@@ -73,7 +73,10 @@ public:
       "require. This is typically used for MPI tests, and should be used in "
       "conjunction with the ctest_test PARALLEL_LEVEL option.\n"
       "EXPENSIVE: If set to true, this test will be run before tests that "
-      "are not marked as expensive.  This should be used in conjunction with "
+      "are not marked as expensive. This should be used in conjunction with "
+      "the ctest_test PARALLEL_LEVEL option.\n"
+      "RUN_SERIAL: If set to true, this test will not run in parallel with "
+      "any other tests. This should be used in conjunction with "
       "the ctest_test PARALLEL_LEVEL option.\n";
     }