From: Julien Lancelot Date: Thu, 18 Jun 2015 13:23:51 +0000 (+0200) Subject: SONAR-6643 Remove VariationDecorator from the batch X-Git-Tag: 5.2-RC1~1413 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=569848e5c4aac2902d249fe7e7dbe279d5394c39;p=sonarqube.git SONAR-6643 Remove VariationDecorator from the batch --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index ec1cd10a490..92ad324bcc6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -42,7 +42,6 @@ import org.sonar.batch.compute.OverallBranchCoverageDecorator; import org.sonar.batch.compute.OverallCoverageDecorator; import org.sonar.batch.compute.OverallLineCoverageDecorator; import org.sonar.batch.compute.UnitTestDecorator; -import org.sonar.batch.compute.VariationDecorator; import org.sonar.batch.cpd.CpdComponents; import org.sonar.batch.debt.DebtDecorator; import org.sonar.batch.debt.IssueChangelogDebtCalculator; @@ -128,7 +127,6 @@ public class BatchComponents { CommentDensityDecorator.class, DirectoriesDecorator.class, FilesDecorator.class, - VariationDecorator.class, NewCoverageFileAnalyzer.class, NewItCoverageFileAnalyzer.class, NewOverallCoverageFileAnalyzer.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java deleted file mode 100644 index f3885ef3f8c..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/compute/VariationDecorator.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.compute; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorBarriers; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependedUpon; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.batch.RequiresDB; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilters; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; -import org.sonar.api.measures.RuleMeasure; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; -import org.sonar.api.resources.Scopes; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.technicaldebt.batch.Characteristic; -import org.sonar.batch.components.PastMeasuresLoader; -import org.sonar.batch.components.PastSnapshot; -import org.sonar.batch.components.TimeMachineConfiguration; - -@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) -@RequiresDB -public class VariationDecorator implements Decorator { - - private List projectPastSnapshots; - private MetricFinder metricFinder; - private PastMeasuresLoader pastMeasuresLoader; - private RuleFinder ruleFinder; - - public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, TimeMachineConfiguration timeMachineConfiguration, RuleFinder ruleFinder) { - this(pastMeasuresLoader, metricFinder, timeMachineConfiguration.getProjectPastSnapshots(), ruleFinder); - } - - VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, List projectPastSnapshots, RuleFinder ruleFinder) { - this.pastMeasuresLoader = pastMeasuresLoader; - this.projectPastSnapshots = projectPastSnapshots; - this.metricFinder = metricFinder; - this.ruleFinder = ruleFinder; - } - - @Override - public boolean shouldExecuteOnProject(Project project) { - return true; - } - - @DependsUpon - public Collection dependsUponMetrics() { - return pastMeasuresLoader.getMetrics(); - } - - @Override - public void decorate(Resource resource, DecoratorContext context) { - for (PastSnapshot projectPastSnapshot : projectPastSnapshots) { - if (shouldComputeVariation(resource)) { - computeVariation(resource, context, projectPastSnapshot); - } - } - } - - boolean shouldComputeVariation(Resource resource) { - if (Scopes.FILE.equals(resource.getScope()) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier())) { - return false; - } - - // measures on files are currently purged, so past measures are not available on files - return StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()); - } - - private void computeVariation(Resource resource, DecoratorContext context, PastSnapshot pastSnapshot) { - List pastMeasures = pastMeasuresLoader.getPastMeasures(resource, pastSnapshot); - compareWithPastMeasures(context, pastSnapshot.getIndex(), pastMeasures); - } - - private void compareWithPastMeasures(DecoratorContext context, int index, List pastMeasures) { - Map pastMeasuresByKey = new HashMap<>(); - for (Object[] pastMeasure : pastMeasures) { - pastMeasuresByKey.put(new MeasureKey(pastMeasure), pastMeasure); - } - - // for each measure, search equivalent past measure - for (Measure measure : context.getMeasures(MeasuresFilters.all())) { - // compare with past measure - Integer metricId = measure.getMetric().getId(); - if (metricId == null) { - Metric metric = metricFinder.findByKey(measure.getMetric().getKey()); - if (metric == null) { - throw new IllegalStateException("Unknow metric with key: " + measure.getMetric().getKey()); - } - metricId = metric.getId(); - } - Characteristic characteristic = measure.getCharacteristic(); - Integer characteristicId = characteristic != null ? characteristic.id() : null; - Integer personId = measure.getPersonId(); - Integer ruleId = null; - if (measure instanceof RuleMeasure) { - Rule rule = ruleFinder.findByKey(((RuleMeasure) measure).ruleKey()); - if (rule != null) { - ruleId = rule.getId(); - } - } - - Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, personId, ruleId)); - if (updateVariation(measure, pastMeasure, index)) { - context.saveMeasure(measure); - } - } - } - - boolean updateVariation(Measure measure, Object[] pastMeasure, int index) { - if (pastMeasure != null && PastMeasuresLoader.hasValue(pastMeasure) && measure.getValue() != null) { - double variation = measure.getValue() - PastMeasuresLoader.getValue(pastMeasure); - measure.setVariation(index, variation); - return true; - } - return false; - } - - @Override - public String toString() { - return getClass().getSimpleName(); - } - - static final class MeasureKey { - int metricId; - Integer characteristicId; - Integer personId; - Integer ruleId; - - MeasureKey(Object[] pastFields) { - metricId = PastMeasuresLoader.getMetricId(pastFields); - characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields); - personId = PastMeasuresLoader.getPersonId(pastFields); - ruleId = PastMeasuresLoader.getRuleId(pastFields); - } - - MeasureKey(int metricId, @Nullable Integer characteristicId, @Nullable Integer personId, @Nullable Integer ruleId) { - this.metricId = metricId; - this.characteristicId = characteristicId; - this.personId = personId; - this.ruleId = ruleId; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - MeasureKey that = (MeasureKey) o; - if (metricId != that.metricId) { - return false; - } - if (characteristicId != null ? !characteristicId.equals(that.characteristicId) : that.characteristicId != null) { - return false; - } - if (personId != null ? !personId.equals(that.personId) : that.personId != null) { - return false; - } - if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int result = metricId; - result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0); - result = 31 * result + (personId != null ? personId.hashCode() : 0); - result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0); - return result; - } - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java deleted file mode 100644 index 21f26e09090..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/compute/VariationDecoratorTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.compute; - -import java.util.Arrays; -import java.util.Date; -import org.junit.Test; -import org.mockito.Matchers; -import org.sonar.api.batch.DecoratorContext; -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.RuleMeasure; -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.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.batch.components.PastMeasuresLoader; -import org.sonar.batch.components.PastSnapshot; -import org.sonar.batch.components.TimeMachineConfiguration; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class VariationDecoratorTest extends AbstractDbUnitTestCase { - - public static final int NCLOC_ID = 12; - public static final Metric NCLOC = new Metric("ncloc").setId(NCLOC_ID); - - 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 timeMachineConfiguration = mock(TimeMachineConfiguration.class); - VariationDecorator decorator = new VariationDecorator(mock(PastMeasuresLoader.class), mock(MetricFinder.class), timeMachineConfiguration, mock(RuleFinder.class)); - - assertThat(decorator.shouldComputeVariation(new Project("foo"))).isTrue(); - assertThat(decorator.shouldComputeVariation(File.create("foo/bar.c"))).isFalse(); - } - - @Test - public void shouldCompareAndSaveVariation() { - Resource dir = Directory.create("org/foo"); - - PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class); - PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1); - PastSnapshot pastSnapshot3 = new PastSnapshot("days", new Date()).setIndex(3); - - // first past analysis - when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList( - new Object[] {NCLOC_ID, null, null, null, 180.0}, - new Object[] {COVERAGE_ID, null, null, null, 75.0})); - - // second past analysis - when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot3)).thenReturn(Arrays.asList( - new Object[] {NCLOC_ID, null, null, null, 240.0})); - - // current analysis - DecoratorContext context = mock(DecoratorContext.class); - Measure currentNcloc = newMeasure(NCLOC, 200.0); - Measure currentCoverage = newMeasure(COVERAGE, 80.0); - when(context.getMeasures(Matchers.anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage)); - - VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3), mock(RuleFinder.class)); - decorator.decorate(dir, context); - - // context updated for each variation : 2 times for ncloc and 1 time for coverage - verify(context, times(3)).saveMeasure(Matchers.anyObject()); - - assertThat(currentNcloc.getVariation1()).isEqualTo(20.0); - assertThat(currentNcloc.getVariation2()).isNull(); - assertThat(currentNcloc.getVariation3()).isEqualTo(-40.0); - - assertThat(currentCoverage.getVariation1()).isEqualTo(5.0); - assertThat(currentCoverage.getVariation2()).isNull(); - assertThat(currentCoverage.getVariation3()).isNull(); - } - - @Test - public void shouldComputeVariationOfRuleMeasures() { - RuleFinder ruleFinder = mock(RuleFinder.class); - - Rule rule1 = Rule.create("repo", "rule1"); - rule1.setId(1); - Rule rule2 = Rule.create("repo", "rule2"); - rule2.setId(2); - - when(ruleFinder.findByKey(rule1.ruleKey())).thenReturn(rule1); - when(ruleFinder.findByKey(rule2.ruleKey())).thenReturn(rule2); - - Resource dir = Directory.create("org/foo"); - - PastMeasuresLoader pastMeasuresLoader = mock(PastMeasuresLoader.class); - PastSnapshot pastSnapshot1 = new PastSnapshot("days", new Date()).setIndex(1); - - // first past analysis - when(pastMeasuresLoader.getPastMeasures(dir, pastSnapshot1)).thenReturn(Arrays.asList( - new Object[] {VIOLATIONS_ID, null, null, null, 180.0},// total - new Object[] {VIOLATIONS_ID, null, null, rule1.getId(), 100.0},// rule 1 - new Object[] {VIOLATIONS_ID, null, null, rule2.getId(), 80.0})); // rule 2 - - // current analysis - DecoratorContext context = mock(DecoratorContext.class); - Measure violations = newMeasure(VIOLATIONS, 200.0); - Measure violationsRule1 = RuleMeasure.createForRule(VIOLATIONS, rule1, 130.0); - Measure violationsRule2 = RuleMeasure.createForRule(VIOLATIONS, rule2, 70.0); - when(context.getMeasures(Matchers.anyObject())).thenReturn(Arrays.asList(violations, violationsRule1, violationsRule2)); - - VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1), ruleFinder); - decorator.decorate(dir, context); - - // context updated for each variation - verify(context, times(3)).saveMeasure(Matchers.anyObject()); - - assertThat(violations.getVariation1()).isEqualTo(20.0); - } - - private Measure newMeasure(Metric metric, double value) { - return new Measure(metric, value); - } -}