how to clean jacoco.exec after running integration tests in a multi-module project - sonarqube

I have a multimodule Maven project, it is analyzed using the Sonar Maven runner and coverage is done with Jacoco. For our integration tests we want to see the coverage across all modules (because they are integration tests after all).
Therefore we configure the jacoco-it.exec file to be in ${user.dir}, with the appendproperty to true. This way all modules append their information to the same location and coverage is calculated over all modules.
But since append is true the file will still be there on a next run, since it isn't placed in a directory that maven cleans. This leads to incorrect coverage reports.
What is the best way to clean up this file after a sonar run? Ideally I would like to configure this in the same pom profile as our jacoco/sonar configuration, so that no other projects need to remember to set a clean step in Jenkins or whereever. The sonar/jacoco configuration is in a company wide parent pom file.

Since you are using Maven, you could try and use the maven-antrun-plugin to delete the file.
I don't know how you run Sonar Maven, but you can either bind the maven-antrun-plugin task to a phase after the one the Sonar Maven Runner is bound to (and you would have the file deleted automatically and the end of each run) or you can call the maven-antrun-plugin from the command line.

Related

How to write a Maven plugin IT test that correctly fails its build, resulting in an overall pass?

When generating a skeleton Maven plugin from archetype, the new project includes a Maven project under the src/it directory. It is an integration it (hinted at by the it dir name) and fresh out-of-the-box it passes when run during Maven's integration-test phase.
There are nearly 10 such IT Maven projects, a subset of which intentionally result in BUILD FAILURE, and attendant verify.groovy scripts that ensure those builds fail for the correct reason. Ideally each IT test sub-build that fails for the correct reason results in that IT test passing, but by including any of these failing IT tests as part of the whole integration test suite causes the overall Maven run to fail as well, which is incorrect in my case.
How do I coax Maven to run those failing Maven sub-builds, ignore their build results, but honor the results of their Groovy verification scripts?
Edit: One IT test (disabled) is committed here.
If you like to write an integration test which is intended to fail as a result
you have to express this via the invoker.properties file like this:
invoker.buildResult=failure
The full description of the file can be found in the documentation.

SonarQube Jacoco JUnit : SonarScanner get many unexpected problems

I have a simple project that need to Run JUnit test and let SonarQube to scan / run the Test of JUnit result with SonarScanner. I put my project at Github here
There are some problems:
WARN: Class "XXX" is not accessible through the classloader sonar (Reference)
No jacoco-it.exec and jacoco-ut.exec, only run jacoco.exec at SonarScanner
Cannot exclude some files when running Test JUnit, because I only want to Run Test in my Service Folder (Reference)
This is my sonar-project.properties :
# Required metadata
sonar.projectKey=com.example:Sample
sonar.projectName=Java :: Example :: SonarQube Scanner
sonar.projectVersion=1.0
# Comma-separated paths to directories with sources (required)
sonar.sources=src
sonar.exclusions=src/main/resources/**
#sonar.test.inclusions=src/main/java/com/example/service/**, src/test/java/**
#sonar.test.exclusions=src/main/java/com/example/controller/**
# Encoding of the source files
sonar.sourceEncoding=UTF-8
#Jacoco
sonar.junit.reportsPath=target/surefire-reports
sonar.jacoco.reportPath =target/jacoco.exec
sonar.jacoco.reportMissing.force.zero=true
sonar.java.binaries=target/classes/**
#sonar.java.libraries=libs/**
When I Run Maven Test until build success, It create some files and folders in folder Target.
After that I run my SonarScanner to Scan my project, but I got those problems.
My question:
How can I run my SonarQube Scanner without any WARN ?
How to exclude files properly when scanning JUnit result? Because I use the reference settings, and Coverage still scan the files
How to create jacoco-it.exec and jacoco-ut.exec and run it on SonarScanner?
My project is based on this Reference
Use SonarQube Scanner for Maven instead of just SonarQube Scanner. Otherwise you fall into troubles with configuration, into which you fall, because need to do everything manually:
sonar.sources most likely is incorrect - should be src/main/java and will be properly configured by Scanner for Maven, and that's why you're getting undesired test files analysed as main files
as well as sonar.tests that normally for Maven based projects points to src/test/java
sonar.java.libraries is empty and that's why you're getting Class "XXX" is not accessible through the classloader sonar - it might be quite hard to list all required JAR files of dependencies of your Maven project, while again Scanner for Maven will do this automatically and most importantly will do this correctly
sonar.projectKey with Scanner for Maven will be set automatically to Maven groupId:artifactId
sonar.projectName and sonar.version with Scanner for Maven will be set correctly to Maven project name and version respectively, so that you don't need to change version, when it will change in Maven project
others such as sonar.sourceEncoding, sonar.java.binaries, sonar.java.test.binaries and sonar.java.test.libraries with Scanner for Maven will also be set automatically
If needed you'll still be able to provide other additional properties
via command line such as mvn ... sonar:sonar -Dsonar.something=something
or in SonarQube UI
or specify them directly in properties section of pom.xml
How to create jacoco-it.exec and jacoco-ut.exec and run it on SonarScanner?
Usually jacoco-ut.exec refers to coverage data about unit tests and jacoco-it.exec refers to coverage data about integration tests. They are created by jacoco-maven-plugin, in your pom.xml you configured jacoco-maven-plugin for creation of jacoco.exec.

sonar-maven-plugin with multi-module maven

I have a multi-module maven project which seems to have correctly generated OWASP dependency reports at both the parent and child module /target dirs using the org.owasp:dependency-check-maven plugin as so:
However, referencing the plugin docs, and executing the sonar-maven-plugin as below, I just can't work out what the correct command should be, any combination seems to lead to a build failure:
mvn sonar:sonar -Dsonar.sources=? -Dsonar.dependencyCheck.reportPath=?
Can anyone explain how to configure a multi-module maven project and have Sonar recognise the OWASP dependency reports?
Below is a screenshot of the starting point - we've had a CI pipeline up and running producing separate unit and integration test coverage stats for each of the submodules for some time.
Ok, so have contacted the author and the dependency-check-sonar-plugin doesn't work with a multi-module maven project.
So we are just going to produce a static artefact in a one-off fashion and not attempt to integrate with our CI pipeline.

How do I set up a TeamCity build job to execute a maven job with no pom

We have an in-house developed MOJO that generates content and doesn't require you to have an existing project or POM. Think of the maven archetype plugin, where you can just run mvn [mojo]:[goal] and have maven just execute that goal without a POM.
This MOJO connects to a specific database instance in a specific environment, and generates some metadata for the contents of the database, so our testers can inspect the metadata and locate production-like data that has certain attributes they need for a given test.
When you execute the metadata mojo, maven resolves the MOJO from the available repo's (in our case an Artifactory repo), and it then does its work and returns. It does not create any artifacts or other outputs.
We use TeamCity as our CI server, but it also has metadata generation jobs so with one click a dev can kick of a metadata generation job against a specific database.
The problem with this is the Maven runner in TeamCity requires a POM. If TC hasn't already checked out a project from a VCS, or the project it's checked out doesn't have a POM, the maven runner won't do anything. In this case, there is nothing to check out (the MOJO is resolved from Artifactory) so there is no POM.
I can set up the TC job to use the Command Line runner and have it execute, say, mvn com.example:metadata-generate -DenvironmentName=UAT1, but then it's impossible to specify the maven settings file that maven should use.
So my question is, how do I do this? Is it possible to have the maven runner execute an arbitrary maven command without needing a POM? Alternatively, using the Command line runner, is it possible to have a TC job copy a specific maven settings file to the build agent so it can be referenced in the maven command as mvn com.example:metadata-generate -DenvironmentName=UAT1 -s {path-to-settings-file}?
So its turns out that TC handles pom-less maven builds just fine. My problem was that the MOJO was not declared to not require a project.
Comparing my MOJO with the MavenArchetypePlugin source, I needed to declare my MOJO with the class level javadoc tag #requiresProject false.
Once I had that in place, TC ran my pom-less job perfectly well. All I had to do was clear the Path to POM file: field in the TC build configuration and leave it blank.
You can customize the name of the pom file that you use as an argument into the maven build-step in the teamcity and use this as the second "build step".Lets call the parameter as pom.file.name
In the first step , resolve all the in-house dependencies that you have and set the name of the pom file you want to execute into the variable pom.file.name
If you want to know more about how to change tha value of a variable in teamcity, you can read about it here

How to configure Hudson to use Maven for dependecies and run JUnit

In Eclipse I have my "Dynamic Web Project" configured with Maven taking care automatically of all my dependencies (once I specify them in pom.xml). After implementing my Unit Tests I can simply run them all by right-clicking on project and selecting: Run As -> JUnit Test.
How/where can I now configure Hudson so after checkout of all my sources from SVN repository it would automatically invoke(?) Maven (to download all dependencies) and then run all available tests with JUnit?
When you set up a project in Hudson (now Jenkins) in the configuration page you may choose the build phases that Jenkins will run. Then it will run them in the order you specify. There you will have Maven steps where you'll define your goals.
Jenkins itself has to know where to find a Maven installation (or Ant, or any other command that it must run to build). This could be done in the server configuration page.
I think that's the default behavior of Hudson (compiling + running tests).
Did you commit on your svn repository the pom.xml file?

Resources