From 5fb958fde950f8a8f9b1629399f0457c46224640 Mon Sep 17 00:00:00 2001 From: Zach Mullen Date: Mon, 7 Sep 2009 10:26:17 -0400 Subject: [PATCH] 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. --- Source/CTest/cmCTestMultiProcessHandler.cxx | 33 +++++++++++++++++---- Source/CTest/cmCTestMultiProcessHandler.h | 2 ++ Source/CTest/cmCTestRunTest.cxx | 2 +- Source/CTest/cmCTestTestHandler.cxx | 5 ++++ Source/CTest/cmCTestTestHandler.h | 1 + Source/cmSetTestsPropertiesCommand.h | 5 +++- 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 07af80459..fadf164d5 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/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(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; diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 9c63be7c9..5d0ae46e8 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/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 TestRunningMap; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index d471c6c3f..0e8d40415 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/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: " diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index d57bfa52a..6ae227b5d 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/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 lval; @@ -2127,6 +2131,7 @@ bool cmCTestTestHandler::AddTest(const std::vector& args) test.IsInBasedOnREOptions = true; test.WillFail = false; test.Expensive = false; + test.RunSerial = false; test.Timeout = 0; test.Processors = 1; if (this->UseIncludeRegExpFlag && diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index e4b5e0736..113c1c9c8 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/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 diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h index f93d9dce8..c975011eb 100644 --- a/Source/cmSetTestsPropertiesCommand.h +++ b/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"; }