SonarQube coverage doesn't work for Ruby SimpleCov v0.21.2

I’m using latest sonarsource/sonar-scanner-cli Docker image.

I’m trying to display tests coverage in SonarQube’s dashboard.

I tried using coverage/coverage.json file produced by SimpleCov v0.21.2 JSONFormatter. I’m getting the following error:

INFO: Sensor SimpleCov Sensor for Ruby coverage [ruby]
ERROR: Cannot read coverage report file, expecting standard SimpleCov resultset JSON format: 'coverage/coverage.json'
java.lang.NullPointerException: null
	at org.sonarsource.ruby.plugin.SimpleCovSensor.mergeFileCoverages(SimpleCovSensor.java:119)
	at org.sonarsource.ruby.plugin.SimpleCovSensor.safeReadCoverageReport(SimpleCovSensor.java:83)
	at org.sonarsource.ruby.plugin.SimpleCovSensor.lambda$execute$0(SimpleCovSensor.java:72)
	at java.base/java.util.HashMap.forEach(Unknown Source)
	at org.sonarsource.ruby.plugin.SimpleCovSensor.execute(SimpleCovSensor.java:72)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
	at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:393)
	at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:389)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:358)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:144)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at com.sun.proxy.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
	at org.sonarsource.scanner.cli.Main.main(Main.java:61)

INFO: Sensor SimpleCov Sensor for Ruby coverage [ruby] (done) | time=32ms

The coverage/coverage.json file looks like this:

{
  "meta": {
    "simplecov_version": "0.21.2"
  },
  "coverage": {
    "/app/app/api/api_app.rb": {
      "lines": [
        null,
        null,
        1,
        1,
        null,
        null,
        1,
        null,
        1,
        null,
        1,
        null,
        null,
        null,
        null,
        1,
        1,
        null,
        1,
        null,
        0,
        0,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null
      ]
    },

I’ve found a few topics and a ticket saying that SimpleCov >= v0.20 + JSONFormatter should work, but that’s not true for me. Am I missing something?

Hi there.

What version of SonarQube are you using?

Hi! The version is 8.6.0.39681 if I’m looking in the right place.

Any thoughts?

Hello, has this issue been resolved?

Hi @Colin do you have any insight into this issue?

I have the same issue here.

SonarQube 9.2.4.50792
Ruby 2.7.3
Rails 6.0

Following the documentation…

I used the simplecov_json_formatter from simplecov >= v0.20 (Doc) and I get this error.

ERROR: Cannot read coverage report file, expecting standard SimpleCov JSON formatter output: 'coverage/.resultset.json'
java.lang.ClassCastException: class org.sonarsource.analyzer.commons.internal.json.simple.JSONObject cannot be cast to class org.sonarsource.analyzer.commons.internal.json.simple.JSONArray (org.sonarsource.analyzer.commons.internal.json.simple.JSONObject and org.sonarsource.analyzer.commons.internal.json.simple.JSONArray are in unnamed module of loader org.sonar.classloader.ClassRealm @5fcacc0)

I tried simplecov-json and it didn’t work either

After many attempts, the solution was to use the simplecov in version < v.0.18 because the return of .resultset.json is

{
  "RSpec": {
    "coverage": {
      "app/model/test.rb": [
        null,
        null,
        1,
        1,
        1,
        1,
        null,
        null,
        1,
        15,
        null,
        15,
        null,
        null,
        1,
        15,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null
      ]
    },
    "timestamp": 1642789609
  }
}

Sonar Scanner Code

        sonar-scanner \
        -D sonar.host.url=$HOST_URL \
        -D sonar.login=$SONAR_LOGIN \
        -D sonar.sources=. \
        -D sonar.projectBaseDir=$BASE_DIR \
        -D sonar.projectName=$PROJECT_NAME \
        -D sonar.projectKey=$PROJECT_KEY

This issue was closed. [SONARSLANG-477] [Ruby] Support simplecov 0.20 coverage format - SonarSource The problem remains.

@Colin Can you help us?

I found the solution.

Using the simplecov_json_formatter from simplecov >= v0.20

I needed to run a sonar scanner like below

        sonar-scanner \
        -D sonar.host.url=$HOST_URL \
        -D sonar.login=$SONAR_LOGIN \
        -D sonar.sources=. \
        -D sonar.ruby.coverage.reportPaths=coverage/coverage.json \
        -D sonar.projectBaseDir=$BASE_DIR \
        -D sonar.projectName=$PROJECT_NAME \
        -D sonar.projectKey=$PROJECT_KEY

@Colin Can you change de docs? Has nothing about it in the docs.

The documentation today

image

2 Likes

This worked for me, thank you :pray:

The solution given above using simplecov_json_formatter is not working for me.

SonarScanner 4.7.0.2747
SonarQube 7.7.0
Ruby 2.7.2
SimpleCov 0.21.2

INFO: Sensor SimpleCov Sensor for Ruby coverage [ruby]
ERROR: Cannot read coverage report file, expecting standard SimpleCov resultset JSON format: 'coverage/coverage.json'
java.lang.NullPointerException: null
        at org.sonarsource.ruby.plugin.SimpleCovSensor.mergeFileCoverages(SimpleCovSensor.java:113)
        at org.sonarsource.ruby.plugin.SimpleCovSensor.execute(SimpleCovSensor.java:71)
        at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:359)
        at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:354)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:317)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:128)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
        at org.sonarsource.scanner.cli.Main.main(Main.java:61)

INFO: Sensor SimpleCov Sensor for Ruby coverage [ruby] (done) | time=11ms

Hi @Marcos_Trejo,

Welcome to the community!

Your version is past EOL. You should upgrade to either the latest version or the current LTS at your earliest convenience. Your upgrade path is:

7.7 → 7.9.6 → 8.9.9 → 9.6 (last step optional)

You may find the Upgrade Guide and the LTS-to-LTS Upgrade Notes helpful. If you have questions about upgrading, feel free to open a new thread for that here.

If your error persists after upgrade, please come back to us.

 
HTH,
Ann