]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11776 Quality Gate failure conditions should be sorted
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 7 Mar 2019 22:45:53 +0000 (16:45 -0600)
committerSonarTech <sonartech@sonarsource.com>
Mon, 11 Mar 2019 19:21:04 +0000 (20:21 +0100)
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/measure/qualitygatedetails/QualityGateDetailsData.java
server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ConditionComparator.java [new file with mode: 0644]
server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/EvaluatedQualityGate.java
server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionComparatorTest.java [new file with mode: 0644]

index 5c0071af71639a85bb8b42a7b5fa7034bcdc4bd3..6b907393f7769807bb6d286fab09bd6909af9314 100644 (file)
@@ -22,11 +22,13 @@ package org.sonar.ce.task.projectanalysis.measure.qualitygatedetails;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 import javax.annotation.concurrent.Immutable;
 import org.sonar.ce.task.projectanalysis.measure.Measure;
 import org.sonar.ce.task.projectanalysis.qualitygate.Condition;
+import org.sonar.server.qualitygate.ConditionComparator;
 
-import static com.google.common.collect.FluentIterable.from;
 import static java.util.Objects.requireNonNull;
 
 @Immutable
@@ -40,7 +42,9 @@ public class QualityGateDetailsData {
 
   public QualityGateDetailsData(Measure.Level level, Iterable<EvaluatedCondition> conditions, boolean ignoredConditions) {
     this.level = requireNonNull(level);
-    this.conditions = from(conditions).toList();
+    this.conditions = StreamSupport.stream(conditions.spliterator(), false)
+      .sorted(new ConditionComparator<>(c -> c.getCondition().getMetric().getKey()))
+      .collect(Collectors.toList());
     this.ignoredConditions = ignoredConditions;
   }
 
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ConditionComparator.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ConditionComparator.java
new file mode 100644 (file)
index 0000000..41fd74b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualitygate;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
+import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY;
+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;
+import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
+
+/**
+ * Sorts conditions, first based on an hardcoded list of metric keys, then alphabetically by metric key.
+ */
+public class ConditionComparator<T> implements Comparator<T> {
+  private static final List<String> CONDITIONS_ORDER = Arrays.asList(NEW_RELIABILITY_RATING_KEY, RELIABILITY_RATING_KEY,
+    NEW_SECURITY_RATING_KEY, SECURITY_RATING_KEY, NEW_MAINTAINABILITY_RATING_KEY, SQALE_RATING_KEY,
+    NEW_COVERAGE_KEY, COVERAGE_KEY,
+    NEW_DUPLICATED_LINES_DENSITY_KEY, DUPLICATED_LINES_DENSITY_KEY);
+  private static final Map<String, Integer> CONDITIONS_ORDER_IDX = IntStream.range(0, CONDITIONS_ORDER.size()).boxed()
+    .collect(Collectors.toMap(CONDITIONS_ORDER::get, x -> x));
+
+  private final Function<T, String> metricKeyExtractor;
+
+  public ConditionComparator(Function<T, String> metricKeyExtractor) {
+    this.metricKeyExtractor = metricKeyExtractor;
+  }
+
+  @Override public int compare(T c1, T c2) {
+    Function<T, Integer> byList = c -> CONDITIONS_ORDER_IDX.getOrDefault(metricKeyExtractor.apply(c), Integer.MAX_VALUE);
+    return Comparator.comparing(byList).thenComparing(metricKeyExtractor).compare(c1, c2);
+  }
+}
index d73a5d8d2e3a8c6373ef031594311ea13c46d506..0f8be785f0629aed3ba19771b77579658460bb2c 100644 (file)
@@ -21,17 +21,13 @@ package org.sonar.server.qualitygate;
 
 import com.google.common.collect.ImmutableSet;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.function.Function;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 import org.sonar.api.measures.Metric;
@@ -39,16 +35,6 @@ import org.sonar.server.qualitygate.EvaluatedCondition.EvaluationStatus;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
-import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY;
-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;
-import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY;
 
 @Immutable
 public class EvaluatedQualityGate {
@@ -113,19 +99,6 @@ public class EvaluatedQualityGate {
   }
 
   public static final class Builder {
-    private static final List<String> CONDITIONS_ORDER = Arrays.asList(NEW_RELIABILITY_RATING_KEY, RELIABILITY_RATING_KEY,
-      NEW_SECURITY_RATING_KEY, SECURITY_RATING_KEY, NEW_MAINTAINABILITY_RATING_KEY, SQALE_RATING_KEY,
-      NEW_COVERAGE_KEY, COVERAGE_KEY,
-      NEW_DUPLICATED_LINES_DENSITY_KEY, DUPLICATED_LINES_DENSITY_KEY);
-    private static final Map<String, Integer> CONDITIONS_ORDER_IDX = IntStream.range(0, CONDITIONS_ORDER.size()).boxed()
-      .collect(Collectors.toMap(CONDITIONS_ORDER::get, x -> x));
-
-    private static final Comparator<EvaluatedCondition> CONDITION_COMPARATOR = (c1, c2) -> {
-      Function<EvaluatedCondition, Integer> byList = c -> CONDITIONS_ORDER_IDX.getOrDefault(c.getCondition().getMetricKey(), Integer.MAX_VALUE);
-      Function<EvaluatedCondition, String> byMetricKey = c -> c.getCondition().getMetricKey();
-      return Comparator.comparing(byList).thenComparing(byMetricKey).compare(c1, c2);
-    };
-
     private QualityGate qualityGate;
     private Metric.Level status;
     private final Map<Condition, EvaluatedCondition> evaluatedConditions = new LinkedHashMap<>();
@@ -167,7 +140,7 @@ public class EvaluatedQualityGate {
     public EvaluatedQualityGate build() {
       checkEvaluatedConditions(qualityGate, evaluatedConditions);
       List<EvaluatedCondition> sortedEvaluatedConditions = new ArrayList<>(evaluatedConditions.values());
-      sortedEvaluatedConditions.sort(CONDITION_COMPARATOR);
+      sortedEvaluatedConditions.sort(new ConditionComparator<>(c -> c.getCondition().getMetricKey()));
       return new EvaluatedQualityGate(
         this.qualityGate,
         this.status,
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionComparatorTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ConditionComparatorTest.java
new file mode 100644 (file)
index 0000000..62ac535
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.qualitygate;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+
+import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_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.SQALE_RATING_KEY;
+
+public class ConditionComparatorTest {
+  @Test
+  public void sort_by_hardcoded_metric_keys_then_alphabetically() {
+    ConditionComparator<String> comparator = new ConditionComparator<>(x -> x);
+    List<String> conditions = Arrays.asList(NEW_DUPLICATED_LINES_DENSITY_KEY, RELIABILITY_RATING_KEY, "rule1", SQALE_RATING_KEY, "abc",
+      NEW_SECURITY_RATING_KEY, "metric", NEW_COVERAGE_KEY);
+    conditions.sort(comparator);
+    assertThat(conditions).contains(RELIABILITY_RATING_KEY, NEW_SECURITY_RATING_KEY, SQALE_RATING_KEY,
+      NEW_COVERAGE_KEY, "abc", "metric", "rule1");
+  }
+}