aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-05-10 11:15:16 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-05-11 12:26:46 +0200
commit4e19fe7ccd4c5ff5ca29fb0bdb831ed03942f441 (patch)
tree7d381f8050c7b12541afecb5c7521e875c8fd92f
parent0e6cefb238f064259b13db23a50b0cfa66aa7790 (diff)
downloadsonarqube-4e19fe7ccd4c5ff5ca29fb0bdb831ed03942f441.tar.gz
sonarqube-4e19fe7ccd4c5ff5ca29fb0bdb831ed03942f441.zip
SONAR-7555 Add measures on number of won't fix issues
-rw-r--r--it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java10
-rw-r--r--it/it-tests/src/test/java/it/issue/IssueMeasureTest.java15
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java15
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java46
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java16
6 files changed, 85 insertions, 20 deletions
diff --git a/it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java b/it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java
index 38b7c016c2f..417344cd14f 100644
--- a/it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java
+++ b/it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java
@@ -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;
diff --git a/it/it-tests/src/test/java/it/issue/IssueMeasureTest.java b/it/it-tests/src/test/java/it/issue/IssueMeasureTest.java
index 016e2da5c45..507d88cc349 100644
--- a/it/it-tests/src/test/java/it/issue/IssueMeasureTest.java
+++ b/it/it-tests/src/test/java/it/issue/IssueMeasureTest.java
@@ -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);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java
index 779dce7fcd2..fa95b9efc83 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IssueCounter.java
@@ -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:
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java
index a55dafba40a..c23c67a60ee 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/IssueCounterTest.java
@@ -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,26 +169,60 @@ 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();
diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
index 45484d7f87a..10a2e7214f0 100644
--- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties
+++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties
@@ -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
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 e20b47360fb..cd3b57d20f5 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
@@ -1539,6 +1539,22 @@ public final class CoreMetrics {
.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
*/
public static final String OPEN_ISSUES_KEY = "open_issues";