]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6605 Move complexity formulas to its own step
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 22 Jul 2015 12:30:59 +0000 (14:30 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 23 Jul 2015 16:00:38 +0000 (18:00 +0200)
server/sonar-server/src/main/java/org/sonar/server/computation/formula/CoreFormulaRepositoryImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComplexityMeasuresStep.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/ComplexityMeasuresStepTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java

index bcfc94318a23918cbf8e832d796438befe8e9a0b..ed09c56752d6403b1b7d3460439c4adc51870334 100644 (file)
@@ -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 (file)
index 0000000..a9e64ed
--- /dev/null
@@ -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<Formula> FORMULAS = ImmutableList.<Formula>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";
+  }
+}
index f1feca9a2492bd5e04d1c6b608a767ae436d262e..4fa5731b79713eaa7f31554eb3340af6ee8598d2 100644 (file)
@@ -63,6 +63,7 @@ public class ComputationSteps {
       CoreMetricFormulaExecutorStep.class,
       LanguageDistributionMeasuresStep.class,
       UnitTestMeasuresStep.class,
+      ComplexityMeasuresStep.class,
 
       // SQALE measures depend on issues
       SqaleMeasuresStep.class,
index a6f6c47e552280fdc9b6502329d1adbe70c6e886..516eb979ac039082d435ed02c7765626963fb496 100644 (file)
@@ -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<String> 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 (file)
index 0000000..fc22ae2
--- /dev/null
@@ -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)));
+  }
+
+}
index d037216c6b68502f878e9f99412c5e4f7eddf032..fa646206d1224e3202bec433c07aec59efad7c35 100644 (file)
@@ -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<Map<String, Object>> dtos = selectSnapshots();
+
+    Map<String, Object> 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);
index 21006bfaadc31b32d8c48984831a20e4e131b340..b5b5cae40963c091c05f20760dfd277faeccfef3 100644 (file)
@@ -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();