aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/build.gradle1
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java31
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContextFactory.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java100
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java180
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java90
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java12
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureCache.java72
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureValueCoder.java56
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java273
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java47
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storage.java500
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storages.java96
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/StoragesManager.java96
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/package-info.java23
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java40
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/index/AbstractCachesTest.java76
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java18
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java49
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumTest.java37
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java60
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java4
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java104
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java112
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/measure/MeasureCacheTest.java162
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java90
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StorageTest.java251
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesManagerTest.java42
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesTest.java90
31 files changed, 241 insertions, 2487 deletions
diff --git a/sonar-scanner-engine/build.gradle b/sonar-scanner-engine/build.gradle
index 9ad0ce807ba..77c26c7466d 100644
--- a/sonar-scanner-engine/build.gradle
+++ b/sonar-scanner-engine/build.gradle
@@ -26,7 +26,6 @@ dependencies {
compile 'org.slf4j:jul-to-slf4j'
compile 'org.slf4j:log4j-over-slf4j'
compile 'org.slf4j:slf4j-api'
- compile 'org.sonarsource:sonar-persistit'
compile project(':sonar-core')
compile project(':sonar-scanner-protocol')
compile project(':sonar-ws')
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java
index 7ef71bbb221..eecbbd15e84 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java
@@ -32,15 +32,12 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.KeyValueFormat.Converter;
-import org.sonar.scanner.scan.measure.MeasureCache;
import static java.util.stream.Collectors.toMap;
public class DefaultFileLinesContext implements FileLinesContext {
private final InputFile inputFile;
private final MetricFinder metricFinder;
- private final MeasureCache measureCache;
/**
* metric key -> line -> value
@@ -48,11 +45,10 @@ public class DefaultFileLinesContext implements FileLinesContext {
private final Map<String, Map<Integer, Object>> map = new HashMap<>();
private final SensorStorage sensorStorage;
- public DefaultFileLinesContext(SensorStorage sensorStorage, InputFile inputFile, MetricFinder metricFinder, MeasureCache measureCache) {
+ public DefaultFileLinesContext(SensorStorage sensorStorage, InputFile inputFile, MetricFinder metricFinder) {
this.sensorStorage = sensorStorage;
this.inputFile = inputFile;
this.metricFinder = metricFinder;
- this.measureCache = measureCache;
}
@Override
@@ -68,13 +64,6 @@ public class DefaultFileLinesContext implements FileLinesContext {
Preconditions.checkArgument(line <= inputFile.lines(), "Line %s is out of range for file %s. File has %s lines.", line, inputFile, inputFile.lines());
}
- public Integer getIntValue(String metricKey, int line) {
- Preconditions.checkNotNull(metricKey);
- checkLineRange(line);
- Map<Integer, Object> lines = map.computeIfAbsent(metricKey, k -> loadData(k, KeyValueFormat.newIntegerConverter()));
- return (Integer) lines.get(line);
- }
-
@Override
public void setStringValue(String metricKey, int line, String value) {
Preconditions.checkNotNull(metricKey);
@@ -84,13 +73,6 @@ public class DefaultFileLinesContext implements FileLinesContext {
setValue(metricKey, line, value);
}
- public String getStringValue(String metricKey, int line) {
- Preconditions.checkNotNull(metricKey);
- checkLineRange(line);
- Map<Integer, Object> lines = map.computeIfAbsent(metricKey, k -> loadData(k, KeyValueFormat.newStringConverter()));
- return (String) lines.get(line);
- }
-
private void setValue(String metricKey, int line, Object value) {
map.computeIfAbsent(metricKey, k -> new HashMap<>())
.put(line, value);
@@ -123,20 +105,9 @@ public class DefaultFileLinesContext implements FileLinesContext {
return lines;
}
- private Map<Integer, Object> loadData(String metricKey, Converter<? extends Object> converter) {
- DefaultMeasure<?> measure = measureCache.byMetric(inputFile.key(), metricKey);
- String data = measure != null ? (String) measure.value() : null;
- if (data != null) {
- return ImmutableMap.copyOf(KeyValueFormat.parse(data, KeyValueFormat.newIntegerConverter(), converter));
- }
- // no such measure
- return ImmutableMap.of();
- }
-
/**
* Checks that measure was not saved.
*
- * @see #loadData(String, Converter)
* @see #save()
*/
private static boolean shouldSave(Map<Integer, Object> lines) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContextFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContextFactory.java
index 8ed50b88710..209f3544810 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContextFactory.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContextFactory.java
@@ -25,24 +25,21 @@ import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.measures.FileLinesContextFactory;
-import org.sonar.scanner.scan.measure.MeasureCache;
@Immutable
public class DefaultFileLinesContextFactory implements FileLinesContextFactory {
private final SensorStorage sensorStorage;
private final MetricFinder metricFinder;
- private final MeasureCache measureCache;
- public DefaultFileLinesContextFactory(SensorStorage sensorStorage, MetricFinder metricFinder, MeasureCache measureCache) {
+ public DefaultFileLinesContextFactory(SensorStorage sensorStorage, MetricFinder metricFinder) {
this.sensorStorage = sensorStorage;
this.metricFinder = metricFinder;
- this.measureCache = measureCache;
}
@Override
public FileLinesContext createFor(InputFile inputFile) {
- return new DefaultFileLinesContext(sensorStorage, inputFile, metricFinder, measureCache);
+ return new DefaultFileLinesContext(sensorStorage, inputFile, metricFinder);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
index 4857692b80c..302f263a92f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
@@ -52,7 +52,6 @@ import org.sonar.scanner.repository.MetricsRepositoryProvider;
import org.sonar.scanner.repository.settings.DefaultGlobalSettingsLoader;
import org.sonar.scanner.repository.settings.GlobalSettingsLoader;
import org.sonar.scanner.scan.ProjectScanContainer;
-import org.sonar.scanner.storage.StoragesManager;
public class GlobalContainer extends ComponentContainer {
private static final Logger LOG = Loggers.get(GlobalContainer.class);
@@ -90,7 +89,6 @@ public class GlobalContainer extends ComponentContainer {
new SonarQubeVersion(apiVersion),
SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER),
- StoragesManager.class,
new GlobalServerSettingsProvider(),
new GlobalConfigurationProvider(),
new ScannerWsClientProvider(),
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java
deleted file mode 100644
index d2bb71b1cd3..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/CoveragePublisher.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.report;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage;
-import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage.Builder;
-import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.filesystem.InputComponentStore;
-import org.sonar.scanner.scan.measure.MeasureCache;
-
-public class CoveragePublisher implements ReportPublisherStep {
-
- private final InputComponentStore componentStore;
- private final MeasureCache measureCache;
-
- public CoveragePublisher(InputComponentStore componentStore, MeasureCache measureCache) {
- this.componentStore = componentStore;
- this.measureCache = measureCache;
- }
-
- @Override
- public void publish(ScannerReportWriter writer) {
- for (final DefaultInputFile inputFile : componentStore.allFilesToPublish()) {
- Map<Integer, LineCoverage.Builder> coveragePerLine = new LinkedHashMap<>();
-
- int lineCount = inputFile.lines();
- applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, coveragePerLine,
- (value, builder) -> builder.setHits(Integer.parseInt(value) > 0));
- applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.CONDITIONS_BY_LINE_KEY, coveragePerLine,
- (value, builder) -> builder.setConditions(Integer.parseInt(value)));
- applyLineMeasure(inputFile.key(), lineCount, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, coveragePerLine,
- (value, builder) -> builder.setCoveredConditions(Integer.parseInt(value)));
-
- writer.writeComponentCoverage(inputFile.scannerId(), coveragePerLine.values().stream().map(BuildCoverage.INSTANCE).collect(Collectors.toList()));
- }
- }
-
- void applyLineMeasure(String inputFileKey, int lineCount, String metricKey, Map<Integer, LineCoverage.Builder> coveragePerLine, MeasureOperation op) {
- DefaultMeasure<?> measure = measureCache.byMetric(inputFileKey, metricKey);
- if (measure != null) {
- Map<Integer, String> lineMeasures = KeyValueFormat.parseIntString((String) measure.value());
- for (Map.Entry<Integer, String> lineMeasure : lineMeasures.entrySet()) {
- int lineIdx = lineMeasure.getKey();
- if (lineIdx <= lineCount) {
- String value = lineMeasure.getValue();
- if (StringUtils.isNotEmpty(value)) {
- LineCoverage.Builder coverageBuilder = coveragePerLine.get(lineIdx);
- if (coverageBuilder == null) {
- coverageBuilder = LineCoverage.newBuilder();
- coverageBuilder.setLine(lineIdx);
- coveragePerLine.put(lineIdx, coverageBuilder);
- }
- op.apply(value, coverageBuilder);
- }
- }
- }
- }
- }
-
- interface MeasureOperation {
- void apply(String value, LineCoverage.Builder builder);
- }
-
- private enum BuildCoverage implements Function<Builder, LineCoverage> {
- INSTANCE;
-
- @Override
- public LineCoverage apply(@Nonnull Builder input) {
- return input.build();
- }
- }
-
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
deleted file mode 100644
index 75692161a69..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.report;
-
-import com.google.common.collect.Iterables;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputFile.Type;
-import org.sonar.api.batch.fs.internal.DefaultInputComponent;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.measure.Metric;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.test.MutableTestPlan;
-import org.sonar.api.test.TestCase.Status;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.scanner.deprecated.test.TestPlanBuilder;
-import org.sonar.scanner.protocol.output.ScannerReport;
-import org.sonar.scanner.protocol.output.ScannerReport.Measure.BoolValue;
-import org.sonar.scanner.protocol.output.ScannerReport.Measure.DoubleValue;
-import org.sonar.scanner.protocol.output.ScannerReport.Measure.IntValue;
-import org.sonar.scanner.protocol.output.ScannerReport.Measure.LongValue;
-import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue;
-import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.filesystem.InputComponentStore;
-import org.sonar.scanner.scan.measure.MeasureCache;
-
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.SKIPPED_TESTS;
-import static org.sonar.api.measures.CoreMetrics.SKIPPED_TESTS_KEY;
-import static org.sonar.api.measures.CoreMetrics.TESTS;
-import static org.sonar.api.measures.CoreMetrics.TESTS_KEY;
-import static org.sonar.api.measures.CoreMetrics.TEST_ERRORS;
-import static org.sonar.api.measures.CoreMetrics.TEST_ERRORS_KEY;
-import static org.sonar.api.measures.CoreMetrics.TEST_EXECUTION_TIME;
-import static org.sonar.api.measures.CoreMetrics.TEST_EXECUTION_TIME_KEY;
-import static org.sonar.api.measures.CoreMetrics.TEST_FAILURES;
-import static org.sonar.api.measures.CoreMetrics.TEST_FAILURES_KEY;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_CONDITIONS;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_CONDITIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES_KEY;
-
-public class MeasuresPublisher implements ReportPublisherStep {
-
- private final InputComponentStore componentStore;
- private final MeasureCache measureCache;
- private final TestPlanBuilder testPlanBuilder;
-
- public MeasuresPublisher(InputComponentStore componentStore, MeasureCache measureCache, TestPlanBuilder testPlanBuilder) {
- this.componentStore = componentStore;
- this.measureCache = measureCache;
- this.testPlanBuilder = testPlanBuilder;
- }
-
- @Override
- public void publish(ScannerReportWriter writer) {
- final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
-
- for (final InputComponent c : componentStore.all()) {
- DefaultInputComponent component = (DefaultInputComponent) c;
- if (component.isFile()) {
- DefaultInputFile file = (DefaultInputFile) component;
- // Recompute all coverage measures from line data to take into account the possible merge of several reports
- updateCoverageFromLineData(file);
- // Recompute test execution measures from MutableTestPlan to take into account the possible merge of several reports
- updateTestExecutionFromTestPlan(file);
- }
-
- Iterable<DefaultMeasure<?>> scannerMeasures = measureCache.byComponentKey(component.key());
- if (scannerMeasures.iterator().hasNext()) {
- writer.writeComponentMeasures(component.scannerId(), StreamSupport.stream(scannerMeasures.spliterator(), false)
- .map(input -> {
- if (input.value() == null) {
- throw new IllegalArgumentException(
- String.format("Measure on metric '%s' and component '%s' has no value, but it's not allowed", input.metric().key(), component.key()));
- }
- builder.clear();
- builder.setMetricKey(input.metric().key());
- setValueAccordingToType(builder, input);
- return builder.build();
- }).collect(Collectors.toList()));
- }
- }
- }
-
- private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure<?> measure) {
- Serializable value = measure.value();
- Metric<?> metric = measure.metric();
- if (Boolean.class.equals(metric.valueType())) {
- builder.setBooleanValue(BoolValue.newBuilder().setValue(((Boolean) value).booleanValue()));
- } else if (Integer.class.equals(metric.valueType())) {
- builder.setIntValue(IntValue.newBuilder().setValue(((Number) value).intValue()));
- } else if (Double.class.equals(metric.valueType())) {
- builder.setDoubleValue(DoubleValue.newBuilder().setValue(((Number) value).doubleValue()));
- } else if (String.class.equals(metric.valueType())) {
- builder.setStringValue(StringValue.newBuilder().setValue((String) value));
- } else if (Long.class.equals(metric.valueType())) {
- builder.setLongValue(LongValue.newBuilder().setValue(((Number) value).longValue()));
- } else {
- throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
- }
- }
-
- private void updateTestExecutionFromTestPlan(final InputFile inputFile) {
- final MutableTestPlan testPlan = testPlanBuilder.getTestPlanByFile(inputFile);
- if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
- return;
- }
- long nonSkippedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() != Status.SKIPPED).count();
- measureCache.put(inputFile.key(), TESTS_KEY, new DefaultMeasure<Integer>().forMetric(TESTS).withValue((int) nonSkippedTests));
- long executionTime = StreamSupport.stream(testPlan.testCases().spliterator(), false).mapToLong(t -> t.durationInMs() != null ? t.durationInMs().longValue() : 0L).sum();
- measureCache.put(inputFile.key(), TEST_EXECUTION_TIME_KEY, new DefaultMeasure<Long>().forMetric(TEST_EXECUTION_TIME).withValue(executionTime));
- long errorTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.ERROR).count();
- measureCache.put(inputFile.key(), TEST_ERRORS_KEY, new DefaultMeasure<Integer>().forMetric(TEST_ERRORS).withValue((int) errorTests));
- long skippedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.SKIPPED).count();
- measureCache.put(inputFile.key(), SKIPPED_TESTS_KEY, new DefaultMeasure<Integer>().forMetric(SKIPPED_TESTS).withValue((int) skippedTests));
- long failedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.FAILURE).count();
- measureCache.put(inputFile.key(), TEST_FAILURES_KEY, new DefaultMeasure<Integer>().forMetric(TEST_FAILURES).withValue((int) failedTests));
- }
-
- private void updateCoverageFromLineData(final InputFile inputFile) {
- if (inputFile.type() != Type.MAIN) {
- return;
- }
- DefaultMeasure<String> lineHitsMeasure = (DefaultMeasure<String>) measureCache.byMetric(inputFile.key(), CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY);
- if (lineHitsMeasure != null) {
- Map<Integer, Integer> lineHits = KeyValueFormat.parseIntInt(lineHitsMeasure.value());
- measureCache.put(inputFile.key(), LINES_TO_COVER_KEY, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(lineHits.keySet().size()));
- measureCache.put(inputFile.key(), UNCOVERED_LINES_KEY,
- new DefaultMeasure<Integer>().forMetric(UNCOVERED_LINES).withValue((int) lineHits.values()
- .stream()
- .filter(hit -> hit == 0)
- .count()));
- }
- DefaultMeasure<String> conditionsMeasure = (DefaultMeasure<String>) measureCache.byMetric(inputFile.key(), CoreMetrics.CONDITIONS_BY_LINE_KEY);
- DefaultMeasure<String> coveredConditionsMeasure = (DefaultMeasure<String>) measureCache.byMetric(inputFile.key(), CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY);
- if (conditionsMeasure != null) {
- Map<Integer, Integer> conditions = KeyValueFormat.parseIntInt(conditionsMeasure.value());
- Map<Integer, Integer> coveredConditions = coveredConditionsMeasure != null ? KeyValueFormat.parseIntInt(coveredConditionsMeasure.value()) : Collections.emptyMap();
- measureCache.put(inputFile.key(), CONDITIONS_TO_COVER_KEY, new DefaultMeasure<Integer>().forMetric(CONDITIONS_TO_COVER).withValue(conditions
- .values()
- .stream()
- .mapToInt(Integer::intValue)
- .sum()));
- measureCache.put(inputFile.key(), UNCOVERED_CONDITIONS_KEY,
- new DefaultMeasure<Integer>().forMetric(UNCOVERED_CONDITIONS)
- .withValue((int) conditions.keySet()
- .stream()
- .mapToInt(line -> conditions.get(line) - coveredConditions.get(line))
- .sum()));
- }
- }
-
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java
index 2843699a626..5ed8769d2f9 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java
@@ -45,6 +45,7 @@ import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.ScannerWsClient;
+import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.scan.ScanProperties;
import org.sonar.scanner.scan.branch.BranchConfiguration;
@@ -83,6 +84,7 @@ public class ReportPublisher implements Startable {
private Path reportDir;
private ScannerReportWriter writer;
+ private ScannerReportReader reader;
public ReportPublisher(ScanProperties properties, ScannerWsClient wsClient, Server server, AnalysisContextReportPublisher contextPublisher,
InputModuleHierarchy moduleHierarchy, GlobalAnalysisMode analysisMode, TempFolder temp, ReportPublisherStep[] publishers, BranchConfiguration branchConfiguration) {
@@ -101,6 +103,7 @@ public class ReportPublisher implements Startable {
public void start() {
reportDir = moduleHierarchy.root().getWorkDir().resolve("scanner-report");
writer = new ScannerReportWriter(reportDir.toFile());
+ reader = new ScannerReportReader(reportDir.toFile());
contextPublisher.init(writer);
if (!analysisMode.isMediumTest()) {
@@ -126,6 +129,10 @@ public class ReportPublisher implements Startable {
return writer;
}
+ public ScannerReportReader getReader() {
+ return reader;
+ }
+
public void execute() {
String taskId = null;
File report = generateReportFile();
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java
new file mode 100644
index 00000000000..9c19a887d68
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info 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.scanner.report;
+
+import com.google.common.collect.Iterables;
+import java.util.Objects;
+import java.util.stream.StreamSupport;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.TestCase;
+import org.sonar.api.test.TestCase.Status;
+import org.sonar.scanner.deprecated.test.TestPlanBuilder;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
+
+import static org.sonar.api.measures.CoreMetrics.SKIPPED_TESTS;
+import static org.sonar.api.measures.CoreMetrics.TESTS;
+import static org.sonar.api.measures.CoreMetrics.TEST_ERRORS;
+import static org.sonar.api.measures.CoreMetrics.TEST_EXECUTION_TIME;
+import static org.sonar.api.measures.CoreMetrics.TEST_FAILURES;
+import static org.sonar.scanner.sensor.DefaultSensorStorage.toReportMeasure;
+
+public class TestExecutionPublisher implements ReportPublisherStep {
+
+ private final InputComponentStore componentStore;
+ private final TestPlanBuilder testPlanBuilder;
+
+ public TestExecutionPublisher(InputComponentStore componentStore, TestPlanBuilder testPlanBuilder) {
+ this.componentStore = componentStore;
+ this.testPlanBuilder = testPlanBuilder;
+ }
+
+ @Override
+ public void publish(ScannerReportWriter writer) {
+ final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
+
+ for (final InputComponent c : componentStore.all()) {
+ DefaultInputComponent component = (DefaultInputComponent) c;
+ if (component.isFile()) {
+ DefaultInputFile file = (DefaultInputFile) component;
+ // Recompute test execution measures from MutableTestPlan to take into account the possible merge of several reports
+ updateTestExecutionFromTestPlan(file, writer);
+ }
+ }
+ }
+
+ private void updateTestExecutionFromTestPlan(final InputFile inputFile, ScannerReportWriter writer) {
+ final MutableTestPlan testPlan = testPlanBuilder.getTestPlanByFile(inputFile);
+ if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
+ return;
+ }
+ long nonSkippedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() != Status.SKIPPED).count();
+ appendMeasure(inputFile, writer, new DefaultMeasure<Integer>().forMetric(TESTS).withValue((int) nonSkippedTests));
+ long executionTime = StreamSupport.stream(testPlan.testCases().spliterator(), false).map(TestCase::durationInMs).filter(Objects::nonNull).mapToLong(Long::longValue).sum();
+ appendMeasure(inputFile, writer, new DefaultMeasure<Long>().forMetric(TEST_EXECUTION_TIME).withValue(executionTime));
+ long errorTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.ERROR).count();
+ appendMeasure(inputFile, writer, new DefaultMeasure<Integer>().forMetric(TEST_ERRORS).withValue((int) errorTests));
+ long skippedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.SKIPPED).count();
+ appendMeasure(inputFile, writer, new DefaultMeasure<Integer>().forMetric(SKIPPED_TESTS).withValue((int) skippedTests));
+ long failedTests = StreamSupport.stream(testPlan.testCases().spliterator(), false).filter(t -> t.status() == Status.FAILURE).count();
+ appendMeasure(inputFile, writer, new DefaultMeasure<Integer>().forMetric(TEST_FAILURES).withValue((int) failedTests));
+ }
+
+ private void appendMeasure(InputFile inputFile, ScannerReportWriter writer, DefaultMeasure measure) {
+ writer.appendComponentMeasure(((DefaultInputComponent) inputFile).scannerId(), toReportMeasure(measure));
+ }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
index b18e5db8fae..dc242a2b4bd 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
@@ -69,11 +69,10 @@ import org.sonar.scanner.report.AnalysisWarningsPublisher;
import org.sonar.scanner.report.ChangedLinesPublisher;
import org.sonar.scanner.report.ComponentsPublisher;
import org.sonar.scanner.report.ContextPropertiesPublisher;
-import org.sonar.scanner.report.CoveragePublisher;
-import org.sonar.scanner.report.MeasuresPublisher;
import org.sonar.scanner.report.MetadataPublisher;
import org.sonar.scanner.report.ReportPublisher;
import org.sonar.scanner.report.SourcePublisher;
+import org.sonar.scanner.report.TestExecutionPublisher;
import org.sonar.scanner.repository.ContextPropertiesCache;
import org.sonar.scanner.repository.DefaultProjectRepositoriesLoader;
import org.sonar.scanner.repository.DefaultQualityProfileLoader;
@@ -107,7 +106,6 @@ import org.sonar.scanner.scan.filesystem.ProjectFileIndexer;
import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator;
import org.sonar.scanner.scan.filesystem.StatusDetection;
import org.sonar.scanner.scan.measure.DefaultMetricFinder;
-import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.scm.ScmChangedFilesProvider;
import org.sonar.scanner.scm.ScmConfiguration;
import org.sonar.scanner.scm.ScmPublisher;
@@ -116,7 +114,6 @@ import org.sonar.scanner.sensor.ProjectSensorContext;
import org.sonar.scanner.sensor.ProjectSensorExtensionDictionnary;
import org.sonar.scanner.sensor.ProjectSensorOptimizer;
import org.sonar.scanner.sensor.ProjectSensorsExecutor;
-import org.sonar.scanner.storage.Storages;
import static org.sonar.api.batch.InstantiationStrategy.PER_BATCH;
import static org.sonar.core.extension.CoreExtensionsInstaller.noExtensionFilter;
@@ -155,7 +152,6 @@ public class ProjectScanContainer extends ComponentContainer {
ProjectReactorValidator.class,
MetricProvider.class,
ProjectInfo.class,
- Storages.class,
new RulesProvider(),
new BranchConfigurationProvider(),
new ProjectBranchesProvider(),
@@ -205,9 +201,6 @@ public class ProjectScanContainer extends ComponentContainer {
Languages.class,
DefaultLanguagesRepository.class,
- // Measures
- MeasureCache.class,
-
// issue exclusions
IssueInclusionPatternInitializer.class,
IssueExclusionPatternInitializer.class,
@@ -237,8 +230,7 @@ public class ProjectScanContainer extends ComponentContainer {
ActiveRulesPublisher.class,
AnalysisWarningsPublisher.class,
ComponentsPublisher.class,
- MeasuresPublisher.class,
- CoveragePublisher.class,
+ TestExecutionPublisher.class,
SourcePublisher.class,
ChangedLinesPublisher.class,
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureCache.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureCache.java
deleted file mode 100644
index 68b30bf84f9..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureCache.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.scan.measure;
-
-import com.google.common.base.Preconditions;
-import javax.annotation.CheckForNull;
-import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.scanner.storage.Storage;
-import org.sonar.scanner.storage.Storage.Entry;
-import org.sonar.scanner.storage.Storages;
-
-/**
- * Cache of all measures. This cache is shared amongst all project modules.
- */
-public class MeasureCache {
-
- private final Storage<DefaultMeasure<?>> cache;
-
- public MeasureCache(Storages caches, MetricFinder metricFinder) {
- caches.registerValueCoder(DefaultMeasure.class, new MeasureValueCoder(metricFinder));
- cache = caches.createCache("measures");
- }
-
- public Iterable<Entry<DefaultMeasure<?>>> entries() {
- return cache.entries();
- }
-
- public Iterable<DefaultMeasure<?>> all() {
- return cache.values();
- }
-
- public Iterable<DefaultMeasure<?>> byComponentKey(String effectiveKey) {
- return cache.values(effectiveKey);
- }
-
- @CheckForNull
- public DefaultMeasure<?> byMetric(String componentKey, String metricKey) {
- return cache.get(componentKey, metricKey);
- }
-
- public MeasureCache put(String componentKey, String metricKey, DefaultMeasure<?> measure) {
- Preconditions.checkNotNull(componentKey);
- Preconditions.checkNotNull(metricKey);
- cache.put(componentKey, metricKey, measure);
- return this;
- }
-
- public boolean contains(String componentKey, String metricKey) {
- Preconditions.checkNotNull(componentKey);
- Preconditions.checkNotNull(metricKey);
- return cache.containsKey(componentKey, metricKey);
- }
-
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureValueCoder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureValueCoder.java
deleted file mode 100644
index c7d87a1d2e0..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/MeasureValueCoder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.scan.measure;
-
-import com.persistit.Value;
-import com.persistit.encoding.CoderContext;
-import com.persistit.encoding.ValueCoder;
-import java.io.Serializable;
-import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-
-class MeasureValueCoder implements ValueCoder {
-
- private final MetricFinder metricFinder;
-
- public MeasureValueCoder(MetricFinder metricFinder) {
- this.metricFinder = metricFinder;
- }
-
- @Override
- public void put(Value value, Object object, CoderContext context) {
- DefaultMeasure<?> m = (DefaultMeasure<?>) object;
- org.sonar.api.batch.measure.Metric<?> metric = m.metric();
- value.putString(metric.key());
- value.put(m.value());
- }
-
- @Override
- public Object get(Value value, Class clazz, CoderContext context) {
- String metricKey = value.getString();
- org.sonar.api.batch.measure.Metric<?> metric = metricFinder.findByKey(metricKey);
- if (metric == null) {
- throw new IllegalStateException("Unknow metric with key " + metricKey);
- }
- return new DefaultMeasure()
- .forMetric(metric)
- .withValue((Serializable) value.get());
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
index ab27aa0b0fa..42965a37d98 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
@@ -19,21 +19,20 @@
*/
package org.sonar.scanner.sensor;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
+import java.io.Serializable;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
+import java.util.SortedMap;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.measure.Metric;
@@ -51,10 +50,12 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Configuration;
+import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.metric.ScannerMetrics;
+import org.sonar.core.util.CloseableIterator;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.internal.pmd.PmdBlockChunker;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
@@ -67,52 +68,15 @@ import org.sonar.scanner.report.ReportPublisher;
import org.sonar.scanner.report.ScannerReportUtils;
import org.sonar.scanner.repository.ContextPropertiesCache;
import org.sonar.scanner.scan.branch.BranchConfiguration;
-import org.sonar.scanner.scan.measure.MeasureCache;
+import static java.lang.Math.max;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableSet;
import static java.util.stream.Collectors.toList;
-import static org.sonar.api.measures.CoreMetrics.BRANCH_COVERAGE;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_DATA_KEY;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.COVERAGE;
-import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA;
-import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
-import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_BRANCH_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_LINES_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_LINE_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_CONDITIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
-import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.LINE_COVERAGE;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_BRANCH_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_LINES_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_LINE_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_CONDITIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY_KEY;
import static org.sonar.api.measures.CoreMetrics.TEST_SUCCESS_DENSITY_KEY;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_CONDITIONS;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_CONDITIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES;
-import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES_KEY;
public class DefaultSensorStorage implements SensorStorage {
@@ -140,51 +104,9 @@ public class DefaultSensorStorage implements SensorStorage {
TEST_SUCCESS_DENSITY_KEY,
PUBLIC_DOCUMENTED_API_DENSITY_KEY)));
- private static final Set<String> COVERAGE_METRIC_KEYS = unmodifiableSet(new HashSet<>(asList(
- UNCOVERED_LINES_KEY,
- LINES_TO_COVER_KEY,
- UNCOVERED_CONDITIONS_KEY,
- CONDITIONS_TO_COVER_KEY,
- CONDITIONS_BY_LINE_KEY,
- COVERED_CONDITIONS_BY_LINE_KEY,
- COVERAGE_LINE_HITS_DATA_KEY)));
-
- private static final Set<String> COVERAGE_BY_LINE_METRIC_KEYS = unmodifiableSet(new HashSet<>(asList(
- COVERAGE_LINE_HITS_DATA_KEY,
- COVERED_CONDITIONS_BY_LINE_KEY,
- CONDITIONS_BY_LINE_KEY)));
-
- private static final Map<String, Metric> DEPRECATED_COVERAGE_METRICS_MAPPING;
-
- static {
- Map<String, Metric> map = new HashMap<>();
- map.put(IT_COVERAGE_KEY, COVERAGE);
- map.put(IT_LINE_COVERAGE_KEY, LINE_COVERAGE);
- map.put(IT_BRANCH_COVERAGE_KEY, BRANCH_COVERAGE);
- map.put(IT_UNCOVERED_LINES_KEY, UNCOVERED_LINES);
- map.put(IT_LINES_TO_COVER_KEY, LINES_TO_COVER);
- map.put(IT_UNCOVERED_CONDITIONS_KEY, UNCOVERED_CONDITIONS);
- map.put(IT_CONDITIONS_TO_COVER_KEY, CONDITIONS_TO_COVER);
- map.put(IT_CONDITIONS_BY_LINE_KEY, CONDITIONS_BY_LINE);
- map.put(IT_COVERED_CONDITIONS_BY_LINE_KEY, COVERED_CONDITIONS_BY_LINE);
- map.put(IT_COVERAGE_LINE_HITS_DATA_KEY, COVERAGE_LINE_HITS_DATA);
- map.put(OVERALL_COVERAGE_KEY, COVERAGE);
- map.put(OVERALL_LINE_COVERAGE_KEY, LINE_COVERAGE);
- map.put(OVERALL_BRANCH_COVERAGE_KEY, BRANCH_COVERAGE);
- map.put(OVERALL_UNCOVERED_LINES_KEY, UNCOVERED_LINES);
- map.put(OVERALL_LINES_TO_COVER_KEY, LINES_TO_COVER);
- map.put(OVERALL_UNCOVERED_CONDITIONS_KEY, UNCOVERED_CONDITIONS);
- map.put(OVERALL_CONDITIONS_TO_COVER_KEY, CONDITIONS_TO_COVER);
- map.put(OVERALL_CONDITIONS_BY_LINE_KEY, CONDITIONS_BY_LINE);
- map.put(OVERALL_COVERED_CONDITIONS_BY_LINE_KEY, COVERED_CONDITIONS_BY_LINE);
- map.put(OVERALL_COVERAGE_LINE_HITS_DATA_KEY, COVERAGE_LINE_HITS_DATA);
- DEPRECATED_COVERAGE_METRICS_MAPPING = Collections.unmodifiableMap(map);
- }
-
private final MetricFinder metricFinder;
private final IssuePublisher moduleIssues;
private final ReportPublisher reportPublisher;
- private final MeasureCache measureCache;
private final SonarCpdBlockIndex index;
private final ContextPropertiesCache contextPropertiesCache;
private final Configuration settings;
@@ -193,13 +115,12 @@ public class DefaultSensorStorage implements SensorStorage {
private final Set<String> alreadyLogged = new HashSet<>();
public DefaultSensorStorage(MetricFinder metricFinder, IssuePublisher moduleIssues, Configuration settings,
- ReportPublisher reportPublisher, MeasureCache measureCache, SonarCpdBlockIndex index,
- ContextPropertiesCache contextPropertiesCache, ScannerMetrics scannerMetrics, BranchConfiguration branchConfiguration) {
+ ReportPublisher reportPublisher, SonarCpdBlockIndex index,
+ ContextPropertiesCache contextPropertiesCache, ScannerMetrics scannerMetrics, BranchConfiguration branchConfiguration) {
this.metricFinder = metricFinder;
this.moduleIssues = moduleIssues;
this.settings = settings;
this.reportPublisher = reportPublisher;
- this.measureCache = measureCache;
this.index = index;
this.contextPropertiesCache = contextPropertiesCache;
this.scannerMetrics = scannerMetrics;
@@ -243,107 +164,48 @@ public class DefaultSensorStorage implements SensorStorage {
return;
}
- DefaultMeasure measureToSave;
- if (DEPRECATED_COVERAGE_METRICS_MAPPING.containsKey(metric.key())) {
- metric = DEPRECATED_COVERAGE_METRICS_MAPPING.get(metric.key());
- measureToSave = new DefaultMeasure<>()
- .forMetric(metric)
- .on(measure.inputComponent())
- .withValue(measure.value());
- } else {
- measureToSave = measure;
- }
-
if (!scannerMetrics.getMetrics().contains(metric)) {
throw new UnsupportedOperationException("Metric '" + metric.key() + "' should not be computed by a Sensor");
}
- if (COVERAGE_METRIC_KEYS.contains(metric.key())) {
- logOnce(metric.key(), "Coverage measure for metric '{}' should not be saved directly by a Sensor. Plugin should be updated to use SensorContext::newCoverage instead.",
- metric.key());
- if (!component.isFile()) {
- throw new UnsupportedOperationException("Saving coverage measure is only allowed on files. Attempt to save '" + metric.key() + "' on '" + component.key() + "'");
- }
- if (((DefaultInputFile) component).isExcludedForCoverage()) {
- return;
- }
- saveCoverageMetricInternal((InputFile) component, metric, measureToSave);
- } else {
- if (measureCache.contains(component.key(), metric.key())) {
- throw new UnsupportedOperationException("Can not add the same measure twice on " + component + ": " + measure);
- }
- measureCache.put(component.key(), metric.key(), measureToSave);
+ if (((DefaultInputComponent) component).hasMeasureFor(metric)) {
+ throw new UnsupportedOperationException("Can not add the same measure twice on " + component + ": " + measure);
}
- }
-
- private void saveCoverageMetricInternal(InputFile file, Metric<?> metric, DefaultMeasure<?> measure) {
- if (COVERAGE_BY_LINE_METRIC_KEYS.contains(metric.key())) {
- validateCoverageMeasure((String) measure.value(), file);
- DefaultMeasure<?> previousMeasure = measureCache.byMetric(file.key(), metric.key());
- if (previousMeasure != null) {
- measureCache.put(file.key(), metric.key(), new DefaultMeasure<String>()
- .forMetric((Metric<String>) metric)
- .withValue(mergeCoverageLineMetric(metric, (String) previousMeasure.value(), (String) measure.value())));
+ ((DefaultInputComponent) component).setHasMeasureFor(metric);
+ if (metric.key().equals(CoreMetrics.EXECUTABLE_LINES_DATA_KEY)) {
+ if (component.isFile()) {
+ ((DefaultInputFile) component).setExecutableLines(
+ KeyValueFormat.parseIntInt((String) measure.value()).entrySet().stream().filter(e -> e.getValue() > 0).map(Map.Entry::getKey).collect(Collectors.toSet()));
} else {
- measureCache.put(file.key(), metric.key(), measure);
+ throw new IllegalArgumentException("Executable lines can only be saved on files");
}
} else {
- // Other coverage metrics are all integer values. Just erase value, it will be recomputed at the end anyway
- measureCache.put(file.key(), metric.key(), measure);
+ reportPublisher.getWriter().appendComponentMeasure(((DefaultInputComponent) component).scannerId(), toReportMeasure(measure));
}
}
- /**
- * Merge the two line coverage data measures. For lines hits use the sum, and for conditions
- * keep max value in case they both contains a value for the same line.
- */
- static String mergeCoverageLineMetric(Metric<?> metric, String value1, String value2) {
- Map<Integer, Integer> data1 = KeyValueFormat.parseIntInt(value1);
- Map<Integer, Integer> data2 = KeyValueFormat.parseIntInt(value2);
- if (metric.key().equals(COVERAGE_LINE_HITS_DATA_KEY)) {
- return KeyValueFormat.format(Stream.of(data1, data2)
- .map(Map::entrySet)
- .flatMap(Collection::stream)
- .collect(
- Collectors.toMap(
- Map.Entry::getKey,
- Map.Entry::getValue,
- Integer::sum,
- TreeMap::new)));
- } else {
- return KeyValueFormat.format(Stream.of(data1, data2)
- .map(Map::entrySet)
- .flatMap(Collection::stream)
- .collect(
- Collectors.toMap(
- Map.Entry::getKey,
- Map.Entry::getValue,
- Integer::max,
- TreeMap::new)));
- }
- }
-
- static void validateCoverageMeasure(String value, InputFile inputFile) {
- Map<Integer, Integer> m = KeyValueFormat.parseIntInt(value);
- validatePositiveLine(m, inputFile.toString());
- validateMaxLine(m, inputFile);
- }
-
- private static void validateMaxLine(Map<Integer, Integer> m, InputFile inputFile) {
- int maxLine = inputFile.lines();
-
- for (int line : m.keySet()) {
- if (line > maxLine) {
- throw new IllegalStateException(String.format("Can't create measure for line %d for file '%s' with %d lines", line, inputFile, maxLine));
- }
- }
+ public static ScannerReport.Measure toReportMeasure(DefaultMeasure measureToSave) {
+ ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
+ builder.setMetricKey(measureToSave.metric().key());
+ setValueAccordingToType(builder, measureToSave);
+ return builder.build();
}
- private static void validatePositiveLine(Map<Integer, Integer> m, String filePath) {
- for (int l : m.keySet()) {
- if (l <= 0) {
- throw new IllegalStateException(String.format("Measure with line %d for file '%s' must be > 0", l, filePath));
- }
+ private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure<?> measure) {
+ Serializable value = measure.value();
+ Metric<?> metric = measure.metric();
+ if (Boolean.class.equals(metric.valueType())) {
+ builder.setBooleanValue(ScannerReport.Measure.BoolValue.newBuilder().setValue((Boolean) value));
+ } else if (Integer.class.equals(metric.valueType())) {
+ builder.setIntValue(ScannerReport.Measure.IntValue.newBuilder().setValue(((Number) value).intValue()));
+ } else if (Double.class.equals(metric.valueType())) {
+ builder.setDoubleValue(ScannerReport.Measure.DoubleValue.newBuilder().setValue(((Number) value).doubleValue()));
+ } else if (String.class.equals(metric.valueType())) {
+ builder.setStringValue(ScannerReport.Measure.StringValue.newBuilder().setValue((String) value));
+ } else if (Long.class.equals(metric.valueType())) {
+ builder.setLongValue(ScannerReport.Measure.LongValue.newBuilder().setValue(((Number) value).longValue()));
+ } else {
+ throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
}
}
@@ -462,22 +324,51 @@ public class DefaultSensorStorage implements SensorStorage {
public void store(DefaultCoverage defaultCoverage) {
DefaultInputFile inputFile = (DefaultInputFile) defaultCoverage.inputFile();
inputFile.setPublished(true);
- if (defaultCoverage.linesToCover() > 0) {
- saveCoverageMetricInternal(inputFile, LINES_TO_COVER, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(defaultCoverage.linesToCover()));
- saveCoverageMetricInternal(inputFile, UNCOVERED_LINES,
- new DefaultMeasure<Integer>().forMetric(UNCOVERED_LINES).withValue(defaultCoverage.linesToCover() - defaultCoverage.coveredLines()));
- saveCoverageMetricInternal(inputFile, COVERAGE_LINE_HITS_DATA,
- new DefaultMeasure<String>().forMetric(COVERAGE_LINE_HITS_DATA).withValue(KeyValueFormat.format(defaultCoverage.hitsByLine())));
+
+ Map<Integer, ScannerReport.LineCoverage.Builder> coveragePerLine = reloadExistingCoverage(inputFile);
+
+ int lineCount = inputFile.lines();
+ mergeLineCoverageValues(lineCount, defaultCoverage.hitsByLine(), coveragePerLine, (value, builder) -> builder.setHits(builder.getHits() || value > 0));
+ mergeLineCoverageValues(lineCount, defaultCoverage.conditionsByLine(), coveragePerLine, (value, builder) -> builder.setConditions(max(value, builder.getConditions())));
+ mergeLineCoverageValues(lineCount, defaultCoverage.coveredConditionsByLine(), coveragePerLine,
+ (value, builder) -> builder.setCoveredConditions(max(value, builder.getCoveredConditions())));
+
+ reportPublisher.getWriter().writeComponentCoverage(inputFile.scannerId(),
+ coveragePerLine.values().stream().map(ScannerReport.LineCoverage.Builder::build).collect(Collectors.toList()));
+
+ }
+
+ private Map<Integer, ScannerReport.LineCoverage.Builder> reloadExistingCoverage(DefaultInputFile inputFile) {
+ Map<Integer, ScannerReport.LineCoverage.Builder> coveragePerLine = new LinkedHashMap<>();
+ try (CloseableIterator<ScannerReport.LineCoverage> lineCoverageCloseableIterator = reportPublisher.getReader().readComponentCoverage(inputFile.scannerId())) {
+ while (lineCoverageCloseableIterator.hasNext()) {
+ final ScannerReport.LineCoverage lineCoverage = lineCoverageCloseableIterator.next();
+ coveragePerLine.put(lineCoverage.getLine(), ScannerReport.LineCoverage.newBuilder(lineCoverage));
+ }
+ }
+ return coveragePerLine;
+ }
+
+ interface LineCoverageOperation {
+ void apply(Integer value, ScannerReport.LineCoverage.Builder builder);
+ }
+
+ private void mergeLineCoverageValues(int lineCount, SortedMap<Integer, Integer> valueByLine, Map<Integer, ScannerReport.LineCoverage.Builder> coveragePerLine,
+ LineCoverageOperation op) {
+ for (Map.Entry<Integer, Integer> lineMeasure : valueByLine.entrySet()) {
+ int lineIdx = lineMeasure.getKey();
+ if (lineIdx <= lineCount) {
+ Integer value = lineMeasure.getValue();
+ op.apply(value, coveragePerLine.computeIfAbsent(lineIdx, line -> ScannerReport.LineCoverage.newBuilder().setLine(line)));
+ }
}
- if (defaultCoverage.conditions() > 0) {
- saveCoverageMetricInternal(inputFile, CONDITIONS_TO_COVER,
- new DefaultMeasure<Integer>().forMetric(CONDITIONS_TO_COVER).withValue(defaultCoverage.conditions()));
- saveCoverageMetricInternal(inputFile, UNCOVERED_CONDITIONS,
- new DefaultMeasure<Integer>().forMetric(UNCOVERED_CONDITIONS).withValue(defaultCoverage.conditions() - defaultCoverage.coveredConditions()));
- saveCoverageMetricInternal(inputFile, COVERED_CONDITIONS_BY_LINE,
- new DefaultMeasure<String>().forMetric(COVERED_CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.coveredConditionsByLine())));
- saveCoverageMetricInternal(inputFile, CONDITIONS_BY_LINE,
- new DefaultMeasure<String>().forMetric(CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.conditionsByLine())));
+ }
+
+ private static void validatePositiveLine(Map<Integer, Integer> m, String filePath) {
+ for (int l : m.keySet()) {
+ if (l <= 0) {
+ throw new IllegalStateException(String.format("Measure with line %d for file '%s' must be > 0", l, filePath));
+ }
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java
index ffec3a709ef..f549ec6216c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/ZeroCoverageSensor.java
@@ -19,41 +19,30 @@
*/
package org.sonar.scanner.source;
-import com.google.common.collect.Sets;
-import java.util.Map;
import java.util.Set;
-import java.util.stream.StreamSupport;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.measure.Metric;
-import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.batch.sensor.coverage.CoverageType;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.scanner.scan.measure.MeasureCache;
-
-import static org.sonar.core.util.stream.MoreCollectors.toSet;
+import org.sonar.api.scanner.sensor.ProjectSensor;
+import org.sonar.scanner.report.ReportPublisher;
@Phase(name = Phase.Name.POST)
-public final class ZeroCoverageSensor implements Sensor {
+public final class ZeroCoverageSensor implements ProjectSensor {
- private final MeasureCache measureCache;
+ private final ReportPublisher reportPublisher;
- public ZeroCoverageSensor(MeasureCache measureCache) {
- this.measureCache = measureCache;
+ public ZeroCoverageSensor(ReportPublisher reportPublisher) {
+ this.reportPublisher = reportPublisher;
}
@Override
public void describe(SensorDescriptor descriptor) {
- descriptor.name("Zero Coverage Sensor")
- .global();
+ descriptor.name("Zero Coverage Sensor");
}
@Override
@@ -63,32 +52,26 @@ public final class ZeroCoverageSensor implements Sensor {
if (((DefaultInputFile) f).isExcludedForCoverage()) {
continue;
}
- if (!isCoverageMeasuresAlreadyDefined(f)) {
- DefaultMeasure<String> execLines = (DefaultMeasure<String>) measureCache.byMetric(f.key(), CoreMetrics.EXECUTABLE_LINES_DATA_KEY);
- if (execLines != null) {
+ if (!isCoverageAlreadyDefined(f)) {
+ ((DefaultInputFile) f).getExecutableLines().ifPresent(execLines -> {
storeZeroCoverageForEachExecutableLine(context, f, execLines);
- }
+ });
}
}
}
- private static void storeZeroCoverageForEachExecutableLine(final SensorContext context, InputFile f, DefaultMeasure<String> execLines) {
+ private static void storeZeroCoverageForEachExecutableLine(final SensorContext context, InputFile f, Set<Integer> executableLines) {
NewCoverage newCoverage = context.newCoverage().onFile(f);
- Map<Integer, Integer> lineMeasures = KeyValueFormat.parseIntInt((String) execLines.value());
- for (Map.Entry<Integer, Integer> lineMeasure : lineMeasures.entrySet()) {
- int lineIdx = lineMeasure.getKey();
- if (lineIdx <= f.lines() && lineMeasure.getValue() > 0) {
+ for (Integer lineIdx : executableLines) {
+ if (lineIdx <= f.lines()) {
newCoverage.lineHits(lineIdx, 0);
}
}
newCoverage.save();
}
- private boolean isCoverageMeasuresAlreadyDefined(InputFile f) {
- Set<String> metricKeys = StreamSupport.stream(measureCache.byComponentKey(f.key()).spliterator(), false)
- .map(m -> m.metric().key()).collect(toSet());
- Set<String> allCoverageMetricKeys = CoverageType.UNIT.allMetrics().stream().map(Metric::key).collect(toSet());
- return !Sets.intersection(metricKeys, allCoverageMetricKeys).isEmpty();
+ private boolean isCoverageAlreadyDefined(InputFile f) {
+ return reportPublisher.getReader().hasCoverage(((DefaultInputFile) f).scannerId());
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storage.java
deleted file mode 100644
index c7b64639b44..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storage.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import com.persistit.Exchange;
-import com.persistit.Key;
-import com.persistit.KeyFilter;
-import com.persistit.exception.PersistitException;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import org.apache.commons.lang.builder.ToStringBuilder;
-
-/**
- * <p>
- * This storage is not thread-safe, due to direct usage of {@link com.persistit.Exchange}
- * </p>
- */
-public class Storage<V> {
-
- private final String name;
- private final Exchange exchange;
-
- Storage(String name, Exchange exchange) {
- this.name = name;
- this.exchange = exchange;
- }
-
- public Storage<V> put(Object key, V value) {
- resetKey(key);
- return doPut(value);
- }
-
- public Storage<V> put(Object firstKey, Object secondKey, V value) {
- resetKey(firstKey, secondKey);
- return doPut(value);
- }
-
- public Storage<V> put(Object firstKey, Object secondKey, Object thirdKey, V value) {
- resetKey(firstKey, secondKey, thirdKey);
- return doPut(value);
- }
-
- public Storage<V> put(Object[] key, V value) {
- resetKey(key);
- return doPut(value);
- }
-
- private Storage<V> doPut(V value) {
- try {
- exchange.getValue().put(value);
- exchange.store();
- return this;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to put element in the storage '" + name + "'", e);
- }
- }
-
- /**
- * Returns the value object associated with keys, or null if not found.
- */
- public V get(Object key) {
- resetKey(key);
- return doGet();
- }
-
- /**
- * Returns the value object associated with keys, or null if not found.
- */
- @CheckForNull
- public V get(Object firstKey, Object secondKey) {
- resetKey(firstKey, secondKey);
- return doGet();
- }
-
- /**
- * Returns the value object associated with keys, or null if not found.
- */
- @CheckForNull
- public V get(Object firstKey, Object secondKey, Object thirdKey) {
- resetKey(firstKey, secondKey, thirdKey);
- return doGet();
- }
-
- /**
- * Returns the value object associated with keys, or null if not found.
- */
- @CheckForNull
- public V get(Object[] key) {
- resetKey(key);
- return doGet();
- }
-
- @SuppressWarnings("unchecked")
- @CheckForNull
- private V doGet() {
- try {
- exchange.fetch();
- if (!exchange.getValue().isDefined()) {
- return null;
- }
- return (V) exchange.getValue().get();
- } catch (Exception e) {
- // TODO add parameters to message
- throw new IllegalStateException("Fail to get element from cache " + name, e);
- }
- }
-
- public boolean containsKey(Object key) {
- resetKey(key);
- return doContainsKey();
- }
-
- public boolean containsKey(Object firstKey, Object secondKey) {
- resetKey(firstKey, secondKey);
- return doContainsKey();
- }
-
- public boolean containsKey(Object firstKey, Object secondKey, Object thirdKey) {
- resetKey(firstKey, secondKey, thirdKey);
- return doContainsKey();
- }
-
- public boolean containsKey(Object[] key) {
- resetKey(key);
- return doContainsKey();
- }
-
- private boolean doContainsKey() {
- try {
- exchange.fetch();
- return exchange.isValueDefined();
- } catch (Exception e) {
- // TODO add parameters to message
- throw new IllegalStateException("Fail to check if element is in cache " + name, e);
- }
- }
-
- public boolean remove(Object key) {
- resetKey(key);
- return doRemove();
- }
-
- public boolean remove(Object firstKey, Object secondKey) {
- resetKey(firstKey, secondKey);
- return doRemove();
- }
-
- public boolean remove(Object firstKey, Object secondKey, Object thirdKey) {
- resetKey(firstKey, secondKey, thirdKey);
- return doRemove();
- }
-
- public boolean remove(Object[] key) {
- resetKey(key);
- return doRemove();
- }
-
- private boolean doRemove() {
- try {
- return exchange.remove();
- } catch (Exception e) {
- // TODO add parameters to message
- throw new IllegalStateException("Fail to get element from cache " + name, e);
- }
- }
-
- /**
- * Removes everything in the specified group.
- */
- public Storage<V> clear(Object key) {
- resetKey(key);
- return doClear();
- }
-
- public Storage<V> clear(Object firstKey, Object secondKey) {
- resetKey(firstKey, secondKey);
- return doClear();
- }
-
- public Storage<V> clear(Object firstKey, Object secondKey, Object thirdKey) {
- resetKey(firstKey, secondKey, thirdKey);
- return doClear();
- }
-
- public Storage<V> clear(Object[] key) {
- resetKey(key);
- return doClear();
- }
-
- private Storage<V> doClear() {
- try {
- Key to = new Key(exchange.getKey());
- to.append(Key.AFTER);
- exchange.removeKeyRange(exchange.getKey(), to);
- return this;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to clear values from cache " + name, e);
- }
- }
-
- /**
- * Clears the default as well as all group caches.
- */
- public void clear() {
- try {
- exchange.clear();
- exchange.removeAll();
- } catch (Exception e) {
- throw new IllegalStateException("Fail to clear cache", e);
- }
- }
-
- /**
- * Returns the set of cache keys associated with this group.
- * TODO implement a lazy-loading equivalent with Iterator/Iterable
- *
- * @return The set of cache keys for this group.
- */
- @SuppressWarnings("rawtypes")
- public Set keySet(Object key) {
- try {
- Set<Object> keys = new LinkedHashSet<>();
- exchange.clear();
- Exchange iteratorExchange = new Exchange(exchange);
- iteratorExchange.append(key);
- iteratorExchange.append(Key.BEFORE);
- while (iteratorExchange.next(false)) {
- keys.add(iteratorExchange.getKey().indexTo(-1).decode());
- }
- return keys;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to get keys from cache " + name, e);
- }
- }
-
- @SuppressWarnings("rawtypes")
- public Set keySet(Object firstKey, Object secondKey) {
- try {
- Set<Object> keys = new LinkedHashSet<>();
- exchange.clear();
- Exchange iteratorExchange = new Exchange(exchange);
- iteratorExchange.append(firstKey);
- iteratorExchange.append(secondKey);
- iteratorExchange.append(Key.BEFORE);
- while (iteratorExchange.next(false)) {
- keys.add(iteratorExchange.getKey().indexTo(-1).decode());
- }
- return keys;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to get keys from cache " + name, e);
- }
- }
-
- /**
- * Returns the set of keys associated with this cache.
- *
- * @return The set containing the keys for this cache.
- */
- public Set<Object> keySet() {
- try {
- Set<Object> keys = new LinkedHashSet<>();
- exchange.clear();
- Exchange iteratorExchange = new Exchange(exchange);
- iteratorExchange.append(Key.BEFORE);
- while (iteratorExchange.next(false)) {
- keys.add(iteratorExchange.getKey().indexTo(-1).decode());
- }
- return keys;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to get keys from cache " + name, e);
- }
- }
-
- /**
- * Lazy-loading values for given keys
- */
- public Iterable<V> values(Object firstKey, Object secondKey) {
- return new ValueIterable<>(exchange, firstKey, secondKey);
- }
-
- /**
- * Lazy-loading values for a given key
- */
- public Iterable<V> values(Object firstKey) {
- return new ValueIterable<>(exchange, firstKey);
- }
-
- /**
- * Lazy-loading values
- */
- public Iterable<V> values() {
- return new ValueIterable<>(exchange);
- }
-
- public Iterable<Entry<V>> entries() {
- return new EntryIterable<>(exchange);
- }
-
- public Iterable<Entry<V>> entries(Object firstKey) {
- return new EntryIterable<>(exchange, firstKey);
- }
-
- private void resetKey(Object key) {
- exchange.clear();
- exchange.append(key);
- }
-
- private void resetKey(Object first, Object second) {
- exchange.clear();
- exchange.append(first).append(second);
- }
-
- private void resetKey(Object first, Object second, Object third) {
- exchange.clear();
- exchange.append(first).append(second).append(third);
- }
-
- private void resetKey(Object[] keys) {
- exchange.clear();
- for (Object o : keys) {
- exchange.append(o);
- }
- }
-
- //
- // LAZY ITERATORS AND ITERABLES
- //
-
- private static class ValueIterable<T> implements Iterable<T> {
- private final Exchange originExchange;
- private final Object[] keys;
-
- private ValueIterable(Exchange originExchange, Object... keys) {
- this.originExchange = originExchange;
- this.keys = keys;
- }
-
- @Override
- public Iterator<T> iterator() {
- originExchange.clear();
- KeyFilter filter = new KeyFilter();
- for (Object key : keys) {
- originExchange.append(key);
- filter = filter.append(KeyFilter.simpleTerm(key));
- }
- originExchange.append(Key.BEFORE);
- Exchange iteratorExchange = new Exchange(originExchange);
- return new ValueIterator<>(iteratorExchange, filter);
- }
- }
-
- private static class ValueIterator<T> implements Iterator<T> {
- private final Exchange exchange;
- private final KeyFilter keyFilter;
-
- private ValueIterator(Exchange exchange, KeyFilter keyFilter) {
- this.exchange = exchange;
- this.keyFilter = keyFilter;
- }
-
- @Override
- public boolean hasNext() {
- try {
- return exchange.hasNext(keyFilter);
- } catch (PersistitException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public T next() {
- try {
- exchange.next(keyFilter);
- } catch (PersistitException e) {
- throw new IllegalStateException(e);
- }
- if (exchange.getValue().isDefined()) {
- return (T) exchange.getValue().get();
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Removing an item is not supported");
- }
- }
-
- private static class EntryIterable<T> implements Iterable<Entry<T>> {
- private final Exchange originExchange;
- private final Object[] keys;
-
- private EntryIterable(Exchange originExchange, Object... keys) {
- this.originExchange = originExchange;
- this.keys = keys;
- }
-
- @Override
- public Iterator<Entry<T>> iterator() {
- originExchange.clear();
- KeyFilter filter = new KeyFilter();
- for (Object key : keys) {
- originExchange.append(key);
- filter = filter.append(KeyFilter.simpleTerm(key));
- }
- originExchange.append(Key.BEFORE);
- Exchange iteratorExchange = new Exchange(originExchange);
- return new EntryIterator<>(iteratorExchange, filter);
- }
- }
-
- private static class EntryIterator<T> implements Iterator<Entry<T>> {
- private final Exchange exchange;
- private final KeyFilter keyFilter;
-
- private EntryIterator(Exchange exchange, KeyFilter keyFilter) {
- this.exchange = exchange;
- this.keyFilter = keyFilter;
- }
-
- @Override
- public boolean hasNext() {
- try {
- return exchange.hasNext(keyFilter);
- } catch (PersistitException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<T> next() {
- try {
- exchange.next(keyFilter);
- } catch (PersistitException e) {
- throw new IllegalStateException(e);
- }
- if (exchange.getValue().isDefined()) {
- T value = (T) exchange.getValue().get();
- Key key = exchange.getKey();
- Object[] array = new Object[key.getDepth()];
- for (int i = 0; i < key.getDepth(); i++) {
- array[i] = key.indexTo(i - key.getDepth()).decode();
- }
- return new Entry<>(array, value);
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Removing an item is not supported");
- }
- }
-
- public static class Entry<V> {
- private final Object[] key;
- private final V value;
-
- Entry(Object[] key, V value) {
- this.key = key;
- this.value = value;
- }
-
- public Object[] key() {
- return key;
- }
-
- public V value() {
- return value;
- }
-
- @Override
- public String toString() {
- return ToStringBuilder.reflectionToString(this);
- }
- }
-
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storages.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storages.java
deleted file mode 100644
index 23827ebe5d0..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/Storages.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import com.google.common.base.Preconditions;
-import com.persistit.Exchange;
-import com.persistit.Persistit;
-import com.persistit.Value;
-import com.persistit.Volume;
-import com.persistit.encoding.CoderManager;
-import com.persistit.encoding.ValueCoder;
-import com.persistit.exception.PersistitException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.picocontainer.Startable;
-
-public class Storages implements Startable {
- private final Map<String, Exchange> cacheMap = new HashMap<>();
- private Persistit persistit;
- private Volume volume;
-
- public Storages(StoragesManager storagesManager) {
- persistit = storagesManager.persistit();
- doStart();
- }
-
- @Override
- public void start() {
- // done in constructor
- }
-
- private void doStart() {
- try {
- persistit.flush();
- volume = persistit.createTemporaryVolume();
- } catch (Exception e) {
- throw new IllegalStateException("Fail to create a cache volume", e);
- }
- }
-
- public void registerValueCoder(Class<?> clazz, ValueCoder coder) {
- CoderManager cm = persistit.getCoderManager();
- cm.registerValueCoder(clazz, coder);
- }
-
- public <V> Storage<V> createCache(String cacheName) {
- Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized");
- Preconditions.checkState(!cacheMap.containsKey(cacheName), "Cache is already created: %s", cacheName);
- try {
- Exchange exchange = persistit.getExchange(volume, cacheName, true);
- exchange.setMaximumValueSize(Value.MAXIMUM_SIZE);
- Storage<V> cache = new Storage<>(cacheName, exchange);
- cacheMap.put(cacheName, exchange);
- return cache;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to create cache: " + cacheName, e);
- }
- }
-
- @Override
- public void stop() {
- for (Entry<String, Exchange> e : cacheMap.entrySet()) {
- persistit.releaseExchange(e.getValue());
- }
-
- cacheMap.clear();
-
- if (volume != null) {
- try {
- volume.close();
- volume.delete();
- } catch (PersistitException e) {
- throw new IllegalStateException("Fail to close caches", e);
- }
- volume = null;
- }
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/StoragesManager.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/StoragesManager.java
deleted file mode 100644
index 3f1b1d9dcbe..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/StoragesManager.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import com.persistit.Persistit;
-import com.persistit.exception.PersistitException;
-import com.persistit.logging.Slf4jAdapter;
-import java.io.File;
-import java.util.Properties;
-import org.picocontainer.Startable;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.utils.TempFolder;
-
-import static org.sonar.core.util.FileUtils.deleteQuietly;
-
-/**
- * Factory of storages
- *
- * @since 3.6
- */
-public class StoragesManager implements Startable {
- private File tempDir;
- private Persistit persistit;
- private final TempFolder tempFolder;
-
- public StoragesManager(TempFolder tempFolder) {
- this.tempFolder = tempFolder;
- initPersistit();
- }
-
- private void initPersistit() {
- try {
- tempDir = tempFolder.newDir("caches");
- persistit = new Persistit();
- persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
- Properties props = new Properties();
- props.setProperty("datapath", tempDir.getAbsolutePath());
- props.setProperty("logpath", "${datapath}/log");
- props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
- props.setProperty("buffer.count.8192", "10");
- props.setProperty("journalpath", "${datapath}/journal");
- props.setProperty("tmpvoldir", "${datapath}");
- props.setProperty("volume.1", "${datapath}/persistit,create,pageSize:8192,initialPages:10,extensionPages:100,maximumPages:25000");
- props.setProperty("jmx", "false");
- persistit.setProperties(props);
- persistit.initialize();
-
- } catch (Exception e) {
- throw new IllegalStateException("Fail to start caches", e);
- }
- }
-
- @Override
- public void start() {
- // already started in constructor
- }
-
- @Override
- public void stop() {
- if (persistit != null) {
- try {
- persistit.close(false);
- persistit = null;
- } catch (PersistitException e) {
- throw new IllegalStateException("Fail to close caches", e);
- }
- }
- deleteQuietly(tempDir);
- tempDir = null;
- }
-
- File tempDir() {
- return tempDir;
- }
-
- Persistit persistit() {
- return persistit;
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/package-info.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/package-info.java
deleted file mode 100644
index 8187995b887..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/storage/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.scanner.storage;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
index 7d28d497230..6bd3a77f43c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
@@ -31,13 +31,9 @@ import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.scanner.scan.measure.MeasureCache;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -56,7 +52,6 @@ public class DefaultFileLinesContextTest {
private DefaultFileLinesContext fileLineMeasures;
- private MeasureCache measureCache;
private SensorStorage sensorStorage;
private DefaultInputFile file;
@@ -77,11 +72,9 @@ public class DefaultFileLinesContextTest {
when(metricFinder.<String>findByKey(BRANCHES_METRIC_KEY)).thenReturn(branchesMetric);
when(metricFinder.<String>findByKey(CoreMetrics.NCLOC_DATA_KEY)).thenReturn(CoreMetrics.NCLOC_DATA);
when(metricFinder.<String>findByKey(CoreMetrics.EXECUTABLE_LINES_DATA_KEY)).thenReturn(CoreMetrics.EXECUTABLE_LINES_DATA);
- measureCache = mock(MeasureCache.class);
sensorStorage = mock(SensorStorage.class);
file = new TestInputFileBuilder("foo", "src/foo.php").initMetadata("Foo\nbar\nbiz").build();
- fileLineMeasures = new DefaultFileLinesContext(sensorStorage, file, metricFinder,
- measureCache);
+ fileLineMeasures = new DefaultFileLinesContext(sensorStorage, file, metricFinder);
}
@Test
@@ -158,36 +151,5 @@ public class DefaultFileLinesContextTest {
fileLineMeasures.setIntValue(HITS_METRIC_KEY, 1, 2);
}
- @Test
- public void shouldLoadIntValues() {
- when(measureCache.byMetric("foo:src/foo.php", HITS_METRIC_KEY)).thenReturn(new DefaultMeasure().withValue("1=2;3=4"));
-
- assertThat(fileLineMeasures.getIntValue(HITS_METRIC_KEY, 1), is(2));
- assertThat(fileLineMeasures.getIntValue(HITS_METRIC_KEY, 3), is(4));
- assertThat("no measure on line", fileLineMeasures.getIntValue(HITS_METRIC_KEY, 2), nullValue());
- }
-
- @Test
- public void shouldLoadStringValues() {
- when(measureCache.byMetric("foo:src/foo.php", AUTHOR_METRIC_KEY)).thenReturn(new DefaultMeasure().withValue("1=simon;3=evgeny"));
-
- assertThat(fileLineMeasures.getStringValue(AUTHOR_METRIC_KEY, 1), is("simon"));
- assertThat(fileLineMeasures.getStringValue(AUTHOR_METRIC_KEY, 3), is("evgeny"));
- assertThat("no measure on line", fileLineMeasures.getStringValue(AUTHOR_METRIC_KEY, 2), nullValue());
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void shouldNotModifyAfterLoad() {
- when(measureCache.byMetric("foo:src/foo.php", AUTHOR_METRIC_KEY)).thenReturn(new DefaultMeasure().withValue("1=simon;3=evgeny"));
-
- fileLineMeasures.getStringValue(AUTHOR_METRIC_KEY, 1);
- fileLineMeasures.setStringValue(AUTHOR_METRIC_KEY, 1, "evgeny");
- }
-
- @Test
- public void shouldNotFailIfNoMeasureInIndex() {
- assertThat(fileLineMeasures.getIntValue(HITS_METRIC_KEY, 1), nullValue());
- assertThat(fileLineMeasures.getStringValue(AUTHOR_METRIC_KEY, 1), nullValue());
- }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/index/AbstractCachesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/index/AbstractCachesTest.java
deleted file mode 100644
index c2b1580ff15..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/index/AbstractCachesTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.index;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.scanner.bootstrap.GlobalTempFolderProvider;
-import org.sonar.scanner.bootstrap.RawScannerProperties;
-import org.sonar.scanner.storage.Storages;
-import org.sonar.scanner.storage.StoragesManager;
-
-public abstract class AbstractCachesTest {
- @ClassRule
- public static TemporaryFolder temp = new TemporaryFolder();
-
- protected static StoragesManager cachesManager;
- protected Storages caches;
-
- private static StoragesManager createCacheOnTemp() {
- Map<String, String> props = ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.getRoot().getAbsolutePath(),
- CoreProperties.GLOBAL_WORKING_DIRECTORY, temp.getRoot().getAbsolutePath());
-
- return new StoragesManager(new GlobalTempFolderProvider().provide(new RawScannerProperties(props)));
- }
-
- @BeforeClass
- public static void startClass() {
- cachesManager = createCacheOnTemp();
- cachesManager.start();
- }
-
- @Before
- public void start() {
- caches = new Storages(cachesManager);
- caches.start();
- }
-
- @After
- public void stop() {
- if (caches != null) {
- caches.stop();
- caches = null;
- }
- }
-
- @AfterClass
- public static void stopClass() {
- if (cachesManager != null) {
- cachesManager.stop();
- }
- }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
index 7c52194f8de..f376d56999e 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
@@ -25,13 +25,15 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.AnalysisResult;
+import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.repository.FileData;
import org.sonar.scanner.scan.branch.BranchType;
@@ -63,6 +65,9 @@ public class BranchMediumTest {
Path filepath = baseDir.toPath().resolve(FILE_PATH);
Files.write(filepath, FILE_CONTENT.getBytes());
+ Path xooUtCoverageFile = baseDir.toPath().resolve(FILE_PATH + ".coverage");
+ FileUtils.write(xooUtCoverageFile.toFile(), "1:2:2:1", StandardCharsets.UTF_8);
+
String md5sum = new FileMetadata()
.readMetadata(Files.newInputStream(filepath), StandardCharsets.UTF_8, FILE_PATH)
.hash();
@@ -73,15 +78,18 @@ public class BranchMediumTest {
public void should_not_skip_report_for_unchanged_files_in_short_branch() {
// sanity check, normally report gets generated
AnalysisResult result = getResult(tester);
- assertThat(getResult(tester).getReportComponent(result.inputFile(FILE_PATH))).isNotNull();
- int fileId = 2;
+ final DefaultInputFile file = (DefaultInputFile) result.inputFile(FILE_PATH);
+ assertThat(getResult(tester).getReportComponent(file)).isNotNull();
+ int fileId = file.scannerId();
assertThat(result.getReportReader().readChangesets(fileId)).isNotNull();
assertThat(result.getReportReader().hasCoverage(fileId)).isTrue();
assertThat(result.getReportReader().readFileSource(fileId)).isNotNull();
// file is not skipped for short branches (need coverage, duplications coming soon)
AnalysisResult result2 = getResult(tester.setBranchType(BranchType.SHORT));
- assertThat(result2.getReportComponent(result2.inputFile(FILE_PATH))).isNotNull();
+ final DefaultInputFile fileOnShortBranch = (DefaultInputFile) result2.inputFile(FILE_PATH);
+ assertThat(result2.getReportComponent(fileOnShortBranch)).isNotNull();
+ fileId = fileOnShortBranch.scannerId();
assertThat(result2.getReportReader().readChangesets(fileId)).isNull();
assertThat(result2.getReportReader().hasCoverage(fileId)).isTrue();
assertThat(result2.getReportReader().readFileSource(fileId)).isNull();
@@ -108,10 +116,8 @@ public class BranchMediumTest {
return tester
.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", PROJECT_KEY)
- .put("sonar.sources", ".")
.put("sonar.scm.provider", "xoo")
.build())
.execute();
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java
index 0b6744565de..c51d03d3785 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java
@@ -23,22 +23,18 @@ import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.AnalysisResult;
+import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.xoo.XooPlugin;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
public class CoverageMediumTest {
@@ -77,13 +73,6 @@ public class CoverageMediumTest {
assertThat(result.coverageFor(file, 2).getHits()).isTrue();
assertThat(result.coverageFor(file, 2).getConditions()).isEqualTo(2);
assertThat(result.coverageFor(file, 2).getCoveredConditions()).isEqualTo(1);
-
- Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .contains(tuple(CoreMetrics.LINES_TO_COVER_KEY, 2),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0),
- tuple(CoreMetrics.CONDITIONS_TO_COVER_KEY, 2),
- tuple(CoreMetrics.UNCOVERED_CONDITIONS_KEY, 1));
}
@Test
@@ -98,7 +87,7 @@ public class CoverageMediumTest {
File xooUtCoverageFile = new File(srcDir, "sample.xoo.coverage");
FileUtils.write(xooUtCoverageFile, "2:2:2:2\n4:0", StandardCharsets.UTF_8);
File xooItCoverageFile = new File(srcDir, "sample.xoo.itcoverage");
- FileUtils.write(xooItCoverageFile, "2:2:2:1\n3:1\n5:0", StandardCharsets.UTF_8);
+ FileUtils.write(xooItCoverageFile, "2:0:2:1\n3:1\n5:0", StandardCharsets.UTF_8);
AnalysisResult result = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
@@ -113,16 +102,6 @@ public class CoverageMediumTest {
assertThat(result.coverageFor(file, 2).getConditions()).isEqualTo(2);
assertThat(result.coverageFor(file, 2).getCoveredConditions()).isEqualTo(2);
assertThat(result.coverageFor(file, 3).getHits()).isTrue();
-
- Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value", "stringValue.value")
- .contains(tuple(CoreMetrics.LINES_TO_COVER_KEY, 4, ""), // 2, 3, 4, 5
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 2, ""), // 4, 5
- tuple(CoreMetrics.CONDITIONS_TO_COVER_KEY, 2, ""), // 2 x 2
- tuple(CoreMetrics.UNCOVERED_CONDITIONS_KEY, 0, ""),
- tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "2=4;3=1;4=0;5=0"),
- tuple(CoreMetrics.CONDITIONS_BY_LINE_KEY, 0, "2=2"),
- tuple(CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, 0, "2=2"));
}
@Test
@@ -148,11 +127,6 @@ public class CoverageMediumTest {
InputFile file = result.inputFile("src/sample.xoo");
assertThat(result.coverageFor(file, 2)).isNull();
-
- Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey")
- .doesNotContain(CoreMetrics.LINES_TO_COVER_KEY, CoreMetrics.UNCOVERED_LINES_KEY, CoreMetrics.CONDITIONS_TO_COVER_KEY,
- CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY);
}
@Test
@@ -306,13 +280,6 @@ public class CoverageMediumTest {
assertThat(result.coverageFor(file, 3).getHits()).isFalse();
assertThat(result.coverageFor(file, 4)).isNull();
-
- Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .contains(tuple(CoreMetrics.LINES_TO_COVER_KEY, 2),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 2));
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.CONDITIONS_TO_COVER_KEY, CoreMetrics.UNCOVERED_CONDITIONS_KEY);
}
// SONAR-9557
@@ -359,18 +326,6 @@ public class CoverageMediumTest {
assertThat(result.coverageFor(file2, 3)).isNull();
assertThat(result.coverageFor(file2, 4)).isNull();
- Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project:module1/src/sample1.xoo")).extracting("metricKey", "intValue.value")
- .contains(tuple(CoreMetrics.LINES_TO_COVER_KEY, 2),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 2));
-
- assertThat(allMeasures.get("com.foo.project:module1/src/sample1.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.CONDITIONS_TO_COVER_KEY,
- CoreMetrics.UNCOVERED_CONDITIONS_KEY);
-
- assertThat(allMeasures.get("com.foo.project:module1/src/sample2.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.LINES_TO_COVER_KEY,
- CoreMetrics.CONDITIONS_TO_COVER_KEY,
- CoreMetrics.UNCOVERED_CONDITIONS_KEY, CoreMetrics.UNCOVERED_LINES_KEY);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumTest.java
index e41b31e8d60..1fc4d93676c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/GenericCoverageMediumTest.java
@@ -26,13 +26,11 @@ import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.AnalysisResult;
+import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.xoo.XooPlugin;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
public class GenericCoverageMediumTest {
private final List<String> logs = new ArrayList<>();
@@ -60,27 +58,11 @@ public class GenericCoverageMediumTest {
assertThat(result.coverageFor(noConditions, 7).getHits()).isFalse();
- assertThat(result.allMeasures().get(noConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
- .containsOnly(
- tuple(CoreMetrics.LINES_TO_COVER_KEY, 2, ""),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 1, ""),
- tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "6=1;7=0"));
-
InputFile withConditions = result.inputFile("xources/hello/WithConditions.xoo");
assertThat(result.coverageFor(withConditions, 3).getHits()).isTrue();
assertThat(result.coverageFor(withConditions, 3).getConditions()).isEqualTo(2);
assertThat(result.coverageFor(withConditions, 3).getCoveredConditions()).isEqualTo(1);
- assertThat(result.allMeasures().get(withConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
- .containsOnly(
- tuple(CoreMetrics.LINES_TO_COVER_KEY, 1, ""),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
- tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "3=1"),
- tuple(CoreMetrics.CONDITIONS_TO_COVER_KEY, 2, ""),
- tuple(CoreMetrics.UNCOVERED_CONDITIONS_KEY, 1, ""),
- tuple(CoreMetrics.CONDITIONS_BY_LINE_KEY, 0, "3=2"),
- tuple(CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, 0, "3=1")
- );
assertThat(logs).noneMatch(l -> l.contains("Please use 'sonar.coverageReportPaths'"));
}
@@ -117,28 +99,11 @@ public class GenericCoverageMediumTest {
assertThat(result.coverageFor(noConditions, 7).getHits()).isTrue();
- assertThat(result.allMeasures().get(noConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
- .containsOnly(
- tuple(CoreMetrics.LINES_TO_COVER_KEY, 2, ""),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
- tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "6=1;7=1"));
-
InputFile withConditions = result.inputFile("xources/hello/WithConditions.xoo");
assertThat(result.coverageFor(withConditions, 3).getHits()).isTrue();
assertThat(result.coverageFor(withConditions, 3).getConditions()).isEqualTo(2);
assertThat(result.coverageFor(withConditions, 3).getCoveredConditions()).isEqualTo(2);
- assertThat(result.allMeasures().get(withConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
- .containsOnly(
- tuple(CoreMetrics.LINES_TO_COVER_KEY, 1, ""),
- tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
- tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "3=2"),
- tuple(CoreMetrics.CONDITIONS_TO_COVER_KEY, 2, ""),
- tuple(CoreMetrics.UNCOVERED_CONDITIONS_KEY, 0, ""),
- tuple(CoreMetrics.CONDITIONS_BY_LINE_KEY, 0, "3=2"),
- tuple(CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY, 0, "3=2")
- );
-
assertThat(logs).noneMatch(l -> l.contains("Please use 'sonar.coverageReportPaths'"));
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java
index 395dff17b10..34e57146bfe 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java
@@ -65,66 +65,6 @@ public class MeasuresMediumTest {
}
@Test
- public void applyExclusionsOnCoverageMeasures() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
-
- File measures = new File(srcDir, "sample.xoo.measures");
- FileUtils.write(measures, "lines_to_cover:2", StandardCharsets.UTF_8);
-
- AnalysisResult result = tester.newAnalysis()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.sources", "src")
- .build())
- .execute();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .containsOnly(tuple("lines_to_cover", 2));
-
- result = tester.newAnalysis()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.sources", "src")
- .put("sonar.coverage.exclusions", "src/sample.xoo")
- .build())
- .execute();
-
- allMeasures = result.allMeasures();
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .isEmpty();
- }
-
- @Test
- public void deprecatedCoverageMeasuresAreConverted() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
-
- File measures = new File(srcDir, "sample.xoo.measures");
- FileUtils.write(measures, "it_lines_to_cover:2", StandardCharsets.UTF_8);
-
- AnalysisResult result = tester.newAnalysis()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.sources", "src")
- .build())
- .execute();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .containsOnly(tuple("lines_to_cover", 2));
-
- assertThat(logTester.logs(LoggerLevel.WARN))
- .contains("Coverage measure for metric 'lines_to_cover' should not be saved directly by a Sensor. Plugin should be updated to use SensorContext::newCoverage instead.");
- }
-
- @Test
public void failIfTryingToSaveServerSideMeasure() throws IOException {
File xooFile = new File(srcDir, "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java
index 42d7f836bf5..62ea71126ae 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java
@@ -80,12 +80,8 @@ public class ScmMediumTest {
tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project")
.put("sonar.sources", "src")
.put("sonar.scm.provider", "xoo")
.build())
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java
deleted file mode 100644
index f1c75d6a3e3..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.report;
-
-import java.io.File;
-import java.io.IOException;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.core.util.CloseableIterator;
-import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage;
-import org.sonar.scanner.protocol.output.ScannerReportReader;
-import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.branch.BranchConfiguration;
-import org.sonar.scanner.scan.filesystem.InputComponentStore;
-import org.sonar.scanner.scan.measure.MeasureCache;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class CoveragePublisherTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- private MeasureCache measureCache;
- private CoveragePublisher publisher;
-
- private DefaultInputFile inputFile;
-
- @Before
- public void prepare() throws IOException {
- String moduleKey = "foo";
- inputFile = new TestInputFileBuilder(moduleKey, "src/Foo.php").setLines(5).build();
- DefaultInputProject rootModule = TestInputFileBuilder.newDefaultInputProject(moduleKey, temp.newFolder());
- InputComponentStore componentCache = new InputComponentStore(mock(BranchConfiguration.class));
- componentCache.put(moduleKey, inputFile);
-
- measureCache = mock(MeasureCache.class);
- when(measureCache.byMetric(anyString(), anyString())).thenReturn(null);
- publisher = new CoveragePublisher(componentCache, measureCache);
- }
-
- @Test
- public void publishCoverage() throws Exception {
-
- DefaultMeasure<String> utLineHits = new DefaultMeasure<String>().forMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA).withValue("2=1;3=1;5=0;6=3");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).thenReturn((DefaultMeasure) utLineHits);
-
- DefaultMeasure<String> conditionsByLine = new DefaultMeasure<String>().forMetric(CoreMetrics.CONDITIONS_BY_LINE).withValue("3=4");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.CONDITIONS_BY_LINE_KEY)).thenReturn((DefaultMeasure) conditionsByLine);
-
- DefaultMeasure<String> coveredConditionsByUts = new DefaultMeasure<String>().forMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE).withValue("3=2");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn((DefaultMeasure) coveredConditionsByUts);
-
- File outputDir = temp.newFolder();
- ScannerReportWriter writer = new ScannerReportWriter(outputDir);
-
- publisher.publish(writer);
-
- try (CloseableIterator<LineCoverage> it = new ScannerReportReader(outputDir).readComponentCoverage(inputFile.scannerId())) {
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(2)
- .setHits(true)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(3)
- .setHits(true)
- .setConditions(4)
- .setCoveredConditions(2)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(5)
- .setHits(false)
- .build());
- }
-
- }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java
deleted file mode 100644
index 6af538c600b..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.report;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.core.util.CloseableIterator;
-import org.sonar.scanner.deprecated.test.TestPlanBuilder;
-import org.sonar.scanner.protocol.output.ScannerReport;
-import org.sonar.scanner.protocol.output.ScannerReportReader;
-import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.branch.BranchConfiguration;
-import org.sonar.scanner.scan.filesystem.InputComponentStore;
-import org.sonar.scanner.scan.measure.MeasureCache;
-
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class MeasuresPublisherTest {
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- private MeasureCache measureCache;
- private MeasuresPublisher publisher;
-
- private File outputDir;
- private ScannerReportWriter writer;
- private DefaultInputFile inputFile;
- private DefaultInputProject project;
-
- @Before
- public void prepare() throws IOException {
- String projectKey = "foo";
- project = TestInputFileBuilder.newDefaultInputProject(projectKey, temp.newFolder());
- inputFile = new TestInputFileBuilder(projectKey, "src/Foo.php").setPublish(true).build();
- InputComponentStore componentCache = new InputComponentStore(mock(BranchConfiguration.class));
- componentCache.put(projectKey, inputFile);
- measureCache = mock(MeasureCache.class);
- when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList());
- publisher = new MeasuresPublisher(componentCache, measureCache, mock(TestPlanBuilder.class));
- outputDir = temp.newFolder();
- writer = new ScannerReportWriter(outputDir);
- }
-
- @Test
- public void publishMeasures() throws Exception {
- DefaultMeasure<Integer> measure = new DefaultMeasure<Integer>().forMetric(CoreMetrics.LINES_TO_COVER)
- .withValue(2);
- // String value
- DefaultMeasure<String> stringMeasure = new DefaultMeasure<String>().forMetric(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION)
- .withValue("foo bar");
- when(measureCache.byComponentKey(inputFile.key())).thenReturn(asList(measure, stringMeasure));
-
- publisher.publish(writer);
- ScannerReportReader reader = new ScannerReportReader(outputDir);
-
- assertThat(reader.readComponentMeasures(project.scannerId())).hasSize(0);
- try (CloseableIterator<ScannerReport.Measure> componentMeasures = reader.readComponentMeasures(inputFile.scannerId())) {
- assertThat(componentMeasures).hasSize(2);
- }
- }
-
- @Test
- public void fail_with_IAE_when_measure_has_no_value() throws Exception {
- DefaultMeasure<Integer> measure = new DefaultMeasure<Integer>().forMetric(CoreMetrics.LINES_TO_COVER);
- when(measureCache.byComponentKey(inputFile.key())).thenReturn(Collections.singletonList(measure));
-
- try {
- publisher.publish(writer);
- fail();
- } catch (RuntimeException e) {
- assertThat(ExceptionUtils.getFullStackTrace(e)).contains("Measure on metric 'lines_to_cover' and component 'foo:src/Foo.php' has no value, but it's not allowed");
- }
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/measure/MeasureCacheTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/measure/MeasureCacheTest.java
deleted file mode 100644
index f3e08e99d2e..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/measure/MeasureCacheTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.scan.measure;
-
-import java.util.Iterator;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.scanner.index.AbstractCachesTest;
-import org.sonar.scanner.storage.Storage.Entry;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class MeasureCacheTest extends AbstractCachesTest {
-
- private static final String COMPONENT_KEY = "struts";
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- private MetricFinder metricFinder;
-
- private MeasureCache measureCache;
-
- @Before
- public void start() {
- super.start();
- metricFinder = mock(MetricFinder.class);
- when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
- when(metricFinder.<String>findByKey(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).thenReturn(CoreMetrics.COVERAGE_LINE_HITS_DATA);
- measureCache = new MeasureCache(caches, metricFinder);
- }
-
- @Test
- public void should_add_measure() {
- assertThat(measureCache.entries()).hasSize(0);
- assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
-
- DefaultMeasure<?> m = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(1.0);
- measureCache.put(COMPONENT_KEY, CoreMetrics.NCLOC_KEY, m);
-
- assertThat(measureCache.contains(COMPONENT_KEY, CoreMetrics.NCLOC_KEY)).isTrue();
- assertThat(measureCache.entries()).hasSize(1);
- Iterator<Entry<DefaultMeasure<?>>> iterator = measureCache.entries().iterator();
- iterator.hasNext();
- Entry<DefaultMeasure<?>> next = iterator.next();
- assertThat(next.value()).isEqualTo(m);
- assertThat(next.key()[0]).isEqualTo(COMPONENT_KEY);
-
- assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(1);
- assertThat(measureCache.byComponentKey(COMPONENT_KEY).iterator().next()).isEqualTo(m);
- }
-
- /**
- * This test fails with stock PersisitIt.
- */
- @Test
- public void should_add_measure_with_too_big_data_for_persistit_pre_patch() {
- assertThat(measureCache.entries()).hasSize(0);
- assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
-
- StringBuilder data = new StringBuilder(4_500_000);
- for (int i = 0; i < 4_500_000; i++) {
- data.append('a');
- }
- DefaultMeasure<?> m = new DefaultMeasure().forMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA).withValue(data.toString());
- measureCache.put(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, m);
-
- assertThat(measureCache.contains(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).isTrue();
- assertThat(measureCache.entries()).hasSize(1);
- Iterator<Entry<DefaultMeasure<?>>> iterator = measureCache.entries().iterator();
- iterator.hasNext();
- Entry<DefaultMeasure<?>> next = iterator.next();
- assertThat(next.value()).isEqualTo(m);
- assertThat(next.key()[0]).isEqualTo(COMPONENT_KEY);
-
- assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(1);
- assertThat(measureCache.byComponentKey(COMPONENT_KEY).iterator().next()).isEqualTo(m);
-
- }
-
- @Test
- public void should_add_measure_with_too_big_data_for_persistit() {
- assertThat(measureCache.entries()).hasSize(0);
- assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
-
- // Limit is 64Mo
- StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1);
- for (int i = 0; i < 64 * 1024 * 1024 + 1; i++) {
- data.append('a');
- }
- DefaultMeasure<?> m = new DefaultMeasure().forMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA).withValue(data.toString());
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Fail to put element in the storage 'measures'");
-
- measureCache.put(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, m);
- }
-
- @Test
- public void should_get_measures() {
- String projectKey = "struts";
- String dirKey = "struts:foo/bar";
- String file1Key = "struts:foo/bar/File1.txt";
- String file2Key = "struts:foo/bar/File2.txt";
-
- assertThat(measureCache.entries()).hasSize(0);
-
- assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
- assertThat(measureCache.byComponentKey(dirKey)).hasSize(0);
-
- DefaultMeasure<?> mFile1 = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(1.0);
- measureCache.put(file1Key, CoreMetrics.NCLOC_DATA_KEY, mFile1);
- DefaultMeasure<?> mFile2 = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(3.0);
- measureCache.put(file2Key, CoreMetrics.NCLOC_DATA_KEY, mFile2);
-
- assertThat(measureCache.entries()).hasSize(2);
- assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
- assertThat(measureCache.byComponentKey(dirKey)).hasSize(0);
-
- DefaultMeasure<?> mDir = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(4.0);
- measureCache.put(dirKey, CoreMetrics.NCLOC_DATA_KEY, mDir);
-
- assertThat(measureCache.entries()).hasSize(3);
- assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
- assertThat(measureCache.byComponentKey(dirKey)).hasSize(1);
- assertThat(measureCache.byComponentKey(dirKey).iterator().next()).isEqualTo(mDir);
-
- DefaultMeasure<?> mProj = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(4.0);
- measureCache.put(projectKey, CoreMetrics.NCLOC_DATA_KEY, mProj);
-
- assertThat(measureCache.entries()).hasSize(4);
- assertThat(measureCache.byComponentKey(projectKey)).hasSize(1);
- assertThat(measureCache.byComponentKey(projectKey).iterator().next()).isEqualTo(mProj);
- assertThat(measureCache.byComponentKey(dirKey)).hasSize(1);
- assertThat(measureCache.byComponentKey(dirKey).iterator().next()).isEqualTo(mDir);
- }
-
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
index 96aef89bfc0..264e666429f 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
@@ -19,9 +19,8 @@
*/
package org.sonar.scanner.sensor;
-import com.google.common.collect.ImmutableMap;
+import java.io.File;
import java.io.IOException;
-import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -48,20 +47,19 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
import org.sonar.scanner.issue.IssuePublisher;
import org.sonar.scanner.protocol.output.FileStructure;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.report.ReportPublisher;
import org.sonar.scanner.repository.ContextPropertiesCache;
import org.sonar.scanner.scan.branch.BranchConfiguration;
-import org.sonar.scanner.scan.measure.MeasureCache;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -79,11 +77,12 @@ public class DefaultSensorStorageTest {
private DefaultSensorStorage underTest;
private MapSettings settings;
private IssuePublisher moduleIssues;
- private MeasureCache measureCache;
private ScannerReportWriter reportWriter;
private ContextPropertiesCache contextPropertiesCache = new ContextPropertiesCache();
private BranchConfiguration branchConfiguration;
private DefaultInputProject project;
+ private ScannerReportReader reportReader;
+ private ReportPublisher reportPublisher;
@Before
public void prepare() throws Exception {
@@ -94,17 +93,18 @@ public class DefaultSensorStorageTest {
settings = new MapSettings();
moduleIssues = mock(IssuePublisher.class);
- measureCache = mock(MeasureCache.class);
- ReportPublisher reportPublisher = mock(ReportPublisher.class);
- reportWriter = new ScannerReportWriter(temp.newFolder());
+ reportPublisher = mock(ReportPublisher.class);
+ final File reportDir = temp.newFolder();
+ reportWriter = new ScannerReportWriter(reportDir);
+ reportReader = new ScannerReportReader(reportDir);
when(reportPublisher.getWriter()).thenReturn(reportWriter);
+ when(reportPublisher.getReader()).thenReturn(reportReader);
branchConfiguration = mock(BranchConfiguration.class);
underTest = new DefaultSensorStorage(metricFinder,
- moduleIssues, settings.asConfig(), reportPublisher, measureCache,
- mock(SonarCpdBlockIndex.class), contextPropertiesCache, new ScannerMetrics(), branchConfiguration);
+ moduleIssues, settings.asConfig(), reportPublisher, mock(SonarCpdBlockIndex.class), contextPropertiesCache, new ScannerMetrics(), branchConfiguration);
project = new DefaultInputProject(ProjectDefinition.create()
.setKey("foo")
@@ -132,7 +132,7 @@ public class DefaultSensorStorageTest {
.forMetric(CoreMetrics.LINES)
.withValue(10));
- verifyNoMoreInteractions(measureCache);
+ verifyNoMoreInteractions(reportPublisher);
}
@Test
@@ -145,7 +145,7 @@ public class DefaultSensorStorageTest {
.forMetric(CoreMetrics.LINES)
.withValue(10));
- verifyNoMoreInteractions(measureCache);
+ verifyNoMoreInteractions(reportPublisher);
}
@Test
@@ -209,35 +209,32 @@ public class DefaultSensorStorageTest {
@Test
public void should_save_file_measure() {
- InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();
+ DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php")
+ .build();
- ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
- when(measureCache.put(eq(file.key()), eq(CoreMetrics.NCLOC_KEY), argumentCaptor.capture())).thenReturn(null);
underTest.store(new DefaultMeasure()
.on(file)
.forMetric(CoreMetrics.NCLOC)
.withValue(10));
- DefaultMeasure m = argumentCaptor.getValue();
- assertThat(m.value()).isEqualTo(10);
- assertThat(m.metric()).isEqualTo(CoreMetrics.NCLOC);
+ ScannerReport.Measure m = reportReader.readComponentMeasures(file.scannerId()).next();
+ assertThat(m.getIntValue().getValue()).isEqualTo(10);
+ assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY);
}
@Test
public void should_not_skip_file_measures_on_short_lived_branch_or_pull_request_when_file_status_is_SAME() {
- InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build();
+ DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build();
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
- ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
- when(measureCache.put(eq(file.key()), eq(CoreMetrics.LINES_TO_COVER_KEY), argumentCaptor.capture())).thenReturn(null);
underTest.store(new DefaultMeasure()
.on(file)
- .forMetric(CoreMetrics.LINES_TO_COVER)
+ .forMetric(CoreMetrics.NCLOC)
.withValue(10));
- DefaultMeasure m = argumentCaptor.getValue();
- assertThat(m.value()).isEqualTo(10);
- assertThat(m.metric()).isEqualTo(CoreMetrics.LINES_TO_COVER);
+ ScannerReport.Measure m = reportReader.readComponentMeasures(file.scannerId()).next();
+ assertThat(m.getIntValue().getValue()).isEqualTo(10);
+ assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY);
}
@Test
@@ -272,17 +269,14 @@ public class DefaultSensorStorageTest {
String projectKey = "myProject";
DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create().setKey(projectKey).setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
- ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
- when(measureCache.put(eq(module.key()), eq(CoreMetrics.NCLOC_KEY), argumentCaptor.capture())).thenReturn(null);
-
underTest.store(new DefaultMeasure()
.on(module)
.forMetric(CoreMetrics.NCLOC)
.withValue(10));
- DefaultMeasure m = argumentCaptor.getValue();
- assertThat(m.value()).isEqualTo(10);
- assertThat(m.metric()).isEqualTo(CoreMetrics.NCLOC);
+ ScannerReport.Measure m = reportReader.readComponentMeasures(module.scannerId()).next();
+ assertThat(m.getIntValue().getValue()).isEqualTo(10);
+ assertThat(m.getMetricKey()).isEqualTo(CoreMetrics.NCLOC_KEY);
}
@Test(expected = UnsupportedOperationException.class)
@@ -321,36 +315,4 @@ public class DefaultSensorStorageTest {
assertThat(contextPropertiesCache.getAll()).containsOnly(entry("foo", "bar"));
}
- @Test
- public void shouldValidateStrictlyPositiveLine() throws Exception {
- InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build();
- Map<Integer, Integer> map = ImmutableMap.of(0, 3);
- String data = KeyValueFormat.format(map);
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("must be > 0");
- underTest.validateCoverageMeasure(data, file);
- }
-
- @Test
- public void shouldValidateMaxLine() throws Exception {
- InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build();
- Map<Integer, Integer> map = ImmutableMap.of(11, 3);
- String data = KeyValueFormat.format(map);
-
- thrown.expect(IllegalStateException.class);
- underTest.validateCoverageMeasure(data, file);
- }
-
- @Test
- public void mergeCoverageLineMetrics_should_be_sorted() {
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=1", "1=1")).isEqualTo("1=2");
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=1", "2=1")).isEqualTo("1=1;2=1");
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA, "2=1", "1=1")).isEqualTo("1=1;2=1");
-
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "1=1", "1=1")).isEqualTo("1=1");
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "1=1", "2=1")).isEqualTo("1=1;2=1");
- assertThat(DefaultSensorStorage.mergeCoverageLineMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE, "2=1", "1=1")).isEqualTo("1=1;2=1");
- }
-
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StorageTest.java
deleted file mode 100644
index 45e9e1e7c5e..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StorageTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import com.google.common.collect.Iterables;
-import org.junit.Test;
-import org.sonar.scanner.index.AbstractCachesTest;
-import org.sonar.scanner.storage.Storage.Entry;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class StorageTest extends AbstractCachesTest {
-
- @Test
- public void one_part_key() {
- Storage<String> cache = caches.createCache("capitals");
-
- assertThat(cache.get("france")).isNull();
-
- cache.put("france", "paris");
- cache.put("italy", "rome");
- assertThat(cache.get("france")).isEqualTo("paris");
- assertThat(cache.keySet()).containsOnly("france", "italy");
- assertThat(cache.keySet("france")).isEmpty();
- Iterable<String> values = cache.values();
- assertThat(values).containsOnly("paris", "rome");
- assertThat(values).containsOnly("paris", "rome");
- assertThat(cache.containsKey("france")).isTrue();
-
- Iterable<Entry<String>> iterable = cache.entries();
- Storage.Entry[] entries = Iterables.toArray(iterable, Storage.Entry.class);
- assertThat(entries).hasSize(2);
- assertThat(iterable).hasSize(2);
- assertThat(entries[0].key()[0]).isEqualTo("france");
- assertThat(entries[0].value()).isEqualTo("paris");
- assertThat(entries[1].key()[0]).isEqualTo("italy");
- assertThat(entries[1].value()).isEqualTo("rome");
-
- cache.remove("france");
- assertThat(cache.get("france")).isNull();
- assertThat(cache.get("italy")).isEqualTo("rome");
- assertThat(cache.keySet()).containsOnly("italy");
- assertThat(cache.keySet("france")).isEmpty();
- assertThat(cache.containsKey("france")).isFalse();
- assertThat(cache.containsKey("italy")).isTrue();
- assertThat(values).containsOnly("rome");
-
- cache.clear();
- assertThat(values).isEmpty();
- }
-
- @Test
- public void test_key_being_prefix_of_another_key() throws Exception {
- Storage<String> cache = caches.createCache("components");
-
- cache.put("struts-el:org.apache.strutsel.taglib.html.ELButtonTag", "the Tag");
- cache.put("struts-el:org.apache.strutsel.taglib.html.ELButtonTagBeanInfo", "the BeanInfo");
-
- assertThat(cache.get("struts-el:org.apache.strutsel.taglib.html.ELButtonTag")).isEqualTo("the Tag");
- assertThat(cache.get("struts-el:org.apache.strutsel.taglib.html.ELButtonTagBeanInfo")).isEqualTo("the BeanInfo");
- }
-
- @Test
- public void two_parts_key() {
- Storage<String> cache = caches.createCache("capitals");
-
- assertThat(cache.get("europe", "france")).isNull();
-
- cache.put("europe", "france", "paris");
- cache.put("europe", "italy", "rome");
- cache.put("asia", "china", "pekin");
- assertThat(cache.get("europe")).isNull();
- assertThat(cache.get("europe", "france")).isEqualTo("paris");
- assertThat(cache.get("europe", "italy")).isEqualTo("rome");
- assertThat(cache.get("europe")).isNull();
- assertThat(cache.keySet("europe")).containsOnly("france", "italy");
- assertThat(cache.keySet()).containsOnly("europe", "asia");
- assertThat(cache.containsKey("europe")).isFalse();
- assertThat(cache.containsKey("europe", "france")).isTrue();
- assertThat(cache.containsKey("europe", "spain")).isFalse();
- assertThat(cache.values()).containsOnly("paris", "rome", "pekin");
- assertThat(cache.values("america")).isEmpty();
- assertThat(cache.values("europe")).containsOnly("paris", "rome");
- assertThat(cache.values("oceania")).isEmpty();
-
- Iterable<Entry<String>> iterable = cache.entries();
- Storage.Entry[] allEntries = Iterables.toArray(iterable, Storage.Entry.class);
- assertThat(allEntries).hasSize(3);
- assertThat(iterable).hasSize(3);
- assertThat(allEntries[0].key()).isEqualTo(new String[] {"asia", "china"});
- assertThat(allEntries[0].value()).isEqualTo("pekin");
- assertThat(allEntries[1].key()).isEqualTo(new String[] {"europe", "france"});
- assertThat(allEntries[1].value()).isEqualTo("paris");
- assertThat(allEntries[2].key()).isEqualTo(new String[] {"europe", "italy"});
- assertThat(allEntries[2].value()).isEqualTo("rome");
-
- Iterable<Entry<String>> iterable2 = cache.entries("europe");
- Storage.Entry[] subEntries = Iterables.toArray(iterable2, Storage.Entry.class);
- assertThat(subEntries).hasSize(2);
- assertThat(iterable2).hasSize(2);
- assertThat(subEntries[0].key()).isEqualTo(new String[] {"europe", "france"});
- assertThat(subEntries[0].value()).isEqualTo("paris");
- assertThat(subEntries[1].key()).isEqualTo(new String[] {"europe", "italy"});
- assertThat(subEntries[1].value()).isEqualTo("rome");
-
- cache.remove("europe", "france");
- assertThat(cache.values()).containsOnly("rome", "pekin");
- assertThat(cache.get("europe", "france")).isNull();
- assertThat(cache.get("europe", "italy")).isEqualTo("rome");
- assertThat(cache.containsKey("europe", "france")).isFalse();
- assertThat(cache.keySet("europe")).containsOnly("italy");
-
- cache.clear("america");
- assertThat(cache.keySet()).containsOnly("europe", "asia");
- cache.clear();
- assertThat(cache.keySet()).isEmpty();
- }
-
- @Test
- public void three_parts_key() {
- Storage<String> cache = caches.createCache("places");
- assertThat(cache.get("europe", "france", "paris")).isNull();
-
- cache.put("europe", "france", "paris", "eiffel tower");
- cache.put("europe", "france", "annecy", "lake");
- cache.put("europe", "france", "poitiers", "notre dame");
- cache.put("europe", "italy", "rome", "colosseum");
- cache.put("europe2", "ukrania", "kiev", "dunno");
- cache.put("asia", "china", "pekin", "great wall");
- cache.put("america", "us", "new york", "empire state building");
- assertThat(cache.get("europe")).isNull();
- assertThat(cache.get("europe", "france")).isNull();
- assertThat(cache.get("europe", "france", "paris")).isEqualTo("eiffel tower");
- assertThat(cache.get("europe", "france", "annecy")).isEqualTo("lake");
- assertThat(cache.get("europe", "italy", "rome")).isEqualTo("colosseum");
- assertThat(cache.keySet()).containsOnly("europe", "asia", "america", "europe2");
- assertThat(cache.keySet("europe")).containsOnly("france", "italy");
- assertThat(cache.keySet("europe", "france")).containsOnly("annecy", "paris", "poitiers");
- assertThat(cache.containsKey("europe")).isFalse();
- assertThat(cache.containsKey("europe", "france")).isFalse();
- assertThat(cache.containsKey("europe", "france", "annecy")).isTrue();
- assertThat(cache.containsKey("europe", "france", "biarritz")).isFalse();
- assertThat(cache.values()).containsOnly("eiffel tower", "lake", "colosseum", "notre dame", "great wall", "empire state building", "dunno");
- assertThat(cache.values("europe")).containsOnly("eiffel tower", "lake", "colosseum", "notre dame");
- assertThat(cache.values("europe", "france")).containsOnly("eiffel tower", "lake", "notre dame");
-
- Iterable<Entry<String>> iterable = cache.entries();
- Storage.Entry[] allEntries = Iterables.toArray(iterable, Storage.Entry.class);
- assertThat(allEntries).hasSize(7);
- assertThat(iterable).hasSize(7);
- assertThat(allEntries[0].key()).isEqualTo(new String[] {"america", "us", "new york"});
- assertThat(allEntries[0].value()).isEqualTo("empire state building");
- assertThat(allEntries[1].key()).isEqualTo(new String[] {"asia", "china", "pekin"});
- assertThat(allEntries[1].value()).isEqualTo("great wall");
- assertThat(allEntries[2].key()).isEqualTo(new String[] {"europe", "france", "annecy"});
- assertThat(allEntries[2].value()).isEqualTo("lake");
- assertThat(allEntries[3].key()).isEqualTo(new String[] {"europe", "france", "paris"});
- assertThat(allEntries[3].value()).isEqualTo("eiffel tower");
- assertThat(allEntries[4].key()).isEqualTo(new String[] {"europe", "france", "poitiers"});
- assertThat(allEntries[4].value()).isEqualTo("notre dame");
- assertThat(allEntries[5].key()).isEqualTo(new String[] {"europe", "italy", "rome"});
- assertThat(allEntries[5].value()).isEqualTo("colosseum");
-
- Iterable<Entry<String>> iterable2 = cache.entries("europe");
- Storage.Entry[] subEntries = Iterables.toArray(iterable2, Storage.Entry.class);
- assertThat(subEntries).hasSize(4);
- assertThat(iterable2).hasSize(4);
- assertThat(subEntries[0].key()).isEqualTo(new String[] {"europe", "france", "annecy"});
- assertThat(subEntries[0].value()).isEqualTo("lake");
- assertThat(subEntries[1].key()).isEqualTo(new String[] {"europe", "france", "paris"});
- assertThat(subEntries[1].value()).isEqualTo("eiffel tower");
- assertThat(subEntries[2].key()).isEqualTo(new String[] {"europe", "france", "poitiers"});
- assertThat(subEntries[2].value()).isEqualTo("notre dame");
- assertThat(subEntries[3].key()).isEqualTo(new String[] {"europe", "italy", "rome"});
- assertThat(subEntries[3].value()).isEqualTo("colosseum");
-
- cache.remove("europe", "france", "annecy");
- assertThat(cache.values()).containsOnly("eiffel tower", "colosseum", "notre dame", "great wall", "empire state building", "dunno");
- assertThat(cache.values("europe")).containsOnly("eiffel tower", "colosseum", "notre dame");
- assertThat(cache.values("europe", "france")).containsOnly("eiffel tower", "notre dame");
- assertThat(cache.get("europe", "france", "annecy")).isNull();
- assertThat(cache.get("europe", "italy", "rome")).isEqualTo("colosseum");
- assertThat(cache.containsKey("europe", "france")).isFalse();
-
- cache.clear("europe", "italy");
- assertThat(cache.values()).containsOnly("eiffel tower", "notre dame", "great wall", "empire state building", "dunno");
-
- cache.clear("europe");
- assertThat(cache.values()).containsOnly("great wall", "empire state building", "dunno");
-
- cache.clear();
- assertThat(cache.values()).isEmpty();
- }
-
- @Test
- public void remove_versus_clear() {
- Storage<String> cache = caches.createCache("capitals");
- cache.put("europe", "france", "paris");
- cache.put("europe", "italy", "rome");
-
- // remove("europe") does not remove sub-keys
- cache.remove("europe");
- assertThat(cache.values()).containsOnly("paris", "rome");
-
- // clear("europe") removes sub-keys
- cache.clear("europe");
- assertThat(cache.values()).isEmpty();
- }
-
- @Test
- public void empty_cache() {
- Storage<String> cache = caches.createCache("empty");
-
- assertThat(cache.get("foo")).isNull();
- assertThat(cache.get("foo", "bar")).isNull();
- assertThat(cache.get("foo", "bar", "baz")).isNull();
- assertThat(cache.keySet()).isEmpty();
- assertThat(cache.keySet("foo")).isEmpty();
- assertThat(cache.containsKey("foo")).isFalse();
- assertThat(cache.containsKey("foo", "bar")).isFalse();
- assertThat(cache.containsKey("foo", "bar", "baz")).isFalse();
- assertThat(cache.values()).isEmpty();
- assertThat(cache.values("foo")).isEmpty();
-
- // do not fail
- cache.remove("foo");
- cache.remove("foo", "bar");
- cache.remove("foo", "bar", "baz");
- cache.clear("foo");
- cache.clear("foo", "bar");
- cache.clear("foo", "bar", "baz");
- cache.clear();
- }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesManagerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesManagerTest.java
deleted file mode 100644
index 5c43aa793d6..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesManagerTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import java.io.File;
-import org.junit.Test;
-import org.sonar.scanner.index.AbstractCachesTest;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class StoragesManagerTest extends AbstractCachesTest {
- @Test
- public void should_stop_and_clean_temp_dir() {
- File tempDir = cachesManager.tempDir();
- assertThat(tempDir).isDirectory().exists();
- assertThat(cachesManager.persistit()).isNotNull();
- assertThat(cachesManager.persistit().isInitialized()).isTrue();
-
- cachesManager.stop();
-
- assertThat(tempDir).doesNotExist();
- assertThat(cachesManager.tempDir()).isNull();
- assertThat(cachesManager.persistit()).isNull();
- }
-}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesTest.java
deleted file mode 100644
index e35ec4f8b16..00000000000
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/storage/StoragesTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.scanner.storage;
-
-import com.persistit.exception.PersistitException;
-import java.io.Serializable;
-import org.junit.Test;
-import org.sonar.scanner.index.AbstractCachesTest;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-public class StoragesTest extends AbstractCachesTest {
- @Test
- public void should_create_cache() {
- Storage<Element> cache = caches.createCache("foo");
- assertThat(cache).isNotNull();
- }
-
- @Test
- public void should_not_create_cache_twice() {
- caches.<Element>createCache("foo");
- try {
- caches.<Element>createCache("foo");
- fail();
- } catch (IllegalStateException e) {
- // ok
- }
- }
-
- @Test
- public void should_clean_resources() {
- Storage<String> c = caches.<String>createCache("test1");
- for (int i = 0; i < 1_000_000; i++) {
- c.put("a" + i, "a" + i);
- }
-
- caches.stop();
-
- // manager continues up
- assertThat(cachesManager.persistit().isInitialized()).isTrue();
-
- caches = new Storages(cachesManager);
- caches.start();
- caches.createCache("test1");
- }
-
- @Test
- public void leak_test() throws PersistitException {
- caches.stop();
-
- int len = 1 * 1024 * 1024;
- StringBuilder sb = new StringBuilder(len);
- for (int i = 0; i < len; i++) {
- sb.append("a");
- }
-
- for (int i = 0; i < 3; i++) {
- caches = new Storages(cachesManager);
- caches.start();
- Storage<String> c = caches.<String>createCache("test" + i);
- c.put("key" + i, sb.toString());
- cachesManager.persistit().flush();
-
- caches.stop();
- }
- }
-
- private static class Element implements Serializable {
- private static final long serialVersionUID = 1L;
-
- }
-}