SonarQube to take the coverage from Clover.xml - java

I have generated a clover.xml report for my service. I want to integrate that with my SonarQube report which is not showing the coverage at all.
I am not sure what exact plugin to add to my pom.xml so sonar can read it.
Here is part of my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/it/java</source>
</sources>
</configuration>
</execution>
</executions></plugin><plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-clover2-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*Constants.java</exclude>
<exclude>**/*LatestTimeSeriesDataServiceImpl.java</exclude>
<exclude>**/TestWebRequest.java</exclude>
</excludes>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.core.codeCoveragePlugin>clover</sonar.core.codeCoveragePlugin>
<sonar.clover.reportPath>target\site\clover\clover.xml</sonar.clover.reportPath>
<sonar.surefire.reportsPath>target\surefire-reports</sonar.surefire.reportsPath>
<sonar.core.codeCoveragePlugin>clover</sonar.core.codeCoveragePlugin>
<sonar.clover.version>${clover.version}</sonar.clover.version>
</configuration>
and this is part of my setting.xml:
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.jdbc.url></sonar.jdbc.url>
<sonar.jdbc.driver></sonar.jdbc.driver>
<sonar.jdbc.username></sonar.jdbc.username>
<sonar.jdbc.password></sonar.jdbc.password>
<sonar.host.url>http://localhost:9000/</sonar.host.url>
</properties>
I hided some values I am not sure if they are confidential or not..
these are the values to my sonar-project.properties:
sonar.projectKey=org.sonarqube:java
sonar.projectName=org.sonarqube:java
sonar.projectVersion=1.0
sonar.sources=path
sonar.tests=path
sonar.language=java
sonar.sourceEncoding=UTF-8
sonar.core.codeCoveragePlugin=clover
sonar.clover.reportPath=target/site/clover/clover.xml
sonar.java.binaries=target/classes
sonar.dynamicAnalysis=reuseReports
in addition i tried to enforce the properties through command line as well:
mvn sonar:sonar -s menlo_settings.xml -Dsonar.host.url=http://localhost:9000/ org.codehaus.mojo:sonar-maven-plugin:2.7.1:sonar -Dsonar.core.codeCoveragePlugin=clover -Dsonar.clover.reportPath=target/site/clover/clover.xml
Nothing is working and I am frustrated!! If anyone know about it please let me know!

Related

Get IT test in Sonar trough maven

Gooday,
I’m trying to get my IT in to the test coverage in sonar. I have a multi module project and I want this to work for all the modules. So as far as I got it through the documentation I found:
https://docs.sonarqube.org/display/PLUG/Usage+of+JaCoCo+with+Java+Plugin
https://github.com/SonarSource/sonar-scanning-examples/tree/master/sonarqube-scanner-maven (witch are outdated btw)
http://www.eclemma.org/jacoco/trunk/doc/maven.html
Integrating JaCoCo with SONAR for unit and integration test coverage (autdated its prity based on old maven and sonar stuff and our sonar is a bit newer (6.3.1)).
But when I run it the test seems to have 0% so obviously I’m doing something wrong. Some in put on where I did go wrong would be nice.
My main Pom:
<properties>
<maven-failsafe-plugin.version>2.20.1</maven-failsafe-plugin.version>
<maven-surefire-plugin.version>2.20.1</maven-surefire-plugin.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPaths>${project.basedir}/../target/</sonar.jacoco.reportPaths>
<argLine>-Xmx256m -XX:MaxPermSize=200m</argLine>
</properties>
...
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent-for-ut</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.basedir}/../target/jacoco-ut.exec</destFile>
</configuration>
</execution>
<execution>
<id>agent-for-it</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.basedir}/../target/jacoco-it.exec</destFile>
</configuration>
</execution>
<execution>
<id>jacoco-site</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
</plugins>
</build>
Ive been messing with for my feeling a whole day and have not found a clear cut answer what I am doing wrong. So some input would be very helpful
well the coverage for both unit and integration tests is a bit fragile...
The configuration you have looks ok. I think what may happens is that the "argLine" property is replaced or not correctly set for the surefire or failsafe plugin. If you run the mvn goals with -X have a close look what happens when failsafe starts what its value is. The argLine should contain the jacoco agent to collect the coverage information.
Another thing: failsafe might write the coverage results into the same jacoco.exec file as surefire.
What I've done (not sure if it's the smartest of all ways): put all things in a profile and use custom properties for the jacoco-plugin and seperate files for the coverage so the sonar report can pick them up:
The sonar-jacoco-listeners is only required if you want to know what test covers which production code. In sonar this is then shown in the green bar what tests called the code.
Other than that:
The pom has some properties:
<surefire.jvm.args></surefire.jvm.args>
<failsafe.jvm.args></failsafe.jvm.args>
<jacoco.append>true</jacoco.append>
</properties>
These can be set if needed and the config uses its own properties to not conflict with the argLine (which is the default for both surefire and failsafe)
The sonar.jacoco.reportPath can be used to write one file for all maven modules, in case some integration tests are in a different module and you want to measure the coverage as well (not too nice code-wise, but well... reality and stuff):
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
Here my coverage profile: (adopt the includes: my/packages/* pattern below!)
<profile>
<dependencies>
<dependency>
<groupId>org.codehaus.sonar-plugins.java</groupId>
<artifactId>sonar-jacoco-listeners</artifactId>
<version>3.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<!-- prepare configuration for surefire tests -->
<execution>
<id>prepare-agent</id>
<phase>initialize</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<propertyName>jacoco.agent.argLine</propertyName>
<append>true</append>
</configuration>
</execution>
<!-- prepare configuration for failsafe integration tests -->
<execution>
<id>prepare-agent-integration</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<propertyName>jacoco.agent.it.argLine</propertyName>
<append>true</append>
</configuration>
</execution>
</executions>
<configuration>
<includes>
<include>my/packages/*</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<properties>
<property>
<name>listener</name>
<value>org.sonar.java.jacoco.JUnitListener</value>
</property>
</properties>
<argLine>${jacoco.agent.argLine} ${surefire.jvm.args}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>${jacoco.agent.it.argLine} ${failsafe.jvm.args}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
So the principle is the same, setup the jacoco agent in the correct phase and run the tests. I assume the jacoco agent is not properly setup or your argLine conflicts with something happening during your build.

How can I exclude files of the Code Coverage of SonarQube using JaCoCo maven plugin

I've got a big issue with the integration of JaCoCo maven plugin for the code covering of SonarQube 6.0.
I've got a multi-module Maven project lets say :
master
|--core
|--web
|--process
in the master pom.xml, I've setted a reporting profile like that :
<profile>
<id>reporting</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<!--<phase>test</phase> -->
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- Sets the path to the file to write the execution data to. -->
<destFile>${sonar.jacoco.reportPath}</destFile>
<!-- Connection with SureFire plugin -->
<propertyName>sonarUnitTestArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to where the execution data is located. -->
<dataFile>${sonar.jacoco.reportPath}</dataFile>
<!-- Sets the output directory for the code coverage report. -->
<outputDirectory>${jacoco.ut.outputdir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>once</forkMode>
<argLine>${sonarUnitTestArgLine} -XX:MaxPermSize=512M -Xms512m -Xmx512m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
in the childs, I overload the configuration by adding some exclusions :
<!-- First attempt -->
<properties>
<sonar.jacoco.excludes>**/model/**/*</sonar.jacoco.excludes>
</properties>
<!-- Second attempt -->
<properties>
<sonar.coverage.exclusions>**/model/**/*</sonar.coverage.exclusions>
</properties>
<!-- Third attempt -->
<profiles>
<profile>
<id>reporting</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude model classes (POJO's) -->
<exclude>**/model/**/*.class</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
the idea here is to remove the Pojo of the code coverage ( we also do it for other types of Class ...)
When I run the mvn command line :
mvn clean generate-sources install verify -P reporting -fn
All my reports are well generated but in Sonar, the exculsions aren't been taking into account ...
Please can you help me fixing this issue ?
After a lot of reasearch, I've found the solution for this problem, I post the answers to help poeple ho'll have the same issue :
In the master-module
<properties>
<sonar.coverage.exclusions>
**/patternA/**/*,
**/patternB/**/*
</sonar.coverage.exclusions>
</properties>
In the sub-modules
<profiles>
<profile>
<id>report</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude model classes (POJO's) -->
<exclude>**/patternA/**/*.class</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
in the master pom
I tried adding just the below details in properties section and it worked for me.
<sonar.coverage.exclusions>
**/patternA/*.java,
**/patternB/*.java
</sonar.coverage.exclusions>

Is there a way to skip execution of a Maven plugin that does not support skip configuration?

I'm wondering if there is a way to skip the execution of a plugin if this plugin/goal does not support a "skip" configuration?
I'm using the iterator-maven-plugin and I want to skip the plugin execution of the deploy-file goald of the deploy plugin for certain items - so changing the phase to none is not an option.
See below for some example code - I basically want the deploy-file goal be executed for some of the items
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>iterator-maven-plugin</artifactId>
<version>0.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>iterator</goal>
</goals>
<configuration>
<itemsWithProperties>
<itemWithProperty>
<name>test</name>
<properties>
<skipDeployment>true</skipDeployment>
</properties>
</itemWithProperty>
<itemWithProperty>
<name>prod</name>
<properties>
<skipDeployment>false</skipDeployment>
</properties>
</itemWithProperty>
</itemsWithProperties>
</configuration>
<pluginExecutors>
<pluginExecutor>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<goal>deploy-file</goal>
<configuration>
<pomFile>${basedir}/target/checkout/#item#/myFile.pom</pomFile>
<file>${basedir}/target/checkout/#item#/myFile.jar</file>
<repositoryId>${mavenRepositoryId}</repositoryId>
<url>${mavenRepositoryUrl}</url>
<!-- if the deploy plugin would support a skip configuration we could do sth. like this -->
<skip>${skipDeployment}</skip>
</configuration>
</pluginExecutor>
</pluginExecutors>
</configuration>
</execution>
</executions>
</plugin>

How to skip generate-sources in Maven

Is there way to skip generate-sources in Maven?
Doing it via command line options
I've scenario where I generate CXF classes when ever I there is change in WSDL or WADL. Hence I generate it explicitly whenever I need. Hence I created a separate profile a new profile cxf-gen along with my usual dev, uat, syst. which has plugins to generate the classes. In short whenever I need to regenerate the classes I switch to the profile and run generate-sources. Here is sample profile I use.
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<envName>dev</envName>
</properties>
</profile>
<profile>
<id>uat</id>
<properties>
<envName>uat</envName>
</properties>
</profile>
<profile>
<id>jaxB-gen</id>
<properties>
<envName>dev</envName>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<!-- CONFIGS ->
</configuration>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>code-gen</id>
<properties>
<envName>dev</envName>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<!-- CONFIGS ->
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- wadl2java Required only when JAXRS classes are to be generated -->
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-wadl2java-plugin</artifactId>
<version>2.7.6</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<!-- CONFIGS ->
</configuration>
<goals>
<goal>wadl2java</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.googlecode.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>0.3.7</version>
<configuration>
<!-- CONFIGS ->
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
This command line option should work if you are using maven-source-plugin (works with Maven 3.6.0):
-Dmaven.source.skip=true
This is an old question and although some answers would somehow work none of them are ideal.
This answer does not break clean builds: calling "mvn <goal>" still produces the expected and backward-compatible result, which is good for continuous integration. Also this answer does not rely on committing generated code to version control, which is a bad idea as it might become out of sync with the source.
I am assuming the generate-sources phase is bound to a plugin goal.
The answer is to create a profile called "clean-build" which is active by default and contains your plugin binding. When a developer trusts they can safely skip generate-sources they may run the following.
mvn -P !clean-build <goal>
Or if the exclamation mark needs to be escaped.
mvn -P \!clean-build <goal>
Here is what the pom.xml might look like.
<profiles>
<profile>
<id>clean-build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
...
<executions>
<execution>
...
<phase>generate-sources</phase>
...
</execution>
</executions>
...
</plugin>
</plugins>
</build>
</profile>
</profiles>
This answer requires Maven 2.0.10+.

Conditionally Execute JMeter Maven Plugin

I'm trying to figure out how to execute my JMeter performance test plan conditionally. I want to have my Jenkins CI job execute it, but when developers run mvn clean install I don't want the below plugins to run. Any ideas on how I can modify my pom.xml to conditionally run the below plugins?
Maven POM.xml JMeter Plugins:
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>verify</phase>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<testFilesDirectory>${project.basedir}/src/test/jmeter</testFilesDirectory>
<ignoreResultFailures>true</ignoreResultFailures>
<testResultsTimestamp>false</testResultsTimestamp>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/jmeter/results</dir>
<stylesheet>${project.basedir}/src/test/resources/jmeter-results-detail-report_21.xsl</stylesheet>
<outputDir>${project.build.directory}/jmeter/results</outputDir>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.RegExpFileMapper">
<pattern>(.*?)\s(.*?)</pattern>
<replacement>$1$2</replacement>
<replaceAll>true</replaceAll>
</fileMapper>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>.html</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<plugin>
<groupId>ch.fortysix</groupId>
<artifactId>maven-postman-plugin</artifactId>
<version>0.1.2</version>
<executions>
<execution>
<id>send a mail</id>
<phase>install</phase>
<goals>
<goal>send-mail</goal>
</goals>
<inherited>false</inherited>
<configuration>
<from>admin#test.com</from>
<subject>Load Test Results</subject>
<failonerror>true</failonerror>
<mailhost>relay.apple.com</mailhost>
<htmlMessageFile>${project.build.directory}/jmeter/results/LoadTestPlan.html</htmlMessageFile>
<receivers>
<receiver>email#me.com</receiver>
</receivers>
<fileSets>
<fileSet>
<directory>${project.build.directory}/jmeter/results</directory>
<includes>
<include>LoadTestPlan.html</include>
</includes>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
The best way to achieve this is with profiles. You define a profile which contains your plugin configuration. This profile would by default be turned off (so when a developer executes mvn clean install it is not activated), and you would only activate it during your Jenkins job.
So for example in your pom you would have something along these lines:
<project>
...
<profiles>
<profile>
<id>ci-environment</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>build.environment</name>
<value>jenkins</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<!-- rest of your jmeter configuration goes here -->
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<!-- rest of your xml-maven configuration goes here -->
</plugin>
<plugin>
<groupId>ch.fortysix</groupId>
<artifactId>maven-postman-plugin</artifactId>
<!-- rest of your postman configuration goes here -->
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
So by default this profile is not active, and the plugins wont execute. On Jenkins you would configure the build to be executed as follows:
mvn clean install -Dbuild.environment=jenkins
As the profile has an id you can also configure Jenkins to specifically use the profile by name as follows:
mvn clean install -Pci-environment
For details on possible ways to activate a profile see the following sonatype resource:
http://books.sonatype.com/mvnref-book/reference/profiles-sect-activation.html

Categories