diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-09-30 11:27:24 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-10-03 18:19:37 +0200 |
commit | 328d1094ff11072c9b4448949428d4cd6318bc16 (patch) | |
tree | f99c2cbe46553da61269ba9e9e6113ff7d550b77 /server | |
parent | 5a8da936d010fa0718b45e88dcf2863283ab61d2 (diff) | |
download | sonarqube-328d1094ff11072c9b4448949428d4cd6318bc16.tar.gz sonarqube-328d1094ff11072c9b4448949428d4cd6318bc16.zip |
SONAR-7782 Compute Reliability Rating on New Code
Diffstat (limited to 'server')
3 files changed, 83 insertions, 49 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java index d95f7a231dc..a46218e8d1c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java @@ -32,12 +32,12 @@ import org.sonar.server.computation.task.projectanalysis.formula.counter.RatingV import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepository; import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations; import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolder; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; @@ -63,6 +63,7 @@ import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rat * Compute following measures : * {@link CoreMetrics#RELIABILITY_RATING_KEY} * {@link CoreMetrics#SECURITY_RATING_KEY} + * {@link CoreMetrics#NEW_RELIABILITY_RATING_KEY} * {@link CoreMetrics#NEW_SECURITY_RATING_KEY} */ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisitorAdapter<ReliabilityAndSecurityRatingMeasuresVisitor.Counter> { @@ -81,8 +82,11 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito // Output metrics private final Metric reliabilityRatingMetric; private final Metric securityRatingMetric; + private final Metric newReliabilityRatingMetric; private final Metric newSecurityRatingMetric; + private final Map<String, Metric> metricsByKey; + public ReliabilityAndSecurityRatingMeasuresVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, ComponentIssuesRepository componentIssuesRepository, PeriodsHolder periodsHolder) { super(LEAVES, POST_ORDER, CounterFactory.INSTANCE); @@ -93,7 +97,14 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito // Output metrics this.reliabilityRatingMetric = metricRepository.getByKey(RELIABILITY_RATING_KEY); this.securityRatingMetric = metricRepository.getByKey(SECURITY_RATING_KEY); + this.newReliabilityRatingMetric = metricRepository.getByKey(NEW_RELIABILITY_RATING_KEY); this.newSecurityRatingMetric = metricRepository.getByKey(NEW_SECURITY_RATING_KEY); + + this.metricsByKey = ImmutableMap.of( + RELIABILITY_RATING_KEY, reliabilityRatingMetric, + SECURITY_RATING_KEY, securityRatingMetric, + NEW_RELIABILITY_RATING_KEY, newReliabilityRatingMetric, + NEW_SECURITY_RATING_KEY, newSecurityRatingMetric); } @Override @@ -128,51 +139,36 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito @Override public void visitProjectView(Component projectView, Path<Counter> path) { - Optional<Measure> reliabilityRatingMeasure = measureRepository.getRawMeasure(projectView, reliabilityRatingMetric); - if (reliabilityRatingMeasure.isPresent()) { - path.parent().reliabilityRating.increment(valueOf(reliabilityRatingMeasure.get().getData())); - } - Optional<Measure> securityRatingMeasure = measureRepository.getRawMeasure(projectView, securityRatingMetric); - if (securityRatingMeasure.isPresent()) { - path.parent().securityRating.increment(valueOf(securityRatingMeasure.get().getData())); - } + path.parent().ratingValueByMetric.entrySet().forEach(entry -> { + Optional<Measure> ratingMeasure = measureRepository.getRawMeasure(projectView, metricsByKey.get(entry.getKey())); + if (ratingMeasure.isPresent()) { + entry.getValue().increment(valueOf(ratingMeasure.get().getData())); + } + }); } private void computeAndSaveMeasures(Component component, Path<Counter> path) { processIssues(component, path); - addReliabilityRatingMeasure(component, path); - addSecurityRatingMeasure(component, path); - addNewSecurityRatingMeasure(component, path); + path.current().ratingValueByMetric.entrySet().forEach( + entry -> measureRepository.add(component, metricsByKey.get(entry.getKey()), createRatingMeasure(entry.getValue().getValue()))); + path.current().newRatingValueByMetric.entrySet().forEach( + entry -> entry.getValue().toMeasureVariations() + .ifPresent(measureVariations -> measureRepository.add( + component, + metricsByKey.get(entry.getKey()), + newMeasureBuilder().setVariations(measureVariations).createNoValue()))); addToParent(path); } private void processIssues(Component component, Path<Counter> path) { - for (Issue issue : componentIssuesRepository.getIssues(component)) { - if (issue.resolution() == null) { + componentIssuesRepository.getIssues(component) + .stream() + .filter(issue -> issue.resolution() == null) + .filter(issue -> issue.type().equals(BUG) || issue.type().equals(VULNERABILITY)) + .forEach(issue -> { path.current().processIssue(issue); - for (Period period : periodsHolder.getPeriods()) { - path.current().processIssue(issue, period); - } - } - } - } - - private void addReliabilityRatingMeasure(Component component, Path<Counter> path) { - Rating rating = path.current().reliabilityRating.getValue(); - measureRepository.add(component, reliabilityRatingMetric, newMeasureBuilder().create(rating.getIndex(), rating.name())); - } - - private void addSecurityRatingMeasure(Component component, Path<Counter> path) { - Rating rating = path.current().securityRating.getValue(); - measureRepository.add(component, securityRatingMetric, newMeasureBuilder().create(rating.getIndex(), rating.name())); - } - - private void addNewSecurityRatingMeasure(Component component, Path<Counter> path) { - java.util.Optional<MeasureVariations> measureVariations = path.current().newSecurityRating.toMeasureVariations(); - if (measureVariations.isPresent()) { - Measure measure = newMeasureBuilder().setVariations(measureVariations.get()).createNoValue(); - measureRepository.add(component, newSecurityRatingMetric, measure); - } + periodsHolder.getPeriods().forEach(period -> path.current().processIssue(issue, period)); + }); } private static void addToParent(Path<Counter> path) { @@ -181,35 +177,43 @@ public class ReliabilityAndSecurityRatingMeasuresVisitor extends PathAwareVisito } } + private static Measure createRatingMeasure(Rating rating) { + return newMeasureBuilder().create(rating.getIndex(), rating.name()); + } + static final class Counter { - private RatingVariationValue reliabilityRating = new RatingVariationValue(); - private RatingVariationValue securityRating = new RatingVariationValue(); - private RatingVariationValue.Array newSecurityRating = new RatingVariationValue.Array(); + private Map<String, RatingVariationValue> ratingValueByMetric = ImmutableMap.of( + RELIABILITY_RATING_KEY, new RatingVariationValue(), + SECURITY_RATING_KEY, new RatingVariationValue()); + private Map<String, RatingVariationValue.Array> newRatingValueByMetric = ImmutableMap.of( + NEW_RELIABILITY_RATING_KEY, new RatingVariationValue.Array(), + NEW_SECURITY_RATING_KEY, new RatingVariationValue.Array()); private Counter() { // prevents instantiation } void add(Counter otherCounter) { - reliabilityRating.increment(otherCounter.reliabilityRating); - securityRating.increment(otherCounter.securityRating); - newSecurityRating.incrementAll(otherCounter.newSecurityRating); + ratingValueByMetric.entrySet().forEach(e -> e.getValue().increment(otherCounter.ratingValueByMetric.get(e.getKey()))); + newRatingValueByMetric.entrySet().forEach(e -> e.getValue().incrementAll(otherCounter.newRatingValueByMetric.get(e.getKey()))); } void processIssue(Issue issue) { Rating rating = RATING_BY_SEVERITY.get(issue.severity()); if (issue.type().equals(BUG)) { - reliabilityRating.increment(rating); + ratingValueByMetric.get(RELIABILITY_RATING_KEY).increment(rating); } else if (issue.type().equals(VULNERABILITY)) { - securityRating.increment(rating); + ratingValueByMetric.get(SECURITY_RATING_KEY).increment(rating); } } void processIssue(Issue issue, Period period) { if (isOnPeriod((DefaultIssue) issue, period)) { Rating rating = RATING_BY_SEVERITY.get(issue.severity()); - if (issue.type().equals(VULNERABILITY)) { - newSecurityRating.increment(period, rating); + if (issue.type().equals(BUG)) { + newRatingValueByMetric.get(NEW_RELIABILITY_RATING_KEY).increment(period, rating); + } else if (issue.type().equals(VULNERABILITY)) { + newRatingValueByMetric.get(NEW_SECURITY_RATING_KEY).increment(period, rating); } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java index 24bfa5574d1..e56fa5d646b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForReportTest.java @@ -44,6 +44,8 @@ import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderRul import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; @@ -107,7 +109,8 @@ public class ReliabilityAndSecurityRatingMeasuresVisitorForReportTest { public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(RELIABILITY_RATING) .add(SECURITY_RATING) - .add(NEW_SECURITY_RATING); + .add(NEW_SECURITY_RATING) + .add(NEW_RELIABILITY_RATING); @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); @@ -243,6 +246,31 @@ public class ReliabilityAndSecurityRatingMeasuresVisitorForReportTest { } @Test + public void compute_new_reliability_rating() throws Exception { + treeRootHolder.setRoot(ROOT_PROJECT); + fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, + newBugIssue(10L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE), + // Should not be taken into account + newBugIssue(1L, MAJOR).setCreationDate(BEFORE_LEAK_PERIOD_DATE), + newVulnerabilityIssue(1L, MAJOR).setCreationDate(AFTER_LEAK_PERIOD_DATE)); + fillComponentIssuesVisitorRule.setIssues(FILE_2_REF, + newBugIssue(2L, CRITICAL).setCreationDate(AFTER_LEAK_PERIOD_DATE), + newBugIssue(3L, MINOR).setCreationDate(AFTER_LEAK_PERIOD_DATE), + // Should not be taken into account + newBugIssue(10L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE).setResolution(RESOLUTION_FIXED)); + fillComponentIssuesVisitorRule.setIssues(MODULE_REF, + newBugIssue(7L, BLOCKER).setCreationDate(AFTER_LEAK_PERIOD_DATE)); + + underTest.visit(ROOT_PROJECT); + + verifyAddedRawMeasureOnLeakPeriod(FILE_1_REF, NEW_RELIABILITY_RATING_KEY, C); + verifyAddedRawMeasureOnLeakPeriod(FILE_2_REF, NEW_RELIABILITY_RATING_KEY, D); + verifyAddedRawMeasureOnLeakPeriod(DIRECTORY_REF, NEW_RELIABILITY_RATING_KEY, D); + verifyAddedRawMeasureOnLeakPeriod(MODULE_REF, NEW_RELIABILITY_RATING_KEY, E); + verifyAddedRawMeasureOnLeakPeriod(PROJECT_REF, NEW_RELIABILITY_RATING_KEY, E); + } + + @Test public void compute_new_security_rating() throws Exception { treeRootHolder.setRoot(ROOT_PROJECT); fillComponentIssuesVisitorRule.setIssues(FILE_1_REF, diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java index 1a437fc9f04..9c2a1b6fbe1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest.java @@ -33,6 +33,7 @@ import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderRul import org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; @@ -85,7 +86,8 @@ public class ReliabilityAndSecurityRatingMeasuresVisitorForViewsTest { public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(RELIABILITY_RATING) .add(SECURITY_RATING) - .add(NEW_SECURITY_RATING); + .add(NEW_SECURITY_RATING) + .add(NEW_RELIABILITY_RATING); @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); |