SonarQube not showing test Jacoco coverage for JUnit tests in a Gradle multi-project - jenkins

I would like to show the test coverage of a multiple project Spring boot application build with Gradle 6.0. We currently use JUnit5.
The test coverage shows 0% in SonarQube even though a few first tests exists.
The build.gradle files in the top level project (https://github.com/OpenReqEU/eclipse-plugin-vogella/blob/master/server/build.gradle) has the following input:
plugins {
id "org.sonarqube" version "2.7"
id 'jacoco'
}
repositories {
jcenter()
}
subprojects {
apply plugin: 'jacoco'
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
jcenter()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
}
jacocoTestReport {
reports {
xml.enabled true
xml.destination file("${buildDir}/coverage-reports/coverage.xml")
//html.destination file("${buildDir}/coverage-reports")
}
}
ext {
springBootVersion = '2.1.1.RELEASE'
}
sourceCompatibility = 1.8
}
wrapper {
gradleVersion = '6.0'
}
In the Jenkins build we set the following parameters:
sonar.projectKey=eclipse-plugin-vogella
sonar.sources=server/com.vogella.prioritizer.server/src/main,server/com.vogella.prioritizer.server.bugzilla/src/main,server/com.vogella.prioritizer.server.issue.api/src/main
sonar.java.binaries=com.vogella.prioritizer.server/build/classes/java/main,com.vogella.prioritizer.server.bugzilla/build/classes/java/main,com.vogella.prioritizer.server.issue.api/build/classes/java/main
sonar.tests=server/com.vogella.prioritizer.server/src/test,server/com.vogella.prioritizer.server.bugzilla/src/test
sonar.coverage.jacoco.xmlReportsPath=server/com.vogella.prioritizer.server.bugzilla/build/jacoco/test.exec,server/com.vogella.prioritizer.server/build/jacoco/test.exec,server/com.vogella.prioritizer.server.issue.api/build/jacoco/test.exec
The result of the build shows an error:
INFO: parsing [/home/jenkins/workspace/issue-prioritizer/coverage-reports/coverage.xml]
ERROR: Reports path not found or is not a directory: /home/jenkins/workspace/issue-prioritizer/coverage-reports/coverage.xml
I see that each project has a generated ${buildDir}/coverage-reports/coverage.xml file but the root file is empty, which is expected as I did not configure anything related to this.
At some point I added a copy task which copied one of the generated xml files from one project into the root folder but the build job complained that the classes were not matching.
Does anybody know how this issue can be solved? I assume I must add a configuration to add a root coverage.xml file which is the aggregate of the individual ones but I have not found a solution for that.
I also tried to apply the jacoco to the root project but that also failed as the root project is not a Java project.

Need to generate report in xml format. Add the sonar property to the xml path as below.
jacocoTestReport {
reports {
xml.enabled true
}
}
sonarqube {
properties {
property "sonar.java.source", "1.8"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.jacoco.reportPaths", "build/reports/jacoco/test/jacocoTestReport.xml"
}
}
Run the gradle command with the jacocoTestReport
gradlew sonarqube jacocoTestReport

I managed to create the aggregated coverage.xml file by changing the top level build.gradle to:
plugins {
// id "org.sonarqube" version "2.7"
id 'jacoco'
}
repositories {
jcenter()
}
subprojects {
println name;
apply plugin: 'jacoco'
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
jcenter()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
}
jacocoTestReport {
reports {
xml.enabled true
}
}
ext {
springBootVersion = '2.1.1.RELEASE'
}
sourceCompatibility = 1.8
}
// run the build with ./gradlew clean build generateMergedReport
task generateMergedReport(type: JacocoReport) {
dependsOn = subprojects.test
additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
classDirectories.setFrom files(subprojects.sourceSets.main.output)
executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')
println executionData;
reports {
xml.enabled true
xml.destination file("../coverage-reports/coverage.xml")
}
}
wrapper {
gradleVersion = '6.0'
}
And changing the Jenkins to build generateMergedReport:
cd server && ./gradlew build generateMergedReport
The SonarQube properties where changed to:
sonar.projectKey=eclipse-plugin-vogella
sonar.sources=server/com.vogella.prioritizer.server/src/main,server/com.vogella.prioritizer.server.bugzilla/src/main,server/com.vogella.prioritizer.server.issue.api/src/main
sonar.java.binaries=com.vogella.prioritizer.server/build/classes/java/main,com.vogella.prioritizer.server.bugzilla/build/classes/java/main,com.vogella.prioritizer.server.issue.api/build/classes/java/main
Unfortunately SonarQube still doesnt find the coverage.xml file.
INFO: parsing [/home/jenkins/workspace/issue-prioritizer/coverage-reports/coverage.xml]
ERROR: Reports path not found or is not a directory: /home/jenkins/workspace/issue-prioritizer/coverage-reports/coverage.xml
Does someone have an idea of what is missing?

Related

Running jmeter tests in jenkinsfile

I'm trying to run some jmeter tests in my jenkinsfile pipeline, but I'm getting some errors.
A problem was found with the configuration of task ':jmReport' (type 'TaskJMReports').
- In plugin 'net.foragerr.jmeter' type 'net.foragerr.jmeter.gradle.plugins.TaskJMReports' property 'reportDir' is missing an input or output annotation.
This is how I'm trying to run it.
build.gradle
plugins {
id "net.foragerr.jmeter" version "1.0.5-2.13"
}
apply plugin: 'net.foragerr.jmeter'
jmeter {
jmTestFiles = [file("src/test/jmeter/TestPlan.jmx")]
enableExtendedReports = true //produce Graphical and CSV reports
}
Pipeline
stage('Run Non-Functional tests - Windows'){
when { expression { env.OS == 'BAT' }}
steps {
dir('') {
bat 'gradlew.bat jmReport'
}
}
}
I'm also tried this away.
build.gradle
plugins {
id "de.qualersoft.jmeter" version "2.1.0"
}
tasks.register('jmRun',JMeterRunTask) {
jmxFile.set("TestPlan.jmx")
}
tasks.register("jmReport",JMeterReportTask) {
jmxFile.set("TestPlan.jmx")
dependsOn("jmRun")
deleteResults=true
}
The stage is the same and I'm getting this error.
> Could not get unknown property 'JMeterRunTask' for root project 'flowcrmtutorial' of type org.gradle.api.Project.
Why am I getting this errors?
For the latter, you are missing the import as stated in the project's README:
https://github.com/qualersoft/jmeter-gradle-plugin#user-content-running-a-jmeter-test
Import task package.
import de.qualersoft.jmeter.gradleplugin.task.*
plugins {
id "de.qualersoft.jmeter" version "2.1.0"
}

How to publish a WAR file to maven (Nexus) repository with Jenkins via Gradle task

I'm struggling with deploying the war file to Nexus repository using Jenkinsfile via Gradle task.
The war is being created successfully. I have also no problem with deploying JARs (since there are examples everywhere how to do it).
So I have this publishing section in my build.grade:
publishing {
repositories {
maven {
URI releasesUrl = new URI("${UploadURL}/repository/releases")
URI snapshotsUrl = new URI("${UploadURL}/repository/snapshots")
afterEvaluate {
url version.endsWith("SNAPSHOT") ? snapshotsUrl : releasesUrl
}
credentials {
username "${user}"
password "${password}"
}
}
}
publications {
mavenWeb(MavenPublication) {
from components.web
artifact war.archivePath
}
}
}
With pluggins:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
The URL for repositories is also specified in the build script correctly (test publish with the jar works just fine)
And the Jenkinsfile:
stage ('Publish war') {
steps {
sh "sh gradlew publish"
}
}
Currently I'm getting this error from jenkins build:
Task :publishMavenWebPublicationToMavenRepository FAILED
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':publishMavenWebPublicationToMavenRepository'.
Failed to publish publication 'mavenWeb' to repository 'maven'
Invalid publication 'mavenWeb': multiple artifacts with the identical extension and classifier ('war', 'null').
I'm quite sure that the problem is within "publications" part of Gradle task.
For publishing the Jars I have been using it like this:
[...]
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar
}
}
[...]
task sourceJar(type: Jar) {
classifier 'sources'
from sourceSets.main.java
}
I do not know how to configure from, artifact and classifier for this task. I do not even know if all of these parameters should be configured... Could anyone help me with that?
It turned out, that the origin of the problem was this section:
afterEvaluate {
url version.endsWith("SNAPSHOT") ? snapshotsUrl : releasesUrl
}
This feature works with Gradle 5.X version however, I was using Gradle 4.8. That lead to null instead of propper url value...
Unfortunately, it took a while since the exception message does not suggest where the problem was.

Grails gradle: How to set System Property

May I know why I'm unable to set the System Property with the systemProperty method when using the grails-gradle-plugin?
My build.gradle as follows:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.grails:grails-gradle-plugin:2.0.0"
}
}
version "0.1"
group "example"
apply plugin: "grails"
repositories {
grails.central() //creates a maven repo for the Grails Central repository (Core libraries and plugins)
}
grails {
grailsVersion = '2.3.5'
groovyVersion = '2.1.9'
springLoadedVersion '1.1.3'
}
dependencies {
bootstrap "org.grails.plugins:tomcat:7.0.50" // No container is deployed by default, so add this
compile 'org.grails.plugins:resources:1.2' // Just an example of adding a Grails plugin
}
test {
println "I'm in the test"
//Could not find method systemProperty() for arguments [geb.env, sauce] on root project
systemProperty 'geb.env', 'sauce'//Fails
}
In the test task, I get the following error when i run $gradle grails-test:
Could not find method systemProperty() for arguments [geb.env, sauce] on root project..."
Is this a problem with the grails-gradle plugin since other plugins like "java" allows me to use setProperty? Thanks.
The error message is correct: there's no systemProperty() method.
As Joshua Moore comments, this should work:
test {
println "I'm in the test"
System.setProperty 'geb.env', 'sauce'
}

Jenkins build for project with provided dependencies

While I am building Gradle based project via Jenkins I'm getting compilation errors. It occurs because a have several jars in build.gradle file with scope 'provided'. I need this to do not include them into generated jar-file. How can I specify path or smth else to let project build on integration server?
Thanx in advance.
Listing of build file provided
configurations {
provided
}
sourceSets {
main {
java { srcDir 'src/main/java' }
resources { srcDir 'src/main/resources' }
compileClasspath += configurations.provided
}
}
dependencies {
provided 'somelib1'
provided 'somelib2'
provided 'somelib3'
}

How to upload artifact to network drive using gradle?

I am reading this:
http://www.gradle.org/docs/current/userguide/artifact_management.html
to understand how to publish/upload my artifact to a network drive/fileshare which is a requirement (we have a maven repo up and running but some artifacts needs to be dumped on a fileshare). The examples I have found are more focused on deploying to repositories, maven, ivy, etc.
I have a simple eclipse java project that I build using gradle 1.2 with the following build.gradle file:
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src'
}
}
test {
java {
srcDir 'test'
}
}
}
repositories {
flatDir {
name "fileRepo"
dirs "file://internal.newtwork.drive/folder/test"
}
}
uploadArchives {
repositories {
add project.repositories.fileRepo
}
}
Where in the gradle docs can I read about how to copy resources to a remote fileshare?
I have tried to update the protocol and the dir attribute based on the below answers but I get this error:
What went wrong:
Execution failed for task ':uploadArchives'.
Could not publish configuration ':archives'.
java.io.FileNotFoundException: /internal.newtwork.drive/folder/test/sample-gradle-java-unspecified.jar (No such file or directory)
The destination is correct so does the flatDir repo not support networkdrives?
You should define the following parameters:
archivesBaseName = 'yourappname'
group = 'your.app.package'
version = '1.0.0'
Your URL doesn't mention a scheme (http:, file:, etc.). I don't know if you can get away with using a file: URL, or whether you need to us a different syntax to specify a directory rather than an HTTP URL, but either way, you'll need to correctly form the URI for the Windows UNC path.
See this question for more details.
It looks like you're crossing your wires. The url would only be part of that ivy repository declaration which you're apparently not using. The filesystem repository would be handled by the flatDir block which is then referenced by the add project.repositories.fileRepo statement. I'd suggest trying the full path in the flatDir dir variable, otherwise the path of least resistance may just be to throw together a simple manual file copy (or other transfer) task which is then added on to the main deploy task you're using.
//Try this,
apply plugin: 'java'
apply plugin: 'maven'
repositories {
maven {
url "$archivaUrl"`enter code here`
credentials {
username = "$userName"
password = "$passWord"
}
}
}
// Dependencies
dependencies {
// specify the lib files at compile and run time
compile fileTree(dir: 'lib', include: ['**/*.jar','*.jar'])
runtime fileTree(dir: 'lib', include: ['**/*.jar','*.jar'])
}
// source path
sourceSets {
main {
java {
srcDirs 'src'
}
}
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "$archivaUrl") {
authentication(userName: "$userName", password: "$passWord")
}
pom.version = "1.0-SNAPSHOT"
pom.artifactId = "fd-common"
pom.groupId = "com.somename.common"
}
}
}

Resources