comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:6
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
ncloc:13
complexity:7
-coverage:89.0
test_execution_time:630
-sqale_index:4830
#Used by dashboard/widgets tests
complexity_in_classes:3
classes:1
ncloc:13
complexity:7
-coverage:89.0
test_execution_time:630
-sqale_index:4830
complexity_in_classes:3
classes:1
comment_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
comment_lines:3
public_api:5
public_undocumented_api:2
-duplicated_files:1
-duplicated_blocks:2
-duplicated_lines:3
*/
package org.sonar.core.metric;
-import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
-import javax.annotation.Nullable;
+import java.util.stream.Collectors;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metrics;
-import static com.google.common.collect.FluentIterable.from;
-import static java.util.Arrays.asList;
import static org.sonar.api.measures.CoreMetrics.ACCESSORS;
import static org.sonar.api.measures.CoreMetrics.CLASSES;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES;
import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA;
import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE;
import static org.sonar.api.measures.CoreMetrics.DIRECTORIES;
+import static org.sonar.api.measures.CoreMetrics.EXECUTABLE_LINES_DATA;
import static org.sonar.api.measures.CoreMetrics.FILES;
import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION;
import static org.sonar.api.measures.CoreMetrics.FUNCTIONS;
import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION;
import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES;
import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC;
-import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.IT_COVERAGE_LINE_HITS_DATA;
-import static org.sonar.api.measures.CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.IT_LINES_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_CONDITIONS;
-import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_LINES;
import static org.sonar.api.measures.CoreMetrics.LINES;
import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER;
import static org.sonar.api.measures.CoreMetrics.NCLOC;
import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA;
import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_LINES_TO_COVER;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_CONDITIONS;
-import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_LINES;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_API;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_UNDOCUMENTED_API;
import static org.sonar.api.measures.CoreMetrics.SKIPPED_TESTS;
COVERED_CONDITIONS_BY_LINE,
CONDITIONS_BY_LINE,
- IT_LINES_TO_COVER,
- IT_UNCOVERED_LINES,
- IT_COVERAGE_LINE_HITS_DATA,
- IT_CONDITIONS_TO_COVER,
- IT_UNCOVERED_CONDITIONS,
- IT_COVERED_CONDITIONS_BY_LINE,
- IT_CONDITIONS_BY_LINE,
-
- OVERALL_LINES_TO_COVER,
- OVERALL_UNCOVERED_LINES,
- OVERALL_COVERAGE_LINE_HITS_DATA,
- OVERALL_CONDITIONS_TO_COVER,
- OVERALL_UNCOVERED_CONDITIONS,
- OVERALL_COVERED_CONDITIONS_BY_LINE,
- OVERALL_CONDITIONS_BY_LINE);
+ EXECUTABLE_LINES_DATA);
private final Set<Metric> metrics;
}
private static Iterable<Metric> getPluginMetrics(Metrics[] metricsRepositories) {
- return from(asList(metricsRepositories)).transformAndConcat(FlattenMetrics.INSTANCE);
- }
-
- private enum FlattenMetrics implements Function<Metrics, List<Metric>> {
- INSTANCE;
-
- @Nullable
- @Override
- public List<Metric> apply(Metrics input) {
- return input.getMetrics();
- }
+ return Arrays.stream(metricsRepositories)
+ .map(Metrics::getMetrics)
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
}
}
@Test
public void check_number_of_allowed_core_metrics() throws Exception {
- assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(47);
+ assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(34);
}
@Test
@Override
public void doSave() {
validateFile();
- Preconditions.checkNotNull(type, "Call ofType() first");
storage.store(this);
}
protected String url;
protected Integer personId;
protected PersistenceMode persistenceMode = PersistenceMode.FULL;
- private boolean fromCore;
public Measure(String metricKey) {
this.metricKey = metricKey;
&& isZeroVariation(variation1, variation2, variation3, variation4, variation5);
}
- /**
- * For internal use
- */
- public boolean isFromCore() {
- return fromCore;
- }
-
- /**
- * For internal use
- */
- public void setFromCore(boolean fromCore) {
- this.fromCore = fromCore;
- }
-
private static boolean isZeroVariation(Double... variations) {
for (Double variation : variations) {
if (variation != null && NumberUtils.compare(variation, 0.0) != 0) {
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.SensorContext;
+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.measures.Measure;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.KeyValueFormat.Converter;
import org.sonar.scanner.scan.measure.MeasureCache;
}
private Map loadData(String metricKey, Converter converter) {
- Measure measure = measureCache.byMetric(inputFile.key(), metricKey);
- String data = measure != null ? measure.getData() : null;
+ 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));
}
import org.sonar.api.resources.Resource;
import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.sensor.DefaultSensorContext;
-import org.sonar.scanner.sensor.coverage.CoverageExclusions;
public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext {
private final DefaultIndex index;
private final Project project;
- private final CoverageExclusions coverageFilter;
public DeprecatedSensorContext(InputModule module, DefaultIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules,
- AnalysisMode analysisMode, CoverageExclusions coverageFilter, SensorStorage sensorStorage, SonarRuntime sonarRuntime) {
+ AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime) {
super(module, settings, fs, activeRules, analysisMode, sensorStorage, sonarRuntime);
this.index = index;
this.project = project;
- this.coverageFilter = coverageFilter;
}
@Override
public Measure saveMeasure(Resource resource, Metric metric, Double value) {
Measure<?> measure = new Measure(metric, value);
- coverageFilter.validate(measure, resource.getPath());
return saveMeasure(resource, measure);
}
@Override
public Measure saveMeasure(Resource resource, Measure measure) {
Resource resourceOrProject = resourceOrProject(resource);
-
- if (coverageFilter.accept(resourceOrProject, measure)) {
- return index.addMeasure(resourceOrProject, measure);
- } else {
- return measure;
- }
+ return index.addMeasure(resourceOrProject, measure);
}
@Override
@Override
public Measure saveMeasure(InputFile inputFile, Metric metric, Double value) {
Measure<?> measure = new Measure(metric, value);
- coverageFilter.validate(measure, inputFile);
return saveMeasure(getResource(inputFile), measure);
}
@Override
public Measure saveMeasure(InputFile inputFile, Measure measure) {
- coverageFilter.validate(measure, inputFile);
return saveMeasure(getResource(inputFile), measure);
}
import com.persistit.Key;
import com.persistit.KeyFilter;
import com.persistit.exception.PersistitException;
-import org.apache.commons.lang.builder.ToStringBuilder;
-
-import javax.annotation.CheckForNull;
-
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
+import javax.annotation.CheckForNull;
+import org.apache.commons.lang.builder.ToStringBuilder;
/**
* <p>
exchange.store();
return this;
} catch (Exception e) {
- throw new IllegalStateException("Fail to put element in the cache " + name, e);
+ throw new IllegalStateException("Fail to put element in the storage '" + name + "'", e);
}
}
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.measure.MetricFinder;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.MeasuresFilters;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.util.stream.Collectors;
import org.sonar.scanner.DefaultProjectTree;
import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.sensor.DefaultSensorStorage;
private final BatchComponentCache componentCache;
private final MeasureCache measureCache;
private final DefaultProjectTree projectTree;
+ private final MetricFinder metricFinder;
// caches
private DefaultSensorStorage sensorStorage;
private Project currentProject;
private Map<Resource, Bucket> buckets = Maps.newLinkedHashMap();
- public DefaultIndex(BatchComponentCache componentCache, DefaultProjectTree projectTree, MeasureCache measureCache) {
+ public DefaultIndex(BatchComponentCache componentCache, DefaultProjectTree projectTree, MeasureCache measureCache, MetricFinder metricFinder) {
this.componentCache = componentCache;
this.projectTree = projectTree;
this.measureCache = measureCache;
+ this.metricFinder = metricFinder;
}
public void start() {
if (indexedResource == null) {
return null;
}
- Collection<Measure> unfiltered = new ArrayList<>();
+ Collection<DefaultMeasure<?>> unfiltered = new ArrayList<>();
if (filter instanceof MeasuresFilters.MetricFilter) {
// optimization
- Measure byMetric = measureCache.byMetric(indexedResource, ((MeasuresFilters.MetricFilter<M>) filter).filterOnMetricKey());
+ DefaultMeasure<?> byMetric = measureCache.byMetric(indexedResource.getEffectiveKey(), ((MeasuresFilters.MetricFilter<M>) filter).filterOnMetricKey());
if (byMetric != null) {
unfiltered.add(byMetric);
}
} else {
- for (Measure measure : measureCache.byResource(indexedResource)) {
+ for (DefaultMeasure<?> measure : measureCache.byComponentKey(indexedResource.getEffectiveKey())) {
unfiltered.add(measure);
}
}
- return filter.filter(unfiltered);
+ return filter.filter(unfiltered.stream().map(DefaultIndex::toDeprecated).collect(Collectors.toList()));
+ }
+
+ private static Measure toDeprecated(org.sonar.api.batch.sensor.measure.Measure<?> measure) {
+ org.sonar.api.measures.Measure deprecatedMeasure = new org.sonar.api.measures.Measure((Metric<?>) measure.metric());
+ setValueAccordingToMetricType(measure, deprecatedMeasure);
+ return deprecatedMeasure;
+ }
+
+ private static void setValueAccordingToMetricType(org.sonar.api.batch.sensor.measure.Measure<?> measure, Measure measureToSave) {
+ ValueType deprecatedType = ((Metric<?>) measure.metric()).getType();
+ switch (deprecatedType) {
+ case BOOL:
+ measureToSave.setValue(Boolean.TRUE.equals(measure.value()) ? 1.0 : 0.0);
+ break;
+ case INT:
+ case MILLISEC:
+ case WORK_DUR:
+ case FLOAT:
+ case PERCENT:
+ case RATING:
+ measureToSave.setValue(((Number) measure.value()).doubleValue());
+ break;
+ case STRING:
+ case LEVEL:
+ case DATA:
+ case DISTRIB:
+ measureToSave.setData((String) measure.value());
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported type :" + deprecatedType);
+ }
}
public Measure addMeasure(Resource resource, Measure measure) {
Bucket bucket = getBucket(resource);
if (bucket != null) {
- sensorStorage.saveMeasure(resource, measure);
+ if (sensorStorage.isDeprecatedMetric(measure.getMetricKey())) {
+ // Ignore deprecated metrics
+ return measure;
+ }
+ org.sonar.api.batch.measure.Metric<?> metric = metricFinder.findByKey(measure.getMetricKey());
+ if (metric == null) {
+ throw new UnsupportedOperationException("Unknown metric: " + measure.getMetricKey());
+ }
+ DefaultMeasure<?> newMeasure;
+ if (Boolean.class.equals(metric.valueType())) {
+ newMeasure = new DefaultMeasure<Boolean>().forMetric((Metric<Boolean>) metric)
+ .withValue(measure.getValue() != 0.0);
+ } else if (Integer.class.equals(metric.valueType())) {
+ newMeasure = new DefaultMeasure<Integer>().forMetric((Metric<Integer>) metric)
+ .withValue(measure.getValue().intValue());
+ } else if (Double.class.equals(metric.valueType())) {
+ newMeasure = new DefaultMeasure<Double>().forMetric((Metric<Double>) metric)
+ .withValue(measure.getValue().doubleValue());
+ } else if (String.class.equals(metric.valueType())) {
+ newMeasure = new DefaultMeasure<String>().forMetric((Metric<String>) metric)
+ .withValue(measure.getData());
+ } else if (Long.class.equals(metric.valueType())) {
+ newMeasure = new DefaultMeasure<Long>().forMetric((Metric<Long>) metric)
+ .withValue(measure.getValue().longValue());
+ } else {
+ throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
+ }
+ sensorStorage.saveMeasure(componentCache.get(resource).inputComponent(), newMeasure);
}
return measure;
}
import javax.annotation.Nonnull;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
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.scan.measure.MeasureCache;
import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.index.BatchComponentCache;
+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.measure.MeasureCache;
public class CoveragePublisher implements ReportPublisherStep {
}
void applyLineMeasure(String inputFileKey, int lineCount, String metricKey, Map<Integer, LineCoverage.Builder> coveragePerLine, MeasureOperation op) {
- Measure measure = measureCache.byMetric(inputFileKey, metricKey);
+ 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()) {
package org.sonar.scanner.report;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import java.io.Serializable;
-import java.util.Set;
import javax.annotation.Nonnull;
import org.sonar.api.batch.measure.Metric;
-import org.sonar.api.measures.Measure;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.index.BatchComponentCache;
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.scan.measure.MeasureCache;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.scan.measure.MeasureCache;
-import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
-import static com.google.common.collect.Sets.newHashSet;
public class MeasuresPublisher implements ReportPublisherStep {
- private static final class MeasureToReportMeasure implements Function<Measure, ScannerReport.Measure> {
+ private static final class MeasureToReportMeasure implements Function<DefaultMeasure, ScannerReport.Measure> {
private final BatchComponent resource;
private final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
}
@Override
- public ScannerReport.Measure apply(@Nonnull Measure input) {
+ public ScannerReport.Measure apply(@Nonnull DefaultMeasure input) {
validateMeasure(input, resource.key());
return toReportMeasure(builder, input);
}
- private static void validateMeasure(Measure measure, String componentKey) {
- if (measure.getValue() == null && measure.getData() == null) {
- throw new IllegalArgumentException(String.format("Measure on metric '%s' and component '%s' has no value, but it's not allowed", measure.getMetricKey(), componentKey));
+ private static void validateMeasure(DefaultMeasure measure, String componentKey) {
+ if (measure.value() == null) {
+ throw new IllegalArgumentException(String.format("Measure on metric '%s' and component '%s' has no value, but it's not allowed", measure.metric().key(), componentKey));
}
}
- private ScannerReport.Measure toReportMeasure(ScannerReport.Measure.Builder builder, Measure measure) {
+ private static ScannerReport.Measure toReportMeasure(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
builder.clear();
- builder.setMetricKey(measure.getMetricKey());
+ builder.setMetricKey(measure.metric().key());
setValueAccordingToType(builder, measure);
return builder.build();
}
- private void setValueAccordingToType(ScannerReport.Measure.Builder builder, Measure measure) {
+ private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
Serializable value = measure.value();
- String data = measure.getData() != null ? measure.getData() : "";
- switch (measure.getMetric().getType()) {
- case INT:
- case RATING:
- builder.setIntValue(IntValue.newBuilder().setValue(((Number) value).intValue()).setData(data));
- break;
- case FLOAT:
- case PERCENT:
- builder.setDoubleValue(DoubleValue.newBuilder().setValue(((Number) value).doubleValue()).setData(data));
- break;
- case BOOL:
- builder.setBooleanValue(BoolValue.newBuilder().setValue(((Boolean) value).booleanValue()).setData(data));
- break;
- case WORK_DUR:
- case MILLISEC:
- builder.setLongValue(LongValue.newBuilder().setValue(((Number) value).longValue()).setData(data));
- break;
- case STRING:
- case DATA:
- case LEVEL:
- case DISTRIB:
- builder.setStringValue(StringValue.newBuilder().setValue((String) value));
- break;
- default:
- throw new IllegalStateException("Unknown metric type: " + measure.getMetric().getType());
+ 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 static final class IsMetricAllowed implements Predicate<Measure> {
- private final Set<String> allowedMetricKeys;
-
- private IsMetricAllowed(Set<String> allowedMetricKeys) {
- this.allowedMetricKeys = allowedMetricKeys;
- }
-
- @Override
- public boolean apply(Measure input) {
- return allowedMetricKeys.contains(input.getMetricKey());
- }
- }
-
private static final class MetricToKey implements Function<Metric, String> {
@Override
public String apply(Metric input) {
@Override
public void publish(ScannerReportWriter writer) {
- final Set<String> allowedMetricKeys = newHashSet(transform(scannerMetrics.getMetrics(), new MetricToKey()));
for (final BatchComponent resource : resourceCache.all()) {
- Iterable<Measure> batchMeasures = measureCache.byResource(resource.resource());
- Iterable<org.sonar.scanner.protocol.output.ScannerReport.Measure> reportMeasures = transform(
- filter(batchMeasures, new IsMetricAllowed(allowedMetricKeys)),
- new MeasureToReportMeasure(resource));
+ Iterable<DefaultMeasure<?>> scannerMeasures = measureCache.byComponentKey(resource.key());
+ Iterable<ScannerReport.Measure> reportMeasures = transform(scannerMeasures, new MeasureToReportMeasure(resource));
writer.writeComponentMeasures(resource.batchId(), reportMeasures);
}
}
import javax.annotation.CheckForNull;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.Resource;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.scanner.index.Cache;
-import org.sonar.scanner.index.Caches;
import org.sonar.scanner.index.Cache.Entry;
+import org.sonar.scanner.index.Caches;
/**
* Cache of all measures. This cache is shared amongst all project modules.
@ScannerSide
public class MeasureCache {
- private final Cache<Measure> cache;
+ private final Cache<DefaultMeasure<?>> cache;
public MeasureCache(Caches caches, MetricFinder metricFinder) {
- caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder));
+ caches.registerValueCoder(DefaultMeasure.class, new MeasureValueCoder(metricFinder));
cache = caches.createCache("measures");
}
- public Iterable<Entry<Measure>> entries() {
+ public Iterable<Entry<DefaultMeasure<?>>> entries() {
return cache.entries();
}
- public Iterable<Measure> all() {
+ public Iterable<DefaultMeasure<?>> all() {
return cache.values();
}
- public Iterable<Measure> byResource(Resource r) {
- return byComponentKey(r.getEffectiveKey());
- }
-
- public Iterable<Measure> byComponentKey(String effectiveKey) {
+ public Iterable<DefaultMeasure<?>> byComponentKey(String effectiveKey) {
return cache.values(effectiveKey);
}
@CheckForNull
- public Measure byMetric(Resource r, String metricKey) {
- return byMetric(r.getEffectiveKey(), metricKey);
- }
-
- @CheckForNull
- public Measure byMetric(String componentKey, String metricKey) {
+ public DefaultMeasure<?> byMetric(String componentKey, String metricKey) {
return cache.get(componentKey, metricKey);
}
- public MeasureCache put(Resource resource, Measure measure) {
- Preconditions.checkNotNull(resource.getEffectiveKey());
- Preconditions.checkNotNull(measure.getMetricKey());
- cache.put(resource.getEffectiveKey(), measure.getMetricKey(), measure);
+ 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(Resource resource, Measure measure) {
- Preconditions.checkNotNull(resource.getEffectiveKey());
- Preconditions.checkNotNull(measure.getMetricKey());
- return cache.containsKey(resource.getEffectiveKey(), measure.getMetricKey());
+ public boolean contains(String componentKey, String metricKey) {
+ Preconditions.checkNotNull(componentKey);
+ Preconditions.checkNotNull(metricKey);
+ return cache.containsKey(componentKey, metricKey);
}
}
import com.persistit.Value;
import com.persistit.encoding.CoderContext;
import com.persistit.encoding.ValueCoder;
-import javax.annotation.Nullable;
+import java.io.Serializable;
import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.PersistenceMode;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
class MeasureValueCoder implements ValueCoder {
@Override
public void put(Value value, Object object, CoderContext context) {
- Measure<?> m = (Measure) object;
- value.putUTF(m.getMetricKey());
- value.put(m.getValue());
- putUTFOrNull(value, m.getData());
- putUTFOrNull(value, m.getDescription());
- value.putString(m.getAlertStatus() != null ? m.getAlertStatus().name() : null);
- putUTFOrNull(value, m.getAlertText());
- value.putDate(m.getDate());
- value.put(m.getVariation1());
- value.put(m.getVariation2());
- value.put(m.getVariation3());
- value.put(m.getVariation4());
- value.put(m.getVariation5());
- putUTFOrNull(value, m.getUrl());
- Integer personId = m.getPersonId();
- value.put(personId != null ? personId.intValue() : null);
- PersistenceMode persistenceMode = m.getPersistenceMode();
- value.putString(persistenceMode != null ? persistenceMode.name() : null);
- }
-
- private static void putUTFOrNull(Value value, @Nullable String utfOrNull) {
- if (utfOrNull != null) {
- value.putUTF(utfOrNull);
- } else {
- value.putNull();
- }
+ 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) {
- Measure<?> m = new Measure();
String metricKey = value.getString();
- org.sonar.api.batch.measure.Metric metric = metricFinder.findByKey(metricKey);
+ org.sonar.api.batch.measure.Metric<?> metric = metricFinder.findByKey(metricKey);
if (metric == null) {
throw new IllegalStateException("Unknow metric with key " + metricKey);
}
- m.setMetric((org.sonar.api.measures.Metric) metric);
- m.setRawValue(value.isNull(true) ? null : value.getDouble());
- m.setData(value.getString());
- m.setDescription(value.getString());
- m.setAlertStatus(value.isNull(true) ? null : Metric.Level.valueOf(value.getString()));
- m.setAlertText(value.getString());
- m.setDate(value.getDate());
- m.setVariation1(value.isNull(true) ? null : value.getDouble());
- m.setVariation2(value.isNull(true) ? null : value.getDouble());
- m.setVariation3(value.isNull(true) ? null : value.getDouble());
- m.setVariation4(value.isNull(true) ? null : value.getDouble());
- m.setVariation5(value.isNull(true) ? null : value.getDouble());
- m.setUrl(value.getString());
- m.setPersonId(value.isNull(true) ? null : value.getInt());
- m.setPersistenceMode(value.isNull(true) ? null : PersistenceMode.valueOf(value.getString()));
+ DefaultMeasure<?> m = new DefaultMeasure()
+ .forMetric(metric)
+ .withValue((Serializable) value.get());
return m;
}
}
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.annotation.Nonnull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.batch.sensor.coverage.CoverageType;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Settings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Resource;
import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.SonarException;
+import org.sonar.core.metric.ScannerMetrics;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.internal.pmd.PmdBlockChunker;
import org.sonar.scanner.cpd.deprecated.DefaultCpdBlockIndexer;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
-import org.sonar.scanner.index.BatchComponent;
import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.issue.ModuleIssues;
import org.sonar.scanner.protocol.output.FileStructure;
import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.sensor.coverage.CoverageExclusions;
+import static org.sonar.api.measures.CoreMetrics.BRANCH_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.COMMENTED_OUT_CODE_LINES_KEY;
+import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER;
+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.COVERED_CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.DEPENDENCY_MATRIX_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORY_CYCLES_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORY_EDGES_WEIGHT_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORY_FEEDBACK_EDGES_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORY_TANGLES_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORY_TANGLE_INDEX_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILE_CYCLES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILE_EDGES_WEIGHT_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILE_FEEDBACK_EDGES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILE_TANGLES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILE_TANGLE_INDEX_KEY;
+import static org.sonar.api.measures.CoreMetrics.IT_BRANCH_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.IT_CONDITIONS_TO_COVER;
+import static org.sonar.api.measures.CoreMetrics.IT_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.IT_COVERAGE_LINE_HITS_DATA;
+import static org.sonar.api.measures.CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.IT_LINES_TO_COVER;
+import static org.sonar.api.measures.CoreMetrics.IT_LINE_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_CONDITIONS;
+import static org.sonar.api.measures.CoreMetrics.IT_UNCOVERED_LINES;
+import static org.sonar.api.measures.CoreMetrics.LINES;
+import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER;
+import static org.sonar.api.measures.CoreMetrics.LINE_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_BRANCH_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_CONDITIONS_TO_COVER;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_LINES_TO_COVER;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_LINE_COVERAGE;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_CONDITIONS;
+import static org.sonar.api.measures.CoreMetrics.OVERALL_UNCOVERED_LINES;
+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_LINES;
+
public class DefaultSensorStorage implements SensorStorage {
private static final Logger LOG = LoggerFactory.getLogger(DefaultSensorStorage.class);
- private static final List<Metric> INTERNAL_METRICS = Arrays.<Metric>asList(
+ private static final List<Metric<?>> INTERNAL_METRICS = Arrays.<Metric<?>>asList(
// Computed by LinesSensor
- CoreMetrics.LINES);
+ LINES);
private static final List<String> DEPRECATED_METRICS_KEYS = Arrays.asList(
- CoreMetrics.DEPENDENCY_MATRIX_KEY,
- CoreMetrics.DIRECTORY_CYCLES_KEY,
- CoreMetrics.DIRECTORY_EDGES_WEIGHT_KEY,
- CoreMetrics.DIRECTORY_FEEDBACK_EDGES_KEY,
- CoreMetrics.DIRECTORY_TANGLE_INDEX_KEY,
- CoreMetrics.DIRECTORY_TANGLES_KEY,
- CoreMetrics.FILE_CYCLES_KEY,
- CoreMetrics.FILE_EDGES_WEIGHT_KEY,
- CoreMetrics.FILE_FEEDBACK_EDGES_KEY,
- CoreMetrics.FILE_TANGLE_INDEX_KEY,
- CoreMetrics.FILE_TANGLES_KEY);
+ DEPENDENCY_MATRIX_KEY,
+ DIRECTORY_CYCLES_KEY,
+ DIRECTORY_EDGES_WEIGHT_KEY,
+ DIRECTORY_FEEDBACK_EDGES_KEY,
+ DIRECTORY_TANGLE_INDEX_KEY,
+ DIRECTORY_TANGLES_KEY,
+ FILE_CYCLES_KEY,
+ FILE_EDGES_WEIGHT_KEY,
+ FILE_FEEDBACK_EDGES_KEY,
+ FILE_TANGLE_INDEX_KEY,
+ FILE_TANGLES_KEY,
+ COMMENTED_OUT_CODE_LINES_KEY);
+
+ private static final List<String> COMPUTED_ON_CE_SIDE_METRICS_KEYS = Arrays.asList(
+ TEST_SUCCESS_DENSITY_KEY,
+ PUBLIC_DOCUMENTED_API_DENSITY_KEY);
private final MetricFinder metricFinder;
private final ModuleIssues moduleIssues;
private final SonarCpdBlockIndex index;
private final ContextPropertiesCache contextPropertiesCache;
private final Settings settings;
+ private final ScannerMetrics scannerMetrics;
+ private final Map<Metric<?>, Metric<?>> deprecatedCoverageMetricMapping = new IdentityHashMap<>();
+ private final Set<Metric<?>> coverageMetrics = new HashSet<>();
+ private final Set<Metric<?>> byLineMetrics = new HashSet<>();
public DefaultSensorStorage(MetricFinder metricFinder, ModuleIssues moduleIssues,
Settings settings,
CoverageExclusions coverageExclusions, BatchComponentCache componentCache, ReportPublisher reportPublisher,
MeasureCache measureCache, SonarCpdBlockIndex index,
- ContextPropertiesCache contextPropertiesCache) {
+ ContextPropertiesCache contextPropertiesCache, ScannerMetrics scannerMetrics) {
this.metricFinder = metricFinder;
this.moduleIssues = moduleIssues;
this.settings = settings;
this.measureCache = measureCache;
this.index = index;
this.contextPropertiesCache = contextPropertiesCache;
- }
+ this.scannerMetrics = scannerMetrics;
- private Metric findMetricOrFail(String metricKey) {
- Metric m = (Metric) metricFinder.findByKey(metricKey);
- if (m == null) {
- throw new IllegalStateException("Unknow metric with key: " + metricKey);
- }
- return m;
+ coverageMetrics.add(UNCOVERED_LINES);
+ coverageMetrics.add(LINES_TO_COVER);
+ coverageMetrics.add(UNCOVERED_CONDITIONS);
+ coverageMetrics.add(CONDITIONS_TO_COVER);
+ coverageMetrics.add(CONDITIONS_BY_LINE);
+ coverageMetrics.add(COVERED_CONDITIONS_BY_LINE);
+ coverageMetrics.add(COVERAGE_LINE_HITS_DATA);
+
+ byLineMetrics.add(COVERAGE_LINE_HITS_DATA);
+ byLineMetrics.add(COVERED_CONDITIONS_BY_LINE);
+ byLineMetrics.add(CONDITIONS_BY_LINE);
+
+ deprecatedCoverageMetricMapping.put(IT_COVERAGE, COVERAGE);
+ deprecatedCoverageMetricMapping.put(IT_LINE_COVERAGE, LINE_COVERAGE);
+ deprecatedCoverageMetricMapping.put(IT_BRANCH_COVERAGE, BRANCH_COVERAGE);
+ deprecatedCoverageMetricMapping.put(IT_UNCOVERED_LINES, UNCOVERED_LINES);
+ deprecatedCoverageMetricMapping.put(IT_LINES_TO_COVER, LINES_TO_COVER);
+ deprecatedCoverageMetricMapping.put(IT_UNCOVERED_CONDITIONS, UNCOVERED_CONDITIONS);
+ deprecatedCoverageMetricMapping.put(IT_CONDITIONS_TO_COVER, CONDITIONS_TO_COVER);
+ deprecatedCoverageMetricMapping.put(IT_CONDITIONS_BY_LINE, CONDITIONS_BY_LINE);
+ deprecatedCoverageMetricMapping.put(IT_COVERED_CONDITIONS_BY_LINE, COVERED_CONDITIONS_BY_LINE);
+ deprecatedCoverageMetricMapping.put(IT_COVERAGE_LINE_HITS_DATA, COVERAGE_LINE_HITS_DATA);
+ deprecatedCoverageMetricMapping.put(OVERALL_COVERAGE, COVERAGE);
+ deprecatedCoverageMetricMapping.put(OVERALL_LINE_COVERAGE, LINE_COVERAGE);
+ deprecatedCoverageMetricMapping.put(OVERALL_BRANCH_COVERAGE, BRANCH_COVERAGE);
+ deprecatedCoverageMetricMapping.put(OVERALL_UNCOVERED_LINES, UNCOVERED_LINES);
+ deprecatedCoverageMetricMapping.put(OVERALL_LINES_TO_COVER, LINES_TO_COVER);
+ deprecatedCoverageMetricMapping.put(OVERALL_UNCOVERED_CONDITIONS, UNCOVERED_CONDITIONS);
+ deprecatedCoverageMetricMapping.put(OVERALL_CONDITIONS_TO_COVER, CONDITIONS_TO_COVER);
+ deprecatedCoverageMetricMapping.put(OVERALL_CONDITIONS_BY_LINE, CONDITIONS_BY_LINE);
+ deprecatedCoverageMetricMapping.put(OVERALL_COVERED_CONDITIONS_BY_LINE, COVERED_CONDITIONS_BY_LINE);
+ deprecatedCoverageMetricMapping.put(OVERALL_COVERAGE_LINE_HITS_DATA, COVERAGE_LINE_HITS_DATA);
}
@Override
public void store(Measure newMeasure) {
- DefaultMeasure<?> measure = (DefaultMeasure<?>) newMeasure;
- org.sonar.api.measures.Metric m = findMetricOrFail(measure.metric().key());
- org.sonar.api.measures.Measure measureToSave = new org.sonar.api.measures.Measure(m);
- setValueAccordingToMetricType(newMeasure, m, measureToSave);
- measureToSave.setFromCore(measure.isFromCore());
- InputComponent inputComponent = newMeasure.inputComponent();
- Resource resource = componentCache.get(inputComponent).resource();
- if (coverageExclusions.accept(resource, measureToSave)) {
- saveMeasure(resource, measureToSave);
- }
+ saveMeasure(newMeasure.inputComponent(), (DefaultMeasure<?>) newMeasure);
}
- public void saveMeasure(Resource resource, org.sonar.api.measures.Measure measure) {
- if (DEPRECATED_METRICS_KEYS.contains(measure.getMetricKey())) {
- // Ignore deprecated metrics
+ public void saveMeasure(InputComponent component, DefaultMeasure<?> measure) {
+ if (isDeprecatedMetric(measure.metric().key()) || isComputedOnCeMetric(measure.metric().key())) {
+ LOG.debug("Metric '{}' should not be saved by Sensors. It will be ignored.", measure.metric().key());
+ // Ignore deprecated and CE side metrics
return;
}
- org.sonar.api.batch.measure.Metric metric = metricFinder.findByKey(measure.getMetricKey());
+ Metric<?> metric = metricFinder.findByKey(measure.metric().key());
if (metric == null) {
- throw new SonarException("Unknown metric: " + measure.getMetricKey());
+ throw new UnsupportedOperationException("Unknown metric: " + measure.metric().key());
+ }
+ if (!scannerMetrics.getMetrics().contains(metric)) {
+ throw new UnsupportedOperationException("Metric '" + metric.key() + "' should not be computed by a Sensor");
}
if (!measure.isFromCore() && INTERNAL_METRICS.contains(metric)) {
LOG.debug("Metric " + metric.key() + " is an internal metric computed by SonarQube. Provided value is ignored.");
+ return;
+ }
+ if (deprecatedCoverageMetricMapping.containsKey(metric)) {
+ metric = deprecatedCoverageMetricMapping.get(metric);
}
- if (measureCache.contains(resource, measure)) {
- throw new SonarException("Can not add the same measure twice on " + resource + ": " + measure);
+
+ if (coverageMetrics.contains(metric)) {
+ if (!component.isFile()) {
+ throw new UnsupportedOperationException("Saving coverage metric is only allowed on files. Attempt to save '" + metric.key() + "' on '" + component.key() + "'");
+ }
+ if (coverageExclusions.isExcluded((InputFile) component)) {
+ return;
+ }
+ saveCoverageMetricInternal((InputFile) component, metric, measure);
+ } 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(), measure);
}
- measureCache.put(resource, measure);
}
- private void setValueAccordingToMetricType(Measure<?> measure, org.sonar.api.measures.Metric<?> m, org.sonar.api.measures.Measure measureToSave) {
- switch (m.getType()) {
- case BOOL:
- measureToSave.setValue(Boolean.TRUE.equals(measure.value()) ? 1.0 : 0.0);
- break;
- case INT:
- case MILLISEC:
- case WORK_DUR:
- case FLOAT:
- case PERCENT:
- case RATING:
- measureToSave.setValue(((Number) measure.value()).doubleValue());
- break;
- case STRING:
- case LEVEL:
- case DATA:
- case DISTRIB:
- measureToSave.setData((String) measure.value());
- break;
- default:
- throw new UnsupportedOperationException("Unsupported type :" + m.getType());
+ private void saveCoverageMetricInternal(InputFile file, Metric<?> metric, DefaultMeasure<?> measure) {
+ if (isLineMetrics(metric)) {
+ 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(KeyValueFormat.format(mergeLineMetric((String) previousMeasure.value(), (String) measure.value()))));
+ } else {
+ measureCache.put(file.key(), metric.key(), measure);
+ }
+ } else {
+ // Other coverage metrics are all integer values
+ DefaultMeasure<?> previousMeasure = measureCache.byMetric(file.key(), metric.key());
+ if (previousMeasure != null) {
+ measureCache.put(file.key(), metric.key(), new DefaultMeasure<Integer>()
+ .forMetric((Metric<Integer>) metric)
+ .withValue(Math.max((Integer) previousMeasure.value(), (Integer) measure.value())));
+ } else {
+ measureCache.put(file.key(), metric.key(), measure);
+ }
}
}
- @Override
- public void store(Issue issue) {
- moduleIssues.initAndAddIssue(issue);
+ /**
+ * Merge the two line data measures, keeping max value in case they both contains a value for the same line.
+ */
+ private Map<Integer, Integer> mergeLineMetric(String value1, String value2) {
+ Map<Integer, Integer> data1 = KeyValueFormat.parseIntInt(value1);
+ Map<Integer, Integer> data2 = KeyValueFormat.parseIntInt(value2);
+ return Stream.of(data1, data2)
+ .map(Map::entrySet)
+ .flatMap(Collection::stream)
+ .collect(
+ Collectors.toMap(
+ Map.Entry::getKey,
+ Map.Entry::getValue,
+ Integer::max));
+ }
+
+ public boolean isDeprecatedMetric(String metricKey) {
+ return DEPRECATED_METRICS_KEYS.contains(metricKey);
}
- private File getFile(InputFile file) {
- BatchComponent r = componentCache.get(file);
- if (r == null) {
- throw new IllegalStateException("Provided input file is not indexed");
+ public boolean isComputedOnCeMetric(String metricKey) {
+ return COMPUTED_ON_CE_SIDE_METRICS_KEYS.contains(metricKey);
+ }
+
+ private boolean isLineMetrics(Metric<?> metric) {
+ return this.byLineMetrics.contains(metric);
+ }
+
+ public void validateCoverageMeasure(String value, InputFile inputFile) {
+ Map<Integer, Integer> m = KeyValueFormat.parseIntInt(value);
+ validatePositiveLine(m, inputFile.absolutePath());
+ 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.absolutePath(), maxLine));
+ }
}
- return (File) r.resource();
+ }
+
+ 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));
+ }
+ }
+ }
+
+ @Override
+ public void store(Issue issue) {
+ moduleIssues.initAndAddIssue(issue);
}
@Override
@Override
public void store(DefaultCoverage defaultCoverage) {
- File file = getFile(defaultCoverage.inputFile());
- if (coverageExclusions.hasMatchingPattern(file)) {
+ if (coverageExclusions.isExcluded(defaultCoverage.inputFile())) {
return;
}
- CoverageType type = defaultCoverage.type();
if (defaultCoverage.linesToCover() > 0) {
- saveMeasure(file, new org.sonar.api.measures.Measure(type.linesToCover(), (double) defaultCoverage.linesToCover()));
- saveMeasure(file, new org.sonar.api.measures.Measure(type.uncoveredLines(), (double) (defaultCoverage.linesToCover() - defaultCoverage.coveredLines())));
- saveMeasure(file, new org.sonar.api.measures.Measure(type.lineHitsData()).setData(KeyValueFormat.format(defaultCoverage.hitsByLine())));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), LINES_TO_COVER, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(defaultCoverage.linesToCover()));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), UNCOVERED_LINES,
+ new DefaultMeasure<Integer>().forMetric(UNCOVERED_LINES).withValue(defaultCoverage.linesToCover() - defaultCoverage.coveredLines()));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), COVERAGE_LINE_HITS_DATA,
+ new DefaultMeasure<String>().forMetric(COVERAGE_LINE_HITS_DATA).withValue(KeyValueFormat.format(defaultCoverage.hitsByLine())));
}
if (defaultCoverage.conditions() > 0) {
- saveMeasure(file, new org.sonar.api.measures.Measure(type.conditionsToCover(), (double) defaultCoverage.conditions()));
- saveMeasure(file, new org.sonar.api.measures.Measure(type.uncoveredConditions(), (double) (defaultCoverage.conditions() - defaultCoverage.coveredConditions())));
- saveMeasure(file, new org.sonar.api.measures.Measure(type.coveredConditionsByLine()).setData(KeyValueFormat.format(defaultCoverage.coveredConditionsByLine())));
- saveMeasure(file, new org.sonar.api.measures.Measure(type.conditionsByLine()).setData(KeyValueFormat.format(defaultCoverage.conditionsByLine())));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), CONDITIONS_TO_COVER,
+ new DefaultMeasure<Integer>().forMetric(CONDITIONS_TO_COVER).withValue(defaultCoverage.conditions()));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), UNCOVERED_CONDITIONS,
+ new DefaultMeasure<Integer>().forMetric(UNCOVERED_CONDITIONS).withValue(defaultCoverage.conditions() - defaultCoverage.coveredConditions()));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), COVERED_CONDITIONS_BY_LINE,
+ new DefaultMeasure<String>().forMetric(COVERED_CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.coveredConditionsByLine())));
+ saveCoverageMetricInternal(defaultCoverage.inputFile(), CONDITIONS_BY_LINE,
+ new DefaultMeasure<String>().forMetric(CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.conditionsByLine())));
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.scanner.sensor.coverage;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-
-import java.util.Collection;
-
-public class CoverageConstants {
-
- public static final Collection<Metric> COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER,
- CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS,
- CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
-
- public static final Collection<Metric> LINE_COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES,
- CoreMetrics.NEW_LINES_TO_COVER);
-
- public static final Collection<Metric> BRANCH_COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER,
- CoreMetrics.NEW_UNCOVERED_CONDITIONS, CoreMetrics.NEW_CONDITIONS_TO_COVER);
-
- private CoverageConstants() {
- }
-}
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
+import org.picocontainer.Startable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.config.Settings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.WildcardPattern;
-public class CoverageExclusions {
+public class CoverageExclusions implements Startable {
private static final Logger LOG = LoggerFactory.getLogger(CoverageExclusions.class);
private final Settings settings;
- private final Set<Metric> coverageMetrics;
- private final Set<Metric> byLineMetrics;
- private Collection<WildcardPattern> resourcePatterns;
+ private Collection<WildcardPattern> exclusionPatterns;
- private final FileSystem fs;
-
- public CoverageExclusions(Settings settings, FileSystem fs) {
+ public CoverageExclusions(Settings settings) {
this.settings = settings;
- this.fs = fs;
- this.coverageMetrics = new HashSet<>();
- this.byLineMetrics = new HashSet<>();
- // UT
- coverageMetrics.add(CoreMetrics.COVERAGE);
- coverageMetrics.add(CoreMetrics.LINE_COVERAGE);
- coverageMetrics.add(CoreMetrics.BRANCH_COVERAGE);
- coverageMetrics.add(CoreMetrics.UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.UNCOVERED_CONDITIONS);
- coverageMetrics.add(CoreMetrics.CONDITIONS_TO_COVER);
- coverageMetrics.add(CoreMetrics.CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.COVERED_CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.COVERAGE_LINE_HITS_DATA);
- coverageMetrics.add(CoreMetrics.NEW_LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.NEW_UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.NEW_UNCOVERED_CONDITIONS);
- // IT
- coverageMetrics.add(CoreMetrics.IT_COVERAGE);
- coverageMetrics.add(CoreMetrics.IT_LINE_COVERAGE);
- coverageMetrics.add(CoreMetrics.IT_BRANCH_COVERAGE);
- coverageMetrics.add(CoreMetrics.IT_UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.IT_LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.IT_UNCOVERED_CONDITIONS);
- coverageMetrics.add(CoreMetrics.IT_CONDITIONS_TO_COVER);
- coverageMetrics.add(CoreMetrics.IT_CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA);
- coverageMetrics.add(CoreMetrics.NEW_IT_LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.NEW_IT_UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
- // OVERALL
- coverageMetrics.add(CoreMetrics.OVERALL_COVERAGE);
- coverageMetrics.add(CoreMetrics.OVERALL_LINE_COVERAGE);
- coverageMetrics.add(CoreMetrics.OVERALL_BRANCH_COVERAGE);
- coverageMetrics.add(CoreMetrics.OVERALL_UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.OVERALL_LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.OVERALL_UNCOVERED_CONDITIONS);
- coverageMetrics.add(CoreMetrics.OVERALL_CONDITIONS_TO_COVER);
- coverageMetrics.add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE);
- coverageMetrics.add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA);
- coverageMetrics.add(CoreMetrics.NEW_OVERALL_LINES_TO_COVER);
- coverageMetrics.add(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES);
- coverageMetrics.add(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS);
-
- byLineMetrics.add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA);
- byLineMetrics.add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE);
- byLineMetrics.add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE);
- byLineMetrics.add(CoreMetrics.COVERAGE_LINE_HITS_DATA);
- byLineMetrics.add(CoreMetrics.COVERED_CONDITIONS_BY_LINE);
- byLineMetrics.add(CoreMetrics.CONDITIONS_BY_LINE);
- byLineMetrics.add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA);
- byLineMetrics.add(CoreMetrics.IT_CONDITIONS_BY_LINE);
- byLineMetrics.add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE);
-
- initPatterns();
- }
-
- private boolean isLineMetrics(Metric<?> metric) {
- return this.byLineMetrics.contains(metric);
- }
-
- public void validate(Measure<?> measure, InputFile inputFile) {
- Metric<?> metric = measure.getMetric();
-
- if (!isLineMetrics(metric)) {
- return;
- }
-
- Map<Integer, Integer> m = KeyValueFormat.parseIntInt(measure.getData());
- validatePositiveLine(m, inputFile.absolutePath());
- validateMaxLine(m, inputFile);
- }
-
- @CheckForNull
- private InputFile getInputFile(String filePath) {
- return fs.inputFile(fs.predicates().hasRelativePath(filePath));
- }
-
- public void validate(Measure<?> measure, String filePath) {
- Metric<?> metric = measure.getMetric();
-
- if (!isLineMetrics(metric)) {
- return;
- }
-
- InputFile inputFile = getInputFile(filePath);
-
- if (inputFile == null) {
- throw new IllegalStateException(String.format("Can't create measure for resource '%s': resource is not indexed as a file", filePath));
- }
-
- validate(measure, inputFile);
- }
-
- private static void validateMaxLine(Map<Integer, Integer> m, InputFile inputFile) {
- int maxLine = inputFile.lines();
-
- for (int l : m.keySet()) {
- if (l > maxLine) {
- throw new IllegalStateException(String.format("Can't create measure for line %d for file '%s' with %d lines", l, inputFile.absolutePath(), maxLine));
- }
- }
- }
-
- 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));
- }
- }
}
- public boolean accept(Resource resource, Measure<?> measure) {
- if (isCoverageMetric(measure.getMetric())) {
- return !hasMatchingPattern(resource);
- } else {
- return true;
- }
+ @Override
+ public void start() {
+ initPatterns();
}
- private boolean isCoverageMetric(Metric<?> metric) {
- return this.coverageMetrics.contains(metric);
+ @Override
+ public void stop() {
+ // Nothing to do
}
- public boolean hasMatchingPattern(Resource resource) {
+ public boolean isExcluded(InputFile file) {
boolean found = false;
- Iterator<WildcardPattern> iterator = resourcePatterns.iterator();
+ Iterator<WildcardPattern> iterator = exclusionPatterns.iterator();
while (!found && iterator.hasNext()) {
- found = resource.matchFilePattern(iterator.next().toString());
+ found = iterator.next().match(file.relativePath());
}
return found;
}
for (String pattern : settings.getStringArray(CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY)) {
builder.add(WildcardPattern.create(pattern));
}
- resourcePatterns = builder.build();
- log("Excluded sources for coverage: ", resourcePatterns);
+ exclusionPatterns = builder.build();
+ log("Excluded sources for coverage: ", exclusionPatterns);
}
private static void log(String title, Collection<WildcardPattern> patterns) {
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.measures.Measure;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.scanner.scan.measure.MeasureCache;
@Phase(name = Phase.Name.POST)
public final class ZeroCoverageSensor implements Sensor {
- private static final class MeasureToMetricKey implements Function<Measure, String> {
+ private static final class MeasureToMetricKey implements Function<DefaultMeasure<?>, String> {
@Override
- public String apply(Measure input) {
- return input.getMetricKey();
+ public String apply(DefaultMeasure<?> input) {
+ return input.metric().key();
}
}
FileSystem fs = context.fileSystem();
for (InputFile f : fs.inputFiles(fs.predicates().hasType(Type.MAIN))) {
if (!isCoverageMeasuresAlreadyDefined(f)) {
- Measure execLines = measureCache.byMetric(f.key(), CoreMetrics.EXECUTABLE_LINES_DATA_KEY);
+ DefaultMeasure<String> execLines = (DefaultMeasure<String>) measureCache.byMetric(f.key(), CoreMetrics.EXECUTABLE_LINES_DATA_KEY);
if (execLines != null) {
storeZeroCoverageForEachExecutableLine(context, f, execLines);
}
}
}
- private static void storeZeroCoverageForEachExecutableLine(final SensorContext context, InputFile f, Measure execLines) {
- NewCoverage newCoverage = context.newCoverage().ofType(CoverageType.UNIT).onFile(f);
+ private static void storeZeroCoverageForEachExecutableLine(final SensorContext context, InputFile f, DefaultMeasure<String> execLines) {
+ NewCoverage newCoverage = context.newCoverage().onFile(f);
Map<Integer, String> lineMeasures = KeyValueFormat.parseIntString((String) execLines.value());
for (Map.Entry<Integer, String> lineMeasure : lineMeasures.entrySet()) {
int lineIdx = lineMeasure.getKey();
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.internal.SensorContextTester;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.scanner.DefaultFileLinesContext;
import org.sonar.scanner.scan.measure.MeasureCache;
import static org.assertj.core.api.Assertions.assertThat;
@Test
public void shouldLoadIntValues() {
- when(measureCache.byMetric("foo:src/foo.php", HITS_METRIC_KEY)).thenReturn(new Measure(HITS_METRIC_KEY).setData("1=2;3=4"));
+ 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));
@Test
public void shouldLoadStringValues() {
- when(measureCache.byMetric("foo:src/foo.php", AUTHOR_METRIC_KEY)).thenReturn(new Measure(AUTHOR_METRIC_KEY).setData("1=simon;3=evgeny"));
+ 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"));
@Test(expected = UnsupportedOperationException.class)
public void shouldNotModifyAfterLoad() {
- when(measureCache.byMetric("foo:src/foo.php", AUTHOR_METRIC_KEY)).thenReturn(new Measure(AUTHOR_METRIC_KEY).setData("1=simon;3=evgeny"));
+ 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");
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.profiles.RulesProfile;
DefaultProjectTree projectTree = mock(DefaultProjectTree.class);
BatchComponentCache resourceCache = new BatchComponentCache();
- index = new DefaultIndex(resourceCache, projectTree, mock(MeasureCache.class));
+ index = new DefaultIndex(resourceCache, projectTree, mock(MeasureCache.class), mock(MetricFinder.class));
baseDir = temp.newFolder();
project = new Project("project");
}
@Test
- public void unitTests() throws IOException {
+ public void singleReport() throws IOException {
File baseDir = temp.getRoot();
File srcDir = new File(baseDir, "src");
tuple(CoreMetrics.UNCOVERED_CONDITIONS_KEY, 1));
}
+ @Test
+ public void twoReports() throws IOException {
+
+ File baseDir = temp.getRoot();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "function foo() {\n if (a && b) {\nalert('hello');\n}\n}");
+ File xooUtCoverageFile = new File(srcDir, "sample.xoo.coverage");
+ FileUtils.write(xooUtCoverageFile, "2:2:2:2");
+ File xooItCoverageFile = new File(srcDir, "sample.xoo.itcoverage");
+ FileUtils.write(xooItCoverageFile, "2:2:2:1\n3:1");
+
+ TaskResult result = tester.newTask()
+ .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")
+ .build())
+ .start();
+
+ InputFile file = result.inputFile("src/sample.xoo");
+ assertThat(result.coverageFor(file, 2).getUtHits()).isTrue();
+ assertThat(result.coverageFor(file, 2).getConditions()).isEqualTo(2);
+ assertThat(result.coverageFor(file, 2).getUtCoveredConditions()).isEqualTo(2);
+ assertThat(result.coverageFor(file, 3).getUtHits()).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")
+ .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
public void exclusions() throws IOException {
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
import org.sonar.api.resources.Project;
import org.sonar.core.util.CloseableIterator;
-import org.sonar.scanner.protocol.output.ScannerReport.LineCoverage;
-import org.sonar.scanner.report.CoveragePublisher;
-import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.index.BatchComponentCache;
+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.measure.MeasureCache;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
@Test
public void publishCoverage() throws Exception {
- Measure utLineHits = new Measure<>(CoreMetrics.COVERAGE_LINE_HITS_DATA).setData("2=1;3=1;5=0;6=3");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).thenReturn(utLineHits);
-
- Measure itsConditionsByLine = new Measure<>(CoreMetrics.IT_CONDITIONS_BY_LINE).setData("3=4");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_CONDITIONS_BY_LINE_KEY)).thenReturn(itsConditionsByLine);
-
- Measure conditionsByLine = new Measure<>(CoreMetrics.CONDITIONS_BY_LINE).setData("3=4");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.CONDITIONS_BY_LINE_KEY)).thenReturn(conditionsByLine);
-
- Measure coveredConditionsByUts = new Measure<>(CoreMetrics.COVERED_CONDITIONS_BY_LINE).setData("3=2");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn(coveredConditionsByUts);
-
- Measure itLineHits = new Measure<>(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA).setData("2=0;3=0;5=1");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY)).thenReturn(itLineHits);
-
- Measure coveredConditionsByIts = new Measure<>(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE).setData("3=1");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn(coveredConditionsByIts);
-
- Measure overallCoveredConditions = new Measure<>(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE).setData("3=2");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn(overallCoveredConditions);
-
- File outputDir = temp.newFolder();
- ScannerReportWriter writer = new ScannerReportWriter(outputDir);
-
- publisher.publish(writer);
-
- try (CloseableIterator<LineCoverage> it = new ScannerReportReader(outputDir).readComponentCoverage(2)) {
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(2)
- .setUtHits(true)
- .setItHits(false)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(3)
- .setUtHits(true)
- .setItHits(false)
- .setConditions(4)
- .setUtCoveredConditions(2)
- .setItCoveredConditions(1)
- .setOverallCoveredConditions(2)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(5)
- .setUtHits(false)
- .setItHits(true)
- .build());
- }
-
- }
-
- @Test
- public void publishCoverageOnlyUts() throws Exception {
-
- Measure utLineHits = new Measure<>(CoreMetrics.COVERAGE_LINE_HITS_DATA).setData("2=1;3=1;5=0;6=3");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).thenReturn(utLineHits);
+ 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);
- Measure conditionsByLine = new Measure<>(CoreMetrics.CONDITIONS_BY_LINE).setData("3=4");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.CONDITIONS_BY_LINE_KEY)).thenReturn(conditionsByLine);
+ 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);
- Measure coveredConditionsByUts = new Measure<>(CoreMetrics.COVERED_CONDITIONS_BY_LINE).setData("3=2");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn(coveredConditionsByUts);
+ 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);
}
}
-
- @Test
- public void publishCoverageOnlyIts() throws Exception {
-
- Measure itsConditionsByLine = new Measure<>(CoreMetrics.IT_CONDITIONS_BY_LINE).setData("3=4");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_CONDITIONS_BY_LINE_KEY)).thenReturn(itsConditionsByLine);
-
- Measure itLineHits = new Measure<>(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA).setData("2=0;3=0;5=1");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY)).thenReturn(itLineHits);
-
- Measure coveredConditionsByIts = new Measure<>(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE).setData("3=1");
- when(measureCache.byMetric("foo:src/Foo.php", CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY)).thenReturn(coveredConditionsByIts);
-
- File outputDir = temp.newFolder();
- ScannerReportWriter writer = new ScannerReportWriter(outputDir);
-
- publisher.publish(writer);
-
- try (CloseableIterator<LineCoverage> it = new ScannerReportReader(outputDir).readComponentCoverage(2)) {
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(2)
- .setItHits(false)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(3)
- .setItHits(false)
- .setConditions(4)
- .setItCoveredConditions(1)
- .build());
- assertThat(it.next()).isEqualTo(LineCoverage.newBuilder()
- .setLine(5)
- .setItHits(true)
- .build());
- }
-
- }
}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.core.util.CloseableIterator;
import org.sonar.scanner.index.BatchComponentCache;
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.MeasuresPublisher;
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.Matchers.any;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MeasuresPublisherTest {
+ private static final String FILE_KEY = "foo:src/Foo.php";
+
@Rule
public ExpectedException thrown = ExpectedException.none();
public void prepare() {
Project p = new Project("foo").setAnalysisDate(new Date(1234567L));
BatchComponentCache resourceCache = new BatchComponentCache();
- sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
+ sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey(FILE_KEY);
resourceCache.add(p, null);
resourceCache.add(sampleFile, null);
measureCache = mock(MeasureCache.class);
- when(measureCache.byResource(any(Resource.class))).thenReturn(Collections.<Measure>emptyList());
+ when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList());
publisher = new MeasuresPublisher(resourceCache, measureCache, new ScannerMetrics());
}
@Test
public void publishMeasures() throws Exception {
- Measure measure = new Measure<>(CoreMetrics.LINES_TO_COVER)
- .setValue(2.0);
+ DefaultMeasure<Integer> measure = new DefaultMeasure<Integer>().forMetric(CoreMetrics.LINES_TO_COVER)
+ .withValue(2);
// String value
- Measure stringMeasure = new Measure<>(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION)
- .setData("foo bar");
- when(measureCache.byResource(sampleFile)).thenReturn(asList(measure, stringMeasure));
+ DefaultMeasure<String> stringMeasure = new DefaultMeasure<String>().forMetric(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION)
+ .withValue("foo bar");
+ when(measureCache.byComponentKey(FILE_KEY)).thenReturn(asList(measure, stringMeasure));
File outputDir = temp.newFolder();
ScannerReportWriter writer = new ScannerReportWriter(outputDir);
@Test
public void fail_with_IAE_when_measure_has_no_value() throws Exception {
- Measure measure = new Measure<>(CoreMetrics.LINES_TO_COVER);
- when(measureCache.byResource(sampleFile)).thenReturn(Collections.singletonList(measure));
+ DefaultMeasure<Integer> measure = new DefaultMeasure<Integer>().forMetric(CoreMetrics.LINES_TO_COVER);
+ when(measureCache.byComponentKey(FILE_KEY)).thenReturn(Collections.singletonList(measure));
File outputDir = temp.newFolder();
ScannerReportWriter writer = new ScannerReportWriter(outputDir);
*/
package org.sonar.scanner.scan.measure;
-import java.util.Date;
import java.util.Iterator;
-import org.apache.commons.lang.builder.EqualsBuilder;
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.api.measures.Measure;
-import org.sonar.api.measures.Metric.Level;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
import org.sonar.scanner.index.AbstractCachesTest;
import org.sonar.scanner.index.Cache.Entry;
import static org.mockito.Mockito.when;
public class MeasureCacheTest extends AbstractCachesTest {
+
+ private static final String COMPONENT_KEY = "struts";
+
@Rule
public ExpectedException thrown = ExpectedException.none();
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() {
- Project p = new Project("struts");
-
assertThat(measureCache.entries()).hasSize(0);
- assertThat(measureCache.byResource(p)).hasSize(0);
+ assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
- Measure m = new Measure(CoreMetrics.NCLOC, 1.0);
- measureCache.put(p, m);
+ DefaultMeasure<?> m = new DefaultMeasure().forMetric(CoreMetrics.NCLOC).withValue(1.0);
+ measureCache.put(COMPONENT_KEY, CoreMetrics.NCLOC_KEY, m);
- assertThat(measureCache.contains(p, m)).isTrue();
+ assertThat(measureCache.contains(COMPONENT_KEY, CoreMetrics.NCLOC_KEY)).isTrue();
assertThat(measureCache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
+ Iterator<Entry<DefaultMeasure<?>>> iterator = measureCache.entries().iterator();
iterator.hasNext();
- Entry<Measure> next = iterator.next();
+ Entry<DefaultMeasure<?>> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
- assertThat(next.key()[0]).isEqualTo("struts");
+ assertThat(next.key()[0]).isEqualTo(COMPONENT_KEY);
- assertThat(measureCache.byResource(p)).hasSize(1);
- assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
- }
-
- @Test
- public void should_add_measure_with_big_data() {
- Project p = new Project("struts");
-
- assertThat(measureCache.entries()).hasSize(0);
-
- assertThat(measureCache.byResource(p)).hasSize(0);
-
- Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
- m.setAlertText("foooooooooooooooooooooooooooooooooooo");
- StringBuilder data = new StringBuilder();
- for (int i = 0; i < 1_048_575; i++) {
- data.append("a");
- }
-
- m.setData(data.toString());
-
- measureCache.put(p, m);
-
- assertThat(measureCache.contains(p, m)).isTrue();
- assertThat(measureCache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
- iterator.hasNext();
- Entry<Measure> next = iterator.next();
- assertThat(next.value()).isEqualTo(m);
- assertThat(next.key()[0]).isEqualTo("struts");
-
- assertThat(measureCache.byResource(p)).hasSize(1);
- assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
+ 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_pre_patch() {
- Project p = new Project("struts");
-
assertThat(measureCache.entries()).hasSize(0);
+ assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
- assertThat(measureCache.byResource(p)).hasSize(0);
-
- Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
- StringBuilder data = new StringBuilder();
- for (int i = 0; i < 500000; i++) {
- data.append("some data");
+ StringBuilder data = new StringBuilder(4_500_000);
+ for (int i = 0; i < 4_500_000; i++) {
+ data.append('a');
}
- m.setData(data.toString());
-
- measureCache.put(p, m);
+ 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(p, m)).isTrue();
+ assertThat(measureCache.contains(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY)).isTrue();
assertThat(measureCache.entries()).hasSize(1);
- Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
+ Iterator<Entry<DefaultMeasure<?>>> iterator = measureCache.entries().iterator();
iterator.hasNext();
- Entry<Measure> next = iterator.next();
+ Entry<DefaultMeasure<?>> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
- assertThat(next.key()[0]).isEqualTo("struts");
+ assertThat(next.key()[0]).isEqualTo(COMPONENT_KEY);
- assertThat(measureCache.byResource(p)).hasSize(1);
- assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
+ 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() {
- Project p = new Project("struts");
-
assertThat(measureCache.entries()).hasSize(0);
+ assertThat(measureCache.byComponentKey(COMPONENT_KEY)).hasSize(0);
- assertThat(measureCache.byResource(p)).hasSize(0);
-
- Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
- StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1);
// Limit is 64Mo
- for (int i = 0; i < (64 * 1024 * 1024 + 1); i++) {
+ StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1);
+ for (int i = 0; i < 64 * 1024 * 1024 + 1; i++) {
data.append('a');
}
- m.setData(data.toString());
+ 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 cache measures");
+ thrown.expectMessage("Fail to put element in the storage 'measures'");
- measureCache.put(p, m);
+ measureCache.put(COMPONENT_KEY, CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, m);
}
@Test
public void should_get_measures() {
- Project p = new Project("struts");
- Resource dir = Directory.create("foo/bar").setEffectiveKey("struts:foo/bar");
- Resource file1 = Directory.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
- Resource file2 = Directory.create("foo/bar/File2.txt").setEffectiveKey("struts:foo/bar/File2.txt");
+ 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.byResource(p)).hasSize(0);
- assertThat(measureCache.byResource(dir)).hasSize(0);
+ assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
+ assertThat(measureCache.byComponentKey(dirKey)).hasSize(0);
- Measure mFile1 = new Measure(CoreMetrics.NCLOC, 1.0);
- measureCache.put(file1, mFile1);
- Measure mFile2 = new Measure(CoreMetrics.NCLOC, 3.0);
- measureCache.put(file2, mFile2);
+ 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.byResource(p)).hasSize(0);
- assertThat(measureCache.byResource(dir)).hasSize(0);
+ assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
+ assertThat(measureCache.byComponentKey(dirKey)).hasSize(0);
- Measure mDir = new Measure(CoreMetrics.NCLOC, 4.0);
- measureCache.put(dir, mDir);
+ 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.byResource(p)).hasSize(0);
- assertThat(measureCache.byResource(dir)).hasSize(1);
- assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);
+ assertThat(measureCache.byComponentKey(projectKey)).hasSize(0);
+ assertThat(measureCache.byComponentKey(dirKey)).hasSize(1);
+ assertThat(measureCache.byComponentKey(dirKey).iterator().next()).isEqualTo(mDir);
- Measure mProj = new Measure(CoreMetrics.NCLOC, 4.0);
- measureCache.put(p, mProj);
+ 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.byResource(p)).hasSize(1);
- assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(mProj);
- assertThat(measureCache.byResource(dir)).hasSize(1);
- assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);
+ 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);
}
- @Test
- public void test_measure_coder() throws Exception {
- Resource file1 = File.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
-
- Measure measure = new Measure(CoreMetrics.NCLOC, 3.14);
- measure.setData("data");
- measure.setAlertStatus(Level.ERROR);
- measure.setAlertText("alert");
- measure.setDate(new Date());
- measure.setDescription("description");
- measure.setPersistenceMode(null);
- measure.setPersonId(3);
- measure.setUrl("http://foo");
- measure.setVariation1(11.0);
- measure.setVariation2(12.0);
- measure.setVariation3(13.0);
- measure.setVariation4(14.0);
- measure.setVariation5(15.0);
- measureCache.put(file1, measure);
-
- Measure savedMeasure = measureCache.byResource(file1).iterator().next();
- assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
-
- }
}
*/
package org.sonar.scanner.sensor;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
-import org.sonar.api.config.Settings;
import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.metric.ScannerMetrics;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
import org.sonar.scanner.index.BatchComponentCache;
import org.sonar.scanner.issue.ModuleIssues;
private DefaultSensorStorage underTest;
private Settings settings;
private ModuleIssues moduleIssues;
- private Project project;
private MeasureCache measureCache;
private ContextPropertiesCache contextPropertiesCache = new ContextPropertiesCache();
- private BatchComponentCache resourceCache;
+ private BatchComponentCache componentCache;
@Before
public void prepare() throws Exception {
when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
settings = new MapSettings();
moduleIssues = mock(ModuleIssues.class);
- project = new Project("myProject");
measureCache = mock(MeasureCache.class);
CoverageExclusions coverageExclusions = mock(CoverageExclusions.class);
- when(coverageExclusions.accept(any(Resource.class), any(Measure.class))).thenReturn(true);
- resourceCache = new BatchComponentCache();
+ when(coverageExclusions.isExcluded(any(InputFile.class))).thenReturn(false);
+ componentCache = new BatchComponentCache();
ReportPublisher reportPublisher = mock(ReportPublisher.class);
when(reportPublisher.getWriter()).thenReturn(new ScannerReportWriter(temp.newFolder()));
underTest = new DefaultSensorStorage(metricFinder,
- moduleIssues, settings, coverageExclusions, resourceCache, reportPublisher, measureCache,
- mock(SonarCpdBlockIndex.class), contextPropertiesCache);
+ moduleIssues, settings, coverageExclusions, componentCache, reportPublisher, measureCache,
+ mock(SonarCpdBlockIndex.class), contextPropertiesCache, new ScannerMetrics());
}
@Test
public void shouldFailIfUnknownMetric() {
InputFile file = new DefaultInputFile("foo", "src/Foo.php");
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Unknow metric with key: lines");
+ thrown.expect(UnsupportedOperationException.class);
+ thrown.expectMessage("Unknown metric: lines");
underTest.store(new DefaultMeasure()
.on(file)
public void shouldSaveFileMeasureToSensorContext() {
InputFile file = new DefaultInputFile("foo", "src/Foo.php");
- ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
+ ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class);
Resource sonarFile = File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
- resourceCache.add(sonarFile, null).setInputComponent(file);
- when(measureCache.put(eq(sonarFile), argumentCaptor.capture())).thenReturn(null);
+ componentCache.add(sonarFile, null).setInputComponent(file);
+ 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));
- org.sonar.api.measures.Measure m = argumentCaptor.getValue();
- assertThat(m.getValue()).isEqualTo(10.0);
- assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
+ DefaultMeasure m = argumentCaptor.getValue();
+ assertThat(m.value()).isEqualTo(10);
+ assertThat(m.metric()).isEqualTo(CoreMetrics.NCLOC);
}
@Test
public void shouldSaveProjectMeasureToSensorContext() {
- DefaultInputModule module = new DefaultInputModule(project.getEffectiveKey());
- resourceCache.add(project, null).setInputComponent(module);
+ String projectKey = "myProject";
+ DefaultInputModule module = new DefaultInputModule(projectKey);
+ componentCache.add(new Project(projectKey), null).setInputComponent(module);
- ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
- when(measureCache.put(eq(project), argumentCaptor.capture())).thenReturn(null);
+ 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));
- org.sonar.api.measures.Measure m = argumentCaptor.getValue();
- assertThat(m.getValue()).isEqualTo(10.0);
- assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
+ DefaultMeasure m = argumentCaptor.getValue();
+ assertThat(m.value()).isEqualTo(10);
+ assertThat(m.metric()).isEqualTo(CoreMetrics.NCLOC);
}
@Test(expected = UnsupportedOperationException.class)
Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java")
.setModuleBaseDir(temp.newFolder().toPath());
- resourceCache.add(sonarFile, null).setInputComponent(inputFile);
+ componentCache.add(sonarFile, null).setInputComponent(inputFile);
DefaultHighlighting h = new DefaultHighlighting(null)
.onFile(inputFile);
underTest.store(h);
Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java")
.setModuleBaseDir(temp.newFolder().toPath());
- resourceCache.add(sonarFile, null).setInputComponent(inputFile);
+ componentCache.add(sonarFile, null).setInputComponent(inputFile);
DefaultSymbolTable st = new DefaultSymbolTable(null)
.onFile(inputFile);
underTest.store(st);
@Test
public void shouldStoreContextProperty() {
underTest.storeProperty("foo", "bar");
-
assertThat(contextPropertiesCache.getAll()).containsOnly(entry("foo", "bar"));
+ }
+
+ @Test
+ public void shouldValidateStrictlyPositiveLine() throws Exception {
+ DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath());
+ 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 {
+ DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath());
+ Map<Integer, Integer> map = ImmutableMap.of(11, 3);
+ String data = KeyValueFormat.format(map);
+
+ thrown.expect(IllegalStateException.class);
+ underTest.validateCoverageMeasure(data, file);
}
}
*/
package org.sonar.scanner.sensor.coverage;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
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.DefaultFileSystem;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.config.MapSettings;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.config.ExclusionProperties;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class CoverageExclusionsTest {
- @Rule
- public ExpectedException exception = ExpectedException.none();
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
private Settings settings;
- private DefaultFileSystem fs;
-
- private CoverageExclusions filter;
+ private CoverageExclusions coverageExclusions;
@Before
- public void createFilter() {
+ public void prepare() {
settings = new MapSettings(new PropertyDefinitions(ExclusionProperties.all()));
- fs = new DefaultFileSystem(temp.getRoot());
- filter = new CoverageExclusions(settings, fs);
- }
-
- @Test
- public void shouldValidateStrictlyPositiveLine() {
- DefaultInputFile file = new DefaultInputFile("module", "testfile");
- Measure measure = mock(Measure.class);
- Map<Integer, Integer> map = ImmutableMap.of(0, 3);
-
- String data = KeyValueFormat.format(map);
- when(measure.getMetric()).thenReturn(CoreMetrics.IT_CONDITIONS_BY_LINE);
- when(measure.getData()).thenReturn(data);
-
- fs.add(file);
-
- exception.expect(IllegalStateException.class);
- exception.expectMessage("must be > 0");
- filter.validate(measure, "testfile");
+ coverageExclusions = new CoverageExclusions(settings);
}
@Test
- public void shouldValidateFileExists() {
- DefaultInputFile file = new DefaultInputFile("module", "testfile");
- Measure measure = mock(Measure.class);
- Map<Integer, Integer> map = ImmutableMap.of(0, 3);
-
- String data = KeyValueFormat.format(map);
- when(measure.getMetric()).thenReturn(CoreMetrics.IT_CONDITIONS_BY_LINE);
- when(measure.getData()).thenReturn(data);
-
- fs.add(file);
-
- exception.expect(IllegalStateException.class);
- exception.expectMessage("resource is not indexed as a file");
- filter.validate(measure, "dummy");
- }
-
- @Test
- public void shouldValidateMaxLine() {
- DefaultInputFile file = new DefaultInputFile("module", "testfile");
- file.setLines(10);
- Measure measure = mock(Measure.class);
- Map<Integer, Integer> map = ImmutableMap.of(11, 3);
-
- String data = KeyValueFormat.format(map);
- when(measure.getMetric()).thenReturn(CoreMetrics.COVERED_CONDITIONS_BY_LINE);
- when(measure.getData()).thenReturn(data);
-
- exception.expect(IllegalStateException.class);
- filter.validate(measure, file);
- }
-
- @Test
- public void shouldNotFilterNonCoverageMetrics() {
- Measure otherMeasure = mock(Measure.class);
- when(otherMeasure.getMetric()).thenReturn(CoreMetrics.LINES);
- assertThat(filter.accept(mock(Resource.class), otherMeasure)).isTrue();
- }
-
- @Test
- public void shouldFilterFileBasedOnPattern() {
- Resource resource = File.create("src/org/polop/File.php", null, false);
- Measure coverageMeasure = mock(Measure.class);
- when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.LINES_TO_COVER);
-
+ public void shouldExcludeFileBasedOnPattern() {
+ InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php");
settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*");
- filter.initPatterns();
- assertThat(filter.accept(resource, coverageMeasure)).isFalse();
+ coverageExclusions.initPatterns();
+ assertThat(coverageExclusions.isExcluded(file)).isTrue();
}
@Test
- public void shouldNotFilterFileBasedOnPattern() {
- Resource resource = File.create("src/org/polop/File.php", null, false);
- Measure coverageMeasure = mock(Measure.class);
- when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.COVERAGE);
-
+ public void shouldNotExcludeFileBasedOnPattern() {
+ InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php");
settings.setProperty("sonar.coverage.exclusions", "src/org/other/*");
- filter.initPatterns();
- assertThat(filter.accept(resource, coverageMeasure)).isTrue();
+ coverageExclusions.initPatterns();
+ assertThat(coverageExclusions.isExcluded(file)).isFalse();
}
}