Browse Source

ENH: add the ability to run tests by labels

Bill Hoffman 16 years ago
parent
commit
4e710a9ebe

+ 12 - 0
Source/CTest/cmCTestTestCommand.cxx

@@ -26,6 +26,8 @@ cmCTestTestCommand::cmCTestTestCommand()
   this->Arguments[ctt_STRIDE] = "STRIDE";
   this->Arguments[ctt_EXCLUDE] = "EXCLUDE";
   this->Arguments[ctt_INCLUDE] = "INCLUDE";
+  this->Arguments[ctt_EXCLUDE_LABEL] = "EXCLUDE_LABEL";
+  this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL";
   this->Arguments[ctt_LAST] = 0;
   this->Last = ctt_LAST;
 }
@@ -78,6 +80,16 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
     {
     handler->SetOption("IncludeRegularExpression", this->Values[ctt_INCLUDE]);
     }
+  if(this->Values[ctt_EXCLUDE_LABEL])
+    {
+    handler->SetOption("ExcludeLabelRegularExpression",
+                       this->Values[ctt_EXCLUDE_LABEL]);
+    }
+  if(this->Values[ctt_INCLUDE_LABEL])
+    {
+    handler->SetOption("LabelRegularExpression", 
+                       this->Values[ctt_INCLUDE_LABEL]);
+    }
   return handler;
 }
 

+ 8 - 2
Source/CTest/cmCTestTestCommand.h

@@ -63,13 +63,17 @@ public:
       "  ctest_test([BUILD build_dir]\n"
       "             [START start number] [END end number]\n"
       "             [STRIDE stride number] [EXCLUDE exclude regex ]\n"
-      "             [INCLUDE include regex] [RETURN_VALUE res] )\n"
+      "             [INCLUDE include regex] [RETURN_VALUE res] \n" 
+      "             [EXCLUDE_LABEL exclude regex] \n"
+      "             [INCLUDE_LABEL label regex] )\n"
       "Tests the given build directory and stores results in Test.xml. The "
       "second argument is a variable that will hold value. Optionally, "
       "you can specify the starting test number START, the ending test number "
       "END, the number of tests to skip between each test STRIDE, a regular "
       "expression for tests to run INCLUDE, or a regular expression for tests "
-      "to not run EXCLUDE.";
+      "to not run EXCLUDE. EXCLUDE_LABEL and INCLUDE_LABEL are regular "
+      "expression for test to be included or excluded by the test "
+      "property LABEL.";
     }
 
   cmTypeMacro(cmCTestTestCommand, cmCTestHandlerCommand);
@@ -86,6 +90,8 @@ protected:
     ctt_STRIDE,
     ctt_EXCLUDE,
     ctt_INCLUDE,
+    ctt_EXCLUDE_LABEL,
+    ctt_INCLUDE_LABEL,
     ctt_LAST
   };
 };

+ 101 - 1
Source/CTest/cmCTestTestHandler.cxx

@@ -391,6 +391,8 @@ cmCTestTestHandler::cmCTestTestHandler()
 {
   this->UseUnion = false;
 
+  this->UseIncludeLabelRegExpFlag   = false;
+  this->UseExcludeLabelRegExpFlag   = false;
   this->UseIncludeRegExpFlag   = false;
   this->UseExcludeRegExpFlag   = false;
   this->UseExcludeRegExpFirst  = false;
@@ -433,6 +435,8 @@ void cmCTestTestHandler::Initialize()
   this->UseIncludeRegExpFlag = false;
   this->UseExcludeRegExpFlag = false;
   this->UseExcludeRegExpFirst = false;
+  this->IncludeLabelRegularExpression = "";
+  this->ExcludeLabelRegularExpression = "";
   this->IncludeRegExp = "";
   this->ExcludeRegExp = "";
 
@@ -492,6 +496,18 @@ int cmCTestTestHandler::ProcessHandler()
   this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
   this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
   const char* val;
+  val = this->GetOption("LabelRegularExpression");
+  if ( val )
+    {
+    this->UseIncludeLabelRegExpFlag = true;
+    this->IncludeLabelRegExp = val;
+    }
+  val = this->GetOption("ExcludeLabelRegularExpression");
+  if ( val )
+    {
+    this->UseExcludeLabelRegExpFlag = true;
+    this->ExcludeLabelRegularExpression = val;
+    }
   val = this->GetOption("IncludeRegularExpression");
   if ( val )
     {
@@ -938,6 +954,79 @@ void cmCTestTestHandler::ProcessOneTest(cmCTestTestProperties *it,
   this->TestResults.push_back( cres );
 }
 
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
+{
+  // if not using Labels to filter then return
+  if (!this->UseIncludeLabelRegExpFlag )
+    {
+    return;
+    }
+  // if there are no labels and we are filtering by labels
+  // then exclude the test as it does not have the label
+  if(it.Labels.size() == 0 )
+    {
+    it.IsInBasedOnREOptions = false;
+    return;
+    }
+  // check to see if the label regular expression matches
+  bool found = false;  // assume it does not match
+  // loop over all labels and look for match
+  for(std::vector<std::string>::iterator l = it.Labels.begin();
+      l !=  it.Labels.end(); ++l)
+    {
+    if(this->IncludeLabelRegularExpression.find(*l))
+      {
+      found = true;
+      }
+    }
+  // if no match was found, exclude the test
+  if(!found)
+    {
+    it.IsInBasedOnREOptions = false;
+    }
+}
+
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
+{
+  // if not using Labels to filter then return
+  if (!this->UseExcludeLabelRegExpFlag )
+    {
+    return;
+    }
+  // if there are no labels and we are excluding by labels
+  // then do nothing as a no label can not be a match
+  if(it.Labels.size() == 0 )
+    {
+    return;
+    }
+  // check to see if the label regular expression matches
+  bool found = false;  // assume it does not match
+  // loop over all labels and look for match
+  for(std::vector<std::string>::iterator l = it.Labels.begin();
+      l !=  it.Labels.end(); ++l)
+    {
+    if(this->ExcludeLabelRegularExpression.find(*l))
+      {
+      found = true;
+      }
+    }
+  // if match was found, exclude the test
+  if(found)
+    {
+    it.IsInBasedOnREOptions = false;
+    }
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilter(cmCTestTestProperties& it)
+{
+  this->CheckLabelFilterInclude(it);
+  this->CheckLabelFilterExclude(it);
+}
+
 //----------------------------------------------------------------------
 void cmCTestTestHandler::ComputeTestList()
 {
@@ -952,12 +1041,12 @@ void cmCTestTestHandler::ComputeTestList()
     this->GetListOfTests();
     }
   cmCTestTestHandler::ListOfTests::size_type tmsize = this->TestList.size();
-
   // how many tests are in based on RegExp?
   int inREcnt = 0;
   cmCTestTestHandler::ListOfTests::iterator it;
   for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
     {
+    this->CheckLabelFilter(*it);
     if (it->IsInBasedOnREOptions)
       {
       inREcnt ++;
@@ -1808,6 +1897,16 @@ std::string cmCTestTestHandler
 //----------------------------------------------------------------------
 void cmCTestTestHandler::GetListOfTests()
 {
+  if ( !this->IncludeLabelRegExp.empty() )
+    {
+    this->IncludeLabelRegularExpression.
+      compile(this->IncludeLabelRegExp.c_str());
+    }
+  if ( !this->IncludeLabelRegExp.empty() )
+    {
+    this->ExcludeLabelRegularExpression.
+      compile(this->ExcludeLabelRegExp.c_str());
+    }
   if ( !this->IncludeRegExp.empty() )
     {
     this->IncludeTestsRegularExpression.compile(this->IncludeRegExp.c_str());
@@ -2376,6 +2475,7 @@ bool cmCTestTestHandler::SetTestsProperties(
               {
               rtit->Labels.push_back(*crit);
               }
+            
             }
           if ( key == "MEASUREMENT" )
             {

+ 9 - 0
Source/CTest/cmCTestTestHandler.h

@@ -234,16 +234,25 @@ private:
 
   std::vector<int>        TestsToRun;
 
+  bool UseIncludeLabelRegExpFlag;
+  bool UseExcludeLabelRegExpFlag;
   bool UseIncludeRegExpFlag;
   bool UseExcludeRegExpFlag;
   bool UseExcludeRegExpFirst;
+  std::string IncludeLabelRegExp;
+  std::string ExcludeLabelRegExp;
   std::string IncludeRegExp;
   std::string ExcludeRegExp;
+  cmsys::RegularExpression IncludeLabelRegularExpression;
+  cmsys::RegularExpression ExcludeLabelRegularExpression;
   cmsys::RegularExpression IncludeTestsRegularExpression;
   cmsys::RegularExpression ExcludeTestsRegularExpression;
 
   std::string GenerateRegressionImages(const std::string& xml);
   cmsys::RegularExpression DartStuff1;
+  void CheckLabelFilter(cmCTestTestProperties& it);
+  void CheckLabelFilterExclude(cmCTestTestProperties& it);
+  void CheckLabelFilterInclude(cmCTestTestProperties& it);
 
   std::string TestsToRunString;
   bool UseUnion;

+ 16 - 0
Source/cmCTest.cxx

@@ -1813,6 +1813,22 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
     this->GetHandler("memcheck")->
       SetPersistentOption("IncludeRegularExpression", args[i].c_str());
     }
+  if(this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1)
+    {
+    i++;
+    this->GetHandler("test")->
+      SetPersistentOption("LabelRegularExpression", args[i].c_str());
+    this->GetHandler("memcheck")->
+      SetPersistentOption("LabelRegularExpression", args[i].c_str());
+    }
+  if(this->CheckArgument(arg, "-LE", "--label-exclude") && i < args.size() - 1)
+    {
+    i++;
+    this->GetHandler("test")->
+      SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str());
+    this->GetHandler("memcheck")->
+      SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str());
+    }
   
   if(this->CheckArgument(arg, "-E", "--exclude-regex") &&
      i < args.size() - 1)