summaryrefslogtreecommitdiffstats
path: root/Source/CTest
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-03-09 16:19:56 (GMT)
committerBrad King <brad.king@kitware.com>2009-03-09 16:19:56 (GMT)
commit1d96c943e0d029c4ad0b98d5a08e34f54ed8a8e5 (patch)
treeca4a1a4510666c516a3e77e9613793a0272a6dec /Source/CTest
parenta86e81c3589d64a2a777b1b90490cb80b951d983 (diff)
downloadCMake-1d96c943e0d029c4ad0b98d5a08e34f54ed8a8e5.zip
CMake-1d96c943e0d029c4ad0b98d5a08e34f54ed8a8e5.tar.gz
CMake-1d96c943e0d029c4ad0b98d5a08e34f54ed8a8e5.tar.bz2
ENH: Efficiently filter CTest coverage by label
This teaches CTest to process coverage information only for object files in targets containing labels of interest. This change also improves loading of global coverage information by globbing only in each target support directory instead of the entire build tree.
Diffstat (limited to 'Source/CTest')
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx73
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h3
2 files changed, 58 insertions, 18 deletions
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index fa9a220..ee9a169 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -694,17 +694,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
cmsys::RegularExpression st2re5(st2gcovOutputRex5.c_str());
cmsys::RegularExpression st2re6(st2gcovOutputRex6.c_str());
-
- cmsys::Glob gl;
- gl.RecurseOn();
- gl.RecurseThroughSymlinksOff();
- std::string daGlob = cont->BinaryDir + "/*.da";
- gl.FindFiles(daGlob);
- std::vector<std::string> files = gl.GetFiles();
- daGlob = cont->BinaryDir + "/*.gcda";
- gl.FindFiles(daGlob);
- std::vector<std::string>& moreFiles = gl.GetFiles();
- files.insert(files.end(), moreFiles.begin(), moreFiles.end());
+ std::vector<std::string> files;
+ this->FindGCovFiles(files);
std::vector<std::string>::iterator it;
if ( files.size() == 0 )
@@ -1061,6 +1052,37 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
return file_count;
}
+//----------------------------------------------------------------------------
+void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
+{
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+
+ for(LabelMapType::const_iterator lmi = this->TargetDirs.begin();
+ lmi != this->TargetDirs.end(); ++lmi)
+ {
+ // Skip targets containing no interesting labels.
+ if(!this->IntersectsFilter(lmi->second))
+ {
+ continue;
+ }
+
+ // Coverage files appear next to their object files in the target
+ // support directory.
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " globbing for coverage in: " << lmi->first << std::endl);
+ std::string daGlob = lmi->first;
+ daGlob += "/*.da";
+ gl.FindFiles(daGlob);
+ files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
+ daGlob = lmi->first;
+ daGlob += "/*.gcda";
+ gl.FindFiles(daGlob);
+ files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
+ }
+}
+
//----------------------------------------------------------------------
int cmCTestCoverageHandler::HandleTracePyCoverage(
cmCTestCoverageHandlerContainer* cont)
@@ -1763,6 +1785,7 @@ void cmCTestCoverageHandler::LoadLabels()
//----------------------------------------------------------------------
void cmCTestCoverageHandler::LoadLabels(const char* dir)
{
+ LabelSet& dirLabels = this->TargetDirs[dir];
std::string fname = dir;
fname += "/Labels.txt";
std::ifstream fin(fname.c_str());
@@ -1789,6 +1812,7 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir)
// Label lines appear indented by one space.
std::string label = line.substr(1);
int id = this->GetLabelId(label);
+ dirLabels.insert(id);
if(inTarget)
{
targetLabels.push_back(id);
@@ -1847,6 +1871,23 @@ cmCTestCoverageHandler::SetLabelFilter(std::set<cmStdString> const& labels)
}
//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::IntersectsFilter(LabelSet const& labels)
+{
+ // If there is no label filter then nothing is filtered out.
+ if(this->LabelFilter.empty())
+ {
+ return true;
+ }
+
+ std::vector<int> ids;
+ cmsys_stl::set_intersection
+ (labels.begin(), labels.end(),
+ this->LabelFilter.begin(), this->LabelFilter.end(),
+ cmsys_stl::back_inserter(ids));
+ return !ids.empty();
+}
+
+//----------------------------------------------------------------------
bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
{
// If there is no label filter then nothing is filtered out.
@@ -1857,15 +1898,11 @@ bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
// The source is filtered out if it does not have any labels in
// common with the filter set.
- std::vector<int> ids;
std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc);
- if(li != this->SourceLabels.end() && !li->second.empty())
+ if(li != this->SourceLabels.end())
{
- cmsys_stl::set_intersection
- (li->second.begin(), li->second.end(),
- this->LabelFilter.begin(), this->LabelFilter.end(),
- cmsys_stl::back_inserter(ids));
+ return !this->IntersectsFilter(li->second);
}
- return ids.empty();
+ return true;
}
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 46bcec1..c58b6ab 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -61,6 +61,7 @@ private:
//! Handle coverage using GCC's GCov
int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont);
+ void FindGCovFiles(std::vector<std::string>& files);
//! Handle coverage using Bullseye
int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont);
@@ -145,6 +146,7 @@ private:
class LabelSet: public std::set<int> {};
typedef std::map<cmStdString, LabelSet> LabelMapType;
LabelMapType SourceLabels;
+ LabelMapType TargetDirs;
// Map from label name to label id.
typedef std::map<cmStdString, int> LabelIdMapType;
@@ -159,6 +161,7 @@ private:
// Label-based filtering.
std::set<int> LabelFilter;
+ bool IntersectsFilter(LabelSet const& labels);
bool IsFilteredOut(std::string const& source);
};