user3823829
user3823829

Reputation: 91

SonarQube not accepting externally generated JaCoCo report for IT coverage

My attempt at solving this has been painstaking to say the least, and I've gone through every single support document I can find online. I'll get right to it. We're running black-box tests... a lot of black-box tests... and the only way to generate code coverage from them is by passing a JaCoCo agent to the JVM the old-fashioned way.

We are not using failsafe to run these tests, rather an in-house suite. This is a multi-module maven project, which means that this JaCoCo exec file is generated in in a groupId/artifactId hierarchy:

and so on.

However, project trunks obviously don't conform to this structure. Manually generating an HTML report from an exec file like this is a little tricky (since you can only feed it a single source directory and it will expect to see a "com" folder in the root,) but it's perfectly reasonable, very possible, and has been done.

However when we trigger Sonar analysis with the arguments

-Dsonar.itReportPath=/opt/jacoco/it-report.exec -Dsonar.dynamicAnalysis=reuseReports

the Sonar JaCoCo plugin produces a disappointing:

[INFO] [21:34:28.406] Sensor JaCoCoItSensor...
[INFO] [21:34:28.406] Project coverage is set to 0% as no JaCoCo execution data has been dumped: /opt/jacoco/it-report.exec
[INFO] [21:34:28.444] No information about coverage per test.

The theories are going wild now, but I want to try here before I commit to another misadventure, as our build process has a hundred moving parts and reconfiguring it for no reason would waste many, many working hours.

The reason this is so frustrating is because almost every solution I find that deals with IT coverage in Sonar seems to follow the same blasé formula of:

  1. Attach a JaCoCo agent to the JVM
  2. Define a sonar.jacoco.itReportPath property pointing to the report
  3. Press a button
  4. Enjoy IT coverage

We're using SonarQube 3.6.1, we're going to try upgrading to 4.5 as soon as possible. That's the first step. In the meantime, anybody know what the deal is and is there any reason why Sonar would not reuse this report? Is the directory hierarchy that big of a deal? It's not hard to locate groupID folders nested in a file tree. Is this a problem that can simply be solved by upgrading to 4.5?

I'm almost out of gas here, I'd appreciate anything I can get.

Edit 1: Going to try blacklisting 3rd party jars from agent analysis. This will be a pain. I'm not sure if the JaCoCo agent -include flag automatically excludes anything out of that scope, but it might be easier to build that functionality into JaCoCo myself rather than dig through however many dozens of 3rd party groupIds there are and blacklist them all (and then have to maintain it all down the road.)

I have a good feeling that when SonarQube sees 3rd party coverage it rejects the exec file.

Edit 2: Successfully blacklisted 3rd party classes from JaCoCo analysis.

[INFO] [10:34:05.347] Sensor JaCoCoItSensor...
[INFO] [10:34:05.352] Project coverage is set to 0% as no JaCoCo execution data has been dumped: /opt/jacoco/it-report.exec
[INFO] [10:34:06.179] No information about coverage per test.

Nope.

Upvotes: 3

Views: 2862

Answers (1)

Niels Bech Nielsen
Niels Bech Nielsen

Reputation: 4859

I can't really offer a great explanation since I use maven surefire to execute jacoco, but I did manage to make it work for a multimodule project when I

  1. added the jacoco junit listener to surefire and
  2. made sure the report was written into a single location and each run would append it.

I was thinking that the second part may be useful for you (i.e. appending result to a single location)

Find below the profile I used if you need inspiration.

  <profile>
  <!-- ========================================================================= -->
  <!-- Use shared code coverage report in sonarQube -->
  <!-- This profile enables cross project coverage reports, -->
  <!-- ========================================================================= -->
  <id>sonar-jacoco-analysis</id>
  <properties>
    <!-- Sonar -->
    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
    <sonar.language>java</sonar.language>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.6.3.201306030806</version>
        <configuration>
          <destFile>${sonar.jacoco.reportPath}</destFile>
          <append>true</append>
        </configuration>
        <executions>
          <execution>
            <id>agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <!-- Minimal supported version is 2.4 -->
        <version>2.13</version>
        <configuration>
          <properties>
            <property>
              <name>listener</name>
              <value>org.sonar.java.jacoco.JUnitListener</value>
            </property>
          </properties>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.codehaus.sonar-plugins.java</groupId>
      <artifactId>sonar-jacoco-listeners</artifactId>
      <version>1.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</profile>

Upvotes: 1

Related Questions