diff options
author | Steve Marion <steve.marion@sonarsource.com> | 2025-02-28 16:38:04 +0100 |
---|---|---|
committer | Matteo Mara <matteo.mara@sonarsource.com> | 2025-03-17 22:23:55 +0100 |
commit | a087eb237d62b3280f1fc5d3540b1b57afccd4bd (patch) | |
tree | e7cbc5dfa9581be63b0cdb9d8e1a2657a0f187f5 /sonar-plugin-api-impl/src | |
parent | e496fb60dd1fbf1fd90b6ca08b9499ba8035a5c0 (diff) | |
download | sonarqube-a087eb237d62b3280f1fc5d3540b1b57afccd4bd.tar.gz sonarqube-a087eb237d62b3280f1fc5d3540b1b57afccd4bd.zip |
SONAR-24521 Implements sonar plugin API addAnalysisData method in the scanner-engine.
Add Xoo plugin sensor that utilizes the analysisData method.
Diffstat (limited to 'sonar-plugin-api-impl/src')
3 files changed, 79 insertions, 6 deletions
diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java index b62b77831b4..09157ef9420 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java @@ -19,12 +19,17 @@ */ package org.sonar.api.batch.sensor.internal; +import static org.sonar.api.utils.Preconditions.checkArgument; + +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.sonar.api.batch.sensor.code.NewSignificantCode; import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; import org.sonar.api.batch.sensor.coverage.NewCoverage; @@ -41,8 +46,6 @@ import org.sonar.api.batch.sensor.rule.AdHocRule; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; -import static org.sonar.api.utils.Preconditions.checkArgument; - class InMemorySensorStorage implements SensorStorage { Map<String, Map<String, Measure>> measuresByComponentAndMetric = new HashMap<>(); @@ -58,6 +61,7 @@ class InMemorySensorStorage implements SensorStorage { Map<String, DefaultSymbolTable> symbolsPerComponent = new HashMap<>(); Map<String, String> contextProperties = new HashMap<>(); Map<String, String> telemetryEntries = new HashMap<>(); + Map<String, AnalysisData> analysisDataEntries = new HashMap<>(); Map<String, DefaultSignificantCode> significantCodePerComponent = new HashMap<>(); @Override @@ -157,4 +161,21 @@ class InMemorySensorStorage implements SensorStorage { } significantCodePerComponent.put(fileKey, significantCode); } + + public void storeAnalysisData(String key, String mimeType, InputStream data) { + checkArgument(!StringUtils.isBlank(key), "Key must not be null"); + checkArgument(!StringUtils.isBlank(mimeType), "MimeType must not be null"); + checkArgument(data != null, "Data must not be null"); + if (analysisDataEntries.containsKey(key)) { + throw new UnsupportedOperationException("Trying to save analysis data twice for the same key is not supported: " + key); + } + try (data) { + byte[] bytes = data.readAllBytes(); + analysisDataEntries.put(key, new AnalysisData(key, mimeType, bytes)); + } catch (IOException e) { + throw new IllegalStateException("Failed to read data from InputStream", e); + } + } + + record AnalysisData(String key, String mimeType, byte[] data) { } } diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index 02c5fa5191f..b4fd5512335 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -19,7 +19,10 @@ */ package org.sonar.api.batch.sensor.internal; +import static java.util.Collections.unmodifiableMap; + import java.io.File; +import java.io.InputStream; import java.io.Serializable; import java.nio.charset.Charset; import java.nio.file.Path; @@ -87,8 +90,6 @@ import org.sonar.api.scanner.fs.InputProject; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; -import static java.util.Collections.unmodifiableMap; - /** * Utility class to help testing {@link Sensor}. This is not an API and method signature may evolve. * <p> @@ -447,6 +448,12 @@ public class SensorContextTester implements SensorContext { sensorStorage.storeTelemetry(key, value); } + @Override + public void addAnalysisData(String key, String mimeType, InputStream data) { + //No Need to check the source of the plugin in the tester + sensorStorage.storeAnalysisData(key,mimeType, data); + } + public void setCacheEnabled(boolean enabled) { this.cacheEnabled = enabled; } diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java index d4ca8ee5865..85b073639b6 100644 --- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java @@ -19,12 +19,16 @@ */ package org.sonar.api.batch.sensor.internal; -import org.junit.Test; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.data.MapEntry.entry; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.Test; + public class InMemorySensorStorageTest { InMemorySensorStorage underTest = new InMemorySensorStorage(); @@ -50,4 +54,45 @@ public class InMemorySensorStorageTest { .isInstanceOf(IllegalArgumentException.class) .hasMessage("Value of context property must not be null"); } + + @Test + public void test_storeAnalysisData() { + // Given + String key = "analysisKey"; + String mimeType = "mimeType"; + String dataString = "analysisData"; + ByteArrayInputStream dataStream = new ByteArrayInputStream(dataString.getBytes(StandardCharsets.UTF_8)); + + // When + underTest.storeAnalysisData(key, mimeType, dataStream); + + // Then + assertThat(underTest.analysisDataEntries).containsKey(key); + assertThat(new String(underTest.analysisDataEntries.get(key).data(), StandardCharsets.UTF_8)).isEqualTo(dataString); + } + + @Test + public void storeAnalysisData_throws_UOE_if_operation_not_supported() { + underTest.storeAnalysisData("unsupportedKey", "mimeType", new ByteArrayInputStream("dummyData".getBytes(StandardCharsets.UTF_8))); + ByteArrayInputStream dataStream = new ByteArrayInputStream("newData".getBytes(StandardCharsets.UTF_8)); + + assertThatThrownBy(() -> underTest.storeAnalysisData("unsupportedKey", "mimeType", dataStream)) + .isInstanceOf(UnsupportedOperationException.class); + } + + @Test + public void storeAnalysisData_throws_IOE_on_data_handling_error() { + InputStream faultyStream = new InputStream() { + @Override + public int read() throws IOException { + throw new IOException("Simulated IO Exception"); + } + }; + + assertThatThrownBy(() -> underTest.storeAnalysisData("validKey", "mimeType", faultyStream)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Failed to read data from InputStream"); + } + + } |