diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-08-06 11:28:40 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-08-06 12:52:33 +0200 |
commit | 8e6415a4c7444f7c6e03b10e8fa8eb535cc7e505 (patch) | |
tree | aacc9e22f21f755e98a9ac2ad945136ee36f0419 /sonar-plugin-api/src | |
parent | e55369090f3be4f1e4baa791b05c3f5cf1cef6e1 (diff) | |
download | sonarqube-8e6415a4c7444f7c6e03b10e8fa8eb535cc7e505.tar.gz sonarqube-8e6415a4c7444f7c6e03b10e8fa8eb535cc7e505.zip |
SONAR-7654 API to propagate props from scanner to CE
Diffstat (limited to 'sonar-plugin-api/src')
9 files changed, 188 insertions, 2 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index e11f6da0153..998ca07919a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -144,4 +144,13 @@ public interface SensorContext { */ NewAnalysisError newAnalysisError(); + /** + * Add a property to the scanner context. This context is available + * in Compute Engine when processing the report. + * + * @see org.sonar.api.ce.posttask.PostProjectAnalysisTask.ProjectAnalysis#getScannerContext() + * @since 6.1 + */ + void addContextProperty(String key, String value); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java index 5a79149cbc3..6cc91e10760 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java @@ -35,6 +35,8 @@ import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.utils.SonarException; +import static com.google.common.base.Preconditions.checkArgument; + class InMemorySensorStorage implements SensorStorage { Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create(); @@ -46,6 +48,7 @@ class InMemorySensorStorage implements SensorStorage { Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>(); Table<String, CoverageType, DefaultCoverage> coverageByComponentAndType = HashBasedTable.create(); Map<String, DefaultSymbolTable> symbolsPerComponent = new HashMap<>(); + Map<String, String> contextProperties = new HashMap<>(); @Override public void store(Measure measure) { @@ -108,4 +111,10 @@ class InMemorySensorStorage implements SensorStorage { allAnalysisErrors.add(analysisError); } + @Override + public void storeProperty(String key, String value) { + checkArgument(key != null, "Key of context property must not be null"); + checkArgument(value != null, "Value of context property must not be null"); + contextProperties.put(key, value); + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index ba9020829a4..f3971eb7fb7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -19,6 +19,7 @@ */ package org.sonar.api.batch.sensor.internal; +import com.google.common.collect.ImmutableMap; import java.io.File; import java.io.Serializable; import java.nio.file.Path; @@ -310,4 +311,16 @@ public class SensorContextTester implements SensorContext { return null; } + @Override + public void addContextProperty(String key, String value) { + sensorStorage.storeProperty(key, value); + } + + /** + * @return an immutable map of the context properties defined with {@link SensorContext#addContextProperty(String, String)}. + * @since 6.1 + */ + public Map<String, String> getContextProperties() { + return ImmutableMap.copyOf(sensorStorage.contextProperties); + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java index 9f61766afec..cc8af33dbc5 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java @@ -55,9 +55,17 @@ public interface SensorStorage { * @since 5.6 */ void store(DefaultSymbolTable symbolTable); - + /** * @since 6.0 */ void store(AnalysisError analysisError); + + /** + * Value is overridden if the key was already stored. + * @throws IllegalArgumentException if key is null + * @throws IllegalArgumentException if value is null + * @since 6.1 + */ + void storeProperty(String key, String value); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTask.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTask.java index b33da79e6f1..b4ed6ea8963 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTask.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTask.java @@ -74,5 +74,13 @@ public interface PostProjectAnalysisTask { * */ Date getDate(); + + /** + * Context as defined by scanner through {@link org.sonar.api.batch.sensor.SensorContext#addContextProperty(String, String)}. + * It does not contain the settings used by scanner. + * + * @since 6.1 + */ + ScannerContext getScannerContext(); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java index 39ae7776f98..394ce62b7a4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java @@ -22,7 +22,9 @@ package org.sonar.api.ce.posttask; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -93,6 +95,7 @@ public class PostProjectAnalysisTaskTester { private static final String PROJECT_CAN_NOT_BE_NULL = "project cannot be null"; private static final String CE_TASK_CAN_NOT_BE_NULL = "ceTask cannot be null"; private static final String STATUS_CAN_NOT_BE_NULL = "status cannot be null"; + private static final String SCANNER_CONTEXT_CAN_NOT_BE_NULL = "scannerContext cannot be null"; private final PostProjectAnalysisTask underTest; @CheckForNull @@ -103,6 +106,7 @@ public class PostProjectAnalysisTaskTester { private Date date; @CheckForNull private QualityGate qualityGate; + private ScannerContext scannerContext; private PostProjectAnalysisTaskTester(PostProjectAnalysisTask underTest) { this.underTest = requireNonNull(underTest, "PostProjectAnalysisTask instance cannot be null"); @@ -128,6 +132,10 @@ public class PostProjectAnalysisTaskTester { return new ConditionBuilder(); } + public static ScannerContextBuilder newScannerContextBuilder() { + return new ScannerContextBuilder(); + } + public PostProjectAnalysisTaskTester withCeTask(CeTask ceTask) { this.ceTask = requireNonNull(ceTask, CE_TASK_CAN_NOT_BE_NULL); return this; @@ -138,6 +146,14 @@ public class PostProjectAnalysisTaskTester { return this; } + /** + * @since 6.1 + */ + public PostProjectAnalysisTaskTester withScannerContext(ScannerContext scannerContext) { + this.scannerContext = requireNonNull(scannerContext, SCANNER_CONTEXT_CAN_NOT_BE_NULL); + return this; + } + public PostProjectAnalysisTaskTester at(Date date) { this.date = requireNonNull(date, DATE_CAN_NOT_BE_NULL); return this; @@ -156,6 +172,11 @@ public class PostProjectAnalysisTaskTester { this.underTest.finished( new PostProjectAnalysisTask.ProjectAnalysis() { @Override + public ScannerContext getScannerContext() { + return scannerContext; + } + + @Override public CeTask getCeTask() { return ceTask; } @@ -525,4 +546,21 @@ public class PostProjectAnalysisTaskTester { checkState(errorThreshold != null || warningThreshold != null, "At least one of errorThreshold and warningThreshold must be non null"); } } + + public static final class ScannerContextBuilder { + private final Map<String, String> properties = new HashMap<>(); + + private ScannerContextBuilder() { + // prevents instantiation outside PostProjectAnalysisTaskTester + } + + public ScannerContext build() { + return new ScannerContext() { + @Override + public Map<String, String> getProperties() { + return properties; + } + }; + } + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/ScannerContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/ScannerContext.java new file mode 100644 index 00000000000..6a714bdfd36 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/ScannerContext.java @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.ce.posttask; + +import java.util.Map; + +/** + * @since 6.1 + */ +public interface ScannerContext { + + /** + * @return immutable map of properties sent by scanner + */ + Map<String, String> getProperties(); +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java new file mode 100644 index 00000000000..22bfa504ee1 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.batch.sensor.internal; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.MapEntry.entry; + +public class InMemorySensorStorageTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + InMemorySensorStorage underTest = new InMemorySensorStorage(); + + @Test + public void test_storeProperty() { + assertThat(underTest.contextProperties).isEmpty(); + + underTest.storeProperty("foo", "bar"); + assertThat(underTest.contextProperties).containsOnly(entry("foo", "bar")); + } + + @Test + public void storeProperty_throws_IAE_if_key_is_null() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Key of context property must not be null"); + + underTest.storeProperty(null, "bar"); + } + + @Test + public void storeProperty_throws_IAE_if_value_is_null() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Value of context property must not be null"); + + underTest.storeProperty("foo", null); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java index a4dad0ea510..79f96f23e55 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java @@ -48,6 +48,7 @@ import org.sonar.api.utils.SonarException; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.assertj.core.data.MapEntry.entry; public class SensorContextTesterTest { @@ -332,9 +333,17 @@ public class SensorContextTesterTest { } @Test - public void testCacnellation() { + public void testCancellation() { assertThat(tester.isCancelled()).isFalse(); tester.setCancelled(true); assertThat(tester.isCancelled()).isTrue(); } + + @Test + public void testContextProperties() { + assertThat(tester.getContextProperties()).isEmpty(); + + tester.addContextProperty("foo", "bar"); + assertThat(tester.getContextProperties()).containsOnly(entry("foo", "bar")); + } } |