You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/11/25 07:41:55 UTC

[tomcat] branch 9.0.x updated: Switch from Cobertura to JaCoCo for code coverage

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 3e313f3  Switch from Cobertura to JaCoCo for code coverage
3e313f3 is described below

commit 3e313f361e39a77d0d813b26c3cd934a3b616c77
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Nov 8 12:41:36 2021 +0000

    Switch from Cobertura to JaCoCo for code coverage
---
 build.properties.default   |  23 ++--
 build.xml                  | 324 ++++++++++++++++++---------------------------
 webapps/docs/changelog.xml |   9 ++
 3 files changed, 151 insertions(+), 205 deletions(-)

diff --git a/build.properties.default b/build.properties.default
index 70c235c..444ed56 100644
--- a/build.properties.default
+++ b/build.properties.default
@@ -62,12 +62,11 @@ test.verbose=true
 
 # Number of parallel threads to use for testing. The recommended value is one
 # thread per core.
-# Note: Cobertura code coverage currently requires this to be set to 1. Setting
-#       a value above one will disable code coverage if enabled.
 test.threads=1
 
-# Note the Cobertura code coverage tool is GPLv2 licensed
-test.cobertura=false
+# Note the JaCoCo code coverage tool is EPLv2 licensed
+# Enabling code coverage extends the time taken to run the tests by ~50%
+test.coverage=false
 
 # Note the FindBugs is LGPL licensed
 execute.findbugs=false
@@ -275,14 +274,14 @@ checkstyle.home=${base.path}/checkstyle-${checkstyle.version}
 checkstyle.jar=${checkstyle.home}/checkstyle-${checkstyle.version}-all.jar
 checkstyle.loc=${base-gh.loc}/checkstyle/checkstyle/releases/download/checkstyle-${checkstyle.version}/checkstyle-${checkstyle.version}-all.jar
 
-# ----- Cobertura code coverage tool -----
-cobertura.version=2.1.1
-cobertura.checksum.enabled=true
-cobertura.checksum.algorithm=MD5|SHA-1
-cobertura.checksum.value=4f46638aa8e4d89565c038092398ea06|99cb44d36555feedcedc46263c23c2f5394ef342
-cobertura.home=${base.path}/cobertura-${cobertura.version}
-cobertura.jar=${cobertura.home}/cobertura-${cobertura.version}.jar
-cobertura.loc=${base-sf.loc}/cobertura/cobertura-${cobertura.version}-bin.tar.gz
+# ----- JaCoCo code coverage tool -----
+jacoco.version=0.8.7
+jacoco.checksum.enabled=true
+jacoco.checksum.algorithm=MD5|SHA-1
+jacoco.checksum.value=174fde230d1090a5622119d5096bce07|983a52a030f4123b671840a27426ed73479f45cc
+jacoco.home=${base.path}/jacoco-${jacoco.version}
+jacoco.jar=${jacoco.home}/lib/jacocoant.jar
+jacoco.loc=${base-maven.loc}/org/jacoco/jacoco/${jacoco.version}/jacoco-${jacoco.version}.zip
 
 # ----- SpotBugs (originally FindBugs) -----
 findbugs.version=4.2.3
diff --git a/build.xml b/build.xml
index 4566582..1fd83ff 100644
--- a/build.xml
+++ b/build.xml
@@ -16,7 +16,10 @@
   limitations under the License.
 -->
 <project name="Tomcat 9.0" default="deploy" basedir="."
-  xmlns:if="ant:if" xmlns:unless="ant:unless">
+  xmlns:if="ant:if"
+  xmlns:unless="ant:unless"
+  xmlns:jacoco="antlib:org.jacoco.ant"
+  >
 
   <!-- ===================== Initialize Property Values ==================== -->
 
@@ -181,11 +184,9 @@
   <property name="test.formatter" value="-Dorg.apache.juli.formatter=java.util.logging.SimpleFormatter"/>
   <property name="test.relaxTiming" value="false"/>
 
-  <!-- Cobertura code coverage settings -->
-  <property name="cobertura.out" value="${tomcat.output}/coverage"/>
-  <property name="cobertura.datafile" value="${cobertura.out}/cobertura.ser"/>
-  <property name="tomcat.classes.cobertura" value="${tomcat.classes}-cobertura"/>
-  <property name="cobertura.report.format" value="html"/>
+  <!-- Code coverage settings -->
+  <property name="coverage.out" value="${tomcat.output}/coverage"/>
+  <property name="coverage.datafile" value="${coverage.out}/jacoco.exec"/>
 
   <!-- FindBugs settings -->
   <property name="findbugs.out" value="${tomcat.output}/findbugs"/>
@@ -1848,10 +1849,7 @@
   <property name="junit.formatter.extension" value=".txt" />
 
   <target name="test" description="Runs the JUnit test cases"
-          depends="test-nio,test-nio2,test-apr,cobertura-report,test-status" />
-
-  <target name="test-only" description="Runs the JUnit test cases without additional processing"
-          depends="test-only-nio,test-only-nio2,test-only-apr,test-status" />
+          depends="setup-jacoco,test-nio,test-nio2,test-apr,coverage-report,test-status" />
 
   <target name="test-status"
           description="Analyses logs directory and reports on skipped tests, test failures and test errors">
@@ -1889,42 +1887,24 @@
   </target>
 
   <target name="test-nio" description="Runs the JUnit test cases for NIO. Does not stop on errors."
-          depends="test-compile,deploy,cobertura-instrument,test-openssl-exists" if="${execute.test.nio}">
-    <runtests protocol="org.apache.coyote.http11.Http11NioProtocol"
-              extension=".NIO" />
-  </target>
-
-  <target name="test-only-nio" description="Runs the JUnit test cases for NIO. Does not stop on errors."
-          depends="cobertura-disabled,test-openssl-exists" if="${execute.test.nio}">
+          depends="test-compile,deploy,test-openssl-exists" if="${execute.test.nio}">
     <runtests protocol="org.apache.coyote.http11.Http11NioProtocol"
               extension=".NIO" />
   </target>
 
   <target name="test-nio2" description="Runs the JUnit test cases for NIO2. Does not stop on errors."
-          depends="test-compile,deploy,cobertura-instrument,test-openssl-exists" if="${execute.test.nio2}">
-    <runtests protocol="org.apache.coyote.http11.Http11Nio2Protocol"
-              extension=".NIO2" />
-  </target>
-
-  <target name="test-only-nio2" description="Runs the JUnit test cases for NIO2. Does not stop on errors."
-          depends="cobertura-disabled,test-openssl-exists" if="${execute.test.nio2}">
+          depends="test-compile,deploy,test-openssl-exists" if="${execute.test.nio2}">
     <runtests protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               extension=".NIO2" />
   </target>
 
   <target name="test-apr" description="Runs the JUnit test cases for APR. Does not stop on errors."
-          depends="test-compile,deploy,test-apr-exists,cobertura-instrument,test-openssl-exists"
+          depends="test-compile,deploy,test-apr-exists,test-openssl-exists"
           if="${apr.exists}">
     <runtests protocol="org.apache.coyote.http11.Http11AprProtocol"
               extension=".APR" />
   </target>
 
-  <target name="test-only-apr" description="Runs the JUnit test cases for APR. Does not stop on errors."
-          depends="cobertura-disabled,test-openssl-exists" if="${execute.test.apr}">
-    <runtests protocol="org.apache.coyote.http11.Http11AprProtocol"
-              extension=".APR" />
-  </target>
-
   <target name="test-apr-exists" description="Checks for APR lib"
           if="${execute.test.apr}">
     <available file="${test.apr.loc}" property="apr.exists" />
@@ -1956,164 +1936,108 @@
 
     <sequential>
       <mkdir dir="${test.reports}" />
-      <junit printsummary="yes" fork="yes" dir="." showoutput="${test.verbose}"
-        errorproperty="test.result.error"
-        failureproperty="test.result.failure"
-        haltonfailure="${test.haltonfailure}"
-        threads="${test.threads}">
-
-        <jvmarg value="${test.jvmarg.egd}"/>
-        <jvmarg value="-Dfile.encoding=UTF-8"/>
-        <jvmarg value="-Djava.library.path=${test.apr.loc}"/>
-        <jvmarg value="${test.formatter}"/>
-        <jvmarg value="-Djava.net.preferIPv4Stack=${java.net.preferIPv4Stack}"/>
-
-        <!-- Java 9 -->
-        <jvmarg value="${java9.test.option.1}"/>
-        <jvmarg value="${java9.test.option.2}"/>
-        <jvmarg value="${java9.test.option.3}"/>
-        <jvmarg value="${java9.test.option.4}"/>
-        <jvmarg value="${java9.test.option.5}"/>
-
-        <classpath refid="tomcat.test.run.classpath" />
-
-        <sysproperty key="tomcat.test.temp" value="${test.temp}" />
-        <sysproperty key="tomcat.test.basedir" value="${test.basedir}" />
-        <sysproperty key="tomcat.test.tomcatbuild" value="${tomcat.build}" />
-        <sysproperty key="tomcat.test.protocol" value="@{protocol}" />
-        <sysproperty key="tomcat.test.accesslog" value="${test.accesslog}" />
-        <sysproperty key="tomcat.test.reports" value="${test.reports}" />
-        <sysproperty key="tomcat.test.openssl.path" value="${test.openssl.path}" />
-        <sysproperty key="tomcat.test.openssl.unimplemented" value="${test.openssl.unimplemented}" />
-        <sysproperty key="tomcat.test.relaxTiming" value="${test.relaxTiming}" />
-        <sysproperty key="tomcat.test.sslImplementation" value="${test.sslImplementation}" />
-        <sysproperty key="tomcat.test.http2.loopCount" value="${test.http2.loopCount}" />
-        <!-- File for Cobertura to write coverage results to -->
-        <sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.datafile}" />
-
-        <formatter type="${junit.formatter.type}"
-                   usefile="${junit.formatter.usefile}"
-                   extension="@{extension}${junit.formatter.extension}" />
-
-        <!-- If test.entry is defined, run a single test, otherwise run all valid tests -->
-        <test todir="${test.reports}" name="${test.entry}"
-              if="test.entry" unless="test.entry.methods"
-           />
-        <test todir="${test.reports}" name="${test.entry}" methods="${test.entry.methods}"
-              if="test.entry.methods"
-           />
-        <batchtest todir="${test.reports}" unless="test.entry">
-          <!-- Include all by default -->
-          <fileset dir="test" includes="${test.name}" excludes="${test.exclude}">
-            <!-- Exclude helper classes -->
-            <exclude name="**/Tester*.java" />
-            <!-- Exclude the tests known to fail -->
-            <exclude name="org/apache/catalina/tribes/test/**" />
-            <!-- Exclude the OpenSSL tests unless OpenSSL is available -->
-            <exclude name="org/apache/tomcat/util/net/openssl/ciphers/**" unless="${test.openssl.exists}" />
-            <!-- Exclude performance tests. E.g. on systems with slow/inconsistent timing -->
-            <exclude name="**/*Performance.java" if="${test.excludePerformance}" />
-            <!-- Exclude tests that Gump can't compile -->
-            <exclude name="org/apache/tomcat/buildutil/**" />
-            <!--
-              Avoid running tests which require the SecurityManager with other
-              tests. See below for more details.
-            -->
-            <exclude name="**/*SecurityManager.java" />
-          </fileset>
-        </batchtest>
-        <!--
-           Run tests which require the SecurityManager in their own forked
-           batch to ensure that global/system security settings don't pollute
-           other tests. See SecurityManagerBaseTest.java for more details.
-        -->
-        <batchtest todir="${test.reports}" unless="test.entry" fork="true">
-          <fileset dir="test" includes="**/SecurityManager.java" excludes="${test.exclude}" />
-        </batchtest>
-      </junit>
+      <jacoco:coverage
+          enabled="${test.coverage}"
+          destfile="${coverage.datafile}"
+          >
+        <junit printsummary="yes" fork="yes" dir="." showoutput="${test.verbose}"
+          errorproperty="test.result.error"
+          failureproperty="test.result.failure"
+          haltonfailure="${test.haltonfailure}"
+          threads="${test.threads}">
+
+          <jvmarg value="${test.jvmarg.egd}"/>
+          <jvmarg value="-Dfile.encoding=UTF-8"/>
+          <jvmarg value="-Djava.library.path=${test.apr.loc}"/>
+          <jvmarg value="${test.formatter}"/>
+          <jvmarg value="-Djava.net.preferIPv4Stack=${java.net.preferIPv4Stack}"/>
+
+          <!-- Java 9 -->
+          <jvmarg value="${java9.test.option.1}"/>
+          <jvmarg value="${java9.test.option.2}"/>
+          <jvmarg value="${java9.test.option.3}"/>
+          <jvmarg value="${java9.test.option.4}"/>
+          <jvmarg value="${java9.test.option.5}"/>
+
+          <classpath refid="tomcat.test.classpath" />
+
+          <sysproperty key="tomcat.test.temp" value="${test.temp}" />
+          <sysproperty key="tomcat.test.basedir" value="${test.basedir}" />
+          <sysproperty key="tomcat.test.tomcatbuild" value="${tomcat.build}" />
+          <sysproperty key="tomcat.test.protocol" value="@{protocol}" />
+          <sysproperty key="tomcat.test.accesslog" value="${test.accesslog}" />
+          <sysproperty key="tomcat.test.reports" value="${test.reports}" />
+          <sysproperty key="tomcat.test.openssl.path" value="${test.openssl.path}" />
+          <sysproperty key="tomcat.test.openssl.unimplemented" value="${test.openssl.unimplemented}" />
+          <sysproperty key="tomcat.test.relaxTiming" value="${test.relaxTiming}" />
+          <sysproperty key="tomcat.test.sslImplementation" value="${test.sslImplementation}" />
+          <sysproperty key="tomcat.test.http2.loopCount" value="${test.http2.loopCount}" />
+          <!-- File for Cobertura to write coverage results to -->
+          <sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.datafile}" />
+
+          <formatter type="${junit.formatter.type}"
+                     usefile="${junit.formatter.usefile}"
+                     extension="@{extension}${junit.formatter.extension}" />
+
+          <!-- If test.entry is defined, run a single test, otherwise run all valid tests -->
+          <test todir="${test.reports}" name="${test.entry}"
+                if="test.entry" unless="test.entry.methods"
+             />
+          <test todir="${test.reports}" name="${test.entry}" methods="${test.entry.methods}"
+                if="test.entry.methods"
+             />
+          <batchtest todir="${test.reports}" unless="test.entry">
+            <!-- Include all by default -->
+            <fileset dir="test" includes="${test.name}" excludes="${test.exclude}">
+              <!-- Exclude helper classes -->
+              <exclude name="**/Tester*.java" />
+              <!-- Exclude the tests known to fail -->
+              <exclude name="org/apache/catalina/tribes/test/**" />
+              <!-- Exclude the OpenSSL tests unless OpenSSL is available -->
+              <exclude name="org/apache/tomcat/util/net/openssl/ciphers/**" unless="${test.openssl.exists}" />
+              <!-- Exclude performance tests. E.g. on systems with slow/inconsistent timing -->
+              <exclude name="**/*Performance.java" if="${test.excludePerformance}" />
+              <!-- Exclude tests that Gump can't compile -->
+              <exclude name="org/apache/tomcat/buildutil/**" />
+              <!--
+                Avoid running tests which require the SecurityManager with other
+                tests. See below for more details.
+              -->
+              <exclude name="**/*SecurityManager.java" />
+            </fileset>
+          </batchtest>
+          <!--
+             Run tests which require the SecurityManager in their own forked
+             batch to ensure that global/system security settings don't pollute
+             other tests. See SecurityManagerBaseTest.java for more details.
+          -->
+          <batchtest todir="${test.reports}" unless="test.entry" fork="true">
+            <fileset dir="test" includes="**/SecurityManager.java" excludes="${test.exclude}" />
+          </batchtest>
+        </junit>
+      </jacoco:coverage>
     </sequential>
   </macrodef>
 
-  <target name="cobertura-init">
-    <condition property="cobertura.enabled" value="true">
-      <and>
-        <istrue value="${test.cobertura}"/>
-        <equals arg1="1" arg2="${test.threads}"/>
-      </and>
-    </condition>
-    <condition property="cobertura.disabled" value="true">
-      <and>
-        <istrue value="${test.cobertura}"/>
-        <not>
-          <equals arg1="1" arg2="${test.threads}"/>
-        </not>
-      </and>
-    </condition>
-  </target>
-
-  <target name="cobertura-disabled" unless="${cobertura.enabled}"
-          depends="cobertura-init">
-    <!-- Define classpath used to run tests when Cobertura is turned off. -->
-    <path id="tomcat.test.run.classpath">
-      <path refid="tomcat.test.classpath" />
-    </path>
-  </target>
-
-  <target name="cobertura-disabled-log" if="${cobertura.disabled}"
-          depends="cobertura-init">
-    <echo message="Code coverage disabled because test.threads is greater than 1"/>
-  </target>
-
-  <target name="cobertura-instrument"
-          depends="compile,download-cobertura,cobertura-disabled,cobertura-disabled-log"
-          if="${cobertura.enabled}"
-          description="Adds Cobertura instrumentation to the compiled bytecode">
-
-    <path id="cobertura.classpath">
-      <fileset dir="${cobertura.home}">
-        <include name="cobertura-${cobertura.version}.jar" />
-        <include name="lib/**/*.jar" />
-        <exclude name="lib/**/jetty*.jar" />
-        <exclude name="lib/**/servlet-api*.jar" />
-      </fileset>
-      <pathelement path="res/cobertura"/>
-    </path>
-
-    <taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
-
-    <cobertura-instrument datafile="${cobertura.datafile}"
-                          todir="${tomcat.classes.cobertura}">
-      <fileset dir="${tomcat.classes}">
-        <include name="**/*.class"/>
-        <exclude name="**/ClassLoaderLogManager.class"/>
-        <exclude name="**/ClassLoaderLogManager*.class"/>
-        <exclude name="**/FileHandler.class"/>
-        <exclude name="**/AsyncFileHandler.class"/>
-        <exclude name="**/AsyncFileHandler*.class"/>
-        <exclude name="**/OneLineFormatter.class"/>
-        <exclude name="**/OneLineFormatter*.class"/>
-        <exclude name="**/DateFormatCache.class"/>
-        <exclude name="**/DateFormatCache*.class"/>
-      </fileset>
-      <auxClasspath path="${jdt.jar}" />
-    </cobertura-instrument>
-
-    <!-- Define classpath used to run tests -->
-    <!-- The Cobertura instrumented classes must appear first on the classpath -->
-    <path id="tomcat.test.run.classpath">
-      <path location="${tomcat.classes.cobertura}" />
-      <path refid="tomcat.test.classpath" />
-      <path refid="cobertura.classpath"/>
-    </path>
-  </target>
-
-  <target name="cobertura-report" if="${cobertura.enabled}"
+  <target name="coverage-report" if="${test.coverage}"
           depends="test-nio,test-nio2,test-apr"
-          description="Creates report from gathered Cobertura results">
+          description="Creates report from gathered Code coverage results">
+
+    <jacoco:report>
+      <executiondata>
+        <file file="${coverage.datafile}"/>
+      </executiondata>
+      <structure name="Tomcat 10.0.x Code Coverage">
+        <classfiles>
+          <fileset dir="${tomcat.classes}"/>
+        </classfiles>
+        <sourcefiles encoding="UTF-8">
+          <fileset dir="java"/>
+        </sourcefiles>
+      </structure>
+      <html destdir="${coverage.out}"/>
+    </jacoco:report>
 
-    <cobertura-report srcdir="${basedir}/java" destdir="${cobertura.out}"
-                      datafile="${cobertura.datafile}"
-                      format="${cobertura.report.format}"/>
   </target>
 
   <target name="findbugs"
@@ -3269,20 +3193,34 @@ skip.installer property in build.properties" />
 
   </target>
 
-  <target name="download-cobertura"
-          if="${test.cobertura}"
-          description="Download the Cobertura code coverage tool" >
+  <target name="download-jacoco"
+          description="Download the Jacoco code coverage tool" >
 
-    <antcall target="downloadgz">
-      <param name="sourcefile" value="${cobertura.loc}"/>
-      <param name="destfile" value="${cobertura.jar}"/>
-      <param name="checksum.enabled" value="${cobertura.checksum.enabled}"/>
-      <param name="checksum.algorithm" value="${cobertura.checksum.algorithm}"/>
-      <param name="checksum.value" value="${cobertura.checksum.value}"/>
+    <antcall target="downloadzip">
+      <param name="sourcefile" value="${jacoco.loc}"/>
+      <param name="destfile" value="${jacoco.jar}"/>
+      <param name="destdir" value="${jacoco.home}"/>
+      <param name="checksum.enabled" value="${jacoco.checksum.enabled}"/>
+      <param name="checksum.algorithm" value="${jacoco.checksum.algorithm}"/>
+      <param name="checksum.value" value="${jacoco.checksum.value}"/>
     </antcall>
 
   </target>
 
+  <target name="setup-jacoco" depends="download-jacoco">
+    <!-- Add JaCoCo tasks to project -->
+    <path id="jacoco.classpath">
+      <fileset file="${jacoco.jar}" />
+    </path>
+
+    <taskdef uri="antlib:org.jacoco.ant"
+             resource="org/jacoco/ant/antlib.xml"
+             classpathref="jacoco.classpath"
+             />
+
+  </target>
+
+
   <target name="download-findbugs"
           if="${execute.findbugs}"
           description="Download FindBugs" >
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 469fc4b..029405b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -229,6 +229,15 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="Other">
+    <changelog>
+      <fix>
+        Switch from Cobertura to JaCoCo for code coverage as Cobertura does not
+        support code coverage for code compiled for Java 11 onwards. It also
+        removes the need to use a single thread to run the tests. (markt)
+      </fix>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 9.0.54 (remm)" rtext="2021-10-01">
   <subsection name="Catalina">

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org