diff options
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.cxx | 40 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.h | 5 | ||||
-rw-r--r-- | Source/CTest/cmParseJacocoCoverage.cxx | 167 | ||||
-rw-r--r-- | Source/CTest/cmParseJacocoCoverage.h | 59 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 16 | ||||
-rw-r--r-- | Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java | 52 | ||||
-rw-r--r-- | Tests/JacocoCoverage/Coverage/target/site/jacoco.xml | 1 | ||||
-rw-r--r-- | Tests/JacocoCoverage/DartConfiguration.tcl.in | 8 |
9 files changed, 348 insertions, 1 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fe6cc1b..c3c24fe 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -518,6 +518,7 @@ set(CTEST_SRCS cmCTest.cxx CTest/cmParseMumpsCoverage.cxx CTest/cmParseCacheCoverage.cxx CTest/cmParseGTMCoverage.cxx + CTest/cmParseJacocoCoverage.cxx CTest/cmParsePHPCoverage.cxx CTest/cmParseCoberturaCoverage.cxx CTest/cmCTestEmptyBinaryDirectoryCommand.cxx diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index da27c8c..76f6584 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -14,6 +14,7 @@ #include "cmParseCoberturaCoverage.h" #include "cmParseGTMCoverage.h" #include "cmParseCacheCoverage.h" +#include "cmParseJacocoCoverage.h" #include "cmCTest.h" #include "cmake.h" #include "cmMakefile.h" @@ -415,6 +416,13 @@ int cmCTestCoverageHandler::ProcessHandler() return error; } + file_count += this->HandleJacocoCoverage(&cont); + error = cont.Error; + if ( file_count < 0 ) + { + return error; + } + std::set<std::string> uncovered = this->FindUncoveredFiles(&cont); if ( file_count == 0 ) @@ -872,6 +880,38 @@ struct cmCTestCoverageHandlerLocale }; //---------------------------------------------------------------------- +int cmCTestCoverageHandler::HandleJacocoCoverage( + cmCTestCoverageHandlerContainer* cont) +{ + cmParseJacocoCoverage cov = + cmParseJacocoCoverage(*cont, this->CTest); + cmsys::Glob g; + std::vector<std::string> files; + g.SetRecurse(true); + + std::string SourceDir + = this->CTest->GetCTestConfiguration("SourceDirectory"); + std::string coverageFile = SourceDir+ "/*jacoco.xml"; + + g.FindFiles(coverageFile); + files=g.GetFiles(); + if (files.size() > 0) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found Jacoco Files, Performing Coverage" << std::endl); + cov.LoadCoverageData(files); + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find Jacoco coverage files: " << coverageFile + << std::endl); + } + return static_cast<int>(cont->TotalCoverage.size()); +} + + +//---------------------------------------------------------------------- int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestCoverageHandlerContainer* cont) { diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index 38a3353..d0f274c 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -81,7 +81,10 @@ private: //! Handle coverage for mumps int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont); - //! Handle coverage using Bullseye + //! Handle coverage for Jacoco + int HandleJacocoCoverage(cmCTestCoverageHandlerContainer* cont); + +//! Handle coverage using Bullseye int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont); int RunBullseyeCoverageBranch(cmCTestCoverageHandlerContainer* cont, diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx new file mode 100644 index 0000000..4723dd3 --- /dev/null +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -0,0 +1,167 @@ +#include "cmStandardIncludes.h" +#include <stdio.h> +#include <stdlib.h> +#include "cmSystemTools.h" +#include "cmXMLParser.h" +#include "cmParseJacocoCoverage.h" +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> +#include <cmsys/FStream.hxx> + + +class cmParseJacocoCoverage::XMLParser: public cmXMLParser +{ + public: + XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont) + : CTest(ctest), Coverage(cont) + { + this->PackageName = ""; + this->ModuleName = ""; + this->FileName = ""; + this->CurFileName = ""; + this->FilePaths.push_back(this->Coverage.SourceDir); + } + + virtual ~XMLParser() + { + } + + protected: + + virtual void EndElement(const std::string&) + { + } + + virtual void StartElement(const std::string& name, + const char** atts) + { + if(name == "package") + { + this->PackageName = atts[1]; + std::string FilePath = this->Coverage.SourceDir + + "/" + this->ModuleName + "/src/main/java/" + + this->PackageName; + this->FilePaths.push_back(FilePath); + } + else if(name == "sourcefile") + { + this->FileName = atts[1]; + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: " + << this->FileName << std::endl); + for(size_t i=0;i < FilePaths.size();i++) + { + std::string finalpath = FilePaths[i] + "/" + this->FileName; + if(cmSystemTools::FileExists(finalpath.c_str())) + { + this->CurFileName = finalpath; + break; + } + } + cmsys::ifstream fin(this->CurFileName.c_str()); + if(this->CurFileName == "" || !fin ) + { + this->CurFileName = this->Coverage.BinaryDir + "/" + + this->FileName; + fin.open(this->CurFileName.c_str()); + if (!fin) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Jacoco Coverage: Error opening " << this->CurFileName + << std::endl); + this->Coverage.Error++; + } + } + std::string line; + FileLinesType& curFileLines = + this->Coverage.TotalCoverage[this->CurFileName]; + curFileLines.push_back(-1); + while(cmSystemTools::GetLineFromStream(fin, line)) + { + curFileLines.push_back(-1); + } + } + else if(name == "report") + { + this->ModuleName=atts[1]; + } + else if(name == "line") + { + int tagCount = 0; + int nr = -1; + int ci = -1; + while(true) + { + if(strcmp(atts[tagCount],"ci") == 0) + { + ci = atoi(atts[tagCount+1]); + } + else if (strcmp(atts[tagCount],"nr") == 0) + { + nr = atoi(atts[tagCount+1]); + } + if (ci > -1 && nr > 0) + { + FileLinesType& curFileLines= + this->Coverage.TotalCoverage[this->CurFileName]; + if(curFileLines.size() > 0) + { + curFileLines[nr-1] = ci; + } + break; + } + ++tagCount; + } + } + } + + private: + std::string PackageName; + std::string FileName; + std::string ModuleName; + std::string CurFileName; + std::vector<std::string> FilePaths; + typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector + FileLinesType; + cmCTest* CTest; + cmCTestCoverageHandlerContainer& Coverage; +}; + +cmParseJacocoCoverage::cmParseJacocoCoverage( + cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest) + :Coverage(cont), CTest(ctest) + { + } + +bool cmParseJacocoCoverage::LoadCoverageData( + const std::vector<std::string> files) +{ + // load all the jacoco.xml files in the source directory + cmsys::Directory dir; + size_t i; + std::string path; + size_t numf = files.size(); + for (i = 0; i < numf; i++) + { + path = files[i]; + + cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Reading XML File " << path << std::endl); + if(cmSystemTools::GetFilenameLastExtension(path) == ".xml") + { + if(!this->ReadJacocoXML(path.c_str())) + { + return false; + } + } + } + return true; +} + +bool cmParseJacocoCoverage::ReadJacocoXML(const char* file) +{ + cmParseJacocoCoverage::XMLParser + parser(this->CTest, this->Coverage); + parser.ParseFile(file); + return true; +} diff --git a/Source/CTest/cmParseJacocoCoverage.h b/Source/CTest/cmParseJacocoCoverage.h new file mode 100644 index 0000000..dad05a3 --- /dev/null +++ b/Source/CTest/cmParseJacocoCoverage.h @@ -0,0 +1,59 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmParseJacocoCoverage_h +#define cmParseJacocoCoverage_h + +#include "cmStandardIncludes.h" +#include "cmCTestCoverageHandler.h" + + +/** \class cmParseJacocoCoverage + * \brief Parse JaCoCO coverage information + * + * This class is used to parse coverage information for + * java using the JaCoCo tool: + * + * http://www.eclemma.org/jacoco/trunk/index.html + */ +class cmParseJacocoCoverage +{ +public: + cmParseJacocoCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); + bool LoadCoverageData(const std::vector<std::string> files); + + std::string PackageName; + std::string FileName; + std::string ModuleName; + std::string CurFileName; +private: + // implement virtual from parent + // remove files with no coverage + void RemoveUnCoveredFiles(); + // Read a single mcov file + bool ReadJacocoXML(const char* f); + // split a string based on , + bool SplitString(std::vector<std::string>& args, + std::string const& line); + bool FindJavaFile(std::string const& routine, + std::string& filepath); + void InitializeJavaFile(std::string& file); + bool LoadSource(std::string d); + + class XMLParser; + std::map<std::string, std::string> RoutineToDirectory; + cmCTestCoverageHandlerContainer& Coverage; + cmCTest* CTest; +}; + +#endif diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 05442a1..852f78f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2202,6 +2202,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release "Process file.*CoverageTest.java.*Total LOC:.*18.*Percentage Coverage: 72.22.*" ENVIRONMENT COVFILE=) + + # Adding a test case for JaCoCo Coverage + configure_file( + "${CMake_SOURCE_DIR}/Tests/JacocoCoverage/DartConfiguration.tcl.in" + "${CMake_BINARY_DIR}/Testing/JacocoCoverage/DartConfiguration.tcl") + file(COPY "${CMake_SOURCE_DIR}/Tests/JacocoCoverage/Coverage" + DESTINATION "${CMake_BINARY_DIR}/Testing/JacocoCoverage") + add_test(NAME CTestJacocoCoverage + COMMAND cmake -E chdir + ${CMake_BINARY_DIR}/Testing/JacocoCoverage + $<TARGET_FILE:ctest> -T Coverage --debug) + set_tests_properties(CTestJacocoCoverage PROPERTIES + PASS_REGULAR_EXPRESSION + "Process file.*CoverageTest.java.*Total LOC:.*17.*Percentage Coverage: 76.47*" + ENVIRONMENT COVFILE=) + function(add_config_tests cfg) set(base "${CMake_BINARY_DIR}/Tests/CTestConfig") diff --git a/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java b/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java new file mode 100644 index 0000000..4fb43c6 --- /dev/null +++ b/Tests/JacocoCoverage/Coverage/src/main/java/org/cmake/CoverageTest.java @@ -0,0 +1,52 @@ +package org.cmake.Coverage; + +import java.io.Serializable; +import java.util.Map; +import java.util.List; +import java.awt.*; + +public class CoverageTest { + + public static String VarOne = "test1"; + public static String VarTwo = "test2"; + private Integer IntOne = 4; + + public static Boolean equalsVarOne(String inString) { + + if(VarOne.equals(inString)){ + return true; + } + else { + return false; + } + } + + public static boolean equalsVarTwo(String inString){ + + if(VarTwo.equals(inString)){ + return true; + } + else { + return false; + } + } + + private Integer timesIntOne(Integer inVal){ + + return inVal * IntOne; + } + + public static boolean whileLoop(Integer StopInt){ + + Integer i = 0; + while(i < StopInt){ + i=i+1; + } + if (i.equals(5)){ + return true; + } + else { + return false; + } + } +} diff --git a/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml new file mode 100644 index 0000000..49c3e87 --- /dev/null +++ b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN" "report.dtd"><report name="Coverage"><sessioninfo id="vagrant-ubuntu-precise-32-f1c264e9" start="1402427058670" dump="1402427059269"/><package name="org/cmake"><class name="org/cmake/Coverage/CoverageTest"><method name="<init>" desc="()V" line="8"><counter type="INSTRUCTION" missed="7" covered="0"/><counter type="LINE" missed="2" covered="0"/><counter type="COMPLEXITY" missed="1" covered="0"/><counter type="METHOD" missed="1" covered="0"/></method><method name="equalsVarOne" desc="(Ljava/lang/String;)Ljava/lang/Boolean;" line="16"><counter type="INSTRUCTION" missed="3" covered="7"/><counter type="BRANCH" missed="1" covered="1"/><counter type="LINE" missed="1" covered="2"/><counter type="COMPLEXITY" missed="1" covered="1"/><counter type="METHOD" missed="0" covered="1"/></method><method name="equalsVarTwo" desc="(Ljava/lang/String;)Z" line="26"><counter type="INSTRUCTION" missed="0" covered="8"/><counter type="BRANCH" missed="0" covered="2"/><counter type="LINE" missed="0" covered="3"/><counter type="COMPLEXITY" missed="0" covered="2"/><counter type="METHOD" missed="0" covered="1"/></method><method name="timesIntOne" desc="(Ljava/lang/Integer;)Ljava/lang/Integer;" line="36"><counter type="INSTRUCTION" missed="8" covered="0"/><counter type="LINE" missed="1" covered="0"/><counter type="COMPLEXITY" missed="1" covered="0"/><counter type="METHOD" missed="1" covered="0"/></method><method name="whileLoop" desc="(Ljava/lang/Integer;)Z" line="41"><counter type="INSTRUCTION" missed="0" covered="24"/><counter type="BRANCH" missed="0" covered="4"/><counter type="LINE" missed="0" covered="6"/><counter type="COMPLEXITY" missed="0" covered="3"/><counter type="METHOD" missed="0" covered="1"/></method><method name="<clinit>" desc="()V" line="10"><counter type="INSTRUCTION" missed="0" covered="5"/><counter type="LINE" missed="0" covered="2"/><counter type="COMPLEXITY" missed="0" covered="1"/><counter type="METHOD" missed="0" covered="1"/></method><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></class><sourcefile name="CoverageTest.java"><line nr="8" mi="2" ci="0" mb="0" cb="0"/><line nr="10" mi="0" ci="2" mb="0" cb="0"/><line nr="11" mi="0" ci="3" mb="0" cb="0"/><line nr="12" mi="5" ci="0" mb="0" cb="0"/><line nr="16" mi="0" ci="4" mb="1" cb="1"/><line nr="17" mi="0" ci="3" mb="0" cb="0"/><line nr="20" mi="3" ci="0" mb="0" cb="0"/><line nr="26" mi="0" ci="4" mb="0" cb="2"/><line nr="27" mi="0" ci="2" mb="0" cb="0"/><line nr="30" mi="0" ci="2" mb="0" cb="0"/><line nr="36" mi="8" ci="0" mb="0" cb="0"/><line nr="41" mi="0" ci="3" mb="0" cb="0"/><line nr="42" mi="0" ci="5" mb="0" cb="2"/><line nr="43" mi="0" ci="7" mb="0" cb="0"/><line nr="45" mi="0" ci="5" mb="0" cb="2"/><line nr="46" mi="0" ci="2" mb="0" cb="0"/><line nr="49" mi="0" ci="2" mb="0" cb="0"/><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></sourcefile><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></package><counter type="INSTRUCTION" missed="18" covered="44"/><counter type="BRANCH" missed="1" covered="7"/><counter type="LINE" missed="4" covered="13"/><counter type="COMPLEXITY" missed="3" covered="7"/><counter type="METHOD" missed="2" covered="4"/><counter type="CLASS" missed="0" covered="1"/></report> diff --git a/Tests/JacocoCoverage/DartConfiguration.tcl.in b/Tests/JacocoCoverage/DartConfiguration.tcl.in new file mode 100644 index 0000000..cc10e9c --- /dev/null +++ b/Tests/JacocoCoverage/DartConfiguration.tcl.in @@ -0,0 +1,8 @@ +# This file is configured by CMake automatically as DartConfiguration.tcl +# If you choose not to use CMake, this file may be hand configured, by +# filling in the required variables. + + +# Configuration directories and files +SourceDirectory: ${CMake_BINARY_DIR}/Testing/JacocoCoverage +BuildDirectory: ${CMake_BINARY_DIR}/Testing/JacocoCoverage |