Uploaded image for project: 'Clover'
  1. Clover
  2. CLOV-595

Please document instructions for integrating Clover with Eclipse PDE builds

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Fixed
    • 3.0
    • CEP Plugin
    • None
    • Our product teams collect and evaluate feedback from a number of different sources. To learn more about how we use customer feedback in the planning process, check out our new feature policy.

    Description

      Assumptions:

      a) 1 or more plugin projects
      b) 1 or more feature projects
      c) 1 project used to drive the build which may or may not contain customized xml files e.g. allElements.xml, customTargets.xml
      d) 1 or more test plugin projects using JUnit to run the tests
      e) 1 or more test feature projects
      f) Building is achieved through the headless PDE build system
      g) You build your plugins against an Eclipse installation that has the Clover-for-Eclipse plugins installed and you have input a valid Clover license.
      h) Testing is achieved through the Eclipse Test Framework
      i) You test your plugins by creating a fresh Eclipse installation and overlaying your plugins and features (including test plugins and features) and launching the Eclipse Test Framework test application.

      General approach:

      The first and most important aspect of the approach is the interception of the generation of all build.xmls for plugins & features. When this happens, I perform an XSLT transformation on plugin build.xmls which inserts a single clover task call just before the javac call. E.g.:

      <clover-setup enabled="true|false" initstring="/path/to/initstring"/>
      

      This allows Clover to instrument before compilation.

      The last aspect of the approach invokes the Clover HTML report at the end of the test run. This is the easiest part.

      Example workspace setup:

      My example workspace is based off the RCP quickstart project (http://rcpquickstart.com/2008/08/04/updated-pde-build-and-test-example/). The workspace is structured as follows:

      com.rcpquickstart.helloworld (main plugin)
      com.rcpquickstart.helloworld.build-ant-test (build project)
      com.rcpquickstart.helloworld.feature (main feature)
      com.rcpquickstart.helloworld.test (test plugin)
      com.rcpquickstart.helloworld.test.feature (test feature)

      Steps to get this working for your build

      1. Add the following to the build.properties of the build project

      clover.enabled=true
      # Where the instrumentation database and coverage recordings are put
      clover.initstring=${buildDirectory}/.clover/coverage.db
      # Where HTML/XML/PDF reports are put
      clover.reportdir=${buildDirectory}/coverage-reports
      # Version of com.cenqua.clover.eclipse.ant
      clover.version=2.4.3.v20090309110000
      # Location of clover jar
      clover.jar=${eclipseLocation}/plugins/com.cenqua.clover.ant_${clover.version}/clover-eclipse-ant.jar
      

      2. Add buildWithClover.xsl to the build project

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      	<xsl:param name="initstring" expression="no_initstring_supplied"/>
      	<xsl:param name="enabled" expression="false"/>
      	<xsl:template match="node()|@*">
      	   <xsl:copy>
      	   <xsl:apply-templates select="@*"/>
      	   <xsl:apply-templates/>
      	   </xsl:copy>
      	 </xsl:template>
      	 <xsl:template match="javac">
      		<clover-setup initstring="{$initstring}" enabled="{$enabled}"/>
      		<xsl:copy>
      			<xsl:apply-templates select="@* | node()" />
      		</xsl:copy>
      	 </xsl:template>
      </xsl:stylesheet>
      

      3. In the build project, add or edit customTargets.xml. If this file doesn't exist, take a copy from ECLIPSE_PDE_INSTALLATION/org.eclipse.pde.build_X.Y.Z/templates/headless-build
      Add this macrodef somewhere within the <project></project> element:

      	<macrodef name="cloverizeBuildXml">
      		<attribute name="file"/>
      		<sequential>
      			<xslt in="@{file}" out="@{file}.out" style="${buildDirectory}/plugins/com.rcpquickstart.helloworld.build-and-test/buildWithClover.xsl">
      				<param name="initstring" expression="${clover.initstring}/"/>
      				<param name="enabled" expression="${clover.enabled}"/>
      			</xslt>
      			<move file="@{file}.out" tofile="@{file}"/>
      		</sequential>
      	</macrodef>
      

      Edit the postGenerate target as follows:

      	<target name="postGenerate">
      		<!-- repeat this for as many plugins as you want coverage for -->
      		<cloverizeBuildXml file="${buildDirectory}/plugins/com.rcpquickstart.helloworld/build.xml"/>
      		<cloverizeBuildXml file="${buildDirectory}/plugins/com.rcpquickstart.helloworld.test/build.xml"/>
      		<antcall target="clean" />
      	</target>
      

      5. Add this to the build project build.xml to invoke the Clover HTML report:

      	<target name="clover.report">
      		<!-- Set up Clover location and instrumentation path -->
      		<taskdef resource="cloverlib.xml" classpath="${clover.jar}"/>
      
      		<!-- 
      			Produce coverage analysis docs using Clover 
      		-->
      		<clover-report failonerror="false" initstring="${clover.initstring}">
      	       <current outfile="${clover.reportdir}">
      	          <format type="html"/>
      	       </current>
      		</clover-report>
      	</target>
      

      6. You may not always want to run a code coverage build (e.g. you may want to toggle it by a property supplied through Bamboo). In that case you will need a few more build project build.xml changes to rewrite build.properties before it is used. Rewriting the build.properties is required because the labyrinthine RCP build system ignores properties specified on the command line and takes them from build.properties directly.

      So in the build project build.properties, make clover.enabled=false instead of true
      Now rename build.properties to build.properties.base (this will have to be a permanent change w.r.t. for this project)
      Add the following to the very top of the build project build.xml just after the <project ... > element

              <!-- ensure clover.enabled is always set to something -->
      	<condition property="clover.enabled" value="${clover.enabled}" else="false">
      		<isset property="clover.enabled"/>
      	</condition>
      	
      	<copy file="build.properties.base" tofile="build.properties"/>
      	<propertyfile file="build.properties">
      		<entry key="clover.enabled" value="${clover.enabled}"/>
      	</propertyfile>	
      

      This will ensure that Clover compilation is enabled/disabled depending on the value you supply to ant for clover.enabled. E.g. ant -Dclover.enabled=true build.xml clean init test clover.report


      One thing I forgot to mention is that you need to ensure whatever is hosting your unit tests as they run (presumably some Eclipse instance) makes the Clover jar available to the running instrumented tests / plugins. This can be done by ensuring the following is added to the launch line of whatever is running your tests (presumably in the build project's build.xml):

      -Xbootclasspath/a:${clover.jar}
      

      Here's the Clover-enabled RCP Quickstart project. As I don't have access to a Linux machine I've kept it as is (configured for OSX) but there shouldn't be any major differences with your setup.

      Properties specific to my setup:

      pdeBuildPluginVersion=3.4.1.R34x_v20081217
      equinoxLauncherPluginVersion=1.0.101.R34x_v20081125
      # the Eclipse instance you're compiling against
      base=/Users/michaelstudman/Projects/Cenqua/Eclipse/Installs/Eclipse_3.4.2PDE
      # the Eclipse instance used to drive compilation
      eclipseLocation=/Users/michaelstudman/Projects/Cenqua/Eclipse/Installs/Eclipse_3.4.2PDE
      # the platform you wish to build for, you will probably want something like linux, gtk, x86
      configs=macosx, carbon, x86
      # where the build results go
      buildDirectory=${user.home}/eclipse.build
      # my eclipse installations don't look like "Eclipse_3.4.2PDE/eclipse/[plugins|features|...]"  but rather "Eclipse_3.4.2PDE/[plugins|features|...]" so this is the same as ${base}
      baseLocation=${base}
      

      I have not zipped up the fresh Eclipse archive (eclipse-rcp-ganymede-SR2-macosx-carbon-1.tar.gz) I used to build the Eclipse instance to run the tests as this is too large. You will need to download a version appropriate for your own platform, put in com.rcpquickstart.helloworld.build-and-test and then update build.xml accordingly. I have included the eclipse-test-framework-3.4.2.zip

      Attachments

        Activity

          People

            Unassigned Unassigned
            mstudman Michael Studman (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: