From 9ab07e28ce0128a4004d3ce9187ca98f159838e4 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 22 Jul 2015 14:30:59 +0200 Subject: [PATCH] SONAR-6605 Move complexity formulas to its own step --- .../formula/CoreFormulaRepositoryImpl.java | 39 +-- .../step/ComplexityMeasuresStep.java | 97 ++++++++ .../computation/step/ComputationSteps.java | 1 + .../computation/step/PersistMeasuresStep.java | 9 +- .../step/ComplexityMeasuresStepTest.java | 224 ++++++++++++++++++ .../step/PersistMeasuresStepTest.java | 21 ++ .../org/sonar/api/measures/CoreMetrics.java | 1 - 7 files changed, 350 insertions(+), 42 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/step/ComplexityMeasuresStep.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/step/ComplexityMeasuresStepTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/CoreFormulaRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/CoreFormulaRepositoryImpl.java index bcfc94318a2..ed09c56752d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/formula/CoreFormulaRepositoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/formula/CoreFormulaRepositoryImpl.java @@ -23,18 +23,7 @@ package org.sonar.server.computation.formula; import com.google.common.collect.ImmutableList; import java.util.List; -import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY; -import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY; import static org.sonar.api.measures.CoreMetrics.COMMENTED_OUT_CODE_LINES_KEY; -import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY; -import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY; -import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_KEY; -import static org.sonar.api.measures.CoreMetrics.FILES_KEY; -import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY; -import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_KEY; -import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; -import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY; -import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_KEY; public class CoreFormulaRepositoryImpl implements CoreFormulaRepository { @@ -43,33 +32,7 @@ public class CoreFormulaRepositoryImpl implements CoreFormulaRepository { // {@link org.sonar.api.measures.CoreMetrics} // Sum formulas - new SumFormula(COMMENTED_OUT_CODE_LINES_KEY), - new SumFormula(COMPLEXITY_KEY), - new SumFormula(COMPLEXITY_IN_CLASSES_KEY), - // TODO this formula seems to be useless as this measure seems only required on files - new SumFormula(COMPLEXITY_IN_FUNCTIONS_KEY), - - // new SumFormula(CoreMetrics.COMMENT_LINES_KEY), - - // Distribution formulas - new DistributionFormula(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY), - new DistributionFormula(FILE_COMPLEXITY_DISTRIBUTION_KEY), - - // Average formulas, must be executed after all sum formulas as they depend on their measures - AverageFormula.Builder.newBuilder().setOutputMetricKey(FILE_COMPLEXITY_KEY) - .setMainMetricKey(COMPLEXITY_KEY) - .setByMetricKey(FILES_KEY) - .build(), - AverageFormula.Builder.newBuilder().setOutputMetricKey(CLASS_COMPLEXITY_KEY) - .setMainMetricKey(COMPLEXITY_IN_CLASSES_KEY) - .setByMetricKey(CLASSES_KEY) - .setFallbackMetricKey(COMPLEXITY_KEY) - .build(), - AverageFormula.Builder.newBuilder().setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) - .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) - .setByMetricKey(FUNCTIONS_KEY) - .setFallbackMetricKey(COMPLEXITY_KEY) - .build() + new SumFormula(COMMENTED_OUT_CODE_LINES_KEY) ); /** diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComplexityMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComplexityMeasuresStep.java new file mode 100644 index 00000000000..a9e64edf4e6 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComplexityMeasuresStep.java @@ -0,0 +1,97 @@ +/* + * 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.server.computation.step; + +import com.google.common.collect.ImmutableList; +import org.sonar.server.computation.component.TreeRootHolder; +import org.sonar.server.computation.formula.AverageFormula; +import org.sonar.server.computation.formula.DistributionFormula; +import org.sonar.server.computation.formula.Formula; +import org.sonar.server.computation.formula.FormulaExecutorComponentVisitor; +import org.sonar.server.computation.formula.SumFormula; +import org.sonar.server.computation.measure.MeasureRepository; +import org.sonar.server.computation.metric.MetricRepository; + +import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.FILES_KEY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_KEY; + +/** + * Computes complexity measures on files and then aggregates them on higher components. + */ +public class ComplexityMeasuresStep implements ComputationStep { + + private static final ImmutableList FORMULAS = ImmutableList.of( + new SumFormula(COMPLEXITY_KEY), + new SumFormula(COMPLEXITY_IN_CLASSES_KEY), + new SumFormula(COMPLEXITY_IN_FUNCTIONS_KEY), + + new DistributionFormula(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY), + new DistributionFormula(FILE_COMPLEXITY_DISTRIBUTION_KEY), + new DistributionFormula(CLASS_COMPLEXITY_DISTRIBUTION_KEY), + + AverageFormula.Builder.newBuilder().setOutputMetricKey(FILE_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_KEY) + .setByMetricKey(FILES_KEY) + .build(), + AverageFormula.Builder.newBuilder().setOutputMetricKey(CLASS_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_CLASSES_KEY) + .setByMetricKey(CLASSES_KEY) + .setFallbackMetricKey(COMPLEXITY_KEY) + .build(), + AverageFormula.Builder.newBuilder().setOutputMetricKey(FUNCTION_COMPLEXITY_KEY) + .setMainMetricKey(COMPLEXITY_IN_FUNCTIONS_KEY) + .setByMetricKey(FUNCTIONS_KEY) + .setFallbackMetricKey(COMPLEXITY_KEY) + .build() + ); + + private final TreeRootHolder treeRootHolder; + private final MetricRepository metricRepository; + private final MeasureRepository measureRepository; + + public ComplexityMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) { + this.treeRootHolder = treeRootHolder; + this.metricRepository = metricRepository; + this.measureRepository = measureRepository; + } + + @Override + public void execute() { + FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) + .buildFor(FORMULAS) + .visit(treeRootHolder.getRoot()); + } + + @Override + public String getDescription() { + return "Aggregation of complexity measures"; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java index f1feca9a249..4fa5731b797 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java @@ -63,6 +63,7 @@ public class ComputationSteps { CoreMetricFormulaExecutorStep.class, LanguageDistributionMeasuresStep.class, UnitTestMeasuresStep.class, + ComplexityMeasuresStep.class, // SQALE measures depend on issues SqaleMeasuresStep.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java index a6f6c47e552..516eb979ac0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java @@ -28,7 +28,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; import javax.annotation.Nonnull; -import org.sonar.api.measures.CoreMetrics; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.measure.MeasureDto; @@ -44,6 +43,9 @@ import org.sonar.server.computation.metric.Metric; import org.sonar.server.computation.metric.MetricRepository; import static com.google.common.collect.FluentIterable.from; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY; import static org.sonar.server.computation.component.ComponentVisitor.Order.PRE_ORDER; public class PersistMeasuresStep implements ComputationStep { @@ -52,8 +54,9 @@ public class PersistMeasuresStep implements ComputationStep { * List of metrics that should not be persisted on file measure (Waiting for SONAR-6688 to be implemented) */ private static final List NOT_TO_PERSIST_ON_FILE_METRIC_KEYS = ImmutableList.of( - CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY, - CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY + FILE_COMPLEXITY_DISTRIBUTION_KEY, + FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, + CLASS_COMPLEXITY_DISTRIBUTION_KEY ); private final DbClient dbClient; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComplexityMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComplexityMeasuresStepTest.java new file mode 100644 index 00000000000..fc22ae201da --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComplexityMeasuresStepTest.java @@ -0,0 +1,224 @@ +/* + * 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.server.computation.step; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.server.computation.batch.BatchReportReaderRule; +import org.sonar.server.computation.batch.TreeRootHolderRule; +import org.sonar.server.computation.component.DumbComponent; +import org.sonar.server.computation.measure.MeasureRepositoryRule; +import org.sonar.server.computation.metric.MetricRepositoryRule; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.guava.api.Assertions.assertThat; +import static org.sonar.api.measures.CoreMetrics.CLASSES; +import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_CLASSES_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_IN_FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.FILES; +import static org.sonar.api.measures.CoreMetrics.FILES_KEY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTIONS; +import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY; +import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_KEY; +import static org.sonar.server.computation.component.Component.Type.DIRECTORY; +import static org.sonar.server.computation.component.Component.Type.FILE; +import static org.sonar.server.computation.component.Component.Type.MODULE; +import static org.sonar.server.computation.component.Component.Type.PROJECT; +import static org.sonar.server.computation.component.DumbComponent.builder; +import static org.sonar.server.computation.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf; +import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries; + +public class ComplexityMeasuresStepTest { + + private static final int ROOT_REF = 1; + private static final int MODULE_REF = 11; + private static final int SUB_MODULE_REF = 111; + private static final int DIRECTORY_REF = 1111; + private static final int FILE_1_REF = 11111; + private static final int FILE_2_REF = 11121; + + private static final DumbComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF) + .addChildren( + builder(MODULE, MODULE_REF) + .addChildren( + builder(MODULE, SUB_MODULE_REF) + .addChildren( + builder(DIRECTORY, DIRECTORY_REF) + .addChildren( + builder(FILE, FILE_1_REF).build(), + builder(FILE, FILE_2_REF).build() + ).build() + ) + .build() + ).build() + ).build(); + + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(MULTIPLE_FILES_TREE); + + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(COMPLEXITY) + .add(COMPLEXITY_IN_CLASSES) + .add(COMPLEXITY_IN_FUNCTIONS) + .add(FUNCTION_COMPLEXITY_DISTRIBUTION) + .add(FILE_COMPLEXITY_DISTRIBUTION) + .add(CLASS_COMPLEXITY_DISTRIBUTION) + .add(FILE_COMPLEXITY) + .add(FILES) + .add(CLASS_COMPLEXITY) + .add(CLASSES) + .add(FUNCTION_COMPLEXITY) + .add(FUNCTIONS) + ; + + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + private ComputationStep underTest = new ComplexityMeasuresStep(treeRootHolder, metricRepository, measureRepository); + + @Test + public void aggregate_complexity() throws Exception { + verify_sum_aggregation(COMPLEXITY_KEY); + } + + @Test + public void aggregate_complexity_in_classes() throws Exception { + verify_sum_aggregation(COMPLEXITY_IN_CLASSES_KEY); + } + + @Test + public void aggregate_complexity_in_functions() throws Exception { + verify_sum_aggregation(COMPLEXITY_IN_FUNCTIONS_KEY); + } + + private void verify_sum_aggregation(String metricKey){ + measureRepository.addRawMeasure(FILE_1_REF, metricKey, newMeasureBuilder().create(10)); + measureRepository.addRawMeasure(FILE_2_REF, metricKey, newMeasureBuilder().create(40)); + + underTest.execute(); + + assertThat(measureRepository.getAddedRawMeasure(FILE_1_REF, metricKey)).isAbsent(); + assertThat(measureRepository.getAddedRawMeasure(FILE_2_REF, metricKey)).isAbsent(); + + int expectedNonFileValue = 50; + assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + } + + @Test + public void aggregate_function_complexity_distribution() throws Exception { + verify_distribution_aggregation(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY); + } + + @Test + public void aggregate_file_complexity_distribution() throws Exception { + verify_distribution_aggregation(FILE_COMPLEXITY_DISTRIBUTION_KEY); + } + + @Test + public void aggregate_class_complexity_distribution() throws Exception { + verify_distribution_aggregation(CLASS_COMPLEXITY_DISTRIBUTION_KEY); + } + + private void verify_distribution_aggregation(String metricKey){ + measureRepository.addRawMeasure(FILE_1_REF, metricKey, newMeasureBuilder().create("0.5=3;3.5=5;6.5=9")); + measureRepository.addRawMeasure(FILE_2_REF, metricKey, newMeasureBuilder().create("0.5=0;3.5=2;6.5=1")); + + underTest.execute(); + + assertThat(measureRepository.getAddedRawMeasure(FILE_1_REF, metricKey)).isAbsent(); + assertThat(measureRepository.getAddedRawMeasure(FILE_2_REF, metricKey)).isAbsent(); + + String expectedNonFileValue = "0.5=3;3.5=7;6.5=10"; + assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + } + + @Test + public void compute_and_aggregate_file_complexity() throws Exception { + verify_average_compute_and_aggregation(FILE_COMPLEXITY_KEY, COMPLEXITY_KEY, FILES_KEY); + } + + @Test + public void compute_and_aggregate_class_complexity() throws Exception { + verify_average_compute_and_aggregation(CLASS_COMPLEXITY_KEY, COMPLEXITY_IN_CLASSES_KEY, CLASSES_KEY); + } + + @Test + public void compute_and_aggregate_class_complexity_with_fallback_metric() throws Exception { + verify_average_compute_and_aggregation(CLASS_COMPLEXITY_KEY, COMPLEXITY_KEY, CLASSES_KEY); + } + + @Test + public void compute_and_aggregate_function_complexity() throws Exception { + verify_average_compute_and_aggregation(FUNCTION_COMPLEXITY_KEY, COMPLEXITY_IN_FUNCTIONS_KEY, FUNCTIONS_KEY); + } + + @Test + public void compute_and_aggregate_function_complexity_with_fallback_metric() throws Exception { + verify_average_compute_and_aggregation(FUNCTION_COMPLEXITY_KEY, COMPLEXITY_KEY, FUNCTIONS_KEY); + } + + private void verify_average_compute_and_aggregation(String metricKey, String mainMetric, String byMetric){ + measureRepository.addRawMeasure(FILE_1_REF, mainMetric, newMeasureBuilder().create(5)); + measureRepository.addRawMeasure(FILE_1_REF, byMetric, newMeasureBuilder().create(2)); + + measureRepository.addRawMeasure(FILE_2_REF, mainMetric, newMeasureBuilder().create(1)); + measureRepository.addRawMeasure(FILE_2_REF, byMetric, newMeasureBuilder().create(1)); + + underTest.execute(); + + assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(2.5))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(1d))); + + double expectedNonFileValue = 2d; + assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(entryOf(metricKey, newMeasureBuilder().create(expectedNonFileValue))); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java index d037216c6b6..fa646206d12 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java @@ -44,6 +44,8 @@ import org.sonar.server.computation.period.Period; import org.sonar.test.DbTests; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION; +import static org.sonar.api.measures.CoreMetrics.CLASS_COMPLEXITY_DISTRIBUTION_KEY; import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION; import static org.sonar.api.measures.CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION_KEY; import static org.sonar.api.measures.CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION; @@ -219,6 +221,25 @@ public class PersistMeasuresStepTest extends BaseStepTest { assertThat(dto.get("textValue")).isEqualTo("0=1;2=10"); } + @Test + public void do_not_insert_class_complexity_distribution_metric_on_files() { + metricRepository.add(1, CLASS_COMPLEXITY_DISTRIBUTION); + + measureRepository.addRawMeasure(PROJECT_REF, CLASS_COMPLEXITY_DISTRIBUTION_KEY, Measure.newMeasureBuilder().create("0=1;2=10")); + measureRepository.addRawMeasure(FILE_REF, CLASS_COMPLEXITY_DISTRIBUTION_KEY, Measure.newMeasureBuilder().create("0=1;2=10")); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable("project_measures")).isEqualTo(1); + + List> dtos = selectSnapshots(); + + Map dto = dtos.get(0); + assertThat(dto.get("snapshotId")).isEqualTo(3L); + assertThat(dto.get("componentId")).isEqualTo(projectDto.getId()); + assertThat(dto.get("textValue")).isEqualTo("0=1;2=10"); + } + private ComponentDto addComponent(String key) { ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(Uuids.create()); dbClient.componentDao().insert(dbTester.getSession(), componentDto); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java index 21006bfaadc..b5b5cae4096 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java @@ -372,7 +372,6 @@ public final class CoreMetrics { .setDirection(Metric.DIRECTION_NONE) .setQualitative(true) .setDomain(DOMAIN_COMPLEXITY) - .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)) .setHidden(true) .create(); -- 2.39.5