Code coverage reports (Cobertura / JaCoCo) are not being pushed to sonar

Hello all,

I have a groovy project which I am trying to upload code coverage generated by Cobertura (I’ve also tried jacoco with no luck) to Sonar for.

I’m using gradle as my build framework and I’ve been stumbling over a variety of issues, but I finally have a stable build showing up in Sonar with all desired metrics BUT code coverage.

The Cobertura / Jacoco coverage files are definitely being created in the build directory of the project, but for some reason they never make it to sonar.

I’m using an ant task to generate the code, but anyways here are the relevant portions of my build.gradle file -

apply plugin: "groovy"
apply plugin: "eclipse"
apply plugin: "maven"
apply plugin: "application"
apply plugin: "sonar"
  sourceSets {
 main {
  groovy { srcDir 'src/main/groovy' }
   resources { srcDir 'src/main/resources' }
 }
 test {
   groovy {
   srcDirs = ['src/test/groovy', 'src/integration-test/groovy']
    resources {
    srcDir = 'src/test/resources'
   }
   }
 }
}
  def cobSerFile="${project.buildDir}/cobertura.ser"
def srcOriginal="${sourceSets.main.output.classesDir}"
def srcCopy="${srcOriginal}-copy"
  dependencies {
    ...
testRuntime 'net.sourceforge.cobertura:cobertura:1.9.3'
...
}
  ...
  test.doFirst
{
 ant {
   // delete data file for cobertura, otherwise coverage would be added
  delete(file:cobSerFile, failonerror:false)
   // delete copy of original classes
  delete(dir: srcCopy, failonerror:false)
   // import cobertura task, so it is available in the script
  taskdef(resource:'tasks.properties', classpath: configurations.testRuntime.asPath)
   // create copy (backup) of original class files
  copy(todir: srcCopy) {
   fileset(dir: srcOriginal)
   }
  // instrument the relevant classes in-place
  'cobertura-instrument'(datafile:cobSerFile) {
    fileset(dir: srcOriginal,
       includes:"**/*.class",
       excludes:"**/*Test.class")
   }
 }
}
   test {
 systemProperties["net.sourceforge.cobertura.datafile"] = cobSerFile
}
   test.doLast {
 if (new File(srcCopy).exists()) {
  // replace instrumented classes with backup copy again
   ant {
   delete(file: srcOriginal)
   move(file: srcCopy,
       tofile: srcOriginal)
  }
  // create cobertura reports
   ant.'cobertura-report'(destdir:"${project.buildDir}/reports/cobertura/coverage",
    format:'xml', srcdir:sourceSets.main, datafile:cobSerFile)
   ant.'cobertura-report'(destdir:"${project.buildDir.path}/reports/coverage",
   format:'html', srcdir:sourceSets.main, datafile:cobSerFile)
     }
}
  sonar {
 server {
   url = "http://javawebdev-v1:9000"
 }
  database {
  url = "jdbc:mysql://javawebdev-v1:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true"
   driverClassName = "com.mysql.jdbc.Driver"
  username = "sonar"
   password = "sonar"
 }
 project {
   coberturaReportPath = new File(buildDir, "/reports/cobertura/coverage/coverage.xml")
  language = "grvy"
   dynamicAnalysis="reuseReports"
 }
}

Does anyone have any idea what I’m doing wrong here?

Thanks!

-Zachary Carter

Maybe the info (’–info’) or debug (’–debug’) log shows something.

I gave it a shot, but didn’t see anything or even the line ‘Parsing {…xml}’ which is supposed to be indicative of it picking up a cobertura report to parse.

Basically at this point I’m going to fork the sonar plugin, add some more debug information to try to figure out why the report isn’t being parsed, and then I’ll install my own custom verison of the plugin once I figure out why. I’ll reply back here when I have more information later today.

I came up with a fix but it wasn’t easy or pretty.

The groovy sonar plugin is tightly coupled with maven, so if you are using gradle without maven you’re never going to be able to get code coverage to work.

What I had to do was fork the Groovy sonar plugin, and make some modifications to the CoberturaSensor.java file (mainly remove any mention of maven, alter the constructor and any references to the class, etc…)

Once I did that, like magic my code coverage started showing up in Sonar.

It was pretty painful to figure out and it doesn’t sound like many others are having this problem so I won’t go too in depth into the solution, but if anyone needs more info let me know and I’ll be happy to provide it.

Thanks,

-Zach

Is this something you could push back to Sonar?

Yeah I definitely plan to, I’m constantly frustrated with their lack of gradle support. I already created a comment on their user mailling list since I figured it was a sonar plugin issue. I’ll create a comment on the developer list tonight and see if I can’t get a JIRA created there as well.

Here’s the newly created Jira - http://jira.codehaus.org/browse/SONARPLUGINS-2286

I’ll keep on top of it to see if they want my help in implementing a patch but I’m sure they can handle it themselves it the project is still being worked on actively. If not I’ll have to see what other recourse is available.

Hi,

i have cobertura working with sonar by using this:

apply from: "cobertura.gradle"
sonar {
    server { url = "http://sonarserver.de" }
    database {
        url = jdbc:mysql://databaseserver.de:3306/sonar?useUnicode=true&characterEncoding=utf8
        driverClassName = "com.mysql.jdbc.Driver"
        username = user
        password = secret
    }
}
  subprojects { Project p ->
    p.tasks.withType(Compile) { options.encoding = "UTF-8" }
    p.tasks.withType(FindBugs) { ignoreFailures = true }
    sonar {
        project {
            coberturaReportPath = file("${p.reporting.baseDir}/cobertura/coverage.xml")
        }
    }
}

Content of cobertura.gradle can be found here:

https://github.com/matlockx/simple-gradle-java.g8/blob/master/src/main/g8/cobertura.gradle

NOTE: this is from a root gradle file in a multiproject

Thanks! Added my vote.

Zach, I’m running into the same issue. Do you happen to have your forked code handy?

Hi Cedric,

Sorry it took me so long to reply.

I don’t have my forked code handy. One of my co-workers took over our gradle / sonar integration effort and I believe she found a new plugin that doesn’t have these issues.

Here’s a link to the new Gradle plugin - http://www.gradle.org/docs/current/userguide/sonar_runner_plugin.html

I hope this helps. If not let me know and I can try to reproduce the code I changed.

Thanks!

-Zach

Excellent and thanks for the tip. I was working with sonar runner and hitting the same issue with the cobertura reports, mostly because it appeared to be an issue with the Sonar plugin installed on the server itself. But I wound up taking your code snippet from the JIRA issue and applying it to a fork of sonar-groovy here:

https://github.com/Spantree/sonar-groovy

Seems to work from Gradle, Sonar Runner or Maven with this fork installed on the server, but I didn’t test very deeply on the Maven side so I’m not quite ready to issue a pull request back to SonarCommunity.

Good deal. If you run into any issues just let me know!

I am still having the same problem of coverage being shown as a dash. I’m using SonarQube 4.0, Sonar Runner 2.3, and Cobertura 1.9.4.1 (technically I’m using Grails to drive it all through the “code-coverage” plugin v1.2.7, which uses Cobertura). I tried building your latest snapshot for sonar-groovy; I see the “Sensor Groovy CoberturaSensor…” appear in the logs when the runner is going, I see my coverage.xml being referenced, but I don’t see coverage in Sonar web UI. :slight_smile:

I also tried the latest sonar-goovy-plugin 1.0-SNAPSHOT from: http://repository-sonarplugins.forge.cloudbees.com/snapshot/org/codehaus/sonar-plugins/sonar-groovy-plugin/1.0-SNAPSHOT/

Still no luck. I may try downgrading Sonar to 3.X and try my luck there. What versions of sonar + runner did you have working?

Btw, here’s a relevant StackOverflow link: http://stackoverflow.com/questions/20712633/sonar-runner-not-importing-cobertura-coverage-xml-report-for-groovy-grails-proje