|
@@ -32,6 +32,22 @@
|
|
|
|
|
|
|
|
#define SAFEDIV(x,y) (((y)!=0)?((x)/(y)):(0))
|
|
#define SAFEDIV(x,y) (((y)!=0)?((x)/(y)):(0))
|
|
|
|
|
|
|
|
|
|
+//----------------------------------------------------------------------
|
|
|
|
|
+//**********************************************************************
|
|
|
|
|
+class cmCTestCoverageHandlerContainer
|
|
|
|
|
+{
|
|
|
|
|
+public:
|
|
|
|
|
+ int Error;
|
|
|
|
|
+ std::string SourceDir;
|
|
|
|
|
+ std::string BinaryDir;
|
|
|
|
|
+ typedef std::vector<int> SingleFileCoverageVector;
|
|
|
|
|
+ typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap;
|
|
|
|
|
+ TotalCoverageMap TotalCoverage;
|
|
|
|
|
+ std::ostream* OFS;
|
|
|
|
|
+};
|
|
|
|
|
+//**********************************************************************
|
|
|
|
|
+//----------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
//----------------------------------------------------------------------
|
|
//----------------------------------------------------------------------
|
|
|
cmCTestCoverageHandler::cmCTestCoverageHandler()
|
|
cmCTestCoverageHandler::cmCTestCoverageHandler()
|
|
|
{
|
|
{
|
|
@@ -186,12 +202,12 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
return error;
|
|
return error;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ std::string coverage_start_time = this->CTest->CurrentTime();
|
|
|
|
|
+
|
|
|
std::string sourceDir
|
|
std::string sourceDir
|
|
|
= this->CTest->GetCTestConfiguration("SourceDirectory");
|
|
= this->CTest->GetCTestConfiguration("SourceDirectory");
|
|
|
std::string binaryDir
|
|
std::string binaryDir
|
|
|
= this->CTest->GetCTestConfiguration("BuildDirectory");
|
|
= this->CTest->GetCTestConfiguration("BuildDirectory");
|
|
|
- std::string gcovCommand
|
|
|
|
|
- = this->CTest->GetCTestConfiguration("CoverageCommand");
|
|
|
|
|
|
|
|
|
|
cmGeneratedFileStream ofs;
|
|
cmGeneratedFileStream ofs;
|
|
|
double elapsed_time_start = cmSystemTools::GetTime();
|
|
double elapsed_time_start = cmSystemTools::GetTime();
|
|
@@ -209,191 +225,474 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
std::string asfGlob = sourceDir + "/*";
|
|
std::string asfGlob = sourceDir + "/*";
|
|
|
std::string abfGlob = binaryDir + "/*";
|
|
std::string abfGlob = binaryDir + "/*";
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // Style 1
|
|
|
|
|
- std::string st1gcovOutputRex1
|
|
|
|
|
- = "[0-9]+\\.[0-9]+% of [0-9]+ (source |)lines executed in file (.*)$";
|
|
|
|
|
- std::string st1gcovOutputRex2 = "^Creating (.*\\.gcov)\\.";
|
|
|
|
|
- cmsys::RegularExpression st1re1(st1gcovOutputRex1.c_str());
|
|
|
|
|
- cmsys::RegularExpression st1re2(st1gcovOutputRex2.c_str());
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Style 2
|
|
|
|
|
- std::string st2gcovOutputRex1 = "^File *[`'](.*)'$";
|
|
|
|
|
- std::string st2gcovOutputRex2
|
|
|
|
|
- = "Lines executed: *[0-9]+\\.[0-9]+% of [0-9]+$";
|
|
|
|
|
- std::string st2gcovOutputRex3 = "^(.*):creating [`'](.*\\.gcov)'";
|
|
|
|
|
- std::string st2gcovOutputRex4 = "^(.*):unexpected EOF *$";
|
|
|
|
|
- std::string st2gcovOutputRex5 = "^(.*):cannot open source file*$";
|
|
|
|
|
- std::string st2gcovOutputRex6
|
|
|
|
|
- = "^(.*):source file is newer than graph file `(.*)'$";
|
|
|
|
|
- cmsys::RegularExpression st2re1(st2gcovOutputRex1.c_str());
|
|
|
|
|
- cmsys::RegularExpression st2re2(st2gcovOutputRex2.c_str());
|
|
|
|
|
- cmsys::RegularExpression st2re3(st2gcovOutputRex3.c_str());
|
|
|
|
|
- cmsys::RegularExpression st2re4(st2gcovOutputRex4.c_str());
|
|
|
|
|
- cmsys::RegularExpression st2re5(st2gcovOutputRex5.c_str());
|
|
|
|
|
- cmsys::RegularExpression st2re6(st2gcovOutputRex6.c_str());
|
|
|
|
|
-
|
|
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Performing coverage" << std::endl);
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Performing coverage" << std::endl);
|
|
|
|
|
|
|
|
- std::string coverage_start_time = this->CTest->CurrentTime();
|
|
|
|
|
|
|
+ cmCTestCoverageHandlerContainer cont;
|
|
|
|
|
+ cont.Error = error;
|
|
|
|
|
+ cont.SourceDir = sourceDir;
|
|
|
|
|
+ cont.BinaryDir = binaryDir;
|
|
|
|
|
+ cont.OFS = &ofs;
|
|
|
|
|
|
|
|
- std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
|
|
|
|
|
- std::string tempDir = testingDir + "/CoverageInfo";
|
|
|
|
|
- std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
|
|
|
|
|
- cmSystemTools::MakeDirectory(tempDir.c_str());
|
|
|
|
|
- cmSystemTools::ChangeDirectory(tempDir.c_str());
|
|
|
|
|
|
|
+ int file_count = 0;
|
|
|
|
|
|
|
|
- cmsys::Glob gl;
|
|
|
|
|
- gl.RecurseOn();
|
|
|
|
|
- std::string daGlob = binaryDir + "/*.da";
|
|
|
|
|
- gl.FindFiles(daGlob);
|
|
|
|
|
- std::vector<std::string> files = gl.GetFiles();
|
|
|
|
|
- daGlob = binaryDir + "/*.gcda";
|
|
|
|
|
- gl.FindFiles(daGlob);
|
|
|
|
|
- std::vector<std::string>& moreFiles = gl.GetFiles();
|
|
|
|
|
- files.insert(files.end(), moreFiles.begin(), moreFiles.end());
|
|
|
|
|
- std::vector<std::string>::iterator it;
|
|
|
|
|
|
|
+ file_count += this->HandleGCovCoverage(&cont);
|
|
|
|
|
+ if ( file_count < 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ return error;
|
|
|
|
|
+ }
|
|
|
|
|
+ file_count += this->HandleTracePyCoverage(&cont);
|
|
|
|
|
+ if ( file_count < 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ return error;
|
|
|
|
|
+ }
|
|
|
|
|
+ error = cont.Error;
|
|
|
|
|
|
|
|
- if ( files.size() == 0 )
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if ( file_count == 0 )
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, WARNING,
|
|
cmCTestLog(this->CTest, WARNING,
|
|
|
" Cannot find any coverage files. Ignoring Coverage request."
|
|
" Cannot find any coverage files. Ignoring Coverage request."
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- // No coverage files is a valid thing, so the exit code is 0
|
|
|
|
|
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ return error;
|
|
|
}
|
|
}
|
|
|
|
|
+ cmGeneratedFileStream covSumFile;
|
|
|
|
|
+ cmGeneratedFileStream covLogFile;
|
|
|
|
|
|
|
|
- this->CustomCoverageExcludeRegex.empty();
|
|
|
|
|
- std::vector<cmStdString>::iterator rexIt;
|
|
|
|
|
- for ( rexIt = this->CustomCoverageExclude.begin();
|
|
|
|
|
- rexIt != this->CustomCoverageExclude.end();
|
|
|
|
|
- ++ rexIt )
|
|
|
|
|
|
|
+ if (!this->StartResultingXML("Coverage", covSumFile))
|
|
|
{
|
|
{
|
|
|
- this->CustomCoverageExcludeRegex.push_back(
|
|
|
|
|
- cmsys::RegularExpression(rexIt->c_str()));
|
|
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Cannot open coverage summary file." << std::endl);
|
|
|
|
|
+ return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- typedef std::vector<int> singleFileCoverageVector;
|
|
|
|
|
- typedef std::map<std::string, singleFileCoverageVector> totalCoverageMap;
|
|
|
|
|
-
|
|
|
|
|
- totalCoverageMap totalCoverage;
|
|
|
|
|
-
|
|
|
|
|
- int gcovStyle = 0;
|
|
|
|
|
-
|
|
|
|
|
- std::set<std::string> missingFiles;
|
|
|
|
|
|
|
+ this->CTest->StartXML(covSumFile);
|
|
|
|
|
+ // Produce output xml files
|
|
|
|
|
|
|
|
- std::string actualSourceFile = "";
|
|
|
|
|
|
|
+ covSumFile << "<Coverage>" << std::endl
|
|
|
|
|
+ << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>"
|
|
|
|
|
+ << std::endl;
|
|
|
|
|
+ int logFileCount = 0;
|
|
|
|
|
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator fileIterator;
|
|
|
|
|
+ int cnt = 0;
|
|
|
|
|
+ long total_tested = 0;
|
|
|
|
|
+ long total_untested = 0;
|
|
|
|
|
+ //std::string fullSourceDir = sourceDir + "/";
|
|
|
|
|
+ //std::string fullBinaryDir = binaryDir + "/";
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT,
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT,
|
|
|
- " Processing coverage (each . represents one file):" << std::endl);
|
|
|
|
|
|
|
+ " Acumulating results (each . represents one file):" << std::endl);
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
- int file_count = 0;
|
|
|
|
|
- for ( it = files.begin(); it != files.end(); ++ it )
|
|
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<std::string> errorsWhileAccumulating;
|
|
|
|
|
+
|
|
|
|
|
+ file_count = 0;
|
|
|
|
|
+ for ( fileIterator = cont.TotalCoverage.begin();
|
|
|
|
|
+ fileIterator != cont.TotalCoverage.end();
|
|
|
|
|
+ ++fileIterator )
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
|
|
|
- std::string fileDir = cmSystemTools::GetFilenamePath(it->c_str());
|
|
|
|
|
- std::string command = "\"" + gcovCommand + "\" -l -o \"" + fileDir
|
|
|
|
|
- + "\" \"" + *it + "\"";
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- std::string output = "";
|
|
|
|
|
- std::string errors = "";
|
|
|
|
|
- int retVal = 0;
|
|
|
|
|
- ofs << "* Run coverage for: " << fileDir.c_str() << std::endl;
|
|
|
|
|
- ofs << " Command: " << command.c_str() << std::endl;
|
|
|
|
|
- int res = this->CTest->RunCommand(command.c_str(), &output, &errors,
|
|
|
|
|
- &retVal, tempDir.c_str(), 0 /*this->TimeOut*/);
|
|
|
|
|
-
|
|
|
|
|
- ofs << " Output: " << output.c_str() << std::endl;
|
|
|
|
|
- ofs << " Errors: " << errors.c_str() << std::endl;
|
|
|
|
|
- if ( ! res )
|
|
|
|
|
|
|
+ file_count ++;
|
|
|
|
|
+ if ( file_count % 50 == 0 )
|
|
|
{
|
|
{
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- "Problem running coverage on file: " << it->c_str() << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- "Command produced error: " << errors << std::endl);
|
|
|
|
|
- error ++;
|
|
|
|
|
- continue;
|
|
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
|
|
|
|
|
+ << " out of "
|
|
|
|
|
+ << cont.TotalCoverage.size() << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
}
|
|
}
|
|
|
- if ( retVal != 0 )
|
|
|
|
|
|
|
+ if ( cnt % 100 == 0 )
|
|
|
{
|
|
{
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Coverage command returned: "
|
|
|
|
|
- << retVal << " while processing: " << it->c_str() << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- "Command produced error: " << error << std::endl);
|
|
|
|
|
|
|
+ this->EndCoverageLogFile(covLogFile, logFileCount);
|
|
|
|
|
+ logFileCount ++;
|
|
|
|
|
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ const std::string fullFileName = fileIterator->first;
|
|
|
|
|
+ const std::string fileName
|
|
|
|
|
+ = cmSystemTools::GetFilenameName(fullFileName.c_str());
|
|
|
|
|
+ std::string fullFilePath
|
|
|
|
|
+ = cmSystemTools::GetFilenamePath(fullFileName.c_str());
|
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
- "--------------------------------------------------------------"
|
|
|
|
|
- << std::endl
|
|
|
|
|
- << output << std::endl
|
|
|
|
|
- << "--------------------------------------------------------------"
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- std::vector<cmStdString> lines;
|
|
|
|
|
- std::vector<cmStdString>::iterator line;
|
|
|
|
|
|
|
+ "Process file: " << fullFileName << std::endl);
|
|
|
|
|
|
|
|
|
|
+ cmSystemTools::ConvertToUnixSlashes(fullFilePath);
|
|
|
|
|
|
|
|
- // Globals for storing current source file and current gcov file;
|
|
|
|
|
- cmSystemTools::Split(output.c_str(), lines);
|
|
|
|
|
- for ( line = lines.begin(); line != lines.end(); ++line)
|
|
|
|
|
|
|
+ if ( !cmSystemTools::FileExists(fullFileName.c_str()) )
|
|
|
{
|
|
{
|
|
|
- std::string sourceFile;
|
|
|
|
|
- std::string gcovFile;
|
|
|
|
|
- cmCTestLog(this->CTest, DEBUG, "Line: [" << line->c_str() << "]"
|
|
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
|
|
|
|
|
+ << fullFileName.c_str() << std::endl);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bool shouldIDoCoverage
|
|
|
|
|
+ = this->ShouldIDoCoverage(fullFileName.c_str(),
|
|
|
|
|
+ sourceDir.c_str(), binaryDir.c_str());
|
|
|
|
|
+ if ( !shouldIDoCoverage )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ ".NoDartCoverage found, so skip coverage check for: "
|
|
|
|
|
+ << fullFileName.c_str()
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- if ( line->size() == 0 )
|
|
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov
|
|
|
|
|
+ = fileIterator->second;
|
|
|
|
|
+ covLogFile << "\t<File Name=\""
|
|
|
|
|
+ << this->CTest->MakeXMLSafe(fileName.c_str())
|
|
|
|
|
+ << "\" FullPath=\"" << this->CTest->MakeXMLSafe(
|
|
|
|
|
+ this->CTest->GetShortPathToFile(
|
|
|
|
|
+ fileIterator->first.c_str())) << "\">" << std::endl
|
|
|
|
|
+ << "\t\t<Report>" << std::endl;
|
|
|
|
|
+
|
|
|
|
|
+ std::ifstream ifs(fullFileName.c_str());
|
|
|
|
|
+ if ( !ifs)
|
|
|
|
|
+ {
|
|
|
|
|
+ cmOStringStream ostr;
|
|
|
|
|
+ ostr << "Cannot open source file: " << fullFileName.c_str();
|
|
|
|
|
+ errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
+ error ++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int tested = 0;
|
|
|
|
|
+ int untested = 0;
|
|
|
|
|
+
|
|
|
|
|
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector::size_type cc;
|
|
|
|
|
+ std::string line;
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ "Actually perfoming coverage for: " << fullFileName << std::endl);
|
|
|
|
|
+ for ( cc= 0; cc < fcov.size(); cc ++ )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( !cmSystemTools::GetLineFromStream(ifs, line) &&
|
|
|
|
|
+ cc != fcov.size() -1 )
|
|
|
{
|
|
{
|
|
|
- // Ignore empty line; probably style 2
|
|
|
|
|
|
|
+ cmOStringStream ostr;
|
|
|
|
|
+ ostr << "Problem reading source file: " << fullFileName.c_str()
|
|
|
|
|
+ << " line:" << cc;
|
|
|
|
|
+ errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
+ error ++;
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- else if ( st1re1.find(line->c_str()) )
|
|
|
|
|
|
|
+ covLogFile << "\t\t<Line Number=\"" << cc << "\" Count=\"" << fcov[cc]
|
|
|
|
|
+ << "\">"
|
|
|
|
|
+ << this->CTest->MakeXMLSafe(line.c_str()) << "</Line>" << std::endl;
|
|
|
|
|
+ if ( fcov[cc] == 0 )
|
|
|
{
|
|
{
|
|
|
- if ( gcovStyle != 0 )
|
|
|
|
|
- {
|
|
|
|
|
- if ( gcovStyle != 1 )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- error ++;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- gcovStyle = 1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- actualSourceFile = "";
|
|
|
|
|
- sourceFile = st1re1.match(2);
|
|
|
|
|
|
|
+ untested ++;
|
|
|
}
|
|
}
|
|
|
- else if ( st1re2.find(line->c_str() ) )
|
|
|
|
|
|
|
+ else if ( fcov[cc] > 0 )
|
|
|
{
|
|
{
|
|
|
- if ( gcovStyle != 0 )
|
|
|
|
|
- {
|
|
|
|
|
- if ( gcovStyle != 1 )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- error ++;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- gcovStyle = 1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- gcovFile = st1re2.match(1);
|
|
|
|
|
|
|
+ tested ++;
|
|
|
}
|
|
}
|
|
|
- else if ( st2re1.find(line->c_str() ) )
|
|
|
|
|
- {
|
|
|
|
|
- if ( gcovStyle != 0 )
|
|
|
|
|
- {
|
|
|
|
|
- if ( gcovStyle != 2 )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- error ++;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- gcovStyle = 2;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- actualSourceFile = "";
|
|
|
|
|
- sourceFile = st2re1.match(1);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ if ( cmSystemTools::GetLineFromStream(ifs, line) )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmOStringStream ostr;
|
|
|
|
|
+ ostr << "Looks like there are more lines in the file: " << line;
|
|
|
|
|
+ errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
+ }
|
|
|
|
|
+ float cper = 0;
|
|
|
|
|
+ float cmet = 0;
|
|
|
|
|
+ if ( tested + untested > 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cper = (100 * SAFEDIV(static_cast<float>(tested),
|
|
|
|
|
+ static_cast<float>(tested + untested)));
|
|
|
|
|
+ cmet = ( SAFEDIV(static_cast<float>(tested + 10),
|
|
|
|
|
+ static_cast<float>(tested + untested + 10)));
|
|
|
|
|
+ }
|
|
|
|
|
+ total_tested += tested;
|
|
|
|
|
+ total_untested += untested;
|
|
|
|
|
+ covLogFile << "\t\t</Report>" << std::endl
|
|
|
|
|
+ << "\t</File>" << std::endl;
|
|
|
|
|
+ covSumFile << "\t<File Name=\"" << this->CTest->MakeXMLSafe(fileName)
|
|
|
|
|
+ << "\" FullPath=\"" << this->CTest->MakeXMLSafe(
|
|
|
|
|
+ this->CTest->GetShortPathToFile(fullFileName.c_str()))
|
|
|
|
|
+ << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
|
|
|
|
|
+ << "\t\t<LOCTested>" << tested << "</LOCTested>\n"
|
|
|
|
|
+ << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
|
|
|
|
|
+ << "\t\t<PercentCoverage>";
|
|
|
|
|
+ covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
+ covSumFile.precision(2);
|
|
|
|
|
+ covSumFile << (cper) << "</PercentCoverage>\n"
|
|
|
|
|
+ << "\t\t<CoverageMetric>";
|
|
|
|
|
+ covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
+ covSumFile.precision(2);
|
|
|
|
|
+ covSumFile << (cmet) << "</CoverageMetric>\n"
|
|
|
|
|
+ << "\t</File>" << std::endl;
|
|
|
|
|
+ cnt ++;
|
|
|
|
|
+ }
|
|
|
|
|
+ this->EndCoverageLogFile(covLogFile, logFileCount);
|
|
|
|
|
+
|
|
|
|
|
+ if ( errorsWhileAccumulating.size() > 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Error(s) while acumulating results:" << std::endl);
|
|
|
|
|
+ std::vector<std::string>::iterator erIt;
|
|
|
|
|
+ for ( erIt = errorsWhileAccumulating.begin();
|
|
|
|
|
+ erIt != errorsWhileAccumulating.end();
|
|
|
|
|
+ ++ erIt )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ " " << erIt->c_str() << std::endl);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int total_lines = total_tested + total_untested;
|
|
|
|
|
+ float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
|
|
|
|
|
+ static_cast<float>(total_lines));
|
|
|
|
|
+ if ( total_lines == 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ percent_coverage = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::string end_time = this->CTest->CurrentTime();
|
|
|
|
|
+
|
|
|
|
|
+ covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
|
|
|
|
|
+ << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
|
|
|
|
|
+ << "\t<LOC>" << total_lines << "</LOC>\n"
|
|
|
|
|
+ << "\t<PercentCoverage>";
|
|
|
|
|
+ covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
+ covSumFile.precision(2);
|
|
|
|
|
+ covSumFile << (percent_coverage)<< "</PercentCoverage>\n"
|
|
|
|
|
+ << "\t<EndDateTime>" << end_time << "</EndDateTime>\n";
|
|
|
|
|
+ covSumFile << "<ElapsedMinutes>" <<
|
|
|
|
|
+ static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
|
|
|
|
|
+ << "</ElapsedMinutes>"
|
|
|
|
|
+ << "</Coverage>" << std::endl;
|
|
|
|
|
+ this->CTest->EndXML(covSumFile);
|
|
|
|
|
+
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "" << std::endl
|
|
|
|
|
+ << "\tCovered LOC: "
|
|
|
|
|
+ << total_tested << std::endl
|
|
|
|
|
+ << "\tNot covered LOC: " << total_untested << std::endl
|
|
|
|
|
+ << "\tTotal LOC: " << total_lines << std::endl
|
|
|
|
|
+ << "\tPercentage Coverage: "
|
|
|
|
|
+ << std::setiosflags(std::ios::fixed)
|
|
|
|
|
+ << std::setprecision(2)
|
|
|
|
|
+ << (percent_coverage) << "%" << std::endl);
|
|
|
|
|
+
|
|
|
|
|
+ ofs << "\tCovered LOC: " << total_tested << std::endl
|
|
|
|
|
+ << "\tNot covered LOC: " << total_untested << std::endl
|
|
|
|
|
+ << "\tTotal LOC: " << total_lines << std::endl
|
|
|
|
|
+ << "\tPercentage Coverage: "
|
|
|
|
|
+ << std::setiosflags(std::ios::fixed)
|
|
|
|
|
+ << std::setprecision(2)
|
|
|
|
|
+ << (percent_coverage) << "%" << std::endl;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ if ( error )
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//----------------------------------------------------------------------
|
|
|
|
|
+void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf)
|
|
|
|
|
+{
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ " Add coverage exclude regular expressions." << std::endl);
|
|
|
|
|
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE",
|
|
|
|
|
+ this->CustomCoverageExclude);
|
|
|
|
|
+ std::vector<cmStdString>::iterator it;
|
|
|
|
|
+ for ( it = this->CustomCoverageExclude.begin();
|
|
|
|
|
+ it != this->CustomCoverageExclude.end();
|
|
|
|
|
+ ++ it )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: "
|
|
|
|
|
+ << it->c_str() << std::endl);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//----------------------------------------------------------------------
|
|
|
|
|
+int cmCTestCoverageHandler::HandleGCovCoverage(
|
|
|
|
|
+ cmCTestCoverageHandlerContainer* cont)
|
|
|
|
|
+{
|
|
|
|
|
+ std::string gcovCommand
|
|
|
|
|
+ = this->CTest->GetCTestConfiguration("CoverageCommand");
|
|
|
|
|
+
|
|
|
|
|
+ // Style 1
|
|
|
|
|
+ std::string st1gcovOutputRex1
|
|
|
|
|
+ = "[0-9]+\\.[0-9]+% of [0-9]+ (source |)lines executed in file (.*)$";
|
|
|
|
|
+ std::string st1gcovOutputRex2 = "^Creating (.*\\.gcov)\\.";
|
|
|
|
|
+ cmsys::RegularExpression st1re1(st1gcovOutputRex1.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st1re2(st1gcovOutputRex2.c_str());
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // Style 2
|
|
|
|
|
+ std::string st2gcovOutputRex1 = "^File *[`'](.*)'$";
|
|
|
|
|
+ std::string st2gcovOutputRex2
|
|
|
|
|
+ = "Lines executed: *[0-9]+\\.[0-9]+% of [0-9]+$";
|
|
|
|
|
+ std::string st2gcovOutputRex3 = "^(.*):creating [`'](.*\\.gcov)'";
|
|
|
|
|
+ std::string st2gcovOutputRex4 = "^(.*):unexpected EOF *$";
|
|
|
|
|
+ std::string st2gcovOutputRex5 = "^(.*):cannot open source file*$";
|
|
|
|
|
+ std::string st2gcovOutputRex6
|
|
|
|
|
+ = "^(.*):source file is newer than graph file `(.*)'$";
|
|
|
|
|
+ cmsys::RegularExpression st2re1(st2gcovOutputRex1.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st2re2(st2gcovOutputRex2.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st2re3(st2gcovOutputRex3.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st2re4(st2gcovOutputRex4.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st2re5(st2gcovOutputRex5.c_str());
|
|
|
|
|
+ cmsys::RegularExpression st2re6(st2gcovOutputRex6.c_str());
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ cmsys::Glob gl;
|
|
|
|
|
+ gl.RecurseOn();
|
|
|
|
|
+ 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>::iterator it;
|
|
|
|
|
+
|
|
|
|
|
+ if ( files.size() == 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ " Cannot find any GCov coverage files."
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ // No coverage files is a valid thing, so the exit code is 0
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
|
|
|
|
|
+ std::string tempDir = testingDir + "/CoverageInfo";
|
|
|
|
|
+ std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
|
|
|
|
|
+ cmSystemTools::MakeDirectory(tempDir.c_str());
|
|
|
|
|
+ cmSystemTools::ChangeDirectory(tempDir.c_str());
|
|
|
|
|
+
|
|
|
|
|
+ this->CustomCoverageExcludeRegex.empty();
|
|
|
|
|
+ std::vector<cmStdString>::iterator rexIt;
|
|
|
|
|
+ for ( rexIt = this->CustomCoverageExclude.begin();
|
|
|
|
|
+ rexIt != this->CustomCoverageExclude.end();
|
|
|
|
|
+ ++ rexIt )
|
|
|
|
|
+ {
|
|
|
|
|
+ this->CustomCoverageExcludeRegex.push_back(
|
|
|
|
|
+ cmsys::RegularExpression(rexIt->c_str()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int gcovStyle = 0;
|
|
|
|
|
+
|
|
|
|
|
+ std::set<std::string> missingFiles;
|
|
|
|
|
+
|
|
|
|
|
+ std::string actualSourceFile = "";
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
|
|
|
|
|
+ " Processing coverage (each . represents one file):" << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
|
|
+ int file_count = 0;
|
|
|
|
|
+ for ( it = files.begin(); it != files.end(); ++ it )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
|
|
|
|
|
+ std::string fileDir = cmSystemTools::GetFilenamePath(it->c_str());
|
|
|
|
|
+ std::string command = "\"" + gcovCommand + "\" -l -o \"" + fileDir
|
|
|
|
|
+ + "\" \"" + *it + "\"";
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ std::string output = "";
|
|
|
|
|
+ std::string errors = "";
|
|
|
|
|
+ int retVal = 0;
|
|
|
|
|
+ *cont->OFS << "* Run coverage for: " << fileDir.c_str() << std::endl;
|
|
|
|
|
+ *cont->OFS << " Command: " << command.c_str() << std::endl;
|
|
|
|
|
+ int res = this->CTest->RunCommand(command.c_str(), &output, &errors,
|
|
|
|
|
+ &retVal, tempDir.c_str(), 0 /*this->TimeOut*/);
|
|
|
|
|
+
|
|
|
|
|
+ *cont->OFS << " Output: " << output.c_str() << std::endl;
|
|
|
|
|
+ *cont->OFS << " Errors: " << errors.c_str() << std::endl;
|
|
|
|
|
+ if ( ! res )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Problem running coverage on file: " << it->c_str() << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Command produced error: " << errors << std::endl);
|
|
|
|
|
+ cont->Error ++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ( retVal != 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Coverage command returned: "
|
|
|
|
|
+ << retVal << " while processing: " << it->c_str() << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Command produced error: " << cont->Error << std::endl);
|
|
|
|
|
+ }
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ "--------------------------------------------------------------"
|
|
|
|
|
+ << std::endl
|
|
|
|
|
+ << output << std::endl
|
|
|
|
|
+ << "--------------------------------------------------------------"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ std::vector<cmStdString> lines;
|
|
|
|
|
+ std::vector<cmStdString>::iterator line;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // Globals for storing current source file and current gcov file;
|
|
|
|
|
+ cmSystemTools::Split(output.c_str(), lines);
|
|
|
|
|
+ for ( line = lines.begin(); line != lines.end(); ++line)
|
|
|
|
|
+ {
|
|
|
|
|
+ std::string sourceFile;
|
|
|
|
|
+ std::string gcovFile;
|
|
|
|
|
+ cmCTestLog(this->CTest, DEBUG, "Line: [" << line->c_str() << "]"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ if ( line->size() == 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ // Ignore empty line; probably style 2
|
|
|
|
|
+ }
|
|
|
|
|
+ else if ( st1re1.find(line->c_str()) )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 1 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ cont->Error ++;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ gcovStyle = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ actualSourceFile = "";
|
|
|
|
|
+ sourceFile = st1re1.match(2);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if ( st1re2.find(line->c_str() ) )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 1 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ cont->Error ++;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ gcovStyle = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ gcovFile = st1re2.match(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if ( st2re1.find(line->c_str() ) )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( gcovStyle != 2 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ cont->Error ++;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ gcovStyle = 2;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ actualSourceFile = "";
|
|
|
|
|
+ sourceFile = st2re1.match(1);
|
|
|
}
|
|
}
|
|
|
else if ( st2re2.find(line->c_str() ) )
|
|
else if ( st2re2.find(line->c_str() ) )
|
|
|
{
|
|
{
|
|
@@ -403,7 +702,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
gcovStyle = 2;
|
|
gcovStyle = 2;
|
|
@@ -417,7 +716,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
gcovStyle = 2;
|
|
gcovStyle = 2;
|
|
@@ -433,7 +732,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
gcovStyle = 2;
|
|
gcovStyle = 2;
|
|
@@ -450,7 +749,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
gcovStyle = 2;
|
|
gcovStyle = 2;
|
|
@@ -467,7 +766,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style"
|
|
|
<< std::endl);
|
|
<< std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
gcovStyle = 2;
|
|
gcovStyle = 2;
|
|
@@ -480,12 +779,13 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
"Unknown line: [" << line->c_str() << "]" << std::endl);
|
|
"Unknown line: [" << line->c_str() << "]" << std::endl);
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cont->Error ++;
|
|
|
//abort();
|
|
//abort();
|
|
|
}
|
|
}
|
|
|
if ( !gcovFile.empty() && actualSourceFile.size() )
|
|
if ( !gcovFile.empty() && actualSourceFile.size() )
|
|
|
{
|
|
{
|
|
|
- singleFileCoverageVector* vec = &totalCoverage[actualSourceFile];
|
|
|
|
|
|
|
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector* vec
|
|
|
|
|
+ = &cont->TotalCoverage[actualSourceFile];
|
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in file: "
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in file: "
|
|
|
<< gcovFile << std::endl);
|
|
<< gcovFile << std::endl);
|
|
|
std::ifstream ifile(gcovFile.c_str());
|
|
std::ifstream ifile(gcovFile.c_str());
|
|
@@ -527,7 +827,7 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
if ( lineIdx >= 0 )
|
|
if ( lineIdx >= 0 )
|
|
|
{
|
|
{
|
|
|
while ( vec->size() <=
|
|
while ( vec->size() <=
|
|
|
- static_cast<singleFileCoverageVector::size_type>(lineIdx) )
|
|
|
|
|
|
|
+ static_cast<size_t>(lineIdx) )
|
|
|
{
|
|
{
|
|
|
vec->push_back(-1);
|
|
vec->push_back(-1);
|
|
|
}
|
|
}
|
|
@@ -550,311 +850,212 @@ int cmCTestCoverageHandler::ProcessHandler()
|
|
|
{
|
|
{
|
|
|
gcovFile = "";
|
|
gcovFile = "";
|
|
|
// Is it in the source dir?
|
|
// Is it in the source dir?
|
|
|
- if ( sourceFile.size() > sourceDir.size() &&
|
|
|
|
|
- sourceFile.substr(0, sourceDir.size()) == sourceDir &&
|
|
|
|
|
- sourceFile[sourceDir.size()] == '/' )
|
|
|
|
|
|
|
+ if ( sourceFile.size() > cont->SourceDir.size() &&
|
|
|
|
|
+ sourceFile.substr(0, cont->SourceDir.size()) == cont->SourceDir &&
|
|
|
|
|
+ sourceFile[cont->SourceDir.size()] == '/' )
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced s: "
|
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced s: "
|
|
|
<< sourceFile.c_str() << std::endl);
|
|
<< sourceFile.c_str() << std::endl);
|
|
|
- ofs << " produced in source dir: " << sourceFile.c_str()
|
|
|
|
|
|
|
+ *cont->OFS << " produced in source dir: " << sourceFile.c_str()
|
|
|
<< std::endl;
|
|
<< std::endl;
|
|
|
actualSourceFile
|
|
actualSourceFile
|
|
|
= cmSystemTools::CollapseFullPath(sourceFile.c_str());
|
|
= cmSystemTools::CollapseFullPath(sourceFile.c_str());
|
|
|
}
|
|
}
|
|
|
// Binary dir?
|
|
// Binary dir?
|
|
|
- if ( sourceFile.size() > binaryDir.size() &&
|
|
|
|
|
- sourceFile.substr(0, binaryDir.size()) == binaryDir &&
|
|
|
|
|
- sourceFile[binaryDir.size()] == '/' )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced b: "
|
|
|
|
|
- << sourceFile.c_str() << std::endl);
|
|
|
|
|
- ofs << " produced in binary dir: " << sourceFile.c_str()
|
|
|
|
|
- << std::endl;
|
|
|
|
|
- actualSourceFile
|
|
|
|
|
- = cmSystemTools::CollapseFullPath(sourceFile.c_str());
|
|
|
|
|
- }
|
|
|
|
|
- if ( actualSourceFile.empty() )
|
|
|
|
|
- {
|
|
|
|
|
- if ( missingFiles.find(actualSourceFile) == missingFiles.end() )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
- "Something went wrong" << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "File: ["
|
|
|
|
|
- << sourceFile.c_str() << "]" << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "s: ["
|
|
|
|
|
- << sourceFile.substr(0, sourceDir.size()) << "]" << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "b: ["
|
|
|
|
|
- << sourceFile.substr(0, binaryDir.size()) << "]" << std::endl);
|
|
|
|
|
- ofs << " Something went wrong. Cannot find: "
|
|
|
|
|
- << sourceFile.c_str()
|
|
|
|
|
- << " in source dir: " << sourceDir.c_str()
|
|
|
|
|
- << " or binary dir: " << binaryDir.c_str() << std::endl;
|
|
|
|
|
- missingFiles.insert(actualSourceFile);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- file_count ++;
|
|
|
|
|
- if ( file_count % 50 == 0 )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
|
|
|
|
|
- << " out of " << files.size() << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- cmGeneratedFileStream covSumFile;
|
|
|
|
|
- cmGeneratedFileStream covLogFile;
|
|
|
|
|
-
|
|
|
|
|
- if (!this->StartResultingXML("Coverage", covSumFile))
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- "Cannot open coverage summary file." << std::endl);
|
|
|
|
|
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- this->CTest->StartXML(covSumFile);
|
|
|
|
|
- // Produce output xml files
|
|
|
|
|
-
|
|
|
|
|
- covSumFile << "<Coverage>" << std::endl
|
|
|
|
|
- << "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>"
|
|
|
|
|
- << std::endl;
|
|
|
|
|
- int logFileCount = 0;
|
|
|
|
|
- if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
|
|
|
|
|
- {
|
|
|
|
|
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
- totalCoverageMap::iterator fileIterator;
|
|
|
|
|
- int cnt = 0;
|
|
|
|
|
- long total_tested = 0;
|
|
|
|
|
- long total_untested = 0;
|
|
|
|
|
- //std::string fullSourceDir = sourceDir + "/";
|
|
|
|
|
- //std::string fullBinaryDir = binaryDir + "/";
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT,
|
|
|
|
|
- " Acumulating results (each . represents one file):" << std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
|
|
-
|
|
|
|
|
- std::vector<std::string> errorsWhileAccumulating;
|
|
|
|
|
-
|
|
|
|
|
- file_count = 0;
|
|
|
|
|
- for ( fileIterator = totalCoverage.begin();
|
|
|
|
|
- fileIterator != totalCoverage.end();
|
|
|
|
|
- ++fileIterator )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
|
|
|
|
|
|
|
+ if ( sourceFile.size() > cont->BinaryDir.size() &&
|
|
|
|
|
+ sourceFile.substr(0, cont->BinaryDir.size()) == cont->BinaryDir &&
|
|
|
|
|
+ sourceFile[cont->BinaryDir.size()] == '/' )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced b: "
|
|
|
|
|
+ << sourceFile.c_str() << std::endl);
|
|
|
|
|
+ *cont->OFS << " produced in binary dir: " << sourceFile.c_str()
|
|
|
|
|
+ << std::endl;
|
|
|
|
|
+ actualSourceFile
|
|
|
|
|
+ = cmSystemTools::CollapseFullPath(sourceFile.c_str());
|
|
|
|
|
+ }
|
|
|
|
|
+ if ( actualSourceFile.empty() )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( missingFiles.find(actualSourceFile) == missingFiles.end() )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ "Something went wrong" << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "File: ["
|
|
|
|
|
+ << sourceFile.c_str() << "]" << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "s: ["
|
|
|
|
|
+ << sourceFile.substr(0, cont->SourceDir.size()) << "]" << std::endl);
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "b: ["
|
|
|
|
|
+ << sourceFile.substr(0, cont->BinaryDir.size()) << "]" << std::endl);
|
|
|
|
|
+ *cont->OFS << " Something went wrong. Cannot find: "
|
|
|
|
|
+ << sourceFile.c_str()
|
|
|
|
|
+ << " in source dir: " << cont->SourceDir.c_str()
|
|
|
|
|
+ << " or binary dir: " << cont->BinaryDir.c_str() << std::endl;
|
|
|
|
|
+ missingFiles.insert(actualSourceFile);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
file_count ++;
|
|
file_count ++;
|
|
|
if ( file_count % 50 == 0 )
|
|
if ( file_count % 50 == 0 )
|
|
|
{
|
|
{
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
|
|
|
- << " out of "
|
|
|
|
|
- << totalCoverage.size() << std::endl);
|
|
|
|
|
|
|
+ << " out of " << files.size() << std::endl);
|
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
|
|
|
}
|
|
}
|
|
|
- if ( cnt % 100 == 0 )
|
|
|
|
|
- {
|
|
|
|
|
- this->EndCoverageLogFile(covLogFile, logFileCount);
|
|
|
|
|
- logFileCount ++;
|
|
|
|
|
- if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
|
|
|
|
|
- {
|
|
|
|
|
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- const std::string fullFileName = fileIterator->first;
|
|
|
|
|
- const std::string fileName
|
|
|
|
|
- = cmSystemTools::GetFilenameName(fullFileName.c_str());
|
|
|
|
|
- std::string fullFilePath
|
|
|
|
|
- = cmSystemTools::GetFilenamePath(fullFileName.c_str());
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Process file: "
|
|
|
|
|
- << fullFileName << std::endl);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
+ return file_count;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- cmSystemTools::ConvertToUnixSlashes(fullFilePath);
|
|
|
|
|
|
|
+//----------------------------------------------------------------------
|
|
|
|
|
+int cmCTestCoverageHandler::HandleTracePyCoverage(
|
|
|
|
|
+ cmCTestCoverageHandlerContainer* cont)
|
|
|
|
|
+{
|
|
|
|
|
+ cmsys::Glob gl;
|
|
|
|
|
+ gl.RecurseOn();
|
|
|
|
|
+ std::string daGlob = cont->BinaryDir + "/*.cover";
|
|
|
|
|
+ gl.FindFiles(daGlob);
|
|
|
|
|
+ std::vector<std::string> files = gl.GetFiles();
|
|
|
|
|
|
|
|
- if ( !cmSystemTools::FileExists(fullFileName.c_str()) )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
|
|
|
|
|
- << fullFileName.c_str() << std::endl);
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if ( files.size() == 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ " Cannot find any Python Trace.py coverage files."
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ // No coverage files is a valid thing, so the exit code is 0
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- bool shouldIDoCoverage
|
|
|
|
|
- = this->ShouldIDoCoverage(fullFileName.c_str(),
|
|
|
|
|
- sourceDir.c_str(), binaryDir.c_str());
|
|
|
|
|
- if ( !shouldIDoCoverage )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
- ".NoDartCoverage found, so skip coverage check for: "
|
|
|
|
|
- << fullFileName.c_str()
|
|
|
|
|
- << std::endl);
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
|
|
|
|
|
+ std::string tempDir = testingDir + "/CoverageInfo";
|
|
|
|
|
+ std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
|
|
|
|
|
+ cmSystemTools::MakeDirectory(tempDir.c_str());
|
|
|
|
|
+ cmSystemTools::ChangeDirectory(tempDir.c_str());
|
|
|
|
|
|
|
|
- const singleFileCoverageVector& fcov = fileIterator->second;
|
|
|
|
|
- covLogFile << "\t<File Name=\""
|
|
|
|
|
- << this->CTest->MakeXMLSafe(fileName.c_str())
|
|
|
|
|
- << "\" FullPath=\"" << this->CTest->MakeXMLSafe(
|
|
|
|
|
- this->CTest->GetShortPathToFile(
|
|
|
|
|
- fileIterator->first.c_str())) << "\">" << std::endl
|
|
|
|
|
- << "\t\t<Report>" << std::endl;
|
|
|
|
|
|
|
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
|
|
|
- std::ifstream ifs(fullFileName.c_str());
|
|
|
|
|
- if ( !ifs)
|
|
|
|
|
|
|
+ std::vector<std::string>::iterator fileIt;
|
|
|
|
|
+ int file_count = 0;
|
|
|
|
|
+ for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
|
|
|
|
|
+ {
|
|
|
|
|
+ std::string fileName = this->FindFile(cont, *fileIt);
|
|
|
|
|
+ if ( fileName.empty() )
|
|
|
{
|
|
{
|
|
|
- cmOStringStream ostr;
|
|
|
|
|
- ostr << "Cannot open source file: " << fullFileName.c_str();
|
|
|
|
|
- errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
- error ++;
|
|
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Cannot find source Python file corresponding to: "
|
|
|
|
|
+ << fileIt->c_str() << std::endl);
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- int tested = 0;
|
|
|
|
|
- int untested = 0;
|
|
|
|
|
-
|
|
|
|
|
- singleFileCoverageVector::size_type cc;
|
|
|
|
|
- std::string line;
|
|
|
|
|
- for ( cc= 0; cc < fcov.size(); cc ++ )
|
|
|
|
|
- {
|
|
|
|
|
- if ( !cmSystemTools::GetLineFromStream(ifs, line) &&
|
|
|
|
|
- cc != fcov.size() -1 )
|
|
|
|
|
- {
|
|
|
|
|
- cmOStringStream ostr;
|
|
|
|
|
- ostr << "Problem reading source file: " << fullFileName.c_str()
|
|
|
|
|
- << " line:" << cc;
|
|
|
|
|
- errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
- error ++;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- covLogFile << "\t\t<Line Number=\"" << cc << "\" Count=\"" << fcov[cc]
|
|
|
|
|
- << "\">"
|
|
|
|
|
- << this->CTest->MakeXMLSafe(line.c_str()) << "</Line>" << std::endl;
|
|
|
|
|
- if ( fcov[cc] == 0 )
|
|
|
|
|
- {
|
|
|
|
|
- untested ++;
|
|
|
|
|
- }
|
|
|
|
|
- else if ( fcov[cc] > 0 )
|
|
|
|
|
- {
|
|
|
|
|
- tested ++;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if ( cmSystemTools::GetLineFromStream(ifs, line) )
|
|
|
|
|
- {
|
|
|
|
|
- cmOStringStream ostr;
|
|
|
|
|
- ostr << "Looks like there are more lines in the file: " << line;
|
|
|
|
|
- errorsWhileAccumulating.push_back(ostr.str());
|
|
|
|
|
- }
|
|
|
|
|
- float cper = 0;
|
|
|
|
|
- float cmet = 0;
|
|
|
|
|
- if ( tested + untested > 0 )
|
|
|
|
|
|
|
+ std::string actualSourceFile
|
|
|
|
|
+ = cmSystemTools::CollapseFullPath(fileName.c_str());
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ " Check coverage for file: " << actualSourceFile.c_str()
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector* vec
|
|
|
|
|
+ = &cont->TotalCoverage[actualSourceFile];
|
|
|
|
|
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
+ " in file: " << fileIt->c_str() << std::endl);
|
|
|
|
|
+ std::ifstream ifile(fileIt->c_str());
|
|
|
|
|
+ if ( ! ifile )
|
|
|
{
|
|
{
|
|
|
- cper = (100 * SAFEDIV(static_cast<float>(tested),
|
|
|
|
|
- static_cast<float>(tested + untested)));
|
|
|
|
|
- cmet = ( SAFEDIV(static_cast<float>(tested + 10),
|
|
|
|
|
- static_cast<float>(tested + untested + 10)));
|
|
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
|
|
|
|
|
+ << fileIt->c_str() << std::endl);
|
|
|
}
|
|
}
|
|
|
- total_tested += tested;
|
|
|
|
|
- total_untested += untested;
|
|
|
|
|
- covLogFile << "\t\t</Report>" << std::endl
|
|
|
|
|
- << "\t</File>" << std::endl;
|
|
|
|
|
- covSumFile << "\t<File Name=\"" << this->CTest->MakeXMLSafe(fileName)
|
|
|
|
|
- << "\" FullPath=\"" << this->CTest->MakeXMLSafe(
|
|
|
|
|
- this->CTest->GetShortPathToFile(fullFileName.c_str()))
|
|
|
|
|
- << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
|
|
|
|
|
- << "\t\t<LOCTested>" << tested << "</LOCTested>\n"
|
|
|
|
|
- << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n"
|
|
|
|
|
- << "\t\t<PercentCoverage>";
|
|
|
|
|
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
- covSumFile.precision(2);
|
|
|
|
|
- covSumFile << (cper) << "</PercentCoverage>\n"
|
|
|
|
|
- << "\t\t<CoverageMetric>";
|
|
|
|
|
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
- covSumFile.precision(2);
|
|
|
|
|
- covSumFile << (cmet) << "</CoverageMetric>\n"
|
|
|
|
|
- << "\t</File>" << std::endl;
|
|
|
|
|
- cnt ++;
|
|
|
|
|
- }
|
|
|
|
|
- this->EndCoverageLogFile(covLogFile, logFileCount);
|
|
|
|
|
-
|
|
|
|
|
- if ( errorsWhileAccumulating.size() > 0 )
|
|
|
|
|
- {
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl);
|
|
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- "Error(s) while acumulating results:" << std::endl);
|
|
|
|
|
- std::vector<std::string>::iterator erIt;
|
|
|
|
|
- for ( erIt = errorsWhileAccumulating.begin();
|
|
|
|
|
- erIt != errorsWhileAccumulating.end();
|
|
|
|
|
- ++ erIt )
|
|
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
- cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
- " " << erIt->c_str() << std::endl);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- int total_lines = total_tested + total_untested;
|
|
|
|
|
- float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
|
|
|
|
|
- static_cast<float>(total_lines));
|
|
|
|
|
- if ( total_lines == 0 )
|
|
|
|
|
- {
|
|
|
|
|
- percent_coverage = 0;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::string end_time = this->CTest->CurrentTime();
|
|
|
|
|
-
|
|
|
|
|
- covSumFile << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
|
|
|
|
|
- << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
|
|
|
|
|
- << "\t<LOC>" << total_lines << "</LOC>\n"
|
|
|
|
|
- << "\t<PercentCoverage>";
|
|
|
|
|
- covSumFile.setf(std::ios::fixed, std::ios::floatfield);
|
|
|
|
|
- covSumFile.precision(2);
|
|
|
|
|
- covSumFile << (percent_coverage)<< "</PercentCoverage>\n"
|
|
|
|
|
- << "\t<EndDateTime>" << end_time << "</EndDateTime>\n";
|
|
|
|
|
- covSumFile << "<ElapsedMinutes>" <<
|
|
|
|
|
- static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
|
|
|
|
|
- << "</ElapsedMinutes>"
|
|
|
|
|
- << "</Coverage>" << std::endl;
|
|
|
|
|
- this->CTest->EndXML(covSumFile);
|
|
|
|
|
-
|
|
|
|
|
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "\tCovered LOC: "
|
|
|
|
|
- << total_tested << std::endl
|
|
|
|
|
- << "\tNot covered LOC: " << total_untested << std::endl
|
|
|
|
|
- << "\tTotal LOC: " << total_lines << std::endl
|
|
|
|
|
- << "\tPercentage Coverage: "
|
|
|
|
|
- << std::setiosflags(std::ios::fixed)
|
|
|
|
|
- << std::setprecision(2)
|
|
|
|
|
- << (percent_coverage) << "%" << std::endl);
|
|
|
|
|
|
|
+ long cnt = -1;
|
|
|
|
|
+ std::string nl;
|
|
|
|
|
+ while ( cmSystemTools::GetLineFromStream(ifile, nl) )
|
|
|
|
|
+ {
|
|
|
|
|
+ cnt ++;
|
|
|
|
|
|
|
|
- ofs << "\tCovered LOC: " << total_tested << std::endl
|
|
|
|
|
- << "\tNot covered LOC: " << total_untested << std::endl
|
|
|
|
|
- << "\tTotal LOC: " << total_lines << std::endl
|
|
|
|
|
- << "\tPercentage Coverage: "
|
|
|
|
|
- << std::setiosflags(std::ios::fixed)
|
|
|
|
|
- << std::setprecision(2)
|
|
|
|
|
- << (percent_coverage) << "%" << std::endl;
|
|
|
|
|
|
|
+ // Skip empty lines
|
|
|
|
|
+ if ( !nl.size() )
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
|
|
+ // Skip unused lines
|
|
|
|
|
+ if ( nl.size() < 12 )
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if ( error )
|
|
|
|
|
- {
|
|
|
|
|
- return -1;
|
|
|
|
|
|
|
+ // Read the coverage count from the beginning of the Trace.py output
|
|
|
|
|
+ // line
|
|
|
|
|
+ std::string prefix = nl.substr(0, 6);
|
|
|
|
|
+ if ( prefix[5] != ' ' && prefix[5] != ':' )
|
|
|
|
|
+ {
|
|
|
|
|
+ // This is a hack. We should really do something more elaborate
|
|
|
|
|
+ prefix = nl.substr(0, 7);
|
|
|
|
|
+ if ( prefix[6] != ' ' && prefix[6] != ':' )
|
|
|
|
|
+ {
|
|
|
|
|
+ prefix = nl.substr(0, 8);
|
|
|
|
|
+ if ( prefix[7] != ' ' && prefix[7] != ':' )
|
|
|
|
|
+ {
|
|
|
|
|
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
|
|
|
|
|
+ "Currently the limit is maximum coverage of 999999"
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ int cov = atoi(prefix.c_str());
|
|
|
|
|
+ if ( prefix[prefix.size()-1] != ':' )
|
|
|
|
|
+ {
|
|
|
|
|
+ // This line does not have ':' so no coverage here. That said,
|
|
|
|
|
+ // Trace.py does not handle not covered lines versus comments etc.
|
|
|
|
|
+ // So, this will be set to 0.
|
|
|
|
|
+ cov = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ cmCTestLog(this->CTest, DEBUG, "Prefix: " << prefix.c_str()
|
|
|
|
|
+ << " cov: " << cov
|
|
|
|
|
+ << std::endl);
|
|
|
|
|
+ // Read the line number starting at the 10th character of the gcov
|
|
|
|
|
+ // output line
|
|
|
|
|
+ int lineIdx = cnt;
|
|
|
|
|
+ if ( lineIdx >= 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ while ( vec->size() <=
|
|
|
|
|
+ static_cast<size_t>(lineIdx) )
|
|
|
|
|
+ {
|
|
|
|
|
+ vec->push_back(-1);
|
|
|
|
|
+ }
|
|
|
|
|
+ // Initially all entries are -1 (not used). If we get coverage
|
|
|
|
|
+ // information, increment it to 0 first.
|
|
|
|
|
+ if ( (*vec)[lineIdx] < 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ if ( cov >= 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ (*vec)[lineIdx] = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ (*vec)[lineIdx] += cov;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ++ file_count;
|
|
|
}
|
|
}
|
|
|
- return 0;
|
|
|
|
|
|
|
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
|
|
|
|
|
+ return file_count;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
//----------------------------------------------------------------------
|
|
|
-void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf)
|
|
|
|
|
|
|
+std::string cmCTestCoverageHandler::FindFile(
|
|
|
|
|
+ cmCTestCoverageHandlerContainer* cont,
|
|
|
|
|
+ std::string fileName)
|
|
|
{
|
|
{
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
|
|
|
|
- " Add coverage exclude regular expressions." << std::endl);
|
|
|
|
|
- this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE",
|
|
|
|
|
- this->CustomCoverageExclude);
|
|
|
|
|
- std::vector<cmStdString>::iterator it;
|
|
|
|
|
- for ( it = this->CustomCoverageExclude.begin();
|
|
|
|
|
- it != this->CustomCoverageExclude.end();
|
|
|
|
|
- ++ it )
|
|
|
|
|
|
|
+ std::string fileNameNoE
|
|
|
|
|
+ = cmSystemTools::GetFilenameWithoutLastExtension(fileName);
|
|
|
|
|
+ // First check in source and binary directory
|
|
|
|
|
+ std::string fullName = cont->SourceDir + "/" + fileNameNoE + ".py";
|
|
|
|
|
+ if ( cmSystemTools::FileExists(fullName.c_str()) )
|
|
|
{
|
|
{
|
|
|
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: "
|
|
|
|
|
- << it->c_str() << std::endl);
|
|
|
|
|
|
|
+ return fullName;
|
|
|
|
|
+ }
|
|
|
|
|
+ fullName = cont->BinaryDir + "/" + fileNameNoE + ".py";
|
|
|
|
|
+ if ( cmSystemTools::FileExists(fullName.c_str()) )
|
|
|
|
|
+ {
|
|
|
|
|
+ return fullName;
|
|
|
}
|
|
}
|
|
|
|
|
+ return "";
|
|
|
}
|
|
}
|