Skip to content

Commit

Permalink
SONAR-7555 Add measures on number of won't fix issues
Browse files Browse the repository at this point in the history
  • Loading branch information
julienlancelot committed May 11, 2016
1 parent 0e6cefb commit 4e19fe7
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 20 deletions.
10 changes: 5 additions & 5 deletions it/it-tests/src/test/java/it/dbCleaner/PurgeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public void test_evolution_of_number_of_rows_when_scanning_two_times_the_same_pr
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 
Expand All @@ -105,8 +105,8 @@ public void test_evolution_of_number_of_rows_when_scanning_two_times_the_same_pr
// 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;

Expand Down
15 changes: 9 additions & 6 deletions it/it-tests/src/test/java/it/issue/IssueMeasureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public void issues_by_severity_measures() {

/**
* SONAR-4330
* SONAR-7555
*/
@Test
public void issues_by_resolution_and_status_measures() {
Expand All @@ -75,19 +76,21 @@ public void issues_by_resolution_and_status_measures() {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
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;
Expand All @@ -39,6 +38,8 @@
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;
Expand All @@ -58,6 +59,7 @@
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;
Expand All @@ -67,10 +69,8 @@
/**
* 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>
Expand Down Expand Up @@ -167,6 +167,7 @@ private void addMeasuresByStatus(Component component) {
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) {
Expand Down Expand Up @@ -231,6 +232,7 @@ private static class Counter {
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);

Expand All @@ -240,6 +242,7 @@ void add(Counter counter) {
reopened += counter.reopened;
confirmed += counter.confirmed;
falsePositives += counter.falsePositives;
wontFix += counter.wontFix;
severityBag.addAll(counter.severityBag);
typeBag.addAll(counter.typeBag);
}
Expand All @@ -249,8 +252,10 @@ void add(DefaultIssue issue) {
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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
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;
Expand All @@ -63,6 +64,7 @@
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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -165,25 +169,59 @@ public void count_issues_by_status() {
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();
Expand Down
3 changes: 3 additions & 0 deletions sonar-core/src/main/resources/org/sonar/l10n/core.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit 4e19fe7

Please sign in to comment.