]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-1835 Sonar should sort alerts based on the functional meaning of the indicators
authorJulien Lancelot <julien.lancelot@gmail.com>
Wed, 21 Aug 2013 17:34:22 +0000 (19:34 +0200)
committerJulien Lancelot <julien.lancelot@gmail.com>
Wed, 21 Aug 2013 17:34:22 +0000 (19:34 +0200)
sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSort.java
sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java
sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterExecutorTest.java
sonar-core/src/test/resources/org/sonar/core/measure/MeasureFilterExecutorTest/sort_by_alert.xml [new file with mode: 0644]

index b3ee0d6f1aeb346e946e43d996c218362b386024..b9e02f35468a1576e3a20074b873455ef0329e12 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.core.measure;
 
+import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 
 class MeasureFilterSort {
@@ -83,6 +84,10 @@ class MeasureFilterSort {
     return Field.DATE.equals(field) || Field.PROJECT_CREATION_DATE.equals(field);
   }
 
+  boolean isOnAlert() {
+    return metric != null && metric.getKey().equals(CoreMetrics.ALERT_STATUS_KEY);
+  }
+
   boolean isAsc() {
     return asc;
   }
index ea072f115ae037a7e981c311f82deb596837d20f..252040641112560424dc7fa5a54fc1913eae8bba 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.measure;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Ordering;
 import org.apache.commons.dbutils.DbUtils;
@@ -191,6 +192,8 @@ class MeasureFilterSql {
       rowProcessor = new NumericSortRowProcessor();
     } else if (filter.sort().isOnDate()) {
       rowProcessor = new DateSortRowProcessor();
+    } else if (filter.sort().isOnAlert()) {
+      rowProcessor = new AlertSortRowProcessor();
     } else {
       rowProcessor = new TextSortRowProcessor();
     }
@@ -250,7 +253,25 @@ class MeasureFilterSql {
       }
       return ordering;
     }
+  }
 
+  static class AlertSortRowProcessor extends TextSortRowProcessor {
+    Function sortFieldFunction() {
+      return new Function<MeasureFilterRow, Integer>() {
+        public Integer apply(MeasureFilterRow row) {
+          return ImmutableList.of("OK", "WARN", "ERROR").indexOf(row.getSortText());
+        }
+      };
+    }
+
+    @Override
+    Ordering sortFieldOrdering(boolean ascending) {
+      Ordering<Integer> ordering = Ordering.<Integer>natural().nullsLast();
+      if (!ascending) {
+        ordering = ordering.reverse();
+      }
+      return ordering;
+    }
   }
 
   static class NumericSortRowProcessor extends RowProcessor {
@@ -325,3 +346,4 @@ class MeasureFilterSql {
     });
   }
 }
+
index 392ead327cd1ce3a86762afde14d428cb9fb1f73..71e39f7e897cee08b80c5bafed79a3ca80d753ec 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.core.measure;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.core.persistence.TestDatabase;
@@ -359,6 +360,36 @@ public class MeasureFilterExecutorTest {
     assertThat(DateUtils.formatDate(rows.get(1).getSortDate())).isEqualTo("2008-12-19");
   }
 
+  @Test
+  public void sort_by_ascending_alert() throws SQLException {
+    db.prepareDbUnit(getClass(), "sort_by_alert.xml");
+
+    Metric alert = new Metric.Builder(CoreMetrics.ALERT_STATUS_KEY, "Alert", Metric.ValueType.LEVEL).create().setId(5);
+    MeasureFilter filter = new MeasureFilter().setResourceQualifiers(Arrays.asList("TRK")).setSortOnMetric(alert);
+    List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext());
+
+    // Php Project OK, Java Project WARN then Js Project ERROR
+    assertThat(rows).hasSize(3);
+    verifyPhpProject(rows.get(0));
+    verifyJavaProject(rows.get(1));
+    verifyProject(rows.get(2), 120L, 20L, 20L);
+  }
+
+  @Test
+  public void sort_by_descending_alert() throws SQLException {
+    db.prepareDbUnit(getClass(), "sort_by_alert.xml");
+
+    Metric alert = new Metric.Builder(CoreMetrics.ALERT_STATUS_KEY, "Alert", Metric.ValueType.LEVEL).create().setId(5);
+    MeasureFilter filter = new MeasureFilter().setResourceQualifiers(Arrays.asList("TRK")).setSortOnMetric(alert).setSortAsc(false);
+    List<MeasureFilterRow> rows = executor.execute(filter, new MeasureFilterContext());
+
+    // Js Project ERROR, Java Project WARN, then Php Project OK
+    assertThat(rows).hasSize(3);
+    verifyProject(rows.get(0), 120L, 20L, 20L);
+    verifyJavaProject(rows.get(1));
+    verifyPhpProject(rows.get(2));
+  }
+
   @Test
   public void condition_on_numeric_measure() throws SQLException {
     db.prepareDbUnit(getClass(), "shared.xml");
@@ -547,26 +578,24 @@ public class MeasureFilterExecutorTest {
 
 
   private void verifyJavaProject(MeasureFilterRow row) {
-    assertThat(row.getSnapshotId()).isEqualTo(JAVA_PROJECT_SNAPSHOT_ID);
-    assertThat(row.getResourceId()).isEqualTo(JAVA_PROJECT_ID);
-    assertThat(row.getResourceRootId()).isEqualTo(JAVA_PROJECT_ID);
+    verifyProject(row, JAVA_PROJECT_SNAPSHOT_ID, JAVA_PROJECT_ID, JAVA_PROJECT_ID);
   }
 
   private void verifyJavaBigFile(MeasureFilterRow row) {
-    assertThat(row.getSnapshotId()).isEqualTo(JAVA_FILE_BIG_SNAPSHOT_ID);
-    assertThat(row.getResourceId()).isEqualTo(JAVA_FILE_BIG_ID);
-    assertThat(row.getResourceRootId()).isEqualTo(JAVA_PROJECT_ID);
+    verifyProject(row, JAVA_FILE_BIG_SNAPSHOT_ID, JAVA_FILE_BIG_ID, JAVA_PROJECT_ID);
   }
 
   private void verifyJavaTinyFile(MeasureFilterRow row) {
-    assertThat(row.getSnapshotId()).isEqualTo(JAVA_FILE_TINY_SNAPSHOT_ID);
-    assertThat(row.getResourceId()).isEqualTo(JAVA_FILE_TINY_ID);
-    assertThat(row.getResourceRootId()).isEqualTo(JAVA_PROJECT_ID);
+    verifyProject(row, JAVA_FILE_TINY_SNAPSHOT_ID, JAVA_FILE_TINY_ID, JAVA_PROJECT_ID);
   }
 
   private void verifyPhpProject(MeasureFilterRow row) {
-    assertThat(row.getSnapshotId()).isEqualTo(PHP_SNAPSHOT_ID);
-    assertThat(row.getResourceId()).isEqualTo(PHP_PROJECT_ID);
-    assertThat(row.getResourceRootId()).isEqualTo(PHP_PROJECT_ID);
+    verifyProject(row, PHP_SNAPSHOT_ID, PHP_PROJECT_ID, PHP_PROJECT_ID);
+  }
+
+  private void verifyProject(MeasureFilterRow row, Long snashotId, Long resourceId, Long resourceRootId) {
+    assertThat(row.getSnapshotId()).isEqualTo(snashotId);
+    assertThat(row.getResourceId()).isEqualTo(resourceId);
+    assertThat(row.getResourceRootId()).isEqualTo(resourceRootId);
   }
 }
diff --git a/sonar-core/src/test/resources/org/sonar/core/measure/MeasureFilterExecutorTest/sort_by_alert.xml b/sonar-core/src/test/resources/org/sonar/core/measure/MeasureFilterExecutorTest/sort_by_alert.xml
new file mode 100644 (file)
index 0000000..292037e
--- /dev/null
@@ -0,0 +1,81 @@
+<dataset>
+  <metrics id="5" name="alert_status" val_type="LEVEL" description="Alert" domain="General"
+           short_name="Alert" qualitative="[true]" user_managed="[false]" enabled="[true]" origin="JAV"
+           worst_value="[null]"
+           optimized_best_value="[true]" best_value="[null]" direction="1" hidden="[false]"
+           delete_historical_data="[null]"/>
+
+  <!-- java project -->
+  <projects kee="java_project" long_name="Java project" scope="PRJ" qualifier="TRK" name="Java project"
+            id="1" root_id="[null]"
+            description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"
+            created_at="2008-12-19 00:00:00.00"/>
+
+  <snapshots id="101" project_id="1" root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" path="" depth="0"
+             purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]"
+             period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]"
+             period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             created_at="2008-12-20 00:00:00.00" build_date="2008-12-20 00:00:00.00"
+             version="1.0" status="P" islast="[true]"/>
+
+
+  <!-- alert -->
+  <project_measures id="1001" metric_id="5" value="510" snapshot_id="101"
+                    url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
+                    variation_value_4="[null]" variation_value_5="400"
+                    rule_priority="[null]" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="WARN" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" characteristic_id="[null]"/>
+
+  <!-- php project -->
+  <projects kee="php_project" long_name="PHP project" scope="PRJ" qualifier="TRK" name="PHP project"
+            id="10" root_id="[null]"
+            description="[null]" enabled="[true]" language="php" copy_resource_id="[null]" person_id="[null]"
+            created_at="2012-12-12 04:06:00.00"/>
+
+
+  <snapshots id="110" project_id="10" root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" path="" depth="0"
+             purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]"
+             period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]"
+             period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             created_at="2012-12-13 04:06:00.00" build_date="2012-12-13 04:06:00.00"
+             version="3.0" status="P" islast="[true]"/>
+
+  <!-- alert -->
+  <project_measures id="1010" metric_id="5" value="5000" snapshot_id="110"
+                    url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
+                    variation_value_4="[null]" variation_value_5="[null]"
+                    rule_priority="[null]" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="OK" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" characteristic_id="[null]"/>
+
+  <!-- js project -->
+  <projects kee="js_project" long_name="JS project" scope="PRJ" qualifier="TRK" name="JS project"
+            id="20" root_id="[null]"
+            description="[null]" enabled="[true]" language="js" copy_resource_id="[null]" person_id="[null]"
+            created_at="2012-12-12 04:06:00.00"/>
+
+
+  <snapshots id="120" project_id="20" root_project_id="20" root_snapshot_id="[null]" parent_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" path="" depth="0"
+             purge_status="[null]" period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]"
+             period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]"
+             period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             created_at="2012-12-13 04:06:00.00" build_date="2012-12-13 04:06:00.00"
+             version="3.0" status="P" islast="[true]"/>
+
+  <!-- alert -->
+  <project_measures id="1020" metric_id="5" value="5000" snapshot_id="120"
+                    url="[null]" variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]"
+                    variation_value_4="[null]" variation_value_5="[null]"
+                    rule_priority="[null]" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="ERROR" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" characteristic_id="[null]"/>
+
+
+</dataset>
\ No newline at end of file