]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7555 Add measures on number of won't fix issues 943/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 10 May 2016 09:15:16 +0000 (11:15 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 11 May 2016 10:26:46 +0000 (12:26 +0200)
it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java
it/it-tests/src/test/java/it/issue/IssueMeasureTest.java
server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java
server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java
sonar-core/src/main/resources/org/sonar/l10n/core.properties
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java

index 38b7c016c2fbe698bba2b71cc7de1cd005e9e9ff..417344cd14fd48ba9e7d6ae01fef7e71be78f833 100644 (file)
@@ -76,9 +76,9 @@ public class PurgeTest {
     collector.checkThat("Wrong number of files", count("projects where qualifier in ('FIL')"), equalTo(4));
     collector.checkThat("Wrong number of unit test files", count("projects where qualifier in ('UTS')"), equalTo(0));
 
-    int measuresOnTrk = 44;
-    int measuresOnBrc = 216;
-    int measuresOnDir = 137;
+    int measuresOnTrk = 45;
+    int measuresOnBrc = 222;
+    int measuresOnDir = 141;
     int measuresOnFil = 69;
 
     // count measures 
@@ -105,8 +105,8 @@ public class PurgeTest {
     // must be a different date, else a single snapshot is kept per day
     scan(PROJECT_SAMPLE_PATH, DateFormatUtils.ISO_DATE_FORMAT.format(today));
 
-    int newMeasuresOnTrk = 54;
-    int newMeasuresOnBrc = 280;
+    int newMeasuresOnTrk = 55;
+    int newMeasuresOnBrc = 286;
     int newMeasuresOnDir = 44;
     int newMeasuresOnFil = 0;
 
index 016e2da5c4558f560d6bc5c33a129e8a7a93227d..507d88cc349350ab9e326cbb9b96995727378f01 100644 (file)
@@ -64,6 +64,7 @@ public class IssueMeasureTest extends AbstractIssueTest {
 
   /**
    * SONAR-4330
+   * SONAR-7555
    */
   @Test
   public void issues_by_resolution_and_status_measures() {
@@ -75,19 +76,21 @@ public class IssueMeasureTest extends AbstractIssueTest {
     List<Issue> issues = searchIssuesByProject(SAMPLE_PROJECT_KEY);
     assertThat(issues).hasSize(17);
 
-    // 1 is a false-positive, 1 is confirmed, 1 is reopened, and the remaining ones stays open
+    // 1 is a false-positive, 1 is a won't fix, 1 is confirmed, 1 is reopened, and the remaining ones stays open
     adminIssueClient().doTransition(issues.get(0).key(), "falsepositive");
-    adminIssueClient().doTransition(issues.get(1).key(), "confirm");
-    adminIssueClient().doTransition(issues.get(2).key(), "resolve");
-    adminIssueClient().doTransition(issues.get(2).key(), "reopen");
+    adminIssueClient().doTransition(issues.get(1).key(), "wontfix");
+    adminIssueClient().doTransition(issues.get(2).key(), "confirm");
+    adminIssueClient().doTransition(issues.get(3).key(), "resolve");
+    adminIssueClient().doTransition(issues.get(3).key(), "reopen");
 
     // Re analyze the project to compute measures
     runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample");
 
     Resource project = ORCHESTRATOR.getServer().getWsClient().find(
-      ResourceQuery.createForMetrics(SAMPLE_PROJECT_KEY, "false_positive_issues", "open_issues", "reopened_issues", "confirmed_issues"));
+      ResourceQuery.createForMetrics(SAMPLE_PROJECT_KEY, "false_positive_issues", "wont_fix_issues", "open_issues", "reopened_issues", "confirmed_issues"));
     assertThat(project.getMeasureIntValue("false_positive_issues")).isEqualTo(1);
-    assertThat(project.getMeasureIntValue("open_issues")).isEqualTo(14);
+    assertThat(project.getMeasureIntValue("wont_fix_issues")).isEqualTo(1);
+    assertThat(project.getMeasureIntValue("open_issues")).isEqualTo(13);
     assertThat(project.getMeasureIntValue("reopened_issues")).isEqualTo(1);
     assertThat(project.getMeasureIntValue("confirmed_issues")).isEqualTo(1);
   }
index 779dce7fcd268a0e545ca1b38ab9816a4aaa2fcd..fa95b9efc83cefc37e9d22ca2e1c58a94385cd29 100644 (file)
@@ -26,7 +26,6 @@ import com.google.common.collect.Multiset;
 import java.util.HashMap;
 import java.util.Map;
 import javax.annotation.Nullable;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.rules.RuleType;
 import org.sonar.core.issue.DefaultIssue;
@@ -39,6 +38,8 @@ import org.sonar.server.computation.metric.MetricRepository;
 import org.sonar.server.computation.period.Period;
 import org.sonar.server.computation.period.PeriodsHolder;
 
+import static org.sonar.api.issue.Issue.RESOLUTION_FALSE_POSITIVE;
+import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
 import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
 import static org.sonar.api.issue.Issue.STATUS_OPEN;
 import static org.sonar.api.issue.Issue.STATUS_REOPENED;
@@ -58,6 +59,7 @@ import static org.sonar.api.measures.CoreMetrics.NEW_VIOLATIONS_KEY;
 import static org.sonar.api.measures.CoreMetrics.OPEN_ISSUES_KEY;
 import static org.sonar.api.measures.CoreMetrics.REOPENED_ISSUES_KEY;
 import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY;
+import static org.sonar.api.measures.CoreMetrics.WONT_FIX_ISSUES_KEY;
 import static org.sonar.api.rule.Severity.BLOCKER;
 import static org.sonar.api.rule.Severity.CRITICAL;
 import static org.sonar.api.rule.Severity.INFO;
@@ -67,10 +69,8 @@ import static org.sonar.api.rule.Severity.MINOR;
 /**
  * For each component, computes the measures related to number of issues:
  * <ul>
- * <li>unresolved issues</li>
- * <li>false-positives</li>
- * <li>open issues</li>
  * <li>issues per status (open, reopen, confirmed)</li>
+ * <li>issues per resolution (unresolved, false-positives, won't fix)</li>
  * <li>issues per severity (from info to blocker)</li>
  * <li>issues per type (code smell, bug, vulnerability)</li>
  * </ul>
@@ -167,6 +167,7 @@ public class IssueCounter extends IssueVisitor {
     addMeasure(component, REOPENED_ISSUES_KEY, currentCounters.counter().reopened);
     addMeasure(component, CONFIRMED_ISSUES_KEY, currentCounters.counter().confirmed);
     addMeasure(component, FALSE_POSITIVE_ISSUES_KEY, currentCounters.counter().falsePositives);
+    addMeasure(component, WONT_FIX_ISSUES_KEY, currentCounters.counter().wontFix);
   }
 
   private void addMeasuresByType(Component component) {
@@ -231,6 +232,7 @@ public class IssueCounter extends IssueVisitor {
     private int reopened = 0;
     private int confirmed = 0;
     private int falsePositives = 0;
+    private int wontFix = 0;
     private final Multiset<String> severityBag = HashMultiset.create();
     private final EnumMultiset<RuleType> typeBag = EnumMultiset.create(RuleType.class);
 
@@ -240,6 +242,7 @@ public class IssueCounter extends IssueVisitor {
       reopened += counter.reopened;
       confirmed += counter.confirmed;
       falsePositives += counter.falsePositives;
+      wontFix += counter.wontFix;
       severityBag.addAll(counter.severityBag);
       typeBag.addAll(counter.typeBag);
     }
@@ -249,8 +252,10 @@ public class IssueCounter extends IssueVisitor {
         unresolved++;
         typeBag.add(issue.type());
         severityBag.add(issue.severity());
-      } else if (Issue.RESOLUTION_FALSE_POSITIVE.equals(issue.resolution())) {
+      } else if (RESOLUTION_FALSE_POSITIVE.equals(issue.resolution())) {
         falsePositives++;
+      } else if (RESOLUTION_WONT_FIX.equals(issue.resolution())) {
+        wontFix++;
       }
       switch (issue.status()) {
         case STATUS_OPEN:
index a55dafba40a237c7cafe7980717a332bc57d7002..c23c67a60eee86cdb8cfc4f0a08fd79f1365b35e 100644 (file)
@@ -43,6 +43,7 @@ import org.sonar.server.computation.period.PeriodsHolderRule;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.issue.Issue.RESOLUTION_FALSE_POSITIVE;
 import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
+import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
 import static org.sonar.api.issue.Issue.STATUS_CLOSED;
 import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
 import static org.sonar.api.issue.Issue.STATUS_OPEN;
@@ -63,6 +64,7 @@ import static org.sonar.api.measures.CoreMetrics.NEW_VIOLATIONS_KEY;
 import static org.sonar.api.measures.CoreMetrics.OPEN_ISSUES_KEY;
 import static org.sonar.api.measures.CoreMetrics.REOPENED_ISSUES_KEY;
 import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY;
+import static org.sonar.api.measures.CoreMetrics.WONT_FIX_ISSUES_KEY;
 import static org.sonar.api.rule.Severity.BLOCKER;
 import static org.sonar.api.rule.Severity.CRITICAL;
 import static org.sonar.api.rule.Severity.MAJOR;
@@ -92,6 +94,7 @@ public class IssueCounterTest {
   static final Metric NEW_MINOR_ISSUES_METRIC = new MetricImpl(14, NEW_MINOR_VIOLATIONS_KEY, NEW_MINOR_VIOLATIONS_KEY, INT);
   static final Metric NEW_INFO_ISSUES_METRIC = new MetricImpl(15, NEW_INFO_VIOLATIONS_KEY, NEW_INFO_VIOLATIONS_KEY, INT);
   static final Metric FALSE_POSITIVE_ISSUES_METRIC = new MetricImpl(16, FALSE_POSITIVE_ISSUES_KEY, FALSE_POSITIVE_ISSUES_KEY, INT);
+  static final Metric WONT_FIX_ISSUES_METRIC = new MetricImpl(23, WONT_FIX_ISSUES_KEY, WONT_FIX_ISSUES_KEY, INT);
   static final Metric CODE_SMELLS_METRIC = new MetricImpl(17, CoreMetrics.CODE_SMELLS_KEY, CoreMetrics.CODE_SMELLS_KEY, INT);
   static final Metric BUGS_METRIC = new MetricImpl(18, CoreMetrics.BUGS_KEY, CoreMetrics.BUGS_KEY, INT);
   static final Metric VULNERABILITIES_METRIC = new MetricImpl(19, CoreMetrics.VULNERABILITIES_KEY, CoreMetrics.VULNERABILITIES_KEY, INT);
@@ -126,6 +129,7 @@ public class IssueCounterTest {
     .add(NEW_MINOR_ISSUES_METRIC)
     .add(NEW_INFO_ISSUES_METRIC)
     .add(FALSE_POSITIVE_ISSUES_METRIC)
+    .add(WONT_FIX_ISSUES_METRIC)
     .add(CODE_SMELLS_METRIC)
     .add(BUGS_METRIC)
     .add(VULNERABILITIES_METRIC)
@@ -165,25 +169,59 @@ public class IssueCounterTest {
     underTest.beforeComponent(PROJECT);
     underTest.afterComponent(PROJECT);
 
-    // count by status
     assertThat(measureRepository.getRawMeasure(FILE1, ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
     assertThat(measureRepository.getRawMeasure(FILE1, OPEN_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
-    assertThat(measureRepository.getRawMeasure(FILE1, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
     assertThat(measureRepository.getRawMeasure(FILE1, CONFIRMED_ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
 
     assertThat(measureRepository.getRawMeasure(FILE2, ISSUES_METRIC).get().getIntValue()).isEqualTo(2);
     assertThat(measureRepository.getRawMeasure(FILE2, OPEN_ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
-    assertThat(measureRepository.getRawMeasure(FILE2, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
     assertThat(measureRepository.getRawMeasure(FILE2, CONFIRMED_ISSUES_METRIC).get().getIntValue()).isEqualTo(2);
 
     assertThat(measureRepository.getRawMeasure(FILE3, ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
 
     assertThat(measureRepository.getRawMeasure(PROJECT, ISSUES_METRIC).get().getIntValue()).isEqualTo(3);
     assertThat(measureRepository.getRawMeasure(PROJECT, OPEN_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
-    assertThat(measureRepository.getRawMeasure(PROJECT, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
     assertThat(measureRepository.getRawMeasure(PROJECT, CONFIRMED_ISSUES_METRIC).get().getIntValue()).isEqualTo(2);
   }
 
+  @Test
+  public void count_issues_by_resolution() {
+    periodsHolder.setPeriods();
+
+    // bottom-up traversal -> from files to project
+    underTest.beforeComponent(FILE1);
+    underTest.onIssue(FILE1, createIssue(null, STATUS_OPEN, BLOCKER));
+    underTest.onIssue(FILE1, createIssue(RESOLUTION_FIXED, STATUS_CLOSED, MAJOR));
+    underTest.onIssue(FILE1, createIssue(RESOLUTION_FALSE_POSITIVE, STATUS_RESOLVED, MAJOR));
+    underTest.onIssue(FILE1, createIssue(RESOLUTION_WONT_FIX, STATUS_CLOSED, MAJOR));
+    underTest.afterComponent(FILE1);
+
+    underTest.beforeComponent(FILE2);
+    underTest.onIssue(FILE2, createIssue(null, STATUS_CONFIRMED, BLOCKER));
+    underTest.onIssue(FILE2, createIssue(null, STATUS_CONFIRMED, MAJOR));
+    underTest.onIssue(FILE2, createIssue(RESOLUTION_WONT_FIX, STATUS_CLOSED, MAJOR));
+    underTest.afterComponent(FILE2);
+
+    underTest.beforeComponent(FILE3);
+    underTest.afterComponent(FILE3);
+
+    underTest.beforeComponent(PROJECT);
+    underTest.afterComponent(PROJECT);
+
+    assertThat(measureRepository.getRawMeasure(FILE1, ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
+    assertThat(measureRepository.getRawMeasure(FILE1, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
+    assertThat(measureRepository.getRawMeasure(FILE1, WONT_FIX_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
+
+    assertThat(measureRepository.getRawMeasure(FILE2, ISSUES_METRIC).get().getIntValue()).isEqualTo(2);
+    assertThat(measureRepository.getRawMeasure(FILE2, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
+    assertThat(measureRepository.getRawMeasure(FILE2, WONT_FIX_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
+
+    assertThat(measureRepository.getRawMeasure(FILE3, ISSUES_METRIC).get().getIntValue()).isEqualTo(0);
+
+    assertThat(measureRepository.getRawMeasure(PROJECT, FALSE_POSITIVE_ISSUES_METRIC).get().getIntValue()).isEqualTo(1);
+    assertThat(measureRepository.getRawMeasure(PROJECT, WONT_FIX_ISSUES_METRIC).get().getIntValue()).isEqualTo(2);
+  }
+
   @Test
   public void count_unresolved_issues_by_severity() {
     periodsHolder.setPeriods();
index 45484d7f87add222a6d1fe047d56520c22f14d21..10a2e7214f0b3a6b73e2b151a634762cb57cd196 100644 (file)
@@ -2731,6 +2731,9 @@ metric.profile_version.description=Selected quality profile version
 metric.false_positive_issues.name=False Positive Issues
 metric.false_positive_issues.description=False positive issues
 
+metric.wont_fix_issues.name=Won't Fix  Issues
+metric.wont_fix_issues.description=Won't fix issues
+
 metric.open_issues.name=Open Issues
 metric.open_issues.description=Open issues
 
index e20b47360fbd41b9c94f833958568c8fb7ec3154..cd3b57d20f547b55c4d2c7487700ef7aa12b8b08 100644 (file)
@@ -1538,6 +1538,22 @@ public final class CoreMetrics {
     .setOptimizedBestValue(true)
     .create();
 
+  /**
+   * @since 5.6
+   */
+  public static final String WONT_FIX_ISSUES_KEY = "wont_fix_issues";
+
+  /**
+   * @since 5.6
+   */
+  public static final Metric<Integer> WONT_FIX_ISSUES = new Metric.Builder(WONT_FIX_ISSUES_KEY, "Won't Fix Issues", Metric.ValueType.INT)
+    .setDescription("Won't fix issues")
+    .setDirection(Metric.DIRECTION_WORST)
+    .setDomain(DOMAIN_ISSUES)
+    .setBestValue(0.0)
+    .setOptimizedBestValue(true)
+    .create();
+
   /**
    * @since 3.6
    */