diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2011-06-29 12:54:22 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2011-06-29 12:54:22 +0200 |
commit | 4415d64999d90301ad128afa5949c73a65bfd43d (patch) | |
tree | 05498dfcea07ae2589378af9c59d616060328a2d | |
parent | 18b21f2ce809939ebfe25a31a4663526a1ad8b61 (diff) | |
download | sonarqube-4415d64999d90301ad128afa5949c73a65bfd43d.tar.gz sonarqube-4415d64999d90301ad128afa5949c73a65bfd43d.zip |
SONAR-2553 API: compute the variations on all measures
3 files changed, 78 insertions, 30 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index c475fbfbe09..a1c9d5236b1 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -95,12 +95,14 @@ public class VariationDecorator implements Decorator { } // for each measure, search equivalent past measure - for (Measure measure : context.getMeasures(new CustomMeasureFilter())) { + for (Measure measure : context.getMeasures(MeasuresFilters.all())) { // compare with past measure Integer metricId = (measure.getMetric().getId() != null ? measure.getMetric().getId() : metricFinder.findByKey(measure.getMetric().getKey()).getId()); Integer characteristicId = (measure.getCharacteristic() != null ? measure.getCharacteristic().getId() : null); + Integer ruleId = (measure instanceof RuleMeasure ? ((RuleMeasure)measure).getRule().getId() : null); + Integer severityId = (measure instanceof RuleMeasure ? ((RuleMeasure)measure).getRulePriority().ordinal() : null); - Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId)); + Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, ruleId, severityId)); if (updateVariation(measure, pastMeasure, index)) { context.saveMeasure(measure); } @@ -121,30 +123,24 @@ public class VariationDecorator implements Decorator { return getClass().getSimpleName(); } - static class CustomMeasureFilter implements MeasuresFilter<Collection<Measure>> { - public Collection<Measure> filter(Collection<Measure> measures) { - List<Measure> result = Lists.newArrayList(); - for (Measure measure : measures) { - if (!(measure instanceof RuleMeasure)) { - result.add(measure); - } - } - return result; - } - } - static final class MeasureKey { int metricId; Integer characteristicId; + Integer ruleId; + Integer severityId; MeasureKey(Object[] pastFields) { metricId = PastMeasuresLoader.getMetricId(pastFields); characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields); + ruleId = PastMeasuresLoader.getRuleId(pastFields); + severityId = PastMeasuresLoader.getSeverityId(pastFields); } - MeasureKey(int metricId, Integer characteristicId) { + MeasureKey(int metricId, Integer characteristicId, Integer ruleId, Integer severityId) { this.metricId = metricId; this.characteristicId = characteristicId; + this.ruleId = ruleId; + this.severityId = severityId; } @Override @@ -162,6 +158,12 @@ public class VariationDecorator implements Decorator { if (characteristicId != null ? !characteristicId.equals(that.characteristicId) : that.characteristicId != null) { return false; } + if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) { + return false; + } + if (severityId != null ? !severityId.equals(that.severityId) : that.severityId != null) { + return false; + } return true; } @@ -169,6 +171,8 @@ public class VariationDecorator implements Decorator { public int hashCode() { int result = metricId; result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0); + result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0); + result = 31 * result + (severityId != null ? severityId.hashCode() : 0); return result; } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java index 9e4ac766aaf..ba963a10f0a 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java @@ -24,11 +24,10 @@ import org.mockito.Matchers; import org.sonar.api.CoreProperties; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilter; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; +import org.sonar.api.measures.*; import org.sonar.api.resources.*; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RulePriority; import org.sonar.batch.components.PastMeasuresLoader; import org.sonar.batch.components.PastSnapshot; import org.sonar.batch.components.TimeMachineConfiguration; @@ -50,6 +49,9 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { public static final int COVERAGE_ID = 16; public static final Metric COVERAGE = new Metric("coverage").setId(COVERAGE_ID); + public static final int VIOLATIONS_ID = 17; + public static final Metric VIOLATIONS = new Metric("violations").setId(VIOLATIONS_ID); + @Test public void shouldComputeVariations() { TimeMachineConfiguration conf = mock(TimeMachineConfiguration.class); @@ -98,12 +100,12 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { // first past analysis when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList( - new Object[]{NCLOC_ID, null, 180.0}, - new Object[]{COVERAGE_ID, null, 75.0})); + new Object[]{NCLOC_ID, null, null, null, 180.0}, + new Object[]{COVERAGE_ID, null, null, null, 75.0})); // second past analysis when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot3)).thenReturn(Arrays.<Object[]>asList( - new Object[]{NCLOC_ID, null, 240.0})); + new Object[]{NCLOC_ID, null, null, null, 240.0})); // current analysis DecoratorContext context = mock(DecoratorContext.class); @@ -126,11 +128,41 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { assertThat(currentCoverage.getVariation3(), nullValue()); } - private Measure newMeasure(Metric metric, double value) { - return new Measure(metric, value); + @Test + public void shouldComputeVariationOfRuleMeasures() { + Rule rule1 = Rule.create(); + rule1.setId(1); + Rule rule2 = Rule.create(); + rule2.setId(2); + + Resource javaPackage = new JavaPackage("org.foo"); + + PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class); + PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1); + + // first past analysis + when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList( + new Object[]{VIOLATIONS_ID, null, null, null, 180.0},//total + new Object[]{VIOLATIONS_ID, null, rule1.getId(), RulePriority.BLOCKER.ordinal(), 100.0},// rule 1 + new Object[]{VIOLATIONS_ID, null, rule2.getId(), RulePriority.MAJOR.ordinal(), 80.0})); // rule 2 + + // current analysis + DecoratorContext context = mock(DecoratorContext.class); + Measure violations = newMeasure(VIOLATIONS, 200.0); + Measure violationsRule1 = new RuleMeasure(VIOLATIONS, rule1, RulePriority.BLOCKER, null).setValue(130.0); + Measure violationsRule2 = new RuleMeasure(VIOLATIONS, rule2, RulePriority.MAJOR, null).setValue(70.0); + when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2)); + + VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), false); + decorator.decorate(javaPackage, context); + + // context updated for each variation + verify(context, times(3)).saveMeasure(Matchers.<Measure>anyObject()); + + assertThat(violations.getVariation1(), is(20.0)); } - private MeasureModel newMeasureModel(Metric metric, double value) { - return new MeasureModel(metric.getId(), value); + private Measure newMeasure(Metric metric, double value) { + return new Measure(metric, value); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java index c4dd2a56dc0..994625b1281 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java @@ -66,8 +66,8 @@ public class PastMeasuresLoader implements BatchExtension { } public List<Object[]> getPastMeasures(String resourceKey, Snapshot projectPastSnapshot) { - String sql = "select m.metric_id, m.characteristic_id, m.value from project_measures m, snapshots s" + - " where m.snapshot_id=s.id and m.metric_id in (:metricIds) and m.rule_id is null and m.rule_priority is null " + + String sql = "select m.metric_id, m.characteristic_id, m.rule_id, m.rule_priority, m.value from project_measures m, snapshots s" + + " where m.snapshot_id=s.id and m.metric_id in (:metricIds) " + " and (s.root_snapshot_id=:rootSnapshotId or s.id=:rootSnapshotId) and s.status=:status and s.project_id=(select p.id from projects p where p.kee=:resourceKey and p.qualifier<>:lib)"; return session.createNativeQuery(sql) .setParameter("metricIds", metricByIds.keySet()) @@ -89,11 +89,23 @@ public class PastMeasuresLoader implements BatchExtension { return number!=null ? number.intValue() : null; } + public static Integer getRuleId(Object[] row) { + // can be BigDecimal on Oracle + Number number = (Number) row[2]; + return number!=null ? number.intValue() : null; + } + + public static Integer getSeverityId(Object[] row) { + // can be BigDecimal on Oracle + Number number = (Number) row[3]; + return number!=null ? number.intValue() : null; + } + public static boolean hasValue(Object[] row) { - return row[2] != null; + return row[4] != null; } public static double getValue(Object[] row) { - return ((Number) row[2]).doubleValue(); + return ((Number) row[4]).doubleValue(); } } |